[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH] Remove interface subscription and unplug code from the co-installed...
...and use the new XENBUS_UNPLUG interface to request unplug. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- include/unplug_interface.h | 115 +++++++++++ src/coinst/coinst.c | 504 ++++++--------------------------------------- src/xenvbd.inf | 6 +- src/xenvbd/driver.c | 30 ++- src/xenvbd/driver.h | 2 +- src/xenvbd/fdo.c | 55 ++++- src/xenvbd/fdo.h | 6 + src/xenvbd/pdo.c | 58 +++++- 8 files changed, 312 insertions(+), 464 deletions(-) create mode 100644 include/unplug_interface.h diff --git a/include/unplug_interface.h b/include/unplug_interface.h new file mode 100644 index 0000000..99d4e7d --- /dev/null +++ b/include/unplug_interface.h @@ -0,0 +1,115 @@ +/* Copyright (c) Citrix Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*! \file unplug_interface.h + \brief XENBUS UNPLUG Interface + + This interface provides a method to request emulated device unplug +*/ + +#ifndef _XENBUS_UNPLUG_INTERFACE_H +#define _XENBUS_UNPLUG_INTERFACE_H + +#ifndef _WINDLL + +/*! \typedef XENBUS_UNPLUG_ACQUIRE + \brief Acquire a reference to the UNPLUG interface + + \param Interface The interface header +*/ +typedef NTSTATUS +(*XENBUS_UNPLUG_ACQUIRE)( + IN PINTERFACE Interface + ); + +/*! \typedef XENBUS_UNPLUG_RELEASE + \brief Release a reference to the UNPLUG interface + + \param Interface The interface header +*/ +typedef VOID +(*XENBUS_UNPLUG_RELEASE)( + IN PINTERFACE Interface + ); + +/*! \enum _XENBUS_UNPLUG_DEVICE_TYPE + \brief Type of device to be unplugged +*/ +typedef enum _XENBUS_UNPLUG_DEVICE_TYPE { + XENBUS_UNPLUG_DEVICE_TYPE_INVALID = 0, + XENBUS_UNPLUG_DEVICE_TYPE_NICS, /*!< NICs */ + XENBUS_UNPLUG_DEVICE_TYPE_DISKS, /*!< Disks */ +} XENBUS_UNPLUG_DEVICE_TYPE, *PXENBUS_UNPLUG_DEVICE_TYPE; + +/*! \typedef XENBUS_UNPLUG_REQUEST + \brief Request unplug of a type of emulated device + + \param Interface The interface header + \param Type The type of device + \param Make Set to TRUE if the request is being made, FALSE if it is + being revoked. +*/ +typedef VOID +(*XENBUS_UNPLUG_REQUEST)( + IN PINTERFACE Interface, + IN XENBUS_UNPLUG_DEVICE_TYPE Type, + IN BOOLEAN Make + ); + +// {73db6517-3d06-4937-989f-199b7501e229} +DEFINE_GUID(GUID_XENBUS_UNPLUG_INTERFACE, +0x73db6517, 0x3d06, 0x4937, 0x98, 0x9f, 0x19, 0x9b, 0x75, 0x01, 0xe2, 0x29); + +/*! \struct _XENBUS_UNPLUG_INTERFACE_V1 + \brief UNPLUG interface version 1 + \ingroup interfaces +*/ +struct _XENBUS_UNPLUG_INTERFACE_V1 { + INTERFACE Interface; + XENBUS_UNPLUG_ACQUIRE UnplugAcquire; + XENBUS_UNPLUG_RELEASE UnplugRelease; + XENBUS_UNPLUG_REQUEST UnplugRequest; +}; + +typedef struct _XENBUS_UNPLUG_INTERFACE_V1 XENBUS_UNPLUG_INTERFACE, *PXENBUS_UNPLUG_INTERFACE; + +/*! \def XENBUS_UNPLUG + \brief Macro at assist in method invocation +*/ +#define XENBUS_UNPLUG(_Method, _Interface, ...) \ + (_Interface)->Unplug ## _Method((PINTERFACE)(_Interface), __VA_ARGS__) + +#endif // _WINDLL + +#define XENBUS_UNPLUG_INTERFACE_VERSION_MIN 1 +#define XENBUS_UNPLUG_INTERFACE_VERSION_MAX 1 + +#endif // _XENBUS_UNPLUG_INTERFACE_H diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c index 7233b9b..9069435 100644 --- a/src/coinst/coinst.c +++ b/src/coinst/coinst.c @@ -35,13 +35,6 @@ #include <stdlib.h> #include <strsafe.h> -#include <debug_interface.h> -#include <suspend_interface.h> -#include <evtchn_interface.h> -#include <store_interface.h> -#include <gnttab_interface.h> -#include <emulated_interface.h> - #include <version.h> __user_code; @@ -53,8 +46,8 @@ __user_code; #define SERVICE_KEY(_Driver) \ SERVICES_KEY ## "\\" ## #_Driver -#define UNPLUG_KEY \ - SERVICE_KEY(XENFILT) ## "\\Unplug" +#define STATUS_KEY \ + SERVICE_KEY(XENVBD) ## "\\Status" #define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control" @@ -190,271 +183,6 @@ __FunctionName( } static BOOLEAN -InstallUnplugService( - IN PTCHAR ClassName, - IN PTCHAR ServiceName - ) -{ - HKEY UnplugKey; - HRESULT Error; - DWORD Type; - DWORD OldLength; - DWORD NewLength; - PTCHAR ServiceNames; - ULONG Offset; - - Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, - UNPLUG_KEY, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &UnplugKey, - NULL); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail1; - } - - Error = RegQueryValueEx(UnplugKey, - ClassName, - NULL, - &Type, - NULL, - &OldLength); - if (Error != ERROR_SUCCESS) { - if (Error == ERROR_FILE_NOT_FOUND) { - Type = REG_MULTI_SZ; - OldLength = sizeof (TCHAR); - } else { - SetLastError(Error); - goto fail2; - } - } - - if (Type != REG_MULTI_SZ) { - SetLastError(ERROR_BAD_FORMAT); - goto fail3; - } - - NewLength = OldLength + (DWORD)((strlen(ServiceName) + 1) * sizeof (TCHAR)); - - ServiceNames = calloc(1, NewLength); - if (ServiceNames == NULL) - goto fail4; - - Offset = 0; - if (OldLength != sizeof (TCHAR)) { - Error = RegQueryValueEx(UnplugKey, - ClassName, - NULL, - &Type, - (LPBYTE)ServiceNames, - &OldLength); - if (Error != ERROR_SUCCESS) { - SetLastError(ERROR_BAD_FORMAT); - goto fail5; - } - - while (ServiceNames[Offset] != '\0') { - ULONG ServiceNameLength; - - ServiceNameLength = (ULONG)strlen(&ServiceNames[Offset]) / sizeof (TCHAR); - - if (_stricmp(&ServiceNames[Offset], ServiceName) == 0) { - Log("%s already present", ServiceName); - goto done; - } - - Offset += ServiceNameLength + 1; - } - } - - memmove(&ServiceNames[Offset], ServiceName, strlen(ServiceName)); - Log("added %s", ServiceName); - - Error = RegSetValueEx(UnplugKey, - ClassName, - 0, - REG_MULTI_SZ, - (LPBYTE)ServiceNames, - NewLength); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail6; - } - -done: - free(ServiceNames); - - RegCloseKey(UnplugKey); - - return TRUE; - -fail6: - Log("fail5"); - -fail5: - Log("fail5"); - - free(ServiceNames); - -fail4: - Log("fail5"); - -fail3: - Log("fail5"); - -fail2: - Log("fail5"); - - RegCloseKey(UnplugKey); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; - - Message = __GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } - - return FALSE; -} - -static BOOLEAN -RemoveUnplugService( - IN PTCHAR ClassName, - IN PTCHAR ServiceName - ) -{ - HKEY UnplugKey; - HRESULT Error; - DWORD Type; - DWORD OldLength; - DWORD NewLength; - PTCHAR ServiceNames; - ULONG Offset; - ULONG ServiceNameLength; - - Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - UNPLUG_KEY, - 0, - KEY_ALL_ACCESS, - &UnplugKey); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail1; - } - - Error = RegQueryValueEx(UnplugKey, - ClassName, - NULL, - &Type, - NULL, - &OldLength); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail2; - } - - if (Type != REG_MULTI_SZ) { - SetLastError(ERROR_BAD_FORMAT); - goto fail3; - } - - ServiceNames = calloc(1, OldLength); - if (ServiceNames == NULL) - goto fail4; - - Error = RegQueryValueEx(UnplugKey, - ClassName, - NULL, - &Type, - (LPBYTE)ServiceNames, - &OldLength); - if (Error != ERROR_SUCCESS) { - SetLastError(ERROR_BAD_FORMAT); - goto fail5; - } - - Offset = 0; - ServiceNameLength = 0; - while (ServiceNames[Offset] != '\0') { - ServiceNameLength = (ULONG)strlen(&ServiceNames[Offset]) / sizeof (TCHAR); - - if (_stricmp(&ServiceNames[Offset], ServiceName) == 0) - goto remove; - - Offset += ServiceNameLength + 1; - } - - goto done; - -remove: - NewLength = OldLength - ((ServiceNameLength + 1) * sizeof (TCHAR)); - - memmove(&ServiceNames[Offset], - &ServiceNames[Offset + ServiceNameLength + 1], - (NewLength - Offset) * sizeof (TCHAR)); - - Log("removed %s", ServiceName); - - Error = RegSetValueEx(UnplugKey, - ClassName, - 0, - REG_MULTI_SZ, - (LPBYTE)ServiceNames, - NewLength); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail6; - } - -done: - free(ServiceNames); - - RegCloseKey(UnplugKey); - - return TRUE; - -fail6: - Log("fail6"); - -fail5: - Log("fail5"); - - free(ServiceNames); - -fail4: - Log("fail4"); - -fail3: - Log("fail3"); - -fail2: - Log("fail2"); - - RegCloseKey(UnplugKey); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; - - Message = __GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } - - return FALSE; -} - -static BOOLEAN OverrideGroupPolicyOptions( ) { @@ -610,154 +338,65 @@ fail1: } static BOOLEAN -RequestReboot( - IN HDEVINFO DeviceInfoSet, - IN PSP_DEVINFO_DATA DeviceInfoData +CheckStatus( + OUT PBOOLEAN NeedReboot ) { - SP_DEVINSTALL_PARAMS DeviceInstallParams; - HRESULT Error; - - DeviceInstallParams.cbSize = sizeof (DeviceInstallParams); - - if (!SetupDiGetDeviceInstallParams(DeviceInfoSet, - DeviceInfoData, - &DeviceInstallParams)) - goto fail1; - - DeviceInstallParams.Flags |= DI_NEEDREBOOT; - - Log("Flags = %08x", DeviceInstallParams.Flags); - - if (!SetupDiSetDeviceInstallParams(DeviceInfoSet, - DeviceInfoData, - &DeviceInstallParams)) - goto fail2; - - return TRUE; - -fail2: - Log("fail2"); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; - - Message = __GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } - - return FALSE; -} - -static HKEY -OpenInterfacesKey( - IN PTCHAR ProviderName - ) -{ - HRESULT Result; - TCHAR KeyName[MAX_PATH]; - HKEY Key; - HRESULT Error; - - Result = StringCbPrintf(KeyName, - MAX_PATH, - "%s\\%s\\Interfaces", - SERVICES_KEY, - ProviderName); - if (!SUCCEEDED(Result)) { - SetLastError(ERROR_BUFFER_OVERFLOW); - goto fail1; - } + HKEY StatusKey; + HRESULT Error; + DWORD ValueLength; + DWORD Value; + DWORD Type; Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - KeyName, + STATUS_KEY, 0, - KEY_ALL_ACCESS, - &Key); + KEY_READ, + &StatusKey); if (Error != ERROR_SUCCESS) { SetLastError(Error); - goto fail2; - } - - return Key; - -fail2: - Log("fail2"); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; - Message = __GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); + goto fail1; } - return NULL; -} - -static BOOLEAN -SubscribeInterface( - IN PTCHAR ProviderName, - IN PTCHAR SubscriberName, - IN PTCHAR InterfaceName, - IN DWORD InterfaceVersion - ) -{ - HKEY Key; - HKEY InterfacesKey; - HRESULT Error; - - InterfacesKey = OpenInterfacesKey(ProviderName); - if (InterfacesKey == NULL) - goto fail1; + ValueLength = sizeof (Value); - Error = RegCreateKeyEx(InterfacesKey, - SubscriberName, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &Key, - NULL); + Error = RegQueryValueEx(StatusKey, + "NeedReboot", + NULL, + &Type, + (LPBYTE)&Value, + &ValueLength); if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail2; + if (Error == ERROR_FILE_NOT_FOUND) { + Type = REG_DWORD; + Value = 0; + } else { + SetLastError(Error); + goto fail2; + } } - Error = RegSetValueEx(Key, - InterfaceName, - 0, - REG_DWORD, - (const BYTE *)&InterfaceVersion, - sizeof(DWORD)); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); + if (Type != REG_DWORD) { + SetLastError(ERROR_BAD_FORMAT); goto fail3; } - Log("%s: %s_%s_INTERFACE_VERSION %u", - SubscriberName, - ProviderName, - InterfaceName, - InterfaceVersion); + *NeedReboot = (Value != 0) ? TRUE : FALSE; - RegCloseKey(Key); - RegCloseKey(InterfacesKey); + if (*NeedReboot) + Log("NeedReboot"); + + RegCloseKey(StatusKey); return TRUE; fail3: - RegCloseKey(Key); + Log("fail3"); fail2: - RegCloseKey(InterfacesKey); + Log("fail2"); + + RegCloseKey(StatusKey); fail1: Error = GetLastError(); @@ -772,49 +411,42 @@ fail1: return FALSE; } -#define SUBSCRIBE_INTERFACE(_ProviderName, _SubscriberName, _InterfaceName) \ - do { \ - (VOID) SubscribeInterface(#_ProviderName, \ - #_SubscriberName, \ - #_InterfaceName, \ - _ProviderName ## _ ## _InterfaceName ## _INTERFACE_VERSION_MAX); \ - } while (FALSE); - static BOOLEAN -UnsubscribeInterfaces( - IN PTCHAR ProviderName, - IN PTCHAR SubscriberName +RequestReboot( + IN HDEVINFO DeviceInfoSet, + IN PSP_DEVINFO_DATA DeviceInfoData ) { - HKEY InterfacesKey; - HRESULT Error; + SP_DEVINSTALL_PARAMS DeviceInstallParams; + HRESULT Error; - Log("%s: %s", SubscriberName, ProviderName); + DeviceInstallParams.cbSize = sizeof (DeviceInstallParams); - InterfacesKey = OpenInterfacesKey(ProviderName); - if (InterfacesKey == NULL) { + if (!SetupDiGetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &DeviceInstallParams)) goto fail1; - } - Error = RegDeleteTree(InterfacesKey, - SubscriberName); - if (Error != ERROR_SUCCESS) { - SetLastError(Error); - goto fail2; - } + DeviceInstallParams.Flags |= DI_NEEDREBOOT; - RegCloseKey(InterfacesKey); + Log("Flags = %08x", DeviceInstallParams.Flags); + + if (!SetupDiSetDeviceInstallParams(DeviceInfoSet, + DeviceInfoData, + &DeviceInstallParams)) + goto fail2; return TRUE; fail2: - RegCloseKey(InterfacesKey); + Log("fail2"); fail1: Error = GetLastError(); { PTCHAR Message; + Message = __GetErrorMessage(Error); Log("fail1 (%s)", Message); LocalFree(Message); @@ -846,26 +478,21 @@ __DifInstallPostProcess( IN PCOINSTALLER_CONTEXT_DATA Context ) { - UNREFERENCED_PARAMETER(DeviceInfoSet); - UNREFERENCED_PARAMETER(DeviceInfoData); + BOOLEAN Success; + BOOLEAN NeedReboot; + UNREFERENCED_PARAMETER(Context); Log("====>"); - SUBSCRIBE_INTERFACE(XENBUS, XENVBD, STORE); - SUBSCRIBE_INTERFACE(XENBUS, XENVBD, EVTCHN); - SUBSCRIBE_INTERFACE(XENBUS, XENVBD, GNTTAB); - SUBSCRIBE_INTERFACE(XENBUS, XENVBD, SUSPEND); - SUBSCRIBE_INTERFACE(XENBUS, XENVBD, DEBUG); - - SUBSCRIBE_INTERFACE(XENFILT, XENVBD, EMULATED); - (VOID) OverrideGroupPolicyOptions(); (VOID) IncreaseDiskTimeOut(); - (VOID) InstallUnplugService("DISKS", "XENVBD"); + NeedReboot = FALSE; - (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData); + Success = CheckStatus(&NeedReboot); + if (Success && NeedReboot) + (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData); Log("<===="); @@ -941,11 +568,6 @@ __DifRemovePreProcess( Log("====>"); - (VOID) RemoveUnplugService("DISKS", "XENVBD"); - - UnsubscribeInterfaces("XENFILT", "XENVBD"); - UnsubscribeInterfaces("XENBUS", "XENVBD"); - return NO_ERROR; } diff --git a/src/xenvbd.inf b/src/xenvbd.inf index dc7ca24..e92d3fb 100644 --- a/src/xenvbd.inf +++ b/src/xenvbd.inf @@ -53,9 +53,9 @@ xenvbd_coinst.dll=0,, %Company%=Inst,NT$ARCH$ [Inst.NT$ARCH$] -%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_XSC000&DEV_VBD&REV_08000008 -%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_XS0001&DEV_VBD&REV_08000008 -%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_XS0002&DEV_VBD&REV_08000008 +%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_XSC000&DEV_VBD&REV_08000009 +%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_XS0001&DEV_VBD&REV_08000009 +%XenVbdDesc%=XenVbd_Inst,XENBUS\VEN_XS0002&DEV_VBD&REV_08000009 [XenVbd_Inst] CopyFiles=XenVbd_Copyfiles diff --git a/src/xenvbd/driver.c b/src/xenvbd/driver.c index f5f73ca..2a41c8c 100644 --- a/src/xenvbd/driver.c +++ b/src/xenvbd/driver.c @@ -47,7 +47,7 @@ #define IS_PDO ((ULONG)'odp') //============================================================================= XENVBD_PARAMETERS DriverParameters; -HANDLE DriverServiceKey; +HANDLE DriverStatusKey; #define XENVBD_POOL_TAG 'dbvX' @@ -615,7 +615,7 @@ DriverUnload( DAY_STR "/" MONTH_STR "/" YEAR_STR); StorPortDriverUnload(_DriverObject); BufferTerminate(); - ZwClose(DriverServiceKey); + ZwClose(DriverStatusKey); Trace("<=== (Irql=%d)\n", KeGetCurrentIrql()); } @@ -631,6 +631,7 @@ DriverEntry( OBJECT_ATTRIBUTES Attributes; UNICODE_STRING Unicode; HW_INITIALIZATION_DATA InitData; + HANDLE ServiceKey; // RegistryPath == NULL if crashing! if (RegistryPath == NULL) { @@ -655,14 +656,33 @@ DriverEntry( NULL, NULL); - Status = ZwOpenKey(&DriverServiceKey, + Status = ZwOpenKey(&ServiceKey, KEY_ALL_ACCESS, &Attributes); if (!NT_SUCCESS(Status)) goto done; - RtlInitUnicodeString(&Unicode, L"NeedReboot"); - (VOID)ZwDeleteValueKey(DriverServiceKey, &Unicode); + RtlInitUnicodeString(&Unicode, L"Status"); + + InitializeObjectAttributes(&Attributes, + &Unicode, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + ServiceKey, + NULL); + + Status = ZwCreateKey(&DriverStatusKey, + KEY_ALL_ACCESS, + &Attributes, + 0, + NULL, + REG_OPTION_VOLATILE, + NULL + ); + + ZwClose(ServiceKey); + + if (!NT_SUCCESS(Status)) + goto done; KeInitializeSpinLock(&__XenvbdLock); __XenvbdFdo = NULL; diff --git a/src/xenvbd/driver.h b/src/xenvbd/driver.h index bfb6277..0bbf6cb 100644 --- a/src/xenvbd/driver.h +++ b/src/xenvbd/driver.h @@ -56,7 +56,7 @@ typedef struct _XENVBD_PARAMETERS { extern XENVBD_PARAMETERS DriverParameters; -extern HANDLE DriverServiceKey; +extern HANDLE DriverStatusKey; // Fdo Device Extension management extern VOID diff --git a/src/xenvbd/fdo.c b/src/xenvbd/fdo.c index b146f7c..3a569f3 100644 --- a/src/xenvbd/fdo.c +++ b/src/xenvbd/fdo.c @@ -76,6 +76,7 @@ struct _XENVBD_FDO { XENBUS_GNTTAB_INTERFACE Gnttab; XENBUS_DEBUG_INTERFACE Debug; XENBUS_SUSPEND_INTERFACE Suspend; + XENBUS_UNPLUG_INTERFACE Unplug; XENFILT_EMULATED_INTERFACE Emulated; // Debug Callback @@ -583,7 +584,7 @@ __FdoNotifyInstaller( RtlInitUnicodeString(&Unicode, L"NeedReboot"); - status = ZwSetValueKey(DriverServiceKey, + status = ZwSetValueKey(DriverStatusKey, &Unicode, Partial->TitleIndex, Partial->Type, @@ -759,8 +760,20 @@ FdoScan( StorPortNotification(BusChangeDetected, Fdo, 0); } - if (NeedReboot) + if (NeedReboot) { + PXENBUS_UNPLUG_INTERFACE Unplug; + + Unplug = FdoAcquireUnplug(Fdo); + ASSERT(Unplug != NULL); + + XENBUS_UNPLUG(Request, + Unplug, + XENBUS_UNPLUG_DEVICE_TYPE_DISKS, + TRUE); + XENBUS_UNPLUG(Release, Unplug); + __FdoNotifyInstaller(Fdo); + } } return STATUS_SUCCESS; @@ -891,6 +904,16 @@ __FdoQueryInterfaces( if (!NT_SUCCESS(Status)) goto fail5; + // Get UNPLUG Interface + Status = QUERY_INTERFACE(Fdo, + XENBUS, + UNPLUG, + (PINTERFACE)&Fdo->Unplug, + sizeof (Fdo->Unplug), + FALSE); + if (!NT_SUCCESS(Status)) + goto fail6; + // Get EMULATED Interface (optional) Status = QUERY_INTERFACE(Fdo, XENFILT, @@ -899,10 +922,13 @@ __FdoQueryInterfaces( sizeof (Fdo->Emulated), TRUE); if (!NT_SUCCESS(Status)) - goto fail6; + goto fail7; return STATUS_SUCCESS; +fail7: + RtlZeroMemory(&Fdo->Unplug, + sizeof (XENBUS_UNPLUG_INTERFACE)); fail6: RtlZeroMemory(&Fdo->Debug, sizeof (XENBUS_DEBUG_INTERFACE)); @@ -928,6 +954,8 @@ __FdoZeroInterfaces( { RtlZeroMemory(&Fdo->Emulated, sizeof (XENFILT_EMULATED_INTERFACE)); + RtlZeroMemory(&Fdo->Unplug, + sizeof (XENBUS_UNPLUG_INTERFACE)); RtlZeroMemory(&Fdo->Debug, sizeof (XENBUS_DEBUG_INTERFACE)); RtlZeroMemory(&Fdo->Suspend, @@ -972,8 +1000,14 @@ __FdoAcquire( if (!NT_SUCCESS(status)) goto fail6; + status = XENBUS_UNPLUG(Acquire, &Fdo->Unplug); + if (!NT_SUCCESS(status)) + goto fail7; + return STATUS_SUCCESS; +fail7: + XENBUS_UNPLUG(Release, &Fdo->Unplug); fail6: XENBUS_EVTCHN(Release, &Fdo->Evtchn); fail5: @@ -993,6 +1027,7 @@ __FdoRelease( __in PXENVBD_FDO Fdo ) { + XENBUS_UNPLUG(Release, &Fdo->Unplug); XENBUS_STORE(Release, &Fdo->Store); XENBUS_EVTCHN(Release, &Fdo->Evtchn); XENBUS_GNTTAB(Release, &Fdo->Gnttab); @@ -1927,3 +1962,17 @@ FdoAcquireSuspend( return &Fdo->Suspend; } + +PXENBUS_UNPLUG_INTERFACE +FdoAcquireUnplug( + __in PXENVBD_FDO Fdo + ) +{ + NTSTATUS status; + + status = XENBUS_UNPLUG(Acquire, &Fdo->Unplug); + if (!NT_SUCCESS(status)) + return NULL; + + return &Fdo->Unplug; +} diff --git a/src/xenvbd/fdo.h b/src/xenvbd/fdo.h index fcb5803..981ffbb 100644 --- a/src/xenvbd/fdo.h +++ b/src/xenvbd/fdo.h @@ -43,6 +43,7 @@ typedef struct _XENVBD_FDO XENVBD_FDO, *PXENVBD_FDO; #include <gnttab_interface.h> #include <debug_interface.h> #include <suspend_interface.h> +#include <unplug_interface.h> // Reference Counting extern LONG @@ -192,4 +193,9 @@ FdoAcquireSuspend( __in PXENVBD_FDO Fdo ); +extern PXENBUS_UNPLUG_INTERFACE +FdoAcquireUnplug( + __in PXENVBD_FDO Fdo + ); + #endif // _XENVBD_FDO_H diff --git a/src/xenvbd/pdo.c b/src/xenvbd/pdo.c index a77aeed..587b2f2 100644 --- a/src/xenvbd/pdo.c +++ b/src/xenvbd/pdo.c @@ -652,11 +652,11 @@ PdoDestroy( __checkReturn NTSTATUS PdoD3ToD0( - __in PXENVBD_PDO Pdo + __in PXENVBD_PDO Pdo ) { - NTSTATUS Status; - const ULONG TargetId = PdoGetTargetId(Pdo); + NTSTATUS Status; + const ULONG TargetId = PdoGetTargetId(Pdo); if (!PdoSetDevicePowerState(Pdo, PowerDeviceD0)) return STATUS_SUCCESS; @@ -694,10 +694,10 @@ fail1: VOID PdoD0ToD3( - __in PXENVBD_PDO Pdo + __in PXENVBD_PDO Pdo ) { - const ULONG TargetId = PdoGetTargetId(Pdo); + const ULONG TargetId = PdoGetTargetId(Pdo); if (!PdoSetDevicePowerState(Pdo, PowerDeviceD3)) return; @@ -2588,11 +2588,23 @@ PdoDispatchPnp( __PdoCheckEjectPending(Pdo); switch (Stack->MinorFunction) { - case IRP_MN_START_DEVICE: + case IRP_MN_START_DEVICE: { + PXENBUS_UNPLUG_INTERFACE Unplug; + + Unplug = FdoAcquireUnplug(PdoGetFdo(Pdo)); + ASSERT(Unplug != NULL); + + XENBUS_UNPLUG(Request, + Unplug, + XENBUS_UNPLUG_DEVICE_TYPE_DISKS, + TRUE); + XENBUS_UNPLUG(Release, Unplug); + (VOID) PdoD3ToD0(Pdo); + PdoSetDevicePnpState(Pdo, Started); break; - + } case IRP_MN_QUERY_STOP_DEVICE: PdoSetDevicePnpState(Pdo, StopPending); break; @@ -2601,10 +2613,22 @@ PdoDispatchPnp( __PdoRestoreDevicePnpState(Pdo, StopPending); break; - case IRP_MN_STOP_DEVICE: + case IRP_MN_STOP_DEVICE: { + PXENBUS_UNPLUG_INTERFACE Unplug; + + Unplug = FdoAcquireUnplug(PdoGetFdo(Pdo)); + ASSERT(Unplug != NULL); + PdoSetDevicePnpState(Pdo, Stopped); - break; + XENBUS_UNPLUG(Request, + Unplug, + XENBUS_UNPLUG_DEVICE_TYPE_DISKS, + FALSE); + XENBUS_UNPLUG(Release, Unplug); + + break; + } case IRP_MN_QUERY_REMOVE_DEVICE: PdoSetDevicePnpState(Pdo, RemovePending); break; @@ -2618,10 +2642,22 @@ PdoDispatchPnp( PdoSetDevicePnpState(Pdo, SurpriseRemovePending); break; - case IRP_MN_REMOVE_DEVICE: + case IRP_MN_REMOVE_DEVICE: { + PXENBUS_UNPLUG_INTERFACE Unplug; + + Unplug = FdoAcquireUnplug(PdoGetFdo(Pdo)); + ASSERT(Unplug != NULL); + __PdoRemoveDevice(Pdo); - break; + XENBUS_UNPLUG(Request, + Unplug, + XENBUS_UNPLUG_DEVICE_TYPE_DISKS, + FALSE); + XENBUS_UNPLUG(Release, Unplug); + + break; + } case IRP_MN_EJECT: __PdoEject(Pdo); break; -- 2.1.1 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |