HIDP_DEVICE_DESC和HIDP_COLLECTION_DESC、HIDP_REPORT_IDS关系注释
2022-05-14
228
0
在说明Hid.dll的导出函数Hid.dll导出函数HidD_GetPreparsedData,其实会涉及到Hidparser.sys中比较重要的两个结构体,就是HIDP_COLLECTION_DESC和HIDP_REPORT_IDS。
这两个结构体的定义如下:
typedef struct _HIDP_COLLECTION_DESC
{
USAGE UsagePage;
USAGE Usage;
UCHAR CollectionNumber;
UCHAR Reserved[15];
USHORT InputLength;
USHORT OutputLength;
USHORT FeatureLength;
USHORT PreparsedDataLength;
PHIDP_PREPARSED_DATA PreparsedData;
}HIDP_COLLECTION_DESC, * PHIDP_COLLECTION_DESC;
typedef struct _HIDP_REPORT_IDS
{
UCHAR ReportID;
UCHAR CollectionNumber;
USHORT InputLength;
USHORT OutputLength;
USHORT FeatureLength;
}HIDP_REPORT_IDS, * PHIDP_REPORT_IDS;
可以看到,其中HIDP_COLLECTION_DESC用于描述一个HID功能设备报告描述符的基本信息,另一个HIDP_REPORT_IDS和其类似,信息更加简化些,并且一个HID报告描述符解析出的HIDP_COLLECTION_DESC和HIDP_REPORT_IDS的数量应该是相同的,都是CollectionCount。
我们在HidD_GetPreparsedData一节看到其中的部分代码,这里我们再加其更加详细的初始化代码,在reactos的hidparser中如下:
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;
ULONG Index;
PVOID ParserContext;
//
// first parse the report descriptor
//
ParserStatus = HidParser_ParseReportDescriptor(Parser, ReportDesc, DescLength, &ParserContext);
if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
{
//
// failed to parse report descriptor
//
Parser->Debug("[HIDPARSER] Failed to parse report descriptor with %x\n", ParserStatus);
return ParserStatus;
}
//
// get collection count
//
CollectionCount = HidParser_NumberOfTopCollections(ParserContext);
if (CollectionCount == 0)
{
//
// no top level collections found
//
ASSERT(FALSE);
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++)
{
//
// set preparsed data length
//
DeviceDescription->CollectionDesc[Index].PreparsedDataLength = HidParser_GetContextSize(Parser, ParserContext, Index);
ParserStatus = HidParser_BuildContext(Parser, ParserContext, Index, DeviceDescription->CollectionDesc[Index].PreparsedDataLength, (PVOID*)&DeviceDescription->CollectionDesc[Index].PreparsedData);
if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
{
//
// no memory
//
Parser->Free(DeviceDescription->CollectionDesc);
Parser->Free(DeviceDescription->ReportIDs);
return ParserStatus;
}
//
// init report description
//
DeviceDescription->ReportIDs[Index].CollectionNumber = Index + 1;
DeviceDescription->ReportIDs[Index].ReportID = Index; //FIXME
DeviceDescription->ReportIDs[Index].InputLength = HidParser_GetReportLength((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_INPUT);
DeviceDescription->ReportIDs[Index].OutputLength = HidParser_GetReportLength((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_OUTPUT);
DeviceDescription->ReportIDs[Index].FeatureLength = HidParser_GetReportLength((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_FEATURE);
DeviceDescription->ReportIDs[Index].InputLength += (HidParser_UsesReportId((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_INPUT) ? 1 : 0);
DeviceDescription->ReportIDs[Index].OutputLength += (HidParser_UsesReportId((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_OUTPUT) ? 1 : 0);
DeviceDescription->ReportIDs[Index].FeatureLength += (HidParser_UsesReportId((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_FEATURE) ? 1 : 0);
//
// init collection description
//
DeviceDescription->CollectionDesc[Index].CollectionNumber = Index + 1;
//
// get collection usage page
//
ParserStatus = HidParser_GetCollectionUsagePage((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, &DeviceDescription->CollectionDesc[Index].Usage, &DeviceDescription->CollectionDesc[Index].UsagePage);
if (ParserStatus != HIDPARSER_STATUS_SUCCESS)
{
// collection not found
Parser->Free(DeviceDescription->CollectionDesc);
Parser->Free(DeviceDescription->ReportIDs);
return ParserStatus;
}
//
// windows seems to prepend the report id, regardless if it is required
//
DeviceDescription->CollectionDesc[Index].CollectionNumber = Index + 1;
DeviceDescription->CollectionDesc[Index].InputLength = DeviceDescription->ReportIDs[Index].InputLength;
DeviceDescription->CollectionDesc[Index].OutputLength = DeviceDescription->ReportIDs[Index].OutputLength;
DeviceDescription->CollectionDesc[Index].FeatureLength = DeviceDescription->ReportIDs[Index].FeatureLength;
DeviceDescription->CollectionDesc[Index].InputLength += (HidParser_UsesReportId((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_INPUT) == FALSE ? 1 : 0);
DeviceDescription->CollectionDesc[Index].OutputLength += (HidParser_UsesReportId((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_OUTPUT) == FALSE ? 1 : 0);
DeviceDescription->CollectionDesc[Index].FeatureLength += (HidParser_UsesReportId((PVOID)DeviceDescription->CollectionDesc[Index].PreparsedData, HID_REPORT_TYPE_FEATURE) == FALSE ? 1 : 0);
}
//
// store collection & report count
//
DeviceDescription->CollectionDescLength = CollectionCount;
DeviceDescription->ReportIDsLength = CollectionCount;
//
// done
//
return STATUS_SUCCESS;
}
这里还涉及一个结构体HIDP_DEVICE_DESC,其结构体定义如下:
typedef struct _HIDP_DEVICE_DESC
{
PHIDP_COLLECTION_DESC CollectionDesc;
ULONG CollectionDescLength;
PHIDP_REPORT_IDS ReportIDs;
ULONG ReportIDsLength;
HIDP_GETCOLDESC_DBG Dbg;
}HIDP_DEVICE_DESC, * PHIDP_DEVICE_DESC;
它们之间的关系如下:
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936