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