读写HID的设备代码C语言代码

9 篇文章 1 订阅

先上一段代码吧,不是我写的;从大神的文章里面Ctrl+V过来的;消化完后自己在整理一份;

//原文地址:https://mp.weixin.qq.com/s/ChYpe-9IW9ofurMZ0zlNgg

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <setupapi.h>

extern "C" {

    void __stdcall
        HidD_GetHidGuid(
            OUT   LPGUID   HidGuid
        );

    typedef struct _HIDD_ATTRIBUTES {
        ULONG   Size; // = sizeof (struct _HIDD_ATTRIBUTES)

                      //
        // Vendor ids of this hid device
        //
        USHORT  VendorID;
        USHORT  ProductID;
        USHORT  VersionNumber;

        //
        // Additional fields will be added to the end of this structure.
        //
    } HIDD_ATTRIBUTES, * PHIDD_ATTRIBUTES;

    BOOLEAN __stdcall
        HidD_GetAttributes(
            IN  HANDLE              HidDeviceObject,
            OUT PHIDD_ATTRIBUTES    Attributes
        );

    BOOLEAN __stdcall
        HidD_SetFeature(
            _In_    HANDLE   HidDeviceObject,
            _In_reads_bytes_(ReportBufferLength) PVOID ReportBuffer,
            _In_    ULONG    ReportBufferLength
        );
}

#pragma comment( lib, "hid.lib" )
#pragma comment( lib, "setupapi.lib" )

void SetAll(HANDLE hUsb, bool AllOn)
{
    BOOL Result;
    UCHAR WriteReportBuffer[65];

    for (int i = 0; i < 8; i++) {
        WriteReportBuffer[i] = 0x00;
    }
    for (int i = 8; i < 65; i++) {
        WriteReportBuffer[i] = 0x5a;
    }

    WriteReportBuffer[1] = 0x0b;
    for (byte i = 0; i < 5; i++) {
        WriteReportBuffer[6] = i;
        if (AllOn) {
            WriteReportBuffer[7] = 0x01;
        }

        DWORD lpNumberOfBytesWritten;

        Result = WriteFile(hUsb,
            WriteReportBuffer,
            65,
            &lpNumberOfBytesWritten,
            NULL);
        //printf("Written %d bytes Result [%d]\n", lpNumberOfBytesWritten, Result);
    }


}

int main()
{
    GUID HidGuid;
    BOOL Result;
    int  counter = -1;


    HidD_GetHidGuid(&HidGuid);
    printf("HID GUID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n"
        , HidGuid.Data1, HidGuid.Data2, HidGuid.Data3
        , HidGuid.Data4[0], HidGuid.Data4[1], HidGuid.Data4[2], HidGuid.Data4[3], HidGuid.Data4[4]
        , HidGuid.Data4[5], HidGuid.Data4[6], HidGuid.Data4[7]);

    HDEVINFO hDevInfo = SetupDiGetClassDevs(&HidGuid, NULL, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    if (INVALID_HANDLE_VALUE != hDevInfo)
    {
        SP_DEVICE_INTERFACE_DATA strtInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) };
        for (DWORD index = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &HidGuid, index, &strtInterfaceData); ++index)
        {

            char buf[1000];
            SP_DEVICE_INTERFACE_DETAIL_DATA& strtDetailData = (SP_DEVICE_INTERFACE_DETAIL_DATA&)buf[0];
            strtDetailData.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
            if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &strtInterfaceData, &strtDetailData, _countof(buf), NULL, NULL))
            {
                printf("[%d] path: %ls\n", index, strtDetailData.DevicePath);

                HANDLE hUsb = CreateFile(strtDetailData.DevicePath,
                    NULL, FILE_SHARE_WRITE,
                    NULL, OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    NULL);

                HIDD_ATTRIBUTES strtAttrib = { sizeof(HIDD_ATTRIBUTES) };
                Result = HidD_GetAttributes(hUsb, &strtAttrib);
                CloseHandle(hUsb);

                if (TRUE == Result)
                {
                    if ((0x04D8 == strtAttrib.VendorID) &&
                        (0xFEDC == strtAttrib.ProductID))
                    {
                        printf("VendorID : %hX\n", strtAttrib.VendorID);
                        printf("ProductID: %hX\n", strtAttrib.ProductID);
                        printf("VerNumber: %hX\n", strtAttrib.VersionNumber);

                        hUsb = CreateFile(strtDetailData.DevicePath,
                            GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL, NULL);

                        SetAll(hUsb,TRUE);
                        Sleep(3000);
                        SetAll(hUsb, FALSE);

                        CloseHandle(hUsb);

                    }
                }
            }
        }

        if (GetLastError() != ERROR_NO_MORE_ITEMS)
        {
            printf("No more items!\n");
        }

        SetupDiDestroyDeviceInfoList(hDevInfo);

    }  //if( INVALID_HANDLE_VALUE != hDevInfo )
    system("PAUSE");
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
赋所有源代码开发工具vs2010 framework3.5 baidu搜索c# HidUsb都是大同小异案例,而且拿下来基本不能用。大都是围绕public static extern int CreateFile(省略众多参数..);发现没有,copy下来测试基本都是用不了的。 原因很简单:windows不允许你用程序随便就去访问硬件设备。所以在此把之前做过的基于C#开发读写HidUsb设备的项目整理成一个简单的小案例,分享给大家,开发环境VS2010。 该案例重点在public static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile); 看着貌似也是用到CreateFile这个函数,其实并不然,注意到没有"SafeFileHandle",这就是重点! 这样windows是允许程序访问外接hidusb设备的。 当然具体如何运用这个函数现在已经不是您应该 关心的了,因为我已经为您把它封装成一个类,您只要调用相应的方法就OK. 例: //第一步:获取HidUsb设备信息 List slist = new List(); UsbHidDevice usbhid = new UsbHidDevice(); usbhid.GetDeviceList(ref slist); //HidUsb设备信息包含在List数据集中 注:当获取到HidUsb设备信息为:\\?\hid#vid_0e2c&pid;_0112#6&1b44c403;&0&0000;#{4d1e55b2-f16f-11cf-88cb-001111000030}, 注意该字符串里的“vid_0e2c”和“pid_0112”部分,那么: vid为0e2c, pid为:0112 //第二步:创建一个HidUsb设备访问实例 UsbHidDevice Device = new UsbHidDevice(vid, pid); //第三步:连接HidUsb设备 Boolean connBool = Device.Connect(); //第四步:实现数据接收事件 Device.DataReceived += new UsbHidDevice.DataReceivedDelegate(Device_DataReceived); //当HidUsb设备返回信息时触发此事件 void Device_DataReceived(byte[] data) { //处理接收到的数据逻辑 } //第五步:向Hid设备发送数据"0xa0 00 0x12 0x9 0x22" string txt = "0xa0 00 0x12 0x9 0x22"; //把数据转换为字节数组 byte[] data = ConvertHelper.StringToByte(txt2); byte bt = 0; CommandMessage cmdMsg = new CommandMessage(bt, data); Boolean sbool = Device.SendMessage(cmdMsg); //发送数据 //第六步:释放所有资源 Device.Dispose();
以下是使用C语言读写ini文件的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_SIZE 1024 // 定义一个结构体,用于存储读取到的ini文件中的键值对 typedef struct { char key[MAX_LINE_SIZE]; char value[MAX_LINE_SIZE]; } KeyValue; // 定义一个函数,用于去除字符串两端的空格和换行符 void trim(char *str) { int len = strlen(str); while (len > 0 && (str[len - 1] == ' ' || str[len - 1] == '\n' || str[len - 1] == '\r')) { str[--len] = '\0'; } int start = 0; while (str[start] && (str[start] == ' ' || str[start] == '\n' || str[start] == '\r')) { ++start; } if (start > 0) { memmove(str, str + start, len - start + 1); } } // 定义一个函数,用于读取ini文件中的键值对 int read_ini_file(const char *filename, KeyValue *kv, int max_count) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { return -1; } int count = 0; char line[MAX_LINE_SIZE]; while (fgets(line, MAX_LINE_SIZE, fp) != NULL) { trim(line); if (strlen(line) == 0) { continue; } if (line[0] == '[' && line[strlen(line) - 1] == ']') { // 这是一个节(Section)的名称,忽略掉 continue; } char *p = strchr(line, '='); if (p == NULL) { // 没有找到等号,忽略掉 continue; } *p++ = '\0'; trim(line); trim(p); strncpy(kv[count].key, line, MAX_LINE_SIZE - 1); strncpy(kv[count].value, p, MAX_LINE_SIZE - 1); ++count; if (count >= max_count) { // 配对的键值对数量已经达到了最大值,停止读取 break; } } fclose(fp); return count; } // 定义一个函数,用于写入ini文件中的键值对 int write_ini_file(const char *filename, KeyValue *kv, int count) { FILE *fp = fopen(filename, "w"); if (fp == NULL) { return -1; } for (int i = 0; i < count; ++i) { fprintf(fp, "%s=%s\n", kv[i].key, kv[i].value); } fclose(fp); return 0; } int main() { // 读取ini文件中的键值对,并打印出来 KeyValue kv[1024]; int count = read_ini_file("config.ini", kv, 1024); for (int i = 0; i < count; ++i) { printf("%s=%s\n", kv[i].key, kv[i].value); } // 修改键值对 for (int i = 0; i < count; ++i) { if (strcmp(kv[i].key, "name") == 0) { strcpy(kv[i].value, "Alice"); break; } } // 写入ini文件 write_ini_file("config.ini", kv, count); return 0; } ``` 以上代码仅供参考,具体实现方式可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值