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

[win-pv-devel] [PATCH] Re-synchronize registry.c with XENBUS



The registry code in XENBUS has some fixes that are not present in the
XENIFACE copy, so import the updated code from XENBUS.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xeniface/registry.c | 263 ++++++++++++++++++++++++++++++++++++++++++------
 src/xeniface/registry.h |  41 +++++++-
 2 files changed, 268 insertions(+), 36 deletions(-)

diff --git a/src/xeniface/registry.c b/src/xeniface/registry.c
index 136502c..d994e13 100644
--- a/src/xeniface/registry.c
+++ b/src/xeniface/registry.c
@@ -32,10 +32,10 @@
 #include <ntddk.h>
 
 #include "registry.h"
-#include "util.h"
 #include "assert.h"
+#include "util.h"
 
-#define REGISTRY_POOL 'GERX'
+#define REGISTRY_TAG 'GERX'
 
 static UNICODE_STRING   RegistryPath;
 
@@ -44,7 +44,7 @@ __RegistryAllocate(
     IN  ULONG   Length
     )
 {
-    return __AllocatePoolWithTag(NonPagedPool, Length, REGISTRY_POOL);
+    return __AllocatePoolWithTag(NonPagedPool, Length, REGISTRY_TAG);
 }
 
 static FORCEINLINE VOID
@@ -52,7 +52,7 @@ __RegistryFree(
     IN  PVOID   Buffer
     )
 {
-    __FreePoolWithTag(Buffer, REGISTRY_POOL);
+    __FreePoolWithTag(Buffer, REGISTRY_TAG);
 }
 
 NTSTATUS
@@ -116,6 +116,40 @@ fail1:
 }
 
 NTSTATUS
+RegistryCreateKey(
+    IN  HANDLE          Parent,
+    IN  PUNICODE_STRING Path,
+    IN  ULONG           Options,
+    OUT PHANDLE         Key
+    )
+{
+    OBJECT_ATTRIBUTES   Attributes;
+    NTSTATUS            status;
+
+    InitializeObjectAttributes(&Attributes,
+                               Path,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               Parent,
+                               NULL);
+
+    status = ZwCreateKey(Key,
+                         KEY_ALL_ACCESS,
+                         &Attributes,
+                         0,
+                         NULL,
+                         Options,
+                         NULL
+                         );
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
+NTSTATUS
 RegistryOpenServiceKey(
     IN  ACCESS_MASK     DesiredAccess,
     OUT PHANDLE         Key
@@ -125,6 +159,14 @@ RegistryOpenServiceKey(
 }
 
 NTSTATUS
+RegistryCreateServiceKey(
+    OUT PHANDLE         Key
+    )
+{
+    return RegistryCreateKey(NULL, &RegistryPath, REG_OPTION_NON_VOLATILE, 
Key);
+}
+
+NTSTATUS
 RegistryOpenSoftwareKey(
     IN  PDEVICE_OBJECT  DeviceObject,
     IN  ACCESS_MASK     DesiredAccess,
@@ -330,6 +372,8 @@ RegistryDeleteSubKey(
 
     ZwClose(SubKey);
 
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
@@ -347,7 +391,7 @@ fail1:
 NTSTATUS
 RegistryEnumerateSubKeys(
     IN  HANDLE              Key,
-    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PANSI_STRING),
     IN  PVOID               Context
     )
 {
@@ -390,6 +434,7 @@ RegistryEnumerateSubKeys(
         goto fail4;
 
     for (Index = 0; Index < Full->SubKeys; Index++) {
+        ULONG           Ignore;
         UNICODE_STRING  Unicode;
         ANSI_STRING     Ansi;
 
@@ -398,7 +443,7 @@ RegistryEnumerateSubKeys(
                                 KeyBasicInformation,
                                 Basic,
                                 Size,
-                                &Size);
+                                &Ignore);
         if (!NT_SUCCESS(status))
             goto fail5;
 
@@ -418,7 +463,7 @@ RegistryEnumerateSubKeys(
 
         Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        
 
-        status = Callback(Context, Key, Ansi.Buffer);
+        status = Callback(Context, Key, &Ansi);
 
         __RegistryFree(Ansi.Buffer);
         Ansi.Buffer = NULL;
@@ -450,7 +495,7 @@ fail1:
 NTSTATUS
 RegistryEnumerateValues(
     IN  HANDLE                      Key,
-    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PANSI_STRING, 
ULONG),
     IN  PVOID                       Context
     )
 {
@@ -493,6 +538,7 @@ RegistryEnumerateValues(
         goto fail4;
 
     for (Index = 0; Index < Full->Values; Index++) {
+        ULONG           Ignore;
         UNICODE_STRING  Unicode;
         ANSI_STRING     Ansi;
 
@@ -501,7 +547,7 @@ RegistryEnumerateValues(
                                      KeyValueBasicInformation,
                                      Basic,
                                      Size,
-                                     &Size);
+                                     &Ignore);
         if (!NT_SUCCESS(status))
             goto fail5;
 
@@ -517,7 +563,7 @@ RegistryEnumerateValues(
 
         Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        
 
-        status = Callback(Context, Key, Ansi.Buffer);
+        status = Callback(Context, Key, &Ansi, Basic->Type);
 
         __RegistryFree(Ansi.Buffer);
 
@@ -566,6 +612,8 @@ RegistryDeleteValue(
 
     RtlFreeUnicodeString(&Unicode);
 
+    (VOID) ZwFlushKey(Key);
+
     return STATUS_SUCCESS;
 
 fail2:
@@ -686,6 +734,8 @@ RegistryUpdateDwordValue(
 
     __RegistryFree(Partial);
 
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
@@ -806,6 +856,7 @@ NTSTATUS
 RegistryQuerySzValue(
     IN  HANDLE                      Key,
     IN  PCHAR                       Name,
+    OUT PULONG                      Type OPTIONAL,
     OUT PANSI_STRING                *Array
     )
 {
@@ -867,6 +918,9 @@ RegistryQuerySzValue(
     if (*Array == NULL)
         goto fail5;
 
+    if (Type != NULL)
+        *Type = Value->Type;
+
     __RegistryFree(Value);
 
     RtlFreeUnicodeString(&Unicode);
@@ -886,6 +940,150 @@ fail1:
 }
 
 NTSTATUS
+RegistryQueryBinaryValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    OUT PVOID                       *Buffer,
+    OUT PULONG                      Length
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    ULONG                           Size;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             NULL,
+                             0,
+                             &Size);
+    if (status != STATUS_BUFFER_OVERFLOW &&
+        status != STATUS_BUFFER_TOO_SMALL)
+        goto fail2;
+
+#pragma prefast(suppress:6102)
+    Partial = __RegistryAllocate(Size);
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail3;
+
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             Partial,
+                             Size,
+                             &Size);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    switch (Partial->Type) {
+    case REG_BINARY:
+        *Buffer = __RegistryAllocate(Partial->DataLength);
+
+        status = STATUS_NO_MEMORY;
+        if (*Buffer == NULL)
+            break;
+
+        *Length = Partial->DataLength;
+        RtlCopyMemory(*Buffer, Partial->Data, Partial->DataLength);
+        break;
+
+    default:
+        status = STATUS_INVALID_PARAMETER;
+        *Buffer = NULL;
+        break;
+    }
+
+    if (*Buffer == NULL)
+        goto fail5;
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail5:
+fail4:
+    __RegistryFree(Partial);
+
+fail3:
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryUpdateBinaryValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    IN  PVOID                       Buffer,
+    IN  ULONG                       Length
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, 
Data) +
+                                 Length);
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail2;
+
+    Partial->TitleIndex = 0;
+    Partial->Type = REG_BINARY;
+    Partial->DataLength = Length;
+    RtlCopyMemory(Partial->Data, Buffer, Partial->DataLength);
+
+    status = ZwSetValueKey(Key,
+                           &Unicode,
+                           Partial->TitleIndex,
+                           Partial->Type,
+                           Partial->Data,
+                           Partial->DataLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    __RegistryFree(Partial);
+
+    (VOID) ZwFlushKey(Key);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    __RegistryFree(Partial);
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+
+    return status;
+}
+
+NTSTATUS
 RegistryQueryKeyName(
     IN  HANDLE              Key,
     OUT PANSI_STRING        *Array
@@ -960,7 +1158,7 @@ RegistryQuerySystemStartOption(
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    status = RegistryQuerySzValue(Key, "SystemStartOptions", &Ansi);
+    status = RegistryQuerySzValue(Key, "SystemStartOptions", NULL, &Ansi);
     if (!NT_SUCCESS(status))
         goto fail2;
 
@@ -969,13 +1167,13 @@ RegistryQuerySystemStartOption(
     Length = (ULONG)strlen(Prefix);
 
     Option = __strtok_r(Ansi[0].Buffer, " ", &Context);
-    if (strncmp(Prefix, Option, Length) == 0)
-        goto found;
-
-    while ((Option = __strtok_r(NULL, " ", &Context)) != NULL)
+    while (Option != NULL) {
         if (strncmp(Prefix, Option, Length) == 0)
             goto found;
 
+        Option = __strtok_r(NULL, " ", &Context);
+    }
+
     status = STATUS_OBJECT_NAME_NOT_FOUND;
     goto fail3;
 
@@ -1115,12 +1313,11 @@ RegistryUpdateSzValue(
     IN  HANDLE                      Key,
     IN  PCHAR                       Name,
     IN  ULONG                       Type,
-    ...
+    IN  PANSI_STRING                Array
     )
 {
     ANSI_STRING                     Ansi;
     UNICODE_STRING                  Unicode;
-    va_list                         Arguments;
     PKEY_VALUE_PARTIAL_INFORMATION  Partial;
     NTSTATUS                        status;
 
@@ -1129,33 +1326,23 @@ RegistryUpdateSzValue(
     status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
     if (!NT_SUCCESS(status))
         goto fail1;
-        
-    va_start(Arguments, Type);
-    switch (Type) {
-    case REG_SZ: {
-        PANSI_STRING    Argument;
-
-        Argument = va_arg(Arguments, PANSI_STRING);
 
+    switch (Type) {
+    case REG_SZ:
         status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToSz(Argument);        
+        Partial = RegistryAnsiToSz(Array);
         break;
-    }
-    case REG_MULTI_SZ: {
-        PANSI_STRING    Argument;
-
-        Argument = va_arg(Arguments, PANSI_STRING);
 
+    case REG_MULTI_SZ:
         status = STATUS_NO_MEMORY;
-        Partial = RegistryAnsiToMultiSz(Argument);        
+        Partial = RegistryAnsiToMultiSz(Array);
         break;
-    }
+
     default:
         status = STATUS_INVALID_PARAMETER;
         Partial = NULL;
         break;
     }
-    va_end(Arguments);
 
     if (Partial == NULL)
         goto fail2;
@@ -1171,6 +1358,8 @@ RegistryUpdateSzValue(
 
     __RegistryFree(Partial);
 
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
@@ -1202,6 +1391,14 @@ RegistryFreeSzValue(
 }
 
 VOID
+RegistryFreeBinaryValue(
+    IN  PVOID   Buffer
+    )
+{
+    __RegistryFree(Buffer);
+}
+
+VOID
 RegistryCloseKey(
     IN  HANDLE  Key
     )
diff --git a/src/xeniface/registry.h b/src/xeniface/registry.h
index 7a89804..92aa7b6 100644
--- a/src/xeniface/registry.h
+++ b/src/xeniface/registry.h
@@ -53,12 +53,25 @@ RegistryOpenKey(
     );
 
 extern NTSTATUS
+RegistryCreateKey(
+    IN  HANDLE          Parent,
+    IN  PUNICODE_STRING Path,
+    IN  ULONG           Options,
+    OUT PHANDLE         Key
+    );
+
+extern NTSTATUS
 RegistryOpenServiceKey(
     IN  ACCESS_MASK DesiredAccess,
     OUT PHANDLE     Key
     );
 
 extern NTSTATUS
+RegistryCreateServiceKey(
+    OUT PHANDLE     Key
+    );
+
+extern NTSTATUS
 RegistryOpenSoftwareKey(
     IN  PDEVICE_OBJECT  DeviceObject,
     IN  ACCESS_MASK     DesiredAccess,
@@ -97,14 +110,14 @@ RegistryDeleteSubKey(
 extern NTSTATUS
 RegistryEnumerateSubKeys(
     IN  HANDLE      Key,
-    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PANSI_STRING),
     IN  PVOID       Context
     );
 
 extern NTSTATUS
 RegistryEnumerateValues(
     IN  HANDLE      Key,
-    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PANSI_STRING, ULONG),
     IN  PVOID       Context
     );
 
@@ -132,10 +145,27 @@ extern NTSTATUS
 RegistryQuerySzValue(
     IN  HANDLE          Key,
     IN  PCHAR           Name,
+    OUT PULONG          Type OPTIONAL,
     OUT PANSI_STRING    *Array
     );
 
 extern NTSTATUS
+RegistryQueryBinaryValue(
+    IN  HANDLE          Key,
+    IN  PCHAR           Name,
+    OUT PVOID           *Buffer,
+    OUT PULONG          Length
+    );
+
+extern NTSTATUS
+RegistryUpdateBinaryValue(
+    IN  HANDLE          Key,
+    IN  PCHAR           Name,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length
+    );
+
+extern NTSTATUS
 RegistryQueryKeyName(
     IN  HANDLE              Key,
     OUT PANSI_STRING        *Array
@@ -152,12 +182,17 @@ RegistryFreeSzValue(
     IN  PANSI_STRING    Array
     );
 
+extern VOID
+RegistryFreeBinaryValue(
+    IN  PVOID           Buffer
+    );
+
 extern NTSTATUS
 RegistryUpdateSzValue(
     IN  HANDLE          Key,
     IN  PCHAR           Name,
     IN  ULONG           Type,
-    ...
+    IN  PANSI_STRING    Array
     );
 
 extern VOID
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://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®.