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