有关BCB访问USB HID设备

各位:
    我做了个下位机设备,通过USB和PC机通信。下位机将USB数据枚举成了HID设备,可以免驱被WIN7识别。但是用BCB开发上位机程序的时候,用BCB如何能直接访问这个HID设备呢?我用libusb,发现如果不对这个HID设备install filter的话,就没办法访问。install filter之后倒是可以用libusb -win来读写了。但是这样感觉有点麻烦。有什么方法,能让BCB直接就访问HID吗?
    多谢!

回答: 有关BCB访问USB HID设备

  1. 是CB6的控件

readfile读取usb HID设备连续多次写入读出后读不出来数据

  1. Q
    刚解决了写不进去数据的问题,现在发现连续往此HID设备里写入读出若干条数据后,用readfile读出的数据是上一条指令的,buff每次都清空的,或者执行好几次rwitefile、readfile才能返回当前指令应该返回的数据。关键代码如下:
    WriteHandle=CreateFile 
    (detailData->DevicePath, 
    GENERIC_WRITE, 
    FILE_SHARE_READ|FILE_SHARE_WRITE, 
    (LPSECURITY_ATTRIBUTES)NULL,
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL,
    NULL);
    ReadHandle=CreateFile 
    (detailData->DevicePath, 
    GENERIC_READ, 
    FILE_SHARE_READ|FILE_SHARE_WRITE,
    (LPSECURITY_ATTRIBUTES)NULL, 
    OPEN_EXISTING, 
    FILE_ATTRIBUTE_NORMAL,
    NULL);

    //写数据
    HANDLE hEventObject;
    if (hEventObject == 0)
    {
    hEventObject = CreateEvent 
    (NULL, 
    TRUE, 
    TRUE, 
    "");
    DisplayLastError("CreateEvent: ") ;

    //Set the members of the overlapped structure.

    HIDOverlapped.hEvent = hEventObject;
    HIDOverlapped.Offset = 0;
    HIDOverlapped.OffsetHigh = 0;
    }
    if (WriteHandle != INVALID_HANDLE_VALUE)
    {
    Result = WriteFile 
    (WriteHandle, 
    OutputReport, 
    Capabilities.OutputReportByteLength,
    &BytesWritten, 
    (LPOVERLAPPED) &HIDOverlapped
    //0
    );
    }
    /*Result = */WaitForSingleObject(hEventObject, 2000);
    ResetEvent(hEventObject);

    //读数据
    HANDLE hEventObject1;
    if (hEventObject1 == 0)
    {
    hEventObject1 = CreateEvent 
    (NULL, 
    TRUE, 
    FALSE, 
    NULL);
    DisplayLastError("CreateEvent: ") ;

    //Set the members of the overlapped structure.

    HIDOverlapped.hEvent = hEventObject1;
    HIDOverlapped.Offset = 0;
    HIDOverlapped.OffsetHigh = 0;
    }
    if (ReadHandle != INVALID_HANDLE_VALUE)
    {
    Result = ReadFile 
    (ReadHandle, 
    InputReport, 
    Capabilities.InputReportByteLength, 
    &NumberOfBytesRead,
    (LPOVERLAPPED) &HIDOverlapped); 
    }
    Result = WaitForSingleObject(hEventObject1, 6000);
    switch (Result)
    {
    case WAIT_OBJECT_0:
    {
    break;
    }
    case WAIT_TIMEOUT:
    {
    Result = CancelIo(ReadHandle);
    break;
    }
    default:
    {
    break;
    }
    }
    ResetEvent(hEventObject);


    这是为什么呢?大家帮忙找找原因。
  2. A
    读写没必要用不同的HANDLE
    WriteFile 调试看是否每次都发送成功了
    不要一次发多个数据, HID缓冲可能会被冲掉

访问USB 大容量存储设备

  1. Q
    我想实现跟USB存储设备之间的通信,但是遇到了一些问题,比较棘手,希望指教下:


    hDevHandle = CreateFile(dwDevicePath,
    GENERIC_READ|GENERIC_WRITE,
    FILE_SHARE_READ|FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
    NULL);
     

    获得句柄后,

    BOOL bResult;
        DWORD nBytesWritten;
        OVERLAPPED gOverlapped;
    DWORD dwResult;

    OVERLAPPED writeOS;

        dwResult = MPUSB_FAIL;

        Sleep(50);

    // set up overlapped structure fields
    memset(&gOverlapped,0,sizeof(gOverlapped));
    gOverlapped.Internal     = 0;
        gOverlapped.InternalHigh = 0;
        gOverlapped.Offset       = 0;
    gOverlapped.OffsetHigh   = 0;
    gOverlapped.hEvent       = CreateEvent(NULL, TRUE, FALSE, NULL);


        if(pLength != NULL)*pLength = 0;

        // attempt an asynchronous read operation
    bResult = WriteFile(hDevHandle,pData,dwLen,&nBytesWritten,&gOverlapped);

    DWORD err = GetLastError();


    在获取错误代码的时候 发现err一直为87 ,无效的参数,设备也打开成功了,就是写不了数据,是哪里出错了呢?
  2. A
    #include "windows.h"
    #include "tchar.h"
    #include "iostream.h"

    char * DispDriveType(int n)
    {
     switch(n)//关于磁盘类型的定义,在 winbase.h 中定义
    {
    case 0://DRIVE_UNKNOWN
       return "未知磁盘";
       break;
     case 1://DRIVE_NO_ROOT_DIR 无法找到根目录
       return "磁盘不存在";
       break;
     case 2://DRIVE_REMOVABLE 可移动驱动器
       return "可移动磁盘";
       break;
     case 3://DRIVE_FIXED 固定磁盘驱动器:本地硬盘或移动硬盘
       return "本地磁盘";
       break;
     case 4://DRIVE_REMOTE
       return "网络驱动器";
       break;
     case 5://DRIVE_CDROM
       return "CD/DVD_ROM";
       break;
     case 6://DRIVE_RAMDISK
       return "随机存取磁盘";
       break;
     }
    }
    void main()
    {
     TCHAR a[256];
     DWORD len=GetLogicalDriveStrings(sizeof(a)/sizeof(TCHAR),a);
     cout<<"磁盘符号"<<"\t"<<"磁盘类型"<<endl;
     for(TCHAR *s=a;*s;s+=_tcslen(s)+1)
     {
       cout<<s<<"\t\t"<<DispDriveType(GetDriveType(s))<<endl;
     }
     cin.get();
    }

    用这个得到可移动磁盘盘符,然后按楼上的用盘符操作

usb hid设备数据读取方法

  1. Q
    试了很多,由于本的vfp水平有限,没有把别人的示例转换成vfp可用的,直接对hid.dll,setupapi.dll的调用也都有问题,所以请求高手们出手帮助。这里是一个别人做好的程序,希望能把vb的示例转成vfp的,或者有高手直接对原来的hid.dll,setupapi.dll进行封装。示例地址:http://d.download.csdn.net/down/1483288/inhaos。
  2. A
    按 vb 的用法重写了一下,楼主试试看,如果还是不行就没办法了:


    #define MAX_DEVICES        10

    Declare Long GetList in UsbHidApi.dll ;
        Long VendorID, Long ProductID, ;
        Long Manufacturer, Long SerialNumber, Long DeviceName, ;
        String @DeviceList, Long MaxDevices
    Declare Long GlobalAlloc in WIN32API Long uFlags, Long dwBytes
    Declare Long GlobalFree in WIN32API Long hMem

    Local Array laDevList[MAX_DEVICES]

    m.pDevList = ''
    For m.ii = 1 To MAX_DEVICES
        m.laDevList[m.ii] = GlobalAlloc(0x40, 150)
        m.pDevList = m.pDevList ;
            + BinToC(m.laDevList[m.ii], 'rs') ;
            + BinToC(m.laDevList[m.ii] + 50, 'rs') ;
            + BinToC(m.laDevList[m.ii] + 100, 'rs') ;
            + Replicate(Chr(0), 24)
    EndFor
    m.lnFoundNums = GetList(0xffff, 0xffff, 0, 0, 0, @ m.pDevList, MAX_DEVICES)
    Clear
    ? '找到的设备数:' + Transform(m.lnFoundNums)
    For m.ii = 1 To MAX_DEVICES
        m.cDevContext = Sys(2600, m.laDevList[m.ii], 150)
        GlobalFree( m.laDevList[m.ii] )
        ? 'Device ' + Transform(m.ii) + ':' ;
            + 0h0d0a09 + 'DeviceName:   ' + Trim(Substr(m.cDevContext, 1, 50), Chr(0)) ;
            + 0h0d0a09 + 'Manufacturer: ' + Trim(Substr(m.cDevContext, 51, 50), Chr(0)) ;
            + 0h0d0a09 + 'SerialNumber: ' + Trim(Substr(m.cDevContext, 101, 50), Chr(0)) ;
            + 0h0d0a
    EndFor

usb(hid)设备的GUID是什么东西?

  1. Q
    现在知道PID,VID可以在下位机里面改,但是我需要GUID,GUID是不是也可以通过下位机改??
    不太明白GUID的概念.
  2. A
    GUID 有好多种   但都是用做唯一标识  

    其中ClassGUID 用途就是PNP枚举设备的时候

    首先调用目标驱动的driverentry

    然后安装其 up\low Filters 然后在该驱动的键下 找到其类的GUID

    然后在 class键  中找到该GUID的键 打开

    在这个键下面查找类驱动的up\low Filters  并调用driverentry

哪位大侠知道如何获取 HID 设备的“USB 人体学输入设备”设备范例 ID

  1. Q
    当一个 HID 设备插入 PC 机上时,在设备管理器的人体学输入设备项下会出现两个入口:

    * HID-comlian device
    * USB 人体学输入设备

    看后者的属性页时,“详细信息”页上可看到“设备范例 Id”, 如:

    USB\VID_4853&PID_084B\5&FF9BDDE&0&2

    请问,如何通过程序代码获取这个信息。

    我的目的是,插入多个相同设备时,获取插入 HUB 上的 HID 设备与插入的口的对应关系,告知用户哪一个设备已经处理完毕。

    能够以其他方法获得上述 ID 中最后的信息 &2 也可以。

    谢谢。
  2. A
    API太多了,还是用WMI吧。
    参考:http://hi.baidu.com/coo_boi/item/8d19038c3364d7814514cf81

求助!关于usb存储设备访问记录的问题。谢谢大家

  1. Q
        经理让我找找能记录usb存储设备访问电脑的软件,要求能记下用户使用usb存储设备在这台电脑上都考走了什么东西,或者用usb存储设备向电脑上拷了什么东西。
        我知道有个usbview软件,能记录usb访问记录,但只能记录哪些usb设备连接过过电脑。经理让我找个能详细记录的,能完成刚才上面说的的功能。大家说有这样的软件吗?能实现吗?
        本人第一次发帖,有诸多不懂,也不知道是不是发对地方了,还请大家见谅。请大家帮助。谢谢大家!
  2. A
    在google上输入usb monitor搜索

USB HID 读写文件返回87错误

  1. Q
    用MFC开发USB HID , 读写返回87错误,异步方式,代码如下,请朋友们帮忙解答下,不胜感激!

    void CSYNCDlg::OnBnClickedButton2()
    {
    // TODO:  在此添加控件通知处理程序代码
    UpdateData(true);
    bStopHID = false;

    CString temp;
    CString DevicePath;
    temp = "";
    int Count = 0; //Total number of devices found
    DWORD strSize = 0, requiredSize = 0;
    BOOL result1, result2;
    ULONG DeviceInterfaceDetailDataSize;
    SP_DEVINFO_DATA DeviceInfoData;
    SP_DEVICE_INTERFACE_DATA  DeviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
    //PSP_DEVICE_INTERFACE_DETAIL_DATA test;
    //1
    GUID deviceId;
    HidD_GetHidGuid(&deviceId);

    int venderID = v_eVendorID;
    int productID = v_eProductID;

    int nError;
    int v_eDataToWrite;
    unsigned int inbuffer[2];
    unsigned long numBytesReturned;
    HIDD_ATTRIBUTES devAttr;
    PHIDP_PREPARSED_DATA PreparsedData;
    HIDP_CAPS Capabilities;
    int readValue;
    bool LED;
    int flag = 0;
    inbuffer[0] = 0;


    //CString ShowMessage;
    //ShowMessage.Empty();

    OVERLAPPED    Overlapped;
    Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    Overlapped.Offset = 0;
    Overlapped.OffsetHigh = 0;


    //把界面里的二进制转换成10进制
    // inbuffer[1] = m_eByte0 * 1 + m_eByte1 * 2 + m_eByte2 * 4 + m_eByte3 * 8 + m_eByte4 * 16 + m_eByte5 * 32 + m_eByte6 * 64 + m_eByte7 * 128;

    inbuffer[1] = GetDlgItemInt(IDC_EDIT2);
    v_eDataToWrite = inbuffer[1];
    UpdateData(false);

    //2
    HDEVINFO handle;
    handle = SetupDiGetClassDevs(&deviceId, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); //Get only HID devices
    int i = 0;
    int j = m_ctllHIDdevices.GetCount();
    for (i = 0; i < m_ctllHIDdevices.GetCount(); i++)
    {
    m_ctllHIDdevices.GetText(i, temp);
    DevicePath = temp;
    HANDLE hCom = CreateFile(
    DevicePath,
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED, // 重叠方式 
    NULL);
    if (hCom == INVALID_HANDLE_VALUE)
    {
    //AfxMessageBox(_T("Invalide Device Path..."));
    continue;
    }
    devAttr.Size = sizeof(HIDD_ATTRIBUTES);
    if (!HidD_GetAttributes(hCom, &devAttr))
    {
    CloseHandle(hCom);
    AfxMessageBox(_T("Cannot get the parameters of the HID..."));
    return;
    }
    //temp.Format("Vendor ID: %d, Product ID:%d",devAttr.VendorID,devAttr.ProductID); //Compare with the Vendor ID and Product ID from Nakamura-san
    //AfxMessageBox(temp);

    if (!HidD_GetPreparsedData(hCom, &PreparsedData))
    {
    CloseHandle(hCom);
    AfxMessageBox(_T("Cannot get the Preparsed Data..."));
    return;
    }


    if (!HidP_GetCaps(PreparsedData, &Capabilities))
    {
    CloseHandle(hCom);
    AfxMessageBox(_T("Cannot get the Cap Data..."));
    return;
    }


    //ShowMessage = _T("开始查找USB设备......\r\nUSB类的GUID标识为:\r\n");
    //SetDlgItemText(IDC_EDIT2, ShowMessage);
    //ShowMessage += _T("a5dcbf10-6530-11d2-901f-00c04fb951ed\r\n\r\n");
    //SetDlgItemText(IDC_EDIT2, ShowMessage);


    // Write File
    if (devAttr.VendorID == venderID && devAttr.ProductID == productID)
    {
    result1 = WriteFile(hCom, inbuffer, 64, &numBytesReturned, &Overlapped);
    //temp=inbuffer;
    //p->m_eDataRead=CString(inbuffer);
    //p->UpdateData(false);
    if (!result1)
    {
    nError = GetLastError();
    AfxMessageBox(_T("Cannot Write Data..."));
    return;

    }
    AfxMessageBox(_T("Suncess..."));
    break;

    }
    }
    if (i == j)
    {
    AfxMessageBox(_T("There is no such HID device..."));
    }

    return;
    }
  2. A
    HidP_GetCaps
    这里获取的信息, 看包长度看是否正确

    只是测试下,通讯正常不正常,这个长度已经够用了!
    不好,  WriteFile 你发65个, 就需要至少65的空间

    OVERLAPPED 使用之前用 memset清0

HID设备如何收发数据?需不需要类似串口通信的什么通信协议,

  1. Q
           如题。
           以前一直做串口通信,协议什么的也比较清楚了。
           最近来了个HID设备(血氧仪),属于usb类的,还给了个相关协议,但是看着跟串口协议挺像的,不知道是不是这个协议,关键是没弄过。
           从网上找了很多HID通信的Demo,国内的国外的,在其中把vid和pid都设置正确了的,能正确识别设备但还是不能正确收发数据,看了看里面的代码好像也没特别的用到什么协议。
           不知道是用错了还是必须要什么协议支持,求高手赐教HID设备如何收发数据?需不需要类似串口通信的什么通信协议,
  2. A
    把你的CreateFile创建m_hWriteHandle的函数贴下,还有你的overlapped赋值处理过程贴下。第四个参数你赋值为0看看。

USB HID 读写STM32数据失败

  1. Q
      USB HID  读取STM32数据失败,写数据成功。使用 hid.DLL在使用readfile 读取数据时总是失败,同步时读取程序无响应死掉,异步时readfile返回0,使用bus hound 查看确定是有数据返回,但是就是readfile 接收不到。
    请教有经验的大侠,在使用readfile 读取hid 数据时需要注意什么? 与hid 报告描述符的哪个参数设置有关?在写数据正常情况下是否可以确定与读取数据相关的某些参数设置正确?

    先谢过了!
  2. A
    你是什么样的Hid设备?
    对应的HID Descriptor是怎么写的?