[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Re-work monitor service registry keys
Instead of using the monitor service key directly to place reboot requests, use a key under HKLM\SOFTWARE. This is a better place to handle interactions between separate PV driver packages. Also, give the monitor service a description and add a parameter to control the reboot prompt dialog timeout. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- src/coinst/coinst.c | 3 +- src/monitor/monitor.c | 277 ++++++++++++++++++++++++++++++++++++++++---------- src/xenbus.inf | 30 ++++-- src/xenbus/driver.c | 103 +++++++++++-------- 4 files changed, 304 insertions(+), 109 deletions(-) diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c index 1241ad1..f09e548 100644 --- a/src/coinst/coinst.c +++ b/src/coinst/coinst.c @@ -1371,7 +1371,8 @@ MonitorDelete( SERVICE_CONTROL_STOP, &Status); - if (!Success) + if (!Success && + GetLastError() != ERROR_SERVICE_NOT_ACTIVE) goto fail3; Success = DeleteService(Service); diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 739aaff..e2e8e20 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -48,6 +48,7 @@ typedef struct _MONITOR_CONTEXT { SERVICE_STATUS Status; SERVICE_STATUS_HANDLE Service; + HKEY ParametersKey; HANDLE EventLog; HANDLE StopEvent; HANDLE RequestEvent; @@ -62,10 +63,10 @@ MONITOR_CONTEXT MonitorContext; #define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services" #define SERVICE_KEY(_Service) \ - SERVICES_KEY ## "\\" ## #_Service + SERVICES_KEY ## "\\" ## _Service -#define REQUEST_KEY \ - SERVICE_KEY(XENBUS_MONITOR) ## "\\Request" +#define PARAMETERS_KEY(_Service) \ + SERVICE_KEY(_Service) ## "\\Parameters" static VOID #pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024' @@ -305,6 +306,34 @@ DoReboot( SHTDN_REASON_FLAG_PLANNED); } +static DWORD +GetPromptTimeout( + VOID + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + DWORD Type; + DWORD Value; + DWORD ValueLength; + HRESULT Error; + + ValueLength = sizeof (Value); + + Error = RegQueryValueEx(Context->ParametersKey, + "PromptTimeout", + NULL, + &Type, + (LPBYTE)&Value, + &ValueLength); + if (Error != ERROR_SUCCESS || + Type != REG_DWORD) + Value = 0; + + Log("%u", Value); + + return Value; +} + static VOID PromptForReboot( IN PTCHAR DriverName @@ -419,6 +448,7 @@ PromptForReboot( DWORD SessionId = SessionInfo[Index].SessionId; PTCHAR Name = SessionInfo[Index].pWinStationName; WTS_CONNECTSTATE_CLASS State = SessionInfo[Index].State; + DWORD Timeout; DWORD Response; Log("[%u]: %s [%s]", @@ -429,6 +459,8 @@ PromptForReboot( if (State != WTSActive) continue; + Timeout = GetPromptTimeout(); + Success = WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, SessionId, Title, @@ -436,7 +468,7 @@ PromptForReboot( Message, sizeof (Message), MB_YESNO | MB_ICONEXCLAMATION, - 0, + Timeout, &Response, TRUE); @@ -445,7 +477,7 @@ PromptForReboot( Context->RebootPending = TRUE; - if (Response == IDYES) + if (Response == IDYES || Response == IDTIMEOUT) DoReboot(); break; @@ -500,16 +532,18 @@ fail1: } static VOID -CheckRebootValue( +CheckRequestSubKeys( VOID ) { PMONITOR_CONTEXT Context = &MonitorContext; + DWORD SubKeys; + DWORD MaxSubKeyLength; + DWORD SubKeyLength; + PTCHAR SubKeyName; + DWORD Index; + HKEY SubKey; HRESULT Error; - DWORD MaxValueLength; - DWORD RebootLength; - PTCHAR Reboot; - DWORD Type; Log("====>"); @@ -517,64 +551,93 @@ CheckRebootValue( NULL, NULL, NULL, + &SubKeys, + &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, - &MaxValueLength, - NULL, NULL); if (Error != ERROR_SUCCESS) { SetLastError(Error); goto fail1; } - RebootLength = MaxValueLength + sizeof (TCHAR); + SubKeyLength = MaxSubKeyLength + sizeof (TCHAR); - Reboot = calloc(1, RebootLength); - if (Reboot == NULL) + SubKeyName = calloc(1, SubKeyLength); + if (SubKeyName == NULL) goto fail2; - Error = RegQueryValueEx(Context->RequestKey, - "Reboot", - NULL, - &Type, - (LPBYTE)Reboot, - &RebootLength); - if (Error != ERROR_SUCCESS) { - if (Error == ERROR_FILE_NOT_FOUND) - goto done; + for (Index = 0; Index < SubKeys; Index++) { + DWORD Length; + DWORD Type; + DWORD Reboot; + + SubKeyLength = MaxSubKeyLength + sizeof (TCHAR); + memset(SubKeyName, 0, SubKeyLength); + + Error = RegEnumKeyEx(Context->RequestKey, + Index, + (LPTSTR)SubKeyName, + &SubKeyLength, + NULL, + NULL, + NULL, + NULL); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail3; + } - SetLastError(Error); - goto fail3; - } + Log("%s", SubKeyName); - if (Type != REG_SZ) { - SetLastError(ERROR_BAD_FORMAT); - goto fail4; + Error = RegOpenKeyEx(Context->RequestKey, + SubKeyName, + 0, + KEY_READ, + &SubKey); + if (Error != ERROR_SUCCESS) + continue; + + Length = sizeof (DWORD); + Error = RegQueryValueEx(SubKey, + "Reboot", + NULL, + &Type, + (LPBYTE)&Reboot, + &Length); + if (Error != ERROR_SUCCESS || + Type != REG_DWORD) + goto loop; + + if (Reboot != 0) + goto found; + +loop: + RegCloseKey(SubKey); } - if (!Context->RebootPending) - PromptForReboot(Reboot); + goto done; - if (Context->RebootPending) - (VOID) RegDeleteValue(Context->RequestKey, "Reboot"); +found: + RegCloseKey(SubKey); + + if (!Context->RebootPending) + PromptForReboot(SubKeyName); done: - free(Reboot); + free(SubKeyName); Log("<===="); return; -fail4: - Log("fail4"); - fail3: Log("fail3"); - free(Reboot); + free(SubKeyName); fail2: Log("fail2"); @@ -600,7 +663,7 @@ CheckRequestKey( Log("====>"); - CheckRebootValue(); + CheckRequestSubKeys(); Error = RegNotifyChangeKeyValue(Context->RequestKey, TRUE, @@ -693,6 +756,84 @@ fail1: return FALSE; } +static BOOL +GetRequestKeyName( + OUT PTCHAR *RequestKeyName + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + DWORD MaxValueLength; + DWORD RequestKeyNameLength; + DWORD Type; + HRESULT Error; + + Error = RegQueryInfoKey(Context->ParametersKey, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &MaxValueLength, + NULL, + NULL); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail1; + } + + RequestKeyNameLength = MaxValueLength + sizeof (TCHAR); + + *RequestKeyName = calloc(1, RequestKeyNameLength); + if (RequestKeyName == NULL) + goto fail2; + + Error = RegQueryValueEx(Context->ParametersKey, + "RequestKey", + NULL, + &Type, + (LPBYTE)(*RequestKeyName), + &RequestKeyNameLength); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail3; + } + + if (Type != REG_SZ) { + SetLastError(ERROR_BAD_FORMAT); + goto fail4; + } + + Log("%s", *RequestKeyName); + + return TRUE; + +fail4: + Log("fail4"); + +fail3: + Log("fail3"); + + free(*RequestKeyName); + +fail2: + Log("fail2"); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} + VOID WINAPI MonitorMain( _In_ DWORD argc, @@ -700,6 +841,7 @@ MonitorMain( ) { PMONITOR_CONTEXT Context = &MonitorContext; + PTCHAR RequestKeyName; BOOL Success; HRESULT Error; @@ -708,21 +850,28 @@ MonitorMain( Log("====>"); - Success = AcquireShutdownPrivilege(); + Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + PARAMETERS_KEY(__MODULE__), + 0, + KEY_READ, + &Context->ParametersKey); + if (Error != ERROR_SUCCESS) + goto fail1; + Success = AcquireShutdownPrivilege(); if (!Success) - goto fail1; + goto fail2; Context->Service = RegisterServiceCtrlHandlerEx(MONITOR_NAME, MonitorCtrlHandlerEx, NULL); if (Context->Service == NULL) - goto fail2; + goto fail3; Context->EventLog = RegisterEventSource(NULL, MONITOR_NAME); if (Context->EventLog == NULL) - goto fail3; + goto fail4; Context->Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; Context->Status.dwServiceSpecificExitCode = 0; @@ -735,24 +884,26 @@ MonitorMain( NULL); if (Context->StopEvent == NULL) - goto fail4; + goto fail5; Context->RequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (Context->RequestEvent == NULL) - goto fail5; + goto fail6; + + Success = GetRequestKeyName(&RequestKeyName); + if (!Success) + goto fail7; Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REQUEST_KEY, + RequestKeyName, 0, KEY_ALL_ACCESS, &Context->RequestKey); - if (Error != ERROR_SUCCESS) - goto fail6; + goto fail8; SetEvent(Context->RequestEvent); @@ -788,6 +939,8 @@ MonitorMain( } done: + (VOID) RegDeleteTree(Context->RequestKey, NULL); + CloseHandle(Context->RequestKey); CloseHandle(Context->RequestEvent); CloseHandle(Context->StopEvent); @@ -796,33 +949,45 @@ done: (VOID) DeregisterEventSource(Context->EventLog); + CloseHandle(Context->ParametersKey); + Log("<===="); return; -fail6: - Log("fail6"); +fail8: + Log("fail8"); - ReportStatus(SERVICE_STOPPED, GetLastError(), 0); + free(RequestKeyName); + +fail7: + Log("fail7"); CloseHandle(Context->RequestEvent); +fail6: + Log("fail6"); + + CloseHandle(Context->StopEvent); + fail5: Log("fail5"); - CloseHandle(Context->StopEvent); + ReportStatus(SERVICE_STOPPED, GetLastError(), 0); + + (VOID) DeregisterEventSource(Context->EventLog); fail4: Log("fail4"); - (VOID) DeregisterEventSource(Context->EventLog); - fail3: Log("fail3"); fail2: Log("fail2"); + CloseHandle(Context->ParametersKey); + fail1: Error = GetLastError(); diff --git a/src/xenbus.inf b/src/xenbus.inf index 0b65e00..dc4e71d 100644 --- a/src/xenbus.inf +++ b/src/xenbus.inf @@ -72,9 +72,9 @@ xenbus_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dl ; DisplayName Section DeviceID ; ----------- ------- -------- -%XenBusDesc% =XenBus_Inst, PCI\VEN_5853&DEV_@VENDOR_DEVICE_ID@&SUBSYS_@VENDOR_DEVICE_ID@5853&REV_01 -%XenBusDesc% =XenBus_Inst, PCI\VEN_5853&DEV_0002 -%XenBusDesc% =XenBus_Inst, PCI\VEN_5853&DEV_0001 +%XenBusName% =XenBus_Inst, PCI\VEN_5853&DEV_@VENDOR_DEVICE_ID@&SUBSYS_@VENDOR_DEVICE_ID@5853&REV_01 +%XenBusName% =XenBus_Inst, PCI\VEN_5853&DEV_0002 +%XenBusName% =XenBus_Inst, PCI\VEN_5853&DEV_0001 [XenBus_Inst] CopyFiles=XenBus_CopyFiles @@ -86,7 +86,7 @@ AddService=xenbus,%SPSVCINST_ASSOCSERVICE%,XenBus_Service AddService=xenfilt,,XenFilt_Service, [XenBus_Service] -DisplayName=%XenBusDesc% +DisplayName=%XenBusName% ServiceType=%SERVICE_KERNEL_DRIVER% StartType=%SERVICE_BOOT_START% ErrorControl=%SERVICE_ERROR_NORMAL% @@ -98,6 +98,7 @@ AddReg = XenBus_Parameters, XenBus_Interrupts HKR,"Parameters",,0x00000010 HKR,"Parameters","SupportedClasses",0x00010000,"VIF","VBD","IFACE" HKR,"Parameters","SyntheticClasses",0x00010000,"IFACE" +HKR,"Parameters","RequestKey",0x00000000,%RequestKey% [XenBus_Interrupts] HKR,"Interrupt Management",,0x00000010 @@ -106,7 +107,7 @@ HKR,"Interrupt Management\MessageSignaledInterruptProperties","MSISupported",0x0 HKR,"Interrupt Management\GroupPolicy",,0x00010001,1 [XenFilt_Service] -DisplayName=%XenFiltDesc% +DisplayName=%XenFiltName% ServiceType=%SERVICE_KERNEL_DRIVER% StartType=%SERVICE_BOOT_START% ErrorControl=%SERVICE_ERROR_NORMAL% @@ -120,15 +121,20 @@ HKR,"Parameters","ACPI\PNP0A03",0x00000000,"DEVICE" HKR,"Parameters","PCIIDE\IDEChannel",0x00000000,"DISK" [Monitor_Service] -DisplayName=%MonitorDesc% +DisplayName=%MonitorName% +Description=%MonitorDesc% ServiceType=%SERVICE_WIN32_OWN_PROCESS% StartType=%SERVICE_AUTO_START% ErrorControl=%SERVICE_ERROR_NORMAL% ServiceBinary=%11%\xenbus_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.exe -AddReg = Monitor_Request +AddReg = Monitor_Parameters, Monitor_Request + +[Monitor_Parameters] +HKR,"Parameters",,0x00000010 +HKR,"Parameters","RequestKey",0x00000000,%RequestKey% [Monitor_Request] -HKR,"Request",,0x00000010 +HKLM,%RequestKey% ,,0x00000010 [Monitor_EventLog] AddReg=Monitor_EventLog_AddReg @@ -148,9 +154,11 @@ HKR,,CoInstallers32,0x00010000,"xenbus_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@M Vendor="@VENDOR_NAME@" DiskDesc="@PRODUCT_NAME@ PV Bus Package" -XenBusDesc="@PRODUCT_NAME@ PV Bus" -XenFiltDesc="@PRODUCT_NAME@ Generic Bus Filter" -MonitorDesc="@PRODUCT_NAME@ PV Driver Monitor" +XenBusName="@PRODUCT_NAME@ PV Bus" +XenFiltName="@PRODUCT_NAME@ Generic Bus Filter" +MonitorName="@PRODUCT_NAME@ PV Driver Monitor" +MonitorDesc="Provides support for @PRODUCT_NAME@ PV drivers" +RequestKey="SOFTWARE\@VENDOR_NAME@\@PRODUCT_NAME@\PV Driver Monitor\Request" SERVICE_BOOT_START=0x0 SERVICE_SYSTEM_START=0x1 diff --git a/src/xenbus/driver.c b/src/xenbus/driver.c index 31388be..4360edc 100644 --- a/src/xenbus/driver.c +++ b/src/xenbus/driver.c @@ -122,55 +122,78 @@ DriverGetParametersKey( return __DriverGetParametersKey(); } -#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 static FORCEINLINE VOID __DriverRequestReboot( VOID ) { - HANDLE RequestKey; - ANSI_STRING Ansi[2]; - NTSTATUS status; + PANSI_STRING Ansi; + CHAR RequestKeyName[MAXNAMELEN]; + HANDLE RequestKey; + HANDLE SubKey; + NTSTATUS status; Info("====>\n"); ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + status = RegistryQuerySzValue(__DriverGetParametersKey(), + "RequestKey", + NULL, + &Ansi); + if (!NT_SUCCESS(status)) + goto fail1; + + status = RtlStringCbPrintfA(RequestKeyName, + MAXNAMELEN, + "\\Registry\\Machine\\%Z", + &Ansi[0]); + ASSERT(NT_SUCCESS(status)); + status = RegistryOpenSubKey(NULL, - REQUEST_KEY, + RequestKeyName, KEY_ALL_ACCESS, &RequestKey); if (!NT_SUCCESS(status)) - goto fail1; - - RtlZeroMemory(Ansi, sizeof (Ansi)); + goto fail2; - RtlInitAnsiString(&Ansi[0], "XENBUS"); + status = RegistryCreateSubKey(RequestKey, + __MODULE__, + REG_OPTION_NON_VOLATILE, + &SubKey); + if (!NT_SUCCESS(status)) + goto fail3; - status = RegistryUpdateSzValue(RequestKey, - "Reboot", - REG_SZ, - Ansi); + status = RegistryUpdateDwordValue(SubKey, + "Reboot", + 1); if (!NT_SUCCESS(status)) - goto fail2; + goto fail4; - RegistryCloseKey(RequestKey); + RegistryCloseKey(SubKey); + + RegistryFreeSzValue(Ansi); Info("<====\n"); return; +fail4: + Error("fail4\n"); + + RegistryCloseKey(SubKey); + +fail3: + Error("fail3\n"); + + RegistryCloseKey(RequestKey); + fail2: Error("fail2\n"); - RegistryCloseKey(RequestKey); + RegistryFreeSzValue(Ansi); fail1: Error("fail1 (%08x)\n", status); @@ -681,35 +704,35 @@ DriverEntry( MONTH, YEAR); - status = XenTouch(__MODULE__, - MAJOR_VERSION, - MINOR_VERSION, - MICRO_VERSION, - BUILD_NUMBER); - if (!NT_SUCCESS(status)) { - __DriverRequestReboot(); - goto fail1; - } - status = RegistryInitialize(RegistryPath); if (!NT_SUCCESS(status)) - goto fail2; + goto fail1; status = RegistryOpenServiceKey(KEY_READ, &ServiceKey); if (!NT_SUCCESS(status)) - goto fail3; + goto fail2; status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey); if (!NT_SUCCESS(status)) - goto fail4; + goto fail3; __DriverSetParametersKey(ParametersKey); RegistryCloseKey(ServiceKey); + status = XenTouch(__MODULE__, + MAJOR_VERSION, + MINOR_VERSION, + MICRO_VERSION, + BUILD_NUMBER); + if (!NT_SUCCESS(status)) { + __DriverRequestReboot(); + goto done; + } + DriverObject->DriverExtension->AddDevice = DriverAddDevice; for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) { @@ -718,6 +741,7 @@ DriverEntry( DriverObject->MajorFunction[Index] = DriverDispatch; } +done: InitializeMutex(&Driver.Mutex); InitializeListHead(&Driver.List); Driver.References = 1; @@ -726,19 +750,16 @@ DriverEntry( return STATUS_SUCCESS; -fail4: - Error("fail4\n"); - - RegistryCloseKey(ServiceKey); - fail3: Error("fail3\n"); - RegistryTeardown(); + RegistryCloseKey(ServiceKey); fail2: Error("fail2\n"); + RegistryTeardown(); + fail1: Error("fail1 (%08x)\n", status); -- 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 |