ReactOS  0.4.13-dev-563-g0561610
hidusb.c
Go to the documentation of this file.
1 /*
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
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  */
10 
11 #include "hidusb.h"
12 
15  PUSBD_INTERFACE_INFORMATION InterfaceInformation)
16 {
17  ULONG Index;
18 
19  //
20  // sanity check
21  //
22  ASSERT(InterfaceInformation->NumberOfPipes);
23 
24  for (Index = 0; Index < InterfaceInformation->NumberOfPipes; Index++)
25  {
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))
28  {
29  //
30  // found handle
31  //
32  return &InterfaceInformation->Pipes[Index];
33  }
34  }
35 
36  //
37  // not found
38  //
39  return NULL;
40 }
41 
46 {
47  PIRP Irp;
48  KEVENT Event;
50  PHID_DEVICE_EXTENSION DeviceExtension;
51  PIO_STACK_LOCATION IoStack;
53 
54  //
55  // get device extension
56  //
57  DeviceExtension = DeviceObject->DeviceExtension;
58 
59  //
60  // init result
61  //
62  *PortStatus = 0;
63 
64  //
65  // init event
66  //
68 
69  //
70  // build irp
71  //
73  DeviceExtension->NextDeviceObject,
74  NULL,
75  0,
76  NULL,
77  0,
78  TRUE,
79  &Event,
80  &IoStatus);
81  if (!Irp)
82  {
83  //
84  // no memory
85  //
87  }
88 
89  //
90  // get stack location
91  //
92  IoStack = IoGetNextIrpStackLocation(Irp);
93 
94  //
95  // store result buffer
96  //
97  IoStack->Parameters.Others.Argument1 = PortStatus;
98 
99  //
100  // call driver
101  //
102  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
103  if (Status == STATUS_PENDING)
104  {
105  //
106  // wait for completion
107  //
109  return IoStatus.Status;
110  }
111 
112  //
113  // done
114  //
115  return Status;
116 }
117 
118 NTSTATUS
121 {
122  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
123  PHID_DEVICE_EXTENSION DeviceExtension;
124  PUSBD_PIPE_INFORMATION PipeInformation;
125  PURB Urb;
127 
128  //
129  // get device extension
130  //
131  DeviceExtension = DeviceObject->DeviceExtension;
132  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
133 
134  //
135  // get interrupt pipe handle
136  //
137  ASSERT(HidDeviceExtension->InterfaceInfo);
138  PipeInformation = HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo);
139  ASSERT(PipeInformation);
140  ASSERT(PipeInformation->PipeHandle);
141 
142  //
143  // allocate urb
144  //
146  if (!Urb)
147  {
148  //
149  // no memory
150  //
152  }
153 
154  //
155  // init urb
156  //
157  RtlZeroMemory(Urb, sizeof(struct _URB_PIPE_REQUEST));
159  Urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST);
160  Urb->UrbPipeRequest.PipeHandle = PipeInformation->PipeHandle;
161 
162  //
163  // dispatch request
164  //
166 
167  //
168  // free urb
169  //
171 
172  //
173  // done
174  //
175  return Status;
176 }
177 
178 NTSTATUS
181 {
182  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
183  PHID_DEVICE_EXTENSION DeviceExtension;
184  PURB Urb;
186  PUSBD_PIPE_INFORMATION PipeInformation;
187 
188  //
189  // get device extension
190  //
191  DeviceExtension = DeviceObject->DeviceExtension;
192  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
193 
194  //
195  // allocate urb
196  //
198  if (!Urb)
199  {
200  //
201  // no memory
202  //
204  }
205 
206  //
207  // get pipe information
208  //
209  PipeInformation = HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo);
210  ASSERT(PipeInformation);
211  ASSERT(PipeInformation->PipeHandle);
212 
213  //
214  // init urb
215  //
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;
220 
221  //
222  // dispatch request
223  //
225 
226  //
227  // free urb
228  //
230 
231  //
232  // done
233  //
234  return Status;
235 }
236 
237 NTSTATUS
240 {
241  KEVENT Event;
242  PIRP Irp;
243  PHID_DEVICE_EXTENSION DeviceExtension;
246 
247  //
248  // get device extension
249  //
250  DeviceExtension = DeviceObject->DeviceExtension;
251 
252  //
253  // init event
254  //
256 
257  //
258  // build irp
259  //
261  DeviceExtension->NextDeviceObject,
262  NULL,
263  0,
264  NULL,
265  0,
266  TRUE,
267  &Event,
268  &IoStatusBlock);
269  if (!Irp)
270  {
271  //
272  // no memory
273  //
275  }
276 
277  //
278  // send the irp
279  //
280  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
281  if (Status == STATUS_PENDING)
282  {
283  //
284  // wait for request completion
285  //
288  }
289 
290  //
291  // done
292  //
293  return IoStatusBlock.Status;
294 }
295 
296 NTSTATUS
297 NTAPI
300  IN PIRP Irp)
301 {
302  PIO_STACK_LOCATION IoStack;
303 
304  //
305  // get current irp stack location
306  //
308 
309  //
310  // sanity check for hidclass driver
311  //
312  ASSERT(IoStack->MajorFunction == IRP_MJ_CREATE || IoStack->MajorFunction == IRP_MJ_CLOSE);
313 
314  //
315  // informational debug print
316  //
317  DPRINT("HIDUSB Request: %x\n", IoStack->MajorFunction);
318 
319  //
320  // complete request
321  //
322  Irp->IoStatus.Information = 0;
323  Irp->IoStatus.Status = STATUS_SUCCESS;
325 
326  //
327  // done
328  //
329  return STATUS_SUCCESS;
330 }
331 
332 VOID
333 NTAPI
336  IN PVOID Ctx)
337 {
340  PHID_USB_RESET_CONTEXT ResetContext;
341  PHID_DEVICE_EXTENSION DeviceExtension;
342 
343  DPRINT("[HIDUSB] ResetWorkerRoutine\n");
344 
345  //
346  // get context
347  //
348  ResetContext = Ctx;
349 
350  //
351  // get device extension
352  //
353  DeviceExtension = ResetContext->DeviceObject->DeviceExtension;
354 
355  //
356  // get port status
357  //
359  DPRINT("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status, PortStatus);
360  if (NT_SUCCESS(Status))
361  {
363  {
364  //
365  // port is disabled
366  //
368  DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status);
369  }
370  else
371  {
372  //
373  // abort pipe
374  //
375  Status = HidUsb_AbortPipe(ResetContext->DeviceObject);
376  DPRINT1("[HIDUSB] ResetWorkerRoutine AbortPipe %x\n", Status);
377  if (NT_SUCCESS(Status))
378  {
379  //
380  // reset port
381  //
382  Status = HidUsb_ResetPort(ResetContext->DeviceObject);
383  DPRINT1("[HIDUSB] ResetPort %x\n", Status);
385  {
386  //
387  // invalidate device state
388  //
390  }
391 
392  //
393  // reset interrupt pipe
394  //
395  if (NT_SUCCESS(Status))
396  {
397  //
398  // reset pipe
399  //
401  DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status);
402  }
403  }
404  }
405  }
406 
407  //
408  // cleanup
409  //
411  IoFreeWorkItem(ResetContext->WorkItem);
412  IoCompleteRequest(ResetContext->Irp, IO_NO_INCREMENT);
413  ExFreePoolWithTag(ResetContext, HIDUSB_TAG);
414 }
415 
416 
417 NTSTATUS
418 NTAPI
421  IN PIRP Irp,
422  IN PVOID Context)
423 {
424  PURB Urb;
425  PHID_USB_RESET_CONTEXT ResetContext;
426 
427  //
428  // get urb
429  //
430  Urb = Context;
431  ASSERT(Urb);
432 
433  DPRINT("[HIDUSB] HidUsb_ReadReportCompletion %p Status %x Urb Status %x\n", Irp, Irp->IoStatus, Urb->UrbHeader.Status);
434 
435  if (Irp->PendingReturned)
436  {
437  //
438  // mark irp pending
439  //
441  }
442 
443  //
444  // did the reading report succeed / cancelled
445  //
446  if (NT_SUCCESS(Irp->IoStatus.Status) || Irp->IoStatus.Status == STATUS_CANCELLED || Irp->IoStatus.Status == STATUS_DEVICE_NOT_CONNECTED)
447  {
448  //
449  // store result length
450  //
451  Irp->IoStatus.Information = Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
452 
453  //
454  // FIXME handle error
455  //
456  ASSERT(Urb->UrbHeader.Status == USBD_STATUS_SUCCESS || Urb->UrbHeader.Status == USBD_STATUS_DEVICE_GONE);
457 
458  //
459  // free the urb
460  //
462 
463  //
464  // finish completion
465  //
467  }
468 
469  //
470  // allocate reset context
471  //
473  if (ResetContext)
474  {
475  //
476  // allocate work item
477  //
478  ResetContext->WorkItem = IoAllocateWorkItem(DeviceObject);
479  if (ResetContext->WorkItem)
480  {
481  //
482  // init reset context
483  //
484  ResetContext->Irp = Irp;
485  ResetContext->DeviceObject = DeviceObject;
486 
487  //
488  // queue the work item
489  //
491 
492  //
493  // free urb
494  //
496 
497  //
498  // defer completion
499  //
501  }
502  //
503  // free context
504  //
505  ExFreePoolWithTag(ResetContext, HIDUSB_TAG);
506  }
507 
508  //
509  // free urb
510  //
512 
513  //
514  // complete request
515  //
517 }
518 
519 
520 NTSTATUS
521 NTAPI
524  IN PIRP Irp)
525 {
526  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
527  PHID_DEVICE_EXTENSION DeviceExtension;
528  PIO_STACK_LOCATION IoStack;
529  PURB Urb;
530  PUSBD_PIPE_INFORMATION PipeInformation;
531 
532  //
533  // get device extension
534  //
535  DeviceExtension = DeviceObject->DeviceExtension;
536  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
537 
538  //
539  // get current stack location
540  //
542 
543  //
544  // sanity checks
545  //
546  ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength);
547  ASSERT(Irp->UserBuffer);
548  ASSERT(HidDeviceExtension->InterfaceInfo);
549 
550  //
551  // get interrupt input pipe
552  //
553  PipeInformation = HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo);
554  ASSERT(PipeInformation);
555 
556  //
557  // lets allocate urb
558  //
560  if (!Urb)
561  {
562  //
563  // no memory
564  //
566  }
567 
568  //
569  // init urb
570  //
571  RtlZeroMemory(Urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER));
572 
573  //
574  // sanity check
575  //
576  ASSERT(Irp->UserBuffer);
577  ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength);
578  ASSERT(PipeInformation->PipeHandle);
579 
580  //
581  // build the urb
582  //
584  sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
585  PipeInformation->PipeHandle,
586  Irp->UserBuffer,
587  NULL,
588  IoStack->Parameters.DeviceIoControl.OutputBufferLength,
590  NULL);
591 
592  //
593  // store configuration handle
594  //
595  Urb->UrbHeader.UsbdDeviceHandle = HidDeviceExtension->ConfigurationHandle;
596 
597  //
598  // get next location to setup irp
599  //
600  IoStack = IoGetNextIrpStackLocation(Irp);
601 
602  //
603  // init irp for lower driver
604  //
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;
611 
612 
613  //
614  // set completion routine
615  //
617 
618  //
619  // call driver
620  //
621  return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
622 }
623 
624 
625 NTSTATUS
626 NTAPI
629  IN PIRP Irp)
630 {
631  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
632  PHID_DEVICE_EXTENSION DeviceExtension;
633  PVOID Report = NULL;
635  PIO_STACK_LOCATION IoStack;
637 
638  //
639  // get device extension
640  //
641  DeviceExtension = DeviceObject->DeviceExtension;
642  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
643 
644  //
645  // sanity checks
646  //
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);
652 
653  //
654  // FIXME: support old hid version
655  //
656  BufferLength = HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength;
659  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
660  &Report,
661  &BufferLength,
662  HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType,
663  0,
664  HidDeviceExtension->InterfaceInfo->InterfaceNumber);
665  if (!NT_SUCCESS(Status))
666  {
667  //
668  // failed to get descriptor
669  // try with old hid version
670  //
671  BufferLength = HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength;
674  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
675  &Report,
676  &BufferLength,
677  HidDeviceExtension->HidDescriptor->DescriptorList[0].bReportType,
678  0,
679  0 /* FIXME*/);
680  if (!NT_SUCCESS(Status))
681  {
682  DPRINT("[HIDUSB] failed to get report descriptor with %x\n", Status);
683  return Status;
684  }
685  }
686 
687  //
688  // get current stack location
689  //
691  DPRINT("[HIDUSB] GetReportDescriptor: Status %x ReportLength %lu OutputBufferLength %lu TransferredLength %lu\n", Status, HidDeviceExtension->HidDescriptor->DescriptorList[0].wReportLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, BufferLength);
692 
693  //
694  // get length to copy
695  //
696  Length = min(IoStack->Parameters.DeviceIoControl.OutputBufferLength, BufferLength);
697  ASSERT(Length);
698 
699  //
700  // copy result
701  //
702  RtlCopyMemory(Irp->UserBuffer, Report, Length);
703 
704  //
705  // store result length
706  //
707  Irp->IoStatus.Information = Length;
708 
709  //
710  // free the report buffer
711  //
712  ExFreePoolWithTag(Report, HIDUSB_TAG);
713 
714  //
715  // done
716  //
717  return Status;
718 
719 }
720 
721 NTSTATUS
722 NTAPI
725  IN PIRP Irp)
726 {
727  PIO_STACK_LOCATION IoStack;
728  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
729  PHID_DEVICE_EXTENSION DeviceExtension;
731  ULONG Length;
733 
734  //
735  // get device extension
736  //
737  DeviceExtension = DeviceObject->DeviceExtension;
738  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
739 
740  //
741  // get current stack location
742  //
744 
745  switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
746  {
748  {
749  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_DEVICE_ATTRIBUTES))
750  {
751  //
752  // invalid request
753  //
754  Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
755  DPRINT1("[HIDUSB] IOCTL_HID_GET_DEVICE_ATTRIBUTES invalid buffer\n");
758  }
759  //
760  // store result
761  //
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;
770 
771  //
772  // complete request
773  //
774  Irp->IoStatus.Status = STATUS_SUCCESS;
776  return STATUS_SUCCESS;
777  }
779  {
780  //
781  // sanity check
782  //
783  ASSERT(HidDeviceExtension->HidDescriptor);
784  DPRINT("[HIDUSB] IOCTL_HID_GET_DEVICE_DESCRIPTOR DescriptorLength %lu OutputBufferLength %lu\n", HidDeviceExtension->HidDescriptor->bLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
785 
786  //
787  // store length
788  //
789  Length = min(HidDeviceExtension->HidDescriptor->bLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength);
790 
791  //
792  // copy descriptor
793  //
794  RtlCopyMemory(Irp->UserBuffer, HidDeviceExtension->HidDescriptor, Length);
795 
796  //
797  // store result length
798  //
799  Irp->IoStatus.Information = HidDeviceExtension->HidDescriptor->bLength;
800  Irp->IoStatus.Status = STATUS_SUCCESS;
801 
802  /* complete request */
804  return STATUS_SUCCESS;
805  }
807  {
809  DPRINT("[HIDUSB] IOCTL_HID_GET_REPORT_DESCRIPTOR Status %x\n", Status);
810  Irp->IoStatus.Status = Status;
812  return Status;
813  }
815  {
816  DPRINT("[HIDUSB] IOCTL_HID_READ_REPORT\n");
818  return Status;
819  }
821  {
822  DPRINT1("[HIDUSB] IOCTL_HID_WRITE_REPORT not implemented \n");
823  ASSERT(FALSE);
824  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
826  return STATUS_NOT_IMPLEMENTED;
827  }
829  {
830  DPRINT1("[HIDUSB] IOCTL_GET_PHYSICAL_DESCRIPTOR not implemented \n");
831  ASSERT(FALSE);
832  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
834  return STATUS_NOT_IMPLEMENTED;
835  }
837  {
838  DPRINT1("[HIDUSB] IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST not implemented \n");
839  ASSERT(FALSE);
840  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
842  return STATUS_NOT_IMPLEMENTED;
843  }
845  {
846  DPRINT1("[HIDUSB] IOCTL_HID_GET_FEATURE not implemented \n");
847  ASSERT(FALSE);
848  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
850  return STATUS_NOT_IMPLEMENTED;
851  }
853  {
854  DPRINT1("[HIDUSB] IOCTL_HID_SET_FEATURE not implemented \n");
855  ASSERT(FALSE);
856  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
858  return STATUS_NOT_IMPLEMENTED;
859  }
861  {
862  DPRINT1("[HIDUSB] IOCTL_HID_SET_OUTPUT_REPORT not implemented \n");
863  ASSERT(FALSE);
864  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
866  return STATUS_NOT_IMPLEMENTED;
867  }
869  {
870  DPRINT1("[HIDUSB] IOCTL_HID_GET_INPUT_REPORT not implemented \n");
871  ASSERT(FALSE);
872  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
874  return STATUS_NOT_IMPLEMENTED;
875  }
877  {
878  DPRINT1("[HIDUSB] IOCTL_HID_GET_INDEXED_STRING not implemented \n");
879  ASSERT(FALSE);
880  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
882  return STATUS_NOT_IMPLEMENTED;
883  }
885  {
886  DPRINT1("[HIDUSB] IOCTL_HID_GET_MS_GENRE_DESCRIPTOR not implemented \n");
887  ASSERT(FALSE);
888  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
890  return STATUS_NOT_IMPLEMENTED;
891  }
892  default:
893  {
895  ASSERT(FALSE);
896  Status = Irp->IoStatus.Status;
898  return Status;
899  }
900  }
901 }
902 
903 NTSTATUS
904 NTAPI
907  IN PIRP Irp)
908 {
909  PHID_DEVICE_EXTENSION DeviceExtension;
910 
911  DeviceExtension = DeviceObject->DeviceExtension;
914  return PoCallDriver(DeviceExtension->NextDeviceObject, Irp);
915 }
916 
917 NTSTATUS
918 NTAPI
921  IN PIRP Irp)
922 {
923  PHID_DEVICE_EXTENSION DeviceExtension;
924 
925  //
926  // get hid device extension
927  //
928  DeviceExtension = DeviceObject->DeviceExtension;
929 
930  //
931  // skip stack location
932  //
934 
935  //
936  // submit request
937  //
938  return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
939 }
940 
941 NTSTATUS
942 NTAPI
945  IN PIRP Irp,
946  IN PVOID Context)
947 {
948  //
949  // signal event
950  //
951  KeSetEvent(Context, 0, FALSE);
952 
953  //
954  // done
955  //
957 }
958 
959 NTSTATUS
962  IN PURB Urb)
963 {
964  PIRP Irp;
965  KEVENT Event;
966  PHID_DEVICE_EXTENSION DeviceExtension;
968  PIO_STACK_LOCATION IoStack;
970 
971  //
972  // init event
973  //
975 
976  //
977  // get device extension
978  //
979  DeviceExtension = DeviceObject->DeviceExtension;
980 
981  //
982  // build irp
983  //
985  DeviceExtension->NextDeviceObject,
986  NULL,
987  0,
988  NULL,
989  0,
990  TRUE,
991  &Event,
992  &IoStatus);
993  if (!Irp)
994  {
995  //
996  // no memory
997  //
999  }
1000 
1001  //
1002  // get next stack location
1003  //
1004  IoStack = IoGetNextIrpStackLocation(Irp);
1005 
1006  //
1007  // store urb
1008  //
1009  IoStack->Parameters.Others.Argument1 = Urb;
1010 
1011  //
1012  // set completion routine
1013  //
1015 
1016  //
1017  // call driver
1018  //
1019  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1020 
1021  //
1022  // wait for the request to finish
1023  //
1024  if (Status == STATUS_PENDING)
1025  {
1027  }
1028 
1029  //
1030  // complete request
1031  //
1033 
1034  if (Status == STATUS_PENDING)
1035  {
1036  //
1037  // get final status
1038  //
1039  Status = IoStatus.Status;
1040  }
1041 
1042  DPRINT("[HIDUSB] DispatchUrb %x\n", Status);
1043 
1044 
1045  //
1046  // done
1047  //
1048  return Status;
1049 }
1050 
1051 NTSTATUS
1054  IN USHORT UrbFunction,
1055  IN USHORT UrbLength,
1056  IN OUT PVOID *UrbBuffer,
1057  IN OUT PULONG UrbBufferLength,
1059  IN UCHAR Index,
1060  IN USHORT LanguageIndex)
1061 {
1062  PURB Urb;
1063  NTSTATUS Status;
1064  UCHAR Allocated = FALSE;
1065 
1066  //
1067  // allocate urb
1068  //
1070  if (!Urb)
1071  {
1072  //
1073  // no memory
1074  //
1076  }
1077 
1078  //
1079  // is there an urb buffer
1080  //
1081  if (!*UrbBuffer)
1082  {
1083  //
1084  // allocate buffer
1085  //
1086  *UrbBuffer = ExAllocatePoolWithTag(NonPagedPool, *UrbBufferLength, HIDUSB_TAG);
1087  if (!*UrbBuffer)
1088  {
1089  //
1090  // no memory
1091  //
1094  }
1095 
1096  //
1097  // zero buffer
1098  //
1099  RtlZeroMemory(*UrbBuffer, *UrbBufferLength);
1100  Allocated = TRUE;
1101  }
1102 
1103  //
1104  // zero urb
1105  //
1106  RtlZeroMemory(Urb, UrbLength);
1107 
1108  //
1109  // build descriptor request
1110  //
1111  UsbBuildGetDescriptorRequest(Urb, UrbLength, DescriptorType, Index, LanguageIndex, *UrbBuffer, NULL, *UrbBufferLength, NULL);
1112 
1113  //
1114  // set urb function
1115  //
1116  Urb->UrbHeader.Function = UrbFunction;
1117 
1118  //
1119  // dispatch urb
1120  //
1122 
1123  //
1124  // did the request fail
1125  //
1126  if (!NT_SUCCESS(Status))
1127  {
1128  if (Allocated)
1129  {
1130  //
1131  // free allocated buffer
1132  //
1133  ExFreePoolWithTag(*UrbBuffer, HIDUSB_TAG);
1134  *UrbBuffer = NULL;
1135  }
1136 
1137  //
1138  // free urb
1139  //
1141  *UrbBufferLength = 0;
1142  return Status;
1143  }
1144 
1145  //
1146  // did urb request fail
1147  //
1148  if (!NT_SUCCESS(Urb->UrbHeader.Status))
1149  {
1150  if (Allocated)
1151  {
1152  //
1153  // free allocated buffer
1154  //
1155  ExFreePoolWithTag(*UrbBuffer, HIDUSB_TAG);
1156  *UrbBuffer = NULL;
1157  }
1158 
1159  //
1160  // free urb
1161  //
1163  *UrbBufferLength = 0;
1164  return STATUS_UNSUCCESSFUL;
1165  }
1166 
1167  //
1168  // store result length
1169  //
1170  *UrbBufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
1171 
1172  //
1173  // free urb
1174  //
1176 
1177  //
1178  // completed successfully
1179  //
1180  return STATUS_SUCCESS;
1181 }
1182 
1183 NTSTATUS
1186 {
1187  PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
1188  NTSTATUS Status;
1190  PURB Urb;
1191  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
1192  PHID_DEVICE_EXTENSION DeviceExtension;
1193 
1194  //
1195  // get device extension
1196  //
1197  DeviceExtension = DeviceObject->DeviceExtension;
1198  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
1199 
1200  //
1201  // now parse the descriptors
1202  //
1203  InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor,
1204  HidDeviceExtension->ConfigurationDescriptor,
1205  -1,
1206  -1,
1208  -1,
1209  -1);
1210  if (!InterfaceDescriptor)
1211  {
1212  //
1213  // bogus configuration descriptor
1214  //
1215  return STATUS_INVALID_PARAMETER;
1216  }
1217 
1218  //
1219  // sanity check
1220  //
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));
1225 
1226  //
1227  // setup interface list
1228  //
1230  InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
1231 
1232  //
1233  // build urb
1234  //
1236  if (!Urb)
1237  {
1238  //
1239  // no memory
1240  //
1242  }
1243 
1244  //
1245  // dispatch request
1246  //
1248  if (NT_SUCCESS(Status))
1249  {
1250  //
1251  // store configuration handle
1252  //
1253  HidDeviceExtension->ConfigurationHandle = Urb->UrbSelectConfiguration.ConfigurationHandle;
1254 
1255  //
1256  // copy interface info
1257  //
1258  HidDeviceExtension->InterfaceInfo = ExAllocatePoolWithTag(NonPagedPool, Urb->UrbSelectConfiguration.Interface.Length, HIDUSB_TAG);
1259  if (HidDeviceExtension->InterfaceInfo)
1260  {
1261  //
1262  // copy interface info
1263  //
1264  RtlCopyMemory(HidDeviceExtension->InterfaceInfo, &Urb->UrbSelectConfiguration.Interface, Urb->UrbSelectConfiguration.Interface.Length);
1265  }
1266  }
1267 
1268  //
1269  // free urb request
1270  //
1271  ExFreePoolWithTag(Urb, 0);
1272 
1273  //
1274  // done
1275  //
1276  return Status;
1277 }
1278 
1279 NTSTATUS
1282 {
1283  PHID_DEVICE_EXTENSION DeviceExtension;
1284  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
1285  NTSTATUS Status;
1286  PURB Urb;
1287 
1288  //
1289  // get device extension
1290  //
1291  DeviceExtension = DeviceObject->DeviceExtension;
1292  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
1293 
1294  //
1295  // build urb
1296  //
1298  sizeof(struct _URB_SELECT_CONFIGURATION),
1299  HIDUSB_URB_TAG);
1300  if (!Urb)
1301  {
1302  //
1303  // no memory
1304  //
1306  }
1307 
1308  //
1309  // format urb
1310  //
1312  sizeof(struct _URB_SELECT_CONFIGURATION),
1313  NULL);
1314 
1315  //
1316  // dispatch request
1317  //
1319  if (!NT_SUCCESS(Status))
1320  {
1321  DPRINT1("[HIDUSB] Dispatching unconfigure URB failed with %lx\n", Status);
1322  }
1323  else if (!USBD_SUCCESS(Urb->UrbHeader.Status))
1324  {
1325  DPRINT("[HIDUSB] Unconfigure URB failed with %lx\n", Status);
1326  }
1327 
1328  //
1329  // free urb
1330  //
1332 
1333  //
1334  // free resources
1335  //
1336  HidDeviceExtension->ConfigurationHandle = NULL;
1337 
1338  if (HidDeviceExtension->InterfaceInfo)
1339  {
1340  ExFreePoolWithTag(HidDeviceExtension->InterfaceInfo, HIDUSB_TAG);
1341  HidDeviceExtension->InterfaceInfo = NULL;
1342  }
1343 
1344  if (HidDeviceExtension->ConfigurationDescriptor)
1345  {
1347  HidDeviceExtension->ConfigurationDescriptor = NULL;
1348  HidDeviceExtension->HidDescriptor = NULL;
1349  }
1350 
1351  if (HidDeviceExtension->DeviceDescriptor)
1352  {
1353  ExFreePoolWithTag(HidDeviceExtension->DeviceDescriptor, HIDUSB_TAG);
1354  HidDeviceExtension->DeviceDescriptor = NULL;
1355  }
1356 
1357  //
1358  // done
1359  //
1360  return Status;
1361 }
1362 
1363 NTSTATUS
1366 {
1367  PURB Urb;
1368  NTSTATUS Status;
1369 
1370  //
1371  // allocate urb
1372  //
1374  if (!Urb)
1375  {
1376  //
1377  // no memory
1378  //
1380  }
1381 
1382  //
1383  // zero urb
1384  //
1386 
1387  //
1388  // format urb
1389  //
1392  sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
1393  0,
1394  0,
1395  USB_SET_IDLE_REQUEST, // HID_SET_IDLE
1396  0,
1397  0,
1398  NULL,
1399  NULL,
1400  0,
1401  NULL);
1402 
1403  //
1404  // dispatch urb
1405  //
1407 
1408  //
1409  // free urb
1410  //
1412 
1413  //
1414  // print status
1415  //
1416  DPRINT1("Status %x\n", Status);
1417  return Status;
1418 }
1419 
1420 
1421 VOID
1424 {
1425  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
1426  PHID_DEVICE_EXTENSION DeviceExtension;
1427  PURB Urb;
1428  UCHAR Protocol[1];
1429 
1430  //
1431  // get device extension
1432  //
1433  DeviceExtension = DeviceObject->DeviceExtension;
1434  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
1435  ASSERT(HidDeviceExtension->InterfaceInfo);
1436 
1437  if (HidDeviceExtension->InterfaceInfo->SubClass != 0x1)
1438  {
1439  //
1440  // device does not support the boot protocol
1441  //
1442  return;
1443  }
1444 
1445  //
1446  // allocate urb
1447  //
1449  if (!Urb)
1450  {
1451  //
1452  // no memory
1453  //
1454  return;
1455  }
1456 
1457  //
1458  // zero urb
1459  //
1461 
1462  //
1463  // format urb
1464  //
1467  sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
1469  0,
1471  0,
1472  0,
1473  Protocol,
1474  NULL,
1475  1,
1476  NULL);
1477  Protocol[0] = 0xFF;
1478 
1479  //
1480  // dispatch urb
1481  //
1483 
1484  //
1485  // free urb
1486  //
1488 
1489  //
1490  // boot protocol active 0x00 disabled 0x1
1491  //
1492  if (Protocol[0] != 0x1)
1493  {
1494  if (Protocol[0] == 0x00)
1495  {
1496  DPRINT1("[HIDUSB] Need to disable boot protocol!\n");
1497  }
1498  else
1499  {
1500  DPRINT1("[HIDUSB] Unexpected protocol value %x\n", Protocol[0] & 0xFF);
1501  }
1502  }
1503 }
1504 
1505 NTSTATUS
1508 {
1509  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
1510  PHID_DEVICE_EXTENSION DeviceExtension;
1511  NTSTATUS Status;
1512  ULONG DescriptorLength;
1513  PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
1514  PHID_DESCRIPTOR HidDescriptor;
1515 
1516  //
1517  // get device extension
1518  //
1519  DeviceExtension = DeviceObject->DeviceExtension;
1520  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
1521 
1522  //
1523  // get device descriptor
1524  //
1525  DescriptorLength = sizeof(USB_DEVICE_DESCRIPTOR);
1528  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
1529  (PVOID *)&HidDeviceExtension->DeviceDescriptor,
1530  &DescriptorLength,
1532  0,
1533  0);
1534  if (!NT_SUCCESS(Status))
1535  {
1536  //
1537  // failed to obtain device descriptor
1538  //
1539  DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status);
1540  return Status;
1541  }
1542 
1543  //
1544  // now get the configuration descriptor
1545  //
1546  DescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
1549  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
1550  (PVOID *)&HidDeviceExtension->ConfigurationDescriptor,
1551  &DescriptorLength,
1553  0,
1554  0);
1555  if (!NT_SUCCESS(Status))
1556  {
1557  //
1558  // failed to obtain device descriptor
1559  //
1560  DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status);
1561  return Status;
1562  }
1563 
1564  //
1565  // sanity check
1566  //
1567  ASSERT(DescriptorLength);
1568  ASSERT(HidDeviceExtension->ConfigurationDescriptor);
1569  ASSERT(HidDeviceExtension->ConfigurationDescriptor->bLength);
1570 
1571  //
1572  // store full length
1573  //
1574  DescriptorLength = HidDeviceExtension->ConfigurationDescriptor->wTotalLength;
1575 
1576  //
1577  // delete partial configuration descriptor
1578  //
1580  HidDeviceExtension->ConfigurationDescriptor = NULL;
1581 
1582  //
1583  // get full configuration descriptor
1584  //
1587  sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
1588  (PVOID *)&HidDeviceExtension->ConfigurationDescriptor,
1589  &DescriptorLength,
1591  0,
1592  0);
1593  if (!NT_SUCCESS(Status))
1594  {
1595  //
1596  // failed to obtain device descriptor
1597  //
1598  DPRINT1("[HIDUSB] failed to get device descriptor %x\n", Status);
1599  return Status;
1600  }
1601 
1602  //
1603  // now parse the descriptors
1604  //
1605  InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor,
1606  HidDeviceExtension->ConfigurationDescriptor,
1607  -1,
1608  -1,
1610  -1,
1611  -1);
1612  if (!InterfaceDescriptor)
1613  {
1614  //
1615  // no interface class
1616  //
1617  DPRINT1("[HIDUSB] HID Interface descriptor not found\n");
1618  return STATUS_UNSUCCESSFUL;
1619  }
1620 
1621  //
1622  // sanity check
1623  //
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));
1627 
1628  //
1629  // move to next descriptor
1630  //
1631  HidDescriptor = (PHID_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
1632  ASSERT(HidDescriptor->bLength >= 2);
1633 
1634  //
1635  // check if this is the hid descriptor
1636  //
1637  if (HidDescriptor->bLength == sizeof(HID_DESCRIPTOR) && HidDescriptor->bDescriptorType == HID_HID_DESCRIPTOR_TYPE)
1638  {
1639  //
1640  // found
1641  //
1642  HidDeviceExtension->HidDescriptor = HidDescriptor;
1643 
1644  //
1645  // select configuration
1646  //
1648 
1649  //
1650  // done
1651  //
1652  DPRINT("[HIDUSB] SelectConfiguration %x\n", Status);
1653 
1654  if (NT_SUCCESS(Status))
1655  {
1656  //
1657  // now set the device idle
1658  //
1660 
1661  //
1662  // get protocol
1663  //
1665  return Status;
1666  }
1667  }
1668  else
1669  {
1670  //
1671  // FIXME parse hid descriptor
1672  // select configuration
1673  // set idle
1674  // and get protocol
1675  //
1676  UNIMPLEMENTED;
1677  ASSERT(FALSE);
1678  }
1679  return Status;
1680 }
1681 
1682 
1683 NTSTATUS
1684 NTAPI
1687  IN PIRP Irp)
1688 {
1689  NTSTATUS Status;
1690  PIO_STACK_LOCATION IoStack;
1691  PHID_DEVICE_EXTENSION DeviceExtension;
1692  KEVENT Event;
1693 
1694  //
1695  // get device extension
1696  //
1697  DeviceExtension = DeviceObject->DeviceExtension;
1698 
1699  //
1700  // get current stack location
1701  //
1702  IoStack = IoGetCurrentIrpStackLocation(Irp);
1703  DPRINT("[HIDUSB] Pnp %x\n", IoStack->MinorFunction);
1704 
1705  //
1706  // handle requests based on request type
1707  //
1708  switch (IoStack->MinorFunction)
1709  {
1710  case IRP_MN_REMOVE_DEVICE:
1711  {
1712  //
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
1716  //
1718 
1719  //
1720  // pass request onto lower driver
1721  //
1723  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1724 
1725  return Status;
1726  }
1728  {
1729  //
1730  // device can not be disabled
1731  //
1732  Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
1733 
1734  //
1735  // pass request to next request
1736  //
1738  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1739 
1740  //
1741  // done
1742  //
1743  return Status;
1744  }
1747  {
1748  //
1749  // we're fine with it
1750  //
1751  Irp->IoStatus.Status = STATUS_SUCCESS;
1752 
1753  //
1754  // pass request to next driver
1755  //
1757  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1758 
1759  //
1760  // done
1761  //
1762  return Status;
1763  }
1764  case IRP_MN_STOP_DEVICE:
1765  {
1766  //
1767  // unconfigure device
1768  //
1770 
1771  //
1772  // prepare irp
1773  //
1777 
1778  //
1779  // send irp and wait for completion
1780  //
1781  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1782  if (Status == STATUS_PENDING)
1783  {
1785  Status = Irp->IoStatus.Status;
1786  }
1787 
1788  //
1789  // done
1790  //
1792  return Status;
1793  }
1795  {
1796  //
1797  // prepare irp
1798  //
1802 
1803  //
1804  // send irp and wait for completion
1805  //
1806  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1807  if (Status == STATUS_PENDING)
1808  {
1810  Status = Irp->IoStatus.Status;
1811  }
1812 
1813  if (NT_SUCCESS(Status) && IoStack->Parameters.DeviceCapabilities.Capabilities != NULL)
1814  {
1815  //
1816  // don't need to safely remove
1817  //
1818  IoStack->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE;
1819  }
1820 
1821  //
1822  // done
1823  //
1825  return Status;
1826  }
1827  case IRP_MN_START_DEVICE:
1828  {
1829  //
1830  // prepare irp
1831  //
1835 
1836  //
1837  // send irp and wait for completion
1838  //
1839  Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1840  if (Status == STATUS_PENDING)
1841  {
1843  Status = Irp->IoStatus.Status;
1844  }
1845 
1846  //
1847  // did the device successfully start
1848  //
1849  if (!NT_SUCCESS(Status))
1850  {
1851  //
1852  // failed
1853  //
1854  DPRINT1("HIDUSB: IRP_MN_START_DEVICE failed with %x\n", Status);
1856  return Status;
1857  }
1858 
1859  //
1860  // start device
1861  //
1863 
1864  //
1865  // complete request
1866  //
1867  Irp->IoStatus.Status = Status;
1868  DPRINT("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status);
1870  return Status;
1871  }
1872  default:
1873  {
1874  //
1875  // forward and forget request
1876  //
1878  return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
1879  }
1880  }
1881 }
1882 
1883 NTSTATUS
1884 NTAPI
1888 {
1889  PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
1890  PHID_DEVICE_EXTENSION DeviceExtension;
1891 
1892  //
1893  // get device extension
1894  //
1895  DeviceExtension = DeviceObject->DeviceExtension;
1896  HidDeviceExtension = DeviceExtension->MiniDeviceExtension;
1897 
1898  //
1899  // init event
1900  //
1901  KeInitializeEvent(&HidDeviceExtension->Event, NotificationEvent, FALSE);
1902 
1903  //
1904  // done
1905  //
1906  return STATUS_SUCCESS;
1907 }
1908 
1909 VOID
1910 NTAPI
1913 {
1914  UNIMPLEMENTED;
1915 }
1916 
1917 
1918 NTSTATUS
1919 NTAPI
1922  IN PUNICODE_STRING RegPath)
1923 {
1925  NTSTATUS Status;
1926 
1927  //
1928  // initialize driver object
1929  //
1938 
1939  //
1940  // prepare registration info
1941  //
1943 
1944  //
1945  // fill in registration info
1946  //
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;
1952 
1953  //
1954  // register driver
1955  //
1957 
1958  //
1959  // informal debug
1960  //
1961  DPRINT("********* HIDUSB *********\n");
1962  DPRINT("HIDUSB Registration Status %x\n", Status);
1963 
1964  return Status;
1965 }
PHID_DESCRIPTOR HidDescriptor
Definition: hidusb.h:47
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define USBD_STATUS_DEVICE_GONE
Definition: usb.h:210
struct _USB_DEVICE_DESCRIPTOR USB_DEVICE_DESCRIPTOR
#define IN
Definition: typedefs.h:38
PIO_WORKITEM WorkItem
Definition: hidusb.h:61
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define UsbBuildSelectConfigurationRequest(urb, length, configurationDescriptor)
Definition: usbdlib.h:53
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USB_PORT_STATUS_ENABLE
Definition: usb200.h:152
PVOID MiniDeviceExtension
Definition: hidport.h:19
#define USB_SET_IDLE_REQUEST
Definition: hidusb.h:87
NTSTATUS NTAPI HidInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:723
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
NTSTATUS NTAPI HidSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:919
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
NTSTATUS NTAPI PoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp)
Definition: power.c:485
VOID NTAPI Hid_Unload(IN PDRIVER_OBJECT DriverObject)
Definition: hidusb.c:1911
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS NTAPI HidAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:1885
#define IOCTL_HID_GET_MS_GENRE_DESCRIPTOR
Definition: hidclass.h:77
UCHAR bNumDescriptors
Definition: hidport.h:39
USBD_PIPE_INFORMATION Pipes[1]
Definition: usb.h:286
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:168
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor
Definition: hidusb.h:32
LONG NTSTATUS
Definition: precomp.h:26
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
NTSTATUS Hid_SetIdle(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:1364
#define STATUS_CONTINUE_COMPLETION
NTSTATUS Hid_GetDescriptor(IN PDEVICE_OBJECT DeviceObject, IN USHORT UrbFunction, IN USHORT UrbLength, IN OUT PVOID *UrbBuffer, IN OUT PULONG UrbBufferLength, IN UCHAR DescriptorType, IN UCHAR Index, IN USHORT LanguageIndex)
Definition: hidusb.c:1052
#define UsbBuildGetDescriptorRequest(urb, length, descriptorType, descriptorIndex, languageId, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:23
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define USB_ENDPOINT_DIRECTION_MASK
Definition: usb100.h:73
NTSTATUS NTAPI HidUsb_GetReportDescriptor(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:627
PDEVICE_OBJECT PhysicalDeviceObject
Definition: hidport.h:17
NTSTATUS HidUsb_ResetPort(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:238
struct _HID_DEVICE_ATTRIBUTES HID_DEVICE_ATTRIBUTES
#define UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR bDescriptorType
Definition: hidport.h:36
NTSTATUS HidUsb_ResetInterruptPipe(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:119
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
Definition: usbdlib.h:7
NTSTATUS HidUsb_GetPortStatus(IN PDEVICE_OBJECT DeviceObject, IN PULONG PortStatus)
Definition: hidusb.c:43
#define HID_REPORT_DESCRIPTOR_TYPE
Definition: hidport.h:95
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define USB_DEVICE_DESCRIPTOR_TYPE
Definition: usb100.h:49
#define IRP_MN_QUERY_REMOVE_DEVICE
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegPath)
Definition: hidusb.c:1920
#define IOCTL_HID_WRITE_REPORT
Definition: hidport.h:87
_In_ ULONG BufferLength
Definition: usbdlib.h:225
NTSTATUS NTAPI HidPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:905
#define HID_REVISION
Definition: hidclass.h:32
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2173
#define USB_CONFIGURATION_DESCRIPTOR_TYPE
Definition: usb100.h:50
#define IOCTL_GET_PHYSICAL_DESCRIPTOR
Definition: hidclass.h:56
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:434
NTSTATUS NTAPI Hid_PnpCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: hidusb.c:943
#define USB_DEVICE_CLASS_HUMAN_INTERFACE
Definition: usb100.h:93
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:297
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS HidUsb_AbortPipe(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:179
void DPRINT(...)
Definition: polytest.cpp:61
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: hidusb.h:27
USBD_PIPE_HANDLE PipeHandle
Definition: usb.h:264
#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
Definition: usb.h:116
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
UCHAR bLength
Definition: hidport.h:35
#define IRP_MN_QUERY_STOP_DEVICE
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
struct _URB_HEADER UrbHeader
Definition: usb.h:531
PDEVICE_OBJECT NextDeviceObject
Definition: hidport.h:18
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE
Definition: usb.h:126
#define IOCTL_HID_GET_FEATURE
Definition: hidclass.h:60
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define USB_GET_PROTOCOL_REQUEST
Definition: hidusb.h:88
PDEVICE_OBJECT DeviceObject
Definition: hidusb.h:66
VOID Hid_GetProtocol(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:1422
#define IRP_MN_STOP_DEVICE
UCHAR EndpointAddress
Definition: usb.h:261
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS NTAPI HidUsb_ReadReport(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:522
_Must_inspect_result_ _In_ CONST FLT_REGISTRATION * Registration
Definition: fltkernel.h:991
struct _HID_DESCRIPTOR HID_DESCRIPTOR
#define IOCTL_HID_GET_DEVICE_DESCRIPTOR
Definition: hidport.h:84
#define IRP_MN_START_DEVICE
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
static const UCHAR Index[8]
Definition: usbohci.c:18
#define PNP_DEVICE_NOT_DISABLEABLE
Definition: iotypes.h:968
#define IOCTL_HID_GET_REPORT_DESCRIPTOR
Definition: hidport.h:85
#define IOCTL_HID_GET_DEVICE_ATTRIBUTES
Definition: hidport.h:91
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define IOCTL_HID_GET_INPUT_REPORT
Definition: hidclass.h:63
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define USBD_STATUS_SUCCESS
Definition: usb.h:170
#define IOCTL_HID_READ_REPORT
Definition: hidport.h:86
VOID NTAPI IoInvalidateDeviceState(IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: pnpmgr.c:4434
struct _URB_PIPE_REQUEST UrbPipeRequest
Definition: usb.h:534
unsigned char UCHAR
Definition: xmlstorage.h:181
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IOCTL_HID_SET_OUTPUT_REPORT
Definition: hidclass.h:71
PUSBD_INTERFACE_INFORMATION InterfaceInfo
Definition: hidusb.h:37
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2179
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE
Definition: usb.h:97
#define HIDUSB_TAG
Definition: hidusb.h:90
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
_Outptr_ PUSB_DEVICE_HANDLE _In_ PUSB_DEVICE_HANDLE _In_ USHORT PortStatus
Definition: hubbusif.h:40
#define IRP_MJ_SYSTEM_CONTROL
struct _USB_CONFIGURATION_DESCRIPTOR USB_CONFIGURATION_DESCRIPTOR
Status
Definition: gdiplustypes.h:24
VOID NTAPI HidUsb_ResetWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Ctx)
Definition: hidusb.c:334
NTSTATUS NTAPI HidRegisterMinidriver(IN PHID_MINIDRIVER_REGISTRATION MinidriverRegistration)
Definition: hidclass.c:1244
struct _HID_DESCRIPTOR::_HID_DESCRIPTOR_DESC_LIST DescriptorList[1]
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2111
#define USBD_SHORT_TRANSFER_OK
Definition: usb.h:154
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
struct _URB_SELECT_CONFIGURATION UrbSelectConfiguration
Definition: usb.h:533
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
USBD_PIPE_TYPE PipeType
Definition: usb.h:263
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbdlib.h:8
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
Definition: usb.h:529
unsigned short USHORT
Definition: pedump.c:61
#define URB_FUNCTION_ABORT_PIPE
Definition: usb.h:88
USBD_CONFIGURATION_HANDLE ConfigurationHandle
Definition: hidusb.h:42
#define URB_FUNCTION_CLASS_INTERFACE
Definition: usb.h:113
NTSTATUS NTAPI HidUsb_ReadReportCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: hidusb.c:419
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IOCTL_HID_SET_FEATURE
Definition: hidclass.h:69
#define IOCTL_INTERNAL_USB_RESET_PORT
Definition: usbioctl.h:35
#define IOCTL_INTERNAL_USB_GET_PORT_STATUS
Definition: usbioctl.h:44
#define IOCTL_HID_GET_INDEXED_STRING
Definition: hidclass.h:76
NTSTATUS NTAPI HidCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:298
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
#define IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST
Definition: hidport.h:92
PUSBD_PIPE_INFORMATION HidUsb_GetInputInterruptInterfaceHandle(PUSBD_INTERFACE_INFORMATION InterfaceInformation)
Definition: hidusb.c:14
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT
Definition: usb.h:122
NTSTATUS Hid_DisableConfiguration(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:1280
#define OUT
Definition: typedefs.h:39
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2180
#define HIDUSB_URB_TAG
Definition: hidusb.h:91
NTSTATUS Hid_SelectConfiguration(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:1184
struct _URB_BULK_OR_INTERRUPT_TRANSFER UrbBulkOrInterruptTransfer
Definition: usb.h:543
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _HID_DESCRIPTOR * PHID_DESCRIPTOR
NTSTATUS Hid_PnpStart(IN PDEVICE_OBJECT DeviceObject)
Definition: hidusb.c:1506
#define USBD_SUCCESS(Status)
Definition: usb.h:167
NTSTATUS Hid_DispatchUrb(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: hidusb.c:960
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _URB_CONTROL_DESCRIPTOR_REQUEST UrbControlDescriptorRequest
Definition: usb.h:545
#define HID_HID_DESCRIPTOR_TYPE
Definition: hidport.h:94
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define UsbBuildInterruptOrBulkTransferRequest(urb, length, pipeHandle, transferBuffer, transferBufferMDL, transferBufferLength, transferFlags, link)
Definition: usbdlib.h:12
NTSTATUS NTAPI HidPnp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidusb.c:1685
PURB NTAPI USBD_CreateConfigurationRequestEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PUSBD_INTERFACE_LIST_ENTRY InterfaceList)
Definition: usbd.c:329
return STATUS_SUCCESS
Definition: btrfs.c:2777
IoMarkIrpPending(Irp)
_In_ ULONG _In_ PVOID _In_ LONG DescriptorType
Definition: usbdlib.h:145
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define IRP_MN_QUERY_CAPABILITIES