list_ports_win.cc
Go to the documentation of this file.
1 #if defined(_WIN32)
2 
3 /*
4  * Copyright (c) 2014 Craig Lilley <cralilley@gmail.com>
5  * This software is made available under the terms of the MIT licence.
6  * A copy of the licence can be obtained from:
7  * http://opensource.org/licenses/MIT
8  */
9 
10 #include "serial/serial.h"
11 #include <tchar.h>
12 #include <windows.h>
13 #include <setupapi.h>
14 #include <initguid.h>
15 #include <devguid.h>
16 #include <cstring>
17 
18 using serial::PortInfo;
19 using std::vector;
20 using std::string;
21 
22 static const DWORD port_name_max_length = 256;
23 static const DWORD friendly_name_max_length = 256;
24 static const DWORD hardware_id_max_length = 256;
25 
26 // Convert a wide Unicode string to an UTF8 string
27 std::string utf8_encode(const std::wstring &wstr)
28 {
29  int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
30  std::string strTo( size_needed, 0 );
31  WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
32  return strTo;
33 }
34 
35 vector<PortInfo>
37 {
38  vector<PortInfo> devices_found;
39 
40  HDEVINFO device_info_set = SetupDiGetClassDevs(
41  (const GUID *) &GUID_DEVCLASS_PORTS,
42  NULL,
43  NULL,
44  DIGCF_PRESENT);
45 
46  unsigned int device_info_set_index = 0;
47  SP_DEVINFO_DATA device_info_data;
48 
49  device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
50 
51  while(SetupDiEnumDeviceInfo(device_info_set, device_info_set_index, &device_info_data))
52  {
53  device_info_set_index++;
54 
55  // Get port name
56 
57  HKEY hkey = SetupDiOpenDevRegKey(
58  device_info_set,
59  &device_info_data,
60  DICS_FLAG_GLOBAL,
61  0,
62  DIREG_DEV,
63  KEY_READ);
64 
65  TCHAR port_name[port_name_max_length];
66  DWORD port_name_length = port_name_max_length;
67 
68  LONG return_code = RegQueryValueEx(
69  hkey,
70  _T("PortName"),
71  NULL,
72  NULL,
73  (LPBYTE)port_name,
74  &port_name_length);
75 
76  RegCloseKey(hkey);
77 
78  if(return_code != EXIT_SUCCESS)
79  continue;
80 
81  if(port_name_length > 0 && port_name_length <= port_name_max_length)
82  port_name[port_name_length-1] = '\0';
83  else
84  port_name[0] = '\0';
85 
86  // Ignore parallel ports
87 
88  if(_tcsstr(port_name, _T("LPT")) != NULL)
89  continue;
90 
91  // Get port friendly name
92 
93  TCHAR friendly_name[friendly_name_max_length];
94  DWORD friendly_name_actual_length = 0;
95 
96  BOOL got_friendly_name = SetupDiGetDeviceRegistryProperty(
97  device_info_set,
98  &device_info_data,
99  SPDRP_FRIENDLYNAME,
100  NULL,
101  (PBYTE)friendly_name,
102  friendly_name_max_length,
103  &friendly_name_actual_length);
104 
105  if(got_friendly_name == TRUE && friendly_name_actual_length > 0)
106  friendly_name[friendly_name_actual_length-1] = '\0';
107  else
108  friendly_name[0] = '\0';
109 
110  // Get hardware ID
111 
112  TCHAR hardware_id[hardware_id_max_length];
113  DWORD hardware_id_actual_length = 0;
114 
115  BOOL got_hardware_id = SetupDiGetDeviceRegistryProperty(
116  device_info_set,
117  &device_info_data,
118  SPDRP_HARDWAREID,
119  NULL,
120  (PBYTE)hardware_id,
121  hardware_id_max_length,
122  &hardware_id_actual_length);
123 
124  if(got_hardware_id == TRUE && hardware_id_actual_length > 0)
125  hardware_id[hardware_id_actual_length-1] = '\0';
126  else
127  hardware_id[0] = '\0';
128 
129  #ifdef UNICODE
130  std::string portName = utf8_encode(port_name);
131  std::string friendlyName = utf8_encode(friendly_name);
132  std::string hardwareId = utf8_encode(hardware_id);
133  #else
134  std::string portName = port_name;
135  std::string friendlyName = friendly_name;
136  std::string hardwareId = hardware_id;
137  #endif
138 
139  PortInfo port_entry;
140  port_entry.port = portName;
141  port_entry.description = friendlyName;
142  port_entry.hardware_id = hardwareId;
143 
144  devices_found.push_back(port_entry);
145  }
146 
147  SetupDiDestroyDeviceInfoList(device_info_set);
148 
149  return devices_found;
150 }
151 
152 #endif // #if defined(_WIN32)
std::vector< PortInfo > list_ports()


serial
Author(s): William Woodall , John Harrison
autogenerated on Thu Jan 9 2020 07:18:58