最近項目上需要做一個小上位機,獲取相同HID設備的信息,並逐個進行系統設置。
經過1天的調試,已經完成了。前期在相同HID設備句柄獲取方面,受到了一點小小的阻力,網上也沒有獲取到相關的信息,可能有遇到同樣問題的朋友,把我的解決方式貼出來,或許會有點作用吧。
基於VS2015,使用MFC自帶USB類庫。核心代碼如下,思路其實很簡單:通常我們使用PID和VID來獲得不同設備的句柄,相同PID和VID的設備,就需要其他的特徵來獲取句柄,調試過程中發現,相同HID的設備,設備路徑是不同的,可以用設備路徑作爲區分,來獲得句柄即可。
HANDLE OpenSamePIDDevice(int overlapped, unsigned short Pid_Value)
{
int Pid_count = 0;
LPCWSTR device_path = NULL;
HANDLE hidHandle = NULL;
HidD_GetHidGuid(&hidGuid); //取得類別
HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL,
(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); //獲取設備信息羣
if (hDevInfo == INVALID_HANDLE_VALUE)//未獲得設備信息羣則直接退出
return INVALID_HANDLE_VALUE;
SP_DEVICE_INTERFACE_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
int deviceNo = 0;
SetLastError(NO_ERROR);
while (GetLastError() != ERROR_NO_MORE_ITEMS)
{
if (SetupDiEnumInterfaceDevice(hDevInfo, 0, &hidGuid, deviceNo, &devInfoData)) //枚舉成功?
{
ULONG requiredLength = 0;
SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, NULL, 0, &requiredLength, NULL);//獲得接口詳細信息
PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*)malloc(requiredLength);
devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
if (!SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, devDetail, requiredLength, NULL, NULL))//獲得詳細信息失敗則退出
{
free(devDetail);
SetupDiDestroyDeviceInfoList(hDevInfo);
return INVALID_HANDLE_VALUE;
}
if (overlapped) //打開設備
{
hidHandle = CreateFile(devDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
}
else
{
hidHandle = CreateFile(devDetail->DevicePath,
GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
}
//if (devDetail != NULL)
//free(devDetail);
if (hidHandle == INVALID_HANDLE_VALUE)
{
SetupDiDestroyDeviceInfoList(hDevInfo);
// free(devDetail);
return INVALID_HANDLE_VALUE;
}
_HIDD_ATTRIBUTES hidAttributes;
if (!HidD_GetAttributes(hidHandle, &hidAttributes))
{
CloseHandle(hidHandle);
SetupDiDestroyDeviceInfoList(hDevInfo);
return INVALID_HANDLE_VALUE;
}
if ((USB_VID == hidAttributes.VendorID)&(Pid_Value == hidAttributes.ProductID)) //僅僅根據VID進行STM32設備判斷
{
++Pid_count;
if (Pid_count == 1)
{
//獲得句柄
if(Pid_Value == Falcon_Handset_PID)
{
hHandSet1 = hidHandle;
}
else if(Pid_Value == Falcon_Camera_PID)
{
hCamera1 = hidHandle;
}
device_path = devDetail->DevicePath;//用於路徑比較
}
if ((Pid_count != 1)&(device_path!= devDetail->DevicePath))
{
if (Pid_Value == Falcon_Handset_PID)
{
hHandSet2 = hidHandle;
}
else if (Pid_Value == Falcon_Camera_PID)
{
hCamera2 = hidHandle;
}
break;
}
//CloseHandle(hidHandle);
++deviceNo;
}
else
{
CloseHandle(hidHandle);
++deviceNo;
}
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);
return hidHandle;
}