自定义HID应用程序开发(Windows)
+ -

自定义HID的同步操作示例

2021-09-14 1010 0

如本人通过枚举系统中所有的HID设备,通过同步操作来读取HID设备。
这里的数据长度都为64字节。

#include<windows.h>
#include <winioctl.h>
#include <setupapi.h>
#include <initguid.h>
#include <stdio.h>
#include<hidsdi.h>
#include<tchar.h>
#pragma comment(lib,"Setupapi.lib ")
#pragma comment(lib,"hid.lib ")
BOOL USBEnumDevice(OUT PTCHAR pDeviceName, IN LPGUID pGuid, IN int instance)
{
    HDEVINFO info = SetupDiGetClassDevs((GUID*)pGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
    if (info == INVALID_HANDLE_VALUE)
    {
        printf("No HDEVINFO available for this GUID\n");
        return FALSE;
    }
    // Get interface data for the requested instance
    SP_INTERFACE_DEVICE_DATA ifdata;
    ifdata.cbSize = sizeof(ifdata);
    if (!SetupDiEnumDeviceInterfaces(info, NULL, (GUID*)pGuid, instance, &ifdata))
    {
        _tprintf(TEXT("No SP_INTERFACE_DEVICE_DATA available for this GUID instance\n"));
        SetupDiDestroyDeviceInfoList(info);
        return FALSE;
    }
    // Get size of symbolic link name
    DWORD ReqLen;
    SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &ReqLen, NULL);
    PSP_INTERFACE_DEVICE_DETAIL_DATA ifDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new TCHAR[ReqLen]);
    if (ifDetail == NULL)
    {
        SetupDiDestroyDeviceInfoList(info);
        return FALSE;
    }
    // Get symbolic link name
    ifDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
    if (!SetupDiGetDeviceInterfaceDetail(info, &ifdata, ifDetail, ReqLen, NULL, NULL))
    {
        SetupDiDestroyDeviceInfoList(info);
        delete ifDetail;
        return FALSE;
    }
    //printf("Symbolic link is %s\n", ifDetail->DevicePath);
    memcpy(pDeviceName, ifDetail->DevicePath, _tcslen(ifDetail->DevicePath) * sizeof(TCHAR));
    pDeviceName[_tcslen(ifDetail->DevicePath)] = TEXT('\0');
    delete[] ifDetail;
    SetupDiDestroyDeviceInfoList(info);
    return TRUE;
}
int main()
{
    GUID hidGuid;
    ::HidD_GetHidGuid((LPGUID)&hidGuid);                      // 取HID设备GUID
    for (int i = 0;; i++)
    {
        TCHAR strDevicePath[512] = { 0 };
        if (!USBEnumDevice(strDevicePath, &hidGuid, i))
        {
            break;
        }
       // _tprintf(TEXT("%d %s\n"), i, strDevicePath);

        HANDLE tmp_DeviceHandle = CreateFile(strDevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL , NULL);
        if (tmp_DeviceHandle == INVALID_HANDLE_VALUE)
        {
            CloseHandle(tmp_DeviceHandle);
            continue;
        }
        //=============== Get Attribute ===============
        HIDD_ATTRIBUTES Attributes;
        ZeroMemory(&Attributes, sizeof(Attributes));
        Attributes.Size = sizeof(HIDD_ATTRIBUTES);
        if (!HidD_GetAttributes(tmp_DeviceHandle, &Attributes))
        {
            CloseHandle(tmp_DeviceHandle);
            continue;
        }


        if (Attributes.VendorID != 0x1234 || Attributes.ProductID != 0x3456)
        {
            CloseHandle(tmp_DeviceHandle);
            continue;
        }

     //   _tprintf(TEXT("%d %s\n"), i, strDevicePath);
     //   _tprintf(TEXT("Vendor ID: %04x, Product ID:%04x\n"), Attributes.VendorID, Attributes.ProductID);
        /////////////////////////////////
        ULONG bufferLength = 126;
        TCHAR ProductString[126] = { 0 };;
        if (!HidD_GetProductString(tmp_DeviceHandle, ProductString, bufferLength))
        {
            CloseHandle(tmp_DeviceHandle);
            continue;
        }
        //=============== Get Capabilities ===============
        PHIDP_PREPARSED_DATA PreparsedData;
        if (!HidD_GetPreparsedData(tmp_DeviceHandle, &PreparsedData))
        {
            CloseHandle(tmp_DeviceHandle);
            printf("Cannot get the Preparsed Data...\n");
            continue;
        }
        HIDP_CAPS ReturnCapabilities;
        if (!HidP_GetCaps(PreparsedData, &ReturnCapabilities))
        {
            CloseHandle(tmp_DeviceHandle);
            printf("Cannot get the Cap Data...\n");
            continue;
        }
        // Normal USB Device
        if ((ReturnCapabilities.OutputReportByteLength == 0x40) &&
            (ReturnCapabilities.InputReportByteLength == 0x40) &&
            (ReturnCapabilities.Usage == 0x0001) &&
            (ReturnCapabilities.UsagePage == 0xFF00))
        {
        }

        UCHAR data[64] = { 0 };
        data[0] = 0x01;
        data[1] = 0x82;


        //OVERLAPPED ol;
        //memset(&ol, 0, sizeof(ol));

        ULONG rtn = 0;
        BOOL isok = WriteFile(tmp_DeviceHandle, data, 64, &rtn,NULL);
        DWORD e = GetLastError();
        if (isok)
        {
            printf("ok\n");
        }

        data[2] = 0x97;
        data[3] = 0x00;
        isok = WriteFile(tmp_DeviceHandle, data, 64, &rtn, NULL);
        e = GetLastError();
        if (isok)
        {
            printf("ok\n");
        }


        BOOL isfirst = true;
        ULONG index = 0;
        while (1)
        {
            int len;
            isok = ReadFile(tmp_DeviceHandle, data, 64, &rtn, NULL);
            printf("%d %02X %02X %02X\n", index, data[0], data[1], data[2]);
        }

    }
}
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 篇笔记 写笔记

UVC 等时传输中的URB_ISOCH_TRANSFER
通过UVC规范可知,视频图像数据的读取可使用两种端点传输方式,分别为:BULK 块/批量传输方式ISO 等时/同步传输方式在Windows内核中,USB数据的读取是通过URB来进行传输的,其结构体是一个大大的共用体,根据数据传输的方式对应其不同的结构体,其内容如下:typedef _Struct_s......
UVC等时传输中的dwMaxPayloadTransferSize
UVC的视频流接口控制请求的数据大小可为26字节,34字节和48字节,其分别对应的是UVC的1.0,1,1和UVC1.5版本。在其整个视频流控制接口参数偏移地址22处的字段为一4字节的dwMaxPayloadTransferSize,根据其字段解释为“指定设备在单个有效负载传输中可以传输或接收的最大......
USB 同步帧SynchFrame
ID请求码说明12SYNCH_FRAME用于设备设置和报告一个端点的同步帧SynchFrame用于设置并报告端点的同步帧号,用于同步传输,只适用于同步端点。在SynchFrame请求的数据阶段,USB设备将向USB主机返回2个字节的帧号数据bmRequestType(1)bRequest(1)wVa......
USB 等时/同步传输、块传输与转换设置在UVC摄像头驱动中的探讨
最近在Windows10 x64环境下,开发了一个虚拟UVC摄像头驱动。确切的来说这不是摄像头驱动,而是一个虚拟USB总线驱动。使用该虚拟总线驱动使用应用软件通过IOCTL控制总线子设备的创建与卸载。框架设计驱动安装完成后,是一个单纯的USB虚拟总线。应用软件通过发送自定义IOCTL码IOCTL......
USB 同步/等时传输方式
USB协议规定了四种传输类型:控制传输、批量传输、同步传输、中断传输。等时传输也有“同步传输”的叫法,一般用于要求数据连续、实时且数据量大的场合,其对传输延时十分敏感,类似用于USB摄像设备,USB语音设备等等。同步事务没有握手包。当一个同步传输中有多个事务时,最后一个事务之前的事务的数据长......
UVC 同步延迟控制
同步延迟控制的目的是将多个视频流从一个设备动态同步到主机,或者从多个设备同步到主机,以补偿多个流之间的不同延迟。延迟是源从采集到总线上数据传输的内部延迟。只有那些能够使用可调延迟延迟参数的视频流设备支持此控制。该控件用于通知设备上的视频应用缓冲存储器管理器,以通过控制视频数据到其端点的输出定时来控制......
USB超高速 同步传输
正如USB2.0一样,超速同步传输类型是用来支持想要能容忍错误,周期性的轮询服务的传输流。超速跟USB2.0一样不发送起始帧,但是时序信息要通过同步时间戳包(ITP)被发送给设备。这个规格的协议层章详细描述了用来完成同步传输的包,总线事务和事务处理流程。也描述了怎么样传送时序信息给设备。超速同步传输......
UVC 处理单元特定类请求示例
笔者手中有一UVC摄像头,其处理单元描述符bUnitID为2,其处理单元描述符内容如下: -------- Video Control Processing Unit Descriptor -----------------------bLength ......
USB 同步/等时传输及反馈端点
USB的四种传输之一同步传输,用于数据实时性比较高,数据量较大但数据的完整性不是很严格的场合。由于时间是同步传输的关键部分,因此USB设计者了解这些不同实体在USB中如何处理时间是很重要的。在大部分的通讯系统中,数据的发送者和接收者以同步的方式进行数据收发。在异步通信系统中,允许数据发送者检测接收方......
UAC麦克见音频同步端点描述符
UAC音频采用同步传输,故数据传输的端点必须为同步传输。端点描述符的数据结构如下:关于同步传输可详见:http://www.usbzh.com/article/detail-118.html标准端点描述符代码如下:/* USB_DT_ENDPOINT: Endpoint descriptor......
Windows下USB驱动同步URB转IRP请求函数代码
URB和IRP类似,只不过一个应用于通用的Windows驱动,一个专职于USB。USB的URB的负载是IRP,其通过负载到IRP时,然后使用通用的Windows IRP请求发向下层目标USB设备。USB与IRP的关联是通过IRP的IO_STACK_LOCATION的 IoStack->Para......
Windows下USB驱动同步URB转IRP请求函数代码-改进版
URB的同步调用一般使用:Windows下USB驱动同步URB转IRP请求函数代码 http://www.usbzh.com/article/detail-547.html但是,在某些特定的情况下,有时会因为下底设备并没有完成而挂死。这里提供一种超时取消IRP的方法,同时考虑到了线和切换的情况。这里......
自定义HID的同步操作示例
如本人通过枚举系统中所有的HID设备,通过同步操作来读取HID设备。这里的数据长度都为64字节。#include#include #include #include
GitHub上已经封装好的HidApi库来进行开发,下载地址是https://github.com/yigityuce/HidApi这里弄了一个简单的测试程序:#include #include #include "hi......
自定义HID的异步操作和同步类似,这里有两个关键的区别:第一:CreateFile时wFlagsAndAttributes参数包括FILE_FLAG_OVERLAPPED标识。第二:ReadFile,WriteFile必须的OVERLAPPED参数;异步CreateFile打开HID示例: ......
关注公众号
  • HID人机交互
  • Linux&USB
  • UAC音频
  • TYPE-C
  • USB规范
  • USB大容量存储
  • USB百科
  • USB周边
  • UVC摄像头
  • Windows系统USB
  • 音视频博客
  • 取消
    感谢您的支持,我会继续努力的!
    扫码支持
    扫码打赏,你说多少就多少

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

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