list_ports_win.cc
Go to the documentation of this file.
00001 #if defined(_WIN32)
00002 
00003 /*
00004  * Copyright (c) 2014 Craig Lilley <cralilley@gmail.com>
00005  * This software is made available under the terms of the MIT licence.
00006  * A copy of the licence can be obtained from:
00007  * http://opensource.org/licenses/MIT
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 // Convert a wide Unicode string to an UTF8 string
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                 // Get port name
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                 // Ignore parallel ports
00086 
00087                 if(_tcsstr(port_name, _T("LPT")) != NULL)
00088                         continue;
00089 
00090                 // Get port friendly name
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                 // Get hardware ID
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)


serial
Author(s): William Woodall , John Harrison
autogenerated on Mon Oct 6 2014 07:34:37