urg_serial_utils_windows.c
Go to the documentation of this file.
1 
13 #include "urg_c/urg_serial_utils.h"
14 #include "urg_c/urg_detect_os.h"
15 #include <windows.h>
16 #include <setupapi.h>
17 #include <string.h>
18 #include <stdio.h>
19 
20 
21 #if defined(URG_MSC)
22 #define snprintf _snprintf
23 #endif
24 
25 
26 enum {
27  MAX_PORTS = 16,
29 };
30 
31 
33 static int is_urg_ports[MAX_PORTS];
34 static int found_ports_size = 0;
35 
36 static char *search_driver_names[] = {
37  "URG Series USB Device Driver",
38  "URG-X002 USB Device Driver",
39 };
40 
41 
42 static void swap_item(int from_index, int to_index)
43 {
44  char buffer[DEVICE_NAME_SIZE];
45  int is_urg_port;
46 
47  if (from_index == to_index) {
48  return;
49  }
50 
51  strncpy(buffer, found_ports[to_index], DEVICE_NAME_SIZE);
52  strncpy(found_ports[to_index], found_ports[from_index], DEVICE_NAME_SIZE);
53  strncpy(found_ports[from_index], buffer, DEVICE_NAME_SIZE);
54 
55  is_urg_port = is_urg_ports[to_index];
56  is_urg_ports[to_index] = is_urg_ports[from_index];
57  is_urg_ports[from_index] = is_urg_port;
58 }
59 
60 
61 static void sort_ports(void)
62 {
63  int last_index = 0;
64  int i;
65 
66  for (i = 0; i < found_ports_size; ++i) {
67  if ((is_urg_ports[i] == 1) && (last_index < i)) {
68  swap_item(i, last_index);
69  last_index = i + 1;
70  }
71  }
72 }
73 
74 
76 {
77  // デバイスマネージャの一覧から COM デバイスを探す
78 
79  //4D36E978-E325-11CE-BFC1-08002BE10318
80  GUID GUID_DEVINTERFACE_COM_DEVICE = {
81  0x4D36E978L, 0xE325, 0x11CE,
82  {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 }
83  };
84 
85  HDEVINFO hdi;
86  SP_DEVINFO_DATA sDevInfo;
87  int i;
88 
89  found_ports_size = 0;
90  hdi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COM_DEVICE, 0, 0,
91  DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
92  if (hdi == INVALID_HANDLE_VALUE) {
93  return 0;
94  }
95 
96  sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
97  for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &sDevInfo); ++i){
98 
99  enum {
100  BufferSize = 256,
101  ComNameLengthMax = 7,
102  };
103  char buffer[BufferSize + 1];
104  DWORD dwRegType;
105  DWORD dwSize;
106  int is_urg_port;
107  char *p;
108  int n;
109  int j;
110 
111  // フレンドリーネームを取得して COM 番号を取り出す
112  SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_FRIENDLYNAME,
113  &dwRegType, (BYTE*)buffer, BufferSize,
114  &dwSize);
115  n = (int)strlen(buffer);
116  if (n < ComNameLengthMax) {
117  // COM 名が短過ぎた場合、処理しない
118  // 問題がある場合は、修正する continue; } // (COMx) の最後の括弧の位置に '\0' を代入する p = strrchr(buffer, ')'); if (p) { *p = '\0'; } // COM と番号までの文字列を抜き出す p = strstr(&buffer[n - ComNameLengthMax], "COM"); if (! p) { continue; } snprintf(found_ports[found_ports_size], DEVICE_NAME_SIZE, "%s", p); // デバイス名を取得し、URG ポートかの判定に用いる SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_DEVICEDESC, &dwRegType, (BYTE*)buffer, BufferSize, &dwSize); is_urg_port = 0; n = sizeof(search_driver_names) / sizeof(search_driver_names[0]); for (j = 0; j < n; ++j) { if (! strcmp(search_driver_names[j], buffer)) { is_urg_port = 1; break; } } is_urg_ports[found_ports_size] = is_urg_port; ++found_ports_size; } SetupDiDestroyDeviceInfoList(hdi); // is_urg_port の要素が先頭に来るようにソートする sort_ports(); return found_ports_size; } const char *urg_serial_port_name(int index) { if ((index < 0) || (index >= found_ports_size)) { return ""; } else { return found_ports[index]; } } int urg_serial_is_urg_port(int index) { if ((index < 0) || (index >= found_ports_size)) { return -1; } else { return is_urg_ports[index]; } }
119  continue;
120  }
121 
122  // (COMx) の最後の括弧の位置に '\0' を代入する p = strrchr(buffer, ')'); if (p) { *p = '\0'; } // COM と番号までの文字列を抜き出す p = strstr(&buffer[n - ComNameLengthMax], "COM"); if (! p) { continue; } snprintf(found_ports[found_ports_size], DEVICE_NAME_SIZE, "%s", p); // デバイス名を取得し、URG ポートかの判定に用いる SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_DEVICEDESC, &dwRegType, (BYTE*)buffer, BufferSize, &dwSize); is_urg_port = 0; n = sizeof(search_driver_names) / sizeof(search_driver_names[0]); for (j = 0; j < n; ++j) { if (! strcmp(search_driver_names[j], buffer)) { is_urg_port = 1; break; } } is_urg_ports[found_ports_size] = is_urg_port; ++found_ports_size; } SetupDiDestroyDeviceInfoList(hdi); // is_urg_port の要素が先頭に来るようにソートする sort_ports(); return found_ports_size; } const char *urg_serial_port_name(int index) { if ((index < 0) || (index >= found_ports_size)) { return ""; } else { return found_ports[index]; } } int urg_serial_is_urg_port(int index) { if ((index < 0) || (index >= found_ports_size)) { return -1; } else { return is_urg_ports[index]; } }
123  p = strrchr(buffer, ')');
124  if (p) {
125  *p = '\0';
126  }
127 
128  // COM と番号までの文字列を抜き出す
129  p = strstr(&buffer[n - ComNameLengthMax], "COM");
130  if (! p) {
131  continue;
132  }
133 
134  snprintf(found_ports[found_ports_size], DEVICE_NAME_SIZE, "%s", p);
135 
136  // デバイス名を取得し、URG ポートかの判定に用いる SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_DEVICEDESC, &dwRegType, (BYTE*)buffer, BufferSize, &dwSize); is_urg_port = 0; n = sizeof(search_driver_names) / sizeof(search_driver_names[0]); for (j = 0; j < n; ++j) { if (! strcmp(search_driver_names[j], buffer)) { is_urg_port = 1; break; } } is_urg_ports[found_ports_size] = is_urg_port; ++found_ports_size; } SetupDiDestroyDeviceInfoList(hdi); // is_urg_port の要素が先頭に来るようにソートする sort_ports(); return found_ports_size; } const char *urg_serial_port_name(int index) { if ((index < 0) || (index >= found_ports_size)) { return ""; } else { return found_ports[index]; } } int urg_serial_is_urg_port(int index) { if ((index < 0) || (index >= found_ports_size)) { return -1; } else { return is_urg_ports[index]; } }
137  SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_DEVICEDESC,
138  &dwRegType, (BYTE*)buffer, BufferSize,
139  &dwSize);
140  is_urg_port = 0;
141  n = sizeof(search_driver_names) / sizeof(search_driver_names[0]);
142  for (j = 0; j < n; ++j) {
143  if (! strcmp(search_driver_names[j], buffer)) {
144  is_urg_port = 1;
145  break;
146  }
147  }
148  is_urg_ports[found_ports_size] = is_urg_port;
150  }
151  SetupDiDestroyDeviceInfoList(hdi);
152 
153  // is_urg_port の要素が先頭に来るようにソートする sort_ports(); return found_ports_size; } const char *urg_serial_port_name(int index) { if ((index < 0) || (index >= found_ports_size)) { return ""; } else { return found_ports[index]; } } int urg_serial_is_urg_port(int index) { if ((index < 0) || (index >= found_ports_size)) { return -1; } else { return is_urg_ports[index]; } }
154  sort_ports();
155 
156  return found_ports_size;
157 }
158 
159 
160 const char *urg_serial_port_name(int index)
161 {
162  if ((index < 0) || (index >= found_ports_size)) {
163  return "";
164  } else {
165  return found_ports[index];
166  }
167 }
168 
169 
171 {
172  if ((index < 0) || (index >= found_ports_size)) {
173  return -1;
174  } else {
175  return is_urg_ports[index];
176  }
177 }
static void sort_ports(void)
シリアル用の補助関数
OS の検出.
static char * search_driver_names[]
const char * urg_serial_port_name(int index)
検索したシリアルポート名を返す
int urg_serial_is_urg_port(int index)
ポートが URG かどうか
static void swap_item(int from_index, int to_index)
static int found_ports_size
int urg_serial_find_port(void)
シリアルポートを検索する
static int is_urg_ports[MAX_PORTS]
static char found_ports[MAX_PORTS][DEVICE_NAME_SIZE]


urg_c
Author(s): Satofumi Kamimura , Katsumi Kimoto, Adrian Boeing
autogenerated on Thu Jun 6 2019 19:27:49