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

[win-pv-devel] [PATCH 2/3] Store (IRP_MN_QUERY_DEVICE_TEXT) DeviceTextLocationInformation...


  • To: <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Paul Durrant <paul.durrant@xxxxxxxxxx>
  • Date: Mon, 20 May 2019 17:46:16 +0100
  • Authentication-results: esa5.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:43 +0000
  • Ironport-sdr: 5AcMgxjEawpmR0qETaGwGqYc3tBWdLZditORS4siz5UYFK//i37vWiovdFlNjFOSBAEsQb/fcy Y/dyD+IPJEn90UHb9K4yPMCHWot3wrcNIZsuXzaAckV0FYZUZIVyAUhDZ6klfAeFzDY5GHFOtA sY37kxEm3nAB0vk6CXRL8umpB7fUWSaS5TjdsIjtFzlUVw/weE3f8HjzM4SbsJE3bHa6aZGh6F 7i1hSIIYAMJSiUNoBphd8gqbj40fcvRLm4zUUXLovxn16DVZhDQ3x4vLtWueX4ylAzx+vkNbnX pLA=
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

...for active XENBUS instance.

When we 'trick' Windows into thinking that the active XENBUS device hasn't
moved (should it actually move in the PCI bus topology) we ought to make
sure that the location information remains constant as well is the
InstanceID. Thus it needs to be sampled and stored in the registry at
installation time. Subsequent patches will add the necessary code into
XENFILT to pull off the trick.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenbus/driver.c |  51 ++++++++++--------
 src/xenbus/driver.h |   7 +--
 src/xenbus/fdo.c    | 150 ++++++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 163 insertions(+), 45 deletions(-)

diff --git a/src/xenbus/driver.c b/src/xenbus/driver.c
index 0ede4ef..c49a7de 100644
--- a/src/xenbus/driver.c
+++ b/src/xenbus/driver.c
@@ -306,12 +306,14 @@ DriverRemoveFunctionDeviceObject(
 
 NTSTATUS
 DriverGetActive(
-    OUT PCHAR       DeviceID,
-    OUT PCHAR       InstanceID
+    IN  const CHAR  *Key,
+    OUT PCHAR       *Value
     )
 {
     HANDLE          ActiveKey;
+    CHAR            Name[MAXNAMELEN];
     PANSI_STRING    Ansi;
+    ULONG           Length;
     NTSTATUS        status;
 
     Trace("====>\n");
@@ -325,30 +327,25 @@ DriverGetActive(
     if (!NT_SUCCESS(status))
         goto fail1;
 
+    status = RtlStringCbPrintfA(Name, MAXNAMELEN, "Active%s", Key);
+    ASSERT(NT_SUCCESS(status));
+
     status = RegistryQuerySzValue(ActiveKey,
-                                  "ActiveDeviceID",
+                                  Name,
                                   NULL,
                                   &Ansi);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    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, 'SUB');
 
-    status = RegistryQuerySzValue(ActiveKey,
-                                  "ActiveInstanceID",
-                                  NULL,
-                                  &Ansi);
-    if (!NT_SUCCESS(status))
+    status = STATUS_NO_MEMORY;
+    if (*Value == NULL)
         goto fail3;
 
-    status = RtlStringCbPrintfA(InstanceID,
-                                MAX_DEVICE_ID_LEN,
+    status = RtlStringCbPrintfA(*Value,
+                                Length,
                                 "%Z",
                                 &Ansi[0]);
     ASSERT(NT_SUCCESS(status));
@@ -362,8 +359,7 @@ DriverGetActive(
     return STATUS_SUCCESS;
 
 fail3:
-    if (status != STATUS_OBJECT_NAME_NOT_FOUND)
-        Error("fail3\n");
+    Error("fail3\n");
 
 fail2:
     if (status != STATUS_OBJECT_NAME_NOT_FOUND)
@@ -455,7 +451,8 @@ fail1:
 NTSTATUS
 DriverSetActive(
     IN  PCHAR   DeviceID,
-    IN  PCHAR   InstanceID
+    IN  PCHAR   InstanceID,
+    IN  PCHAR   LocationInformation
     )
 {
     HANDLE      ActiveKey;
@@ -498,7 +495,16 @@ DriverSetActive(
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    Info("%s\\%s\n", DeviceID, InstanceID);
+    RtlInitAnsiString(&Ansi[0], LocationInformation);
+
+    status = RegistryUpdateSzValue(ActiveKey,
+                                   "ActiveLocationInformation",
+                                   REG_SZ,
+                                   Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    Info("%s\\%s: %s\n", DeviceID, InstanceID, LocationInformation);
 
     RegistryCloseKey(ActiveKey);
 
@@ -506,6 +512,9 @@ DriverSetActive(
 
     return STATUS_SUCCESS;
 
+fail5:
+    Error("fail5\n");
+
 fail4:
     Error("fail4\n");
 
diff --git a/src/xenbus/driver.h b/src/xenbus/driver.h
index 30f6091..3875b42 100644
--- a/src/xenbus/driver.h
+++ b/src/xenbus/driver.h
@@ -66,14 +66,15 @@ DriverReleaseMutex(
 
 extern NTSTATUS
 DriverGetActive(
-    OUT PCHAR   DeviceID,
-    OUT PCHAR   InstanceID
+    IN  const CHAR  *Key,
+    OUT PCHAR       *Value
     );
 
 NTSTATUS
 DriverSetActive(
     IN  PCHAR   DeviceID,
-    IN  PCHAR   InstanceID
+    IN  PCHAR   InstanceID,
+    IN  PCHAR   LocationInformation
     );
 
 NTSTATUS
diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c
index 8ca8f52..2b9c690 100644
--- a/src/xenbus/fdo.c
+++ b/src/xenbus/fdo.c
@@ -552,13 +552,15 @@ static NTSTATUS
 FdoQueryId(
     IN  PXENBUS_FDO         Fdo,
     IN  BUS_QUERY_ID_TYPE   Type,
-    OUT PCHAR               Id
+    OUT PCHAR               *Id
     )
 {
     KEVENT                  Event;
     IO_STATUS_BLOCK         StatusBlock;
     PIRP                    Irp;
     PIO_STACK_LOCATION      StackLocation;
+    PWCHAR                  Buffer;
+    ULONG                   Length;
     NTSTATUS                status;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
@@ -598,16 +600,110 @@ FdoQueryId(
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = RtlStringCbPrintfA(Id,
-                                MAXNAMELEN,
-                                "%ws",
-                                (PWCHAR)StatusBlock.Information);
+    Buffer = (PWCHAR)StatusBlock.Information;
+    Length = (ULONG)(wcslen(Buffer) + 1) * sizeof (CHAR);
+
+    *Id = __AllocatePoolWithTag(PagedPool, Length, 'SUB');
+
+    status = STATUS_NO_MEMORY;
+    if (*Id == NULL)
+        goto fail3;
+
+    status = RtlStringCbPrintfA(*Id, Length, "%ws", Buffer);
     ASSERT(NT_SUCCESS(status));
 
+    ExFreePool(Buffer);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
     ExFreePool((PVOID)StatusBlock.Information);
 
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+__drv_requiresIRQL(PASSIVE_LEVEL)
+static NTSTATUS
+FdoQueryDeviceText(
+    IN  PXENBUS_FDO         Fdo,
+    IN  DEVICE_TEXT_TYPE    Type,
+    OUT PCHAR               *Text
+    )
+{
+    KEVENT                  Event;
+    IO_STATUS_BLOCK         StatusBlock;
+    PIRP                    Irp;
+    PIO_STACK_LOCATION      StackLocation;
+    PWCHAR                  Buffer;
+    ULONG                   Length;
+    NTSTATUS                status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+                                       Fdo->LowerDeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &StatusBlock);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (Irp == NULL)
+        goto fail1;
+
+    StackLocation = IoGetNextIrpStackLocation(Irp);
+    StackLocation->MinorFunction = IRP_MN_QUERY_DEVICE_TEXT;
+
+    StackLocation->Parameters.QueryDeviceText.DeviceTextType = Type;
+
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = StatusBlock.Status;
+    }
+
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    Buffer = (PWCHAR)StatusBlock.Information;
+    Length = (ULONG)(wcslen(Buffer) + 1) * sizeof (CHAR);
+
+    *Text = __AllocatePoolWithTag(PagedPool, Length, 'SUB');
+
+    status = STATUS_NO_MEMORY;
+    if (*Text == NULL)
+        goto fail3;
+
+    status = RtlStringCbPrintfA(*Text, Length, "%ws", Buffer);
+    ASSERT(NT_SUCCESS(status));
+
+    ExFreePool(Buffer);
+
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
+    ExFreePool((PVOID)StatusBlock.Information);
+
 fail2:
     Error("fail2\n");
 
@@ -622,44 +718,56 @@ FdoSetActive(
     IN  PXENBUS_FDO Fdo
     )
 {
-    CHAR            DeviceID[MAX_DEVICE_ID_LEN];
-    CHAR            InstanceID[MAX_DEVICE_ID_LEN];
-    CHAR            ActiveDeviceID[MAX_DEVICE_ID_LEN];
-    CHAR            ActiveInstanceID[MAX_DEVICE_ID_LEN];
+    PCHAR           DeviceID;
+    PCHAR           InstanceID;
+    PCHAR           ActiveDeviceID;
+    PCHAR           LocationInformation;
     NTSTATUS        status;
 
     status = FdoQueryId(Fdo,
                         BusQueryDeviceID,
-                        DeviceID);
+                        &DeviceID);
     if (!NT_SUCCESS(status))
         goto fail1;
 
     status = FdoQueryId(Fdo,
                         BusQueryInstanceID,
-                        InstanceID);
+                        &InstanceID);
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = DriverGetActive(ActiveDeviceID,
-                             ActiveInstanceID);
+    status = FdoQueryDeviceText(Fdo,
+                                DeviceTextLocationInformation,
+                                &LocationInformation);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    status = DriverGetActive("DeviceID", &ActiveDeviceID);
     if (NT_SUCCESS(status)) {
-        if (_stricmp(DeviceID, ActiveDeviceID) != 0)
-            goto done;
+        Fdo->Active = (_stricmp(DeviceID, ActiveDeviceID) == 0) ? TRUE : FALSE;
+        ExFreePool(ActiveDeviceID);
     } else {
-        status = DriverSetActive(DeviceID,
-                                 InstanceID);
-        if (!NT_SUCCESS(status))
-            goto done;
+        status = DriverSetActive(DeviceID, InstanceID, LocationInformation);
+        if (NT_SUCCESS(status))
+            Fdo->Active = TRUE;
     }
 
-    Fdo->Active = TRUE;
+    ExFreePool(LocationInformation);
+    ExFreePool(InstanceID);
+    ExFreePool(DeviceID);
 
-done:
     return STATUS_SUCCESS;
 
+fail3:
+    Error("fail3\n");
+
+    ExFreePool(InstanceID);
+
 fail2:
     Error("fail2\n");
 
+    ExFreePool(DeviceID);
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
-- 
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®.