[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XENBUS PATCH v4 07/11] xenfilt: Add Xenbus device precedence mechanism
Define registry values in xenfilt\Parameters with the names being compatible IDs and values being numeric precedences. The Xenbus device with the highest precedence should always be activated over devices with lower precedence, ignoring Active* values. If a device is force-activated, get its IDs directly instead of via Active* values. Define XENBUS_EMULATED_ACTIVATION_STATUS in emulated_interface.h for latter use. Signed-off-by: Tu Dinh <ngoc-tu.dinh@xxxxxxxxxx> --- include/emulated_interface.h | 10 ++++++ src/xenfilt/driver.c | 59 ++++++++++++++++++++++++++++++++++ src/xenfilt/driver.h | 7 ++++ src/xenfilt/fdo.c | 28 +++++++++++++++- src/xenfilt/pdo.c | 62 ++++++++++++++++++++---------------- src/xenfilt/pdo.h | 7 ++-- 6 files changed, 141 insertions(+), 32 deletions(-) diff --git a/include/emulated_interface.h b/include/emulated_interface.h index ead9c14..86a9e06 100644 --- a/include/emulated_interface.h +++ b/include/emulated_interface.h @@ -42,6 +42,16 @@ #ifndef _WINDLL +/*! \typedef XENBUS_EMULATED_ACTIVATION_STATUS + \brief If the device was force-activated, force-deactivated or + otherwise. +*/ +typedef enum _XENBUS_EMULATED_ACTIVATION_STATUS { + XENBUS_EMULATED_ACTIVATE_NEUTRAL = 0, + XENBUS_EMULATED_FORCE_ACTIVATED = 1, + XENBUS_EMULATED_FORCE_DEACTIVATED = 2, +} XENBUS_EMULATED_ACTIVATION_STATUS, *PXENBUS_EMULATED_ACTIVATION_STATUS; + /*! \typedef XENFILT_EMULATED_ACQUIRE \brief Acquire a reference to the EMULATED interface diff --git a/src/xenfilt/driver.c b/src/xenfilt/driver.c index 16e4deb..4b69568 100644 --- a/src/xenfilt/driver.c +++ b/src/xenfilt/driver.c @@ -279,6 +279,65 @@ DriverGetActive( return __DriverGetActive(Key, Value); } +_On_failure_(_Post_satisfies_(*Precedence == 0)) +NTSTATUS +DriverGetPrecedence( + _In_ PDEVICE_OBJECT PhysicalDeviceObject, + _Out_ PULONG Precedence + ) +{ + HANDLE ParametersKey; + PSTR CompatibleIDs; + ULONG Index; + NTSTATUS status; + + status = RegistryOpenParametersKey(KEY_READ, &ParametersKey); + if (!NT_SUCCESS(status)) + goto fail1; + + status = DriverQueryId(PhysicalDeviceObject, + BusQueryCompatibleIDs, + &CompatibleIDs); + if (!NT_SUCCESS(status)) + goto fail2; + + Index = 0; + + do { + ULONG Length = (ULONG)strlen(&CompatibleIDs[Index]); + + if (Length == 0) + break; + + status = RegistryQueryDwordValue(ParametersKey, + &CompatibleIDs[Index], + Precedence); + if (NT_SUCCESS(status)) + goto done; + + Index += Length + 1; + } while (1); + + *Precedence = 0; + +done: + if (*Precedence) + Info("%s found precedence %lX\n", CompatibleIDs, *Precedence); + + ExFreePool(CompatibleIDs); + RegistryCloseKey(ParametersKey); + + return STATUS_SUCCESS; + +fail2: + RegistryCloseKey(ParametersKey); + +fail1: + *Precedence = 0; + + return status; +} + static BOOLEAN DriverIsActivePresent( VOID diff --git a/src/xenfilt/driver.h b/src/xenfilt/driver.h index 9c703c1..cf6a2d6 100644 --- a/src/xenfilt/driver.h +++ b/src/xenfilt/driver.h @@ -54,6 +54,13 @@ DriverGetActive( _Outptr_result_z_ PSTR *Value ); +_On_failure_(_Post_satisfies_(*Precedence == 0)) +extern NTSTATUS +DriverGetPrecedence( + _In_ PDEVICE_OBJECT PhysicalDeviceObject, + _Out_ PULONG Precedence + ); + typedef enum _XENFILT_FILTER_STATE { XENFILT_FILTER_ENABLED = 0, XENFILT_FILTER_PENDING, diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c index 594da4a..87302bb 100644 --- a/src/xenfilt/fdo.c +++ b/src/xenfilt/fdo.c @@ -404,6 +404,8 @@ FdoEnumerate( ULONG Count; PLIST_ENTRY ListEntry; ULONG Index; + ULONG ActiveIndex; + ULONG Precedence; NTSTATUS status; Count = Relations->Count; @@ -458,11 +460,35 @@ FdoEnumerate( ListEntry = Next; } + ActiveIndex = Precedence = 0; + for (Index = 0; Index < Count; Index++) { + ULONG ThisPrecedence; + + if (PhysicalDeviceObject[Index] != NULL) { + status = DriverGetPrecedence(PhysicalDeviceObject[Index], + &ThisPrecedence); + if (ThisPrecedence > Precedence) { + ActiveIndex = Index; + Precedence = ThisPrecedence; + } + } + } + // Walk the list and create PDO filters for any new devices for (Index = 0; Index < Count; Index++) { #pragma warning(suppress:6385) // Reading invalid data from 'PhysicalDeviceObject' if (PhysicalDeviceObject[Index] != NULL) { - (VOID) PdoCreate(Fdo, PhysicalDeviceObject[Index], Fdo->Type); + XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate = + XENBUS_EMULATED_ACTIVATE_NEUTRAL; + + if (Precedence > 0) + ForceActivate = Index == ActiveIndex ? + XENBUS_EMULATED_FORCE_ACTIVATED : + XENBUS_EMULATED_FORCE_DEACTIVATED; + (VOID) PdoCreate(Fdo, + PhysicalDeviceObject[Index], + Fdo->Type, + ForceActivate); ObDereferenceObject(PhysicalDeviceObject[Index]); } } diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c index 4f40c4f..58c9ef0 100644 --- a/src/xenfilt/pdo.c +++ b/src/xenfilt/pdo.c @@ -249,15 +249,16 @@ __PdoGetFdo( static NTSTATUS PdoSetDeviceInformation( - _In_ PXENFILT_PDO Pdo + _In_ PXENFILT_PDO Pdo, + _In_ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate ) { - PXENFILT_DX Dx = Pdo->Dx; - PSTR DeviceID; - PSTR ActiveDeviceID; - PSTR InstanceID; - PSTR LocationInformation; - NTSTATUS status; + PXENFILT_DX Dx = Pdo->Dx; + PSTR DeviceID; + PSTR ActiveDeviceID; + PSTR InstanceID; + PSTR LocationInformation; + NTSTATUS status; status = DriverQueryId(Pdo->LowerDeviceObject, BusQueryDeviceID, @@ -265,19 +266,23 @@ PdoSetDeviceInformation( if (!NT_SUCCESS(status)) goto fail1; - status = DriverGetActive("DeviceID", - &ActiveDeviceID); - if (NT_SUCCESS(status)) { - Pdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ? - TRUE : - FALSE; - - ExFreePool(ActiveDeviceID); + if (ForceActivate != XENBUS_EMULATED_ACTIVATE_NEUTRAL) { + Pdo->Active = ForceActivate == XENBUS_EMULATED_FORCE_ACTIVATED; } else { - Pdo->Active = FALSE; + status = DriverGetActive("DeviceID", + &ActiveDeviceID); + if (NT_SUCCESS(status)) { + Pdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ? + TRUE : + FALSE; + + ExFreePool(ActiveDeviceID); + } else { + Pdo->Active = FALSE; + } } - if (Pdo->Active) { + if (Pdo->Active && ForceActivate == XENBUS_EMULATED_ACTIVATE_NEUTRAL) { status = DriverGetActive("InstanceID", &InstanceID); if (!NT_SUCCESS(status)) @@ -1620,18 +1625,19 @@ PdoSuspend( NTSTATUS PdoCreate( - _In_ PXENFILT_FDO Fdo, - _In_ PDEVICE_OBJECT PhysicalDeviceObject, - _In_ XENFILT_EMULATED_OBJECT_TYPE Type + _In_ PXENFILT_FDO Fdo, + _In_ PDEVICE_OBJECT PhysicalDeviceObject, + _In_ XENFILT_EMULATED_OBJECT_TYPE Type, + _In_ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate ) { - PDEVICE_OBJECT LowerDeviceObject; - ULONG DeviceType; - PDEVICE_OBJECT FilterDeviceObject; - PXENFILT_DX Dx; - PXENFILT_PDO Pdo; - PSTR CompatibleIDs; - NTSTATUS status; + PDEVICE_OBJECT LowerDeviceObject; + ULONG DeviceType; + PDEVICE_OBJECT FilterDeviceObject; + PXENFILT_DX Dx; + PXENFILT_PDO Pdo; + PSTR CompatibleIDs; + NTSTATUS status; ASSERT(Type != XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN); @@ -1680,7 +1686,7 @@ PdoCreate( Pdo->LowerDeviceObject = LowerDeviceObject; Pdo->Type = Type; - status = PdoSetDeviceInformation(Pdo); + status = PdoSetDeviceInformation(Pdo, ForceActivate); if (!NT_SUCCESS(status)) goto fail4; diff --git a/src/xenfilt/pdo.h b/src/xenfilt/pdo.h index 85bc07f..c0c06a4 100644 --- a/src/xenfilt/pdo.h +++ b/src/xenfilt/pdo.h @@ -80,9 +80,10 @@ PdoGetDeviceObject( extern NTSTATUS PdoCreate( - _In_ PXENFILT_FDO Fdo, - _In_ PDEVICE_OBJECT PhysicalDeviceObject, - _In_ XENFILT_EMULATED_OBJECT_TYPE Type + _In_ PXENFILT_FDO Fdo, + _In_ PDEVICE_OBJECT PhysicalDeviceObject, + _In_ XENFILT_EMULATED_OBJECT_TYPE Type, + _In_ XENBUS_EMULATED_ACTIVATION_STATUS ForceActivate ); extern VOID -- 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 |