虚拟键盘鼠标UVKM自义HID接口

2023-06-12 425 0

这里可以参考一个Windows自定义HID接口来实现:

HID.h

#pragma once
#include <Windows.h>

typedef struct _MOUSE_STRUCT
{
    UCHAR ReportId;//A0
    union
    {
        UCHAR Value;
        struct
        {
            UCHAR LeftBtn : 1;
            UCHAR RightBtn : 1;
            UCHAR Reseved : 6;
        }u;
    }btn;

    UCHAR Horizontal;
    UCHAR Veritical;
    UCHAR Wheel;
}MOUSE_STRUCT;

typedef struct _GMOUSE_STRUCT
{
    UCHAR ReportId; //A2
    union
    {
        UCHAR Button;
        struct
        {
            UCHAR LeftBtn : 1;
            UCHAR RightBtn : 1;
            UCHAR Reseved : 6;
        }u;
    }btn;
    USHORT X;
    USHORT Y;
}GMOUSE_STRUCT;

typedef struct _KEYBOARD_STRUCT
{
    UCHAR ReportId;//A1
    union
    {
        UCHAR Value;
        struct
        {
            UCHAR LeftCtrl : 1;
            UCHAR LeftShift : 1;
            UCHAR LeftAlt : 1;
            UCHAR LeftGui : 1;
            UCHAR RightCtrl : 1;
            UCHAR RightShift : 1;
            UCHAR RightlAlt : 1;
            UCHAR RightGui : 1;
        }u;
    }Fun;
    UCHAR Reserved;
    UCHAR Key[6];
}KEYBOARD_STRUCT;

class CHid
{
private:
    HANDLE m_hDeivce;
public:
    BOOL OpenHid(USHORT VID=0x0000,USHORT PID=0xF001,USHORT BCD=0x0100);
    VOID CloseHid();
    BOOL SetReport(PVOID pData, ULONG nLen);
};

HID.CPP

#include "pch.h"
#include "CHid.h"
#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;
}
BOOL CHid::OpenHid(USHORT VID, USHORT PID, USHORT BCD)
{
//    CloseHid();

    GUID hidGuid;
    ::HidD_GetHidGuid((LPGUID)&hidGuid);                      // 取HID设备GUID
    for (int i = 0;; i++)
    {
        TCHAR strDevicePath[512] = { 0 };
        if (!USBEnumDevice(strDevicePath, &hidGuid, i))
        {
            break;
        }

        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)
        {
            continue;
        }

        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 != VID || Attributes.ProductID != PID || Attributes.VersionNumber != BCD)
        {
            CloseHandle(tmp_DeviceHandle);
            continue;
        }

        m_hDeivce = tmp_DeviceHandle;
        return TRUE;
    }

    return FALSE;
}
VOID CHid::CloseHid()
{
    if (m_hDeivce != INVALID_HANDLE_VALUE)
    {
        CloseHandle(m_hDeivce);  
    }
    m_hDeivce = INVALID_HANDLE_VALUE;
}
BOOL CHid::SetReport(PVOID pData, ULONG nLen)
{
    if (nLen > 254)
    {
        return FALSE;
    }

    UCHAR data[256] = { 0 };
    data[0] = 0x05; //ID
    data[1] = nLen; //length
    CopyMemory(&data[2], pData, nLen);

    ULONG rtn = 0;
    return WriteFile(m_hDeivce, data, sizeof(data), &rtn, NULL);
}
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下自定义HID设备通讯调试工具HidTool
功能枚举系统中可用的自定义HID设备,并进行数据通讯.在软件界面中显示该HID设备的,VID,PID,产品名称,输入报告长度,输出报告长度,特性报告长度和该输入报告所使用的USAGE_PAGE和USAGE。另外,对于一些用户,也可以指定Windows系统关于HID读取输入报告的缓冲区大小,系统默......
自定义通讯HID报告描述符(hidraw)
在进行HID通讯时,免不了设计自定义HID,这个可以使用系统驱动,实现设备免驱。在应用层可以使用windows提供的HID接口进行数据读写。自定义HID报告描述符10x06,0x00,0xFF, //0 GLOBAL_USAGE_PAGE(Undefined)......
Windows自定义HID设备通讯开发概述
HID设备是USB规范中最早提出并支持的一类通讯设备,常见的键盘、鼠标、游戏手柄都属于HID设备。HID设备一般用于数据量小但实时性要求较高的环境,所以HID设备采用的是USB四种通讯类弄的中中断传传输类型。除了上述描述符的标准的HID设备,HID也提供一种自定义通讯,并由Windows提供驱动,而......
Windows自定义HID API相关函数解释
CreateFile()CreateFile()函数的函数原型为:HANDLE CreateFile( LPCWSTR lpFileName, //指向路径的指针 DWORD dwDesiredAccess, //访问模式(读/写) DWORD dwShareM......
自定义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示例: ......
可以通过SET_FEATURE和GET_FEATURE实现自定义HID的Feature通讯。通讯的数据长度可以自行更改,当然也得更改对应的HID描述符里的内容配置描述符中部分HID描述符和端点描述符09 21 01 01 00 01 22 20 00 //HID描述符07 05 81 0......
以前在Windows搞了很多虚拟的USB设备,像麦克风,扬声器,摄像头,键盘,鼠标等USB设备,突估有人说没有自定义HID设备啊。我一想,确实没有,要不搞一个。不过话又说回来,搞这个有什么用了?我想了想可能是为了调试,或者为了软件隔离吧。比如说有一个软件用户不想和我们的软件有任何接口,但之间又必须通......
在Windows操作系统下,使用自定义HID接口通讯时,离不开hid.dll,就算你使用的是hidapi等第三方HID库,它的底层也是HID.dll这个库。而我们使用系统原生的hid.dll库时,也一般是这样引用的。#include#pragma comment(......
HID就是人机接口,从使用环境来看,有系统独占设备,如键盘、鼠标,游戏手柄等,另外一部分为自定义HID设备,就是给开发自己使用的。系统独占设备就是不能被别的程序使用,比如我们就不能在应用层打开键盘对的应HID来获取键盘返回的数据。自定义HID设备就是系统只创建节点,我们在应用层可以使用我们自己的通讯......
这里可以参考一个Windows自定义HID接口来实现:HID.h#pragma once#include typedef struct _MOUSE_STRUCT{ UCHAR ReportId;//A0 union { ......
HID设备分为专用设备和自定义设备。专用设备为系统独占设备,由系统打开,并进行数据的处理,如键盘鼠标,触摸屏。自定义设备为自定义通讯的设备,比如我们可用于固件升级。专用设备用CreateFile打开时返回GetLastError()==5。HID设备无论应用层是否打开,其实驱动已经开始进行数据的读......
头文件chid.h#pragma once#include #include class CHid{private: HANDLE m_hDeivce;public: BOOL OpenHid(USHOR......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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