[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 3/3] Use stored LocationInformation for active device...
...when responding to IRP_MN_QUERY_DEVICE_TEXT. This patch also re-works various parts of XENFILT to avoid copying textual information around unnecessarily. It also removes duplicate query functionality from fdo.c and uses the equivalent code in driver.c. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> --- src/xenfilt/driver.c | 200 ++++++++++++++++++++++++--------- src/xenfilt/driver.h | 25 ++++- src/xenfilt/fdo.c | 223 ++++++++++-------------------------- src/xenfilt/fdo.h | 2 - src/xenfilt/pdo.c | 311 +++++++++++++++++++++++++++++++++++++++++---------- src/xenfilt/pdo.h | 2 - 6 files changed, 477 insertions(+), 286 deletions(-) diff --git a/src/xenfilt/driver.c b/src/xenfilt/driver.c index c96f406..ca53ad6 100644 --- a/src/xenfilt/driver.c +++ b/src/xenfilt/driver.c @@ -226,14 +226,18 @@ DriverRemoveFunctionDeviceObject( --Driver.References; } +#define MAXNAMELEN 128 + static FORCEINLINE NTSTATUS __DriverGetActive( - OUT PCHAR DeviceID, - OUT PCHAR InstanceID + IN const CHAR *Key, + OUT PCHAR *Value ) { HANDLE ParametersKey; + CHAR Name[MAXNAMELEN]; PANSI_STRING Ansi; + ULONG Length; NTSTATUS status; Trace("====>\n"); @@ -242,30 +246,25 @@ __DriverGetActive( ParametersKey = __DriverGetParametersKey(); + status = RtlStringCbPrintfA(Name, MAXNAMELEN, "Active%s", Key); + ASSERT(NT_SUCCESS(status)); + status = RegistryQuerySzValue(ParametersKey, - "ActiveDeviceID", + Name, NULL, &Ansi); if (!NT_SUCCESS(status)) goto fail1; - status = RtlStringCbPrintfA(DeviceID, - MAX_DEVICE_ID_LEN, - "%Z", - &Ansi[0]); - ASSERT(NT_SUCCESS(status)); - - RegistryFreeSzValue(Ansi); + Length = Ansi[0].Length + sizeof (CHAR); + *Value = __AllocatePoolWithTag(PagedPool, Length, 'TLIF'); - status = RegistryQuerySzValue(ParametersKey, - "ActiveInstanceID", - NULL, - &Ansi); - if (!NT_SUCCESS(status)) + status = STATUS_NO_MEMORY; + if (*Value == NULL) goto fail2; - status = RtlStringCbPrintfA(InstanceID, - MAX_DEVICE_ID_LEN, + status = RtlStringCbPrintfA(*Value, + Length, "%Z", &Ansi[0]); ASSERT(NT_SUCCESS(status)); @@ -280,18 +279,19 @@ fail2: Error("fail2\n"); fail1: - Error("fail1 (%08x)\n", status); + if (status != STATUS_OBJECT_NAME_NOT_FOUND) + Error("fail1 (%08x)\n", status); return status; } NTSTATUS DriverGetActive( - OUT PCHAR DeviceID, - OUT PCHAR InstanceID + IN const CHAR *Key, + OUT PCHAR *Value ) { - return __DriverGetActive(DeviceID, InstanceID); + return __DriverGetActive(Key, Value); } static BOOLEAN @@ -299,8 +299,7 @@ DriverIsActivePresent( VOID ) { - CHAR ActiveDeviceID[MAX_DEVICE_ID_LEN]; - CHAR ActiveInstanceID[MAX_DEVICE_ID_LEN]; + PCHAR ActiveDeviceID; BOOLEAN Present; NTSTATUS status; @@ -310,8 +309,8 @@ DriverIsActivePresent( Present = FALSE; - status = __DriverGetActive(ActiveDeviceID, - ActiveInstanceID); + status = __DriverGetActive("DeviceID", + &ActiveDeviceID); if (!NT_SUCCESS(status)) goto done; @@ -320,6 +319,8 @@ DriverIsActivePresent( ActiveDeviceID, NULL); + ExFreePool(ActiveDeviceID); + done: XENFILT_EMULATED(Release, &Driver.EmulatedInterface); @@ -452,7 +453,7 @@ DriverUnload( __drv_functionClass(IO_COMPLETION_ROUTINE) __drv_sameIRQL static NTSTATUS -DriverQueryIdCompletion( +DriverQueryCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context @@ -468,22 +469,23 @@ DriverQueryIdCompletion( return STATUS_MORE_PROCESSING_REQUIRED; } -static FORCEINLINE NTSTATUS +NTSTATUS DriverQueryId( - IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PDEVICE_OBJECT DeviceObject, IN BUS_QUERY_ID_TYPE Type, - OUT PCHAR Id + OUT PCHAR *Id ) { - PDEVICE_OBJECT DeviceObject; PIRP Irp; KEVENT Event; PIO_STACK_LOCATION StackLocation; + PWCHAR Buffer; + ULONG Length; NTSTATUS status; ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - DeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject); + ObReferenceObject(DeviceObject); Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); @@ -503,7 +505,7 @@ DriverQueryId( KeInitializeEvent(&Event, NotificationEvent, FALSE); IoSetCompletionRoutine(Irp, - DriverQueryIdCompletion, + DriverQueryCompletion, &Event, TRUE, TRUE, @@ -527,19 +529,117 @@ DriverQueryId( if (!NT_SUCCESS(status)) goto fail2; - status = RtlStringCbPrintfA(Id, - MAX_DEVICE_ID_LEN, - "%ws", - (PWCHAR)Irp->IoStatus.Information); + Buffer = (PWCHAR)Irp->IoStatus.Information; + Length = (ULONG)(wcslen(Buffer) + 1) * sizeof (CHAR); + + *Id = __AllocatePoolWithTag(PagedPool, Length, 'TLIF'); + + status = STATUS_NO_MEMORY; + if (*Id == NULL) + goto fail3; + + status = RtlStringCbPrintfA(*Id, Length, "%ws", Buffer); ASSERT(NT_SUCCESS(status)); - ExFreePool((PVOID)Irp->IoStatus.Information); + ExFreePool(Buffer); + IoFreeIrp(Irp); + ObDereferenceObject(DeviceObject); + + return STATUS_SUCCESS; + +fail3: + ExFreePool(Buffer); + +fail2: + IoFreeIrp(Irp); + +fail1: + ObDereferenceObject(DeviceObject); + + return status; +} + +NTSTATUS +DriverQueryDeviceText( + IN PDEVICE_OBJECT DeviceObject, + IN DEVICE_TEXT_TYPE Type, + OUT PCHAR *Text + ) +{ + PIRP Irp; + KEVENT Event; + PIO_STACK_LOCATION StackLocation; + PWCHAR Buffer; + ULONG Length; + NTSTATUS status; + + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + + ObReferenceObject(DeviceObject); + + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + + status = STATUS_INSUFFICIENT_RESOURCES; + if (Irp == NULL) + goto fail1; + + StackLocation = IoGetNextIrpStackLocation(Irp); + + StackLocation->MajorFunction = IRP_MJ_PNP; + StackLocation->MinorFunction = IRP_MN_QUERY_DEVICE_TEXT; + StackLocation->Flags = 0; + StackLocation->Parameters.QueryDeviceText.DeviceTextType = Type; + StackLocation->DeviceObject = DeviceObject; + StackLocation->FileObject = NULL; + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + IoSetCompletionRoutine(Irp, + DriverQueryCompletion, + &Event, + TRUE, + TRUE, + TRUE); + // Default completion status + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + + status = IoCallDriver(DeviceObject, Irp); + if (status == STATUS_PENDING) { + (VOID) KeWaitForSingleObject(&Event, + Executive, + KernelMode, + FALSE, + NULL); + status = Irp->IoStatus.Status; + } else { + ASSERT3U(status, ==, Irp->IoStatus.Status); + } + + if (!NT_SUCCESS(status)) + goto fail2; + + Buffer = (PWCHAR)Irp->IoStatus.Information; + Length = (ULONG)(wcslen(Buffer) + 1) * sizeof (CHAR); + + *Text = __AllocatePoolWithTag(PagedPool, Length, 'TLIF'); + + status = STATUS_NO_MEMORY; + if (*Text == NULL) + goto fail3; + + status = RtlStringCbPrintfA(*Text, Length, "%ws", Buffer); + ASSERT(NT_SUCCESS(status)); + + ExFreePool(Buffer); IoFreeIrp(Irp); ObDereferenceObject(DeviceObject); return STATUS_SUCCESS; +fail3: + ExFreePool(Buffer); + fail2: IoFreeIrp(Irp); @@ -576,26 +676,19 @@ DriverAddDevice( ) { HANDLE ParametersKey; - CHAR DeviceID[MAX_DEVICE_ID_LEN]; - CHAR InstanceID[MAX_DEVICE_ID_LEN]; + PCHAR DeviceID; PANSI_STRING Type; NTSTATUS status; ASSERT3P(DriverObject, ==, __DriverGetDriverObject()); - ParametersKey = __DriverGetParametersKey(); - status = DriverQueryId(PhysicalDeviceObject, BusQueryDeviceID, - DeviceID); + &DeviceID); if (!NT_SUCCESS(status)) goto fail1; - status = DriverQueryId(PhysicalDeviceObject, - BusQueryInstanceID, - InstanceID); - if (!NT_SUCCESS(status)) - goto fail2; + ParametersKey = __DriverGetParametersKey(); status = RegistryQuerySzValue(ParametersKey, DeviceID, @@ -605,25 +698,26 @@ DriverAddDevice( __DriverAcquireMutex(); status = FdoCreate(PhysicalDeviceObject, - DeviceID, - InstanceID, DriverGetEmulatedType(Type)); if (!NT_SUCCESS(status)) - goto fail3; + goto fail2; __DriverReleaseMutex(); RegistryFreeSzValue(Type); } - return STATUS_SUCCESS; + ExFreePool(DeviceID); -fail3: - __DriverReleaseMutex(); + return STATUS_SUCCESS; fail2: + __DriverReleaseMutex(); + fail1: + ExFreePool(DeviceID); + return status; } diff --git a/src/xenfilt/driver.h b/src/xenfilt/driver.h index c6ae957..286580b 100644 --- a/src/xenfilt/driver.h +++ b/src/xenfilt/driver.h @@ -54,8 +54,8 @@ DriverReleaseMutex( extern NTSTATUS DriverGetActive( - OUT PCHAR DeviceID, - OUT PCHAR InstanceID + IN const CHAR *Key, + OUT PCHAR *Value ); typedef enum _XENFILT_FILTER_STATE { @@ -74,6 +74,20 @@ DriverGetFilterState( VOID ); +extern NTSTATUS +DriverQueryId( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN BUS_QUERY_ID_TYPE Type, + OUT PCHAR *Id + ); + +extern NTSTATUS +DriverQueryDeviceText( + IN PDEVICE_OBJECT LowerDeviceObject, + IN DEVICE_TEXT_TYPE Type, + OUT PCHAR *Text + ); + #include "emulated.h" PXENFILT_EMULATED_CONTEXT @@ -87,8 +101,6 @@ typedef struct _XENFILT_PDO XENFILT_PDO, *PXENFILT_PDO; #include "pdo.h" #include "fdo.h" -#define MAX_DEVICE_ID_LEN 200 - extern VOID DriverAddFunctionDeviceObject( IN PXENFILT_FDO Fdo @@ -112,8 +124,9 @@ typedef struct _XENFILT_DX { SYSTEM_POWER_STATE SystemPowerState; DEVICE_POWER_STATE DevicePowerState; - CHAR DeviceID[MAX_DEVICE_ID_LEN]; - CHAR InstanceID[MAX_DEVICE_ID_LEN]; + PCHAR DeviceID; + PCHAR InstanceID; + PCHAR LocationInformation; IO_REMOVE_LOCK RemoveLock; diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c index f41288e..3e87911 100644 --- a/src/xenfilt/fdo.c +++ b/src/xenfilt/fdo.c @@ -212,20 +212,17 @@ FdoGetPhysicalDeviceObject( return __FdoGetPhysicalDeviceObject(Fdo); } -static FORCEINLINE VOID +static FORCEINLINE NTSTATUS __FdoSetDeviceID( - IN PXENFILT_FDO Fdo, - IN PCHAR DeviceID + IN PXENFILT_FDO Fdo ) { PXENFILT_DX Dx = Fdo->Dx; - NTSTATUS status; - status = RtlStringCbPrintfA(Dx->DeviceID, - MAX_DEVICE_ID_LEN, - "%s", - DeviceID); - ASSERT(NT_SUCCESS(status)); + return DriverQueryId(Fdo->PhysicalDeviceObject, + BusQueryDeviceID, + &Dx->DeviceID); + } static FORCEINLINE PCHAR @@ -239,19 +236,26 @@ __FdoGetDeviceID( } static FORCEINLINE VOID +__FdoClearDeviceID( + IN PXENFILT_FDO Fdo + ) +{ + PXENFILT_DX Dx = Fdo->Dx; + + ExFreePool(Dx->DeviceID); + Dx->DeviceID = NULL; +} + +static FORCEINLINE NTSTATUS __FdoSetInstanceID( - IN PXENFILT_FDO Fdo, - IN PCHAR InstanceID + IN PXENFILT_FDO Fdo ) { PXENFILT_DX Dx = Fdo->Dx; - NTSTATUS status; - status = RtlStringCbPrintfA(Dx->InstanceID, - MAX_DEVICE_ID_LEN, - "%s", - InstanceID); - ASSERT(NT_SUCCESS(status)); + return DriverQueryId(Fdo->PhysicalDeviceObject, + BusQueryInstanceID, + &Dx->InstanceID); } static FORCEINLINE PCHAR @@ -265,6 +269,17 @@ __FdoGetInstanceID( } static FORCEINLINE VOID +__FdoClearInstanceID( + IN PXENFILT_FDO Fdo + ) +{ + PXENFILT_DX Dx = Fdo->Dx; + + ExFreePool(Dx->InstanceID); + Dx->InstanceID = NULL; +} + +static FORCEINLINE VOID __FdoSetName( IN PXENFILT_FDO Fdo ) @@ -383,143 +398,6 @@ FdoHasEnumerated( return Fdo->Enumerated; } -__drv_functionClass(IO_COMPLETION_ROUTINE) -__drv_sameIRQL -static NTSTATUS -FdoQueryIdCompletion( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) -{ - PKEVENT Event = Context; - - UNREFERENCED_PARAMETER(DeviceObject); - UNREFERENCED_PARAMETER(Irp); - - KeSetEvent(Event, IO_NO_INCREMENT, FALSE); - - return STATUS_MORE_PROCESSING_REQUIRED; -} - -static NTSTATUS -FdoQueryId( - IN PXENFILT_FDO Fdo, - IN PDEVICE_OBJECT DeviceObject, - IN BUS_QUERY_ID_TYPE Type, - OUT PCHAR Id - ) -{ - PIRP Irp; - KEVENT Event; - PIO_STACK_LOCATION StackLocation; - NTSTATUS status; - - UNREFERENCED_PARAMETER(Fdo); - - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); - - Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); - - status = STATUS_INSUFFICIENT_RESOURCES; - if (Irp == NULL) - goto fail1; - - StackLocation = IoGetNextIrpStackLocation(Irp); - - StackLocation->MajorFunction = IRP_MJ_PNP; - StackLocation->MinorFunction = IRP_MN_QUERY_ID; - StackLocation->Flags = 0; - StackLocation->Parameters.QueryId.IdType = Type; - StackLocation->DeviceObject = DeviceObject; - StackLocation->FileObject = NULL; - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - IoSetCompletionRoutine(Irp, - FdoQueryIdCompletion, - &Event, - TRUE, - TRUE, - TRUE); - - // Default completion status - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - - status = IoCallDriver(DeviceObject, Irp); - if (status == STATUS_PENDING) { - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); - status = Irp->IoStatus.Status; - } else { - ASSERT3U(status, ==, Irp->IoStatus.Status); - } - - if (!NT_SUCCESS(status)) - goto fail2; - - status = RtlStringCbPrintfA(Id, - MAX_DEVICE_ID_LEN, - "%ws", - (PWCHAR)Irp->IoStatus.Information); - ASSERT(NT_SUCCESS(status)); - - ExFreePool((PVOID)Irp->IoStatus.Information); - - IoFreeIrp(Irp); - - return STATUS_SUCCESS; - -fail2: - IoFreeIrp(Irp); - -fail1: - return status; -} - -static NTSTATUS -FdoAddDevice( - IN PXENFILT_FDO Fdo, - IN PDEVICE_OBJECT PhysicalDeviceObject - ) -{ - CHAR DeviceID[MAX_DEVICE_ID_LEN]; - CHAR InstanceID[MAX_DEVICE_ID_LEN]; - NTSTATUS status; - - status = FdoQueryId(Fdo, - PhysicalDeviceObject, - BusQueryDeviceID, - DeviceID); - if (!NT_SUCCESS(status)) - goto fail1; - - status = FdoQueryId(Fdo, - PhysicalDeviceObject, - BusQueryInstanceID, - InstanceID); - if (!NT_SUCCESS(status)) - goto fail2; - - status = PdoCreate(Fdo, - PhysicalDeviceObject, - DeviceID, - InstanceID, - Fdo->Type); - if (!NT_SUCCESS(status)) - goto fail3; - - return STATUS_SUCCESS; - -fail3: -fail2: -fail1: - return status; -} - static VOID FdoEnumerate( IN PXENFILT_FDO Fdo, @@ -588,7 +466,7 @@ FdoEnumerate( for (Index = 0; Index < Count; Index++) { #pragma warning(suppress:6385) // Reading invalid data from 'PhysicalDeviceObject' if (PhysicalDeviceObject[Index] != NULL) { - (VOID) FdoAddDevice(Fdo, PhysicalDeviceObject[Index]); + (VOID) PdoCreate(Fdo, PhysicalDeviceObject[Index], Fdo->Type); ObDereferenceObject(PhysicalDeviceObject[Index]); } } @@ -2076,8 +1954,6 @@ FdoDispatch( NTSTATUS FdoCreate( IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PCHAR DeviceID, - IN PCHAR InstanceID, IN XENFILT_EMULATED_OBJECT_TYPE Type ) { @@ -2140,14 +2016,20 @@ FdoCreate( if (!NT_SUCCESS(status)) goto fail5; + status = __FdoSetDeviceID(Fdo); + if (!NT_SUCCESS(status)) + goto fail6; + + status = __FdoSetInstanceID(Fdo); + if (!NT_SUCCESS(status)) + goto fail7; + + __FdoSetName(Fdo); + InitializeMutex(&Fdo->Mutex); InitializeListHead(&Fdo->List); Fdo->References = 1; - __FdoSetDeviceID(Fdo, DeviceID); - __FdoSetInstanceID(Fdo, InstanceID); - __FdoSetName(Fdo); - Info("%p (%s)\n", FilterDeviceObject, __FdoGetName(Fdo)); @@ -2165,6 +2047,18 @@ FdoCreate( return STATUS_SUCCESS; +fail7: + Error("fail7\n"); + + __FdoClearDeviceID(Fdo); + +fail6: + Error("fail6\n"); + + ThreadAlert(Fdo->DevicePowerThread); + ThreadJoin(Fdo->DevicePowerThread); + Fdo->DevicePowerThread = NULL; + fail5: Error("fail5\n"); @@ -2222,11 +2116,14 @@ FdoDestroy( FilterDeviceObject, __FdoGetName(Fdo)); - RtlZeroMemory(Fdo->Name, sizeof (Fdo->Name)); - RtlZeroMemory(&Fdo->List, sizeof (LIST_ENTRY)); RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX)); + RtlZeroMemory(Fdo->Name, sizeof (Fdo->Name)); + + __FdoClearInstanceID(Fdo); + __FdoClearDeviceID(Fdo); + ThreadAlert(Fdo->DevicePowerThread); ThreadJoin(Fdo->DevicePowerThread); Fdo->DevicePowerThread = NULL; diff --git a/src/xenfilt/fdo.h b/src/xenfilt/fdo.h index 62a667f..11fff44 100644 --- a/src/xenfilt/fdo.h +++ b/src/xenfilt/fdo.h @@ -43,8 +43,6 @@ typedef struct _XENFILT_FDO XENFILT_FDO, *PXENFILT_FDO; extern NTSTATUS FdoCreate( IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PCHAR DeviceID, - IN PCHAR InstanceID, IN XENFILT_EMULATED_OBJECT_TYPE Type ); diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c index 41ffa1b..9fba36c 100644 --- a/src/xenfilt/pdo.c +++ b/src/xenfilt/pdo.c @@ -67,6 +67,7 @@ struct _XENFILT_PDO { XENFILT_EMULATED_OBJECT_TYPE Type; PXENFILT_EMULATED_OBJECT EmulatedObject; + BOOLEAN Active; }; static FORCEINLINE PVOID @@ -250,46 +251,108 @@ __PdoGetFdo( return Pdo->Fdo; } -static VOID -PdoSetDeviceInstance( - IN PXENFILT_PDO Pdo, - IN PCHAR DeviceID, - IN PCHAR InstanceID +static NTSTATUS +PdoSetDeviceInformation( + IN PXENFILT_PDO Pdo ) { PXENFILT_DX Dx = Pdo->Dx; - CHAR ActiveDeviceID[MAX_DEVICE_ID_LEN]; - CHAR ActiveInstanceID[MAX_DEVICE_ID_LEN]; + PCHAR DeviceID; + PCHAR ActiveDeviceID; + PCHAR InstanceID; + PCHAR LocationInformation; NTSTATUS status; - status = DriverGetActive(ActiveDeviceID, - ActiveInstanceID); + status = DriverQueryId(Pdo->LowerDeviceObject, + BusQueryDeviceID, + &DeviceID); if (!NT_SUCCESS(status)) - goto done; + goto fail1; - if (_stricmp(DeviceID, ActiveDeviceID) != 0) - goto done; + status = DriverGetActive("DeviceID", + &ActiveDeviceID); + if (NT_SUCCESS(status)) { + Pdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ? + TRUE : + FALSE; - if (_stricmp(InstanceID, ActiveInstanceID) != 0) { - Warning("(%s) '%s' -> '%s'\n", - Dx->DeviceID, - InstanceID, - ActiveInstanceID); - InstanceID = ActiveInstanceID; + ExFreePool(ActiveDeviceID); + } else { + Pdo->Active = FALSE; } -done: - status = RtlStringCbPrintfA(Dx->DeviceID, - MAX_DEVICE_ID_LEN, - "%s", - DeviceID); - ASSERT(NT_SUCCESS(status)); + if (Pdo->Active) { + status = DriverGetActive("InstanceID", + &InstanceID); + if (!NT_SUCCESS(status)) + goto fail2; - status = RtlStringCbPrintfA(Dx->InstanceID, - MAX_DEVICE_ID_LEN, - "%s", - InstanceID); - ASSERT(NT_SUCCESS(status)); + status = DriverGetActive("LocationInformation", + &LocationInformation); + if (!NT_SUCCESS(status)) + goto fail3; + } else { + status = DriverQueryId(Pdo->LowerDeviceObject, + BusQueryInstanceID, + &InstanceID); + if (!NT_SUCCESS(status)) + InstanceID = NULL; + + status = DriverQueryDeviceText(Pdo->LowerDeviceObject, + DeviceTextLocationInformation, + &LocationInformation); + if (!NT_SUCCESS(status)) + LocationInformation = NULL; + } + + Dx->DeviceID = DeviceID; + Dx->InstanceID = InstanceID; + Dx->LocationInformation = LocationInformation; + + return STATUS_SUCCESS; + +fail3: + Error("fail3\n"); + + ASSERT(Pdo->Active); + ExFreePool(InstanceID); + +fail2: + Error("fail2\n"); + + ASSERT(Pdo->Active); + ExFreePool(DeviceID); + + Pdo->Active = FALSE; + +fail1: + Error("fail1 (%08x)\n", status); + + return status; +} + +static VOID +PdoClearDeviceInformation( + IN PXENFILT_PDO Pdo + ) +{ + PXENFILT_DX Dx = Pdo->Dx; + + if (Dx->LocationInformation != NULL) { + ExFreePool(Dx->LocationInformation); + Dx->LocationInformation = NULL; + } + + if (Dx->InstanceID != NULL) { + ExFreePool(Dx->InstanceID); + Dx->InstanceID = NULL; + } + + ASSERT(Dx->DeviceID != NULL); + ExFreePool(Dx->DeviceID); + Dx->DeviceID = NULL; + + Pdo->Active = FALSE; } static FORCEINLINE PCHAR @@ -299,6 +362,7 @@ __PdoGetDeviceID( { PXENFILT_DX Dx = Pdo->Dx; + ASSERT(Dx->DeviceID != NULL); return Dx->DeviceID; } @@ -309,7 +373,19 @@ __PdoGetInstanceID( { PXENFILT_DX Dx = Pdo->Dx; - return Dx->InstanceID; + return (Dx->InstanceID != NULL) ? + Dx->InstanceID : ""; +} + +static FORCEINLINE PCHAR +__PdoGetLocationInformation( + IN PXENFILT_PDO Pdo + ) +{ + PXENFILT_DX Dx = Pdo->Dx; + + return (Dx->LocationInformation != NULL) ? + Dx->LocationInformation : ""; } static FORCEINLINE VOID @@ -317,14 +393,20 @@ __PdoSetName( IN PXENFILT_PDO Pdo ) { - PXENFILT_DX Dx = Pdo->Dx; NTSTATUS status; - status = RtlStringCbPrintfA(Pdo->Name, - MAXNAMELEN, - "%s\\%s", - Dx->DeviceID, - Dx->InstanceID); + if (strlen(__PdoGetInstanceID(Pdo)) == 0) + status = RtlStringCbPrintfA(Pdo->Name, + MAXNAMELEN, + "%s", + __PdoGetDeviceID(Pdo)); + else + status = RtlStringCbPrintfA(Pdo->Name, + MAXNAMELEN, + "%s\\%s", + __PdoGetDeviceID(Pdo), + __PdoGetInstanceID(Pdo)); + ASSERT(NT_SUCCESS(status)); } @@ -974,13 +1056,104 @@ fail1: } static NTSTATUS +PdoQueryDeviceText( + IN PXENFILT_PDO Pdo, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION StackLocation; + UNICODE_STRING Text; + NTSTATUS status; + + status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); + if (!NT_SUCCESS(status)) + goto fail1; + + status = PdoForwardIrpSynchronously(Pdo, Irp); + if (!NT_SUCCESS(status)) + goto fail2; + + StackLocation = IoGetCurrentIrpStackLocation(Irp); + + RtlZeroMemory(&Text, sizeof (UNICODE_STRING)); + + switch (StackLocation->Parameters.QueryDeviceText.DeviceTextType) { + case DeviceTextLocationInformation: + Text.MaximumLength = + (USHORT)(strlen(__PdoGetLocationInformation(Pdo)) * + sizeof (WCHAR)); + + Trace("DeviceTextLocationInformation\n"); + break; + + default: + goto done; + } + + status = STATUS_OBJECT_NAME_NOT_FOUND; + if (Text.MaximumLength == 0) + goto fail3; + + Text.MaximumLength += sizeof (WCHAR); + Text.Buffer = __AllocatePoolWithTag(PagedPool, + Text.MaximumLength, + 'TLIF'); + + status = STATUS_NO_MEMORY; + if (Text.Buffer == NULL) + goto fail4; + + switch (StackLocation->Parameters.QueryDeviceText.DeviceTextType) { + case DeviceTextLocationInformation: + status = RtlStringCbPrintfW(Text.Buffer, + Text.MaximumLength, + L"%hs", + __PdoGetLocationInformation(Pdo)); + ASSERT(NT_SUCCESS(status)); + + break; + + default: + ASSERT(FALSE); + break; + } + + Text.Length = (USHORT)(wcslen(Text.Buffer) * sizeof (WCHAR)); + + ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + + Trace("- %wZ\n", &Text); + + ExFreePool((PVOID)Irp->IoStatus.Information); + Irp->IoStatus.Information = (ULONG_PTR)Text.Buffer; + +done: + IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; + +fail4: +fail3: +fail2: + IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); + +fail1: + Irp->IoStatus.Status = status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return status; +} + +static NTSTATUS PdoQueryId( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - PWCHAR Buffer; UNICODE_STRING Id; NTSTATUS status; @@ -994,49 +1167,55 @@ PdoQueryId( StackLocation = IoGetCurrentIrpStackLocation(Irp); + RtlZeroMemory(&Id, sizeof (UNICODE_STRING)); + switch (StackLocation->Parameters.QueryId.IdType) { case BusQueryInstanceID: + Id.MaximumLength = (USHORT)(strlen(__PdoGetInstanceID(Pdo)) * + sizeof (WCHAR)); + Trace("BusQueryInstanceID\n"); - Id.MaximumLength = MAX_DEVICE_ID_LEN * sizeof (WCHAR); break; case BusQueryDeviceID: + Id.MaximumLength = (USHORT)(strlen(__PdoGetDeviceID(Pdo)) * + sizeof (WCHAR)); + Trace("BusQueryDeviceID\n"); - Id.MaximumLength = MAX_DEVICE_ID_LEN * sizeof (WCHAR); break; default: goto done; } - Buffer = __AllocatePoolWithTag(PagedPool, Id.MaximumLength, 'TLIF'); - - status = STATUS_NO_MEMORY; - if (Buffer == NULL) + status = STATUS_OBJECT_NAME_NOT_FOUND; + if (Id.MaximumLength == 0) goto fail3; - Id.Buffer = Buffer; - Id.Length = 0; + Id.MaximumLength += sizeof (WCHAR); + Id.Buffer = __AllocatePoolWithTag(PagedPool, Id.MaximumLength, 'TLIF'); + + status = STATUS_NO_MEMORY; + if (Id.Buffer == NULL) + goto fail4; switch (StackLocation->Parameters.QueryId.IdType) { case BusQueryInstanceID: - status = RtlStringCbPrintfW(Buffer, + status = RtlStringCbPrintfW(Id.Buffer, Id.MaximumLength, L"%hs", __PdoGetInstanceID(Pdo)); ASSERT(NT_SUCCESS(status)); - Buffer += wcslen(Buffer); break; case BusQueryDeviceID: - status = RtlStringCbPrintfW(Buffer, + status = RtlStringCbPrintfW(Id.Buffer, Id.MaximumLength, L"%hs", __PdoGetDeviceID(Pdo)); ASSERT(NT_SUCCESS(status)); - Buffer += wcslen(Buffer); break; default: @@ -1044,8 +1223,7 @@ PdoQueryId( break; } - Id.Length = (USHORT)((ULONG_PTR)Buffer - (ULONG_PTR)Id.Buffer); - Buffer = Id.Buffer; + Id.Length = (USHORT)(wcslen(Id.Buffer) * sizeof (WCHAR)); ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); @@ -1062,6 +1240,7 @@ done: return STATUS_SUCCESS; +fail4: fail3: fail2: IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); @@ -1167,6 +1346,10 @@ PdoDispatchPnp( status = PdoQueryInterface(Pdo, Irp); break; + case IRP_MN_QUERY_DEVICE_TEXT: + status = PdoQueryDeviceText(Pdo, Irp); + break; + case IRP_MN_QUERY_ID: status = PdoQueryId(Pdo, Irp); break; @@ -1922,8 +2105,6 @@ NTSTATUS PdoCreate( PXENFILT_FDO Fdo, PDEVICE_OBJECT PhysicalDeviceObject, - PCHAR DeviceID, - PCHAR InstanceID, XENFILT_EMULATED_OBJECT_TYPE Type ) { @@ -1987,21 +2168,24 @@ PdoCreate( if (!NT_SUCCESS(status)) goto fail5; + status = PdoSetDeviceInformation(Pdo); + if (!NT_SUCCESS(status)) + goto fail6; + status = EmulatedAddObject(DriverGetEmulatedContext(), - DeviceID, - InstanceID, + __PdoGetDeviceID(Pdo), + __PdoGetInstanceID(Pdo), Pdo->Type, &Pdo->EmulatedObject); if (!NT_SUCCESS(status)) - goto fail6; - - PdoSetDeviceInstance(Pdo, DeviceID, InstanceID); + goto fail7; __PdoSetName(Pdo); - Info("%p (%s)\n", + Info("%p (%s) %s\n", FilterDeviceObject, - __PdoGetName(Pdo)); + __PdoGetName(Pdo), + Pdo->Active ? "[ACTIVE]" : ""); Dx->Pdo = Pdo; @@ -2016,6 +2200,11 @@ PdoCreate( return STATUS_SUCCESS; +fail7: + Error("fail7\n"); + + PdoClearDeviceInformation(Pdo); + fail6: Error("fail6\n"); @@ -2089,6 +2278,8 @@ PdoDestroy( Pdo->EmulatedObject); Pdo->EmulatedObject = NULL; + PdoClearDeviceInformation(Pdo); + ThreadAlert(Pdo->DevicePowerThread); ThreadJoin(Pdo->DevicePowerThread); Pdo->DevicePowerThread = NULL; diff --git a/src/xenfilt/pdo.h b/src/xenfilt/pdo.h index 0dfd384..5d57e02 100644 --- a/src/xenfilt/pdo.h +++ b/src/xenfilt/pdo.h @@ -81,8 +81,6 @@ extern NTSTATUS PdoCreate( IN PXENFILT_FDO Fdo, IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PCHAR DeviceID, - IN PCHAR InstanceID, IN XENFILT_EMULATED_OBJECT_TYPE Type ); -- 2.5.3 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |