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 DPRINT("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 DPRINT("[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 DPRINT("[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, HidDeviceExtension
->InterfaceInfo
->InterfaceNumber
);
650 if (!NT_SUCCESS(Status
))
653 // failed to get descriptor
654 // try with old hid version
656 BufferLength
= HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
;
657 Status
= Hid_GetDescriptor(DeviceObject
, URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT
, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST
), &Report
, &BufferLength
, HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].bReportType
, 0, 0 /* FIXME*/);
658 if (!NT_SUCCESS(Status
))
660 DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status
);
666 // get current stack location
668 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
669 DPRINT("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status
, HidDeviceExtension
->HidDescriptor
->DescriptorList
[0].wReportLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, BufferLength
);
672 // get length to copy
674 Length
= min(IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
, BufferLength
);
680 RtlCopyMemory(Irp
->UserBuffer
, Report
, Length
);
683 // store result length
685 Irp
->IoStatus
.Information
= Length
;
696 HidInternalDeviceControl(
697 IN PDEVICE_OBJECT DeviceObject
,
700 PIO_STACK_LOCATION IoStack
;
701 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
702 PHID_DEVICE_EXTENSION DeviceExtension
;
703 PHID_DEVICE_ATTRIBUTES Attributes
;
708 // get device extension
710 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
711 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
714 // get current stack location
716 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
718 switch(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
)
720 case IOCTL_HID_GET_DEVICE_ATTRIBUTES
:
722 if (IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
< sizeof(HID_DEVICE_ATTRIBUTES
))
727 Irp
->IoStatus
.Status
= STATUS_INVALID_BUFFER_SIZE
;
728 DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES invalid buffer\n");
729 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
730 return STATUS_INVALID_BUFFER_SIZE
;
735 DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES\n");
736 ASSERT(HidDeviceExtension
->DeviceDescriptor
);
737 Irp
->IoStatus
.Information
= sizeof(HID_DESCRIPTOR
);
738 Attributes
= (PHID_DEVICE_ATTRIBUTES
)Irp
->UserBuffer
;
739 Attributes
->Size
= sizeof(HID_DEVICE_ATTRIBUTES
);
740 Attributes
->VendorID
= HidDeviceExtension
->DeviceDescriptor
->idVendor
;
741 Attributes
->ProductID
= HidDeviceExtension
->DeviceDescriptor
->idProduct
;
742 Attributes
->VersionNumber
= HidDeviceExtension
->DeviceDescriptor
->bcdDevice
;
747 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
748 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
749 return STATUS_SUCCESS
;
751 case IOCTL_HID_GET_DEVICE_DESCRIPTOR
:
756 ASSERT(HidDeviceExtension
->HidDescriptor
);
757 DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension
->HidDescriptor
->bLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
762 Length
= min(HidDeviceExtension
->HidDescriptor
->bLength
, IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
);
767 RtlCopyMemory(Irp
->UserBuffer
, HidDeviceExtension
->HidDescriptor
, Length
);
770 // store result length
772 Irp
->IoStatus
.Information
= HidDeviceExtension
->HidDescriptor
->bLength
;
773 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
775 /* complete request */
776 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
777 return STATUS_SUCCESS
;
779 case IOCTL_HID_GET_REPORT_DESCRIPTOR
:
781 Status
= HidUsb_GetReportDescriptor(DeviceObject
, Irp
);
782 DPRINT("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status
);
783 Irp
->IoStatus
.Status
= Status
;
784 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
787 case IOCTL_HID_READ_REPORT
:
789 DPRINT("[HIDUSB] IOCTL_HID_READ_REPORT\n");
790 Status
= HidUsb_ReadReport(DeviceObject
, Irp
);
793 case IOCTL_HID_WRITE_REPORT
:
795 DPRINT1("[HIDUSB] IOCTL_HID_WRITE_REPORT not implemented \n");
797 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
798 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
799 return STATUS_NOT_IMPLEMENTED
;
801 case IOCTL_GET_PHYSICAL_DESCRIPTOR
:
803 DPRINT1("[HIDUSB] IOCTL_GET_PHYSICAL_DESCRIPTOR not implemented \n");
805 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
806 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
807 return STATUS_NOT_IMPLEMENTED
;
809 case IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST
:
811 DPRINT1("[HIDUSB] IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST not implemented \n");
813 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
814 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
815 return STATUS_NOT_IMPLEMENTED
;
817 case IOCTL_HID_GET_FEATURE
:
819 DPRINT1("[HIDUSB] IOCTL_HID_GET_FEATURE not implemented \n");
821 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
822 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
823 return STATUS_NOT_IMPLEMENTED
;
825 case IOCTL_HID_SET_FEATURE
:
827 DPRINT1("[HIDUSB] IOCTL_HID_SET_FEATURE not implemented \n");
829 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
830 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
831 return STATUS_NOT_IMPLEMENTED
;
833 case IOCTL_HID_SET_OUTPUT_REPORT
:
835 DPRINT1("[HIDUSB] IOCTL_HID_SET_OUTPUT_REPORT not implemented \n");
837 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
838 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
839 return STATUS_NOT_IMPLEMENTED
;
841 case IOCTL_HID_GET_INPUT_REPORT
:
843 DPRINT1("[HIDUSB] IOCTL_HID_GET_INPUT_REPORT not implemented \n");
845 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
846 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
847 return STATUS_NOT_IMPLEMENTED
;
849 case IOCTL_HID_GET_INDEXED_STRING
:
851 DPRINT1("[HIDUSB] IOCTL_HID_GET_INDEXED_STRING not implemented \n");
853 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
854 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
855 return STATUS_NOT_IMPLEMENTED
;
857 case IOCTL_HID_GET_MS_GENRE_DESCRIPTOR
:
859 DPRINT1("[HIDUSB] IOCTL_HID_GET_MS_GENRE_DESCRIPTOR not implemented \n");
861 Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
862 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
863 return STATUS_NOT_IMPLEMENTED
;
869 Status
= Irp
->IoStatus
.Status
;
870 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
879 IN PDEVICE_OBJECT DeviceObject
,
884 return STATUS_NOT_IMPLEMENTED
;
890 IN PDEVICE_OBJECT DeviceObject
,
893 PHID_DEVICE_EXTENSION DeviceExtension
;
896 // get hid device extension
898 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
901 // copy stack location
903 IoCopyCurrentIrpStackLocationToNext(Irp
);
908 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
914 IN PDEVICE_OBJECT DeviceObject
,
921 KeSetEvent((PRKEVENT
)Context
, 0, FALSE
);
926 return STATUS_MORE_PROCESSING_REQUIRED
;
932 IN PDEVICE_OBJECT DeviceObject
,
937 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
938 PHID_DEVICE_EXTENSION DeviceExtension
;
939 IO_STATUS_BLOCK IoStatus
;
940 PIO_STACK_LOCATION IoStack
;
946 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
949 // get device extension
951 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
952 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
958 Irp
= IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB
, DeviceExtension
->NextDeviceObject
, NULL
, 0, NULL
, 0, TRUE
, &Event
, &IoStatus
);
964 return STATUS_INSUFFICIENT_RESOURCES
;
968 // get next stack location
970 IoStack
= IoGetNextIrpStackLocation(Irp
);
975 IoStack
->Parameters
.Others
.Argument1
= (PVOID
)Urb
;
978 // set completion routine
980 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
985 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
988 // wait for the request to finish
990 if (Status
== STATUS_PENDING
)
992 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
998 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1000 if (Status
== STATUS_PENDING
)
1005 Status
= IoStatus
.Status
;
1008 DPRINT("[HIDUSB] DispatchUrb %x\n", Status
);
1019 IN PDEVICE_OBJECT DeviceObject
,
1020 IN USHORT UrbFunction
,
1021 IN USHORT UrbLength
,
1022 IN OUT PVOID
*UrbBuffer
,
1023 IN OUT PULONG UrbBufferLength
,
1024 IN UCHAR DescriptorType
,
1026 IN USHORT LanguageIndex
)
1030 UCHAR Allocated
= FALSE
;
1035 Urb
= (PURB
)ExAllocatePool(NonPagedPool
, UrbLength
);
1041 return STATUS_INSUFFICIENT_RESOURCES
;
1045 // is there an urb buffer
1052 *UrbBuffer
= ExAllocatePool(NonPagedPool
, *UrbBufferLength
);
1059 return STATUS_INSUFFICIENT_RESOURCES
;
1065 RtlZeroMemory(*UrbBuffer
, *UrbBufferLength
);
1072 RtlZeroMemory(Urb
, UrbLength
);
1075 // build descriptor request
1077 UsbBuildGetDescriptorRequest(Urb
, UrbLength
, DescriptorType
, Index
, LanguageIndex
, *UrbBuffer
, NULL
, *UrbBufferLength
, NULL
);
1082 Urb
->UrbHeader
.Function
= UrbFunction
;
1087 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1090 // did the request fail
1092 if (!NT_SUCCESS(Status
))
1097 // free allocated buffer
1099 ExFreePool(*UrbBuffer
);
1107 *UrbBufferLength
= 0;
1112 // did urb request fail
1114 if (!NT_SUCCESS(Urb
->UrbHeader
.Status
))
1119 // free allocated buffer
1121 ExFreePool(*UrbBuffer
);
1129 *UrbBufferLength
= 0;
1130 return STATUS_UNSUCCESSFUL
;
1134 // store result length
1136 *UrbBufferLength
= Urb
->UrbControlDescriptorRequest
.TransferBufferLength
;
1144 // completed successfully
1146 return STATUS_SUCCESS
;
1150 Hid_SelectConfiguration(
1151 IN PDEVICE_OBJECT DeviceObject
)
1153 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1155 USBD_INTERFACE_LIST_ENTRY InterfaceList
[2];
1157 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1158 PHID_DEVICE_EXTENSION DeviceExtension
;
1161 // get device extension
1163 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1164 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1167 // now parse the descriptors
1169 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(HidDeviceExtension
->ConfigurationDescriptor
,
1170 HidDeviceExtension
->ConfigurationDescriptor
,
1173 USB_DEVICE_CLASS_HUMAN_INTERFACE
,
1176 if (!InterfaceDescriptor
)
1179 // bogus configuration descriptor
1181 return STATUS_INVALID_PARAMETER
;
1187 ASSERT(InterfaceDescriptor
);
1188 ASSERT(InterfaceDescriptor
->bInterfaceClass
== USB_DEVICE_CLASS_HUMAN_INTERFACE
);
1189 ASSERT(InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
1190 ASSERT(InterfaceDescriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
1193 // setup interface list
1195 RtlZeroMemory(InterfaceList
, sizeof(InterfaceList
));
1196 InterfaceList
[0].InterfaceDescriptor
= InterfaceDescriptor
;
1201 Urb
= USBD_CreateConfigurationRequestEx(HidDeviceExtension
->ConfigurationDescriptor
, InterfaceList
);
1207 return STATUS_INSUFFICIENT_RESOURCES
;
1213 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1214 if (NT_SUCCESS(Status
))
1217 // store configuration handle
1219 HidDeviceExtension
->ConfigurationHandle
= Urb
->UrbSelectConfiguration
.ConfigurationHandle
;
1222 // copy interface info
1224 HidDeviceExtension
->InterfaceInfo
= (PUSBD_INTERFACE_INFORMATION
)ExAllocatePool(NonPagedPool
, Urb
->UrbSelectConfiguration
.Interface
.Length
);
1225 if (HidDeviceExtension
->InterfaceInfo
)
1228 // copy interface info
1230 RtlCopyMemory(HidDeviceExtension
->InterfaceInfo
, &Urb
->UrbSelectConfiguration
.Interface
, Urb
->UrbSelectConfiguration
.Interface
.Length
);
1247 IN PDEVICE_OBJECT DeviceObject
)
1249 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1250 PHID_DEVICE_EXTENSION DeviceExtension
;
1255 // get device extension
1257 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1258 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1263 Urb
= ExAllocatePool(NonPagedPool
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
1269 return STATUS_INSUFFICIENT_RESOURCES
;
1275 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
1280 UsbBuildVendorRequest(Urb
,
1281 URB_FUNCTION_CLASS_INTERFACE
,
1282 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
),
1285 USB_SET_IDLE_REQUEST
, // HID_SET_IDLE
1296 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1306 DPRINT1("Status %x\n", Status
);
1313 IN PDEVICE_OBJECT DeviceObject
)
1315 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1316 PHID_DEVICE_EXTENSION DeviceExtension
;
1322 // get device extension
1324 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1325 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1326 ASSERT(HidDeviceExtension
->InterfaceInfo
);
1328 if (HidDeviceExtension
->InterfaceInfo
->SubClass
!= 0x1)
1331 // device does not support the boot protocol
1340 Urb
= ExAllocatePool(NonPagedPool
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
1352 RtlZeroMemory(Urb
, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
));
1357 UsbBuildVendorRequest(Urb
,
1358 URB_FUNCTION_CLASS_INTERFACE
,
1359 sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST
),
1360 USBD_TRANSFER_DIRECTION_IN
,
1362 USB_GET_PROTOCOL_REQUEST
,
1373 Status
= Hid_DispatchUrb(DeviceObject
, Urb
);
1381 // boot protocol active 0x00 disabled 0x1
1383 if (Protocol
[0] != 0x1)
1385 if (Protocol
[0] == 0x00)
1387 DPRINT1("[HIDUSB] Need to disable boot protocol!\n");
1391 DPRINT1("[HIDUSB] Unexpected protocol value %x\n", Protocol
[0] & 0xFF);
1398 IN PDEVICE_OBJECT DeviceObject
)
1400 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1401 PHID_DEVICE_EXTENSION DeviceExtension
;
1403 ULONG DescriptorLength
;
1404 PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
;
1405 PHID_DESCRIPTOR HidDescriptor
;
1408 // get device extension
1410 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1411 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1414 // get device descriptor
1416 DescriptorLength
= sizeof(USB_DEVICE_DESCRIPTOR
);
1417 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);
1418 if (!NT_SUCCESS(Status
))
1421 // failed to obtain device descriptor
1423 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1428 // now get the configuration descriptor
1430 DescriptorLength
= sizeof(USB_CONFIGURATION_DESCRIPTOR
);
1431 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);
1432 if (!NT_SUCCESS(Status
))
1435 // failed to obtain device descriptor
1437 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1444 ASSERT(DescriptorLength
);
1445 ASSERT(HidDeviceExtension
->ConfigurationDescriptor
);
1446 ASSERT(HidDeviceExtension
->ConfigurationDescriptor
->bLength
);
1449 // store full length
1451 DescriptorLength
= HidDeviceExtension
->ConfigurationDescriptor
->wTotalLength
;
1454 // delete partial configuration descriptor
1456 ExFreePool(HidDeviceExtension
->ConfigurationDescriptor
);
1457 HidDeviceExtension
->ConfigurationDescriptor
= NULL
;
1460 // get full configuration descriptor
1462 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);
1463 if (!NT_SUCCESS(Status
))
1466 // failed to obtain device descriptor
1468 DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status
);
1473 // now parse the descriptors
1475 InterfaceDescriptor
= USBD_ParseConfigurationDescriptorEx(HidDeviceExtension
->ConfigurationDescriptor
,
1476 HidDeviceExtension
->ConfigurationDescriptor
,
1479 USB_DEVICE_CLASS_HUMAN_INTERFACE
,
1482 if (!InterfaceDescriptor
)
1485 // no interface class
1487 DPRINT1("[HIDUSB] HID Interface descriptor not found\n");
1488 return STATUS_UNSUCCESSFUL
;
1494 ASSERT(InterfaceDescriptor
->bInterfaceClass
== USB_DEVICE_CLASS_HUMAN_INTERFACE
);
1495 ASSERT(InterfaceDescriptor
->bDescriptorType
== USB_INTERFACE_DESCRIPTOR_TYPE
);
1496 ASSERT(InterfaceDescriptor
->bLength
== sizeof(USB_INTERFACE_DESCRIPTOR
));
1499 // move to next descriptor
1501 HidDescriptor
= (PHID_DESCRIPTOR
)((ULONG_PTR
)InterfaceDescriptor
+ InterfaceDescriptor
->bLength
);
1502 ASSERT(HidDescriptor
->bLength
>= 2);
1505 // check if this is the hid descriptor
1507 if (HidDescriptor
->bLength
== sizeof(HID_DESCRIPTOR
) && HidDescriptor
->bDescriptorType
== HID_HID_DESCRIPTOR_TYPE
)
1512 HidDeviceExtension
->HidDescriptor
= HidDescriptor
;
1515 // select configuration
1517 Status
= Hid_SelectConfiguration(DeviceObject
);
1522 DPRINT1("[HIDUSB] SelectConfiguration %x\n", Status
);
1524 if (NT_SUCCESS(Status
))
1527 // now set the device idle
1529 Hid_SetIdle(DeviceObject
);
1534 Hid_GetProtocol(DeviceObject
);
1541 // FIXME parse hid descriptor
1542 // select configuration
1556 IN PDEVICE_OBJECT DeviceObject
,
1560 PIO_STACK_LOCATION IoStack
;
1561 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1562 PHID_DEVICE_EXTENSION DeviceExtension
;
1566 // get device extension
1568 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1569 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1572 // get current stack location
1574 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1575 DPRINT("[HIDUSB] Pnp %x\n", IoStack
->MinorFunction
);
1578 // handle requests based on request type
1580 switch(IoStack
->MinorFunction
)
1582 case IRP_MN_REMOVE_DEVICE
:
1585 // pass request onto lower driver
1587 IoSkipCurrentIrpStackLocation(Irp
);
1588 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1593 if (HidDeviceExtension
->ConfigurationDescriptor
)
1595 ExFreePool(HidDeviceExtension
->ConfigurationDescriptor
);
1596 HidDeviceExtension
->ConfigurationDescriptor
= NULL
;
1600 // delete and detach device
1602 IoDetachDevice(DeviceExtension
->NextDeviceObject
);
1603 IoDeleteDevice(DeviceObject
);
1607 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
1610 // device can not be disabled
1612 Irp
->IoStatus
.Information
|= PNP_DEVICE_NOT_DISABLEABLE
;
1615 // pass request to next request
1617 IoSkipCurrentIrpStackLocation(Irp
);
1618 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1625 case IRP_MN_QUERY_STOP_DEVICE
:
1626 case IRP_MN_QUERY_REMOVE_DEVICE
:
1629 // we're fine with it
1631 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1634 // pass request to next driver
1636 IoSkipCurrentIrpStackLocation(Irp
);
1637 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1644 case IRP_MN_STOP_DEVICE
:
1647 // FIXME: unconfigure the device
1653 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1654 IoCopyCurrentIrpStackLocationToNext(Irp
);
1655 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1658 // send irp and wait for completion
1660 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1661 if (Status
== STATUS_PENDING
)
1663 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1664 Status
= Irp
->IoStatus
.Status
;
1670 if (HidDeviceExtension
->HidDescriptor
)
1672 ExFreePool(HidDeviceExtension
->HidDescriptor
);
1673 HidDeviceExtension
->HidDescriptor
= NULL
;
1679 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1682 case IRP_MN_QUERY_CAPABILITIES
:
1687 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1688 IoCopyCurrentIrpStackLocationToNext(Irp
);
1689 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1692 // send irp and wait for completion
1694 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1695 if (Status
== STATUS_PENDING
)
1697 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1698 Status
= Irp
->IoStatus
.Status
;
1701 if (NT_SUCCESS(Status
) && IoStack
->Parameters
.DeviceCapabilities
.Capabilities
!= NULL
)
1704 // don't need to safely remove
1706 IoStack
->Parameters
.DeviceCapabilities
.Capabilities
->SurpriseRemovalOK
= TRUE
;
1712 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1715 case IRP_MN_START_DEVICE
:
1720 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1721 IoCopyCurrentIrpStackLocationToNext(Irp
);
1722 IoSetCompletionRoutine(Irp
, Hid_PnpCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1725 // send irp and wait for completion
1727 Status
= IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1728 if (Status
== STATUS_PENDING
)
1730 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1731 Status
= Irp
->IoStatus
.Status
;
1735 // did the device successfully start
1737 if (!NT_SUCCESS(Status
))
1742 DPRINT1("HIDUSB: IRP_MN_START_DEVICE failed with %x\n", Status
);
1743 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1750 Status
= Hid_PnpStart(DeviceObject
);
1755 Irp
->IoStatus
.Status
= Status
;
1756 DPRINT("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status
);
1757 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1763 // forward and forget request
1765 IoSkipCurrentIrpStackLocation(Irp
);
1766 return IoCallDriver(DeviceExtension
->NextDeviceObject
, Irp
);
1774 IN PDRIVER_OBJECT DriverObject
,
1775 IN PDEVICE_OBJECT DeviceObject
)
1777 PHID_USB_DEVICE_EXTENSION HidDeviceExtension
;
1778 PHID_DEVICE_EXTENSION DeviceExtension
;
1781 // get device extension
1783 DeviceExtension
= (PHID_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1784 HidDeviceExtension
= (PHID_USB_DEVICE_EXTENSION
)DeviceExtension
->MiniDeviceExtension
;
1789 KeInitializeEvent(&HidDeviceExtension
->Event
, NotificationEvent
, FALSE
);
1794 return STATUS_SUCCESS
;
1800 IN PDRIVER_OBJECT DriverObject
)
1809 IN PDRIVER_OBJECT DriverObject
,
1810 IN PUNICODE_STRING RegPath
)
1812 HID_MINIDRIVER_REGISTRATION Registration
;
1816 // initialize driver object
1818 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = HidCreate
;
1819 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = HidCreate
;
1820 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = HidInternalDeviceControl
;
1821 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = HidPower
;
1822 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = HidSystemControl
;
1823 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = HidPnp
;
1824 DriverObject
->DriverExtension
->AddDevice
= HidAddDevice
;
1825 DriverObject
->DriverUnload
= Hid_Unload
;
1828 // prepare registration info
1830 RtlZeroMemory(&Registration
, sizeof(HID_MINIDRIVER_REGISTRATION
));
1833 // fill in registration info
1835 Registration
.Revision
= HID_REVISION
;
1836 Registration
.DriverObject
= DriverObject
;
1837 Registration
.RegistryPath
= RegPath
;
1838 Registration
.DeviceExtensionSize
= sizeof(HID_USB_DEVICE_EXTENSION
);
1839 Registration
.DevicesArePolled
= FALSE
;
1844 Status
= HidRegisterMinidriver(&Registration
);
1849 DPRINT("********* HIDUSB *********\n");
1850 DPRINT("HIDUSB Registration Status %x\n", Status
);