https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f15de1555420f87aa20c2c...
commit f15de1555420f87aa20c2cfaeb07a1e46846e350 Author: Dmitry Borisov di.sean@protonmail.com AuthorDate: Thu Mar 4 18:48:43 2021 +0600 Commit: Dmitry Borisov di.sean@protonmail.com CommitDate: Sun Jun 20 19:24:26 2021 +0600
[ISAPNP] Fixes and improvements for IRP handling
- Implement device removal. - Finish the Read Port special handling introduced in 21514e473f5. - Gracefully handle low memory situations. - Implement IRQ translator. - Correctly stub power IRP handling. - Remove unneeded dispatch routines; implement WMI IRP handling. - Do not handle requests like WRITE_CONFIG. - Add a signature member to device extensions to make checks clearer. --- drivers/bus/isapnp/CMakeLists.txt | 1 + drivers/bus/isapnp/fdo.c | 166 +++++++++++++++++---- drivers/bus/isapnp/interface.c | 73 ++++++++++ drivers/bus/isapnp/isapnp.c | 295 ++++++++++++++++++++++++-------------- drivers/bus/isapnp/isapnp.h | 80 +++++++++-- drivers/bus/isapnp/pdo.c | 292 +++++++++++++++++++++++++++---------- 6 files changed, 682 insertions(+), 225 deletions(-)
diff --git a/drivers/bus/isapnp/CMakeLists.txt b/drivers/bus/isapnp/CMakeLists.txt index 0d91dbf2691..6b8a6747546 100644 --- a/drivers/bus/isapnp/CMakeLists.txt +++ b/drivers/bus/isapnp/CMakeLists.txt @@ -4,6 +4,7 @@ list(APPEND SOURCE pdo.c fdo.c hardware.c + interface.c isapnp.h)
add_library(isapnp MODULE ${SOURCE} isapnp.rc) diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c index 7b32e790246..5d61c8b2dc4 100644 --- a/drivers/bus/isapnp/fdo.c +++ b/drivers/bus/isapnp/fdo.c @@ -4,6 +4,7 @@ * PURPOSE: FDO-specific code * COPYRIGHT: Copyright 2010 Cameron Gutman cameron.gutman@reactos.org * Copyright 2020 Hervé Poussineau hpoussin@reactos.org + * Copyright 2021 Dmitry Borisov di.sean@protonmail.com */
#include "isapnp.h" @@ -16,14 +17,22 @@ CODE_SEG("PAGE") NTSTATUS IsaFdoStartDevice( _In_ PISAPNP_FDO_EXTENSION FdoExt, - _Inout_ PIRP Irp, - _In_ PIO_STACK_LOCATION IrpSp) + _Inout_ PIRP Irp) { - UNREFERENCED_PARAMETER(Irp); - UNREFERENCED_PARAMETER(IrpSp); + NTSTATUS Status;
PAGED_CODE();
+ if (!IoForwardIrpSynchronously(FdoExt->Ldo, Irp)) + { + return STATUS_UNSUCCESSFUL; + } + Status = Irp->IoStatus.Status; + if (!NT_SUCCESS(Status)) + { + return Status; + } + FdoExt->Common.State = dsStarted;
return STATUS_SUCCESS; @@ -32,19 +41,83 @@ IsaFdoStartDevice( static CODE_SEG("PAGE") NTSTATUS -IsaFdoQueryDeviceRelations( +IsaFdoQueryBusRelations( _In_ PISAPNP_FDO_EXTENSION FdoExt, - _Inout_ PIRP Irp, - _In_ PIO_STACK_LOCATION IrpSp) + _Inout_ PIRP Irp) { PAGED_CODE();
- if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) - return Irp->IoStatus.Status; - return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE); }
+static +CODE_SEG("PAGE") +NTSTATUS +IsaFdoRemoveDevice( + _In_ PISAPNP_FDO_EXTENSION FdoExt, + _Inout_ PIRP Irp) +{ + NTSTATUS Status; + PLIST_ENTRY Entry; + + PAGED_CODE(); + + IsaPnpAcquireDeviceDataLock(FdoExt); + + /* Remove our logical devices */ + while (!IsListEmpty(&FdoExt->DeviceListHead)) + { + PISAPNP_LOGICAL_DEVICE LogDevice = CONTAINING_RECORD(RemoveHeadList(&FdoExt-> + DeviceListHead), + ISAPNP_LOGICAL_DEVICE, + DeviceLink); + + --FdoExt->DeviceCount; + + if (LogDevice->Pdo) + { + IsaPnpRemoveLogicalDeviceDO(LogDevice->Pdo); + } + } + + IsaPnpReleaseDeviceDataLock(FdoExt); + + IsaPnpAcquireBusDataLock(); + + /* Remove the Read Port */ + if (FdoExt->ReadPortPdo) + { + IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo); + ReadPortCreated = FALSE; + } + + /* Find the next ISA bus, if any */ + Entry = BusListHead.Flink; + if (Entry != &BusListHead) + { + PISAPNP_FDO_EXTENSION NextIsaBus = CONTAINING_RECORD(Entry, + ISAPNP_FDO_EXTENSION, + BusLink); + + /* Create a new Read Port for it */ + if (!ReadPortCreated) + IoInvalidateDeviceRelations(NextIsaBus->Pdo, BusRelations); + } + + RemoveEntryList(&FdoExt->BusLink); + + IsaPnpReleaseBusDataLock(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(FdoExt->Ldo, Irp); + + IoDetachDevice(FdoExt->Ldo); + IoDeleteDevice(FdoExt->Common.Self); + + return Status; +} + CODE_SEG("PAGE") NTSTATUS IsaFdoPnp( @@ -52,43 +125,82 @@ IsaFdoPnp( _Inout_ PIRP Irp, _In_ PIO_STACK_LOCATION IrpSp) { - NTSTATUS Status = Irp->IoStatus.Status; + NTSTATUS Status;
PAGED_CODE();
+ DPRINT("%s(%p, %p) FDO %lu, Minor - %X\n", + __FUNCTION__, + FdoExt, + Irp, + FdoExt->BusNumber, + IrpSp->MinorFunction); + switch (IrpSp->MinorFunction) { case IRP_MN_START_DEVICE: - Status = IsaForwardIrpSynchronous(FdoExt, Irp); - - if (NT_SUCCESS(Status)) - Status = IsaFdoStartDevice(FdoExt, Irp, IrpSp); + Status = IsaFdoStartDevice(FdoExt, Irp);
Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status;
- case IRP_MN_STOP_DEVICE: - FdoExt->Common.State = dsStopped; + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) + break;
- Status = STATUS_SUCCESS; - break; + Status = IsaFdoQueryBusRelations(FdoExt, Irp); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT);
- case IRP_MN_QUERY_DEVICE_RELATIONS: - Status = IsaFdoQueryDeviceRelations(FdoExt, Irp, IrpSp); + return Status; + }
Irp->IoStatus.Status = Status; + break; + }
- IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; + case IRP_MN_REMOVE_DEVICE: + return IsaFdoRemoveDevice(FdoExt, Irp);
- case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: - DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); + case IRP_MN_QUERY_PNP_DEVICE_STATE: + Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + + case IRP_MN_QUERY_INTERFACE: + { + Status = IsaFdoQueryInterface(FdoExt, IrpSp); + if (Status == STATUS_NOT_SUPPORTED) + { + break; + } + else if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; + } + + Irp->IoStatus.Status = Status; + break; + } + + case IRP_MN_SURPRISE_REMOVAL: + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_STOP_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + case IRP_MN_STOP_DEVICE: + Irp->IoStatus.Status = STATUS_SUCCESS; break;
default: - DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction); + DPRINT("Unknown PnP code: %X\n", IrpSp->MinorFunction); break; }
diff --git a/drivers/bus/isapnp/interface.c b/drivers/bus/isapnp/interface.c new file mode 100644 index 00000000000..057589bb35a --- /dev/null +++ b/drivers/bus/isapnp/interface.c @@ -0,0 +1,73 @@ +/* + * PROJECT: ReactOS ISA PnP Bus driver + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Driver interface + * COPYRIGHT: Copyright 2021 Dmitry Borisov di.sean@protonmail.com + */ + +/* INCLUDES *******************************************************************/ + +#include "isapnp.h" + +#define NDEBUG +#include <debug.h> + +/* FUNCTIONS ******************************************************************/ + +CODE_SEG("PAGE") +NTSTATUS +IsaFdoQueryInterface( + _In_ PISAPNP_FDO_EXTENSION FdoExt, + _In_ PIO_STACK_LOCATION IrpSp) +{ + PAGED_CODE(); + + if (IsEqualGUIDAligned(IrpSp->Parameters.QueryInterface.InterfaceType, + &GUID_TRANSLATOR_INTERFACE_STANDARD)) + { + NTSTATUS Status; + CM_RESOURCE_TYPE ResourceType; + ULONG ParentBusType, ParentBusNumber, Dummy; + + ResourceType = PtrToUlong(IrpSp->Parameters.QueryInterface.InterfaceSpecificData); + + if (IrpSp->Parameters.QueryInterface.Size < sizeof(TRANSLATOR_INTERFACE) || + ResourceType != CmResourceTypeInterrupt) + { + return STATUS_NOT_SUPPORTED; + } + + Status = IoGetDeviceProperty(FdoExt->Pdo, + DevicePropertyLegacyBusType, + sizeof(ParentBusType), + &ParentBusType, + &Dummy); + if (!NT_SUCCESS(Status)) + { + DPRINT1("BusType request failed with status 0x%08lx\n", Status); + return Status; + } + + Status = IoGetDeviceProperty(FdoExt->Pdo, + DevicePropertyBusNumber, + sizeof(ParentBusNumber), + &ParentBusNumber, + &Dummy); + if (!NT_SUCCESS(Status)) + { + DPRINT1("BusNumber request failed with status 0x%08lx\n", Status); + return Status; + } + + return HalGetInterruptTranslator(ParentBusType, + ParentBusNumber, + Isa, + IrpSp->Parameters.QueryInterface.Size, + IrpSp->Parameters.QueryInterface.Version, + (PTRANSLATOR_INTERFACE)IrpSp-> + Parameters.QueryInterface.Interface, + &ParentBusNumber); + } + + return STATUS_NOT_SUPPORTED; +} diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index c477fecf767..148dfb6b090 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -4,15 +4,28 @@ * PURPOSE: Driver entry * COPYRIGHT: Copyright 2010 Cameron Gutman cameron.gutman@reactos.org * Copyright 2020 Hervé Poussineau hpoussin@reactos.org + * Copyright 2021 Dmitry Borisov di.sean@protonmail.com */
+/* INCLUDES *******************************************************************/ + #include "isapnp.h"
#define NDEBUG #include <debug.h>
+/* GLOBALS ********************************************************************/ + +KEVENT BusSyncEvent; + +_Guarded_by_(BusSyncEvent) BOOLEAN ReadPortCreated = FALSE;
+_Guarded_by_(BusSyncEvent) +LIST_ENTRY BusListHead; + +/* FUNCTIONS ******************************************************************/ + static CODE_SEG("PAGE") NTSTATUS @@ -301,49 +314,6 @@ IsaPnpCreateLogicalDeviceResources( return STATUS_SUCCESS; }
-static IO_COMPLETION_ROUTINE ForwardIrpCompletion; - -static -NTSTATUS -NTAPI -ForwardIrpCompletion( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - UNREFERENCED_PARAMETER(DeviceObject); - - if (Irp->PendingReturned) - KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); - - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -NTAPI -IsaForwardIrpSynchronous( - IN PISAPNP_FDO_EXTENSION FdoExt, - IN PIRP Irp) -{ - KEVENT Event; - NTSTATUS Status; - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - IoCopyCurrentIrpStackLocationToNext(Irp); - - IoSetCompletionRoutine(Irp, ForwardIrpCompletion, &Event, TRUE, TRUE, TRUE); - - Status = IoCallDriver(FdoExt->Ldo, Irp); - if (Status == STATUS_PENDING) - { - Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); - if (NT_SUCCESS(Status)) - Status = Irp->IoStatus.Status; - } - - return Status; -} - _Dispatch_type_(IRP_MJ_CREATE) _Dispatch_type_(IRP_MJ_CLOSE) static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaCreateClose; @@ -359,7 +329,6 @@ IsaCreateClose( PAGED_CODE();
Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = FILE_OPENED;
DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
@@ -368,51 +337,37 @@ IsaCreateClose( return STATUS_SUCCESS; }
-static DRIVER_DISPATCH IsaIoctl; +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) +_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) +static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaForwardOrIgnore;
static +CODE_SEG("PAGE") NTSTATUS NTAPI -IsaIoctl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) +IsaForwardOrIgnore( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) { - PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - NTSTATUS Status; + PISAPNP_COMMON_EXTENSION CommonExt = DeviceObject->DeviceExtension;
- DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); + PAGED_CODE(); + + DPRINT("%s(%p, %p) Minor - %X\n", __FUNCTION__, DeviceObject, Irp, + IoGetCurrentIrpStackLocation(Irp)->MinorFunction);
- switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) + if (CommonExt->Signature == IsaPnpBus) { - default: - DPRINT1("Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); - Status = STATUS_NOT_SUPPORTED; - break; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(((PISAPNP_FDO_EXTENSION)CommonExt)->Ldo, Irp); } + else + { + NTSTATUS Status = Irp->IoStatus.Status;
- Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return Status; -} - -static DRIVER_DISPATCH IsaReadWrite; - -static -NTSTATUS -NTAPI -IsaReadWrite( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); - - Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_NOT_SUPPORTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } }
static @@ -533,7 +488,7 @@ IsaPnpCreateReadPortDO(
PdoExt = FdoExt->ReadPortPdo->DeviceExtension; RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION)); - PdoExt->Common.IsFdo = FALSE; + PdoExt->Common.Signature = IsaPnpReadDataPort; PdoExt->Common.Self = FdoExt->ReadPortPdo; PdoExt->Common.State = dsStopped; PdoExt->FdoExt = FdoExt; @@ -551,17 +506,33 @@ IsaPnpCreateReadPortDO( return Status;
Failure: - if (PdoExt->RequirementsList) - ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP); + IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo);
- if (PdoExt->ResourceList) - ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP); - - IoDeleteDevice(FdoExt->ReadPortPdo); + FdoExt->ReadPortPdo = NULL;
return Status; }
+CODE_SEG("PAGE") +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); +} + CODE_SEG("PAGE") NTSTATUS IsaPnpFillDeviceRelations( @@ -577,6 +548,8 @@ IsaPnpFillDeviceRelations(
PAGED_CODE();
+ IsaPnpAcquireBusDataLock(); + /* Try to claim the Read Port for our FDO */ if (!ReadPortCreated) { @@ -587,26 +560,68 @@ IsaPnpFillDeviceRelations( ReadPortCreated = TRUE; }
+ IsaPnpReleaseBusDataLock(); + /* Inactive ISA bus */ if (!FdoExt->ReadPortPdo) IncludeDataPort = FALSE;
+ IsaPnpAcquireDeviceDataLock(FdoExt); + + /* If called from the FDO dispatch routine && Active bus */ + if (IncludeDataPort && FdoExt->ReadPortPdo) + { + PISAPNP_PDO_EXTENSION ReadPortExt = FdoExt->ReadPortPdo->DeviceExtension; + + if ((ReadPortExt->Flags & ISAPNP_READ_PORT_ALLOW_FDO_SCAN) && + !(ReadPortExt->Flags & ISAPNP_SCANNED_BY_READ_PORT)) + { + DPRINT("Rescan ISA PnP bus\n"); + + /* Run the isolation protocol */ + if (NT_SUCCESS(IsaHwTryReadDataPort(FdoExt->ReadDataPort))) + { + /* Card identification */ + (VOID)IsaHwFillDeviceList(FdoExt); + } + } + + ReadPortExt->Flags &= ~ISAPNP_SCANNED_BY_READ_PORT; + } + PdoCount = FdoExt->DeviceCount; if (IncludeDataPort) ++PdoCount;
+ CurrentEntry = FdoExt->DeviceListHead.Flink; + while (CurrentEntry != &FdoExt->DeviceListHead) + { + IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceLink); + + if (!(IsaDevice->Flags & ISAPNP_PRESENT)) + --PdoCount; + + CurrentEntry = CurrentEntry->Flink; + } + DeviceRelations = ExAllocatePoolWithTag(PagedPool, FIELD_OFFSET(DEVICE_RELATIONS, Objects[PdoCount]), TAG_ISAPNP); if (!DeviceRelations) { + IsaPnpReleaseDeviceDataLock(FdoExt); return STATUS_NO_MEMORY; }
if (IncludeDataPort) { + PISAPNP_PDO_EXTENSION ReadPortExt = FdoExt->ReadPortPdo->DeviceExtension; + DeviceRelations->Objects[i++] = FdoExt->ReadPortPdo; ObReferenceObject(FdoExt->ReadPortPdo); + + /* The Read Port PDO can only be removed by FDO */ + ReadPortExt->Flags |= ISAPNP_ENUMERATED; }
CurrentEntry = FdoExt->DeviceListHead.Flink; @@ -616,6 +631,9 @@ IsaPnpFillDeviceRelations(
IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceLink);
+ if (!(IsaDevice->Flags & ISAPNP_PRESENT)) + goto SkipPdo; + if (!IsaDevice->Pdo) { Status = IoCreateDevice(FdoExt->DriverObject, @@ -626,43 +644,66 @@ IsaPnpFillDeviceRelations( FALSE, &IsaDevice->Pdo); if (!NT_SUCCESS(Status)) - { - break; - } + goto SkipPdo;
IsaDevice->Pdo->Flags &= ~DO_DEVICE_INITIALIZING; - - //Device->Pdo->Flags |= DO_POWER_PAGABLE; + /* The power pagable flag is always unset */
PdoExt = IsaDevice->Pdo->DeviceExtension;
RtlZeroMemory(PdoExt, sizeof(ISAPNP_PDO_EXTENSION)); - - PdoExt->Common.IsFdo = FALSE; + PdoExt->Common.Signature = IsaPnpLogicalDevice; 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)) + if (!NT_SUCCESS(IsaPnpCreateLogicalDeviceRequirements(PdoExt)) || + !NT_SUCCESS(IsaPnpCreateLogicalDeviceResources(PdoExt))) { + if (PdoExt->RequirementsList) + { + ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP); + PdoExt->RequirementsList = NULL; + } + + if (PdoExt->ResourceList) + { + ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP); + PdoExt->ResourceList = NULL; + } + IoDeleteDevice(IsaDevice->Pdo); IsaDevice->Pdo = NULL; - break; + goto SkipPdo; } } + else + { + PdoExt = IsaDevice->Pdo->DeviceExtension; + } DeviceRelations->Objects[i++] = IsaDevice->Pdo; - ObReferenceObject(IsaDevice->Pdo);
+ PdoExt->Flags |= ISAPNP_ENUMERATED; + + CurrentEntry = CurrentEntry->Flink; + continue; + +SkipPdo: + if (IsaDevice->Pdo) + { + PdoExt = IsaDevice->Pdo->DeviceExtension; + + if (PdoExt) + PdoExt->Flags &= ~ISAPNP_ENUMERATED; + } + CurrentEntry = CurrentEntry->Flink; }
+ IsaPnpReleaseDeviceDataLock(FdoExt); + DeviceRelations->Count = i;
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; @@ -694,7 +735,7 @@ IsaAddDevice( NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, - TRUE, + FALSE, &Fdo); if (!NT_SUCCESS(Status)) { @@ -706,17 +747,26 @@ IsaAddDevice( RtlZeroMemory(FdoExt, sizeof(*FdoExt));
FdoExt->Common.Self = Fdo; - FdoExt->Common.IsFdo = TRUE; + FdoExt->Common.Signature = IsaPnpBus; FdoExt->Common.State = dsStopped; FdoExt->DriverObject = DriverObject; FdoExt->BusNumber = BusNumber++; FdoExt->Pdo = PhysicalDeviceObject; FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject); + if (!FdoExt->Ldo) + { + IoDeleteDevice(Fdo); + return STATUS_DEVICE_REMOVED; + }
InitializeListHead(&FdoExt->DeviceListHead); KeInitializeEvent(&FdoExt->DeviceSyncEvent, SynchronizationEvent, TRUE);
+ IsaPnpAcquireBusDataLock(); + InsertTailList(&BusListHead, &FdoExt->BusLink); + IsaPnpReleaseBusDataLock(); + Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS; @@ -735,9 +785,22 @@ IsaPower( PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension; NTSTATUS Status;
- if (!DevExt->IsFdo) + if (DevExt->Signature != IsaPnpBus) { - Status = Irp->IoStatus.Status; + switch (IoGetCurrentIrpStackLocation(Irp)->MinorFunction) + { + case IRP_MN_SET_POWER: + case IRP_MN_QUERY_POWER: + Status = STATUS_SUCCESS; + Irp->IoStatus.Status = Status; + break; + + default: + Status = Irp->IoStatus.Status; + break; + } + + PoStartNextPowerIrp(Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } @@ -763,9 +826,7 @@ IsaPnp(
PAGED_CODE();
- DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); - - if (DevExt->IsFdo) + if (DevExt->Signature == IsaPnpBus) return IsaFdoPnp((PISAPNP_FDO_EXTENSION)DevExt, Irp, IrpSp); else return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt, Irp, IrpSp); @@ -782,13 +843,25 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaCreateClose; - DriverObject->MajorFunction[IRP_MJ_READ] = IsaReadWrite; - DriverObject->MajorFunction[IRP_MJ_WRITE] = IsaReadWrite; - DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaIoctl; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaForwardOrIgnore; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsaForwardOrIgnore; DriverObject->MajorFunction[IRP_MJ_PNP] = IsaPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = IsaPower; DriverObject->DriverExtension->AddDevice = IsaAddDevice;
+ /* FIXME: Fix SDK headers */ +#if 0 + _No_competing_thread_begin_ +#endif + + KeInitializeEvent(&BusSyncEvent, SynchronizationEvent, TRUE); + InitializeListHead(&BusListHead); + + /* FIXME: Fix SDK headers */ +#if 0 + _No_competing_thread_end_ +#endif + return STATUS_SUCCESS; }
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h index 4eb7fb4e19b..e476f9737b0 100644 --- a/drivers/bus/isapnp/isapnp.h +++ b/drivers/bus/isapnp/isapnp.h @@ -9,7 +9,7 @@ #ifndef _ISAPNP_PCH_ #define _ISAPNP_PCH_
-#include <wdm.h> +#include <ntddk.h> #include <ntstrsafe.h> #include <section_attribs.h> #include "isapnphw.h" @@ -60,13 +60,24 @@ typedef struct _ISAPNP_LOGICAL_DEVICE ISAPNP_DMA Dma[2]; UCHAR CSN; UCHAR LDN; + + ULONG Flags; +#define ISAPNP_PRESENT 0x00000001 /**< @brief Cleared when the device is physically removed. */ + LIST_ENTRY DeviceLink; } ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
+typedef enum _ISAPNP_SIGNATURE +{ + IsaPnpBus = 'odFI', + IsaPnpLogicalDevice = 'veDI', + IsaPnpReadDataPort = 'pdRI' +} ISAPNP_SIGNATURE; + typedef struct _ISAPNP_COMMON_EXTENSION { + ISAPNP_SIGNATURE Signature; PDEVICE_OBJECT Self; - BOOLEAN IsFdo; ISAPNP_DEVICE_STATE State; } ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION;
@@ -75,13 +86,19 @@ typedef struct _ISAPNP_FDO_EXTENSION ISAPNP_COMMON_EXTENSION Common; PDEVICE_OBJECT Ldo; PDEVICE_OBJECT Pdo; - PDEVICE_OBJECT ReadPortPdo; + PDEVICE_OBJECT ReadPortPdo; /**< @remarks The pointer is NULL for all inactive FDOs. */ ULONG BusNumber; KEVENT DeviceSyncEvent; + + _Guarded_by_(DeviceSyncEvent) LIST_ENTRY DeviceListHead; + + _Guarded_by_(DeviceSyncEvent) ULONG DeviceCount; + PDRIVER_OBJECT DriverObject; PUCHAR ReadDataPort; + LIST_ENTRY BusLink; } ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
typedef struct _ISAPNP_PDO_EXTENSION @@ -90,10 +107,44 @@ typedef struct _ISAPNP_PDO_EXTENSION 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. */ +#define ISAPNP_SCANNED_BY_READ_PORT 0x00000002 /**< @brief The bus has been scanned by Read Port PDO. */ +#define ISAPNP_READ_PORT_ALLOW_FDO_SCAN 0x00000004 /**< @brief Allows the active FDO to scan the bus. */ + + _Write_guarded_by_(_Global_interlock_) + volatile LONG SpecialFiles; } ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION;
+extern KEVENT BusSyncEvent; + +_Guarded_by_(BusSyncEvent) +extern BOOLEAN ReadPortCreated; + +_Guarded_by_(BusSyncEvent) +extern LIST_ENTRY BusListHead; + +_Requires_lock_not_held_(BusSyncEvent) +_Acquires_lock_(BusSyncEvent) +FORCEINLINE +VOID +IsaPnpAcquireBusDataLock(VOID) +{ + KeWaitForSingleObject(&BusSyncEvent, Executive, KernelMode, FALSE, NULL); +} + +_Releases_lock_(BusSyncEvent) +FORCEINLINE +VOID +IsaPnpReleaseBusDataLock(VOID) +{ + KeSetEvent(&BusSyncEvent, IO_NO_INCREMENT, FALSE); +} + _Requires_lock_not_held_(FdoExt->DeviceSyncEvent) _Acquires_lock_(FdoExt->DeviceSyncEvent) FORCEINLINE @@ -115,6 +166,11 @@ IsaPnpReleaseDeviceDataLock(
/* isapnp.c */
+CODE_SEG("PAGE") +VOID +IsaPnpRemoveReadPortDO( + _In_ PDEVICE_OBJECT Pdo); + CODE_SEG("PAGE") NTSTATUS IsaPnpFillDeviceRelations( @@ -125,12 +181,6 @@ IsaPnpFillDeviceRelations( CODE_SEG("INIT") DRIVER_INITIALIZE DriverEntry;
-NTSTATUS -NTAPI -IsaForwardIrpSynchronous( - _In_ PISAPNP_FDO_EXTENSION FdoExt, - _Inout_ PIRP Irp); - /* fdo.c */ CODE_SEG("PAGE") NTSTATUS @@ -139,6 +189,13 @@ IsaFdoPnp( _Inout_ PIRP Irp, _In_ PIO_STACK_LOCATION IrpSp);
+/* interface.c */ +CODE_SEG("PAGE") +NTSTATUS +IsaFdoQueryInterface( + _In_ PISAPNP_FDO_EXTENSION FdoExt, + _In_ PIO_STACK_LOCATION IrpSp); + /* pdo.c */ CODE_SEG("PAGE") NTSTATUS @@ -147,6 +204,11 @@ IsaPdoPnp( _Inout_ PIRP Irp, _In_ PIO_STACK_LOCATION IrpSp);
+CODE_SEG("PAGE") +VOID +IsaPnpRemoveLogicalDeviceDO( + _In_ PDEVICE_OBJECT Pdo); + /* hardware.c */ CODE_SEG("PAGE") NTSTATUS diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c index 1fae349f9e0..27aedff6c6f 100644 --- a/drivers/bus/isapnp/pdo.c +++ b/drivers/bus/isapnp/pdo.c @@ -4,6 +4,7 @@ * PURPOSE: PDO-specific code * COPYRIGHT: Copyright 2010 Cameron Gutman cameron.gutman@reactos.org * Copyright 2020 Hervé Poussineau hpoussin@reactos.org + * Copyright 2021 Dmitry Borisov di.sean@protonmail.com */
#include "isapnp.h" @@ -24,7 +25,7 @@ IsaPdoQueryDeviceRelations( PAGED_CODE();
if (IrpSp->Parameters.QueryDeviceRelations.Type == RemovalRelations && - PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo) + PdoExt->Common.Signature == IsaPnpReadDataPort) { return IsaPnpFillDeviceRelations(PdoExt->FdoExt, Irp, FALSE); } @@ -70,8 +71,7 @@ IsaPdoQueryCapabilities(
DeviceCapabilities->UniqueID = TRUE;
- if (PdoExt->FdoExt->ReadPortPdo && - PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo) + if (PdoExt->Common.Signature == IsaPnpReadDataPort) { DeviceCapabilities->RawDeviceOK = TRUE; DeviceCapabilities->SilentInstall = TRUE; @@ -89,13 +89,17 @@ CODE_SEG("PAGE") NTSTATUS IsaPdoQueryPnpDeviceState( _In_ PISAPNP_PDO_EXTENSION PdoExt, - _Inout_ PIRP Irp, - _In_ PIO_STACK_LOCATION IrpSp) + _Inout_ PIRP Irp) { PAGED_CODE();
- Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; - return STATUS_SUCCESS; + if (PdoExt->SpecialFiles > 0) + { + Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; + return STATUS_SUCCESS; + } + + return Irp->IoStatus.Status; }
static @@ -319,6 +323,8 @@ IsaPdoQueryResources( ULONG ListSize; PCM_RESOURCE_LIST ResourceList;
+ UNREFERENCED_PARAMETER(IrpSp); + PAGED_CODE();
if (!PdoExt->ResourceList) @@ -345,6 +351,8 @@ IsaPdoQueryResourceRequirements( ULONG ListSize; PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
+ UNREFERENCED_PARAMETER(IrpSp); + PAGED_CODE();
if (!PdoExt->RequirementsList) @@ -367,6 +375,7 @@ IsaPdoStartReadPort( _In_ PISAPNP_FDO_EXTENSION FdoExt, _In_ PIO_STACK_LOCATION IrpSp) { + PISAPNP_PDO_EXTENSION PdoExt = FdoExt->ReadPortPdo->DeviceExtension; PCM_RESOURCE_LIST ResourceList = IrpSp->Parameters.StartDevice.AllocatedResources; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; ULONG i; @@ -410,6 +419,9 @@ IsaPdoStartReadPort(
if (FdoExt->DeviceCount > 0) { + PdoExt->Flags |= ISAPNP_READ_PORT_ALLOW_FDO_SCAN | + ISAPNP_SCANNED_BY_READ_PORT; + IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations); IoInvalidateDeviceRelations(FdoExt->ReadPortPdo, RemovalRelations); } @@ -426,61 +438,19 @@ IsaPdoStartReadPort( }
static +CODE_SEG("PAGE") NTSTATUS -NTAPI -IsaPdoOnRepeaterComplete( - PDEVICE_OBJECT Tdo, - PIRP SubIrp, - PVOID NeedsVote) -{ - PIO_STACK_LOCATION SubStack = IoGetCurrentIrpStackLocation(SubIrp); - PIRP Irp = (PIRP)SubStack->Parameters.Others.Argument1; - ObDereferenceObject(Tdo); - - if (SubIrp->IoStatus.Status == STATUS_NOT_SUPPORTED) - { - if (NeedsVote) - { - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - } - } - else - { - Irp->IoStatus = SubIrp->IoStatus; - } - - IoFreeIrp(SubIrp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_MORE_PROCESSING_REQUIRED; -} - -NTSTATUS -NTAPI -IsaPdoRepeatRequest( +IsaPdoFilterResourceRequirements( _In_ PISAPNP_PDO_EXTENSION PdoExt, - _In_ PIRP Irp, - _In_ BOOLEAN NeedsVote) + _Inout_ PIRP Irp, + _In_ PIO_STACK_LOCATION IrpSp) { - PDEVICE_OBJECT Fdo = PdoExt->FdoExt->Common.Self; - PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp); - PDEVICE_OBJECT Tdo = IoGetAttachedDeviceReference(Fdo); - PIRP SubIrp = IoAllocateIrp(Tdo->StackSize + 1, FALSE); - PIO_STACK_LOCATION SubStack = IoGetNextIrpStackLocation(SubIrp); - - SubStack->DeviceObject = Tdo; - SubStack->Parameters.Others.Argument1 = (PVOID)Irp; - - IoSetNextIrpStackLocation(SubIrp); - SubStack = IoGetNextIrpStackLocation(SubIrp); - RtlCopyMemory(SubStack, Stack, FIELD_OFFSET(IO_STACK_LOCATION, CompletionRoutine)); - SubStack->Control = 0; - IoSetCompletionRoutine(SubIrp, IsaPdoOnRepeaterComplete, (PVOID)(ULONG_PTR)NeedsVote, TRUE, TRUE, TRUE); - - SubIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; - IoMarkIrpPending(Irp); - IoCallDriver(Tdo, SubIrp); - - return STATUS_PENDING; + PAGED_CODE(); + + /* TODO: Handle */ + UNREFERENCED_PARAMETER(PdoExt); + UNREFERENCED_PARAMETER(IrpSp); + return Irp->IoStatus.Status; }
static @@ -508,6 +478,124 @@ IsaPdoQueryBusInformation( return STATUS_SUCCESS; }
+static +CODE_SEG("PAGE") +NTSTATUS +IsaPdoQueryDeviceUsageNotification( + _In_ PISAPNP_PDO_EXTENSION PdoExt, + _Inout_ PIRP Irp, + _In_ PIO_STACK_LOCATION IrpSp) +{ + BOOLEAN InPath = IrpSp->Parameters.UsageNotification.InPath; + + PAGED_CODE(); + + switch (IrpSp->Parameters.UsageNotification.Type) + { + case DeviceUsageTypePaging: + case DeviceUsageTypeHibernation: + case DeviceUsageTypeDumpFile: + IoAdjustPagingPathCount(&PdoExt->SpecialFiles, InPath); + IoInvalidateDeviceState(PdoExt->Common.Self); + break; + + default: + return Irp->IoStatus.Status; + } + + /* Do not send it to FDO for compatibility */ + return STATUS_SUCCESS; +} + +static +CODE_SEG("PAGE") +NTSTATUS +IsaPdoRemoveDevice( + _In_ PISAPNP_PDO_EXTENSION PdoExt, + _In_ BOOLEAN FinalRemove) +{ + PISAPNP_FDO_EXTENSION FdoExt = PdoExt->FdoExt; + + PAGED_CODE(); + + if (FinalRemove && !(PdoExt->Flags & ISAPNP_ENUMERATED)) + { + IsaPnpAcquireDeviceDataLock(FdoExt); + + RemoveEntryList(&PdoExt->IsaPnpDevice->DeviceLink); + --FdoExt->DeviceCount; + + IsaPnpReleaseDeviceDataLock(FdoExt); + + IsaPnpRemoveLogicalDeviceDO(PdoExt->Common.Self); + } + + return STATUS_SUCCESS; +} + +static +CODE_SEG("PAGE") +NTSTATUS +IsaReadPortRemoveDevice( + _In_ PISAPNP_PDO_EXTENSION PdoExt, + _In_ BOOLEAN FinalRemove) +{ + PISAPNP_FDO_EXTENSION FdoExt = PdoExt->FdoExt; + PLIST_ENTRY Entry; + + PAGED_CODE(); + + IsaPnpAcquireDeviceDataLock(FdoExt); + + /* Logical devices will receive a remove request afterwards */ + for (Entry = FdoExt->DeviceListHead.Flink; + Entry != &FdoExt->DeviceListHead; + Entry = Entry->Flink) + { + PISAPNP_LOGICAL_DEVICE LogDevice = CONTAINING_RECORD(Entry, + ISAPNP_LOGICAL_DEVICE, + DeviceLink); + + LogDevice->Flags &= ~ISAPNP_PRESENT; + } + + IsaPnpReleaseDeviceDataLock(FdoExt); + + PdoExt->Flags &= ~ISAPNP_READ_PORT_ALLOW_FDO_SCAN; + IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations); + + if (FinalRemove && !(PdoExt->Flags & ISAPNP_ENUMERATED)) + { + IsaPnpRemoveReadPortDO(PdoExt->Common.Self); + } + + return STATUS_SUCCESS; +} + +CODE_SEG("PAGE") +VOID +IsaPnpRemoveLogicalDeviceDO( + _In_ PDEVICE_OBJECT Pdo) +{ + PISAPNP_PDO_EXTENSION PdoExt = Pdo->DeviceExtension; + PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice; + + PAGED_CODE(); + ASSERT(LogDev); + + DPRINT("Removing CSN %u, LDN %u\n", LogDev->CSN, LogDev->LDN); + + if (PdoExt->RequirementsList) + ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP); + + if (PdoExt->ResourceList) + ExFreePoolWithTag(PdoExt->ResourceList, TAG_ISAPNP); + + ExFreePoolWithTag(LogDev, TAG_ISAPNP); + + IoDeleteDevice(PdoExt->Common.Self); +} + CODE_SEG("PAGE") NTSTATUS IsaPdoPnp( @@ -519,10 +607,29 @@ IsaPdoPnp(
PAGED_CODE();
+ if (PdoExt->Common.Signature == IsaPnpLogicalDevice) + { + DPRINT("%s(%p, %p) CSN %u, LDN %u, Minor - %X\n", + __FUNCTION__, + PdoExt, + Irp, + PdoExt->IsaPnpDevice->CSN, + PdoExt->IsaPnpDevice->LDN, + IrpSp->MinorFunction); + } + else + { + DPRINT("%s(%p, %p) ReadPort, Minor - %X\n", + __FUNCTION__, + PdoExt, + Irp, + IrpSp->MinorFunction); + } + switch (IrpSp->MinorFunction) { case IRP_MN_START_DEVICE: - if (PdoExt->IsaPnpDevice) + if (PdoExt->Common.Signature == IsaPnpLogicalDevice) Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice); else Status = IsaPdoStartReadPort(PdoExt->FdoExt, IrpSp); @@ -532,15 +639,36 @@ IsaPdoPnp( break;
case IRP_MN_STOP_DEVICE: - if (PdoExt->IsaPnpDevice) + if (PdoExt->Common.Signature == IsaPnpLogicalDevice) Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice); else + { + PdoExt->Flags &= ~ISAPNP_READ_PORT_ALLOW_FDO_SCAN; Status = STATUS_SUCCESS; + }
if (NT_SUCCESS(Status)) PdoExt->Common.State = dsStopped; break;
+ case IRP_MN_QUERY_STOP_DEVICE: + { + if (PdoExt->SpecialFiles > 0) + Status = STATUS_DEVICE_BUSY; + else + Status = STATUS_SUCCESS; + break; + } + + case IRP_MN_QUERY_REMOVE_DEVICE: + { + if (PdoExt->SpecialFiles > 0) + Status = STATUS_DEVICE_BUSY; + else + Status = STATUS_SUCCESS; + break; + } + case IRP_MN_QUERY_DEVICE_RELATIONS: Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp); break; @@ -549,9 +677,22 @@ IsaPdoPnp( Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp); break;
+ case IRP_MN_SURPRISE_REMOVAL: + if (PdoExt->Common.Signature == IsaPnpLogicalDevice) + Status = IsaPdoRemoveDevice(PdoExt, FALSE); + else + Status = IsaReadPortRemoveDevice(PdoExt, FALSE); + break; + + case IRP_MN_REMOVE_DEVICE: + if (PdoExt->Common.Signature == IsaPnpLogicalDevice) + Status = IsaPdoRemoveDevice(PdoExt, TRUE); + else + Status = IsaReadPortRemoveDevice(PdoExt, TRUE); + break; + case IRP_MN_QUERY_PNP_DEVICE_STATE: - if (PdoExt->Common.Self == PdoExt->FdoExt->ReadPortPdo) - Status = IsaPdoQueryPnpDeviceState(PdoExt, Irp, IrpSp); + Status = IsaPdoQueryPnpDeviceState(PdoExt, Irp); break;
case IRP_MN_QUERY_RESOURCES: @@ -563,36 +704,31 @@ IsaPdoPnp( break;
case IRP_MN_QUERY_ID: - if (PdoExt->IsaPnpDevice) + if (PdoExt->Common.Signature == IsaPnpLogicalDevice) Status = IsaPdoQueryId(PdoExt, Irp, IrpSp); else Status = IsaReadPortQueryId(Irp, IrpSp); break;
+ case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: + Status = IsaPdoFilterResourceRequirements(PdoExt, Irp, IrpSp); + break; + case IRP_MN_QUERY_BUS_INFORMATION: Status = IsaPdoQueryBusInformation(PdoExt, Irp); break;
- case IRP_MN_QUERY_REMOVE_DEVICE: - case IRP_MN_REMOVE_DEVICE: + case IRP_MN_DEVICE_USAGE_NOTIFICATION: + Status = IsaPdoQueryDeviceUsageNotification(PdoExt, Irp, IrpSp); + break; + case IRP_MN_CANCEL_REMOVE_DEVICE: - case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: - case IRP_MN_QUERY_DEVICE_TEXT: - case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: - case IRP_MN_SURPRISE_REMOVAL: Status = STATUS_SUCCESS; break;
- case IRP_MN_READ_CONFIG: - case IRP_MN_WRITE_CONFIG: - case IRP_MN_EJECT: - case IRP_MN_SET_LOCK: - case IRP_MN_DEVICE_USAGE_NOTIFICATION: - return IsaPdoRepeatRequest(PdoExt, Irp, TRUE); - default: - DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction); + DPRINT("Unknown PnP code: %X\n", IrpSp->MinorFunction); break; }