52 #define MAX_TITLE_LENGTH 8192
55 #define UV__NANOSEC 1000000000
64 #define MAX_ENV_VAR_LENGTH 32767
81 LARGE_INTEGER perf_frequency;
89 if (QueryPerformanceFrequency(&perf_frequency)) {
98 int utf8_len, utf16_buffer_len, utf16_len;
102 if (
buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
106 if (*size_ptr > 32768) {
108 utf16_buffer_len = 32768;
110 utf16_buffer_len = (
int) *size_ptr;
113 utf16_buffer = (WCHAR*)
uv__malloc(
sizeof(WCHAR) * utf16_buffer_len);
119 utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
120 if (utf16_len <= 0) {
121 err = GetLastError();
126 utf16_buffer[utf16_len] =
L'\0';
129 utf8_len = WideCharToMultiByte(CP_UTF8,
138 err = GetLastError();
146 *size_ptr = utf8_len - 1;
157 WCHAR utf16_buffer[MAX_PATH];
164 utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
165 if (utf16_len == 0) {
167 }
else if (utf16_len > MAX_PATH) {
174 utf16_buffer[utf16_len] =
L'\0';
178 if (utf16_buffer[utf16_len - 1] ==
L'\\' &&
179 !(utf16_len == 3 && utf16_buffer[1] ==
L':')) {
181 utf16_buffer[utf16_len] =
L'\0';
185 r = WideCharToMultiByte(CP_UTF8,
195 }
else if (
r > (
int) *
size) {
201 r = WideCharToMultiByte(CP_UTF8,
206 *
size > INT_MAX ? INT_MAX : (
int) *
size,
219 WCHAR utf16_buffer[MAX_PATH];
221 WCHAR drive_letter,
env_var[4];
227 if (MultiByteToWideChar(CP_UTF8,
233 DWORD
error = GetLastError();
237 if (
error == ERROR_INSUFFICIENT_BUFFER) {
238 return UV_ENAMETOOLONG;
244 if (!SetCurrentDirectoryW(utf16_buffer)) {
251 utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
252 if (utf16_len == 0) {
254 }
else if (utf16_len > MAX_PATH) {
260 if (utf16_buffer[utf16_len - 1] ==
L'\\' &&
261 !(utf16_len == 3 && utf16_buffer[1] ==
L':')) {
263 utf16_buffer[utf16_len] =
L'\0';
266 if (utf16_len < 2 || utf16_buffer[1] !=
L':') {
270 }
else if (utf16_buffer[0] >=
L'A' && utf16_buffer[0] <=
L'Z') {
271 drive_letter = utf16_buffer[0];
272 }
else if (utf16_buffer[0] >=
L'a' && utf16_buffer[0] <=
L'z') {
274 drive_letter = utf16_buffer[0] -
L'a' +
L'A';
280 if (drive_letter != 0) {
287 if (!SetEnvironmentVariableW(
env_var, utf16_buffer)) {
298 avg[0] = avg[1] = avg[2] = 0;
303 MEMORYSTATUSEX memory_status;
304 memory_status.dwLength =
sizeof(memory_status);
306 if (!GlobalMemoryStatusEx(&memory_status)) {
310 return (
uint64_t)memory_status.ullAvailPhys;
315 MEMORYSTATUSEX memory_status;
316 memory_status.dwLength =
sizeof(memory_status);
318 if (!GlobalMemoryStatusEx(&memory_status)) {
322 return (
uint64_t)memory_status.ullTotalPhys;
332 return GetCurrentProcessId();
340 DWORD current_pid = GetCurrentProcessId();
342 pe.dwSize =
sizeof(PROCESSENTRY32);
343 handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
345 if (Process32First(
handle, &pe)) {
347 if (pe.th32ProcessID == current_pid) {
348 parent_pid = pe.th32ParentProcessID;
351 }
while( Process32Next(
handle, &pe));
367 WCHAR* title_w = NULL;
372 length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
374 err = GetLastError();
384 length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w,
length);
386 err = GetLastError();
395 if (!SetConsoleTitleW(title_w)) {
396 err = GetLastError();
416 if (!GetConsoleTitleW(title_w,
sizeof(title_w) /
sizeof(WCHAR))) {
473 if (!QueryPerformanceCounter(&
counter)) {
486 HANDLE current_process;
487 PROCESS_MEMORY_COUNTERS pmc;
489 current_process = GetCurrentProcess();
491 if (!GetProcessMemoryInfo(current_process, &pmc,
sizeof(pmc))) {
495 *rss = pmc.WorkingSetSize;
502 BYTE stack_buffer[4096];
503 BYTE* malloced_buffer = NULL;
504 BYTE*
buffer = (BYTE*) stack_buffer;
508 PERF_DATA_BLOCK* data_block;
509 PERF_OBJECT_TYPE* object_type;
510 PERF_COUNTER_DEFINITION* counter_definition;
518 result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
524 if (
result == ERROR_SUCCESS) {
526 }
else if (
result != ERROR_MORE_DATA) {
540 if (malloced_buffer == NULL) {
546 if (data_size <
sizeof(*data_block))
549 data_block = (PERF_DATA_BLOCK*)
buffer;
551 if (wmemcmp(data_block->Signature,
L"PERF", 4) != 0)
554 if (data_size < data_block->HeaderLength +
sizeof(*object_type))
557 object_type = (PERF_OBJECT_TYPE*) (
buffer + data_block->HeaderLength);
559 if (object_type->NumInstances != PERF_NO_INSTANCES)
562 counter_definition = (PERF_COUNTER_DEFINITION*) (
buffer +
563 data_block->HeaderLength + object_type->HeaderLength);
564 for (
i = 0;
i < object_type->NumCounters;
i++) {
565 if ((BYTE*) counter_definition +
sizeof(*counter_definition) >
570 if (counter_definition->CounterNameTitleIndex == 674 &&
571 counter_definition->CounterSize ==
sizeof(
uint64_t)) {
572 if (counter_definition->CounterOffset +
sizeof(
uint64_t) > data_size ||
573 !(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
576 BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
577 counter_definition->CounterOffset;
579 *uptime = floor((
double) (object_type->PerfTime.QuadPart -
value) /
580 (
double) object_type->PerfFreq.QuadPart);
586 counter_definition = (PERF_COUNTER_DEFINITION*)
587 ((BYTE*) counter_definition + counter_definition->ByteLength);
606 SYSTEM_INFO system_info;
619 GetSystemInfo(&system_info);
620 cpu_count = system_info.dwNumberOfProcessors;
622 cpu_infos =
uv__calloc(cpu_count,
sizeof *cpu_infos);
623 if (cpu_infos == NULL) {
624 err = ERROR_OUTOFMEMORY;
628 sppi_size = cpu_count *
sizeof(*sppi);
631 err = ERROR_OUTOFMEMORY;
644 assert(result_size == sppi_size);
646 for (
i = 0;
i < cpu_count;
i++) {
650 DWORD cpu_speed_size =
sizeof(cpu_speed);
651 WCHAR cpu_brand[256];
652 DWORD cpu_brand_size =
sizeof(cpu_brand);
655 len = _snwprintf(key_name,
657 L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
662 err = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
667 if (
err != ERROR_SUCCESS) {
671 err = RegQueryValueExW(processor_key,
677 if (
err != ERROR_SUCCESS) {
678 RegCloseKey(processor_key);
682 err = RegQueryValueExW(processor_key,
683 L"ProcessorNameString",
688 RegCloseKey(processor_key);
689 if (
err != ERROR_SUCCESS)
692 cpu_info = &cpu_infos[
i];
693 cpu_info->
speed = cpu_speed;
696 sppi[
i].IdleTime.QuadPart) / 10000;
698 cpu_info->
cpu_times.
irq = sppi[
i].InterruptTime.QuadPart / 10000;
702 cpu_brand_size /
sizeof(WCHAR),
708 *cpu_count_ptr = cpu_count;
709 *cpu_infos_ptr = cpu_infos;
714 if (cpu_infos != NULL) {
716 for (
i = 0;
i < cpu_count;
i++)
729 WORD service_pack_major,
730 WORD service_pack_minor) {
731 OSVERSIONINFOEX osvi;
732 DWORDLONG condition_mask = 0;
733 int op = VER_GREATER_EQUAL;
736 ZeroMemory(&osvi,
sizeof(OSVERSIONINFOEX));
737 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFOEX);
738 osvi.dwMajorVersion = os_major;
739 osvi.dwMinorVersion = os_minor;
740 osvi.wServicePackMajor = service_pack_major;
741 osvi.wServicePackMinor = service_pack_minor;
744 VER_SET_CONDITION(condition_mask, VER_MAJORVERSION,
op);
745 VER_SET_CONDITION(condition_mask, VER_MINORVERSION,
op);
746 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR,
op);
747 VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR,
op);
750 return (
int) VerifyVersionInfo(
752 VER_MAJORVERSION | VER_MINORVERSION |
753 VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
759 struct sockaddr* address,
760 struct sockaddr* prefix_address,
766 assert(address->sa_family == family);
767 assert(prefix_address->sa_family == family);
771 prefix_address_data =
774 address_data = (
uint8_t*) &(((
struct sockaddr_in *) address)->sin_addr);
775 prefix_address_data =
776 (
uint8_t*) &(((
struct sockaddr_in *) prefix_address)->sin_addr);
779 for (
i = 0; i < prefix_len >> 3;
i++) {
780 if (address_data[
i] != prefix_address_data[
i])
785 return prefix_address_data[
i] ==
786 (address_data[
i] & (0xff << (8 - prefix_len % 8)));
794 IP_ADAPTER_ADDRESSES* win_address_buf;
795 ULONG win_address_buf_size;
796 IP_ADAPTER_ADDRESSES* adapter;
800 size_t uv_address_buf_size;
805 int is_vista_or_greater;
808 *addresses_ptr = NULL;
812 if (is_vista_or_greater) {
813 flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
814 GAA_FLAG_SKIP_DNS_SERVER;
820 flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
821 GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX;
827 win_address_buf_size = 0;
828 win_address_buf = NULL;
836 r = GetAdaptersAddresses(AF_UNSPEC,
840 &win_address_buf_size);
842 if (
r == ERROR_SUCCESS)
848 case ERROR_BUFFER_OVERFLOW:
851 win_address_buf =
uv__malloc(win_address_buf_size);
852 if (win_address_buf == NULL)
857 case ERROR_NO_DATA: {
860 if (uv_address_buf == NULL)
864 *addresses_ptr = uv_address_buf;
869 case ERROR_ADDRESS_NOT_ASSOCIATED:
872 case ERROR_INVALID_PARAMETER:
886 assert(
r != ERROR_SUCCESS);
894 uv_address_buf_size = 0;
896 for (adapter = win_address_buf;
898 adapter = adapter->Next) {
899 IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
905 if (adapter->OperStatus != IfOperStatusUp ||
906 adapter->FirstUnicastAddress == NULL)
910 name_size = WideCharToMultiByte(CP_UTF8,
912 adapter->FriendlyName,
918 if (name_size <= 0) {
922 uv_address_buf_size += name_size;
926 for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
927 adapter->FirstUnicastAddress;
928 unicast_address != NULL;
929 unicast_address = unicast_address->Next) {
936 uv_address_buf =
uv__malloc(uv_address_buf_size);
937 if (uv_address_buf == NULL) {
944 uv_address = uv_address_buf;
945 name_buf = (
char*) (uv_address_buf +
count);
948 for (adapter = win_address_buf;
950 adapter = adapter->Next) {
951 IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
953 size_t max_name_size;
955 if (adapter->OperStatus != IfOperStatusUp ||
956 adapter->FirstUnicastAddress == NULL)
960 max_name_size = (
char*) uv_address_buf + uv_address_buf_size - name_buf;
961 if (max_name_size > (
size_t) INT_MAX)
962 max_name_size = INT_MAX;
963 name_size = WideCharToMultiByte(CP_UTF8,
965 adapter->FriendlyName,
971 if (name_size <= 0) {
978 for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
979 adapter->FirstUnicastAddress;
980 unicast_address != NULL;
981 unicast_address = unicast_address->Next) {
985 sa = unicast_address->Address.lpSockaddr;
988 if (is_vista_or_greater) {
990 ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength;
997 IP_ADAPTER_PREFIX*
prefix;
1002 if (
prefix->Address.lpSockaddr->sa_family != sa->sa_family ||
1003 prefix->PrefixLength <= prefix_len)
1008 prefix_len =
prefix->PrefixLength;
1016 prefix_len = (sa->sa_family ==
AF_INET6) ? 128 : 32;
1019 memset(uv_address, 0,
sizeof *uv_address);
1021 uv_address->
name = name_buf;
1023 if (adapter->PhysicalAddressLength ==
sizeof(uv_address->
phys_addr)) {
1025 adapter->PhysicalAddress,
1030 (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
1038 if (prefix_len % 8) {
1040 0xff << (8 - prefix_len % 8);
1048 htonl(0xffffffff << (32 - prefix_len)) : 0;
1054 name_buf += name_size;
1059 *addresses_ptr = uv_address_buf;
1073 FILETIME createTime, exitTime, kernelTime, userTime;
1074 SYSTEMTIME kernelSystemTime, userSystemTime;
1075 PROCESS_MEMORY_COUNTERS memCounters;
1076 IO_COUNTERS ioCounters;
1079 ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
1084 ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime);
1089 ret = FileTimeToSystemTime(&userTime, &userSystemTime);
1094 ret = GetProcessMemoryInfo(GetCurrentProcess(),
1096 sizeof(memCounters));
1101 ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
1106 memset(uv_rusage, 0,
sizeof(*uv_rusage));
1109 userSystemTime.wMinute * 60 +
1110 userSystemTime.wSecond;
1114 kernelSystemTime.wMinute * 60 +
1115 kernelSystemTime.wSecond;
1166 wchar_t path[MAX_PATH + 2];
1191 bufsize = WideCharToMultiByte(CP_UTF8, 0,
path, -1, NULL, 0, NULL, NULL);
1195 }
else if (bufsize > *
size) {
1201 bufsize = WideCharToMultiByte(CP_UTF8,
1213 *
size = bufsize - 1;
1243 bufsize = WideCharToMultiByte(CP_UTF8,
1264 bufsize = WideCharToMultiByte(CP_UTF8,
1279 (*utf8)[bufsize] =
'\0';
1298 bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0);
1306 *utf16 =
uv__malloc(
sizeof(WCHAR) * (bufsize + 1));
1312 bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
1320 (*utf16)[bufsize] =
L'\0';
1327 wchar_t username[
UNLEN + 1];
1328 wchar_t path[MAX_PATH];
1336 if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
1340 if (!GetUserProfileDirectoryW(token,
path, &bufsize)) {
1345 if (
r == ERROR_INSUFFICIENT_BUFFER)
1355 if (!GetUserNameW(username, &bufsize)) {
1359 if (
r == ERROR_INSUFFICIENT_BUFFER)
1401 env = GetEnvironmentStringsW();
1405 for (penv =
env,
i = 0; *penv !=
L'\0'; penv += wcslen(penv) + 1,
i++);
1408 if (*envitems == NULL) {
1409 FreeEnvironmentStringsW(
env);
1416 while (*penv !=
L'\0' && cnt <
i) {
1425 ptr = strchr(
buf + 1,
'=');
1433 envitem = &(*envitems)[cnt];
1440 penv += wcslen(penv) + 1;
1443 FreeEnvironmentStringsW(
env);
1449 FreeEnvironmentStringsW(
env);
1451 for (
i = 0;
i < cnt;
i++) {
1452 envitem = &(*envitems)[cnt];
1478 SetLastError(ERROR_SUCCESS);
1485 if (
r != ERROR_SUCCESS)
1490 bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
1494 }
else if (bufsize > *
size) {
1500 bufsize = WideCharToMultiByte(CP_UTF8,
1512 *
size = bufsize - 1;
1537 r = SetEnvironmentVariableW(name_w, value_w);
1560 r = SetEnvironmentVariableW(name_w, NULL);
1579 if (gethostname(
buf,
sizeof(
buf)) != 0)
1582 buf[
sizeof(
buf) - 1] =
'\0';
1600 *
handle = GetCurrentProcess();
1607 if (
r == ERROR_INVALID_PARAMETER)
1635 if (
r == REALTIME_PRIORITY_CLASS)
1637 else if (
r == HIGH_PRIORITY_CLASS)
1639 else if (
r == ABOVE_NORMAL_PRIORITY_CLASS)
1641 else if (
r == NORMAL_PRIORITY_CLASS)
1643 else if (
r == BELOW_NORMAL_PRIORITY_CLASS)
1665 priority_class = REALTIME_PRIORITY_CLASS;
1667 priority_class = HIGH_PRIORITY_CLASS;
1669 priority_class = ABOVE_NORMAL_PRIORITY_CLASS;
1671 priority_class = NORMAL_PRIORITY_CLASS;
1673 priority_class = BELOW_NORMAL_PRIORITY_CLASS;
1675 priority_class = IDLE_PRIORITY_CLASS;
1682 if (SetPriorityClass(
handle, priority_class) == 0)
1693 OSVERSIONINFOW os_info;
1694 SYSTEM_INFO system_info;
1696 WCHAR product_name_w[256];
1697 DWORD product_name_w_size;
1699 int processor_level;
1706 os_info.dwOSVersionInfoSize =
sizeof(os_info);
1707 os_info.szCSDVersion[0] =
L'\0';
1715 #pragma warning(suppress : 4996)
1716 if (GetVersionExW(&os_info) == 0) {
1724 r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
1725 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
1730 if (
r == ERROR_SUCCESS) {
1731 product_name_w_size =
sizeof(product_name_w);
1732 r = RegGetValueW(registry_key,
1737 (PVOID) product_name_w,
1738 &product_name_w_size);
1739 RegCloseKey(registry_key);
1741 if (
r == ERROR_SUCCESS) {
1742 version_size = WideCharToMultiByte(CP_UTF8,
1750 if (version_size == 0) {
1758 if (os_info.szCSDVersion[0] !=
L'\0') {
1759 if (version_size > 0)
1760 buffer->version[version_size - 1] =
' ';
1762 if (WideCharToMultiByte(CP_UTF8,
1764 os_info.szCSDVersion,
1766 buffer->version + version_size,
1767 sizeof(
buffer->version) - version_size,
1780 (
unsigned int) os_info.dwMajorVersion,
1781 (
unsigned int) os_info.dwMinorVersion);
1782 assert(
r <
sizeof(
buffer->sysname));
1791 (
unsigned int) os_info.dwMajorVersion,
1792 (
unsigned int) os_info.dwMinorVersion,
1793 (
unsigned int) os_info.dwBuildNumber);
1794 assert(
r <
sizeof(
buffer->release));
1797 GetSystemInfo(&system_info);
1799 switch (system_info.wProcessorArchitecture) {
1800 case PROCESSOR_ARCHITECTURE_AMD64:
1803 case PROCESSOR_ARCHITECTURE_IA64:
1806 case PROCESSOR_ARCHITECTURE_INTEL:
1809 if (system_info.wProcessorLevel > 3) {
1810 processor_level = system_info.wProcessorLevel < 6 ?
1811 system_info.wProcessorLevel : 6;
1812 buffer->machine[1] =
'0' + processor_level;
1816 case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
1819 case PROCESSOR_ARCHITECTURE_MIPS:
1822 case PROCESSOR_ARCHITECTURE_ALPHA:
1823 case PROCESSOR_ARCHITECTURE_ALPHA64:
1826 case PROCESSOR_ARCHITECTURE_PPC:
1829 case PROCESSOR_ARCHITECTURE_SHX:
1832 case PROCESSOR_ARCHITECTURE_ARM:
1843 buffer->sysname[0] =
'\0';
1844 buffer->release[0] =
'\0';
1845 buffer->version[0] =
'\0';
1846 buffer->machine[0] =
'\0';
1854 ULARGE_INTEGER ularge;
1859 GetSystemTimeAsFileTime(&file_time);
1860 ularge.LowPart = file_time.dwLowDateTime;
1861 ularge.HighPart = file_time.dwHighDateTime;