1、頭文件包含,庫文件鏈接
在VC中開發HID應用程序時,需要包含setupapi.h和hidsdi.h,包含方式必須爲extern "C",如下所示:
extern "C" {
// Declare the C libraries used
#include "setupapi.h" // Must link in setupapi.lib
#include "hidsdi.h" // Must link in hid.lib
}
然後在setting—>Link—>object/libary modules 中添加setupapi.lib hid.lib 兩個庫文件。
2、Windows操作HID設備的API
API函數 |
DLL |
功能 |
HidD_GetHidGuid |
Hid.dll |
取得類別 |
SetupDiGetClassDevs |
Setupapi.dll |
獲取一個設備信息羣,包含指定類的所有設備 |
SetupDiEnumDeviceInterfaces |
Setupapi.dll |
獲取信息羣內一個設備的信息 |
SetupDiGetDeviceInterfaceDetail |
Setupapi.dll |
獲取設備路徑 |
HidD_GetAttributes |
Hid.dll |
獲取廠商與產品,版本號 |
HidP_GetValueCaps |
Hid.dll |
獲取描述設備能力的結構 |
CreateFile ReadFile |
Kernel32.dll Kernel32.dl |
開啓設備通信 從設備讀取一個報文 |
WriteFile |
Kernel32.dll |
發送一個報文給設備 |
CloseHandle |
Kernel32.dll |
釋放CreateFile創建的資源 |
SetupDiDestroyDeviceInfoList |
Setupapi.dll |
釋放SetupDiGetClassDevs使用的資源 |
HidD_GetPreparsedData |
Hid.dll |
獲取保存設備能力信息的緩衝器的句柄 |
HidD_SetFeature |
Hid.dll |
發送一個特徵報文給設備 |
HidD_GetFeature |
Hid.dll |
從設備獲取特徵報文 |
void __stdcall HidD_GetHidGuid(
__out LPGUID HidGuid //指針指向調用者分配的GUID的內存區域,通常返回HID設備的GUID
);
HDEVINFO SetupDiGetClassDevs(
__in_opt const GUID *ClassGuid,// 一個特定類別GUID的指針
__in_opt PCTSTR Enumerator, //過濾梅舉的內容
__in_opt HWND hwndParent, //用於關聯到集合成員中的用戶接口的頂層窗口句柄
__in DWORD Flags //建立設備信息表的控制選項,DIGCF_PRESENT(當前存在的設備)DIGCF_ALLCLASSES(所有設備)DIGCF_PROFILE(當前硬件概況);
如成功,返回包含所有與指定參數匹配的已經安裝設備信息句柄,否則返回INVALID_HANDLE_VALUE
BOOL SetupDiEnumDeviceInterfaces(
__in HDEVINFO DeviceInfoSet, //一個指向設備信息集合的句柄,包含設備接口返回信息,通常是SetupDiGetClassDevs的返回
__in_opt PSP_DEVINFO_DATA DeviceInfoData, //指向特定設備的SP_DEVINFO_DATA 類型的指針,
__in const GUID *InterfaceClassGuid, //指向制定設備接口類的GUID指針
__in DWORD MemberIndex, //設備信息中接口列表的索引值(初始值爲0)
__out PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData //指向調用者分配的SP_DEVICE_INTERFACE_DATA類型的內存區域的指針,調用前必須先配置DeviceInterfaceData.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA)
);
如成功,返回TRUE,否則返回FALSE,並可以調用GetLastError(void)獲取錯誤信息
BOOL SetupDiGetDeviceInterfaceDetail(
__in HDEVINFO DeviceInfoSet, //一個指向設備信息集合的句柄,包含設備接口返回信息,通常是SetupDiGetClassDevs的返回
__in PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, //指向SP_DEVICE_INTERFACE_DATA類型的內存區域的指針,SetupDiEnumDeviceInterfaces的返回
__out_opt PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,//SP_DEVICE_INTERFACE_DETAIL_DATA 類型指針,用於獲取路徑,調用前必須先配置DeviceInterfaceDetailData.cbSize =sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)
__in DWORD DeviceInterfaceDetailDataSize, //DeviceInterfaceDetailData 的長度,
__out_opt PDWORD RequiredSize, //DeviceInterfaceDetailData 的實際長度
__out_opt PSP_DEVINFO_DATA DeviceInfoData //PSP_DEVINFO_DATA 類型的指針,存放支持的設備接口信息,DeviceInfoData.cbSize =sizeof(SP_DEVINFO_DATA)
);
如成功,返回TRUE,否則返回FALSE,並可以調用GetLastError(void)獲取錯誤信息
BOOLEAN __stdcall HidD_GetAttributes(
__in HANDLE HidDeviceObject, //HID設備句柄
__out PHIDD_ATTRIBUTES Attributes //HIDD_ATTRIBUTES類型指針
);
HANDLE WINAPI CreateFile(
__in LPCTSTR lpFileName, //已打開的設備名稱
__in DWORD dwDesiredAccess, //操作權限,GENERIC_READ(讀模式), GENERIC_WRITE(寫模式), 或者both
__in DWORD dwShareMode, //共享模式,0(禁止訪問),FILE_SHARE_DELETE(刪除),FILE_SHARE_READ(讀),FILE_SHARE_WRITE(寫)
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, //SECURITY_ATTRIBUTES 類型指針
__in DWORD dwCreationDisposition, //打開方式,對於設備來說經常設爲 OPEN_EXISTING
__in DWORD dwFlagsAndAttributes, //設備屬性和標識,經常設爲FILE_ATTRIBUTE_NORMAL
__in_opt HANDLE hTemplateFile //模板文件句柄
);
如成功,則返回一個文件或設備的句柄
BOOL WINAPI ReadFile(
__in HANDLE hFile, //文件或設備的句柄
__out LPVOID lpBuffer, //存放讀取數據的指針
__in DWORD nNumberOfBytesToRead, //讀取數據長度的最大值
__out_opt LPDWORD lpNumberOfBytesRead, //讀取數據的實際長度
__inout_opt LPOVERLAPPED lpOverlapped //OVERLAPPED 類型指針,如果該設備或文件被重複打開,需要傳入次參數
);
如成功,返回TRUE,否則返回FALSE,並可以調用GetLastError(void)獲取錯誤信息
BOOL WINAPI WriteFile(
__in HANDLE hFile, //文件或設備的句柄
__in LPCVOID lpBuffer, //存放寫入數據的指針
__in DWORD nNumberOfBytesToWrite, //寫入數據長度的最大值
__out_opt LPDWORD lpNumberOfBytesWritten, //寫入數據的實際長度
__inout_opt LPOVERLAPPED lpOverlapped //OVERLAPPED 類型指針,如果該設備或文件被重複打開,需要傳入次參數
);
如成功,返回TRUE,否則返回FALSE,並可以調用GetLastError(void)獲取錯誤信息
BOOL SetupDiDestroyDeviceInfoList( __in HDEVINFO DeviceInfoSet); //釋放SetupDiGetClassDevs使用的資源
3、代碼示例
打開一個指定VendorID和ProductID的HID設備
PSP_DEVICE_INTERFACE_DETAIL_DATA HID_FindDevices(USHORT V_ID, USHORT P_ID, unsigned short *FIFO_Length)
{
GUID HidGuid;
HDEVINFO DevInfo;
HIDD_ATTRIBUTES DevAttributes;
SP_DEVICE_INTERFACE_DATA DevData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DevDetail;
PHIDP_PREPARSED_DATA PreparsedData;
HIDP_CAPS Capabilities;
ULONG Length;
int Index;
BOOL ok;
HANDLE DevHandle;
int DevCount = 0;
/* Get GUID for all System HIDs */
HidD_GetHidGuid(&HidGuid);
/* Get Device Information for all present devices */
DevInfo = SetupDiGetClassDevs(&HidGuid,
NULL,
NULL,
(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)
);
DevData.cbSize = sizeof(DevData);
DevDetail = NULL;
Index = -1;
*FIFO_Length = 0;
/* Scan all Devices */
do {
Index++;
/* Device Interface Element of a Device Information set */
ok = SetupDiEnumDeviceInterfaces(DevInfo,
0,
&HidGuid,
Index,
&DevData
);
if (!ok) break;
/* Get Device Interface Details - Get Length */
ok = SetupDiGetDeviceInterfaceDetail(DevInfo,
&DevData,
NULL,
0,
&Length,
NULL
);
/* Allocate memory for Device Detailed Data */
DevDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(Length);
/* Set cbSize in the DevDetail structure */
DevDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
/* Get Device Interface Details */
ok = SetupDiGetDeviceInterfaceDetail(DevInfo,
&DevData,
DevDetail,
Length,
NULL,
NULL
);
if (!ok)
{
free(DevDetail);
DevDetail = NULL;
continue;
}
/* Create File for Device Read/Write */
DevHandle = CreateFile(DevDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
(LPSECURITY_ATTRIBUTES)NULL,
OPEN_EXISTING,
0,
NULL
);
if (DevHandle == INVALID_HANDLE_VALUE)
{
free(DevDetail);
DevDetail = NULL;
continue;
}
DevAttributes.Size = sizeof(DevAttributes);
ok = HidD_GetAttributes(DevHandle,&DevAttributes);
if(!ok)
{
free(DevDetail);
CloseHandle(DevHandle);
DevDetail = NULL;
continue;
}
if(DevAttributes.VendorID!=V_ID||DevAttributes.ProductID != P_ID)
{
free(DevDetail);
CloseHandle(DevHandle);
DevDetail = NULL;
continue;
}
/* Get Preparsed Data */
ok = HidD_GetPreparsedData(DevHandle, &PreparsedData);
if (!ok)
{
free(DevDetail);
CloseHandle(DevHandle);
DevDetail = NULL;
continue;
}
/* Get Device's Capabilities */
HidP_GetCaps(PreparsedData, &Capabilities);
*FIFO_Length = Capabilities.InputReportByteLength;
CloseHandle (DevHandle);
break;
} while (DevCount < 20);
SetupDiDestroyDeviceInfoList (DevInfo);
return DevDetail;
}
轉載自:http://blog.csdn.net/leo_wonty/article/details/6716005