2 * PROJECT: ReactOS HID Parser Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/hidparser/hidparser.c
7 * Michael Martin (michael.martin@reactos.org)
8 * Johannes Anderwald (johannes.anderwald@reactos.org)
17 TranslateHidParserStatus(
18 IN HIDPARSER_STATUS Status
)
22 case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES
:
23 return HIDP_STATUS_INTERNAL_ERROR
;
24 case HIDPARSER_STATUS_NOT_IMPLEMENTED
:
25 return HIDP_STATUS_NOT_IMPLEMENTED
;
26 case HIDPARSER_STATUS_REPORT_NOT_FOUND
:
27 return HIDP_STATUS_REPORT_DOES_NOT_EXIST
;
28 case HIDPARSER_STATUS_INVALID_REPORT_LENGTH
:
29 return HIDP_STATUS_INVALID_REPORT_LENGTH
;
30 case HIDPARSER_STATUS_INVALID_REPORT_TYPE
:
31 return HIDP_STATUS_INVALID_REPORT_TYPE
;
32 case HIDPARSER_STATUS_BUFFER_TOO_SMALL
:
33 return HIDP_STATUS_BUFFER_TOO_SMALL
;
34 case HIDPARSER_STATUS_USAGE_NOT_FOUND
:
35 return HIDP_STATUS_USAGE_NOT_FOUND
;
36 case HIDPARSER_STATUS_I8042_TRANS_UNKNOWN
:
37 return HIDP_STATUS_I8042_TRANS_UNKNOWN
;
38 case HIDPARSER_STATUS_COLLECTION_NOT_FOUND
:
39 return HIDP_STATUS_NOT_IMPLEMENTED
; //FIXME
40 case HIDPARSER_STATUS_BAD_LOG_PHY_VALUES
:
41 return HIDP_STATUS_BAD_LOG_PHY_VALUES
;
43 DPRINT1("TranslateHidParserStatus Status %ld not implemented\n", Status
);
44 return HIDP_STATUS_NOT_IMPLEMENTED
;
49 HidParser_GetCollectionDescription(
50 IN PHID_PARSER Parser
,
51 IN PHIDP_REPORT_DESCRIPTOR ReportDesc
,
53 IN POOL_TYPE PoolType
,
54 OUT PHIDP_DEVICE_DESC DeviceDescription
)
56 HIDPARSER_STATUS ParserStatus
;
57 ULONG CollectionCount
;
62 // first parse the report descriptor
64 ParserStatus
= HidParser_ParseReportDescriptor(Parser
, ReportDesc
, DescLength
, &ParserContext
);
65 if (ParserStatus
!= HIDPARSER_STATUS_SUCCESS
)
68 // failed to parse report descriptor
70 Parser
->Debug("[HIDPARSER] Failed to parse report descriptor with %x\n", ParserStatus
);
75 // get collection count
77 CollectionCount
= HidParser_NumberOfTopCollections(ParserContext
);
78 if (CollectionCount
== 0)
81 // no top level collections found
84 return STATUS_NO_DATA_DETECTED
;
90 Parser
->Zero(DeviceDescription
, sizeof(HIDP_DEVICE_DESC
));
93 // allocate collection
95 DeviceDescription
->CollectionDesc
= (PHIDP_COLLECTION_DESC
)Parser
->Alloc(sizeof(HIDP_COLLECTION_DESC
) * CollectionCount
);
96 if (!DeviceDescription
->CollectionDesc
)
101 return STATUS_INSUFFICIENT_RESOURCES
;
105 // allocate report description
107 DeviceDescription
->ReportIDs
= (PHIDP_REPORT_IDS
)Parser
->Alloc(sizeof(HIDP_REPORT_IDS
) * CollectionCount
);
108 if (!DeviceDescription
->ReportIDs
)
113 Parser
->Free(DeviceDescription
->CollectionDesc
);
114 return STATUS_INSUFFICIENT_RESOURCES
;
117 for(Index
= 0; Index
< CollectionCount
; Index
++)
120 // set preparsed data length
122 DeviceDescription
->CollectionDesc
[Index
].PreparsedDataLength
= HidParser_GetContextSize(Parser
, ParserContext
, Index
);
123 ParserStatus
= HidParser_BuildContext(Parser
, ParserContext
, Index
, DeviceDescription
->CollectionDesc
[Index
].PreparsedDataLength
, (PVOID
*)&DeviceDescription
->CollectionDesc
[Index
].PreparsedData
);
124 if (ParserStatus
!= HIDPARSER_STATUS_SUCCESS
)
129 Parser
->Free(DeviceDescription
->CollectionDesc
);
130 Parser
->Free(DeviceDescription
->ReportIDs
);
135 // init report description
137 DeviceDescription
->ReportIDs
[Index
].CollectionNumber
= Index
+ 1;
138 DeviceDescription
->ReportIDs
[Index
].ReportID
= Index
; //FIXME
139 DeviceDescription
->ReportIDs
[Index
].InputLength
= HidParser_GetReportLength((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_INPUT
);
140 DeviceDescription
->ReportIDs
[Index
].OutputLength
= HidParser_GetReportLength((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_OUTPUT
);
141 DeviceDescription
->ReportIDs
[Index
].FeatureLength
= HidParser_GetReportLength((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_FEATURE
);
144 DeviceDescription
->ReportIDs
[Index
].InputLength
+= (HidParser_UsesReportId((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_INPUT
) ? 1 : 0);
145 DeviceDescription
->ReportIDs
[Index
].OutputLength
+= (HidParser_UsesReportId((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_OUTPUT
) ? 1 : 0);
146 DeviceDescription
->ReportIDs
[Index
].FeatureLength
+= (HidParser_UsesReportId((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_FEATURE
) ? 1 : 0);
150 // init collection description
152 DeviceDescription
->CollectionDesc
[Index
].CollectionNumber
= Index
+ 1;
155 // get collection usage page
157 ParserStatus
= HidParser_GetCollectionUsagePage((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, &DeviceDescription
->CollectionDesc
[Index
].Usage
, &DeviceDescription
->CollectionDesc
[Index
].UsagePage
);
158 if (ParserStatus
!= HIDPARSER_STATUS_SUCCESS
)
160 // collection not found
161 Parser
->Free(DeviceDescription
->CollectionDesc
);
162 Parser
->Free(DeviceDescription
->ReportIDs
);
167 // windows seems to prepend the report id, regardless if it is required
169 DeviceDescription
->CollectionDesc
[Index
].CollectionNumber
= Index
+ 1;
170 DeviceDescription
->CollectionDesc
[Index
].InputLength
= DeviceDescription
->ReportIDs
[Index
].InputLength
;
171 DeviceDescription
->CollectionDesc
[Index
].OutputLength
= DeviceDescription
->ReportIDs
[Index
].OutputLength
;
172 DeviceDescription
->CollectionDesc
[Index
].FeatureLength
= DeviceDescription
->ReportIDs
[Index
].FeatureLength
;
174 DeviceDescription
->CollectionDesc
[Index
].InputLength
+= (HidParser_UsesReportId((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_INPUT
) == FALSE
? 1 : 0);
175 DeviceDescription
->CollectionDesc
[Index
].OutputLength
+= (HidParser_UsesReportId((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_OUTPUT
) == FALSE
? 1 : 0);
176 DeviceDescription
->CollectionDesc
[Index
].FeatureLength
+= (HidParser_UsesReportId((PVOID
)DeviceDescription
->CollectionDesc
[Index
].PreparsedData
, HID_REPORT_TYPE_FEATURE
) == FALSE
? 1 : 0);
182 // store collection & report count
184 DeviceDescription
->CollectionDescLength
= CollectionCount
;
185 DeviceDescription
->ReportIDsLength
= CollectionCount
;
190 return STATUS_SUCCESS
;
195 HidParser_FreeCollectionDescription(
196 IN PHID_PARSER Parser
,
197 IN PHIDP_DEVICE_DESC DeviceDescription
)
202 // first free all context
204 for(Index
= 0; Index
< DeviceDescription
->CollectionDescLength
; Index
++)
207 // free collection context
209 Parser
->Free(DeviceDescription
->CollectionDesc
[Index
].PreparsedData
);
213 // now free collection description
215 Parser
->Free(DeviceDescription
->CollectionDesc
);
218 // free report description
220 Parser
->Free(DeviceDescription
->ReportIDs
);
227 IN PHID_PARSER Parser
,
228 IN PVOID CollectionContext
,
229 OUT PHIDP_CAPS Capabilities
)
234 Parser
->Zero(Capabilities
, sizeof(HIDP_CAPS
));
239 HidParser_GetCollectionUsagePage(CollectionContext
, &Capabilities
->Usage
, &Capabilities
->UsagePage
);
240 Capabilities
->InputReportByteLength
= HidParser_GetReportLength(CollectionContext
, HID_REPORT_TYPE_INPUT
);
241 Capabilities
->OutputReportByteLength
= HidParser_GetReportLength(CollectionContext
, HID_REPORT_TYPE_OUTPUT
);
242 Capabilities
->FeatureReportByteLength
= HidParser_GetReportLength(CollectionContext
, HID_REPORT_TYPE_FEATURE
);
245 // always pre-prend report id
247 Capabilities
->InputReportByteLength
= (Capabilities
->InputReportByteLength
> 0 ? Capabilities
->InputReportByteLength
+ 1 : 0);
248 Capabilities
->OutputReportByteLength
= (Capabilities
->OutputReportByteLength
> 0 ? Capabilities
->OutputReportByteLength
+ 1 : 0);
249 Capabilities
->FeatureReportByteLength
= (Capabilities
->FeatureReportByteLength
> 0 ? Capabilities
->FeatureReportByteLength
+ 1 : 0);
252 // get number of link collection nodes
254 Capabilities
->NumberLinkCollectionNodes
= HidParser_GetTotalCollectionCount(CollectionContext
);
259 Capabilities
->NumberInputDataIndices
= HidParser_GetReportItemTypeCountFromReportType(CollectionContext
, HID_REPORT_TYPE_INPUT
, TRUE
);
260 Capabilities
->NumberOutputDataIndices
= HidParser_GetReportItemTypeCountFromReportType(CollectionContext
, HID_REPORT_TYPE_OUTPUT
, TRUE
);
261 Capabilities
->NumberFeatureDataIndices
= HidParser_GetReportItemTypeCountFromReportType(CollectionContext
, HID_REPORT_TYPE_FEATURE
, TRUE
);
266 Capabilities
->NumberInputValueCaps
= HidParser_GetReportItemTypeCountFromReportType(CollectionContext
, HID_REPORT_TYPE_INPUT
, FALSE
);
267 Capabilities
->NumberOutputValueCaps
= HidParser_GetReportItemTypeCountFromReportType(CollectionContext
, HID_REPORT_TYPE_OUTPUT
, FALSE
);
268 Capabilities
->NumberFeatureValueCaps
= HidParser_GetReportItemTypeCountFromReportType(CollectionContext
, HID_REPORT_TYPE_FEATURE
, FALSE
);
274 Capabilities
->NumberInputButtonCaps
= HidParser_GetReportItemCountFromReportType(CollectionContext
, HID_REPORT_TYPE_INPUT
);
275 Capabilities
->NumberOutputButtonCaps
= HidParser_GetReportItemCountFromReportType(CollectionContext
, HID_REPORT_TYPE_OUTPUT
);
276 Capabilities
->NumberFeatureButtonCaps
= HidParser_GetReportItemCountFromReportType(CollectionContext
, HID_REPORT_TYPE_FEATURE
);
281 return HIDP_STATUS_SUCCESS
;
287 HidParser_MaxUsageListLength(
288 IN PHID_PARSER Parser
,
289 IN PVOID CollectionContext
,
290 IN HIDP_REPORT_TYPE ReportType
,
291 IN USAGE UsagePage OPTIONAL
)
294 // FIXME test what should be returned when usage page is not defined
296 if (UsagePage
== HID_USAGE_PAGE_UNDEFINED
)
309 if (ReportType
== HidP_Input
)
314 return HidParser_GetMaxUsageListLengthWithReportAndPage(CollectionContext
, HID_REPORT_TYPE_INPUT
, UsagePage
);
316 else if (ReportType
== HidP_Output
)
321 return HidParser_GetMaxUsageListLengthWithReportAndPage(CollectionContext
, HID_REPORT_TYPE_OUTPUT
, UsagePage
);
323 else if (ReportType
== HidP_Feature
)
328 return HidParser_GetMaxUsageListLengthWithReportAndPage(CollectionContext
, HID_REPORT_TYPE_FEATURE
, UsagePage
);
333 // invalid report type
339 #undef HidParser_GetButtonCaps
344 HidParser_GetButtonCaps(
345 IN PHID_PARSER Parser
,
346 IN PVOID CollectionContext
,
347 IN HIDP_REPORT_TYPE ReportType
,
348 IN PHIDP_BUTTON_CAPS ButtonCaps
,
349 IN PUSHORT ButtonCapsLength
)
351 return HidParser_GetSpecificButtonCaps(Parser
, CollectionContext
, ReportType
, HID_USAGE_PAGE_UNDEFINED
, HIDP_LINK_COLLECTION_UNSPECIFIED
, HID_USAGE_PAGE_UNDEFINED
, ButtonCaps
, (PULONG
)ButtonCapsLength
);
357 HidParser_GetSpecificValueCaps(
358 IN PHID_PARSER Parser
,
359 IN PVOID CollectionContext
,
360 IN HIDP_REPORT_TYPE ReportType
,
362 IN USHORT LinkCollection
,
364 OUT PHIDP_VALUE_CAPS ValueCaps
,
365 IN OUT PUSHORT ValueCapsLength
)
367 HIDPARSER_STATUS ParserStatus
;
370 // FIXME: implement searching in specific collection
372 ASSERT(LinkCollection
== HIDP_LINK_COLLECTION_UNSPECIFIED
);
374 if (ReportType
== HidP_Input
)
379 ParserStatus
= HidParser_GetSpecificValueCapsWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_INPUT
, UsagePage
, Usage
, ValueCaps
, ValueCapsLength
);
381 else if (ReportType
== HidP_Output
)
386 ParserStatus
= HidParser_GetSpecificValueCapsWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_OUTPUT
, UsagePage
, Usage
, ValueCaps
, ValueCapsLength
);
388 else if (ReportType
== HidP_Feature
)
393 ParserStatus
= HidParser_GetSpecificValueCapsWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_FEATURE
, UsagePage
, Usage
, ValueCaps
, ValueCapsLength
);
398 // invalid report type
400 return HIDP_STATUS_INVALID_REPORT_TYPE
;
404 if (ParserStatus
== HIDPARSER_STATUS_SUCCESS
)
409 return HIDP_STATUS_SUCCESS
;
415 return TranslateHidParserStatus(ParserStatus
);
421 HidParser_UsageListDifference(
422 IN PUSAGE PreviousUsageList
,
423 IN PUSAGE CurrentUsageList
,
424 OUT PUSAGE BreakUsageList
,
425 OUT PUSAGE MakeUsageList
,
426 IN ULONG UsageListLength
)
428 ULONG Index
, SubIndex
, bFound
, BreakUsageIndex
= 0, MakeUsageIndex
= 0;
429 USAGE CurrentUsage
, Usage
;
436 /* get current usage */
437 CurrentUsage
= PreviousUsageList
[Index
];
439 /* is the end of list reached? */
443 /* start searching in current usage list */
448 /* get usage of current list */
449 Usage
= CurrentUsageList
[SubIndex
];
451 /* end of list reached? */
455 /* check if it matches the current one */
456 if (CurrentUsage
== Usage
)
463 /* move to next usage */
465 }while(SubIndex
< UsageListLength
);
467 /* was the usage found ?*/
470 /* store it in the break usage list */
471 BreakUsageList
[BreakUsageIndex
] = CurrentUsage
;
475 /* move to next usage */
478 }while(Index
< UsageListLength
);
480 /* now process the new items */
484 /* get current usage */
485 CurrentUsage
= CurrentUsageList
[Index
];
487 /* is the end of list reached? */
491 /* start searching in current usage list */
496 /* get usage of previous list */
497 Usage
= PreviousUsageList
[SubIndex
];
499 /* end of list reached? */
503 /* check if it matches the current one */
504 if (CurrentUsage
== Usage
)
511 /* move to next usage */
513 }while(SubIndex
< UsageListLength
);
515 /* was the usage found ?*/
518 /* store it in the make usage list */
519 MakeUsageList
[MakeUsageIndex
] = CurrentUsage
;
523 /* move to next usage */
526 }while(Index
< UsageListLength
);
529 /* does the break list contain empty entries */
530 if (BreakUsageIndex
< UsageListLength
)
532 /* zeroize entries */
533 RtlZeroMemory(&BreakUsageList
[BreakUsageIndex
], sizeof(USAGE
) * (UsageListLength
- BreakUsageIndex
));
536 /* does the make usage list contain empty entries */
537 if (MakeUsageIndex
< UsageListLength
)
539 /* zeroize entries */
540 RtlZeroMemory(&MakeUsageList
[MakeUsageIndex
], sizeof(USAGE
) * (UsageListLength
- MakeUsageIndex
));
544 return HIDP_STATUS_SUCCESS
;
551 IN PHID_PARSER Parser
,
552 IN PVOID CollectionContext
,
553 IN HIDP_REPORT_TYPE ReportType
,
555 IN USHORT LinkCollection OPTIONAL
,
556 OUT USAGE
*UsageList
,
557 IN OUT PULONG UsageLength
,
559 IN ULONG ReportLength
)
561 HIDPARSER_STATUS ParserStatus
;
564 // FIXME: implement searching in specific collection
566 ASSERT(LinkCollection
== HIDP_LINK_COLLECTION_UNSPECIFIED
);
568 if (ReportType
== HidP_Input
)
573 ParserStatus
= HidParser_GetUsagesWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_INPUT
, UsagePage
, UsageList
, UsageLength
, Report
, ReportLength
);
575 else if (ReportType
== HidP_Output
)
580 ParserStatus
= HidParser_GetUsagesWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_OUTPUT
, UsagePage
, UsageList
, UsageLength
, Report
, ReportLength
);
582 else if (ReportType
== HidP_Feature
)
587 ParserStatus
= HidParser_GetUsagesWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_FEATURE
, UsagePage
, UsageList
, UsageLength
, Report
, ReportLength
);
592 // invalid report type
594 return HIDP_STATUS_INVALID_REPORT_TYPE
;
597 if (ParserStatus
== HIDPARSER_STATUS_SUCCESS
)
602 return HIDP_STATUS_SUCCESS
;
608 return TranslateHidParserStatus(ParserStatus
);
614 HidParser_GetScaledUsageValue(
615 IN PHID_PARSER Parser
,
616 IN PVOID CollectionContext
,
617 IN HIDP_REPORT_TYPE ReportType
,
619 IN USHORT LinkCollection OPTIONAL
,
621 OUT PLONG UsageValue
,
623 IN ULONG ReportLength
)
625 HIDPARSER_STATUS ParserStatus
;
628 // FIXME: implement searching in specific collection
630 ASSERT(LinkCollection
== HIDP_LINK_COLLECTION_UNSPECIFIED
);
632 if (ReportType
== HidP_Input
)
637 ParserStatus
= HidParser_GetScaledUsageValueWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_INPUT
, UsagePage
, Usage
, UsageValue
, Report
, ReportLength
);
639 else if (ReportType
== HidP_Output
)
644 ParserStatus
= HidParser_GetScaledUsageValueWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_OUTPUT
, UsagePage
, Usage
, UsageValue
, Report
, ReportLength
);
646 else if (ReportType
== HidP_Feature
)
651 ParserStatus
= HidParser_GetScaledUsageValueWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_FEATURE
, UsagePage
, Usage
, UsageValue
, Report
, ReportLength
);
656 // invalid report type
658 return HIDP_STATUS_INVALID_REPORT_TYPE
;
661 if (ParserStatus
== HIDPARSER_STATUS_SUCCESS
)
666 return HIDP_STATUS_SUCCESS
;
672 return TranslateHidParserStatus(ParserStatus
);
678 HidParser_TranslateUsageAndPagesToI8042ScanCodes(
679 IN PHID_PARSER Parser
,
680 IN PUSAGE_AND_PAGE ChangedUsageList
,
681 IN ULONG UsageListLength
,
682 IN HIDP_KEYBOARD_DIRECTION KeyAction
,
683 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState
,
684 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure
,
685 IN PVOID InsertCodesContext
)
688 HIDPARSER_STATUS Status
= HIDPARSER_STATUS_SUCCESS
;
690 for(Index
= 0; Index
< UsageListLength
; Index
++)
693 // check current usage
695 if (ChangedUsageList
[Index
].UsagePage
== HID_USAGE_PAGE_KEYBOARD
)
698 // process keyboard usage
700 Status
= HidParser_TranslateKbdUsage(Parser
, ChangedUsageList
[Index
].Usage
, KeyAction
, ModifierState
, InsertCodesProcedure
, InsertCodesContext
);
702 else if (ChangedUsageList
[Index
].UsagePage
== HID_USAGE_PAGE_CONSUMER
)
705 // process consumer usage
707 Status
= HidParser_TranslateCustUsage(Parser
, ChangedUsageList
[Index
].Usage
, KeyAction
, ModifierState
, InsertCodesProcedure
, InsertCodesContext
);
712 // invalid page / end of usage list page
714 return HIDP_STATUS_I8042_TRANS_UNKNOWN
;
720 if (Status
!= HIDPARSER_STATUS_SUCCESS
)
725 return TranslateHidParserStatus(Status
);
729 if (Status
!= HIDPARSER_STATUS_SUCCESS
)
734 return TranslateHidParserStatus(Status
);
740 return HIDP_STATUS_SUCCESS
;
747 HidParser_GetUsagesEx(
748 IN PHID_PARSER Parser
,
749 IN PVOID CollectionContext
,
750 IN HIDP_REPORT_TYPE ReportType
,
751 IN USHORT LinkCollection
,
752 OUT PUSAGE_AND_PAGE ButtonList
,
753 IN OUT ULONG
*UsageLength
,
755 IN ULONG ReportLength
)
757 return HidParser_GetUsages(Parser
, CollectionContext
, ReportType
, HID_USAGE_PAGE_UNDEFINED
, LinkCollection
, (PUSAGE
)ButtonList
, UsageLength
, Report
, ReportLength
);
763 HidParser_UsageAndPageListDifference(
764 IN PUSAGE_AND_PAGE PreviousUsageList
,
765 IN PUSAGE_AND_PAGE CurrentUsageList
,
766 OUT PUSAGE_AND_PAGE BreakUsageList
,
767 OUT PUSAGE_AND_PAGE MakeUsageList
,
768 IN ULONG UsageListLength
)
770 ULONG Index
, SubIndex
, BreakUsageListIndex
= 0, MakeUsageListIndex
= 0, bFound
;
771 PUSAGE_AND_PAGE CurrentUsage
, Usage
;
775 /* process removed usages */
779 /* get usage from current index */
780 CurrentUsage
= &PreviousUsageList
[Index
];
782 /* end of list reached? */
783 if (CurrentUsage
->Usage
== 0 && CurrentUsage
->UsagePage
== 0)
786 /* search in current list */
792 Usage
= &CurrentUsageList
[SubIndex
];
794 /* end of list reached? */
795 if (Usage
->Usage
== 0 && Usage
->UsagePage
== 0)
799 if (Usage
->Usage
== CurrentUsage
->Usage
&& Usage
->UsagePage
== CurrentUsage
->UsagePage
)
805 /* move to next index */
808 }while(SubIndex
< UsageListLength
);
812 /* store it in break usage list */
813 BreakUsageList
[BreakUsageListIndex
].Usage
= CurrentUsage
->Usage
;
814 BreakUsageList
[BreakUsageListIndex
].UsagePage
= CurrentUsage
->UsagePage
;
815 BreakUsageListIndex
++;
818 /* move to next index */
821 }while(Index
< UsageListLength
);
823 /* process new usages */
827 /* get usage from current index */
828 CurrentUsage
= &CurrentUsageList
[Index
];
830 /* end of list reached? */
831 if (CurrentUsage
->Usage
== 0 && CurrentUsage
->UsagePage
== 0)
834 /* search in current list */
840 Usage
= &PreviousUsageList
[SubIndex
];
842 /* end of list reached? */
843 if (Usage
->Usage
== 0 && Usage
->UsagePage
== 0)
847 if (Usage
->Usage
== CurrentUsage
->Usage
&& Usage
->UsagePage
== CurrentUsage
->UsagePage
)
853 /* move to next index */
856 }while(SubIndex
< UsageListLength
);
860 /* store it in break usage list */
861 MakeUsageList
[MakeUsageListIndex
].Usage
= CurrentUsage
->Usage
;
862 MakeUsageList
[MakeUsageListIndex
].UsagePage
= CurrentUsage
->UsagePage
;
863 MakeUsageListIndex
++;
866 /* move to next index */
868 }while(Index
< UsageListLength
);
871 /* are there remaining free list entries */
872 if (BreakUsageListIndex
< UsageListLength
)
875 RtlZeroMemory(&BreakUsageList
[BreakUsageListIndex
], (UsageListLength
- BreakUsageListIndex
) * sizeof(USAGE_AND_PAGE
));
878 /* are there remaining free list entries */
879 if (MakeUsageListIndex
< UsageListLength
)
882 RtlZeroMemory(&MakeUsageList
[MakeUsageListIndex
], (UsageListLength
- MakeUsageListIndex
) * sizeof(USAGE_AND_PAGE
));
886 return HIDP_STATUS_SUCCESS
;
892 HidParser_GetSpecificButtonCaps(
893 IN PHID_PARSER Parser
,
894 IN PVOID CollectionContext
,
895 IN HIDP_REPORT_TYPE ReportType
,
897 IN USHORT LinkCollection
,
899 OUT PHIDP_BUTTON_CAPS ButtonCaps
,
900 IN OUT PULONG ButtonCapsLength
)
904 return STATUS_NOT_IMPLEMENTED
;
912 IN PHID_PARSER Parser
,
913 IN PVOID CollectionContext
,
914 IN HIDP_REPORT_TYPE ReportType
,
915 OUT PHIDP_DATA DataList
,
916 IN OUT PULONG DataLength
,
918 IN ULONG ReportLength
)
922 return STATUS_NOT_IMPLEMENTED
;
928 HidParser_GetExtendedAttributes(
929 IN PHID_PARSER Parser
,
930 IN PVOID CollectionContext
,
931 IN HIDP_REPORT_TYPE ReportType
,
933 OUT PHIDP_EXTENDED_ATTRIBUTES Attributes
,
934 IN OUT PULONG LengthAttributes
)
938 return STATUS_NOT_IMPLEMENTED
;
944 HidParser_GetLinkCollectionNodes(
945 IN PHID_PARSER Parser
,
946 IN PVOID CollectionContext
,
947 OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes
,
948 IN OUT PULONG LinkCollectionNodesLength
)
952 return STATUS_NOT_IMPLEMENTED
;
958 HidParser_GetUsageValue(
959 IN PHID_PARSER Parser
,
960 IN PVOID CollectionContext
,
961 IN HIDP_REPORT_TYPE ReportType
,
963 IN USHORT LinkCollection
,
965 OUT PULONG UsageValue
,
967 IN ULONG ReportLength
)
969 HIDPARSER_STATUS ParserStatus
;
972 // FIXME: implement searching in specific collection
974 ASSERT(LinkCollection
== HIDP_LINK_COLLECTION_UNSPECIFIED
);
976 if (ReportType
== HidP_Input
)
981 ParserStatus
= HidParser_GetUsageValueWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_INPUT
, UsagePage
, Usage
, UsageValue
, Report
, ReportLength
);
983 else if (ReportType
== HidP_Output
)
988 ParserStatus
= HidParser_GetUsageValueWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_OUTPUT
, UsagePage
, Usage
, UsageValue
, Report
, ReportLength
);
990 else if (ReportType
== HidP_Feature
)
995 ParserStatus
= HidParser_GetUsageValueWithReport(Parser
, CollectionContext
, HID_REPORT_TYPE_FEATURE
, UsagePage
, Usage
, UsageValue
, Report
, ReportLength
);
1000 // invalid report type
1002 return HIDP_STATUS_INVALID_REPORT_TYPE
;
1005 if (ParserStatus
== HIDPARSER_STATUS_SUCCESS
)
1010 return HIDP_STATUS_SUCCESS
;
1016 return TranslateHidParserStatus(ParserStatus
);
1021 HidParser_SysPowerEvent(
1022 IN PHID_PARSER Parser
,
1023 IN PVOID CollectionContext
,
1025 IN USHORT HidPacketLength
,
1026 OUT PULONG OutputBuffer
)
1030 return STATUS_NOT_IMPLEMENTED
;
1035 HidParser_SysPowerCaps (
1036 IN PHID_PARSER Parser
,
1037 IN PVOID CollectionContext
,
1038 OUT PULONG OutputBuffer
)
1042 return STATUS_NOT_IMPLEMENTED
;
1048 HidParser_GetUsageValueArray(
1049 IN PHID_PARSER Parser
,
1050 IN PVOID CollectionContext
,
1051 IN HIDP_REPORT_TYPE ReportType
,
1053 IN USHORT LinkCollection OPTIONAL
,
1055 OUT PCHAR UsageValue
,
1056 IN USHORT UsageValueByteLength
,
1058 IN ULONG ReportLength
)
1062 return STATUS_NOT_IMPLEMENTED
;
1068 HidParser_UnsetUsages(
1069 IN PHID_PARSER Parser
,
1070 IN PVOID CollectionContext
,
1071 IN HIDP_REPORT_TYPE ReportType
,
1073 IN USHORT LinkCollection
,
1074 IN PUSAGE UsageList
,
1075 IN OUT PULONG UsageLength
,
1076 IN OUT PCHAR Report
,
1077 IN ULONG ReportLength
)
1081 return STATUS_NOT_IMPLEMENTED
;
1087 HidParser_TranslateUsagesToI8042ScanCodes(
1088 IN PUSAGE ChangedUsageList
,
1089 IN ULONG UsageListLength
,
1090 IN HIDP_KEYBOARD_DIRECTION KeyAction
,
1091 IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState
,
1092 IN PHIDP_INSERT_SCANCODES InsertCodesProcedure
,
1093 IN PVOID InsertCodesContext
)
1097 return STATUS_NOT_IMPLEMENTED
;
1103 HidParser_SetUsages(
1104 IN PHID_PARSER Parser
,
1105 IN PVOID CollectionContext
,
1106 IN HIDP_REPORT_TYPE ReportType
,
1108 IN USHORT LinkCollection
,
1109 IN PUSAGE UsageList
,
1110 IN OUT PULONG UsageLength
,
1111 IN OUT PCHAR Report
,
1112 IN ULONG ReportLength
)
1116 return STATUS_NOT_IMPLEMENTED
;
1122 HidParser_SetUsageValueArray(
1123 IN PHID_PARSER Parser
,
1124 IN PVOID CollectionContext
,
1125 IN HIDP_REPORT_TYPE ReportType
,
1127 IN USHORT LinkCollection OPTIONAL
,
1129 IN PCHAR UsageValue
,
1130 IN USHORT UsageValueByteLength
,
1132 IN ULONG ReportLength
)
1136 return STATUS_NOT_IMPLEMENTED
;
1142 HidParser_SetUsageValue(
1143 IN PHID_PARSER Parser
,
1144 IN PVOID CollectionContext
,
1145 IN HIDP_REPORT_TYPE ReportType
,
1147 IN USHORT LinkCollection
,
1149 IN ULONG UsageValue
,
1150 IN OUT PCHAR Report
,
1151 IN ULONG ReportLength
)
1155 return STATUS_NOT_IMPLEMENTED
;
1161 HidParser_SetScaledUsageValue(
1162 IN PHID_PARSER Parser
,
1163 IN PVOID CollectionContext
,
1164 IN HIDP_REPORT_TYPE ReportType
,
1166 IN USHORT LinkCollection OPTIONAL
,
1169 IN OUT PCHAR Report
,
1170 IN ULONG ReportLength
)
1174 return STATUS_NOT_IMPLEMENTED
;
1181 IN PHID_PARSER Parser
,
1182 IN PVOID CollectionContext
,
1183 IN HIDP_REPORT_TYPE ReportType
,
1184 IN PHIDP_DATA DataList
,
1185 IN OUT PULONG DataLength
,
1186 IN OUT PCHAR Report
,
1187 IN ULONG ReportLength
)
1191 return STATUS_NOT_IMPLEMENTED
;
1197 HidParser_MaxDataListLength(
1198 IN PHID_PARSER Parser
,
1199 IN PVOID CollectionContext
,
1200 IN HIDP_REPORT_TYPE ReportType
)
1210 HidParser_InitializeReportForID(
1211 IN PHID_PARSER Parser
,
1212 IN PVOID CollectionContext
,
1213 IN HIDP_REPORT_TYPE ReportType
,
1215 IN OUT PCHAR Report
,
1216 IN ULONG ReportLength
)
1220 return STATUS_NOT_IMPLEMENTED
;
1223 #undef HidParser_GetValueCaps
1228 HidParser_GetValueCaps(
1229 IN PHID_PARSER Parser
,
1230 IN PVOID CollectionContext
,
1231 HIDP_REPORT_TYPE ReportType
,
1232 PHIDP_VALUE_CAPS ValueCaps
,
1233 PULONG ValueCapsLength
)
1237 return STATUS_NOT_IMPLEMENTED
;