1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * 3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 9e66f31c5Sopenharmony_ci * 10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 12e66f31c5Sopenharmony_ci * 13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 20e66f31c5Sopenharmony_ci */ 21e66f31c5Sopenharmony_ci 22e66f31c5Sopenharmony_ci#include <assert.h> 23e66f31c5Sopenharmony_ci#include <direct.h> 24e66f31c5Sopenharmony_ci#include <limits.h> 25e66f31c5Sopenharmony_ci#include <stdio.h> 26e66f31c5Sopenharmony_ci#include <string.h> 27e66f31c5Sopenharmony_ci#include <time.h> 28e66f31c5Sopenharmony_ci#include <wchar.h> 29e66f31c5Sopenharmony_ci 30e66f31c5Sopenharmony_ci#include "uv.h" 31e66f31c5Sopenharmony_ci#include "internal.h" 32e66f31c5Sopenharmony_ci 33e66f31c5Sopenharmony_ci/* clang-format off */ 34e66f31c5Sopenharmony_ci#include <sysinfoapi.h> 35e66f31c5Sopenharmony_ci#include <winsock2.h> 36e66f31c5Sopenharmony_ci#include <winperf.h> 37e66f31c5Sopenharmony_ci#include <iphlpapi.h> 38e66f31c5Sopenharmony_ci#include <psapi.h> 39e66f31c5Sopenharmony_ci#include <tlhelp32.h> 40e66f31c5Sopenharmony_ci#include <windows.h> 41e66f31c5Sopenharmony_ci/* clang-format on */ 42e66f31c5Sopenharmony_ci#include <userenv.h> 43e66f31c5Sopenharmony_ci#include <math.h> 44e66f31c5Sopenharmony_ci 45e66f31c5Sopenharmony_ci/* 46e66f31c5Sopenharmony_ci * Max title length; the only thing MSDN tells us about the maximum length 47e66f31c5Sopenharmony_ci * of the console title is that it is smaller than 64K. However in practice 48e66f31c5Sopenharmony_ci * it is much smaller, and there is no way to figure out what the exact length 49e66f31c5Sopenharmony_ci * of the title is or can be, at least not on XP. To make it even more 50e66f31c5Sopenharmony_ci * annoying, GetConsoleTitle fails when the buffer to be read into is bigger 51e66f31c5Sopenharmony_ci * than the actual maximum length. So we make a conservative guess here; 52e66f31c5Sopenharmony_ci * just don't put the novel you're writing in the title, unless the plot 53e66f31c5Sopenharmony_ci * survives truncation. 54e66f31c5Sopenharmony_ci */ 55e66f31c5Sopenharmony_ci#define MAX_TITLE_LENGTH 8192 56e66f31c5Sopenharmony_ci 57e66f31c5Sopenharmony_ci/* The number of nanoseconds in one second. */ 58e66f31c5Sopenharmony_ci#define UV__NANOSEC 1000000000 59e66f31c5Sopenharmony_ci 60e66f31c5Sopenharmony_ci/* Max user name length, from iphlpapi.h */ 61e66f31c5Sopenharmony_ci#ifndef UNLEN 62e66f31c5Sopenharmony_ci# define UNLEN 256 63e66f31c5Sopenharmony_ci#endif 64e66f31c5Sopenharmony_ci 65e66f31c5Sopenharmony_ci 66e66f31c5Sopenharmony_ci/* A RtlGenRandom() by any other name... */ 67e66f31c5Sopenharmony_ciextern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength); 68e66f31c5Sopenharmony_ci 69e66f31c5Sopenharmony_ci/* Cached copy of the process title, plus a mutex guarding it. */ 70e66f31c5Sopenharmony_cistatic char *process_title; 71e66f31c5Sopenharmony_cistatic CRITICAL_SECTION process_title_lock; 72e66f31c5Sopenharmony_ci 73e66f31c5Sopenharmony_ci/* Frequency of the high-resolution clock. */ 74e66f31c5Sopenharmony_cistatic uint64_t hrtime_frequency_ = 0; 75e66f31c5Sopenharmony_ci 76e66f31c5Sopenharmony_ci 77e66f31c5Sopenharmony_ci/* 78e66f31c5Sopenharmony_ci * One-time initialization code for functionality defined in util.c. 79e66f31c5Sopenharmony_ci */ 80e66f31c5Sopenharmony_civoid uv__util_init(void) { 81e66f31c5Sopenharmony_ci LARGE_INTEGER perf_frequency; 82e66f31c5Sopenharmony_ci 83e66f31c5Sopenharmony_ci /* Initialize process title access mutex. */ 84e66f31c5Sopenharmony_ci InitializeCriticalSection(&process_title_lock); 85e66f31c5Sopenharmony_ci 86e66f31c5Sopenharmony_ci /* Retrieve high-resolution timer frequency 87e66f31c5Sopenharmony_ci * and precompute its reciprocal. 88e66f31c5Sopenharmony_ci */ 89e66f31c5Sopenharmony_ci if (QueryPerformanceFrequency(&perf_frequency)) { 90e66f31c5Sopenharmony_ci hrtime_frequency_ = perf_frequency.QuadPart; 91e66f31c5Sopenharmony_ci } else { 92e66f31c5Sopenharmony_ci uv_fatal_error(GetLastError(), "QueryPerformanceFrequency"); 93e66f31c5Sopenharmony_ci } 94e66f31c5Sopenharmony_ci} 95e66f31c5Sopenharmony_ci 96e66f31c5Sopenharmony_ci 97e66f31c5Sopenharmony_ciint uv_exepath(char* buffer, size_t* size_ptr) { 98e66f31c5Sopenharmony_ci size_t utf8_len, utf16_buffer_len, utf16_len; 99e66f31c5Sopenharmony_ci WCHAR* utf16_buffer; 100e66f31c5Sopenharmony_ci int err; 101e66f31c5Sopenharmony_ci 102e66f31c5Sopenharmony_ci if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) { 103e66f31c5Sopenharmony_ci return UV_EINVAL; 104e66f31c5Sopenharmony_ci } 105e66f31c5Sopenharmony_ci 106e66f31c5Sopenharmony_ci if (*size_ptr > 32768) { 107e66f31c5Sopenharmony_ci /* Windows paths can never be longer than this. */ 108e66f31c5Sopenharmony_ci utf16_buffer_len = 32768; 109e66f31c5Sopenharmony_ci } else { 110e66f31c5Sopenharmony_ci utf16_buffer_len = (int) *size_ptr; 111e66f31c5Sopenharmony_ci } 112e66f31c5Sopenharmony_ci 113e66f31c5Sopenharmony_ci utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len); 114e66f31c5Sopenharmony_ci if (!utf16_buffer) { 115e66f31c5Sopenharmony_ci return UV_ENOMEM; 116e66f31c5Sopenharmony_ci } 117e66f31c5Sopenharmony_ci 118e66f31c5Sopenharmony_ci /* Get the path as UTF-16. */ 119e66f31c5Sopenharmony_ci utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len); 120e66f31c5Sopenharmony_ci if (utf16_len <= 0) { 121e66f31c5Sopenharmony_ci err = GetLastError(); 122e66f31c5Sopenharmony_ci goto error; 123e66f31c5Sopenharmony_ci } 124e66f31c5Sopenharmony_ci 125e66f31c5Sopenharmony_ci /* Convert to UTF-8 */ 126e66f31c5Sopenharmony_ci utf8_len = *size_ptr - 1; /* Reserve space for NUL */ 127e66f31c5Sopenharmony_ci err = uv_utf16_to_wtf8(utf16_buffer, utf16_len, &buffer, &utf8_len); 128e66f31c5Sopenharmony_ci if (err == UV_ENOBUFS) { 129e66f31c5Sopenharmony_ci utf8_len = *size_ptr - 1; 130e66f31c5Sopenharmony_ci err = 0; 131e66f31c5Sopenharmony_ci } 132e66f31c5Sopenharmony_ci *size_ptr = utf8_len; 133e66f31c5Sopenharmony_ci 134e66f31c5Sopenharmony_ci uv__free(utf16_buffer); 135e66f31c5Sopenharmony_ci 136e66f31c5Sopenharmony_ci return err; 137e66f31c5Sopenharmony_ci 138e66f31c5Sopenharmony_ci error: 139e66f31c5Sopenharmony_ci uv__free(utf16_buffer); 140e66f31c5Sopenharmony_ci return uv_translate_sys_error(err); 141e66f31c5Sopenharmony_ci} 142e66f31c5Sopenharmony_ci 143e66f31c5Sopenharmony_ci 144e66f31c5Sopenharmony_cistatic int uv__cwd(WCHAR** buf, DWORD *len) { 145e66f31c5Sopenharmony_ci WCHAR* p; 146e66f31c5Sopenharmony_ci DWORD n; 147e66f31c5Sopenharmony_ci DWORD t; 148e66f31c5Sopenharmony_ci 149e66f31c5Sopenharmony_ci t = GetCurrentDirectoryW(0, NULL); 150e66f31c5Sopenharmony_ci for (;;) { 151e66f31c5Sopenharmony_ci if (t == 0) 152e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 153e66f31c5Sopenharmony_ci 154e66f31c5Sopenharmony_ci /* |t| is the size of the buffer _including_ nul. */ 155e66f31c5Sopenharmony_ci p = uv__malloc(t * sizeof(*p)); 156e66f31c5Sopenharmony_ci if (p == NULL) 157e66f31c5Sopenharmony_ci return UV_ENOMEM; 158e66f31c5Sopenharmony_ci 159e66f31c5Sopenharmony_ci /* |n| is the size of the buffer _excluding_ nul but _only on success_. 160e66f31c5Sopenharmony_ci * If |t| was too small because another thread changed the working 161e66f31c5Sopenharmony_ci * directory, |n| is the size the buffer should be _including_ nul. 162e66f31c5Sopenharmony_ci * It therefore follows we must resize when n >= t and fail when n == 0. 163e66f31c5Sopenharmony_ci */ 164e66f31c5Sopenharmony_ci n = GetCurrentDirectoryW(t, p); 165e66f31c5Sopenharmony_ci if (n > 0) 166e66f31c5Sopenharmony_ci if (n < t) 167e66f31c5Sopenharmony_ci break; 168e66f31c5Sopenharmony_ci 169e66f31c5Sopenharmony_ci uv__free(p); 170e66f31c5Sopenharmony_ci t = n; 171e66f31c5Sopenharmony_ci } 172e66f31c5Sopenharmony_ci 173e66f31c5Sopenharmony_ci /* The returned directory should not have a trailing slash, unless it points 174e66f31c5Sopenharmony_ci * at a drive root, like c:\. Remove it if needed. 175e66f31c5Sopenharmony_ci */ 176e66f31c5Sopenharmony_ci t = n - 1; 177e66f31c5Sopenharmony_ci if (p[t] == L'\\' && !(n == 3 && p[1] == L':')) { 178e66f31c5Sopenharmony_ci p[t] = L'\0'; 179e66f31c5Sopenharmony_ci n = t; 180e66f31c5Sopenharmony_ci } 181e66f31c5Sopenharmony_ci 182e66f31c5Sopenharmony_ci *buf = p; 183e66f31c5Sopenharmony_ci *len = n; 184e66f31c5Sopenharmony_ci 185e66f31c5Sopenharmony_ci return 0; 186e66f31c5Sopenharmony_ci} 187e66f31c5Sopenharmony_ci 188e66f31c5Sopenharmony_ci 189e66f31c5Sopenharmony_ciint uv_cwd(char* buffer, size_t* size) { 190e66f31c5Sopenharmony_ci DWORD utf16_len; 191e66f31c5Sopenharmony_ci WCHAR *utf16_buffer; 192e66f31c5Sopenharmony_ci int r; 193e66f31c5Sopenharmony_ci 194e66f31c5Sopenharmony_ci if (buffer == NULL || size == NULL) { 195e66f31c5Sopenharmony_ci return UV_EINVAL; 196e66f31c5Sopenharmony_ci } 197e66f31c5Sopenharmony_ci 198e66f31c5Sopenharmony_ci r = uv__cwd(&utf16_buffer, &utf16_len); 199e66f31c5Sopenharmony_ci if (r < 0) 200e66f31c5Sopenharmony_ci return r; 201e66f31c5Sopenharmony_ci 202e66f31c5Sopenharmony_ci r = uv__copy_utf16_to_utf8(utf16_buffer, utf16_len, buffer, size); 203e66f31c5Sopenharmony_ci 204e66f31c5Sopenharmony_ci uv__free(utf16_buffer); 205e66f31c5Sopenharmony_ci 206e66f31c5Sopenharmony_ci return r; 207e66f31c5Sopenharmony_ci} 208e66f31c5Sopenharmony_ci 209e66f31c5Sopenharmony_ci 210e66f31c5Sopenharmony_ciint uv_chdir(const char* dir) { 211e66f31c5Sopenharmony_ci WCHAR *utf16_buffer; 212e66f31c5Sopenharmony_ci DWORD utf16_len; 213e66f31c5Sopenharmony_ci WCHAR drive_letter, env_var[4]; 214e66f31c5Sopenharmony_ci int r; 215e66f31c5Sopenharmony_ci 216e66f31c5Sopenharmony_ci /* Convert to UTF-16 */ 217e66f31c5Sopenharmony_ci r = uv__convert_utf8_to_utf16(dir, &utf16_buffer); 218e66f31c5Sopenharmony_ci if (r) 219e66f31c5Sopenharmony_ci return r; 220e66f31c5Sopenharmony_ci 221e66f31c5Sopenharmony_ci if (!SetCurrentDirectoryW(utf16_buffer)) { 222e66f31c5Sopenharmony_ci uv__free(utf16_buffer); 223e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 224e66f31c5Sopenharmony_ci } 225e66f31c5Sopenharmony_ci 226e66f31c5Sopenharmony_ci /* uv__cwd() will return a new buffer. */ 227e66f31c5Sopenharmony_ci uv__free(utf16_buffer); 228e66f31c5Sopenharmony_ci utf16_buffer = NULL; 229e66f31c5Sopenharmony_ci 230e66f31c5Sopenharmony_ci /* Windows stores the drive-local path in an "hidden" environment variable, 231e66f31c5Sopenharmony_ci * which has the form "=C:=C:\Windows". SetCurrentDirectory does not update 232e66f31c5Sopenharmony_ci * this, so we'll have to do it. */ 233e66f31c5Sopenharmony_ci r = uv__cwd(&utf16_buffer, &utf16_len); 234e66f31c5Sopenharmony_ci if (r == UV_ENOMEM) { 235e66f31c5Sopenharmony_ci /* When updating the environment variable fails, return UV_OK anyway. 236e66f31c5Sopenharmony_ci * We did successfully change current working directory, only updating 237e66f31c5Sopenharmony_ci * hidden env variable failed. */ 238e66f31c5Sopenharmony_ci return 0; 239e66f31c5Sopenharmony_ci } 240e66f31c5Sopenharmony_ci if (r < 0) { 241e66f31c5Sopenharmony_ci return r; 242e66f31c5Sopenharmony_ci } 243e66f31c5Sopenharmony_ci 244e66f31c5Sopenharmony_ci if (utf16_len < 2 || utf16_buffer[1] != L':') { 245e66f31c5Sopenharmony_ci /* Doesn't look like a drive letter could be there - probably an UNC path. 246e66f31c5Sopenharmony_ci * TODO: Need to handle win32 namespaces like \\?\C:\ ? */ 247e66f31c5Sopenharmony_ci drive_letter = 0; 248e66f31c5Sopenharmony_ci } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') { 249e66f31c5Sopenharmony_ci drive_letter = utf16_buffer[0]; 250e66f31c5Sopenharmony_ci } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') { 251e66f31c5Sopenharmony_ci /* Convert to uppercase. */ 252e66f31c5Sopenharmony_ci drive_letter = utf16_buffer[0] - L'a' + L'A'; 253e66f31c5Sopenharmony_ci } else { 254e66f31c5Sopenharmony_ci /* Not valid. */ 255e66f31c5Sopenharmony_ci drive_letter = 0; 256e66f31c5Sopenharmony_ci } 257e66f31c5Sopenharmony_ci 258e66f31c5Sopenharmony_ci if (drive_letter != 0) { 259e66f31c5Sopenharmony_ci /* Construct the environment variable name and set it. */ 260e66f31c5Sopenharmony_ci env_var[0] = L'='; 261e66f31c5Sopenharmony_ci env_var[1] = drive_letter; 262e66f31c5Sopenharmony_ci env_var[2] = L':'; 263e66f31c5Sopenharmony_ci env_var[3] = L'\0'; 264e66f31c5Sopenharmony_ci 265e66f31c5Sopenharmony_ci SetEnvironmentVariableW(env_var, utf16_buffer); 266e66f31c5Sopenharmony_ci } 267e66f31c5Sopenharmony_ci 268e66f31c5Sopenharmony_ci uv__free(utf16_buffer); 269e66f31c5Sopenharmony_ci return 0; 270e66f31c5Sopenharmony_ci} 271e66f31c5Sopenharmony_ci 272e66f31c5Sopenharmony_ci 273e66f31c5Sopenharmony_civoid uv_loadavg(double avg[3]) { 274e66f31c5Sopenharmony_ci /* Can't be implemented */ 275e66f31c5Sopenharmony_ci avg[0] = avg[1] = avg[2] = 0; 276e66f31c5Sopenharmony_ci} 277e66f31c5Sopenharmony_ci 278e66f31c5Sopenharmony_ci 279e66f31c5Sopenharmony_ciuint64_t uv_get_free_memory(void) { 280e66f31c5Sopenharmony_ci MEMORYSTATUSEX memory_status; 281e66f31c5Sopenharmony_ci memory_status.dwLength = sizeof(memory_status); 282e66f31c5Sopenharmony_ci 283e66f31c5Sopenharmony_ci if (!GlobalMemoryStatusEx(&memory_status)) { 284e66f31c5Sopenharmony_ci return 0; 285e66f31c5Sopenharmony_ci } 286e66f31c5Sopenharmony_ci 287e66f31c5Sopenharmony_ci return (uint64_t)memory_status.ullAvailPhys; 288e66f31c5Sopenharmony_ci} 289e66f31c5Sopenharmony_ci 290e66f31c5Sopenharmony_ci 291e66f31c5Sopenharmony_ciuint64_t uv_get_total_memory(void) { 292e66f31c5Sopenharmony_ci MEMORYSTATUSEX memory_status; 293e66f31c5Sopenharmony_ci memory_status.dwLength = sizeof(memory_status); 294e66f31c5Sopenharmony_ci 295e66f31c5Sopenharmony_ci if (!GlobalMemoryStatusEx(&memory_status)) { 296e66f31c5Sopenharmony_ci return 0; 297e66f31c5Sopenharmony_ci } 298e66f31c5Sopenharmony_ci 299e66f31c5Sopenharmony_ci return (uint64_t)memory_status.ullTotalPhys; 300e66f31c5Sopenharmony_ci} 301e66f31c5Sopenharmony_ci 302e66f31c5Sopenharmony_ci 303e66f31c5Sopenharmony_ciuint64_t uv_get_constrained_memory(void) { 304e66f31c5Sopenharmony_ci return 0; /* Memory constraints are unknown. */ 305e66f31c5Sopenharmony_ci} 306e66f31c5Sopenharmony_ci 307e66f31c5Sopenharmony_ci 308e66f31c5Sopenharmony_ciuint64_t uv_get_available_memory(void) { 309e66f31c5Sopenharmony_ci return uv_get_free_memory(); 310e66f31c5Sopenharmony_ci} 311e66f31c5Sopenharmony_ci 312e66f31c5Sopenharmony_ci 313e66f31c5Sopenharmony_ciuv_pid_t uv_os_getpid(void) { 314e66f31c5Sopenharmony_ci return GetCurrentProcessId(); 315e66f31c5Sopenharmony_ci} 316e66f31c5Sopenharmony_ci 317e66f31c5Sopenharmony_ci 318e66f31c5Sopenharmony_ciuv_pid_t uv_os_getppid(void) { 319e66f31c5Sopenharmony_ci int parent_pid = -1; 320e66f31c5Sopenharmony_ci HANDLE handle; 321e66f31c5Sopenharmony_ci PROCESSENTRY32 pe; 322e66f31c5Sopenharmony_ci DWORD current_pid = GetCurrentProcessId(); 323e66f31c5Sopenharmony_ci 324e66f31c5Sopenharmony_ci pe.dwSize = sizeof(PROCESSENTRY32); 325e66f31c5Sopenharmony_ci handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 326e66f31c5Sopenharmony_ci 327e66f31c5Sopenharmony_ci if (Process32First(handle, &pe)) { 328e66f31c5Sopenharmony_ci do { 329e66f31c5Sopenharmony_ci if (pe.th32ProcessID == current_pid) { 330e66f31c5Sopenharmony_ci parent_pid = pe.th32ParentProcessID; 331e66f31c5Sopenharmony_ci break; 332e66f31c5Sopenharmony_ci } 333e66f31c5Sopenharmony_ci } while( Process32Next(handle, &pe)); 334e66f31c5Sopenharmony_ci } 335e66f31c5Sopenharmony_ci 336e66f31c5Sopenharmony_ci CloseHandle(handle); 337e66f31c5Sopenharmony_ci return parent_pid; 338e66f31c5Sopenharmony_ci} 339e66f31c5Sopenharmony_ci 340e66f31c5Sopenharmony_ci 341e66f31c5Sopenharmony_cichar** uv_setup_args(int argc, char** argv) { 342e66f31c5Sopenharmony_ci return argv; 343e66f31c5Sopenharmony_ci} 344e66f31c5Sopenharmony_ci 345e66f31c5Sopenharmony_ci 346e66f31c5Sopenharmony_civoid uv__process_title_cleanup(void) { 347e66f31c5Sopenharmony_ci} 348e66f31c5Sopenharmony_ci 349e66f31c5Sopenharmony_ci 350e66f31c5Sopenharmony_ciint uv_set_process_title(const char* title) { 351e66f31c5Sopenharmony_ci int err; 352e66f31c5Sopenharmony_ci int length; 353e66f31c5Sopenharmony_ci WCHAR* title_w = NULL; 354e66f31c5Sopenharmony_ci 355e66f31c5Sopenharmony_ci uv__once_init(); 356e66f31c5Sopenharmony_ci 357e66f31c5Sopenharmony_ci err = uv__convert_utf8_to_utf16(title, &title_w); 358e66f31c5Sopenharmony_ci if (err) 359e66f31c5Sopenharmony_ci return err; 360e66f31c5Sopenharmony_ci 361e66f31c5Sopenharmony_ci /* If the title must be truncated insert a \0 terminator there */ 362e66f31c5Sopenharmony_ci length = wcslen(title_w); 363e66f31c5Sopenharmony_ci if (length >= MAX_TITLE_LENGTH) 364e66f31c5Sopenharmony_ci title_w[MAX_TITLE_LENGTH - 1] = L'\0'; 365e66f31c5Sopenharmony_ci 366e66f31c5Sopenharmony_ci if (!SetConsoleTitleW(title_w)) { 367e66f31c5Sopenharmony_ci err = GetLastError(); 368e66f31c5Sopenharmony_ci goto done; 369e66f31c5Sopenharmony_ci } 370e66f31c5Sopenharmony_ci 371e66f31c5Sopenharmony_ci EnterCriticalSection(&process_title_lock); 372e66f31c5Sopenharmony_ci uv__free(process_title); 373e66f31c5Sopenharmony_ci process_title = uv__strdup(title); 374e66f31c5Sopenharmony_ci LeaveCriticalSection(&process_title_lock); 375e66f31c5Sopenharmony_ci 376e66f31c5Sopenharmony_ci err = 0; 377e66f31c5Sopenharmony_ci 378e66f31c5Sopenharmony_cidone: 379e66f31c5Sopenharmony_ci uv__free(title_w); 380e66f31c5Sopenharmony_ci return uv_translate_sys_error(err); 381e66f31c5Sopenharmony_ci} 382e66f31c5Sopenharmony_ci 383e66f31c5Sopenharmony_ci 384e66f31c5Sopenharmony_cistatic int uv__get_process_title(void) { 385e66f31c5Sopenharmony_ci WCHAR title_w[MAX_TITLE_LENGTH]; 386e66f31c5Sopenharmony_ci DWORD wlen; 387e66f31c5Sopenharmony_ci 388e66f31c5Sopenharmony_ci wlen = GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR)); 389e66f31c5Sopenharmony_ci if (wlen == 0) 390e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 391e66f31c5Sopenharmony_ci 392e66f31c5Sopenharmony_ci return uv__convert_utf16_to_utf8(title_w, wlen, &process_title); 393e66f31c5Sopenharmony_ci} 394e66f31c5Sopenharmony_ci 395e66f31c5Sopenharmony_ci 396e66f31c5Sopenharmony_ciint uv_get_process_title(char* buffer, size_t size) { 397e66f31c5Sopenharmony_ci size_t len; 398e66f31c5Sopenharmony_ci int r; 399e66f31c5Sopenharmony_ci 400e66f31c5Sopenharmony_ci if (buffer == NULL || size == 0) 401e66f31c5Sopenharmony_ci return UV_EINVAL; 402e66f31c5Sopenharmony_ci 403e66f31c5Sopenharmony_ci uv__once_init(); 404e66f31c5Sopenharmony_ci 405e66f31c5Sopenharmony_ci EnterCriticalSection(&process_title_lock); 406e66f31c5Sopenharmony_ci /* 407e66f31c5Sopenharmony_ci * If the process_title was never read before nor explicitly set, 408e66f31c5Sopenharmony_ci * we must query it with getConsoleTitleW 409e66f31c5Sopenharmony_ci */ 410e66f31c5Sopenharmony_ci if (process_title == NULL) { 411e66f31c5Sopenharmony_ci r = uv__get_process_title(); 412e66f31c5Sopenharmony_ci if (r) { 413e66f31c5Sopenharmony_ci LeaveCriticalSection(&process_title_lock); 414e66f31c5Sopenharmony_ci return r; 415e66f31c5Sopenharmony_ci } 416e66f31c5Sopenharmony_ci } 417e66f31c5Sopenharmony_ci 418e66f31c5Sopenharmony_ci assert(process_title); 419e66f31c5Sopenharmony_ci len = strlen(process_title) + 1; 420e66f31c5Sopenharmony_ci 421e66f31c5Sopenharmony_ci if (size < len) { 422e66f31c5Sopenharmony_ci LeaveCriticalSection(&process_title_lock); 423e66f31c5Sopenharmony_ci return UV_ENOBUFS; 424e66f31c5Sopenharmony_ci } 425e66f31c5Sopenharmony_ci 426e66f31c5Sopenharmony_ci memcpy(buffer, process_title, len); 427e66f31c5Sopenharmony_ci LeaveCriticalSection(&process_title_lock); 428e66f31c5Sopenharmony_ci 429e66f31c5Sopenharmony_ci return 0; 430e66f31c5Sopenharmony_ci} 431e66f31c5Sopenharmony_ci 432e66f31c5Sopenharmony_ci 433e66f31c5Sopenharmony_ci/* https://github.com/libuv/libuv/issues/1674 */ 434e66f31c5Sopenharmony_ciint uv_clock_gettime(uv_clock_id clock_id, uv_timespec64_t* ts) { 435e66f31c5Sopenharmony_ci FILETIME ft; 436e66f31c5Sopenharmony_ci int64_t t; 437e66f31c5Sopenharmony_ci 438e66f31c5Sopenharmony_ci if (ts == NULL) 439e66f31c5Sopenharmony_ci return UV_EFAULT; 440e66f31c5Sopenharmony_ci 441e66f31c5Sopenharmony_ci switch (clock_id) { 442e66f31c5Sopenharmony_ci case UV_CLOCK_MONOTONIC: 443e66f31c5Sopenharmony_ci uv__once_init(); 444e66f31c5Sopenharmony_ci t = uv__hrtime(UV__NANOSEC); 445e66f31c5Sopenharmony_ci ts->tv_sec = t / 1000000000; 446e66f31c5Sopenharmony_ci ts->tv_nsec = t % 1000000000; 447e66f31c5Sopenharmony_ci return 0; 448e66f31c5Sopenharmony_ci case UV_CLOCK_REALTIME: 449e66f31c5Sopenharmony_ci GetSystemTimePreciseAsFileTime(&ft); 450e66f31c5Sopenharmony_ci /* In 100-nanosecond increments from 1601-01-01 UTC because why not? */ 451e66f31c5Sopenharmony_ci t = (int64_t) ft.dwHighDateTime << 32 | ft.dwLowDateTime; 452e66f31c5Sopenharmony_ci /* Convert to UNIX epoch, 1970-01-01. Still in 100 ns increments. */ 453e66f31c5Sopenharmony_ci t -= 116444736000000000ll; 454e66f31c5Sopenharmony_ci /* Now convert to seconds and nanoseconds. */ 455e66f31c5Sopenharmony_ci ts->tv_sec = t / 10000000; 456e66f31c5Sopenharmony_ci ts->tv_nsec = t % 10000000 * 100; 457e66f31c5Sopenharmony_ci return 0; 458e66f31c5Sopenharmony_ci } 459e66f31c5Sopenharmony_ci 460e66f31c5Sopenharmony_ci return UV_EINVAL; 461e66f31c5Sopenharmony_ci} 462e66f31c5Sopenharmony_ci 463e66f31c5Sopenharmony_ci 464e66f31c5Sopenharmony_ciuint64_t uv_hrtime(void) { 465e66f31c5Sopenharmony_ci uv__once_init(); 466e66f31c5Sopenharmony_ci return uv__hrtime(UV__NANOSEC); 467e66f31c5Sopenharmony_ci} 468e66f31c5Sopenharmony_ci 469e66f31c5Sopenharmony_ci 470e66f31c5Sopenharmony_ciuint64_t uv__hrtime(unsigned int scale) { 471e66f31c5Sopenharmony_ci LARGE_INTEGER counter; 472e66f31c5Sopenharmony_ci double scaled_freq; 473e66f31c5Sopenharmony_ci double result; 474e66f31c5Sopenharmony_ci 475e66f31c5Sopenharmony_ci assert(hrtime_frequency_ != 0); 476e66f31c5Sopenharmony_ci assert(scale != 0); 477e66f31c5Sopenharmony_ci if (!QueryPerformanceCounter(&counter)) { 478e66f31c5Sopenharmony_ci uv_fatal_error(GetLastError(), "QueryPerformanceCounter"); 479e66f31c5Sopenharmony_ci } 480e66f31c5Sopenharmony_ci assert(counter.QuadPart != 0); 481e66f31c5Sopenharmony_ci 482e66f31c5Sopenharmony_ci /* Because we have no guarantee about the order of magnitude of the 483e66f31c5Sopenharmony_ci * performance counter interval, integer math could cause this computation 484e66f31c5Sopenharmony_ci * to overflow. Therefore we resort to floating point math. 485e66f31c5Sopenharmony_ci */ 486e66f31c5Sopenharmony_ci scaled_freq = (double) hrtime_frequency_ / scale; 487e66f31c5Sopenharmony_ci result = (double) counter.QuadPart / scaled_freq; 488e66f31c5Sopenharmony_ci return (uint64_t) result; 489e66f31c5Sopenharmony_ci} 490e66f31c5Sopenharmony_ci 491e66f31c5Sopenharmony_ci 492e66f31c5Sopenharmony_ciint uv_resident_set_memory(size_t* rss) { 493e66f31c5Sopenharmony_ci HANDLE current_process; 494e66f31c5Sopenharmony_ci PROCESS_MEMORY_COUNTERS pmc; 495e66f31c5Sopenharmony_ci 496e66f31c5Sopenharmony_ci current_process = GetCurrentProcess(); 497e66f31c5Sopenharmony_ci 498e66f31c5Sopenharmony_ci if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) { 499e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 500e66f31c5Sopenharmony_ci } 501e66f31c5Sopenharmony_ci 502e66f31c5Sopenharmony_ci *rss = pmc.WorkingSetSize; 503e66f31c5Sopenharmony_ci 504e66f31c5Sopenharmony_ci return 0; 505e66f31c5Sopenharmony_ci} 506e66f31c5Sopenharmony_ci 507e66f31c5Sopenharmony_ci 508e66f31c5Sopenharmony_ciint uv_uptime(double* uptime) { 509e66f31c5Sopenharmony_ci *uptime = GetTickCount64() / 1000.0; 510e66f31c5Sopenharmony_ci return 0; 511e66f31c5Sopenharmony_ci} 512e66f31c5Sopenharmony_ci 513e66f31c5Sopenharmony_ci 514e66f31c5Sopenharmony_ciunsigned int uv_available_parallelism(void) { 515e66f31c5Sopenharmony_ci SYSTEM_INFO info; 516e66f31c5Sopenharmony_ci unsigned rc; 517e66f31c5Sopenharmony_ci 518e66f31c5Sopenharmony_ci /* TODO(bnoordhuis) Use GetLogicalProcessorInformationEx() to support systems 519e66f31c5Sopenharmony_ci * with > 64 CPUs? See https://github.com/libuv/libuv/pull/3458 520e66f31c5Sopenharmony_ci */ 521e66f31c5Sopenharmony_ci GetSystemInfo(&info); 522e66f31c5Sopenharmony_ci 523e66f31c5Sopenharmony_ci rc = info.dwNumberOfProcessors; 524e66f31c5Sopenharmony_ci if (rc < 1) 525e66f31c5Sopenharmony_ci rc = 1; 526e66f31c5Sopenharmony_ci 527e66f31c5Sopenharmony_ci return rc; 528e66f31c5Sopenharmony_ci} 529e66f31c5Sopenharmony_ci 530e66f31c5Sopenharmony_ci 531e66f31c5Sopenharmony_ciint uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { 532e66f31c5Sopenharmony_ci uv_cpu_info_t* cpu_infos; 533e66f31c5Sopenharmony_ci SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; 534e66f31c5Sopenharmony_ci DWORD sppi_size; 535e66f31c5Sopenharmony_ci SYSTEM_INFO system_info; 536e66f31c5Sopenharmony_ci DWORD cpu_count, i; 537e66f31c5Sopenharmony_ci NTSTATUS status; 538e66f31c5Sopenharmony_ci ULONG result_size; 539e66f31c5Sopenharmony_ci int err; 540e66f31c5Sopenharmony_ci uv_cpu_info_t* cpu_info; 541e66f31c5Sopenharmony_ci 542e66f31c5Sopenharmony_ci cpu_infos = NULL; 543e66f31c5Sopenharmony_ci cpu_count = 0; 544e66f31c5Sopenharmony_ci sppi = NULL; 545e66f31c5Sopenharmony_ci 546e66f31c5Sopenharmony_ci uv__once_init(); 547e66f31c5Sopenharmony_ci 548e66f31c5Sopenharmony_ci GetSystemInfo(&system_info); 549e66f31c5Sopenharmony_ci cpu_count = system_info.dwNumberOfProcessors; 550e66f31c5Sopenharmony_ci 551e66f31c5Sopenharmony_ci cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos); 552e66f31c5Sopenharmony_ci if (cpu_infos == NULL) { 553e66f31c5Sopenharmony_ci err = ERROR_OUTOFMEMORY; 554e66f31c5Sopenharmony_ci goto error; 555e66f31c5Sopenharmony_ci } 556e66f31c5Sopenharmony_ci 557e66f31c5Sopenharmony_ci sppi_size = cpu_count * sizeof(*sppi); 558e66f31c5Sopenharmony_ci sppi = uv__malloc(sppi_size); 559e66f31c5Sopenharmony_ci if (sppi == NULL) { 560e66f31c5Sopenharmony_ci err = ERROR_OUTOFMEMORY; 561e66f31c5Sopenharmony_ci goto error; 562e66f31c5Sopenharmony_ci } 563e66f31c5Sopenharmony_ci 564e66f31c5Sopenharmony_ci status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, 565e66f31c5Sopenharmony_ci sppi, 566e66f31c5Sopenharmony_ci sppi_size, 567e66f31c5Sopenharmony_ci &result_size); 568e66f31c5Sopenharmony_ci if (!NT_SUCCESS(status)) { 569e66f31c5Sopenharmony_ci err = pRtlNtStatusToDosError(status); 570e66f31c5Sopenharmony_ci goto error; 571e66f31c5Sopenharmony_ci } 572e66f31c5Sopenharmony_ci 573e66f31c5Sopenharmony_ci assert(result_size == sppi_size); 574e66f31c5Sopenharmony_ci 575e66f31c5Sopenharmony_ci for (i = 0; i < cpu_count; i++) { 576e66f31c5Sopenharmony_ci WCHAR key_name[128]; 577e66f31c5Sopenharmony_ci HKEY processor_key; 578e66f31c5Sopenharmony_ci DWORD cpu_speed; 579e66f31c5Sopenharmony_ci DWORD cpu_speed_size = sizeof(cpu_speed); 580e66f31c5Sopenharmony_ci WCHAR cpu_brand[256]; 581e66f31c5Sopenharmony_ci DWORD cpu_brand_size = sizeof(cpu_brand); 582e66f31c5Sopenharmony_ci size_t len; 583e66f31c5Sopenharmony_ci 584e66f31c5Sopenharmony_ci len = _snwprintf(key_name, 585e66f31c5Sopenharmony_ci ARRAY_SIZE(key_name), 586e66f31c5Sopenharmony_ci L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", 587e66f31c5Sopenharmony_ci i); 588e66f31c5Sopenharmony_ci 589e66f31c5Sopenharmony_ci assert(len > 0 && len < ARRAY_SIZE(key_name)); 590e66f31c5Sopenharmony_ci 591e66f31c5Sopenharmony_ci err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 592e66f31c5Sopenharmony_ci key_name, 593e66f31c5Sopenharmony_ci 0, 594e66f31c5Sopenharmony_ci KEY_QUERY_VALUE, 595e66f31c5Sopenharmony_ci &processor_key); 596e66f31c5Sopenharmony_ci if (err != ERROR_SUCCESS) { 597e66f31c5Sopenharmony_ci goto error; 598e66f31c5Sopenharmony_ci } 599e66f31c5Sopenharmony_ci 600e66f31c5Sopenharmony_ci err = RegQueryValueExW(processor_key, 601e66f31c5Sopenharmony_ci L"~MHz", 602e66f31c5Sopenharmony_ci NULL, 603e66f31c5Sopenharmony_ci NULL, 604e66f31c5Sopenharmony_ci (BYTE*)&cpu_speed, 605e66f31c5Sopenharmony_ci &cpu_speed_size); 606e66f31c5Sopenharmony_ci if (err != ERROR_SUCCESS) { 607e66f31c5Sopenharmony_ci RegCloseKey(processor_key); 608e66f31c5Sopenharmony_ci goto error; 609e66f31c5Sopenharmony_ci } 610e66f31c5Sopenharmony_ci 611e66f31c5Sopenharmony_ci err = RegQueryValueExW(processor_key, 612e66f31c5Sopenharmony_ci L"ProcessorNameString", 613e66f31c5Sopenharmony_ci NULL, 614e66f31c5Sopenharmony_ci NULL, 615e66f31c5Sopenharmony_ci (BYTE*)&cpu_brand, 616e66f31c5Sopenharmony_ci &cpu_brand_size); 617e66f31c5Sopenharmony_ci RegCloseKey(processor_key); 618e66f31c5Sopenharmony_ci if (err != ERROR_SUCCESS) 619e66f31c5Sopenharmony_ci goto error; 620e66f31c5Sopenharmony_ci 621e66f31c5Sopenharmony_ci cpu_info = &cpu_infos[i]; 622e66f31c5Sopenharmony_ci cpu_info->speed = cpu_speed; 623e66f31c5Sopenharmony_ci cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; 624e66f31c5Sopenharmony_ci cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - 625e66f31c5Sopenharmony_ci sppi[i].IdleTime.QuadPart) / 10000; 626e66f31c5Sopenharmony_ci cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; 627e66f31c5Sopenharmony_ci cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; 628e66f31c5Sopenharmony_ci cpu_info->cpu_times.nice = 0; 629e66f31c5Sopenharmony_ci 630e66f31c5Sopenharmony_ci uv__convert_utf16_to_utf8(cpu_brand, 631e66f31c5Sopenharmony_ci cpu_brand_size / sizeof(WCHAR), 632e66f31c5Sopenharmony_ci &(cpu_info->model)); 633e66f31c5Sopenharmony_ci } 634e66f31c5Sopenharmony_ci 635e66f31c5Sopenharmony_ci uv__free(sppi); 636e66f31c5Sopenharmony_ci 637e66f31c5Sopenharmony_ci *cpu_count_ptr = cpu_count; 638e66f31c5Sopenharmony_ci *cpu_infos_ptr = cpu_infos; 639e66f31c5Sopenharmony_ci 640e66f31c5Sopenharmony_ci return 0; 641e66f31c5Sopenharmony_ci 642e66f31c5Sopenharmony_ci error: 643e66f31c5Sopenharmony_ci if (cpu_infos != NULL) { 644e66f31c5Sopenharmony_ci /* This is safe because the cpu_infos array is zeroed on allocation. */ 645e66f31c5Sopenharmony_ci for (i = 0; i < cpu_count; i++) 646e66f31c5Sopenharmony_ci uv__free(cpu_infos[i].model); 647e66f31c5Sopenharmony_ci } 648e66f31c5Sopenharmony_ci 649e66f31c5Sopenharmony_ci uv__free(cpu_infos); 650e66f31c5Sopenharmony_ci uv__free(sppi); 651e66f31c5Sopenharmony_ci 652e66f31c5Sopenharmony_ci return uv_translate_sys_error(err); 653e66f31c5Sopenharmony_ci} 654e66f31c5Sopenharmony_ci 655e66f31c5Sopenharmony_ci 656e66f31c5Sopenharmony_ciint uv_interface_addresses(uv_interface_address_t** addresses_ptr, 657e66f31c5Sopenharmony_ci int* count_ptr) { 658e66f31c5Sopenharmony_ci IP_ADAPTER_ADDRESSES* win_address_buf; 659e66f31c5Sopenharmony_ci ULONG win_address_buf_size; 660e66f31c5Sopenharmony_ci IP_ADAPTER_ADDRESSES* adapter; 661e66f31c5Sopenharmony_ci 662e66f31c5Sopenharmony_ci uv_interface_address_t* uv_address_buf; 663e66f31c5Sopenharmony_ci char* name_buf; 664e66f31c5Sopenharmony_ci size_t uv_address_buf_size; 665e66f31c5Sopenharmony_ci uv_interface_address_t* uv_address; 666e66f31c5Sopenharmony_ci 667e66f31c5Sopenharmony_ci int count; 668e66f31c5Sopenharmony_ci ULONG flags; 669e66f31c5Sopenharmony_ci 670e66f31c5Sopenharmony_ci *addresses_ptr = NULL; 671e66f31c5Sopenharmony_ci *count_ptr = 0; 672e66f31c5Sopenharmony_ci 673e66f31c5Sopenharmony_ci flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | 674e66f31c5Sopenharmony_ci GAA_FLAG_SKIP_DNS_SERVER; 675e66f31c5Sopenharmony_ci 676e66f31c5Sopenharmony_ci /* Fetch the size of the adapters reported by windows, and then get the list 677e66f31c5Sopenharmony_ci * itself. */ 678e66f31c5Sopenharmony_ci win_address_buf_size = 0; 679e66f31c5Sopenharmony_ci win_address_buf = NULL; 680e66f31c5Sopenharmony_ci 681e66f31c5Sopenharmony_ci for (;;) { 682e66f31c5Sopenharmony_ci ULONG r; 683e66f31c5Sopenharmony_ci 684e66f31c5Sopenharmony_ci /* If win_address_buf is 0, then GetAdaptersAddresses will fail with. 685e66f31c5Sopenharmony_ci * ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in 686e66f31c5Sopenharmony_ci * win_address_buf_size. */ 687e66f31c5Sopenharmony_ci r = GetAdaptersAddresses(AF_UNSPEC, 688e66f31c5Sopenharmony_ci flags, 689e66f31c5Sopenharmony_ci NULL, 690e66f31c5Sopenharmony_ci win_address_buf, 691e66f31c5Sopenharmony_ci &win_address_buf_size); 692e66f31c5Sopenharmony_ci 693e66f31c5Sopenharmony_ci if (r == ERROR_SUCCESS) 694e66f31c5Sopenharmony_ci break; 695e66f31c5Sopenharmony_ci 696e66f31c5Sopenharmony_ci uv__free(win_address_buf); 697e66f31c5Sopenharmony_ci 698e66f31c5Sopenharmony_ci switch (r) { 699e66f31c5Sopenharmony_ci case ERROR_BUFFER_OVERFLOW: 700e66f31c5Sopenharmony_ci /* This happens when win_address_buf is NULL or too small to hold all 701e66f31c5Sopenharmony_ci * adapters. */ 702e66f31c5Sopenharmony_ci win_address_buf = uv__malloc(win_address_buf_size); 703e66f31c5Sopenharmony_ci if (win_address_buf == NULL) 704e66f31c5Sopenharmony_ci return UV_ENOMEM; 705e66f31c5Sopenharmony_ci 706e66f31c5Sopenharmony_ci continue; 707e66f31c5Sopenharmony_ci 708e66f31c5Sopenharmony_ci case ERROR_NO_DATA: { 709e66f31c5Sopenharmony_ci /* No adapters were found. */ 710e66f31c5Sopenharmony_ci uv_address_buf = uv__malloc(1); 711e66f31c5Sopenharmony_ci if (uv_address_buf == NULL) 712e66f31c5Sopenharmony_ci return UV_ENOMEM; 713e66f31c5Sopenharmony_ci 714e66f31c5Sopenharmony_ci *count_ptr = 0; 715e66f31c5Sopenharmony_ci *addresses_ptr = uv_address_buf; 716e66f31c5Sopenharmony_ci 717e66f31c5Sopenharmony_ci return 0; 718e66f31c5Sopenharmony_ci } 719e66f31c5Sopenharmony_ci 720e66f31c5Sopenharmony_ci case ERROR_ADDRESS_NOT_ASSOCIATED: 721e66f31c5Sopenharmony_ci return UV_EAGAIN; 722e66f31c5Sopenharmony_ci 723e66f31c5Sopenharmony_ci case ERROR_INVALID_PARAMETER: 724e66f31c5Sopenharmony_ci /* MSDN says: 725e66f31c5Sopenharmony_ci * "This error is returned for any of the following conditions: the 726e66f31c5Sopenharmony_ci * SizePointer parameter is NULL, the Address parameter is not 727e66f31c5Sopenharmony_ci * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for 728e66f31c5Sopenharmony_ci * the parameters requested is greater than ULONG_MAX." 729e66f31c5Sopenharmony_ci * Since the first two conditions are not met, it must be that the 730e66f31c5Sopenharmony_ci * adapter data is too big. 731e66f31c5Sopenharmony_ci */ 732e66f31c5Sopenharmony_ci return UV_ENOBUFS; 733e66f31c5Sopenharmony_ci 734e66f31c5Sopenharmony_ci default: 735e66f31c5Sopenharmony_ci /* Other (unspecified) errors can happen, but we don't have any special 736e66f31c5Sopenharmony_ci * meaning for them. */ 737e66f31c5Sopenharmony_ci assert(r != ERROR_SUCCESS); 738e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 739e66f31c5Sopenharmony_ci } 740e66f31c5Sopenharmony_ci } 741e66f31c5Sopenharmony_ci 742e66f31c5Sopenharmony_ci /* Count the number of enabled interfaces and compute how much space is 743e66f31c5Sopenharmony_ci * needed to store their info. */ 744e66f31c5Sopenharmony_ci count = 0; 745e66f31c5Sopenharmony_ci uv_address_buf_size = 0; 746e66f31c5Sopenharmony_ci 747e66f31c5Sopenharmony_ci for (adapter = win_address_buf; 748e66f31c5Sopenharmony_ci adapter != NULL; 749e66f31c5Sopenharmony_ci adapter = adapter->Next) { 750e66f31c5Sopenharmony_ci IP_ADAPTER_UNICAST_ADDRESS* unicast_address; 751e66f31c5Sopenharmony_ci int name_size; 752e66f31c5Sopenharmony_ci 753e66f31c5Sopenharmony_ci /* Interfaces that are not 'up' should not be reported. Also skip 754e66f31c5Sopenharmony_ci * interfaces that have no associated unicast address, as to avoid 755e66f31c5Sopenharmony_ci * allocating space for the name for this interface. */ 756e66f31c5Sopenharmony_ci if (adapter->OperStatus != IfOperStatusUp || 757e66f31c5Sopenharmony_ci adapter->FirstUnicastAddress == NULL) 758e66f31c5Sopenharmony_ci continue; 759e66f31c5Sopenharmony_ci 760e66f31c5Sopenharmony_ci /* Compute the size of the interface name. */ 761e66f31c5Sopenharmony_ci name_size = uv_utf16_length_as_wtf8(adapter->FriendlyName, -1); 762e66f31c5Sopenharmony_ci uv_address_buf_size += name_size + 1; 763e66f31c5Sopenharmony_ci 764e66f31c5Sopenharmony_ci /* Count the number of addresses associated with this interface, and 765e66f31c5Sopenharmony_ci * compute the size. */ 766e66f31c5Sopenharmony_ci for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) 767e66f31c5Sopenharmony_ci adapter->FirstUnicastAddress; 768e66f31c5Sopenharmony_ci unicast_address != NULL; 769e66f31c5Sopenharmony_ci unicast_address = unicast_address->Next) { 770e66f31c5Sopenharmony_ci count++; 771e66f31c5Sopenharmony_ci uv_address_buf_size += sizeof(uv_interface_address_t); 772e66f31c5Sopenharmony_ci } 773e66f31c5Sopenharmony_ci } 774e66f31c5Sopenharmony_ci 775e66f31c5Sopenharmony_ci /* Allocate space to store interface data plus adapter names. */ 776e66f31c5Sopenharmony_ci uv_address_buf = uv__malloc(uv_address_buf_size); 777e66f31c5Sopenharmony_ci if (uv_address_buf == NULL) { 778e66f31c5Sopenharmony_ci uv__free(win_address_buf); 779e66f31c5Sopenharmony_ci return UV_ENOMEM; 780e66f31c5Sopenharmony_ci } 781e66f31c5Sopenharmony_ci 782e66f31c5Sopenharmony_ci /* Compute the start of the uv_interface_address_t array, and the place in 783e66f31c5Sopenharmony_ci * the buffer where the interface names will be stored. */ 784e66f31c5Sopenharmony_ci uv_address = uv_address_buf; 785e66f31c5Sopenharmony_ci name_buf = (char*) (uv_address_buf + count); 786e66f31c5Sopenharmony_ci 787e66f31c5Sopenharmony_ci /* Fill out the output buffer. */ 788e66f31c5Sopenharmony_ci for (adapter = win_address_buf; 789e66f31c5Sopenharmony_ci adapter != NULL; 790e66f31c5Sopenharmony_ci adapter = adapter->Next) { 791e66f31c5Sopenharmony_ci IP_ADAPTER_UNICAST_ADDRESS* unicast_address; 792e66f31c5Sopenharmony_ci size_t name_size; 793e66f31c5Sopenharmony_ci int r; 794e66f31c5Sopenharmony_ci 795e66f31c5Sopenharmony_ci if (adapter->OperStatus != IfOperStatusUp || 796e66f31c5Sopenharmony_ci adapter->FirstUnicastAddress == NULL) 797e66f31c5Sopenharmony_ci continue; 798e66f31c5Sopenharmony_ci 799e66f31c5Sopenharmony_ci /* Convert the interface name to UTF8. */ 800e66f31c5Sopenharmony_ci name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf; 801e66f31c5Sopenharmony_ci r = uv__copy_utf16_to_utf8(adapter->FriendlyName, 802e66f31c5Sopenharmony_ci -1, 803e66f31c5Sopenharmony_ci name_buf, 804e66f31c5Sopenharmony_ci &name_size); 805e66f31c5Sopenharmony_ci if (r) { 806e66f31c5Sopenharmony_ci uv__free(win_address_buf); 807e66f31c5Sopenharmony_ci uv__free(uv_address_buf); 808e66f31c5Sopenharmony_ci return r; 809e66f31c5Sopenharmony_ci } 810e66f31c5Sopenharmony_ci name_size += 1; /* Add NUL byte. */ 811e66f31c5Sopenharmony_ci 812e66f31c5Sopenharmony_ci /* Add an uv_interface_address_t element for every unicast address. */ 813e66f31c5Sopenharmony_ci for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) 814e66f31c5Sopenharmony_ci adapter->FirstUnicastAddress; 815e66f31c5Sopenharmony_ci unicast_address != NULL; 816e66f31c5Sopenharmony_ci unicast_address = unicast_address->Next) { 817e66f31c5Sopenharmony_ci struct sockaddr* sa; 818e66f31c5Sopenharmony_ci ULONG prefix_len; 819e66f31c5Sopenharmony_ci 820e66f31c5Sopenharmony_ci sa = unicast_address->Address.lpSockaddr; 821e66f31c5Sopenharmony_ci 822e66f31c5Sopenharmony_ci prefix_len = 823e66f31c5Sopenharmony_ci ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength; 824e66f31c5Sopenharmony_ci 825e66f31c5Sopenharmony_ci memset(uv_address, 0, sizeof *uv_address); 826e66f31c5Sopenharmony_ci 827e66f31c5Sopenharmony_ci uv_address->name = name_buf; 828e66f31c5Sopenharmony_ci 829e66f31c5Sopenharmony_ci if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) { 830e66f31c5Sopenharmony_ci memcpy(uv_address->phys_addr, 831e66f31c5Sopenharmony_ci adapter->PhysicalAddress, 832e66f31c5Sopenharmony_ci sizeof(uv_address->phys_addr)); 833e66f31c5Sopenharmony_ci } 834e66f31c5Sopenharmony_ci 835e66f31c5Sopenharmony_ci uv_address->is_internal = 836e66f31c5Sopenharmony_ci (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK); 837e66f31c5Sopenharmony_ci 838e66f31c5Sopenharmony_ci if (sa->sa_family == AF_INET6) { 839e66f31c5Sopenharmony_ci uv_address->address.address6 = *((struct sockaddr_in6 *) sa); 840e66f31c5Sopenharmony_ci 841e66f31c5Sopenharmony_ci uv_address->netmask.netmask6.sin6_family = AF_INET6; 842e66f31c5Sopenharmony_ci memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3); 843e66f31c5Sopenharmony_ci /* This check ensures that we don't write past the size of the data. */ 844e66f31c5Sopenharmony_ci if (prefix_len % 8) { 845e66f31c5Sopenharmony_ci uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] = 846e66f31c5Sopenharmony_ci 0xff << (8 - prefix_len % 8); 847e66f31c5Sopenharmony_ci } 848e66f31c5Sopenharmony_ci 849e66f31c5Sopenharmony_ci } else { 850e66f31c5Sopenharmony_ci uv_address->address.address4 = *((struct sockaddr_in *) sa); 851e66f31c5Sopenharmony_ci 852e66f31c5Sopenharmony_ci uv_address->netmask.netmask4.sin_family = AF_INET; 853e66f31c5Sopenharmony_ci uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ? 854e66f31c5Sopenharmony_ci htonl(0xffffffff << (32 - prefix_len)) : 0; 855e66f31c5Sopenharmony_ci } 856e66f31c5Sopenharmony_ci 857e66f31c5Sopenharmony_ci uv_address++; 858e66f31c5Sopenharmony_ci } 859e66f31c5Sopenharmony_ci 860e66f31c5Sopenharmony_ci name_buf += name_size; 861e66f31c5Sopenharmony_ci } 862e66f31c5Sopenharmony_ci 863e66f31c5Sopenharmony_ci uv__free(win_address_buf); 864e66f31c5Sopenharmony_ci 865e66f31c5Sopenharmony_ci *addresses_ptr = uv_address_buf; 866e66f31c5Sopenharmony_ci *count_ptr = count; 867e66f31c5Sopenharmony_ci 868e66f31c5Sopenharmony_ci return 0; 869e66f31c5Sopenharmony_ci} 870e66f31c5Sopenharmony_ci 871e66f31c5Sopenharmony_ci 872e66f31c5Sopenharmony_civoid uv_free_interface_addresses(uv_interface_address_t* addresses, 873e66f31c5Sopenharmony_ci int count) { 874e66f31c5Sopenharmony_ci uv__free(addresses); 875e66f31c5Sopenharmony_ci} 876e66f31c5Sopenharmony_ci 877e66f31c5Sopenharmony_ci 878e66f31c5Sopenharmony_ciint uv_getrusage(uv_rusage_t *uv_rusage) { 879e66f31c5Sopenharmony_ci FILETIME createTime, exitTime, kernelTime, userTime; 880e66f31c5Sopenharmony_ci SYSTEMTIME kernelSystemTime, userSystemTime; 881e66f31c5Sopenharmony_ci PROCESS_MEMORY_COUNTERS memCounters; 882e66f31c5Sopenharmony_ci IO_COUNTERS ioCounters; 883e66f31c5Sopenharmony_ci int ret; 884e66f31c5Sopenharmony_ci 885e66f31c5Sopenharmony_ci ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime); 886e66f31c5Sopenharmony_ci if (ret == 0) { 887e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 888e66f31c5Sopenharmony_ci } 889e66f31c5Sopenharmony_ci 890e66f31c5Sopenharmony_ci ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime); 891e66f31c5Sopenharmony_ci if (ret == 0) { 892e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 893e66f31c5Sopenharmony_ci } 894e66f31c5Sopenharmony_ci 895e66f31c5Sopenharmony_ci ret = FileTimeToSystemTime(&userTime, &userSystemTime); 896e66f31c5Sopenharmony_ci if (ret == 0) { 897e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 898e66f31c5Sopenharmony_ci } 899e66f31c5Sopenharmony_ci 900e66f31c5Sopenharmony_ci ret = GetProcessMemoryInfo(GetCurrentProcess(), 901e66f31c5Sopenharmony_ci &memCounters, 902e66f31c5Sopenharmony_ci sizeof(memCounters)); 903e66f31c5Sopenharmony_ci if (ret == 0) { 904e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 905e66f31c5Sopenharmony_ci } 906e66f31c5Sopenharmony_ci 907e66f31c5Sopenharmony_ci ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters); 908e66f31c5Sopenharmony_ci if (ret == 0) { 909e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 910e66f31c5Sopenharmony_ci } 911e66f31c5Sopenharmony_ci 912e66f31c5Sopenharmony_ci memset(uv_rusage, 0, sizeof(*uv_rusage)); 913e66f31c5Sopenharmony_ci 914e66f31c5Sopenharmony_ci uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 + 915e66f31c5Sopenharmony_ci userSystemTime.wMinute * 60 + 916e66f31c5Sopenharmony_ci userSystemTime.wSecond; 917e66f31c5Sopenharmony_ci uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000; 918e66f31c5Sopenharmony_ci 919e66f31c5Sopenharmony_ci uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 + 920e66f31c5Sopenharmony_ci kernelSystemTime.wMinute * 60 + 921e66f31c5Sopenharmony_ci kernelSystemTime.wSecond; 922e66f31c5Sopenharmony_ci uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000; 923e66f31c5Sopenharmony_ci 924e66f31c5Sopenharmony_ci uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount; 925e66f31c5Sopenharmony_ci uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024; 926e66f31c5Sopenharmony_ci 927e66f31c5Sopenharmony_ci uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount; 928e66f31c5Sopenharmony_ci uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount; 929e66f31c5Sopenharmony_ci 930e66f31c5Sopenharmony_ci return 0; 931e66f31c5Sopenharmony_ci} 932e66f31c5Sopenharmony_ci 933e66f31c5Sopenharmony_ci 934e66f31c5Sopenharmony_ciint uv_os_homedir(char* buffer, size_t* size) { 935e66f31c5Sopenharmony_ci uv_passwd_t pwd; 936e66f31c5Sopenharmony_ci size_t len; 937e66f31c5Sopenharmony_ci int r; 938e66f31c5Sopenharmony_ci 939e66f31c5Sopenharmony_ci /* Check if the USERPROFILE environment variable is set first. The task of 940e66f31c5Sopenharmony_ci performing input validation on buffer and size is taken care of by 941e66f31c5Sopenharmony_ci uv_os_getenv(). */ 942e66f31c5Sopenharmony_ci r = uv_os_getenv("USERPROFILE", buffer, size); 943e66f31c5Sopenharmony_ci 944e66f31c5Sopenharmony_ci /* Don't return an error if USERPROFILE was not found. */ 945e66f31c5Sopenharmony_ci if (r != UV_ENOENT) 946e66f31c5Sopenharmony_ci return r; 947e66f31c5Sopenharmony_ci 948e66f31c5Sopenharmony_ci /* USERPROFILE is not set, so call uv_os_get_passwd() */ 949e66f31c5Sopenharmony_ci r = uv_os_get_passwd(&pwd); 950e66f31c5Sopenharmony_ci 951e66f31c5Sopenharmony_ci if (r != 0) { 952e66f31c5Sopenharmony_ci return r; 953e66f31c5Sopenharmony_ci } 954e66f31c5Sopenharmony_ci 955e66f31c5Sopenharmony_ci len = strlen(pwd.homedir); 956e66f31c5Sopenharmony_ci 957e66f31c5Sopenharmony_ci if (len >= *size) { 958e66f31c5Sopenharmony_ci *size = len + 1; 959e66f31c5Sopenharmony_ci uv_os_free_passwd(&pwd); 960e66f31c5Sopenharmony_ci return UV_ENOBUFS; 961e66f31c5Sopenharmony_ci } 962e66f31c5Sopenharmony_ci 963e66f31c5Sopenharmony_ci memcpy(buffer, pwd.homedir, len + 1); 964e66f31c5Sopenharmony_ci *size = len; 965e66f31c5Sopenharmony_ci uv_os_free_passwd(&pwd); 966e66f31c5Sopenharmony_ci 967e66f31c5Sopenharmony_ci return 0; 968e66f31c5Sopenharmony_ci} 969e66f31c5Sopenharmony_ci 970e66f31c5Sopenharmony_ci 971e66f31c5Sopenharmony_ciint uv_os_tmpdir(char* buffer, size_t* size) { 972e66f31c5Sopenharmony_ci wchar_t *path; 973e66f31c5Sopenharmony_ci size_t len; 974e66f31c5Sopenharmony_ci 975e66f31c5Sopenharmony_ci if (buffer == NULL || size == NULL || *size == 0) 976e66f31c5Sopenharmony_ci return UV_EINVAL; 977e66f31c5Sopenharmony_ci 978e66f31c5Sopenharmony_ci len = 0; 979e66f31c5Sopenharmony_ci len = GetTempPathW(0, NULL); 980e66f31c5Sopenharmony_ci if (len == 0) { 981e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 982e66f31c5Sopenharmony_ci } 983e66f31c5Sopenharmony_ci /* Include space for terminating null char. */ 984e66f31c5Sopenharmony_ci len += 1; 985e66f31c5Sopenharmony_ci path = uv__malloc(len * sizeof(wchar_t)); 986e66f31c5Sopenharmony_ci if (path == NULL) { 987e66f31c5Sopenharmony_ci return UV_ENOMEM; 988e66f31c5Sopenharmony_ci } 989e66f31c5Sopenharmony_ci len = GetTempPathW(len, path); 990e66f31c5Sopenharmony_ci 991e66f31c5Sopenharmony_ci if (len == 0) { 992e66f31c5Sopenharmony_ci uv__free(path); 993e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 994e66f31c5Sopenharmony_ci } 995e66f31c5Sopenharmony_ci 996e66f31c5Sopenharmony_ci /* The returned directory should not have a trailing slash, unless it points 997e66f31c5Sopenharmony_ci * at a drive root, like c:\. Remove it if needed. */ 998e66f31c5Sopenharmony_ci if (path[len - 1] == L'\\' && 999e66f31c5Sopenharmony_ci !(len == 3 && path[1] == L':')) { 1000e66f31c5Sopenharmony_ci len--; 1001e66f31c5Sopenharmony_ci path[len] = L'\0'; 1002e66f31c5Sopenharmony_ci } 1003e66f31c5Sopenharmony_ci 1004e66f31c5Sopenharmony_ci return uv__copy_utf16_to_utf8(path, len, buffer, size); 1005e66f31c5Sopenharmony_ci} 1006e66f31c5Sopenharmony_ci 1007e66f31c5Sopenharmony_ci 1008e66f31c5Sopenharmony_ci/* 1009e66f31c5Sopenharmony_ci * Converts a UTF-16 string into a UTF-8 one. The resulting string is 1010e66f31c5Sopenharmony_ci * null-terminated. 1011e66f31c5Sopenharmony_ci * 1012e66f31c5Sopenharmony_ci * If utf16 is null terminated, utf16len can be set to -1, otherwise it must 1013e66f31c5Sopenharmony_ci * be specified. 1014e66f31c5Sopenharmony_ci */ 1015e66f31c5Sopenharmony_ciint uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8) { 1016e66f31c5Sopenharmony_ci size_t utf8_len = 0; 1017e66f31c5Sopenharmony_ci 1018e66f31c5Sopenharmony_ci if (utf16 == NULL) 1019e66f31c5Sopenharmony_ci return UV_EINVAL; 1020e66f31c5Sopenharmony_ci 1021e66f31c5Sopenharmony_ci *utf8 = NULL; 1022e66f31c5Sopenharmony_ci return uv_utf16_to_wtf8(utf16, utf16len, utf8, &utf8_len); 1023e66f31c5Sopenharmony_ci} 1024e66f31c5Sopenharmony_ci 1025e66f31c5Sopenharmony_ci 1026e66f31c5Sopenharmony_ci/* 1027e66f31c5Sopenharmony_ci * Converts a UTF-8 string into a UTF-16 one. The resulting string is 1028e66f31c5Sopenharmony_ci * null-terminated. 1029e66f31c5Sopenharmony_ci */ 1030e66f31c5Sopenharmony_ciint uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16) { 1031e66f31c5Sopenharmony_ci int bufsize; 1032e66f31c5Sopenharmony_ci 1033e66f31c5Sopenharmony_ci if (utf8 == NULL) 1034e66f31c5Sopenharmony_ci return UV_EINVAL; 1035e66f31c5Sopenharmony_ci 1036e66f31c5Sopenharmony_ci /* Check how much space we need (including NUL). */ 1037e66f31c5Sopenharmony_ci bufsize = uv_wtf8_length_as_utf16(utf8); 1038e66f31c5Sopenharmony_ci if (bufsize < 0) 1039e66f31c5Sopenharmony_ci return UV__EINVAL; 1040e66f31c5Sopenharmony_ci 1041e66f31c5Sopenharmony_ci /* Allocate the destination buffer. */ 1042e66f31c5Sopenharmony_ci *utf16 = uv__malloc(sizeof(WCHAR) * bufsize); 1043e66f31c5Sopenharmony_ci 1044e66f31c5Sopenharmony_ci if (*utf16 == NULL) 1045e66f31c5Sopenharmony_ci return UV_ENOMEM; 1046e66f31c5Sopenharmony_ci 1047e66f31c5Sopenharmony_ci /* Convert to UTF-16 */ 1048e66f31c5Sopenharmony_ci uv_wtf8_to_utf16(utf8, *utf16, bufsize); 1049e66f31c5Sopenharmony_ci 1050e66f31c5Sopenharmony_ci return 0; 1051e66f31c5Sopenharmony_ci} 1052e66f31c5Sopenharmony_ci 1053e66f31c5Sopenharmony_ci 1054e66f31c5Sopenharmony_ci/* 1055e66f31c5Sopenharmony_ci * Converts a UTF-16 string into a UTF-8 one in an existing buffer. The 1056e66f31c5Sopenharmony_ci * resulting string is null-terminated. 1057e66f31c5Sopenharmony_ci * 1058e66f31c5Sopenharmony_ci * If utf16 is null terminated, utf16len can be set to -1, otherwise it must 1059e66f31c5Sopenharmony_ci * be specified. 1060e66f31c5Sopenharmony_ci */ 1061e66f31c5Sopenharmony_ciint uv__copy_utf16_to_utf8(const WCHAR* utf16buffer, size_t utf16len, char* utf8, size_t *size) { 1062e66f31c5Sopenharmony_ci int r; 1063e66f31c5Sopenharmony_ci 1064e66f31c5Sopenharmony_ci if (utf8 == NULL || size == NULL) 1065e66f31c5Sopenharmony_ci return UV_EINVAL; 1066e66f31c5Sopenharmony_ci 1067e66f31c5Sopenharmony_ci if (*size == 0) { 1068e66f31c5Sopenharmony_ci *size = uv_utf16_length_as_wtf8(utf16buffer, utf16len); 1069e66f31c5Sopenharmony_ci r = UV_ENOBUFS; 1070e66f31c5Sopenharmony_ci } else { 1071e66f31c5Sopenharmony_ci *size -= 1; /* Reserve space for NUL. */ 1072e66f31c5Sopenharmony_ci r = uv_utf16_to_wtf8(utf16buffer, utf16len, &utf8, size); 1073e66f31c5Sopenharmony_ci } 1074e66f31c5Sopenharmony_ci if (r == UV_ENOBUFS) 1075e66f31c5Sopenharmony_ci *size += 1; /* Add space for NUL. */ 1076e66f31c5Sopenharmony_ci return r; 1077e66f31c5Sopenharmony_ci} 1078e66f31c5Sopenharmony_ci 1079e66f31c5Sopenharmony_ci 1080e66f31c5Sopenharmony_cistatic int uv__getpwuid_r(uv_passwd_t* pwd) { 1081e66f31c5Sopenharmony_ci HANDLE token; 1082e66f31c5Sopenharmony_ci wchar_t username[UNLEN + 1]; 1083e66f31c5Sopenharmony_ci wchar_t *path; 1084e66f31c5Sopenharmony_ci DWORD bufsize; 1085e66f31c5Sopenharmony_ci int r; 1086e66f31c5Sopenharmony_ci 1087e66f31c5Sopenharmony_ci if (pwd == NULL) 1088e66f31c5Sopenharmony_ci return UV_EINVAL; 1089e66f31c5Sopenharmony_ci 1090e66f31c5Sopenharmony_ci /* Get the home directory using GetUserProfileDirectoryW() */ 1091e66f31c5Sopenharmony_ci if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0) 1092e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 1093e66f31c5Sopenharmony_ci 1094e66f31c5Sopenharmony_ci bufsize = 0; 1095e66f31c5Sopenharmony_ci GetUserProfileDirectoryW(token, NULL, &bufsize); 1096e66f31c5Sopenharmony_ci if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 1097e66f31c5Sopenharmony_ci r = GetLastError(); 1098e66f31c5Sopenharmony_ci CloseHandle(token); 1099e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 1100e66f31c5Sopenharmony_ci } 1101e66f31c5Sopenharmony_ci 1102e66f31c5Sopenharmony_ci path = uv__malloc(bufsize * sizeof(wchar_t)); 1103e66f31c5Sopenharmony_ci if (path == NULL) { 1104e66f31c5Sopenharmony_ci CloseHandle(token); 1105e66f31c5Sopenharmony_ci return UV_ENOMEM; 1106e66f31c5Sopenharmony_ci } 1107e66f31c5Sopenharmony_ci 1108e66f31c5Sopenharmony_ci if (!GetUserProfileDirectoryW(token, path, &bufsize)) { 1109e66f31c5Sopenharmony_ci r = GetLastError(); 1110e66f31c5Sopenharmony_ci CloseHandle(token); 1111e66f31c5Sopenharmony_ci uv__free(path); 1112e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 1113e66f31c5Sopenharmony_ci } 1114e66f31c5Sopenharmony_ci 1115e66f31c5Sopenharmony_ci CloseHandle(token); 1116e66f31c5Sopenharmony_ci 1117e66f31c5Sopenharmony_ci /* Get the username using GetUserNameW() */ 1118e66f31c5Sopenharmony_ci bufsize = ARRAY_SIZE(username); 1119e66f31c5Sopenharmony_ci if (!GetUserNameW(username, &bufsize)) { 1120e66f31c5Sopenharmony_ci r = GetLastError(); 1121e66f31c5Sopenharmony_ci uv__free(path); 1122e66f31c5Sopenharmony_ci 1123e66f31c5Sopenharmony_ci /* This should not be possible */ 1124e66f31c5Sopenharmony_ci if (r == ERROR_INSUFFICIENT_BUFFER) 1125e66f31c5Sopenharmony_ci return UV_ENOMEM; 1126e66f31c5Sopenharmony_ci 1127e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 1128e66f31c5Sopenharmony_ci } 1129e66f31c5Sopenharmony_ci 1130e66f31c5Sopenharmony_ci pwd->homedir = NULL; 1131e66f31c5Sopenharmony_ci r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir); 1132e66f31c5Sopenharmony_ci uv__free(path); 1133e66f31c5Sopenharmony_ci 1134e66f31c5Sopenharmony_ci if (r != 0) 1135e66f31c5Sopenharmony_ci return r; 1136e66f31c5Sopenharmony_ci 1137e66f31c5Sopenharmony_ci pwd->username = NULL; 1138e66f31c5Sopenharmony_ci r = uv__convert_utf16_to_utf8(username, -1, &pwd->username); 1139e66f31c5Sopenharmony_ci 1140e66f31c5Sopenharmony_ci if (r != 0) { 1141e66f31c5Sopenharmony_ci uv__free(pwd->homedir); 1142e66f31c5Sopenharmony_ci return r; 1143e66f31c5Sopenharmony_ci } 1144e66f31c5Sopenharmony_ci 1145e66f31c5Sopenharmony_ci pwd->shell = NULL; 1146e66f31c5Sopenharmony_ci pwd->uid = -1; 1147e66f31c5Sopenharmony_ci pwd->gid = -1; 1148e66f31c5Sopenharmony_ci 1149e66f31c5Sopenharmony_ci return 0; 1150e66f31c5Sopenharmony_ci} 1151e66f31c5Sopenharmony_ci 1152e66f31c5Sopenharmony_ci 1153e66f31c5Sopenharmony_ciint uv_os_get_passwd(uv_passwd_t* pwd) { 1154e66f31c5Sopenharmony_ci return uv__getpwuid_r(pwd); 1155e66f31c5Sopenharmony_ci} 1156e66f31c5Sopenharmony_ci 1157e66f31c5Sopenharmony_ci 1158e66f31c5Sopenharmony_ciint uv_os_get_passwd2(uv_passwd_t* pwd, uv_uid_t uid) { 1159e66f31c5Sopenharmony_ci return UV_ENOTSUP; 1160e66f31c5Sopenharmony_ci} 1161e66f31c5Sopenharmony_ci 1162e66f31c5Sopenharmony_ci 1163e66f31c5Sopenharmony_ciint uv_os_get_group(uv_group_t* grp, uv_uid_t gid) { 1164e66f31c5Sopenharmony_ci return UV_ENOTSUP; 1165e66f31c5Sopenharmony_ci} 1166e66f31c5Sopenharmony_ci 1167e66f31c5Sopenharmony_ci 1168e66f31c5Sopenharmony_ciint uv_os_environ(uv_env_item_t** envitems, int* count) { 1169e66f31c5Sopenharmony_ci wchar_t* env; 1170e66f31c5Sopenharmony_ci wchar_t* penv; 1171e66f31c5Sopenharmony_ci int i, cnt; 1172e66f31c5Sopenharmony_ci uv_env_item_t* envitem; 1173e66f31c5Sopenharmony_ci 1174e66f31c5Sopenharmony_ci *envitems = NULL; 1175e66f31c5Sopenharmony_ci *count = 0; 1176e66f31c5Sopenharmony_ci 1177e66f31c5Sopenharmony_ci env = GetEnvironmentStringsW(); 1178e66f31c5Sopenharmony_ci if (env == NULL) 1179e66f31c5Sopenharmony_ci return 0; 1180e66f31c5Sopenharmony_ci 1181e66f31c5Sopenharmony_ci for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++); 1182e66f31c5Sopenharmony_ci 1183e66f31c5Sopenharmony_ci *envitems = uv__calloc(i, sizeof(**envitems)); 1184e66f31c5Sopenharmony_ci if (*envitems == NULL) { 1185e66f31c5Sopenharmony_ci FreeEnvironmentStringsW(env); 1186e66f31c5Sopenharmony_ci return UV_ENOMEM; 1187e66f31c5Sopenharmony_ci } 1188e66f31c5Sopenharmony_ci 1189e66f31c5Sopenharmony_ci penv = env; 1190e66f31c5Sopenharmony_ci cnt = 0; 1191e66f31c5Sopenharmony_ci 1192e66f31c5Sopenharmony_ci while (*penv != L'\0' && cnt < i) { 1193e66f31c5Sopenharmony_ci char* buf; 1194e66f31c5Sopenharmony_ci char* ptr; 1195e66f31c5Sopenharmony_ci 1196e66f31c5Sopenharmony_ci if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0) 1197e66f31c5Sopenharmony_ci goto fail; 1198e66f31c5Sopenharmony_ci 1199e66f31c5Sopenharmony_ci /* Using buf + 1 here because we know that `buf` has length at least 1, 1200e66f31c5Sopenharmony_ci * and some special environment variables on Windows start with a = sign. */ 1201e66f31c5Sopenharmony_ci ptr = strchr(buf + 1, '='); 1202e66f31c5Sopenharmony_ci if (ptr == NULL) { 1203e66f31c5Sopenharmony_ci uv__free(buf); 1204e66f31c5Sopenharmony_ci goto do_continue; 1205e66f31c5Sopenharmony_ci } 1206e66f31c5Sopenharmony_ci 1207e66f31c5Sopenharmony_ci *ptr = '\0'; 1208e66f31c5Sopenharmony_ci 1209e66f31c5Sopenharmony_ci envitem = &(*envitems)[cnt]; 1210e66f31c5Sopenharmony_ci envitem->name = buf; 1211e66f31c5Sopenharmony_ci envitem->value = ptr + 1; 1212e66f31c5Sopenharmony_ci 1213e66f31c5Sopenharmony_ci cnt++; 1214e66f31c5Sopenharmony_ci 1215e66f31c5Sopenharmony_ci do_continue: 1216e66f31c5Sopenharmony_ci penv += wcslen(penv) + 1; 1217e66f31c5Sopenharmony_ci } 1218e66f31c5Sopenharmony_ci 1219e66f31c5Sopenharmony_ci FreeEnvironmentStringsW(env); 1220e66f31c5Sopenharmony_ci 1221e66f31c5Sopenharmony_ci *count = cnt; 1222e66f31c5Sopenharmony_ci return 0; 1223e66f31c5Sopenharmony_ci 1224e66f31c5Sopenharmony_cifail: 1225e66f31c5Sopenharmony_ci FreeEnvironmentStringsW(env); 1226e66f31c5Sopenharmony_ci 1227e66f31c5Sopenharmony_ci for (i = 0; i < cnt; i++) { 1228e66f31c5Sopenharmony_ci envitem = &(*envitems)[cnt]; 1229e66f31c5Sopenharmony_ci uv__free(envitem->name); 1230e66f31c5Sopenharmony_ci } 1231e66f31c5Sopenharmony_ci uv__free(*envitems); 1232e66f31c5Sopenharmony_ci 1233e66f31c5Sopenharmony_ci *envitems = NULL; 1234e66f31c5Sopenharmony_ci *count = 0; 1235e66f31c5Sopenharmony_ci return UV_ENOMEM; 1236e66f31c5Sopenharmony_ci} 1237e66f31c5Sopenharmony_ci 1238e66f31c5Sopenharmony_ci 1239e66f31c5Sopenharmony_ciint uv_os_getenv(const char* name, char* buffer, size_t* size) { 1240e66f31c5Sopenharmony_ci wchar_t fastvar[512]; 1241e66f31c5Sopenharmony_ci wchar_t* var; 1242e66f31c5Sopenharmony_ci DWORD varlen; 1243e66f31c5Sopenharmony_ci wchar_t* name_w; 1244e66f31c5Sopenharmony_ci size_t len; 1245e66f31c5Sopenharmony_ci int r; 1246e66f31c5Sopenharmony_ci 1247e66f31c5Sopenharmony_ci if (name == NULL || buffer == NULL || size == NULL || *size == 0) 1248e66f31c5Sopenharmony_ci return UV_EINVAL; 1249e66f31c5Sopenharmony_ci 1250e66f31c5Sopenharmony_ci r = uv__convert_utf8_to_utf16(name, &name_w); 1251e66f31c5Sopenharmony_ci 1252e66f31c5Sopenharmony_ci if (r != 0) 1253e66f31c5Sopenharmony_ci return r; 1254e66f31c5Sopenharmony_ci 1255e66f31c5Sopenharmony_ci var = fastvar; 1256e66f31c5Sopenharmony_ci varlen = ARRAY_SIZE(fastvar); 1257e66f31c5Sopenharmony_ci 1258e66f31c5Sopenharmony_ci for (;;) { 1259e66f31c5Sopenharmony_ci SetLastError(ERROR_SUCCESS); 1260e66f31c5Sopenharmony_ci len = GetEnvironmentVariableW(name_w, var, varlen); 1261e66f31c5Sopenharmony_ci 1262e66f31c5Sopenharmony_ci if (len < varlen) 1263e66f31c5Sopenharmony_ci break; 1264e66f31c5Sopenharmony_ci 1265e66f31c5Sopenharmony_ci /* Try repeatedly because we might have been preempted by another thread 1266e66f31c5Sopenharmony_ci * modifying the environment variable just as we're trying to read it. 1267e66f31c5Sopenharmony_ci */ 1268e66f31c5Sopenharmony_ci if (var != fastvar) 1269e66f31c5Sopenharmony_ci uv__free(var); 1270e66f31c5Sopenharmony_ci 1271e66f31c5Sopenharmony_ci varlen = 1 + len; 1272e66f31c5Sopenharmony_ci var = uv__malloc(varlen * sizeof(*var)); 1273e66f31c5Sopenharmony_ci 1274e66f31c5Sopenharmony_ci if (var == NULL) { 1275e66f31c5Sopenharmony_ci r = UV_ENOMEM; 1276e66f31c5Sopenharmony_ci goto fail; 1277e66f31c5Sopenharmony_ci } 1278e66f31c5Sopenharmony_ci } 1279e66f31c5Sopenharmony_ci 1280e66f31c5Sopenharmony_ci uv__free(name_w); 1281e66f31c5Sopenharmony_ci name_w = NULL; 1282e66f31c5Sopenharmony_ci 1283e66f31c5Sopenharmony_ci if (len == 0) { 1284e66f31c5Sopenharmony_ci r = GetLastError(); 1285e66f31c5Sopenharmony_ci if (r != ERROR_SUCCESS) { 1286e66f31c5Sopenharmony_ci r = uv_translate_sys_error(r); 1287e66f31c5Sopenharmony_ci goto fail; 1288e66f31c5Sopenharmony_ci } 1289e66f31c5Sopenharmony_ci } 1290e66f31c5Sopenharmony_ci 1291e66f31c5Sopenharmony_ci r = uv__copy_utf16_to_utf8(var, len, buffer, size); 1292e66f31c5Sopenharmony_ci 1293e66f31c5Sopenharmony_cifail: 1294e66f31c5Sopenharmony_ci 1295e66f31c5Sopenharmony_ci if (name_w != NULL) 1296e66f31c5Sopenharmony_ci uv__free(name_w); 1297e66f31c5Sopenharmony_ci 1298e66f31c5Sopenharmony_ci if (var != fastvar) 1299e66f31c5Sopenharmony_ci uv__free(var); 1300e66f31c5Sopenharmony_ci 1301e66f31c5Sopenharmony_ci return r; 1302e66f31c5Sopenharmony_ci} 1303e66f31c5Sopenharmony_ci 1304e66f31c5Sopenharmony_ci 1305e66f31c5Sopenharmony_ciint uv_os_setenv(const char* name, const char* value) { 1306e66f31c5Sopenharmony_ci wchar_t* name_w; 1307e66f31c5Sopenharmony_ci wchar_t* value_w; 1308e66f31c5Sopenharmony_ci int r; 1309e66f31c5Sopenharmony_ci 1310e66f31c5Sopenharmony_ci if (name == NULL || value == NULL) 1311e66f31c5Sopenharmony_ci return UV_EINVAL; 1312e66f31c5Sopenharmony_ci 1313e66f31c5Sopenharmony_ci r = uv__convert_utf8_to_utf16(name, &name_w); 1314e66f31c5Sopenharmony_ci 1315e66f31c5Sopenharmony_ci if (r != 0) 1316e66f31c5Sopenharmony_ci return r; 1317e66f31c5Sopenharmony_ci 1318e66f31c5Sopenharmony_ci r = uv__convert_utf8_to_utf16(value, &value_w); 1319e66f31c5Sopenharmony_ci 1320e66f31c5Sopenharmony_ci if (r != 0) { 1321e66f31c5Sopenharmony_ci uv__free(name_w); 1322e66f31c5Sopenharmony_ci return r; 1323e66f31c5Sopenharmony_ci } 1324e66f31c5Sopenharmony_ci 1325e66f31c5Sopenharmony_ci r = SetEnvironmentVariableW(name_w, value_w); 1326e66f31c5Sopenharmony_ci uv__free(name_w); 1327e66f31c5Sopenharmony_ci uv__free(value_w); 1328e66f31c5Sopenharmony_ci 1329e66f31c5Sopenharmony_ci if (r == 0) 1330e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 1331e66f31c5Sopenharmony_ci 1332e66f31c5Sopenharmony_ci return 0; 1333e66f31c5Sopenharmony_ci} 1334e66f31c5Sopenharmony_ci 1335e66f31c5Sopenharmony_ci 1336e66f31c5Sopenharmony_ciint uv_os_unsetenv(const char* name) { 1337e66f31c5Sopenharmony_ci wchar_t* name_w; 1338e66f31c5Sopenharmony_ci int r; 1339e66f31c5Sopenharmony_ci 1340e66f31c5Sopenharmony_ci if (name == NULL) 1341e66f31c5Sopenharmony_ci return UV_EINVAL; 1342e66f31c5Sopenharmony_ci 1343e66f31c5Sopenharmony_ci r = uv__convert_utf8_to_utf16(name, &name_w); 1344e66f31c5Sopenharmony_ci 1345e66f31c5Sopenharmony_ci if (r != 0) 1346e66f31c5Sopenharmony_ci return r; 1347e66f31c5Sopenharmony_ci 1348e66f31c5Sopenharmony_ci r = SetEnvironmentVariableW(name_w, NULL); 1349e66f31c5Sopenharmony_ci uv__free(name_w); 1350e66f31c5Sopenharmony_ci 1351e66f31c5Sopenharmony_ci if (r == 0) 1352e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 1353e66f31c5Sopenharmony_ci 1354e66f31c5Sopenharmony_ci return 0; 1355e66f31c5Sopenharmony_ci} 1356e66f31c5Sopenharmony_ci 1357e66f31c5Sopenharmony_ci 1358e66f31c5Sopenharmony_ciint uv_os_gethostname(char* buffer, size_t* size) { 1359e66f31c5Sopenharmony_ci WCHAR buf[UV_MAXHOSTNAMESIZE]; 1360e66f31c5Sopenharmony_ci 1361e66f31c5Sopenharmony_ci if (buffer == NULL || size == NULL || *size == 0) 1362e66f31c5Sopenharmony_ci return UV_EINVAL; 1363e66f31c5Sopenharmony_ci 1364e66f31c5Sopenharmony_ci uv__once_init(); /* Initialize winsock */ 1365e66f31c5Sopenharmony_ci 1366e66f31c5Sopenharmony_ci if (pGetHostNameW == NULL) 1367e66f31c5Sopenharmony_ci return UV_ENOSYS; 1368e66f31c5Sopenharmony_ci 1369e66f31c5Sopenharmony_ci if (pGetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0) 1370e66f31c5Sopenharmony_ci return uv_translate_sys_error(WSAGetLastError()); 1371e66f31c5Sopenharmony_ci 1372e66f31c5Sopenharmony_ci return uv__copy_utf16_to_utf8(buf, -1, buffer, size); 1373e66f31c5Sopenharmony_ci} 1374e66f31c5Sopenharmony_ci 1375e66f31c5Sopenharmony_ci 1376e66f31c5Sopenharmony_cistatic int uv__get_handle(uv_pid_t pid, int access, HANDLE* handle) { 1377e66f31c5Sopenharmony_ci int r; 1378e66f31c5Sopenharmony_ci 1379e66f31c5Sopenharmony_ci if (pid == 0) 1380e66f31c5Sopenharmony_ci *handle = GetCurrentProcess(); 1381e66f31c5Sopenharmony_ci else 1382e66f31c5Sopenharmony_ci *handle = OpenProcess(access, FALSE, pid); 1383e66f31c5Sopenharmony_ci 1384e66f31c5Sopenharmony_ci if (*handle == NULL) { 1385e66f31c5Sopenharmony_ci r = GetLastError(); 1386e66f31c5Sopenharmony_ci 1387e66f31c5Sopenharmony_ci if (r == ERROR_INVALID_PARAMETER) 1388e66f31c5Sopenharmony_ci return UV_ESRCH; 1389e66f31c5Sopenharmony_ci else 1390e66f31c5Sopenharmony_ci return uv_translate_sys_error(r); 1391e66f31c5Sopenharmony_ci } 1392e66f31c5Sopenharmony_ci 1393e66f31c5Sopenharmony_ci return 0; 1394e66f31c5Sopenharmony_ci} 1395e66f31c5Sopenharmony_ci 1396e66f31c5Sopenharmony_ci 1397e66f31c5Sopenharmony_ciint uv_os_getpriority(uv_pid_t pid, int* priority) { 1398e66f31c5Sopenharmony_ci HANDLE handle; 1399e66f31c5Sopenharmony_ci int r; 1400e66f31c5Sopenharmony_ci 1401e66f31c5Sopenharmony_ci if (priority == NULL) 1402e66f31c5Sopenharmony_ci return UV_EINVAL; 1403e66f31c5Sopenharmony_ci 1404e66f31c5Sopenharmony_ci r = uv__get_handle(pid, PROCESS_QUERY_LIMITED_INFORMATION, &handle); 1405e66f31c5Sopenharmony_ci 1406e66f31c5Sopenharmony_ci if (r != 0) 1407e66f31c5Sopenharmony_ci return r; 1408e66f31c5Sopenharmony_ci 1409e66f31c5Sopenharmony_ci r = GetPriorityClass(handle); 1410e66f31c5Sopenharmony_ci 1411e66f31c5Sopenharmony_ci if (r == 0) { 1412e66f31c5Sopenharmony_ci r = uv_translate_sys_error(GetLastError()); 1413e66f31c5Sopenharmony_ci } else { 1414e66f31c5Sopenharmony_ci /* Map Windows priority classes to Unix nice values. */ 1415e66f31c5Sopenharmony_ci if (r == REALTIME_PRIORITY_CLASS) 1416e66f31c5Sopenharmony_ci *priority = UV_PRIORITY_HIGHEST; 1417e66f31c5Sopenharmony_ci else if (r == HIGH_PRIORITY_CLASS) 1418e66f31c5Sopenharmony_ci *priority = UV_PRIORITY_HIGH; 1419e66f31c5Sopenharmony_ci else if (r == ABOVE_NORMAL_PRIORITY_CLASS) 1420e66f31c5Sopenharmony_ci *priority = UV_PRIORITY_ABOVE_NORMAL; 1421e66f31c5Sopenharmony_ci else if (r == NORMAL_PRIORITY_CLASS) 1422e66f31c5Sopenharmony_ci *priority = UV_PRIORITY_NORMAL; 1423e66f31c5Sopenharmony_ci else if (r == BELOW_NORMAL_PRIORITY_CLASS) 1424e66f31c5Sopenharmony_ci *priority = UV_PRIORITY_BELOW_NORMAL; 1425e66f31c5Sopenharmony_ci else /* IDLE_PRIORITY_CLASS */ 1426e66f31c5Sopenharmony_ci *priority = UV_PRIORITY_LOW; 1427e66f31c5Sopenharmony_ci 1428e66f31c5Sopenharmony_ci r = 0; 1429e66f31c5Sopenharmony_ci } 1430e66f31c5Sopenharmony_ci 1431e66f31c5Sopenharmony_ci CloseHandle(handle); 1432e66f31c5Sopenharmony_ci return r; 1433e66f31c5Sopenharmony_ci} 1434e66f31c5Sopenharmony_ci 1435e66f31c5Sopenharmony_ci 1436e66f31c5Sopenharmony_ciint uv_os_setpriority(uv_pid_t pid, int priority) { 1437e66f31c5Sopenharmony_ci HANDLE handle; 1438e66f31c5Sopenharmony_ci int priority_class; 1439e66f31c5Sopenharmony_ci int r; 1440e66f31c5Sopenharmony_ci 1441e66f31c5Sopenharmony_ci /* Map Unix nice values to Windows priority classes. */ 1442e66f31c5Sopenharmony_ci if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW) 1443e66f31c5Sopenharmony_ci return UV_EINVAL; 1444e66f31c5Sopenharmony_ci else if (priority < UV_PRIORITY_HIGH) 1445e66f31c5Sopenharmony_ci priority_class = REALTIME_PRIORITY_CLASS; 1446e66f31c5Sopenharmony_ci else if (priority < UV_PRIORITY_ABOVE_NORMAL) 1447e66f31c5Sopenharmony_ci priority_class = HIGH_PRIORITY_CLASS; 1448e66f31c5Sopenharmony_ci else if (priority < UV_PRIORITY_NORMAL) 1449e66f31c5Sopenharmony_ci priority_class = ABOVE_NORMAL_PRIORITY_CLASS; 1450e66f31c5Sopenharmony_ci else if (priority < UV_PRIORITY_BELOW_NORMAL) 1451e66f31c5Sopenharmony_ci priority_class = NORMAL_PRIORITY_CLASS; 1452e66f31c5Sopenharmony_ci else if (priority < UV_PRIORITY_LOW) 1453e66f31c5Sopenharmony_ci priority_class = BELOW_NORMAL_PRIORITY_CLASS; 1454e66f31c5Sopenharmony_ci else 1455e66f31c5Sopenharmony_ci priority_class = IDLE_PRIORITY_CLASS; 1456e66f31c5Sopenharmony_ci 1457e66f31c5Sopenharmony_ci r = uv__get_handle(pid, PROCESS_SET_INFORMATION, &handle); 1458e66f31c5Sopenharmony_ci 1459e66f31c5Sopenharmony_ci if (r != 0) 1460e66f31c5Sopenharmony_ci return r; 1461e66f31c5Sopenharmony_ci 1462e66f31c5Sopenharmony_ci if (SetPriorityClass(handle, priority_class) == 0) 1463e66f31c5Sopenharmony_ci r = uv_translate_sys_error(GetLastError()); 1464e66f31c5Sopenharmony_ci 1465e66f31c5Sopenharmony_ci CloseHandle(handle); 1466e66f31c5Sopenharmony_ci return r; 1467e66f31c5Sopenharmony_ci} 1468e66f31c5Sopenharmony_ci 1469e66f31c5Sopenharmony_ciint uv_thread_getpriority(uv_thread_t tid, int* priority) { 1470e66f31c5Sopenharmony_ci int r; 1471e66f31c5Sopenharmony_ci 1472e66f31c5Sopenharmony_ci if (priority == NULL) 1473e66f31c5Sopenharmony_ci return UV_EINVAL; 1474e66f31c5Sopenharmony_ci 1475e66f31c5Sopenharmony_ci r = GetThreadPriority(tid); 1476e66f31c5Sopenharmony_ci if (r == THREAD_PRIORITY_ERROR_RETURN) 1477e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 1478e66f31c5Sopenharmony_ci 1479e66f31c5Sopenharmony_ci *priority = r; 1480e66f31c5Sopenharmony_ci return 0; 1481e66f31c5Sopenharmony_ci} 1482e66f31c5Sopenharmony_ci 1483e66f31c5Sopenharmony_ciint uv_thread_setpriority(uv_thread_t tid, int priority) { 1484e66f31c5Sopenharmony_ci int r; 1485e66f31c5Sopenharmony_ci 1486e66f31c5Sopenharmony_ci switch (priority) { 1487e66f31c5Sopenharmony_ci case UV_THREAD_PRIORITY_HIGHEST: 1488e66f31c5Sopenharmony_ci r = SetThreadPriority(tid, THREAD_PRIORITY_HIGHEST); 1489e66f31c5Sopenharmony_ci break; 1490e66f31c5Sopenharmony_ci case UV_THREAD_PRIORITY_ABOVE_NORMAL: 1491e66f31c5Sopenharmony_ci r = SetThreadPriority(tid, THREAD_PRIORITY_ABOVE_NORMAL); 1492e66f31c5Sopenharmony_ci break; 1493e66f31c5Sopenharmony_ci case UV_THREAD_PRIORITY_NORMAL: 1494e66f31c5Sopenharmony_ci r = SetThreadPriority(tid, THREAD_PRIORITY_NORMAL); 1495e66f31c5Sopenharmony_ci break; 1496e66f31c5Sopenharmony_ci case UV_THREAD_PRIORITY_BELOW_NORMAL: 1497e66f31c5Sopenharmony_ci r = SetThreadPriority(tid, THREAD_PRIORITY_BELOW_NORMAL); 1498e66f31c5Sopenharmony_ci break; 1499e66f31c5Sopenharmony_ci case UV_THREAD_PRIORITY_LOWEST: 1500e66f31c5Sopenharmony_ci r = SetThreadPriority(tid, THREAD_PRIORITY_LOWEST); 1501e66f31c5Sopenharmony_ci break; 1502e66f31c5Sopenharmony_ci default: 1503e66f31c5Sopenharmony_ci return 0; 1504e66f31c5Sopenharmony_ci } 1505e66f31c5Sopenharmony_ci 1506e66f31c5Sopenharmony_ci if (r == 0) 1507e66f31c5Sopenharmony_ci return uv_translate_sys_error(GetLastError()); 1508e66f31c5Sopenharmony_ci 1509e66f31c5Sopenharmony_ci return 0; 1510e66f31c5Sopenharmony_ci} 1511e66f31c5Sopenharmony_ci 1512e66f31c5Sopenharmony_ciint uv_os_uname(uv_utsname_t* buffer) { 1513e66f31c5Sopenharmony_ci /* Implementation loosely based on 1514e66f31c5Sopenharmony_ci https://github.com/gagern/gnulib/blob/master/lib/uname.c */ 1515e66f31c5Sopenharmony_ci OSVERSIONINFOW os_info; 1516e66f31c5Sopenharmony_ci SYSTEM_INFO system_info; 1517e66f31c5Sopenharmony_ci HKEY registry_key; 1518e66f31c5Sopenharmony_ci WCHAR product_name_w[256]; 1519e66f31c5Sopenharmony_ci DWORD product_name_w_size; 1520e66f31c5Sopenharmony_ci size_t version_size; 1521e66f31c5Sopenharmony_ci int processor_level; 1522e66f31c5Sopenharmony_ci int r; 1523e66f31c5Sopenharmony_ci 1524e66f31c5Sopenharmony_ci if (buffer == NULL) 1525e66f31c5Sopenharmony_ci return UV_EINVAL; 1526e66f31c5Sopenharmony_ci 1527e66f31c5Sopenharmony_ci uv__once_init(); 1528e66f31c5Sopenharmony_ci os_info.dwOSVersionInfoSize = sizeof(os_info); 1529e66f31c5Sopenharmony_ci os_info.szCSDVersion[0] = L'\0'; 1530e66f31c5Sopenharmony_ci 1531e66f31c5Sopenharmony_ci /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx() 1532e66f31c5Sopenharmony_ci if RtlGetVersion() is not available. */ 1533e66f31c5Sopenharmony_ci if (pRtlGetVersion) { 1534e66f31c5Sopenharmony_ci pRtlGetVersion(&os_info); 1535e66f31c5Sopenharmony_ci } else { 1536e66f31c5Sopenharmony_ci /* Silence GetVersionEx() deprecation warning. */ 1537e66f31c5Sopenharmony_ci #ifdef _MSC_VER 1538e66f31c5Sopenharmony_ci #pragma warning(suppress : 4996) 1539e66f31c5Sopenharmony_ci #endif 1540e66f31c5Sopenharmony_ci if (GetVersionExW(&os_info) == 0) { 1541e66f31c5Sopenharmony_ci r = uv_translate_sys_error(GetLastError()); 1542e66f31c5Sopenharmony_ci goto error; 1543e66f31c5Sopenharmony_ci } 1544e66f31c5Sopenharmony_ci } 1545e66f31c5Sopenharmony_ci 1546e66f31c5Sopenharmony_ci /* Populate the version field. */ 1547e66f31c5Sopenharmony_ci version_size = 0; 1548e66f31c5Sopenharmony_ci r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 1549e66f31c5Sopenharmony_ci L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 1550e66f31c5Sopenharmony_ci 0, 1551e66f31c5Sopenharmony_ci KEY_QUERY_VALUE | KEY_WOW64_64KEY, 1552e66f31c5Sopenharmony_ci ®istry_key); 1553e66f31c5Sopenharmony_ci 1554e66f31c5Sopenharmony_ci if (r == ERROR_SUCCESS) { 1555e66f31c5Sopenharmony_ci product_name_w_size = sizeof(product_name_w); 1556e66f31c5Sopenharmony_ci r = RegGetValueW(registry_key, 1557e66f31c5Sopenharmony_ci NULL, 1558e66f31c5Sopenharmony_ci L"ProductName", 1559e66f31c5Sopenharmony_ci RRF_RT_REG_SZ, 1560e66f31c5Sopenharmony_ci NULL, 1561e66f31c5Sopenharmony_ci (PVOID) product_name_w, 1562e66f31c5Sopenharmony_ci &product_name_w_size); 1563e66f31c5Sopenharmony_ci RegCloseKey(registry_key); 1564e66f31c5Sopenharmony_ci 1565e66f31c5Sopenharmony_ci if (r == ERROR_SUCCESS) { 1566e66f31c5Sopenharmony_ci /* Windows 11 shares dwMajorVersion with Windows 10 1567e66f31c5Sopenharmony_ci * this workaround tries to disambiguate that by checking 1568e66f31c5Sopenharmony_ci * if the dwBuildNumber is from Windows 11 releases (>= 22000). 1569e66f31c5Sopenharmony_ci * 1570e66f31c5Sopenharmony_ci * This workaround replaces the ProductName key value 1571e66f31c5Sopenharmony_ci * from "Windows 10 *" to "Windows 11 *" */ 1572e66f31c5Sopenharmony_ci if (os_info.dwMajorVersion == 10 && 1573e66f31c5Sopenharmony_ci os_info.dwBuildNumber >= 22000 && 1574e66f31c5Sopenharmony_ci product_name_w_size >= ARRAY_SIZE(L"Windows 10")) { 1575e66f31c5Sopenharmony_ci /* If ProductName starts with "Windows 10" */ 1576e66f31c5Sopenharmony_ci if (wcsncmp(product_name_w, L"Windows 10", ARRAY_SIZE(L"Windows 10") - 1) == 0) { 1577e66f31c5Sopenharmony_ci /* Bump 10 to 11 */ 1578e66f31c5Sopenharmony_ci product_name_w[9] = '1'; 1579e66f31c5Sopenharmony_ci } 1580e66f31c5Sopenharmony_ci } 1581e66f31c5Sopenharmony_ci 1582e66f31c5Sopenharmony_ci version_size = sizeof(buffer->version); 1583e66f31c5Sopenharmony_ci r = uv__copy_utf16_to_utf8(product_name_w, 1584e66f31c5Sopenharmony_ci -1, 1585e66f31c5Sopenharmony_ci buffer->version, 1586e66f31c5Sopenharmony_ci &version_size); 1587e66f31c5Sopenharmony_ci if (r) 1588e66f31c5Sopenharmony_ci goto error; 1589e66f31c5Sopenharmony_ci } 1590e66f31c5Sopenharmony_ci } 1591e66f31c5Sopenharmony_ci 1592e66f31c5Sopenharmony_ci /* Append service pack information to the version if present. */ 1593e66f31c5Sopenharmony_ci if (os_info.szCSDVersion[0] != L'\0') { 1594e66f31c5Sopenharmony_ci if (version_size > 0) 1595e66f31c5Sopenharmony_ci buffer->version[version_size++] = ' '; 1596e66f31c5Sopenharmony_ci 1597e66f31c5Sopenharmony_ci version_size = sizeof(buffer->version) - version_size; 1598e66f31c5Sopenharmony_ci r = uv__copy_utf16_to_utf8(os_info.szCSDVersion, 1599e66f31c5Sopenharmony_ci -1, 1600e66f31c5Sopenharmony_ci buffer->version + 1601e66f31c5Sopenharmony_ci sizeof(buffer->version) - version_size, 1602e66f31c5Sopenharmony_ci &version_size); 1603e66f31c5Sopenharmony_ci if (r) 1604e66f31c5Sopenharmony_ci goto error; 1605e66f31c5Sopenharmony_ci } 1606e66f31c5Sopenharmony_ci 1607e66f31c5Sopenharmony_ci /* Populate the sysname field. */ 1608e66f31c5Sopenharmony_ci#ifdef __MINGW32__ 1609e66f31c5Sopenharmony_ci r = snprintf(buffer->sysname, 1610e66f31c5Sopenharmony_ci sizeof(buffer->sysname), 1611e66f31c5Sopenharmony_ci "MINGW32_NT-%u.%u", 1612e66f31c5Sopenharmony_ci (unsigned int) os_info.dwMajorVersion, 1613e66f31c5Sopenharmony_ci (unsigned int) os_info.dwMinorVersion); 1614e66f31c5Sopenharmony_ci assert((size_t)r < sizeof(buffer->sysname)); 1615e66f31c5Sopenharmony_ci#else 1616e66f31c5Sopenharmony_ci uv__strscpy(buffer->sysname, "Windows_NT", sizeof(buffer->sysname)); 1617e66f31c5Sopenharmony_ci#endif 1618e66f31c5Sopenharmony_ci 1619e66f31c5Sopenharmony_ci /* Populate the release field. */ 1620e66f31c5Sopenharmony_ci r = snprintf(buffer->release, 1621e66f31c5Sopenharmony_ci sizeof(buffer->release), 1622e66f31c5Sopenharmony_ci "%d.%d.%d", 1623e66f31c5Sopenharmony_ci (unsigned int) os_info.dwMajorVersion, 1624e66f31c5Sopenharmony_ci (unsigned int) os_info.dwMinorVersion, 1625e66f31c5Sopenharmony_ci (unsigned int) os_info.dwBuildNumber); 1626e66f31c5Sopenharmony_ci assert((size_t)r < sizeof(buffer->release)); 1627e66f31c5Sopenharmony_ci 1628e66f31c5Sopenharmony_ci /* Populate the machine field. */ 1629e66f31c5Sopenharmony_ci GetSystemInfo(&system_info); 1630e66f31c5Sopenharmony_ci 1631e66f31c5Sopenharmony_ci switch (system_info.wProcessorArchitecture) { 1632e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_AMD64: 1633e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "x86_64", sizeof(buffer->machine)); 1634e66f31c5Sopenharmony_ci break; 1635e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_IA64: 1636e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "ia64", sizeof(buffer->machine)); 1637e66f31c5Sopenharmony_ci break; 1638e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_INTEL: 1639e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "i386", sizeof(buffer->machine)); 1640e66f31c5Sopenharmony_ci 1641e66f31c5Sopenharmony_ci if (system_info.wProcessorLevel > 3) { 1642e66f31c5Sopenharmony_ci processor_level = system_info.wProcessorLevel < 6 ? 1643e66f31c5Sopenharmony_ci system_info.wProcessorLevel : 6; 1644e66f31c5Sopenharmony_ci buffer->machine[1] = '0' + processor_level; 1645e66f31c5Sopenharmony_ci } 1646e66f31c5Sopenharmony_ci 1647e66f31c5Sopenharmony_ci break; 1648e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: 1649e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "i686", sizeof(buffer->machine)); 1650e66f31c5Sopenharmony_ci break; 1651e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_MIPS: 1652e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "mips", sizeof(buffer->machine)); 1653e66f31c5Sopenharmony_ci break; 1654e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_ALPHA: 1655e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_ALPHA64: 1656e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "alpha", sizeof(buffer->machine)); 1657e66f31c5Sopenharmony_ci break; 1658e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_PPC: 1659e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "powerpc", sizeof(buffer->machine)); 1660e66f31c5Sopenharmony_ci break; 1661e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_SHX: 1662e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "sh", sizeof(buffer->machine)); 1663e66f31c5Sopenharmony_ci break; 1664e66f31c5Sopenharmony_ci case PROCESSOR_ARCHITECTURE_ARM: 1665e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine)); 1666e66f31c5Sopenharmony_ci break; 1667e66f31c5Sopenharmony_ci default: 1668e66f31c5Sopenharmony_ci uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine)); 1669e66f31c5Sopenharmony_ci break; 1670e66f31c5Sopenharmony_ci } 1671e66f31c5Sopenharmony_ci 1672e66f31c5Sopenharmony_ci return 0; 1673e66f31c5Sopenharmony_ci 1674e66f31c5Sopenharmony_cierror: 1675e66f31c5Sopenharmony_ci buffer->sysname[0] = '\0'; 1676e66f31c5Sopenharmony_ci buffer->release[0] = '\0'; 1677e66f31c5Sopenharmony_ci buffer->version[0] = '\0'; 1678e66f31c5Sopenharmony_ci buffer->machine[0] = '\0'; 1679e66f31c5Sopenharmony_ci return r; 1680e66f31c5Sopenharmony_ci} 1681e66f31c5Sopenharmony_ci 1682e66f31c5Sopenharmony_ciint uv_gettimeofday(uv_timeval64_t* tv) { 1683e66f31c5Sopenharmony_ci /* Based on https://doxygen.postgresql.org/gettimeofday_8c_source.html */ 1684e66f31c5Sopenharmony_ci const uint64_t epoch = (uint64_t) 116444736000000000ULL; 1685e66f31c5Sopenharmony_ci FILETIME file_time; 1686e66f31c5Sopenharmony_ci ULARGE_INTEGER ularge; 1687e66f31c5Sopenharmony_ci 1688e66f31c5Sopenharmony_ci if (tv == NULL) 1689e66f31c5Sopenharmony_ci return UV_EINVAL; 1690e66f31c5Sopenharmony_ci 1691e66f31c5Sopenharmony_ci GetSystemTimeAsFileTime(&file_time); 1692e66f31c5Sopenharmony_ci ularge.LowPart = file_time.dwLowDateTime; 1693e66f31c5Sopenharmony_ci ularge.HighPart = file_time.dwHighDateTime; 1694e66f31c5Sopenharmony_ci tv->tv_sec = (int64_t) ((ularge.QuadPart - epoch) / 10000000L); 1695e66f31c5Sopenharmony_ci tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10); 1696e66f31c5Sopenharmony_ci return 0; 1697e66f31c5Sopenharmony_ci} 1698e66f31c5Sopenharmony_ci 1699e66f31c5Sopenharmony_ciint uv__random_rtlgenrandom(void* buf, size_t buflen) { 1700e66f31c5Sopenharmony_ci if (buflen == 0) 1701e66f31c5Sopenharmony_ci return 0; 1702e66f31c5Sopenharmony_ci 1703e66f31c5Sopenharmony_ci if (SystemFunction036(buf, buflen) == FALSE) 1704e66f31c5Sopenharmony_ci return UV_EIO; 1705e66f31c5Sopenharmony_ci 1706e66f31c5Sopenharmony_ci return 0; 1707e66f31c5Sopenharmony_ci} 1708e66f31c5Sopenharmony_ci 1709e66f31c5Sopenharmony_civoid uv_sleep(unsigned int msec) { 1710e66f31c5Sopenharmony_ci Sleep(msec); 1711e66f31c5Sopenharmony_ci} 1712