From 4ba8a8b59bebabd941e42d14493e4cd02a3e5972 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Sun, 15 Jan 2023 22:41:49 +0600 Subject: [PATCH] [ISAPNP] Allocate the Read Port resources on demand This will simplify failure paths and reduce memory usage --- drivers/bus/isapnp/isapnp.c | 43 ++++++------------------------------- drivers/bus/isapnp/isapnp.h | 28 ++++++++++++++++++------ drivers/bus/isapnp/pdo.c | 35 +++++++++++++++++++----------- 3 files changed, 50 insertions(+), 56 deletions(-) diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 0ff17876e75..514322c69c0 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -1038,9 +1038,8 @@ IsaForwardOrIgnore( } CODE_SEG("PAGE") -NTSTATUS +PIO_RESOURCE_REQUIREMENTS_LIST IsaPnpCreateReadPortDORequirements( - _In_ PISAPNP_PDO_EXTENSION PdoExt, _In_opt_ ULONG SelectedReadPort) { ULONG ResourceCount, ListSize, i; @@ -1087,7 +1086,7 @@ IsaPnpCreateReadPortDORequirements( sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1); RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP); if (!RequirementsList) - return STATUS_NO_MEMORY; + return NULL; RequirementsList->ListSize = ListSize; RequirementsList->AlternativeLists = 1; @@ -1182,15 +1181,12 @@ IsaPnpCreateReadPortDORequirements( } } - PdoExt->RequirementsList = RequirementsList; - return STATUS_SUCCESS; + return RequirementsList; } -static CODE_SEG("PAGE") -NTSTATUS -IsaPnpCreateReadPortDOResources( - _In_ PISAPNP_PDO_EXTENSION PdoExt) +PCM_RESOURCE_LIST +IsaPnpCreateReadPortDOResources(VOID) { const USHORT Ports[] = { ISAPNP_WRITE_DATA, ISAPNP_ADDRESS }; ULONG ListSize, i; @@ -1203,7 +1199,7 @@ IsaPnpCreateReadPortDOResources( sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (RTL_NUMBER_OF(Ports) - 1); ResourceList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP); if (!ResourceList) - return STATUS_NO_MEMORY; + return NULL; ResourceList->Count = 1; ResourceList->List[0].InterfaceType = Internal; @@ -1223,9 +1219,7 @@ IsaPnpCreateReadPortDOResources( Descriptor++; } - PdoExt->ResourceList = ResourceList; - PdoExt->ResourceListSize = ListSize; - return STATUS_SUCCESS; + return ResourceList; } static @@ -1259,23 +1253,8 @@ IsaPnpCreateReadPortDO( PdoExt->Common.State = dsStopped; PdoExt->FdoExt = FdoExt; - Status = IsaPnpCreateReadPortDORequirements(PdoExt, 0); - if (!NT_SUCCESS(Status)) - goto Failure; - - Status = IsaPnpCreateReadPortDOResources(PdoExt); - if (!NT_SUCCESS(Status)) - goto Failure; - FdoExt->ReadPortPdo->Flags &= ~DO_DEVICE_INITIALIZING; - return Status; - -Failure: - IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo); - - FdoExt->ReadPortPdo = NULL; - return Status; } @@ -1284,18 +1263,10 @@ VOID IsaPnpRemoveReadPortDO( _In_ PDEVICE_OBJECT Pdo) { - PISAPNP_PDO_EXTENSION ReadPortExt = Pdo->DeviceExtension; - PAGED_CODE(); DPRINT("Removing Read Port\n"); - if (ReadPortExt->RequirementsList) - ExFreePoolWithTag(ReadPortExt->RequirementsList, TAG_ISAPNP); - - if (ReadPortExt->ResourceList) - ExFreePoolWithTag(ReadPortExt->ResourceList, TAG_ISAPNP); - IoDeleteDevice(Pdo); } diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h index ad48008251f..ea84d2d5148 100644 --- a/drivers/bus/isapnp/isapnp.h +++ b/drivers/bus/isapnp/isapnp.h @@ -176,12 +176,7 @@ typedef struct _ISAPNP_FDO_EXTENSION typedef struct _ISAPNP_PDO_EXTENSION { ISAPNP_COMMON_EXTENSION Common; - PISAPNP_LOGICAL_DEVICE IsaPnpDevice; PISAPNP_FDO_EXTENSION FdoExt; - PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; - - PCM_RESOURCE_LIST ResourceList; - ULONG ResourceListSize; ULONG Flags; #define ISAPNP_ENUMERATED 0x00000001 /**< @brief Whether the device has been reported to the PnP manager. */ @@ -189,6 +184,22 @@ typedef struct _ISAPNP_PDO_EXTENSION #define ISAPNP_READ_PORT_ALLOW_FDO_SCAN 0x00000004 /**< @brief Allows the active FDO to scan the bus. */ #define ISAPNP_READ_PORT_NEED_REBALANCE 0x00000008 /**< @brief The I/O resource requirements have changed. */ + union + { + /* Data belonging to logical devices */ + struct + { + PISAPNP_LOGICAL_DEVICE IsaPnpDevice; + + PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; + + PCM_RESOURCE_LIST ResourceList; + ULONG ResourceListSize; + }; + + ULONG SelectedPort; + }; + _Write_guarded_by_(_Global_interlock_) volatile LONG SpecialFiles; } ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION; @@ -315,11 +326,14 @@ FindMemoryDescriptor( _Out_opt_ PUCHAR WriteOrder); CODE_SEG("PAGE") -NTSTATUS +PIO_RESOURCE_REQUIREMENTS_LIST IsaPnpCreateReadPortDORequirements( - _In_ PISAPNP_PDO_EXTENSION PdoExt, _In_opt_ ULONG SelectedReadPort); +CODE_SEG("PAGE") +PCM_RESOURCE_LIST +IsaPnpCreateReadPortDOResources(VOID); + CODE_SEG("PAGE") VOID IsaPnpRemoveReadPortDO( diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c index 3946ce31485..5e8979ad274 100644 --- a/drivers/bus/isapnp/pdo.c +++ b/drivers/bus/isapnp/pdo.c @@ -478,8 +478,17 @@ IsaPdoQueryResources( PAGED_CODE(); - if (PdoExt->Common.Signature == IsaPnpLogicalDevice && - !(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES)) + if (PdoExt->Common.Signature == IsaPnpReadDataPort) + { + ResourceList = IsaPnpCreateReadPortDOResources(); + if (!ResourceList) + return STATUS_NO_MEMORY; + + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + return STATUS_SUCCESS; + } + + if (!(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES)) { Irp->IoStatus.Information = 0; return STATUS_SUCCESS; @@ -513,6 +522,16 @@ IsaPdoQueryResourceRequirements( PAGED_CODE(); + if (PdoExt->Common.Signature == IsaPnpReadDataPort) + { + RequirementsList = IsaPnpCreateReadPortDORequirements(PdoExt->SelectedPort); + if (!RequirementsList) + return STATUS_NO_MEMORY; + + Irp->IoStatus.Information = (ULONG_PTR)RequirementsList; + return STATUS_SUCCESS; + } + if (!PdoExt->RequirementsList) return Irp->IoStatus.Status; @@ -593,19 +612,9 @@ IsaPdoStartReadPort( ASSERT(SelectedPort != 0); - if (PdoExt->RequirementsList) - { - ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP); - PdoExt->RequirementsList = NULL; - } - /* Discard the Read Ports at conflicting locations */ - Status = IsaPnpCreateReadPortDORequirements(PdoExt, SelectedPort); - if (!NT_SUCCESS(Status)) - return Status; - + PdoExt->SelectedPort = SelectedPort; PdoExt->Flags |= ISAPNP_READ_PORT_NEED_REBALANCE; - IoInvalidateDeviceState(PdoExt->Common.Self); return STATUS_SUCCESS;