https://git.reactos.org/?p=reactos.git;a=commitdiff;h=21514e473f5969f90811872f5993f3accc3f1ddb

commit 21514e473f5969f90811872f5993f3accc3f1ddb
Author:     Dmitry Borisov <[email protected]>
AuthorDate: Thu Mar 4 18:45:38 2021 +0600
Commit:     Dmitry Borisov <[email protected]>
CommitDate: Sun Jun 20 19:22:32 2021 +0600

    [ISAPNP] Make Read Data Port PDO unique
    
    This PDO is created only once during start of first FDO.
    Other buses will remain in an inactive state until
    the first FDO receives a remove request.
    
    CORE-17034
---
 drivers/bus/isapnp/isapnp.c | 223 +++++++++++++++++++++++++-------------------
 1 file changed, 128 insertions(+), 95 deletions(-)

diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index d5aea3de39e..aa0ae2b6433 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -11,6 +11,8 @@
 #define NDEBUG
 #include <debug.h>
 
+BOOLEAN ReadPortCreated = FALSE;
+
 static
 CODE_SEG("PAGE")
 NTSTATUS
@@ -299,94 +301,6 @@ IsaPnpCreateLogicalDeviceResources(
     return STATUS_SUCCESS;
 }
 
-CODE_SEG("PAGE")
-NTSTATUS
-IsaPnpFillDeviceRelations(
-    _In_ PISAPNP_FDO_EXTENSION FdoExt,
-    _Inout_ PIRP Irp,
-    _In_ BOOLEAN IncludeDataPort)
-{
-    PISAPNP_PDO_EXTENSION PdoExt;
-    NTSTATUS Status = STATUS_SUCCESS;
-    PLIST_ENTRY CurrentEntry;
-    PISAPNP_LOGICAL_DEVICE IsaDevice;
-    PDEVICE_RELATIONS DeviceRelations;
-    ULONG i = 0;
-
-    PAGED_CODE();
-
-    DeviceRelations = ExAllocatePool(NonPagedPool,
-                                     sizeof(DEVICE_RELATIONS) + 
sizeof(DEVICE_OBJECT) * FdoExt->DeviceCount);
-    if (!DeviceRelations)
-    {
-        return STATUS_NO_MEMORY;
-    }
-
-    if (IncludeDataPort)
-    {
-        DeviceRelations->Objects[i++] = FdoExt->ReadPortPdo;
-        ObReferenceObject(FdoExt->ReadPortPdo);
-    }
-
-    CurrentEntry = FdoExt->DeviceListHead.Flink;
-    while (CurrentEntry != &FdoExt->DeviceListHead)
-    {
-        IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, 
DeviceLink);
-
-        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;
-            }
-
-            IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
-
-            //Device->Pdo->Flags |= DO_POWER_PAGABLE;
-
-            PdoExt = 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;
-            PdoExt->FdoExt = FdoExt;
-
-            Status = IsaPnpCreateLogicalDeviceRequirements(PdoExt);
-
-            if (NT_SUCCESS(Status))
-                Status = IsaPnpCreateLogicalDeviceResources(PdoExt);
-
-            if (!NT_SUCCESS(Status))
-            {
-                IoDeleteDevice(IsaDevice->Pdo);
-                IsaDevice->Pdo = NULL;
-                break;
-            }
-        }
-        DeviceRelations->Objects[i++] = IsaDevice->Pdo;
-
-        ObReferenceObject(IsaDevice->Pdo);
-
-        CurrentEntry = CurrentEntry->Flink;
-    }
-
-    DeviceRelations->Count = i;
-
-    Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
-
-    return Status;
-}
-
 static IO_COMPLETION_ROUTINE ForwardIrpCompletion;
 
 static
@@ -603,6 +517,9 @@ IsaPnpCreateReadPortDO(
     NTSTATUS Status;
 
     PAGED_CODE();
+    ASSERT(ReadPortCreated == FALSE);
+
+    DPRINT("Creating Read Port\n");
 
     Status = IoCreateDevice(FdoExt->DriverObject,
                             sizeof(ISAPNP_PDO_EXTENSION),
@@ -623,11 +540,132 @@ IsaPnpCreateReadPortDO(
 
     Status = IsaPnpCreateReadPortDORequirements(PdoExt);
     if (!NT_SUCCESS(Status))
-        return Status;
+        goto Failure;
 
     Status = IsaPnpCreateReadPortDOResources(PdoExt);
     if (!NT_SUCCESS(Status))
-        return Status;
+        goto Failure;
+
+    FdoExt->ReadPortPdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    return Status;
+
+Failure:
+    if (PdoExt->RequirementsList)
+        ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP);
+
+    if (PdoExt->ResourceList)
+        ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP);
+
+    IoDeleteDevice(FdoExt->ReadPortPdo);
+
+    return Status;
+}
+
+CODE_SEG("PAGE")
+NTSTATUS
+IsaPnpFillDeviceRelations(
+    _In_ PISAPNP_FDO_EXTENSION FdoExt,
+    _Inout_ PIRP Irp,
+    _In_ BOOLEAN IncludeDataPort)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PLIST_ENTRY CurrentEntry;
+    PISAPNP_LOGICAL_DEVICE IsaDevice;
+    PDEVICE_RELATIONS DeviceRelations;
+    ULONG PdoCount, i = 0;
+
+    PAGED_CODE();
+
+    /* Try to claim the Read Port for our FDO */
+    if (!ReadPortCreated)
+    {
+        Status = IsaPnpCreateReadPortDO(FdoExt);
+        if (!NT_SUCCESS(Status))
+            return Status;
+
+        ReadPortCreated = TRUE;
+    }
+
+    /* Inactive ISA bus */
+    if (!FdoExt->ReadPortPdo)
+        IncludeDataPort = FALSE;
+
+    PdoCount = FdoExt->DeviceCount;
+    if (IncludeDataPort)
+        ++PdoCount;
+
+    DeviceRelations = ExAllocatePoolWithTag(PagedPool,
+                                            FIELD_OFFSET(DEVICE_RELATIONS, 
Objects[PdoCount]),
+                                            TAG_ISAPNP);
+    if (!DeviceRelations)
+    {
+        return STATUS_NO_MEMORY;
+    }
+
+    if (IncludeDataPort)
+    {
+        DeviceRelations->Objects[i++] = FdoExt->ReadPortPdo;
+        ObReferenceObject(FdoExt->ReadPortPdo);
+    }
+
+    CurrentEntry = FdoExt->DeviceListHead.Flink;
+    while (CurrentEntry != &FdoExt->DeviceListHead)
+    {
+        PISAPNP_PDO_EXTENSION PdoExt;
+
+        IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, 
DeviceLink);
+
+        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;
+            }
+
+            IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+            //Device->Pdo->Flags |= DO_POWER_PAGABLE;
+
+            PdoExt = 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;
+            PdoExt->FdoExt = FdoExt;
+
+            Status = IsaPnpCreateLogicalDeviceRequirements(PdoExt);
+
+            if (NT_SUCCESS(Status))
+                Status = IsaPnpCreateLogicalDeviceResources(PdoExt);
+
+            if (!NT_SUCCESS(Status))
+            {
+                IoDeleteDevice(IsaDevice->Pdo);
+                IsaDevice->Pdo = NULL;
+                break;
+            }
+        }
+        DeviceRelations->Objects[i++] = IsaDevice->Pdo;
+
+        ObReferenceObject(IsaDevice->Pdo);
+
+        CurrentEntry = CurrentEntry->Flink;
+    }
+
+    DeviceRelations->Count = i;
+
+    Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
 
     return Status;
 }
@@ -677,12 +715,7 @@ IsaAddDevice(
     InitializeListHead(&FdoExt->DeviceListHead);
     KeInitializeEvent(&FdoExt->DeviceSyncEvent, SynchronizationEvent, TRUE);
 
-    Status = IsaPnpCreateReadPortDO(FdoExt);
-    if (!NT_SUCCESS(Status))
-        return Status;
-
     Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
-    FdoExt->ReadPortPdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
     return STATUS_SUCCESS;
 }

Reply via email to