[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |