--- /dev/null
--- /dev/null
-
- VOID
- HidP_FreeCollectionDescription (
- IN PHIDP_DEVICE_DESC DeviceDescription)
+ + /*
+ + * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
+ + * LICENSE: GPL - See COPYING in the top level directory
+ + * FILE: drivers/usb/hidparse/hidparse.c
+ + * PURPOSE: HID Parser
+ + * PROGRAMMERS:
+ + * Michael Martin (michael.martin@reactos.org)
+ + * Johannes Anderwald (johannes.anderwald@reactos.org)
+ + */
+ +
+ + #include "hidparse.h"
+ +
- DPRINT1("HidP_FreeCollectionDescription DeviceDescription %p\n", DeviceDescription);
++++++++ + PVOID
++++++++ + NTAPI
++++++++ + AllocFunction(
++++++++ + IN ULONG ItemSize)
+++++++ + {
- // free collection
++++++++ + PVOID Item = ExAllocatePool(NonPagedPool, ItemSize);
++++++++ + if (Item)
++++++++ + {
++++++++ + //
++++++++ + // zero item
++++++++ + //
++++++++ + RtlZeroMemory(Item, ItemSize);
++++++++ + }
+++++++ +
+++++++ + //
- ExFreePool(DeviceDescription->CollectionDesc);
++++++++ + // done
+++++++ + //
----- - HidP_FreeCollectionDescription (
----- - IN PHIDP_DEVICE_DESC DeviceDescription)
++++++++ + return Item;
++++++++ + }
+ +
++ + VOID
++ + NTAPI
----- - DPRINT1("HidP_FreeCollectionDescription DeviceDescription %p\n", DeviceDescription);
----- -
++++++++ + FreeFunction(
++++++++ + IN PVOID Item)
++ + {
- // free report ids
----- - // free collection
+ + //
- ExFreePool(DeviceDescription->ReportIDs);
----- - ExFreePool(DeviceDescription->CollectionDesc);
++++++++ + // free item
+ + //
- // free description itself
----- - // free report ids
++++++++ + ExFreePool(Item);
++++++++ + }
+ +
++++++++ + VOID
++++++++ + NTAPI
++++++++ + ZeroFunction(
++++++++ + IN PVOID Item,
++++++++ + IN ULONG ItemSize)
++++++++ + {
+ + //
- ExFreePool(DeviceDescription);
----- - ExFreePool(DeviceDescription->ReportIDs);
++++++++ + // zero item
+ + //
----- - #undef HidP_GetButtonCaps
++++++++ + RtlZeroMemory(Item, ItemSize);
++ + }
+ +
- ----- - HIDAPI
- ----- - NTSTATUS
++++++++ + VOID
++++++++ + NTAPI
++++++++ + CopyFunction(
++++++++ + IN PVOID Target,
++++++++ + IN PVOID Source,
++++++++ + IN ULONG Length)
++++++++ + {
++++++++ + //
++++++++ + // copy item
++++++++ + //
++++++++ + RtlCopyMemory(Target, Source, Length);
+++++++ + }
+ +
- ----- - HidP_GetButtonCaps(
- ----- - HIDP_REPORT_TYPE ReportType,
- ----- - PHIDP_BUTTON_CAPS ButtonCaps,
- ----- - PUSHORT ButtonCapsLength,
- ----- - PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + VOID
+ + NTAPI
- return HidP_GetSpecificButtonCaps(ReportType, 0, 0, 0, ButtonCaps, (PULONG)ButtonCapsLength, PreparsedData);
----- - return HidP_GetSpecificButtonCaps(ReportType, HID_USAGE_PAGE_UNDEFINED, 0, 0, ButtonCaps, (PULONG)ButtonCapsLength, PreparsedData);
++++++++ + DebugFunction(
++++++++ + IN LPCSTR FormatStr, ...)
+ + {
- ----- - HIDAPI
- ----- - NTSTATUS
++++++++ +
++++++++ + va_list args;
++++++++ + unsigned int i;
++++++++ + char printbuffer[1024];
++++++++ +
++++++++ + va_start(args, FormatStr);
++++++++ + i = vsprintf(printbuffer, FormatStr, args);
++++++++ + va_end(args);
++++++++ +
++++++++ + DbgPrint(printbuffer);
+ + }
+ +
- ----- - HidP_GetSpecificButtonCaps(
- ----- - IN HIDP_REPORT_TYPE ReportType,
- ----- - IN USAGE UsagePage,
- ----- - IN USHORT LinkCollection,
- ----- - IN USAGE Usage,
- ----- - OUT PHIDP_BUTTON_CAPS ButtonCaps,
- ----- - IN OUT PULONG ButtonCapsLength,
- ----- - IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + VOID
+ + NTAPI
- ----- - UNIMPLEMENTED
- ----- - ASSERT(FALSE);
- ----- - return STATUS_NOT_IMPLEMENTED;
++++++++ + HidP_FreeCollectionDescription (
++++++++ + IN PHIDP_DEVICE_DESC DeviceDescription)
+ + {
- ----- - UNIMPLEMENTED
- ----- - ASSERT(FALSE);
- ----- - return STATUS_NOT_IMPLEMENTED;
++++++++ + HID_PARSER Parser;
++++++++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, NULL, &Parser);
++++++++ +
++++++++ + //
++++++++ + // free collection
++++++++ + //
++++++++ + HidParser_FreeCollectionDescription(&Parser, DeviceDescription);
+ + }
+ +
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_GetCaps(
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + OUT PHIDP_CAPS Capabilities)
+ + {
- ----- - UNIMPLEMENTED
- ----- - ASSERT(FALSE);
- ----- - return STATUS_NOT_IMPLEMENTED;
++++++++ + HID_PARSER Parser;
++++++++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, PreparsedData, &Parser);
++++++++ +
++++++++ + //
++++++++ + // get caps
++++++++ + //
++++++++ + return HidParser_GetCaps(&Parser, Capabilities);
+ + }
+ +
+ + NTSTATUS
++ + NTAPI
+ + HidP_GetCollectionDescription(
+ + IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
+ + IN ULONG DescLength,
+ + IN POOL_TYPE PoolType,
+ + OUT PHIDP_DEVICE_DESC DeviceDescription)
+ + {
- ----- - HidP_GetData(
++++++++ + PHID_PARSER Parser;
++++++++ + HIDPARSER_STATUS Status;
++++++++ +
++++++++ + //
++++++++ + // first allocate the parser
++++++++ + //
++++++++ + Status = HidParser_AllocateParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, &Parser);
++++++++ + if (Status != HIDPARSER_STATUS_SUCCESS)
++++++++ + {
++++++++ + //
++++++++ + // not enough memory
++++++++ + //
++++++++ + return STATUS_INSUFFICIENT_RESOURCES;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // get description;
++++++++ + //
++++++++ + Status = HidParser_GetCollectionDescription(Parser, ReportDesc, DescLength, PoolType, DeviceDescription);
++++++++ +
++++++++ + //
++++++++ + // FIXME parser memory leak
++++++++ + //
++++++++ + return Status;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + ULONG
++++++++ + NTAPI
++++++++ + HidP_MaxUsageListLength(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage OPTIONAL,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + {
++++++++ + HID_PARSER Parser;
++++++++ +
++++++++ + //
++++++++ + // sanity check
++++++++ + //
++++++++ + ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
++++++++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, PreparsedData, &Parser);
++++++++ +
++++++++ +
++++++++ + //
++++++++ + // get usage length
++++++++ + //
++++++++ + return HidParser_MaxUsageListLength(&Parser, ReportType, UsagePage);
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
- ----- - OUT PHIDP_DATA DataList,
- ----- - IN OUT PULONG DataLength,
----- - IN PHIDP_PREPARSED_DATA PreparsedData,
----- - IN PCHAR Report,
----- - IN ULONG ReportLength)
++++++++ + HidP_GetSpecificValueCaps(
+ + IN HIDP_REPORT_TYPE ReportType,
----- - UNIMPLEMENTED
----- - ASSERT(FALSE);
----- - return STATUS_NOT_IMPLEMENTED;
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PHIDP_VALUE_CAPS ValueCaps,
++++++++ + IN OUT PULONG ValueCapsLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData)
++ + {
----- - HidP_GetExtendedAttributes(
++++++++ + HID_PARSER Parser;
++++++++ +
++++++++ + //
++++++++ + // sanity check
++++++++ + //
++++++++ + ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
++++++++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, PreparsedData, &Parser);
++++++++ +
++++++++ + //
++++++++ + // get value caps
++++++++ + //
++++++++ + return HidParser_GetSpecificValueCaps(&Parser, ReportType, UsagePage, LinkCollection, Usage, ValueCaps, ValueCapsLength);
++ + }
++ +
++ + HIDAPI
++ + NTSTATUS
++ + NTAPI
----- - IN USHORT DataIndex,
++++++++ + HidP_GetUsages(
++ + IN HIDP_REPORT_TYPE ReportType,
----- - OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
----- - IN OUT PULONG LengthAttributes)
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + OUT USAGE *UsageList,
++++++++ + IN OUT ULONG *UsageLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
- ----- - UNIMPLEMENTED
- ----- - ASSERT(FALSE);
- ----- - return STATUS_NOT_IMPLEMENTED;
+++++++ + IN PCHAR Report,
+++++++ + IN ULONG ReportLength)
+ + {
- HidP_GetExtendedAttributes(
----- - HidP_GetLinkCollectionNodes(
----- - OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
----- - IN OUT PULONG LinkCollectionNodesLength,
----- - IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + HID_PARSER Parser;
++++++++ +
++++++++ + //
++++++++ + // sanity check
++++++++ + //
++++++++ + ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
++++++++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, PreparsedData, &Parser);
++++++++ +
++++++++ + //
++++++++ + // get usages
++++++++ + //
++++++++ + return HidParser_GetUsages(&Parser, ReportType, UsagePage, LinkCollection, UsageList, UsageLength, Report, ReportLength);
+ + }
+ +
++++++++ +
++++++++ + #undef HidP_GetButtonCaps
++++++++ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
----- - UNIMPLEMENTED
----- - ASSERT(FALSE);
----- - return STATUS_NOT_IMPLEMENTED;
++++++++ + HidP_UsageListDifference(
++++++++ + IN PUSAGE PreviousUsageList,
++++++++ + IN PUSAGE CurrentUsageList,
++++++++ + OUT PUSAGE BreakUsageList,
++++++++ + OUT PUSAGE MakeUsageList,
++++++++ + IN ULONG UsageListLength)
++ + {
----- - HidP_GetScaledUsageValue(
++++++++ + return HidParser_UsageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength);
++ + }
++ +
++ + HIDAPI
++ + NTSTATUS
++ + NTAPI
- IN USHORT DataIndex,
----- - IN USAGE UsagePage,
----- - IN USHORT LinkCollection OPTIONAL,
----- - IN USAGE Usage,
----- - OUT PLONG UsageValue,
++++++++ + HidP_GetUsagesEx(
+ + IN HIDP_REPORT_TYPE ReportType,
- OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
- IN OUT PULONG LengthAttributes)
++++++++ + IN USHORT LinkCollection,
++++++++ + OUT PUSAGE_AND_PAGE ButtonList,
++++++++ + IN OUT ULONG *UsageLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
- ----- - UNIMPLEMENTED
- ----- - ASSERT(FALSE);
- ----- - return STATUS_NOT_IMPLEMENTED;
++ + IN PCHAR Report,
++ + IN ULONG ReportLength)
+ + {
- HidP_GetLinkCollectionNodes(
- OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
- IN OUT PULONG LinkCollectionNodesLength,
- IN PHIDP_PREPARSED_DATA PreparsedData)
----- - HidP_GetUsageValue(
++++++++ + return HidP_GetUsages(ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, (PUSAGE)ButtonList, UsageLength, PreparsedData, Report, ReportLength);
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
++++++++ + HidP_UsageAndPageListDifference(
++++++++ + IN PUSAGE_AND_PAGE PreviousUsageList,
++++++++ + IN PUSAGE_AND_PAGE CurrentUsageList,
++++++++ + OUT PUSAGE_AND_PAGE BreakUsageList,
++++++++ + OUT PUSAGE_AND_PAGE MakeUsageList,
++++++++ + IN ULONG UsageListLength)
+++++++ + {
----- - IN USHORT LinkCollection,
++++++++ + return HidParser_UsageAndPageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength);
+++++++ + }
+++++++ +
+++++++ + HIDAPI
+++++++ + NTSTATUS
+++++++ + NTAPI
+++++++ + HidP_GetScaledUsageValue(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
----- - OUT PULONG UsageValue,
+++++++ + IN USHORT LinkCollection OPTIONAL,
+ + IN USAGE Usage,
- ----- - UNIMPLEMENTED
- ----- - ASSERT(FALSE);
- ----- - return STATUS_NOT_IMPLEMENTED;
----- - }
+++++++ + OUT PLONG UsageValue,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
- HidP_GetUsageValue(
----- - HidP_UsageListDifference(
----- - IN PUSAGE PreviousUsageList,
----- - IN PUSAGE CurrentUsageList,
----- - OUT PUSAGE BreakUsageList,
----- - OUT PUSAGE MakeUsageList,
----- - IN ULONG UsageListLength)
++++++++ + HID_PARSER Parser;
++ +
++++++++ + //
++++++++ + // sanity check
++++++++ + //
++++++++ + ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, PreparsedData, &Parser);
++++++++ +
++++++++ + //
++++++++ + // get scaled usage value
++++++++ + //
++++++++ + return HidParser_GetScaledUsageValue(&Parser, ReportType, UsagePage, LinkCollection, Usage, UsageValue, Report, ReportLength);
+++++++ + }
+ +
+ ++ ++HIDAPI
+ ++ ++NTSTATUS
+ ++ ++NTAPI
----- - ULONG Index, SubIndex, bFound, BreakUsageIndex = 0, MakeUsageIndex = 0;
----- - USAGE CurrentUsage, Usage;
++++++++++++HidP_TranslateUsageAndPagesToI8042ScanCodes(
++++++++++++ IN PUSAGE_AND_PAGE ChangedUsageList,
++++++++++++ IN ULONG UsageListLength,
++++++++++++ IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++++++ IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
++++++++++++ IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++++++ IN PVOID InsertCodesContext)
++ ++ ++{
----- - if (UsageListLength)
----- - {
----- - Index = 0;
----- - do
----- - {
----- - /* get current usage */
----- - CurrentUsage = PreviousUsageList[Index];
----- -
----- - /* is the end of list reached? */
----- - if (!CurrentUsage)
----- - break;
----- -
----- - /* start searching in current usage list */
----- - SubIndex = 0;
----- - bFound = FALSE;
----- - do
----- - {
----- - /* get usage of current list */
----- - Usage = CurrentUsageList[SubIndex];
----- -
----- - /* end of list reached? */
----- - if (!Usage)
----- - break;
----- -
----- - /* check if it matches the current one */
----- - if (CurrentUsage == Usage)
----- - {
----- - /* it does */
----- - bFound = TRUE;
----- - break;
----- - }
----- -
----- - /* move to next usage */
----- - SubIndex++;
----- - }while(SubIndex < UsageListLength);
----- -
----- - /* was the usage found ?*/
----- - if (!bFound)
----- - {
----- - /* store it in the break usage list */
----- - BreakUsageList[BreakUsageIndex] = CurrentUsage;
----- - BreakUsageIndex++;
----- - }
----- -
----- - /* move to next usage */
----- - Index++;
----- -
----- - }while(Index < UsageListLength);
----- -
----- - /* now process the new items */
----- - Index = 0;
----- - do
----- - {
----- - /* get current usage */
----- - CurrentUsage = CurrentUsageList[Index];
----- -
----- - /* is the end of list reached? */
----- - if (!CurrentUsage)
----- - break;
----- -
----- - /* start searching in current usage list */
----- - SubIndex = 0;
----- - bFound = FALSE;
----- - do
----- - {
----- - /* get usage of previous list */
----- - Usage = PreviousUsageList[SubIndex];
----- -
----- - /* end of list reached? */
----- - if (!Usage)
----- - break;
----- -
----- - /* check if it matches the current one */
----- - if (CurrentUsage == Usage)
----- - {
----- - /* it does */
----- - bFound = TRUE;
----- - break;
----- - }
----- -
----- - /* move to next usage */
----- - SubIndex++;
----- - }while(SubIndex < UsageListLength);
----- -
----- - /* was the usage found ?*/
----- - if (!bFound)
----- - {
----- - /* store it in the make usage list */
----- - MakeUsageList[MakeUsageIndex] = CurrentUsage;
----- - MakeUsageIndex++;
----- - }
----- -
----- - /* move to next usage */
----- - Index++;
----- -
----- - }while(Index < UsageListLength);
----- - }
++++++++++++ HID_PARSER Parser;
++ ++ ++
----- - /* does the break list contain empty entries */
----- - if (BreakUsageIndex < UsageListLength)
----- - {
----- - /* zeroize entries */
----- - RtlZeroMemory(&BreakUsageList[BreakUsageIndex], sizeof(USAGE) * (UsageListLength - BreakUsageIndex));
----- - }
++++++++++++ //
++++++++++++ // sanity check
++++++++++++ //
++++++++++++ ASSERT(ReportType == HidP_Input || ReportType == HidP_Output || ReportType == HidP_Feature);
++ ++ ++
----- - /* does the make usage list contain empty entries */
----- - if (MakeUsageIndex < UsageListLength)
----- - {
----- - /* zeroize entries */
----- - RtlZeroMemory(&MakeUsageList[MakeUsageIndex], sizeof(USAGE) * (UsageListLength - MakeUsageIndex));
----- - }
++++++++++++ //
++++++++++++ // init parser
++++++++++++ //
++++++++++++ HidParser_InitParser(AllocFunction, FreeFunction, ZeroFunction, CopyFunction, DebugFunction, NULL, &Parser);
++++++++++++
++++++++++++ //
++++++++++++ // translate usage pages
++++++++++++ //
++++++++++++ return HidParser_TranslateUsageAndPagesToI8042ScanCodes(Parser, UsageListLength, KeyAction, ModifierState, InsertCodesProcedure, InsertCodesContext);
++++++++++++}
++ ++ ++
----- - /* done */
----- - return HIDP_STATUS_SUCCESS;
++ ++ ++
----- - HidP_GetSpecificValueCaps(
++++++++++++
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidP_GetButtonCaps(
++++++++ + HIDP_REPORT_TYPE ReportType,
++++++++ + PHIDP_BUTTON_CAPS ButtonCaps,
++++++++ + PUSHORT ButtonCapsLength,
++++++++ + PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + {
++++++++ + return HidP_GetSpecificButtonCaps(ReportType, HID_USAGE_PAGE_UNDEFINED, 0, 0, ButtonCaps, (PULONG)ButtonCapsLength, PreparsedData);
++ + }
++ +
++ + HIDAPI
++ + NTSTATUS
++ + NTAPI
- OUT PULONG UsageValue,
- IN PHIDP_PREPARSED_DATA PreparsedData,
- IN PCHAR Report,
- IN ULONG ReportLength)
----- - OUT PHIDP_VALUE_CAPS ValueCaps,
----- - IN OUT PULONG ValueCapsLength,
++++++++ + HidP_GetSpecificButtonCaps(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection,
+ + IN USAGE Usage,
-
-
++++++++ + OUT PHIDP_BUTTON_CAPS ButtonCaps,
++++++++ + IN OUT PULONG ButtonCapsLength,
++ + IN PHIDP_PREPARSED_DATA PreparsedData)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
----- - ULONG
+ + HIDAPI
- HidP_UsageListDifference(
- IN PUSAGE PreviousUsageList,
- IN PUSAGE CurrentUsageList,
- OUT PUSAGE BreakUsageList,
- OUT PUSAGE MakeUsageList,
- IN ULONG UsageListLength)
----- - HidP_MaxUsageListLength(
+++++++ + NTSTATUS
+ + NTAPI
----- - IN USAGE UsagePage OPTIONAL,
----- - IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + HidP_GetData(
++ + IN HIDP_REPORT_TYPE ReportType,
- HidP_GetSpecificValueCaps(
----- - HidP_GetUsages(
++++++++ + OUT PHIDP_DATA DataList,
++++++++ + IN OUT PULONG DataLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
- IN USHORT LinkCollection,
- IN USAGE Usage,
- OUT PHIDP_VALUE_CAPS ValueCaps,
- IN OUT PULONG ValueCapsLength,
- IN PHIDP_PREPARSED_DATA PreparsedData)
----- - IN USHORT LinkCollection OPTIONAL,
----- - OUT USAGE *UsageList,
----- - IN OUT ULONG *UsageLength,
++++++++ + HidP_GetExtendedAttributes(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
- ULONG
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
++++++++ + IN OUT PULONG LengthAttributes)
+++++++ + {
+++++++ + UNIMPLEMENTED
+++++++ + ASSERT(FALSE);
+++++++ + return STATUS_NOT_IMPLEMENTED;
+++++++ + }
+++++++ +
+++++++ + HIDAPI
- HidP_MaxUsageListLength(
- IN HIDP_REPORT_TYPE ReportType,
- IN USAGE UsagePage OPTIONAL,
- IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + NTSTATUS
+++++++ + NTAPI
- HidP_GetUsages(
++++++++ + HidP_GetLinkCollectionNodes(
++++++++ + OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
++++++++ + IN OUT PULONG LinkCollectionNodesLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData)
+++++++ + {
+++++++ + UNIMPLEMENTED
+++++++ + ASSERT(FALSE);
+++++++ + return STATUS_NOT_IMPLEMENTED;
+++++++ + }
+++++++ +
+++++++ + HIDAPI
+++++++ + NTSTATUS
+++++++ + NTAPI
- IN USHORT LinkCollection OPTIONAL,
- OUT USAGE *UsageList,
- IN OUT ULONG *UsageLength,
++++++++ + HidP_GetUsageValue(
+++++++ + IN HIDP_REPORT_TYPE ReportType,
+++++++ + IN USAGE UsagePage,
- ----- - HIDAPI
- ----- - NTSTATUS
- ----- - NTAPI
- ----- - HidP_GetUsagesEx(
- ----- - IN HIDP_REPORT_TYPE ReportType,
- ----- - IN USHORT LinkCollection,
- ----- - OUT PUSAGE_AND_PAGE ButtonList,
- ----- - IN OUT ULONG *UsageLength,
- ----- - IN PHIDP_PREPARSED_DATA PreparsedData,
- ----- - IN PCHAR Report,
- ----- - IN ULONG ReportLength)
- ----- - {
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
----- - return HidP_GetUsages(ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, (PUSAGE)ButtonList, UsageLength, PreparsedData, Report, ReportLength);
- ----- - }
- ----- -
- ----- -
- ----- - HIDAPI
- ----- - NTSTATUS
- ----- - NTAPI
- ----- - HidP_UsageAndPageListDifference(
- ----- - IN PUSAGE_AND_PAGE PreviousUsageList,
- ----- - IN PUSAGE_AND_PAGE CurrentUsageList,
- ----- - OUT PUSAGE_AND_PAGE BreakUsageList,
- ----- - OUT PUSAGE_AND_PAGE MakeUsageList,
- ----- - IN ULONG UsageListLength)
- ----- - {
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
----- - ULONG Index, SubIndex, BreakUsageListIndex = 0, MakeUsageListIndex = 0, bFound;
----- - PUSAGE_AND_PAGE CurrentUsage, Usage;
----- -
----- - if (UsageListLength)
----- - {
----- - /* process removed usages */
----- - Index = 0;
----- - do
----- - {
----- - /* get usage from current index */
----- - CurrentUsage = &PreviousUsageList[Index];
----- -
----- - /* end of list reached? */
----- - if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
----- - break;
----- -
----- - /* search in current list */
----- - SubIndex = 0;
----- - bFound = FALSE;
----- - do
----- - {
----- - /* get usage */
----- - Usage = &CurrentUsageList[SubIndex];
----- -
----- - /* end of list reached? */
----- - if (Usage->Usage == 0 && Usage->UsagePage == 0)
----- - break;
----- -
----- - /* does it match */
----- - if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
----- - {
----- - /* found match */
----- - bFound = TRUE;
----- - }
----- -
----- - /* move to next index */
----- - SubIndex++;
----- -
----- - }while(SubIndex < UsageListLength);
----- -
----- - if (!bFound)
----- - {
----- - /* store it in break usage list */
----- - BreakUsageList[BreakUsageListIndex].Usage = CurrentUsage->Usage;
----- - BreakUsageList[BreakUsageListIndex].UsagePage = CurrentUsage->UsagePage;
----- - BreakUsageListIndex++;
----- - }
----- -
----- - /* move to next index */
----- - Index++;
----- -
----- - }while(Index < UsageListLength);
----- -
----- - /* process new usages */
----- - Index = 0;
----- - do
----- - {
----- - /* get usage from current index */
----- - CurrentUsage = &CurrentUsageList[Index];
----- -
----- - /* end of list reached? */
----- - if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
----- - break;
----- -
----- - /* search in current list */
----- - SubIndex = 0;
----- - bFound = FALSE;
----- - do
----- - {
----- - /* get usage */
----- - Usage = &PreviousUsageList[SubIndex];
----- -
----- - /* end of list reached? */
----- - if (Usage->Usage == 0 && Usage->UsagePage == 0)
----- - break;
----- -
----- - /* does it match */
----- - if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
----- - {
----- - /* found match */
----- - bFound = TRUE;
----- - }
----- -
----- - /* move to next index */
----- - SubIndex++;
----- -
----- - }while(SubIndex < UsageListLength);
----- -
----- - if (!bFound)
----- - {
----- - /* store it in break usage list */
----- - MakeUsageList[MakeUsageListIndex].Usage = CurrentUsage->Usage;
----- - MakeUsageList[MakeUsageListIndex].UsagePage = CurrentUsage->UsagePage;
----- - MakeUsageListIndex++;
----- - }
----- -
----- - /* move to next index */
----- - Index++;
----- - }while(Index < UsageListLength);
----- - }
----- -
----- - /* are there remaining free list entries */
----- - if (BreakUsageListIndex < UsageListLength)
----- - {
----- - /* zero them */
----- - RtlZeroMemory(&BreakUsageList[BreakUsageListIndex], (UsageListLength - BreakUsageListIndex) * sizeof(USAGE_AND_PAGE));
----- - }
----- -
----- - /* are there remaining free list entries */
----- - if (MakeUsageListIndex < UsageListLength)
----- - {
----- - /* zero them */
----- - RtlZeroMemory(&MakeUsageList[MakeUsageListIndex], (UsageListLength - MakeUsageListIndex) * sizeof(USAGE_AND_PAGE));
----- - }
----- -
----- - /* done */
----- - return HIDP_STATUS_SUCCESS;
- ----- - }
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PULONG UsageValue,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + NTSTATUS
++ + NTAPI
+ + HidP_SysPowerEvent (
+ + IN PCHAR HidPacket,
+ + IN USHORT HidPacketLength,
+ + IN PHIDP_PREPARSED_DATA Ppd,
+ + OUT PULONG OutputBuffer)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + NTSTATUS
++ + NTAPI
+ + HidP_SysPowerCaps (
+ + IN PHIDP_PREPARSED_DATA Ppd,
+ + OUT PULONG OutputBuffer)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_GetUsageValueArray(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection OPTIONAL,
+ + IN USAGE Usage,
+ + OUT PCHAR UsageValue,
+ + IN USHORT UsageValueByteLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
- ----- ----HIDAPI
- ----- ----NTSTATUS
- ----- ----NTAPI
- ----- ----HidP_TranslateUsageAndPagesToI8042ScanCodes(
- ----- ---- IN PUSAGE_AND_PAGE ChangedUsageList,
- ----- ---- IN ULONG UsageListLength,
- ----- ---- IN HIDP_KEYBOARD_DIRECTION KeyAction,
- ----- ---- IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
- ----- ---- IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
- ----- ---- IN PVOID InsertCodesContext)
- ----- ----{
- ----- ---- UNIMPLEMENTED
- ----- ---- ASSERT(FALSE);
- ----- ---- return STATUS_NOT_IMPLEMENTED;
- ----- ----}
- ----- ----
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_UnsetUsages(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection,
+ + IN PUSAGE UsageList,
+ + IN OUT PULONG UsageLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_TranslateUsagesToI8042ScanCodes(
+ + IN PUSAGE ChangedUsageList,
+ + IN ULONG UsageListLength,
+ + IN HIDP_KEYBOARD_DIRECTION KeyAction,
+ + IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
+ + IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
+ + IN PVOID InsertCodesContext)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_SetUsages(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection,
+ + IN PUSAGE UsageList,
+ + IN OUT PULONG UsageLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_SetUsageValueArray(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection OPTIONAL,
+ + IN USAGE Usage,
+ + IN PCHAR UsageValue,
+ + IN USHORT UsageValueByteLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_SetUsageValue(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection,
+ + IN USAGE Usage,
+ + IN ULONG UsageValue,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_SetScaledUsageValue(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN USAGE UsagePage,
+ + IN USHORT LinkCollection OPTIONAL,
+ + IN USAGE Usage,
+ + IN LONG UsageValue,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_SetData(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN PHIDP_DATA DataList,
+ + IN OUT PULONG DataLength,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + ULONG
+ + NTAPI
+ + HidP_MaxDataListLength(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN PHIDP_PREPARSED_DATA PreparsedData)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_InitializeReportForID(
+ + IN HIDP_REPORT_TYPE ReportType,
+ + IN UCHAR ReportID,
+ + IN PHIDP_PREPARSED_DATA PreparsedData,
+ + IN OUT PCHAR Report,
+ + IN ULONG ReportLength)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
++ + #undef HidP_GetValueCaps
++ +
+ + HIDAPI
+ + NTSTATUS
+ + NTAPI
+ + HidP_GetValueCaps(
+ + HIDP_REPORT_TYPE ReportType,
+ + PHIDP_VALUE_CAPS ValueCaps,
+ + PULONG ValueCapsLength,
+ + PHIDP_PREPARSED_DATA PreparsedData)
+ + {
+ + UNIMPLEMENTED
+ + ASSERT(FALSE);
+ + return STATUS_NOT_IMPLEMENTED;
+ + }
+ +
+ + NTSTATUS
+ + NTAPI
+ + DriverEntry(
+ + IN PDRIVER_OBJECT DriverObject,
+ + IN PUNICODE_STRING RegPath)
+ + {
+ +
+ + DPRINT1("********* HID PARSE *********\n");
+ + return STATUS_SUCCESS;
+ + }
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
- IN PKEYBOARD_INPUT_DATA InputData,
- IN ULONG InputDataLength)
++++++++ +++/*
++++++++ +++ * PROJECT: ReactOS HID Stack
++++++++ +++ * LICENSE: GPL - See COPYING in the top level directory
++++++++ +++ * FILE: drivers/hid/kbdhid/kbdhid.c
++++++++ +++ * PURPOSE: Keyboard HID Driver
++++++++ +++ * PROGRAMMERS:
++++++++ +++ * Michael Martin (michael.martin@reactos.org)
++++++++ +++ * Johannes Anderwald (johannes.anderwald@reactos.org)
++++++++ +++ */
++++++++ +++
++++++++ +++#include "kbdhid.h"
++++++++ +++
++++++++ +++VOID
++++++++ +++KbdHid_DispatchInputData(
++++++++ +++ IN PKBDHID_DEVICE_EXTENSION DeviceExtension,
- (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassService)(DeviceExtension->ClassDeviceObject, InputData, InputData + InputDataLength + 1, &InputDataConsumed);
++++++++++++ IN PKEYBOARD_INPUT_DATA InputData)
++++++++ +++{
++++++++ +++ KIRQL OldIrql;
++++++++ +++ ULONG InputDataConsumed;
++++++++ +++
++++++++ +++ if (!DeviceExtension->ClassService)
++++++++ +++ return;
++++++++ +++
++++++++ +++ /* sanity check */
++++++++ +++ ASSERT(DeviceExtension->ClassService);
++++++++ +++ ASSERT(DeviceExtension->ClassDeviceObject);
++++++++ +++
++++++++ +++ /* raise irql */
++++++++ +++ KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
++++++++ +++
++++++++ +++ /* dispatch input data */
- UNIMPLEMENTED
- ASSERT(FALSE);
++++++++++++ (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassService)(DeviceExtension->ClassDeviceObject, InputData, InputData + 1, &InputDataConsumed);
++++++++ +++
++++++++ +++ /* lower irql to previous level */
++++++++ +++ KeLowerIrql(OldIrql);
++++++++ +++}
++++++++ +++
++++++++++++BOOLEAN
++++++++++++NTAPI
++++++++++++KbdHid_InsertScanCodes(
++++++++++++ IN PVOID Context,
++++++++++++ IN PCHAR NewScanCodes,
++++++++++++ IN ULONG Length)
++++++++++++{
++++++++++++ KEYBOARD_INPUT_DATA InputData;
++++++++++++ ULONG Index;
++++++++++++
++++++++++++ for(Index = 0; Index < Length; Index++)
++++++++++++ {
++++++++++++ DPRINT1("[KBDHID] ScanCode Index %lu ScanCode %x\n", Index, NewScanCodes[Index] & 0xFF);
++++++++++++ //
++++++++++++ // TODO: set up input data
++++++++++++ //
++++++++++++ //KbdHid_DispatchInputData((PKBDHID_DEVICE_EXTENSION)Context, &InputData);
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // done
++++++++++++ //
++++++++++++ return TRUE;
++++++++++++}
++++++++++++
++++++++++++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_ReadCompletion(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp,
++++++++ +++ IN PVOID Context)
++++++++ +++{
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++++++ NTSTATUS Status;
++++++++++++ ULONG ButtonLength;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)Context;
++++++++ +++
++++++++ +++ if (Irp->IoStatus.Status == STATUS_PRIVILEGE_NOT_HELD ||
++++++++ +++ Irp->IoStatus.Status == STATUS_DEVICE_NOT_CONNECTED ||
++++++++ +++ Irp->IoStatus.Status == STATUS_CANCELLED ||
++++++++ +++ DeviceExtension->StopReadReport)
++++++++ +++ {
++++++++ +++ /* failed to read or should be stopped*/
++++++++ +++ DPRINT1("[KBDHID] ReadCompletion terminating read Status %x\n", Irp->IoStatus.Status);
++++++++ +++
++++++++ +++ /* report no longer active */
++++++++ +++ DeviceExtension->ReadReportActive = FALSE;
++++++++ +++
++++++++ +++ /* request stopping of the report cycle */
++++++++ +++ DeviceExtension->StopReadReport = FALSE;
++++++++ +++
++++++++ +++ /* signal completion event */
++++++++ +++ KeSetEvent(&DeviceExtension->ReadCompletionEvent, 0, 0);
++++++++ +++ return STATUS_MORE_PROCESSING_REQUIRED;
++++++++ +++ }
++++++++ +++
- /* dispatch mouse action */
- //KbdHid_DispatchInputData(DeviceExtension, &InputData);
++++++++++++ /* get current usages */
++++++++++++ ButtonLength = DeviceExtension->UsageListLength;
++++++++++++ Status = HidP_GetUsagesEx(HidP_Input, HIDP_LINK_COLLECTION_UNSPECIFIED, DeviceExtension->CurrentUsageList, &ButtonLength, DeviceExtension->PreparsedData, DeviceExtension->Report, DeviceExtension->ReportLength);
++++++++++++ ASSERT(Status == HIDP_STATUS_SUCCESS);
++++++++++++
++++++++++++ /* FIXME check if needs mapping */
++++++++++++
++++++++++++ /* get usage difference */
++++++++++++ Status = HidP_UsageAndPageListDifference(DeviceExtension->PreviousUsageList, DeviceExtension->CurrentUsageList, DeviceExtension->BreakUsageList, DeviceExtension->MakeUsageList, DeviceExtension->UsageListLength);
++++++++++++ ASSERT(Status == HIDP_STATUS_SUCCESS);
++++++++++++
++++++++++++ /* replace previous usage list with current list */
++++++++++++ RtlMoveMemory(DeviceExtension->PreviousUsageList, DeviceExtension->CurrentUsageList, sizeof(USAGE_AND_PAGE) * DeviceExtension->UsageListLength);
++++++++ +++
- DPRINT1("[KBDHID] Unknown DeviceControl %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
++++++++++++ /* translate break usage list */
++++++++++++ HidP_TranslateUsageAndPagesToI8042ScanCodes(DeviceExtension->BreakUsageList, DeviceExtension->UsageListLength, HidP_Keyboard_Break, &DeviceExtension->ModifierState, KbdHid_InsertScanCodes, DeviceExtension);
++++++++++++ ASSERT(Status == HIDP_STATUS_SUCCESS);
++++++++++++
++++++++++++ /* translate new usage list */
++++++++++++ HidP_TranslateUsageAndPagesToI8042ScanCodes(DeviceExtension->MakeUsageList, DeviceExtension->UsageListLength, HidP_Keyboard_Make, &DeviceExtension->ModifierState, KbdHid_InsertScanCodes, DeviceExtension);
++++++++++++ ASSERT(Status == HIDP_STATUS_SUCCESS);
++++++++ +++
++++++++ +++ /* re-init read */
++++++++ +++ KbdHid_InitiateRead(DeviceExtension);
++++++++ +++
++++++++ +++ /* stop completion */
++++++++ +++ return STATUS_MORE_PROCESSING_REQUIRED;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++KbdHid_InitiateRead(
++++++++ +++ IN PKBDHID_DEVICE_EXTENSION DeviceExtension)
++++++++ +++{
++++++++ +++ PIO_STACK_LOCATION IoStack;
++++++++ +++ NTSTATUS Status;
++++++++ +++
++++++++ +++ /* re-use irp */
++++++++ +++ IoReuseIrp(DeviceExtension->Irp, STATUS_SUCCESS);
++++++++ +++
++++++++ +++ /* init irp */
++++++++ +++ DeviceExtension->Irp->MdlAddress = DeviceExtension->ReportMDL;
++++++++ +++
++++++++ +++ /* get next stack location */
++++++++ +++ IoStack = IoGetNextIrpStackLocation(DeviceExtension->Irp);
++++++++ +++
++++++++ +++ /* init stack location */
++++++++ +++ IoStack->Parameters.Read.Length = DeviceExtension->ReportLength;
++++++++ +++ IoStack->Parameters.Read.Key = 0;
++++++++ +++ IoStack->Parameters.Read.ByteOffset.QuadPart = 0LL;
++++++++ +++ IoStack->MajorFunction = IRP_MJ_READ;
++++++++ +++ IoStack->FileObject = DeviceExtension->FileObject;
++++++++ +++
++++++++ +++ /* set completion routine */
++++++++ +++ IoSetCompletionRoutine(DeviceExtension->Irp, KbdHid_ReadCompletion, DeviceExtension, TRUE, TRUE, TRUE);
++++++++ +++
++++++++ +++ /* read is active */
++++++++ +++ DeviceExtension->ReadReportActive = TRUE;
++++++++ +++
++++++++ +++ /* start the read */
++++++++ +++ Status = IoCallDriver(DeviceExtension->NextDeviceObject, DeviceExtension->Irp);
++++++++ +++
++++++++ +++ /* done */
++++++++ +++ return Status;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_CreateCompletion(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp,
++++++++ +++ IN PVOID Context)
++++++++ +++{
++++++++ +++ KeSetEvent((PKEVENT)Context, 0, FALSE);
++++++++ +++ return STATUS_MORE_PROCESSING_REQUIRED;
++++++++ +++}
++++++++ +++
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_Create(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ PIO_STACK_LOCATION IoStack;
++++++++ +++ NTSTATUS Status;
++++++++ +++ KEVENT Event;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++
++++++++ +++ DPRINT1("[KBDHID]: IRP_MJ_CREATE\n");
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* get stack location */
++++++++ +++ IoStack = IoGetCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* copy stack location to next */
++++++++ +++ IoCopyCurrentIrpStackLocationToNext(Irp);
++++++++ +++
++++++++ +++ /* init event */
++++++++ +++ KeInitializeEvent(&Event, NotificationEvent, FALSE);
++++++++ +++
++++++++ +++ /* prepare irp */
++++++++ +++ IoSetCompletionRoutine(Irp, KbdHid_CreateCompletion, &Event, TRUE, TRUE, TRUE);
++++++++ +++
++++++++ +++ /* call lower driver */
++++++++ +++ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++ if (Status == STATUS_PENDING)
++++++++ +++ {
++++++++ +++ /* request pending */
++++++++ +++ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
++++++++ +++ }
++++++++ +++
++++++++ +++ /* check for success */
++++++++ +++ if (!NT_SUCCESS(Status))
++++++++ +++ {
++++++++ +++ /* failed */
++++++++ +++ Irp->IoStatus.Status = Status;
++++++++ +++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* is the driver already in use */
++++++++ +++ if (DeviceExtension->FileObject == NULL)
++++++++ +++ {
++++++++ +++ /* did the caller specify correct attributes */
++++++++ +++ ASSERT(IoStack->Parameters.Create.SecurityContext);
++++++++ +++ if (IoStack->Parameters.Create.SecurityContext->DesiredAccess)
++++++++ +++ {
++++++++ +++ /* store file object */
++++++++ +++ DeviceExtension->FileObject = IoStack->FileObject;
++++++++ +++
++++++++ +++ /* reset event */
++++++++ +++ KeResetEvent(&DeviceExtension->ReadCompletionEvent);
++++++++ +++
++++++++ +++ /* initiating read */
++++++++ +++ Status = KbdHid_InitiateRead(DeviceExtension);
++++++++ +++ DPRINT1("[KBDHID] KbdHid_InitiateRead: status %x\n", Status);
++++++++ +++ if (Status == STATUS_PENDING)
++++++++ +++ {
++++++++ +++ /* report irp is pending */
++++++++ +++ Status = STATUS_SUCCESS;
++++++++ +++ }
++++++++ +++ }
++++++++ +++ }
++++++++ +++
++++++++ +++ /* complete request */
++++++++ +++ Irp->IoStatus.Status = Status;
++++++++ +++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++ +++ return Status;
++++++++ +++}
++++++++ +++
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_Close(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ DPRINT("[KBDHID] IRP_MJ_CLOSE ReadReportActive %x\n", DeviceExtension->ReadReportActive);
++++++++ +++
++++++++ +++ if (DeviceExtension->ReadReportActive)
++++++++ +++ {
++++++++ +++ /* request stopping of the report cycle */
++++++++ +++ DeviceExtension->StopReadReport = TRUE;
++++++++ +++
++++++++ +++ /* wait until the reports have been read */
++++++++ +++ KeWaitForSingleObject(&DeviceExtension->ReadCompletionEvent, Executive, KernelMode, FALSE, NULL);
++++++++ +++
++++++++ +++ /* cancel irp */
++++++++ +++ IoCancelIrp(DeviceExtension->Irp);
++++++++ +++ }
++++++++ +++
++++++++ +++ DPRINT("[KBDHID] IRP_MJ_CLOSE ReadReportActive %x\n", DeviceExtension->ReadReportActive);
++++++++ +++
++++++++ +++ /* remove file object */
++++++++ +++ DeviceExtension->FileObject = NULL;
++++++++ +++
++++++++ +++ /* skip location */
++++++++ +++ IoSkipCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* pass irp to down the stack */
++++++++ +++ return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_InternalDeviceControl(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ PIO_STACK_LOCATION IoStack;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++++++ PCONNECT_DATA Data;
++++++++++++ PKEYBOARD_ATTRIBUTES Attributes;
++++++++ +++
++++++++ +++ /* get current stack location */
++++++++ +++ IoStack = IoGetCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ DPRINT1("[KBDHID] InternalDeviceControl %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
- ASSERT(FALSE);
++++++++++++ if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_ATTRIBUTES)
++++++++++++ {
++++++++++++ /* verify output buffer length */
++++++++++++ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUSE_ATTRIBUTES))
++++++++++++ {
++++++++++++ /* invalid request */
++++++++++++ DPRINT1("[MOUHID] IOCTL_MOUSE_QUERY_ATTRIBUTES Buffer too small\n");
++++++++++++ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_BUFFER_TOO_SMALL;
++++++++++++ }
++++++++++++
++++++++++++ /* get output buffer */
++++++++++++ Attributes = (PKEYBOARD_ATTRIBUTES)Irp->AssociatedIrp.SystemBuffer;
++++++++++++
++++++++++++ /* copy attributes */
++++++++++++ RtlCopyMemory(Attributes, &DeviceExtension->Attributes, sizeof(KEYBOARD_ATTRIBUTES));
++++++++++++
++++++++++++ /* complete request */
++++++++++++ Irp->IoStatus.Information = sizeof(MOUSE_ATTRIBUTES);
++++++++++++ Irp->IoStatus.Status = STATUS_SUCCESS;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_SUCCESS;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_CONNECT)
++++++++++++ {
++++++++++++ /* verify input buffer length */
++++++++++++ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA))
++++++++++++ {
++++++++++++ /* invalid request */
++++++++++++ Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_INVALID_PARAMETER;
++++++++++++ }
++++++++++++
++++++++++++ /* is it already connected */
++++++++++++ if (DeviceExtension->ClassService)
++++++++++++ {
++++++++++++ /* already connected */
++++++++++++ Irp->IoStatus.Status = STATUS_SHARING_VIOLATION;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_SHARING_VIOLATION;
++++++++++++ }
++++++++++++
++++++++++++ /* get connect data */
++++++++++++ Data = (PCONNECT_DATA)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
++++++++ +++
++++++++++++ /* store connect details */
++++++++++++ DeviceExtension->ClassDeviceObject = Data->ClassDeviceObject;
++++++++++++ DeviceExtension->ClassService = Data->ClassService;
++++++++++++
++++++++++++ /* completed successfully */
++++++++++++ Irp->IoStatus.Status = STATUS_SUCCESS;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_SUCCESS;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_DISCONNECT)
++++++++++++ {
++++++++++++ /* not implemented */
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_ENABLE)
++++++++++++ {
++++++++++++ /* not supported */
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_SUPPORTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_KEYBOARD_DISABLE)
++++++++++++ {
++++++++++++ /* not supported */
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_SUPPORTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_INDICATORS)
++++++++++++ {
++++++++++++ /* not implemented */
++++++++++++ DPRINT1("IOCTL_KEYBOARD_QUERY_INDICATORS not implemented\n");
++++++++++++ ASSERT(FALSE);
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_TYPEMATIC)
++++++++++++ {
++++++++++++ /* not implemented */
++++++++++++ DPRINT1("IOCTL_KEYBOARD_QUERY_TYPEMATIC not implemented\n");
++++++++++++ ASSERT(FALSE);
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_SET_INDICATORS)
++++++++++++ {
++++++++++++ /* not implemented */
++++++++++++ DPRINT1("IOCTL_KEYBOARD_SET_INDICATORS not implemented\n");
++++++++++++ ASSERT(FALSE);
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_SET_TYPEMATIC)
++++++++++++ {
++++++++++++ /* not implemented */
++++++++++++ DPRINT1("IOCTL_KEYBOARD_SET_TYPEMATIC not implemented\n");
++++++++++++ ASSERT(FALSE);
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++ else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION)
++++++++++++ {
++++++++++++ /* not implemented */
++++++++++++ DPRINT1("IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION not implemented\n");
++++++++++++ ASSERT(FALSE);
++++++++++++ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
++++++++++++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++++++ return STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++
++++++++++++ /* unknown control code */
++++++++++++ DPRINT1("[KBDHID] Unknown DeviceControl %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
++++++++ +++ /* unknown request not supported */
++++++++ +++ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
++++++++ +++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++ +++ return STATUS_NOT_SUPPORTED;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_DeviceControl(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* skip stack location */
++++++++ +++ IoSkipCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* pass and forget */
++++++++ +++ return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_Power(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ UNIMPLEMENTED
++++++++ +++ return STATUS_NOT_IMPLEMENTED;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++KbdHid_SubmitRequest(
++++++++ +++ PDEVICE_OBJECT DeviceObject,
++++++++ +++ ULONG IoControlCode,
++++++++ +++ ULONG InputBufferSize,
++++++++ +++ PVOID InputBuffer,
++++++++ +++ ULONG OutputBufferSize,
++++++++ +++ PVOID OutputBuffer)
++++++++ +++{
++++++++ +++ KEVENT Event;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++ PIRP Irp;
++++++++ +++ NTSTATUS Status;
++++++++ +++ IO_STATUS_BLOCK IoStatus;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* init event */
++++++++ +++ KeInitializeEvent(&Event, NotificationEvent, FALSE);
++++++++ +++
++++++++ +++ /* build request */
++++++++ +++ Irp = IoBuildDeviceIoControlRequest(IoControlCode, DeviceExtension->NextDeviceObject, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, FALSE, &Event, &IoStatus);
++++++++ +++ if (!Irp)
++++++++ +++ {
++++++++ +++ /* no memory */
++++++++ +++ return STATUS_INSUFFICIENT_RESOURCES;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* send request */
++++++++ +++ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++ if (Status == STATUS_PENDING)
++++++++ +++ {
++++++++ +++ /* wait for request to complete */
++++++++ +++ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
++++++++ +++ Status = IoStatus.Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* done */
++++++++ +++ return Status;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_StartDevice(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject)
++++++++ +++{
++++++++ +++ NTSTATUS Status;
++++++++ +++ ULONG Buttons;
++++++++ +++ HID_COLLECTION_INFORMATION Information;
++++++++ +++ PHIDP_PREPARSED_DATA PreparsedData;
++++++++ +++ HIDP_CAPS Capabilities;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++ PUSAGE_AND_PAGE Buffer;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* query collection information */
++++++++ +++ Status = KbdHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_INFORMATION, 0, NULL, sizeof(HID_COLLECTION_INFORMATION), &Information);
++++++++ +++ if (!NT_SUCCESS(Status))
++++++++ +++ {
++++++++ +++ /* failed to query collection information */
++++++++ +++ DPRINT1("[KBDHID] failed to obtain collection information with %x\n", Status);
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* lets allocate space for preparsed data */
++++++++ +++ PreparsedData = (PHIDP_PREPARSED_DATA)ExAllocatePool(NonPagedPool, Information.DescriptorSize);
++++++++ +++ if (!PreparsedData)
++++++++ +++ {
++++++++ +++ /* no memory */
++++++++ +++ DPRINT1("[KBDHID] no memory size %u\n", Information.DescriptorSize);
++++++++ +++ return STATUS_INSUFFICIENT_RESOURCES;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* now obtain the preparsed data */
++++++++ +++ Status = KbdHid_SubmitRequest(DeviceObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, 0, NULL, Information.DescriptorSize, PreparsedData);
++++++++ +++ if (!NT_SUCCESS(Status))
++++++++ +++ {
++++++++ +++ /* failed to get preparsed data */
++++++++ +++ DPRINT1("[KBDHID] failed to obtain collection information with %x\n", Status);
++++++++ +++ ExFreePool(PreparsedData);
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* lets get the caps */
++++++++ +++ Status = HidP_GetCaps(PreparsedData, &Capabilities);
++++++++ +++ if (Status != HIDP_STATUS_SUCCESS)
++++++++ +++ {
++++++++ +++ /* failed to get capabilities */
++++++++ +++ DPRINT1("[KBDHID] failed to obtain caps with %x\n", Status);
++++++++ +++ ExFreePool(PreparsedData);
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ DPRINT1("[KBDHID] Usage %x UsagePage %x InputReportLength %lu\n", Capabilities.Usage, Capabilities.UsagePage, Capabilities.InputReportByteLength);
++++++++ +++
++++++++ +++ /* init input report*/
++++++++ +++ DeviceExtension->ReportLength = Capabilities.InputReportByteLength;
++++++++ +++ ASSERT(DeviceExtension->ReportLength);
++++++++ +++ DeviceExtension->Report = (PUCHAR)ExAllocatePool(NonPagedPool, DeviceExtension->ReportLength);
++++++++ +++ ASSERT(DeviceExtension->Report);
++++++++ +++ RtlZeroMemory(DeviceExtension->Report, DeviceExtension->ReportLength);
++++++++ +++
++++++++ +++ /* build mdl */
++++++++ +++ DeviceExtension->ReportMDL = IoAllocateMdl(DeviceExtension->Report, DeviceExtension->ReportLength, FALSE, FALSE, NULL);
++++++++ +++ ASSERT(DeviceExtension->ReportMDL);
++++++++ +++
++++++++ +++ /* init mdl */
++++++++ +++ MmBuildMdlForNonPagedPool(DeviceExtension->ReportMDL);
++++++++ +++
++++++++ +++ /* get max number of buttons */
++++++++ +++ Buttons = HidP_MaxUsageListLength(HidP_Input, HID_USAGE_PAGE_BUTTON, PreparsedData);
++++++++ +++ DPRINT1("[KBDHID] Buttons %lu\n", Buttons);
++++++++ +++ ASSERT(Buttons > 0);
++++++++ +++
++++++++ +++ /* now allocate an array for those buttons */
++++++++ +++ Buffer = (PUSAGE_AND_PAGE)ExAllocatePool(NonPagedPool, sizeof(USAGE_AND_PAGE) * 4 * Buttons);
++++++++ +++ if (!Buffer)
++++++++ +++ {
++++++++ +++ /* no memory */
++++++++ +++ ExFreePool(PreparsedData);
++++++++ +++ return STATUS_INSUFFICIENT_RESOURCES;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* init usage lists */
++++++++ +++ RtlZeroMemory(Buffer, sizeof(USAGE_AND_PAGE) * 4 * Buttons);
++++++++ +++ DeviceExtension->CurrentUsageList = Buffer;
++++++++ +++ Buffer += Buttons;
++++++++ +++ DeviceExtension->PreviousUsageList = Buffer;
++++++++ +++ Buffer += Buttons;
++++++++ +++ DeviceExtension->MakeUsageList = Buffer;
++++++++ +++ Buffer += Buttons;
++++++++ +++ DeviceExtension->BreakUsageList = Buffer;
++++++++ +++
++++++++ +++ //
++++++++ +++ // FIMXE: implement device hacks
++++++++ +++ //
++++++++ +++ // UsageMappings
++++++++ +++ // KeyboardTypeOverride
++++++++ +++ // KeyboardSubTypeOverride
++++++++ +++ // KeyboardNumberTotalKeysOverride
++++++++ +++ // KeyboardNumberFunctionKeysOverride
++++++++ +++ // KeyboardNumberIndicatorsOverride
++++++++ +++
++++++++ +++ /* store number of buttons */
++++++++ +++ DeviceExtension->UsageListLength = (USHORT)Buttons;
++++++++ +++
++++++++ +++ /* store preparsed data */
++++++++ +++ DeviceExtension->PreparsedData = PreparsedData;
++++++++ +++
++++++++ +++ /* completed successfully */
++++++++ +++ return STATUS_SUCCESS;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_StartDeviceCompletion(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp,
++++++++ +++ IN PVOID Context)
++++++++ +++{
++++++++ +++ KeSetEvent((PKEVENT)Context, 0, FALSE);
++++++++ +++ return STATUS_MORE_PROCESSING_REQUIRED;
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_Flush(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ PIO_STACK_LOCATION IoStack;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* skip current stack location */
++++++++ +++ IoSkipCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* get next stack location */
++++++++ +++ IoStack = IoGetNextIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* change request to hid flush queue request */
++++++++ +++ IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
++++++++ +++ IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_HID_FLUSH_QUEUE;
++++++++ +++
++++++++ +++ /* call device */
++++++++ +++ return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_Pnp(
++++++++ +++ IN PDEVICE_OBJECT DeviceObject,
++++++++ +++ IN PIRP Irp)
++++++++ +++{
++++++++ +++ PIO_STACK_LOCATION IoStack;
++++++++ +++ KEVENT Event;
++++++++ +++ NTSTATUS Status;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* get current irp stack */
++++++++ +++ IoStack = IoGetCurrentIrpStackLocation(Irp);
++++++++ +++ DPRINT1("[KBDHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
++++++++ +++
++++++++ +++ if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE)
++++++++ +++ {
++++++++ +++ /* indicate success */
++++++++ +++ Irp->IoStatus.Status = STATUS_SUCCESS;
++++++++ +++
++++++++ +++ /* skip irp stack location */
++++++++ +++ IoSkipCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* dispatch to lower device */
++++++++ +++ return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++ }
++++++++ +++ else if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
++++++++ +++ {
++++++++ +++ /* FIXME synchronization */
++++++++ +++
++++++++ +++ /* cancel irp */
++++++++ +++ IoCancelIrp(DeviceExtension->Irp);
++++++++ +++
++++++++ +++ /* indicate success */
++++++++ +++ Irp->IoStatus.Status = STATUS_SUCCESS;
++++++++ +++
++++++++ +++ /* skip irp stack location */
++++++++ +++ IoSkipCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* dispatch to lower device */
++++++++ +++ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++
++++++++ +++ IoFreeIrp(DeviceExtension->Irp);
++++++++ +++ IoDetachDevice(DeviceExtension->NextDeviceObject);
++++++++ +++ IoDeleteDevice(DeviceObject);
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++ else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
++++++++ +++ {
++++++++ +++ /* init event */
++++++++ +++ KeInitializeEvent(&Event, NotificationEvent, FALSE);
++++++++ +++
++++++++ +++ /* copy stack location */
++++++++ +++ IoCopyCurrentIrpStackLocationToNext (Irp);
++++++++ +++
++++++++ +++ /* set completion routine */
++++++++ +++ IoSetCompletionRoutine(Irp, KbdHid_StartDeviceCompletion, &Event, TRUE, TRUE, TRUE);
++++++++ +++ Irp->IoStatus.Status = 0;
++++++++ +++
++++++++ +++ /* pass request */
++++++++ +++ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++ if (Status == STATUS_PENDING)
++++++++ +++ {
++++++++ +++ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
++++++++ +++ Status = Irp->IoStatus.Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ if (!NT_SUCCESS(Status))
++++++++ +++ {
++++++++ +++ /* failed */
++++++++ +++ Irp->IoStatus.Status = Status;
++++++++ +++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* lets start the device */
++++++++ +++ Status = KbdHid_StartDevice(DeviceObject);
++++++++ +++ DPRINT1("KbdHid_StartDevice %x\n", Status);
++++++++ +++
++++++++ +++ /* complete request */
++++++++ +++ Irp->IoStatus.Status = Status;
++++++++ +++ IoCompleteRequest(Irp, IO_NO_INCREMENT);
++++++++ +++
++++++++ +++ /* done */
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++ else
++++++++ +++ {
++++++++ +++ /* skip irp stack location */
++++++++ +++ IoSkipCurrentIrpStackLocation(Irp);
++++++++ +++
++++++++ +++ /* dispatch to lower device */
++++++++ +++ return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
++++++++ +++ }
++++++++ +++}
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++KbdHid_AddDevice(
++++++++ +++ IN PDRIVER_OBJECT DriverObject,
++++++++ +++ IN PDEVICE_OBJECT PhysicalDeviceObject)
++++++++ +++{
++++++++ +++ NTSTATUS Status;
++++++++ +++ PDEVICE_OBJECT DeviceObject, NextDeviceObject;
++++++++ +++ PKBDHID_DEVICE_EXTENSION DeviceExtension;
++++++++ +++ POWER_STATE State;
++++++++ +++
++++++++ +++ /* create device object */
++++++++ +++ Status = IoCreateDevice(DriverObject, sizeof(KBDHID_DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 0, FALSE, &DeviceObject);
++++++++ +++ if (!NT_SUCCESS(Status))
++++++++ +++ {
++++++++ +++ /* failed to create device object */
++++++++ +++ return Status;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* now attach it */
++++++++ +++ NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
++++++++ +++ if (!NextDeviceObject)
++++++++ +++ {
++++++++ +++ /* failed to attach */
++++++++ +++ IoDeleteDevice(DeviceObject);
++++++++ +++ return STATUS_DEVICE_NOT_CONNECTED;
++++++++ +++ }
++++++++ +++
++++++++ +++ /* get device extension */
++++++++ +++ DeviceExtension = (PKBDHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
++++++++ +++
++++++++ +++ /* zero extension */
++++++++ +++ RtlZeroMemory(DeviceExtension, sizeof(KBDHID_DEVICE_EXTENSION));
++++++++ +++
++++++++ +++ /* init device extension */
++++++++ +++ DeviceExtension->NextDeviceObject = NextDeviceObject;
++++++++ +++ KeInitializeEvent(&DeviceExtension->ReadCompletionEvent, NotificationEvent, FALSE);
++++++++++++
++++++++++++ /* init keyboard attributes */
++++++++++++ DeviceExtension->Attributes.KeyboardIdentifier.Type = KEYBOARD_TYPE_UNKNOWN;
++++++++++++ DeviceExtension->Attributes.KeyboardIdentifier.Subtype = MICROSOFT_KBD_101_TYPE;
++++++++++++ DeviceExtension->Attributes.NumberOfFunctionKeys = MICROSOFT_KBD_FUNC;
++++++++++++ DeviceExtension->Attributes.NumberOfIndicators = 3; // caps, num lock, scroll lock
++++++++++++ DeviceExtension->Attributes.NumberOfKeysTotal = 101;
++++++++++++ DeviceExtension->Attributes.InputDataQueueLength = 1;
++++++++++++ DeviceExtension->Attributes.KeyRepeatMinimum.Rate = KEYBOARD_TYPEMATIC_RATE_MINIMUM;
++++++++++++ DeviceExtension->Attributes.KeyRepeatMinimum.Delay = KEYBOARD_TYPEMATIC_DELAY_MINIMUM;
++++++++++++ DeviceExtension->Attributes.KeyRepeatMaximum.Rate = KEYBOARD_TYPEMATIC_RATE_DEFAULT;
++++++++++++ DeviceExtension->Attributes.KeyRepeatMaximum.Delay = KEYBOARD_TYPEMATIC_DELAY_MAXIMUM;
++++++++++++
++++++++++++ /* allocate irp */
++++++++ +++ DeviceExtension->Irp = IoAllocateIrp(NextDeviceObject->StackSize, FALSE);
++++++++ +++
++++++++ +++ /* FIXME handle allocation error */
++++++++ +++ ASSERT(DeviceExtension->Irp);
++++++++ +++
++++++++ +++ /* set power state to D0 */
++++++++ +++ State.DeviceState = PowerDeviceD0;
++++++++ +++ PoSetPowerState(DeviceObject, DevicePowerState, State);
++++++++ +++
++++++++ +++ /* init device object */
++++++++ +++ DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
++++++++ +++ DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
++++++++ +++
++++++++ +++ /* completed successfully */
++++++++ +++ return STATUS_SUCCESS;
++++++++ +++}
++++++++ +++
++++++++ +++VOID
++++++++ +++NTAPI
++++++++ +++KbdHid_Unload(
++++++++ +++ IN PDRIVER_OBJECT DriverObject)
++++++++ +++{
++++++++ +++ UNIMPLEMENTED
++++++++ +++}
++++++++ +++
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++NTAPI
++++++++ +++DriverEntry(
++++++++ +++ IN PDRIVER_OBJECT DriverObject,
++++++++ +++ IN PUNICODE_STRING RegPath)
++++++++ +++{
++++++++ +++ /* initialize driver object */
++++++++ +++ DriverObject->DriverUnload = KbdHid_Unload;
++++++++ +++ DriverObject->DriverExtension->AddDevice = KbdHid_AddDevice;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_CREATE] = KbdHid_Create;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_CLOSE] = KbdHid_Close;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = KbdHid_Flush;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KbdHid_DeviceControl;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = KbdHid_InternalDeviceControl;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_POWER] = KbdHid_Power;
++++++++ +++ DriverObject->MajorFunction[IRP_MJ_PNP] = KbdHid_Pnp;
++++++++ +++ DriverObject->DriverUnload = KbdHid_Unload;
++++++++ +++ DriverObject->DriverExtension->AddDevice = KbdHid_AddDevice;
++++++++ +++
++++++++ +++ /* done */
++++++++ +++ return STATUS_SUCCESS;
++++++++ +++}
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
- #include <ntddmou.h>
++++++++ +++#pragma once
++++++++ +++
++++++++ +++#define _HIDPI_NO_FUNCTION_MACROS_
++++++++ +++#include <ntddk.h>
++++++++ +++#include <hidclass.h>
++++++++ +++#include <hidpddi.h>
++++++++ +++#include <hidpi.h>
++++++++ +++#include <debug.h>
- PVOID PreparsedData;
++++++++ +++#include <kbdmou.h>
++++++++++++//#include <kbd.h>
++++++++++++#include <ntddkbd.h>
++++++++ +++#include <debug.h>
++++++++ +++
++++++++ +++
++++++++ +++typedef struct
++++++++ +++{
++++++++ +++ //
++++++++ +++ // lower device object
++++++++ +++ //
++++++++ +++ PDEVICE_OBJECT NextDeviceObject;
++++++++ +++
++++++++ +++ //
++++++++ +++ // irp which is used for reading input reports
++++++++ +++ //
++++++++ +++ PIRP Irp;
++++++++ +++
++++++++ +++ //
++++++++ +++ // event
++++++++ +++ //
++++++++ +++ KEVENT ReadCompletionEvent;
++++++++ +++
++++++++ +++ //
++++++++ +++ // device object for class callback
++++++++ +++ //
++++++++ +++ PDEVICE_OBJECT ClassDeviceObject;
++++++++ +++
++++++++ +++ //
++++++++ +++ // class callback
++++++++ +++ //
++++++++ +++ PVOID ClassService;
++++++++ +++
++++++++ +++ //
++++++++ +++ // usage list length
++++++++ +++ //
++++++++ +++ USHORT UsageListLength;
++++++++ +++
++++++++ +++ //
++++++++ +++ // current usage list length
++++++++ +++ //
++++++++ +++ PUSAGE_AND_PAGE CurrentUsageList;
++++++++ +++
++++++++ +++ //
++++++++ +++ // previous usage list
++++++++ +++ //
++++++++ +++ PUSAGE_AND_PAGE PreviousUsageList;
++++++++ +++
++++++++ +++ //
++++++++ +++ // removed usage item list
++++++++ +++ //
++++++++ +++ PUSAGE_AND_PAGE BreakUsageList;
++++++++ +++
++++++++ +++ //
++++++++ +++ // new item usage list
++++++++ +++ //
++++++++ +++ PUSAGE_AND_PAGE MakeUsageList;
++++++++ +++
++++++++ +++ //
++++++++ +++ // preparsed data
++++++++ +++ //
- PUCHAR Report;
++++++++++++ PHIDP_PREPARSED_DATA PreparsedData;
++++++++ +++
++++++++ +++ //
++++++++ +++ // mdl for reading input report
++++++++ +++ //
++++++++ +++ PMDL ReportMDL;
++++++++ +++
++++++++ +++ //
++++++++ +++ // input report buffer
++++++++ +++ //
++++++++++++ PCHAR Report;
++++++++ +++
++++++++ +++ //
++++++++ +++ // input report length
++++++++ +++ //
++++++++ +++ ULONG ReportLength;
++++++++ +++
++++++++ +++ //
++++++++ +++ // file object the device is reading reports from
++++++++ +++ //
++++++++ +++ PFILE_OBJECT FileObject;
++++++++ +++
++++++++ +++ //
++++++++ +++ // report read is active
++++++++ +++ //
++++++++ +++ UCHAR ReadReportActive;
++++++++ +++
++++++++ +++ //
++++++++ +++ // stop reading flag
++++++++ +++ //
++++++++ +++ UCHAR StopReadReport;
++++++++ +++
++++++++++++ //
++++++++++++ // keyboard attributes
++++++++++++ //
++++++++++++ KEYBOARD_ATTRIBUTES Attributes;
++++++++++++
++++++++++++ //
++++++++++++ // keyboard modifier state
++++++++++++ //
++++++++++++ HIDP_KEYBOARD_MODIFIER_STATE ModifierState;
++++++++++++
++++++++ +++}KBDHID_DEVICE_EXTENSION, *PKBDHID_DEVICE_EXTENSION;
++++++++ +++
++++++++++++/* defaults from kbfiltr.h */
++++++++++++#define KEYBOARD_TYPEMATIC_RATE_MINIMUM 2
++++++++++++#define KEYBOARD_TYPEMATIC_RATE_MAXIMUM 30
++++++++++++#define KEYBOARD_TYPEMATIC_RATE_DEFAULT 30
++++++++++++#define KEYBOARD_TYPEMATIC_DELAY_MINIMUM 250
++++++++++++#define KEYBOARD_TYPEMATIC_DELAY_MAXIMUM 1000
++++++++++++#define KEYBOARD_TYPEMATIC_DELAY_DEFAULT 250
++++++++++++
++++++++++++/* FIXME: write kbd.h */
++++++++++++#define MICROSOFT_KBD_FUNC 12
++++++++++++#define KEYBOARD_TYPE_UNKNOWN (0x51)
++++++++++++#define MICROSOFT_KBD_101_TYPE 0
++++++++++++
++++++++++++
++++++++++++
++++++++ +++
++++++++ +++NTSTATUS
++++++++ +++KbdHid_InitiateRead(
++++++++ +++ IN PKBDHID_DEVICE_EXTENSION DeviceExtension);
++++++++++++
add_subdirectory(chew)
add_subdirectory(csq)
++++++++ + add_subdirectory(hidparser)
add_subdirectory(ip)
-----------add_subdirectory(oskittcp)
+++++++++++add_subdirectory(lwip)
add_subdirectory(sound)
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
++++++++ + /*
++++++++ + * PROJECT: ReactOS HID Parser Library
++++++++ + * LICENSE: GPL - See COPYING in the top level directory
++++++++ + * FILE: lib/drivers/hidparser/api.c
++++++++ + * PURPOSE: HID Parser
++++++++ + * PROGRAMMERS:
++++++++ + * Michael Martin (michael.martin@reactos.org)
++++++++ + * Johannes Anderwald (johannes.anderwald@reactos.org)
++++++++ + */
++++++++ +
++++++++ +
++++++++ + #include "parser.h"
++++++++ +
++++++++++++static ULONG KeyboardScanCodes[256] =
++++++++++++{
++++++++++++ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
++++++++++++ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
++++++++++++ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
++++++++++++ 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
++++++++++++ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
++++++++++++ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
++++++++++++ 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
++++++++++++ 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
++++++++++++ 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
++++++++++++ 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++++++++++++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++++++++++++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++++++++++++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++++++++++++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++++++++++++ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
++++++++++++ 150,158,159,128,136,177,178,176,142,152,173,140
++++++++++++};
++++++++++++
++++++++++++
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_NumberOfTopCollections(
++++++++ + IN PHID_PARSER Parser)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ + ASSERT(ParserContext->RootCollection);
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount);
++++++++ +
++++++++ + //
++++++++ + // number of top collections
++++++++ + //
++++++++ + return ParserContext->RootCollection->NodeCount;
++++++++ + }
++++++++ +
++++++++ + PHID_COLLECTION
++++++++ + HidParser_GetCollection(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG CollectionNumber)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ + ASSERT(ParserContext->RootCollection);
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount);
++++++++ +
++++++++ + //
++++++++ + // is collection index out of bounds
++++++++ + //
++++++++ + if (CollectionNumber < ParserContext->RootCollection->NodeCount)
++++++++ + {
++++++++ + //
++++++++ + // valid collection
++++++++ + //
++++++++ + return ParserContext->RootCollection->Nodes[CollectionNumber];
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // no such collection
++++++++ + //
++++++++ + Parser->Debug("HIDPARSE] No such collection %lu\n", CollectionNumber);
++++++++ + return NULL;
++++++++ + }
++++++++ +
++++++++ + PHID_REPORT
++++++++ + HidParser_GetReportByType(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + ULONG ReportCount = 0;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ + for(Index = 0; Index < ParserContext->ReportCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // check if the report type match
++++++++ + //
++++++++ + if (ParserContext->Reports[Index]->Type == ReportType)
++++++++ + {
++++++++ + //
++++++++ + // found report
++++++++ + //
++++++++ + return ParserContext->Reports[Index];
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // report not found
++++++++ + //
++++++++ + return NULL;
++++++++ + }
++++++++ +
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_NumberOfReports(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + ULONG ReportCount = 0;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ + for(Index = 0; Index < ParserContext->ReportCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // check if the report type match
++++++++ + //
++++++++ + if (ParserContext->Reports[Index]->Type == ReportType)
++++++++ + {
++++++++ + //
++++++++ + // found report
++++++++ + //
++++++++ + ReportCount++;
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + return ReportCount;
++++++++ + }
++++++++ +
++++++++ + HIDPARSER_STATUS
++++++++ + HidParser_GetCollectionUsagePage(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG CollectionIndex,
++++++++ + OUT PUSHORT Usage,
++++++++ + OUT PUSHORT UsagePage)
++++++++ + {
++++++++ + PHID_COLLECTION Collection;
++++++++ +
++++++++ + //
++++++++ + // find collection
++++++++ + //
++++++++ + Collection = HidParser_GetCollection(Parser, CollectionIndex);
++++++++ + if (!Collection)
++++++++ + {
++++++++ + //
++++++++ + // collection not found
++++++++ + //
++++++++ + return HIDPARSER_STATUS_COLLECTION_NOT_FOUND;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // store result
++++++++ + //
++++++++ + *UsagePage = (Collection->Usage >> 16);
++++++++ + *Usage = (Collection->Usage & 0xFFFF);
++++++++ + return HIDPARSER_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetReportLength(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + PHID_REPORT Report;
++++++++ + ULONG ReportLength;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get first report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no report found
++++++++ + //
++++++++ + return 0;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // get report length
++++++++ + //
++++++++ + ReportLength = Report->ReportSize;
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + if (ReportLength)
++++++++ + {
++++++++ + //
++++++++ + // byte aligned length
++++++++ + //
++++++++ + ASSERT(ReportLength % 8 == 0);
++++++++ + return ReportLength / 8;
++++++++ + }
++++++++ + return ReportLength;
++++++++ + }
++++++++ +
++++++++ + UCHAR
++++++++ + HidParser_IsReportIDUsed(
++++++++ + IN PHID_PARSER Parser)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // return flag
++++++++ + //
++++++++ + return ParserContext->UseReportIDs;
++++++++ + }
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetReportItemCountFromReportType(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + PHID_REPORT Report;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no such report
++++++++ + //
++++++++ + return 0;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // return report item count
++++++++ + //
++++++++ + return Report->ItemCount;
++++++++ + }
++++++++ +
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetReportItemTypeCountFromReportType(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType,
++++++++ + IN ULONG bData)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + PHID_REPORT Report;
++++++++ + ULONG ItemCount = 0;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no such report
++++++++ + //
++++++++ + return 0;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // enumerate all items
++++++++ + //
++++++++ + for(Index = 0; Index < Report->ItemCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // check item type
++++++++ + //
++++++++ + if (Report->Items[Index]->HasData && bData == TRUE)
++++++++ + {
++++++++ + //
++++++++ + // found data item
++++++++ + //
++++++++ + ItemCount++;
++++++++ + }
++++++++ + else if (Report->Items[Index]->HasData == FALSE && bData == FALSE)
++++++++ + {
++++++++ + //
++++++++ + // found value item
++++++++ + //
++++++++ + ItemCount++;
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // no report items
++++++++ + //
++++++++ + return ItemCount;
++++++++ + }
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetContextSize(
++++++++ + IN PHID_PARSER Parser)
++++++++ + {
++++++++ + //
++++++++ + // FIXME the context must contain all parsed info
++++++++ + //
++++++++ + return sizeof(HID_PARSER_CONTEXT);
++++++++ + }
++++++++ +
++++++++ + VOID
++++++++ + HidParser_FreeContext(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN PUCHAR Context,
++++++++ + IN ULONG ContextLength)
++++++++ + {
++++++++ + //
++++++++ + // FIXME implement freeing of parsed info
++++++++ + //
++++++++ + }
++++++++ +
++++++++ + HIDPARSER_STATUS
++++++++ + HidParser_AllocateParser(
++++++++ + IN PHIDPARSER_ALLOC_FUNCTION AllocFunction,
++++++++ + IN PHIDPARSER_FREE_FUNCTION FreeFunction,
++++++++ + IN PHIDPARSER_ZERO_FUNCTION ZeroFunction,
++++++++ + IN PHIDPARSER_COPY_FUNCTION CopyFunction,
++++++++ + IN PHIDPARSER_DEBUG_FUNCTION DebugFunction,
++++++++ + OUT PHID_PARSER *OutParser)
++++++++ + {
++++++++ + PHID_PARSER Parser;
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ +
++++++++ + //
++++++++ + // allocate
++++++++ + //
++++++++ + Parser = (PHID_PARSER)AllocFunction(sizeof(HID_PARSER));
++++++++ + if (!Parser)
++++++++ + {
++++++++ + //
++++++++ + // no memory
++++++++ + //
++++++++ + return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // allocate parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)AllocFunction(sizeof(HID_PARSER_CONTEXT));
++++++++ + if (!ParserContext)
++++++++ + {
++++++++ + //
++++++++ + // no memory
++++++++ + //
++++++++ + FreeFunction(Parser);
++++++++ + return HIDPARSER_STATUS_INSUFFICIENT_RESOURCES;
++++++++ + }
++++++++ +
++++++++ +
++++++++ + //
++++++++ + // init parser
++++++++ + //
++++++++ + Parser->Alloc = AllocFunction;
++++++++ + Parser->Free = FreeFunction;
++++++++ + Parser->Zero = ZeroFunction;
++++++++ + Parser->Copy = CopyFunction;
++++++++ + Parser->Debug = DebugFunction;
++++++++ + Parser->ParserContext = ParserContext;
++++++++ +
++++++++ + //
++++++++ + // store result
++++++++ + //
++++++++ + *OutParser = Parser;
++++++++ + //
++++++++ + // success
++++++++ + //
++++++++ + return HIDPARSER_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + VOID
++++++++ + HidParser_InitParser(
++++++++ + IN PHIDPARSER_ALLOC_FUNCTION AllocFunction,
++++++++ + IN PHIDPARSER_FREE_FUNCTION FreeFunction,
++++++++ + IN PHIDPARSER_ZERO_FUNCTION ZeroFunction,
++++++++ + IN PHIDPARSER_COPY_FUNCTION CopyFunction,
++++++++ + IN PHIDPARSER_DEBUG_FUNCTION DebugFunction,
++++++++ + IN PVOID ParserContext,
++++++++ + OUT PHID_PARSER Parser)
++++++++ + {
++++++++ + Parser->Alloc = AllocFunction;
++++++++ + Parser->Free = FreeFunction;
++++++++ + Parser->Zero = ZeroFunction;
++++++++ + Parser->Copy = CopyFunction;
++++++++ + Parser->Debug = DebugFunction;
++++++++ + Parser->ParserContext = ParserContext;
++++++++ + }
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetCollectionCount(
++++++++ + IN PHID_COLLECTION Collection)
++++++++ + {
++++++++ + ULONG Index;
++++++++ + ULONG Count = Collection->NodeCount;
++++++++ +
++++++++ + for(Index = 0; Index < Collection->NodeCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // count collection for sub nodes
++++++++ + //
++++++++ + Count += HidParser_GetCollectionCount(Collection->Nodes[Index]);
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + return Count;
++++++++ + }
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetTotalCollectionCount(
++++++++ + IN PHID_PARSER Parser)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity check
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ + ASSERT(ParserContext->RootCollection);
++++++++ +
++++++++ + //
++++++++ + // count collections
++++++++ + //
++++++++ + return HidParser_GetCollectionCount(ParserContext->RootCollection);
++++++++ + }
++++++++ +
++++++++ + ULONG
++++++++ + HidParser_GetMaxUsageListLengthWithReportAndPage(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType,
++++++++ + IN USAGE UsagePage OPTIONAL)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + PHID_REPORT Report;
++++++++ + ULONG ItemCount = 0;
++++++++ + USHORT CurrentUsagePage;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no such report
++++++++ + //
++++++++ + return 0;
++++++++ + }
++++++++ +
++++++++ + for(Index = 0; Index < Report->ItemCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // check usage page
++++++++ + //
++++++++ + CurrentUsagePage = (Report->Items[Index]->UsageMinimum >> 16);
++++++++ + if (CurrentUsagePage == UsagePage && Report->Items[Index]->HasData)
++++++++ + {
++++++++ + //
++++++++ + // found item
++++++++ + //
++++++++ + ItemCount++;
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + return ItemCount;
++++++++ + }
++++++++ +
++++++++ + HIDPARSER_STATUS
++++++++ + HidParser_GetSpecificValueCapsWithReport(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType,
++++++++ + IN USHORT UsagePage,
++++++++ + IN USHORT Usage,
++++++++ + OUT PHIDP_VALUE_CAPS ValueCaps,
++++++++ + IN OUT PULONG ValueCapsLength)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + PHID_REPORT Report;
++++++++ + ULONG ItemCount = 0;
++++++++ + USHORT CurrentUsagePage;
++++++++ + USHORT CurrentUsage;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no such report
++++++++ + //
++++++++ + return HIDPARSER_STATUS_REPORT_NOT_FOUND;
++++++++ + }
++++++++ +
++++++++ + for(Index = 0; Index < Report->ItemCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // check usage page
++++++++ + //
++++++++ + CurrentUsagePage = (Report->Items[Index]->UsageMinimum >> 16);
++++++++ + CurrentUsage = (Report->Items[Index]->UsageMinimum & 0xFFFF);
++++++++ +
++++++++ + if ((Usage == CurrentUsage && UsagePage == CurrentUsagePage) || (Usage == 0 && UsagePage == CurrentUsagePage) || (Usage == CurrentUsage && UsagePage == 0) || (Usage == 0 && UsagePage == 0))
++++++++ + {
++++++++ + //
++++++++ + // check if there is enough place for the caps
++++++++ + //
++++++++ + if (ItemCount < *ValueCapsLength)
++++++++ + {
++++++++ + //
++++++++ + // zero caps
++++++++ + //
++++++++ + Parser->Zero(&ValueCaps[ItemCount], sizeof(HIDP_VALUE_CAPS));
++++++++ +
++++++++ + //
++++++++ + // init caps
++++++++ + //
++++++++ + ValueCaps[ItemCount].UsagePage = CurrentUsagePage;
++++++++ + ValueCaps[ItemCount].ReportID = Report->ReportID;
++++++++ + ValueCaps[ItemCount].LogicalMin = Report->Items[Index]->Minimum;
++++++++ + ValueCaps[ItemCount].LogicalMax = Report->Items[Index]->Maximum;
++++++++ + ValueCaps[ItemCount].IsAbsolute = !Report->Items[Index]->Relative;
++++++++ + ValueCaps[ItemCount].BitSize = Report->Items[Index]->BitCount;
++++++++ +
++++++++ + //
++++++++ + // FIXME: FILLMEIN
++++++++ + //
++++++++ + }
++++++++ +
++++++++ +
++++++++ + //
++++++++ + // found item
++++++++ + //
++++++++ + ItemCount++;
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // store result
++++++++ + //
++++++++ + *ValueCapsLength = ItemCount;
++++++++ +
++++++++ + if (ItemCount)
++++++++ + {
++++++++ + //
++++++++ + // success
++++++++ + //
++++++++ + return HIDPARSER_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // item not found
++++++++ + //
++++++++ + return HIDPARSER_STATUS_USAGE_NOT_FOUND;
++++++++ + }
++++++++ +
++++++++ + HIDPARSER_STATUS
++++++++ + HidParser_GetUsagesWithReport(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + OUT USAGE *UsageList,
++++++++ + IN OUT PULONG UsageLength,
++++++++ + IN PCHAR ReportDescriptor,
++++++++ + IN ULONG ReportDescriptorLength)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + PHID_REPORT Report;
++++++++ + ULONG ItemCount = 0;
++++++++ + USHORT CurrentUsagePage;
++++++++ + PHID_REPORT_ITEM ReportItem;
++++++++ + UCHAR Activated;
++++++++ + ULONG Data;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no such report
++++++++ + //
++++++++ + return HIDPARSER_STATUS_REPORT_NOT_FOUND;
++++++++ + }
++++++++ +
++++++++ + if (Report->ReportSize / 8 != (ReportDescriptorLength - 1))
++++++++ + {
++++++++ + //
++++++++ + // invalid report descriptor length
++++++++ + //
++++++++ + return HIDPARSER_STATUS_INVALID_REPORT_LENGTH;
++++++++ + }
++++++++ +
++++++++ + for(Index = 0; Index < Report->ItemCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // get report item
++++++++ + //
++++++++ + ReportItem = Report->Items[Index];
++++++++ +
++++++++ + //
++++++++ + // does it have data
++++++++ + //
++++++++ + if (!ReportItem->HasData)
++++++++ + continue;
++++++++ +
++++++++ + //
++++++++ + // check usage page
++++++++ + //
++++++++ + CurrentUsagePage = (ReportItem->UsageMinimum >> 16);
++++++++ +
++++++++ + //
++++++++ + // does usage match
++++++++ + //
++++++++ + if (UsagePage != CurrentUsagePage)
++++++++ + continue;
++++++++ +
++++++++ + //
++++++++ + // check if the specified usage is activated
++++++++ + //
++++++++ + ASSERT(ReportItem->ByteOffset < ReportDescriptorLength);
++++++++ + ASSERT(ReportItem->BitCount < 8);
++++++++ +
++++++++ + //
++++++++ + // one extra shift for skipping the prepended report id
++++++++ + //
++++++++ + Data = ReportDescriptor[ReportItem->ByteOffset + 1];
++++++++ +
++++++++ + //
++++++++ + // shift data
++++++++ + //
++++++++ + Data >>= ReportItem->Shift;
++++++++ +
++++++++ + //
++++++++ + // clear unwanted bits
++++++++ + //
++++++++ + Data &= ReportItem->Mask;
++++++++ +
++++++++ + //
++++++++ + // is it activated
++++++++ + //
++++++++ + Activated = (Data != 0);
++++++++ +
++++++++ + if (!Activated)
++++++++ + continue;
++++++++ +
++++++++ + //
++++++++ + // is there enough space for the usage
++++++++ + //
++++++++ + if (ItemCount >= *UsageLength)
++++++++ + {
++++++++ + ItemCount++;
++++++++ + continue;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // store item
++++++++ + //
++++++++ + UsageList[ItemCount] = (ReportItem->UsageMinimum & 0xFFFF);
++++++++ + ItemCount++;
++++++++ + }
++++++++ +
++++++++ + if (ItemCount > *UsageLength)
++++++++ + {
++++++++ + //
++++++++ + // list too small
++++++++ + //
++++++++ + return HIDPARSER_STATUS_BUFFER_TOO_SMALL;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // success, clear rest of array
++++++++ + //
++++++++ + Parser->Zero(&UsageList[ItemCount], (*UsageLength - ItemCount) * sizeof(USAGE));
++++++++ +
++++++++ + //
++++++++ + // store result size
++++++++ + //
++++++++ + *UsageLength = ItemCount;
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + return HIDPARSER_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + HIDPARSER_STATUS
++++++++ + HidParser_GetScaledUsageValueWithReport(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN ULONG ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USAGE Usage,
++++++++ + OUT PLONG UsageValue,
++++++++ + IN PCHAR ReportDescriptor,
++++++++ + IN ULONG ReportDescriptorLength)
++++++++ + {
++++++++ + PHID_PARSER_CONTEXT ParserContext;
++++++++ + ULONG Index;
++++++++ + PHID_REPORT Report;
++++++++ + ULONG ItemCount = 0;
++++++++ + USHORT CurrentUsagePage;
++++++++ + PHID_REPORT_ITEM ReportItem;
++++++++ + ULONG Data;
++++++++ +
++++++++ + //
++++++++ + // get parser context
++++++++ + //
++++++++ + ParserContext = (PHID_PARSER_CONTEXT)Parser->ParserContext;
++++++++ +
++++++++ + //
++++++++ + // sanity checks
++++++++ + //
++++++++ + ASSERT(ParserContext);
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top collecions
++++++++ + //
++++++++ + ASSERT(ParserContext->RootCollection->NodeCount == 1);
++++++++ +
++++++++ + //
++++++++ + // get report
++++++++ + //
++++++++ + Report = HidParser_GetReportByType(Parser, ReportType);
++++++++ + if (!Report)
++++++++ + {
++++++++ + //
++++++++ + // no such report
++++++++ + //
++++++++ + return HIDPARSER_STATUS_REPORT_NOT_FOUND;
++++++++ + }
++++++++ +
++++++++ + if (Report->ReportSize / 8 != (ReportDescriptorLength - 1))
++++++++ + {
++++++++ + //
++++++++ + // invalid report descriptor length
++++++++ + //
++++++++ + return HIDPARSER_STATUS_INVALID_REPORT_LENGTH;
++++++++ + }
++++++++ +
++++++++ + for(Index = 0; Index < Report->ItemCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // get report item
++++++++ + //
++++++++ + ReportItem = Report->Items[Index];
++++++++ +
++++++++ + //
++++++++ + // check usage page
++++++++ + //
++++++++ + CurrentUsagePage = (ReportItem->UsageMinimum >> 16);
++++++++ +
++++++++ + //
++++++++ + // does usage page match
++++++++ + //
++++++++ + if (UsagePage != CurrentUsagePage)
++++++++ + continue;
++++++++ +
++++++++ + //
++++++++ + // does the usage match
++++++++ + //
++++++++ + if (Usage != (ReportItem->UsageMinimum & 0xFFFF))
++++++++ + continue;
++++++++ +
++++++++ + //
++++++++ + // check if the specified usage is activated
++++++++ + //
++++++++ + ASSERT(ReportItem->ByteOffset < ReportDescriptorLength);
++++++++ +
++++++++ + //
++++++++ + // one extra shift for skipping the prepended report id
++++++++ + //
++++++++ + Data = 0;
++++++++ + Parser->Copy(&Data, &ReportDescriptor[ReportItem->ByteOffset +1], min(sizeof(ULONG), ReportDescriptorLength - (ReportItem->ByteOffset + 1)));
++++++++ + Data = ReportDescriptor[ReportItem->ByteOffset + 1];
++++++++ +
++++++++ + //
++++++++ + // shift data
++++++++ + //
++++++++ + Data >>= ReportItem->Shift;
++++++++ +
++++++++ + //
++++++++ + // clear unwanted bits
++++++++ + //
++++++++ + Data &= ReportItem->Mask;
++++++++ +
++++++++ + if (ReportItem->Minimum > ReportItem->Maximum)
++++++++ + {
++++++++ + //
++++++++ + // logical boundaries are signed values
++++++++ + //
++++++++ + if ((Data & ~(ReportItem->Mask >> 1)) != 0)
++++++++ + {
++++++++ + Data |= ~ReportItem->Mask;
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // store result
++++++++ + //
++++++++ + *UsageValue = Data;
++++++++ + return HIDPARSER_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // usage not found
++++++++ + //
++++++++ + return HIDPARSER_STATUS_USAGE_NOT_FOUND;
++++++++ + }
++++++++++++
++++++++++++ULONG
++++++++++++HidParser_GetScanCode(
++++++++++++ IN USAGE Usage)
++++++++++++{
++++++++++++ if (Usage < sizeof(KeyboardScanCodes) / sizeof(KeyboardScanCodes[0]))
++++++++++++ {
++++++++++++ //
++++++++++++ // valid usage
++++++++++++ //
++++++++++++ return KeyboardScanCodes[Usage];
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // invalid usage
++++++++++++ //
++++++++++++ return 0;
++++++++++++}
++++++++++++
++++++++++++VOID
++++++++++++HidParser_DispatchKey(
++++++++++++ IN PCHAR ScanCodes,
++++++++++++ IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++++++ IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++++++ IN PVOID InsertCodesContext)
++++++++++++{
++++++++++++ ULONG Index;
++++++++++++ ULONG Length = 0;
++++++++++++
++++++++++++ //
++++++++++++ // count code length
++++++++++++ //
++++++++++++ for(Index = 0; Index < sizeof(ULONG); Index++)
++++++++++++ {
++++++++++++ if (ScanCodes[Index] == 0)
++++++++++++ {
++++++++++++ //
++++++++++++ // last scan code
++++++++++++ //
++++++++++++ break;
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // is this a key break
++++++++++++ //
++++++++++++ if (KeyAction == HidP_KeyboardBreak)
++++++++++++ {
++++++++++++ //
++++++++++++ // add break
++++++++++++ //
++++++++++++ ScanCodes[Index] |= KEY_BREAK;
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // more scan counts
++++++++++++ //
++++++++++++ Length++;
++++++++++++ }
++++++++++++
++++++++++++ if (Length > 0)
++++++++++++ {
++++++++++++ //
++++++++++++ // dispatch scan codes
++++++++++++ //
++++++++++++ InsertCodesProcedure(InsertCodesContext, ScanCodes, Length);
++++++++++++ }
++++++++++++}
++++++++++++
++++++++++++
++++++++++++HIDPARSER_STATUS
++++++++++++HidParser_TranslateUsage(
++++++++++++ IN PHID_PARSER Parser,
++++++++++++ IN USAGE Usage,
++++++++++++ IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++++++ IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
++++++++++++ IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++++++ IN PVOID InsertCodesContext)
++++++++++++{
++++++++++++ ULONG ScanCode;
++++++++++++
++++++++++++ //
++++++++++++ // get scan code
++++++++++++ //
++++++++++++ ScanCode = HidParser_GetScanCode(Usage);
++++++++++++ if (!ScanCode)
++++++++++++ {
++++++++++++ //
++++++++++++ // invalid lookup or no scan code available
++++++++++++ //
++++++++++++ return HIDPARSER_STATUS_I8042_TRANS_UNKNOWN;
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // FIXME: translate modifier states
++++++++++++ //
++++++++++++
++++++++++++ HidParser_DispatchKey((PCHAR)&ScanCode, KeyAction, InsertCodesProcedure, InsertCodesContext);
++++++++++++
++++++++++++ //
++++++++++++ // done
++++++++++++ //
++++++++++++ return HIDPARSER_STATUS_SUCCESS;
++++++++++++}
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
- -- UNIMPLEMENTED
- -- return STATUS_NOT_IMPLEMENTED;
++++++++ + /*
++++++++ + * PROJECT: ReactOS HID Parser Library
++++++++ + * LICENSE: GPL - See COPYING in the top level directory
++++++++ + * FILE: lib/drivers/hidparser/hidparser.c
++++++++ + * PURPOSE: HID Parser
++++++++ + * PROGRAMMERS:
++++++++ + * Michael Martin (michael.martin@reactos.org)
++++++++ + * Johannes Anderwald (johannes.anderwald@reactos.org)
++++++++ + */
++++++++ +
++++++++ + #include "parser.h"
++++++++ +
++++++++ + NTSTATUS
++++++++ + TranslateHidParserStatus(
++++++++ + IN HIDPARSER_STATUS Status)
++++++++ + {
- --HIDAPI
- --NTSTATUS
- --NTAPI
- --HidParser_TranslateUsageAndPagesToI8042ScanCodes(
- -- IN PUSAGE_AND_PAGE ChangedUsageList,
- -- IN ULONG UsageListLength,
- -- IN HIDP_KEYBOARD_DIRECTION KeyAction,
- -- IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
- -- IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
- -- IN PVOID InsertCodesContext)
- --{
- -- UNIMPLEMENTED
- -- ASSERT(FALSE);
- -- return STATUS_NOT_IMPLEMENTED;
- --}
- --
++++++++++++ switch(Status)
++++++++++++ {
++++++++++++ case HIDPARSER_STATUS_INSUFFICIENT_RESOURCES:
++++++++++++ return HIDP_STATUS_INTERNAL_ERROR;
++++++++++++ case HIDPARSER_STATUS_NOT_IMPLEMENTED:
++++++++++++ return HIDP_STATUS_NOT_IMPLEMENTED;
++++++++++++ case HIDPARSER_STATUS_REPORT_NOT_FOUND:
++++++++++++ return HIDP_STATUS_REPORT_DOES_NOT_EXIST;
++++++++++++ case HIDPARSER_STATUS_INVALID_REPORT_LENGTH:
++++++++++++ return HIDP_STATUS_INVALID_REPORT_LENGTH;
++++++++++++ case HIDPARSER_STATUS_INVALID_REPORT_TYPE:
++++++++++++ return HIDP_STATUS_INVALID_REPORT_TYPE;
++++++++++++ case HIDPARSER_STATUS_BUFFER_TOO_SMALL:
++++++++++++ return HIDP_STATUS_BUFFER_TOO_SMALL;
++++++++++++ case HIDPARSER_STATUS_USAGE_NOT_FOUND:
++++++++++++ return HIDP_STATUS_USAGE_NOT_FOUND;
++++++++++++ case HIDPARSER_STATUS_I8042_TRANS_UNKNOWN:
++++++++++++ return HIDP_STATUS_I8042_TRANS_UNKNOWN;
++++++++++++ case HIDPARSER_STATUS_COLLECTION_NOT_FOUND:
++++++++++++ return HIDP_STATUS_NOT_IMPLEMENTED; //FIXME
++++++++++++ }
++++++++++++ DPRINT1("TranslateHidParserStatus Status %ld not implemented\n", Status);
++++++++++++ return HIDP_STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetCollectionDescription(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
++++++++ + IN ULONG DescLength,
++++++++ + IN POOL_TYPE PoolType,
++++++++ + OUT PHIDP_DEVICE_DESC DeviceDescription)
++++++++ + {
++++++++ + HIDPARSER_STATUS ParserStatus;
++++++++ + ULONG CollectionCount, ReportCount;
++++++++ + ULONG Index;
++++++++ +
++++++++ + //
++++++++ + // first parse the report descriptor
++++++++ + //
++++++++ + ParserStatus = HidParser_ParseReportDescriptor(Parser, ReportDesc, DescLength);
++++++++ + if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
++++++++ + {
++++++++ + //
++++++++ + // failed to parse report descriptor
++++++++ + //
++++++++ + Parser->Debug("[HIDPARSER] Failed to parse report descriptor with %x\n", ParserStatus);
++++++++ + return TranslateHidParserStatus(ParserStatus);
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // get collection count
++++++++ + //
++++++++ + CollectionCount = HidParser_NumberOfTopCollections(Parser);
++++++++ +
++++++++ + //
++++++++ + // FIXME: only one top level collection is supported
++++++++ + //
++++++++ + ASSERT(CollectionCount <= 1);
++++++++ + if (CollectionCount == 0)
++++++++ + {
++++++++ + //
++++++++ + // no top level collections found
++++++++ + //
++++++++ + return STATUS_NO_DATA_DETECTED;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // zero description
++++++++ + //
++++++++ + Parser->Zero(DeviceDescription, sizeof(HIDP_DEVICE_DESC));
++++++++ +
++++++++ + //
++++++++ + // allocate collection
++++++++ + //
++++++++ + DeviceDescription->CollectionDesc = (PHIDP_COLLECTION_DESC)Parser->Alloc(sizeof(HIDP_COLLECTION_DESC) * CollectionCount);
++++++++ + if (!DeviceDescription->CollectionDesc)
++++++++ + {
++++++++ + //
++++++++ + // no memory
++++++++ + //
++++++++ + return STATUS_INSUFFICIENT_RESOURCES;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // allocate report description
++++++++ + //
++++++++ + DeviceDescription->ReportIDs = (PHIDP_REPORT_IDS)Parser->Alloc(sizeof(HIDP_REPORT_IDS) * CollectionCount);
++++++++ + if (!DeviceDescription->ReportIDs)
++++++++ + {
++++++++ + //
++++++++ + // no memory
++++++++ + //
++++++++ + Parser->Free(DeviceDescription->CollectionDesc);
++++++++ + return STATUS_INSUFFICIENT_RESOURCES;
++++++++ + }
++++++++ +
++++++++ + for(Index = 0; Index < CollectionCount; Index++)
++++++++ + {
++++++++ + //
++++++++ + // init report description
++++++++ + //
++++++++ + DeviceDescription->ReportIDs[Index].CollectionNumber = Index + 1;
++++++++ + DeviceDescription->ReportIDs[Index].ReportID = Index; //FIXME
++++++++ + DeviceDescription->ReportIDs[Index].InputLength = HidParser_GetReportLength(Parser, HID_REPORT_TYPE_INPUT);
++++++++ + DeviceDescription->ReportIDs[Index].OutputLength = HidParser_GetReportLength(Parser, HID_REPORT_TYPE_OUTPUT);
++++++++ + DeviceDescription->ReportIDs[Index].FeatureLength = HidParser_GetReportLength(Parser, HID_REPORT_TYPE_FEATURE);
++++++++ +
++++++++ + //
++++++++ + // init collection description
++++++++ + //
++++++++ + DeviceDescription->CollectionDesc[Index].CollectionNumber = Index + 1;
++++++++ +
++++++++ + //
++++++++ + // get collection usage page
++++++++ + //
++++++++ + ParserStatus = HidParser_GetCollectionUsagePage(Parser, Index, &DeviceDescription->CollectionDesc[Index].Usage, &DeviceDescription->CollectionDesc[Index].UsagePage);
++++++++ +
++++++++ + //
++++++++ + // windows seems to prepend the report id, regardless if it is required
++++++++ + //
++++++++ + DeviceDescription->CollectionDesc[Index].InputLength = (DeviceDescription->ReportIDs[Index].InputLength > 0 ? DeviceDescription->ReportIDs[Index].InputLength + 1 : 0);
++++++++ + DeviceDescription->CollectionDesc[Index].OutputLength = (DeviceDescription->ReportIDs[Index].OutputLength > 0 ? DeviceDescription->ReportIDs[Index].OutputLength + 1 : 0);
++++++++ + DeviceDescription->CollectionDesc[Index].FeatureLength = (DeviceDescription->ReportIDs[Index].FeatureLength > 0 ? DeviceDescription->ReportIDs[Index].FeatureLength + 1 : 0);
++++++++ +
++++++++ + //
++++++++ + // set preparsed data length
++++++++ + //
++++++++ + DeviceDescription->CollectionDesc[Index].PreparsedDataLength = HidParser_GetContextSize(Parser);
++++++++ + DeviceDescription->CollectionDesc[Index].PreparsedData = Parser->Alloc(DeviceDescription->CollectionDesc[Index].PreparsedDataLength);
++++++++ + if (!DeviceDescription->CollectionDesc[Index].PreparsedData)
++++++++ + {
++++++++ + //
++++++++ + // no memory
++++++++ + //
++++++++ + return STATUS_INSUFFICIENT_RESOURCES;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // copy context
++++++++ + //
++++++++ + Parser->Copy(DeviceDescription->CollectionDesc[Index].PreparsedData, Parser->ParserContext, DeviceDescription->CollectionDesc[Index].PreparsedDataLength);
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // store collection & report count
++++++++ + //
++++++++ + DeviceDescription->CollectionDescLength = CollectionCount;
++++++++ + DeviceDescription->ReportIDsLength = CollectionCount;
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + return STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + VOID
++++++++ + NTAPI
++++++++ + HidParser_FreeCollectionDescription(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN PHIDP_DEVICE_DESC DeviceDescription)
++++++++ + {
++++++++ + ULONG Index;
++++++++ +
++++++++ + //
++++++++ + // first free all context
++++++++ + //
++++++++ + for(Index = 0; Index < DeviceDescription->CollectionDescLength; Index++)
++++++++ + {
++++++++ + //
++++++++ + // free parser context
++++++++ + //
++++++++ + HidParser_FreeContext(Parser, (PUCHAR)DeviceDescription->CollectionDesc[Index].PreparsedData, DeviceDescription->CollectionDesc[Index].PreparsedDataLength);
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // now free collection description
++++++++ + //
++++++++ + Parser->Free(DeviceDescription->CollectionDesc);
++++++++ +
++++++++ + //
++++++++ + // free report description
++++++++ + //
++++++++ + ExFreePool(DeviceDescription->ReportIDs);
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + OUT PHIDP_CAPS Capabilities)
++++++++ + {
++++++++ + ULONG CollectionNumber;
++++++++ + //
++++++++ + // zero capabilities
++++++++ + //
++++++++ + Parser->Zero(Capabilities, sizeof(HIDP_CAPS));
++++++++ +
++++++++ + //
++++++++ + // FIXME support multiple top level collections
++++++++ + //
++++++++ + CollectionNumber = 0;
++++++++ +
++++++++ + //
++++++++ + // init capabilities
++++++++ + //
++++++++ + HidParser_GetCollectionUsagePage(Parser, CollectionNumber, &Capabilities->Usage, &Capabilities->UsagePage);
++++++++ + Capabilities->InputReportByteLength = HidParser_GetReportLength(Parser, HID_REPORT_TYPE_INPUT);
++++++++ + Capabilities->OutputReportByteLength = HidParser_GetReportLength(Parser, HID_REPORT_TYPE_OUTPUT);
++++++++ + Capabilities->FeatureReportByteLength = HidParser_GetReportLength(Parser, HID_REPORT_TYPE_FEATURE);
++++++++ +
++++++++ + //
++++++++ + // always pre-prend report id
++++++++ + //
++++++++ + Capabilities->InputReportByteLength = (Capabilities->InputReportByteLength > 0 ? Capabilities->InputReportByteLength + 1 : 0);
++++++++ + Capabilities->OutputReportByteLength = (Capabilities->OutputReportByteLength > 0 ? Capabilities->OutputReportByteLength + 1 : 0);
++++++++ + Capabilities->FeatureReportByteLength = (Capabilities->FeatureReportByteLength > 0 ? Capabilities->FeatureReportByteLength + 1 : 0);
++++++++ +
++++++++ + //
++++++++ + // get number of link collection nodes
++++++++ + //
++++++++ + Capabilities->NumberLinkCollectionNodes = HidParser_GetTotalCollectionCount(Parser);
++++++++ +
++++++++ + //
++++++++ + // get data indices
++++++++ + //
++++++++ + Capabilities->NumberInputDataIndices = HidParser_GetReportItemTypeCountFromReportType(Parser, HID_REPORT_TYPE_INPUT, TRUE);
++++++++ + Capabilities->NumberOutputDataIndices = HidParser_GetReportItemTypeCountFromReportType(Parser, HID_REPORT_TYPE_OUTPUT, TRUE);
++++++++ + Capabilities->NumberFeatureDataIndices = HidParser_GetReportItemTypeCountFromReportType(Parser, HID_REPORT_TYPE_FEATURE, TRUE);
++++++++ +
++++++++ + //
++++++++ + // get value caps
++++++++ + //
++++++++ + Capabilities->NumberInputValueCaps = HidParser_GetReportItemTypeCountFromReportType(Parser, HID_REPORT_TYPE_INPUT, FALSE);
++++++++ + Capabilities->NumberOutputValueCaps = HidParser_GetReportItemTypeCountFromReportType(Parser, HID_REPORT_TYPE_OUTPUT, FALSE);
++++++++ + Capabilities->NumberFeatureValueCaps = HidParser_GetReportItemTypeCountFromReportType(Parser, HID_REPORT_TYPE_FEATURE, FALSE);
++++++++ +
++++++++ +
++++++++ + //
++++++++ + // get button caps
++++++++ + //
++++++++ + Capabilities->NumberInputButtonCaps = HidParser_GetReportItemCountFromReportType(Parser, HID_REPORT_TYPE_INPUT);
++++++++ + Capabilities->NumberOutputButtonCaps = HidParser_GetReportItemCountFromReportType(Parser, HID_REPORT_TYPE_OUTPUT);
++++++++ + Capabilities->NumberFeatureButtonCaps = HidParser_GetReportItemCountFromReportType(Parser, HID_REPORT_TYPE_FEATURE);
++++++++ +
++++++++ + //
++++++++ + // done
++++++++ + //
++++++++ + return HIDP_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + ULONG
++++++++ + NTAPI
++++++++ + HidParser_MaxUsageListLength(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage OPTIONAL)
++++++++ + {
++++++++ + //
++++++++ + // FIXME test what should be returned when usage page is not defined
++++++++ + //
++++++++ + if (UsagePage == HID_USAGE_PAGE_UNDEFINED)
++++++++ + {
++++++++ + //
++++++++ + // implement me
++++++++ + //
++++++++ + UNIMPLEMENTED
++++++++ +
++++++++ + //
++++++++ + // invalid report
++++++++ + //
++++++++ + return 0;
++++++++ + }
++++++++ +
++++++++ + if (ReportType == HidP_Input)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + return HidParser_GetMaxUsageListLengthWithReportAndPage(Parser, HID_REPORT_TYPE_INPUT, UsagePage);
++++++++ + }
++++++++ + else if (ReportType == HidP_Output)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + return HidParser_GetMaxUsageListLengthWithReportAndPage(Parser, HID_REPORT_TYPE_OUTPUT, UsagePage);
++++++++ + }
++++++++ + else if (ReportType == HidP_Feature)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + return HidParser_GetMaxUsageListLengthWithReportAndPage(Parser, HID_REPORT_TYPE_FEATURE, UsagePage);
++++++++ + }
++++++++ + else
++++++++ + {
++++++++ + //
++++++++ + // invalid report type
++++++++ + //
++++++++ + return 0;
++++++++ + }
++++++++ + }
++++++++ +
++++++++ + #undef HidParser_GetButtonCaps
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetButtonCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN PHIDP_BUTTON_CAPS ButtonCaps,
++++++++ + IN PUSHORT ButtonCapsLength)
++++++++ + {
++++++++ + return HidParser_GetSpecificButtonCaps(Parser, ReportType, HID_USAGE_PAGE_UNDEFINED, HIDP_LINK_COLLECTION_UNSPECIFIED, HID_USAGE_PAGE_UNDEFINED, ButtonCaps, (PULONG)ButtonCapsLength);
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetSpecificValueCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PHIDP_VALUE_CAPS ValueCaps,
++++++++ + IN OUT PULONG ValueCapsLength)
++++++++ + {
++++++++ + HIDPARSER_STATUS ParserStatus;
++++++++ +
++++++++ + //
++++++++ + // FIXME: implement searching in specific collection
++++++++ + //
++++++++ + ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
++++++++ +
++++++++ + if (ReportType == HidP_Input)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetSpecificValueCapsWithReport(Parser, HID_REPORT_TYPE_INPUT, UsagePage, Usage, ValueCaps, ValueCapsLength);
++++++++ + }
++++++++ + else if (ReportType == HidP_Output)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetSpecificValueCapsWithReport(Parser, HID_REPORT_TYPE_OUTPUT, UsagePage, Usage, ValueCaps, ValueCapsLength);
++++++++ + }
++++++++ + else if (ReportType == HidP_Feature)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetSpecificValueCapsWithReport(Parser, HID_REPORT_TYPE_FEATURE, UsagePage, Usage, ValueCaps, ValueCapsLength);
++++++++ + }
++++++++ + else
++++++++ + {
++++++++ + //
++++++++ + // invalid report type
++++++++ + //
++++++++ + return HIDP_STATUS_INVALID_REPORT_TYPE;
++++++++ + }
++++++++ +
++++++++ +
++++++++ + if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
++++++++ + {
++++++++ + //
++++++++ + // success
++++++++ + //
++++++++ + return HIDP_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // translate error
++++++++ + //
++++++++ + return TranslateHidParserStatus(ParserStatus);
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_UsageListDifference(
++++++++ + IN PUSAGE PreviousUsageList,
++++++++ + IN PUSAGE CurrentUsageList,
++++++++ + OUT PUSAGE BreakUsageList,
++++++++ + OUT PUSAGE MakeUsageList,
++++++++ + IN ULONG UsageListLength)
++++++++ + {
++++++++ + ULONG Index, SubIndex, bFound, BreakUsageIndex = 0, MakeUsageIndex = 0;
++++++++ + USAGE CurrentUsage, Usage;
++++++++ +
++++++++ + if (UsageListLength)
++++++++ + {
++++++++ + Index = 0;
++++++++ + do
++++++++ + {
++++++++ + /* get current usage */
++++++++ + CurrentUsage = PreviousUsageList[Index];
++++++++ +
++++++++ + /* is the end of list reached? */
++++++++ + if (!CurrentUsage)
++++++++ + break;
++++++++ +
++++++++ + /* start searching in current usage list */
++++++++ + SubIndex = 0;
++++++++ + bFound = FALSE;
++++++++ + do
++++++++ + {
++++++++ + /* get usage of current list */
++++++++ + Usage = CurrentUsageList[SubIndex];
++++++++ +
++++++++ + /* end of list reached? */
++++++++ + if (!Usage)
++++++++ + break;
++++++++ +
++++++++ + /* check if it matches the current one */
++++++++ + if (CurrentUsage == Usage)
++++++++ + {
++++++++ + /* it does */
++++++++ + bFound = TRUE;
++++++++ + break;
++++++++ + }
++++++++ +
++++++++ + /* move to next usage */
++++++++ + SubIndex++;
++++++++ + }while(SubIndex < UsageListLength);
++++++++ +
++++++++ + /* was the usage found ?*/
++++++++ + if (!bFound)
++++++++ + {
++++++++ + /* store it in the break usage list */
++++++++ + BreakUsageList[BreakUsageIndex] = CurrentUsage;
++++++++ + BreakUsageIndex++;
++++++++ + }
++++++++ +
++++++++ + /* move to next usage */
++++++++ + Index++;
++++++++ +
++++++++ + }while(Index < UsageListLength);
++++++++ +
++++++++ + /* now process the new items */
++++++++ + Index = 0;
++++++++ + do
++++++++ + {
++++++++ + /* get current usage */
++++++++ + CurrentUsage = CurrentUsageList[Index];
++++++++ +
++++++++ + /* is the end of list reached? */
++++++++ + if (!CurrentUsage)
++++++++ + break;
++++++++ +
++++++++ + /* start searching in current usage list */
++++++++ + SubIndex = 0;
++++++++ + bFound = FALSE;
++++++++ + do
++++++++ + {
++++++++ + /* get usage of previous list */
++++++++ + Usage = PreviousUsageList[SubIndex];
++++++++ +
++++++++ + /* end of list reached? */
++++++++ + if (!Usage)
++++++++ + break;
++++++++ +
++++++++ + /* check if it matches the current one */
++++++++ + if (CurrentUsage == Usage)
++++++++ + {
++++++++ + /* it does */
++++++++ + bFound = TRUE;
++++++++ + break;
++++++++ + }
++++++++ +
++++++++ + /* move to next usage */
++++++++ + SubIndex++;
++++++++ + }while(SubIndex < UsageListLength);
++++++++ +
++++++++ + /* was the usage found ?*/
++++++++ + if (!bFound)
++++++++ + {
++++++++ + /* store it in the make usage list */
++++++++ + MakeUsageList[MakeUsageIndex] = CurrentUsage;
++++++++ + MakeUsageIndex++;
++++++++ + }
++++++++ +
++++++++ + /* move to next usage */
++++++++ + Index++;
++++++++ +
++++++++ + }while(Index < UsageListLength);
++++++++ + }
++++++++ +
++++++++ + /* does the break list contain empty entries */
++++++++ + if (BreakUsageIndex < UsageListLength)
++++++++ + {
++++++++ + /* zeroize entries */
++++++++ + RtlZeroMemory(&BreakUsageList[BreakUsageIndex], sizeof(USAGE) * (UsageListLength - BreakUsageIndex));
++++++++ + }
++++++++ +
++++++++ + /* does the make usage list contain empty entries */
++++++++ + if (MakeUsageIndex < UsageListLength)
++++++++ + {
++++++++ + /* zeroize entries */
++++++++ + RtlZeroMemory(&MakeUsageList[MakeUsageIndex], sizeof(USAGE) * (UsageListLength - MakeUsageIndex));
++++++++ + }
++++++++ +
++++++++ + /* done */
++++++++ + return HIDP_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsages(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + OUT USAGE *UsageList,
++++++++ + IN OUT PULONG UsageLength,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + HIDPARSER_STATUS ParserStatus;
++++++++ +
++++++++ + //
++++++++ + // FIXME: implement searching in specific collection
++++++++ + //
++++++++ + ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
++++++++ +
++++++++ + if (ReportType == HidP_Input)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetUsagesWithReport(Parser, HID_REPORT_TYPE_INPUT, UsagePage, UsageList, UsageLength, Report, ReportLength);
++++++++ + }
++++++++ + else if (ReportType == HidP_Output)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetUsagesWithReport(Parser, HID_REPORT_TYPE_OUTPUT, UsagePage, UsageList, UsageLength, Report, ReportLength);
++++++++ + }
++++++++ + else if (ReportType == HidP_Feature)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetUsagesWithReport(Parser, HID_REPORT_TYPE_FEATURE, UsagePage, UsageList, UsageLength, Report, ReportLength);
++++++++ + }
++++++++ + else
++++++++ + {
++++++++ + //
++++++++ + // invalid report type
++++++++ + //
++++++++ + return HIDP_STATUS_INVALID_REPORT_TYPE;
++++++++ + }
++++++++ +
++++++++ + if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
++++++++ + {
++++++++ + //
++++++++ + // success
++++++++ + //
++++++++ + return HIDP_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // translate error
++++++++ + //
++++++++ + return TranslateHidParserStatus(ParserStatus);
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetScaledUsageValue(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + OUT PLONG UsageValue,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + HIDPARSER_STATUS ParserStatus;
++++++++ +
++++++++ + //
++++++++ + // FIXME: implement searching in specific collection
++++++++ + //
++++++++ + ASSERT(LinkCollection == HIDP_LINK_COLLECTION_UNSPECIFIED);
++++++++ +
++++++++ + if (ReportType == HidP_Input)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetScaledUsageValueWithReport(Parser, HID_REPORT_TYPE_INPUT, UsagePage, Usage, UsageValue, Report, ReportLength);
++++++++ + }
++++++++ + else if (ReportType == HidP_Output)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetScaledUsageValueWithReport(Parser, HID_REPORT_TYPE_OUTPUT, UsagePage, Usage, UsageValue, Report, ReportLength);
++++++++ + }
++++++++ + else if (ReportType == HidP_Feature)
++++++++ + {
++++++++ + //
++++++++ + // input report
++++++++ + //
++++++++ + ParserStatus = HidParser_GetScaledUsageValueWithReport(Parser, HID_REPORT_TYPE_FEATURE, UsagePage, Usage, UsageValue, Report, ReportLength);
++++++++ + }
++++++++ + else
++++++++ + {
++++++++ + //
++++++++ + // invalid report type
++++++++ + //
++++++++ + return HIDP_STATUS_INVALID_REPORT_TYPE;
++++++++ + }
++++++++ +
++++++++ + if (ParserStatus == HIDPARSER_STATUS_SUCCESS)
++++++++ + {
++++++++ + //
++++++++ + // success
++++++++ + //
++++++++ + return HIDP_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + //
++++++++ + // translate error
++++++++ + //
++++++++ + return TranslateHidParserStatus(ParserStatus);
++++++++ + }
++++++++ +
++++++++++++HIDAPI
++++++++++++NTSTATUS
++++++++++++NTAPI
++++++++++++HidParser_TranslateUsageAndPagesToI8042ScanCodes(
++++++++++++ IN PHID_PARSER Parser,
++++++++++++ IN PUSAGE_AND_PAGE ChangedUsageList,
++++++++++++ IN ULONG UsageListLength,
++++++++++++ IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++++++ IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
++++++++++++ IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++++++ IN PVOID InsertCodesContext)
++++++++++++{
++++++++++++ ULONG Index;
++++++++++++ HIDPARSER_STATUS Status = HIDPARSER_STATUS_SUCCESS;
++++++++++++
++++++++++++ for(Index = 0; Index < UsageListLength; Index++)
++++++++++++ {
++++++++++++ //
++++++++++++ // check current usage
++++++++++++ //
++++++++++++ if (ChangedUsageList[Index].UsagePage == HID_USAGE_PAGE_KEYBOARD)
++++++++++++ {
++++++++++++ //
++++++++++++ // process usage
++++++++++++ //
++++++++++++ Status = HidParser_TranslateUsage(Parser, ChangedUsageList[Index].Usage, KeyAction, ModifierState, InsertCodesProcedure, InsertCodesContext);
++++++++++++ }
++++++++++++ else if (ChangedUsageList[Index].UsagePage == HID_USAGE_PAGE_CONSUMER)
++++++++++++ {
++++++++++++ //
++++++++++++ // FIXME: implement me
++++++++++++ //
++++++++++++ UNIMPLEMENTED
++++++++++++ Status = HIDPARSER_STATUS_NOT_IMPLEMENTED;
++++++++++++ }
++++++++++++ else
++++++++++++ {
++++++++++++ //
++++++++++++ // invalid page
++++++++++++ //
++++++++++++ DPRINT1("[HIDPARSE] Error unexpected usage page %x\n", ChangedUsageList[Index].UsagePage);
++++++++++++ return HIDP_STATUS_I8042_TRANS_UNKNOWN;
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // check status
++++++++++++ //
++++++++++++ if (Status != HIDPARSER_STATUS_SUCCESS)
++++++++++++ {
++++++++++++ //
++++++++++++ // failed
++++++++++++ //
++++++++++++ return TranslateHidParserStatus(Status);
++++++++++++ }
++++++++++++ }
++++++++++++
++++++++++++ if (Status != HIDPARSER_STATUS_SUCCESS)
++++++++++++ {
++++++++++++ //
++++++++++++ // failed
++++++++++++ //
++++++++++++ return TranslateHidParserStatus(Status);
++++++++++++ }
++++++++++++
++++++++++++ //
++++++++++++ // done
++++++++++++ //
++++++++++++ return HIDP_STATUS_SUCCESS;
++++++++++++}
++++++++++++
++++++++++++
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsagesEx(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USHORT LinkCollection,
++++++++ + OUT PUSAGE_AND_PAGE ButtonList,
++++++++ + IN OUT ULONG *UsageLength,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + return HidParser_GetUsages(Parser, ReportType, HID_USAGE_PAGE_UNDEFINED, LinkCollection, (PUSAGE)ButtonList, UsageLength, Report, ReportLength);
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_UsageAndPageListDifference(
++++++++ + IN PUSAGE_AND_PAGE PreviousUsageList,
++++++++ + IN PUSAGE_AND_PAGE CurrentUsageList,
++++++++ + OUT PUSAGE_AND_PAGE BreakUsageList,
++++++++ + OUT PUSAGE_AND_PAGE MakeUsageList,
++++++++ + IN ULONG UsageListLength)
++++++++ + {
++++++++ + ULONG Index, SubIndex, BreakUsageListIndex = 0, MakeUsageListIndex = 0, bFound;
++++++++ + PUSAGE_AND_PAGE CurrentUsage, Usage;
++++++++ +
++++++++ + if (UsageListLength)
++++++++ + {
++++++++ + /* process removed usages */
++++++++ + Index = 0;
++++++++ + do
++++++++ + {
++++++++ + /* get usage from current index */
++++++++ + CurrentUsage = &PreviousUsageList[Index];
++++++++ +
++++++++ + /* end of list reached? */
++++++++ + if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
++++++++ + break;
++++++++ +
++++++++ + /* search in current list */
++++++++ + SubIndex = 0;
++++++++ + bFound = FALSE;
++++++++ + do
++++++++ + {
++++++++ + /* get usage */
++++++++ + Usage = &CurrentUsageList[SubIndex];
++++++++ +
++++++++ + /* end of list reached? */
++++++++ + if (Usage->Usage == 0 && Usage->UsagePage == 0)
++++++++ + break;
++++++++ +
++++++++ + /* does it match */
++++++++ + if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
++++++++ + {
++++++++ + /* found match */
++++++++ + bFound = TRUE;
++++++++ + }
++++++++ +
++++++++ + /* move to next index */
++++++++ + SubIndex++;
++++++++ +
++++++++ + }while(SubIndex < UsageListLength);
++++++++ +
++++++++ + if (!bFound)
++++++++ + {
++++++++ + /* store it in break usage list */
++++++++ + BreakUsageList[BreakUsageListIndex].Usage = CurrentUsage->Usage;
++++++++ + BreakUsageList[BreakUsageListIndex].UsagePage = CurrentUsage->UsagePage;
++++++++ + BreakUsageListIndex++;
++++++++ + }
++++++++ +
++++++++ + /* move to next index */
++++++++ + Index++;
++++++++ +
++++++++ + }while(Index < UsageListLength);
++++++++ +
++++++++ + /* process new usages */
++++++++ + Index = 0;
++++++++ + do
++++++++ + {
++++++++ + /* get usage from current index */
++++++++ + CurrentUsage = &CurrentUsageList[Index];
++++++++ +
++++++++ + /* end of list reached? */
++++++++ + if (CurrentUsage->Usage == 0 && CurrentUsage->UsagePage == 0)
++++++++ + break;
++++++++ +
++++++++ + /* search in current list */
++++++++ + SubIndex = 0;
++++++++ + bFound = FALSE;
++++++++ + do
++++++++ + {
++++++++ + /* get usage */
++++++++ + Usage = &PreviousUsageList[SubIndex];
++++++++ +
++++++++ + /* end of list reached? */
++++++++ + if (Usage->Usage == 0 && Usage->UsagePage == 0)
++++++++ + break;
++++++++ +
++++++++ + /* does it match */
++++++++ + if (Usage->Usage == CurrentUsage->Usage && Usage->UsagePage == CurrentUsage->UsagePage)
++++++++ + {
++++++++ + /* found match */
++++++++ + bFound = TRUE;
++++++++ + }
++++++++ +
++++++++ + /* move to next index */
++++++++ + SubIndex++;
++++++++ +
++++++++ + }while(SubIndex < UsageListLength);
++++++++ +
++++++++ + if (!bFound)
++++++++ + {
++++++++ + /* store it in break usage list */
++++++++ + MakeUsageList[MakeUsageListIndex].Usage = CurrentUsage->Usage;
++++++++ + MakeUsageList[MakeUsageListIndex].UsagePage = CurrentUsage->UsagePage;
++++++++ + MakeUsageListIndex++;
++++++++ + }
++++++++ +
++++++++ + /* move to next index */
++++++++ + Index++;
++++++++ + }while(Index < UsageListLength);
++++++++ + }
++++++++ +
++++++++ + /* are there remaining free list entries */
++++++++ + if (BreakUsageListIndex < UsageListLength)
++++++++ + {
++++++++ + /* zero them */
++++++++ + RtlZeroMemory(&BreakUsageList[BreakUsageListIndex], (UsageListLength - BreakUsageListIndex) * sizeof(USAGE_AND_PAGE));
++++++++ + }
++++++++ +
++++++++ + /* are there remaining free list entries */
++++++++ + if (MakeUsageListIndex < UsageListLength)
++++++++ + {
++++++++ + /* zero them */
++++++++ + RtlZeroMemory(&MakeUsageList[MakeUsageListIndex], (UsageListLength - MakeUsageListIndex) * sizeof(USAGE_AND_PAGE));
++++++++ + }
++++++++ +
++++++++ + /* done */
++++++++ + return HIDP_STATUS_SUCCESS;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetSpecificButtonCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PHIDP_BUTTON_CAPS ButtonCaps,
++++++++ + IN OUT PULONG ButtonCapsLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetData(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + OUT PHIDP_DATA DataList,
++++++++ + IN OUT PULONG DataLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetExtendedAttributes(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USHORT DataIndex,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
++++++++ + IN OUT PULONG LengthAttributes)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetLinkCollectionNodes(
++++++++ + OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
++++++++ + IN OUT PULONG LinkCollectionNodesLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsageValue(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PULONG UsageValue,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ +
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SysPowerEvent (
++++++++ + IN PCHAR HidPacket,
++++++++ + IN USHORT HidPacketLength,
++++++++ + IN PHIDP_PREPARSED_DATA Ppd,
++++++++ + OUT PULONG OutputBuffer)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SysPowerCaps (
++++++++ + IN PHIDP_PREPARSED_DATA Ppd,
++++++++ + OUT PULONG OutputBuffer)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsageValueArray(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + OUT PCHAR UsageValue,
++++++++ + IN USHORT UsageValueByteLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_UnsetUsages(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN PUSAGE UsageList,
++++++++ + IN OUT PULONG UsageLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_TranslateUsagesToI8042ScanCodes(
++++++++ + IN PUSAGE ChangedUsageList,
++++++++ + IN ULONG UsageListLength,
++++++++ + IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++ + IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
++++++++ + IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++ + IN PVOID InsertCodesContext)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetUsages(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN PUSAGE UsageList,
++++++++ + IN OUT PULONG UsageLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetUsageValueArray(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + IN PCHAR UsageValue,
++++++++ + IN USHORT UsageValueByteLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetUsageValue(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + IN ULONG UsageValue,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetScaledUsageValue(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + IN LONG UsageValue,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetData(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN PHIDP_DATA DataList,
++++++++ + IN OUT PULONG DataLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + ULONG
++++++++ + NTAPI
++++++++ + HidParser_MaxDataListLength(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_InitializeReportForID(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN UCHAR ReportID,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
++++++++ +
++++++++ + #undef HidParser_GetValueCaps
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetValueCaps(
++++++++ + HIDP_REPORT_TYPE ReportType,
++++++++ + PHIDP_VALUE_CAPS ValueCaps,
++++++++ + PULONG ValueCapsLength,
++++++++ + PHIDP_PREPARSED_DATA PreparsedData)
++++++++ + {
++++++++ + UNIMPLEMENTED
++++++++ + ASSERT(FALSE);
++++++++ + return STATUS_NOT_IMPLEMENTED;
++++++++ + }
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
--- /dev/null
- -- HIDPARSER_STATUS_USAGE_NOT_FOUND = 8
++++++++ + /*
++++++++ + * PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
++++++++ + * LICENSE: GPL - See COPYING in the top level directory
++++++++ + * FILE: lib/drivers/hidparser/hidparser.c
++++++++ + * PURPOSE: HID Parser
++++++++ + * PROGRAMMERS:
++++++++ + * Michael Martin (michael.martin@reactos.org)
++++++++ + * Johannes Anderwald (johannes.anderwald@reactos.org)
++++++++ + */
++++++++ +
++++++++ + #pragma once
++++++++ +
++++++++ + #define _HIDPI_
++++++++ + #define _HIDPI_NO_FUNCTION_MACROS_
++++++++ + #include <ntddk.h>
++++++++ + #include <hidpddi.h>
++++++++ + #include <hidpi.h>
++++++++ + #include <debug.h>
++++++++ +
++++++++ + //
++++++++ + // function prototypes
++++++++ + //
++++++++ + typedef PVOID (NTAPI *PHIDPARSER_ALLOC_FUNCTION)(ULONG Size);
++++++++ + typedef VOID (NTAPI *PHIDPARSER_FREE_FUNCTION)(PVOID Item);
++++++++ + typedef VOID (NTAPI *PHIDPARSER_ZERO_FUNCTION)(PVOID Item, ULONG Size);
++++++++ + typedef VOID (NTAPI *PHIDPARSER_COPY_FUNCTION)(PVOID Target, PVOID Source, ULONG Size);
++++++++ + typedef VOID (NTAPI *PHIDPARSER_DEBUG_FUNCTION)(LPCSTR Src, ...);
++++++++ +
++++++++ + //
++++++++ + // status code
++++++++ + //
++++++++ + typedef long HIDPARSER_STATUS;
++++++++ +
++++++++ + //
++++++++ + // result codes
++++++++ + //
++++++++ + typedef enum
++++++++ + {
++++++++ + HIDPARSER_STATUS_SUCCESS = 0,
++++++++ + HIDPARSER_STATUS_INSUFFICIENT_RESOURCES = -1,
++++++++ + HIDPARSER_STATUS_NOT_IMPLEMENTED = -2,
++++++++ + HIDPARSER_STATUS_REPORT_NOT_FOUND = -3,
++++++++ + HIDPARSER_STATUS_COLLECTION_NOT_FOUND = -4,
++++++++ + HIDPARSER_STATUS_INVALID_REPORT_LENGTH = -5,
++++++++ + HIDPARSER_STATUS_INVALID_REPORT_TYPE = -6,
++++++++ + HIDPARSER_STATUS_BUFFER_TOO_SMALL = -7,
++++++++++++ HIDPARSER_STATUS_USAGE_NOT_FOUND = -8,
++++++++++++ HIDPARSER_STATUS_I8042_TRANS_UNKNOWN = -9
++++++++ + }HIDPARSER_STATUS_CODES;
++++++++ +
++++++++ + typedef struct
++++++++ + {
++++++++ + //
++++++++ + // size of struct
++++++++ + //
++++++++ + unsigned long Size;
++++++++ +
++++++++ + //
++++++++ + // allocation function
++++++++ + //
++++++++ + PHIDPARSER_ALLOC_FUNCTION Alloc;
++++++++ +
++++++++ + //
++++++++ + // free function
++++++++ + //
++++++++ + PFREE_FUNCTION Free;
++++++++ +
++++++++ + //
++++++++ + // zero function
++++++++ + //
++++++++ + PHIDPARSER_ZERO_FUNCTION Zero;
++++++++ +
++++++++ + //
++++++++ + // copy function
++++++++ + //
++++++++ + PHIDPARSER_COPY_FUNCTION Copy;
++++++++ +
++++++++ + //
++++++++ + // debug function
++++++++ + //
++++++++ + PHIDPARSER_DEBUG_FUNCTION Debug;
++++++++ +
++++++++ + //
++++++++ + // parser context
++++++++ + //
++++++++ + void * ParserContext;
++++++++ +
++++++++ + }HID_PARSER, *PHID_PARSER;
++++++++ +
++++++++ + HIDPARSER_STATUS
++++++++ + HidParser_AllocateParser(
++++++++ + IN PHIDPARSER_ALLOC_FUNCTION AllocFunction,
++++++++ + IN PHIDPARSER_FREE_FUNCTION FreeFunction,
++++++++ + IN PHIDPARSER_ZERO_FUNCTION ZeroFunction,
++++++++ + IN PHIDPARSER_COPY_FUNCTION CopyFunction,
++++++++ + IN PHIDPARSER_DEBUG_FUNCTION DebugFunction,
++++++++ + OUT PHID_PARSER *OutParser);
++++++++ +
++++++++ + VOID
++++++++ + HidParser_InitParser(
++++++++ + IN PHIDPARSER_ALLOC_FUNCTION AllocFunction,
++++++++ + IN PHIDPARSER_FREE_FUNCTION FreeFunction,
++++++++ + IN PHIDPARSER_ZERO_FUNCTION ZeroFunction,
++++++++ + IN PHIDPARSER_COPY_FUNCTION CopyFunction,
++++++++ + IN PHIDPARSER_DEBUG_FUNCTION DebugFunction,
++++++++ + IN PVOID ParserContext,
++++++++ + OUT PHID_PARSER Parser);
++++++++ +
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetCollectionDescription(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN PHIDP_REPORT_DESCRIPTOR ReportDesc,
++++++++ + IN ULONG DescLength,
++++++++ + IN POOL_TYPE PoolType,
++++++++ + OUT PHIDP_DEVICE_DESC DeviceDescription);
++++++++ +
++++++++ + VOID
++++++++ + NTAPI
++++++++ + HidParser_FreeCollectionDescription(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN PHIDP_DEVICE_DESC DeviceDescription);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + OUT PHIDP_CAPS Capabilities);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetSpecificValueCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PHIDP_VALUE_CAPS ValueCaps,
++++++++ + IN OUT PULONG ValueCapsLength);
++++++++ +
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetButtonCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + HIDP_REPORT_TYPE ReportType,
++++++++ + PHIDP_BUTTON_CAPS ButtonCaps,
++++++++ + PUSHORT ButtonCapsLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetSpecificButtonCaps(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PHIDP_BUTTON_CAPS ButtonCaps,
++++++++ + IN OUT PULONG ButtonCapsLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetScaledUsageValue(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + OUT PLONG UsageValue,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetData(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + OUT PHIDP_DATA DataList,
++++++++ + IN OUT PULONG DataLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetExtendedAttributes(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USHORT DataIndex,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
++++++++ + IN OUT PULONG LengthAttributes);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetLinkCollectionNodes(
++++++++ + OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
++++++++ + IN OUT PULONG LinkCollectionNodesLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsageValue(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + OUT PULONG UsageValue,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_UsageListDifference(
++++++++ + IN PUSAGE PreviousUsageList,
++++++++ + IN PUSAGE CurrentUsageList,
++++++++ + OUT PUSAGE BreakUsageList,
++++++++ + OUT PUSAGE MakeUsageList,
++++++++ + IN ULONG UsageListLength);
++++++++ +
++++++++ +
++++++++ + HIDAPI
++++++++ + ULONG
++++++++ + NTAPI
++++++++ + HidParser_MaxUsageListLength(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage OPTIONAL);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsages(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + OUT USAGE *UsageList,
++++++++ + IN OUT ULONG *UsageLength,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsagesEx(
++++++++ + IN PHID_PARSER Parser,
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USHORT LinkCollection,
++++++++ + OUT PUSAGE_AND_PAGE ButtonList,
++++++++ + IN OUT ULONG *UsageLength,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ +
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SysPowerEvent (
++++++++ + IN PCHAR HidPacket,
++++++++ + IN USHORT HidPacketLength,
++++++++ + IN PHIDP_PREPARSED_DATA Ppd,
++++++++ + OUT PULONG OutputBuffer);
++++++++ +
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SysPowerCaps (
++++++++ + IN PHIDP_PREPARSED_DATA Ppd,
++++++++ + OUT PULONG OutputBuffer);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetUsageValueArray(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + OUT PCHAR UsageValue,
++++++++ + IN USHORT UsageValueByteLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_UsageAndPageListDifference(
++++++++ + IN PUSAGE_AND_PAGE PreviousUsageList,
++++++++ + IN PUSAGE_AND_PAGE CurrentUsageList,
++++++++ + OUT PUSAGE_AND_PAGE BreakUsageList,
++++++++ + OUT PUSAGE_AND_PAGE MakeUsageList,
++++++++ + IN ULONG UsageListLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_UnsetUsages(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN PUSAGE UsageList,
++++++++ + IN OUT PULONG UsageLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_TranslateUsagesToI8042ScanCodes(
++++++++ + IN PUSAGE ChangedUsageList,
++++++++ + IN ULONG UsageListLength,
++++++++ + IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++ + IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
++++++++ + IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++ + IN PVOID InsertCodesContext);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_TranslateUsageAndPagesToI8042ScanCodes(
++++++++ + IN PUSAGE_AND_PAGE ChangedUsageList,
++++++++ + IN ULONG UsageListLength,
++++++++ + IN HIDP_KEYBOARD_DIRECTION KeyAction,
++++++++ + IN OUT PHIDP_KEYBOARD_MODIFIER_STATE ModifierState,
++++++++ + IN PHIDP_INSERT_SCANCODES InsertCodesProcedure,
++++++++ + IN PVOID InsertCodesContext);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetUsages(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN PUSAGE UsageList,
++++++++ + IN OUT PULONG UsageLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetUsageValueArray(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + IN PCHAR UsageValue,
++++++++ + IN USHORT UsageValueByteLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetUsageValue(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection,
++++++++ + IN USAGE Usage,
++++++++ + IN ULONG UsageValue,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetScaledUsageValue(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN USAGE UsagePage,
++++++++ + IN USHORT LinkCollection OPTIONAL,
++++++++ + IN USAGE Usage,
++++++++ + IN LONG UsageValue,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_SetData(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN PHIDP_DATA DataList,
++++++++ + IN OUT PULONG DataLength,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + ULONG
++++++++ + NTAPI
++++++++ + HidParser_MaxDataListLength(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_InitializeReportForID(
++++++++ + IN HIDP_REPORT_TYPE ReportType,
++++++++ + IN UCHAR ReportID,
++++++++ + IN PHIDP_PREPARSED_DATA PreparsedData,
++++++++ + IN OUT PCHAR Report,
++++++++ + IN ULONG ReportLength);
++++++++ +
++++++++ + HIDAPI
++++++++ + NTSTATUS
++++++++ + NTAPI
++++++++ + HidParser_GetValueCaps(
++++++++ + HIDP_REPORT_TYPE ReportType,
++++++++ + PHIDP_VALUE_CAPS ValueCaps,
++++++++ + PULONG ValueCapsLength,
++++++++ + PHIDP_PREPARSED_DATA PreparsedData);
display.inf
fdc.inf
font.inf
+++++++++++ hal.inf
hdc.inf
++++++++ ++ input.inf
intl.inf
keyboard.inf
ks.inf
; we use a separate one to keep things clean\r
battery.inf\r
cdrom.inf\r
+++++++++++cpu.inf\r
+++++++++++disk.inf\r
display.inf\r
fdc.inf\r
+++++++++++hal.inf\r
hdc.inf\r
++++++++ ++ input.inf\r
keyboard.inf\r
machine.inf\r
msmouse.inf\r
ObSystemDeviceMap->DriveType,
sizeof(ObSystemDeviceMap->DriveType));
----------- /* FIXME: Release the DeviceMap Spinlock */
----------- // KeReleasepinLock(DeviceMap->Lock, OldIrql);
+++++++++++ KeReleaseGuardedMutex(&ObpDeviceMapLock);
+++++++++++}
+++++++++++
++++++++++++NTSTATUS
++++++++++++NTAPI
++++++++++++ObIsDosDeviceLocallyMapped(
++++++++++++ IN ULONG Index,
++++++++++++ OUT PUCHAR DosDeviceState)
++++++++++++{
++++++++++++ /* check parameters */
++++++++++++ if (Index < 1 || Index > 26)
++++++++++++ {
++++++++++++ /* invalid index */
++++++++++++ return STATUS_INVALID_PARAMETER;
++++++++++++ }
++++++++++++
++++++++++++ /* acquire lock */
++++++++++++ KeAcquireGuardedMutex(&ObpDeviceMapLock);
++++++++++++
++++++++++++ /* get drive mapping status */
++++++++++++ *DosDeviceState = (ObSystemDeviceMap->DriveMap & (1 << Index)) != 0;
++++++++++++
++++++++++++ /* release lock */
++++++++++++ KeReleaseGuardedMutex(&ObpDeviceMapLock);
++++++++++++
++++++++++++ /* done */
++++++++++++ return STATUS_SUCCESS;
+ }
+
/* EOF */