https://git.reactos.org/?p=reactos.git;a=commitdiff;h=21514e473f5969f908118…
commit 21514e473f5969f90811872f5993f3accc3f1ddb
Author: Dmitry Borisov <di.sean(a)protonmail.com>
AuthorDate: Thu Mar 4 18:45:38 2021 +0600
Commit: Dmitry Borisov <di.sean(a)protonmail.com>
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;
}