[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v5] 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 |