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