xref: /reactos/drivers/bus/isapnp/stub.c (revision 53221834)
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