ReactOS  0.4.15-dev-506-ga3ec01c
parser.c File Reference
#include "parser.h"
#include <debug.h>
Include dependency graph for parser.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID HidParser_DeleteReport (IN PHID_REPORT Report)
 
VOID HidParser_FreeCollection (IN PHID_COLLECTION Collection)
 
NTSTATUS HidParser_AllocateCollection (IN PHID_COLLECTION ParentCollection, IN UCHAR Type, IN PLOCAL_ITEM_STATE LocalItemState, OUT PHID_COLLECTION *OutCollection)
 
NTSTATUS HidParser_AddCollection (IN PHID_COLLECTION CurrentCollection, IN PHID_COLLECTION NewCollection)
 
NTSTATUS HidParser_FindReportInCollection (IN PHID_COLLECTION Collection, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
 
NTSTATUS HidParser_FindReport (IN PHID_PARSER_CONTEXT ParserContext, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
 
NTSTATUS HidParser_AllocateReport (IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
 
NTSTATUS HidParser_AddReportToCollection (IN PHID_PARSER_CONTEXT ParserContext, IN PHID_COLLECTION CurrentCollection, IN PHID_REPORT NewReport)
 
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)
 
NTSTATUS HidParser_ReserveReportItems (IN PHID_REPORT Report, IN ULONG ReportCount, OUT PHID_REPORT *OutReport)
 
VOID HidParser_SignRange (IN ULONG Minimum, IN ULONG Maximum, OUT PULONG NewMinimum, OUT PULONG NewMaximum)
 
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)
 
BOOLEAN HidParser_UpdateCurrentCollectionReport (IN PHID_COLLECTION Collection, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
 
BOOLEAN HidParser_UpdateCollectionReport (IN PHID_PARSER_CONTEXT ParserContext, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
 
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)
 
NTSTATUS HidParser_ParseReportDescriptor (IN PUCHAR ReportDescriptor, IN ULONG ReportLength, OUT PVOID *OutParser)
 
PHID_COLLECTION HidParser_GetCollection (PHID_PARSER_CONTEXT ParserContext, IN ULONG CollectionNumber)
 
ULONG HidParser_NumberOfTopCollections (IN PVOID ParserCtx)
 
NTSTATUS HidParser_BuildContext (IN PVOID ParserContext, IN ULONG CollectionIndex, IN ULONG ContextSize, OUT PVOID *CollectionContext)
 
ULONG HidParser_GetContextSize (IN PVOID ParserContext, IN ULONG CollectionIndex)
 

Variables

static UCHAR ItemSize [4] = { 0, 1, 2, 4 }
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file parser.c.

Function Documentation

◆ HidParser_AddCollection()

NTSTATUS HidParser_AddCollection ( IN PHID_COLLECTION  CurrentCollection,
IN PHID_COLLECTION  NewCollection 
)

Definition at line 126 of file parser.c.

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 }
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
struct __HID_COLLECTION__ ** Nodes
Definition: parser.h:213
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
unsigned int ULONG
Definition: retypes.h:1
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
Definition: mmfuncs.h:773

Referenced by HidParser_ParseReportDescriptor().

◆ HidParser_AddMainItem()

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 at line 644 of file parser.c.

651 {
653  ULONG Index;
654  PHID_REPORT NewReport;
655  BOOLEAN Found;
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 }
BOOLEAN HidParser_UpdateCollectionReport(IN PHID_PARSER_CONTEXT ParserContext, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
Definition: parser.c:631
HID_REPORT_ITEM Items[1]
Definition: parser.h:228
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS HidParser_ReserveReportItems(IN PHID_REPORT Report, IN ULONG ReportCount, OUT PHID_REPORT *OutReport)
Definition: parser.c:370
unsigned char BOOLEAN
return Found
Definition: dirsup.c:1270
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
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
ULONG ItemCount
Definition: parser.h:226
ULONG ItemAllocated
Definition: parser.h:227
unsigned int ULONG
Definition: retypes.h:1
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_ParseReportDescriptor().

◆ HidParser_AddReportToCollection()

NTSTATUS HidParser_AddReportToCollection ( IN PHID_PARSER_CONTEXT  ParserContext,
IN PHID_COLLECTION  CurrentCollection,
IN PHID_REPORT  NewReport 
)

Definition at line 271 of file parser.c.

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 }
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
Definition: mmfuncs.h:773

Referenced by HidParser_GetReport().

◆ HidParser_AllocateCollection()

NTSTATUS HidParser_AllocateCollection ( IN PHID_COLLECTION  ParentCollection,
IN UCHAR  Type,
IN PLOCAL_ITEM_STATE  LocalItemState,
OUT PHID_COLLECTION OutCollection 
)

Definition at line 37 of file parser.c.

42 {
43  PHID_COLLECTION Collection;
44  USAGE_VALUE UsageValue;
45 
46  //
47  // first allocate the collection
48  //
49  Collection = (PHID_COLLECTION)AllocFunction(sizeof(HID_COLLECTION));
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 }
union usage_value::@4007 u
UCHAR PhysicalID
Definition: parser.h:209
Type
Definition: Type.h:6
ULONG Extended
Definition: parser.h:153
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
VOID __cdecl DebugFunction(IN LPCSTR FormatStr,...)
Definition: hid.c:80
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct __HID_COLLECTION__ * PHID_COLLECTION
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
struct __HID_COLLECTION__ * Root
Definition: parser.h:214
#define COLLECTION_LOGICAL
Definition: parser.h:60
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_ParseReportDescriptor().

◆ HidParser_AllocateReport()

NTSTATUS HidParser_AllocateReport ( IN UCHAR  ReportType,
IN UCHAR  ReportID,
OUT PHID_REPORT OutReport 
)

Definition at line 238 of file parser.c.

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 }
struct _HID_REPORT * PHID_REPORT
UCHAR ReportID
Definition: parser.h:224
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
_Must_inspect_result_ _In_ UCHAR ReportID
Definition: hidpi.h:482
UCHAR Type
Definition: parser.h:223
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_GetReport().

◆ HidParser_BuildContext()

NTSTATUS HidParser_BuildContext ( IN PVOID  ParserContext,
IN ULONG  CollectionIndex,
IN ULONG  ContextSize,
OUT PVOID CollectionContext 
)

Definition at line 1303 of file parser.c.

1308 {
1309  PHID_COLLECTION Collection;
1310  PVOID Context;
1311  NTSTATUS Status;
1312 
1313  //
1314  // lets get the collection
1315  //
1316  Collection = HidParser_GetCollection((PHID_PARSER_CONTEXT)ParserContext, CollectionIndex);
1317  ASSERT(Collection);
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  //
1335  if (Status == HIDP_STATUS_SUCCESS)
1336  {
1337  //
1338  // store context
1339  //
1340  *CollectionContext = Context;
1341  }
1342 
1343  //
1344  // done
1345  //
1346  return Status;
1347 }
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
NTSTATUS HidParser_BuildCollectionContext(IN PHID_COLLECTION RootCollection, IN PVOID Context, IN ULONG ContextSize)
Definition: context.c:185
smooth NULL
Definition: ftsmooth.c:416
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PHID_COLLECTION HidParser_GetCollection(PHID_PARSER_CONTEXT ParserContext, IN ULONG CollectionNumber)
Definition: parser.c:1248
Status
Definition: gdiplustypes.h:24
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
struct tagContext Context
Definition: acpixf.h:1034
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_GetCollectionDescription().

◆ HidParser_DeleteReport()

VOID HidParser_DeleteReport ( IN PHID_REPORT  Report)

Definition at line 19 of file parser.c.

21 {
22  //
23  // not implemented
24  //
25 }

◆ HidParser_FindReport()

NTSTATUS HidParser_FindReport ( IN PHID_PARSER_CONTEXT  ParserContext,
IN UCHAR  ReportType,
IN UCHAR  ReportID,
OUT PHID_REPORT OutReport 
)

Definition at line 225 of file parser.c.

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 }
_Must_inspect_result_ _In_ UCHAR ReportID
Definition: hidpi.h:482
NTSTATUS HidParser_FindReportInCollection(IN PHID_COLLECTION Collection, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:182

Referenced by HidParser_GetReport().

◆ HidParser_FindReportInCollection()

NTSTATUS HidParser_FindReportInCollection ( IN PHID_COLLECTION  Collection,
IN UCHAR  ReportType,
IN UCHAR  ReportID,
OUT PHID_REPORT OutReport 
)

Definition at line 182 of file parser.c.

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 }
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
#define HIDP_STATUS_REPORT_DOES_NOT_EXIST
Definition: hidpi.h:265
static const UCHAR Index[8]
Definition: usbohci.c:18
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ UCHAR ReportID
Definition: hidpi.h:482
NTSTATUS HidParser_FindReportInCollection(IN PHID_COLLECTION Collection, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:182
unsigned int ULONG
Definition: retypes.h:1
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_FindReport().

◆ HidParser_FreeCollection()

VOID HidParser_FreeCollection ( IN PHID_COLLECTION  Collection)

Definition at line 28 of file parser.c.

30 {
31  //
32  // not implemented
33  //
34 }

◆ HidParser_GetCollection()

PHID_COLLECTION HidParser_GetCollection ( PHID_PARSER_CONTEXT  ParserContext,
IN ULONG  CollectionNumber 
)

Definition at line 1248 of file parser.c.

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 }
smooth NULL
Definition: ftsmooth.c:416
PHID_COLLECTION RootCollection
Definition: parser.h:246
struct __HID_COLLECTION__ ** Nodes
Definition: parser.h:213
VOID __cdecl DebugFunction(IN LPCSTR FormatStr,...)
Definition: hid.c:80
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by HidParser_BuildContext(), and HidParser_GetContextSize().

◆ HidParser_GetContextSize()

ULONG HidParser_GetContextSize ( IN PVOID  ParserContext,
IN ULONG  CollectionIndex 
)

Definition at line 1351 of file parser.c.

1354 {
1355  PHID_COLLECTION Collection;
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  //
1366  Size = HidParser_CalculateContextSize(Collection);
1367  return Size;
1368 }
ULONG HidParser_CalculateContextSize(IN PHID_COLLECTION Collection)
Definition: context.c:65
PHID_COLLECTION HidParser_GetCollection(PHID_PARSER_CONTEXT ParserContext, IN ULONG CollectionNumber)
Definition: parser.c:1248
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
unsigned int ULONG
Definition: retypes.h:1

Referenced by HidParser_GetCollectionDescription().

◆ HidParser_GetReport()

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 at line 317 of file parser.c.

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 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS HidParser_AllocateReport(IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:238
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
NTSTATUS HidParser_AddReportToCollection(IN PHID_PARSER_CONTEXT ParserContext, IN PHID_COLLECTION CurrentCollection, IN PHID_REPORT NewReport)
Definition: parser.c:271
Status
Definition: gdiplustypes.h:24
NTSTATUS HidParser_FindReport(IN PHID_PARSER_CONTEXT ParserContext, IN UCHAR ReportType, IN UCHAR ReportID, OUT PHID_REPORT *OutReport)
Definition: parser.c:225
_Must_inspect_result_ _In_ UCHAR ReportID
Definition: hidpi.h:482
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_ParseReportDescriptor().

◆ HidParser_InitReportItem()

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 at line 456 of file parser.c.

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 }
union usage_value::@4007 u
ULONG Extended
Definition: parser.h:153
VOID HidParser_SignRange(IN ULONG Minimum, IN ULONG Maximum, OUT PULONG NewMinimum, OUT PULONG NewMaximum)
Definition: parser.c:428
unsigned int ULONG
Definition: retypes.h:1
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248

Referenced by HidParser_AddMainItem().

◆ HidParser_NumberOfTopCollections()

ULONG HidParser_NumberOfTopCollections ( IN PVOID  ParserCtx)

Definition at line 1279 of file parser.c.

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 }
struct HID_PARSER_CONTEXT * PHID_PARSER_CONTEXT
PHID_COLLECTION RootCollection
Definition: parser.h:246
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by HidParser_GetCollectionDescription().

◆ HidParser_ParseReportDescriptor()

NTSTATUS HidParser_ParseReportDescriptor ( IN PUCHAR  ReportDescriptor,
IN ULONG  ReportLength,
OUT PVOID OutParser 
)

Definition at line 707 of file parser.c.

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;
849  ParserContext->LocalItemState.UsageStack[Index].IsExtended = TRUE;
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;
859  ParserContext->LocalItemState.UsageMinimum.IsExtended
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) {
904  case ITEM_TAG_MAIN_INPUT:
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  //
955  Index = ParserContext->LocalItemState.UsageStackAllocated;
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;
967  ParserContext->LocalItemState.UsageStackAllocated = Index;
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 
1002  case ITEM_TAG_GLOBAL_UNIT:
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 
1023  case ITEM_TAG_GLOBAL_PUSH:
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  }
1043  case ITEM_TAG_GLOBAL_POP:
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  {
1086  case ITEM_TAG_LOCAL_USAGE:
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;
1138  ParserContext->LocalItemState.UsageMinimum.IsExtended
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;
1146  ParserContext->LocalItemState.UsageMaximum.IsExtended
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 }
union usage_value::@4007 u
#define HIDP_STATUS_USAGE_NOT_FOUND
Definition: hidpi.h:253
UCHAR StringIndexSet
Definition: parser.h:179
#define TRUE
Definition: types.h:120
struct __GLOBAL_ITEM_STATE__ * Next
Definition: parser.h:141
#define ITEM_TYPE_LONG
Definition: parser.h:24
#define ITEM_TAG_GLOBAL_POP
Definition: parser.h:43
#define ITEM_TAG_GLOBAL_UNIT
Definition: parser.h:38
UCHAR UsageMaximumSet
Definition: parser.h:170
ULONG UsageStackAllocated
Definition: parser.h:164
ULONG DesignatorMinimum
Definition: parser.h:175
#define ITEM_TAG_GLOBAL_PUSH
Definition: parser.h:42
ULONG LogicalMinimum
Definition: parser.h:132
#define ITEM_TAG_LOCAL_USAGE_MINIMUM
Definition: parser.h:46
unsigned char * PUCHAR
Definition: retypes.h:3
struct __GLOBAL_ITEM_STATE_ * PGLOBAL_ITEM_STATE
USAGE_VALUE UsageMinimum
Definition: parser.h:166
LONG NTSTATUS
Definition: precomp.h:26
#define ITEM_TAG_LOCAL_STRING_INDEX
Definition: parser.h:51
ULONG DesignatorIndex
Definition: parser.h:172
#define ITEM_TAG_GLOBAL_LOGICAL_MINIMUM
Definition: parser.h:33
ULONG UsageStackUsed
Definition: parser.h:163
#define ITEM_TAG_MAIN_INPUT
Definition: parser.h:26
#define ITEM_TYPE_GLOBAL
Definition: parser.h:22
ULONG DesignatorMaximum
Definition: parser.h:176
#define ITEM_TAG_MAIN_COLLECTION
Definition: parser.h:29
#define ITEM_TAG_GLOBAL_UNIT_EXPONENT
Definition: parser.h:37
ULONG LogicialMaximum
Definition: parser.h:133
struct MAIN_ITEM_DATA * PMAIN_ITEM_DATA
#define ITEM_TAG_MAIN_OUTPUT
Definition: parser.h:27
ULONG Extended
Definition: parser.h:153
#define ITEM_TAG_LOCAL_DESIGNATOR_MAXIMUM
Definition: parser.h:50
UCHAR UData8[4]
Definition: parser.h:93
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR Size
Definition: parser.h:82
#define HID_REPORT_TYPE_ANY
Definition: parser.h:18
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
ULONG PhysicalMaximum
Definition: parser.h:135
#define ITEM_TAG_MAIN_FEATURE
Definition: parser.h:28
UCHAR Tag
Definition: parser.h:84
#define ITEM_TAG_LOCAL_STRING_MINIMUM
Definition: parser.h:52
#define ITEM_TAG_GLOBAL_LOGICAL_MAXIMUM
Definition: parser.h:34
#define ITEM_TAG_LOCAL_USAGE
Definition: parser.h:45
smooth NULL
Definition: ftsmooth.c:416
struct usage_value::@4007::@4008 s
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
VOID NTAPI ZeroFunction(IN PVOID Item, IN ULONG ItemSize)
Definition: hid.c:61
PHID_COLLECTION RootCollection
Definition: parser.h:246
struct SHORT_ITEM * PSHORT_ITEM
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
#define HID_REPORT_TYPE_INPUT
UCHAR StringMaximum
Definition: parser.h:181
struct usage_value * PUSAGE_VALUE
#define HID_REPORT_TYPE_OUTPUT
struct ITEM_PREFIX * PITEM_PREFIX
NTSTATUS HidParser_AllocateCollection(IN PHID_COLLECTION ParentCollection, IN UCHAR Type, IN PLOCAL_ITEM_STATE LocalItemState, OUT PHID_COLLECTION *OutCollection)
Definition: parser.c:37
#define HID_REPORT_TYPE_FEATURE
USHORT UData16[2]
Definition: parser.h:95
UCHAR UsageMinimumSet
Definition: parser.h:169
static const UCHAR Index[8]
Definition: usbohci.c:18
#define ITEM_TAG_LOCAL_USAGE_MAXIMUM
Definition: parser.h:47
ULONG PhysicalMinimum
Definition: parser.h:134
#define ITEM_TAG_GLOBAL_REPORT_SIZE
Definition: parser.h:39
#define ITEM_TAG_LOCAL_STRING_MAXIMUM
Definition: parser.h:53
#define ITEM_TAG_MAIN_END_COLLECTION
Definition: parser.h:30
#define ITEM_TYPE_MAIN
Definition: parser.h:21
VOID __cdecl DebugFunction(IN LPCSTR FormatStr,...)
Definition: hid.c:80
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
UCHAR DesignatorIndexSet
Definition: parser.h:173
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR UseReportIDs
Definition: parser.h:251
_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:48
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
static UCHAR ItemSize[4]
Definition: parser.c:16
Status
Definition: gdiplustypes.h:24
UCHAR LongItemTag
Definition: parser.h:107
LOCAL_ITEM_STATE LocalItemState
Definition: parser.h:241
USAGE_VALUE UsageMaximum
Definition: parser.h:167
GLOBAL_ITEM_STATE GlobalItemState
Definition: parser.h:236
struct LONG_ITEM * PLONG_ITEM
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
struct __HID_COLLECTION__ * Root
Definition: parser.h:214
#define ITEM_TAG_GLOBAL_REPORT_ID
Definition: parser.h:40
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
UCHAR IsExtended
Definition: parser.h:156
#define ITEM_TAG_GLOBAL_PHYSICAL_MAXIMUM
Definition: parser.h:36
UCHAR Type
Definition: parser.h:83
UCHAR StringIndex
Definition: parser.h:178
#define ITEM_TAG_GLOBAL_USAGE_PAGE
Definition: parser.h:32
#define COLLECTION_LOGICAL
Definition: parser.h:60
#define ITEM_TAG_LOCAL_DESIGNATOR_MINIMUM
Definition: parser.h:49
PUSAGE_VALUE UsageStack
Definition: parser.h:162
UCHAR StringMinimum
Definition: parser.h:180
#define ITEM_TAG_GLOBAL_REPORT_COUNT
Definition: parser.h:41
#define ITEM_TAG_GLOBAL_PHYSICAL_MINIMUM
Definition: parser.h:35
ULONG UData32
Definition: parser.h:97
unsigned int ULONG
Definition: retypes.h:1
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248
union SHORT_ITEM::@4006 Data
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
Definition: mmfuncs.h:773
#define ITEM_TYPE_LOCAL
Definition: parser.h:23
UCHAR DataSize
Definition: parser.h:106
NTSTATUS HidParser_AddCollection(IN PHID_COLLECTION CurrentCollection, IN PHID_COLLECTION NewCollection)
Definition: parser.c:126

Referenced by HidParser_GetCollectionDescription().

◆ HidParser_ReserveReportItems()

NTSTATUS HidParser_ReserveReportItems ( IN PHID_REPORT  Report,
IN ULONG  ReportCount,
OUT PHID_REPORT OutReport 
)

Definition at line 370 of file parser.c.

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 }
struct _HID_REPORT * PHID_REPORT
struct _HID_REPORT HID_REPORT
#define HIDP_STATUS_INTERNAL_ERROR
Definition: hidpi.h:257
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
unsigned int ULONG
Definition: retypes.h:1
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
Definition: mmfuncs.h:773

Referenced by HidParser_AddMainItem().

◆ HidParser_SignRange()

VOID HidParser_SignRange ( IN ULONG  Minimum,
IN ULONG  Maximum,
OUT PULONG  NewMinimum,
OUT PULONG  NewMaximum 
)

Definition at line 428 of file parser.c.

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 }
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned int ULONG
Definition: retypes.h:1

Referenced by HidParser_InitReportItem().

◆ HidParser_UpdateCollectionReport()

BOOLEAN HidParser_UpdateCollectionReport ( IN PHID_PARSER_CONTEXT  ParserContext,
IN PHID_REPORT  Report,
IN PHID_REPORT  NewReport 
)

Definition at line 631 of file parser.c.

635 {
636  //
637  // update in current collection
638  //
639  return HidParser_UpdateCurrentCollectionReport(ParserContext->RootCollection->Nodes[ParserContext->RootCollection->NodeCount-1], Report, NewReport);
640 }
BOOLEAN HidParser_UpdateCurrentCollectionReport(IN PHID_COLLECTION Collection, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
Definition: parser.c:582

Referenced by HidParser_AddMainItem().

◆ HidParser_UpdateCurrentCollectionReport()

BOOLEAN HidParser_UpdateCurrentCollectionReport ( IN PHID_COLLECTION  Collection,
IN PHID_REPORT  Report,
IN PHID_REPORT  NewReport 
)

Definition at line 582 of file parser.c.

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 }
#define TRUE
Definition: types.h:120
BOOLEAN HidParser_UpdateCurrentCollectionReport(IN PHID_COLLECTION Collection, IN PHID_REPORT Report, IN PHID_REPORT NewReport)
Definition: parser.c:582
unsigned char BOOLEAN
return Found
Definition: dirsup.c:1270
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned int ULONG
Definition: retypes.h:1

Referenced by HidParser_UpdateCollectionReport().

Variable Documentation

◆ ItemSize