xref: /reactos/drivers/ksfilter/swenum/swenum.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS Kernel Streaming
4  * FILE:            drivers/ksfilter/swenum/swenum.c
5  * PURPOSE:         KS Allocator functions
6  * PROGRAMMER:      Johannes Anderwald
7  */
8 
9 
10 #include "precomp.h"
11 
12 const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
13 
14 NTSTATUS
15 NTAPI
SwDispatchPower(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)16 SwDispatchPower(
17     IN PDEVICE_OBJECT DeviceObject,
18     IN PIRP Irp)
19 {
20     NTSTATUS Status, PnpStatus;
21     BOOLEAN ChildDevice;
22     PIO_STACK_LOCATION IoStack;
23     PDEVICE_OBJECT PnpDeviceObject = NULL;
24 
25     /* get current stack location */
26     IoStack = IoGetCurrentIrpStackLocation(Irp);
27 
28     /* check if the device object is a child device */
29     Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
30 
31     /* get bus enum pnp object */
32     PnpStatus = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
33 
34     /* check for success */
35     if (!NT_SUCCESS(Status) || !NT_SUCCESS(PnpStatus))
36     {
37         /* start next power irp */
38         PoStartNextPowerIrp(Irp);
39 
40         /* just complete the irp */
41         Irp->IoStatus.Status = STATUS_SUCCESS;
42 
43         /* complete the irp */
44         IoCompleteRequest(Irp, IO_NO_INCREMENT);
45 
46         /* done */
47         return STATUS_SUCCESS;
48     }
49 
50     if (IoStack->MinorFunction == IRP_MN_SET_POWER || IoStack->MinorFunction == IRP_MN_QUERY_POWER)
51     {
52         /* fake success */
53         Irp->IoStatus.Status = STATUS_SUCCESS;
54     }
55 
56     if (!ChildDevice)
57     {
58         /* forward to pnp device object */
59         PoStartNextPowerIrp(Irp);
60 
61         /* skip current location */
62         IoSkipCurrentIrpStackLocation(Irp);
63 
64         /* done */
65         return PoCallDriver(PnpDeviceObject, Irp);
66     }
67 
68     /* start next power irp */
69     PoStartNextPowerIrp(Irp);
70 
71     /* just complete the irp */
72     Irp->IoStatus.Status = STATUS_SUCCESS;
73 
74     /* complete the irp */
75     IoCompleteRequest(Irp, IO_NO_INCREMENT);
76 
77     /* done */
78     return STATUS_SUCCESS;
79 }
80 
81 NTSTATUS
82 NTAPI
SwDispatchPnp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)83 SwDispatchPnp(
84     IN PDEVICE_OBJECT DeviceObject,
85     IN PIRP Irp)
86 {
87     NTSTATUS Status;
88     BOOLEAN ChildDevice;
89     PIO_STACK_LOCATION IoStack;
90     PDEVICE_OBJECT PnpDeviceObject = NULL;
91 
92     /* get current stack location */
93     IoStack = IoGetCurrentIrpStackLocation(Irp);
94 
95     /* check if the device object is a child device */
96     Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
97 
98     /* check for success */
99     if (!NT_SUCCESS(Status))
100     {
101         /* failed */
102         Irp->IoStatus.Status = Status;
103         IoCompleteRequest(Irp, IO_NO_INCREMENT);
104         return Status;
105     }
106 
107     DPRINT("SwDispatchPnp ChildDevice %u Request %x\n", ChildDevice, IoStack->MinorFunction);
108 
109     /* let ks handle it */
110     Status = KsServiceBusEnumPnpRequest(DeviceObject, Irp);
111 
112     /* check if the request was for a pdo */
113     if (ChildDevice)
114     {
115         if (Status != STATUS_NOT_SUPPORTED)
116         {
117             /* store result */
118             Irp->IoStatus.Status = Status;
119         }
120 
121         /* complete request */
122         IoCompleteRequest(Irp, IO_NO_INCREMENT);
123 
124         /* done */
125         return Status;
126     }
127 
128     DPRINT("SwDispatchPnp KsServiceBusEnumPnpRequest Status %x\n", Status);
129 
130     if (NT_SUCCESS(Status))
131     {
132         /* invalid request or not supported */
133         Irp->IoStatus.Status = Status;
134         IoCompleteRequest(Irp, IO_NO_INCREMENT);
135         return Status;
136     }
137 
138     /* get bus enum pnp object */
139     Status = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
140 
141     DPRINT("SwDispatchPnp KsGetBusEnumPnpDeviceObject Status %x\n", Status);
142 
143     /* check for success */
144     if (!NT_SUCCESS(Status))
145     {
146         /* failed to get pnp object */
147         Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
148         IoCompleteRequest(Irp, IO_NO_INCREMENT);
149         return STATUS_NOT_SUPPORTED;
150     }
151 
152     /* sanity check */
153     ASSERT(PnpDeviceObject);
154 
155     /* get current stack location */
156     IoStack = IoGetCurrentIrpStackLocation(Irp);
157 
158     if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
159     {
160         /* delete the device */
161         IoDeleteDevice(DeviceObject);
162     }
163     else
164     {
165         if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES || IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
166         {
167             /* no resources required */
168             Irp->IoStatus.Information = 0;
169             Irp->IoStatus.Status = STATUS_SUCCESS;
170 
171             /* skip current location */
172             IoSkipCurrentIrpStackLocation(Irp);
173 
174             /* call the pnp device object */
175             return IoCallDriver(PnpDeviceObject, Irp);
176         }
177 
178         if (IoStack->MajorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
179         {
180             /* device cannot be disabled */
181             Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
182             Irp->IoStatus.Status = STATUS_SUCCESS;
183 
184             /* skip current location */
185             IoSkipCurrentIrpStackLocation(Irp);
186 
187             /* call the pnp device object */
188             return IoCallDriver(PnpDeviceObject, Irp);
189         }
190 
191         if (Status == STATUS_NOT_SUPPORTED)
192         {
193             /* skip current location */
194             IoSkipCurrentIrpStackLocation(Irp);
195 
196             /* call the pnp device object */
197             return IoCallDriver(PnpDeviceObject, Irp);
198         }
199     }
200 
201     /* complete the request */
202     Irp->IoStatus.Status = Status;
203     IoCompleteRequest(Irp, IO_NO_INCREMENT);
204 
205     return Status;
206 }
207 
208 NTSTATUS
209 NTAPI
SwDispatchSystemControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)210 SwDispatchSystemControl(
211     IN PDEVICE_OBJECT DeviceObject,
212     IN PIRP Irp)
213 {
214     NTSTATUS Status;
215     BOOLEAN ChildDevice;
216     PDEVICE_OBJECT PnpDeviceObject;
217 
218     /* check if the device object is a child device */
219     Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
220 
221     /* check for success */
222     if (NT_SUCCESS(Status))
223     {
224         if (!ChildDevice)
225         {
226             /* bus devices dont support internal requests */
227             Irp->IoStatus.Status = STATUS_SUCCESS;
228             IoCompleteRequest(Irp, IO_NO_INCREMENT);
229             return STATUS_SUCCESS;
230         }
231 
232         /* get bus enum pnp object */
233         Status = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
234 
235         /* check for success */
236         if (NT_SUCCESS(Status))
237         {
238             /* skip current location */
239             IoSkipCurrentIrpStackLocation(Irp);
240             /* call the pnp device object */
241             return IoCallDriver(PnpDeviceObject, Irp);
242         }
243 
244     }
245 
246     /* complete the request */
247     Irp->IoStatus.Status = Status;
248     IoCompleteRequest(Irp, IO_NO_INCREMENT);
249 
250     return Status;
251 
252 }
253 
254 NTSTATUS
255 NTAPI
SwDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)256 SwDispatchDeviceControl(
257     IN PDEVICE_OBJECT DeviceObject,
258     IN PIRP Irp)
259 {
260     PIO_STACK_LOCATION IoStack;
261     NTSTATUS Status;
262 
263     /* get current stack location */
264     IoStack = IoGetCurrentIrpStackLocation(Irp);
265 
266     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_INSTALL_INTERFACE)
267     {
268         /* install interface */
269         Status = KsInstallBusEnumInterface(Irp);
270         DPRINT("SwDispatchDeviceControl IOCTL_SWENUM_INSTALL_INTERFACE %x\n", Status);
271     }
272     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_REMOVE_INTERFACE)
273     {
274         /* remove interface */
275         Status = KsRemoveBusEnumInterface(Irp);
276         DPRINT("SwDispatchDeviceControl IOCTL_SWENUM_REMOVE_INTERFACE %x\n", Status);
277 
278     }
279     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_GET_BUS_ID)
280     {
281         /* get bus id */
282         Status = KsGetBusEnumIdentifier(Irp);
283         DPRINT("SwDispatchDeviceControl IOCTL_SWENUM_GET_BUS_ID %x\n", Status);
284     }
285     else
286     {
287         DPRINT("SwDispatchDeviceControl Unknown IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
288         Status = STATUS_INVALID_PARAMETER;
289     }
290 
291     /* store result */
292     Irp->IoStatus.Status = Status;
293 
294     /* complete irp */
295     IoCompleteRequest(Irp, IO_NO_INCREMENT);
296 
297     /* done */
298     return Status;
299 }
300 
301 
302 NTSTATUS
303 NTAPI
SwDispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)304 SwDispatchCreate(
305     IN PDEVICE_OBJECT DeviceObject,
306     IN PIRP Irp)
307 {
308     NTSTATUS Status;
309     BOOLEAN ChildDevice;
310 
311     /* check if the device object is a child device */
312     Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
313 
314     DPRINT("SwDispatchCreate %x\n", Status);
315 
316     /* check for success */
317     if (NT_SUCCESS(Status))
318     {
319         if (ChildDevice)
320         {
321             /* child devices cant create devices */
322             Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
323             IoCompleteRequest(Irp, IO_NO_INCREMENT);
324             return STATUS_OBJECT_NAME_NOT_FOUND;
325         }
326         /* perform the create request */
327         Status = KsServiceBusEnumCreateRequest(DeviceObject, Irp);
328         DPRINT("SwDispatchCreate %x\n", Status);
329     }
330 
331     /* check the irp is pending */
332     if (Status != STATUS_PENDING)
333     {
334         /* irp is ok to complete */
335         Irp->IoStatus.Status = Status;
336         IoCompleteRequest(Irp, IO_NO_INCREMENT);
337     }
338 
339     return Status;
340 }
341 
342 
343 NTSTATUS
344 NTAPI
SwDispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)345 SwDispatchClose(
346     IN PDEVICE_OBJECT DeviceObject,
347     IN PIRP Irp)
348 {
349     /* just complete the irp */
350     Irp->IoStatus.Status = STATUS_SUCCESS;
351 
352     /* complete the irp */
353     IoCompleteRequest(Irp, IO_NO_INCREMENT);
354 
355     /* done */
356     return STATUS_SUCCESS;
357 
358 }
359 
360 NTSTATUS
361 NTAPI
SwAddDevice(IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT PhysicalDeviceObject)362 SwAddDevice(
363     IN PDRIVER_OBJECT DriverObject,
364     IN PDEVICE_OBJECT PhysicalDeviceObject)
365 {
366     NTSTATUS Status;
367     PDEVICE_OBJECT FunctionalDeviceObject;
368 
369     DPRINT("SWENUM AddDevice\n");
370     /* create the device */
371     Status = IoCreateDevice(DriverObject, sizeof(KSDEVICE_HEADER), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &FunctionalDeviceObject);
372 
373     if (!NT_SUCCESS(Status))
374     {
375         /* failed */
376         return Status;
377     }
378 
379     /* create the bus enum object */
380     Status = KsCreateBusEnumObject(L"SW", FunctionalDeviceObject, PhysicalDeviceObject, NULL, &KSMEDIUMSETID_Standard, L"Devices");
381 
382     /* check for success */
383     if (NT_SUCCESS(Status))
384     {
385         /* set device flags */
386         FunctionalDeviceObject->Flags |= DO_POWER_PAGABLE;
387         FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
388     }
389     else
390     {
391         /* failed to create bus enum object */
392         IoDeleteDevice(FunctionalDeviceObject);
393     }
394 
395     /* done */
396     return Status;
397 }
398 
399 VOID
400 NTAPI
SwUnload(IN PDRIVER_OBJECT DriverObject)401 SwUnload(
402     IN  PDRIVER_OBJECT DriverObject)
403 {
404     /* nop */
405 }
406 
407 NTSTATUS
408 NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPathName)409 DriverEntry(
410     IN PDRIVER_OBJECT DriverObject,
411     IN PUNICODE_STRING RegistryPathName)
412 {
413 
414     /* setup add device routine */
415     DriverObject->DriverExtension->AddDevice = SwAddDevice;
416 
417     /* setup unload routine */
418     DriverObject->DriverUnload = SwUnload;
419 
420     /* misc irp handling routines */
421     DriverObject->MajorFunction[IRP_MJ_CREATE] = SwDispatchCreate;
422     DriverObject->MajorFunction[IRP_MJ_CLOSE] = SwDispatchClose;
423     DriverObject->MajorFunction[IRP_MJ_PNP] = SwDispatchPnp;
424     DriverObject->MajorFunction[IRP_MJ_POWER] = SwDispatchPower;
425     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SwDispatchDeviceControl;
426     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SwDispatchSystemControl;
427 
428     DPRINT("SWENUM loaded\n");
429     return STATUS_SUCCESS;
430 }
431 
432