https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c4813f73f56d21ccc9926…
commit c4813f73f56d21ccc9926ff2f93980aea040b141
Author:     Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon Mar 16 19:24:07 2020 +0100
Commit:     Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Fri Mar 20 22:40:11 2020 +0100
    [ISAPNP] Report a ReadDataPort PDO
    This PDO will later request resources required for ISAPNP bus.
---
 drivers/bus/isapnp/fdo.c    |  2 +-
 drivers/bus/isapnp/isapnp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++-
 drivers/bus/isapnp/isapnp.h |  4 ++-
 drivers/bus/isapnp/pdo.c    | 27 +++++++++++++++++---
 4 files changed, 87 insertions(+), 7 deletions(-)
diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
index 6417d6e68bc..f232766b180 100644
--- a/drivers/bus/isapnp/fdo.c
+++ b/drivers/bus/isapnp/fdo.c
@@ -59,7 +59,7 @@ IsaFdoQueryDeviceRelations(
         return Status;
     }
-    return IsaPnpFillDeviceRelations(FdoExt, Irp);
+    return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE);
 }
 NTSTATUS
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 0382f8c843d..41488efc5a7 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -140,7 +140,8 @@ NTSTATUS
 NTAPI
 IsaPnpFillDeviceRelations(
   IN PISAPNP_FDO_EXTENSION FdoExt,
-  IN PIRP Irp)
+  IN PIRP Irp,
+  IN BOOLEAN IncludeDataPort)
 {
     PISAPNP_PDO_EXTENSION PdoExt;
     NTSTATUS Status = STATUS_SUCCESS;
@@ -156,6 +157,12 @@ IsaPnpFillDeviceRelations(
         return STATUS_NO_MEMORY;
     }
+    if (IncludeDataPort)
+    {
+        DeviceRelations->Objects[i++] = FdoExt->DataPortPdo;
+        ObReferenceObject(FdoExt->DataPortPdo);
+    }
+
     CurrentEntry = FdoExt->DeviceListHead.Flink;
     while (CurrentEntry != &FdoExt->DeviceListHead)
     {
@@ -320,6 +327,53 @@ IsaReadWrite(
     return STATUS_NOT_SUPPORTED;
 }
+static
+NTSTATUS
+NTAPI
+IsaPnpCreateReadPortDO(PISAPNP_FDO_EXTENSION FdoExt)
+{
+  UNICODE_STRING DeviceID = RTL_CONSTANT_STRING(L"ISAPNP\\ReadDataPort\0");
+  UNICODE_STRING HardwareIDs =
RTL_CONSTANT_STRING(L"ISAPNP\\ReadDataPort\0\0");
+  UNICODE_STRING InstanceID = RTL_CONSTANT_STRING(L"0\0");
+  PISAPNP_PDO_EXTENSION PdoExt;
+
+  NTSTATUS Status;
+  Status = IoCreateDevice(FdoExt->DriverObject,
+                          sizeof(ISAPNP_PDO_EXTENSION),
+                          NULL,
+                          FILE_DEVICE_CONTROLLER,
+                          FILE_DEVICE_SECURE_OPEN,
+                          FALSE,
+                          &FdoExt->DataPortPdo);
+  if (!NT_SUCCESS(Status))
+      return Status;
+  PdoExt = (PISAPNP_PDO_EXTENSION)FdoExt->DataPortPdo->DeviceExtension;
+  RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
+  PdoExt->Common.IsFdo = FALSE;
+  PdoExt->Common.Self = FdoExt->DataPortPdo;
+  PdoExt->Common.State = dsStopped;
+
+  Status = IsaPnpDuplicateUnicodeString(0,
+                                        &DeviceID,
+                                        &PdoExt->DeviceID);
+  if (!NT_SUCCESS(Status))
+      return Status;
+
+  Status = IsaPnpDuplicateUnicodeString(0,
+                                        &HardwareIDs,
+                                        &PdoExt->HardwareIDs);
+  if (!NT_SUCCESS(Status))
+      return Status;
+
+  Status = IsaPnpDuplicateUnicodeString(0,
+                                        &InstanceID,
+                                        &PdoExt->InstanceID);
+  if (!NT_SUCCESS(Status))
+      return Status;
+
+  return Status;
+}
+
 static
 NTSTATUS
 NTAPI
@@ -360,7 +414,12 @@ IsaAddDevice(
     InitializeListHead(&FdoExt->DeviceListHead);
     KeInitializeSpinLock(&FdoExt->Lock);
+    Status = IsaPnpCreateReadPortDO(FdoExt);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
     Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+    FdoExt->DataPortPdo->Flags &= ~DO_DEVICE_INITIALIZING;
     return STATUS_SUCCESS;
 }
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 3321ff8b9ec..724ccfea79d 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -37,6 +37,7 @@ typedef struct _ISAPNP_FDO_EXTENSION {
     ISAPNP_COMMON_EXTENSION Common;
     PDEVICE_OBJECT Ldo;
     PDEVICE_OBJECT Pdo;
+    PDEVICE_OBJECT DataPortPdo;
     LIST_ENTRY DeviceListHead;
     ULONG DeviceCount;
     PDRIVER_OBJECT DriverObject;
@@ -68,7 +69,8 @@ NTSTATUS
 NTAPI
 IsaPnpFillDeviceRelations(
     IN PISAPNP_FDO_EXTENSION FdoExt,
-    IN PIRP Irp);
+    IN PIRP Irp,
+    IN BOOLEAN IncludeDataPort);
 DRIVER_INITIALIZE DriverEntry;
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 78026a3b40a..1f3f7e18f7b 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -44,13 +44,26 @@ IsaPdoQueryCapabilities(
 {
     PDEVICE_CAPABILITIES DeviceCapabilities;
     PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
+    ULONG i;
     DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
     if (DeviceCapabilities->Version != 1)
         return STATUS_REVISION_MISMATCH;
-    DeviceCapabilities->UniqueID = LogDev->SerialNumber != 0xffffffff;
-    DeviceCapabilities->Address = LogDev->CSN;
+    if (LogDev)
+    {
+        DeviceCapabilities->UniqueID = LogDev->SerialNumber != 0xffffffff;
+        DeviceCapabilities->Address = LogDev->CSN;
+    }
+    else
+    {
+        DeviceCapabilities->UniqueID = TRUE;
+        DeviceCapabilities->SilentInstall = TRUE;
+        DeviceCapabilities->RawDeviceOK = TRUE;
+        for (i = 0; i < POWER_SYSTEM_MAXIMUM; i++)
+            DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
+        DeviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
+    }
     return STATUS_SUCCESS;
 }
@@ -115,14 +128,20 @@ IsaPdoPnp(
     switch (IrpSp->MinorFunction)
     {
        case IRP_MN_START_DEVICE:
-         Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
+           if (PdoExt->IsaPnpDevice)
+               Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
+           else
+               Status = STATUS_SUCCESS;
          if (NT_SUCCESS(Status))
              PdoExt->Common.State = dsStarted;
          break;
        case IRP_MN_STOP_DEVICE:
-         Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
+           if (PdoExt->IsaPnpDevice)
+               Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
+           else
+               Status = STATUS_SUCCESS;
          if (NT_SUCCESS(Status))
              PdoExt->Common.State = dsStopped;