2 * PROJECT: ReactOS Universal Serial Bus Human Interface Device Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/hidusb/hidusb.c
5 * PURPOSE: HID USB Interface Driver
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
13 PUSBD_PIPE_INFORMATION
14 HidUsb_GetInputInterruptInterfaceHandle(
15 PUSBD_INTERFACE_INFORMATION InterfaceInformation
)
22 ASSERT(InterfaceInformation
->NumberOfPipes
);
24 for(Index
= 0; Index
< InterfaceInformation
->NumberOfPipes
; Index
++)
26 //DPRINT1("[HIDUSB] EndpointAddress %x PipeType %x PipeHandle %x\n", InterfaceInformation->Pipes[Index].EndpointAddress, InterfaceInformation->Pipes[Index].PipeType, InterfaceInformation->Pipes[Index].PipeHandle);
27 if (InterfaceInformation
->Pipes
[Index
].PipeType
== UsbdPipeTypeInterrupt
&& (InterfaceInformation
->Pipes
[Index
].EndpointAddress
& USB_ENDPOINT_DIRECTION_MASK
))
32 return &InterfaceInformation
->Pipes
[Index
];
44 IN PDEVICE_OBJECT DeviceObject
,
49 IO_STATUS_BLOCK IoStatus
;
50 PHID_DEVICE_EXTENSION DeviceExtension
;
51 PIO_STACK_LOCATION IoStack
;
55 // get device extension
57 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
67 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
72 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS
, DeviceExtension
->NextDeviceObject
, NULL
, 0, NULL
, 0, TRUE
, &Event
, &IoStatus
);
78 return STATUS_INSUFFICIENT_RESOURCES
;
84 IoStack
= IoGetNextIrpStackLocation(Irp
);
87 // store result buffer
89 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)PortStatus
;
94 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
95 if (Status
== STATUS_PENDING
)
98 // wait for completion
100 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, 0, NULL
);
101 return IoStatus
.Status
;
111 HidUsb_ResetInterruptPipe(
112 IN PDEVICE_OBJECT DeviceObject
)
114 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
115 PHID_DEVICE_EXTENSION DeviceExtension
;
116 PUSBD_PIPE_INFORMATION PipeInformation
;
121 // get device extension
123 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
124 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
127 // get interrupt pipe handle
129 ASSERT(HidDeviceExtension
->InterfaceInfo
);
130 PipeInformation
= HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension
->InterfaceInfo
);
131 ASSERT(PipeInformation
);
132 ASSERT(PipeInformation
->PipeHandle
);
137 Urb
= ExAllocatePool(NonPagedPool
, sizeof(struct _URB_PIPE_REQUEST
));
143 return STATUS_INSUFFICIENT_RESOURCES
;
149 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
150 Urb
->UrbHeader
.Function
= URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
;
151 Urb
->UrbHeader
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
152 Urb
->UrbPipeRequest
.PipeHandle
= PipeInformation
->PipeHandle
;
157 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
172 IN PDEVICE_OBJECT DeviceObject
)
174 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
175 PHID_DEVICE_EXTENSION DeviceExtension
;
178 PUSBD_PIPE_INFORMATION PipeInformation
;
181 // get device extension
183 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
184 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
189 Urb
= ExAllocatePool(NonPagedPool
, sizeof(struct _URB_PIPE_REQUEST
));
195 return STATUS_INSUFFICIENT_RESOURCES
;
199 // get pipe information
201 PipeInformation
= HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension
->InterfaceInfo
);
202 ASSERT(PipeInformation
);
203 ASSERT(PipeInformation
->PipeHandle
);
208 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
209 Urb
->UrbHeader
.Function
= URB_FUNCTION_ABORT_PIPE
;
210 Urb
->UrbHeader
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
211 Urb
->UrbPipeRequest
.PipeHandle
= PipeInformation
->PipeHandle
;
216 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
231 IN PDEVICE_OBJECT DeviceObject
)
235 PHID_DEVICE_EXTENSION DeviceExtension
;
236 IO_STATUS_BLOCK IoStatusBlock
;
240 // get device extension
242 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
247 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
252 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT
, DeviceExtension
->NextDeviceObject
, NULL
, 0, NULL
, 0, TRUE
, &Event
, &IoStatusBlock
);
258 return STATUS_INSUFFICIENT_RESOURCES
;
264 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
265 if (Status
== STATUS_PENDING
)
268 // wait for request completion
270 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
271 Status
= IoStatusBlock
.Status
;
277 return IoStatusBlock
.Status
;
283 IN PDEVICE_OBJECT DeviceObject
,
286 PIO_STACK_LOCATION IoStack
;
289 // get current irp stack location
291 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
294 // sanity check for hidclass driver
296 ASSERT(IoStack
->MajorFunction
== IRP_MJ_CREATE
|| IoStack
->MajorFunction
== IRP_MJ_CLOSE
);
301 Irp
->IoStatus
.Information
= 0;
302 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
303 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
306 // informal debug print
308 DPRINT1("HIDUSB Request: %x\n", IoStack
->MajorFunction
);
313 return STATUS_SUCCESS
;
318 HidUsb_ResetWorkerRoutine(
319 IN PDEVICE_OBJECT DeviceObject
,
324 PHID_USB_RESET_CONTEXT ResetContext
;
325 PHID_DEVICE_EXTENSION DeviceExtension
;
327 DPRINT1("[HIDUSB] ResetWorkerRoutine\n");
332 ResetContext
= (PHID_USB_RESET_CONTEXT
)Ctx
;
335 // get device extension
337 DeviceExtension
= (PHID_DEVICE_EXTENSION
)ResetContext
->DeviceObject
->DeviceExtension
;
342 Status
= HidUsb_GetPortStatus(ResetContext
->DeviceObject
, &PortStatus
);
343 DPRINT1("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status
, PortStatus
);
344 if (NT_SUCCESS(Status
))
346 if (!(PortStatus
& USB_PORT_STATUS_ENABLE
))
351 Status
= HidUsb_ResetInterruptPipe(ResetContext
->DeviceObject
);
352 DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status
);
359 Status
= HidUsb_AbortPipe(ResetContext
->DeviceObject
);
360 DPRINT1("[HIDUSB] ResetWorkerRoutine AbortPipe %x\n", Status
);
361 if (NT_SUCCESS(Status
))
366 Status
= HidUsb_ResetPort(ResetContext
->DeviceObject
);
367 DPRINT1("[HIDUSB] ResetPort %x\n", Status
);
368 if (Status
== STATUS_DEVICE_DATA_ERROR
)
371 // invalidate device state
373 IoInvalidateDeviceState(DeviceExtension
->PhysicalDeviceObject
);
377 // reset interrupt pipe
379 if (NT_SUCCESS(Status
))
384 Status
= HidUsb_ResetInterruptPipe(ResetContext
->DeviceObject
);
385 DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status
);
394 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
395 IoFreeWorkItem(ResetContext
->WorkItem
);
396 IoCompleteRequest(ResetContext
->Irp
, IO_NO_INCREMENT
);
397 ExFreePool(ResetContext
);
403 HidUsb_ReadReportCompletion(
404 IN PDEVICE_OBJECT DeviceObject
,
408 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
409 PHID_DEVICE_EXTENSION DeviceExtension
;
411 PHID_USB_RESET_CONTEXT ResetContext
;
419 DPRINT("[HIDUSB] HidUsb_ReadReportCompletion %p Status %x Urb Status %x\n", Irp
, Irp
->IoStatus
, Urb
->UrbHeader
.Status
);
421 if (Irp
->PendingReturned
)
426 IoMarkIrpPending(Irp
);
430 // did the reading report succeed / cancelled
432 if (NT_SUCCESS(Irp
->IoStatus
.Status
) || Irp
->IoStatus
.Status
== STATUS_CANCELLED
|| Irp
->IoStatus
.Status
== STATUS_DEVICE_NOT_CONNECTED
)
435 // store result length
437 Irp
->IoStatus
.Information
= Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
;
440 // FIXME handle error
442 ASSERT(Urb
->UrbHeader
.Status
== USBD_STATUS_SUCCESS
);
452 return STATUS_CONTINUE_COMPLETION
;
456 // get device extension
458 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
459 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
462 // allocate reset context
464 ResetContext
= (PHID_USB_RESET_CONTEXT
)ExAllocatePool(NonPagedPool
, sizeof(HID_USB_RESET_CONTEXT
));
468 // allocate work item
470 ResetContext
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
471 if (ResetContext
->WorkItem
)
474 // init reset context
476 ResetContext
->Irp
= Irp
;
477 ResetContext
->DeviceObject
= DeviceObject
;
480 // queue the work item
482 IoQueueWorkItem(ResetContext
->WorkItem
, HidUsb_ResetWorkerRoutine
, DelayedWorkQueue
, ResetContext
);
492 return STATUS_MORE_PROCESSING_REQUIRED
;
497 ExFreePool(ResetContext
);
508 return STATUS_CONTINUE_COMPLETION
;
515 IN PDEVICE_OBJECT DeviceObject
,
518 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
519 PHID_DEVICE_EXTENSION DeviceExtension
;
520 PIO_STACK_LOCATION IoStack
;
522 PUSBD_PIPE_INFORMATION PipeInformation
;
525 // get device extension
527 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
528 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
531 // get current stack location
533 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
538 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
539 ASSERT(Irp
->UserBuffer
);
540 ASSERT(HidDeviceExtension
->InterfaceInfo
);
543 // get interrupt input pipe
545 PipeInformation
= HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension
->InterfaceInfo
);
546 ASSERT(PipeInformation
);
551 Urb
= (PURB
)ExAllocatePool(NonPagedPool
, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
));
557 return STATUS_INSUFFICIENT_RESOURCES
;
563 RtlZeroMemory(Urb
, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
));
568 ASSERT(Irp
->UserBuffer
);
569 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
570 ASSERT(PipeInformation
->PipeHandle
);
575 UsbBuildInterruptOrBulkTransferRequest(Urb
,
576 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
577 PipeInformation
->PipeHandle
,
580 IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
581 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
585 // store configuration handle
587 Urb
->UrbHeader
.UsbdDeviceHandle
= HidDeviceExtension
->ConfigurationHandle
;
590 // get next location to setup irp
592 IoStack
= IoGetNextIrpStackLocation(Irp
);
595 // init irp for lower driver
597 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
598 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
599 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= 0;
600 IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
= 0;
601 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= NULL
;
602 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)Urb
;
606 // set completion routine
608 IoSetCompletionRoutine(Irp
, HidUsb_ReadReportCompletion
, (PVOID
)Urb
, TRUE
, TRUE
, TRUE
);
613 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
619 HidUsb_GetReportDescriptor(
620 IN PDEVICE_OBJECT DeviceObject
,
623 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
624 PHID_DEVICE_EXTENSION DeviceExtension
;
626 ULONG BufferLength
, Length
;
627 PIO_STACK_LOCATION IoStack
;
631 // get device extension
633 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
634 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
639 ASSERT(HidDeviceExtension
);
640 ASSERT(HidDeviceExtension
->HidDescriptor
);
641 ASSERT(HidDeviceExtension
->HidDescriptor
->bNumDescriptors
>= 1);
642 ASSERT(HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].bReportType
== HID_REPORT_DESCRIPTOR_TYPE
);
643 ASSERT(HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
> 0);
646 // FIXME: support old hid version
648 BufferLength
= HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
;
649 Status
= Hid_GetDescriptor(DeviceObject
, URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
), &Report
, &BufferLength
, HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].bReportType
, 0, 0);
650 if (!NT_SUCCESS(Status
))
653 // failed to get descriptor
655 DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status
);
661 // get current stack location
663 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
664 DPRINT1("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status
, HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, BufferLength
);
667 // get length to copy
669 Length
= min(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, BufferLength
);
675 RtlCopyMemory(Irp
->UserBuffer
, Report
, Length
);
678 // store result length
680 Irp
->IoStatus
.Information
= Length
;
691 HidInternalDeviceControl(
692 IN PDEVICE_OBJECT DeviceObject
,
695 PIO_STACK_LOCATION IoStack
;
696 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
697 PHID_DEVICE_EXTENSION DeviceExtension
;
698 PHID_DEVICE_ATTRIBUTES Attributes
;
703 // get device extension
705 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
706 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
709 // get current stack location
711 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
713 switch(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
)
715 case IOCTL_HID_GET_DEVICE_ATTRIBUTES
:
717 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(HID_DEVICE_ATTRIBUTES
))
722 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
723 DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES invalid buffer\n");
724 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
725 return STATUS_INVALID_BUFFER_SIZE
;
730 DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES\n");
731 ASSERT(HidDeviceExtension
->DeviceDescriptor
);
732 Irp
->IoStatus
.Information
= sizeof(HID_DESCRIPTOR
);
733 Attributes
= (PHID_DEVICE_ATTRIBUTES
)Irp
->UserBuffer
;
734 Attributes
->Size
= sizeof(HID_DEVICE_ATTRIBUTES
);
735 Attributes
->VendorID
= HidDeviceExtension
->DeviceDescriptor
->idVendor
;
736 Attributes
->ProductID
= HidDeviceExtension
->DeviceDescriptor
->idProduct
;
737 Attributes
->VersionNumber
= HidDeviceExtension
->DeviceDescriptor
->bcdDevice
;
742 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
743 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
744 return STATUS_SUCCESS
;
746 case IOCTL_HID_GET_DEVICE_DESCRIPTOR
:
751 ASSERT(HidDeviceExtension
->HidDescriptor
);
752 DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension
->HidDescriptor
->bLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
757 Length
= min(HidDeviceExtension
->HidDescriptor
->bLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
762 RtlCopyMemory(Irp
->UserBuffer
, HidDeviceExtension
->HidDescriptor
, Length
);
765 // store result length
767 Irp
->IoStatus
.Information
= HidDeviceExtension
->HidDescriptor
->bLength
;
768 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
770 /* complete request */
771 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
772 return STATUS_SUCCESS
;
774 case IOCTL_HID_GET_REPORT_DESCRIPTOR
:
776 Status
= HidUsb_GetReportDescriptor(DeviceObject
, Irp
);
777 DPRINT1("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status
);
778 Irp
->IoStatus
.Status
= Status
;
779 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
782 case IOCTL_HID_READ_REPORT
:
784 DPRINT("[HIDUSB] IOCTL_HID_READ_REPORT\n");
785 Status
= HidUsb_ReadReport(DeviceObject
, Irp
);
788 case IOCTL_HID_WRITE_REPORT
:
790 DPRINT1("[HIDUSB] IOCTL_HID_WRITE_REPORT not implemented \n");
792 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
793 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
794 return STATUS_NOT_IMPLEMENTED
;
796 case IOCTL_GET_PHYSICAL_DESCRIPTOR
:
798 DPRINT1("[HIDUSB] IOCTL_GET_PHYSICAL_DESCRIPTOR not implemented \n");
800 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
801 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
802 return STATUS_NOT_IMPLEMENTED
;
804 case IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST
:
806 DPRINT1("[HIDUSB] IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST not implemented \n");
808 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
809 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
810 return STATUS_NOT_IMPLEMENTED
;
812 case IOCTL_HID_GET_FEATURE
:
814 DPRINT1("[HIDUSB] IOCTL_HID_GET_FEATURE not implemented \n");
816 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
817 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
818 return STATUS_NOT_IMPLEMENTED
;
820 case IOCTL_HID_SET_FEATURE
:
822 DPRINT1("[HIDUSB] IOCTL_HID_SET_FEATURE not implemented \n");
824 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
825 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
826 return STATUS_NOT_IMPLEMENTED
;
828 case IOCTL_HID_SET_OUTPUT_REPORT
:
830 DPRINT1("[HIDUSB] IOCTL_HID_SET_OUTPUT_REPORT not implemented \n");
832 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
833 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
834 return STATUS_NOT_IMPLEMENTED
;
836 case IOCTL_HID_GET_INPUT_REPORT
:
838 DPRINT1("[HIDUSB] IOCTL_HID_GET_INPUT_REPORT not implemented \n");
840 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
841 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
842 return STATUS_NOT_IMPLEMENTED
;
844 case IOCTL_HID_GET_INDEXED_STRING
:
846 DPRINT1("[HIDUSB] IOCTL_HID_GET_INDEXED_STRING not implemented \n");
848 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
849 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
850 return STATUS_NOT_IMPLEMENTED
;
852 case IOCTL_HID_GET_MS_GENRE_DESCRIPTOR
:
854 DPRINT1("[HIDUSB] IOCTL_HID_GET_MS_GENRE_DESCRIPTOR not implemented \n");
856 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
857 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
858 return STATUS_NOT_IMPLEMENTED
;
864 Status
= Irp
->IoStatus
.Status
;
865 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
874 IN PDEVICE_OBJECT DeviceObject
,
879 return STATUS_NOT_IMPLEMENTED
;
885 IN PDEVICE_OBJECT DeviceObject
,
888 PHID_DEVICE_EXTENSION DeviceExtension
;
891 // get hid device extension
893 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
896 // copy stack location
898 IoCopyCurrentIrpStackLocationToNext(Irp
);
903 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
909 IN PDEVICE_OBJECT DeviceObject
,
916 KeSetEvent((PRKEVENT
)Context
, 0, FALSE
);
921 return STATUS_MORE_PROCESSING_REQUIRED
;
927 IN PDEVICE_OBJECT DeviceObject
,
932 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
933 PHID_DEVICE_EXTENSION DeviceExtension
;
934 IO_STATUS_BLOCK IoStatus
;
935 PIO_STACK_LOCATION IoStack
;
941 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
944 // get device extension
946 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
947 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
953 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB
, DeviceExtension
->NextDeviceObject
, NULL
, 0, NULL
, 0, TRUE
, &Event
, &IoStatus
);
959 return STATUS_INSUFFICIENT_RESOURCES
;
963 // get next stack location
965 IoStack
= IoGetNextIrpStackLocation(Irp
);
970 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)Urb
;
973 // set completion routine
975 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
980 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
983 // wait for the request to finish
985 if (Status
== STATUS_PENDING
)
987 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
993 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
995 if (Status
== STATUS_PENDING
)
1000 Status
= IoStatus
.Status
;
1003 DPRINT1("[HIDUSB] DispatchUrb %x\n", Status
);
1014 IN PDEVICE_OBJECT DeviceObject
,
1015 IN USHORT UrbFunction
,
1016 IN USHORT UrbLength
,
1017 IN OUT PVOID
*UrbBuffer
,
1018 IN OUT PULONG UrbBufferLength
,
1019 IN UCHAR DescriptorType
,
1021 IN USHORT LanguageIndex
)
1025 UCHAR Allocated
= FALSE
;
1030 Urb
= (PURB
)ExAllocatePool(NonPagedPool
, UrbLength
);
1036 return STATUS_INSUFFICIENT_RESOURCES
;
1040 // is there an urb buffer
1047 *UrbBuffer
= ExAllocatePool(NonPagedPool
, *UrbBufferLength
);
1054 return STATUS_INSUFFICIENT_RESOURCES
;
1060 RtlZeroMemory(*UrbBuffer
, *UrbBufferLength
);
1067 RtlZeroMemory(Urb
, UrbLength
);
1070 // build descriptor request
1072 UsbBuildGetDescriptorRequest(Urb
, UrbLength
, DescriptorType
, Index
, LanguageIndex
, *UrbBuffer
, NULL
, *UrbBufferLength
, NULL
);
1077 Urb
->UrbHeader
.Function
= UrbFunction
;
1082 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1085 // did the request fail
1087 if (!NT_SUCCESS(Status
))
1092 // free allocated buffer
1094 ExFreePool(*UrbBuffer
);
1102 *UrbBufferLength
= 0;
1107 // did urb request fail
1109 if (!NT_SUCCESS(Urb
->UrbHeader
.Status
))
1114 // free allocated buffer
1116 ExFreePool(*UrbBuffer
);
1124 *UrbBufferLength
= 0;
1125 return STATUS_UNSUCCESSFUL
;
1129 // store result length
1131 *UrbBufferLength
= Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
1139 // completed successfully
1141 return STATUS_SUCCESS
;
1145 Hid_SelectConfiguration(
1146 IN PDEVICE_OBJECT DeviceObject
)
1148 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1150 USBD_INTERFACE_LIST_ENTRY InterfaceList
[2];
1152 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1153 PHID_DEVICE_EXTENSION DeviceExtension
;
1156 // get device extension
1158 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1159 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1162 // now parse the descriptors
1164 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(HidDeviceExtension
->ConfigurationDescriptor
,
1165 HidDeviceExtension
->ConfigurationDescriptor
,
1168 USB_DEVICE_CLASS_HUMAN_INTERFACE
,
1175 ASSERT(InterfaceDescriptor
);
1176 ASSERT(InterfaceDescriptor
->bInterfaceClass
== USB_DEVICE_CLASS_HUMAN_INTERFACE
);
1177 ASSERT(InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
1178 ASSERT(InterfaceDescriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
1181 // setup interface list
1183 RtlZeroMemory(InterfaceList
, sizeof(InterfaceList
));
1184 InterfaceList
[0].InterfaceDescriptor
= InterfaceDescriptor
;
1189 Urb
= USBD_CreateConfigurationRequestEx(HidDeviceExtension
->ConfigurationDescriptor
, InterfaceList
);
1195 return STATUS_INSUFFICIENT_RESOURCES
;
1201 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1202 if (NT_SUCCESS(Status
))
1205 // store configuration handle
1207 HidDeviceExtension
->ConfigurationHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
1210 // copy interface info
1212 HidDeviceExtension
->InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
)ExAllocatePool(NonPagedPool
, Urb
->UrbSelectConfiguration
.Interface
.Length
);
1213 if (HidDeviceExtension
->InterfaceInfo
)
1216 // copy interface info
1218 RtlCopyMemory(HidDeviceExtension
->InterfaceInfo
, &Urb
->UrbSelectConfiguration
.Interface
, Urb
->UrbSelectConfiguration
.Interface
.Length
);
1236 IN PDEVICE_OBJECT DeviceObject
)
1238 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1239 PHID_DEVICE_EXTENSION DeviceExtension
;
1241 ULONG DescriptorLength
;
1242 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1243 PHID_DESCRIPTOR HidDescriptor
;
1246 // get device extension
1248 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1249 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1252 // get device descriptor
1254 DescriptorLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
1255 Status
= Hid_GetDescriptor(DeviceObject
, URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
), (PVOID
*)&HidDeviceExtension
->DeviceDescriptor
, &DescriptorLength
, USB_DEVICE_DESCRIPTOR_TYPE
, 0, 0);
1256 if (!NT_SUCCESS(Status
))
1259 // failed to obtain device descriptor
1261 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1266 // now get the configuration descriptor
1268 DescriptorLength
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
1269 Status
= Hid_GetDescriptor(DeviceObject
, URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
), (PVOID
*)&HidDeviceExtension
->ConfigurationDescriptor
, &DescriptorLength
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, 0, 0);
1270 if (!NT_SUCCESS(Status
))
1273 // failed to obtain device descriptor
1275 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1282 ASSERT(DescriptorLength
);
1283 ASSERT(HidDeviceExtension
->ConfigurationDescriptor
);
1284 ASSERT(HidDeviceExtension
->ConfigurationDescriptor
->bLength
);
1287 // store full length
1289 DescriptorLength
= HidDeviceExtension
->ConfigurationDescriptor
->wTotalLength
;
1292 // delete partial configuration descriptor
1294 ExFreePool(HidDeviceExtension
->ConfigurationDescriptor
);
1295 HidDeviceExtension
->ConfigurationDescriptor
= NULL
;
1298 // get full configuration descriptor
1300 Status
= Hid_GetDescriptor(DeviceObject
, URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
), (PVOID
*)&HidDeviceExtension
->ConfigurationDescriptor
, &DescriptorLength
, USB_CONFIGURATION_DESCRIPTOR_TYPE
, 0, 0);
1301 if (!NT_SUCCESS(Status
))
1304 // failed to obtain device descriptor
1306 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1311 // now parse the descriptors
1313 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(HidDeviceExtension
->ConfigurationDescriptor
,
1314 HidDeviceExtension
->ConfigurationDescriptor
,
1317 USB_DEVICE_CLASS_HUMAN_INTERFACE
,
1320 if (!InterfaceDescriptor
)
1323 // no interface class
1325 DPRINT1("[HIDUSB] HID Class found\n");
1326 return STATUS_UNSUCCESSFUL
;
1332 ASSERT(InterfaceDescriptor
->bInterfaceClass
== USB_DEVICE_CLASS_HUMAN_INTERFACE
);
1333 ASSERT(InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
1334 ASSERT(InterfaceDescriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
1337 // move to next descriptor
1339 HidDescriptor
= (PHID_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
1340 ASSERT(HidDescriptor
->bLength
>= 2);
1343 // check if this is the hid descriptor
1345 if (HidDescriptor
->bLength
== sizeof(HID_DESCRIPTOR
) && HidDescriptor
->bDescriptorType
== HID_HID_DESCRIPTOR_TYPE
)
1350 HidDeviceExtension
->HidDescriptor
= HidDescriptor
;
1353 // select configuration
1355 Status
= Hid_SelectConfiguration(DeviceObject
);
1356 ASSERT(Status
== STATUS_SUCCESS
);
1361 DPRINT1("[HIDUSB] SelectConfiguration %x\n", Status
);
1366 // FIXME parse hid descriptor
1370 return STATUS_SUCCESS
;
1377 IN PDEVICE_OBJECT DeviceObject
,
1381 PIO_STACK_LOCATION IoStack
;
1382 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1383 PHID_DEVICE_EXTENSION DeviceExtension
;
1387 // get device extension
1389 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1390 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1393 // get current stack location
1395 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1396 DPRINT1("[HIDUSB] Pnp %x\n", IoStack
->MinorFunction
);
1399 // handle requests based on request type
1401 switch(IoStack
->MinorFunction
)
1403 case IRP_MN_REMOVE_DEVICE
:
1406 // pass request onto lower driver
1408 IoSkipCurrentIrpStackLocation(Irp
);
1409 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1414 if (HidDeviceExtension
->HidDescriptor
)
1416 ExFreePool(HidDeviceExtension
->HidDescriptor
);
1417 HidDeviceExtension
->HidDescriptor
= NULL
;
1425 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1428 // device can not be disabled
1430 Irp
->IoStatus
.Information
|= PNP_DEVICE_NOT_DISABLEABLE
;
1433 // pass request to next request
1435 IoSkipCurrentIrpStackLocation(Irp
);
1436 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1443 case IRP_MN_STOP_DEVICE
:
1446 // FIXME: unconfigure the device
1452 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1453 IoCopyCurrentIrpStackLocationToNext(Irp
);
1454 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1457 // send irp and wait for completion
1459 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1460 if (Status
== STATUS_PENDING
)
1462 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1463 Status
= Irp
->IoStatus
.Status
;
1469 if (HidDeviceExtension
->HidDescriptor
)
1471 ExFreePool(HidDeviceExtension
->HidDescriptor
);
1472 HidDeviceExtension
->HidDescriptor
= NULL
;
1478 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1481 case IRP_MN_QUERY_CAPABILITIES
:
1486 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1487 IoCopyCurrentIrpStackLocationToNext(Irp
);
1488 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1491 // send irp and wait for completion
1493 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1494 if (Status
== STATUS_PENDING
)
1496 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1497 Status
= Irp
->IoStatus
.Status
;
1500 if (NT_SUCCESS(Status
))
1503 // driver supports D1 & D2
1505 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->DeviceD1
= TRUE
;
1506 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->DeviceD2
= TRUE
;
1509 // don't need to safely remove
1511 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->SurpriseRemovalOK
= TRUE
;
1517 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1520 case IRP_MN_START_DEVICE
:
1525 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1526 IoCopyCurrentIrpStackLocationToNext(Irp
);
1527 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1530 // send irp and wait for completion
1532 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1533 if (Status
== STATUS_PENDING
)
1535 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1536 Status
= Irp
->IoStatus
.Status
;
1540 // did the device successfully start
1542 if (!NT_SUCCESS(Status
))
1547 DPRINT1("HIDUSB: IRP_MN_START_DEVICE failed with %x\n", Status
);
1548 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1555 Status
= Hid_PnpStart(DeviceObject
);
1560 Irp
->IoStatus
.Status
= Status
;
1561 DPRINT1("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status
);
1562 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1568 // forward and forget request
1570 IoSkipCurrentIrpStackLocation(Irp
);
1571 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1579 IN PDRIVER_OBJECT DriverObject
,
1580 IN PDEVICE_OBJECT DeviceObject
)
1582 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1583 PHID_DEVICE_EXTENSION DeviceExtension
;
1586 // get device extension
1588 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1589 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1594 KeInitializeEvent(&HidDeviceExtension
->Event
, NotificationEvent
, FALSE
);
1599 return STATUS_SUCCESS
;
1605 IN PDRIVER_OBJECT DriverObject
,
1606 IN PUNICODE_STRING RegPath
)
1608 HID_MINIDRIVER_REGISTRATION Registration
;
1612 // initialize driver object
1614 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = HidCreate
;
1615 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = HidCreate
;
1616 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = HidInternalDeviceControl
;
1617 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = HidPower
;
1618 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = HidSystemControl
;
1619 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = HidPnp
;
1620 DriverObject
->DriverExtension
->AddDevice
= HidAddDevice
;
1623 // prepare registration info
1625 RtlZeroMemory(&Registration
, sizeof(HID_MINIDRIVER_REGISTRATION
));
1628 // fill in registration info
1630 Registration
.Revision
= HID_REVISION
;
1631 Registration
.DriverObject
= DriverObject
;
1632 Registration
.RegistryPath
= RegPath
;
1633 Registration
.DeviceExtensionSize
= sizeof(HID_USB_DEVICE_EXTENSION
);
1634 Registration
.DevicesArePolled
= FALSE
;
1639 Status
= HidRegisterMinidriver(&Registration
);
1644 DPRINT1("********* HIDUSB *********\n");
1645 DPRINT1("HIDUSB Registration Status %x\n", Status
);