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