ReactOS  0.4.15-dev-1197-g8081ba9
context.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/context.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 typedef struct
17 {
19  union
20  {
21  UCHAR RawData[1];
22  };
24 
25 ULONG
27  IN PHID_COLLECTION Collection)
28 {
29  ULONG Size = 0, Index;
30 
31  Size = sizeof(HID_COLLECTION);
32 
33  //
34  // add size required for the number of report items
35  //
36  for(Index = 0; Index < Collection->ReportCount; Index++)
37  {
38  //
39  // get report size
40  //
41  ASSERT(Collection->Reports[Index]->ItemCount);
42  Size += sizeof(HID_REPORT) + Collection->Reports[Index]->ItemCount * sizeof(HID_REPORT_ITEM);
43  }
44 
45  //
46  // calculate size for sub collections
47  //
48  for(Index = 0; Index < Collection->NodeCount; Index++)
49  {
50  Size += HidParser_CalculateCollectionSize(Collection->Nodes[Index]);
51  }
52 
53  //
54  // append size for the offset
55  //
56  Size += (Collection->ReportCount + Collection->NodeCount) * sizeof(ULONG);
57 
58  //
59  // done
60  //
61  return Size;
62 }
63 
64 ULONG
66  IN PHID_COLLECTION Collection)
67 {
68  ULONG Size;
69 
70  //
71  // minimum size is the size of the collection
72  //
74 
75  //
76  // append collection context size
77  //
78  Size += sizeof(HID_COLLECTION_CONTEXT);
79  return Size;
80 }
81 
82 ULONG
84  IN PHID_COLLECTION Collection,
85  IN PHID_COLLECTION_CONTEXT CollectionContext,
86  IN ULONG CurrentOffset)
87 {
88  ULONG Index;
89  ULONG ReportSize;
90  ULONG InitialOffset;
91  ULONG CollectionSize;
92  PHID_COLLECTION TargetCollection;
93 
94  //
95  // backup initial offset
96  //
97  InitialOffset = CurrentOffset;
98 
99  //
100  // get target collection
101  //
102  TargetCollection = (PHID_COLLECTION)(&CollectionContext->RawData[CurrentOffset]);
103 
104  //
105  // first copy the collection details
106  //
107  CopyFunction(TargetCollection, Collection, sizeof(HID_COLLECTION));
108 
109  //
110  // calulcate collection size
111  //
112  CollectionSize = sizeof(HID_COLLECTION) + sizeof(ULONG) * (Collection->ReportCount + Collection->NodeCount);
113 
114  //
115  // increase offset
116  //
117  CurrentOffset += CollectionSize;
118 
119  //
120  // sanity check
121  //
122  ASSERT(CurrentOffset < CollectionContext->Size);
123 
124  //
125  // first store the report items
126  //
127  for(Index = 0; Index < Collection->ReportCount; Index++)
128  {
129  //
130  // calculate report size
131  //
132  ReportSize = sizeof(HID_REPORT) + Collection->Reports[Index]->ItemCount * sizeof(HID_REPORT_ITEM);
133 
134  //
135  // sanity check
136  //
137  ASSERT(CurrentOffset + ReportSize < CollectionContext->Size);
138 
139  //
140  // copy report item
141  //
142  CopyFunction(&CollectionContext->RawData[CurrentOffset], Collection->Reports[Index], ReportSize);
143 
144  //
145  // store offset to report item
146  //
147  TargetCollection->Offsets[Index] = CurrentOffset;
148 
149  //
150  // move to next offset
151  //
152  CurrentOffset += ReportSize;
153  }
154 
155  ASSERT(CurrentOffset <= CollectionContext->Size);
156 
157  //
158  // now store the sub collections
159  //
160  for(Index = 0; Index < Collection->NodeCount; Index++)
161  {
162  //
163  // store offset
164  //
165  TargetCollection->Offsets[Collection->ReportCount + Index] = CurrentOffset;
166 
167  //
168  // store sub collections
169  //
170  CurrentOffset += HidParser_StoreCollection(Collection->Nodes[Index], CollectionContext, CurrentOffset);
171 
172  //
173  // sanity check
174  //
175  ASSERT(CurrentOffset < CollectionContext->Size);
176  }
177 
178  //
179  // return size of collection
180  //
181  return CurrentOffset - InitialOffset;
182 }
183 
184 NTSTATUS
186  IN PHID_COLLECTION RootCollection,
187  IN PVOID Context,
189 {
190  PHID_COLLECTION_CONTEXT CollectionContext;
191  ULONG CollectionSize;
192 
193  //
194  // init context
195  //
196  CollectionContext = (PHID_COLLECTION_CONTEXT)Context;
197  CollectionContext->Size = ContextSize;
198 
199  //
200  // store collections
201  //
202  CollectionSize = HidParser_StoreCollection(RootCollection, CollectionContext, 0);
203 
204  //
205  // sanity check
206  //
207  ASSERT(CollectionSize + sizeof(HID_COLLECTION_CONTEXT) == ContextSize);
208 
209  DPRINT("CollectionContext %p\n", CollectionContext);
210  DPRINT("CollectionContext RawData %p\n", CollectionContext->RawData);
211  DPRINT("CollectionContext Size %lu\n", CollectionContext->Size);
212 
213  //
214  // done
215  //
216  return HIDP_STATUS_SUCCESS;
217 }
218 
221  IN PHID_COLLECTION_CONTEXT CollectionContext,
222  IN PHID_COLLECTION Collection,
223  IN UCHAR ReportType)
224 {
225  ULONG Index;
226  PHID_REPORT Report;
227  PHID_COLLECTION SubCollection;
228 
229  //
230  // search first in local array
231  //
232  for(Index = 0; Index < Collection->ReportCount; Index++)
233  {
234  //
235  // get report
236  //
237  Report = (PHID_REPORT)(CollectionContext->RawData + Collection->Offsets[Index]);
238  if (Report->Type == ReportType)
239  {
240  //
241  // found report
242  //
243  return Report;
244  }
245  }
246 
247  //
248  // now search in sub collections
249  //
250  for(Index = 0; Index < Collection->NodeCount; Index++)
251  {
252  //
253  // get collection
254  //
255  SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->ReportCount + Index]);
256 
257  //
258  // recursively search collection
259  //
260  Report = HidParser_SearchReportInCollection(CollectionContext, SubCollection, ReportType);
261  if (Report)
262  {
263  //
264  // found report
265  //
266  return Report;
267  }
268  }
269 
270  //
271  // not found
272  //
273  return NULL;
274 }
275 
278  IN PVOID Context,
279  IN UCHAR ReportType)
280 {
282 
283  //
284  // done
285  //
286  return HidParser_SearchReportInCollection(CollectionContext, (PHID_COLLECTION)&CollectionContext->RawData, ReportType);
287 }
288 
291  IN PVOID Context)
292 {
294 
295  //
296  // return root collection
297  //
298  return (PHID_COLLECTION)CollectionContext->RawData;
299 }
300 
301 ULONG
303  IN PHID_COLLECTION_CONTEXT CollectionContext,
304  IN PHID_COLLECTION Collection)
305 {
306  ULONG Index;
307  ULONG Count = Collection->NodeCount;
308  PHID_COLLECTION SubCollection;
309 
310  for(Index = 0; Index < Collection->NodeCount; Index++)
311  {
312  //
313  // get offset to sub collection
314  //
315  SubCollection = (PHID_COLLECTION)(CollectionContext->RawData + Collection->Offsets[Collection->ReportCount + Index]);
316 
317  //
318  // count collection for sub nodes
319  //
320  Count += HidParser_GetCollectionCount(CollectionContext, SubCollection);
321  }
322 
323  //
324  // done
325  //
326  return Count;
327 }
328 
329 ULONG
331  IN PVOID Context)
332 {
333  PHID_COLLECTION_CONTEXT CollectionContext;
334 
335  //
336  // get parser context
337  //
338  CollectionContext = (PHID_COLLECTION_CONTEXT)Context;
339 
340  //
341  // count collections
342  //
343  return HidParser_GetCollectionCount(CollectionContext, (PHID_COLLECTION)CollectionContext->RawData);
344 }
struct _HID_REPORT * PHID_REPORT
#define IN
Definition: typedefs.h:39
struct _HID_REPORT HID_REPORT
ULONG HidParser_GetCollectionCount(IN PHID_COLLECTION_CONTEXT CollectionContext, IN PHID_COLLECTION Collection)
Definition: context.c:302
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
_Must_inspect_result_ _In_ FLT_CONTEXT_TYPE _In_ SIZE_T ContextSize
Definition: fltkernel.h:1444
PHID_COLLECTION HidParser_GetCollectionFromContext(IN PVOID Context)
Definition: context.c:290
ULONG HidParser_CalculateContextSize(IN PHID_COLLECTION Collection)
Definition: context.c:65
NTSTATUS HidParser_BuildCollectionContext(IN PHID_COLLECTION RootCollection, IN PVOID Context, IN ULONG ContextSize)
Definition: context.c:185
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct __HID_COLLECTION__ HID_COLLECTION
ULONG Offsets[1]
Definition: parser.h:217
static const UCHAR Index[8]
Definition: usbohci.c:18
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct HID_COLLECTION_CONTEXT * PHID_COLLECTION_CONTEXT
unsigned char UCHAR
Definition: xmlstorage.h:181
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
struct __HID_COLLECTION__ * PHID_COLLECTION
ULONG HidParser_GetTotalCollectionCount(IN PVOID Context)
Definition: context.c:330
ULONG HidParser_StoreCollection(IN PHID_COLLECTION Collection, IN PHID_COLLECTION_CONTEXT CollectionContext, IN ULONG CurrentOffset)
Definition: context.c:83
PHID_REPORT HidParser_GetReportInCollection(IN PVOID Context, IN UCHAR ReportType)
Definition: context.c:277
unsigned int ULONG
Definition: retypes.h:1
UCHAR Type
Definition: parser.h:223
#define HIDP_STATUS_SUCCESS
Definition: hidpi.h:248
ULONG HidParser_CalculateCollectionSize(IN PHID_COLLECTION Collection)
Definition: context.c:26
PHID_REPORT HidParser_SearchReportInCollection(IN PHID_COLLECTION_CONTEXT CollectionContext, IN PHID_COLLECTION Collection, IN UCHAR ReportType)
Definition: context.c:220
_Inout_ PSIZE_T _In_opt_ PMDLX _In_ MM_ROTATE_DIRECTION _In_ PMM_ROTATE_COPY_CALLBACK_FUNCTION CopyFunction
Definition: mmfuncs.h:772