ReactOS  0.4.14-dev-41-g31d7680
hidclass.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/hid/hidclass/hidclass.c
5  * PURPOSE: HID Class Driver
6  * PROGRAMMERS:
7  * Michael Martin (michael.martin@reactos.org)
8  * Johannes Anderwald (johannes.anderwald@reactos.org)
9  */
10 
11 #include "precomp.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
18 
20 NTAPI
23 {
24  return STATUS_SUCCESS;
25 }
26 
28 NTAPI
30 {
31  return STATUS_SUCCESS;
32 }
33 
35 NTAPI
39 {
40  WCHAR CharDeviceName[64];
43  PDEVICE_OBJECT NewDeviceObject;
44  PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
45  ULONG DeviceExtensionSize;
47 
48  /* increment device number */
50 
51  /* construct device name */
52  swprintf(CharDeviceName, L"\\Device\\_HID%08x", HidClassDeviceNumber);
53 
54  /* initialize device name */
55  RtlInitUnicodeString(&DeviceName, CharDeviceName);
56 
57  /* get driver object extension */
59  if (!DriverExtension)
60  {
61  /* device removed */
62  ASSERT(FALSE);
64  }
65 
66  /* calculate device extension size */
67  DeviceExtensionSize = sizeof(HIDCLASS_FDO_EXTENSION) + DriverExtension->DeviceExtensionSize;
68 
69  /* now create the device */
70  Status = IoCreateDevice(DriverObject, DeviceExtensionSize, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &NewDeviceObject);
71  if (!NT_SUCCESS(Status))
72  {
73  /* failed to create device object */
74  ASSERT(FALSE);
75  return Status;
76  }
77 
78  /* get device extension */
79  FDODeviceExtension = NewDeviceObject->DeviceExtension;
80 
81  /* zero device extension */
82  RtlZeroMemory(FDODeviceExtension, sizeof(HIDCLASS_FDO_EXTENSION));
83 
84  /* initialize device extension */
85  FDODeviceExtension->Common.IsFDO = TRUE;
86  FDODeviceExtension->Common.DriverExtension = DriverExtension;
88  FDODeviceExtension->Common.HidDeviceExtension.MiniDeviceExtension = (PVOID)((ULONG_PTR)FDODeviceExtension + sizeof(HIDCLASS_FDO_EXTENSION));
90  if (FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject == NULL)
91  {
92  /* no PDO */
93  IoDeleteDevice(NewDeviceObject);
94  DPRINT1("[HIDCLASS] failed to attach to device stack\n");
95  return STATUS_DEVICE_REMOVED;
96  }
97 
98  /* sanity check */
99  ASSERT(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
100 
101  /* increment stack size */
102  NewDeviceObject->StackSize++;
103 
104  /* init device object */
105  NewDeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
106  NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
107 
108  /* now call driver provided add device routine */
109  ASSERT(DriverExtension->AddDevice != 0);
110  Status = DriverExtension->AddDevice(DriverObject, NewDeviceObject);
111  if (!NT_SUCCESS(Status))
112  {
113  /* failed */
114  DPRINT1("HIDCLASS: AddDevice failed with %x\n", Status);
116  IoDeleteDevice(NewDeviceObject);
117  return Status;
118  }
119 
120  /* succeeded */
121  return Status;
122 }
123 
124 VOID
125 NTAPI
128 {
130 }
131 
132 NTSTATUS
133 NTAPI
136  IN PIRP Irp)
137 {
138  PIO_STACK_LOCATION IoStack;
139  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
140  PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
142 
143  //
144  // get device extension
145  //
146  CommonDeviceExtension = DeviceObject->DeviceExtension;
147  if (CommonDeviceExtension->IsFDO)
148  {
149  //
150  // only supported for PDO
151  //
152  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
154  return STATUS_UNSUCCESSFUL;
155  }
156 
157  //
158  // must be a PDO
159  //
160  ASSERT(CommonDeviceExtension->IsFDO == FALSE);
161 
162  //
163  // get device extension
164  //
165  PDODeviceExtension = DeviceObject->DeviceExtension;
166 
167  //
168  // get stack location
169  //
171 
172  DPRINT("ShareAccess %x\n", IoStack->Parameters.Create.ShareAccess);
173  DPRINT("Options %x\n", IoStack->Parameters.Create.Options);
174  DPRINT("DesiredAccess %x\n", IoStack->Parameters.Create.SecurityContext->DesiredAccess);
175 
176  //
177  // allocate context
178  //
180  if (!Context)
181  {
182  //
183  // no memory
184  //
185  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
188  }
189 
190  //
191  // init context
192  //
194  Context->DeviceExtension = PDODeviceExtension;
196  InitializeListHead(&Context->ReadPendingIrpListHead);
197  InitializeListHead(&Context->IrpCompletedListHead);
198  KeInitializeEvent(&Context->IrpReadComplete, NotificationEvent, FALSE);
199 
200  //
201  // store context
202  //
203  ASSERT(IoStack->FileObject);
204  IoStack->FileObject->FsContext = Context;
205 
206  //
207  // done
208  //
209  Irp->IoStatus.Status = STATUS_SUCCESS;
211  return STATUS_SUCCESS;
212 }
213 
214 NTSTATUS
215 NTAPI
218  IN PIRP Irp)
219 {
220  PIO_STACK_LOCATION IoStack;
221  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
222  PHIDCLASS_FILEOP_CONTEXT IrpContext;
223  BOOLEAN IsRequestPending = FALSE;
224  KIRQL OldLevel;
226  PIRP ListIrp;
227 
228  //
229  // get device extension
230  //
231  CommonDeviceExtension = DeviceObject->DeviceExtension;
232 
233  //
234  // is it a FDO request
235  //
236  if (CommonDeviceExtension->IsFDO)
237  {
238  //
239  // how did the request get there
240  //
241  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1;
244  }
245 
246  //
247  // get stack location
248  //
250 
251  //
252  // sanity checks
253  //
254  ASSERT(IoStack->FileObject);
255  ASSERT(IoStack->FileObject->FsContext);
256 
257  //
258  // get irp context
259  //
260  IrpContext = IoStack->FileObject->FsContext;
261  ASSERT(IrpContext);
262 
263  //
264  // acquire lock
265  //
266  KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
267 
268  if (!IsListEmpty(&IrpContext->ReadPendingIrpListHead))
269  {
270  //
271  // FIXME cancel irp
272  //
273  IsRequestPending = TRUE;
274  }
275 
276  //
277  // signal stop
278  //
279  IrpContext->StopInProgress = TRUE;
280 
281  //
282  // release lock
283  //
284  KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
285 
286  if (IsRequestPending)
287  {
288  //
289  // wait for request to complete
290  //
291  DPRINT1("[HIDCLASS] Waiting for read irp completion...\n");
293  }
294 
295  //
296  // acquire lock
297  //
298  KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
299 
300  //
301  // sanity check
302  //
304 
305  //
306  // now free all irps
307  //
308  while (!IsListEmpty(&IrpContext->IrpCompletedListHead))
309  {
310  //
311  // remove head irp
312  //
313  Entry = RemoveHeadList(&IrpContext->IrpCompletedListHead);
314 
315  //
316  // get irp
317  //
318  ListIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
319 
320  //
321  // free the irp
322  //
323  IoFreeIrp(ListIrp);
324  }
325 
326  //
327  // release lock
328  //
329  KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
330 
331  //
332  // remove context
333  //
334  IoStack->FileObject->FsContext = NULL;
335 
336  //
337  // free context
338  //
339  ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
340 
341  //
342  // complete request
343  //
344  Irp->IoStatus.Status = STATUS_SUCCESS;
346  return STATUS_SUCCESS;
347 }
348 
349 NTSTATUS
350 NTAPI
353  IN PIRP Irp,
354  IN PVOID Ctx)
355 {
356  PHIDCLASS_IRP_CONTEXT IrpContext;
357  KIRQL OldLevel;
358  PUCHAR Address;
359  ULONG Offset;
360  PHIDP_COLLECTION_DESC CollectionDescription;
361  PHIDP_REPORT_IDS ReportDescription;
363 
364  //
365  // get irp context
366  //
367  IrpContext = Ctx;
368 
369  DPRINT("HidClass_ReadCompleteIrp Irql %lu\n", KeGetCurrentIrql());
370  DPRINT("HidClass_ReadCompleteIrp Status %lx\n", Irp->IoStatus.Status);
371  DPRINT("HidClass_ReadCompleteIrp Length %lu\n", Irp->IoStatus.Information);
372  DPRINT("HidClass_ReadCompleteIrp Irp %p\n", Irp);
373  DPRINT("HidClass_ReadCompleteIrp InputReportBuffer %p\n", IrpContext->InputReportBuffer);
374  DPRINT("HidClass_ReadCompleteIrp InputReportBufferLength %li\n", IrpContext->InputReportBufferLength);
375  DPRINT("HidClass_ReadCompleteIrp OriginalIrp %p\n", IrpContext->OriginalIrp);
376 
377  //
378  // copy result
379  //
380  if (Irp->IoStatus.Information)
381  {
382  //
383  // get address
384  //
386  if (Address)
387  {
388  //
389  // reports may have a report id prepended
390  //
391  Offset = 0;
392 
393  //
394  // get collection description
395  //
397  IrpContext->FileOp->DeviceExtension->CollectionNumber);
398  ASSERT(CollectionDescription);
399 
400  //
401  // get report description
402  //
404  IrpContext->FileOp->DeviceExtension->CollectionNumber);
405  ASSERT(ReportDescription);
406 
407  if (CollectionDescription && ReportDescription)
408  {
409  //
410  // calculate offset
411  //
412  ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
413  Offset = CollectionDescription->InputLength - ReportDescription->InputLength;
414  }
415 
416  //
417  // copy result
418  //
420  }
421  }
422 
423  //
424  // copy result status
425  //
426  IrpContext->OriginalIrp->IoStatus.Status = Irp->IoStatus.Status;
427  IrpContext->OriginalIrp->IoStatus.Information = Irp->IoStatus.Information;
428 
429  //
430  // free input report buffer
431  //
433 
434  //
435  // remove us from pending list
436  //
437  KeAcquireSpinLock(&IrpContext->FileOp->Lock, &OldLevel);
438 
439  //
440  // remove from pending list
441  //
442  RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
443 
444  //
445  // is list empty
446  //
448 
449  //
450  // insert into completed list
451  //
452  InsertTailList(&IrpContext->FileOp->IrpCompletedListHead, &Irp->Tail.Overlay.ListEntry);
453 
454  //
455  // release lock
456  //
457  KeReleaseSpinLock(&IrpContext->FileOp->Lock, OldLevel);
458 
459  //
460  // complete original request
461  //
463 
464 
465  DPRINT("StopInProgress %x IsEmpty %x\n", IrpContext->FileOp->StopInProgress, IsEmpty);
466  if (IrpContext->FileOp->StopInProgress && IsEmpty)
467  {
468  //
469  // last pending irp
470  //
471  DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
472  KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
473  }
474 
475  if (IrpContext->FileOp->StopInProgress && IsEmpty)
476  {
477  //
478  // last pending irp
479  //
480  DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
481  KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
482  }
483 
484  //
485  // free irp context
486  //
487  ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
488 
489  //
490  // done
491  //
493 }
494 
495 PIRP
498 {
499  KIRQL OldLevel;
500  PIRP Irp = NULL;
501  PLIST_ENTRY ListEntry;
502 
503  //
504  // acquire lock
505  //
506  KeAcquireSpinLock(&Context->Lock, &OldLevel);
507 
508  //
509  // is list empty?
510  //
511  if (!IsListEmpty(&Context->IrpCompletedListHead))
512  {
513  //
514  // grab first entry
515  //
516  ListEntry = RemoveHeadList(&Context->IrpCompletedListHead);
517 
518  //
519  // get irp
520  //
521  Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry);
522  }
523 
524  //
525  // release lock
526  //
527  KeReleaseSpinLock(&Context->Lock, OldLevel);
528 
529  //
530  // done
531  //
532  return Irp;
533 }
534 
535 NTSTATUS
538  IN PIRP RequestIrp,
540  IN ULONG DeviceIoControlCode,
542  OUT PIRP *OutIrp,
543  OUT PHIDCLASS_IRP_CONTEXT *OutIrpContext)
544 {
545  PIRP Irp;
546  PIO_STACK_LOCATION IoStack;
547  PHIDCLASS_IRP_CONTEXT IrpContext;
548  PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
549  PHIDP_COLLECTION_DESC CollectionDescription;
550  PHIDP_REPORT_IDS ReportDescription;
551 
552  //
553  // get an irp from fresh list
554  //
556  if (!Irp)
557  {
558  //
559  // build new irp
560  //
562  if (!Irp)
563  {
564  //
565  // no memory
566  //
568  }
569  }
570  else
571  {
572  //
573  // re-use irp
574  //
576  }
577 
578  //
579  // allocate completion context
580  //
582  if (!IrpContext)
583  {
584  //
585  // no memory
586  //
587  IoFreeIrp(Irp);
589  }
590 
591  //
592  // get device extension
593  //
594  PDODeviceExtension = DeviceObject->DeviceExtension;
595  ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
596 
597  //
598  // init irp context
599  //
600  RtlZeroMemory(IrpContext, sizeof(HIDCLASS_IRP_CONTEXT));
601  IrpContext->OriginalIrp = RequestIrp;
602  IrpContext->FileOp = Context;
603 
604  //
605  // get collection description
606  //
608  IrpContext->FileOp->DeviceExtension->CollectionNumber);
609  ASSERT(CollectionDescription);
610 
611  //
612  // get report description
613  //
615  IrpContext->FileOp->DeviceExtension->CollectionNumber);
616  ASSERT(ReportDescription);
617 
618  //
619  // sanity check
620  //
621  ASSERT(CollectionDescription->InputLength >= ReportDescription->InputLength);
622 
623  if (Context->StopInProgress)
624  {
625  //
626  // stop in progress
627  //
628  DPRINT1("[HIDCLASS] Stop In Progress\n");
629  Irp->IoStatus.Status = STATUS_CANCELLED;
631  return STATUS_CANCELLED;
632 
633  }
634 
635  //
636  // store report length
637  //
638  IrpContext->InputReportBufferLength = ReportDescription->InputLength;
639 
640  //
641  // allocate buffer
642  //
644  if (!IrpContext->InputReportBuffer)
645  {
646  //
647  // no memory
648  //
649  IoFreeIrp(Irp);
650  ExFreePoolWithTag(IrpContext, HIDCLASS_TAG);
652  }
653 
654  //
655  // get stack location
656  //
657  IoStack = IoGetNextIrpStackLocation(Irp);
658 
659  //
660  // init stack location
661  //
663  IoStack->Parameters.DeviceIoControl.IoControlCode = DeviceIoControlCode;
664  IoStack->Parameters.DeviceIoControl.OutputBufferLength = IrpContext->InputReportBufferLength;
665  IoStack->Parameters.DeviceIoControl.InputBufferLength = 0;
666  IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
667  Irp->UserBuffer = IrpContext->InputReportBuffer;
668  IoStack->DeviceObject = DeviceObject;
669 
670  //
671  // store result
672  //
673  *OutIrp = Irp;
674  *OutIrpContext = IrpContext;
675 
676  //
677  // done
678  //
679  return STATUS_SUCCESS;
680 }
681 
682 NTSTATUS
683 NTAPI
686  IN PIRP Irp)
687 {
688  PIO_STACK_LOCATION IoStack;
690  KIRQL OldLevel;
692  PIRP NewIrp;
693  PHIDCLASS_IRP_CONTEXT NewIrpContext;
694  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
695 
696  //
697  // get current stack location
698  //
700 
701  //
702  // get device extension
703  //
704  CommonDeviceExtension = DeviceObject->DeviceExtension;
705  ASSERT(CommonDeviceExtension->IsFDO == FALSE);
706 
707  //
708  // sanity check
709  //
710  ASSERT(IoStack->FileObject);
711  ASSERT(IoStack->FileObject->FsContext);
712 
713  //
714  // get context
715  //
716  Context = IoStack->FileObject->FsContext;
717  ASSERT(Context);
718 
719  //
720  // FIXME support polled devices
721  //
722  ASSERT(Context->DeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE);
723 
724  if (Context->StopInProgress)
725  {
726  //
727  // stop in progress
728  //
729  DPRINT1("[HIDCLASS] Stop In Progress\n");
730  Irp->IoStatus.Status = STATUS_CANCELLED;
732  return STATUS_CANCELLED;
733  }
734 
735  //
736  // build irp request
737  //
739  Irp,
740  Context,
742  IoStack->Parameters.Read.Length,
743  &NewIrp,
744  &NewIrpContext);
745  if (!NT_SUCCESS(Status))
746  {
747  //
748  // failed
749  //
750  DPRINT1("HidClass_BuildIrp failed with %x\n", Status);
751  Irp->IoStatus.Status = Status;
753  return Status;
754  }
755 
756  //
757  // acquire lock
758  //
759  KeAcquireSpinLock(&Context->Lock, &OldLevel);
760 
761  //
762  // insert irp into pending list
763  //
764  InsertTailList(&Context->ReadPendingIrpListHead, &NewIrp->Tail.Overlay.ListEntry);
765 
766  //
767  // set completion routine
768  //
769  IoSetCompletionRoutine(NewIrp, HidClass_ReadCompleteIrp, NewIrpContext, TRUE, TRUE, TRUE);
770 
771  //
772  // make next location current
773  //
775 
776  //
777  // release spin lock
778  //
779  KeReleaseSpinLock(&Context->Lock, OldLevel);
780 
781  //
782  // mark irp pending
783  //
785 
786  //
787  // let's dispatch the request
788  //
789  ASSERT(Context->DeviceExtension);
790  Status = Context->DeviceExtension->Common.DriverExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL](Context->DeviceExtension->FDODeviceObject, NewIrp);
791 
792  //
793  // complete
794  //
795  return STATUS_PENDING;
796 }
797 
798 NTSTATUS
799 NTAPI
802  IN PIRP Irp)
803 {
804  PIO_STACK_LOCATION IoStack;
805  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
806  PIRP SubIrp;
807  KEVENT Event;
809  HID_XFER_PACKET XferPacket;
811  ULONG Length;
812 
814  Length = IoStack->Parameters.Write.Length;
815  if (Length < 1)
816  {
817  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
820  }
821 
822  RtlZeroMemory(&XferPacket, sizeof(XferPacket));
823  XferPacket.reportBufferLen = Length;
824  XferPacket.reportBuffer = Irp->UserBuffer;
825  XferPacket.reportId = XferPacket.reportBuffer[0];
826 
827  CommonDeviceExtension = DeviceObject->DeviceExtension;
830  CommonDeviceExtension->HidDeviceExtension.NextDeviceObject,
831  NULL, 0,
832  NULL, 0,
833  TRUE,
834  &Event,
835  &IoStatusBlock);
836  if (!SubIrp)
837  {
838  Irp->IoStatus.Status = STATUS_NO_MEMORY;
840  return STATUS_NOT_IMPLEMENTED;
841  }
842  SubIrp->UserBuffer = &XferPacket;
844  Status = IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, SubIrp);
845  if (Status == STATUS_PENDING)
846  {
849  }
850  Irp->IoStatus.Status = Status;
852  return Status;
853 }
854 
855 NTSTATUS
856 NTAPI
859  IN PIRP Irp)
860 {
861  PIO_STACK_LOCATION IoStack;
862  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
863  PHID_COLLECTION_INFORMATION CollectionInformation;
864  PHIDP_COLLECTION_DESC CollectionDescription;
865  PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension;
866 
867  //
868  // get device extension
869  //
870  CommonDeviceExtension = DeviceObject->DeviceExtension;
871 
872  //
873  // only PDO are supported
874  //
875  if (CommonDeviceExtension->IsFDO)
876  {
877  //
878  // invalid request
879  //
880  DPRINT1("[HIDCLASS] DeviceControl Irp for FDO arrived\n");
881  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER_1;
884  }
885 
886  ASSERT(CommonDeviceExtension->IsFDO == FALSE);
887 
888  //
889  // get pdo device extension
890  //
891  PDODeviceExtension = DeviceObject->DeviceExtension;
892 
893  //
894  // get stack location
895  //
897 
898  switch (IoStack->Parameters.DeviceIoControl.IoControlCode)
899  {
901  {
902  //
903  // check if output buffer is big enough
904  //
905  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(HID_COLLECTION_INFORMATION))
906  {
907  //
908  // invalid buffer size
909  //
910  Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
913  }
914 
915  //
916  // get output buffer
917  //
918  CollectionInformation = Irp->AssociatedIrp.SystemBuffer;
919  ASSERT(CollectionInformation);
920 
921  //
922  // get collection description
923  //
924  CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
925  PDODeviceExtension->CollectionNumber);
926  ASSERT(CollectionDescription);
927 
928  //
929  // init result buffer
930  //
931  CollectionInformation->DescriptorSize = CollectionDescription->PreparsedDataLength;
932  CollectionInformation->Polled = CommonDeviceExtension->DriverExtension->DevicesArePolled;
933  CollectionInformation->VendorID = CommonDeviceExtension->Attributes.VendorID;
934  CollectionInformation->ProductID = CommonDeviceExtension->Attributes.ProductID;
935  CollectionInformation->VersionNumber = CommonDeviceExtension->Attributes.VersionNumber;
936 
937  //
938  // complete request
939  //
940  Irp->IoStatus.Information = sizeof(HID_COLLECTION_INFORMATION);
941  Irp->IoStatus.Status = STATUS_SUCCESS;
943  return STATUS_SUCCESS;
944  }
946  {
947  //
948  // get collection description
949  //
950  CollectionDescription = HidClassPDO_GetCollectionDescription(&CommonDeviceExtension->DeviceDescription,
951  PDODeviceExtension->CollectionNumber);
952  ASSERT(CollectionDescription);
953 
954  //
955  // check if output buffer is big enough
956  //
957  if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < CollectionDescription->PreparsedDataLength)
958  {
959  //
960  // invalid buffer size
961  //
962  Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
965  }
966 
967  //
968  // copy result
969  //
970  ASSERT(Irp->UserBuffer);
971  RtlCopyMemory(Irp->UserBuffer, CollectionDescription->PreparsedData, CollectionDescription->PreparsedDataLength);
972 
973  //
974  // complete request
975  //
976  Irp->IoStatus.Information = CollectionDescription->PreparsedDataLength;
977  Irp->IoStatus.Status = STATUS_SUCCESS;
979  return STATUS_SUCCESS;
980  }
982  {
983  PIRP SubIrp;
984  KEVENT Event;
986  HID_XFER_PACKET XferPacket;
988  PHIDP_REPORT_IDS ReportDescription;
989 
990  if (IoStack->Parameters.DeviceIoControl.InputBufferLength < 1)
991  {
992  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
995  }
996  ReportDescription = HidClassPDO_GetReportDescriptionByReportID(&PDODeviceExtension->Common.DeviceDescription, ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[0]);
997  if (!ReportDescription || IoStack->Parameters.DeviceIoControl.OutputBufferLength < ReportDescription->FeatureLength)
998  {
999  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1001  return STATUS_INVALID_PARAMETER;
1002  }
1003 
1004  RtlZeroMemory(&XferPacket, sizeof(XferPacket));
1005  XferPacket.reportBufferLen = ReportDescription->FeatureLength;
1007  XferPacket.reportId = ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[0];
1008  if (!XferPacket.reportBuffer)
1009  {
1010  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1013  }
1014 
1017  CommonDeviceExtension->HidDeviceExtension.NextDeviceObject,
1018  NULL, 0,
1019  NULL, 0,
1020  TRUE,
1021  &Event,
1022  &IoStatusBlock);
1023  if (!SubIrp)
1024  {
1025  Irp->IoStatus.Status = STATUS_NO_MEMORY;
1027  return STATUS_NOT_IMPLEMENTED;
1028  }
1029  SubIrp->UserBuffer = &XferPacket;
1031  Status = IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, SubIrp);
1032  if (Status == STATUS_PENDING)
1033  {
1036  }
1037  Irp->IoStatus.Status = Status;
1039  return Status;
1040  }
1041  case IOCTL_HID_SET_FEATURE:
1042  {
1043  PIRP SubIrp;
1044  KEVENT Event;
1046  HID_XFER_PACKET XferPacket;
1047  NTSTATUS Status;
1048  PHIDP_REPORT_IDS ReportDescription;
1049 
1050  if (IoStack->Parameters.DeviceIoControl.InputBufferLength < 1)
1051  {
1052  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1054  return STATUS_INVALID_PARAMETER;
1055  }
1056  ReportDescription = HidClassPDO_GetReportDescriptionByReportID(&PDODeviceExtension->Common.DeviceDescription, ((PUCHAR)Irp->AssociatedIrp.SystemBuffer)[0]);
1057  if (!ReportDescription || IoStack->Parameters.DeviceIoControl.InputBufferLength < ReportDescription->FeatureLength)
1058  {
1059  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1061  return STATUS_INVALID_PARAMETER;
1062  }
1063 
1064  RtlZeroMemory(&XferPacket, sizeof(XferPacket));
1065  XferPacket.reportBufferLen = ReportDescription->FeatureLength;
1066  XferPacket.reportBuffer = Irp->AssociatedIrp.SystemBuffer;
1067  XferPacket.reportId = XferPacket.reportBuffer[0];
1068 
1071  CommonDeviceExtension->HidDeviceExtension.NextDeviceObject,
1072  NULL, 0,
1073  NULL, 0,
1074  TRUE,
1075  &Event,
1076  &IoStatusBlock);
1077  if (!SubIrp)
1078  {
1079  Irp->IoStatus.Status = STATUS_NO_MEMORY;
1081  return STATUS_NOT_IMPLEMENTED;
1082  }
1083  SubIrp->UserBuffer = &XferPacket;
1085  Status = IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, SubIrp);
1086  if (Status == STATUS_PENDING)
1087  {
1090  }
1091  Irp->IoStatus.Status = Status;
1093  return Status;
1094  }
1095  default:
1096  {
1097  DPRINT1("[HIDCLASS] DeviceControl IoControlCode 0x%x not implemented\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
1098  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1100  return STATUS_NOT_IMPLEMENTED;
1101  }
1102  }
1103 }
1104 
1105 NTSTATUS
1106 NTAPI
1109  IN PIRP Irp)
1110 {
1111  UNIMPLEMENTED;
1112  ASSERT(FALSE);
1113  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1115  return STATUS_NOT_IMPLEMENTED;
1116 }
1117 
1118 NTSTATUS
1119 NTAPI
1122  IN PIRP Irp)
1123 {
1124  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
1125  CommonDeviceExtension = DeviceObject->DeviceExtension;
1126 
1127  if (CommonDeviceExtension->IsFDO)
1128  {
1131  }
1132  else
1133  {
1134  Irp->IoStatus.Status = STATUS_SUCCESS;
1137  return STATUS_SUCCESS;
1138  }
1139 }
1140 
1141 NTSTATUS
1142 NTAPI
1145  IN PIRP Irp)
1146 {
1147  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
1148 
1149  //
1150  // get common device extension
1151  //
1152  CommonDeviceExtension = DeviceObject->DeviceExtension;
1153 
1154  //
1155  // check type of device object
1156  //
1157  if (CommonDeviceExtension->IsFDO)
1158  {
1159  //
1160  // handle request
1161  //
1162  return HidClassFDO_PnP(DeviceObject, Irp);
1163  }
1164  else
1165  {
1166  //
1167  // handle request
1168  //
1169  return HidClassPDO_PnP(DeviceObject, Irp);
1170  }
1171 }
1172 
1173 NTSTATUS
1174 NTAPI
1177  IN PIRP Irp)
1178 {
1179  PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
1180 
1181  //
1182  // get common device extension
1183  //
1184  CommonDeviceExtension = DeviceObject->DeviceExtension;
1185 
1186  //
1187  // FIXME: support PDO
1188  //
1189  ASSERT(CommonDeviceExtension->IsFDO == TRUE);
1190 
1191  //
1192  // skip current irp stack location
1193  //
1195 
1196  //
1197  // dispatch to lower device object
1198  //
1199  return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp);
1200 }
1201 
1202 NTSTATUS
1203 NTAPI
1206  IN PIRP Irp)
1207 {
1208  PIO_STACK_LOCATION IoStack;
1209 
1210  //
1211  // get current stack location
1212  //
1213  IoStack = IoGetCurrentIrpStackLocation(Irp);
1214  DPRINT("[HIDCLASS] Dispatch Major %x Minor %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
1215 
1216  //
1217  // dispatch request based on major function
1218  //
1219  switch (IoStack->MajorFunction)
1220  {
1221  case IRP_MJ_CREATE:
1222  return HidClass_Create(DeviceObject, Irp);
1223  case IRP_MJ_CLOSE:
1224  return HidClass_Close(DeviceObject, Irp);
1225  case IRP_MJ_READ:
1226  return HidClass_Read(DeviceObject, Irp);
1227  case IRP_MJ_WRITE:
1228  return HidClass_Write(DeviceObject, Irp);
1229  case IRP_MJ_DEVICE_CONTROL:
1233  case IRP_MJ_POWER:
1234  return HidClass_Power(DeviceObject, Irp);
1235  case IRP_MJ_PNP:
1236  return HidClass_PnP(DeviceObject, Irp);
1237  default:
1239  }
1240 }
1241 
1242 NTSTATUS
1243 NTAPI
1245  IN PHID_MINIDRIVER_REGISTRATION MinidriverRegistration)
1246 {
1247  NTSTATUS Status;
1249 
1250  /* check if the version matches */
1251  if (MinidriverRegistration->Revision > HID_REVISION)
1252  {
1253  /* revision mismatch */
1254  ASSERT(FALSE);
1255  return STATUS_REVISION_MISMATCH;
1256  }
1257 
1258  /* now allocate the driver object extension */
1259  Status = IoAllocateDriverObjectExtension(MinidriverRegistration->DriverObject,
1261  sizeof(HIDCLASS_DRIVER_EXTENSION),
1262  (PVOID *)&DriverExtension);
1263  if (!NT_SUCCESS(Status))
1264  {
1265  /* failed to allocate driver extension */
1266  ASSERT(FALSE);
1267  return Status;
1268  }
1269 
1270  /* zero driver extension */
1272 
1273  /* init driver extension */
1274  DriverExtension->DriverObject = MinidriverRegistration->DriverObject;
1275  DriverExtension->DeviceExtensionSize = MinidriverRegistration->DeviceExtensionSize;
1276  DriverExtension->DevicesArePolled = MinidriverRegistration->DevicesArePolled;
1277  DriverExtension->AddDevice = MinidriverRegistration->DriverObject->DriverExtension->AddDevice;
1278  DriverExtension->DriverUnload = MinidriverRegistration->DriverObject->DriverUnload;
1279 
1280  /* copy driver dispatch routines */
1281  RtlCopyMemory(DriverExtension->MajorFunction,
1282  MinidriverRegistration->DriverObject->MajorFunction,
1283  sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1));
1284 
1285  /* initialize lock */
1287 
1288  /* now replace dispatch routines */
1289  DriverExtension->DriverObject->DriverExtension->AddDevice = HidClassAddDevice;
1290  DriverExtension->DriverObject->DriverUnload = HidClassDriverUnload;
1291  DriverExtension->DriverObject->MajorFunction[IRP_MJ_CREATE] = HidClassDispatch;
1292  DriverExtension->DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidClassDispatch;
1293  DriverExtension->DriverObject->MajorFunction[IRP_MJ_READ] = HidClassDispatch;
1294  DriverExtension->DriverObject->MajorFunction[IRP_MJ_WRITE] = HidClassDispatch;
1295  DriverExtension->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HidClassDispatch;
1296  DriverExtension->DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HidClassDispatch;
1297  DriverExtension->DriverObject->MajorFunction[IRP_MJ_POWER] = HidClassDispatch;
1298  DriverExtension->DriverObject->MajorFunction[IRP_MJ_PNP] = HidClassDispatch;
1299 
1300  /* done */
1301  return STATUS_SUCCESS;
1302 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:311
#define DO_POWER_PAGABLE
static LPWSTR ClientIdentificationAddress
Definition: hidclass.c:16
#define IN
Definition: typedefs.h:38
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:795
#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 STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID MiniDeviceExtension
Definition: hidport.h:19
NTSTATUS NTAPI HidClassAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
Definition: hidclass.c:36
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1764
NTSTATUS NTAPI HidClass_InternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:1107
struct _Entry Entry
Definition: kefuncs.h:640
VOID NTAPI IoReuseIrp(IN OUT PIRP Irp, IN NTSTATUS Status)
Definition: irp.c:1971
ULONG reportBufferLen
Definition: hidclass.h:152
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
NTSTATUS NTAPI HidClass_Create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:134
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
HID_DEVICE_ATTRIBUTES Attributes
Definition: precomp.h:49
unsigned char * PUCHAR
Definition: retypes.h:3
PHIDP_PREPARSED_DATA PreparsedData
Definition: hidpddi.h:17
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI HidClass_Write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:800
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
PHIDCLASS_PDO_DEVICE_EXTENSION DeviceExtension
Definition: precomp.h:121
NTSTATUS NTAPI DllUnload(VOID)
Definition: hidclass.c:29
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
IRP
Definition: iotypes.h:2463
NTSTATUS NTAPI HidClass_Read(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:684
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1114
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
LIST_ENTRY ReadPendingIrpListHead
Definition: precomp.h:131
NTSTATUS NTAPI HidClass_DispatchDefault(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:1175
USHORT FeatureLength
Definition: hidpddi.h:26
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
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
USHORT InputLength
Definition: hidpddi.h:24
#define HIDCLASS_TAG
Definition: precomp.h:10
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
PDEVICE_OBJECT PhysicalDeviceObject
Definition: hidport.h:17
#define IOCTL_HID_GET_COLLECTION_DESCRIPTOR
Definition: hidclass.h:58
NTSTATUS NTAPI HidClass_PnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:1143
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2820
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS NTAPI HidClass_Power(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:1120
USHORT PreparsedDataLength
Definition: hidpddi.h:16
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define IOCTL_HID_WRITE_REPORT
Definition: hidport.h:87
_In_ ULONG BufferLength
Definition: usbdlib.h:225
HIDP_DEVICE_DESC DeviceDescription
Definition: precomp.h:44
#define HID_REVISION
Definition: hidclass.h:32
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
ULONG InputReportBufferLength
Definition: precomp.h:170
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PUCHAR reportBuffer
Definition: hidclass.h:151
NTSTATUS NTAPI HidClass_DeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:857
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define IoCompleteRequest
Definition: irp.c:1240
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
HID_DEVICE_EXTENSION HidDeviceExtension
Definition: precomp.h:29
HIDCLASS_COMMON_DEVICE_EXTENSION Common
Definition: precomp.h:58
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS HidClassPDO_PnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: pdo.c:379
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:636
PDEVICE_OBJECT NextDeviceObject
Definition: hidport.h:18
PVOID InputReportBuffer
Definition: precomp.h:165
#define IOCTL_HID_GET_FEATURE
Definition: hidclass.h:60
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
PHIDP_REPORT_IDS HidClassPDO_GetReportDescription(PHIDP_DEVICE_DESC DeviceDescription, ULONG CollectionNumber)
Definition: pdo.c:45
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define IOCTL_HID_GET_COLLECTION_INFORMATION
Definition: hidclass.h:59
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 IOCTL_HID_READ_REPORT
Definition: hidport.h:86
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static const WCHAR L[]
Definition: oid.c:1250
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1842
LIST_ENTRY IrpCompletedListHead
Definition: precomp.h:136
Definition: typedefs.h:117
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
static ULONG HidClassDeviceNumber
Definition: hidclass.c:17
PHIDCLASS_FILEOP_CONTEXT FileOp
Definition: precomp.h:160
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI HidRegisterMinidriver(IN PHID_MINIDRIVER_REGISTRATION MinidriverRegistration)
Definition: hidclass.c:1244
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
HIDCLASS_COMMON_DEVICE_EXTENSION Common
Definition: precomp.h:87
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
DRIVER_DISPATCH * PDRIVER_DISPATCH
Definition: iotypes.h:2154
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:626
struct _HID_COLLECTION_INFORMATION HID_COLLECTION_INFORMATION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
PIRP HidClass_GetIrp(IN PHIDCLASS_FILEOP_CONTEXT Context)
Definition: hidclass.c:496
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_DEVICE_UNKNOWN
Definition: winioctl.h:139
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IOCTL_HID_SET_FEATURE
Definition: hidclass.h:69
NTSTATUS NTAPI HidClassDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:1204
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 IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS HidClassFDO_PnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:631
NTSTATUS NTAPI HidClass_Close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: hidclass.c:216
#define OUT
Definition: typedefs.h:39
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PHIDP_REPORT_IDS HidClassPDO_GetReportDescriptionByReportID(PHIDP_DEVICE_DESC DeviceDescription, UCHAR ReportID)
Definition: pdo.c:71
struct tagContext Context
Definition: acpixf.h:1024
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
WCHAR * LPWSTR
Definition: xmlstorage.h:184
NTSTATUS NTAPI DllInitialize(IN PUNICODE_STRING RegistryPath)
Definition: hidclass.c:21
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:605
NTSTATUS HidClassFDO_DispatchRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: fdo.c:217
return STATUS_SUCCESS
Definition: btrfs.c:2966
IoMarkIrpPending(Irp)
signed int * PLONG
Definition: retypes.h:5
HRESULT Create([out]ITransactionReceiver **ppReceiver)
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
base of all file and directory entries
Definition: entries.h:82
VOID NTAPI HidClassDriverUnload(IN PDRIVER_OBJECT DriverObject)
Definition: hidclass.c:126
PHIDP_COLLECTION_DESC HidClassPDO_GetCollectionDescription(PHIDP_DEVICE_DESC DeviceDescription, ULONG CollectionNumber)
Definition: pdo.c:19
PHIDCLASS_DRIVER_EXTENSION DriverExtension
Definition: precomp.h:39
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
NTSTATUS NTAPI HidClass_ReadCompleteIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Ctx)
Definition: hidclass.c:351
NTSTATUS HidClass_BuildIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP RequestIrp, IN PHIDCLASS_FILEOP_CONTEXT Context, IN ULONG DeviceIoControlCode, IN ULONG BufferLength, OUT PIRP *OutIrp, OUT PHIDCLASS_IRP_CONTEXT *OutIrpContext)
Definition: hidclass.c:536