[HIDPARSE]
[reactos.git] / lib / drivers / hidparser / hidparser.c
1 /*
2 * PROJECT: ReactOS HID Parser Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/hidparser/hidparser.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 NTSTATUS
14 TranslateHidParserStatus(
15 IN HIDPARSER_STATUS Status)
16 {
17 switch(Status)
18 {
19 case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES:
20 return HIDP_STATUS_INTERNAL_ERROR;
21 case HIDPARSER_STATUS_NOT_IMPLEMENTED:
22 return HIDP_STATUS_NOT_IMPLEMENTED;
23 case HIDPARSER_STATUS_REPORT_NOT_FOUND:
24 return HIDP_STATUS_REPORT_DOES_NOT_EXIST;
25 case HIDPARSER_STATUS_INVALID_REPORT_LENGTH:
26 return HIDP_STATUS_INVALID_REPORT_LENGTH;
27 case HIDPARSER_STATUS_INVALID_REPORT_TYPE:
28 return HIDP_STATUS_INVALID_REPORT_TYPE;
29 case HIDPARSER_STATUS_BUFFER_TOO_SMALL:
30 return HIDP_STATUS_BUFFER_TOO_SMALL;
31 case HIDPARSER_STATUS_USAGE_NOT_FOUND:
32 return HIDP_STATUS_USAGE_NOT_FOUND;
33 case HIDPARSER_STATUS_I8042_TRANS_UNKNOWN:
34 return HIDP_STATUS_I8042_TRANS_UNKNOWN;
35 case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
36 return HIDP_STATUS_NOT_IMPLEMENTED; //FIXME
37 }
38 DPRINT1("TranslateHidParserStatus Status %ld not implemented\n", Status);
39 return HIDP_STATUS_NOT_IMPLEMENTED;
40 }
41
42 NTSTATUS
43 NTAPI
44 HidParser_GetCollectionDescription(
45 IN PHID_PARSER Parser,
46 IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
47 IN ULONG DescLength,
48 IN POOL_TYPE PoolType,
49 OUT PHIDP_DEVICE_DESC DeviceDescription)
50 {
51 HIDPARSER_STATUS ParserStatus;
52 ULONG CollectionCount;
53 ULONG Index;
54 PVOID ParserContext;
55
56 //
57 // first parse the report descriptor
58 //
59 ParserStatus = HidParser_ParseReportDescriptor(Parser, ReportDesc, DescLength, &ParserContext);
60 if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
61 {
62 //
63 // failed to parse report descriptor
64 //
65 Parser->Debug("[HIDPARSER] Failed to parse report descriptor with %x\n", ParserStatus);
66 return TranslateHidParserStatus(ParserStatus);
67 }
68
69 //
70 // get collection count
71 //
72 CollectionCount = HidParser_NumberOfTopCollections(ParserContext);
73 if (CollectionCount == 0)
74 {
75 //
76 // no top level collections found
77 //
78 ASSERT(FALSE);
79 return STATUS_NO_DATA_DETECTED;
80 }
81
82 //
83 // zero description
84 //
85 Parser->Zero(DeviceDescription, sizeof(HIDP_DEVICE_DESC));
86
87 //
88 // allocate collection
89 //
90 DeviceDescription->CollectionDesc = (PHIDP_COLLECTION_DESC)Parser->Alloc(sizeof(HIDP_COLLECTION_DESC) * CollectionCount);
91 if (!DeviceDescription->CollectionDesc)
92 {
93 //
94 // no memory
95 //
96 return STATUS_INSUFFICIENT_RESOURCES;
97 }
98
99 //
100 // allocate report description
101 //
102 DeviceDescription->ReportIDs = (PHIDP_REPORT_IDS)Parser->Alloc(sizeof(HIDP_REPORT_IDS) * CollectionCount);
103 if (!DeviceDescription->ReportIDs)
104 {
105 //
106 // no memory
107 //
108 Parser->Free(DeviceDescription->CollectionDesc);
109 return STATUS_INSUFFICIENT_RESOURCES;
110 }
111
112 for(Index = 0; Index < CollectionCount; Index++)
113 {
114 //
115 // set preparsed data length
116 //
117 DeviceDescription->CollectionDesc[Index].PreparsedDataLength = HidParser_GetContextSize(Parser, ParserContext, Index);
118 ParserStatus = HidParser_BuildContext(Parser, ParserContext, Index, DeviceDescription->CollectionDesc[Index].PreparsedDataLength, (PVOID*)&DeviceDescription->CollectionDesc[Index].PreparsedData);
119 if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
120 {
121 //
122 // no memory
123 //
124 return TranslateHidParserStatus(ParserStatus);
125 }
126
127 //
128 // init report description
129 //
130 DeviceDescription->ReportIDs[Index].CollectionNumber = Index + 1;
131 DeviceDescription->ReportIDs[Index].ReportID = Index; //FIXME
132 DeviceDescription->ReportIDs[Index].InputLength = HidParser_GetReportLength((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_INPUT);
133 DeviceDescription->ReportIDs[Index].OutputLength = HidParser_GetReportLength((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_OUTPUT);
134 DeviceDescription->ReportIDs[Index].FeatureLength = HidParser_GetReportLength((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_FEATURE);
135
136 //
137 // init collection description
138 //
139 DeviceDescription->CollectionDesc[Index].CollectionNumber = Index + 1;
140
141 //
142 // get collection usage page
143 //
144 ParserStatus = HidParser_GetCollectionUsagePage((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, &DeviceDescription->CollectionDesc[Index].Usage, &DeviceDescription->CollectionDesc[Index].UsagePage);
145
146 //
147 // windows seems to prepend the report id, regardless if it is required
148 //
149 DeviceDescription->CollectionDesc[Index].InputLength = (DeviceDescription->ReportIDs[Index].InputLength > 0 ? DeviceDescription->ReportIDs[Index].InputLength + 1 : 0);
150 DeviceDescription->CollectionDesc[Index].OutputLength = (DeviceDescription->ReportIDs[Index].OutputLength > 0 ? DeviceDescription->ReportIDs[Index].OutputLength + 1 : 0);
151 DeviceDescription->CollectionDesc[Index].FeatureLength = (DeviceDescription->ReportIDs[Index].FeatureLength > 0 ? DeviceDescription->ReportIDs[Index].FeatureLength + 1 : 0);
152 }
153
154 //
155 // store collection & report count
156 //
157 DeviceDescription->CollectionDescLength = CollectionCount;
158 DeviceDescription->ReportIDsLength = CollectionCount;
159
160 //
161 // done
162 //
163 return STATUS_SUCCESS;
164 }
165
166 VOID
167 NTAPI
168 HidParser_FreeCollectionDescription(
169 IN PHID_PARSER Parser,
170 IN PHIDP_DEVICE_DESC DeviceDescription)
171 {
172 ULONG Index;
173
174 //
175 // first free all context
176 //
177 for(Index = 0; Index < DeviceDescription->CollectionDescLength; Index++)
178 {
179 //
180 // free collection context
181 //
182 Parser->Free(DeviceDescription->CollectionDesc[Index].PreparsedData);
183 }
184
185 //
186 // now free collection description
187 //
188 Parser->Free(DeviceDescription->CollectionDesc);
189
190 //
191 // free report description
192 //
193 ExFreePool(DeviceDescription->ReportIDs);
194 }
195
196 HIDAPI
197 NTSTATUS
198 NTAPI
199 HidParser_GetCaps(
200 IN PHID_PARSER Parser,
201 IN PVOID CollectionContext,
202 OUT PHIDP_CAPS Capabilities)
203 {
204 //
205 // zero capabilities
206 //
207 Parser->Zero(Capabilities, sizeof(HIDP_CAPS));
208
209 //
210 // init capabilities
211 //
212 HidParser_GetCollectionUsagePage(CollectionContext, &Capabilities->Usage, &Capabilities->UsagePage);
213 Capabilities->InputReportByteLength = HidParser_GetReportLength(CollectionContext, HID_REPORT_TYPE_INPUT);
214 Capabilities->OutputReportByteLength = HidParser_GetReportLength(CollectionContext, HID_REPORT_TYPE_OUTPUT);
215 Capabilities->FeatureReportByteLength = HidParser_GetReportLength(CollectionContext, HID_REPORT_TYPE_FEATURE);
216
217 //
218 // always pre-prend report id
219 //
220 Capabilities->InputReportByteLength = (Capabilities->InputReportByteLength > 0 ? Capabilities->InputReportByteLength + 1 : 0);
221 Capabilities->OutputReportByteLength = (Capabilities->OutputReportByteLength > 0 ? Capabilities->OutputReportByteLength + 1 : 0);
222 Capabilities->FeatureReportByteLength = (Capabilities->FeatureReportByteLength > 0 ? Capabilities->FeatureReportByteLength + 1 : 0);
223
224 //
225 // get number of link collection nodes
226 //
227 Capabilities->NumberLinkCollectionNodes = HidParser_GetTotalCollectionCount(CollectionContext);
228
229 //
230 // get data indices
231 //
232 Capabilities->NumberInputDataIndices = HidParser_GetReportItemTypeCountFromReportType(CollectionContext, HID_REPORT_TYPE_INPUT, TRUE);
233 Capabilities->NumberOutputDataIndices = HidParser_GetReportItemTypeCountFromReportType(CollectionContext, HID_REPORT_TYPE_OUTPUT, TRUE);
234 Capabilities->NumberFeatureDataIndices = HidParser_GetReportItemTypeCountFromReportType(CollectionContext, HID_REPORT_TYPE_FEATURE, TRUE);
235
236 //
237 // get value caps
238 //
239 Capabilities->NumberInputValueCaps = HidParser_GetReportItemTypeCountFromReportType(CollectionContext, HID_REPORT_TYPE_INPUT, FALSE);
240 Capabilities->NumberOutputValueCaps = HidParser_GetReportItemTypeCountFromReportType(CollectionContext, HID_REPORT_TYPE_OUTPUT, FALSE);
241 Capabilities->NumberFeatureValueCaps = HidParser_GetReportItemTypeCountFromReportType(CollectionContext, HID_REPORT_TYPE_FEATURE, FALSE);
242
243
244 //
245 // get button caps
246 //
247 Capabilities->NumberInputButtonCaps = HidParser_GetReportItemCountFromReportType(CollectionContext, HID_REPORT_TYPE_INPUT);
248 Capabilities->NumberOutputButtonCaps = HidParser_GetReportItemCountFromReportType(CollectionContext, HID_REPORT_TYPE_OUTPUT);
249 Capabilities->NumberFeatureButtonCaps = HidParser_GetReportItemCountFromReportType(CollectionContext, HID_REPORT_TYPE_FEATURE);
250
251 //
252 // done
253 //
254 return HIDP_STATUS_SUCCESS;
255 }
256
257 HIDAPI
258 ULONG
259 NTAPI
260 HidParser_MaxUsageListLength(
261 IN PHID_PARSER Parser,
262 IN PVOID CollectionContext,
263 IN HIDP_REPORT_TYPE ReportType,
264 IN USAGE UsagePage OPTIONAL)
265 {
266 //
267 // FIXME test what should be returned when usage page is not defined
268 //
269 if (UsagePage == HID_USAGE_PAGE_UNDEFINED)
270 {
271 //
272 // implement me
273 //
274 UNIMPLEMENTED
275
276 //
277 // invalid report
278 //
279 return 0;
280 }
281
282 if (ReportType == HidP_Input)
283 {
284 //
285 // input report
286 //
287 return HidParser_GetMaxUsageListLengthWithReportAndPage(CollectionContext, HID_REPORT_TYPE_INPUT, UsagePage);
288 }
289 else if (ReportType == HidP_Output)
290 {
291 //
292 // input report
293 //
294 return HidParser_GetMaxUsageListLengthWithReportAndPage(CollectionContext, HID_REPORT_TYPE_OUTPUT, UsagePage);
295 }
296 else if (ReportType == HidP_Feature)
297 {
298 //
299 // input report
300 //
301 return HidParser_GetMaxUsageListLengthWithReportAndPage(CollectionContext, HID_REPORT_TYPE_FEATURE, UsagePage);
302 }
303 else
304 {
305 //
306 // invalid report type
307 //
308 return 0;
309 }
310 }
311
312 #undef HidParser_GetButtonCaps
313
314 HIDAPI
315 NTSTATUS
316 NTAPI
317 HidParser_GetButtonCaps(
318 IN PHID_PARSER Parser,
319 IN PVOID CollectionContext,
320 IN HIDP_REPORT_TYPE ReportType,
321 IN PHIDP_BUTTON_CAPS ButtonCaps,
322 IN PUSHORT ButtonCapsLength)
323 {
324 return HidParser_GetSpecificButtonCaps(Parser, CollectionContext, ReportType, HID_USAGE_PAGE_UNDEFINED, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_PAGE_UNDEFINED, ButtonCaps, (PULONG)ButtonCapsLength);
325 }
326
327 HIDAPI
328 NTSTATUS
329 NTAPI
330 HidParser_GetSpecificValueCaps(
331 IN PHID_PARSER Parser,
332 IN PVOID CollectionContext,
333 IN HIDP_REPORT_TYPE ReportType,
334 IN USAGE UsagePage,
335 IN USHORT LinkCollection,
336 IN USAGE Usage,
337 OUT PHIDP_VALUE_CAPS ValueCaps,
338 IN OUT PULONG ValueCapsLength)
339 {
340 HIDPARSER_STATUS ParserStatus;
341
342 //
343 // FIXME: implement searching in specific collection
344 //
345 ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
346
347 if (ReportType == HidP_Input)
348 {
349 //
350 // input report
351 //
352 ParserStatus = HidParser_GetSpecificValueCapsWithReport(Parser, CollectionContext, HID_REPORT_TYPE_INPUT, UsagePage, Usage, ValueCaps, ValueCapsLength);
353 }
354 else if (ReportType == HidP_Output)
355 {
356 //
357 // input report
358 //
359 ParserStatus = HidParser_GetSpecificValueCapsWithReport(Parser, CollectionContext, HID_REPORT_TYPE_OUTPUT, UsagePage, Usage, ValueCaps, ValueCapsLength);
360 }
361 else if (ReportType == HidP_Feature)
362 {
363 //
364 // input report
365 //
366 ParserStatus = HidParser_GetSpecificValueCapsWithReport(Parser, CollectionContext, HID_REPORT_TYPE_FEATURE, UsagePage, Usage, ValueCaps, ValueCapsLength);
367 }
368 else
369 {
370 //
371 // invalid report type
372 //
373 return HIDP_STATUS_INVALID_REPORT_TYPE;
374 }
375
376
377 if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
378 {
379 //
380 // success
381 //
382 return HIDP_STATUS_SUCCESS;
383 }
384
385 //
386 // translate error
387 //
388 return TranslateHidParserStatus(ParserStatus);
389 }
390
391 HIDAPI
392 NTSTATUS
393 NTAPI
394 HidParser_UsageListDifference(
395 IN PUSAGE PreviousUsageList,
396 IN PUSAGE CurrentUsageList,
397 OUT PUSAGE BreakUsageList,
398 OUT PUSAGE MakeUsageList,
399 IN ULONG UsageListLength)
400 {
401 ULONG Index, SubIndex, bFound, BreakUsageIndex = 0, MakeUsageIndex = 0;
402 USAGE CurrentUsage, Usage;
403
404 if (UsageListLength)
405 {
406 Index = 0;
407 do
408 {
409 /* get current usage */
410 CurrentUsage = PreviousUsageList[Index];
411
412 /* is the end of list reached? */
413 if (!CurrentUsage)
414 break;
415
416 /* start searching in current usage list */
417 SubIndex = 0;
418 bFound = FALSE;
419 do
420 {
421 /* get usage of current list */
422 Usage = CurrentUsageList[SubIndex];
423
424 /* end of list reached? */
425 if (!Usage)
426 break;
427
428 /* check if it matches the current one */
429 if (CurrentUsage == Usage)
430 {
431 /* it does */
432 bFound = TRUE;
433 break;
434 }
435
436 /* move to next usage */
437 SubIndex++;
438 }while(SubIndex < UsageListLength);
439
440 /* was the usage found ?*/
441 if (!bFound)
442 {
443 /* store it in the break usage list */
444 BreakUsageList[BreakUsageIndex] = CurrentUsage;
445 BreakUsageIndex++;
446 }
447
448 /* move to next usage */
449 Index++;
450
451 }while(Index < UsageListLength);
452
453 /* now process the new items */
454 Index = 0;
455 do
456 {
457 /* get current usage */
458 CurrentUsage = CurrentUsageList[Index];
459
460 /* is the end of list reached? */
461 if (!CurrentUsage)
462 break;
463
464 /* start searching in current usage list */
465 SubIndex = 0;
466 bFound = FALSE;
467 do
468 {
469 /* get usage of previous list */
470 Usage = PreviousUsageList[SubIndex];
471
472 /* end of list reached? */
473 if (!Usage)
474 break;
475
476 /* check if it matches the current one */
477 if (CurrentUsage == Usage)
478 {
479 /* it does */
480 bFound = TRUE;
481 break;
482 }
483
484 /* move to next usage */
485 SubIndex++;
486 }while(SubIndex < UsageListLength);
487
488 /* was the usage found ?*/
489 if (!bFound)
490 {
491 /* store it in the make usage list */
492 MakeUsageList[MakeUsageIndex] = CurrentUsage;
493 MakeUsageIndex++;
494 }
495
496 /* move to next usage */
497 Index++;
498
499 }while(Index < UsageListLength);
500 }
501
502 /* does the break list contain empty entries */
503 if (BreakUsageIndex < UsageListLength)
504 {
505 /* zeroize entries */
506 RtlZeroMemory(&BreakUsageList[BreakUsageIndex], sizeof(USAGE) * (UsageListLength - BreakUsageIndex));
507 }
508
509 /* does the make usage list contain empty entries */
510 if (MakeUsageIndex < UsageListLength)
511 {
512 /* zeroize entries */
513 RtlZeroMemory(&MakeUsageList[MakeUsageIndex], sizeof(USAGE) * (UsageListLength - MakeUsageIndex));
514 }
515
516 /* done */
517 return HIDP_STATUS_SUCCESS;
518 }
519
520 HIDAPI
521 NTSTATUS
522 NTAPI
523 HidParser_GetUsages(
524 IN PHID_PARSER Parser,
525 IN PVOID CollectionContext,
526 IN HIDP_REPORT_TYPE ReportType,
527 IN USAGE UsagePage,
528 IN USHORT LinkCollection OPTIONAL,
529 OUT USAGE *UsageList,
530 IN OUT PULONG UsageLength,
531 IN PCHAR Report,
532 IN ULONG ReportLength)
533 {
534 HIDPARSER_STATUS ParserStatus;
535
536 //
537 // FIXME: implement searching in specific collection
538 //
539 ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
540
541 if (ReportType == HidP_Input)
542 {
543 //
544 // input report
545 //
546 ParserStatus = HidParser_GetUsagesWithReport(Parser, CollectionContext, HID_REPORT_TYPE_INPUT, UsagePage, UsageList, UsageLength, Report, ReportLength);
547 }
548 else if (ReportType == HidP_Output)
549 {
550 //
551 // input report
552 //
553 ParserStatus = HidParser_GetUsagesWithReport(Parser, CollectionContext, HID_REPORT_TYPE_OUTPUT, UsagePage, UsageList, UsageLength, Report, ReportLength);
554 }
555 else if (ReportType == HidP_Feature)
556 {
557 //
558 // input report
559 //
560 ParserStatus = HidParser_GetUsagesWithReport(Parser, CollectionContext, HID_REPORT_TYPE_FEATURE, UsagePage, UsageList, UsageLength, Report, ReportLength);
561 }
562 else
563 {
564 //
565 // invalid report type
566 //
567 return HIDP_STATUS_INVALID_REPORT_TYPE;
568 }
569
570 if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
571 {
572 //
573 // success
574 //
575 return HIDP_STATUS_SUCCESS;
576 }
577
578 //
579 // translate error
580 //
581 return TranslateHidParserStatus(ParserStatus);
582 }
583
584 HIDAPI
585 NTSTATUS
586 NTAPI
587 HidParser_GetScaledUsageValue(
588 IN PHID_PARSER Parser,
589 IN PVOID CollectionContext,
590 IN HIDP_REPORT_TYPE ReportType,
591 IN USAGE UsagePage,
592 IN USHORT LinkCollection OPTIONAL,
593 IN USAGE Usage,
594 OUT PLONG UsageValue,
595 IN PCHAR Report,
596 IN ULONG ReportLength)
597 {
598 HIDPARSER_STATUS ParserStatus;
599
600 //
601 // FIXME: implement searching in specific collection
602 //
603 ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
604
605 if (ReportType == HidP_Input)
606 {
607 //
608 // input report
609 //
610 ParserStatus = HidParser_GetScaledUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_INPUT, UsagePage, Usage, UsageValue, Report, ReportLength);
611 }
612 else if (ReportType == HidP_Output)
613 {
614 //
615 // input report
616 //
617 ParserStatus = HidParser_GetScaledUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_OUTPUT, UsagePage, Usage, UsageValue, Report, ReportLength);
618 }
619 else if (ReportType == HidP_Feature)
620 {
621 //
622 // input report
623 //
624 ParserStatus = HidParser_GetScaledUsageValueWithReport(Parser, CollectionContext, HID_REPORT_TYPE_FEATURE, UsagePage, Usage, UsageValue, Report, ReportLength);
625 }
626 else
627 {
628 //
629 // invalid report type
630 //
631 return HIDP_STATUS_INVALID_REPORT_TYPE;
632 }
633
634 if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
635 {
636 //
637 // success
638 //
639 return HIDP_STATUS_SUCCESS;
640 }
641
642 //
643 // translate error
644 //
645 return TranslateHidParserStatus(ParserStatus);
646 }
647
648 HIDAPI
649 NTSTATUS
650 NTAPI
651 HidParser_TranslateUsageAndPagesToI8042ScanCodes(
652 IN PHID_PARSER Parser,
653 IN PUSAGE_AND_PAGE ChangedUsageList,
654 IN ULONG UsageListLength,
655 IN HIDP_KEYBOARD_DIRECTION KeyAction,
656 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
657 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
658 IN PVOID InsertCodesContext)
659 {
660 ULONG Index;
661 HIDPARSER_STATUS Status = HIDPARSER_STATUS_SUCCESS;
662
663 for(Index = 0; Index < UsageListLength; Index++)
664 {
665 //
666 // check current usage
667 //
668 if (ChangedUsageList[Index].UsagePage == HID_USAGE_PAGE_KEYBOARD)
669 {
670 //
671 // process usage
672 //
673 Status = HidParser_TranslateUsage(Parser, ChangedUsageList[Index].Usage, KeyAction, ModifierState, InsertCodesProcedure, InsertCodesContext);
674 }
675 else if (ChangedUsageList[Index].UsagePage == HID_USAGE_PAGE_CONSUMER)
676 {
677 //
678 // FIXME: implement me
679 //
680 UNIMPLEMENTED
681 Status = HIDPARSER_STATUS_NOT_IMPLEMENTED;
682 }
683 else
684 {
685 //
686 // invalid page / end of usage list page
687 //
688 return HIDP_STATUS_I8042_TRANS_UNKNOWN;
689 }
690
691 //
692 // check status
693 //
694 if (Status != HIDPARSER_STATUS_SUCCESS)
695 {
696 //
697 // failed
698 //
699 return TranslateHidParserStatus(Status);
700 }
701 }
702
703 if (Status != HIDPARSER_STATUS_SUCCESS)
704 {
705 //
706 // failed
707 //
708 return TranslateHidParserStatus(Status);
709 }
710
711 //
712 // done
713 //
714 return HIDP_STATUS_SUCCESS;
715 }
716
717
718 HIDAPI
719 NTSTATUS
720 NTAPI
721 HidParser_GetUsagesEx(
722 IN PHID_PARSER Parser,
723 IN PVOID CollectionContext,
724 IN HIDP_REPORT_TYPE ReportType,
725 IN USHORT LinkCollection,
726 OUT PUSAGE_AND_PAGE ButtonList,
727 IN OUT ULONG *UsageLength,
728 IN PCHAR Report,
729 IN ULONG ReportLength)
730 {
731 return HidParser_GetUsages(Parser, CollectionContext, ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, (PUSAGE)ButtonList, UsageLength, Report, ReportLength);
732 }
733
734 HIDAPI
735 NTSTATUS
736 NTAPI
737 HidParser_UsageAndPageListDifference(
738 IN PUSAGE_AND_PAGE PreviousUsageList,
739 IN PUSAGE_AND_PAGE CurrentUsageList,
740 OUT PUSAGE_AND_PAGE BreakUsageList,
741 OUT PUSAGE_AND_PAGE MakeUsageList,
742 IN ULONG UsageListLength)
743 {
744 ULONG Index, SubIndex, BreakUsageListIndex = 0, MakeUsageListIndex = 0, bFound;
745 PUSAGE_AND_PAGE CurrentUsage, Usage;
746
747 if (UsageListLength)
748 {
749 /* process removed usages */
750 Index = 0;
751 do
752 {
753 /* get usage from current index */
754 CurrentUsage = &PreviousUsageList[Index];
755
756 /* end of list reached? */
757 if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
758 break;
759
760 /* search in current list */
761 SubIndex = 0;
762 bFound = FALSE;
763 do
764 {
765 /* get usage */
766 Usage = &CurrentUsageList[SubIndex];
767
768 /* end of list reached? */
769 if (Usage->Usage == 0 && Usage->UsagePage == 0)
770 break;
771
772 /* does it match */
773 if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
774 {
775 /* found match */
776 bFound = TRUE;
777 }
778
779 /* move to next index */
780 SubIndex++;
781
782 }while(SubIndex < UsageListLength);
783
784 if (!bFound)
785 {
786 /* store it in break usage list */
787 BreakUsageList[BreakUsageListIndex].Usage = CurrentUsage->Usage;
788 BreakUsageList[BreakUsageListIndex].UsagePage = CurrentUsage->UsagePage;
789 BreakUsageListIndex++;
790 }
791
792 /* move to next index */
793 Index++;
794
795 }while(Index < UsageListLength);
796
797 /* process new usages */
798 Index = 0;
799 do
800 {
801 /* get usage from current index */
802 CurrentUsage = &CurrentUsageList[Index];
803
804 /* end of list reached? */
805 if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
806 break;
807
808 /* search in current list */
809 SubIndex = 0;
810 bFound = FALSE;
811 do
812 {
813 /* get usage */
814 Usage = &PreviousUsageList[SubIndex];
815
816 /* end of list reached? */
817 if (Usage->Usage == 0 && Usage->UsagePage == 0)
818 break;
819
820 /* does it match */
821 if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
822 {
823 /* found match */
824 bFound = TRUE;
825 }
826
827 /* move to next index */
828 SubIndex++;
829
830 }while(SubIndex < UsageListLength);
831
832 if (!bFound)
833 {
834 /* store it in break usage list */
835 MakeUsageList[MakeUsageListIndex].Usage = CurrentUsage->Usage;
836 MakeUsageList[MakeUsageListIndex].UsagePage = CurrentUsage->UsagePage;
837 MakeUsageListIndex++;
838 }
839
840 /* move to next index */
841 Index++;
842 }while(Index < UsageListLength);
843 }
844
845 /* are there remaining free list entries */
846 if (BreakUsageListIndex < UsageListLength)
847 {
848 /* zero them */
849 RtlZeroMemory(&BreakUsageList[BreakUsageListIndex], (UsageListLength - BreakUsageListIndex) * sizeof(USAGE_AND_PAGE));
850 }
851
852 /* are there remaining free list entries */
853 if (MakeUsageListIndex < UsageListLength)
854 {
855 /* zero them */
856 RtlZeroMemory(&MakeUsageList[MakeUsageListIndex], (UsageListLength - MakeUsageListIndex) * sizeof(USAGE_AND_PAGE));
857 }
858
859 /* done */
860 return HIDP_STATUS_SUCCESS;
861 }
862
863 HIDAPI
864 NTSTATUS
865 NTAPI
866 HidParser_GetSpecificButtonCaps(
867 IN PHID_PARSER Parser,
868 IN PVOID CollectionContext,
869 IN HIDP_REPORT_TYPE ReportType,
870 IN USAGE UsagePage,
871 IN USHORT LinkCollection,
872 IN USAGE Usage,
873 OUT PHIDP_BUTTON_CAPS ButtonCaps,
874 IN OUT PULONG ButtonCapsLength)
875 {
876 UNIMPLEMENTED
877 ASSERT(FALSE);
878 return STATUS_NOT_IMPLEMENTED;
879 }
880
881
882 HIDAPI
883 NTSTATUS
884 NTAPI
885 HidParser_GetData(
886 IN PHID_PARSER Parser,
887 IN PVOID CollectionContext,
888 IN HIDP_REPORT_TYPE ReportType,
889 OUT PHIDP_DATA DataList,
890 IN OUT PULONG DataLength,
891 IN PCHAR Report,
892 IN ULONG ReportLength)
893 {
894 UNIMPLEMENTED
895 ASSERT(FALSE);
896 return STATUS_NOT_IMPLEMENTED;
897 }
898
899 HIDAPI
900 NTSTATUS
901 NTAPI
902 HidParser_GetExtendedAttributes(
903 IN PHID_PARSER Parser,
904 IN PVOID CollectionContext,
905 IN HIDP_REPORT_TYPE ReportType,
906 IN USHORT DataIndex,
907 OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
908 IN OUT PULONG LengthAttributes)
909 {
910 UNIMPLEMENTED
911 ASSERT(FALSE);
912 return STATUS_NOT_IMPLEMENTED;
913 }
914
915 HIDAPI
916 NTSTATUS
917 NTAPI
918 HidParser_GetLinkCollectionNodes(
919 IN PHID_PARSER Parser,
920 IN PVOID CollectionContext,
921 OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
922 IN OUT PULONG LinkCollectionNodesLength)
923 {
924 UNIMPLEMENTED
925 ASSERT(FALSE);
926 return STATUS_NOT_IMPLEMENTED;
927 }
928
929 HIDAPI
930 NTSTATUS
931 NTAPI
932 HidParser_GetUsageValue(
933 IN PHID_PARSER Parser,
934 IN PVOID CollectionContext,
935 IN HIDP_REPORT_TYPE ReportType,
936 IN USAGE UsagePage,
937 IN USHORT LinkCollection,
938 IN USAGE Usage,
939 OUT PULONG UsageValue,
940 IN PCHAR Report,
941 IN ULONG ReportLength)
942 {
943 UNIMPLEMENTED
944 ASSERT(FALSE);
945 return STATUS_NOT_IMPLEMENTED;
946 }
947
948 NTSTATUS
949 NTAPI
950 HidParser_SysPowerEvent(
951 IN PHID_PARSER Parser,
952 IN PVOID CollectionContext,
953 IN PCHAR HidPacket,
954 IN USHORT HidPacketLength,
955 OUT PULONG OutputBuffer)
956 {
957 UNIMPLEMENTED
958 ASSERT(FALSE);
959 return STATUS_NOT_IMPLEMENTED;
960 }
961
962 NTSTATUS
963 NTAPI
964 HidParser_SysPowerCaps (
965 IN PHID_PARSER Parser,
966 IN PVOID CollectionContext,
967 OUT PULONG OutputBuffer)
968 {
969 UNIMPLEMENTED
970 ASSERT(FALSE);
971 return STATUS_NOT_IMPLEMENTED;
972 }
973
974 HIDAPI
975 NTSTATUS
976 NTAPI
977 HidParser_GetUsageValueArray(
978 IN PHID_PARSER Parser,
979 IN PVOID CollectionContext,
980 IN HIDP_REPORT_TYPE ReportType,
981 IN USAGE UsagePage,
982 IN USHORT LinkCollection OPTIONAL,
983 IN USAGE Usage,
984 OUT PCHAR UsageValue,
985 IN USHORT UsageValueByteLength,
986 IN PCHAR Report,
987 IN ULONG ReportLength)
988 {
989 UNIMPLEMENTED
990 ASSERT(FALSE);
991 return STATUS_NOT_IMPLEMENTED;
992 }
993
994 HIDAPI
995 NTSTATUS
996 NTAPI
997 HidParser_UnsetUsages(
998 IN PHID_PARSER Parser,
999 IN PVOID CollectionContext,
1000 IN HIDP_REPORT_TYPE ReportType,
1001 IN USAGE UsagePage,
1002 IN USHORT LinkCollection,
1003 IN PUSAGE UsageList,
1004 IN OUT PULONG UsageLength,
1005 IN OUT PCHAR Report,
1006 IN ULONG ReportLength)
1007 {
1008 UNIMPLEMENTED
1009 ASSERT(FALSE);
1010 return STATUS_NOT_IMPLEMENTED;
1011 }
1012
1013 HIDAPI
1014 NTSTATUS
1015 NTAPI
1016 HidParser_TranslateUsagesToI8042ScanCodes(
1017 IN PUSAGE ChangedUsageList,
1018 IN ULONG UsageListLength,
1019 IN HIDP_KEYBOARD_DIRECTION KeyAction,
1020 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
1021 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
1022 IN PVOID InsertCodesContext)
1023 {
1024 UNIMPLEMENTED
1025 ASSERT(FALSE);
1026 return STATUS_NOT_IMPLEMENTED;
1027 }
1028
1029 HIDAPI
1030 NTSTATUS
1031 NTAPI
1032 HidParser_SetUsages(
1033 IN PHID_PARSER Parser,
1034 IN PVOID CollectionContext,
1035 IN HIDP_REPORT_TYPE ReportType,
1036 IN USAGE UsagePage,
1037 IN USHORT LinkCollection,
1038 IN PUSAGE UsageList,
1039 IN OUT PULONG UsageLength,
1040 IN OUT PCHAR Report,
1041 IN ULONG ReportLength)
1042 {
1043 UNIMPLEMENTED
1044 ASSERT(FALSE);
1045 return STATUS_NOT_IMPLEMENTED;
1046 }
1047
1048 HIDAPI
1049 NTSTATUS
1050 NTAPI
1051 HidParser_SetUsageValueArray(
1052 IN PHID_PARSER Parser,
1053 IN PVOID CollectionContext,
1054 IN HIDP_REPORT_TYPE ReportType,
1055 IN USAGE UsagePage,
1056 IN USHORT LinkCollection OPTIONAL,
1057 IN USAGE Usage,
1058 IN PCHAR UsageValue,
1059 IN USHORT UsageValueByteLength,
1060 OUT PCHAR Report,
1061 IN ULONG ReportLength)
1062 {
1063 UNIMPLEMENTED
1064 ASSERT(FALSE);
1065 return STATUS_NOT_IMPLEMENTED;
1066 }
1067
1068 HIDAPI
1069 NTSTATUS
1070 NTAPI
1071 HidParser_SetUsageValue(
1072 IN PHID_PARSER Parser,
1073 IN PVOID CollectionContext,
1074 IN HIDP_REPORT_TYPE ReportType,
1075 IN USAGE UsagePage,
1076 IN USHORT LinkCollection,
1077 IN USAGE Usage,
1078 IN ULONG UsageValue,
1079 IN OUT PCHAR Report,
1080 IN ULONG ReportLength)
1081 {
1082 UNIMPLEMENTED
1083 ASSERT(FALSE);
1084 return STATUS_NOT_IMPLEMENTED;
1085 }
1086
1087 HIDAPI
1088 NTSTATUS
1089 NTAPI
1090 HidParser_SetScaledUsageValue(
1091 IN PHID_PARSER Parser,
1092 IN PVOID CollectionContext,
1093 IN HIDP_REPORT_TYPE ReportType,
1094 IN USAGE UsagePage,
1095 IN USHORT LinkCollection OPTIONAL,
1096 IN USAGE Usage,
1097 IN LONG UsageValue,
1098 IN OUT PCHAR Report,
1099 IN ULONG ReportLength)
1100 {
1101 UNIMPLEMENTED
1102 ASSERT(FALSE);
1103 return STATUS_NOT_IMPLEMENTED;
1104 }
1105
1106 HIDAPI
1107 NTSTATUS
1108 NTAPI
1109 HidParser_SetData(
1110 IN PHID_PARSER Parser,
1111 IN PVOID CollectionContext,
1112 IN HIDP_REPORT_TYPE ReportType,
1113 IN PHIDP_DATA DataList,
1114 IN OUT PULONG DataLength,
1115 IN OUT PCHAR Report,
1116 IN ULONG ReportLength)
1117 {
1118 UNIMPLEMENTED
1119 ASSERT(FALSE);
1120 return STATUS_NOT_IMPLEMENTED;
1121 }
1122
1123 HIDAPI
1124 ULONG
1125 NTAPI
1126 HidParser_MaxDataListLength(
1127 IN PHID_PARSER Parser,
1128 IN PVOID CollectionContext,
1129 IN HIDP_REPORT_TYPE ReportType)
1130 {
1131 UNIMPLEMENTED
1132 ASSERT(FALSE);
1133 return 0;
1134 }
1135
1136 HIDAPI
1137 NTSTATUS
1138 NTAPI
1139 HidParser_InitializeReportForID(
1140 IN PHID_PARSER Parser,
1141 IN PVOID CollectionContext,
1142 IN HIDP_REPORT_TYPE ReportType,
1143 IN UCHAR ReportID,
1144 IN OUT PCHAR Report,
1145 IN ULONG ReportLength)
1146 {
1147 UNIMPLEMENTED
1148 ASSERT(FALSE);
1149 return STATUS_NOT_IMPLEMENTED;
1150 }
1151
1152 #undef HidParser_GetValueCaps
1153
1154 HIDAPI
1155 NTSTATUS
1156 NTAPI
1157 HidParser_GetValueCaps(
1158 IN PHID_PARSER Parser,
1159 IN PVOID CollectionContext,
1160 HIDP_REPORT_TYPE ReportType,
1161 PHIDP_VALUE_CAPS ValueCaps,
1162 PULONG ValueCapsLength)
1163 {
1164 UNIMPLEMENTED
1165 ASSERT(FALSE);
1166 return STATUS_NOT_IMPLEMENTED;
1167 }