WinUSB枚举和打开设备
2022-05-11
2733
0
打开设备之前,得先枚举到设备,获取到设备的链接名,然后才能通过CreateFile打开设备,与之通讯。
设备接口GUID
枚举设备是通过winsub驱动的inf文件中的DeviceInterfaceGUIDs来实现的。在WinUSB驱动设备时,会使用该GUID来注册设备接口,所以我们也需要此接口来枚举设备。
DeviceInterfaceGUIDs由用户定义,在该设备的inf文件中,如:
[ADB.HW.AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,"{5E9DCF7E-5A2A-49C9-A992-704D47B92CF2}"
枚举设备
枚举设备可以通过SetupAPI函数来实现,也可以使用CM系列函数实现。
SetupAPI函数我们比较熟悉,其代码可以参考:http://www.usbzh.com/article/detail-111.html
CM函数是比较新的一套API,最新的WDK10生成应用层示例代码时,自动生成:
HRESULT
RetrieveDevicePath(
_Out_bytecap_(BufLen) LPTSTR DevicePath,
_In_ ULONG BufLen,
_Out_opt_ PBOOL FailureDeviceNotFound
)
/*++
Routine description:
Retrieve the device path that can be used to open the WinUSB-based device.
If multiple devices have the same device interface GUID, there is no
guarantee of which one will be returned.
Arguments:
DevicePath - On successful return, the path of the device (use with CreateFile).
BufLen - The size of DevicePath's buffer, in bytes
FailureDeviceNotFound - TRUE when failure is returned due to no devices
found with the correct device interface (device not connected, driver
not installed, or device is disabled in Device Manager); FALSE
otherwise.
Return value:
HRESULT
--*/
{
CONFIGRET cr = CR_SUCCESS;
HRESULT hr = S_OK;
PTSTR DeviceInterfaceList = NULL;
ULONG DeviceInterfaceListLength = 0;
if (NULL != FailureDeviceNotFound) {
*FailureDeviceNotFound = FALSE;
}
//
// Enumerate all devices exposing the interface. Do this in a loop
// in case a new interface is discovered while this code is executing,
// causing CM_Get_Device_Interface_List to return CR_BUFFER_SMALL.
//
do {
cr = CM_Get_Device_Interface_List_Size(&DeviceInterfaceListLength,
(LPGUID)&GUID_DEVINTERFACE_WINUSB,
NULL,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
hr = HRESULT_FROM_WIN32(CM_MapCrToWin32Err(cr, ERROR_INVALID_DATA));
break;
}
DeviceInterfaceList = (PTSTR)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
DeviceInterfaceListLength * sizeof(TCHAR));
if (DeviceInterfaceList == NULL) {
hr = E_OUTOFMEMORY;
break;
}
cr = CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_WINUSB,
NULL,
DeviceInterfaceList,
DeviceInterfaceListLength,
CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cr != CR_SUCCESS) {
HeapFree(GetProcessHeap(), 0, DeviceInterfaceList);
if (cr != CR_BUFFER_SMALL) {
hr = HRESULT_FROM_WIN32(CM_MapCrToWin32Err(cr, ERROR_INVALID_DATA));
}
}
} while (cr == CR_BUFFER_SMALL);
if (FAILED(hr)) {
return hr;
}
//
// If the interface list is empty, no devices were found.
//
if (*DeviceInterfaceList == TEXT('\0')) {
if (NULL != FailureDeviceNotFound) {
*FailureDeviceNotFound = TRUE;
}
hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
HeapFree(GetProcessHeap(), 0, DeviceInterfaceList);
return hr;
}
//
// Give path of the first found device interface instance to the caller. CM_Get_Device_Interface_List ensured
// the instance is NULL-terminated.
//
hr = StringCbCopy(DevicePath,
BufLen,
DeviceInterfaceList);
HeapFree(GetProcessHeap(), 0, DeviceInterfaceList);
return hr;
}
这里的GUID_DEVINTERFACE_WINUSB就是DeviceInterfaceGUIDs。
打开设备
打开设备比较简单,就是CreateFile。
HRESULT
OpenDevice(
_Out_ PDEVICE_DATA DeviceData,
_Out_opt_ PBOOL FailureDeviceNotFound
)
/*++
Routine description:
Open all needed handles to interact with the device.
If the device has multiple USB interfaces, this function grants access to
only the first interface.
If multiple devices have the same device interface GUID, there is no
guarantee of which one will be returned.
Arguments:
DeviceData - Struct filled in by this function. The caller should use the
WinusbHandle to interact with the device, and must pass the struct to
CloseDevice when finished.
FailureDeviceNotFound - TRUE when failure is returned due to no devices
found with the correct device interface (device not connected, driver
not installed, or device is disabled in Device Manager); FALSE
otherwise.
Return value:
HRESULT
--*/
{
HRESULT hr = S_OK;
BOOL bResult;
DeviceData->HandlesOpen = FALSE;
hr = RetrieveDevicePath(DeviceData->DevicePath,
sizeof(DeviceData->DevicePath),
FailureDeviceNotFound);
if (FAILED(hr)) {
return hr;
}
DeviceData->DeviceHandle = CreateFile(DeviceData->DevicePath,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (INVALID_HANDLE_VALUE == DeviceData->DeviceHandle) {
hr = HRESULT_FROM_WIN32(GetLastError());
return hr;
}
bResult = WinUsb_Initialize(DeviceData->DeviceHandle,
&DeviceData->WinusbHandle);
if (FALSE == bResult) {
hr = HRESULT_FROM_WIN32(GetLastError());
CloseHandle(DeviceData->DeviceHandle);
return hr;
}
DeviceData->HandlesOpen = TRUE;
return hr;
}
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936