1 /* 2 * PROJECT: ReactOS ISA PnP Bus driver 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Stub driver 5 * COPYRIGHT: Copyright 2021 Dmitry Borisov <di.sean@protonmail.com> 6 */ 7 8 /* 9 * This driver does nothing, and only used if a platform has no ISA PnP support. 10 * We need to keep FDO because ACPI driver depends on it. The ACPI bus filter 11 * attaches legacy ISA/LPC devices to this FDO. 12 */ 13 14 /* INCLUDES *******************************************************************/ 15 16 #include "isapnp.h" 17 18 #define NDEBUG 19 #include <debug.h> 20 21 /* FUNCTIONS ******************************************************************/ 22 23 _Dispatch_type_(IRP_MJ_CREATE) 24 _Dispatch_type_(IRP_MJ_CLOSE) 25 static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaStubCreateClose; 26 27 static 28 CODE_SEG("PAGE") 29 NTSTATUS 30 NTAPI 31 IsaStubCreateClose( 32 _In_ PDEVICE_OBJECT DeviceObject, 33 _Inout_ PIRP Irp) 34 { 35 UNREFERENCED_PARAMETER(DeviceObject); 36 37 PAGED_CODE(); 38 39 Irp->IoStatus.Status = STATUS_SUCCESS; 40 IoCompleteRequest(Irp, IO_NO_INCREMENT); 41 42 return STATUS_SUCCESS; 43 } 44 45 _Dispatch_type_(IRP_MJ_DEVICE_CONTROL) 46 _Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) 47 static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaStubForward; 48 49 static 50 CODE_SEG("PAGE") 51 NTSTATUS 52 NTAPI 53 IsaStubForward( 54 _In_ PDEVICE_OBJECT DeviceObject, 55 _Inout_ PIRP Irp) 56 { 57 PISAPNP_FDO_EXTENSION FdoExt = DeviceObject->DeviceExtension; 58 59 PAGED_CODE(); 60 61 IoSkipCurrentIrpStackLocation(Irp); 62 return IoCallDriver(FdoExt->Ldo, Irp); 63 } 64 65 _Dispatch_type_(IRP_MJ_PNP) 66 static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaStubPnp; 67 68 static 69 CODE_SEG("PAGE") 70 NTSTATUS 71 NTAPI 72 IsaStubPnp( 73 _In_ PDEVICE_OBJECT DeviceObject, 74 _Inout_ PIRP Irp) 75 { 76 PISAPNP_FDO_EXTENSION FdoExt = DeviceObject->DeviceExtension; 77 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); 78 NTSTATUS Status; 79 80 PAGED_CODE(); 81 82 DPRINT("%s(%p, %p) Minor - %X\n", 83 __FUNCTION__, 84 FdoExt, 85 Irp, 86 IrpSp->MinorFunction); 87 88 switch (IrpSp->MinorFunction) 89 { 90 case IRP_MN_START_DEVICE: 91 { 92 if (IoForwardIrpSynchronously(FdoExt->Ldo, Irp)) 93 Status = Irp->IoStatus.Status; 94 else 95 Status = STATUS_UNSUCCESSFUL; 96 97 goto CompleteIrp; 98 } 99 100 case IRP_MN_QUERY_DEVICE_RELATIONS: 101 { 102 PDEVICE_RELATIONS DeviceRelations; 103 104 if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations) 105 break; 106 107 DeviceRelations = ExAllocatePoolWithTag(PagedPool, 108 FIELD_OFFSET(DEVICE_RELATIONS, Objects), 109 TAG_ISAPNP); 110 if (!DeviceRelations) 111 { 112 Status = STATUS_NO_MEMORY; 113 goto CompleteIrp; 114 } 115 116 DeviceRelations->Count = 0; 117 118 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; 119 Irp->IoStatus.Status = STATUS_SUCCESS; 120 break; 121 } 122 123 case IRP_MN_REMOVE_DEVICE: 124 { 125 Irp->IoStatus.Status = STATUS_SUCCESS; 126 IoSkipCurrentIrpStackLocation(Irp); 127 Status = IoCallDriver(FdoExt->Ldo, Irp); 128 129 IoDetachDevice(FdoExt->Ldo); 130 IoDeleteDevice(FdoExt->Common.Self); 131 132 return Status; 133 } 134 135 case IRP_MN_QUERY_PNP_DEVICE_STATE: 136 { 137 Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; 138 Irp->IoStatus.Status = STATUS_SUCCESS; 139 break; 140 } 141 142 case IRP_MN_QUERY_INTERFACE: 143 { 144 Status = IsaFdoQueryInterface(FdoExt, IrpSp); 145 if (Status == STATUS_NOT_SUPPORTED) 146 { 147 break; 148 } 149 else if (!NT_SUCCESS(Status)) 150 { 151 goto CompleteIrp; 152 } 153 154 Irp->IoStatus.Status = Status; 155 break; 156 } 157 158 case IRP_MN_QUERY_REMOVE_DEVICE: 159 case IRP_MN_CANCEL_REMOVE_DEVICE: 160 case IRP_MN_QUERY_STOP_DEVICE: 161 case IRP_MN_CANCEL_STOP_DEVICE: 162 case IRP_MN_STOP_DEVICE: 163 case IRP_MN_SURPRISE_REMOVAL: 164 { 165 Irp->IoStatus.Status = STATUS_SUCCESS; 166 break; 167 } 168 169 default: 170 break; 171 } 172 173 IoSkipCurrentIrpStackLocation(Irp); 174 return IoCallDriver(FdoExt->Ldo, Irp); 175 176 CompleteIrp: 177 Irp->IoStatus.Status = Status; 178 IoCompleteRequest(Irp, IO_NO_INCREMENT); 179 return Status; 180 } 181 182 _Dispatch_type_(IRP_MJ_POWER) 183 static DRIVER_DISPATCH_RAISED IsaStubPower; 184 185 static 186 NTSTATUS 187 NTAPI 188 IsaStubPower( 189 _In_ PDEVICE_OBJECT DeviceObject, 190 _Inout_ PIRP Irp) 191 { 192 PISAPNP_FDO_EXTENSION FdoExt = DeviceObject->DeviceExtension; 193 194 PoStartNextPowerIrp(Irp); 195 IoSkipCurrentIrpStackLocation(Irp); 196 return PoCallDriver(FdoExt->Ldo, Irp); 197 } 198 199 static CODE_SEG("PAGE") DRIVER_ADD_DEVICE IsaStubAddDevice; 200 201 static 202 CODE_SEG("PAGE") 203 NTSTATUS 204 NTAPI 205 IsaStubAddDevice( 206 _In_ PDRIVER_OBJECT DriverObject, 207 _In_ PDEVICE_OBJECT PhysicalDeviceObject) 208 { 209 PDEVICE_OBJECT Fdo; 210 PISAPNP_FDO_EXTENSION FdoExt; 211 NTSTATUS Status; 212 213 PAGED_CODE(); 214 215 DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject); 216 217 Status = IoCreateDevice(DriverObject, 218 sizeof(ISAPNP_FDO_EXTENSION), 219 NULL, 220 FILE_DEVICE_BUS_EXTENDER, 221 FILE_DEVICE_SECURE_OPEN, 222 FALSE, 223 &Fdo); 224 if (!NT_SUCCESS(Status)) 225 { 226 DPRINT1("Failed to create FDO (0x%08lx)\n", Status); 227 return Status; 228 } 229 230 FdoExt = Fdo->DeviceExtension; 231 232 RtlZeroMemory(FdoExt, sizeof(ISAPNP_FDO_EXTENSION)); 233 FdoExt->Common.Self = Fdo; 234 FdoExt->Common.Signature = IsaPnpBus; 235 FdoExt->DriverObject = DriverObject; 236 FdoExt->Pdo = PhysicalDeviceObject; 237 FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject); 238 if (!FdoExt->Ldo) 239 { 240 IoDeleteDevice(Fdo); 241 return STATUS_DEVICE_REMOVED; 242 } 243 244 Fdo->Flags &= ~DO_DEVICE_INITIALIZING; 245 246 return STATUS_SUCCESS; 247 } 248 249 static CODE_SEG("PAGE") DRIVER_UNLOAD IsaStubUnload; 250 251 static 252 CODE_SEG("PAGE") 253 VOID 254 NTAPI 255 IsaStubUnload( 256 _In_ PDRIVER_OBJECT DriverObject) 257 { 258 UNREFERENCED_PARAMETER(DriverObject); 259 260 PAGED_CODE(); 261 262 NOTHING; 263 } 264 265 CODE_SEG("INIT") 266 NTSTATUS 267 NTAPI 268 DriverEntry( 269 _In_ PDRIVER_OBJECT DriverObject, 270 _In_ PUNICODE_STRING RegistryPath) 271 { 272 DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath); 273 274 DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaStubCreateClose; 275 DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaStubCreateClose; 276 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaStubForward; 277 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsaStubForward; 278 DriverObject->MajorFunction[IRP_MJ_PNP] = IsaStubPnp; 279 DriverObject->MajorFunction[IRP_MJ_POWER] = IsaStubPower; 280 DriverObject->DriverExtension->AddDevice = IsaStubAddDevice; 281 DriverObject->DriverUnload = IsaStubUnload; 282 283 return STATUS_SUCCESS; 284 } 285