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 #pragma comment (lib, "Setupapi.lib")
19 
20 using serial::PortInfo;
21 using std::vector;
22 using std::string;
23 
24 static const DWORD port_name_max_length = 256;
25 static const DWORD friendly_name_max_length = 256;
26 static const DWORD hardware_id_max_length = 256;
27 
28 // Convert a wide Unicode string to an UTF8 string
29 std::string utf8_encode(const std::wstring &wstr)
30 {
31  int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
32  std::string strTo(size_needed, 0);
33  WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
34  return strTo;
35 }
36 
37 vector<PortInfo>
39 {
40  vector<PortInfo> devices_found;
41 
42  HDEVINFO device_info_set = SetupDiGetClassDevs(
43  (const GUID *)&GUID_DEVCLASS_PORTS,
44  NULL,
45  NULL,
46  DIGCF_PRESENT);
47 
48  unsigned int device_info_set_index = 0;
49  SP_DEVINFO_DATA device_info_data;
50 
51  device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
52 
53  while (SetupDiEnumDeviceInfo(device_info_set, device_info_set_index, &device_info_data))
54  {
55  device_info_set_index++;
56 
57  // Get port name
58 
59  HKEY hkey = SetupDiOpenDevRegKey(
60  device_info_set,
61  &device_info_data,
62  DICS_FLAG_GLOBAL,
63  0,
64  DIREG_DEV,
65  KEY_READ);
66 
67  TCHAR port_name[port_name_max_length];
68  DWORD port_name_length = port_name_max_length;
69 
70  LONG return_code = RegQueryValueEx(
71  hkey,
72  _T("PortName"),
73  NULL,
74  NULL,
75  (LPBYTE)port_name,
76  &port_name_length);
77 
78  RegCloseKey(hkey);
79 
80  if (return_code != EXIT_SUCCESS)
81  continue;
82 
83  if (port_name_length > 0 && port_name_length <= port_name_max_length)
84  port_name[port_name_length - 1] = '\0';
85  else
86  port_name[0] = '\0';
87 
88  // Ignore parallel ports
89 
90  if (_tcsstr(port_name, _T("LPT")) != NULL)
91  continue;
92 
93  // Get port friendly name
94 
95  TCHAR friendly_name[friendly_name_max_length];
96  DWORD friendly_name_actual_length = 0;
97 
98  BOOL got_friendly_name = SetupDiGetDeviceRegistryProperty(
99  device_info_set,
100  &device_info_data,
101  SPDRP_FRIENDLYNAME,
102  NULL,
103  (PBYTE)friendly_name,
104  friendly_name_max_length,
105  &friendly_name_actual_length);
106 
107  if (got_friendly_name == TRUE && friendly_name_actual_length > 0)
108  friendly_name[friendly_name_actual_length - 1] = '\0';
109  else
110  friendly_name[0] = '\0';
111 
112  // Get hardware ID
113 
114  TCHAR hardware_id[hardware_id_max_length];
115  DWORD hardware_id_actual_length = 0;
116 
117  BOOL got_hardware_id = SetupDiGetDeviceRegistryProperty(
118  device_info_set,
119  &device_info_data,
120  SPDRP_HARDWAREID,
121  NULL,
122  (PBYTE)hardware_id,
123  hardware_id_max_length,
124  &hardware_id_actual_length);
125 
126  if (got_hardware_id == TRUE && hardware_id_actual_length > 0)
127  hardware_id[hardware_id_actual_length - 1] = '\0';
128  else
129  hardware_id[0] = '\0';
130 
131 #ifdef UNICODE
132  std::string portName = utf8_encode(port_name);
133  std::string friendlyName = utf8_encode(friendly_name);
134  std::string hardwareId = utf8_encode(hardware_id);
135 #else
136  std::string portName = port_name;
137  std::string friendlyName = friendly_name;
138  std::string hardwareId = hardware_id;
139 #endif
140 
141  PortInfo port_entry;
142  port_entry.port = portName;
143  port_entry.description = friendlyName;
144  port_entry.hardware_id = hardwareId;
145 
146  devices_found.push_back(port_entry);
147  }
148 
149  SetupDiDestroyDeviceInfoList(device_info_set);
150 
151  return devices_found;
152 }
153 
154 #endif // #if defined(_WIN32)
std::vector< PortInfo > list_ports()


xarm_api
Author(s):
autogenerated on Sat May 8 2021 02:51:23