There are other methods for retrieving the COM port number, without using the registry. I’ve pasted my code below. It would be nice if you could use this instead of the registery, since there is no reason why you need to run in Admin mode just to talk to the COM port!
You need to supply bool ValidVidPidPair(uint16_t vid, uint16_t pid);
This should check for the VID/PID of the virtual com port you are looking for. I use this for both FTDI and virtual serial ports.
#include <windows.h>
#include <set>
#include <string>
...
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,0,0,DIGCF_PRESENT|DIGCF_ALLCLASSES);
if ( hDevInfo ){
while (TRUE){
SP_DEVINFO_DATA DeviceInterfaceData;
ZeroMemory(&DeviceInterfaceData, sizeof(DeviceInterfaceData));
DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInterfaceData)){
// SetupDiEnumDeviceInfo failed
break;
}
DWORD dataType;
DWORD actualSize = 0;
wchar_t dataBuf[MAX_PATH + 1];
if (SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInterfaceData, SPDRP_HARDWAREID,
&dataType,(PBYTE) dataBuf, sizeof(dataBuf),&actualSize)){
DWORD vid;
DWORD pid;
DWORD rev;
bool ok = false;
if (swscanf_s(dataBuf,TEXT("USB\\Vid_%04X&Pid_%04X&Rev_%04X"),&vid,&pid,&rev) == 3) {
ok = true;
} else
if (swscanf_s(dataBuf,TEXT("USB\\VID_%04X&PID_%04X&REV_%04X"),&vid,&pid,&rev) == 3) {
ok = true;
}
if (ok) {
if (ValidVidPidPair(vid,pid)) {
// Get the service name associated with this USB device.
// We support usbser and FTD2XX right now.
if (SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInterfaceData,SPDRP_SERVICE,
&dataType, (PBYTE) dataBuf, sizeof(dataBuf), &actualSize)) {
wprintf(TEXT("INFO: Device Service Name: %s VID/PID:%04X/%04X\n"),dataBuf,vid,pid);
std::wstring comportname;
if (wcscmp(dataBuf,TEXT("usbser")) == 0) {
if (SetupDiGetDeviceRegistryProperty(hDevInfo,&DeviceInterfaceData,SPDRP_FRIENDLYNAME,
&dataType, (PBYTE) dataBuf, sizeof(dataBuf), &actualSize)) {
std::wstring friendlyname(dataBuf);
size_t x = friendlyname.find(TEXT("(COM"));
if (x >=0) {
size_t y = friendlyname.find(TEXT(")"),x);
assert(y>x+4);
comportname = TEXT("\\\\.\\");
comportname += friendlyname.substr(x+1,y-x-1);
}
}
}
else if (wcscmp(dataBuf,TEXT("FTD2XX")) == 0) {
comportname = dataBuf;
}
else if (wcscmp(dataBuf,TEXT("FTDIBUS")) == 0) {
comportname = TEXT("FTD2XX") ;
}
// do something with comportname here
}
}
}
}
i++;
}
}
SetupDiDestroyDeviceInfoList(hDevInfo);