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
= DeviceObject
->DeviceExtension
;
67 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
72 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_GET_PORT_STATUS
,
73 DeviceExtension
->NextDeviceObject
,
86 return STATUS_INSUFFICIENT_RESOURCES
;
92 IoStack
= IoGetNextIrpStackLocation(Irp
);
95 // store result buffer
97 IoStack
->Parameters
.Others
.Argument1
= PortStatus
;
102 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
103 if (Status
== STATUS_PENDING
)
106 // wait for completion
108 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, 0, NULL
);
109 return IoStatus
.Status
;
119 HidUsb_ResetInterruptPipe(
120 IN PDEVICE_OBJECT DeviceObject
)
122 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
123 PHID_DEVICE_EXTENSION DeviceExtension
;
124 PUSBD_PIPE_INFORMATION PipeInformation
;
129 // get device extension
131 DeviceExtension
= DeviceObject
->DeviceExtension
;
132 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
135 // get interrupt pipe handle
137 ASSERT(HidDeviceExtension
->InterfaceInfo
);
138 PipeInformation
= HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension
->InterfaceInfo
);
139 ASSERT(PipeInformation
);
140 ASSERT(PipeInformation
->PipeHandle
);
145 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(struct _URB_PIPE_REQUEST
), HIDUSB_URB_TAG
);
151 return STATUS_INSUFFICIENT_RESOURCES
;
157 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
158 Urb
->UrbHeader
.Function
= URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
;
159 Urb
->UrbHeader
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
160 Urb
->UrbPipeRequest
.PipeHandle
= PipeInformation
->PipeHandle
;
165 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
170 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
180 IN PDEVICE_OBJECT DeviceObject
)
182 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
183 PHID_DEVICE_EXTENSION DeviceExtension
;
186 PUSBD_PIPE_INFORMATION PipeInformation
;
189 // get device extension
191 DeviceExtension
= DeviceObject
->DeviceExtension
;
192 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
197 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(struct _URB_PIPE_REQUEST
), HIDUSB_URB_TAG
);
203 return STATUS_INSUFFICIENT_RESOURCES
;
207 // get pipe information
209 PipeInformation
= HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension
->InterfaceInfo
);
210 ASSERT(PipeInformation
);
211 ASSERT(PipeInformation
->PipeHandle
);
216 RtlZeroMemory(Urb
, sizeof(struct _URB_PIPE_REQUEST
));
217 Urb
->UrbHeader
.Function
= URB_FUNCTION_ABORT_PIPE
;
218 Urb
->UrbHeader
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
219 Urb
->UrbPipeRequest
.PipeHandle
= PipeInformation
->PipeHandle
;
224 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
229 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
239 IN PDEVICE_OBJECT DeviceObject
)
243 PHID_DEVICE_EXTENSION DeviceExtension
;
244 IO_STATUS_BLOCK IoStatusBlock
;
248 // get device extension
250 DeviceExtension
= DeviceObject
->DeviceExtension
;
255 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
260 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT
,
261 DeviceExtension
->NextDeviceObject
,
274 return STATUS_INSUFFICIENT_RESOURCES
;
280 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
281 if (Status
== STATUS_PENDING
)
284 // wait for request completion
286 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
287 Status
= IoStatusBlock
.Status
;
293 return IoStatusBlock
.Status
;
299 IN PDEVICE_OBJECT DeviceObject
,
302 PIO_STACK_LOCATION IoStack
;
305 // get current irp stack location
307 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
310 // sanity check for hidclass driver
312 ASSERT(IoStack
->MajorFunction
== IRP_MJ_CREATE
|| IoStack
->MajorFunction
== IRP_MJ_CLOSE
);
315 // informational debug print
317 DPRINT("HIDUSB Request: %x\n", IoStack
->MajorFunction
);
322 Irp
->IoStatus
.Information
= 0;
323 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
324 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
329 return STATUS_SUCCESS
;
334 HidUsb_ResetWorkerRoutine(
335 IN PDEVICE_OBJECT DeviceObject
,
340 PHID_USB_RESET_CONTEXT ResetContext
;
341 PHID_DEVICE_EXTENSION DeviceExtension
;
343 DPRINT("[HIDUSB] ResetWorkerRoutine\n");
351 // get device extension
353 DeviceExtension
= ResetContext
->DeviceObject
->DeviceExtension
;
358 Status
= HidUsb_GetPortStatus(ResetContext
->DeviceObject
, &PortStatus
);
359 DPRINT("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status
, PortStatus
);
360 if (NT_SUCCESS(Status
))
362 if (!(PortStatus
& USB_PORT_STATUS_ENABLE
))
367 Status
= HidUsb_ResetInterruptPipe(ResetContext
->DeviceObject
);
368 DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status
);
375 Status
= HidUsb_AbortPipe(ResetContext
->DeviceObject
);
376 DPRINT1("[HIDUSB] ResetWorkerRoutine AbortPipe %x\n", Status
);
377 if (NT_SUCCESS(Status
))
382 Status
= HidUsb_ResetPort(ResetContext
->DeviceObject
);
383 DPRINT1("[HIDUSB] ResetPort %x\n", Status
);
384 if (Status
== STATUS_DEVICE_DATA_ERROR
)
387 // invalidate device state
389 IoInvalidateDeviceState(DeviceExtension
->PhysicalDeviceObject
);
393 // reset interrupt pipe
395 if (NT_SUCCESS(Status
))
400 Status
= HidUsb_ResetInterruptPipe(ResetContext
->DeviceObject
);
401 DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status
);
410 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
411 IoFreeWorkItem(ResetContext
->WorkItem
);
412 IoCompleteRequest(ResetContext
->Irp
, IO_NO_INCREMENT
);
413 ExFreePoolWithTag(ResetContext
, HIDUSB_TAG
);
419 HidUsb_ReadReportCompletion(
420 IN PDEVICE_OBJECT DeviceObject
,
425 PHID_USB_RESET_CONTEXT ResetContext
;
433 DPRINT("[HIDUSB] HidUsb_ReadReportCompletion %p Status %x Urb Status %x\n", Irp
, Irp
->IoStatus
, Urb
->UrbHeader
.Status
);
435 if (Irp
->PendingReturned
)
440 IoMarkIrpPending(Irp
);
444 // did the reading report succeed / cancelled
446 if (NT_SUCCESS(Irp
->IoStatus
.Status
) || Irp
->IoStatus
.Status
== STATUS_CANCELLED
|| Irp
->IoStatus
.Status
== STATUS_DEVICE_NOT_CONNECTED
)
449 // store result length
451 Irp
->IoStatus
.Information
= Urb
->UrbBulkOrInterruptTransfer
.TransferBufferLength
;
454 // FIXME handle error
456 ASSERT(Urb
->UrbHeader
.Status
== USBD_STATUS_SUCCESS
);
461 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
466 return STATUS_CONTINUE_COMPLETION
;
470 // allocate reset context
472 ResetContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(HID_USB_RESET_CONTEXT
), HIDUSB_TAG
);
476 // allocate work item
478 ResetContext
->WorkItem
= IoAllocateWorkItem(DeviceObject
);
479 if (ResetContext
->WorkItem
)
482 // init reset context
484 ResetContext
->Irp
= Irp
;
485 ResetContext
->DeviceObject
= DeviceObject
;
488 // queue the work item
490 IoQueueWorkItem(ResetContext
->WorkItem
, HidUsb_ResetWorkerRoutine
, DelayedWorkQueue
, ResetContext
);
495 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
500 return STATUS_MORE_PROCESSING_REQUIRED
;
505 ExFreePoolWithTag(ResetContext
, HIDUSB_TAG
);
511 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
516 return STATUS_CONTINUE_COMPLETION
;
523 IN PDEVICE_OBJECT DeviceObject
,
526 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
527 PHID_DEVICE_EXTENSION DeviceExtension
;
528 PIO_STACK_LOCATION IoStack
;
530 PUSBD_PIPE_INFORMATION PipeInformation
;
533 // get device extension
535 DeviceExtension
= DeviceObject
->DeviceExtension
;
536 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
539 // get current stack location
541 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
546 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
547 ASSERT(Irp
->UserBuffer
);
548 ASSERT(HidDeviceExtension
->InterfaceInfo
);
551 // get interrupt input pipe
553 PipeInformation
= HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension
->InterfaceInfo
);
554 ASSERT(PipeInformation
);
559 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
), HIDUSB_URB_TAG
);
565 return STATUS_INSUFFICIENT_RESOURCES
;
571 RtlZeroMemory(Urb
, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
));
576 ASSERT(Irp
->UserBuffer
);
577 ASSERT(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
578 ASSERT(PipeInformation
->PipeHandle
);
583 UsbBuildInterruptOrBulkTransferRequest(Urb
,
584 sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER
),
585 PipeInformation
->PipeHandle
,
588 IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
589 USBD_TRANSFER_DIRECTION_IN
| USBD_SHORT_TRANSFER_OK
,
593 // store configuration handle
595 Urb
->UrbHeader
.UsbdDeviceHandle
= HidDeviceExtension
->ConfigurationHandle
;
598 // get next location to setup irp
600 IoStack
= IoGetNextIrpStackLocation(Irp
);
603 // init irp for lower driver
605 IoStack
->MajorFunction
= IRP_MJ_INTERNAL_DEVICE_CONTROL
;
606 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= IOCTL_INTERNAL_USB_SUBMIT_URB
;
607 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= 0;
608 IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
= 0;
609 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= NULL
;
610 IoStack
->Parameters
.Others
.Argument1
= Urb
;
614 // set completion routine
616 IoSetCompletionRoutine(Irp
, HidUsb_ReadReportCompletion
, Urb
, TRUE
, TRUE
, TRUE
);
621 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
627 HidUsb_GetReportDescriptor(
628 IN PDEVICE_OBJECT DeviceObject
,
631 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
632 PHID_DEVICE_EXTENSION DeviceExtension
;
634 ULONG BufferLength
, Length
;
635 PIO_STACK_LOCATION IoStack
;
639 // get device extension
641 DeviceExtension
= DeviceObject
->DeviceExtension
;
642 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
647 ASSERT(HidDeviceExtension
);
648 ASSERT(HidDeviceExtension
->HidDescriptor
);
649 ASSERT(HidDeviceExtension
->HidDescriptor
->bNumDescriptors
>= 1);
650 ASSERT(HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].bReportType
== HID_REPORT_DESCRIPTOR_TYPE
);
651 ASSERT(HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
> 0);
654 // FIXME: support old hid version
656 BufferLength
= HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
;
657 Status
= Hid_GetDescriptor(DeviceObject
,
658 URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
,
659 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
662 HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].bReportType
,
664 HidDeviceExtension
->InterfaceInfo
->InterfaceNumber
);
665 if (!NT_SUCCESS(Status
))
668 // failed to get descriptor
669 // try with old hid version
671 BufferLength
= HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
;
672 Status
= Hid_GetDescriptor(DeviceObject
,
673 URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT
,
674 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
677 HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].bReportType
,
680 if (!NT_SUCCESS(Status
))
682 DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status
);
688 // get current stack location
690 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
691 DPRINT("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status
, HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, BufferLength
);
694 // get length to copy
696 Length
= min(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, BufferLength
);
702 RtlCopyMemory(Irp
->UserBuffer
, Report
, Length
);
705 // store result length
707 Irp
->IoStatus
.Information
= Length
;
710 // free the report buffer
712 ExFreePoolWithTag(Report
, HIDUSB_TAG
);
723 HidInternalDeviceControl(
724 IN PDEVICE_OBJECT DeviceObject
,
727 PIO_STACK_LOCATION IoStack
;
728 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
729 PHID_DEVICE_EXTENSION DeviceExtension
;
730 PHID_DEVICE_ATTRIBUTES Attributes
;
735 // get device extension
737 DeviceExtension
= DeviceObject
->DeviceExtension
;
738 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
741 // get current stack location
743 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
745 switch (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
)
747 case IOCTL_HID_GET_DEVICE_ATTRIBUTES
:
749 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(HID_DEVICE_ATTRIBUTES
))
754 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
755 DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES invalid buffer\n");
756 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
757 return STATUS_INVALID_BUFFER_SIZE
;
762 DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES\n");
763 ASSERT(HidDeviceExtension
->DeviceDescriptor
);
764 Irp
->IoStatus
.Information
= sizeof(HID_DESCRIPTOR
);
765 Attributes
= Irp
->UserBuffer
;
766 Attributes
->Size
= sizeof(HID_DEVICE_ATTRIBUTES
);
767 Attributes
->VendorID
= HidDeviceExtension
->DeviceDescriptor
->idVendor
;
768 Attributes
->ProductID
= HidDeviceExtension
->DeviceDescriptor
->idProduct
;
769 Attributes
->VersionNumber
= HidDeviceExtension
->DeviceDescriptor
->bcdDevice
;
774 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
775 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
776 return STATUS_SUCCESS
;
778 case IOCTL_HID_GET_DEVICE_DESCRIPTOR
:
783 ASSERT(HidDeviceExtension
->HidDescriptor
);
784 DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension
->HidDescriptor
->bLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
789 Length
= min(HidDeviceExtension
->HidDescriptor
->bLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
794 RtlCopyMemory(Irp
->UserBuffer
, HidDeviceExtension
->HidDescriptor
, Length
);
797 // store result length
799 Irp
->IoStatus
.Information
= HidDeviceExtension
->HidDescriptor
->bLength
;
800 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
802 /* complete request */
803 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
804 return STATUS_SUCCESS
;
806 case IOCTL_HID_GET_REPORT_DESCRIPTOR
:
808 Status
= HidUsb_GetReportDescriptor(DeviceObject
, Irp
);
809 DPRINT("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status
);
810 Irp
->IoStatus
.Status
= Status
;
811 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
814 case IOCTL_HID_READ_REPORT
:
816 DPRINT("[HIDUSB] IOCTL_HID_READ_REPORT\n");
817 Status
= HidUsb_ReadReport(DeviceObject
, Irp
);
820 case IOCTL_HID_WRITE_REPORT
:
822 DPRINT1("[HIDUSB] IOCTL_HID_WRITE_REPORT not implemented \n");
824 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
825 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
826 return STATUS_NOT_IMPLEMENTED
;
828 case IOCTL_GET_PHYSICAL_DESCRIPTOR
:
830 DPRINT1("[HIDUSB] IOCTL_GET_PHYSICAL_DESCRIPTOR 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_SEND_IDLE_NOTIFICATION_REQUEST
:
838 DPRINT1("[HIDUSB] IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST 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_FEATURE
:
846 DPRINT1("[HIDUSB] IOCTL_HID_GET_FEATURE 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_SET_FEATURE
:
854 DPRINT1("[HIDUSB] IOCTL_HID_SET_FEATURE not implemented \n");
856 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
857 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
858 return STATUS_NOT_IMPLEMENTED
;
860 case IOCTL_HID_SET_OUTPUT_REPORT
:
862 DPRINT1("[HIDUSB] IOCTL_HID_SET_OUTPUT_REPORT not implemented \n");
864 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
865 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
866 return STATUS_NOT_IMPLEMENTED
;
868 case IOCTL_HID_GET_INPUT_REPORT
:
870 DPRINT1("[HIDUSB] IOCTL_HID_GET_INPUT_REPORT not implemented \n");
872 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
873 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
874 return STATUS_NOT_IMPLEMENTED
;
876 case IOCTL_HID_GET_INDEXED_STRING
:
878 DPRINT1("[HIDUSB] IOCTL_HID_GET_INDEXED_STRING not implemented \n");
880 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
881 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
882 return STATUS_NOT_IMPLEMENTED
;
884 case IOCTL_HID_GET_MS_GENRE_DESCRIPTOR
:
886 DPRINT1("[HIDUSB] IOCTL_HID_GET_MS_GENRE_DESCRIPTOR not implemented \n");
888 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
889 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
890 return STATUS_NOT_IMPLEMENTED
;
896 Status
= Irp
->IoStatus
.Status
;
897 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
906 IN PDEVICE_OBJECT DeviceObject
,
909 PHID_DEVICE_EXTENSION DeviceExtension
;
911 DeviceExtension
= DeviceObject
->DeviceExtension
;
912 PoStartNextPowerIrp(Irp
);
913 IoSkipCurrentIrpStackLocation(Irp
);
914 return PoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
920 IN PDEVICE_OBJECT DeviceObject
,
923 PHID_DEVICE_EXTENSION DeviceExtension
;
926 // get hid device extension
928 DeviceExtension
= DeviceObject
->DeviceExtension
;
931 // skip stack location
933 IoSkipCurrentIrpStackLocation(Irp
);
938 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
944 IN PDEVICE_OBJECT DeviceObject
,
951 KeSetEvent(Context
, 0, FALSE
);
956 return STATUS_MORE_PROCESSING_REQUIRED
;
961 IN PDEVICE_OBJECT DeviceObject
,
966 PHID_DEVICE_EXTENSION DeviceExtension
;
967 IO_STATUS_BLOCK IoStatus
;
968 PIO_STACK_LOCATION IoStack
;
974 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
977 // get device extension
979 DeviceExtension
= DeviceObject
->DeviceExtension
;
984 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB
,
985 DeviceExtension
->NextDeviceObject
,
998 return STATUS_INSUFFICIENT_RESOURCES
;
1002 // get next stack location
1004 IoStack
= IoGetNextIrpStackLocation(Irp
);
1009 IoStack
->Parameters
.Others
.Argument1
= Urb
;
1012 // set completion routine
1014 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
1019 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1022 // wait for the request to finish
1024 if (Status
== STATUS_PENDING
)
1026 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1032 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1034 if (Status
== STATUS_PENDING
)
1039 Status
= IoStatus
.Status
;
1042 DPRINT("[HIDUSB] DispatchUrb %x\n", Status
);
1053 IN PDEVICE_OBJECT DeviceObject
,
1054 IN USHORT UrbFunction
,
1055 IN USHORT UrbLength
,
1056 IN OUT PVOID
*UrbBuffer
,
1057 IN OUT PULONG UrbBufferLength
,
1058 IN UCHAR DescriptorType
,
1060 IN USHORT LanguageIndex
)
1064 UCHAR Allocated
= FALSE
;
1069 Urb
= ExAllocatePoolWithTag(NonPagedPool
, UrbLength
, HIDUSB_URB_TAG
);
1075 return STATUS_INSUFFICIENT_RESOURCES
;
1079 // is there an urb buffer
1086 *UrbBuffer
= ExAllocatePoolWithTag(NonPagedPool
, *UrbBufferLength
, HIDUSB_TAG
);
1092 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1093 return STATUS_INSUFFICIENT_RESOURCES
;
1099 RtlZeroMemory(*UrbBuffer
, *UrbBufferLength
);
1106 RtlZeroMemory(Urb
, UrbLength
);
1109 // build descriptor request
1111 UsbBuildGetDescriptorRequest(Urb
, UrbLength
, DescriptorType
, Index
, LanguageIndex
, *UrbBuffer
, NULL
, *UrbBufferLength
, NULL
);
1116 Urb
->UrbHeader
.Function
= UrbFunction
;
1121 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1124 // did the request fail
1126 if (!NT_SUCCESS(Status
))
1131 // free allocated buffer
1133 ExFreePoolWithTag(*UrbBuffer
, HIDUSB_TAG
);
1140 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1141 *UrbBufferLength
= 0;
1146 // did urb request fail
1148 if (!NT_SUCCESS(Urb
->UrbHeader
.Status
))
1153 // free allocated buffer
1155 ExFreePoolWithTag(*UrbBuffer
, HIDUSB_TAG
);
1162 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1163 *UrbBufferLength
= 0;
1164 return STATUS_UNSUCCESSFUL
;
1168 // store result length
1170 *UrbBufferLength
= Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
1175 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1178 // completed successfully
1180 return STATUS_SUCCESS
;
1184 Hid_SelectConfiguration(
1185 IN PDEVICE_OBJECT DeviceObject
)
1187 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1189 USBD_INTERFACE_LIST_ENTRY InterfaceList
[2];
1191 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1192 PHID_DEVICE_EXTENSION DeviceExtension
;
1195 // get device extension
1197 DeviceExtension
= DeviceObject
->DeviceExtension
;
1198 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
1201 // now parse the descriptors
1203 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(HidDeviceExtension
->ConfigurationDescriptor
,
1204 HidDeviceExtension
->ConfigurationDescriptor
,
1207 USB_DEVICE_CLASS_HUMAN_INTERFACE
,
1210 if (!InterfaceDescriptor
)
1213 // bogus configuration descriptor
1215 return STATUS_INVALID_PARAMETER
;
1221 ASSERT(InterfaceDescriptor
);
1222 ASSERT(InterfaceDescriptor
->bInterfaceClass
== USB_DEVICE_CLASS_HUMAN_INTERFACE
);
1223 ASSERT(InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
1224 ASSERT(InterfaceDescriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
1227 // setup interface list
1229 RtlZeroMemory(InterfaceList
, sizeof(InterfaceList
));
1230 InterfaceList
[0].InterfaceDescriptor
= InterfaceDescriptor
;
1235 Urb
= USBD_CreateConfigurationRequestEx(HidDeviceExtension
->ConfigurationDescriptor
, InterfaceList
);
1241 return STATUS_INSUFFICIENT_RESOURCES
;
1247 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1248 if (NT_SUCCESS(Status
))
1251 // store configuration handle
1253 HidDeviceExtension
->ConfigurationHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
1256 // copy interface info
1258 HidDeviceExtension
->InterfaceInfo
= ExAllocatePoolWithTag(NonPagedPool
, Urb
->UrbSelectConfiguration
.Interface
.Length
, HIDUSB_TAG
);
1259 if (HidDeviceExtension
->InterfaceInfo
)
1262 // copy interface info
1264 RtlCopyMemory(HidDeviceExtension
->InterfaceInfo
, &Urb
->UrbSelectConfiguration
.Interface
, Urb
->UrbSelectConfiguration
.Interface
.Length
);
1271 ExFreePoolWithTag(Urb
, 0);
1280 Hid_DisableConfiguration(
1281 IN PDEVICE_OBJECT DeviceObject
)
1283 PHID_DEVICE_EXTENSION DeviceExtension
;
1284 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1289 // get device extension
1291 DeviceExtension
= DeviceObject
->DeviceExtension
;
1292 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
1297 Urb
= ExAllocatePoolWithTag(NonPagedPool
,
1298 sizeof(struct _URB_SELECT_CONFIGURATION
),
1305 return STATUS_INSUFFICIENT_RESOURCES
;
1311 UsbBuildSelectConfigurationRequest(Urb
,
1312 sizeof(struct _URB_SELECT_CONFIGURATION
),
1318 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1319 if (!NT_SUCCESS(Status
))
1321 DPRINT1("[HIDUSB] Dispatching unconfigure URB failed with %lx\n", Status
);
1323 else if (!USBD_SUCCESS(Urb
->UrbHeader
.Status
))
1325 DPRINT("[HIDUSB] Unconfigure URB failed with %lx\n", Status
);
1331 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1336 HidDeviceExtension
->ConfigurationHandle
= NULL
;
1338 if (HidDeviceExtension
->InterfaceInfo
)
1340 ExFreePoolWithTag(HidDeviceExtension
->InterfaceInfo
, HIDUSB_TAG
);
1341 HidDeviceExtension
->InterfaceInfo
= NULL
;
1344 if (HidDeviceExtension
->ConfigurationDescriptor
)
1346 ExFreePoolWithTag(HidDeviceExtension
->ConfigurationDescriptor
, HIDUSB_TAG
);
1347 HidDeviceExtension
->ConfigurationDescriptor
= NULL
;
1348 HidDeviceExtension
->HidDescriptor
= NULL
;
1351 if (HidDeviceExtension
->DeviceDescriptor
)
1353 ExFreePoolWithTag(HidDeviceExtension
->DeviceDescriptor
, HIDUSB_TAG
);
1354 HidDeviceExtension
->DeviceDescriptor
= NULL
;
1365 IN PDEVICE_OBJECT DeviceObject
)
1373 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
), HIDUSB_URB_TAG
);
1379 return STATUS_INSUFFICIENT_RESOURCES
;
1385 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
1390 UsbBuildVendorRequest(Urb
,
1391 URB_FUNCTION_CLASS_INTERFACE
,
1392 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
),
1395 USB_SET_IDLE_REQUEST
, // HID_SET_IDLE
1406 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1411 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1416 DPRINT1("Status %x\n", Status
);
1423 IN PDEVICE_OBJECT DeviceObject
)
1425 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1426 PHID_DEVICE_EXTENSION DeviceExtension
;
1431 // get device extension
1433 DeviceExtension
= DeviceObject
->DeviceExtension
;
1434 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
1435 ASSERT(HidDeviceExtension
->InterfaceInfo
);
1437 if (HidDeviceExtension
->InterfaceInfo
->SubClass
!= 0x1)
1440 // device does not support the boot protocol
1448 Urb
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
), HIDUSB_URB_TAG
);
1460 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
1465 UsbBuildVendorRequest(Urb
,
1466 URB_FUNCTION_CLASS_INTERFACE
,
1467 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
),
1468 USBD_TRANSFER_DIRECTION_IN
,
1470 USB_GET_PROTOCOL_REQUEST
,
1482 Hid_DispatchUrb(DeviceObject
, Urb
);
1487 ExFreePoolWithTag(Urb
, HIDUSB_URB_TAG
);
1490 // boot protocol active 0x00 disabled 0x1
1492 if (Protocol
[0] != 0x1)
1494 if (Protocol
[0] == 0x00)
1496 DPRINT1("[HIDUSB] Need to disable boot protocol!\n");
1500 DPRINT1("[HIDUSB] Unexpected protocol value %x\n", Protocol
[0] & 0xFF);
1507 IN PDEVICE_OBJECT DeviceObject
)
1509 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1510 PHID_DEVICE_EXTENSION DeviceExtension
;
1512 ULONG DescriptorLength
;
1513 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1514 PHID_DESCRIPTOR HidDescriptor
;
1517 // get device extension
1519 DeviceExtension
= DeviceObject
->DeviceExtension
;
1520 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
1523 // get device descriptor
1525 DescriptorLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
1526 Status
= Hid_GetDescriptor(DeviceObject
,
1527 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
,
1528 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
1529 (PVOID
*)&HidDeviceExtension
->DeviceDescriptor
,
1531 USB_DEVICE_DESCRIPTOR_TYPE
,
1534 if (!NT_SUCCESS(Status
))
1537 // failed to obtain device descriptor
1539 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1544 // now get the configuration descriptor
1546 DescriptorLength
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
1547 Status
= Hid_GetDescriptor(DeviceObject
,
1548 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
,
1549 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
1550 (PVOID
*)&HidDeviceExtension
->ConfigurationDescriptor
,
1552 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
1555 if (!NT_SUCCESS(Status
))
1558 // failed to obtain device descriptor
1560 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1567 ASSERT(DescriptorLength
);
1568 ASSERT(HidDeviceExtension
->ConfigurationDescriptor
);
1569 ASSERT(HidDeviceExtension
->ConfigurationDescriptor
->bLength
);
1572 // store full length
1574 DescriptorLength
= HidDeviceExtension
->ConfigurationDescriptor
->wTotalLength
;
1577 // delete partial configuration descriptor
1579 ExFreePoolWithTag(HidDeviceExtension
->ConfigurationDescriptor
, HIDUSB_TAG
);
1580 HidDeviceExtension
->ConfigurationDescriptor
= NULL
;
1583 // get full configuration descriptor
1585 Status
= Hid_GetDescriptor(DeviceObject
,
1586 URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
,
1587 sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
),
1588 (PVOID
*)&HidDeviceExtension
->ConfigurationDescriptor
,
1590 USB_CONFIGURATION_DESCRIPTOR_TYPE
,
1593 if (!NT_SUCCESS(Status
))
1596 // failed to obtain device descriptor
1598 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1603 // now parse the descriptors
1605 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(HidDeviceExtension
->ConfigurationDescriptor
,
1606 HidDeviceExtension
->ConfigurationDescriptor
,
1609 USB_DEVICE_CLASS_HUMAN_INTERFACE
,
1612 if (!InterfaceDescriptor
)
1615 // no interface class
1617 DPRINT1("[HIDUSB] HID Interface descriptor not found\n");
1618 return STATUS_UNSUCCESSFUL
;
1624 ASSERT(InterfaceDescriptor
->bInterfaceClass
== USB_DEVICE_CLASS_HUMAN_INTERFACE
);
1625 ASSERT(InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
1626 ASSERT(InterfaceDescriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
1629 // move to next descriptor
1631 HidDescriptor
= (PHID_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
1632 ASSERT(HidDescriptor
->bLength
>= 2);
1635 // check if this is the hid descriptor
1637 if (HidDescriptor
->bLength
== sizeof(HID_DESCRIPTOR
) && HidDescriptor
->bDescriptorType
== HID_HID_DESCRIPTOR_TYPE
)
1642 HidDeviceExtension
->HidDescriptor
= HidDescriptor
;
1645 // select configuration
1647 Status
= Hid_SelectConfiguration(DeviceObject
);
1652 DPRINT("[HIDUSB] SelectConfiguration %x\n", Status
);
1654 if (NT_SUCCESS(Status
))
1657 // now set the device idle
1659 Hid_SetIdle(DeviceObject
);
1664 Hid_GetProtocol(DeviceObject
);
1671 // FIXME parse hid descriptor
1672 // select configuration
1686 IN PDEVICE_OBJECT DeviceObject
,
1690 PIO_STACK_LOCATION IoStack
;
1691 PHID_DEVICE_EXTENSION DeviceExtension
;
1695 // get device extension
1697 DeviceExtension
= DeviceObject
->DeviceExtension
;
1700 // get current stack location
1702 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1703 DPRINT("[HIDUSB] Pnp %x\n", IoStack
->MinorFunction
);
1706 // handle requests based on request type
1708 switch (IoStack
->MinorFunction
)
1710 case IRP_MN_REMOVE_DEVICE
:
1713 // unconfigure device
1714 // FIXME: Call this on IRP_MN_SURPRISE_REMOVAL, but don't send URBs
1715 // FIXME: Don't call this after we've already seen a surprise removal or stop
1717 Hid_DisableConfiguration(DeviceObject
);
1720 // pass request onto lower driver
1722 IoSkipCurrentIrpStackLocation(Irp
);
1723 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1727 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1730 // device can not be disabled
1732 Irp
->IoStatus
.Information
|= PNP_DEVICE_NOT_DISABLEABLE
;
1735 // pass request to next request
1737 IoSkipCurrentIrpStackLocation(Irp
);
1738 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1745 case IRP_MN_QUERY_STOP_DEVICE
:
1746 case IRP_MN_QUERY_REMOVE_DEVICE
:
1749 // we're fine with it
1751 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1754 // pass request to next driver
1756 IoSkipCurrentIrpStackLocation(Irp
);
1757 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1764 case IRP_MN_STOP_DEVICE
:
1767 // unconfigure device
1769 Hid_DisableConfiguration(DeviceObject
);
1774 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1775 IoCopyCurrentIrpStackLocationToNext(Irp
);
1776 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
1779 // send irp and wait for completion
1781 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1782 if (Status
== STATUS_PENDING
)
1784 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1785 Status
= Irp
->IoStatus
.Status
;
1791 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1794 case IRP_MN_QUERY_CAPABILITIES
:
1799 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1800 IoCopyCurrentIrpStackLocationToNext(Irp
);
1801 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
1804 // send irp and wait for completion
1806 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1807 if (Status
== STATUS_PENDING
)
1809 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1810 Status
= Irp
->IoStatus
.Status
;
1813 if (NT_SUCCESS(Status
) && IoStack
->Parameters
.DeviceCapabilities
.Capabilities
!= NULL
)
1816 // don't need to safely remove
1818 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->SurpriseRemovalOK
= TRUE
;
1824 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1827 case IRP_MN_START_DEVICE
:
1832 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1833 IoCopyCurrentIrpStackLocationToNext(Irp
);
1834 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, &Event
, TRUE
, TRUE
, TRUE
);
1837 // send irp and wait for completion
1839 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1840 if (Status
== STATUS_PENDING
)
1842 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1843 Status
= Irp
->IoStatus
.Status
;
1847 // did the device successfully start
1849 if (!NT_SUCCESS(Status
))
1854 DPRINT1("HIDUSB: IRP_MN_START_DEVICE failed with %x\n", Status
);
1855 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1862 Status
= Hid_PnpStart(DeviceObject
);
1867 Irp
->IoStatus
.Status
= Status
;
1868 DPRINT("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status
);
1869 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1875 // forward and forget request
1877 IoSkipCurrentIrpStackLocation(Irp
);
1878 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1886 IN PDRIVER_OBJECT DriverObject
,
1887 IN PDEVICE_OBJECT DeviceObject
)
1889 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1890 PHID_DEVICE_EXTENSION DeviceExtension
;
1893 // get device extension
1895 DeviceExtension
= DeviceObject
->DeviceExtension
;
1896 HidDeviceExtension
= DeviceExtension
->MiniDeviceExtension
;
1901 KeInitializeEvent(&HidDeviceExtension
->Event
, NotificationEvent
, FALSE
);
1906 return STATUS_SUCCESS
;
1912 IN PDRIVER_OBJECT DriverObject
)
1921 IN PDRIVER_OBJECT DriverObject
,
1922 IN PUNICODE_STRING RegPath
)
1924 HID_MINIDRIVER_REGISTRATION Registration
;
1928 // initialize driver object
1930 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = HidCreate
;
1931 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = HidCreate
;
1932 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = HidInternalDeviceControl
;
1933 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = HidPower
;
1934 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = HidSystemControl
;
1935 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = HidPnp
;
1936 DriverObject
->DriverExtension
->AddDevice
= HidAddDevice
;
1937 DriverObject
->DriverUnload
= Hid_Unload
;
1940 // prepare registration info
1942 RtlZeroMemory(&Registration
, sizeof(HID_MINIDRIVER_REGISTRATION
));
1945 // fill in registration info
1947 Registration
.Revision
= HID_REVISION
;
1948 Registration
.DriverObject
= DriverObject
;
1949 Registration
.RegistryPath
= RegPath
;
1950 Registration
.DeviceExtensionSize
= sizeof(HID_USB_DEVICE_EXTENSION
);
1951 Registration
.DevicesArePolled
= FALSE
;
1956 Status
= HidRegisterMinidriver(&Registration
);
1961 DPRINT("********* HIDUSB *********\n");
1962 DPRINT("HIDUSB Registration Status %x\n", Status
);