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