[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH] Update registry code



Bring in new registry code from XENBUS to fix RegistryCreateKey()'s
semantics.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenvif/registry.c | 242 ++++++++++++++++++++++++++++++++------------------
 src/xenvif/util.h     |  42 ++++++++-
 2 files changed, 195 insertions(+), 89 deletions(-)

diff --git a/src/xenvif/registry.c b/src/xenvif/registry.c
index 0d3b3c5..233569f 100644
--- a/src/xenvif/registry.c
+++ b/src/xenvif/registry.c
@@ -115,6 +115,39 @@ 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,
@@ -123,28 +156,92 @@ RegistryCreateKey(
     OUT PHANDLE         Key
     )
 {
-    OBJECT_ATTRIBUTES   Attributes;
+    PWCHAR              Buffer;
+    HANDLE              Root;
+    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);
+
+    Root = Parent;
+
+    if (Parent != NULL) {
+        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 +405,6 @@ RegistryCreateSubKey(
 {
     ANSI_STRING         Ansi;
     UNICODE_STRING      Unicode;
-    OBJECT_ATTRIBUTES   Attributes;
     NTSTATUS            status;
 
     RtlInitAnsiString(&Ansi, Name);
@@ -317,27 +413,57 @@ RegistryCreateSubKey(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    InitializeObjectAttributes(&Attributes,
-                               &Unicode,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               Key,
-                               NULL);
+    status = RegistryCreateKey(Key, &Unicode, Options, SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
 
-    status = ZwCreateKey(SubKey,
-                         KEY_ALL_ACCESS,
-                         &Attributes,
-                         0,
-                         NULL,
-                         Options,
-                         NULL
-                         );
+NTSTATUS
+RegistryDeleteSubKey(
+    IN  PHANDLE         Key,
+    IN  PCHAR           Name
+    )
+{
+    ANSI_STRING         Ansi;
+    UNICODE_STRING      Unicode;
+    HANDLE              SubKey;
+    NTSTATUS            status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
     if (!NT_SUCCESS(status))
         goto fail2;
 
+    status = ZwDeleteKey(SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    ZwClose(SubKey);
+
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
 
+fail3:
+    ZwClose(SubKey);
+
 fail2:
     RtlFreeUnicodeString(&Unicode);
 
@@ -449,64 +575,6 @@ fail1:
     return status;
 }
 
-static NTSTATUS
-RegistryDeleteSubKeyTree(
-    IN  PVOID           Context,
-    IN  PHANDLE         Key,
-    IN  PANSI_STRING    Name
-    )
-{
-    HANDLE              SubKey;
-    NTSTATUS            status;
-
-    UNREFERENCED_PARAMETER(Context);
-
-    status = RegistryOpenSubKey(Key,
-                                Name->Buffer,
-                                KEY_ALL_ACCESS,
-                                &SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    (VOID) RegistryEnumerateSubKeys(SubKey,
-                                    RegistryDeleteSubKeyTree,
-                                    NULL);
-
-    status = ZwDeleteKey(SubKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    ZwClose(SubKey);
-
-    return STATUS_SUCCESS;
-
-fail2:
-    ZwClose(SubKey);
-
-fail1:
-    return status;
-}
-
-NTSTATUS
-RegistryDeleteSubKey(
-    IN  PHANDLE Key,
-    IN  PCHAR   Name
-    )
-{
-    ANSI_STRING Ansi;
-    NTSTATUS    status;
-
-    RtlInitAnsiString(&Ansi, Name);
-
-    status = RegistryDeleteSubKeyTree(NULL,
-                                      Key,
-                                      &Ansi);
-
-    (VOID) ZwFlushKey(Key);
-
-    return status;
-}
-
 NTSTATUS
 RegistryEnumerateValues(
     IN  HANDLE                      Key,
diff --git a/src/xenvif/util.h b/src/xenvif/util.h
index 6d140b0..81dfb49 100644
--- a/src/xenvif/util.h
+++ b/src/xenvif/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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.