#include "hidparse.h"
+PVOID
+NTAPI
+AllocFunction(
+ IN ULONG ItemSize)
+{
+ PVOID Item = ExAllocatePool(NonPagedPool, ItemSize);
+ if (Item)
+ {
+ //
+ // zero item
+ //
+ RtlZeroMemory(Item, ItemSize);
+ }
+
+ //
+ // done
+ //
+ return Item;
+}
VOID
NTAPI
-HidP_FreeCollectionDescription (
- IN PHIDP_DEVICE_DESC DeviceDescription)
+FreeFunction(
+ IN PVOID Item)
{
- DPRINT1("HidP_FreeCollectionDescription DeviceDescription %p\n", DeviceDescription);
-
//
- // free collection
+ // free item
//
- ExFreePool(DeviceDescription->CollectionDesc);
+ ExFreePool(Item);
+}
+VOID
+NTAPI
+ZeroFunction(
+ IN PVOID Item,
+ IN ULONG ItemSize)
+{
//
- // free report ids
+ // zero item
//
- ExFreePool(DeviceDescription->ReportIDs);
+ RtlZeroMemory(Item, ItemSize);
}
-#undef HidP_GetButtonCaps
+VOID
+NTAPI
+CopyFunction(
+ IN PVOID Target,
+ IN PVOID Source,
+ IN ULONG Length)
+{
+ //
+ // copy item
+ //
+ RtlCopyMemory(Target, Source, Length);
+}
-HIDAPI
-NTSTATUS
+VOID
NTAPI
-HidP_GetButtonCaps(
- HIDP_REPORT_TYPE ReportType,
- PHIDP_BUTTON_CAPS ButtonCaps,
- PUSHORT ButtonCapsLength,
- PHIDP_PREPARSED_DATA PreparsedData)
+DebugFunction(
+ IN LPCSTR FormatStr, ...)
{
- return HidP_GetSpecificButtonCaps(ReportType, HID_USAGE_PAGE_UNDEFINED, 0, 0, ButtonCaps, (PULONG)ButtonCapsLength, PreparsedData);
+
+ va_list args;
+ unsigned int i;
+ char printbuffer[1024];
+
+ va_start(args, FormatStr);
+ i = vsprintf(printbuffer, FormatStr, args);
+ va_end(args);
+
+ DbgPrint(printbuffer);
}
-HIDAPI
-NTSTATUS
+VOID
NTAPI
-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)
+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);
}
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
IN POOL_TYPE PoolType,
OUT PHIDP_DEVICE_DESC DeviceDescription)
{
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
+ 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
-HidP_GetData(
+HidP_GetSpecificValueCaps(
IN HIDP_REPORT_TYPE ReportType,
- OUT PHIDP_DATA DataList,
- IN OUT PULONG DataLength,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection,
+ IN USAGE Usage,
+ OUT PHIDP_VALUE_CAPS ValueCaps,
+ IN OUT PULONG ValueCapsLength,
+ 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 value caps
+ //
+ return HidParser_GetSpecificValueCaps(&Parser, ReportType, UsagePage, LinkCollection, Usage, ValueCaps, ValueCapsLength);
+}
+
+HIDAPI
+NTSTATUS
+NTAPI
+HidP_GetUsages(
+ IN HIDP_REPORT_TYPE ReportType,
+ IN USAGE UsagePage,
+ IN USHORT LinkCollection OPTIONAL,
+ OUT USAGE *UsageList,
+ IN OUT ULONG *UsageLength,
IN PHIDP_PREPARSED_DATA PreparsedData,
IN PCHAR Report,
IN ULONG ReportLength)
{
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
+ 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
-HidP_GetExtendedAttributes(
+HidP_UsageListDifference(
+ IN PUSAGE PreviousUsageList,
+ IN PUSAGE CurrentUsageList,
+ OUT PUSAGE BreakUsageList,
+ OUT PUSAGE MakeUsageList,
+ IN ULONG UsageListLength)
+{
+ return HidParser_UsageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength);
+}
+
+HIDAPI
+NTSTATUS
+NTAPI
+HidP_GetUsagesEx(
IN HIDP_REPORT_TYPE ReportType,
- IN USHORT DataIndex,
+ IN USHORT LinkCollection,
+ OUT PUSAGE_AND_PAGE ButtonList,
+ IN OUT ULONG *UsageLength,
IN PHIDP_PREPARSED_DATA PreparsedData,
- OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
- IN OUT PULONG LengthAttributes)
+ 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_GetLinkCollectionNodes(
- OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
- IN OUT PULONG LinkCollectionNodesLength,
- IN PHIDP_PREPARSED_DATA PreparsedData)
+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;
+ return HidParser_UsageAndPageListDifference(PreviousUsageList, CurrentUsageList, BreakUsageList, MakeUsageList, UsageListLength);
}
HIDAPI
IN PCHAR Report,
IN ULONG ReportLength)
{
- UNIMPLEMENTED
- ASSERT(FALSE);
- return STATUS_NOT_IMPLEMENTED;
+ 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
-HidP_GetUsageValue(
+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
+HidP_GetSpecificButtonCaps(
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)
+ OUT PHIDP_BUTTON_CAPS ButtonCaps,
+ IN OUT PULONG ButtonCapsLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData)
{
UNIMPLEMENTED
ASSERT(FALSE);
return STATUS_NOT_IMPLEMENTED;
}
-
-
HIDAPI
NTSTATUS
NTAPI
-HidP_UsageListDifference(
- IN PUSAGE PreviousUsageList,
- IN PUSAGE CurrentUsageList,
- OUT PUSAGE BreakUsageList,
- OUT PUSAGE MakeUsageList,
- IN ULONG UsageListLength)
+HidP_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)
{
- 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;
+ UNIMPLEMENTED
+ ASSERT(FALSE);
+ return STATUS_NOT_IMPLEMENTED;
}
HIDAPI
NTSTATUS
NTAPI
-HidP_GetSpecificValueCaps(
+HidP_GetExtendedAttributes(
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
- IN USHORT LinkCollection,
- IN USAGE Usage,
- OUT PHIDP_VALUE_CAPS ValueCaps,
- IN OUT PULONG ValueCapsLength,
- IN PHIDP_PREPARSED_DATA PreparsedData)
+ IN PHIDP_PREPARSED_DATA PreparsedData,
+ OUT PHIDP_EXTENDED_ATTRIBUTES Attributes,
+ IN OUT PULONG LengthAttributes)
{
UNIMPLEMENTED
ASSERT(FALSE);
}
HIDAPI
-ULONG
+NTSTATUS
NTAPI
-HidP_MaxUsageListLength(
- IN HIDP_REPORT_TYPE ReportType,
- IN USAGE UsagePage OPTIONAL,
- IN PHIDP_PREPARSED_DATA PreparsedData)
+HidP_GetLinkCollectionNodes(
+ OUT PHIDP_LINK_COLLECTION_NODE LinkCollectionNodes,
+ IN OUT PULONG LinkCollectionNodesLength,
+ IN PHIDP_PREPARSED_DATA PreparsedData)
{
UNIMPLEMENTED
ASSERT(FALSE);
HIDAPI
NTSTATUS
NTAPI
-HidP_GetUsages(
+HidP_GetUsageValue(
IN HIDP_REPORT_TYPE ReportType,
IN USAGE UsagePage,
- IN USHORT LinkCollection OPTIONAL,
- OUT USAGE *UsageList,
- IN OUT ULONG *UsageLength,
+ IN USHORT LinkCollection,
+ IN USAGE Usage,
+ OUT PULONG UsageValue,
IN PHIDP_PREPARSED_DATA PreparsedData,
IN PCHAR Report,
IN ULONG ReportLength)
return STATUS_NOT_IMPLEMENTED;
}
-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)
-{
- 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)
-{
- 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