[HIDPARSER]
[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
687 //
688 DPRINT1("[HIDPARSE] Error unexpected usage page %x\n", ChangedUsageList[Index].UsagePage);
689 return HIDP_STATUS_I8042_TRANS_UNKNOWN;
690 }
691
692 //
693 // check status
694 //
695 if (Status != HIDPARSER_STATUS_SUCCESS)
696 {
697 //
698 // failed
699 //
700 return TranslateHidParserStatus(Status);
701 }
702 }
703
704 if (Status != HIDPARSER_STATUS_SUCCESS)
705 {
706 //
707 // failed
708 //
709 return TranslateHidParserStatus(Status);
710 }
711
712 //
713 // done
714 //
715 return HIDP_STATUS_SUCCESS;
716 }
717
718
719 HIDAPI
720 NTSTATUS
721 NTAPI
722 HidParser_GetUsagesEx(
723 IN PHID_PARSER Parser,
724 IN PVOID CollectionContext,
725 IN HIDP_REPORT_TYPE ReportType,
726 IN USHORT LinkCollection,
727 OUT PUSAGE_AND_PAGE ButtonList,
728 IN OUT ULONG *UsageLength,
729 IN PCHAR Report,
730 IN ULONG ReportLength)
731 {
732 return HidParser_GetUsages(Parser, CollectionContext, ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, (PUSAGE)ButtonList, UsageLength, Report, ReportLength);
733 }
734
735 HIDAPI
736 NTSTATUS
737 NTAPI
738 HidParser_UsageAndPageListDifference(
739 IN PUSAGE_AND_PAGE PreviousUsageList,
740 IN PUSAGE_AND_PAGE CurrentUsageList,
741 OUT PUSAGE_AND_PAGE BreakUsageList,
742 OUT PUSAGE_AND_PAGE MakeUsageList,
743 IN ULONG UsageListLength)
744 {
745 ULONG Index, SubIndex, BreakUsageListIndex = 0, MakeUsageListIndex = 0, bFound;
746 PUSAGE_AND_PAGE CurrentUsage, Usage;
747
748 if (UsageListLength)
749 {
750 /* process removed usages */
751 Index = 0;
752 do
753 {
754 /* get usage from current index */
755 CurrentUsage = &PreviousUsageList[Index];
756
757 /* end of list reached? */
758 if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
759 break;
760
761 /* search in current list */
762 SubIndex = 0;
763 bFound = FALSE;
764 do
765 {
766 /* get usage */
767 Usage = &CurrentUsageList[SubIndex];
768
769 /* end of list reached? */
770 if (Usage->Usage == 0 && Usage->UsagePage == 0)
771 break;
772
773 /* does it match */
774 if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
775 {
776 /* found match */
777 bFound = TRUE;
778 }
779
780 /* move to next index */
781 SubIndex++;
782
783 }while(SubIndex < UsageListLength);
784
785 if (!bFound)
786 {
787 /* store it in break usage list */
788 BreakUsageList[BreakUsageListIndex].Usage = CurrentUsage->Usage;
789 BreakUsageList[BreakUsageListIndex].UsagePage = CurrentUsage->UsagePage;
790 BreakUsageListIndex++;
791 }
792
793 /* move to next index */
794 Index++;
795
796 }while(Index < UsageListLength);
797
798 /* process new usages */
799 Index = 0;
800 do
801 {
802 /* get usage from current index */
803 CurrentUsage = &CurrentUsageList[Index];
804
805 /* end of list reached? */
806 if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
807 break;
808
809 /* search in current list */
810 SubIndex = 0;
811 bFound = FALSE;
812 do
813 {
814 /* get usage */
815 Usage = &PreviousUsageList[SubIndex];
816
817 /* end of list reached? */
818 if (Usage->Usage == 0 && Usage->UsagePage == 0)
819 break;
820
821 /* does it match */
822 if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
823 {
824 /* found match */
825 bFound = TRUE;
826 }
827
828 /* move to next index */
829 SubIndex++;
830
831 }while(SubIndex < UsageListLength);
832
833 if (!bFound)
834 {
835 /* store it in break usage list */
836 MakeUsageList[MakeUsageListIndex].Usage = CurrentUsage->Usage;
837 MakeUsageList[MakeUsageListIndex].UsagePage = CurrentUsage->UsagePage;
838 MakeUsageListIndex++;
839 }
840
841 /* move to next index */
842 Index++;
843 }while(Index < UsageListLength);
844 }
845
846 /* are there remaining free list entries */
847 if (BreakUsageListIndex < UsageListLength)
848 {
849 /* zero them */
850 RtlZeroMemory(&BreakUsageList[BreakUsageListIndex], (UsageListLength - BreakUsageListIndex) * sizeof(USAGE_AND_PAGE));
851 }
852
853 /* are there remaining free list entries */
854 if (MakeUsageListIndex < UsageListLength)
855 {
856 /* zero them */
857 RtlZeroMemory(&MakeUsageList[MakeUsageListIndex], (UsageListLength - MakeUsageListIndex) * sizeof(USAGE_AND_PAGE));
858 }
859
860 /* done */
861 return HIDP_STATUS_SUCCESS;
862 }
863
864 HIDAPI
865 NTSTATUS
866 NTAPI
867 HidParser_GetSpecificButtonCaps(
868 IN PHID_PARSER Parser,
869 IN PVOID CollectionContext,
870 IN HIDP_REPORT_TYPE ReportType,
871 IN USAGE UsagePage,
872 IN USHORT LinkCollection,
873 IN USAGE Usage,
874 OUT PHIDP_BUTTON_CAPS ButtonCaps,
875 IN OUT PULONG ButtonCapsLength)
876 {
877 UNIMPLEMENTED
878 ASSERT(FALSE);
879 return STATUS_NOT_IMPLEMENTED;
880 }
881
882
883 HIDAPI
884 NTSTATUS
885 NTAPI
886 HidParser_GetData(
887 IN PHID_PARSER Parser,
888 IN PVOID CollectionContext,
889 IN HIDP_REPORT_TYPE ReportType,
890 OUT PHIDP_DATA DataList,
891 IN OUT PULONG DataLength,
892 IN PCHAR Report,
893 IN ULONG ReportLength)
894 {
895 UNIMPLEMENTED
896 ASSERT(FALSE);
897 return STATUS_NOT_IMPLEMENTED;
898 }
899
900 HIDAPI
901 NTSTATUS
902 NTAPI
903 HidParser_GetExtendedAttributes(
904 IN PHID_PARSER Parser,
905 IN PVOID CollectionContext,
906 IN HIDP_REPORT_TYPE ReportType,
907 IN USHORT DataIndex,
908 OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
909 IN OUT PULONG LengthAttributes)
910 {
911 UNIMPLEMENTED
912 ASSERT(FALSE);
913 return STATUS_NOT_IMPLEMENTED;
914 }
915
916 HIDAPI
917 NTSTATUS
918 NTAPI
919 HidParser_GetLinkCollectionNodes(
920 IN PHID_PARSER Parser,
921 IN PVOID CollectionContext,
922 OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
923 IN OUT PULONG LinkCollectionNodesLength)
924 {
925 UNIMPLEMENTED
926 ASSERT(FALSE);
927 return STATUS_NOT_IMPLEMENTED;
928 }
929
930 HIDAPI
931 NTSTATUS
932 NTAPI
933 HidParser_GetUsageValue(
934 IN PHID_PARSER Parser,
935 IN PVOID CollectionContext,
936 IN HIDP_REPORT_TYPE ReportType,
937 IN USAGE UsagePage,
938 IN USHORT LinkCollection,
939 IN USAGE Usage,
940 OUT PULONG UsageValue,
941 IN PCHAR Report,
942 IN ULONG ReportLength)
943 {
944 UNIMPLEMENTED
945 ASSERT(FALSE);
946 return STATUS_NOT_IMPLEMENTED;
947 }
948
949 NTSTATUS
950 NTAPI
951 HidParser_SysPowerEvent(
952 IN PHID_PARSER Parser,
953 IN PVOID CollectionContext,
954 IN PCHAR HidPacket,
955 IN USHORT HidPacketLength,
956 OUT PULONG OutputBuffer)
957 {
958 UNIMPLEMENTED
959 ASSERT(FALSE);
960 return STATUS_NOT_IMPLEMENTED;
961 }
962
963 NTSTATUS
964 NTAPI
965 HidParser_SysPowerCaps (
966 IN PHID_PARSER Parser,
967 IN PVOID CollectionContext,
968 OUT PULONG OutputBuffer)
969 {
970 UNIMPLEMENTED
971 ASSERT(FALSE);
972 return STATUS_NOT_IMPLEMENTED;
973 }
974
975 HIDAPI
976 NTSTATUS
977 NTAPI
978 HidParser_GetUsageValueArray(
979 IN PHID_PARSER Parser,
980 IN PVOID CollectionContext,
981 IN HIDP_REPORT_TYPE ReportType,
982 IN USAGE UsagePage,
983 IN USHORT LinkCollection OPTIONAL,
984 IN USAGE Usage,
985 OUT PCHAR UsageValue,
986 IN USHORT UsageValueByteLength,
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 PHID_PARSER Parser,
1000 IN PVOID CollectionContext,
1001 IN HIDP_REPORT_TYPE ReportType,
1002 IN USAGE UsagePage,
1003 IN USHORT LinkCollection,
1004 IN PUSAGE UsageList,
1005 IN OUT PULONG UsageLength,
1006 IN OUT PCHAR Report,
1007 IN ULONG ReportLength)
1008 {
1009 UNIMPLEMENTED
1010 ASSERT(FALSE);
1011 return STATUS_NOT_IMPLEMENTED;
1012 }
1013
1014 HIDAPI
1015 NTSTATUS
1016 NTAPI
1017 HidParser_TranslateUsagesToI8042ScanCodes(
1018 IN PUSAGE ChangedUsageList,
1019 IN ULONG UsageListLength,
1020 IN HIDP_KEYBOARD_DIRECTION KeyAction,
1021 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
1022 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
1023 IN PVOID InsertCodesContext)
1024 {
1025 UNIMPLEMENTED
1026 ASSERT(FALSE);
1027 return STATUS_NOT_IMPLEMENTED;
1028 }
1029
1030 HIDAPI
1031 NTSTATUS
1032 NTAPI
1033 HidParser_SetUsages(
1034 IN PHID_PARSER Parser,
1035 IN PVOID CollectionContext,
1036 IN HIDP_REPORT_TYPE ReportType,
1037 IN USAGE UsagePage,
1038 IN USHORT LinkCollection,
1039 IN PUSAGE UsageList,
1040 IN OUT PULONG UsageLength,
1041 IN OUT PCHAR Report,
1042 IN ULONG ReportLength)
1043 {
1044 UNIMPLEMENTED
1045 ASSERT(FALSE);
1046 return STATUS_NOT_IMPLEMENTED;
1047 }
1048
1049 HIDAPI
1050 NTSTATUS
1051 NTAPI
1052 HidParser_SetUsageValueArray(
1053 IN PHID_PARSER Parser,
1054 IN PVOID CollectionContext,
1055 IN HIDP_REPORT_TYPE ReportType,
1056 IN USAGE UsagePage,
1057 IN USHORT LinkCollection OPTIONAL,
1058 IN USAGE Usage,
1059 IN PCHAR UsageValue,
1060 IN USHORT UsageValueByteLength,
1061 OUT PCHAR Report,
1062 IN ULONG ReportLength)
1063 {
1064 UNIMPLEMENTED
1065 ASSERT(FALSE);
1066 return STATUS_NOT_IMPLEMENTED;
1067 }
1068
1069 HIDAPI
1070 NTSTATUS
1071 NTAPI
1072 HidParser_SetUsageValue(
1073 IN PHID_PARSER Parser,
1074 IN PVOID CollectionContext,
1075 IN HIDP_REPORT_TYPE ReportType,
1076 IN USAGE UsagePage,
1077 IN USHORT LinkCollection,
1078 IN USAGE Usage,
1079 IN ULONG UsageValue,
1080 IN OUT PCHAR Report,
1081 IN ULONG ReportLength)
1082 {
1083 UNIMPLEMENTED
1084 ASSERT(FALSE);
1085 return STATUS_NOT_IMPLEMENTED;
1086 }
1087
1088 HIDAPI
1089 NTSTATUS
1090 NTAPI
1091 HidParser_SetScaledUsageValue(
1092 IN PHID_PARSER Parser,
1093 IN PVOID CollectionContext,
1094 IN HIDP_REPORT_TYPE ReportType,
1095 IN USAGE UsagePage,
1096 IN USHORT LinkCollection OPTIONAL,
1097 IN USAGE Usage,
1098 IN LONG UsageValue,
1099 IN OUT PCHAR Report,
1100 IN ULONG ReportLength)
1101 {
1102 UNIMPLEMENTED
1103 ASSERT(FALSE);
1104 return STATUS_NOT_IMPLEMENTED;
1105 }
1106
1107 HIDAPI
1108 NTSTATUS
1109 NTAPI
1110 HidParser_SetData(
1111 IN PHID_PARSER Parser,
1112 IN PVOID CollectionContext,
1113 IN HIDP_REPORT_TYPE ReportType,
1114 IN PHIDP_DATA DataList,
1115 IN OUT PULONG DataLength,
1116 IN OUT PCHAR Report,
1117 IN ULONG ReportLength)
1118 {
1119 UNIMPLEMENTED
1120 ASSERT(FALSE);
1121 return STATUS_NOT_IMPLEMENTED;
1122 }
1123
1124 HIDAPI
1125 ULONG
1126 NTAPI
1127 HidParser_MaxDataListLength(
1128 IN PHID_PARSER Parser,
1129 IN PVOID CollectionContext,
1130 IN HIDP_REPORT_TYPE ReportType)
1131 {
1132 UNIMPLEMENTED
1133 ASSERT(FALSE);
1134 return 0;
1135 }
1136
1137 HIDAPI
1138 NTSTATUS
1139 NTAPI
1140 HidParser_InitializeReportForID(
1141 IN PHID_PARSER Parser,
1142 IN PVOID CollectionContext,
1143 IN HIDP_REPORT_TYPE ReportType,
1144 IN UCHAR ReportID,
1145 IN OUT PCHAR Report,
1146 IN ULONG ReportLength)
1147 {
1148 UNIMPLEMENTED
1149 ASSERT(FALSE);
1150 return STATUS_NOT_IMPLEMENTED;
1151 }
1152
1153 #undef HidParser_GetValueCaps
1154
1155 HIDAPI
1156 NTSTATUS
1157 NTAPI
1158 HidParser_GetValueCaps(
1159 IN PHID_PARSER Parser,
1160 IN PVOID CollectionContext,
1161 HIDP_REPORT_TYPE ReportType,
1162 PHIDP_VALUE_CAPS ValueCaps,
1163 PULONG ValueCapsLength)
1164 {
1165 UNIMPLEMENTED
1166 ASSERT(FALSE);
1167 return STATUS_NOT_IMPLEMENTED;
1168 }