xref: /reactos/drivers/hid/hidparse/hidparse.c (revision 845faec4)
1 /*
2  * PROJECT:     ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        drivers/usb/hidparse/hidparse.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 "hidparse.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 PVOID
17 NTAPI
18 AllocFunction(
19     IN ULONG ItemSize)
20 {
21     PVOID Item = ExAllocatePoolWithTag(NonPagedPool, ItemSize, HIDPARSE_TAG);
22     if (Item)
23     {
24         //
25         // zero item
26         //
27         RtlZeroMemory(Item, ItemSize);
28     }
29 
30     //
31     // done
32     //
33     return Item;
34 }
35 
36 VOID
37 NTAPI
38 FreeFunction(
39     IN PVOID Item)
40 {
41     //
42     // free item
43     //
44     ExFreePoolWithTag(Item, HIDPARSE_TAG);
45 }
46 
47 VOID
48 NTAPI
49 ZeroFunction(
50     IN PVOID Item,
51     IN ULONG ItemSize)
52 {
53     //
54     // zero item
55     //
56     RtlZeroMemory(Item, ItemSize);
57 }
58 
59 VOID
60 NTAPI
61 CopyFunction(
62     IN PVOID Target,
63     IN PVOID Source,
64     IN ULONG Length)
65 {
66     //
67     // copy item
68     //
69     RtlCopyMemory(Target, Source, Length);
70 }
71 
72 VOID
73 __cdecl
74 DebugFunction(
75     IN LPCSTR FormatStr, ...)
76 {
77 #if HID_DBG
78     va_list args;
79     char printbuffer[1024];
80 
81     va_start(args, FormatStr);
82     vsprintf(printbuffer, FormatStr, args);
83     va_end(args);
84 
85     DbgPrint(printbuffer);
86 #endif
87 }
88 
89 VOID
90 NTAPI
91 HidP_FreeCollectionDescription(
92     IN PHIDP_DEVICE_DESC   DeviceDescription)
93 {
94     HID_PARSER Parser;
95 
96     //
97     // init parser
98     //
99     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
100 
101     //
102     // free collection
103     //
104     HidParser_FreeCollectionDescription(&Parser, DeviceDescription);
105 }
106 
107 
108 HIDAPI
109 NTSTATUS
110 NTAPI
111 HidP_GetCaps(
112     IN PHIDP_PREPARSED_DATA  PreparsedData,
113     OUT PHIDP_CAPS  Capabilities)
114 {
115     HID_PARSER Parser;
116 
117     //
118     // init parser
119     //
120     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
121 
122     //
123     // get caps
124     //
125     return HidParser_GetCaps(&Parser, PreparsedData, Capabilities);
126 }
127 
128 NTSTATUS
129 TranslateStatusForUpperLayer(
130     IN HIDPARSER_STATUS Status)
131 {
132     //
133     // now we are handling only this values, for others just return
134     // status as it is.
135     //
136     switch (Status)
137     {
138     case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES:
139         return STATUS_INSUFFICIENT_RESOURCES;
140     case HIDPARSER_STATUS_INVALID_REPORT_TYPE:
141         return HIDP_STATUS_INVALID_REPORT_TYPE;
142     case HIDPARSER_STATUS_BUFFER_TOO_SMALL:
143         return STATUS_BUFFER_TOO_SMALL;
144     case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
145         return STATUS_NO_DATA_DETECTED;
146     default:
147         return Status;
148     }
149 }
150 
151 NTSTATUS
152 NTAPI
153 HidP_GetCollectionDescription(
154     IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
155     IN ULONG DescLength,
156     IN POOL_TYPE PoolType,
157     OUT PHIDP_DEVICE_DESC DeviceDescription)
158 {
159     HID_PARSER Parser;
160     NTSTATUS Status;
161 
162     //
163     // init parser
164     //
165     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
166 
167     //
168     // get description;
169     //
170     Status = HidParser_GetCollectionDescription(&Parser, ReportDesc, DescLength, PoolType, DeviceDescription);
171     return TranslateStatusForUpperLayer(Status);
172 }
173 
174 HIDAPI
175 ULONG
176 NTAPI
177 HidP_MaxUsageListLength(
178     IN HIDP_REPORT_TYPE  ReportType,
179     IN USAGE  UsagePage  OPTIONAL,
180     IN PHIDP_PREPARSED_DATA  PreparsedData)
181 {
182     HID_PARSER Parser;
183 
184     //
185     // sanity check
186     //
187     ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
188 
189     //
190     // init parser
191     //
192     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
193 
194 
195     //
196     // get usage length
197     //
198     return HidParser_MaxUsageListLength(&Parser, PreparsedData, ReportType, UsagePage);
199 }
200 
201 HIDAPI
202 NTSTATUS
203 NTAPI
204 HidP_GetSpecificValueCaps(
205     IN HIDP_REPORT_TYPE  ReportType,
206     IN USAGE  UsagePage,
207     IN USHORT  LinkCollection,
208     IN USAGE  Usage,
209     OUT PHIDP_VALUE_CAPS  ValueCaps,
210     IN OUT PUSHORT  ValueCapsLength,
211     IN PHIDP_PREPARSED_DATA  PreparsedData)
212 {
213     HID_PARSER Parser;
214 
215     //
216     // sanity check
217     //
218     ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
219 
220     //
221     // init parser
222     //
223     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
224 
225     //
226     // get value caps
227     //
228     return HidParser_GetSpecificValueCaps(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, ValueCaps, ValueCapsLength);
229 }
230 
231 HIDAPI
232 NTSTATUS
233 NTAPI
234 HidP_GetUsages(
235     IN HIDP_REPORT_TYPE ReportType,
236     IN USAGE UsagePage,
237     IN USHORT LinkCollection  OPTIONAL,
238     OUT PUSAGE UsageList,
239     IN OUT PULONG UsageLength,
240     IN PHIDP_PREPARSED_DATA  PreparsedData,
241     IN PCHAR Report,
242     IN ULONG ReportLength)
243 {
244     HID_PARSER Parser;
245 
246     //
247     // sanity check
248     //
249     ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
250 
251     //
252     // init parser
253     //
254     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
255 
256     //
257     // get usages
258     //
259     return HidParser_GetUsages(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, UsageList, UsageLength, Report, ReportLength);
260 }
261 
262 
263 #undef HidP_GetButtonCaps
264 
265 HIDAPI
266 NTSTATUS
267 NTAPI
268 HidP_UsageListDifference(
269     IN PUSAGE  PreviousUsageList,
270     IN PUSAGE  CurrentUsageList,
271     OUT PUSAGE  BreakUsageList,
272     OUT PUSAGE  MakeUsageList,
273     IN ULONG  UsageListLength)
274 {
275     return HidParser_UsageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength);
276 }
277 
278 HIDAPI
279 NTSTATUS
280 NTAPI
281 HidP_GetUsagesEx(
282     IN HIDP_REPORT_TYPE  ReportType,
283     IN USHORT  LinkCollection,
284     OUT PUSAGE_AND_PAGE  ButtonList,
285     IN OUT ULONG  *UsageLength,
286     IN PHIDP_PREPARSED_DATA  PreparsedData,
287     IN PCHAR  Report,
288     IN ULONG  ReportLength)
289 {
290     return HidP_GetUsages(ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, &ButtonList->Usage, UsageLength, PreparsedData, Report, ReportLength);
291 }
292 
293 HIDAPI
294 NTSTATUS
295 NTAPI
296 HidP_UsageAndPageListDifference(
297     IN PUSAGE_AND_PAGE  PreviousUsageList,
298     IN PUSAGE_AND_PAGE  CurrentUsageList,
299     OUT PUSAGE_AND_PAGE  BreakUsageList,
300     OUT PUSAGE_AND_PAGE  MakeUsageList,
301     IN ULONG  UsageListLength)
302 {
303     return HidParser_UsageAndPageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength);
304 }
305 
306 HIDAPI
307 NTSTATUS
308 NTAPI
309 HidP_GetScaledUsageValue(
310     IN HIDP_REPORT_TYPE  ReportType,
311     IN USAGE  UsagePage,
312     IN USHORT  LinkCollection  OPTIONAL,
313     IN USAGE  Usage,
314     OUT PLONG  UsageValue,
315     IN PHIDP_PREPARSED_DATA  PreparsedData,
316     IN PCHAR  Report,
317     IN ULONG  ReportLength)
318 {
319     HID_PARSER Parser;
320 
321     //
322     // sanity check
323     //
324     ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
325 
326     //
327     // init parser
328     //
329     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
330 
331     //
332     // get scaled usage value
333     //
334     return HidParser_GetScaledUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength);
335 }
336 
337 HIDAPI
338 NTSTATUS
339 NTAPI
340 HidP_GetUsageValue(
341     IN HIDP_REPORT_TYPE  ReportType,
342     IN USAGE  UsagePage,
343     IN USHORT  LinkCollection,
344     IN USAGE  Usage,
345     OUT PULONG  UsageValue,
346     IN PHIDP_PREPARSED_DATA  PreparsedData,
347     IN PCHAR  Report,
348     IN ULONG  ReportLength)
349 {
350     HID_PARSER Parser;
351 
352     //
353     // sanity check
354     //
355     ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
356 
357     //
358     // init parser
359     //
360     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
361 
362     //
363     // get scaled usage value
364     //
365     return HidParser_GetUsageValue(&Parser, PreparsedData, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength);
366 }
367 
368 
369 HIDAPI
370 NTSTATUS
371 NTAPI
372 HidP_TranslateUsageAndPagesToI8042ScanCodes(
373     IN PUSAGE_AND_PAGE  ChangedUsageList,
374     IN ULONG  UsageListLength,
375     IN HIDP_KEYBOARD_DIRECTION  KeyAction,
376     IN OUT PHIDP_KEYBOARD_MODIFIER_STATE  ModifierState,
377     IN PHIDP_INSERT_SCANCODES  InsertCodesProcedure,
378     IN PVOID  InsertCodesContext)
379 {
380     HID_PARSER Parser;
381 
382     //
383     // init parser
384     //
385     HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
386 
387     //
388     // translate usage pages
389     //
390     return HidParser_TranslateUsageAndPagesToI8042ScanCodes(&Parser, ChangedUsageList, UsageListLength, KeyAction, ModifierState, InsertCodesProcedure, InsertCodesContext);
391 }
392 
393 HIDAPI
394 NTSTATUS
395 NTAPI
396 HidP_GetButtonCaps(
397     HIDP_REPORT_TYPE ReportType,
398     PHIDP_BUTTON_CAPS ButtonCaps,
399     PUSHORT ButtonCapsLength,
400     PHIDP_PREPARSED_DATA PreparsedData)
401 {
402     return HidP_GetSpecificButtonCaps(ReportType, HID_USAGE_PAGE_UNDEFINED, 0, 0, ButtonCaps, ButtonCapsLength, PreparsedData);
403 }
404 
405 HIDAPI
406 NTSTATUS
407 NTAPI
408 HidP_GetSpecificButtonCaps(
409     IN HIDP_REPORT_TYPE ReportType,
410     IN USAGE UsagePage,
411     IN USHORT LinkCollection,
412     IN USAGE Usage,
413     OUT PHIDP_BUTTON_CAPS ButtonCaps,
414     IN OUT PUSHORT ButtonCapsLength,
415     IN PHIDP_PREPARSED_DATA  PreparsedData)
416 {
417     UNIMPLEMENTED;
418     ASSERT(FALSE);
419     return STATUS_NOT_IMPLEMENTED;
420 }
421 
422 HIDAPI
423 NTSTATUS
424 NTAPI
425 HidP_GetData(
426     IN HIDP_REPORT_TYPE  ReportType,
427     OUT PHIDP_DATA  DataList,
428     IN OUT PULONG  DataLength,
429     IN PHIDP_PREPARSED_DATA  PreparsedData,
430     IN PCHAR  Report,
431     IN ULONG  ReportLength)
432 {
433     UNIMPLEMENTED;
434     ASSERT(FALSE);
435     return STATUS_NOT_IMPLEMENTED;
436 }
437 
438 HIDAPI
439 NTSTATUS
440 NTAPI
441 HidP_GetExtendedAttributes(
442     IN HIDP_REPORT_TYPE  ReportType,
443     IN USHORT DataIndex,
444     IN PHIDP_PREPARSED_DATA  PreparsedData,
445     OUT PHIDP_EXTENDED_ATTRIBUTES  Attributes,
446     IN OUT PULONG  LengthAttributes)
447 {
448     UNIMPLEMENTED;
449     ASSERT(FALSE);
450     return STATUS_NOT_IMPLEMENTED;
451 }
452 
453 HIDAPI
454 NTSTATUS
455 NTAPI
456 HidP_GetLinkCollectionNodes(
457     OUT PHIDP_LINK_COLLECTION_NODE  LinkCollectionNodes,
458     IN OUT PULONG  LinkCollectionNodesLength,
459     IN PHIDP_PREPARSED_DATA  PreparsedData)
460 {
461     UNIMPLEMENTED;
462     ASSERT(FALSE);
463     return STATUS_NOT_IMPLEMENTED;
464 }
465 
466 NTSTATUS
467 NTAPI
468 HidP_SysPowerEvent(
469     IN PCHAR HidPacket,
470     IN USHORT HidPacketLength,
471     IN PHIDP_PREPARSED_DATA Ppd,
472     OUT PULONG OutputBuffer)
473 {
474     UNIMPLEMENTED;
475     ASSERT(FALSE);
476     return STATUS_NOT_IMPLEMENTED;
477 }
478 
479 NTSTATUS
480 NTAPI
481 HidP_SysPowerCaps(
482     IN PHIDP_PREPARSED_DATA Ppd,
483     OUT PULONG OutputBuffer)
484 {
485     UNIMPLEMENTED;
486     ASSERT(FALSE);
487     return STATUS_NOT_IMPLEMENTED;
488 }
489 
490 HIDAPI
491 NTSTATUS
492 NTAPI
493 HidP_GetUsageValueArray(
494     IN HIDP_REPORT_TYPE  ReportType,
495     IN USAGE  UsagePage,
496     IN USHORT  LinkCollection  OPTIONAL,
497     IN USAGE  Usage,
498     OUT PCHAR  UsageValue,
499     IN USHORT  UsageValueByteLength,
500     IN PHIDP_PREPARSED_DATA  PreparsedData,
501     IN PCHAR  Report,
502     IN ULONG  ReportLength)
503 {
504     UNIMPLEMENTED;
505     ASSERT(FALSE);
506     return STATUS_NOT_IMPLEMENTED;
507 }
508 
509 
510 HIDAPI
511 NTSTATUS
512 NTAPI
513 HidP_UnsetUsages(
514     IN HIDP_REPORT_TYPE  ReportType,
515     IN USAGE  UsagePage,
516     IN USHORT  LinkCollection,
517     IN PUSAGE  UsageList,
518     IN OUT PULONG  UsageLength,
519     IN PHIDP_PREPARSED_DATA  PreparsedData,
520     IN OUT PCHAR  Report,
521     IN ULONG  ReportLength)
522 {
523     UNIMPLEMENTED;
524     ASSERT(FALSE);
525     return STATUS_NOT_IMPLEMENTED;
526 }
527 
528 HIDAPI
529 NTSTATUS
530 NTAPI
531 HidP_TranslateUsagesToI8042ScanCodes(
532     IN PUSAGE  ChangedUsageList,
533     IN ULONG  UsageListLength,
534     IN HIDP_KEYBOARD_DIRECTION  KeyAction,
535     IN OUT PHIDP_KEYBOARD_MODIFIER_STATE  ModifierState,
536     IN PHIDP_INSERT_SCANCODES  InsertCodesProcedure,
537     IN PVOID  InsertCodesContext)
538 {
539     UNIMPLEMENTED;
540     ASSERT(FALSE);
541     return STATUS_NOT_IMPLEMENTED;
542 }
543 
544 HIDAPI
545 NTSTATUS
546 NTAPI
547 HidP_SetUsages(
548     IN HIDP_REPORT_TYPE  ReportType,
549     IN USAGE  UsagePage,
550     IN USHORT  LinkCollection,
551     IN PUSAGE  UsageList,
552     IN OUT PULONG  UsageLength,
553     IN PHIDP_PREPARSED_DATA  PreparsedData,
554     IN OUT PCHAR  Report,
555     IN ULONG  ReportLength)
556 {
557     UNIMPLEMENTED;
558     ASSERT(FALSE);
559     return STATUS_NOT_IMPLEMENTED;
560 }
561 
562 HIDAPI
563 NTSTATUS
564 NTAPI
565 HidP_SetUsageValueArray(
566     IN HIDP_REPORT_TYPE  ReportType,
567     IN USAGE  UsagePage,
568     IN USHORT  LinkCollection  OPTIONAL,
569     IN USAGE  Usage,
570     IN PCHAR  UsageValue,
571     IN USHORT  UsageValueByteLength,
572     IN PHIDP_PREPARSED_DATA  PreparsedData,
573     OUT PCHAR  Report,
574     IN ULONG  ReportLength)
575 {
576     UNIMPLEMENTED;
577     ASSERT(FALSE);
578     return STATUS_NOT_IMPLEMENTED;
579 }
580 
581 HIDAPI
582 NTSTATUS
583 NTAPI
584 HidP_SetUsageValue(
585     IN HIDP_REPORT_TYPE  ReportType,
586     IN USAGE  UsagePage,
587     IN USHORT  LinkCollection,
588     IN USAGE  Usage,
589     IN ULONG  UsageValue,
590     IN PHIDP_PREPARSED_DATA  PreparsedData,
591     IN OUT PCHAR  Report,
592     IN ULONG  ReportLength)
593 {
594     UNIMPLEMENTED;
595     ASSERT(FALSE);
596     return STATUS_NOT_IMPLEMENTED;
597 }
598 
599 HIDAPI
600 NTSTATUS
601 NTAPI
602 HidP_SetScaledUsageValue(
603     IN HIDP_REPORT_TYPE  ReportType,
604     IN USAGE  UsagePage,
605     IN USHORT  LinkCollection  OPTIONAL,
606     IN USAGE  Usage,
607     IN LONG  UsageValue,
608     IN PHIDP_PREPARSED_DATA  PreparsedData,
609     IN OUT PCHAR  Report,
610     IN ULONG  ReportLength)
611 {
612     UNIMPLEMENTED;
613     ASSERT(FALSE);
614     return STATUS_NOT_IMPLEMENTED;
615 }
616 
617 HIDAPI
618 NTSTATUS
619 NTAPI
620 HidP_SetData(
621     IN HIDP_REPORT_TYPE  ReportType,
622     IN PHIDP_DATA  DataList,
623     IN OUT PULONG  DataLength,
624     IN PHIDP_PREPARSED_DATA  PreparsedData,
625     IN OUT PCHAR  Report,
626     IN ULONG  ReportLength)
627 {
628     UNIMPLEMENTED;
629     ASSERT(FALSE);
630     return STATUS_NOT_IMPLEMENTED;
631 }
632 
633 HIDAPI
634 ULONG
635 NTAPI
636 HidP_MaxDataListLength(
637     IN HIDP_REPORT_TYPE  ReportType,
638     IN PHIDP_PREPARSED_DATA  PreparsedData)
639 {
640     UNIMPLEMENTED;
641     ASSERT(FALSE);
642     return STATUS_NOT_IMPLEMENTED;
643 }
644 
645 HIDAPI
646 NTSTATUS
647 NTAPI
648 HidP_InitializeReportForID(
649     IN HIDP_REPORT_TYPE  ReportType,
650     IN UCHAR  ReportID,
651     IN PHIDP_PREPARSED_DATA  PreparsedData,
652     IN OUT PCHAR  Report,
653     IN ULONG  ReportLength)
654 {
655     UNIMPLEMENTED;
656     ASSERT(FALSE);
657     return STATUS_NOT_IMPLEMENTED;
658 }
659 
660 #undef HidP_GetValueCaps
661 
662 HIDAPI
663 NTSTATUS
664 NTAPI
665 HidP_GetValueCaps(
666     HIDP_REPORT_TYPE ReportType,
667     PHIDP_VALUE_CAPS ValueCaps,
668     PUSHORT ValueCapsLength,
669     PHIDP_PREPARSED_DATA PreparsedData)
670 {
671     UNIMPLEMENTED;
672     ASSERT(FALSE);
673     return STATUS_NOT_IMPLEMENTED;
674 }
675 
676 NTSTATUS
677 NTAPI
678 DriverEntry(
679     IN PDRIVER_OBJECT DriverObject,
680     IN PUNICODE_STRING RegPath)
681 {
682     DPRINT("********* HID PARSE *********\n");
683     return STATUS_SUCCESS;
684 }
685