diff options
Diffstat (limited to 'deps/uv/src/win/util.c')
-rw-r--r-- | deps/uv/src/win/util.c | 174 |
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++; } |