From 54cbe5281bc67fb48b7b414ea58d2cabf72e5e00 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Sun, 4 Nov 2007 11:49:57 +0000 Subject: [PATCH] Fix key parsing by copying the unicode string struct we get from CmFindObject for us to modify, and free the original. We needn't make any assumptions about the string being null terminated. Parse names with duplicated \ characters. Since we assert downstream for a null key, bail early here with an error if we really get a degenerate key name. With the work that others have done on the registry code, this is the last piece needed for the firefox installer. svn path=/trunk/; revision=30104 --- reactos/ntoskrnl/cm/ntfunc.c | 44 +++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/reactos/ntoskrnl/cm/ntfunc.c b/reactos/ntoskrnl/cm/ntfunc.c index 23e7160f8b1..ecf3a8ff28d 100644 --- a/reactos/ntoskrnl/cm/ntfunc.c +++ b/reactos/ntoskrnl/cm/ntfunc.c @@ -135,12 +135,11 @@ NtCreateKey(OUT PHANDLE KeyHandle, IN ULONG CreateOptions, OUT PULONG Disposition) { - UNICODE_STRING RemainingPath = {0}; + UNICODE_STRING RemainingPath = {0}, ReturnedPath = {0}; ULONG LocalDisposition; PKEY_OBJECT KeyObject; NTSTATUS Status = STATUS_SUCCESS; PVOID Object = NULL; - PWSTR Start; UNICODE_STRING ObjectName; OBJECT_CREATE_INFORMATION ObjectCreateInfo; unsigned int i; @@ -219,7 +218,7 @@ NtCreateKey(OUT PHANDLE KeyHandle, Status = CmFindObject(&ObjectCreateInfo, &ObjectName, (PVOID*)&Object, - &RemainingPath, + &ReturnedPath, CmpKeyObjectType, NULL, NULL); @@ -232,8 +231,9 @@ NtCreateKey(OUT PHANDLE KeyHandle, DPRINT1("CmpFindObject failed, Status: 0x%x\n", Status); goto Cleanup; } - - DPRINT("RemainingPath %wZ\n", &RemainingPath); + + RemainingPath = ReturnedPath; + DPRINT("RemainingPath (preparse) %wZ\n", &RemainingPath); if (RemainingPath.Length == 0) { @@ -267,24 +267,21 @@ NtCreateKey(OUT PHANDLE KeyHandle, /* If RemainingPath contains \ we must return error because NtCreateKey doesn't create trees */ - Start = RemainingPath.Buffer; - if (*Start == L'\\') + while (RemainingPath.Length && *RemainingPath.Buffer == L'\\') { - Start++; - //RemainingPath.Length -= sizeof(WCHAR); - //RemainingPath.MaximumLength -= sizeof(WCHAR); - //RemainingPath.Buffer++; - //DPRINT1("String: %wZ\n", &RemainingPath); + RemainingPath.Length -= sizeof(WCHAR); + RemainingPath.MaximumLength -= sizeof(WCHAR); + RemainingPath.Buffer++; } - if (RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] == '\\') + while (RemainingPath.Length && + RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] == '\\') { - RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL; RemainingPath.Length -= sizeof(WCHAR); RemainingPath.MaximumLength -= sizeof(WCHAR); } - for (i = 1; i < RemainingPath.Length / sizeof(WCHAR); i++) + for (i = 0; i < RemainingPath.Length / sizeof(WCHAR); i++) { if (L'\\' == RemainingPath.Buffer[i]) { @@ -299,7 +296,15 @@ NtCreateKey(OUT PHANDLE KeyHandle, } } - DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer, Object); + DPRINT("RemainingPath %wZ ParentObject 0x%p\n", &RemainingPath, Object); + + // + if (RemainingPath.Length == 0 || RemainingPath.Buffer[0] == UNICODE_NULL) + { + Status = STATUS_OBJECT_NAME_NOT_FOUND; + goto Cleanup; + } + /* Acquire hive lock */ KeEnterCriticalRegion(); @@ -331,7 +336,10 @@ NtCreateKey(OUT PHANDLE KeyHandle, goto Cleanup; } - RtlCreateUnicodeString(&KeyObject->Name, Start); + RtlDuplicateUnicodeString + (RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, + &RemainingPath, &KeyObject->Name); + DPRINT("Key Name: %wZ\n", &KeyObject->Name); ParentNode = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->ParentKcb->KeyHive, KeyObject->KeyControlBlock->ParentKcb->KeyCell); @@ -408,7 +416,7 @@ Cleanup: PreviousMode); } if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName); - RtlFreeUnicodeString(&RemainingPath); + RtlFreeUnicodeString(&ReturnedPath); if (Object != NULL) ObDereferenceObject(Object); return Status;