summaryrefslogtreecommitdiff
path: root/deps/uv/src/win/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uv/src/win/util.c')
-rw-r--r--deps/uv/src/win/util.c174
1 files changed, 102 insertions, 72 deletions
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 96b1abe52d..8eedb495d4 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -31,6 +31,7 @@
#include "uv.h"
#include "internal.h"
+#include <Winsock2.h>
#include <iphlpapi.h>
#include <psapi.h>
#include <tlhelp32.h>
@@ -578,47 +579,50 @@ uv_err_t uv_uptime(double* uptime) {
}
-uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
+ uv_cpu_info_t* cpu_infos;
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
DWORD sppi_size;
SYSTEM_INFO system_info;
- DWORD cpu_count, i, r;
+ DWORD cpu_count, r, i;
+ NTSTATUS status;
ULONG result_size;
- size_t size;
uv_err_t err;
uv_cpu_info_t* cpu_info;
- *cpu_infos = NULL;
- *count = 0;
+ cpu_infos = NULL;
+ cpu_count = 0;
+ sppi = NULL;
uv__once_init();
GetSystemInfo(&system_info);
cpu_count = system_info.dwNumberOfProcessors;
- size = cpu_count * sizeof(uv_cpu_info_t);
- *cpu_infos = (uv_cpu_info_t*) malloc(size);
- if (*cpu_infos == NULL) {
+ cpu_infos = calloc(cpu_count, sizeof *cpu_infos);
+ if (cpu_infos == NULL) {
err = uv__new_artificial_error(UV_ENOMEM);
- goto out;
+ goto error;
}
- memset(*cpu_infos, 0, size);
- sppi_size = sizeof(*sppi) * cpu_count;
- sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) malloc(sppi_size);
- if (!sppi) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ sppi_size = cpu_count * sizeof(*sppi);
+ sppi = malloc(sppi_size);
+ if (sppi == NULL) {
+ err = uv__new_artificial_error(UV_ENOMEM);
+ goto error;
}
- r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
- sppi,
- sppi_size,
- &result_size);
- if (r != ERROR_SUCCESS || result_size != sppi_size) {
- err = uv__new_sys_error(GetLastError());
- goto out;
+ status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
+ sppi,
+ sppi_size,
+ &result_size);
+ if (!NT_SUCCESS(status)) {
+ err = uv__new_sys_error(pRtlNtStatusToDosError(status));
+ goto error;
}
+ assert(result_size == sppi_size);
+
for (i = 0; i < cpu_count; i++) {
WCHAR key_name[128];
HKEY processor_key;
@@ -626,11 +630,14 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
DWORD cpu_speed_size = sizeof(cpu_speed);
WCHAR cpu_brand[256];
DWORD cpu_brand_size = sizeof(cpu_brand);
+ int len;
+
+ len = _snwprintf(key_name,
+ ARRAY_SIZE(key_name),
+ L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
+ i);
- _snwprintf(key_name,
- ARRAY_SIZE(key_name),
- L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
- i);
+ assert(len > 0 && len < ARRAY_SIZE(key_name));
r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
key_name,
@@ -639,32 +646,34 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
&processor_key);
if (r != ERROR_SUCCESS) {
err = uv__new_sys_error(GetLastError());
- goto out;
+ goto error;
}
if (RegQueryValueExW(processor_key,
L"~MHz",
- NULL, NULL,
+ NULL,
+ NULL,
(BYTE*) &cpu_speed,
&cpu_speed_size) != ERROR_SUCCESS) {
err = uv__new_sys_error(GetLastError());
RegCloseKey(processor_key);
- goto out;
+ goto error;
}
if (RegQueryValueExW(processor_key,
L"ProcessorNameString",
- NULL, NULL,
+ NULL,
+ NULL,
(BYTE*) &cpu_brand,
&cpu_brand_size) != ERROR_SUCCESS) {
err = uv__new_sys_error(GetLastError());
RegCloseKey(processor_key);
- goto out;
+ goto error;
}
RegCloseKey(processor_key);
- cpu_info = &(*cpu_infos)[i];
+ cpu_info = &cpu_infos[i];
cpu_info->speed = cpu_speed;
cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
@@ -673,57 +682,59 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
cpu_info->cpu_times.nice = 0;
- size = uv_utf16_to_utf8(cpu_brand,
- cpu_brand_size / sizeof(WCHAR),
- NULL,
- 0);
- if (size == 0) {
+
+ len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ cpu_brand,
+ cpu_brand_size / sizeof(WCHAR),
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ if (len == 0) {
err = uv__new_sys_error(GetLastError());
- goto out;
+ goto error;
}
+ assert(len > 0);
+
/* Allocate 1 extra byte for the null terminator. */
- cpu_info->model = (char*) malloc(size + 1);
+ cpu_info->model = malloc(len + 1);
if (cpu_info->model == NULL) {
err = uv__new_artificial_error(UV_ENOMEM);
- goto out;
+ goto error;
}
- if (uv_utf16_to_utf8(cpu_brand,
- cpu_brand_size / sizeof(WCHAR),
- cpu_info->model,
- size) == 0) {
+ if (WideCharToMultiByte(CP_UTF8,
+ 0,
+ cpu_brand,
+ cpu_brand_size / sizeof(WCHAR),
+ cpu_info->model,
+ len,
+ NULL,
+ NULL) == 0) {
err = uv__new_sys_error(GetLastError());
- goto out;
+ goto error;
}
/* Ensure that cpu_info->model is null terminated. */
- cpu_info->model[size] = '\0';
-
- (*count)++;
+ cpu_info->model[len] = '\0';
}
- err = uv_ok_;
+ free(sppi);
- out:
- if (sppi) {
- free(sppi);
- }
+ *cpu_count_ptr = cpu_count;
+ *cpu_infos_ptr = cpu_infos;
- if (err.code != UV_OK &&
- *cpu_infos != NULL) {
- int i;
+ return uv_ok_;
- for (i = 0; i < *count; i++) {
- /* This is safe because the cpu_infos memory area is zeroed out */
- /* immediately after allocating it. */
- free((*cpu_infos)[i].model);
- }
- free(*cpu_infos);
+ error:
+ /* This is safe because the cpu_infos array is zeroed on allocation. */
+ for (i = 0; i < cpu_count; i++)
+ free(cpu_infos[i].model);
- *cpu_infos = NULL;
- *count = 0;
- }
+ free(cpu_infos);
+ free(sppi);
return err;
}
@@ -765,7 +776,7 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses_ptr,
/* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */
/* win_address_buf_size. */
r = GetAdaptersAddresses(AF_UNSPEC,
- 0,
+ GAA_FLAG_INCLUDE_PREFIX,
NULL,
win_address_buf,
&win_address_buf_size);
@@ -882,6 +893,7 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses_ptr,
win_address != NULL;
win_address = win_address->Next) {
IP_ADAPTER_UNICAST_ADDRESS_XP* unicast_address;
+ IP_ADAPTER_PREFIX* prefix;
int name_size;
size_t max_name_size;
@@ -907,23 +919,41 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses_ptr,
return uv__new_sys_error(GetLastError());
}
+ prefix = win_address->FirstPrefix;
+
/* Add an uv_interface_address_t element for every unicast address. */
+ /* Walk the prefix list in tandem with the address list. */
for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS_XP*)
win_address->FirstUnicastAddress;
- unicast_address != NULL;
- unicast_address = unicast_address->Next) {
+ unicast_address != NULL && prefix != NULL;
+ unicast_address = unicast_address->Next, prefix = prefix->Next) {
struct sockaddr* sa;
+ ULONG prefix_len;
+
+ sa = unicast_address->Address.lpSockaddr;
+ prefix_len = prefix->PrefixLength;
+
+ memset(uv_address, 0, sizeof *uv_address);
uv_address->name = name_buf;
+ uv_address->is_internal =
+ (win_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
- sa = unicast_address->Address.lpSockaddr;
- if (sa->sa_family == AF_INET6)
+ if (sa->sa_family == AF_INET6) {
uv_address->address.address6 = *((struct sockaddr_in6 *) sa);
- else
+
+ uv_address->netmask.netmask6.sin6_family = AF_INET6;
+ memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3);
+ uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] =
+ 0xff << (8 - prefix_len % 8);
+
+ } else {
uv_address->address.address4 = *((struct sockaddr_in *) sa);
- uv_address->is_internal =
- (win_address->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
+ uv_address->netmask.netmask4.sin_family = AF_INET;
+ uv_address->netmask.netmask4.sin_addr.s_addr =
+ htonl(0xffffffff << (32 - prefix_len));
+ }
uv_address++;
}