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

[win-pv-devel] [PATCH] Use new monitor request key



The monitor service now uses a request key in registry under HKLM/SOFTWARE.
This patch modifies __DriverRequestReboot() to use the new key, which is
now set as a parameter by the INF file.

This patch also takes this opportunity to update the registry source module
to being it up to date with the XENBUS source base, and make wider use of it.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/coinst/coinst.c   |   3 -
 src/xenvbd.inf        |  16 +--
 src/xenvbd/driver.c   | 327 ++++++++++++++++----------------------------------
 src/xenvbd/registry.c | 265 ++++++++++++++++++++++++++++++++++------
 src/xenvbd/registry.h |  43 ++++++-
 5 files changed, 380 insertions(+), 274 deletions(-)

diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
index f972822..19ed3b3 100644
--- a/src/coinst/coinst.c
+++ b/src/coinst/coinst.c
@@ -52,9 +52,6 @@ __user_code;
 #define UNPLUG_KEY \
         SERVICE_KEY(XEN) ## "\\Unplug"
 
-#define STATUS_KEY  \
-        SERVICE_KEY(XENVBD) ## "\\Status"
-
 #define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control"
 
 #define PNP_KEY \
diff --git a/src/xenvbd.inf b/src/xenvbd.inf
index 5f09eed..9eb96ce 100644
--- a/src/xenvbd.inf
+++ b/src/xenvbd.inf
@@ -54,9 +54,9 @@ xenvbd_coinst.dll=0,,
 %Vendor%=Inst,NT$ARCH$
 
 [Inst.NT$ARCH$]
-%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_VBD&REV_08000009
-%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_@VENDOR_PREFIX@0001&DEV_VBD&REV_08000009
-%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_@VENDOR_PREFIX@0002&DEV_VBD&REV_08000009
+%XenVbdName%=XenVbd_Inst,XENBUS\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_VBD&REV_08000009
+%XenVbdName%=XenVbd_Inst,XENBUS\VEN_@VENDOR_PREFIX@0001&DEV_VBD&REV_08000009
+%XenVbdName%=XenVbd_Inst,XENBUS\VEN_@VENDOR_PREFIX@0002&DEV_VBD&REV_08000009
 
 [XenVbd_Inst] 
 CopyFiles=XenVbd_Copyfiles
@@ -77,7 +77,7 @@ AddService=xenvbd,2,XenVbd_Service,
 AddService=xendisk,,XenDisk_Service,
 
 [XenDisk_Service]
-DisplayName=%XenDiskDesc%
+DisplayName=%XenDiskName%
 ServiceType=%SERVICE_KERNEL_DRIVER%
 StartType=%SERVICE_BOOT_START%
 ErrorControl=%SERVICE_ERROR_NORMAL%
@@ -85,7 +85,7 @@ ServiceBinary=%12%\xendisk.sys
 LoadOrderGroup="Scsi Miniport"
 
 [XenVbd_Service] 
-DisplayName=%XenVbdDesc%
+DisplayName=%XenVbdName%
 ServiceType=%SERVICE_KERNEL_DRIVER% 
 StartType=%SERVICE_BOOT_START% 
 ErrorControl=%SERVICE_ERROR_NORMAL% 
@@ -97,6 +97,7 @@ AddReg=XenVbd_Parameters
 HKR,"Parameters",,0x00000010
 HKR,"Parameters","BusType",0x00010001,0x00000001 
 HKR,"Parameters\PnpInterface","5",0x00010001,0x00000001 
+HKR,"Parameters","RequestKey",0x00000000,%RequestKey%
 
 [XenVbd_Inst.CoInstallers]
 CopyFiles=CoInst_CopyFiles
@@ -112,8 +113,9 @@ 
HKR,,CoInstallers32,0x00010000,"xenvbd_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@M
 
 Vendor = "@VENDOR_NAME@"
 DiskDesc = "@PRODUCT_NAME@ PV Storage Host Adapter Package" 
-XenVbdDesc= "@PRODUCT_NAME@ PV Storage Host Adapter"
-XenDiskDesc= "@PRODUCT_NAME@ PV Storage Filter"
+XenVbdName= "@PRODUCT_NAME@ PV Storage Host Adapter"
+XenDiskName= "@PRODUCT_NAME@ PV Storage Filter"
+RequestKey="SOFTWARE\@VENDOR_NAME@\@PRODUCT_NAME@\PV Driver Monitor\Request"
 
 SERVICE_BOOT_START = 0x0 
 SERVICE_SYSTEM_START = 0x1 
diff --git a/src/xenvbd/driver.c b/src/xenvbd/driver.c
index 33de481..49ac84d 100644
--- a/src/xenvbd/driver.c
+++ b/src/xenvbd/driver.c
@@ -32,6 +32,7 @@
 #include "driver.h"
 #include "fdo.h"
 #include "pdo.h"
+#include "registry.h"
 #include "srbext.h"
 #include "buffer.h"
 #include "debug.h"
@@ -43,7 +44,7 @@
 #include <xenvbd-ntstrsafe.h>
 
 typedef struct _XENVBD_DRIVER {
-    HANDLE              StatusKey;
+    HANDLE              ParametersKey;
     PDRIVER_DISPATCH    StorPortDispatchPnp;
     PDRIVER_DISPATCH    StorPortDispatchPower;
     PDRIVER_UNLOAD      StorPortDriverUnload;
@@ -57,160 +58,28 @@ XENVBD_PARAMETERS   DriverParameters;
 
 #define XENVBD_POOL_TAG     'dbvX'
 
-static FORCEINLINE BOOLEAN
-__IsValid(
-    __in WCHAR                  Char
-    )
-{
-    return !(Char == 0 || Char == L' ' || Char == L'\t' || Char == L'\n' || 
Char == L'\r');
-}
-static DECLSPEC_NOINLINE BOOLEAN
-__DriverGetOption(
-    __in PWCHAR                 Options,
-    __in PWCHAR                 Parameter,
-    __out PWCHAR*               Value
-    )
-{
-    PWCHAR  Ptr;
-    PWCHAR  Buffer;
-    ULONG   Index;
-    ULONG   Length;
-
-    *Value = NULL;
-    Ptr = wcsstr(Options, Parameter);
-    if (Ptr == NULL)
-        return FALSE; // option not present
-
-    // skip Parameter
-    while (*Parameter) {
-        ++Ptr;
-        ++Parameter;
-    }
-
-    // find length of Value, up to next NULL or whitespace
-    for (Length = 0; __IsValid(Ptr[Length]); ++Length) 
-        ;
-    if (Length == 0)
-        return TRUE; // found the option, it had no value so *Value == NULL!
-
-    Buffer = (PWCHAR)__AllocateNonPagedPoolWithTag(__FUNCTION__, __LINE__, 
(Length + 1) * sizeof(WCHAR), XENVBD_POOL_TAG);
-    if (Buffer == NULL)
-        return FALSE; // memory allocation failure, ignore option
-
-    // copy Value
-    for (Index = 0; Index < Length; ++Index)
-        Buffer[Index] = Ptr[Index];
-    Buffer[Length] = L'\0';
-
-    *Value = Buffer;
-    return TRUE;
-}
-static DECLSPEC_NOINLINE NTSTATUS
-__DriverGetSystemStartParams(
-    __out PWCHAR*               Options
+static DECLSPEC_NOINLINE VOID
+__DriverParseOption(
+    IN  const CHAR  *Key,
+    OUT PBOOLEAN    Flag
     )
 {
-    UNICODE_STRING      Unicode;
-    OBJECT_ATTRIBUTES   Attributes;
-    HANDLE              Key;
-    PKEY_VALUE_PARTIAL_INFORMATION  Value;
-    ULONG               Size;
-    NTSTATUS            Status;
-
-    RtlInitUnicodeString(&Unicode, 
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
-    InitializeObjectAttributes(&Attributes, &Unicode, OBJ_CASE_INSENSITIVE | 
OBJ_KERNEL_HANDLE, NULL, NULL);
-
-    Status = ZwOpenKey(&Key, KEY_READ, &Attributes);
-    if (!NT_SUCCESS(Status))
-        goto fail1;
-
-    RtlInitUnicodeString(&Unicode, L"SystemStartOptions");
-    Status = ZwQueryValueKey(Key, &Unicode, KeyValuePartialInformation, NULL, 
0, &Size);
-    if (Status != STATUS_BUFFER_TOO_SMALL &&
-        Status != STATUS_BUFFER_OVERFLOW)
-        goto fail2;
+    PANSI_STRING    Option;
+    PCHAR           Value;
+    NTSTATUS        status;
 
-    Status = STATUS_NO_MEMORY;
-#pragma prefast(suppress:6102)
-    Value = 
(PKEY_VALUE_PARTIAL_INFORMATION)__AllocateNonPagedPoolWithTag(__FUNCTION__, 
__LINE__, Size, XENVBD_POOL_TAG);
-    if (Value == NULL)
-        goto fail3;
+    *Flag = FALSE;
 
-    Status = ZwQueryValueKey(Key, &Unicode, KeyValuePartialInformation, Value, 
Size, &Size);
-    if (!NT_SUCCESS(Status))
-        goto fail4;
-
-    Status = STATUS_INVALID_PARAMETER;
-    if (Value->Type != REG_SZ)
-        goto fail5;
-
-    Status = STATUS_NO_MEMORY;
-    *Options = (PWCHAR)__AllocateNonPagedPoolWithTag(__FUNCTION__, __LINE__, 
Value->DataLength + sizeof(WCHAR), XENVBD_POOL_TAG);
-    if (*Options == NULL)
-        goto fail6;
-
-    RtlCopyMemory(*Options, Value->Data, Value->DataLength);
-
-    __FreePoolWithTag(Value, XENVBD_POOL_TAG);
-
-    ZwClose(Key);
-    return STATUS_SUCCESS;
-
-fail6:
-fail5:
-fail4:
-    __FreePoolWithTag(Value, XENVBD_POOL_TAG);
-fail3:
-fail2:
-    ZwClose(Key);
-fail1:
-    *Options = NULL;
-    return Status;
-}
-static DECLSPEC_NOINLINE VOID
-__DriverParseParameterKey(
-    )
-{
-    NTSTATUS    Status;
-    PWCHAR      Options;
-    PWCHAR      Value;
-
-    // Set default parameters
-    DriverParameters.SynthesizeInquiry = FALSE;
-    DriverParameters.PVCDRom           = FALSE;
-
-    // attempt to read registry for system start parameters
-    Status = __DriverGetSystemStartParams(&Options);
-    if (NT_SUCCESS(Status)) {
-        Trace("Options = \"%ws\"\n", Options);
-
-        // check each option
-        if (__DriverGetOption(Options, L"XENVBD:SYNTH_INQ=", &Value)) {
-            // Value may be NULL (it shouldnt be though!)
-            if (Value) {
-                if (wcscmp(Value, L"ON") == 0) {
-                    DriverParameters.SynthesizeInquiry = TRUE;
-                }
-                __FreePoolWithTag(Value, XENVBD_POOL_TAG);
-            }
-        }
+    status = RegistryQuerySystemStartOption(Key, &Option);
+    if (!NT_SUCCESS(status))
+        return;
 
-        if (__DriverGetOption(Options, L"XENVBD:PVCDROM=", &Value)) {
-            // Value may be NULL (it shouldnt be though!)
-            if (Value) {
-                if (wcscmp(Value, L"ON") == 0) {
-                    DriverParameters.PVCDRom = TRUE;
-                }
-                __FreePoolWithTag(Value, XENVBD_POOL_TAG);
-            }
-        }
+    Value = Option->Buffer + strlen(Key);
 
-        __FreePoolWithTag(Options, XENVBD_POOL_TAG);
-    }
+    if (strcmp(Value, "ON") == 0)
+        *Flag = TRUE;
 
-    Verbose("DriverParameters: %s%s\n", 
-            DriverParameters.SynthesizeInquiry ? "SYNTH_INQ " : "",
-            DriverParameters.PVCDRom ? "PV_CDROM " : "");
+    RegistryFreeSzValue(Option);
 }
 
 NTSTATUS
@@ -279,73 +148,74 @@ __DriverGetFdo(
     return IsFdo;
 }
 
-#define SERVICES_PATH 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"
-
-#define SERVICE_KEY(_Name) \
-        SERVICES_PATH ## "\\" ## #_Name
-
-#define REQUEST_KEY \
-        SERVICE_KEY(XENBUS_MONITOR) ## "\\Request"
+#define MAXNAMELEN  128
 
 VOID
 DriverRequestReboot(
     VOID
     )
 {
-    ANSI_STRING                     Ansi;
-    UNICODE_STRING                  KeyName;
-    UNICODE_STRING                  ValueName;
-    WCHAR                           Value[] = L"XENVBD";
-    OBJECT_ATTRIBUTES               Attributes;
-    HANDLE                          Key;
-    NTSTATUS                        status;
+    PANSI_STRING    Ansi;
+    CHAR            RequestKeyName[MAXNAMELEN];
+    HANDLE          RequestKey;
+    HANDLE          SubKey;
+    NTSTATUS        status;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
 
-    RtlInitAnsiString(&Ansi, REQUEST_KEY);
-
-    status = RtlAnsiStringToUnicodeString(&KeyName, &Ansi, TRUE);
+    status = RegistryQuerySzValue(Driver.ParametersKey,
+                                  "RequestKey",
+                                  NULL,
+                                  &Ansi);
     if (!NT_SUCCESS(status))
         goto fail1;
 
-    InitializeObjectAttributes(&Attributes,
-                               &KeyName,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               NULL,
-                               NULL);
+    status = RtlStringCbPrintfA(RequestKeyName,
+                                MAXNAMELEN,
+                                "\\Registry\\Machine\\%Z",
+                                &Ansi[0]);
+    ASSERT(NT_SUCCESS(status));
 
-    status = ZwOpenKey(&Key,
-                       KEY_ALL_ACCESS,
-                       &Attributes);
+    status = RegistryOpenSubKey(NULL,
+                                RequestKeyName,
+                                KEY_ALL_ACCESS,
+                                &RequestKey);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    RtlInitUnicodeString(&ValueName, L"Reboot");
-
-    status = ZwSetValueKey(Key,
-                           &ValueName,
-                           0,
-                           REG_SZ,
-                           Value,
-                           sizeof(Value));
+    status = RegistryCreateSubKey(RequestKey,
+                                  __MODULE__,
+                                  REG_OPTION_NON_VOLATILE,
+                                  &SubKey);
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    ZwClose(Key);
+    status = RegistryUpdateDwordValue(SubKey,
+                                      "Reboot",
+                                      1);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
-    RtlFreeUnicodeString(&KeyName);
+    RegistryCloseKey(SubKey);
+
+    RegistryFreeSzValue(Ansi);
 
     return;
 
+fail4:
+    Error("fail4\n");
+
+    RegistryCloseKey(SubKey);
+
 fail3:
     Error("fail3\n");
 
-    ZwClose(Key);
+    RegistryCloseKey(RequestKey);
 
 fail2:
     Error("fail2\n");
 
-    RtlFreeUnicodeString(&KeyName);
+    RegistryFreeSzValue(Ansi);
 
 fail1:
     Error("fail1 (%08x)\n", status);
@@ -599,7 +469,7 @@ DriverUnload(
 
     Driver.StorPortDriverUnload(_DriverObject);
     BufferTerminate();
-    ZwClose(Driver.StatusKey);
+    RegistryClose(Driver.ParametersKey);
 
     Trace("<=== (Irql=%d)\n", KeGetCurrentIrql());
 }
@@ -608,15 +478,14 @@ DRIVER_INITIALIZE           DriverEntry;
 
 NTSTATUS
 DriverEntry(
-    IN PDRIVER_OBJECT  _DriverObject,
-    IN PUNICODE_STRING RegistryPath
+    IN PDRIVER_OBJECT       _DriverObject,
+    IN PUNICODE_STRING      RegistryPath
     )
 {
-    NTSTATUS                Status;
-    OBJECT_ATTRIBUTES       Attributes;
-    UNICODE_STRING          Unicode;
     HW_INITIALIZATION_DATA  InitData;
     HANDLE                  ServiceKey;
+    HANDLE                  ParametersKey;
+    NTSTATUS                status;
 
     // RegistryPath == NULL if crashing!
     if (RegistryPath == NULL) {
@@ -630,44 +499,33 @@ DriverEntry(
          MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." 
BUILD_NUMBER_STR,
          DAY_STR "/" MONTH_STR "/" YEAR_STR);
 
-    InitializeObjectAttributes(&Attributes,
-                               RegistryPath,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               NULL,
-                               NULL);
-
-    Status = ZwOpenKey(&ServiceKey,
-                       KEY_ALL_ACCESS,
-                       &Attributes);
-    if (!NT_SUCCESS(Status))
-        goto done;
-
-    RtlInitUnicodeString(&Unicode, L"Status");
+    status = RegistryInitialize(RegistryPath);
+    if (!NT_SUCCESS(status))
+        goto fail1;
 
-    InitializeObjectAttributes(&Attributes,
-                               &Unicode,
-                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
-                               ServiceKey,
-                               NULL);
+    status = RegistryOpenServiceKey(KEY_ALL_ACCESS, &ServiceKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    Status = ZwCreateKey(&Driver.StatusKey,
-                         KEY_ALL_ACCESS,
-                         &Attributes,
-                         0,
-                         NULL,
-                         REG_OPTION_VOLATILE,
-                         NULL
-                         );
+    status = RegistryOpenSubKey(ServiceKey,
+                                "Parameters",
+                                KEY_READ,
+                                &ParametersKey);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    ZwClose(ServiceKey);
+    Driver.ParametersKey = ParametersKey;
 
-    if (!NT_SUCCESS(Status))
-        goto done;
+    RegistryCloseKey(ServiceKey);
 
     KeInitializeSpinLock(&Driver.Lock);
     Driver.Fdo = NULL;
     BufferInitialize();
-    __DriverParseParameterKey();
+
+    __DriverParseOption("XENVBD:SYNTH_INQ=",
+                        &DriverParameters.SynthesizeInquiry);
+    __DriverParseOption("XENVBD:PVCDROM=",
+                        &DriverParameters.PVCDRom);
 
     RtlZeroMemory(&InitData, sizeof(InitData));
 
@@ -693,8 +551,11 @@ DriverEntry(
     InitData.HwAdapterControl           =   HwAdapterControl;
     InitData.HwBuildIo                  =   HwBuildIo;
 
-    Status = StorPortInitialize(_DriverObject, RegistryPath, &InitData, NULL);
-    if (NT_SUCCESS(Status)) {
+    status = StorPortInitialize(_DriverObject,
+                                RegistryPath,
+                                &InitData,
+                                NULL);
+    if (NT_SUCCESS(status)) {
         Driver.StorPortDispatchPnp     = 
_DriverObject->MajorFunction[IRP_MJ_PNP];
         Driver.StorPortDispatchPower   = 
_DriverObject->MajorFunction[IRP_MJ_POWER];
         Driver.StorPortDriverUnload    = _DriverObject->DriverUnload;
@@ -704,7 +565,21 @@ DriverEntry(
         _DriverObject->DriverUnload                 = DriverUnload;
     }
 
-done:
-    Trace("<=== (%08x) (Irql=%d)\n", Status, KeGetCurrentIrql());
-    return Status;
+    Trace("<=== (%08x) (Irql=%d)\n", status, KeGetCurrentIrql());
+    return status;
+
+fail3:
+    Error("fail3\n");
+
+    RegistryCloseKey(ServiceKey);
+
+fail2:
+    Error("fail2\n");
+
+    RegistryTeardown();
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
 }
diff --git a/src/xenvbd/registry.c b/src/xenvbd/registry.c
index 883bcb4..9e5e3e9 100644
--- a/src/xenvbd/registry.c
+++ b/src/xenvbd/registry.c
@@ -31,11 +31,11 @@
 
 #include <ntddk.h>
 
-#include "util.h"
 #include "registry.h"
 #include "assert.h"
+#include "util.h"
 
-#define REGISTRY_POOL 'GERX'
+#define REGISTRY_TAG 'GERX'
 
 static UNICODE_STRING   RegistryPath;
 
@@ -47,7 +47,7 @@ __RegistryAllocate(
     return __AllocateNonPagedPoolWithTag(__FUNCTION__,
                                          __LINE__,
                                          Length,
-                                         REGISTRY_POOL);
+                                         REGISTRY_TAG);
 }
 
 static FORCEINLINE VOID
@@ -55,7 +55,7 @@ __RegistryFree(
     IN  PVOID   Buffer
     )
 {
-    __FreePoolWithTag(Buffer, REGISTRY_POOL);
+    __FreePoolWithTag(Buffer, REGISTRY_TAG);
 }
 
 NTSTATUS
@@ -119,6 +119,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
@@ -128,6 +162,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,
@@ -333,6 +375,8 @@ RegistryDeleteSubKey(
 
     ZwClose(SubKey);
 
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
@@ -350,7 +394,7 @@ fail1:
 NTSTATUS
 RegistryEnumerateSubKeys(
     IN  HANDLE              Key,
-    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PANSI_STRING),
     IN  PVOID               Context
     )
 {
@@ -393,6 +437,7 @@ RegistryEnumerateSubKeys(
         goto fail4;
 
     for (Index = 0; Index < Full->SubKeys; Index++) {
+        ULONG           Ignore;
         UNICODE_STRING  Unicode;
         ANSI_STRING     Ansi;
 
@@ -401,7 +446,7 @@ RegistryEnumerateSubKeys(
                                 KeyBasicInformation,
                                 Basic,
                                 Size,
-                                &Size);
+                                &Ignore);
         if (!NT_SUCCESS(status))
             goto fail5;
 
@@ -421,7 +466,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;
@@ -453,7 +498,7 @@ fail1:
 NTSTATUS
 RegistryEnumerateValues(
     IN  HANDLE                      Key,
-    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PANSI_STRING, 
ULONG),
     IN  PVOID                       Context
     )
 {
@@ -496,6 +541,7 @@ RegistryEnumerateValues(
         goto fail4;
 
     for (Index = 0; Index < Full->Values; Index++) {
+        ULONG           Ignore;
         UNICODE_STRING  Unicode;
         ANSI_STRING     Ansi;
 
@@ -504,7 +550,7 @@ RegistryEnumerateValues(
                                      KeyValueBasicInformation,
                                      Basic,
                                      Size,
-                                     &Size);
+                                     &Ignore);
         if (!NT_SUCCESS(status))
             goto fail5;
 
@@ -520,7 +566,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);
 
@@ -569,6 +615,8 @@ RegistryDeleteValue(
 
     RtlFreeUnicodeString(&Unicode);
 
+    (VOID) ZwFlushKey(Key);
+
     return STATUS_SUCCESS;
 
 fail2:
@@ -689,6 +737,8 @@ RegistryUpdateDwordValue(
 
     __RegistryFree(Partial);
 
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
@@ -809,6 +859,7 @@ NTSTATUS
 RegistryQuerySzValue(
     IN  HANDLE                      Key,
     IN  PCHAR                       Name,
+    OUT PULONG                      Type OPTIONAL,
     OUT PANSI_STRING                *Array
     )
 {
@@ -870,6 +921,9 @@ RegistryQuerySzValue(
     if (*Array == NULL)
         goto fail5;
 
+    if (Type != NULL)
+        *Type = Value->Type;
+
     __RegistryFree(Value);
 
     RtlFreeUnicodeString(&Unicode);
@@ -889,6 +943,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
@@ -945,7 +1143,7 @@ fail1:
 
 NTSTATUS
 RegistryQuerySystemStartOption(
-    IN  PCHAR                       Prefix,
+    IN  const CHAR                  *Prefix,
     OUT PANSI_STRING                *Value
     )
 {
@@ -963,7 +1161,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;
 
@@ -972,13 +1170,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;
 
@@ -1118,12 +1316,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;
 
@@ -1132,33 +1329,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;
@@ -1174,6 +1361,8 @@ RegistryUpdateSzValue(
 
     __RegistryFree(Partial);
 
+    (VOID) ZwFlushKey(Key);
+
     RtlFreeUnicodeString(&Unicode);
 
     return STATUS_SUCCESS;
@@ -1205,6 +1394,14 @@ RegistryFreeSzValue(
 }
 
 VOID
+RegistryFreeBinaryValue(
+    IN  PVOID   Buffer
+    )
+{
+    __RegistryFree(Buffer);
+}
+
+VOID
 RegistryCloseKey(
     IN  HANDLE  Key
     )
diff --git a/src/xenvbd/registry.h b/src/xenvbd/registry.h
index 57cbd66..d39f016 100644
--- a/src/xenvbd/registry.h
+++ b/src/xenvbd/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
@@ -143,7 +173,7 @@ RegistryQueryKeyName(
 
 extern NTSTATUS
 RegistryQuerySystemStartOption(
-    IN  PCHAR           Name,
+    IN  const CHAR      *Prefix,
     OUT PANSI_STRING    *Option
     );
 
@@ -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
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®.