Author: arty
Date: Sun Nov 4 14:49:57 2007
New Revision: 30104
URL:
http://svn.reactos.org/svn/reactos?rev=30104&view=rev
Log:
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.
Modified:
trunk/reactos/ntoskrnl/cm/ntfunc.c
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=3…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Sun Nov 4 14:49:57 2007
@@ -135,12 +135,11 @@
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 @@
Status = CmFindObject(&ObjectCreateInfo,
&ObjectName,
(PVOID*)&Object,
- &RemainingPath,
+ &ReturnedPath,
CmpKeyObjectType,
NULL,
NULL);
@@ -232,8 +231,9 @@
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 @@
/* If RemainingPath contains \ we must return error
because NtCreateKey doesn't create trees */
- Start = RemainingPath.Buffer;
- if (*Start == L'\\')
- {
- Start++;
- //RemainingPath.Length -= sizeof(WCHAR);
- //RemainingPath.MaximumLength -= sizeof(WCHAR);
- //RemainingPath.Buffer++;
- //DPRINT1("String: %wZ\n", &RemainingPath);
- }
-
- if (RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] ==
'\\')
- {
- RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL;
+ while (RemainingPath.Length && *RemainingPath.Buffer == L'\\')
+ {
RemainingPath.Length -= sizeof(WCHAR);
RemainingPath.MaximumLength -= sizeof(WCHAR);
- }
-
- for (i = 1; i < RemainingPath.Length / sizeof(WCHAR); i++)
+ RemainingPath.Buffer++;
+ }
+
+ while (RemainingPath.Length &&
+ RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] ==
'\\')
+ {
+ RemainingPath.Length -= sizeof(WCHAR);
+ RemainingPath.MaximumLength -= sizeof(WCHAR);
+ }
+
+ for (i = 0; i < RemainingPath.Length / sizeof(WCHAR); i++)
{
if (L'\\' == RemainingPath.Buffer[i])
{
@@ -299,7 +296,15 @@
}
}
- 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 @@
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 @@
PreviousMode);
}
if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName);
- RtlFreeUnicodeString(&RemainingPath);
+ RtlFreeUnicodeString(&ReturnedPath);
if (Object != NULL) ObDereferenceObject(Object);
return Status;