C/C++枚举设备管理器上显示的物理串口(能够枚举出USB转串口等)
2016-07-19 17:15
579 查看
调用EnumPort API可以获取到串口,并口,TCP/IP打印端口等。不过该API获取到的串口有很多不是真实的物理串口。要获取物理串口,我们可以通过串口设备类型的GUID获取设备管理器中的实际串口。如下是实现方式:
如上,为了printf函数可以打印出中文,这里调用了 setlocale(LC_ALL,"chs") 函数即可正常打印出中文。
BOOL WcharIsDigit(WCHAR ch) { if(ch >= L'0' && ch <= L'9') { return TRUE; } return FALSE; } // The following define is from ntddser.h in the DDK. It is also // needed for serial port enumeration. #ifndef GUID_CLASS_COMPORT DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, \ 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73); #endif BOOL EnumPortsWdm() { // Create a device information set that will be the container for // the device interfaces. GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL; hDevInfo = SetupDiGetClassDevs( guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); if(INVALID_HANDLE_VALUE == hDevInfo) { return FALSE; } // Enumerate the serial ports BOOL bOk = TRUE; SP_DEVICE_INTERFACE_DATA ifcData; DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*)new char[dwDetDataSize]; if(!pDetData) { return FALSE; } // This is required, according to the documentation. Yes, // it's weird. ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); for (DWORD ii=0; bOk; ii++) { bOk = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guidDev, ii, &ifcData); if (bOk) { // Got a device. Get the details. SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)}; bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, NULL, &devdata); if (bOk) { // Got a path to the device. Try to get some more info. WCHAR fname[256] = {0}; WCHAR desc[256] = {0}; BOOL bSuccess = SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname), NULL); bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL, (PBYTE)desc, sizeof(desc), NULL); BOOL bUsbDevice = FALSE; WCHAR locinfo[256] = {0}; if (SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE)locinfo, sizeof(locinfo), NULL)) { // Just check the first three characters to determine // if the port is connected to the USB bus. This isn't // an infallible method; it would be better to use the // BUS GUID. Currently, Windows doesn't let you query // that though (SPDRP_BUSTYPEGUID seems to exist in // documentation only). bUsbDevice = (wcsncmp(locinfo,L"USB", 3)==0); } if (bSuccess) { printf("FriendlyName = %S\r\n",fname); printf("Port Desc = %S\r\n",desc); } } else { if (pDetData != NULL) { delete [] (char*)pDetData; } if (hDevInfo != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(hDevInfo); } return FALSE; } } else { DWORD err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS) { if (pDetData != NULL) { delete [] (char*)pDetData; } if (hDevInfo != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(hDevInfo); } return FALSE; } } } if (pDetData != NULL) { delete [] (char*)pDetData; } if (hDevInfo != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(hDevInfo); } return TRUE; } int main(int argc,char* argv[]) { setlocale(LC_ALL,"chs"); EnumPortsWdm(); getchar(); return 0; }测试运行如下:
如上,为了printf函数可以打印出中文,这里调用了 setlocale(LC_ALL,"chs") 函数即可正常打印出中文。
相关文章推荐
- 设备管理器空白的解决办法
- 利用SetupAPI实现遍历设备管理器
- 模拟谷歌Android设备管理器的响铃功能
- Android : DevicePolicyManager
- virtualbox主机客户机共享物理串口
- (键盘)代码 19:由于其配置信息(注册表中的)不完整或已损坏,Windows 无法启动这个硬件设备 解决方法
- 别让设备管理器泄露你的秘密
- 设备管理器空白的解决方法
- 设备管理器空白的解决方法
- 修改Android设备在Windows设备管理器出现的设备名称
- Linux基础篇之udev:设备管理器
- Andorra设备管理漏洞解决方法
- 华硕笔记本nvidia显示设置不可用?
- Android 激活设备管理器后就无法再次打开设备管理器界面
- Android-利用设备管理器来实现锁屏功能并可一键自我卸载
- Linux基础篇之udev:设备管理器
- C++中的栈内存和堆内存的区别
- C语言测试 IP port 是否可达
- 结构struct
- C++正则表达式