Go to the documentation of this file.00001 #if defined(_WIN32)
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "serial/serial.h"
00011 #include <tchar.h>
00012 #include <windows.h>
00013 #include <setupapi.h>
00014 #include <initguid.h>
00015 #include <devguid.h>
00016 #include <cstring>
00017
00018 using serial::PortInfo;
00019 using std::vector;
00020 using std::string;
00021
00022 static const DWORD port_name_max_length = 256;
00023 static const DWORD friendly_name_max_length = 256;
00024 static const DWORD hardware_id_max_length = 256;
00025
00026
00027 std::string utf8_encode(const std::wstring &wstr)
00028 {
00029 int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
00030 std::string strTo( size_needed, 0 );
00031 WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
00032 return strTo;
00033 }
00034
00035 vector<PortInfo>
00036 serial::list_ports()
00037 {
00038 vector<PortInfo> devices_found;
00039
00040 HDEVINFO device_info_set = SetupDiGetClassDevs(
00041 (const GUID *) &GUID_DEVCLASS_PORTS,
00042 NULL,
00043 NULL,
00044 DIGCF_PRESENT);
00045
00046 unsigned int device_info_set_index = 0;
00047 SP_DEVINFO_DATA device_info_data;
00048
00049 device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
00050
00051 while(SetupDiEnumDeviceInfo(device_info_set, device_info_set_index, &device_info_data))
00052 {
00053 device_info_set_index++;
00054
00055
00056
00057 HKEY hkey = SetupDiOpenDevRegKey(
00058 device_info_set,
00059 &device_info_data,
00060 DICS_FLAG_GLOBAL,
00061 0,
00062 DIREG_DEV,
00063 KEY_READ);
00064
00065 TCHAR port_name[port_name_max_length];
00066 DWORD port_name_length = port_name_max_length;
00067
00068 LONG return_code = RegQueryValueEx(
00069 hkey,
00070 _T("PortName"),
00071 NULL,
00072 NULL,
00073 (LPBYTE)port_name,
00074 &port_name_length);
00075
00076 RegCloseKey(hkey);
00077
00078 if(return_code != EXIT_SUCCESS)
00079 continue;
00080
00081 if(port_name_length > 0 && port_name_length <= port_name_max_length)
00082 port_name[port_name_length-1] = '\0';
00083 else
00084 port_name[0] = '\0';
00085
00086
00087
00088 if(_tcsstr(port_name, _T("LPT")) != NULL)
00089 continue;
00090
00091
00092
00093 TCHAR friendly_name[friendly_name_max_length];
00094 DWORD friendly_name_actual_length = 0;
00095
00096 BOOL got_friendly_name = SetupDiGetDeviceRegistryProperty(
00097 device_info_set,
00098 &device_info_data,
00099 SPDRP_FRIENDLYNAME,
00100 NULL,
00101 (PBYTE)friendly_name,
00102 friendly_name_max_length,
00103 &friendly_name_actual_length);
00104
00105 if(got_friendly_name == TRUE && friendly_name_actual_length > 0)
00106 friendly_name[friendly_name_actual_length-1] = '\0';
00107 else
00108 friendly_name[0] = '\0';
00109
00110
00111
00112 TCHAR hardware_id[hardware_id_max_length];
00113 DWORD hardware_id_actual_length = 0;
00114
00115 BOOL got_hardware_id = SetupDiGetDeviceRegistryProperty(
00116 device_info_set,
00117 &device_info_data,
00118 SPDRP_HARDWAREID,
00119 NULL,
00120 (PBYTE)hardware_id,
00121 hardware_id_max_length,
00122 &hardware_id_actual_length);
00123
00124 if(got_hardware_id == TRUE && hardware_id_actual_length > 0)
00125 hardware_id[hardware_id_actual_length-1] = '\0';
00126 else
00127 hardware_id[0] = '\0';
00128
00129 #ifdef UNICODE
00130 std::string portName = utf8_encode(port_name);
00131 std::string friendlyName = utf8_encode(friendly_name);
00132 std::string hardwareId = utf8_encode(hardware_id);
00133 #else
00134 std::string portName = port_name;
00135 std::string friendlyName = friendly_name;
00136 std::string hardwareId = hardware_id;
00137 #endif
00138
00139 PortInfo port_entry;
00140 port_entry.port = portName;
00141 port_entry.description = friendlyName;
00142 port_entry.hardware_id = hardwareId;
00143
00144 devices_found.push_back(port_entry);
00145 }
00146
00147 SetupDiDestroyDeviceInfoList(device_info_set);
00148
00149 return devices_found;
00150 }
00151
00152 #endif // #if defined(_WIN32)