(USB HID) VC++ 使用 SetupAPI 操作 USB HID Device

时间:2021-07-12 17:52:26

在VC裡頭使用 Api必須include 跟加入 lib,加入之後就可以在VC裡頭任意使用api了

暫時先貼上程式碼...等待有空時候在更新說明

1 extern "C"
2 {
3 #include <hidsdi.h>
4 #include <SetupAPI.h>
5 }

(USB HID) VC++ 使用 SetupAPI 操作 USB HID Device

Dialog head file

 1 // CUsbHidDlg dialog
 2 class CUsbHidDlg : public CDialogEx
 3 {
 4 // Construction
 5 public:
 6     CUsbHidDlg(CWnd* pParent = NULL);    // standard constructor
 7 
 8 // Dialog Data
 9     enum { IDD = IDD_USBHID_DIALOG };
10 
11     protected:
12     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
13 public:
14     GUID                            HidGuid;
15     HDEVINFO                        DevInfo;
16     HIDD_ATTRIBUTES                    DevAttributes;
17     SP_DEVICE_INTERFACE_DATA        DevData;
18     PSP_DEVICE_INTERFACE_DETAIL_DATA DevDetail;
19     PHIDP_PREPARSED_DATA            PreparsedData;
20     HIDP_CAPS                        Capabilities;
21     ULONG                           Length;
22     int                             Index;
23     BOOL                            ok;
24     HANDLE                            DevHandle;
25     HANDLE                            RdHandle;
26     int                                DevCount = 0;
27 
28     CEdit    m_VID;
29     CEdit    m_PID;
30     CEdit    m_OutID;
31     CEdit    m_InID;
32 
33 // Implementation
34 protected:
35     HICON m_hIcon;
36 
37     // Generated message map functions
38     virtual BOOL OnInitDialog();
39     afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
40     afx_msg void OnPaint();
41     afx_msg HCURSOR OnQueryDragIcon();
42     DECLARE_MESSAGE_MAP()
43 public:
44     afx_msg void OnBnClickedOk();
45 
46 public:
47     BOOL FindHID();
48     BOOL DeviceWriteFile();
49     BOOL DeviceReadFile();
50     BOOL OutReport();
51     BOOL InReport();
52     afx_msg void OnBnClickedWritefile();
53     afx_msg void OnBnClickedReadfile();
54     afx_msg void OnBnClickedGetreport();
55     afx_msg void OnBnClickedSetreport();
56 };

 

FindHid

 1     uint16_t UVID;
 2     uint16_t UPID;
 3 
 4     BOOL bSuccess;
 5     CString buf;
 6     int    index = -1;
 7     CloseHandle(DevHandle);
 8     DevHandle = INVALID_HANDLE_VALUE;
 9     HidD_GetHidGuid(&HidGuid);
10 
11     wchar_t * wbuf = NULL;
12     byte ReportID;
13     GetDlgItemTextW(IDC_VID, buf);
14     UVID = wcstol(buf, &wbuf, 16);
15     GetDlgItemTextW(IDC_PID, buf);
16     UPID = wcstol(buf, &wbuf, 16);
17 
18     buf.Format(_T("%08x-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\r\n"),
19                 HidGuid.Data1, HidGuid.Data2, HidGuid.Data3,
20                 HidGuid.Data4[0],
21                 HidGuid.Data4[1],
22                 HidGuid.Data4[2],
23                 HidGuid.Data4[3],
24                 HidGuid.Data4[4],
25                 HidGuid.Data4[5],
26                 HidGuid.Data4[6],
27                 HidGuid.Data4[7]);
28     SetDlgItemText(IDC_INFO, buf.MakeUpper());
29     ULONG predictedLength = 0;
30     ULONG requiredLength = 0;
31 
32     DevInfo = SetupDiGetClassDevs(&HidGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
33     DevDetail = NULL;
34     DevData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
35     
36     for (int i = 0; i < 128; i++)
37     {
38         bSuccess = SetupDiEnumDeviceInterfaces(DevInfo, 0, &HidGuid, i, &DevData);
39 
40         if (!bSuccess) continue;
41         bSuccess = SetupDiGetDeviceInterfaceDetail(DevInfo, &DevData, NULL, 0, &predictedLength, NULL);
42         DevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(predictedLength);
43         DevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
44         bSuccess = SetupDiGetDeviceInterfaceDetail(DevInfo, &DevData, DevDetail, predictedLength, &requiredLength, NULL);
45         if (!bSuccess)
46         {
47             free(DevDetail);
48             DevDetail = NULL;
49             continue;
50         }
51         // origianl
52         DevHandle = CreateFile(DevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL);
53         
54         if (DevHandle == INVALID_HANDLE_VALUE)
55         {
56             free(DevDetail);
57             DevDetail = NULL;
58             continue;
59         }
60 
61         if (DevHandle != INVALID_HANDLE_VALUE)
62         {
63             HidD_GetAttributes(DevHandle, &DevAttributes);
64 
65             if (!HidD_GetPreparsedData(DevHandle, &PreparsedData))
66             {
67                 CloseHandle(DevHandle);
68                 return 0;
69             }
70 
71             if (!HidP_GetCaps(PreparsedData, &Capabilities))
72             {
73                 CloseHandle(DevHandle);
74                 return 0;
75             }
76 
77 
78             //if (DevAttributes.VendorID == V_ID && DevAttributes.ProductID == P_ID)
79             if (DevAttributes.VendorID == UVID && DevAttributes.ProductID == UPID)
80             {
81                 bSuccess = true;
82                 CString str;
83                 GetDlgItemTextW(IDC_INFO, str);
84                 buf.Format(_T("Find specified Usb Hid device.\r\nVID = 0x%x, PID = 0x%x\r\n"), DevAttributes.VendorID, DevAttributes.ProductID);
85                 str += buf;
86                 SetDlgItemTextW(IDC_INFO, str);
87                 break;
88             }
89             else
90             {
91                 CloseHandle(DevHandle);
92                 DevHandle = INVALID_HANDLE_VALUE;
93             }
94         }
95 
96     }
97 
98     SetupDiDestroyDeviceInfoList(DevInfo);
99     return bSuccess;

WriteFile

 1 BOOL CUsbHidDlg::DeviceWriteFile()
 2 {
 3     CString buf;
 4     CString temp;
 5     BOOL bRet;
 6     byte buffer[8] = { 0 };
 7     UINT len = 8;
 8     DWORD dRet;
 9     int ErrorCode;
10 
11     wchar_t * wbuf = NULL;
12     byte ReportID;
13     GetDlgItemTextW(IDC_OUTID, buf);
14     ReportID = wcstol(buf, &wbuf, 16);
15 
16     //ReportID = _ttoi(buf); Cstring to int
17     buffer[0] = ReportID; /* Out Report ID */
18 
19     /* ok */
20     bRet = WriteFile(DevHandle, buffer, len, &dRet, NULL);
21 
22     ErrorCode = GetLastError();
23 
24     if (bRet){
25         buf.Format(_T("WriteFile Successful, check LED 3 !! \r\n"));
26         temp = buf;
27         SetDlgItemTextW(IDC_INFO, temp);
28     }
29     else{
30         buf.Format(_T("WriteFile Fail !!!\r\n"));
31         temp = buf;
32         SetDlgItemTextW(IDC_INFO, temp);
33     }
34 
35     CString strMsg;
36     LPVOID lpMsgBuf;
37     FormatMessage(
38         FORMAT_MESSAGE_ALLOCATE_BUFFER |
39         FORMAT_MESSAGE_FROM_SYSTEM |
40         FORMAT_MESSAGE_IGNORE_INSERTS,
41         NULL,
42         ErrorCode,
43         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
44         (LPTSTR)&lpMsgBuf,
45         0,
46         NULL);
47     strMsg.Format(_T("\r\n錯誤訊息:%s\n錯誤代碼:0x%x\r\n"), lpMsgBuf, GetLastError());
48     buf += strMsg;
49     SetDlgItemTextW(IDC_INFO, buf);
50     LocalFree(lpMsgBuf); // 記得 free 掉空間
51     return bRet;
52 }

ReadFile

 1 BOOL CUsbHidDlg::DeviceReadFile()
 2 {
 3     CString temp, buf;
 4     BOOL bRet;
 5     byte buffer[8] = { 0 };
 6     UINT len = 8;
 7     DWORD dRet = 0;
 8     buffer[0] = 0x01;
 9     
10     wchar_t * wbuf = NULL;
11     byte ReportID;
12     GetDlgItemTextW(IDC_INID, buf);
13     ReportID = wcstol(buf, &wbuf, 16);
14 
15 
16     buffer[0] = ReportID; /* Out Report ID */
17     //buffer[1] = 0x02;
18     //WriteFile(DevHandle, buffer, 8, &dRet, NULL);
19     
20     bRet = ReadFile(DevHandle, &buffer[0], 8, &dRet, NULL);
21     int ErrorCode = GetLastError();
22 
23     if (bRet){
24         buf.Format(_T("ReadFile Successful, check LED 4 !!! \r\nReadFile data = "));
25         temp = buf;
26         
27         for (int i = 0; i < 8; i++){
28             buf.Format(_T("%.2x "), buffer[i]);
29             temp += buf;
30         }
31         temp += _T(".\r\n");
32 
33         SetDlgItemTextW(IDC_INFO, temp);
34     }
35     else
36     {
37         temp.Format(_T("ReadFile Fail !!!\r\n"));
38         SetDlgItemTextW(IDC_INFO, temp);
39     }
40 
41     CString strMsg;
42     LPVOID lpMsgBuf;
43     FormatMessage(
44         FORMAT_MESSAGE_ALLOCATE_BUFFER |
45         FORMAT_MESSAGE_FROM_SYSTEM |
46         FORMAT_MESSAGE_IGNORE_INSERTS,
47         NULL,
48         ErrorCode,
49         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
50         (LPTSTR)&lpMsgBuf,
51         0,
52         NULL);
53     strMsg.Format(_T("\r\n錯誤訊息:%s\n錯誤代碼:0x%x\r\n"), lpMsgBuf, GetLastError());
54     temp += strMsg;
55     SetDlgItemTextW(IDC_INFO, temp);
56     LocalFree(lpMsgBuf); // 記得 free 掉空間
57 
58 
59     return bRet;
60 }

OutReport

 1 BOOL CUsbHidDlg::OutReport()
 2 {
 3     BOOL bRet;
 4     CString buf;
 5     CString temp;
 6     byte buffer[8] = { 0 };
 7 
 8     UINT len = 8;
 9     DWORD dRet;
10 
11     wchar_t * wbuf = NULL;
12     byte ReportID;
13     GetDlgItemTextW(IDC_OUTID, buf);
14     ReportID = wcstol(buf, &wbuf, 16);
15 
16     buffer[0] = ReportID; /* Out Report ID*/
17     buffer[1] = 0x02; 
18     /* ok */
19     bRet = HidD_SetOutputReport(DevHandle, buffer, len);
20 
21     if (bRet){
22         buf.Format(_T("Send Out Report Successful, check LED 5 !!! \r\n"));
23         temp = buf;
24         SetDlgItemTextW(IDC_INFO, temp);
25     }
26     else{
27         buf.Format(_T("Send Out Report Fail !!!\r\n"));
28         temp = buf;
29         SetDlgItemTextW(IDC_INFO, temp);
30     }
31 
32     /* error message print */
33     CString strMsg;
34     LPVOID lpMsgBuf;
35     FormatMessage(
36         FORMAT_MESSAGE_ALLOCATE_BUFFER |
37         FORMAT_MESSAGE_FROM_SYSTEM |
38         FORMAT_MESSAGE_IGNORE_INSERTS,
39         NULL,
40         GetLastError(),
41         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
42         (LPTSTR)&lpMsgBuf,
43         0,
44         NULL);
45     strMsg.Format(_T("\r\n錯誤訊息:%s\n錯誤代碼:0x%x\r\n"), lpMsgBuf, GetLastError());
46     buf += strMsg;
47     SetDlgItemTextW(IDC_INFO, buf);
48     LocalFree(lpMsgBuf); // 記得 free 掉空間
49     /* error message print */
50 
51     return bRet;
52 }

InReprot

 1 BOOL CUsbHidDlg::InReport()
 2 {
 3     BOOL bRet;
 4     CString temp, buf;
 5     byte buffer[8] = { 0 };
 6     DWORD dRet;
 7     UINT len = 8;
 8 
 9     wchar_t * wbuf = NULL;
10     byte ReportID;
11     GetDlgItemTextW(IDC_INID, buf);
12     ReportID = wcstol(buf, &wbuf, 16);
13 
14     buffer[0] = ReportID; /* IN Report ID*/
15 
16     /* ok */
17     bRet = HidD_GetInputReport(DevHandle, buffer, len);
18     if (bRet){
19         buf.Format(_T("Get In Report Successful, check LED 6 !!! \r\n"));
20         temp = buf;
21         SetDlgItemTextW(IDC_INFO, temp);
22     }
23     else
24     {
25         buf.Format(_T("Get In Report Fail !!! \r\n"));
26         temp = buf;
27         SetDlgItemTextW(IDC_INFO, temp);
28     }
29 
30     /* error message print */
31     CString strMsg;
32     LPVOID lpMsgBuf;
33     FormatMessage(
34         FORMAT_MESSAGE_ALLOCATE_BUFFER |
35         FORMAT_MESSAGE_FROM_SYSTEM |
36         FORMAT_MESSAGE_IGNORE_INSERTS,
37         NULL,
38         GetLastError(),
39         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
40         (LPTSTR)&lpMsgBuf,
41         0,
42         NULL);
43     strMsg.Format(_T("\r\n錯誤訊息:%s\n錯誤代碼:0x%x\r\n"), lpMsgBuf, GetLastError());
44     buf += strMsg;
45     SetDlgItemTextW(IDC_INFO, buf);
46     LocalFree(lpMsgBuf); // 記得 free 掉空間
47     /* error message print */
48     return bRet;
49 }