[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.