https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7a98d28d7f8e58fcf3ef980514b79ec14b59c82b

commit 7a98d28d7f8e58fcf3ef980514b79ec14b59c82b
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Thu Mar 12 11:53:09 2020 +0100
Commit:     Hervé Poussineau <[email protected]>
CommitDate: Sat Mar 14 23:39:01 2020 +0100

    [ISAPNP] Rewrite device reporting method
    
    IoCreateDevice() was called too early, when a spinlock was acquired.
    Create ISAPNP_LOGICAL_DEVICE structure when a device is detected, and call 
IoCreateDevice() later, when required.
---
 drivers/bus/isapnp/fdo.c      | 47 ++++++++++++++++++++++++++++++++-----------
 drivers/bus/isapnp/hardware.c | 26 ++++--------------------
 drivers/bus/isapnp/isapnp.c   |  3 ++-
 drivers/bus/isapnp/isapnp.h   | 28 ++++++++++++++++----------
 drivers/bus/isapnp/pdo.c      | 28 ++++++++++++++------------
 5 files changed, 73 insertions(+), 59 deletions(-)

diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
index c0a5eb9eb91..1529267b1c4 100644
--- a/drivers/bus/isapnp/fdo.c
+++ b/drivers/bus/isapnp/fdo.c
@@ -24,18 +24,16 @@ IsaFdoStartDevice(
   UNREFERENCED_PARAMETER(IrpSp);
 
   KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
-
   Status = IsaHwDetectReadDataPort(FdoExt);
+  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+
   if (!NT_SUCCESS(Status))
   {
-      KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
       return Status;
   }
 
   FdoExt->Common.State = dsStarted;
 
-  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
   return STATUS_SUCCESS;
 }
 
@@ -46,6 +44,7 @@ IsaFdoQueryDeviceRelations(
   IN PIRP Irp,
   IN PIO_STACK_LOCATION IrpSp)
 {
+  PISAPNP_PDO_EXTENSION PdoExt;
   NTSTATUS Status;
   PLIST_ENTRY CurrentEntry;
   PISAPNP_LOGICAL_DEVICE IsaDevice;
@@ -57,11 +56,11 @@ IsaFdoQueryDeviceRelations(
       return Irp->IoStatus.Status;
 
   KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
-
   Status = IsaHwFillDeviceList(FdoExt);
+  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+
   if (!NT_SUCCESS(Status))
   {
-      KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
       return Status;
   }
 
@@ -69,8 +68,7 @@ IsaFdoQueryDeviceRelations(
                             sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * 
(FdoExt->DeviceCount - 1));
   if (!DeviceRelations)
   {
-      KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-      return STATUS_INSUFFICIENT_RESOURCES;
+      return STATUS_NO_MEMORY;
   }
 
   CurrentEntry = FdoExt->DeviceListHead.Flink;
@@ -78,17 +76,42 @@ IsaFdoQueryDeviceRelations(
   {
      IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, 
ListEntry);
 
-     DeviceRelations->Objects[i++] = IsaDevice->Common.Self;
+     if (!IsaDevice->Pdo)
+     {
+         Status = IoCreateDevice(FdoExt->DriverObject,
+                                 sizeof(ISAPNP_PDO_EXTENSION),
+                                 NULL,
+                                 FILE_DEVICE_CONTROLLER,
+                                 FILE_DEVICE_SECURE_OPEN | 
FILE_AUTOGENERATED_DEVICE_NAME,
+                                 FALSE,
+                                 &IsaDevice->Pdo);
+         if (!NT_SUCCESS(Status))
+         {
+            break;
+         }
 
-     ObReferenceObject(IsaDevice->Common.Self);
+         IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+         //Device->Pdo->Flags |= DO_POWER_PAGABLE;
+
+         PdoExt = (PISAPNP_PDO_EXTENSION)IsaDevice->Pdo->DeviceExtension;
+
+         RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION));
+
+         PdoExt->Common.IsFdo = FALSE;
+         PdoExt->Common.Self = IsaDevice->Pdo;
+         PdoExt->Common.State = dsStopped;
+         PdoExt->IsaPnpDevice = IsaDevice;
+     }
+     DeviceRelations->Objects[i++] = IsaDevice->Pdo;
+
+     ObReferenceObject(IsaDevice->Pdo);
 
      CurrentEntry = CurrentEntry->Flink;
   }
 
   DeviceRelations->Count = FdoExt->DeviceCount;
 
-  KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
   Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
 
   return STATUS_SUCCESS;
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index acabdd2d04c..df3d8e398a7 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -463,8 +463,6 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
   ISAPNP_LOGDEVID LogDevId;
   USHORT Csn;
   USHORT LogDev;
-  PDEVICE_OBJECT Pdo;
-  NTSTATUS Status;
 
   ASSERT(FdoExt->ReadDataPort);
 
@@ -472,26 +470,12 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
   {
     for (LogDev = 0; LogDev <= 0xFF; LogDev++)
     {
-      Status = IoCreateDevice(FdoExt->Common.Self->DriverObject,
-                              sizeof(ISAPNP_LOGICAL_DEVICE),
-                              NULL,
-                              FILE_DEVICE_CONTROLLER,
-                              FILE_DEVICE_SECURE_OPEN,
-                              FALSE,
-                              &Pdo);
-      if (!NT_SUCCESS(Status))
-          return Status;
-
-      Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-
-      LogDevice = Pdo->DeviceExtension;
+      LogDevice = ExAllocatePool(NonPagedPool, sizeof(ISAPNP_LOGICAL_DEVICE));
+      if (!LogDevice)
+          return STATUS_NO_MEMORY;
 
       RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
 
-      LogDevice->Common.Self = Pdo;
-      LogDevice->Common.IsFdo = FALSE;
-      LogDevice->Common.State = dsStopped;
-
       LogDevice->CSN = Csn;
       LogDevice->LDN = LogDev;
 
@@ -503,7 +487,7 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
 
       if (Identifier.VendorId & 0x80)
       {
-          IoDeleteDevice(LogDevice->Common.Self);
+          ExFreePool(LogDevice);
           return STATUS_SUCCESS;
       }
 
@@ -525,8 +509,6 @@ ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
 
       WaitForKey();
 
-      Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
-
       InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
       FdoExt->DeviceCount++;
     }
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index ae94622b66b..eebe03c29aa 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -152,6 +152,7 @@ IsaAddDevice(
   FdoExt->Common.Self = Fdo;
   FdoExt->Common.IsFdo = TRUE;
   FdoExt->Common.State = dsStopped;
+  FdoExt->DriverObject = DriverObject;
   FdoExt->Pdo = PhysicalDeviceObject;
   FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
                                             PhysicalDeviceObject);
@@ -186,7 +187,7 @@ IsaPnp(
   }
   else
   {
-     return IsaPdoPnp((PISAPNP_LOGICAL_DEVICE)DevExt,
+     return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt,
                       Irp,
                       IrpSp);
   }
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 538e33b9063..c941712f77a 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -15,6 +15,18 @@ typedef enum {
   dsStarted
 } ISAPNP_DEVICE_STATE;
 
+typedef struct _ISAPNP_LOGICAL_DEVICE {
+  PDEVICE_OBJECT Pdo;
+  UCHAR VendorId[3];
+  USHORT ProdId;
+  ULONG SerialNumber;
+  USHORT IoAddr;
+  UCHAR IrqNo;
+  UCHAR CSN;
+  UCHAR LDN;
+  LIST_ENTRY ListEntry;
+} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+
 typedef struct _ISAPNP_COMMON_EXTENSION {
   PDEVICE_OBJECT Self;
   BOOLEAN IsFdo;
@@ -27,21 +39,15 @@ typedef struct _ISAPNP_FDO_EXTENSION {
   PDEVICE_OBJECT Pdo;
   LIST_ENTRY DeviceListHead;
   ULONG DeviceCount;
+  PDRIVER_OBJECT DriverObject;
   PUCHAR ReadDataPort;
   KSPIN_LOCK Lock;
 } ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
 
-typedef struct _ISAPNP_LOGICAL_DEVICE {
+typedef struct _ISAPNP_PDO_EXTENSION {
   ISAPNP_COMMON_EXTENSION Common;
-  UCHAR VendorId[3];
-  USHORT ProdId;
-  ULONG SerialNumber;
-  USHORT IoAddr;
-  UCHAR IrqNo;
-  UCHAR CSN;
-  UCHAR LDN;
-  LIST_ENTRY ListEntry;
-} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+  PISAPNP_LOGICAL_DEVICE IsaPnpDevice;
+} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
 
 /* isapnp.c */
 
@@ -71,7 +77,7 @@ IsaFdoPnp(
 NTSTATUS
 NTAPI
 IsaPdoPnp(
-  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PISAPNP_PDO_EXTENSION PdoDeviceExtension,
   IN PIRP Irp,
   IN PIO_STACK_LOCATION IrpSp);
 
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 450462f39d6..6e06af29241 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -13,7 +13,7 @@
 NTSTATUS
 NTAPI
 IsaPdoQueryDeviceRelations(
-  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PISAPNP_PDO_EXTENSION PdoExt,
   IN PIRP Irp,
   IN PIO_STACK_LOCATION IrpSp)
 {
@@ -27,8 +27,8 @@ IsaPdoQueryDeviceRelations(
       return STATUS_INSUFFICIENT_RESOURCES;
 
   DeviceRelations->Count = 1;
-  DeviceRelations->Objects[0] = LogDev->Common.Self;
-  ObReferenceObject(LogDev->Common.Self);
+  DeviceRelations->Objects[0] = PdoExt->Common.Self;
+  ObReferenceObject(PdoExt->Common.Self);
 
   Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
 
@@ -38,11 +38,12 @@ IsaPdoQueryDeviceRelations(
 NTSTATUS
 NTAPI
 IsaPdoQueryCapabilities(
-  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PISAPNP_PDO_EXTENSION PdoExt,
   IN PIRP Irp,
   IN PIO_STACK_LOCATION IrpSp)
 {
   PDEVICE_CAPABILITIES DeviceCapabilities;
+  PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
 
   DeviceCapabilities = IrpSp->Parameters.DeviceCapabilities.Capabilities;
   if (DeviceCapabilities->Version != 1)
@@ -57,10 +58,11 @@ IsaPdoQueryCapabilities(
 NTSTATUS
 NTAPI
 IsaPdoQueryId(
-  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PISAPNP_PDO_EXTENSION PdoExt,
   IN PIRP Irp,
   IN PIO_STACK_LOCATION IrpSp)
 {
+  PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
   WCHAR Temp[256];
   PWCHAR Buffer, End;
   ULONG Length;
@@ -140,7 +142,7 @@ IsaPdoQueryId(
 NTSTATUS
 NTAPI
 IsaPdoPnp(
-  IN PISAPNP_LOGICAL_DEVICE LogDev,
+  IN PISAPNP_PDO_EXTENSION PdoExt,
   IN PIRP Irp,
   IN PIO_STACK_LOCATION IrpSp)
 {
@@ -149,25 +151,25 @@ IsaPdoPnp(
   switch (IrpSp->MinorFunction)
   {
      case IRP_MN_START_DEVICE:
-       Status = IsaHwActivateDevice(LogDev);
+       Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
 
        if (NT_SUCCESS(Status))
-           LogDev->Common.State = dsStarted;
+           PdoExt->Common.State = dsStarted;
        break;
 
      case IRP_MN_STOP_DEVICE:
-       Status = IsaHwDeactivateDevice(LogDev);
+       Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
 
        if (NT_SUCCESS(Status))
-           LogDev->Common.State = dsStopped;
+           PdoExt->Common.State = dsStopped;
        break;
 
      case IRP_MN_QUERY_DEVICE_RELATIONS:
-       Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp);
+       Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp);
        break;
 
      case IRP_MN_QUERY_CAPABILITIES:
-       Status = IsaPdoQueryCapabilities(LogDev, Irp, IrpSp);
+       Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp);
        break;
 
      case IRP_MN_QUERY_RESOURCES:
@@ -179,7 +181,7 @@ IsaPdoPnp(
        break;
 
      case IRP_MN_QUERY_ID:
-       Status = IsaPdoQueryId(LogDev, Irp, IrpSp);
+       Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
        break;
 
      default:

Reply via email to