[我正在尝试在Windows 10上读取USB设备,紧随这两个页面using-winusb-api-to-communicate-with-a-usb-device和WinUSBCommTest.cpp,但是当我尝试运行此代码时,由于Windows错误8,ERROR_NOT_ENOUGH_MEMORY,WinUsb_Initialize
失败。而且我不知道如何解决它,有人可以帮我吗?
BOOL GetWinUSBHandle(HANDLE hDeviceHandle, PWINUSB_INTERFACE_HANDLE phWinUSBHandle)
{
if (hDeviceHandle == INVALID_HANDLE_VALUE)
{
return FALSE;
}
BOOL bResult = WinUsb_Initialize(hDeviceHandle, phWinUSBHandle);
if(!bResult)
{
//Error.
printf("WinUsb_Initialize Error %d.", GetLastError());
return FALSE;
}
return bResult;
}
BOOL GetDeviceHandle (GUID guidDeviceInterface, PHANDLE hDeviceHandle)
{
if (guidDeviceInterface==GUID_NULL)
{
return FALSE;
}
BOOL bResult = TRUE;
HDEVINFO hDeviceInfo;
SP_DEVINFO_DATA DeviceInfoData;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;
ULONG requiredLength=0;
LPTSTR lpDevicePath = NULL;
DWORD index = 0;
// Get information about all the installed devices for the specified
// device interface class.
hDeviceInfo = SetupDiGetClassDevs(
&guidDeviceInterface,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDeviceInfo == INVALID_HANDLE_VALUE)
{
// ERROR
PTRACE("Error SetupDiGetClassDevs: %d.\n", GetLastError());
goto done;
}
//Enumerate all the device interfaces in the device information set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); index++)
{
//Reset for this iteration
if (lpDevicePath)
{
LocalFree(lpDevicePath);
}
if (pInterfaceDetailData)
{
LocalFree(pInterfaceDetailData);
}
deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
//Get information about the device interface.
bResult = SetupDiEnumDeviceInterfaces(
hDeviceInfo,
&DeviceInfoData,
&guidDeviceInterface,
0,
&deviceInterfaceData);
// Check if last item
if (GetLastError () == ERROR_NO_MORE_ITEMS)
{
break;
}
//Check for some other error
if (!bResult)
{
printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
goto done;
}
//Interface data is returned in SP_DEVICE_INTERFACE_DETAIL_DATA
//which we need to allocate, so we have to call this function twice.
//First to get the size so that we know how much to allocate
//Second, the actual call with the allocated buffer
bResult = SetupDiGetDeviceInterfaceDetail(
hDeviceInfo,
&deviceInterfaceData,
NULL, 0,
&requiredLength,
NULL);
//Check for some other error
if (!bResult)
{
if ((ERROR_INSUFFICIENT_BUFFER==GetLastError()) && (requiredLength>0))
{
//we got the size, allocate buffer
pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);
if (!pInterfaceDetailData)
{
// ERROR
printf("Error allocating memory for the device detail buffer.\n");
goto done;
}
}
else
{
printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
goto done;
}
}
//get the interface detailed data
pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
//Now call it with the correct size and allocated buffer
bResult = SetupDiGetDeviceInterfaceDetail(
hDeviceInfo,
&deviceInterfaceData,
pInterfaceDetailData,
requiredLength,
NULL,
&DeviceInfoData);
//Check for some other error
if (!bResult)
{
printf("Error SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError());
goto done;
}
//copy device path
size_t nLength = _tcslen(pInterfaceDetailData->DevicePath) + 1;
lpDevicePath = (TCHAR *) LocalAlloc (LPTR, nLength * sizeof(TCHAR));
StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath);
lpDevicePath[nLength-1] = 0;
printf("Device path: %s\n", lpDevicePath);
}
if (!lpDevicePath)
{
//Error.
printf("Error %d.", GetLastError());
goto done;
}
//Open the device
*hDeviceHandle = CreateFile (
lpDevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
if (*hDeviceHandle == INVALID_HANDLE_VALUE)
{
//Error.
printf("Error %d.", GetLastError());
goto done;
}
done:
LocalFree(lpDevicePath);
LocalFree(pInterfaceDetailData);
bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo);
return bResult;
}
如果您在GUID_DEVINTERFACE_USB_DEVICE
上进行枚举,则会得到一个设备(相对于特定接口)。如果您的设备有多个接口,则WinUsb_Initialize
将失败,并显示8-ERROR_NOT_ENOUGH_MEMORY
。您需要列举一些特定的内容,例如GUID_DEVINTERFACE_ANDROID
。当您获取路径时,将其打印出来,您将看到它不是特定于界面的。
This is a GUID_DEVINTERFACE_USB_DEVICE (whole device)
\\?\usb#vid_1004&pid_62c6#vs12345678#{a5dcbf10-6530-11d2-901f-00c04fb951ed
This is a GUID_DEVINTERFACE_ANDROID (specific interface, #1)
\\?\usb#vid_1004&pid_62c6&mi_01#6&987654&1&0001#{f72fe0d4-cbcb-407d-8814-9ed673d0dd6b}