From aa8d624253a0b7a84cddee01da3b8029dee71b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Thu, 16 Apr 2026 15:53:54 +0200 Subject: [PATCH] [SMSS] "BootDir" value creation: Fix fallback code Addendum to commit c498d0930a. `SmpTranslateSystemPartitionInformation()`: Reset the `DirInfo->Name.Buffer` to use the `DirInfoBuffer` scratch area, before doing the OS boot drive letter fallback. Otherwise, writing directly to `DirInfo->Name.Buffer` would use its old value, that is going to be `NULL` when the calls to `NtQueryDirectoryObject()` failed, and this would induce a memory access crash. Take also the opportunity to use structures embedding the `KEY_VALUE_PARTIAL_INFORMATION` and `OBJECT_DIRECTORY_INFORMATION` data headers, instead of straight `CHAR` arrays. This allows the structures to use the correct memory alignments required by these data headers. --- base/system/smss/sminit.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/base/system/smss/sminit.c b/base/system/smss/sminit.c index 3594e52d62c..4a31b6b20df 100644 --- a/base/system/smss/sminit.c +++ b/base/system/smss/sminit.c @@ -811,16 +811,16 @@ NTAPI SmpTranslateSystemPartitionInformation(VOID) { NTSTATUS Status; - UNICODE_STRING UnicodeString, LinkTarget, SearchString, SystemPartition; + UNICODE_STRING UnicodeString, LinkTarget, SymLinkU, SystemPartition; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE KeyHandle, LinkHandle; ULONG Length, Context; size_t StrLength; WCHAR LinkBuffer[MAX_PATH]; - CHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 512]; - PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)ValueBuffer; - CHAR DirInfoBuffer[sizeof(OBJECT_DIRECTORY_INFORMATION) + 512]; - POBJECT_DIRECTORY_INFORMATION DirInfo = (PVOID)DirInfoBuffer; + struct { KEY_VALUE_PARTIAL_INFORMATION; CHAR Buffer[512]; } ValueBuffer; + struct { OBJECT_DIRECTORY_INFORMATION; WCHAR Buffer[256]; } DirInfoBuffer; + PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)&ValueBuffer; + POBJECT_DIRECTORY_INFORMATION DirInfo = (PVOID)&DirInfoBuffer; /* Open the setup key */ RtlInitUnicodeString(&UnicodeString, L"\\Registry\\Machine\\System\\Setup"); @@ -841,7 +841,7 @@ SmpTranslateSystemPartitionInformation(VOID) Status = NtQueryValueKey(KeyHandle, &UnicodeString, KeyValuePartialInformation, - PartialInfo, + &ValueBuffer, sizeof(ValueBuffer), &Length); NtClose(KeyHandle); @@ -863,10 +863,10 @@ SmpTranslateSystemPartitionInformation(VOID) SystemPartition.Length = (USHORT)StrLength; /* Enumerate the directory looking for the symbolic link string */ - RtlInitUnicodeString(&SearchString, L"SymbolicLink"); + RtlInitUnicodeString(&SymLinkU, L"SymbolicLink"); RtlInitEmptyUnicodeString(&LinkTarget, LinkBuffer, sizeof(LinkBuffer)); Status = NtQueryDirectoryObject(SmpDosDevicesObjectDirectory, - DirInfo, + &DirInfoBuffer, sizeof(DirInfoBuffer), TRUE, TRUE, @@ -876,7 +876,7 @@ SmpTranslateSystemPartitionInformation(VOID) while (NT_SUCCESS(Status)) { /* Is this it? */ - if (RtlEqualUnicodeString(&DirInfo->TypeName, &SearchString, TRUE) && + if (RtlEqualUnicodeString(&DirInfo->TypeName, &SymLinkU, TRUE) && (DirInfo->Name.Length == 2 * sizeof(WCHAR)) && (DirInfo->Name.Buffer[1] == L':')) { @@ -911,7 +911,7 @@ SmpTranslateSystemPartitionInformation(VOID) /* Couldn't find it, try again */ Status = NtQueryDirectoryObject(SmpDosDevicesObjectDirectory, - DirInfo, + &DirInfoBuffer, sizeof(DirInfoBuffer), TRUE, FALSE, @@ -928,6 +928,7 @@ SmpTranslateSystemPartitionInformation(VOID) * NOTE: This has been introduced in a post-SP1 Windows 7 update. */ if (Status != STATUS_NO_MORE_ENTRIES) return; + DirInfo->Name.Buffer = DirInfoBuffer.Buffer; DirInfo->Name.Buffer[0] = SharedUserData->NtSystemRoot[0]; DirInfo->Name.Buffer[1] = SharedUserData->NtSystemRoot[1]; // == L':'; #else