...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@citrix.com>
--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");
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));
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
VOID
)
{
- CHAR ActiveDeviceID[MAX_DEVICE_ID_LEN];
- CHAR ActiveInstanceID[MAX_DEVICE_ID_LEN];
+ PCHAR ActiveDeviceID;
BOOLEAN Present;
NTSTATUS status;
Present = FALSE;
- status = __DriverGetActive(ActiveDeviceID,
- ActiveInstanceID);
+ status = __DriverGetActive("DeviceID",
+ &ActiveDeviceID);
if (!NT_SUCCESS(status))
goto done;
ActiveDeviceID,
NULL);
+ ExFreePool(ActiveDeviceID);
+
done:
XENFILT_EMULATED(Release, &Driver.EmulatedInterface);
__drv_functionClass(IO_COMPLETION_ROUTINE)
__drv_sameIRQL
static NTSTATUS
-DriverQueryIdCompletion(
+DriverQueryCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
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);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
IoSetCompletionRoutine(Irp,
- DriverQueryIdCompletion,
+ DriverQueryCompletion,
&Event,
TRUE,
TRUE,
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);
)
{
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,
__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;
}
extern NTSTATUS
DriverGetActive(
- OUT PCHAR DeviceID,
- OUT PCHAR InstanceID
+ IN const CHAR *Key,
+ OUT PCHAR *Value
);
typedef enum _XENFILT_FILTER_STATE {
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
#include "pdo.h"
#include "fdo.h"
-#define MAX_DEVICE_ID_LEN 200
-
extern VOID
DriverAddFunctionDeviceObject(
IN PXENFILT_FDO Fdo
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;
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
}
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
return Dx->InstanceID;
}
+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
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,
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]);
}
}
NTSTATUS
FdoCreate(
IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PCHAR DeviceID,
- IN PCHAR InstanceID,
IN XENFILT_EMULATED_OBJECT_TYPE Type
)
{
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));
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");
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;
extern NTSTATUS
FdoCreate(
IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PCHAR DeviceID,
- IN PCHAR InstanceID,
IN XENFILT_EMULATED_OBJECT_TYPE Type
);
XENFILT_EMULATED_OBJECT_TYPE Type;
PXENFILT_EMULATED_OBJECT EmulatedObject;
+ BOOLEAN Active;
};
static FORCEINLINE PVOID
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
{
PXENFILT_DX Dx = Pdo->Dx;
+ ASSERT(Dx->DeviceID != NULL);
return Dx->DeviceID;
}
{
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
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));
}
return status;
}
+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,
)
{
PIO_STACK_LOCATION StackLocation;
- PWCHAR Buffer;
UNICODE_STRING Id;
NTSTATUS status;
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:
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);
return STATUS_SUCCESS;
+fail4:
fail3:
fail2:
IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
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;
PdoCreate(
PXENFILT_FDO Fdo,
PDEVICE_OBJECT PhysicalDeviceObject,
- PCHAR DeviceID,
- PCHAR InstanceID,
XENFILT_EMULATED_OBJECT_TYPE Type
)
{
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;
return STATUS_SUCCESS;
+fail7:
+ Error("fail7\n");
+
+ PdoClearDeviceInformation(Pdo);
+
fail6:
Error("fail6\n");
Pdo->EmulatedObject);
Pdo->EmulatedObject = NULL;
+ PdoClearDeviceInformation(Pdo);
+
ThreadAlert(Pdo->DevicePowerThread);
ThreadJoin(Pdo->DevicePowerThread);
Pdo->DevicePowerThread = NULL;
PdoCreate(
IN PXENFILT_FDO Fdo,
IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PCHAR DeviceID,
- IN PCHAR InstanceID,
IN XENFILT_EMULATED_OBJECT_TYPE Type
);