Sync with trunk (aka 'I want my virtualbox mouse integration too')
[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 /* check if the device object is a child device */
47 Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
48
49 /* check for success */
50 if (!NT_SUCCESS(Status))
51 {
52 /* failed */
53 Irp->IoStatus.Status = Status;
54 IoCompleteRequest(Irp, IO_NO_INCREMENT);
55 return Status;
56 }
57
58 /* let ks handle it */
59 Status = KsServiceBusEnumPnpRequest(DeviceObject, Irp);
60
61 if (!NT_SUCCESS(Status))
62 {
63 /* invalid request or not supported */
64 Irp->IoStatus.Status = Status;
65 IoCompleteRequest(Irp, IO_NO_INCREMENT);
66 return Status;
67 }
68
69 /* get bus enum pnp object */
70 Status = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
71
72 /* check for success */
73 if (!NT_SUCCESS(Status))
74 {
75 /* failed to get pnp object */
76 Irp->IoStatus.Status = Status;
77 IoCompleteRequest(Irp, IO_NO_INCREMENT);
78 return Status;
79 }
80
81 /* sanity check */
82 ASSERT(PnpDeviceObject);
83
84 /* get current stack location */
85 IoStack = IoGetCurrentIrpStackLocation(Irp);
86
87 if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
88 {
89 /* delete the device */
90 IoDeleteDevice(DeviceObject);
91 }
92
93 /* skip current location */
94 IoSkipCurrentIrpStackLocation(Irp);
95 /* call the pnp device object */
96 return IoCallDriver(PnpDeviceObject, Irp);
97 }
98
99 NTSTATUS
100 NTAPI
101 SwDispatchSystemControl(
102 IN PDEVICE_OBJECT DeviceObject,
103 IN PIRP Irp)
104 {
105 NTSTATUS Status;
106 BOOLEAN ChildDevice;
107 PDEVICE_OBJECT PnpDeviceObject;
108
109 /* check if the device object is a child device */
110 Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
111
112 /* check for success */
113 if (NT_SUCCESS(Status))
114 {
115 if (!ChildDevice)
116 {
117 /* bus devices dont support internal requests */
118 Irp->IoStatus.Status = STATUS_SUCCESS;
119 IoCompleteRequest(Irp, IO_NO_INCREMENT);
120 return STATUS_SUCCESS;
121 }
122
123 /* get bus enum pnp object */
124 Status = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
125
126 /* check for success */
127 if (NT_SUCCESS(Status))
128 {
129 /* skip current location */
130 IoSkipCurrentIrpStackLocation(Irp);
131 /* call the pnp device object */
132 return IoCallDriver(PnpDeviceObject, Irp);
133 }
134
135 }
136
137 /* complete the request */
138 Irp->IoStatus.Status = Status;
139 IoCompleteRequest(Irp, IO_NO_INCREMENT);
140
141 return Status;
142
143 }
144
145 NTSTATUS
146 NTAPI
147 SwDispatchDeviceControl(
148 IN PDEVICE_OBJECT DeviceObject,
149 IN PIRP Irp)
150 {
151 PIO_STACK_LOCATION IoStack;
152 NTSTATUS Status = STATUS_SUCCESS;
153
154 /* get current stack location */
155 IoStack = IoGetCurrentIrpStackLocation(Irp);
156
157 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_INSTALL_INTERFACE)
158 {
159 /* install interface */
160 Status = KsInstallBusEnumInterface(Irp);
161 }
162 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_REMOVE_INTERFACE)
163 {
164 /* remove interface */
165 Status = KsRemoveBusEnumInterface(Irp);
166 }
167 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_GET_BUS_ID)
168 {
169 /* get bus id */
170 return KsGetBusEnumIdentifier(Irp);
171 }
172
173 /* store result */
174 Irp->IoStatus.Status = Status;
175
176 /* complete irp */
177 IoCompleteRequest(Irp, IO_NO_INCREMENT);
178
179 /* done */
180 return Status;
181 }
182
183
184 NTSTATUS
185 NTAPI
186 SwDispatchCreate(
187 IN PDEVICE_OBJECT DeviceObject,
188 IN PIRP Irp)
189 {
190 NTSTATUS Status;
191 BOOLEAN ChildDevice;
192
193 /* check if the device object is a child device */
194 Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
195
196 /* check for success */
197 if (NT_SUCCESS(Status))
198 {
199 if (ChildDevice)
200 {
201 /* child devices cant create devices */
202 Irp->IoStatus.Status = STATUS_OBJECT_NAME_NOT_FOUND;
203 IoCompleteRequest(Irp, IO_NO_INCREMENT);
204 return STATUS_OBJECT_NAME_NOT_FOUND;
205 }
206 /* perform the create request */
207 Status = KsServiceBusEnumCreateRequest(DeviceObject, Irp);
208 }
209
210 /* check the irp is pending */
211 if (Status != STATUS_PENDING)
212 {
213 /* irp is ok to complete */
214 Irp->IoStatus.Status = Status;
215 IoCompleteRequest(Irp, IO_NO_INCREMENT);
216 }
217
218 return Status;
219 }
220
221
222 NTSTATUS
223 NTAPI
224 SwDispatchClose(
225 IN PDEVICE_OBJECT DeviceObject,
226 IN PIRP Irp)
227 {
228 /* just complete the irp */
229 Irp->IoStatus.Status = STATUS_SUCCESS;
230
231 /* complete the irp */
232 IoCompleteRequest(Irp, IO_NO_INCREMENT);
233
234 /* done */
235 return STATUS_SUCCESS;
236
237 }
238
239 NTSTATUS
240 NTAPI
241 SwAddDevice(
242 IN PDRIVER_OBJECT DriverObject,
243 IN PDEVICE_OBJECT PhysicalDeviceObject)
244 {
245 NTSTATUS Status;
246 PDEVICE_OBJECT FunctionalDeviceObject;
247
248 /* create the device */
249 Status = IoCreateDevice(DriverObject, sizeof(KSDEVICE_HEADER), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &FunctionalDeviceObject);
250
251 if (!NT_SUCCESS(Status))
252 {
253 /* failed */
254 return Status;
255 }
256
257 /* create the bus enum object */
258 Status = KsCreateBusEnumObject(L"SW", FunctionalDeviceObject, PhysicalDeviceObject, NULL, &KSMEDIUMSETID_Standard, L"Devices");
259
260 /* check for success */
261 if (NT_SUCCESS(Status))
262 {
263 /* set device flags */
264 FunctionalDeviceObject->Flags |= DO_POWER_PAGABLE;
265 FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
266 }
267 else
268 {
269 /* failed to create bus enum object */
270 IoDeleteDevice(FunctionalDeviceObject);
271 }
272
273 /* done */
274 return Status;
275 }
276
277 VOID
278 NTAPI
279 SwUnload(
280 IN PDRIVER_OBJECT DriverObject)
281 {
282 /* nop */
283 }
284
285 NTSTATUS
286 NTAPI
287 DriverEntry(
288 IN PDRIVER_OBJECT DriverObject,
289 IN PUNICODE_STRING RegistryPathName)
290 {
291
292 /* setup add device routine */
293 DriverObject->DriverExtension->AddDevice = SwAddDevice;
294
295 /* setup unload routine */
296 DriverObject->DriverUnload = SwUnload;
297
298 /* misc irp handling routines */
299 DriverObject->MajorFunction[IRP_MJ_CREATE] = SwDispatchCreate;
300 DriverObject->MajorFunction[IRP_MJ_CLOSE] = SwDispatchClose;
301 DriverObject->MajorFunction[IRP_MJ_PNP] = SwDispatchPnp;
302 DriverObject->MajorFunction[IRP_MJ_POWER] = SwDispatchPower;
303 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SwDispatchDeviceControl;
304 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SwDispatchSystemControl;
305
306
307 return STATUS_SUCCESS;
308 }
309