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