ReactOS 0.4.16-dev-340-g0540c21
parser.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS HID Parser Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/hidparser/parser.c
5 * PURPOSE: HID Parser
6 * PROGRAMMERS:
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
9 */
10
11#include "parser.h"
12
13#define NDEBUG
14#include <debug.h>
15
16static UCHAR ItemSize[4] = { 0, 1, 2, 4 };
17
18VOID
20 IN PHID_REPORT Report)
21{
22 //
23 // not implemented
24 //
25}
26
27VOID
30{
31 //
32 // not implemented
33 //
34}
35
38 IN PHID_COLLECTION ParentCollection,
40 IN PLOCAL_ITEM_STATE LocalItemState,
41 OUT PHID_COLLECTION * OutCollection)
42{
44 USAGE_VALUE UsageValue;
45
46 //
47 // first allocate the collection
48 //
50 if (!Collection)
51 {
52 //
53 // no memory
54 //
56 }
57
58 //
59 // init collection
60 //
61 Collection->Root = ParentCollection;
62 Collection->Type = Type;
63 Collection->StringID = LocalItemState->StringIndex;
64 Collection->PhysicalID = LocalItemState->DesignatorIndex;
65
66 //
67 // set Usage
68 //
69 ASSERT(LocalItemState);
70 ASSERT(LocalItemState->UsageStack);
71
72 if (LocalItemState->UsageStackUsed > 0)
73 {
74 //
75 // usage value from first local stack item
76 //
77 UsageValue.u.Extended = LocalItemState->UsageStack[0].u.Extended;
78 }
79 else if (LocalItemState->UsageMinimumSet)
80 {
81 //
82 // use value from minimum
83 //
84 UsageValue.u.Extended = LocalItemState->UsageMinimum.u.Extended;
85 }
86 else if (LocalItemState->UsageMaximumSet)
87 {
88 //
89 // use value from maximum
90 //
91 UsageValue.u.Extended = LocalItemState->UsageMaximum.u.Extended;
92 }
93 else if (Type == COLLECTION_LOGICAL)
94 {
95 //
96 // root collection
97 //
98 UsageValue.u.Extended = 0;
99 }
100 else
101 {
102 //
103 // no usage set
104 //
105 DebugFunction("HIDPARSE] No usage set\n");
106 UsageValue.u.Extended = 0;
107 }
108
109 //
110 // store usage
111 //
112 Collection->Usage = UsageValue.u.Extended;
113
114 //
115 // store result
116 //
117 *OutCollection = Collection;
118
119 //
120 // done
121 //
122 return HIDP_STATUS_SUCCESS;
123}
124
127 IN PHID_COLLECTION CurrentCollection,
128 IN PHID_COLLECTION NewCollection)
129{
130 PHID_COLLECTION * NewAllocCollection;
131 ULONG CollectionCount;
132
133 //
134 // increment collection array
135 //
136 CollectionCount = CurrentCollection->NodeCount + 1;
137
138 //
139 // allocate new collection
140 //
141 NewAllocCollection = (PHID_COLLECTION*)AllocFunction(sizeof(PHID_COLLECTION) * CollectionCount);
142 if (!NewAllocCollection)
143 {
144 //
145 // no memory
146 //
148 }
149
150 if (CurrentCollection->NodeCount)
151 {
152 //
153 // copy old array
154 //
155 CopyFunction(NewAllocCollection, CurrentCollection->Nodes, CurrentCollection->NodeCount * sizeof(PHID_COLLECTION));
156
157 //
158 // delete old array
159 //
160 FreeFunction(CurrentCollection->Nodes);
161 }
162
163 //
164 // insert new item
165 //
166 NewAllocCollection[CurrentCollection->NodeCount] = (struct __HID_COLLECTION__*)NewCollection;
167
168
169 //
170 // store new array
171 //
172 CurrentCollection->Nodes = NewAllocCollection;
173 CurrentCollection->NodeCount++;
174
175 //
176 // done
177 //
178 return HIDP_STATUS_SUCCESS;
179}
180
184 IN UCHAR ReportType,
186 OUT PHID_REPORT *OutReport)
187{
188 ULONG Index;
190
191 //
192 // search in local list
193 //
194 for(Index = 0; Index < Collection->ReportCount; Index++)
195 {
196 if (Collection->Reports[Index]->Type == ReportType && Collection->Reports[Index]->ReportID == ReportID)
197 {
198 //
199 // found report
200 //
201 *OutReport = Collection->Reports[Index];
202 return HIDP_STATUS_SUCCESS;
203 }
204 }
205
206 //
207 // search in sub collections
208 //
209 for(Index = 0; Index < Collection->NodeCount; Index++)
210 {
211 Status = HidParser_FindReportInCollection(Collection->Nodes[Index], ReportType, ReportID, OutReport);
213 return Status;
214 }
215
216 //
217 // no such report found
218 //
219 *OutReport = NULL;
221}
222
223
226 IN PHID_PARSER_CONTEXT ParserContext,
227 IN UCHAR ReportType,
229 OUT PHID_REPORT *OutReport)
230{
231 //
232 // search in current top level collection
233 //
234 return HidParser_FindReportInCollection(ParserContext->RootCollection->Nodes[ParserContext->RootCollection->NodeCount-1], ReportType, ReportID, OutReport);
235}
236
239 IN UCHAR ReportType,
241 OUT PHID_REPORT *OutReport)
242{
243 PHID_REPORT Report;
244
245 //
246 // allocate report
247 //
248 Report = (PHID_REPORT)AllocFunction(sizeof(HID_REPORT));
249 if (!Report)
250 {
251 //
252 // no memory
253 //
255 }
256
257 //
258 // init report
259 //
260 Report->ReportID = ReportID;
261 Report->Type = ReportType;
262
263 //
264 // done
265 //
266 *OutReport = Report;
267 return HIDP_STATUS_SUCCESS;
268}
269
272 IN PHID_PARSER_CONTEXT ParserContext,
273 IN PHID_COLLECTION CurrentCollection,
274 IN PHID_REPORT NewReport)
275{
276 PHID_REPORT * NewReportArray;
277
278 //
279 // allocate new report array
280 //
281 NewReportArray = (PHID_REPORT*)AllocFunction(sizeof(PHID_REPORT) * (CurrentCollection->ReportCount + 1));
282 if (!NewReportArray)
283 {
284 //
285 // no memory
286 //
288 }
289
290 if (CurrentCollection->ReportCount)
291 {
292 //
293 // copy old array contents
294 //
295 CopyFunction(NewReportArray, CurrentCollection->Reports, sizeof(PHID_REPORT) * CurrentCollection->ReportCount);
296
297 //
298 // free old array
299 //
300 FreeFunction(CurrentCollection->Reports);
301 }
302
303 //
304 // store result
305 //
306 NewReportArray[CurrentCollection->ReportCount] = NewReport;
307 CurrentCollection->Reports = NewReportArray;
308 CurrentCollection->ReportCount++;
309
310 //
311 // completed successfully
312 //
313 return HIDP_STATUS_SUCCESS;
314}
315
318 IN PHID_PARSER_CONTEXT ParserContext,
320 IN UCHAR ReportType,
322 IN UCHAR CreateIfNotExists,
323 OUT PHID_REPORT *OutReport)
324{
326
327 //
328 // try finding existing report
329 //
330 Status = HidParser_FindReport(ParserContext, ReportType, ReportID, OutReport);
331 if (Status == HIDP_STATUS_SUCCESS || CreateIfNotExists == FALSE)
332 {
333 //
334 // founed report
335 //
336 return Status;
337 }
338
339 //
340 // allocate new report
341 //
342 Status = HidParser_AllocateReport(ReportType, ReportID, OutReport);
344 {
345 //
346 // failed to allocate report
347 //
348 return Status;
349 }
350
351 //
352 // add report
353 //
354 Status = HidParser_AddReportToCollection(ParserContext, Collection, *OutReport);
356 {
357 //
358 // failed to allocate report
359 //
360 FreeFunction(*OutReport);
361 }
362
363 //
364 // done
365 //
366 return Status;
367}
368
371 IN PHID_REPORT Report,
373 OUT PHID_REPORT *OutReport)
374{
375 PHID_REPORT NewReport;
376 ULONG OldSize, Size;
377
378 if (Report->ItemCount + ReportCount <= Report->ItemAllocated)
379 {
380 //
381 // space is already allocated
382 //
383 *OutReport = Report;
384 return HIDP_STATUS_SUCCESS;
385 }
386
387 //
388 //calculate new size
389 //
390 OldSize = sizeof(HID_REPORT) + (Report->ItemCount) * sizeof(HID_REPORT_ITEM);
391 Size = ReportCount * sizeof(HID_REPORT_ITEM);
392
393 //
394 // allocate memory
395 //
396 NewReport = (PHID_REPORT)AllocFunction(Size + OldSize);
397 if (!NewReport)
398 {
399 //
400 // no memory
401 //
403 }
404
405
406 //
407 // copy old report
408 //
409 CopyFunction(NewReport, Report, OldSize);
410
411 //
412 // increase array size
413 //
414 NewReport->ItemAllocated += ReportCount;
415
416 //
417 // store result
418 //
419 *OutReport = NewReport;
420
421 //
422 // completed sucessfully
423 //
424 return HIDP_STATUS_SUCCESS;
425}
426
427VOID
429 IN ULONG Minimum,
430 IN ULONG Maximum,
431 OUT PULONG NewMinimum,
432 OUT PULONG NewMaximum)
433{
434 ULONG Mask = 0x80000000;
435 ULONG Index;
436
437 for (Index = 0; Index < 4; Index++)
438 {
439 if (Minimum & Mask)
440 {
441 Minimum |= Mask;
442 if (Maximum & Mask)
443 Maximum |= Mask;
444 return;
445 }
446
447 Mask >>= 8;
448 Mask |= 0xff000000;
449 }
450
451 *NewMinimum = Minimum;
452 *NewMaximum = Maximum;
453}
454
457 IN PHID_REPORT Report,
458 IN PHID_REPORT_ITEM ReportItem,
459 IN PGLOBAL_ITEM_STATE GlobalItemState,
460 IN PLOCAL_ITEM_STATE LocalItemState,
461 IN PMAIN_ITEM_DATA ItemData,
462 IN ULONG ReportItemIndex)
463{
464 ULONG LogicalMinimum;
465 ULONG LogicalMaximum;
466 ULONG PhysicalMinimum;
467 ULONG PhysicalMaximum;
468 ULONG UsageMinimum;
469 ULONG UsageMaximum;
470 USAGE_VALUE UsageValue;
471
472 //
473 // get logical bounds
474 //
475 LogicalMinimum = GlobalItemState->LogicalMinimum;
476 LogicalMaximum = GlobalItemState->LogicialMaximum;
477 if (LogicalMinimum > LogicalMaximum)
478 {
479 //
480 // make them signed
481 //
482 HidParser_SignRange(LogicalMinimum, LogicalMaximum, &LogicalMinimum, &LogicalMaximum);
483 }
484 //ASSERT(LogicalMinimum <= LogicalMaximum);
485
486 //
487 // get physical bounds
488 //
489 PhysicalMinimum = GlobalItemState->PhysicalMinimum;
490 PhysicalMaximum = GlobalItemState->PhysicalMaximum;
491 if (PhysicalMinimum > PhysicalMaximum)
492 {
493 //
494 // make them signed
495 //
496 HidParser_SignRange(PhysicalMinimum, PhysicalMaximum, &PhysicalMinimum, &PhysicalMaximum);
497 }
498 //ASSERT(PhysicalMinimum <= PhysicalMaximum);
499
500 //
501 // get usage bounds
502 //
503 UsageMinimum = 0;
504 UsageMaximum = 0;
505 if (ItemData->ArrayVariable == FALSE)
506 {
507 //
508 // get usage bounds
509 //
510 UsageMinimum = LocalItemState->UsageMinimum.u.Extended;
511 UsageMaximum = LocalItemState->UsageMaximum.u.Extended;
512 }
513 else
514 {
515 //
516 // get usage value from stack
517 //
518 if (ReportItemIndex < LocalItemState->UsageStackUsed)
519 {
520 //
521 // use stack item
522 //
523 UsageValue = LocalItemState->UsageStack[ReportItemIndex];
524 }
525 else
526 {
527 //
528 // get usage minimum from local state
529 //
530 UsageValue = LocalItemState->UsageMinimum;
531
532 //
533 // append item index
534 //
535 UsageValue.u.Extended += ReportItemIndex;
536
537 if (LocalItemState->UsageMaximumSet)
538 {
539 if (UsageValue.u.Extended > LocalItemState->UsageMaximum.u.Extended)
540 {
541 //
542 // maximum reached
543 //
544 UsageValue.u.Extended = LocalItemState->UsageMaximum.u.Extended;
545 }
546 }
547 }
548
549 //
550 // usage usage bounds
551 //
552 UsageMinimum = UsageMaximum = UsageValue.u.Extended;
553 }
554
555 //
556 // now store all values
557 //
558 ReportItem->ByteOffset = (Report->ReportSize / 8);
559 ReportItem->Shift = (Report->ReportSize % 8);
560 ReportItem->Mask = ~(0xFFFFFFFF << GlobalItemState->ReportSize);
561 ReportItem->BitCount = GlobalItemState->ReportSize;
562 ReportItem->HasData = (ItemData->DataConstant == FALSE);
563 ReportItem->Array = (ItemData->ArrayVariable == 0);
564 ReportItem->Relative = (ItemData->Relative != FALSE);
565 ReportItem->Minimum = LogicalMinimum;
566 ReportItem->Maximum = LogicalMaximum;
567 ReportItem->UsageMinimum = UsageMinimum;
568 ReportItem->UsageMaximum = UsageMaximum;
569
570 //
571 // increment report size
572 //
573 Report->ReportSize += GlobalItemState->ReportSize;
574
575 //
576 // completed successfully
577 //
578 return HIDP_STATUS_SUCCESS;
579}
580
584 IN PHID_REPORT Report,
585 IN PHID_REPORT NewReport)
586{
587 ULONG Index;
588 BOOLEAN Found = FALSE, TempFound;
589
590 //
591 // search in local list
592 //
593 for(Index = 0; Index < Collection->ReportCount; Index++)
594 {
595 if (Collection->Reports[Index] == Report)
596 {
597 //
598 // update report
599 //
600 Collection->Reports[Index] = NewReport;
601 Found = TRUE;
602 }
603 }
604
605 //
606 // search in sub collections
607 //
608 for(Index = 0; Index < Collection->NodeCount; Index++)
609 {
610 //
611 // was it found
612 //
613 TempFound = HidParser_UpdateCurrentCollectionReport(Collection->Nodes[Index], Report, NewReport);
614 if (TempFound)
615 {
616 //
617 // the same report should not be found in different collections
618 //
619 ASSERT(Found == FALSE);
620 Found = TRUE;
621 }
622 }
623
624 //
625 // done
626 //
627 return Found;
628}
629
632 IN PHID_PARSER_CONTEXT ParserContext,
633 IN PHID_REPORT Report,
634 IN PHID_REPORT NewReport)
635{
636 //
637 // update in current collection
638 //
639 return HidParser_UpdateCurrentCollectionReport(ParserContext->RootCollection->Nodes[ParserContext->RootCollection->NodeCount-1], Report, NewReport);
640}
641
642
645 IN PHID_PARSER_CONTEXT ParserContext,
646 IN PHID_REPORT Report,
647 IN PGLOBAL_ITEM_STATE GlobalItemState,
648 IN PLOCAL_ITEM_STATE LocalItemState,
649 IN PMAIN_ITEM_DATA ItemData,
651{
653 ULONG Index;
654 PHID_REPORT NewReport;
656
657 //
658 // first grow report item array
659 //
660 Status = HidParser_ReserveReportItems(Report, GlobalItemState->ReportCount, &NewReport);
662 {
663 //
664 // failed to allocate memory
665 //
666 return Status;
667 }
668
669 if (NewReport != Report)
670 {
671 //
672 // update current top level collection
673 //
674 Found = HidParser_UpdateCollectionReport(ParserContext, Report, NewReport);
675 ASSERT(Found);
676 }
677
678 //
679 // sanity check
680 //
681 ASSERT(NewReport->ItemCount + GlobalItemState->ReportCount <= NewReport->ItemAllocated);
682
683 for(Index = 0; Index < GlobalItemState->ReportCount; Index++)
684 {
685 Status = HidParser_InitReportItem(NewReport, &NewReport->Items[NewReport->ItemCount], GlobalItemState, LocalItemState, ItemData, Index);
687 {
688 //
689 // failed to init report item
690 //
691 return Status;
692 }
693
694 //
695 // increment report item count
696 //
697 NewReport->ItemCount++;
698 }
699
700 //
701 // done
702 //
703 return HIDP_STATUS_SUCCESS;
704}
705
708 IN PUCHAR ReportDescriptor,
710 OUT PVOID *OutParser)
711{
712 PGLOBAL_ITEM_STATE LinkedGlobalItemState, NextLinkedGlobalItemState;
713 ULONG Index;
714 PUSAGE_VALUE NewUsageStack, UsageValue;
716 PHID_COLLECTION CurrentCollection, NewCollection;
717 PUCHAR CurrentOffset, ReportEnd;
718 PITEM_PREFIX CurrentItem;
719 ULONG CurrentItemSize;
720 PLONG_ITEM CurrentLongItem;
721 PSHORT_ITEM CurrentShortItem;
722 ULONG Data;
723 UCHAR ReportType;
724 PHID_REPORT Report;
725 PMAIN_ITEM_DATA MainItemData;
726 PHID_PARSER_CONTEXT ParserContext;
727
728 CurrentOffset = ReportDescriptor;
729 ReportEnd = ReportDescriptor + ReportLength;
730
731 if (ReportDescriptor >= ReportEnd)
733
734 //
735 // allocate parser
736 //
737 ParserContext = AllocFunction(sizeof(HID_PARSER_CONTEXT));
738 if (!ParserContext)
740
741
742 //
743 // allocate usage stack
744 //
745 ParserContext->LocalItemState.UsageStackAllocated = 10;
747 if (!ParserContext->LocalItemState.UsageStack)
748 {
749 //
750 // no memory
751 //
752 FreeFunction(ParserContext);
754 }
755
756 //
757 // now allocate root collection
758 //
761 {
762 //
763 // no memory
764 //
765 FreeFunction(ParserContext->LocalItemState.UsageStack);
766 ParserContext->LocalItemState.UsageStack = NULL;
767 FreeFunction(ParserContext);
769 }
770
771 //
772 // start parsing
773 //
774 CurrentCollection = ParserContext->RootCollection;
775
776 do
777 {
778 //
779 // get current item
780 //
781 CurrentItem = (PITEM_PREFIX)CurrentOffset;
782
783 //
784 // get item size
785 //
786 CurrentItemSize = ItemSize[CurrentItem->Size];
787 Data = 0;
788
789 if (CurrentItem->Type == ITEM_TYPE_LONG)
790 {
791 //
792 // increment item size with size of data item
793 //
794 CurrentLongItem = (PLONG_ITEM)CurrentItem;
795 CurrentItemSize += CurrentLongItem->DataSize;
796 }
797 else
798 {
799 //
800 // get short item
801 //
802 CurrentShortItem = (PSHORT_ITEM)CurrentItem;
803
804 //
805 // get associated data
806 //
807 //ASSERT(CurrentItemSize == 1 || CurrentItemSize == 2 || CurrentItemSize == 4);
808 if (CurrentItemSize == 1)
809 Data = CurrentShortItem->Data.UData8[0];
810 else if (CurrentItemSize == 2)
811 Data = CurrentShortItem->Data.UData16[0];
812 else if (CurrentItemSize == 4)
813 Data = CurrentShortItem->Data.UData32;
814 else
815 {
816 //
817 // invalid item size
818 //
819 //DebugFunction("CurrentItem invalid item size %lu\n", CurrentItemSize);
820 }
821
822 }
823 DebugFunction("Tag %x Type %x Size %x Offset %lu Length %lu\n", CurrentItem->Tag, CurrentItem->Type, CurrentItem->Size, ((ULONG_PTR)CurrentItem - (ULONG_PTR)ReportDescriptor), ReportLength);
824 //
825 // handle items
826 //
827 ASSERT(CurrentItem->Type >= ITEM_TYPE_MAIN && CurrentItem->Type <= ITEM_TYPE_LONG);
828 switch(CurrentItem->Type)
829 {
830 case ITEM_TYPE_MAIN:
831 {
832 // preprocess the local state if relevant (usages for
833 // collections and report items)
834 if (CurrentItem->Tag != ITEM_TAG_MAIN_END_COLLECTION)
835 {
836 // make all usages extended for easier later processing
837 for (Index = 0; Index < ParserContext->LocalItemState.UsageStackUsed; Index++)
838 {
839 //
840 // is it already extended
841 //
842 if (ParserContext->LocalItemState.UsageStack[Index].IsExtended)
843 continue;
844
845 //
846 // extend usage item
847 //
848 ParserContext->LocalItemState.UsageStack[Index].u.s.UsagePage = ParserContext->GlobalItemState.UsagePage;
850 }
851
852 if (!ParserContext->LocalItemState.UsageMinimum.IsExtended) {
853 // the specs say if one of them is extended they must
854 // both be extended, so if the minimum isn't, the
855 // maximum mustn't either.
856 ParserContext->LocalItemState.UsageMinimum.u.s.UsagePage
857 = ParserContext->LocalItemState.UsageMaximum.u.s.UsagePage
858 = ParserContext->GlobalItemState.UsagePage;
860 = ParserContext->LocalItemState.UsageMaximum.IsExtended = TRUE;
861 }
862
863 //LocalItemState.usage_stack = usageStack;
864 //ParserContext->LocalItemState.UsageStackUsed = UsageStackUsed;
865 }
866
867 if (CurrentItem->Tag == ITEM_TAG_MAIN_COLLECTION) {
868
869 //
870 // allocate new collection
871 //
872 Status = HidParser_AllocateCollection(CurrentCollection, (UCHAR)Data, &ParserContext->LocalItemState, &NewCollection);
874
875 //
876 // add new collection to current collection
877 //
878 Status = HidParser_AddCollection(CurrentCollection, NewCollection);
880
881 //
882 // make new collection current
883 //
884 CurrentCollection = NewCollection;
885 }
886 else if (CurrentItem->Tag == ITEM_TAG_MAIN_END_COLLECTION)
887 {
888 //
889 // assert on ending the root collection
890 //
891 ASSERT(CurrentCollection != ParserContext->RootCollection);
892
893 //
894 // use parent of current collection
895 //
896 CurrentCollection = CurrentCollection->Root;
897 ASSERT(CurrentCollection);
898 }
899 else
900 {
901 ReportType = HID_REPORT_TYPE_ANY;
902
903 switch (CurrentItem->Tag) {
905 ReportType = HID_REPORT_TYPE_INPUT;
906 break;
907
909 ReportType = HID_REPORT_TYPE_OUTPUT;
910 break;
911
913 ReportType = HID_REPORT_TYPE_FEATURE;
914 break;
915
916 default:
917 DebugFunction("[HIDPARSE] Unknown ReportType Tag %x Type %x Size %x CurrentItemSize %x\n", CurrentItem->Tag, CurrentItem->Type, CurrentItem->Size, CurrentItemSize);
918 ASSERT(FALSE);
919 break;
920 }
921
922 if (ReportType == HID_REPORT_TYPE_ANY)
923 break;
924
925 //
926 // get report
927 //
928 Status = HidParser_GetReport(ParserContext, CurrentCollection, ReportType, ParserContext->GlobalItemState.ReportId, TRUE, &Report);
930
931 // fill in a sensible default if the index isn't set
932 if (!ParserContext->LocalItemState.DesignatorIndexSet) {
933 ParserContext->LocalItemState.DesignatorIndex
934 = ParserContext->LocalItemState.DesignatorMinimum;
935 }
936
937 if (!ParserContext->LocalItemState.StringIndexSet)
938 ParserContext->LocalItemState.StringIndex = ParserContext->LocalItemState.StringMinimum;
939
940 //
941 // get main item data
942 //
943 MainItemData = (PMAIN_ITEM_DATA)&Data;
944
945 //
946 // add states & data to the report
947 //
948 Status = HidParser_AddMainItem(ParserContext, Report, &ParserContext->GlobalItemState, &ParserContext->LocalItemState, MainItemData, CurrentCollection);
950 }
951
952 //
953 // backup stack
954 //
956 NewUsageStack = ParserContext->LocalItemState.UsageStack;
957
958 //
959 // reset the local item state and clear the usage stack
960 //
961 ZeroFunction(&ParserContext->LocalItemState, sizeof(LOCAL_ITEM_STATE));
962
963 //
964 // restore stack
965 //
966 ParserContext->LocalItemState.UsageStack = NewUsageStack;
968 break;
969 }
970 case ITEM_TYPE_GLOBAL:
971 {
972 switch (CurrentItem->Tag) {
974 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_USAGE_PAGE %x\n", Data);
975 ParserContext->GlobalItemState.UsagePage = Data;
976 break;
978 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_LOGICAL_MINIMUM %x\n", Data);
979 ParserContext->GlobalItemState.LogicalMinimum = Data;
980 break;
981
983 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_LOCAL_MAXIMUM %x\n", Data);
984 ParserContext->GlobalItemState.LogicialMaximum = Data;
985 break;
986
988 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_PHYSICAL_MINIMUM %x\n", Data);
989 ParserContext->GlobalItemState.PhysicalMinimum = Data;
990 break;
991
993 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_PHYSICAL_MAXIMUM %x\n", Data);
994 ParserContext->GlobalItemState.PhysicalMaximum = Data;
995 break;
996
998 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_REPORT_UNIT_EXPONENT %x\n", Data);
999 ParserContext->GlobalItemState.UnitExponent = Data;
1000 break;
1001
1003 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_REPORT_UNIT %x\n", Data);
1004 ParserContext->GlobalItemState.Unit = Data;
1005 break;
1006
1008 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_REPORT_SIZE %x\n", Data);
1009 ParserContext->GlobalItemState.ReportSize = Data;
1010 break;
1011
1013 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_REPORT_ID %x\n", Data);
1014 ParserContext->GlobalItemState.ReportId = Data;
1015 ParserContext->UseReportIDs = TRUE;
1016 break;
1017
1019 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_REPORT_COUNT %x\n", Data);
1020 ParserContext->GlobalItemState.ReportCount = Data;
1021 break;
1022
1024 {
1025 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_PUSH\n");
1026 //
1027 // allocate global item state
1028 //
1029 LinkedGlobalItemState = (PGLOBAL_ITEM_STATE)AllocFunction(sizeof(GLOBAL_ITEM_STATE));
1030 ASSERT(LinkedGlobalItemState);
1031
1032 //
1033 // copy global item state
1034 //
1035 CopyFunction(LinkedGlobalItemState, &ParserContext->GlobalItemState, sizeof(GLOBAL_ITEM_STATE));
1036
1037 //
1038 // store pushed item in link member
1039 //
1040 ParserContext->GlobalItemState.Next = (struct __GLOBAL_ITEM_STATE__*)LinkedGlobalItemState;
1041 break;
1042 }
1044 {
1045 DebugFunction("[HIDPARSE] ITEM_TAG_GLOBAL_POP\n");
1046 if (ParserContext->GlobalItemState.Next == NULL)
1047 {
1048 //
1049 // pop without push
1050 //
1051 ASSERT(FALSE);
1052 break;
1053 }
1054
1055 //
1056 // get link
1057 //
1058 LinkedGlobalItemState = (PGLOBAL_ITEM_STATE)ParserContext->GlobalItemState.Next;
1059
1060 //
1061 // replace current item with linked one
1062 //
1063 CopyFunction(&ParserContext->GlobalItemState, LinkedGlobalItemState, sizeof(GLOBAL_ITEM_STATE));
1064
1065 //
1066 // free item
1067 //
1068 FreeFunction(LinkedGlobalItemState);
1069 break;
1070 }
1071
1072 default:
1073 //
1074 // unknown / unsupported tag
1075 //
1076 ASSERT(FALSE);
1077 break;
1078 }
1079
1080 break;
1081 }
1082 case ITEM_TYPE_LOCAL:
1083 {
1084 switch (CurrentItem->Tag)
1085 {
1087 {
1088 if (ParserContext->LocalItemState.UsageStackUsed >= ParserContext->LocalItemState.UsageStackAllocated)
1089 {
1090 //
1091 // increment stack size
1092 //
1093 ParserContext->LocalItemState.UsageStackAllocated += 10;
1094
1095 //
1096 // build new usage stack
1097 //
1098 NewUsageStack = (PUSAGE_VALUE)AllocFunction(sizeof(USAGE_VALUE) * ParserContext->LocalItemState.UsageStackAllocated);
1099 ASSERT(NewUsageStack);
1100
1101 //
1102 // copy old usage stack
1103 //
1104 CopyFunction(NewUsageStack, ParserContext->LocalItemState.UsageStack, sizeof(USAGE_VALUE) * (ParserContext->LocalItemState.UsageStackAllocated - 10));
1105
1106 //
1107 // free old usage stack
1108 //
1109 FreeFunction(ParserContext->LocalItemState.UsageStack);
1110
1111 //
1112 // replace with new usage stack
1113 //
1114 ParserContext->LocalItemState.UsageStack = NewUsageStack;
1115 }
1116
1117 //
1118 // get fresh usage value
1119 //
1120 UsageValue = &ParserContext->LocalItemState.UsageStack[ParserContext->LocalItemState.UsageStackUsed];
1121
1122 //
1123 // init usage stack
1124 //
1125 UsageValue->IsExtended = CurrentItemSize == sizeof(ULONG);
1126 UsageValue->u.Extended = Data;
1127
1128 //
1129 // increment usage stack usage count
1130 //
1131 ParserContext->LocalItemState.UsageStackUsed++;
1132 break;
1133 }
1134
1136 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_USAGE_MINIMUM Data %x\n", Data);
1137 ParserContext->LocalItemState.UsageMinimum.u.Extended = Data;
1139 = CurrentItemSize == sizeof(ULONG);
1140 ParserContext->LocalItemState.UsageMinimumSet = TRUE;
1141 break;
1142
1144 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_USAGE_MAXIMUM Data %x ItemSize %x %x\n", Data, CurrentItemSize, CurrentItem->Size);
1145 ParserContext->LocalItemState.UsageMaximum.u.Extended = Data;
1147 = CurrentItemSize == sizeof(ULONG);
1148 ParserContext->LocalItemState.UsageMaximumSet = TRUE;
1149 break;
1150
1152 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_DESIGNATOR_INDEX Data %x\n", Data);
1153 ParserContext->LocalItemState.DesignatorIndex = Data;
1154 ParserContext->LocalItemState.DesignatorIndexSet = TRUE;
1155 break;
1156
1158 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_DESIGNATOR_MINIMUM Data %x\n", Data);
1159 ParserContext->LocalItemState.DesignatorMinimum = Data;
1160 break;
1161
1163 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_DESIGNATOR_MAXIMUM Data %x\n", Data);
1164 ParserContext->LocalItemState.DesignatorMaximum = Data;
1165 break;
1166
1168 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_STRING_INDEX Data %x\n", Data);
1169 ParserContext->LocalItemState.StringIndex = Data;
1170 ParserContext->LocalItemState.StringIndexSet = TRUE;
1171 break;
1172
1174 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_STRING_MINIMUM Data %x\n", Data);
1175 ParserContext->LocalItemState.StringMinimum = Data;
1176 break;
1177
1179 DebugFunction("[HIDPARSE] ITEM_TAG_LOCAL_STRING_MAXIMUM Data %x\n", Data);
1180 ParserContext->LocalItemState.StringMaximum = Data;
1181 break;
1182
1183 default:
1184 DebugFunction("Unknown Local Item Tag %x\n", CurrentItem->Tag);
1185 ASSERT(FALSE);
1186 break;
1187 }
1188 break;
1189 }
1190
1191 case ITEM_TYPE_LONG:
1192 {
1193 CurrentLongItem = (PLONG_ITEM)CurrentItem;
1194 DebugFunction("Unsupported ITEM_TYPE_LONG Tag %x\n", CurrentLongItem->LongItemTag);
1195 break;
1196 }
1197 }
1198
1199 //
1200 // move to next item
1201 //
1202 CurrentOffset += CurrentItemSize + sizeof(ITEM_PREFIX);
1203
1204 }while (CurrentOffset < ReportEnd);
1205
1206
1207 //
1208 // cleanup global stack
1209 //
1210 LinkedGlobalItemState = (PGLOBAL_ITEM_STATE)ParserContext->GlobalItemState.Next;
1211 while(LinkedGlobalItemState != NULL)
1212 {
1213 DebugFunction("[HIDPARSE] Freeing GlobalState %p\n", LinkedGlobalItemState);
1214 //
1215 // free global item state
1216 //
1217 NextLinkedGlobalItemState = (PGLOBAL_ITEM_STATE)LinkedGlobalItemState->Next;
1218
1219 //
1220 // free state
1221 //
1222 FreeFunction(LinkedGlobalItemState);
1223
1224 //
1225 // move to next global state
1226 //
1227 LinkedGlobalItemState = NextLinkedGlobalItemState;
1228 }
1229
1230 //
1231 // free usage stack
1232 //
1233 FreeFunction(ParserContext->LocalItemState.UsageStack);
1234 ParserContext->LocalItemState.UsageStack = NULL;
1235
1236 //
1237 // store result
1238 //
1239 *OutParser = ParserContext;
1240
1241 //
1242 // done
1243 //
1244 return HIDP_STATUS_SUCCESS;
1245}
1246
1249 PHID_PARSER_CONTEXT ParserContext,
1250 IN ULONG CollectionNumber)
1251{
1252 //
1253 // sanity checks
1254 //
1255 ASSERT(ParserContext);
1256 ASSERT(ParserContext->RootCollection);
1257 ASSERT(ParserContext->RootCollection->NodeCount);
1258
1259 //
1260 // is collection index out of bounds
1261 //
1262 if (CollectionNumber < ParserContext->RootCollection->NodeCount)
1263 {
1264 //
1265 // valid collection
1266 //
1267 return ParserContext->RootCollection->Nodes[CollectionNumber];
1268 }
1269
1270 //
1271 // no such collection
1272 //
1273 DebugFunction("HIDPARSE] No such collection %lu\n", CollectionNumber);
1274 return NULL;
1275}
1276
1277
1278ULONG
1280 IN PVOID ParserCtx)
1281{
1282 PHID_PARSER_CONTEXT ParserContext;
1283
1284 //
1285 // get parser context
1286 //
1287 ParserContext = (PHID_PARSER_CONTEXT)ParserCtx;
1288
1289 //
1290 // sanity checks
1291 //
1292 ASSERT(ParserContext);
1293 ASSERT(ParserContext->RootCollection);
1294 ASSERT(ParserContext->RootCollection->NodeCount);
1295
1296 //
1297 // number of top collections
1298 //
1299 return ParserContext->RootCollection->NodeCount;
1300}
1301
1304 IN PVOID ParserContext,
1305 IN ULONG CollectionIndex,
1307 OUT PVOID *CollectionContext)
1308{
1310 PVOID Context;
1312
1313 //
1314 // lets get the collection
1315 //
1316 Collection = HidParser_GetCollection((PHID_PARSER_CONTEXT)ParserContext, CollectionIndex);
1318
1319 //
1320 // lets allocate the context
1321 //
1323 if (Context == NULL)
1324 {
1325 //
1326 // no memory
1327 //
1329 }
1330
1331 //
1332 // lets build the context
1333 //
1336 {
1337 //
1338 // store context
1339 //
1340 *CollectionContext = Context;
1341 }
1342
1343 //
1344 // done
1345 //
1346 return Status;
1347}
1348
1349
1350ULONG
1352 IN PVOID ParserContext,
1353 IN ULONG CollectionIndex)
1354{
1356 ULONG Size;
1357
1358 //
1359 // lets get the collection
1360 //
1361 Collection = HidParser_GetCollection((PHID_PARSER_CONTEXT)ParserContext, CollectionIndex);
1362
1363 //
1364 // calculate size
1365 //
1367 return Size;
1368}
1369
unsigned char BOOLEAN
Type
Definition: Type.h:7
LONG NTSTATUS
Definition: precomp.h:26
return Found
Definition: dirsup.c:1270
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
unsigned int Mask
Definition: fpcontrol.c:82
Status
Definition: gdiplustypes.h:25
VOID NTAPI ZeroFunction(IN PVOID Item, IN ULONG ItemSize)
Definition: hid.c:61
VOID __cdecl DebugFunction(IN LPCSTR FormatStr,...)
Definition: hid.c:80
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248
_Must_inspect_result_ _In_ UCHAR ReportID
Definition: hidpi.h:482
#define HIDP_STATUS_REPORT_DOES_NOT_EXIST
Definition: hidpi.h:265
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG _In_ PHIDP_PREPARSED_DATA _In_ ULONG ReportLength
Definition: hidpi.h:337
#define HIDP_STATUS_USAGE_NOT_FOUND
Definition: hidpi.h:253
#define ASSERT(a)
Definition: mode.c:44
ULONG HidParser_CalculateContextSize(IN PHID_COLLECTION Collection)
Definition: context.c:65
NTSTATUS HidParser_BuildCollectionContext(IN PHID_COLLECTION RootCollection, IN PVOID Context, IN ULONG ContextSize)
Definition: context.c:185
NTSTATUS HidParser_AddReportToCollection(IN PHID_PARSER_CONTEXT ParserContext, IN PHID_COLLECTION CurrentCollection, IN PHID_REPORT NewReport)
Definition: parser.c:271
ULONG HidParser_GetContextSize(IN PVOID ParserContext, IN ULONG CollectionIndex)
Definition: parser.c:1351
BOOLEAN HidParser_UpdateCurrentCollectionReport(IN PHID_COLLECTION Collection, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
Definition: parser.c:582
NTSTATUS HidParser_FindReport(IN PHID_PARSER_CONTEXT ParserContext, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:225
NTSTATUS HidParser_AllocateCollection(IN PHID_COLLECTION ParentCollection, IN UCHAR Type, IN PLOCAL_ITEM_STATE LocalItemState, OUT PHID_COLLECTION *OutCollection)
Definition: parser.c:37
VOID HidParser_SignRange(IN ULONG Minimum, IN ULONG Maximum, OUT PULONG NewMinimum, OUT PULONG NewMaximum)
Definition: parser.c:428
NTSTATUS HidParser_FindReportInCollection(IN PHID_COLLECTION Collection, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:182
NTSTATUS HidParser_AddMainItem(IN PHID_PARSER_CONTEXT ParserContext, IN PHID_REPORT Report, IN PGLOBAL_ITEM_STATE GlobalItemState, IN PLOCAL_ITEM_STATE LocalItemState, IN PMAIN_ITEM_DATA ItemData, IN PHID_COLLECTION Collection)
Definition: parser.c:644
BOOLEAN HidParser_UpdateCollectionReport(IN PHID_PARSER_CONTEXT ParserContext, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
Definition: parser.c:631
static UCHAR ItemSize[4]
Definition: parser.c:16
NTSTATUS HidParser_BuildContext(IN PVOID ParserContext, IN ULONG CollectionIndex, IN ULONG ContextSize, OUT PVOID *CollectionContext)
Definition: parser.c:1303
NTSTATUS HidParser_AddCollection(IN PHID_COLLECTION CurrentCollection, IN PHID_COLLECTION NewCollection)
Definition: parser.c:126
VOID HidParser_FreeCollection(IN PHID_COLLECTION Collection)
Definition: parser.c:28
NTSTATUS HidParser_GetReport(IN PHID_PARSER_CONTEXT ParserContext, IN PHID_COLLECTION Collection, IN UCHAR ReportType, IN UCHAR ReportID, IN UCHAR CreateIfNotExists, OUT PHID_REPORT *OutReport)
Definition: parser.c:317
NTSTATUS HidParser_ReserveReportItems(IN PHID_REPORT Report, IN ULONG ReportCount, OUT PHID_REPORT *OutReport)
Definition: parser.c:370
NTSTATUS HidParser_ParseReportDescriptor(IN PUCHAR ReportDescriptor, IN ULONG ReportLength, OUT PVOID *OutParser)
Definition: parser.c:707
VOID HidParser_DeleteReport(IN PHID_REPORT Report)
Definition: parser.c:19
NTSTATUS HidParser_InitReportItem(IN PHID_REPORT Report, IN PHID_REPORT_ITEM ReportItem, IN PGLOBAL_ITEM_STATE GlobalItemState, IN PLOCAL_ITEM_STATE LocalItemState, IN PMAIN_ITEM_DATA ItemData, IN ULONG ReportItemIndex)
Definition: parser.c:456
PHID_COLLECTION HidParser_GetCollection(PHID_PARSER_CONTEXT ParserContext, IN ULONG CollectionNumber)
Definition: parser.c:1248
ULONG HidParser_NumberOfTopCollections(IN PVOID ParserCtx)
Definition: parser.c:1279
NTSTATUS HidParser_AllocateReport(IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:238
#define ITEM_TAG_GLOBAL_PUSH
Definition: parser.h:41
struct __GLOBAL_ITEM_STATE_ * PGLOBAL_ITEM_STATE
struct ITEM_PREFIX * PITEM_PREFIX
#define COLLECTION_LOGICAL
Definition: parser.h:59
#define ITEM_TYPE_LONG
Definition: parser.h:23
#define ITEM_TAG_MAIN_COLLECTION
Definition: parser.h:28
#define ITEM_TAG_GLOBAL_UNIT
Definition: parser.h:37
struct _HID_REPORT * PHID_REPORT
#define ITEM_TAG_GLOBAL_USAGE_PAGE
Definition: parser.h:31
#define ITEM_TAG_GLOBAL_LOGICAL_MAXIMUM
Definition: parser.h:33
#define ITEM_TAG_GLOBAL_POP
Definition: parser.h:42
struct usage_value * PUSAGE_VALUE
#define ITEM_TAG_LOCAL_DESIGNATOR_MAXIMUM
Definition: parser.h:49
struct _HID_REPORT HID_REPORT
struct __HID_COLLECTION__ * PHID_COLLECTION
#define HID_REPORT_TYPE_ANY
Definition: parser.h:17
#define ITEM_TYPE_LOCAL
Definition: parser.h:22
#define ITEM_TAG_GLOBAL_REPORT_COUNT
Definition: parser.h:40
struct MAIN_ITEM_DATA * PMAIN_ITEM_DATA
#define ITEM_TAG_LOCAL_USAGE
Definition: parser.h:44
#define ITEM_TAG_GLOBAL_REPORT_ID
Definition: parser.h:39
#define ITEM_TAG_GLOBAL_UNIT_EXPONENT
Definition: parser.h:36
#define ITEM_TAG_LOCAL_STRING_MINIMUM
Definition: parser.h:51
#define ITEM_TAG_GLOBAL_PHYSICAL_MINIMUM
Definition: parser.h:34
#define ITEM_TAG_LOCAL_STRING_MAXIMUM
Definition: parser.h:52
#define ITEM_TAG_GLOBAL_PHYSICAL_MAXIMUM
Definition: parser.h:35
#define ITEM_TAG_MAIN_END_COLLECTION
Definition: parser.h:29
#define ITEM_TAG_LOCAL_DESIGNATOR_MINIMUM
Definition: parser.h:48
#define ITEM_TAG_LOCAL_USAGE_MINIMUM
Definition: parser.h:45
#define ITEM_TAG_LOCAL_USAGE_MAXIMUM
Definition: parser.h:46
#define ITEM_TAG_LOCAL_STRING_INDEX
Definition: parser.h:50
struct LONG_ITEM * PLONG_ITEM
#define ITEM_TYPE_GLOBAL
Definition: parser.h:21
#define ITEM_TAG_GLOBAL_LOGICAL_MINIMUM
Definition: parser.h:32
#define ITEM_TAG_GLOBAL_REPORT_SIZE
Definition: parser.h:38
struct HID_PARSER_CONTEXT * PHID_PARSER_CONTEXT
#define ITEM_TAG_MAIN_INPUT
Definition: parser.h:25
struct SHORT_ITEM * PSHORT_ITEM
#define ITEM_TAG_LOCAL_DESIGNATOR_INDEX
Definition: parser.h:47
#define ITEM_TAG_MAIN_OUTPUT
Definition: parser.h:26
#define ITEM_TYPE_MAIN
Definition: parser.h:20
#define ITEM_TAG_MAIN_FEATURE
Definition: parser.h:27
LOCAL_ITEM_STATE LocalItemState
Definition: parser.h:242
GLOBAL_ITEM_STATE GlobalItemState
Definition: parser.h:237
PHID_COLLECTION RootCollection
Definition: parser.h:247
UCHAR UseReportIDs
Definition: parser.h:252
UCHAR Tag
Definition: parser.h:83
UCHAR Type
Definition: parser.h:82
UCHAR Size
Definition: parser.h:81
UCHAR StringMinimum
Definition: parser.h:181
UCHAR UsageMaximumSet
Definition: parser.h:171
ULONG DesignatorMinimum
Definition: parser.h:176
ULONG UsageStackUsed
Definition: parser.h:164
USAGE_VALUE UsageMaximum
Definition: parser.h:168
UCHAR StringIndexSet
Definition: parser.h:180
UCHAR DesignatorIndexSet
Definition: parser.h:174
UCHAR StringMaximum
Definition: parser.h:182
USAGE_VALUE UsageMinimum
Definition: parser.h:167
ULONG DesignatorMaximum
Definition: parser.h:177
ULONG DesignatorIndex
Definition: parser.h:173
UCHAR UsageMinimumSet
Definition: parser.h:170
PUSAGE_VALUE UsageStack
Definition: parser.h:163
ULONG UsageStackAllocated
Definition: parser.h:165
UCHAR StringIndex
Definition: parser.h:179
UCHAR DataSize
Definition: parser.h:107
UCHAR LongItemTag
Definition: parser.h:108
UCHAR UData8[4]
Definition: parser.h:93
USHORT UData16[2]
Definition: parser.h:95
ULONG UData32
Definition: parser.h:97
union SHORT_ITEM::@4332 Data
UCHAR ReportID
Definition: parser.h:225
UCHAR Type
Definition: parser.h:224
HID_REPORT_ITEM Items[1]
Definition: parser.h:229
ULONG ItemAllocated
Definition: parser.h:228
ULONG ItemCount
Definition: parser.h:227
ULONG LogicialMaximum
Definition: parser.h:134
struct __GLOBAL_ITEM_STATE__ * Next
Definition: parser.h:142
ULONG LogicalMinimum
Definition: parser.h:133
ULONG PhysicalMinimum
Definition: parser.h:135
ULONG PhysicalMaximum
Definition: parser.h:136
ULONG ReportCount
Definition: parser.h:211
struct __HID_COLLECTION__ * Root
Definition: parser.h:215
struct __HID_COLLECTION__ ** Nodes
Definition: parser.h:214
UCHAR IsExtended
Definition: parser.h:157
struct usage_value::@4333::@4334 s
ULONG Extended
Definition: parser.h:154
union usage_value::@4333 u
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define HID_REPORT_TYPE_INPUT
#define HID_REPORT_TYPE_FEATURE
#define HID_REPORT_TYPE_OUTPUT
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCOLLECTION * Collection
Definition: wdfcollection.h:67
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ WDFCOLLECTION Collection
Definition: wdfregistry.h:374
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
Definition: mmfuncs.h:775
unsigned char UCHAR
Definition: xmlstorage.h:181