00001
00013 #include "urg_c/urg_serial_utils.h"
00014 #include "urg_c/urg_detect_os.h"
00015 #include <windows.h>
00016 #include <setupapi.h>
00017 #include <string.h>
00018 #include <stdio.h>
00019
00020
00021 #if defined(URG_MSC)
00022 #define snprintf _snprintf
00023 #endif
00024
00025
00026 enum {
00027 MAX_PORTS = 16,
00028 DEVICE_NAME_SIZE = 7,
00029 };
00030
00031
00032 static char found_ports[MAX_PORTS][DEVICE_NAME_SIZE];
00033 static int is_urg_ports[MAX_PORTS];
00034 static int found_ports_size = 0;
00035
00036 static char *search_driver_names[] = {
00037 "URG Series USB Device Driver",
00038 "URG-X002 USB Device Driver",
00039 };
00040
00041
00042 static void swap_item(int from_index, int to_index)
00043 {
00044 char buffer[DEVICE_NAME_SIZE];
00045 int is_urg_port;
00046
00047 if (from_index == to_index) {
00048 return;
00049 }
00050
00051 strncpy(buffer, found_ports[to_index], DEVICE_NAME_SIZE);
00052 strncpy(found_ports[to_index], found_ports[from_index], DEVICE_NAME_SIZE);
00053 strncpy(found_ports[from_index], buffer, DEVICE_NAME_SIZE);
00054
00055 is_urg_port = is_urg_ports[to_index];
00056 is_urg_ports[to_index] = is_urg_ports[from_index];
00057 is_urg_ports[from_index] = is_urg_port;
00058 }
00059
00060
00061 static void sort_ports(void)
00062 {
00063 int last_index = 0;
00064 int i;
00065
00066 for (i = 0; i < found_ports_size; ++i) {
00067 if ((is_urg_ports[i] == 1) && (last_index < i)) {
00068 swap_item(i, last_index);
00069 last_index = i + 1;
00070 }
00071 }
00072 }
00073
00074
00075 int urg_serial_find_port(void)
00076 {
00077
00078
00079
00080 GUID GUID_DEVINTERFACE_COM_DEVICE = {
00081 0x4D36E978L, 0xE325, 0x11CE,
00082 {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 }
00083 };
00084
00085 HDEVINFO hdi;
00086 SP_DEVINFO_DATA sDevInfo;
00087 int i;
00088
00089 found_ports_size = 0;
00090 hdi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_COM_DEVICE, 0, 0,
00091 DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
00092 if (hdi == INVALID_HANDLE_VALUE) {
00093 return 0;
00094 }
00095
00096 sDevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
00097 for (i = 0; SetupDiEnumDeviceInfo(hdi, i, &sDevInfo); ++i){
00098
00099 enum {
00100 BufferSize = 256,
00101 ComNameLengthMax = 7,
00102 };
00103 char buffer[BufferSize + 1];
00104 DWORD dwRegType;
00105 DWORD dwSize;
00106 int is_urg_port;
00107 char *p;
00108 int n;
00109 int j;
00110
00111
00112 SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_FRIENDLYNAME,
00113 &dwRegType, (BYTE*)buffer, BufferSize,
00114 &dwSize);
00115 n = (int)strlen(buffer);
00116 if (n < ComNameLengthMax) {
00117
00118
00119 continue;
00120 }
00121
00122
00123 p = strrchr(buffer, ')');
00124 if (p) {
00125 *p = '\0';
00126 }
00127
00128
00129 p = strstr(&buffer[n - ComNameLengthMax], "COM");
00130 if (! p) {
00131 continue;
00132 }
00133
00134 snprintf(found_ports[found_ports_size], DEVICE_NAME_SIZE, "%s", p);
00135
00136
00137 SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_DEVICEDESC,
00138 &dwRegType, (BYTE*)buffer, BufferSize,
00139 &dwSize);
00140 is_urg_port = 0;
00141 n = sizeof(search_driver_names) / sizeof(search_driver_names[0]);
00142 for (j = 0; j < n; ++j) {
00143 if (! strcmp(search_driver_names[j], buffer)) {
00144 is_urg_port = 1;
00145 break;
00146 }
00147 }
00148 is_urg_ports[found_ports_size] = is_urg_port;
00149 ++found_ports_size;
00150 }
00151 SetupDiDestroyDeviceInfoList(hdi);
00152
00153
00154 sort_ports();
00155
00156 return found_ports_size;
00157 }
00158
00159
00160 const char *urg_serial_port_name(int index)
00161 {
00162 if ((index < 0) || (index >= found_ports_size)) {
00163 return "";
00164 } else {
00165 return found_ports[index];
00166 }
00167 }
00168
00169
00170 int urg_serial_is_urg_port(int index)
00171 {
00172 if ((index < 0) || (index >= found_ports_size)) {
00173 return -1;
00174 } else {
00175 return is_urg_ports[index];
00176 }
00177 }