|
[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 |