]> xenbits.xensource.com Git - pvdrivers/win/xenbus.git/commitdiff
Introduce new mechanism to unplug emulated devices
authorPaul Durrant <paul.durrant@citrix.com>
Fri, 17 Jul 2015 09:25:46 +0000 (10:25 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Mon, 20 Jul 2015 09:14:37 +0000 (10:14 +0100)
This makes an incompatible change and so the PDO revision is bumped up
without retaining any previous revisions.

With this patch a new unplug interface is exported by XENBUS (so it is
available for query before installing XENFILT). This interface exports
a Request method which is now the one true way of requesting unplug
of emulated devices. Co-installers need not mess with registry keys
any more. Instead drivers should request unplug when they find their
PDOs blocked by aliasing emulated devices, or when they successfully
come online. The reason for the latter case is that unplug is now
single-shot. It needs to be re-requested by PV drivers each time their
PDOs come online otherwise emulated devices will be re-instated on
next reboot.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
28 files changed:
include/revision.h
include/unplug_interface.h
include/xen.h
src/coinst/coinst.c
src/common/registry.c
src/common/registry.h
src/xen/driver.c
src/xen/driver.h [new file with mode: 0644]
src/xen/unplug.c [new file with mode: 0644]
src/xen/unplug.h [new file with mode: 0644]
src/xenbus.inf
src/xenbus/fdo.c
src/xenbus/fdo.h
src/xenbus/pdo.c
src/xenbus/suspend.c
src/xenbus/unplug.c [new file with mode: 0644]
src/xenbus/unplug.h [new file with mode: 0644]
src/xenfilt/driver.c
src/xenfilt/driver.h
src/xenfilt/pdo.c
src/xenfilt/unplug.c [deleted file]
src/xenfilt/unplug.h [deleted file]
vs2012/xen/xen.vcxproj
vs2012/xenbus/xenbus.vcxproj
vs2012/xenfilt/xenfilt.vcxproj
vs2013/xen/xen.vcxproj
vs2013/xenbus/xenbus.vcxproj
vs2013/xenfilt/xenfilt.vcxproj

index 9a91a338aa3f097161a9165cfb018244add64eb4..dfe499516fc8503deb57a80da4e41613277cb03e 100644 (file)
@@ -43,8 +43,8 @@
 // G  - XENBUS_GNTTAB_INTERFACE
 // EM - XENFILT_EMULATED_INTERFACE
 
-//                    REVISION   S  SI   E   D  ST   R   C   G  EM
-#define DEFINE_REVISION_TABLE                                      \
-    DEFINE_REVISION(0x08000008,  1,  2,  4,  1,  1,  1,  1,  1,  1)
+//                    REVISION   S  SI   E   D  ST   R   C   G   U  EM
+#define DEFINE_REVISION_TABLE                                           \
+    DEFINE_REVISION(0x08000009,  1,  2,  4,  1,  1,  1,  1,  1,  1,  1)
 
 #endif  // _REVISION_H
index 8817f53bbcfa00c6486fce4652a39da07e770cea..83b3dc98d8bef5d8fe517330702dc5ee855bab5d 100644 (file)
  */
 
 /*! \file unplug_interface.h
-    \brief XENFILT UNPLUG Interface
+    \brief XENBUS UNPLUG Interface
 
-    This interface provides a primitive to re-unplug emulated devices,
-    which is required on resume-from-suspend
+    This interface provides a method to request emulated device unplug
 */
 
-#ifndef _XENFILT_UNPLUG_INTERFACE_H
-#define _XENFILT_UNPLUG_INTERFACE_H
+#ifndef _XENBUS_UNPLUG_INTERFACE_H
+#define _XENBUS_UNPLUG_INTERFACE_H
 
 #ifndef _WINDLL
 
-/*! \typedef XENFILT_UNPLUG_ACQUIRE
+/*! \typedef XENBUS_UNPLUG_ACQUIRE
     \brief Acquire a reference to the UNPLUG interface
 
     \param Interface The interface header
 */  
 typedef NTSTATUS
-(*XENFILT_UNPLUG_ACQUIRE)(
+(*XENBUS_UNPLUG_ACQUIRE)(
     IN  PINTERFACE  Interface
     );
 
-/*! \typedef XENFILT_UNPLUG_RELEASE
+/*! \typedef XENBUS_UNPLUG_RELEASE
     \brief Release a reference to the UNPLUG interface
 
     \param Interface The interface header
 */  
 typedef VOID
-(*XENFILT_UNPLUG_RELEASE)(
+(*XENBUS_UNPLUG_RELEASE)(
     IN  PINTERFACE  Interface
     );
 
-/*! \typedef XENFILT_UNPLUG_REPLAY
-    \brief Re-unplug emulated devices that were previously unplugged
-    at boot time
+/*! \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
-(*XENFILT_UNPLUG_REPLAY)(
-    IN  PINTERFACE  Interface
+(*XENBUS_UNPLUG_REQUEST)(
+    IN  PINTERFACE                  Interface,
+    IN  XENBUS_UNPLUG_DEVICE_TYPE   Type,
+    IN  BOOLEAN                     Make
     );
 
-// {D5657CFD-3DB5-4A23-A94F-61FD89247FE7}
-DEFINE_GUID(GUID_XENFILT_UNPLUG_INTERFACE,
-0xd5657cfd, 0x3db5, 0x4a23, 0xa9, 0x4f, 0x61, 0xfd, 0x89, 0x24, 0x7f, 0xe7);
+// {73db6517-3d06-4937-989f-199b7501e229}
+DEFINE_GUID(GUID_XENBUS_UNPLUG_INTERFACE,
+0x73db6517, 0x3d06, 0x4937, 0x98, 0x9f, 0x19, 0x9b, 0x75, 0x01, 0xe2, 0x29);
 
-/*! \struct _XENFILT_UNPLUG_INTERFACE_V1
+/*! \struct _XENBUS_UNPLUG_INTERFACE_V1
     \brief UNPLUG interface version 1
     \ingroup interfaces
 */
-struct _XENFILT_UNPLUG_INTERFACE_V1 {
+struct _XENBUS_UNPLUG_INTERFACE_V1 {
     INTERFACE               Interface;
-    XENFILT_UNPLUG_ACQUIRE  Acquire;
-    XENFILT_UNPLUG_RELEASE  Release;
-    XENFILT_UNPLUG_REPLAY   Replay;
+    XENBUS_UNPLUG_ACQUIRE   UnplugAcquire;
+    XENBUS_UNPLUG_RELEASE   UnplugRelease;
+    XENBUS_UNPLUG_REQUEST   UnplugRequest;
 };
 
-typedef struct _XENFILT_UNPLUG_INTERFACE_V1 XENFILT_UNPLUG_INTERFACE, *PXENFILT_UNPLUG_INTERFACE;
+typedef struct _XENBUS_UNPLUG_INTERFACE_V1 XENBUS_UNPLUG_INTERFACE, *PXENBUS_UNPLUG_INTERFACE;
 
-/*! \def XENFILT_UNPLUG
+/*! \def XENBUS_UNPLUG
     \brief Macro at assist in method invocation
 */
-#define XENFILT_UNPLUG(_Method, _Interface, ...)    \
-    (_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+#define XENBUS_UNPLUG(_Method, _Interface, ...)    \
+    (_Interface)->Unplug ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
 
 #endif  // _WINDLL
 
-#define XENFILT_UNPLUG_INTERFACE_VERSION_MIN  1
-#define XENFILT_UNPLUG_INTERFACE_VERSION_MAX  1
+#define XENBUS_UNPLUG_INTERFACE_VERSION_MIN  1
+#define XENBUS_UNPLUG_INTERFACE_VERSION_MAX  1
 
-#endif  // _XENFILT_UNPLUG_INTERFACE_H
+#endif  // _XENBUS_UNPLUG_INTERFACE_H
 
index cf9c2d9e625072bc33343812a518ac75fcd439d4..6007582c0aaaf1d0984143dd643ec7435b329d04 100644 (file)
@@ -307,6 +307,32 @@ ModuleLookup(
     OUT PULONG_PTR  Offset
     );
 
+// UNPLUG
+
+typedef enum _UNPLUG_TYPE {
+    UNPLUG_DISKS = 0,
+    UNPLUG_NICS,
+    UNPLUG_TYPE_COUNT
+} UNPLUG_TYPE, *PUNPLUG_TYPE;
+
+XEN_API
+VOID
+UnplugDevices(
+    VOID
+    );
+
+XEN_API
+NTSTATUS
+UnplugIncrementValue(
+    IN  UNPLUG_TYPE Type
+    );
+
+XEN_API
+NTSTATUS
+UnplugDecrementValue(
+    IN  UNPLUG_TYPE Type
+    );
+
 // LOG
 
 typedef enum _LOG_LEVEL {
index 0b8c30673a3cee4cc6e549da76b4474a14d6b691..2b980a1f9c16838af04057f6b4b8425b36cec921 100644 (file)
@@ -1298,7 +1298,7 @@ fail1:
     return FALSE;
 }
 
-#define DEFINE_REVISION(_N, _S, _SI, _E, _D, _ST, _R, _C, _G, _EM) \
+#define DEFINE_REVISION(_N, _S, _SI, _E, _D, _ST, _R, _C, _G, _U, _EM) \
     (_N)
 
 static DWORD    DeviceRevision[] = {
index 4caeaa5c8e8df11048fc5803f8a96ac23cec6b4a..cb9e31d8c4b70f98e028359a650882088cbe6036 100644 (file)
@@ -115,6 +115,40 @@ fail1:
     return status;
 }
 
+NTSTATUS
+RegistryCreateKey(
+    IN  HANDLE          Parent,
+    IN  PUNICODE_STRING Path,
+    IN  ULONG           Options,
+    OUT PHANDLE         Key
+    )
+{
+    OBJECT_ATTRIBUTES   Attributes;
+    NTSTATUS            status;
+
+    InitializeObjectAttributes(&Attributes,
+                               Path,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               Parent,
+                               NULL);
+
+    status = ZwCreateKey(Key,
+                         KEY_ALL_ACCESS,
+                         &Attributes,
+                         0,
+                         NULL,
+                         Options,
+                         NULL
+                         );
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
 NTSTATUS
 RegistryOpenServiceKey(
     IN  ACCESS_MASK     DesiredAccess,
@@ -124,6 +158,14 @@ RegistryOpenServiceKey(
     return RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, Key);
 }
 
+NTSTATUS
+RegistryCreateServiceKey(
+    OUT PHANDLE         Key
+    )
+{
+    return RegistryCreateKey(NULL, &RegistryPath, REG_OPTION_NON_VOLATILE, Key);
+}
+
 NTSTATUS
 RegistryOpenSoftwareKey(
     IN  PDEVICE_OBJECT  DeviceObject,
index 7f0fa23d779a35c6e0165f117ce6f0473f9f8981..3920b6db660ff0d44d2ac1157b54d036c34609b8 100644 (file)
@@ -52,12 +52,25 @@ RegistryOpenKey(
     OUT PHANDLE         Key
     );
 
+extern NTSTATUS
+RegistryCreateKey(
+    IN  HANDLE          Parent,
+    IN  PUNICODE_STRING Path,
+    IN  ULONG           Options,
+    OUT PHANDLE         Key
+    );
+
 extern NTSTATUS
 RegistryOpenServiceKey(
     IN  ACCESS_MASK DesiredAccess,
     OUT PHANDLE     Key
     );
 
+extern NTSTATUS
+RegistryCreateServiceKey(
+    OUT PHANDLE     Key
+    );
+
 extern NTSTATUS
 RegistryOpenSoftwareKey(
     IN  PDEVICE_OBJECT  DeviceObject,
@@ -83,8 +96,7 @@ RegistryOpenSubKey(
 extern NTSTATUS
 RegistryCreateSubKey(
     IN  HANDLE      Key,
-    IN  PCHAR       Name,
-    IN  ULONG       Options,
+    IN  PCHAR       Name,    IN  ULONG       Options,
     OUT PHANDLE     SubKey
     );
 
index 66a5e8087ed45c895bc11a54696ae3a05e36c4ce..9662ff6863f17a1db645f359b6bf81aa654a2fb2 100644 (file)
 #include <procgrp.h>
 #include <xen.h>
 
+#include "registry.h"
+#include "driver.h"
 #include "hypercall.h"
 #include "log.h"
 #include "module.h"
 #include "process.h"
 #include "system.h"
 #include "acpi.h"
+#include "unplug.h"
 #include "bug_check.h"
 #include "dbg_print.h"
 #include "assert.h"
@@ -51,6 +54,7 @@ extern PULONG   InitSafeBootMode;
 typedef struct _XEN_DRIVER {
     PLOG_DISPOSITION    TraceDisposition;
     PLOG_DISPOSITION    InfoDisposition;
+    HANDLE              UnplugKey;
 } XEN_DRIVER, *PXEN_DRIVER;
 
 static XEN_DRIVER   Driver;
@@ -102,6 +106,30 @@ fail1:
     return STATUS_INCOMPATIBLE_DRIVER_BLOCKED;
 }
 
+static FORCEINLINE VOID
+__DriverSetUnplugKey(
+    IN  HANDLE  Key
+    )
+{
+    Driver.UnplugKey = Key;
+}
+
+static FORCEINLINE HANDLE
+__DriverGetUnplugKey(
+    VOID
+    )
+{
+    return Driver.UnplugKey;
+}
+
+HANDLE
+DriverGetUnplugKey(
+    VOID
+    )
+{
+    return __DriverGetUnplugKey();
+}
+
 static VOID
 DriverOutputBuffer(
     IN  PVOID   Argument,
@@ -122,9 +150,9 @@ DllInitialize(
     IN  PUNICODE_STRING RegistryPath
     )
 {
-    NTSTATUS    status;
-
-    UNREFERENCED_PARAMETER(RegistryPath);
+    HANDLE              ServiceKey;
+    HANDLE              UnplugKey;
+    NTSTATUS            status;
 
     ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
     WdmlibProcgrpInitialize();
@@ -165,59 +193,103 @@ DllInitialize(
          MONTH,
          YEAR);
 
-    status = AcpiInitialize();
+    status = RegistryInitialize(RegistryPath);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = SystemInitialize();
+    status = RegistryCreateServiceKey(&ServiceKey);
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = HypercallInitialize();
+    status = RegistryCreateSubKey(ServiceKey,
+                                  "Unplug",
+                                  REG_OPTION_NON_VOLATILE,
+                                  &UnplugKey);
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    status = BugCheckInitialize();
+    __DriverSetUnplugKey(UnplugKey);
+
+    status = AcpiInitialize();
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    status = ModuleInitialize();
+    status = SystemInitialize();
     if (!NT_SUCCESS(status))
         goto fail6;
 
-    status = ProcessInitialize();
+    status = HypercallInitialize();
     if (!NT_SUCCESS(status))
         goto fail7;
 
+    status = BugCheckInitialize();
+    if (!NT_SUCCESS(status))
+        goto fail8;
+
+    status = ModuleInitialize();
+    if (!NT_SUCCESS(status))
+        goto fail9;
+
+    status = ProcessInitialize();
+    if (!NT_SUCCESS(status))
+        goto fail10;
+
+    status = UnplugInitialize();
+    if (!NT_SUCCESS(status))
+        goto fail11;
+
+    RegistryCloseKey(ServiceKey);
+
 done:
     Trace("<====\n");
 
     return STATUS_SUCCESS;
 
+fail11:
+    Error("fail11\n");
+
+    ProcessTeardown();
+
+fail10:
+    Error("fail10\n");
+
+    ModuleTeardown();
+
+fail9:
+    Error("fail9\n");
+
+    BugCheckTeardown();
+
+fail8:
+    Error("fail8\n");
+
+    HypercallTeardown();
+
 fail7:
     Error("fail7\n");
 
-    ModuleTeardown();
+    SystemTeardown();
 
 fail6:
     Error("fail6\n");
 
-    BugCheckTeardown();
+    AcpiTeardown();
 
 fail5:
     Error("fail5\n");
 
-    HypercallTeardown();
+    RegistryCloseKey(UnplugKey);
+    __DriverSetUnplugKey(NULL);
 
 fail4:
     Error("fail4\n");
 
-    SystemTeardown();
+    RegistryCloseKey(ServiceKey);
 
 fail3:
     Error("fail3\n");
 
-    AcpiTeardown();
+    RegistryTeardown();
 
 fail2:
     Error("fail2\n");
@@ -231,7 +303,7 @@ fail2:
     LogTeardown();
 
 fail1:
-    Error("fail1 (%08x)", status);
+    Error("fail1 (%08x)\n", status);
 
     ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER)));
 
@@ -243,11 +315,15 @@ DllUnload(
     VOID
     )
 {
+    HANDLE  UnplugKey;
+
     Trace("====>\n");
 
     if (*InitSafeBootMode > 0)
         goto done;
 
+    UnplugTeardown();
+
     ProcessTeardown();
 
     ModuleTeardown();
@@ -258,6 +334,13 @@ DllUnload(
 
     SystemTeardown();
 
+    UnplugKey = __DriverGetUnplugKey();
+
+    RegistryCloseKey(UnplugKey);
+    __DriverSetUnplugKey(NULL);
+
+    RegistryTeardown();
+
     Info("XEN %d.%d.%d (%d) (%02d.%02d.%04d)\n",
          MAJOR_VERSION,
          MINOR_VERSION,
diff --git a/src/xen/driver.h b/src/xen/driver.h
new file mode 100644 (file)
index 0000000..c4f7a6f
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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.
+ */
+
+#ifndef _XEN_DRIVER_H
+#define _XEN_DRIVER_H
+
+extern HANDLE
+DriverGetUnplugKey(
+    VOID
+    );
+
+#endif  // _XEN_DRIVER_H
diff --git a/src/xen/unplug.c b/src/xen/unplug.c
new file mode 100644 (file)
index 0000000..77b6b8e
--- /dev/null
@@ -0,0 +1,421 @@
+/* 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.
+ */
+
+#define XEN_API __declspec(dllexport)
+
+#include <ntddk.h>
+#include <ntstrsafe.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <xen.h>
+#include <version.h>
+
+#include "driver.h"
+#include "high.h"
+#include "registry.h"
+#include "unplug.h"
+#include "dbg_print.h"
+#include "assert.h"
+#include "util.h"
+
+#define UNPLUG_TAG  'LPNU'
+
+typedef struct _UNPLUG_CONTEXT {
+    LONG        References;
+    HIGH_LOCK   Lock;
+    BOOLEAN     BlackListed;
+    BOOLEAN     Request[UNPLUG_TYPE_COUNT];
+    BOOLEAN     BootEmulated;
+} UNPLUG_CONTEXT, *PUNPLUG_CONTEXT;
+
+static UNPLUG_CONTEXT   UnplugContext;
+
+static FORCEINLINE PVOID
+__UnplugAllocate(
+    IN  ULONG   Length
+    )
+{
+    return __AllocatePoolWithTag(NonPagedPool, Length, UNPLUG_TAG);
+}
+
+static FORCEINLINE VOID
+__UnplugFree(
+    IN  PVOID   Buffer
+    )
+{
+    ExFreePoolWithTag(Buffer, UNPLUG_TAG);
+}
+
+static VOID
+UnplugSetBootEmulated(
+    VOID
+    )
+{
+    PUNPLUG_CONTEXT Context = &UnplugContext;
+    CHAR            Key[] = "XEN:BOOT_EMULATED=";
+    PANSI_STRING    Option;
+    PCHAR           Value;
+    NTSTATUS        status;
+
+    status = RegistryQuerySystemStartOption(Key, &Option);
+    if (!NT_SUCCESS(status))
+        return;
+
+    Value = Option->Buffer + sizeof (Key) - 1;
+
+    if (strcmp(Value, "TRUE") == 0)
+        Context->BootEmulated = TRUE;
+
+    RegistryFreeSzValue(Option);
+}
+
+static VOID
+UnplugDeviceType(
+    IN  UNPLUG_TYPE Type
+    )
+{
+    PUNPLUG_CONTEXT Context = &UnplugContext;
+
+    switch (Type) {
+    case UNPLUG_DISKS:
+        if (Context->BootEmulated) {
+#pragma prefast(suppress:28138)
+            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0004);
+
+            LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: AUX DISKS\n");
+        } else {
+#pragma prefast(suppress:28138)
+            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001);
+
+            LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n");
+        }
+        break;
+    case UNPLUG_NICS:
+#pragma prefast(suppress:28138)
+        WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002);
+
+        LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n");
+        break;
+    default:
+        ASSERT(FALSE);
+    }
+}
+
+static NTSTATUS
+UnplugPreamble(
+    VOID
+    )
+{
+    PUNPLUG_CONTEXT Context = &UnplugContext;
+    USHORT          Magic;
+    UCHAR           Version;
+    NTSTATUS        status;
+
+    // See docs/misc/hvm-emulated-unplug.markdown for details of the
+    // protocol in use here
+
+#pragma prefast(suppress:28138)
+    Magic = READ_PORT_USHORT((PUSHORT)0x10);
+
+    if (Magic == 0xd249) {
+        Context->BlackListed = TRUE;
+        goto done;
+    }
+
+    status = STATUS_NOT_SUPPORTED;
+    if (Magic != 0x49d2)
+        goto fail1;
+
+#pragma prefast(suppress:28138)
+    Version = READ_PORT_UCHAR((PUCHAR)0x12);
+    if (Version != 0) {
+#pragma prefast(suppress:28138)
+        WRITE_PORT_USHORT((PUSHORT)0x12, 0xFFFF);   // FIXME
+
+#pragma prefast(suppress:28138)
+        WRITE_PORT_ULONG((PULONG)0x10,
+                         (MAJOR_VERSION << 16) |
+                         (MINOR_VERSION << 8) |
+                         MICRO_VERSION);
+
+#pragma prefast(suppress:28138)
+        Magic = READ_PORT_USHORT((PUSHORT)0x10);
+        if (Magic == 0xd249)
+            Context->BlackListed = TRUE;
+    }
+
+done:
+    LogPrintf(LOG_LEVEL_WARNING,
+              "UNPLUG: PRE-AMBLE (DRIVERS %s)\n",
+              (Context->BlackListed) ? "BLACKLISTED" : "NOT BLACKLISTED");
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
+static VOID
+UnplugSetRequest(
+    IN  UNPLUG_TYPE     Type
+    )
+{
+    PUNPLUG_CONTEXT     Context = &UnplugContext;
+    HANDLE              UnplugKey;
+    PCHAR               ValueName;
+    ULONG               Value;
+    KIRQL               Irql;
+    NTSTATUS            status;
+
+    Trace("====>\n");
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    UnplugKey = DriverGetUnplugKey();
+
+    switch (Type) {
+    case UNPLUG_DISKS:
+        ValueName = "DISKS";
+        break;
+    case UNPLUG_NICS:
+        ValueName = "NICS";
+        break;
+    default:
+        ValueName = NULL;
+        ASSERT(FALSE);
+    }
+
+    status = RegistryQueryDwordValue(UnplugKey,
+                                     ValueName,
+                                     &Value);
+    if (!NT_SUCCESS(status))
+        goto done;
+
+    (VOID) RegistryDeleteValue(UnplugKey, ValueName);
+
+    Info("%s\n", ValueName);
+
+    AcquireHighLock(&Context->Lock, &Irql);
+    Context->Request[Type] = (Value != 0) ? TRUE : FALSE;
+    ReleaseHighLock(&Context->Lock, Irql);
+
+done:
+    Trace("<====\n");
+}
+
+XEN_API
+NTSTATUS
+UnplugIncrementValue(
+    IN  UNPLUG_TYPE     Type
+    )
+{
+    HANDLE              UnplugKey;
+    PCHAR               ValueName;
+    ULONG               Value;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    UnplugKey = DriverGetUnplugKey();
+
+    switch (Type) {
+    case UNPLUG_DISKS:
+        ValueName = "DISKS";
+        break;
+    case UNPLUG_NICS:
+        ValueName = "NICS";
+        break;
+    default:
+        ValueName = NULL;
+        ASSERT(FALSE);
+    }
+
+    status = RegistryQueryDwordValue(UnplugKey,
+                                     ValueName,
+                                     &Value);
+    if (!NT_SUCCESS(status))
+        Value = 0;
+
+    Value++;
+
+    status = RegistryUpdateDwordValue(UnplugKey,
+                                      ValueName,
+                                      Value);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Info("%s %u\n", ValueName, Value);
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+XEN_API
+NTSTATUS
+UnplugDecrementValue(
+    IN  UNPLUG_TYPE     Type
+    )
+{
+    HANDLE              UnplugKey;
+    PCHAR               ValueName;
+    LONG                Value;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    UnplugKey = DriverGetUnplugKey();
+
+    switch (Type) {
+    case UNPLUG_DISKS:
+        ValueName = "DISKS";
+        break;
+    case UNPLUG_NICS:
+        ValueName = "NICS";
+        break;
+    default:
+        ValueName = NULL;
+        ASSERT(FALSE);
+    }
+
+    status = RegistryQueryDwordValue(UnplugKey,
+                                     ValueName,
+                                     (PULONG)&Value);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = STATUS_INVALID_PARAMETER;
+    if (--Value < 0)
+        goto fail2;
+
+    status = RegistryUpdateDwordValue(UnplugKey,
+                                      ValueName,
+                                      (ULONG)Value);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Info("%s %u\n", ValueName, (ULONG)Value);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+XEN_API
+VOID
+UnplugDevices(
+    VOID
+    )
+{
+    PUNPLUG_CONTEXT Context = &UnplugContext;
+    UNPLUG_TYPE     Type;
+    KIRQL           Irql;
+    NTSTATUS        status;
+
+    AcquireHighLock(&Context->Lock, &Irql);
+
+    status = UnplugPreamble();
+    ASSERT(NT_SUCCESS(status));
+
+    for (Type = 0; Type < UNPLUG_TYPE_COUNT; Type++) {
+        if (Context->Request[Type])
+            UnplugDeviceType(Type);
+    }
+
+    ReleaseHighLock(&Context->Lock, Irql);
+}
+
+NTSTATUS
+UnplugInitialize(
+    VOID
+    )
+{
+    PUNPLUG_CONTEXT Context = &UnplugContext;
+    LONG            References;
+    UNPLUG_TYPE     Type;
+    NTSTATUS        status;
+
+    References = InterlockedIncrement(&Context->References);
+
+    status = STATUS_OBJECTID_EXISTS;
+    if (References != 1)
+        goto fail1;
+
+    InitializeHighLock(&Context->Lock);
+
+    for (Type = 0; Type < UNPLUG_TYPE_COUNT; Type++)
+        UnplugSetRequest(Type);
+
+    UnplugSetBootEmulated();
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    (VOID) InterlockedDecrement(&Context->References);
+
+    ASSERT(IsZeroMemory(Context, sizeof (UNPLUG_CONTEXT)));
+
+    return status;
+}
+
+VOID
+UnplugTeardown(
+    VOID
+    )
+{
+    PUNPLUG_CONTEXT Context = &UnplugContext;
+    UNPLUG_TYPE     Type;
+
+    Context->BootEmulated = FALSE;
+
+    for (Type = 0; Type < UNPLUG_TYPE_COUNT; Type++)
+        Context->Request[Type] = FALSE;
+
+    RtlZeroMemory(&Context->Lock, sizeof (HIGH_LOCK));
+
+    (VOID) InterlockedDecrement(&Context->References);
+
+    ASSERT(IsZeroMemory(Context, sizeof (UNPLUG_CONTEXT)));
+}
diff --git a/src/xen/unplug.h b/src/xen/unplug.h
new file mode 100644 (file)
index 0000000..bd8e67c
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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.
+ */
+
+#ifndef _XEN_UNPLUG_H
+#define _XEN_UNPLUG_H
+
+#include <ntddk.h>
+#include <xen.h>
+
+extern NTSTATUS
+UnplugInitialize(
+    VOID
+    );
+
+extern VOID
+UnplugTeardown(
+    VOID
+    );
+
+#endif  // _XEN_UNPLUG_H
index 90dcf64eb8ec9993d14e0673dc79591d7a5099dd..7f9370fa71e28949815563907bbea15446a10758 100644 (file)
@@ -71,8 +71,8 @@ xenbus_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll
 [XenBus_Inst] 
 CopyFiles=XenBus_Copyfiles
 
-[XenBus_Inst.Services] 
-AddService=xenbus,0x02,XenBus_Service,
+[XenBus_Inst.Services]
+AddService=xenbus,0x02,XenBus_Service
 AddService=xenfilt,,XenFilt_Service,
 
 [XenBus_Service] 
@@ -82,16 +82,13 @@ StartType=%SERVICE_BOOT_START%
 ErrorControl=%SERVICE_ERROR_NORMAL% 
 ServiceBinary=%12%\xenbus.sys 
 LoadOrderGroup="Boot Bus Extender"
-AddReg = XenBus_Parameters, XenBus_Interfaces, XenBus_Interrupts
+AddReg = XenBus_Parameters, XenBus_Interrupts
 
 [XenBus_Parameters]
 HKR,"Parameters",,0x00000010
 HKR,"Parameters","SupportedClasses",0x00010000,"VIF","VBD","IFACE"
 HKR,"Parameters","SyntheticClasses",0x00010000,"IFACE"
 
-[XenBus_Interfaces]
-HKR,"Interfaces",,0x00000010
-
 [XenBus_Interrupts]
 HKR,"Interrupt Management",,0x00000010
 HKR,"Interrupt Management\MessageSignaledInterruptProperties",,0x00000010
@@ -105,19 +102,13 @@ StartType=%SERVICE_BOOT_START%
 ErrorControl=%SERVICE_ERROR_NORMAL% 
 ServiceBinary=%12%\xenfilt.sys 
 LoadOrderGroup="Boot Bus Extender"
-AddReg = XenFilt_Parameters, XenFilt_Unplug, XenFilt_Interfaces
+AddReg = XenFilt_Parameters
 
 [XenFilt_Parameters]
 HKR,"Parameters",,0x00000010
 HKR,"Parameters","ACPI\PNP0A03",0x00000000,"DEVICE"
 HKR,"Parameters","PCIIDE\IDEChannel",0x00000000,"DISK"
 
-[XenFilt_Unplug]
-HKR,"Unplug",,0x00000010
-
-[XenFilt_Interfaces]
-HKR,"Interfaces",,0x00000010
-
 [XenBus_Inst.CoInstallers]
 CopyFiles=CoInst_CopyFiles
 AddReg=CoInst_AddReg
index 82081113413cf55f374080340f698be0bed67e9a..e8a6f2229c59387a03696920fc0d23f4b2c6bc9a 100644 (file)
@@ -38,8 +38,6 @@
 #include <stdlib.h>
 #include <xen.h>
 
-#include <unplug_interface.h>
-
 #include "names.h"
 #include "registry.h"
 #include "fdo.h"
@@ -58,6 +56,7 @@
 #include "balloon.h"
 #include "driver.h"
 #include "range_set.h"
+#include "unplug.h"
 #include "dbg_print.h"
 #include "assert.h"
 #include "util.h"
@@ -122,6 +121,7 @@ struct _XENBUS_FDO {
     PXENBUS_RANGE_SET_CONTEXT       RangeSetContext;
     PXENBUS_CACHE_CONTEXT           CacheContext;
     PXENBUS_GNTTAB_CONTEXT          GnttabContext;
+    PXENBUS_UNPLUG_CONTEXT          UnplugContext;
     PXENBUS_BALLOON_CONTEXT         BalloonContext;
 
     XENBUS_DEBUG_INTERFACE          DebugInterface;
@@ -130,7 +130,6 @@ struct _XENBUS_FDO {
     XENBUS_STORE_INTERFACE          StoreInterface;
     XENBUS_RANGE_SET_INTERFACE      RangeSetInterface;
     XENBUS_BALLOON_INTERFACE        BalloonInterface;
-    XENFILT_UNPLUG_INTERFACE        UnplugInterface;
 
     PXENBUS_RANGE_SET               RangeSet;
     LIST_ENTRY                      List;
@@ -548,6 +547,7 @@ DEFINE_FDO_GET_CONTEXT(Store, PXENBUS_STORE_CONTEXT)
 DEFINE_FDO_GET_CONTEXT(RangeSet, PXENBUS_RANGE_SET_CONTEXT)
 DEFINE_FDO_GET_CONTEXT(Cache, PXENBUS_CACHE_CONTEXT)
 DEFINE_FDO_GET_CONTEXT(Gnttab, PXENBUS_GNTTAB_CONTEXT)
+DEFINE_FDO_GET_CONTEXT(Unplug, PXENBUS_UNPLUG_CONTEXT)
 DEFINE_FDO_GET_CONTEXT(Balloon, PXENBUS_BALLOON_CONTEXT)
 
 __drv_functionClass(IO_COMPLETION_ROUTINE)
@@ -2508,15 +2508,9 @@ FdoD3ToD0(
             goto fail7;
     }
 
-    if (Fdo->UnplugInterface.Interface.Context != NULL) {
-        status = XENFILT_UNPLUG(Acquire, &Fdo->UnplugInterface);
-        if (!NT_SUCCESS(status))
-            goto fail8;
-    }
-
     status = __FdoD3ToD0(Fdo);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail8;
 
     status = XENBUS_SUSPEND(Register,
                             &Fdo->SuspendInterface,
@@ -2525,7 +2519,7 @@ FdoD3ToD0(
                             Fdo,
                             &Fdo->SuspendCallbackLate);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail9;
 
     KeLowerIrql(Irql);
 
@@ -2556,16 +2550,10 @@ not_active:
 
     return STATUS_SUCCESS;
 
-fail10:
-    Error("fail10\n");
-
-    __FdoD0ToD3(Fdo);
-
 fail9:
     Error("fail9\n");
 
-    if (Fdo->UnplugInterface.Interface.Context != NULL)
-        XENFILT_UNPLUG(Release, &Fdo->UnplugInterface);
+    __FdoD0ToD3(Fdo);
 
 fail8:
     Error("fail8\n");
@@ -2692,9 +2680,6 @@ FdoD0ToD3(
 
     __FdoD0ToD3(Fdo);
 
-    if (Fdo->UnplugInterface.Interface.Context != NULL)
-        XENFILT_UNPLUG(Release, &Fdo->UnplugInterface);
-
     if (Fdo->BalloonInterface.Interface.Context != NULL)
         XENBUS_BALLOON(Release, &Fdo->BalloonInterface);
 
@@ -2733,8 +2718,7 @@ FdoS4ToS3(
 
     HypercallPopulate();
 
-    if (Fdo->UnplugInterface.Interface.Context != NULL)
-        XENFILT_UNPLUG(Replay, &Fdo->UnplugInterface);
+    UnplugDevices();
 
     KeLowerIrql(Irql);
 
@@ -4471,15 +4455,6 @@ fail1:
                       (_Size),                                                          \
                       (_Optional))
 
-VOID
-FdoGetUnplugInterface(
-    IN  PXENBUS_FDO                 Fdo,
-    OUT PXENFILT_UNPLUG_INTERFACE   UnplugInterface
-    )
-{
-    *UnplugInterface = Fdo->UnplugInterface;
-}
-
 static BOOLEAN
 FdoIsBalloonEnabled(
     IN  PXENBUS_FDO Fdo
@@ -4581,44 +4556,39 @@ FdoCreate(
     if (!__FdoIsActive(Fdo))
         goto done;
 
-    status = FDO_QUERY_INTERFACE(Fdo,
-                                 XENFILT,
-                                 UNPLUG,
-                                 (PINTERFACE)&Fdo->UnplugInterface,
-                                 sizeof (Fdo->UnplugInterface),
-                                 TRUE);
+    status = DebugInitialize(Fdo, &Fdo->DebugContext);
     if (!NT_SUCCESS(status))
         goto fail7;
 
-    status = DebugInitialize(Fdo, &Fdo->DebugContext);
+    status = SuspendInitialize(Fdo, &Fdo->SuspendContext);
     if (!NT_SUCCESS(status))
         goto fail8;
 
-    status = SuspendInitialize(Fdo, &Fdo->SuspendContext);
+    status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext);
     if (!NT_SUCCESS(status))
         goto fail9;
 
-    status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext);
+    status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext);
     if (!NT_SUCCESS(status))
         goto fail10;
 
-    status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext);
+    status = StoreInitialize(Fdo, &Fdo->StoreContext);
     if (!NT_SUCCESS(status))
         goto fail11;
 
-    status = StoreInitialize(Fdo, &Fdo->StoreContext);
+    status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext);
     if (!NT_SUCCESS(status))
         goto fail12;
 
-    status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext);
+    status = CacheInitialize(Fdo, &Fdo->CacheContext);
     if (!NT_SUCCESS(status))
         goto fail13;
 
-    status = CacheInitialize(Fdo, &Fdo->CacheContext);
+    status = GnttabInitialize(Fdo, &Fdo->GnttabContext);
     if (!NT_SUCCESS(status))
         goto fail14;
 
-    status = GnttabInitialize(Fdo, &Fdo->GnttabContext);
+    status = UnplugInitialize(Fdo, &Fdo->UnplugContext);
     if (!NT_SUCCESS(status))
         goto fail15;
 
@@ -4687,56 +4657,56 @@ done:
 fail16:
     Error("fail16\n");
 
-    GnttabTeardown(Fdo->GnttabContext);
-    Fdo->GnttabContext = NULL;
+    UnplugTeardown(Fdo->UnplugContext);
+    Fdo->UnplugContext = NULL;
 
 fail15:
     Error("fail15\n");
 
-    CacheTeardown(Fdo->CacheContext);
-    Fdo->CacheContext = NULL;
+    GnttabTeardown(Fdo->GnttabContext);
+    Fdo->GnttabContext = NULL;
 
 fail14:
     Error("fail14\n");
 
-    RangeSetTeardown(Fdo->RangeSetContext);
-    Fdo->RangeSetContext = NULL;
+    CacheTeardown(Fdo->CacheContext);
+    Fdo->CacheContext = NULL;
 
 fail13:
     Error("fail13\n");
 
-    StoreTeardown(Fdo->StoreContext);
-    Fdo->StoreContext = NULL;
+    RangeSetTeardown(Fdo->RangeSetContext);
+    Fdo->RangeSetContext = NULL;
 
 fail12:
     Error("fail12\n");
 
-    EvtchnTeardown(Fdo->EvtchnContext);
-    Fdo->EvtchnContext = NULL;
+    StoreTeardown(Fdo->StoreContext);
+    Fdo->StoreContext = NULL;
 
 fail11:
     Error("fail11\n");
 
-    SharedInfoTeardown(Fdo->SharedInfoContext);
-    Fdo->SharedInfoContext = NULL;
+    EvtchnTeardown(Fdo->EvtchnContext);
+    Fdo->EvtchnContext = NULL;
 
 fail10:
     Error("fail10\n");
 
-    SuspendTeardown(Fdo->SuspendContext);
-    Fdo->SuspendContext = NULL;
+    SharedInfoTeardown(Fdo->SharedInfoContext);
+    Fdo->SharedInfoContext = NULL;
 
 fail9:
     Error("fail9\n");
 
-    DebugTeardown(Fdo->DebugContext);
-    Fdo->DebugContext = NULL;
+    SuspendTeardown(Fdo->SuspendContext);
+    Fdo->SuspendContext = NULL;
 
 fail8:
     Error("fail8\n");
 
-    RtlZeroMemory(&Fdo->UnplugInterface,
-                  sizeof (XENFILT_UNPLUG_INTERFACE));
+    DebugTeardown(Fdo->DebugContext);
+    Fdo->DebugContext = NULL;
 
 fail7:
     Error("fail7\n");
@@ -4834,6 +4804,9 @@ FdoDestroy(
             Fdo->BalloonContext = NULL;
         }
 
+        UnplugTeardown(Fdo->UnplugContext);
+        Fdo->UnplugContext = NULL;
+
         GnttabTeardown(Fdo->GnttabContext);
         Fdo->GnttabContext = NULL;
 
@@ -4858,9 +4831,6 @@ FdoDestroy(
         DebugTeardown(Fdo->DebugContext);
         Fdo->DebugContext = NULL;
 
-        RtlZeroMemory(&Fdo->UnplugInterface,
-                      sizeof (XENFILT_UNPLUG_INTERFACE));
-
         __FdoSetActive(Fdo, FALSE);
     }
 
index 4b99ba005eaaa0cb56ea1f7c603904efd12e4eeb..1feef17b98a4e0760384947f72483767b8038484 100644 (file)
@@ -33,7 +33,6 @@
 #define _XENBUS_FDO_H
 
 #include <ntddk.h>
-#include <unplug_interface.h>
 
 #include "driver.h"
 #include "types.h"
@@ -249,10 +248,11 @@ FdoGetGnttabContext(
     IN  PXENBUS_FDO Fdo
     );
 
-extern VOID
-FdoGetUnplugInterface(
-    IN  PXENBUS_FDO                 Fdo,
-    OUT PXENFILT_UNPLUG_INTERFACE   UnplugInterface
+#include "unplug.h"
+
+extern PXENBUS_UNPLUG_CONTEXT
+FdoGetUnplugContext(
+    IN  PXENBUS_FDO Fdo
     );
 
 extern NTSTATUS
index f305bb775d6599f3bf6076009a65d3a97789c2fc..8e7f90aac4e7efe457e58eaa6ca163c7512fdf1d 100644 (file)
@@ -362,11 +362,12 @@ typedef struct _XENBUS_PDO_REVISION {
     ULONG   RangeSetInterfaceVersion;
     ULONG   CacheInterfaceVersion;
     ULONG   GnttabInterfaceVersion;
+    ULONG   UnplugInterfaceVersion;
     ULONG   EmulatedInterfaceVersion;
 } XENBUS_PDO_REVISION, *PXENBUS_PDO_REVISION;
 
-#define DEFINE_REVISION(_N, _S, _SI, _E, _D, _ST, _R, _C, _G, _EM) \
-    { (_N), (_S), (_SI), (_E), (_D), (_ST), (_R), (_C), (_G), (_EM) }
+#define DEFINE_REVISION(_N, _S, _SI, _E, _D, _ST, _R, _C, _G, _U, _EM) \
+    { (_N), (_S), (_SI), (_E), (_D), (_ST), (_R), (_C), (_G), (_U), (_EM) }
 
 static XENBUS_PDO_REVISION PdoRevision[] = {
     DEFINE_REVISION_TABLE
@@ -426,6 +427,11 @@ PdoDumpRevisions(
         ASSERT(IMPLY(Index == ARRAYSIZE(PdoRevision) - 1,
                      Revision->GnttabInterfaceVersion == XENBUS_GNTTAB_INTERFACE_VERSION_MAX));
 
+        ASSERT3U(Revision->UnplugInterfaceVersion, >=, XENBUS_UNPLUG_INTERFACE_VERSION_MIN);
+        ASSERT3U(Revision->UnplugInterfaceVersion, <=, XENBUS_UNPLUG_INTERFACE_VERSION_MAX);
+        ASSERT(IMPLY(Index == ARRAYSIZE(PdoRevision) - 1,
+                     Revision->UnplugInterfaceVersion == XENBUS_UNPLUG_INTERFACE_VERSION_MAX));
+
         ASSERT3U(Revision->EmulatedInterfaceVersion, >=, XENFILT_EMULATED_INTERFACE_VERSION_MIN);
         ASSERT3U(Revision->EmulatedInterfaceVersion, <=, XENFILT_EMULATED_INTERFACE_VERSION_MAX);
         ASSERT(IMPLY(Index == ARRAYSIZE(PdoRevision) - 1,
@@ -442,6 +448,7 @@ PdoDumpRevisions(
              "RANGE_SET v%u "
              "CACHE v%u "
              "GNTTAB v%u "
+             "UNPLUG v%u\n"
              "EMULATED v%u\n",
              Revision->Number,
              Revision->SuspendInterfaceVersion,
@@ -452,6 +459,7 @@ PdoDumpRevisions(
              Revision->RangeSetInterfaceVersion,
              Revision->CacheInterfaceVersion,
              Revision->GnttabInterfaceVersion,
+             Revision->UnplugInterfaceVersion,
              Revision->EmulatedInterfaceVersion);
     }
 }
@@ -1010,6 +1018,7 @@ DEFINE_PDO_QUERY_INTERFACE(Store)
 DEFINE_PDO_QUERY_INTERFACE(RangeSet)
 DEFINE_PDO_QUERY_INTERFACE(Cache)
 DEFINE_PDO_QUERY_INTERFACE(Gnttab)
+DEFINE_PDO_QUERY_INTERFACE(Unplug)
 
 struct _INTERFACE_ENTRY {
     const GUID  *Guid;
@@ -1027,6 +1036,7 @@ static struct _INTERFACE_ENTRY PdoInterfaceTable[] = {
     { &GUID_XENBUS_RANGE_SET_INTERFACE, "RANGE_SET_INTERFACE", PdoQueryRangeSetInterface },
     { &GUID_XENBUS_CACHE_INTERFACE, "CACHE_INTERFACE", PdoQueryCacheInterface },
     { &GUID_XENBUS_GNTTAB_INTERFACE, "GNTTAB_INTERFACE", PdoQueryGnttabInterface },
+    { &GUID_XENBUS_UNPLUG_INTERFACE, "UNPLUG_INTERFACE", PdoQueryUnplugInterface },
     { &GUID_XENFILT_EMULATED_INTERFACE, "EMULATED_INTERFACE", PdoDelegateIrp },
     { NULL, NULL, NULL }
 };
index b8267951b92036a79efb734afc2c939492667c94..fad35e473522c12054256e8902aab43fdacf93db 100644 (file)
@@ -33,8 +33,6 @@
 #include <stdarg.h>
 #include <xen.h>
 
-#include <unplug_interface.h>
-
 #include "suspend.h"
 #include "thread.h"
 #include "fdo.h"
@@ -58,7 +56,6 @@ struct _XENBUS_SUSPEND_CONTEXT {
     LIST_ENTRY                  LateList;
     XENBUS_DEBUG_INTERFACE      DebugInterface;
     PXENBUS_DEBUG_CALLBACK      DebugCallback;
-    XENFILT_UNPLUG_INTERFACE    UnplugInterface;
 };
 
 #define XENBUS_SUSPEND_TAG  'PSUS'
@@ -153,10 +150,6 @@ SuspendTrigger(
     KIRQL                   Irql;
     NTSTATUS                status;
 
-    status = STATUS_NOT_SUPPORTED;
-    if (Context->UnplugInterface.Interface.Context == NULL)
-        goto fail1;
-
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
     LogPrintf(LOG_LEVEL_INFO,
@@ -179,7 +172,7 @@ SuspendTrigger(
 
         HypercallPopulate();
 
-        XENFILT_UNPLUG(Replay, &Context->UnplugInterface);
+        UnplugDevices();
 
         for (ListEntry = Context->EarlyList.Flink;
              ListEntry != &Context->EarlyList;
@@ -216,11 +209,6 @@ SuspendTrigger(
     KeLowerIrql(Irql);
 
     return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
 }
 
 static ULONG
@@ -338,13 +326,6 @@ SuspendAcquire(
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    if (Context->UnplugInterface.Interface.Context != NULL) {
-        status = XENFILT_UNPLUG(Acquire, &Context->UnplugInterface);
-
-        if (!NT_SUCCESS(status))
-            goto fail3;
-    }
-
     Trace("<====\n");
 
 done:
@@ -352,14 +333,6 @@ done:
 
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
-    XENBUS_DEBUG(Deregister,
-                 &Context->DebugInterface,
-                 Context->DebugCallback);
-    Context->DebugCallback = NULL;
-
 fail2:
     Error("fail2\n");
 
@@ -396,9 +369,6 @@ SuspendRelease(
 
     Context->Count = 0;
 
-    if (Context->UnplugInterface.Interface.Context != NULL)
-        XENFILT_UNPLUG(Release, &Context->UnplugInterface);
-
     XENBUS_DEBUG(Deregister,
                  &Context->DebugInterface,
                  Context->DebugCallback);
@@ -444,8 +414,6 @@ SuspendInitialize(
                                sizeof ((*Context)->DebugInterface));
     ASSERT(NT_SUCCESS(status));
 
-    FdoGetUnplugInterface(Fdo, &(*Context)->UnplugInterface);
-
     InitializeListHead(&(*Context)->EarlyList);
     InitializeListHead(&(*Context)->LateList);
     KeInitializeSpinLock(&(*Context)->Lock);
@@ -509,9 +477,6 @@ SuspendTeardown(
 
     Context->Fdo = NULL;
 
-    RtlZeroMemory(&Context->UnplugInterface,
-                  sizeof (XENFILT_UNPLUG_INTERFACE));
-
     RtlZeroMemory(&Context->DebugInterface,
                   sizeof (XENBUS_DEBUG_INTERFACE));
 
diff --git a/src/xenbus/unplug.c b/src/xenbus/unplug.c
new file mode 100644 (file)
index 0000000..0a1b27a
--- /dev/null
@@ -0,0 +1,241 @@
+/* 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.
+ */
+
+#include <ntddk.h>
+#include <ntstrsafe.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <xen.h>
+
+#include "unplug.h"
+#include "fdo.h"
+#include "mutex.h"
+#include "dbg_print.h"
+#include "assert.h"
+#include "util.h"
+
+struct _XENBUS_UNPLUG_CONTEXT {
+    KSPIN_LOCK  Lock;
+    LONG        References;
+    MUTEX       Mutex;
+};
+
+#define XENBUS_UNPLUG_TAG    'LPNU'
+
+static FORCEINLINE PVOID
+__UnplugAllocate(
+    IN  ULONG   Length
+    )
+{
+    return __AllocatePoolWithTag(NonPagedPool, Length, XENBUS_UNPLUG_TAG);
+}
+
+static FORCEINLINE VOID
+__UnplugFree(
+    IN  PVOID   Buffer
+    )
+{
+    ExFreePoolWithTag(Buffer, XENBUS_UNPLUG_TAG);
+}
+
+static VOID
+UnplugRequest(
+    IN  PINTERFACE                  Interface,
+    IN  XENBUS_UNPLUG_DEVICE_TYPE   Type,
+    IN  BOOLEAN                     Make
+    )
+{
+    PXENBUS_UNPLUG_CONTEXT          Context = Interface->Context;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    AcquireMutex(&Context->Mutex);
+
+    switch (Type) {
+    case XENBUS_UNPLUG_DEVICE_TYPE_NICS:
+        Info("NICS (%s)\n", (Make) ? "MAKE" : "REVOKE");
+
+        if (Make)
+            (VOID) UnplugIncrementValue(UNPLUG_NICS);
+        else
+            (VOID) UnplugDecrementValue(UNPLUG_NICS);
+
+        break;
+
+    case XENBUS_UNPLUG_DEVICE_TYPE_DISKS:
+        Info("DISKS (%s)\n", (Make) ? "MAKE" : "REVOKE");
+
+        if (Make)
+            (VOID) UnplugIncrementValue(UNPLUG_DISKS);
+        else
+            (VOID) UnplugDecrementValue(UNPLUG_DISKS);
+
+        break;
+
+    default:
+        ASSERT(FALSE);
+        break;
+    }
+
+    ReleaseMutex(&Context->Mutex);
+}
+
+static NTSTATUS
+UnplugAcquire(
+    IN  PINTERFACE          Interface
+    )
+{
+    PXENBUS_UNPLUG_CONTEXT  Context = Interface->Context;
+    KIRQL                   Irql;
+
+    KeAcquireSpinLock(&Context->Lock, &Irql);
+
+    if (Context->References++ != 0)
+        goto done;
+
+    Trace("<===>\n");
+
+done:
+    KeReleaseSpinLock(&Context->Lock, Irql);
+
+    return STATUS_SUCCESS;
+}
+
+static VOID
+UnplugRelease(
+    IN  PINTERFACE          Interface
+    )
+{
+    PXENBUS_UNPLUG_CONTEXT  Context = Interface->Context;
+    KIRQL                   Irql;
+
+    KeAcquireSpinLock(&Context->Lock, &Irql);
+
+    if (--Context->References > 0)
+        goto done;
+
+    Trace("<===>\n");
+
+done:
+    KeReleaseSpinLock(&Context->Lock, Irql);
+}
+
+static struct _XENBUS_UNPLUG_INTERFACE_V1 UnplugInterfaceVersion1 = {
+    { sizeof (struct _XENBUS_UNPLUG_INTERFACE_V1), 1, NULL, NULL, NULL },
+    UnplugAcquire,
+    UnplugRelease,
+    UnplugRequest
+};
+
+NTSTATUS
+UnplugInitialize(
+    IN  PXENBUS_FDO             Fdo,
+    OUT PXENBUS_UNPLUG_CONTEXT  *Context
+    )
+{
+    NTSTATUS                    status;
+
+    UNREFERENCED_PARAMETER(Fdo);
+
+    Trace("====>\n");
+
+    *Context = __UnplugAllocate(sizeof (XENBUS_UNPLUG_CONTEXT));
+
+    status = STATUS_NO_MEMORY;
+    if (*Context == NULL)
+        goto fail1;
+
+    KeInitializeSpinLock(&(*Context)->Lock);
+    InitializeMutex(&(*Context)->Mutex);
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+NTSTATUS
+UnplugGetInterface(
+    IN      PXENBUS_UNPLUG_CONTEXT  Context,
+    IN      ULONG                   Version,
+    IN OUT  PINTERFACE              Interface,
+    IN      ULONG                   Size
+    )
+{
+    NTSTATUS                        status;
+
+    ASSERT(Context != NULL);
+
+    switch (Version) {
+    case 1: {
+        struct _XENBUS_UNPLUG_INTERFACE_V1   *UnplugInterface;
+
+        UnplugInterface = (struct _XENBUS_UNPLUG_INTERFACE_V1 *)Interface;
+
+        status = STATUS_BUFFER_OVERFLOW;
+        if (Size < sizeof (struct _XENBUS_UNPLUG_INTERFACE_V1))
+            break;
+
+        *UnplugInterface = UnplugInterfaceVersion1;
+
+        ASSERT3U(Interface->Version, ==, Version);
+        Interface->Context = Context;
+
+        status = STATUS_SUCCESS;
+        break;
+    }
+    default:
+        status = STATUS_NOT_SUPPORTED;
+        break;
+    }
+
+    return status;
+}
+
+VOID
+UnplugTeardown(
+    IN  PXENBUS_UNPLUG_CONTEXT  Context
+    )
+{
+    Trace("====>\n");
+
+    RtlZeroMemory(&Context->Mutex, sizeof (MUTEX));
+    RtlZeroMemory(&Context->Lock, sizeof (KSPIN_LOCK));
+
+    ASSERT(IsZeroMemory(Context, sizeof (XENBUS_UNPLUG_CONTEXT)));
+    __UnplugFree(Context);
+
+    Trace("<====\n");
+}
diff --git a/src/xenbus/unplug.h b/src/xenbus/unplug.h
new file mode 100644 (file)
index 0000000..416b2d4
--- /dev/null
@@ -0,0 +1,62 @@
+/* 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.
+ */
+
+#ifndef _XENBUS_UNPLUG_H
+#define _XENBUS_UNPLUG_H
+
+#include <ntddk.h>
+#include <xen.h>
+#include <unplug_interface.h>
+
+typedef struct _XENBUS_UNPLUG_CONTEXT  XENBUS_UNPLUG_CONTEXT, *PXENBUS_UNPLUG_CONTEXT;
+
+#include "fdo.h"
+
+extern NTSTATUS
+UnplugInitialize(
+    IN  PXENBUS_FDO             Fdo,
+    OUT PXENBUS_UNPLUG_CONTEXT  *Context
+    );
+
+extern NTSTATUS
+UnplugGetInterface(
+    IN      PXENBUS_UNPLUG_CONTEXT  Context,
+    IN      ULONG                   Version,
+    IN OUT  PINTERFACE              Interface,
+    IN      ULONG                   Size
+    );
+
+extern VOID
+UnplugTeardown(
+    IN  PXENBUS_UNPLUG_CONTEXT   Context
+    );
+
+#endif  // _XENBUS_UNPLUG_H
index 16ed6f7e1463c7effc73bbbd3d73296ec189e637..f0ffac0678fc6f4d1e8fe9db90e9027a0f2cb0bd 100644 (file)
@@ -38,7 +38,6 @@
 #include "pdo.h"
 #include "driver.h"
 #include "emulated.h"
-#include "unplug.h"
 #include "mutex.h"
 #include "dbg_print.h"
 #include "assert.h"
@@ -50,7 +49,6 @@ extern PULONG       InitSafeBootMode;
 typedef struct _XENFILT_DRIVER {
     PDRIVER_OBJECT              DriverObject;
     HANDLE                      ParametersKey;
-    HANDLE                      UnplugKey;
 
     PCHAR                       ActiveDeviceID;
     PCHAR                       ActiveInstanceID;
@@ -61,12 +59,7 @@ typedef struct _XENFILT_DRIVER {
     XENFILT_FILTER_STATE        FilterState;
 
     PXENFILT_EMULATED_CONTEXT   EmulatedContext;
-    PXENFILT_UNPLUG_CONTEXT     UnplugContext;
-
     XENFILT_EMULATED_INTERFACE  EmulatedInterface;
-    XENFILT_UNPLUG_INTERFACE    UnplugInterface;
-
-    BOOLEAN                     UnplugAcquired;
 } XENFILT_DRIVER, *PXENFILT_DRIVER;
 
 static XENFILT_DRIVER   Driver;
@@ -138,27 +131,27 @@ DriverGetParametersKey(
 }
 
 static FORCEINLINE VOID
-__DriverSetUnplugKey(
-    IN  HANDLE  Key
+__DriverSetEmulatedContext(
+    IN  PXENFILT_EMULATED_CONTEXT   Context
     )
 {
-    Driver.UnplugKey = Key;
+    Driver.EmulatedContext = Context;
 }
 
-static FORCEINLINE HANDLE
-__DriverGetUnplugKey(
+static FORCEINLINE PXENFILT_EMULATED_CONTEXT
+__DriverGetEmulatedContext(
     VOID
     )
 {
-    return Driver.UnplugKey;
+    return Driver.EmulatedContext;
 }
 
-HANDLE
-DriverGetUnplugKey(
+PXENFILT_EMULATED_CONTEXT
+DriverGetEmulatedContext(
     VOID
     )
 {
-    return __DriverGetUnplugKey();
+    return __DriverGetEmulatedContext();
 }
 
 static FORCEINLINE VOID
@@ -226,26 +219,6 @@ DriverRemoveFunctionDeviceObject(
     --Driver.References;
 }
 
-#define DEFINE_DRIVER_GET_CONTEXT(_Interface, _Type)            \
-static FORCEINLINE _Type                                        \
-__DriverGet ## _Interface ## Context(                           \
-    VOID                                                        \
-    )                                                           \
-{                                                               \
-    return Driver. ## _Interface ## Context;                    \
-}                                                               \
-                                                                \
-_Type                                                           \
-DriverGet ## _Interface ## Context(                             \
-    VOID                                                        \
-    )                                                           \
-{                                                               \
-    return __DriverGet ## _Interface ## Context();              \
-}
-
-DEFINE_DRIVER_GET_CONTEXT(Emulated, PXENFILT_EMULATED_CONTEXT)
-DEFINE_DRIVER_GET_CONTEXT(Unplug, PXENFILT_UNPLUG_CONTEXT)
-
 #define SERVICES_KEY L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"
 
 #define SERVICE_KEY(_Driver)    \
@@ -387,7 +360,6 @@ DriverSetFilterState(
     case XENFILT_FILTER_ENABLED: {
         PLIST_ENTRY ListEntry;
         BOOLEAN     Present;
-        NTSTATUS    status;
 
         // Assume all FDOs have enumerated until we know otherwise
         Driver.FilterState = XENFILT_FILTER_PENDING;
@@ -414,10 +386,8 @@ DriverSetFilterState(
 
         Info("ACTIVE DEVICE %sPRESENT\n", (!Present) ? "NOT " : "");
 
-        if (Present) {
-            status = XENFILT_UNPLUG(Acquire, &Driver.UnplugInterface);
-            Driver.UnplugAcquired = NT_SUCCESS(status) ? TRUE : FALSE;
-        }
+        if (Present)
+            UnplugDevices();
 
         Info("PENDING\n");
         break;
@@ -461,7 +431,6 @@ DriverUnload(
     )
 {
     HANDLE              ParametersKey;
-    HANDLE              UnplugKey;
 
     ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
 
@@ -477,23 +446,11 @@ DriverUnload(
     RtlZeroMemory(&Driver.List, sizeof (LIST_ENTRY));
     RtlZeroMemory(&Driver.Mutex, sizeof (MUTEX));
 
-    if (Driver.UnplugAcquired) {
-        XENFILT_UNPLUG(Release, &Driver.UnplugInterface);
-
-        Driver.UnplugAcquired = FALSE;
-    }
-
     XENFILT_EMULATED(Release, &Driver.EmulatedInterface);
 
-    RtlZeroMemory(&Driver.UnplugInterface,
-                  sizeof (XENFILT_UNPLUG_INTERFACE));
-
     RtlZeroMemory(&Driver.EmulatedInterface,
                   sizeof (XENFILT_EMULATED_INTERFACE));
 
-    UnplugTeardown(Driver.UnplugContext);
-    Driver.UnplugContext = NULL;
-
     EmulatedTeardown(Driver.EmulatedContext);
     Driver.EmulatedContext = NULL;
 
@@ -505,10 +462,6 @@ DriverUnload(
         Driver.ActiveInstanceID = NULL;
     }
 
-    UnplugKey = __DriverGetUnplugKey();
-    __DriverSetUnplugKey(NULL);
-    RegistryCloseKey(UnplugKey);
-
     ParametersKey = __DriverGetParametersKey();
     __DriverSetParametersKey(NULL);
     RegistryCloseKey(ParametersKey);
@@ -763,15 +716,15 @@ DRIVER_INITIALIZE   DriverEntry;
 
 NTSTATUS
 DriverEntry(
-    IN  PDRIVER_OBJECT  DriverObject,
-    IN  PUNICODE_STRING RegistryPath
+    IN  PDRIVER_OBJECT          DriverObject,
+    IN  PUNICODE_STRING         RegistryPath
     )
 {
-    HANDLE              ServiceKey;
-    HANDLE              ParametersKey;
-    HANDLE              UnplugKey;
-    ULONG               Index;
-    NTSTATUS            status;
+    HANDLE                      ServiceKey;
+    HANDLE                      ParametersKey;
+    PXENFILT_EMULATED_CONTEXT   EmulatedContext;
+    ULONG                       Index;
+    NTSTATUS                    status;
 
     ASSERT3P(__DriverGetDriverObject(), ==, NULL);
 
@@ -820,23 +773,15 @@ DriverEntry(
 
     __DriverSetParametersKey(ParametersKey);
 
-    status = RegistryOpenSubKey(ServiceKey, "Unplug", KEY_READ, &UnplugKey);
+    status = DriverSetActiveDeviceInstance();
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    __DriverSetUnplugKey(UnplugKey);
-
-    status = DriverSetActiveDeviceInstance();
+    status = EmulatedInitialize(&EmulatedContext);
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    status = EmulatedInitialize(&Driver.EmulatedContext);
-    if (!NT_SUCCESS(status))
-        goto fail6;
-
-    status = UnplugInitialize(&Driver.UnplugContext);
-    if (!NT_SUCCESS(status))
-        goto fail7;
+    __DriverSetEmulatedContext(EmulatedContext);
 
     status = EmulatedGetInterface(__DriverGetEmulatedContext(),
                                   XENFILT_EMULATED_INTERFACE_VERSION_MAX,
@@ -845,16 +790,9 @@ DriverEntry(
     ASSERT(NT_SUCCESS(status));
     ASSERT(Driver.EmulatedInterface.Interface.Context != NULL);
 
-    status = UnplugGetInterface(__DriverGetUnplugContext(),
-                                 XENFILT_UNPLUG_INTERFACE_VERSION_MAX,
-                                 (PINTERFACE)&Driver.UnplugInterface,
-                                 sizeof (Driver.UnplugInterface));
-    ASSERT(NT_SUCCESS(status));
-    ASSERT(Driver.UnplugInterface.Interface.Context != NULL);
-
     status = XENFILT_EMULATED(Acquire, &Driver.EmulatedInterface);
     if (!NT_SUCCESS(status))
-        goto fail8;
+        goto fail6;
 
     RegistryCloseKey(ServiceKey);
 
@@ -874,26 +812,14 @@ done:
     Trace("<====\n");
     return STATUS_SUCCESS;
 
-fail8:
-    Error("fail8\n");
-
-    RtlZeroMemory(&Driver.UnplugInterface,
-                  sizeof (XENFILT_UNPLUG_INTERFACE));
-
-    RtlZeroMemory(&Driver.EmulatedInterface,
-                  sizeof (XENFILT_EMULATED_INTERFACE));
-
-    UnplugTeardown(Driver.UnplugContext);
-    Driver.UnplugContext = NULL;
-
-fail7:
-    Error("fail7\n");
+fail6:
+    Error("fail6\n");
 
     EmulatedTeardown(Driver.EmulatedContext);
     Driver.EmulatedContext = NULL;
 
-fail6:
-    Error("fail6\n");
+fail5:
+    Error("fail5\n");
 
     if (Driver.ActiveDeviceID != NULL) {
         __DriverFree(Driver.ActiveDeviceID);
@@ -903,12 +829,6 @@ fail6:
         Driver.ActiveInstanceID = NULL;
     }
 
-fail5:
-    Error("fail5\n");
-
-    __DriverSetUnplugKey(NULL);
-    RegistryCloseKey(UnplugKey);
-
 fail4:
     Error("fail4\n");
 
index 7079d27d6f6c39bc273dfb35d7f67ef4eaa35a85..f906d362415bbe8c85001bea5b8cb0f4e41666ad 100644 (file)
@@ -42,11 +42,6 @@ DriverGetParametersKey(
     VOID
     );
 
-extern HANDLE
-DriverGetUnplugKey(
-    VOID
-    );
-
 extern PCHAR
 DriverGetActiveDeviceID(
     VOID
@@ -90,13 +85,6 @@ DriverGetEmulatedContext(
     VOID
     );
 
-#include "unplug.h"
-
-PXENFILT_UNPLUG_CONTEXT
-DriverGetUnplugContext(
-    VOID
-    );
-
 typedef struct _XENFILT_FDO XENFILT_FDO, *PXENFILT_FDO;
 typedef struct _XENFILT_PDO XENFILT_PDO, *PXENFILT_PDO;
 
index 230fdf0f841c1a0014b42bb3f956dda3294e0e48..6fab34626947a3504f1a93b86a3cfe1e17f74615 100644 (file)
@@ -863,7 +863,6 @@ done:                                                               \
 }                                                                   \
 
 DEFINE_PDO_QUERY_INTERFACE(Emulated)
-DEFINE_PDO_QUERY_INTERFACE(Unplug)
 
 struct _INTERFACE_ENTRY {
     const GUID  *Guid;
@@ -876,7 +875,6 @@ struct _INTERFACE_ENTRY {
 
 struct _INTERFACE_ENTRY PdoInterfaceTable[] = {
     DEFINE_INTERFACE_ENTRY(EMULATED_INTERFACE, Emulated),
-    DEFINE_INTERFACE_ENTRY(UNPLUG_INTERFACE, Unplug),
     { NULL, NULL, NULL }
 };
 
diff --git a/src/xenfilt/unplug.c b/src/xenfilt/unplug.c
deleted file mode 100644 (file)
index 0c0948d..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-/* 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.
- */
-
-#include <ntddk.h>
-#include <ntstrsafe.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <xen.h>
-#include <version.h>
-
-#include "driver.h"
-#include "high.h"
-#include "registry.h"
-#include "unplug.h"
-#include "dbg_print.h"
-#include "assert.h"
-#include "util.h"
-
-struct _XENFILT_UNPLUG_CONTEXT {
-    KSPIN_LOCK  Lock;
-    LONG        References;
-    HIGH_LOCK   UnplugLock;
-    BOOLEAN     BlackListed;
-    BOOLEAN     UnplugDisks;
-    BOOLEAN     UnplugNics;
-    BOOLEAN     BootEmulated;
-};
-
-typedef enum _XENFILT_UNPLUG_TYPE {
-    XENFILT_UNPLUG_DISKS = 0,
-    XENFILT_UNPLUG_NICS
-} XENFILT_UNPLUG_TYPE, *PXENFILT_UNPLUG_TYPE;
-
-#define XENFILT_UNPLUG_TAG  'LPNU'
-
-static FORCEINLINE PVOID
-__UnplugAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocatePoolWithTag(NonPagedPool, Length, XENFILT_UNPLUG_TAG);
-}
-
-static FORCEINLINE VOID
-__UnplugFree(
-    IN  PVOID   Buffer
-    )
-{
-    ExFreePoolWithTag(Buffer, XENFILT_UNPLUG_TAG);
-}
-
-static VOID
-UnplugGetFlags(
-    IN  PXENFILT_UNPLUG_CONTEXT Context
-    )
-{
-    HANDLE                      Key;
-    DWORD                       Value;
-    NTSTATUS                    status;
-
-    Context->BootEmulated = FALSE;
-
-    Key = DriverGetParametersKey();
-
-    status = RegistryQueryDwordValue(Key,
-                                     "BootEmulated",
-                                     &Value);
-    if (NT_SUCCESS(status)) {
-        LogPrintf(LOG_LEVEL_WARNING,
-                  "UNPLUG: BOOT_EMULATED %d\n",
-                  Value);
-
-        Context->BootEmulated = (Value == 1) ? TRUE : FALSE;
-    }
-}
-
-static VOID
-UnplugRequest(
-    IN  PXENFILT_UNPLUG_CONTEXT Context,
-    IN  XENFILT_UNPLUG_TYPE     Type
-    )
-{
-    switch (Type) {
-    case XENFILT_UNPLUG_DISKS:
-        if (Context->BootEmulated) {
-#pragma prefast(suppress:28138)
-            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0004);
-
-            LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: AUX DISKS\n");
-        } else {
-#pragma prefast(suppress:28138)
-            WRITE_PORT_USHORT((PUSHORT)0x10, 0x0001);
-
-            LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: DISKS\n");
-        }
-        break;
-    case XENFILT_UNPLUG_NICS:
-#pragma prefast(suppress:28138)
-        WRITE_PORT_USHORT((PUSHORT)0x10, 0x0002);
-
-        LogPrintf(LOG_LEVEL_WARNING, "UNPLUG: NICS\n");
-        break;
-    default:
-        ASSERT(FALSE);
-    }
-}
-
-static NTSTATUS
-UnplugPreamble(
-    IN  PXENFILT_UNPLUG_CONTEXT Context
-    )
-{
-    USHORT                      Magic;
-    UCHAR                       Version;
-    NTSTATUS                    status;
-
-    // See docs/misc/hvm-emulated-unplug.markdown for details of the
-    // protocol in use here
-
-#pragma prefast(suppress:28138)
-    Magic = READ_PORT_USHORT((PUSHORT)0x10);
-    
-    if (Magic == 0xd249) {
-        Context->BlackListed = TRUE;
-        goto done;
-    }
-
-    status = STATUS_NOT_SUPPORTED;
-    if (Magic != 0x49d2)
-        goto fail1;
-
-#pragma prefast(suppress:28138)
-    Version = READ_PORT_UCHAR((PUCHAR)0x12);
-    if (Version != 0) {
-#pragma prefast(suppress:28138)
-        WRITE_PORT_USHORT((PUSHORT)0x12, 0xFFFF);   // FIXME
-
-#pragma prefast(suppress:28138)
-        WRITE_PORT_ULONG((PULONG)0x10, 
-                         (MAJOR_VERSION << 16) |
-                         (MINOR_VERSION << 8) |
-                         MICRO_VERSION);
-
-#pragma prefast(suppress:28138)
-        Magic = READ_PORT_USHORT((PUSHORT)0x10);
-        if (Magic == 0xd249)
-            Context->BlackListed = TRUE;
-    }
-
-done:
-    LogPrintf(LOG_LEVEL_WARNING,
-              "UNPLUG: PRE-AMBLE (DRIVERS %s)\n",
-              (Context->BlackListed) ? "BLACKLISTED" : "NOT BLACKLISTED");
-
-    return STATUS_SUCCESS;
-
-fail1:
-    return status;
-}
-
-#define HKEY_LOCAL_MACHINE  "\\Registry\\Machine"
-#define SERVICES_KEY        HKEY_LOCAL_MACHINE "\\SYSTEM\\CurrentControlSet\\Services"
-
-static VOID
-UnplugCheckForPVDisks(
-    IN  PXENFILT_UNPLUG_CONTEXT Context
-    )
-{
-    HANDLE                      UnplugKey;
-    PANSI_STRING                ServiceNames;
-    ULONG                       Count;
-    ULONG                       Index;
-    KIRQL                       Irql;
-    NTSTATUS                    status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    UnplugKey = DriverGetUnplugKey();
-
-    ServiceNames = NULL;
-
-    status = RegistryQuerySzValue(UnplugKey,
-                                  "DISKS",
-                                  &ServiceNames);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Count = 0;
-    for (Index = 0; ServiceNames[Index].Buffer != NULL; Index++)
-        if (_stricmp(ServiceNames[Index].Buffer, "XENVBD") == 0)
-            Count++;
-
-    if (Count < 1)
-        goto done;
-
-    AcquireHighLock(&Context->UnplugLock, &Irql);
-    Context->UnplugDisks = TRUE;
-    ReleaseHighLock(&Context->UnplugLock, Irql);
-
-done:
-    Info("%s\n", (Context->UnplugDisks) ? "PRESENT" : "NOT PRESENT");
-
-    if (ServiceNames != NULL)
-        RegistryFreeSzValue(ServiceNames);
-}
-
-static VOID
-UnplugCheckForPVNics(
-    IN  PXENFILT_UNPLUG_CONTEXT Context
-    )
-{
-    HANDLE                      UnplugKey;
-    PANSI_STRING                ServiceNames;
-    ULONG                       Count;
-    ULONG                       Index;
-    KIRQL                       Irql;
-    NTSTATUS                    status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    UnplugKey = DriverGetUnplugKey();
-
-    ServiceNames = NULL;
-
-    status = RegistryQuerySzValue(UnplugKey,
-                                  "NICS",
-                                  &ServiceNames);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Count = 0;
-    for (Index = 0; ServiceNames[Index].Buffer != NULL; Index++)
-        if (_stricmp(ServiceNames[Index].Buffer, "XENVIF") == 0 ||
-            _stricmp(ServiceNames[Index].Buffer, "XENNET") == 0)
-            Count++;
-
-    if (Count < 2)
-        goto done;
-
-    AcquireHighLock(&Context->UnplugLock, &Irql);
-    Context->UnplugNics = TRUE;
-    ReleaseHighLock(&Context->UnplugLock, Irql);
-
-done:
-    Info("%s\n", (Context->UnplugNics) ? "PRESENT" : "NOT PRESENT");
-
-    if (ServiceNames != NULL)
-        RegistryFreeSzValue(ServiceNames);
-}
-
-static VOID
-UnplugReplay(
-    IN  PINTERFACE          Interface
-    )
-{
-    PXENFILT_UNPLUG_CONTEXT Context = Interface->Context;
-    KIRQL                   Irql;
-    NTSTATUS                status;
-
-    AcquireHighLock(&Context->UnplugLock, &Irql);
-
-    status = UnplugPreamble(Context);
-    ASSERT(NT_SUCCESS(status));
-
-    if (Context->UnplugDisks)
-        UnplugRequest(Context, XENFILT_UNPLUG_DISKS);
-
-    if (Context->UnplugNics)
-        UnplugRequest(Context, XENFILT_UNPLUG_NICS);
-    
-    ReleaseHighLock(&Context->UnplugLock, Irql);
-}
-
-NTSTATUS
-UnplugAcquire(
-    IN  PINTERFACE          Interface
-    )
-{
-    PXENFILT_UNPLUG_CONTEXT Context = Interface->Context;
-    KIRQL                   Irql;
-    NTSTATUS                status;
-
-    KeAcquireSpinLock(&Context->Lock, &Irql);
-
-    if (Context->References++ != 0)
-        goto done;
-
-    Trace("====>\n");
-
-    (VOID)__AcquireHighLock(&Context->UnplugLock);
-
-    status = UnplugPreamble(Context);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    if (Context->UnplugDisks)
-        UnplugRequest(Context, XENFILT_UNPLUG_DISKS);
-
-    if (Context->UnplugNics)
-        UnplugRequest(Context, XENFILT_UNPLUG_NICS);
-    
-    ReleaseHighLock(&Context->UnplugLock, DISPATCH_LEVEL);
-
-    Trace("<====\n");
-
-done:
-    KeReleaseSpinLock(&Context->Lock, Irql);
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    ReleaseHighLock(&Context->UnplugLock, DISPATCH_LEVEL);
-
-    KeReleaseSpinLock(&Context->Lock, Irql);
-
-    return status;
-}
-
-VOID
-UnplugRelease(
-    IN  PINTERFACE              Interface
-    )
-{
-    PXENFILT_UNPLUG_CONTEXT     Context = Interface->Context;
-    KIRQL                       Irql;
-
-    KeAcquireSpinLock(&Context->Lock, &Irql);
-
-    if (--Context->References > 0)
-        goto done;
-
-    Trace("====>\n");
-
-    Context->BlackListed = FALSE;
-
-    Trace("<====\n");
-
-done:
-    KeReleaseSpinLock(&Context->Lock, Irql);
-}
-
-static struct _XENFILT_UNPLUG_INTERFACE_V1 UnplugInterfaceVersion1 = {
-    { sizeof (struct _XENFILT_UNPLUG_INTERFACE_V1), 1, NULL, NULL, NULL },
-    UnplugAcquire,
-    UnplugRelease,
-    UnplugReplay
-};
-                     
-NTSTATUS
-UnplugInitialize(
-    OUT PXENFILT_UNPLUG_CONTEXT *Context
-    )
-{
-    NTSTATUS                    status;
-
-    Trace("====>\n");
-
-    *Context = __UnplugAllocate(sizeof (XENFILT_UNPLUG_CONTEXT));
-
-    status = STATUS_NO_MEMORY;
-    if (*Context == NULL)
-        goto fail1;
-
-    UnplugCheckForPVDisks(*Context);
-    UnplugCheckForPVNics(*Context);
-    UnplugGetFlags(*Context);
-
-    KeInitializeSpinLock(&(*Context)->Lock);
-    InitializeHighLock(&(*Context)->UnplugLock);
-
-    Trace("<====\n");
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-NTSTATUS
-UnplugGetInterface(
-    IN      PXENFILT_UNPLUG_CONTEXT Context,
-    IN      ULONG                   Version,
-    IN OUT  PINTERFACE              Interface,
-    IN      ULONG                   Size
-    )
-{
-    NTSTATUS                        status;
-
-    ASSERT(Context != NULL);
-
-    switch (Version) {
-    case 1: {
-        struct _XENFILT_UNPLUG_INTERFACE_V1 *UnplugInterface;
-
-        UnplugInterface = (struct _XENFILT_UNPLUG_INTERFACE_V1 *)Interface;
-
-        status = STATUS_BUFFER_OVERFLOW;
-        if (Size < sizeof (struct _XENFILT_UNPLUG_INTERFACE_V1))
-            break;
-
-        *UnplugInterface = UnplugInterfaceVersion1;
-
-        ASSERT3U(Interface->Version, ==, Version);
-        Interface->Context = Context;
-
-        status = STATUS_SUCCESS;
-        break;
-    }
-    default:
-        status = STATUS_NOT_SUPPORTED;
-        break;
-    }
-
-    return status;
-}   
-
-VOID
-UnplugTeardown(
-    IN  PXENFILT_UNPLUG_CONTEXT Context
-    )
-{
-    Trace("====>\n");
-
-    Context->BootEmulated = FALSE;
-    Context->UnplugNics = FALSE;
-    Context->UnplugDisks = FALSE;
-
-    RtlZeroMemory(&Context->UnplugLock, sizeof (HIGH_LOCK));
-    RtlZeroMemory(&Context->Lock, sizeof (KSPIN_LOCK));
-
-    ASSERT(IsZeroMemory(Context, sizeof (XENFILT_UNPLUG_CONTEXT)));
-    __UnplugFree(Context);
-
-    Trace("<====\n");
-}
diff --git a/src/xenfilt/unplug.h b/src/xenfilt/unplug.h
deleted file mode 100644 (file)
index 191d8e2..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* 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.
- */
-
-#ifndef _XENFILT_UNPLUG_H
-#define _XENFILT_UNPLUG_H
-
-#include <ntddk.h>
-#include <xen.h>
-#include <unplug_interface.h>
-
-typedef struct _XENFILT_UNPLUG_CONTEXT  XENFILT_UNPLUG_CONTEXT, *PXENFILT_UNPLUG_CONTEXT;
-
-extern NTSTATUS
-UnplugInitialize(
-    OUT PXENFILT_UNPLUG_CONTEXT *Context
-    );
-
-extern NTSTATUS
-UnplugGetInterface(
-    IN      PXENFILT_UNPLUG_CONTEXT Context,
-    IN      ULONG                   Version,
-    IN OUT  PINTERFACE              Interface,
-    IN      ULONG                   Size
-    );
-
-extern VOID
-UnplugTeardown(
-    IN  PXENFILT_UNPLUG_CONTEXT Context
-    );
-
-#endif  // _XENFILT_UNPLUG_H
index df966af4863854ddc9bf6820c17a44803ca25684..0ffb844a4e8c1aea6abc76539cc8d8e633e582ac 100644 (file)
@@ -90,6 +90,7 @@
     <ClCompile Include="..\..\src\xen\process.c" />
     <ClCompile Include="..\..\src\xen\acpi.c" />
     <ClCompile Include="..\..\src\xen\system.c" />
+    <ClCompile Include="..\..\src\xen\unplug.c" />
   </ItemGroup>
   <ItemGroup>
     <MASM Include="..\..\src\xen\amd64\hypercall_thunk.asm">
index ab78a02f58e6be82a92dbf64ffab444228b7d00c..82f0dbf98d900fece999385b56aa5c1f7e178f51 100644 (file)
@@ -94,6 +94,7 @@
     <ClCompile Include="..\..\src\xenbus\balloon.c" />
     <ClCompile Include="..\..\src\xenbus\cache.c" />
     <ClCompile Include="..\..\src\xenbus\hash_table.c" />
+    <ClCompile Include="..\..\src\xenbus\unplug.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\xenbus\xenbus.rc" />
index 34efda4032ea72df75334818505b0aface373fbc..4d5747d7d99421324bced4d9b15c9294f05fd762 100644 (file)
@@ -68,7 +68,6 @@
   <ItemGroup>
     <ClCompile Include="../../src/common/registry.c" />
     <ClCompile Include="../../src/xenfilt/driver.c" />
-    <ClCompile Include="../../src/xenfilt/unplug.c" />
     <ClCompile Include="../../src/xenfilt/emulated.c" />
     <ClCompile Include="../../src/xenfilt/fdo.c" />
     <ClCompile Include="../../src/xenfilt/pdo.c" />
index cd4045296700147cec26a80ccd79e343f4100b2b..9330d8d53237d6551e890069e98cea7b34100a47 100644 (file)
@@ -93,6 +93,7 @@
     <ClCompile Include="..\..\src\xen\process.c" />
     <ClCompile Include="..\..\src\xen\acpi.c" />
     <ClCompile Include="..\..\src\xen\system.c" />
+    <ClCompile Include="..\..\src\xen\unplug.c" />
   </ItemGroup>
   <ItemGroup>
     <MASM Include="..\..\src\xen\amd64\hypercall_thunk.asm">
index ca486c9242b1a559e733f3003a992c8c77a5ff4b..fb0b0dda91d124231732c2d84b92438118ba941c 100644 (file)
@@ -97,6 +97,7 @@
     <ClCompile Include="..\..\src\xenbus\balloon.c" />
     <ClCompile Include="..\..\src\xenbus\cache.c" />
     <ClCompile Include="..\..\src\xenbus\hash_table.c" />
+    <ClCompile Include="..\..\src\xenbus\unplug.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\xenbus\xenbus.rc" />
index db4a4378bd07f41b8c2ff930c5934c843c6504a0..4f749b11511d044656fbc45b67ea0ad946433c81 100644 (file)
@@ -71,7 +71,6 @@
   <ItemGroup>
     <ClCompile Include="../../src/common/registry.c" />
     <ClCompile Include="../../src/xenfilt/driver.c" />
-    <ClCompile Include="../../src/xenfilt/unplug.c" />
     <ClCompile Include="../../src/xenfilt/emulated.c" />
     <ClCompile Include="../../src/xenfilt/fdo.c" />
     <ClCompile Include="../../src/xenfilt/pdo.c" />