urg_serial_utils_windows.c
Go to the documentation of this file.
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     // デバイスマネージャの一覧から COM デバイスを探す
00078 
00079     //4D36E978-E325-11CE-BFC1-08002BE10318
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         // フレンドリーネームを取得して COM 番号を取り出す
00112         SetupDiGetDeviceRegistryPropertyA(hdi, &sDevInfo, SPDRP_FRIENDLYNAME,
00113                                           &dwRegType, (BYTE*)buffer, BufferSize,
00114                                           &dwSize);
00115         n = (int)strlen(buffer);
00116         if (n < ComNameLengthMax) {
00117             // COM 名が短過ぎた場合、処理しない
00118             // 問題がある場合は、修正する
00119             continue;
00120         }
00121 
00122         // (COMx) の最後の括弧の位置に '\0' を代入する
00123         p = strrchr(buffer, ')');
00124         if (p) {
00125             *p = '\0';
00126         }
00127 
00128         // COM と番号までの文字列を抜き出す
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         // デバイス名を取得し、URG ポートかの判定に用いる
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     // is_urg_port の要素が先頭に来るようにソートする
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 }


urg_c
Author(s): Satofumi Kamimura , Katsumi Kimoto, Adrian Boeing
autogenerated on Wed Aug 26 2015 16:38:27