我通过WinAPI句柄连接到Arduino Uno R3。
std::string name = "COM5";
this->handle = CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
我如何才能安全地区分Arduino,以便我不与不同的东西进行通信或者至少得到它的名字,最好没有第三方库?经过研究后我发现了几个API(QueryDosDevice
和NtQueryObject
),但我不知道如何在我的代码中实现这些。
编辑:我现在能够枚举USB设备,但是我遇到了完全相反的问题。我不知道如何从这些创建文件:
EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY DEVPKEY_Device_BusReportedDeviceDesc = { { 0x540b947e, 0x8b40, 0x45bc, { 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2 } }, 4 };
typedef BOOL(WINAPI *FN_SetupDiGetDeviceProperty)(
__in HDEVINFO DeviceInfoSet,
__in PSP_DEVINFO_DATA DeviceInfoData,
__in const DEVPROPKEY *PropertyKey,
__out DEVPROPTYPE *PropertyType,
__out_opt PBYTE PropertyBuffer,
__in DWORD PropertyBufferSize,
__out_opt PDWORD RequiredSize,
__in DWORD Flags
);
std::vector<device> usbenumerator::ListDevices()
{
DWORD dwSize;
DEVPROPTYPE ulPropertyType;
CONFIGRET status;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
char szDeviceInstanceID[MAX_DEVICE_ID_LEN];
WCHAR szBuffer[4096];
FN_SetupDiGetDeviceProperty GetDeviceProperty = (FN_SetupDiGetDeviceProperty)(GetProcAddress(GetModuleHandle("setupapi.dll"), "SetupDiGetDevicePropertyW"));
hDevInfo = SetupDiGetClassDevs(NULL, "USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
std::vector<device> output;
if (hDevInfo == INVALID_HANDLE_VALUE)
{
return output;
}
for (int i = 0; ; i++)
{
device dev;
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
{
break;
}
status = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
if (status != CR_SUCCESS)
{
continue;
}
std::string deviceID = szDeviceInstanceID;
dev.id = deviceID;
if (GetDeviceProperty && GetDeviceProperty(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc, &ulPropertyType, (BYTE*) szBuffer, sizeof(szBuffer), &dwSize, 0))
{
if (GetDeviceProperty(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc, &ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0))
{
_bstr_t b(szBuffer);
const char* cBusReportedDesc = b;
std::string busReportedDesc = cBusReportedDesc;
dev.busReportedDesc = busReportedDesc;
}
}
output.push_back(dev);
}
return output;
}
答案 0 :(得分:0)
我想我明白了:我基本上是在Windows注册表中创建自己的SymbolicName键副本(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\**YOUR_DEVICE_ID**\Device Parameters
,例如HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_2341&PID_0001\75633313233351E0A1E1\Device Parameters
)
// Error checking omitted
CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
std::string deviceID = szDeviceInstanceID;
std::string did = deviceID;
// Convert all backslashes to hash signs
std::replace(did.begin(), did.end(), '\\', '#');
// The GUID seems to stay the same: https://docs.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-usb-device
std::string rid = "\\??\\" + did + "#{a5dcbf10-6530-11d2-901f-00c04fb951ed}";
handle = CreateFile(rid, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);