https://git.reactos.org/?p=reactos.git;a=commitdiff;h=47886766713b8c1698897…
commit 47886766713b8c16988971cbb63d43206bf8de4f
Author:     Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon Feb 10 21:31:28 2020 +0100
Commit:     Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Mon Feb 10 21:33:36 2020 +0100
    [ISAPNP] Implement IRP_MN_QUERY_CAPABILITIES + IRP_MN_QUERY_ID
---
 drivers/bus/isapnp/isapnp.h |   1 +
 drivers/bus/isapnp/pdo.c    | 110 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 111 insertions(+)
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index aaa0f2c9962..538e33b9063 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -2,6 +2,7 @@
 #define _ISAPNP_PCH_
 #include <wdm.h>
+#include <ntstrsafe.h>
 #ifdef __cplusplus
 extern "C" {
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index aec13d8b2d4..619d3fc4e06 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -35,6 +35,108 @@ IsaPdoQueryDeviceRelations(
   return STATUS_SUCCESS;
 }
+NTSTATUS
+NTAPI
+IsaPdoQueryCapabilities(
+  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  PDEVICE_CAPABILITIES DeviceCapabilities;
+
+  DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
+  if (DeviceCapabilities->Version != 1)
+    return STATUS_UNSUCCESSFUL;
+
+  DeviceCapabilities->UniqueID = LogDev->SerialNumber != 0xffffffff;
+  DeviceCapabilities->Address = LogDev->CSN;
+
+  return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaPdoQueryId(
+  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+  WCHAR Temp[256];
+  PWCHAR Buffer, End;
+  ULONG Length;
+  NTSTATUS Status;
+
+  switch (IrpSp->Parameters.QueryId.IdType)
+  {
+    case BusQueryDeviceID:
+    {
+      DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryDeviceID\n");
+      Status = RtlStringCbPrintfExW(Temp, sizeof(Temp),
+                                    &End,
+                                    NULL, 0,
+                                    L"ISAPNP\\%3S%04X",
+                                    LogDev->VendorId,
+                                    LogDev->ProdId);
+      if (!NT_SUCCESS(Status))
+        return Status;
+      Length = End - Temp;
+      Temp[Length++] = UNICODE_NULL;
+      break;
+    }
+
+    case BusQueryHardwareIDs:
+      DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryHardwareIDs\n");
+      Status = RtlStringCbPrintfExW(Temp, sizeof(Temp),
+                                    &End,
+                                    NULL, 0,
+                                    L"ISAPNP\\%3S%04X",
+                                    LogDev->VendorId,
+                                    LogDev->ProdId);
+      if (!NT_SUCCESS(Status))
+        return Status;
+      Length = End - Temp;
+      Temp[Length++] = UNICODE_NULL;
+      Status = RtlStringCbPrintfExW(Temp + Length, sizeof(Temp) - Length,
+                                    &End,
+                                    NULL, 0,
+                                    L"*%3S%04X",
+                                    LogDev->VendorId,
+                                    LogDev->ProdId);
+      if (!NT_SUCCESS(Status))
+        return Status;
+      Length = End - Temp;
+      Temp[Length++] = UNICODE_NULL;
+      Temp[Length++] = UNICODE_NULL;
+      break;
+
+    case BusQueryInstanceID:
+      DPRINT("IRP_MJ_PNP / IRP_MN_QUERY_ID / BusQueryInstanceID\n");
+      Status = RtlStringCbPrintfExW(Temp, sizeof(Temp),
+                                    &End,
+                                    NULL, 0,
+                                    L"%u",
+                                    LogDev->SerialNumber);
+      if (!NT_SUCCESS(Status))
+        return Status;
+      Length = End - Temp;
+      Temp[Length++] = UNICODE_NULL;
+      break;
+
+    default:
+      DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_ID / unknown query id type 0x%lx\n",
+              IrpSp->Parameters.QueryId.IdType);
+      return Irp->IoStatus.Status;
+  }
+
+  Buffer = ExAllocatePool(PagedPool, Length * sizeof(WCHAR));
+  if (!Buffer)
+      return STATUS_NO_MEMORY;
+
+  RtlCopyMemory(Buffer, Temp, Length * sizeof(WCHAR));
+  Irp->IoStatus.Information = (ULONG_PTR)Buffer;
+  return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 IsaPdoPnp(
@@ -64,6 +166,10 @@ IsaPdoPnp(
        Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp);
        break;
+     case IRP_MN_QUERY_CAPABILITIES:
+       Status = IsaPdoQueryCapabilities(LogDev, Irp, IrpSp);
+       break;
+
      case IRP_MN_QUERY_RESOURCES:
        DPRINT1("IRP_MN_QUERY_RESOURCES is UNIMPLEMENTED!\n");
        break;
@@ -72,6 +178,10 @@ IsaPdoPnp(
        DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS is UNIMPLEMENTED!\n");
        break;
+     case IRP_MN_QUERY_ID:
+       Status = IsaPdoQueryId(LogDev, Irp, IrpSp);
+       break;
+
      default:
        DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
        break;