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 +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; }