[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Bring RegistryCreateKey()'s semantics in line with Win32 RegCreateKeyEx()
RegCreateKeyEx() will create intermediate keys in a path whereas ZwCreateKey() will not. Thus, to align the semantics, this patch will parse the path passwed to RegistryCreateKey() and create subkeys one by one. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- src/common/registry.c | 144 +++++++++++++++++++++++++++++++++++++++----------- src/common/util.h | 42 ++++++++++++++- 2 files changed, 153 insertions(+), 33 deletions(-) diff --git a/src/common/registry.c b/src/common/registry.c index d994e13..2467290 100644 --- a/src/common/registry.c +++ b/src/common/registry.c @@ -115,36 +115,132 @@ fail1: return status; } +static NTSTATUS +RegistryOpenRoot( + IN PWCHAR Path, + OUT PHANDLE Parent, + OUT PWCHAR *ChildPath + ) +{ + const WCHAR Prefix[] = L"\\Registry\\Machine\\"; + ULONG Length; + UNICODE_STRING Unicode; + NTSTATUS status; + + Length = (ULONG)wcslen(Prefix); + + status = STATUS_INVALID_PARAMETER; + if (_wcsnicmp(Path, Prefix, Length) != 0) + goto fail1; + + RtlInitUnicodeString(&Unicode, Prefix); + + status = RegistryOpenKey(NULL, &Unicode, KEY_ALL_ACCESS, Parent); + if (!NT_SUCCESS(status)) + goto fail2; + + *ChildPath = Path + Length; + + return STATUS_SUCCESS; + +fail2: +fail1: + return status; +} + NTSTATUS RegistryCreateKey( - IN HANDLE Parent, + IN HANDLE Root, IN PUNICODE_STRING Path, IN ULONG Options, OUT PHANDLE Key ) { - OBJECT_ATTRIBUTES Attributes; + PWCHAR Buffer; + HANDLE Parent; + PWCHAR ChildPath; + PWCHAR ChildName; + PWCHAR Context; + HANDLE Child; NTSTATUS status; - InitializeObjectAttributes(&Attributes, - Path, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - Parent, - NULL); + // + // UNICODE_STRINGs are not guaranteed to have NUL terminated + // buffers. + // - status = ZwCreateKey(Key, - KEY_ALL_ACCESS, - &Attributes, - 0, - NULL, - Options, - NULL - ); - if (!NT_SUCCESS(status)) + Buffer = __RegistryAllocate(Path->MaximumLength + sizeof (WCHAR)); + + status = STATUS_NO_MEMORY; + if (Buffer == NULL) goto fail1; + RtlCopyMemory(Buffer, Path->Buffer, Path->Length); + + if (Root != NULL) { + Parent = Root; + ChildPath = Buffer; + } else { + status = RegistryOpenRoot(Buffer, &Parent, &ChildPath); + if (!NT_SUCCESS(status)) + goto fail2; + } + + ChildName = __wcstok_r(ChildPath, L"\\", &Context); + + status = STATUS_INVALID_PARAMETER; + if (ChildName == NULL) + goto fail3; + + Child = NULL; + + while (ChildName != NULL) { + UNICODE_STRING Unicode; + OBJECT_ATTRIBUTES Attributes; + + RtlInitUnicodeString(&Unicode, ChildName); + + InitializeObjectAttributes(&Attributes, + &Unicode, + OBJ_CASE_INSENSITIVE | + OBJ_KERNEL_HANDLE | + OBJ_OPENIF, + Parent, + NULL); + + status = ZwCreateKey(&Child, + KEY_ALL_ACCESS, + &Attributes, + 0, + NULL, + Options, + NULL + ); + if (!NT_SUCCESS(status)) + goto fail4; + + ChildName = __wcstok_r(NULL, L"\\", &Context); + + if (Parent != Root) + ZwClose(Parent); + + Parent = Child; + } + + ASSERT(Child != NULL); + + *Key = Child; + return STATUS_SUCCESS; +fail4: +fail3: + if (Parent != Root) + ZwClose(Parent); + +fail2: + __RegistryFree(Buffer); + fail1: return status; } @@ -308,7 +404,6 @@ RegistryCreateSubKey( { ANSI_STRING Ansi; UNICODE_STRING Unicode; - OBJECT_ATTRIBUTES Attributes; NTSTATUS status; RtlInitAnsiString(&Ansi, Name); @@ -317,20 +412,7 @@ RegistryCreateSubKey( if (!NT_SUCCESS(status)) goto fail1; - InitializeObjectAttributes(&Attributes, - &Unicode, - OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, - Key, - NULL); - - status = ZwCreateKey(SubKey, - KEY_ALL_ACCESS, - &Attributes, - 0, - NULL, - Options, - NULL - ); + status = RegistryCreateKey(Key, &Unicode, Options, SubKey); if (!NT_SUCCESS(status)) goto fail2; diff --git a/src/common/util.h b/src/common/util.h index 7798ebd..dc8a60e 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -267,16 +267,54 @@ __strtok_r( if (Token == NULL) return NULL; - while (*Token != L'\0' && + while (*Token != '\0' && strchr(Delimiter, *Token) != NULL) Token++; + if (*Token == '\0') + return NULL; + + End = Token + 1; + while (*End != '\0' && + strchr(Delimiter, *End) == NULL) + End++; + + if (*End != '\0') + *End++ = '\0'; + + *Context = End; + + return Token; +} + +static FORCEINLINE PWCHAR +__wcstok_r( + IN PWCHAR Buffer, + IN PWCHAR Delimiter, + IN OUT PWCHAR *Context + ) +{ + PWCHAR Token; + PWCHAR End; + + if (Buffer != NULL) + *Context = Buffer; + + Token = *Context; + + if (Token == NULL) + return NULL; + + while (*Token != L'\0' && + wcschr(Delimiter, *Token) != NULL) + Token++; + if (*Token == L'\0') return NULL; End = Token + 1; while (*End != L'\0' && - strchr(Delimiter, *End) == NULL) + wcschr(Delimiter, *End) == NULL) End++; if (*End != L'\0') -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |