DEFINE_REVISION(0x09000007, 1, 3, 8, 1, 2, 1, 2, 4, 1, 1, 2), \
DEFINE_REVISION(0x09000008, 1, 3, 9, 1, 2, 1, 2, 4, 1, 1, 2), \
DEFINE_REVISION(0x09000009, 1, 4, 9, 1, 2, 1, 2, 4, 1, 1, 2), \
- DEFINE_REVISION(0x0900000A, 1, 4, 9, 1, 2, 1, 2, 4, 2, 1, 2)
+ DEFINE_REVISION(0x0900000A, 1, 4, 9, 1, 2, 1, 2, 4, 2, 1, 2), \
+ DEFINE_REVISION(0x0900000B, 1, 4, 9, 1, 2, 1, 2, 4, 3, 1, 2)
#endif // _REVISION_H
IN XENBUS_UNPLUG_DEVICE_TYPE Type
);
+/*! \typedef XENBUS_UNPLUG_BOOT_EMULATED
+ \brief Should the boot disk be emulated
+
+ \param Interface The interface header
+*/
+typedef BOOLEAN
+(*XENBUS_UNPLUG_BOOT_EMULATED)(
+ IN PINTERFACE Interface
+ );
+
+/*! \typedef XENBUS_UNPLUG_REBOOT
+ \brief Request a reboot to complete setup
+
+ \param Interface The interface header
+ \param Module The module name requesting a reboot
+*/
+typedef VOID
+(*XENBUS_UNPLUG_REBOOT)(
+ IN PINTERFACE Interface,
+ IN PCHAR Module
+ );
+
// {73db6517-3d06-4937-989f-199b7501e229}
DEFINE_GUID(GUID_XENBUS_UNPLUG_INTERFACE,
0x73db6517, 0x3d06, 0x4937, 0x98, 0x9f, 0x19, 0x9b, 0x75, 0x01, 0xe2, 0x29);
XENBUS_UNPLUG_IS_REQUESTED UnplugIsRequested;
};
-typedef struct _XENBUS_UNPLUG_INTERFACE_V2 XENBUS_UNPLUG_INTERFACE, *PXENBUS_UNPLUG_INTERFACE;
+/*! \struct _XENBUS_UNPLUG_INTERFACE_V3
+ \brief UNPLUG interface version 3
+ \ingroup interfaces
+*/
+struct _XENBUS_UNPLUG_INTERFACE_V3 {
+ INTERFACE Interface;
+ XENBUS_UNPLUG_ACQUIRE UnplugAcquire;
+ XENBUS_UNPLUG_RELEASE UnplugRelease;
+ XENBUS_UNPLUG_REQUEST UnplugRequest;
+ XENBUS_UNPLUG_IS_REQUESTED UnplugIsRequested;
+ XENBUS_UNPLUG_BOOT_EMULATED UnplugBootEmulated;
+ XENBUS_UNPLUG_REBOOT UnplugReboot;
+};
+
+typedef struct _XENBUS_UNPLUG_INTERFACE_V3 XENBUS_UNPLUG_INTERFACE, *PXENBUS_UNPLUG_INTERFACE;
/*! \def XENBUS_UNPLUG
\brief Macro at assist in method invocation
#endif // _WINDLL
#define XENBUS_UNPLUG_INTERFACE_VERSION_MIN 1
-#define XENBUS_UNPLUG_INTERFACE_VERSION_MAX 2
+#define XENBUS_UNPLUG_INTERFACE_VERSION_MAX 3
#endif // _XENBUS_UNPLUG_INTERFACE_H
#include "dbg_print.h"
#include "assert.h"
#include "util.h"
+#include "registry.h"
struct _XENBUS_UNPLUG_CONTEXT {
KSPIN_LOCK Lock;
return Requested;
}
+__drv_requiresIRQL(PASSIVE_LEVEL)
+static BOOLEAN
+UnplugBootEmulated(
+ IN PINTERFACE Interface
+ )
+{
+ PXENBUS_UNPLUG_CONTEXT Context = Interface->Context;
+ CHAR KeyName[] = "XEN:BOOT_EMULATED=";
+ PANSI_STRING Option;
+ PCHAR Value;
+ NTSTATUS status;
+ BOOLEAN BootEmulated;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ AcquireMutex(&Context->Mutex);
+
+ BootEmulated = FALSE;
+
+ status = ConfigQuerySystemStartOption(KeyName, &Option);
+ if (!NT_SUCCESS(status))
+ goto done;
+
+ Value = Option->Buffer + sizeof (KeyName) - 1;
+
+ if (strcmp(Value, "TRUE") == 0)
+ BootEmulated = TRUE;
+ else if (strcmp(Value, "FALSE") != 0)
+ Warning("UNRECOGNIZED VALUE OF %s: %s\n", KeyName, Value);
+
+ RegistryFreeSzValue(Option);
+
+done:
+ ReleaseMutex(&Context->Mutex);
+
+ return BootEmulated;
+}
+
+__drv_requiresIRQL(PASSIVE_LEVEL)
+static VOID
+UnplugReboot(
+ IN PINTERFACE Interface,
+ IN PCHAR Module
+ )
+{
+ PXENBUS_UNPLUG_CONTEXT Context = Interface->Context;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ AcquireMutex(&Context->Mutex);
+
+ ConfigRequestReboot(DriverGetParametersKey(), Module);
+
+ ReleaseMutex(&Context->Mutex);
+
+ return;
+}
+
static NTSTATUS
UnplugAcquire(
IN PINTERFACE Interface
UnplugIsRequested
};
+static struct _XENBUS_UNPLUG_INTERFACE_V3 UnplugInterfaceVersion3 = {
+ { sizeof (struct _XENBUS_UNPLUG_INTERFACE_V3), 3, NULL, NULL, NULL },
+ UnplugAcquire,
+ UnplugRelease,
+ UnplugRequest,
+ UnplugIsRequested,
+ UnplugBootEmulated,
+ UnplugReboot
+};
+
NTSTATUS
UnplugInitialize(
IN PXENBUS_FDO Fdo,
status = STATUS_SUCCESS;
break;
}
+ case 3: {
+ struct _XENBUS_UNPLUG_INTERFACE_V3 *UnplugInterface;
+
+ UnplugInterface = (struct _XENBUS_UNPLUG_INTERFACE_V3 *)Interface;
+
+ status = STATUS_BUFFER_OVERFLOW;
+ if (Size < sizeof (struct _XENBUS_UNPLUG_INTERFACE_V3))
+ break;
+
+ *UnplugInterface = UnplugInterfaceVersion3;
+
+ ASSERT3U(Interface->Version, ==, Version);
+ Interface->Context = Context;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
default:
status = STATUS_NOT_SUPPORTED;
break;