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