[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 3/3] Use stored LocationInformation for active device...


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Date: Mon, 20 May 2019 17:46:17 +0100
  • Authentication-results: esa4.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=paul.durrant@xxxxxxxxxx; spf=Pass smtp.mailfrom=Paul.Durrant@xxxxxxxxxx; spf=None smtp.helo=postmaster@xxxxxxxxxxxxxxxxxxxxxxxxxx
  • Cc: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Delivery-date: Mon, 20 May 2019 16:46:34 +0000
  • Ironport-sdr: 3qWTdfBVss+cpzFpQ12UAwodjpth9eLfpFmE/PBeQQOIlQD3iryAbCf943H/B/RbYBZpdfXnKj p6OX6iSRYDCk8+aa9bMgu+sXCz7YP1JT/q+vQ8ZFPQiqqE1DIUr6pXcahCO1smKl9U45XF0fUc iXlTjmNt0q53vthLy56Q790yB8h4A/YC9TT252L/rJnbgX+Qw4iuSkz3FQ1FqHXlp9oVa0pGK4 A6h5Uwas0aDSoaIA792VIe2NSnYsNKg2Mj7qy24p9LtTt/8nKEMsuHj07M/KR0AeHjWCQLpNQ6 q9k=
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

...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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.