|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XENBUS PATCH v6 08/11] Add EMULATED v3
Allow querying the current active device's forced-activation status by
calling EmulatedIsDevicePresent with DeviceID=NULL.
Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx>
---
include/emulated_interface.h | 51 +++++++++++++---
include/revision.h | 3 +-
src/xenfilt/emulated.c | 115 ++++++++++++++++++++++++++++-------
src/xenfilt/emulated.h | 13 ++--
src/xenfilt/fdo.c | 6 +-
src/xenfilt/pdo.c | 1 +
6 files changed, 148 insertions(+), 41 deletions(-)
diff --git a/include/emulated_interface.h b/include/emulated_interface.h
index 86a9e06..7d47707 100644
--- a/include/emulated_interface.h
+++ b/include/emulated_interface.h
@@ -72,7 +72,7 @@ typedef VOID
_In_ PINTERFACE Interface
);
-/*! \typedef XENFILT_EMULATED_IS_DEVICE_PRESENT
+/*! \typedef XENFILT_EMULATED_IS_DEVICE_PRESENT_V1
\brief Determine whether a given device is present in the VM
\param Interface The interface header
@@ -83,12 +83,33 @@ typedef VOID
FALSE if it is not
*/
typedef BOOLEAN
-(*XENFILT_EMULATED_IS_DEVICE_PRESENT)(
+(*XENFILT_EMULATED_IS_DEVICE_PRESENT_V1)(
_In_ PVOID Context,
_In_ PSTR DeviceID,
_In_opt_ PSTR InstanceID
);
+/*! \typedef XENFILT_EMULATED_IS_DEVICE_PRESENT
+ \brief Determine whether a given device is present in the VM
+
+ \param Interface The interface header
+ \param DeviceID The DeviceID of the device, or NULL to query the force-
+ activated device
+ \param InstanceID The (un-prefixed) InstanceID of the device or
+ NULL to match any device instance
+ \param IsForceActivated If the device was force-activated,
force-deactivated
+ or otherwise.
+ \return TRUE if the specified device is present in the system or
+ FALSE if it is not
+*/
+typedef BOOLEAN
+(*XENFILT_EMULATED_IS_DEVICE_PRESENT)(
+ _In_ PVOID Context,
+ _In_opt_ PSTR DeviceID,
+ _In_opt_ PSTR InstanceID,
+ _Out_opt_ PXENBUS_EMULATED_ACTIVATION_STATUS IsForceActivated
+ );
+
typedef BOOLEAN
(*XENFILT_EMULATED_IS_DISK_PRESENT_V1)(
_In_ PVOID Context,
@@ -120,11 +141,11 @@ DEFINE_GUID(GUID_XENFILT_EMULATED_INTERFACE,
\ingroup interfaces
*/
struct _XENFILT_EMULATED_INTERFACE_V1 {
- INTERFACE Interface;
- XENFILT_EMULATED_ACQUIRE EmulatedAcquire;
- XENFILT_EMULATED_RELEASE EmulatedRelease;
- XENFILT_EMULATED_IS_DEVICE_PRESENT EmulatedIsDevicePresent;
- XENFILT_EMULATED_IS_DISK_PRESENT_V1 EmulatedIsDiskPresentVersion1;
+ INTERFACE Interface;
+ XENFILT_EMULATED_ACQUIRE EmulatedAcquire;
+ XENFILT_EMULATED_RELEASE EmulatedRelease;
+ XENFILT_EMULATED_IS_DEVICE_PRESENT_V1 EmulatedIsDevicePresentVersion1;
+ XENFILT_EMULATED_IS_DISK_PRESENT_V1 EmulatedIsDiskPresentVersion1;
};
/*! \struct _XENFILT_EMULATED_INTERFACE_V2
@@ -132,6 +153,18 @@ struct _XENFILT_EMULATED_INTERFACE_V1 {
\ingroup interfaces
*/
struct _XENFILT_EMULATED_INTERFACE_V2 {
+ INTERFACE Interface;
+ XENFILT_EMULATED_ACQUIRE EmulatedAcquire;
+ XENFILT_EMULATED_RELEASE EmulatedRelease;
+ XENFILT_EMULATED_IS_DEVICE_PRESENT_V1 EmulatedIsDevicePresentVersion1;
+ XENFILT_EMULATED_IS_DISK_PRESENT EmulatedIsDiskPresent;
+};
+
+/*! \struct _XENFILT_EMULATED_INTERFACE_V3
+ \brief EMULATED interface version 3
+ \ingroup interfaces
+*/
+struct _XENFILT_EMULATED_INTERFACE_V3 {
INTERFACE Interface;
XENFILT_EMULATED_ACQUIRE EmulatedAcquire;
XENFILT_EMULATED_RELEASE EmulatedRelease;
@@ -139,7 +172,7 @@ struct _XENFILT_EMULATED_INTERFACE_V2 {
XENFILT_EMULATED_IS_DISK_PRESENT EmulatedIsDiskPresent;
};
-typedef struct _XENFILT_EMULATED_INTERFACE_V2 XENFILT_EMULATED_INTERFACE,
*PXENFILT_EMULATED_INTERFACE;
+typedef struct _XENFILT_EMULATED_INTERFACE_V3 XENFILT_EMULATED_INTERFACE,
*PXENFILT_EMULATED_INTERFACE;
/*! \def XENFILT_EMULATED
\brief Macro at assist in method invocation
@@ -150,6 +183,6 @@ typedef struct _XENFILT_EMULATED_INTERFACE_V2
XENFILT_EMULATED_INTERFACE, *PXENF
#endif // _WINDLL
#define XENFILT_EMULATED_INTERFACE_VERSION_MIN 1
-#define XENFILT_EMULATED_INTERFACE_VERSION_MAX 2
+#define XENFILT_EMULATED_INTERFACE_VERSION_MAX 3
#endif // _XENFILT_EMULATED_INTERFACE_H
diff --git a/include/revision.h b/include/revision.h
index e9e62e6..a63e550 100644
--- a/include/revision.h
+++ b/include/revision.h
@@ -51,6 +51,7 @@
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(0x0900000B, 1, 4, 9, 1, 2, 1, 2, 4, 3, 1, 2)
+ DEFINE_REVISION(0x0900000B, 1, 4, 9, 1, 2, 1, 2, 4, 3, 1, 2), \
+ DEFINE_REVISION(0x0900000C, 1, 4, 9, 1, 2, 1, 2, 4, 3, 1, 3)
#endif // _REVISION_H
diff --git a/src/xenfilt/emulated.c b/src/xenfilt/emulated.c
index 9065364..4205cc5 100644
--- a/src/xenfilt/emulated.c
+++ b/src/xenfilt/emulated.c
@@ -45,9 +45,10 @@
#define MAXNAMELEN 128
typedef struct _XENFILT_EMULATED_DEVICE_DATA {
- CHAR DeviceID[MAXNAMELEN];
- CHAR InstanceID[MAXNAMELEN];
- CHAR CompatibleID[MAXNAMELEN];
+ CHAR DeviceID[MAXNAMELEN];
+ CHAR InstanceID[MAXNAMELEN];
+ CHAR CompatibleID[MAXNAMELEN];
+ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate;
} XENFILT_EMULATED_DEVICE_DATA, *PXENFILT_EMULATED_DEVICE_DATA;
typedef struct _XENFILT_EMULATED_DISK_DATA {
@@ -222,16 +223,17 @@ fail1:
NTSTATUS
EmulatedAddObject(
- _In_ PXENFILT_EMULATED_CONTEXT Context,
- _In_ PSTR DeviceID,
- _In_ PSTR InstanceID,
- _In_opt_ PSTR CompatibleIDs,
- _In_ XENFILT_EMULATED_OBJECT_TYPE Type,
- _Outptr_ PXENFILT_EMULATED_OBJECT *EmulatedObject
+ _In_ PXENFILT_EMULATED_CONTEXT Context,
+ _In_ PSTR DeviceID,
+ _In_ PSTR InstanceID,
+ _In_opt_ PSTR CompatibleIDs,
+ _In_ XENFILT_EMULATED_OBJECT_TYPE Type,
+ _In_ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate,
+ _Outptr_ PXENFILT_EMULATED_OBJECT *EmulatedObject
)
{
- KIRQL Irql;
- NTSTATUS status;
+ KIRQL Irql;
+ NTSTATUS status;
Trace("====>\n");
@@ -267,6 +269,8 @@ EmulatedAddObject(
goto fail2;
(*EmulatedObject)->Type = Type;
+ if (Type == XENFILT_EMULATED_OBJECT_TYPE_PCI)
+ (*EmulatedObject)->Data.Device.ForceActivate = ForceActivate;
KeAcquireSpinLock(&Context->Lock, &Irql);
InsertTailList(&Context->List, &(*EmulatedObject)->ListEntry);
@@ -302,36 +306,66 @@ EmulatedRemoveObject(
__EmulatedFree(EmulatedObject);
}
+static inline BOOLEAN
+EmulatedDeviceMatchesDeviceID(
+ _In_ PXENFILT_EMULATED_DEVICE_DATA Device,
+ _In_opt_ PSTR DeviceID
+ )
+{
+ // EmulatedIsDevicePresent: DeviceID == NULL matches the force-activated
device
+ if (DeviceID)
+ return _stricmp(DeviceID, Device->DeviceID) == 0;
+ else
+ return Device->ForceActivate == XENBUS_EMULATED_FORCE_ACTIVATED;
+}
+
+static inline BOOLEAN
+EmulatedDeviceMatchesInstanceID(
+ _In_ PXENFILT_EMULATED_DEVICE_DATA Device,
+ _In_opt_ PSTR InstanceID
+ )
+{
+ // EmulatedIsDevicePresent: InstanceID == NULL matches any device instance
+ return InstanceID == NULL || _stricmp(InstanceID, Device->InstanceID) == 0;
+}
+
static BOOLEAN
EmulatedIsDevicePresent(
- _In_ PINTERFACE Interface,
- _In_ PSTR DeviceID,
- _In_opt_ PSTR InstanceID
+ _In_ PINTERFACE Interface,
+ _In_opt_ PSTR DeviceID,
+ _In_opt_ PSTR InstanceID,
+ _Out_opt_ PXENBUS_EMULATED_ACTIVATION_STATUS IsForceActivated
)
{
- PXENFILT_EMULATED_CONTEXT Context = Interface->Context;
- KIRQL Irql;
- PLIST_ENTRY ListEntry;
+ PXENFILT_EMULATED_CONTEXT Context =
Interface->Context;
+ KIRQL Irql;
+ PLIST_ENTRY ListEntry;
Trace("====> (%s %s)\n",
- DeviceID,
+ (DeviceID != NULL) ? DeviceID : "ACTIVE",
(InstanceID != NULL) ? InstanceID : "ANY");
+ if (IsForceActivated)
+ *IsForceActivated = XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+
KeAcquireSpinLock(&Context->Lock, &Irql);
ListEntry = Context->List.Flink;
while (ListEntry != &Context->List) {
- PXENFILT_EMULATED_OBJECT EmulatedObject;
+ PXENFILT_EMULATED_OBJECT EmulatedObject;
+ PXENFILT_EMULATED_DEVICE_DATA Device;
EmulatedObject = CONTAINING_RECORD(ListEntry,
XENFILT_EMULATED_OBJECT,
ListEntry);
+ Device = &EmulatedObject->Data.Device;
if (EmulatedObject->Type == XENFILT_EMULATED_OBJECT_TYPE_PCI &&
- _stricmp(DeviceID, EmulatedObject->Data.Device.DeviceID) == 0 &&
- (InstanceID == NULL ||
- _stricmp(InstanceID, EmulatedObject->Data.Device.InstanceID) ==
0)) {
+ EmulatedDeviceMatchesDeviceID(Device, DeviceID) &&
+ EmulatedDeviceMatchesInstanceID(Device, InstanceID)) {
Trace("FOUND\n");
+ if (IsForceActivated)
+ *IsForceActivated = Device->ForceActivate;
break;
}
@@ -345,6 +379,16 @@ EmulatedIsDevicePresent(
return (ListEntry != &Context->List) ? TRUE : FALSE;
}
+static BOOLEAN
+EmulatedIsDevicePresentVersion1(
+ _In_ PINTERFACE Interface,
+ _In_ PSTR DeviceID,
+ _In_opt_ PSTR InstanceID
+ )
+{
+ return EmulatedIsDevicePresent(Interface, DeviceID, InstanceID, NULL);
+}
+
static BOOLEAN
EmulatedIsDiskPresent(
_In_ PINTERFACE Interface,
@@ -454,7 +498,7 @@ static struct _XENFILT_EMULATED_INTERFACE_V1
EmulatedInterfaceVersion1 = {
{ sizeof (struct _XENFILT_EMULATED_INTERFACE_V1), 1, NULL, NULL, NULL },
EmulatedAcquire,
EmulatedRelease,
- EmulatedIsDevicePresent,
+ EmulatedIsDevicePresentVersion1,
EmulatedIsDiskPresentVersion1
};
@@ -462,6 +506,14 @@ static struct _XENFILT_EMULATED_INTERFACE_V2
EmulatedInterfaceVersion2 = {
{ sizeof (struct _XENFILT_EMULATED_INTERFACE_V2), 2, NULL, NULL, NULL },
EmulatedAcquire,
EmulatedRelease,
+ EmulatedIsDevicePresentVersion1,
+ EmulatedIsDiskPresent
+};
+
+static struct _XENFILT_EMULATED_INTERFACE_V3 EmulatedInterfaceVersion3 = {
+ { sizeof (struct _XENFILT_EMULATED_INTERFACE_V3), 3, NULL, NULL, NULL },
+ EmulatedAcquire,
+ EmulatedRelease,
EmulatedIsDevicePresent,
EmulatedIsDiskPresent
};
@@ -541,6 +593,23 @@ EmulatedGetInterface(
status = STATUS_SUCCESS;
break;
}
+ case 3: {
+ struct _XENFILT_EMULATED_INTERFACE_V3 *EmulatedInterface;
+
+ EmulatedInterface = (struct _XENFILT_EMULATED_INTERFACE_V3 *)Interface;
+
+ status = STATUS_BUFFER_OVERFLOW;
+ if (Size < sizeof (struct _XENFILT_EMULATED_INTERFACE_V3))
+ break;
+
+ *EmulatedInterface = EmulatedInterfaceVersion3;
+
+ ASSERT3U(Interface->Version, ==, Version);
+ Interface->Context = Context;
+
+ status = STATUS_SUCCESS;
+ break;
+ }
default:
status = STATUS_NOT_SUPPORTED;
break;
diff --git a/src/xenfilt/emulated.h b/src/xenfilt/emulated.h
index 9b02268..c60020f 100644
--- a/src/xenfilt/emulated.h
+++ b/src/xenfilt/emulated.h
@@ -67,12 +67,13 @@ EmulatedTeardown(
extern NTSTATUS
EmulatedAddObject(
- _In_ PXENFILT_EMULATED_CONTEXT Context,
- _In_ PSTR DeviceID,
- _In_ PSTR InstanceID,
- _In_opt_ PSTR CompatibleIDs,
- _In_ XENFILT_EMULATED_OBJECT_TYPE Type,
- _Outptr_ PXENFILT_EMULATED_OBJECT *EmulatedObject
+ _In_ PXENFILT_EMULATED_CONTEXT Context,
+ _In_ PSTR DeviceID,
+ _In_ PSTR InstanceID,
+ _In_opt_ PSTR CompatibleIDs,
+ _In_ XENFILT_EMULATED_OBJECT_TYPE Type,
+ _In_ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate,
+ _Outptr_ PXENFILT_EMULATED_OBJECT *EmulatedObject
);
extern VOID
diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c
index 87302bb..ad57c95 100644
--- a/src/xenfilt/fdo.c
+++ b/src/xenfilt/fdo.c
@@ -478,13 +478,15 @@ FdoEnumerate(
for (Index = 0; Index < Count; Index++) {
#pragma warning(suppress:6385) // Reading invalid data from
'PhysicalDeviceObject'
if (PhysicalDeviceObject[Index] != NULL) {
- XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate =
-
XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate;
if (Precedence > 0)
ForceActivate = Index == ActiveIndex ?
XENBUS_EMULATED_FORCE_ACTIVATED :
XENBUS_EMULATED_FORCE_DEACTIVATED;
+ else
+ ForceActivate = XENBUS_EMULATED_ACTIVATE_NEUTRAL;
+
(VOID) PdoCreate(Fdo,
PhysicalDeviceObject[Index],
Fdo->Type,
diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c
index 58c9ef0..5327230 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -1701,6 +1701,7 @@ PdoCreate(
__PdoGetInstanceID(Pdo),
CompatibleIDs,
__PdoGetType(Pdo),
+ ForceActivate,
&Pdo->EmulatedObject);
if (!NT_SUCCESS(status))
goto fail5;
--
2.50.1.windows.1
Ngoc Tu Dinh | Vates XCP-ng Developer
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |