Disable USB keyboard and mouse support, as they conflict with i8042prt driver.
[reactos.git] / reactos / drivers / usb / miniport / common / fdo.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS USB miniport driver (Cromwell type)
4 * FILE: drivers/usb/miniport/common/fdo.c
5 * PURPOSE: IRP_MJ_PNP/IRP_MJ_DEVICE_CONTROL operations for FDOs
6 *
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org),
8 * James Tabor (jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net)
9 */
10
11 #define NDEBUG
12 #include <debug.h>
13
14 #include "usbcommon.h"
15
16 #define IO_METHOD_FROM_CTL_CODE(ctlCode) (ctlCode&0x00000003)
17
18 static VOID
19 UsbMpGetUserBuffers(
20 IN PIRP Irp,
21 IN ULONG IoControlCode,
22 OUT PVOID* BufferIn,
23 OUT PVOID* BufferOut)
24 {
25 ASSERT(Irp);
26 ASSERT(BufferIn);
27 ASSERT(BufferOut);
28
29 switch (IO_METHOD_FROM_CTL_CODE(IoControlCode))
30 {
31 case METHOD_BUFFERED:
32 *BufferIn = *BufferOut = Irp->AssociatedIrp.SystemBuffer;
33 break;
34 case METHOD_IN_DIRECT:
35 case METHOD_OUT_DIRECT:
36 *BufferIn = Irp->AssociatedIrp.SystemBuffer;
37 *BufferOut = MmGetSystemAddressForMdl(Irp->MdlAddress);
38 break;
39 case METHOD_NEITHER:
40 *BufferIn = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.Type3InputBuffer;
41 *BufferOut = Irp->UserBuffer;
42 break;
43 default:
44 /* Should never happen */
45 *BufferIn = NULL;
46 *BufferOut = NULL;
47 break;
48 }
49 }
50
51 NTSTATUS STDCALL
52 UsbMpFdoStartDevice(
53 IN PDEVICE_OBJECT DeviceObject,
54 IN PIRP Irp)
55 {
56 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
57 PDRIVER_OBJECT DriverObject;
58 PUSBMP_DRIVER_EXTENSION DriverExtension;
59 PUSBMP_DEVICE_EXTENSION DeviceExtension;
60 PCM_RESOURCE_LIST AllocatedResources;
61
62 if (DeviceObject == KeyboardFdo || DeviceObject == MouseFdo)
63 return STATUS_SUCCESS;
64
65 /*
66 * Get the initialization data we saved in VideoPortInitialize.
67 */
68 DriverObject = DeviceObject->DriverObject;
69 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
70 DeviceExtension = (PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
71
72 /*
73 * Store some resources in the DeviceExtension.
74 */
75 AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
76 if (AllocatedResources != NULL)
77 {
78 CM_FULL_RESOURCE_DESCRIPTOR *FullList;
79 CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
80 ULONG ResourceCount;
81 ULONG ResourceListSize;
82
83 /* Save the resource list */
84 ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
85
86 ResourceListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
87 PartialDescriptors[ResourceCount]);
88
89 DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
90 if (DeviceExtension->AllocatedResources == NULL)
91 {
92 return STATUS_INSUFFICIENT_RESOURCES;
93 }
94
95 RtlCopyMemory(DeviceExtension->AllocatedResources,
96 AllocatedResources,
97 ResourceListSize);
98
99 /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
100 for (FullList = AllocatedResources->List;
101 FullList < AllocatedResources->List + AllocatedResources->Count;
102 FullList++)
103 {
104 /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
105 /*ASSERT(FullList->InterfaceType == PCIBus &&
106 FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
107 1 == FullList->PartialResourceList.Version &&
108 1 == FullList->PartialResourceList.Revision);*/
109 for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
110 Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
111 Descriptor++)
112 {
113 if (Descriptor->Type == CmResourceTypeInterrupt)
114 {
115 DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
116 DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
117 }
118 else if (Descriptor->Type == CmResourceTypePort)
119 {
120 DeviceExtension->BaseAddress = Descriptor->u.Port.Start;
121 DeviceExtension->BaseAddrLength = Descriptor->u.Port.Length;
122 DeviceExtension->Flags = Descriptor->Flags;
123
124 ((struct hc_driver *)pci_ids->driver_data)->flags &= ~HCD_MEMORY;
125 }
126 else if (Descriptor->Type == CmResourceTypeMemory)
127 {
128 DeviceExtension->BaseAddress = Descriptor->u.Memory.Start;
129 DeviceExtension->BaseAddrLength = Descriptor->u.Memory.Length;
130 DeviceExtension->Flags = Descriptor->Flags;
131
132 ((struct hc_driver *)pci_ids->driver_data)->flags |= HCD_MEMORY;
133 }
134 }
135 }
136 }
137
138 /* Print assigned resources */
139 DPRINT("USBMP: Interrupt Vector 0x%lx, %S base 0x%lx, Length 0x%lx\n",
140 DeviceExtension->InterruptVector,
141 ((struct hc_driver *)pci_ids->driver_data)->flags & HCD_MEMORY ? L"Memory" : L"I/O",
142 DeviceExtension->BaseAddress,
143 DeviceExtension->BaseAddrLength);
144
145 /* Init wrapper with this object */
146 return InitLinuxWrapper(DeviceObject);
147 }
148
149 static NTSTATUS
150 UsbMpFdoQueryBusRelations(
151 IN PDEVICE_OBJECT DeviceObject,
152 OUT PDEVICE_RELATIONS* pDeviceRelations)
153 {
154 PUSBMP_DEVICE_EXTENSION DeviceExtension;
155 PDEVICE_RELATIONS DeviceRelations;
156 NTSTATUS Status = STATUS_SUCCESS;
157
158 DeviceExtension = (PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
159
160 /* Handling this IRP is easy, as we only
161 * have one child: the root hub
162 */
163 DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(
164 PagedPool,
165 sizeof(DEVICE_RELATIONS));
166 if (!DeviceRelations)
167 return STATUS_INSUFFICIENT_RESOURCES;
168
169 /* Fill returned structure */
170 DeviceRelations->Count = 1;
171 ObReferenceObject(DeviceExtension->RootHubPdo);
172 DeviceRelations->Objects[0] = DeviceExtension->RootHubPdo;
173
174 *pDeviceRelations = DeviceRelations;
175 return Status;
176 }
177
178 NTSTATUS STDCALL
179 UsbMpPnpFdo(
180 IN PDEVICE_OBJECT DeviceObject,
181 IN PIRP Irp)
182 {
183 PIO_STACK_LOCATION IrpSp;
184 NTSTATUS Status;
185 ULONG MinorFunction;
186 ULONG_PTR Information = 0;
187
188 IrpSp = IoGetCurrentIrpStackLocation(Irp);
189 MinorFunction = IrpSp->MinorFunction;
190
191 switch (MinorFunction)
192 {
193 case IRP_MN_START_DEVICE:
194 {
195 Status = ForwardIrpAndWait(DeviceObject, Irp);
196 if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
197 Status = UsbMpFdoStartDevice(DeviceObject, Irp);
198 break;
199 }
200
201 case IRP_MN_REMOVE_DEVICE:
202 case IRP_MN_QUERY_REMOVE_DEVICE:
203 case IRP_MN_CANCEL_REMOVE_DEVICE:
204 case IRP_MN_SURPRISE_REMOVAL:
205
206 case IRP_MN_STOP_DEVICE:
207 {
208 Status = ForwardIrpAndWait(DeviceObject, Irp);
209 if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
210 Status = STATUS_SUCCESS;
211 IoDeleteDevice(DeviceObject); // just delete device for now
212 break;
213 }
214 case IRP_MN_QUERY_STOP_DEVICE:
215 case IRP_MN_CANCEL_STOP_DEVICE:
216 {
217 Status = STATUS_SUCCESS;
218 break;
219 }
220 case IRP_MN_QUERY_DEVICE_RELATIONS: /* (optional) 0x7 */
221 {
222 switch (IrpSp->Parameters.QueryDeviceRelations.Type)
223 {
224 case BusRelations:
225 {
226 PDEVICE_RELATIONS DeviceRelations;
227 DPRINT("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
228 Status = UsbMpFdoQueryBusRelations(DeviceObject, &DeviceRelations);
229 Information = (ULONG_PTR)DeviceRelations;
230 break;
231 }
232 case RemovalRelations:
233 {
234 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
235 return ForwardIrpAndForget(DeviceObject, Irp);
236 }
237 default:
238 DPRINT1("USBMP: IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
239 IrpSp->Parameters.QueryDeviceRelations.Type);
240 return ForwardIrpAndForget(DeviceObject, Irp);
241 }
242 break;
243 }
244
245 default:
246 {
247 DPRINT1("USBMP: unknown minor function 0x%lx\n", MinorFunction);
248 return ForwardIrpAndForget(DeviceObject, Irp);
249 }
250 }
251 Irp->IoStatus.Information = Information;
252 Irp->IoStatus.Status = Status;
253 IoCompleteRequest(Irp, IO_NO_INCREMENT);
254 return Status;
255 }
256
257 NTSTATUS
258 UsbMpDeviceControlFdo(
259 IN PDEVICE_OBJECT DeviceObject,
260 IN PIRP Irp)
261 {
262 PIO_STACK_LOCATION Stack;
263 ULONG IoControlCode;
264 PUSBMP_DEVICE_EXTENSION DeviceExtension;
265 ULONG LengthIn, LengthOut;
266 ULONG_PTR Information = 0;
267 PVOID BufferIn, BufferOut;
268 NTSTATUS Status;
269
270 DPRINT("USBMP: UsbDeviceControlFdo() called\n");
271
272 Stack = IoGetCurrentIrpStackLocation(Irp);
273 LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
274 LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
275 DeviceExtension = (PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
276 IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
277 UsbMpGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);
278
279 switch (IoControlCode)
280 {
281 case IOCTL_GET_HCD_DRIVERKEY_NAME:
282 {
283 DPRINT("USBMP: IOCTL_GET_HCD_DRIVERKEY_NAME\n");
284 if (LengthOut < sizeof(USB_HCD_DRIVERKEY_NAME))
285 Status = STATUS_BUFFER_TOO_SMALL;
286 else if (BufferOut == NULL)
287 Status = STATUS_INVALID_PARAMETER;
288 else
289 {
290 PUSB_HCD_DRIVERKEY_NAME StringDescriptor;
291 ULONG StringSize;
292 StringDescriptor = (PUSB_HCD_DRIVERKEY_NAME)BufferOut;
293 Status = IoGetDeviceProperty(
294 ((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->PhysicalDeviceObject,
295 DevicePropertyDriverKeyName,
296 LengthOut - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName),
297 StringDescriptor->DriverKeyName,
298 &StringSize);
299 if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
300 {
301 StringDescriptor->ActualLength = StringSize + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName);
302 Information = LengthOut;
303 Status = STATUS_SUCCESS;
304 }
305 }
306 break;
307 }
308 case IOCTL_USB_GET_ROOT_HUB_NAME:
309 {
310 DPRINT("USBMP: IOCTL_USB_GET_ROOT_HUB_NAME\n");
311 if (LengthOut < sizeof(USB_ROOT_HUB_NAME))
312 Status = STATUS_BUFFER_TOO_SMALL;
313 else if (BufferOut == NULL)
314 Status = STATUS_INVALID_PARAMETER;
315 else
316 {
317 PUSB_ROOT_HUB_NAME StringDescriptor;
318 PUNICODE_STRING RootHubInterfaceName;
319 StringDescriptor = (PUSB_ROOT_HUB_NAME)BufferOut;
320 DeviceObject = ((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->RootHubPdo;
321 RootHubInterfaceName = &((PUSBMP_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->HcdInterfaceName;
322
323 StringDescriptor->ActualLength = RootHubInterfaceName->Length + sizeof(WCHAR) + FIELD_OFFSET(USB_ROOT_HUB_NAME, RootHubName);
324 if (StringDescriptor->ActualLength <= LengthOut)
325 {
326 /* Copy root hub name */
327 RtlCopyMemory(
328 StringDescriptor->RootHubName,
329 RootHubInterfaceName->Buffer,
330 RootHubInterfaceName->Length);
331 StringDescriptor->RootHubName[RootHubInterfaceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
332 DPRINT("USBMP: IOCTL_USB_GET_ROOT_HUB_NAME returns '%S'\n", StringDescriptor->RootHubName);
333 Information = StringDescriptor->ActualLength;
334 }
335 else
336 Information = sizeof(USB_ROOT_HUB_NAME);
337 Status = STATUS_SUCCESS;
338 }
339 break;
340 }
341
342 default:
343 {
344 /* Pass Irp to lower driver */
345 DPRINT1("USBMP: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
346 IoSkipCurrentIrpStackLocation(Irp);
347 return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
348 }
349 }
350
351 Irp->IoStatus.Information = Information;
352 Irp->IoStatus.Status = Status;
353 IoCompleteRequest(Irp, IO_NO_INCREMENT);
354 return Status;
355 }
356
357 NTSTATUS
358 UsbMpInternalDeviceControlFdo(
359 IN PDEVICE_OBJECT DeviceObject,
360 IN PIRP Irp)
361 {
362 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST;
363
364 DPRINT("USBMP: UsbMpDeviceInternalControlFdo(DO %p, code 0x%lx) called\n",
365 DeviceObject,
366 IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode);
367
368 if (DeviceObject == KeyboardFdo)
369 {
370 // it's keyboard's IOCTL
371 PIO_STACK_LOCATION Stk;
372
373 Irp->IoStatus.Information = 0;
374 Stk = IoGetCurrentIrpStackLocation(Irp);
375
376 switch (Stk->Parameters.DeviceIoControl.IoControlCode)
377 {
378 case IOCTL_INTERNAL_KEYBOARD_CONNECT:
379 DPRINT("USBMP: IOCTL_INTERNAL_KEYBOARD_CONNECT\n");
380 if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
381 DPRINT1("USBMP: Keyboard IOCTL_INTERNAL_KEYBOARD_CONNECT "
382 "invalid buffer size\n");
383 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
384 goto intcontfailure;
385 }
386
387 RtlCopyMemory(&KbdClassInformation,
388 Stk->Parameters.DeviceIoControl.Type3InputBuffer,
389 sizeof(CONNECT_DATA));
390
391 Irp->IoStatus.Status = STATUS_SUCCESS;
392 break;
393
394 case IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER:
395 DPRINT("USBMP: IOCTL_INTERNAL_I8042_KEYBOARD_WRITE_BUFFER\n");
396 if (Stk->Parameters.DeviceIoControl.InputBufferLength < 1) {
397 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
398 goto intcontfailure;
399 }
400 /* if (!DevExt->KeyboardInterruptObject) {
401 Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
402 goto intcontfailure;
403 }*/
404
405 Irp->IoStatus.Status = STATUS_SUCCESS;
406 break;
407 case IOCTL_KEYBOARD_QUERY_ATTRIBUTES:
408 DPRINT("USBMP: IOCTL_KEYBOARD_QUERY_ATTRIBUTES\n");
409 if (Stk->Parameters.DeviceIoControl.OutputBufferLength <
410 sizeof(KEYBOARD_ATTRIBUTES)) {
411 DPRINT("USBMP: Keyboard IOCTL_KEYBOARD_QUERY_ATTRIBUTES "
412 "invalid buffer size\n");
413 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
414 goto intcontfailure;
415 }
416 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
417 &DevExt->KeyboardAttributes,
418 sizeof(KEYBOARD_ATTRIBUTES));*/
419
420 Irp->IoStatus.Status = STATUS_SUCCESS;
421 break;
422 case IOCTL_KEYBOARD_QUERY_INDICATORS:
423 DPRINT("USBMP: IOCTL_KEYBOARD_QUERY_INDICATORS\n");
424 if (Stk->Parameters.DeviceIoControl.OutputBufferLength <
425 sizeof(KEYBOARD_INDICATOR_PARAMETERS)) {
426 DPRINT("USBMP: Keyboard IOCTL_KEYBOARD_QUERY_INDICATORS "
427 "invalid buffer size\n");
428 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
429 goto intcontfailure;
430 }
431 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
432 &DevExt->KeyboardIndicators,
433 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
434
435 Irp->IoStatus.Status = STATUS_SUCCESS;
436 break;
437 case IOCTL_KEYBOARD_QUERY_TYPEMATIC:
438 DPRINT("USBMP: IOCTL_KEYBOARD_QUERY_TYPEMATIC\n");
439 if (Stk->Parameters.DeviceIoControl.OutputBufferLength <
440 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) {
441 DPRINT("USBMP: Keyboard IOCTL_KEYBOARD_QUERY_TYPEMATIC "
442 "invalid buffer size\n");
443 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
444 goto intcontfailure;
445 }
446 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
447 &DevExt->KeyboardTypematic,
448 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
449
450 Irp->IoStatus.Status = STATUS_SUCCESS;
451 break;
452 case IOCTL_KEYBOARD_SET_INDICATORS:
453 DPRINT("USBMP: IOCTL_KEYBOARD_SET_INDICATORS\n");
454 if (Stk->Parameters.DeviceIoControl.InputBufferLength <
455 sizeof(KEYBOARD_INDICATOR_PARAMETERS)) {
456 DPRINT("USBMP: Keyboard IOCTL_KEYBOARD_SET_INDICTATORS "
457 "invalid buffer size\n");
458 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
459 goto intcontfailure;
460 }
461
462 /*RtlCopyMemory(&DevExt->KeyboardIndicators,
463 Irp->AssociatedIrp.SystemBuffer,
464 sizeof(KEYBOARD_INDICATOR_PARAMETERS));*/
465
466 //DPRINT("%x\n", DevExt->KeyboardIndicators.LedFlags);
467
468 Irp->IoStatus.Status = STATUS_SUCCESS;
469 break;
470 case IOCTL_KEYBOARD_SET_TYPEMATIC:
471 DPRINT("USBMP: IOCTL_KEYBOARD_SET_TYPEMATIC\n");
472 if (Stk->Parameters.DeviceIoControl.InputBufferLength <
473 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS)) {
474 DPRINT("USBMP: Keyboard IOCTL_KEYBOARD_SET_TYPEMATIC "
475 "invalid buffer size\n");
476 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
477 goto intcontfailure;
478 }
479
480 /*RtlCopyMemory(&DevExt->KeyboardTypematic,
481 Irp->AssociatedIrp.SystemBuffer,
482 sizeof(KEYBOARD_TYPEMATIC_PARAMETERS));*/
483
484 Irp->IoStatus.Status = STATUS_SUCCESS;
485 break;
486 case IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION:
487 /* We should check the UnitID, but it's kind of pointless as
488 * all keyboards are supposed to have the same one
489 */
490 #if 0
491 DPRINT("USBMP: IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION\n");
492 if (Stk->Parameters.DeviceIoControl.OutputBufferLength <
493 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION)) {
494 DPRINT("USBMP: IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION: "
495 "invalid buffer size (expected)\n");
496 /* It's to query the buffer size */
497 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
498 goto intcontfailure;
499 }
500 Irp->IoStatus.Information =
501 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION);
502 #endif
503 /*RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
504 &IndicatorTranslation,
505 sizeof(LOCAL_KEYBOARD_INDICATOR_TRANSLATION));*/
506
507 Irp->IoStatus.Status = STATUS_SUCCESS;
508 break;
509 case IOCTL_INTERNAL_I8042_HOOK_KEYBOARD:
510 /* Nothing to do here */
511 Irp->IoStatus.Status = STATUS_SUCCESS;
512 break;
513 default:
514 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
515 break;
516 }
517
518 intcontfailure:
519 Status = Irp->IoStatus.Status;
520 }
521 else if (DeviceObject == MouseFdo)
522 {
523 // it's mouse's IOCTL
524 PIO_STACK_LOCATION Stk;
525
526 Irp->IoStatus.Information = 0;
527 Stk = IoGetCurrentIrpStackLocation(Irp);
528
529 switch (Stk->Parameters.DeviceIoControl.IoControlCode)
530 {
531 case IOCTL_INTERNAL_MOUSE_CONNECT:
532 DPRINT("USBMP: IOCTL_INTERNAL_MOUSE_CONNECT\n");
533 if (Stk->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) {
534 DPRINT1("USBMP: IOCTL_INTERNAL_MOUSE_CONNECT "
535 "invalid buffer size\n");
536 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
537 goto intcontfailure2;
538 }
539
540 RtlCopyMemory(&MouseClassInformation,
541 Stk->Parameters.DeviceIoControl.Type3InputBuffer,
542 sizeof(CONNECT_DATA));
543
544 Irp->IoStatus.Status = STATUS_SUCCESS;
545 break;
546
547 default:
548 Irp->IoStatus.Status = STATUS_SUCCESS;//STATUS_INVALID_DEVICE_REQUEST;
549 break;
550 }
551 intcontfailure2:
552 Status = Irp->IoStatus.Status;
553 }
554 else
555 {
556 DPRINT("USBMP: We got IOCTL for UsbCore\n");
557 IoCompleteRequest(Irp, IO_NO_INCREMENT);
558 return STATUS_SUCCESS;
559 }
560
561
562 if (Status == STATUS_INVALID_DEVICE_REQUEST) {
563 DPRINT1("USBMP: Invalid internal device request!\n");
564 }
565
566 if (Status != STATUS_PENDING)
567 IoCompleteRequest(Irp, IO_NO_INCREMENT);
568
569 return Status;
570 }