]> sigrok.org Git - libserialport.git/blobdiff - windows.c
Fix typos.
[libserialport.git] / windows.c
index 13be8f5827794a810285bd335ae7f387f189de19..523b8d0ac034ba0ebbb486df1c0b6b025ae817c4 100644 (file)
--- a/windows.c
+++ b/windows.c
@@ -1,6 +1,7 @@
 /*
  * This file is part of the libserialport project.
  *
+ * Copyright (C) 2013-2014 Martin Ling <martin-libserialport@earth.li>
  * Copyright (C) 2014 Aurelien Jacobs <aurel@gnuage.org>
  *
  * This program is free software: you can redistribute it and/or modify
@@ -252,7 +253,7 @@ static void enumerate_hub(struct sp_port *port, char *hub_name,
        /* get the number of ports of the hub */
        if (DeviceIoControl(hub_device, IOCTL_USB_GET_NODE_INFORMATION,
                            &hub_info, size, &hub_info, size, &size, NULL))
-               /* enumarate the ports of the hub */
+               /* enumerate the ports of the hub */
                enumerate_hub_ports(port, hub_device,
                   hub_info.u.HubInformation.HubDescriptor.bNumberOfPorts, parent_path);
 
@@ -330,7 +331,7 @@ static void get_usb_details(struct sp_port *port, DEVINST dev_inst_match)
        return;
 }
 
-enum sp_return get_port_details(struct sp_port *port)
+SP_PRIV enum sp_return get_port_details(struct sp_port *port)
 {
        /* Description limited to 127 char,
           anything longer would not be user friendly anyway */
@@ -358,8 +359,10 @@ enum sp_return get_port_details(struct sp_port *port)
                        continue;
                size = sizeof(value);
                if (RegQueryValueExA(device_key, "PortName", NULL, &type, (LPBYTE)value,
-                                    &size) != ERROR_SUCCESS || type != REG_SZ)
+                                    &size) != ERROR_SUCCESS || type != REG_SZ) {
+                       RegCloseKey(device_key);
                        continue;
+               }
                RegCloseKey(device_key);
                value[sizeof(value)-1] = 0;
                if (strcmp(value, port->name))
@@ -445,12 +448,90 @@ enum sp_return get_port_details(struct sp_port *port)
                        free(escaped_port_name);
                        CloseHandle(handle);
 
-                       /* retrive USB device details from the device descriptor */
+                       /* retrieve USB device details from the device descriptor */
                        get_usb_details(port, device_info_data.DevInst);
                }
                break;
        }
 
+       SetupDiDestroyDeviceInfoList(device_info);
+
        RETURN_OK();
 }
 
+SP_PRIV enum sp_return list_ports(struct sp_port ***list)
+{
+       HKEY key;
+       TCHAR *value, *data;
+       DWORD max_value_len, max_data_size, max_data_len;
+       DWORD value_len, data_size, data_len;
+       DWORD type, index = 0;
+       char *name;
+       int name_len;
+       int ret = SP_OK;
+
+       DEBUG("Opening registry key");
+       if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
+                       0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
+               SET_FAIL(ret, "RegOpenKeyEx() failed");
+               goto out_done;
+       }
+       DEBUG("Querying registry key value and data sizes");
+       if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) {
+               SET_FAIL(ret, "RegQueryInfoKey() failed");
+               goto out_close;
+       }
+       max_data_len = max_data_size / sizeof(TCHAR);
+       if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) {
+               SET_ERROR(ret, SP_ERR_MEM, "registry value malloc failed");
+               goto out_close;
+       }
+       if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) {
+               SET_ERROR(ret, SP_ERR_MEM, "registry data malloc failed");
+               goto out_free_value;
+       }
+       DEBUG("Iterating over values");
+       while (
+               value_len = max_value_len + 1,
+               data_size = max_data_size,
+               RegEnumValue(key, index, value, &value_len,
+                       NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS)
+       {
+               if (type == REG_SZ) {
+                       data_len = data_size / sizeof(TCHAR);
+                       data[data_len] = '\0';
+#ifdef UNICODE
+                       name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL);
+#else
+                       name_len = data_len + 1;
+#endif
+                       if (!(name = malloc(name_len))) {
+                               SET_ERROR(ret, SP_ERR_MEM, "registry port name malloc failed");
+                               goto out;
+                       }
+#ifdef UNICODE
+                       WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
+#else
+                       strcpy(name, data);
+#endif
+                       DEBUG_FMT("Found port %s", name);
+                       if (!(*list = list_append(*list, name))) {
+                               SET_ERROR(ret, SP_ERR_MEM, "list append failed");
+                               free(name);
+                               goto out;
+                       }
+                       free(name);
+               }
+               index++;
+       }
+out:
+       free(data);
+out_free_value:
+       free(value);
+out_close:
+       RegCloseKey(key);
+out_done:
+
+       return ret;
+}