HID规范
+ -

HID报告描述符主项InputReport、OutputReport,FeatureReport

2022-05-16 1483 1

HID报告描述符主项除过COLLECTION项,就是输入报告InputReport,输出报告OutputReport和特性报告FeatureReport。

ITEM_PREFIX的BIT2,BIT3为00,bit4-7的值为:

#define ITEM_TAG_MAIN_INPUT                    0x8
#define ITEM_TAG_MAIN_OUTPUT                0x9
#define ITEM_TAG_MAIN_FEATURE                0xb

InputReport、OutputReport,FeatureReport示例

 INPUT (Data,Var,Abs)                    81 02 
 OUTPUT (Data,Var,Abs)                    91 02 
 FEATURE (Data,Var,Abs)                    B1 02

这里各个后面的报告数据MainItemData为0x02,代表(Data,Var,Abs),不过其具有多种配置,更多详见:HID主条目input item、output item和feature item详解http://www.usbzh.com/article/detail-527.html

UCHAR Size:2 UCHAR Type:2 UCHAR Tag:4
ITEM_TAG_MAIN_INPUT XX ITEM_TYPE_MAIN=00 0x08
ITEM_TAG_MAIN_OUTPUT XX ITEM_TYPE_MAIN=00 0x09
ITEM_TAG_MAIN_FEATURE XX ITEM_TYPE_MAIN=00 0x0B
ITEM_TAG_MAIN_COLLECTION XX ITEM_TYPE_MAIN=00 0x0A
ITEM_TAG_MAIN_END_COLLECTION XX ITEM_TYPE_MAIN=00 0x0C

MainItemData的结构可根据上面的定义如下结构体:

typedef struct
{
    USHORT DataConstant:1;
    USHORT ArrayVariable:1;
    USHORT Relative:1;
    USHORT Wrap:1;
    USHORT NonLinear:1;
    USHORT NoPreferred:1;
    USHORT NullState:1;
    USHORT IsVolatile:1;
    USHORT BitsBytes:1;
    UCHAR  reserved[2];
}
MAIN_ITEM_DATA, *PMAIN_ITEM_DATA;

在parser.sys中,一个报告就是一个HID_REPORT结构体,存于HID_COLLECTION的Reports指针数组中,其总数由ReportCount决定。

typedef struct _HID_REPORT
{
    UCHAR Type;
    UCHAR ReportID;
    ULONG ReportSize;   
    ULONG ItemCount;
    ULONG ItemAllocated;
    HID_REPORT_ITEM Items[1];
}HID_REPORT, *PHID_REPORT;

而HID_REPORT_ITEM是在InputReport、OutputReport,FeatureReport各个USAGE使用的size和count。

typedef struct
{
    ULONG ByteOffset;
    UCHAR Shift;
    ULONG Mask;
    UCHAR BitCount;
    UCHAR HasData;
    UCHAR Array;
    UCHAR Relative;
    ULONG Minimum;
    ULONG Maximum;
    ULONG UsageMinimum;
    ULONG UsageMaximum;
    ULONG Data;
    UCHAR Valid;
}HID_REPORT_ITEM, *PHID_REPORT_ITEM;

HID_RPORT中的HID_REPORT_ITEM成员通过HidParser_AddMainItem初始化。

  ReportType = HID_REPORT_TYPE_ANY;

                    switch (CurrentItem->Tag) {
                        case ITEM_TAG_MAIN_INPUT:
                            ReportType = HID_REPORT_TYPE_INPUT;
                            break;

                        case ITEM_TAG_MAIN_OUTPUT:
                            ReportType = HID_REPORT_TYPE_OUTPUT;
                            break;

                        case ITEM_TAG_MAIN_FEATURE:
                            ReportType = HID_REPORT_TYPE_FEATURE;
                            break;

                        default:
                            Parser->Debug("[HIDPARSE] Unknown ReportType Tag %x Type %x Size %x CurrentItemSize %x\n", CurrentItem->Tag, CurrentItem->Type, CurrentItem->Size, CurrentItemSize);
                            ASSERT(FALSE);
                            break;
                    }

                    if (ReportType == HID_REPORT_TYPE_ANY)
                        break;

                    //
                    // get report
                    //
                    Status = HidParser_GetReport(Parser, ParserContext, CurrentCollection, ReportType, ParserContext->GlobalItemState.ReportId, TRUE, &Report);
                    ASSERT(Status == HIDPARSER_STATUS_SUCCESS);

                    // fill in a sensible default if the index isn't set
                    if (!ParserContext->LocalItemState.DesignatorIndexSet) {
                        ParserContext->LocalItemState.DesignatorIndex
                            = ParserContext->LocalItemState.DesignatorMinimum;
                    }

                    if (!ParserContext->LocalItemState.StringIndexSet)
                        ParserContext->LocalItemState.StringIndex = ParserContext->LocalItemState.StringMinimum;

                    //
                    // get main item data
                    //
                    MainItemData = (PMAIN_ITEM_DATA)&Data;

                    //
                    // add states & data to the report
                    //
                    Status = HidParser_AddMainItem(Parser, ParserContext, Report, &ParserContext->GlobalItemState, &ParserContext->LocalItemState, MainItemData, CurrentCollection);
                    ASSERT(Status == HIDPARSER_STATUS_SUCCESS);
                }

                //
                // backup stack
                //
                Index = ParserContext->LocalItemState.UsageStackAllocated;
                NewUsageStack = ParserContext->LocalItemState.UsageStack;

                //
                // reset the local item state and clear the usage stack
                //
                Parser->Zero(&ParserContext->LocalItemState, sizeof(LOCAL_ITEM_STATE));

                //
                // restore stack
                //
                ParserContext->LocalItemState.UsageStack = NewUsageStack;
                ParserContext->LocalItemState.UsageStackAllocated = Index;

这里涉及到LOCAL_ITEM_STATE LocalItemState和GLOBAL_ITEM_STATE GlobalItemState的处理,后续通过LOCAL和GLOABL项来进行分析。

HID人机交互QQ群:564808376    UAC音频QQ群:218581009    UVC相机QQ群:331552032    BOT&UASP大容量存储QQ群:258159197    STC-USB单片机QQ群:315457461    USB技术交流QQ群2:580684376    USB技术交流QQ群:952873936   

0 篇笔记 写笔记

Windows系统HidD_GetPreparsedData数据结构PHIDP_PREPARSED_DATA研究
上天开了一个玩笑,研究了REACTOS的HidD_GetPreparsedData函数的数据结构(http://www.usbzh.com/article/detail-980.html ),竟然发现这和Windows体统的不兼容。所以这一节我们来研究一下Windows下的HidD_GetPrepa......
HID主条目input item、output item和feature item详解
HID的main条目按数据相关性可分为两种:与数据相关的 input、output、featureinput item、output item和feature item描述由一个或多个物理控件提供的数据的信息。 应用程序可以使用此信息来解释设备提供的数据。 单个item中定义的所有数据字段共享......
HID局部条目
local item标记定义控件的特征。这些项目不会影响到下一个main item。如果一个主项定义了多个控件,则它前面可能有几个类似的local item。例如,一个input item可能有几个与其关联的usage item,每个控件一个。Usage、 Usage Minimum 和 Usag......
HID多ReportId数据长度返回的问题
最近搞了一个虚拟的USB HID设备,为了测试各个报告描述符。不过遇到了一个奇怪的问题,以前没有留意,现在分享给大家。比如在自定义的HID的报告描述符中,描述输入的报告内容分别如下:ReportId数据长度总长度011617026061可以看到,当Rep......
HID.DLL导出函数HidD_GetInputReport探究
HidD_GetInputReport的功能HidD_GetInputReport用于获取输入报告(input report)。说明:不过微软关于此函数有一个特别的说明,就是只能获取当前的输入报告,不能连续的获取,因为可能会丢数据。所以如果要连续的获取输入报告,需要使用ReadFile函数。同时,......
Windows系统HID设备获取输入报告ReadFile和HidD_GetInputReport区别
在Windows系统提供的HID接口中获取输入报告内容一般通过两个接口,分别为ReadFile和HidD_GetInputReport。不过大家有没有发现,在实际的使用过程中,大家还是使用ReadFile多一些,在某些的时候也会用HidD_GetInputReport,不过它们之间的区别,好像有时很......
HID_PARSER_CONTEXT解析报告描述符生成的COLLECTION树形结构
通过前面的代码,我们简单的说明了一下HIDP_DEVICE_DESC和HIDP_COLLECTION_DESC、HIDP_REPORT_IDS关系:其实我们在分析其代码的时候,都是通过ParserContext来实现的,这个指针的定义实质上为:typedef struct{ // ......
HID报告描述符主项ITEM_TYPE_MAIN-COLLECTION和END COLLECTION
主项ITEM_TYPE_MAIN时,ITEM_PREFIX的Type(BIT2,BIT3)为0时。#define ITEM_TYPE_MAIN 0x0主项主要包括以下几个:ITEM_TAG_MAIN_COLLECTIONITEM_TAG_MAIN......
HID报告描述符主项InputReportOutputReport,FeatureReport
HID报告描述符主项除过COLLECTION项,就是输入报告InputReport,输出报告OutputReport和特性报告FeatureReport。ITEM_PREFIX的BIT2,BIT3为00,bit4-7的值为:#define ITEM_TAG_MAIN_INPUT ......
HID报告描述符解析过程中的数据结构关系
Hid报告描述符的短项定义了MAIN,GLOBAL,LOCAL三种类型的项。其中MAIN项主要定义了三个类型,分别为集合(COLLECTION),输入报告(Input Report),输出报告(Output Report)和特性报告(Feature Report).在Windows系统的Pars......
使用USB鼠标HID报告描述符分析HID_REPORT及成员HID_REPORT_ITEM关系
HID报告描述分过程比较麻烦,对于MAIN ITEM,相对来说比较简单,就是一个简单的树形结构。但对于GLOBAL ITEM和LOCAL ITEM组织的数据结构定义,还是相对比较麻烦的。每一个HID报告描述符都会有很多集合,这是由MAIN ITEM的Collection关键字定义的,无论它是Appl......
HID报告描述符INPUT ITEM,OUTPUT ITEM,FEATERU ITEM Bit 1{Array (0) | Variable (1)}和HID_REPORT_ITEM的关系
HID的MAIN ITEM的INPUT ITEM,OUTPUT ITEM,FEATERU ITEM Bit定义如下:0:代表是数组1:代表变量我们在 HID主条目input item、output item和feature item详解http://www.usbzh.com/article......
Windows系统HID读输入报告的两种方式HidD_GetInputReport和ReadFile的补充
Windows系统提供了两种方式读取HID的输入报告,分别为HidD_GetInputReport和ReadFile,两都本质都是读取HID的输入报告,但从操作系统层来讲,两都又不同。在 Windows系统HID设备获取输入报告ReadFile和HidD_GetInputReport区别:https......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!