From 5a5afdcc2d1b472478e68db686c79b2a267c8fe2 Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Sat, 21 Oct 2023 22:19:58 +0200 Subject: [PATCH] [0.4.11][SDK:RTL] RtlpCallQueryRegistryRoutine(): Correctly set SpareData and SpareLength (#5466) ports back: 0.4.15-dev-6640-g 02883d1c163c3e11c95ffb873f071be384b13bda SpareData and SpareLength need to be calculated correctly, as they are used later in that function as well. This allows to not overwrite Source UString when writing to Destination UString. Fixes the problem described in the following JIRA issue, where services could not start in 2nd-stage-bootcd-setup when installing ReactOS in a very-long-named directory. CORE-18988 --- sdk/lib/rtl/registry.c | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/sdk/lib/rtl/registry.c b/sdk/lib/rtl/registry.c index bc69d4d0b33..7c15152ff59 100644 --- a/sdk/lib/rtl/registry.c +++ b/sdk/lib/rtl/registry.c @@ -196,36 +196,36 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable, } else { + /* Check if we have length */ + if (KeyValueInfo->DataLength) + { + /* Increase the spare data */ + SpareData += KeyValueInfo->DataOffset + + KeyValueInfo->DataLength; + } + else + { + /* Otherwise, the spare data only has the name data */ + SpareData += FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + + KeyValueInfo->NameLength; + } + + /* Align the pointer and get new size of spare data */ + SpareData = (PVOID)(((ULONG_PTR)SpareData + 7) & ~7); + SpareLength = DataEnd - SpareData; + + /* Check if we have space to copy the data */ + RequiredLength = KeyValueInfo->NameLength + sizeof(UNICODE_NULL); + if ((SpareData > DataEnd) || (SpareLength < RequiredLength)) + { + /* Fail and return the missing length */ + *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) + RequiredLength; + return STATUS_BUFFER_TOO_SMALL; + } + /* Check if this isn't a direct return */ if (!(QueryTable->Flags & RTL_QUERY_REGISTRY_DIRECT)) { - /* Check if we have length */ - if (KeyValueInfo->DataLength) - { - /* Increase the spare data */ - SpareData += KeyValueInfo->DataOffset + - KeyValueInfo->DataLength; - } - else - { - /* Otherwise, the spare data only has the name data */ - SpareData += FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name) + - KeyValueInfo->NameLength; - } - - /* Align the pointer and get new size of spare data */ - SpareData = (PVOID)(((ULONG_PTR)SpareData + 7) & ~7); - SpareLength = DataEnd - SpareData; - - /* Check if we have space to copy the data */ - RequiredLength = KeyValueInfo->NameLength + sizeof(UNICODE_NULL); - if ((SpareData > DataEnd) || (SpareLength < RequiredLength)) - { - /* Fail and return the missing length */ - *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) + RequiredLength; - return STATUS_BUFFER_TOO_SMALL; - } - /* Copy the data and null-terminate it */ Name = (PWCHAR)SpareData; RtlCopyMemory(Name, KeyValueInfo->Name, KeyValueInfo->NameLength); @@ -330,7 +330,7 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable, RtlInitEmptyUnicodeString(&Source, Data, (USHORT)Length); Source.Length = Source.MaximumLength - sizeof(UNICODE_NULL); - /* Setup the desination string */ + /* Setup the destination string */ RtlInitEmptyUnicodeString(&Destination, (PWCHAR)SpareData, 0); /* Check if we're out of space */