diff --git a/drivers/bus/isapnp/CMakeLists.txt b/drivers/bus/isapnp/CMakeLists.txt index 6b8a6747546..c4be1b57da3 100644 --- a/drivers/bus/isapnp/CMakeLists.txt +++ b/drivers/bus/isapnp/CMakeLists.txt @@ -1,11 +1,18 @@ -list(APPEND SOURCE - isapnp.c - pdo.c - fdo.c - hardware.c - interface.c - isapnp.h) +if(ISAPNP_ENABLE) + list(APPEND SOURCE + fdo.c + hardware.c + interface.c + isapnp.c + isapnp.h + pdo.c) +else() + list(APPEND SOURCE + interface.c + isapnp.h + stub.c) +endif() add_library(isapnp MODULE ${SOURCE} isapnp.rc) set_module_type(isapnp kernelmodedriver) diff --git a/drivers/bus/isapnp/stub.c b/drivers/bus/isapnp/stub.c new file mode 100644 index 00000000000..7b37c887adf --- /dev/null +++ b/drivers/bus/isapnp/stub.c @@ -0,0 +1,284 @@ +/* + * PROJECT: ReactOS ISA PnP Bus driver + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Stub driver + * COPYRIGHT: Copyright 2021 Dmitry Borisov + */ + +/* + * This driver does nothing, and only used if a platform has no ISA PnP support. + * We need to keep FDO because ACPI driver depends on it. The ACPI bus filter + * attaches legacy ISA/LPC devices to this FDO. + */ + +/* INCLUDES *******************************************************************/ + +#include "isapnp.h" + +#define NDEBUG +#include + +/* FUNCTIONS ******************************************************************/ + +_Dispatch_type_(IRP_MJ_CREATE) +_Dispatch_type_(IRP_MJ_CLOSE) +static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaStubCreateClose; + +static +CODE_SEG("PAGE") +NTSTATUS +NTAPI +IsaStubCreateClose( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + UNREFERENCED_PARAMETER(DeviceObject); + + PAGED_CODE(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) +_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) +static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaStubForward; + +static +CODE_SEG("PAGE") +NTSTATUS +NTAPI +IsaStubForward( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + PISAPNP_FDO_EXTENSION FdoExt = DeviceObject->DeviceExtension; + + PAGED_CODE(); + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FdoExt->Ldo, Irp); +} + +_Dispatch_type_(IRP_MJ_PNP) +static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaStubPnp; + +static +CODE_SEG("PAGE") +NTSTATUS +NTAPI +IsaStubPnp( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + PISAPNP_FDO_EXTENSION FdoExt = DeviceObject->DeviceExtension; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); + NTSTATUS Status; + + PAGED_CODE(); + + DPRINT("%s(%p, %p) Minor - %X\n", + __FUNCTION__, + FdoExt, + Irp, + IrpSp->MinorFunction); + + switch (IrpSp->MinorFunction) + { + case IRP_MN_START_DEVICE: + { + if (IoForwardIrpSynchronously(FdoExt->Ldo, Irp)) + Status = Irp->IoStatus.Status; + else + Status = STATUS_UNSUCCESSFUL; + + goto CompleteIrp; + } + + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + PDEVICE_RELATIONS DeviceRelations; + + if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) + break; + + DeviceRelations = ExAllocatePoolWithTag(PagedPool, + FIELD_OFFSET(DEVICE_RELATIONS, Objects), + TAG_ISAPNP); + if (!DeviceRelations) + { + Status = STATUS_NO_MEMORY; + goto CompleteIrp; + } + + DeviceRelations->Count = 0; + + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + } + + case IRP_MN_REMOVE_DEVICE: + { + Irp->IoStatus.Status = STATUS_SUCCESS; + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(FdoExt->Ldo, Irp); + + IoDetachDevice(FdoExt->Ldo); + IoDeleteDevice(FdoExt->Common.Self); + + return Status; + } + + 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)) + { + goto CompleteIrp; + } + + Irp->IoStatus.Status = Status; + break; + } + + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_CANCEL_STOP_DEVICE: + case IRP_MN_STOP_DEVICE: + case IRP_MN_SURPRISE_REMOVAL: + { + Irp->IoStatus.Status = STATUS_SUCCESS; + break; + } + + default: + break; + } + + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(FdoExt->Ldo, Irp); + +CompleteIrp: + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +_Dispatch_type_(IRP_MJ_POWER) +static DRIVER_DISPATCH_RAISED IsaStubPower; + +static +NTSTATUS +NTAPI +IsaStubPower( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + PISAPNP_FDO_EXTENSION FdoExt = DeviceObject->DeviceExtension; + + PoStartNextPowerIrp(Irp); + IoSkipCurrentIrpStackLocation(Irp); + return PoCallDriver(FdoExt->Ldo, Irp); +} + +static CODE_SEG("PAGE") DRIVER_ADD_DEVICE IsaStubAddDevice; + +static +CODE_SEG("PAGE") +NTSTATUS +NTAPI +IsaStubAddDevice( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PDEVICE_OBJECT PhysicalDeviceObject) +{ + PDEVICE_OBJECT Fdo; + PISAPNP_FDO_EXTENSION FdoExt; + NTSTATUS Status; + + PAGED_CODE(); + + DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject); + + Status = IoCreateDevice(DriverObject, + sizeof(ISAPNP_FDO_EXTENSION), + NULL, + FILE_DEVICE_BUS_EXTENDER, + FILE_DEVICE_SECURE_OPEN, + FALSE, + &Fdo); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create FDO (0x%08lx)\n", Status); + return Status; + } + + FdoExt = Fdo->DeviceExtension; + + RtlZeroMemory(FdoExt, sizeof(ISAPNP_FDO_EXTENSION)); + FdoExt->Common.Self = Fdo; + FdoExt->Common.Signature = IsaPnpBus; + FdoExt->DriverObject = DriverObject; + FdoExt->Pdo = PhysicalDeviceObject; + FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject); + if (!FdoExt->Ldo) + { + IoDeleteDevice(Fdo); + return STATUS_DEVICE_REMOVED; + } + + Fdo->Flags &= ~DO_DEVICE_INITIALIZING; + + return STATUS_SUCCESS; +} + +static CODE_SEG("PAGE") DRIVER_UNLOAD IsaStubUnload; + +static +CODE_SEG("PAGE") +VOID +NTAPI +IsaStubUnload( + _In_ PDRIVER_OBJECT DriverObject) +{ + UNREFERENCED_PARAMETER(DriverObject); + + PAGED_CODE(); + + NOTHING; +} + +CODE_SEG("INIT") +NTSTATUS +NTAPI +DriverEntry( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath) +{ + DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath); + + DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaStubCreateClose; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaStubCreateClose; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaStubForward; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsaStubForward; + DriverObject->MajorFunction[IRP_MJ_PNP] = IsaStubPnp; + DriverObject->MajorFunction[IRP_MJ_POWER] = IsaStubPower; + DriverObject->DriverExtension->AddDevice = IsaStubAddDevice; + DriverObject->DriverUnload = IsaStubUnload; + + return STATUS_SUCCESS; +} diff --git a/sdk/cmake/config.cmake b/sdk/cmake/config.cmake index 7bf236d08cb..84e032f045a 100644 --- a/sdk/cmake/config.cmake +++ b/sdk/cmake/config.cmake @@ -100,6 +100,9 @@ endif() cmake_dependent_option(BUILD_MP "Whether to build the multiprocessor versions of NTOSKRNL and HAL." ON "ARCH STREQUAL i386" OFF) +cmake_dependent_option(ISAPNP_ENABLE "Whether to enable the ISA PnP support." ON + "ARCH STREQUAL i386 AND NOT SARCH STREQUAL xbox" OFF) + set(GENERATE_DEPENDENCY_GRAPH FALSE CACHE BOOL "Whether to create a GraphML dependency graph of DLLs.")