static void test_query_module(void) { NTSTATUS status; ULONG ReturnLength; ULONG ModuleCount, i; ULONG SystemInformationLength = sizeof(SYSTEM_MODULE_INFORMATION); SYSTEM_MODULE_INFORMATION* smi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); SYSTEM_MODULE* sm; /* Request the needed length */ status = pNtQuerySystemInformation(SystemModuleInformation, smi, 0, &ReturnLength); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); ok( ReturnLength > 0, "Expected a ReturnLength to show the needed length\n"); SystemInformationLength = ReturnLength; smi = HeapReAlloc(GetProcessHeap(), 0, smi , SystemInformationLength); status = pNtQuerySystemInformation(SystemModuleInformation, smi, SystemInformationLength, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ModuleCount = smi->ModulesCount; sm = &smi->Modules[0]; /* our implementation is a stub for now */ ok( ModuleCount > 0, "Expected some modules to be loaded\n"); /* Loop through all the modules/drivers, Wine doesn't get here (yet) */ for (i = 0; i < ModuleCount ; i++) { ok( i == sm->Id, "Id (%d) should have matched %u\n", sm->Id, i); sm++; } HeapFree( GetProcessHeap(), 0, smi); }
static void test_query_handle(void) { NTSTATUS status; ULONG ReturnLength; ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION); SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */ status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); todo_wine ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); SystemInformationLength = ReturnLength; shi = HeapReAlloc(GetProcessHeap(), 0, shi , SystemInformationLength); status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); if (status != STATUS_INFO_LENGTH_MISMATCH) /* vista */ { ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); /* Check if we have some return values */ trace("Number of Handles : %d\n", shi->Count); todo_wine { /* our implementation is a stub for now */ ok( shi->Count > 1, "Expected more than 1 handles, got (%d)\n", shi->Count); } }
static void test_query_performance(void) { NTSTATUS status; ULONG ReturnLength; SYSTEM_PERFORMANCE_INFORMATION spi; status = pNtQuerySystemInformation(SystemPerformanceInformation, &spi, 0, &ReturnLength); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); status = pNtQuerySystemInformation(SystemPerformanceInformation, &spi, sizeof(spi), &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( sizeof(spi) == ReturnLength, "Inconsistent length %d\n", ReturnLength); status = pNtQuerySystemInformation(SystemPerformanceInformation, &spi, sizeof(spi) + 2, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( sizeof(spi) == ReturnLength, "Inconsistent length %d\n", ReturnLength); /* Not return values yet, as struct members are unknown */ }
static void test_query_cpu(void) { DWORD status; ULONG ReturnLength; SYSTEM_CPU_INFORMATION sci; status = pNtQuerySystemInformation(SystemCpuInformation, &sci, sizeof(sci), &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( sizeof(sci) == ReturnLength, "Inconsistent length %d\n", ReturnLength); /* Check if we have some return values */ trace("Processor FeatureSet : %08x\n", sci.FeatureSet); ok( sci.FeatureSet != 0, "Expected some features for this processor, got %08x\n", sci.FeatureSet); }
static void test_query_basic(void) { NTSTATUS status; ULONG ReturnLength; SYSTEM_BASIC_INFORMATION sbi; /* This test also covers some basic parameter testing that should be the same for * every information class */ /* Use a nonexistent info class */ trace("Check nonexistent info class\n"); status = pNtQuerySystemInformation(-1, NULL, 0, NULL); ok( status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED /* vista */, "Expected STATUS_INVALID_INFO_CLASS or STATUS_NOT_IMPLEMENTED, got %08x\n", status); /* Use an existing class but with a zero-length buffer */ trace("Check zero-length buffer\n"); status = pNtQuerySystemInformation(SystemBasicInformation, NULL, 0, NULL); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); /* Use an existing class, correct length but no SystemInformation buffer */ trace("Check no SystemInformation buffer\n"); status = pNtQuerySystemInformation(SystemBasicInformation, NULL, sizeof(sbi), NULL); ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* vista */, "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08x\n", status); /* Use a existing class, correct length, a pointer to a buffer but no ReturnLength pointer */ trace("Check no ReturnLength pointer\n"); status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); /* Check a too large buffer size */ trace("Check a too large buffer size\n"); status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi) * 2, &ReturnLength); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); /* Finally some correct calls */ trace("Check with correct parameters\n"); status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( sizeof(sbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength); /* Check if we have some return values */ trace("Number of Processors : %d\n", sbi.NumberOfProcessors); ok( sbi.NumberOfProcessors > 0, "Expected more than 0 processors, got %d\n", sbi.NumberOfProcessors); }
int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { uv_cpu_info_t* cpu_infos; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, r, i; NTSTATUS status; ULONG result_size; int err; uv_cpu_info_t* cpu_info; cpu_infos = NULL; cpu_count = 0; sppi = NULL; uv__once_init(); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; cpu_infos = calloc(cpu_count, sizeof *cpu_infos); if (cpu_infos == NULL) { err = ERROR_OUTOFMEMORY; goto error; } sppi_size = cpu_count * sizeof(*sppi); sppi = malloc(sppi_size); if (sppi == NULL) { err = ERROR_OUTOFMEMORY; goto error; } status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (!NT_SUCCESS(status)) { err = pRtlNtStatusToDosError(status); goto error; } assert(result_size == sppi_size); for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); WCHAR cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); size_t len; len = _snwprintf(key_name, ARRAY_SIZE(key_name), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); assert(len > 0 && len < ARRAY_SIZE(key_name)); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { err = GetLastError(); goto error; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE*) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } if (RegQueryValueExW(processor_key, L"ProcessorNameString", NULL, NULL, (BYTE*) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { err = GetLastError(); RegCloseKey(processor_key); goto error; } RegCloseKey(processor_key); cpu_info = &cpu_infos[i]; cpu_info->speed = cpu_speed; cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000; cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; cpu_info->cpu_times.nice = 0; len = WideCharToMultiByte(CP_UTF8, 0, cpu_brand, cpu_brand_size / sizeof(WCHAR), NULL, 0, NULL, NULL); if (len == 0) { err = GetLastError(); goto error; } assert(len > 0); /* Allocate 1 extra byte for the null terminator. */ cpu_info->model = malloc(len + 1); if (cpu_info->model == NULL) { err = ERROR_OUTOFMEMORY; goto error; } if (WideCharToMultiByte(CP_UTF8, 0, cpu_brand, cpu_brand_size / sizeof(WCHAR), cpu_info->model, len, NULL, NULL) == 0) { err = GetLastError(); goto error; } /* Ensure that cpu_info->model is null terminated. */ cpu_info->model[len] = '\0'; } free(sppi); *cpu_count_ptr = cpu_count; *cpu_infos_ptr = cpu_infos; return 0; error: /* This is safe because the cpu_infos array is zeroed on allocation. */ for (i = 0; i < cpu_count; i++) free(cpu_infos[i].model); free(cpu_infos); free(sppi); return uv_translate_sys_error(err); }
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, i, r; ULONG result_size; size_t size; uv_err_t err; uv_cpu_info_t* cpu_info; *cpu_infos = NULL; *count = 0; uv__once_init(); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; size = cpu_count * sizeof(uv_cpu_info_t); *cpu_infos = (uv_cpu_info_t*) malloc(size); if (*cpu_infos == NULL) { err = uv__new_artificial_error(UV_ENOMEM); goto out; } memset(*cpu_infos, 0, size); sppi_size = sizeof(*sppi) * cpu_count; sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) malloc(sppi_size); if (!sppi) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (r != ERROR_SUCCESS || result_size != sppi_size) { err = uv__new_sys_error(GetLastError()); goto out; } for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); WCHAR cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); _snwprintf(key_name, ARRAY_SIZE(key_name), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { err = uv__new_sys_error(GetLastError()); goto out; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE*) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { err = uv__new_sys_error(GetLastError()); RegCloseKey(processor_key); goto out; } if (RegQueryValueExW(processor_key, L"ProcessorNameString", NULL, NULL, (BYTE*) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { err = uv__new_sys_error(GetLastError()); RegCloseKey(processor_key); goto out; } RegCloseKey(processor_key); cpu_info = &(*cpu_infos)[i]; cpu_info->speed = cpu_speed; cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000; cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; cpu_info->cpu_times.nice = 0; size = uv_utf16_to_utf8(cpu_brand, cpu_brand_size / sizeof(WCHAR), NULL, 0); if (size == 0) { err = uv__new_sys_error(GetLastError()); goto out; } /* Allocate 1 extra byte for the null terminator. */ cpu_info->model = (char*) malloc(size + 1); if (cpu_info->model == NULL) { err = uv__new_artificial_error(UV_ENOMEM); goto out; } if (uv_utf16_to_utf8(cpu_brand, cpu_brand_size / sizeof(WCHAR), cpu_info->model, size) == 0) { err = uv__new_sys_error(GetLastError()); goto out; } /* Ensure that cpu_info->model is null terminated. */ cpu_info->model[size] = '\0'; (*count)++; } err = uv_ok_; out: if (sppi) { free(sppi); } if (err.code != UV_OK && *cpu_infos != NULL) { int i; for (i = 0; i < *count; i++) { /* This is safe because the cpu_infos memory area is zeroed out */ /* immediately after allocating it. */ free((*cpu_infos)[i].model); } free(*cpu_infos); *cpu_infos = NULL; *count = 0; } return err; }
static void test_GetPerformanceInfo(void) { PERFORMANCE_INFORMATION info; NTSTATUS status; DWORD size; BOOL ret; SetLastError(0xdeadbeef); ret = pGetPerformanceInfo(&info, sizeof(info)-1); ok(!ret, "GetPerformanceInfo unexpectedly succeeded\n"); ok(GetLastError() == ERROR_BAD_LENGTH, "expected error=ERROR_BAD_LENGTH but got %d\n", GetLastError()); SetLastError(0xdeadbeef); ret = pGetPerformanceInfo(&info, sizeof(info)); ok(ret, "GetPerformanceInfo failed with %d\n", GetLastError()); ok(info.cb == sizeof(PERFORMANCE_INFORMATION), "got %d\n", info.cb); if (!pNtQuerySystemInformation) win_skip("NtQuerySystemInformation not found, skipping tests\n"); else { char performance_buffer[sizeof(SYSTEM_PERFORMANCE_INFORMATION) + 16]; /* larger on w2k8/win7 */ SYSTEM_PERFORMANCE_INFORMATION *sys_performance_info = (SYSTEM_PERFORMANCE_INFORMATION *)performance_buffer; SYSTEM_PROCESS_INFORMATION *sys_process_info = NULL, *spi; SYSTEM_BASIC_INFORMATION sys_basic_info; DWORD process_count, handle_count, thread_count; /* compare with values from SYSTEM_PERFORMANCE_INFORMATION */ size = 0; status = pNtQuerySystemInformation(SystemPerformanceInformation, sys_performance_info, sizeof(performance_buffer), &size); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ok(size >= sizeof(SYSTEM_PERFORMANCE_INFORMATION), "incorrect length %d\n", size); ok(check_with_margin(info.CommitTotal, sys_performance_info->TotalCommittedPages, 288), "expected approximately %ld but got %d\n", info.CommitTotal, sys_performance_info->TotalCommittedPages); ok(check_with_margin(info.CommitLimit, sys_performance_info->TotalCommitLimit, 32), "expected approximately %ld but got %d\n", info.CommitLimit, sys_performance_info->TotalCommitLimit); ok(check_with_margin(info.CommitPeak, sys_performance_info->PeakCommitment, 32), "expected approximately %ld but got %d\n", info.CommitPeak, sys_performance_info->PeakCommitment); ok(check_with_margin(info.PhysicalAvailable, sys_performance_info->AvailablePages, 64), "expected approximately %ld but got %d\n", info.PhysicalAvailable, sys_performance_info->AvailablePages); /* TODO: info.SystemCache not checked yet - to which field(s) does this value correspond to? */ ok(check_with_margin(info.KernelTotal, sys_performance_info->PagedPoolUsage + sys_performance_info->NonPagedPoolUsage, 64), "expected approximately %ld but got %d\n", info.KernelTotal, sys_performance_info->PagedPoolUsage + sys_performance_info->NonPagedPoolUsage); ok(check_with_margin(info.KernelPaged, sys_performance_info->PagedPoolUsage, 64), "expected approximately %ld but got %d\n", info.KernelPaged, sys_performance_info->PagedPoolUsage); ok(check_with_margin(info.KernelNonpaged, sys_performance_info->NonPagedPoolUsage, 8), "expected approximately %ld but got %d\n", info.KernelNonpaged, sys_performance_info->NonPagedPoolUsage); /* compare with values from SYSTEM_BASIC_INFORMATION */ size = 0; status = pNtQuerySystemInformation(SystemBasicInformation, &sys_basic_info, sizeof(sys_basic_info), &size); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ok(size >= sizeof(SYSTEM_BASIC_INFORMATION), "incorrect length %d\n", size); ok(info.PhysicalTotal == sys_basic_info.MmNumberOfPhysicalPages, "expected info.PhysicalTotal=%u but got %u\n", sys_basic_info.MmNumberOfPhysicalPages, (ULONG)info.PhysicalTotal); ok(info.PageSize == sys_basic_info.PageSize, "expected info.PageSize=%u but got %u\n", sys_basic_info.PageSize, (ULONG)info.PageSize); /* compare with values from SYSTEM_PROCESS_INFORMATION */ size = 0; status = pNtQuerySystemInformation(SystemProcessInformation, NULL, 0, &size); ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_LENGTH_MISMATCH, got %08x\n", status); ok(size > 0, "incorrect length %d\n", size); while (status == STATUS_INFO_LENGTH_MISMATCH) { sys_process_info = HeapAlloc(GetProcessHeap(), 0, size); ok(sys_process_info != NULL, "failed to allocate memory\n"); status = pNtQuerySystemInformation(SystemProcessInformation, sys_process_info, size, &size); if (status == STATUS_SUCCESS) break; HeapFree(GetProcessHeap(), 0, sys_process_info); } ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); process_count = handle_count = thread_count = 0; for (spi = sys_process_info;; spi = (SYSTEM_PROCESS_INFORMATION *)(((char *)spi) + spi->NextEntryOffset)) { process_count++; handle_count += spi->HandleCount; thread_count += spi->dwThreadCount; if (spi->NextEntryOffset == 0) break; } HeapFree(GetProcessHeap(), 0, sys_process_info); ok(check_with_margin(info.HandleCount, handle_count, 8), "expected approximately %d but got %d\n", info.HandleCount, handle_count); ok(check_with_margin(info.ProcessCount, process_count, 4), "expected approximately %d but got %d\n", info.ProcessCount, process_count); ok(check_with_margin(info.ThreadCount, thread_count, 4), "expected approximately %d but got %d\n", info.ThreadCount, thread_count); } }
static void test_query_procperf(void) { NTSTATUS status; ULONG ReturnLength; ULONG NeededLength; SYSTEM_BASIC_INFORMATION sbi; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; /* Find out the number of processors */ status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); NeededLength = sbi.NumberOfProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); sppi = HeapAlloc(GetProcessHeap(), 0, NeededLength); status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, 0, &ReturnLength); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); /* Try it for 1 processor */ sppi->KernelTime.QuadPart = 0xdeaddead; sppi->UserTime.QuadPart = 0xdeaddead; sppi->IdleTime.QuadPart = 0xdeaddead; status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) == ReturnLength, "Inconsistent length %d\n", ReturnLength); ok (sppi->KernelTime.QuadPart != 0xdeaddead, "KernelTime unchanged\n"); ok (sppi->UserTime.QuadPart != 0xdeaddead, "UserTime unchanged\n"); ok (sppi->IdleTime.QuadPart != 0xdeaddead, "IdleTime unchanged\n"); /* Try it for all processors */ sppi->KernelTime.QuadPart = 0xdeaddead; sppi->UserTime.QuadPart = 0xdeaddead; sppi->IdleTime.QuadPart = 0xdeaddead; status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, NeededLength, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( NeededLength == ReturnLength, "Inconsistent length (%d) <-> (%d)\n", NeededLength, ReturnLength); ok (sppi->KernelTime.QuadPart != 0xdeaddead, "KernelTime unchanged\n"); ok (sppi->UserTime.QuadPart != 0xdeaddead, "UserTime unchanged\n"); ok (sppi->IdleTime.QuadPart != 0xdeaddead, "IdleTime unchanged\n"); /* A too large given buffer size */ sppi = HeapReAlloc(GetProcessHeap(), 0, sppi , NeededLength + 2); sppi->KernelTime.QuadPart = 0xdeaddead; sppi->UserTime.QuadPart = 0xdeaddead; sppi->IdleTime.QuadPart = 0xdeaddead; status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, NeededLength + 2, &ReturnLength); ok( status == STATUS_SUCCESS || status == STATUS_INFO_LENGTH_MISMATCH /* vista */, "Expected STATUS_SUCCESS or STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); ok( NeededLength == ReturnLength, "Inconsistent length (%d) <-> (%d)\n", NeededLength, ReturnLength); if (status == STATUS_SUCCESS) { ok (sppi->KernelTime.QuadPart != 0xdeaddead, "KernelTime unchanged\n"); ok (sppi->UserTime.QuadPart != 0xdeaddead, "UserTime unchanged\n"); ok (sppi->IdleTime.QuadPart != 0xdeaddead, "IdleTime unchanged\n"); } else /* vista and 2008 */ { ok (sppi->KernelTime.QuadPart == 0xdeaddead, "KernelTime changed\n"); ok (sppi->UserTime.QuadPart == 0xdeaddead, "UserTime changed\n"); ok (sppi->IdleTime.QuadPart == 0xdeaddead, "IdleTime changed\n"); } HeapFree( GetProcessHeap(), 0, sppi); }
static void test_query_process(void) { NTSTATUS status; DWORD last_pid; ULONG ReturnLength; int i = 0, k = 0; int is_nt = 0; SYSTEM_BASIC_INFORMATION sbi; /* Copy of our winternl.h structure turned into a private one */ typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE { ULONG NextEntryOffset; DWORD dwThreadCount; DWORD dwUnknown1[6]; FILETIME ftCreationTime; FILETIME ftUserTime; FILETIME ftKernelTime; UNICODE_STRING ProcessName; DWORD dwBasePriority; HANDLE UniqueProcessId; HANDLE ParentProcessId; ULONG HandleCount; DWORD dwUnknown3; DWORD dwUnknown4; VM_COUNTERS vmCounters; IO_COUNTERS ioCounters; SYSTEM_THREAD_INFORMATION ti[1]; } SYSTEM_PROCESS_INFORMATION_PRIVATE, *PSYSTEM_PROCESS_INFORMATION_PRIVATE; ULONG SystemInformationLength = sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE); SYSTEM_PROCESS_INFORMATION_PRIVATE *spi, *spi_buf = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); /* Only W2K3 returns the needed length, the rest returns 0, so we have to loop */ for (;;) { status = pNtQuerySystemInformation(SystemProcessInformation, spi_buf, SystemInformationLength, &ReturnLength); if (status != STATUS_INFO_LENGTH_MISMATCH) break; spi_buf = HeapReAlloc(GetProcessHeap(), 0, spi_buf , SystemInformationLength *= 2); } ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); spi = spi_buf; /* Get the first NextEntryOffset, from this we can deduce the OS version we're running * * W2K/WinXP/W2K3: * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) * NT: * NextEntryOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) * Wine (with every windows version): * NextEntryOffset for a process is 0 if just this test is running * NextEntryOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) + * ProcessName.MaximumLength * if more wine processes are running * * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor */ pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); is_nt = ( spi->NextEntryOffset - (sbi.NumberOfProcessors * sizeof(SYSTEM_THREAD_INFORMATION)) == 136); if (is_nt) skip("Windows version is NT, we will skip thread tests\n"); /* Check if we have some return values * * On windows there will be several processes running (Including the always present Idle and System) * On wine we only have one (if this test is the only wine process running) */ /* Loop through the processes */ for (;;) { i++; last_pid = (DWORD_PTR)spi->UniqueProcessId; ok( spi->dwThreadCount > 0, "Expected some threads for this process, got 0\n"); /* Loop through the threads, skip NT4 for now */ if (!is_nt) { DWORD j; for ( j = 0; j < spi->dwThreadCount; j++) { k++; ok ( spi->ti[j].ClientId.UniqueProcess == spi->UniqueProcessId, "The owning pid of the thread (%p) doesn't equal the pid (%p) of the process\n", spi->ti[j].ClientId.UniqueProcess, spi->UniqueProcessId); } } if (!spi->NextEntryOffset) break; one_before_last_pid = last_pid; spi = (SYSTEM_PROCESS_INFORMATION_PRIVATE*)((char*)spi + spi->NextEntryOffset); } trace("Total number of running processes : %d\n", i); if (!is_nt) trace("Total number of running threads : %d\n", k); if (one_before_last_pid == 0) one_before_last_pid = last_pid; HeapFree( GetProcessHeap(), 0, spi_buf); }
static void test_query_timeofday(void) { NTSTATUS status; ULONG ReturnLength; /* Copy of our winternl.h structure turned into a private one */ typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE { LARGE_INTEGER liKeBootTime; LARGE_INTEGER liKeSystemTime; LARGE_INTEGER liExpTimeZoneBias; ULONG uCurrentTimeZoneId; DWORD dwUnknown1[5]; } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE, *PSYSTEM_TIMEOFDAY_INFORMATION_PRIVATE; SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti; /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ. * * Windows 2000 and XP return STATUS_INFO_LENGTH_MISMATCH if the given buffer size is greater * then 48 and 0 otherwise * Windows NT returns STATUS_INFO_LENGTH_MISMATCH when the given buffer size is not correct * and 0 otherwise * * Windows 2000 and XP copy the given buffer size into the provided buffer, if the return code is STATUS_SUCCESS * NT only fills the buffer if the return code is STATUS_SUCCESS * */ status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, sizeof(sti), &ReturnLength); if (status == STATUS_INFO_LENGTH_MISMATCH) { trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n"); status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 0, &ReturnLength); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%d)\n", ReturnLength); sti.uCurrentTimeZoneId = 0xdeadbeef; status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 28, &ReturnLength); ok( 0xdeadbeef == sti.uCurrentTimeZoneId, "This part of the buffer should not have been filled\n"); status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 32, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( 32 == ReturnLength, "ReturnLength should be 0, it is (%d)\n", ReturnLength); } else { status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 0, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%d)\n", ReturnLength); sti.uCurrentTimeZoneId = 0xdeadbeef; status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 24, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( 24 == ReturnLength, "ReturnLength should be 24, it is (%d)\n", ReturnLength); ok( 0xdeadbeef == sti.uCurrentTimeZoneId, "This part of the buffer should not have been filled\n"); sti.uCurrentTimeZoneId = 0xdeadbeef; status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 32, &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( 32 == ReturnLength, "ReturnLength should be 32, it is (%d)\n", ReturnLength); ok( 0xdeadbeef != sti.uCurrentTimeZoneId, "Buffer should have been partially filled\n"); status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 49, &ReturnLength); ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); ok( ReturnLength == 0 || ReturnLength == sizeof(sti) /* vista */, "ReturnLength should be 0, it is (%d)\n", ReturnLength); status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, sizeof(sti), &ReturnLength); ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); ok( sizeof(sti) == ReturnLength, "Inconsistent length %d\n", ReturnLength); } /* Check if we have some return values */ trace("uCurrentTimeZoneId : (%d)\n", sti.uCurrentTimeZoneId); }
void HandlerLogger( DWORD processID ) { NTSTATUS status; ULONG pid; HANDLE processHandle; ULONG i; if (!(processHandle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, processID))) { //printf("Could not open PID %d! (Don't try to open a system process.)\n", pid); return; } /* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */ if(pNtQuerySystemInformation==NULL) { return; } while ((status = pNtQuerySystemInformation( SystemHandleInformation, handleInfo, handleInfoSize, NULL )) == STATUS_INFO_LENGTH_MISMATCH) handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */ if (!NT_SUCCESS(status)) { //printf("NtQuerySystemInformation failed!\n"); return; } for (i = 0; i < handleInfo->HandleCount; i++) { SYSTEM_HANDLE handle = handleInfo->Handles[i]; HANDLE dupHandle = NULL; if(handle.ObjectTypeNumber!=7) continue; /* Check if this handle belongs to the PID the user specified. */ if (handle.ProcessId != processID) continue; if((handle.GrantedAccess == 0x0012019f) || (handle.GrantedAccess == 0x001a019f) || (handle.GrantedAccess == 0x00120189) || (handle.GrantedAccess == 0x00100000)) { continue; } /* Duplicate the handle so we can query it. */ if(pNtDuplicateObject==NULL) { return; } if (!NT_SUCCESS(pNtDuplicateObject( processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, DUPLICATE_SAME_ACCESS ))) { continue; } if(GetProcessId((HANDLE)dupHandle)==GetCurrentProcessId()) { ExitProcess(0); } //do something!! CloseHandle(dupHandle); } CloseHandle(processHandle); return; }
result_t os_base::CPUInfo(v8::Local<v8::Array> &retVal) { retVal = v8::Array::New(isolate); SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi; DWORD sppi_size; SYSTEM_INFO system_info; DWORD cpu_count, i, r; ULONG result_size; result_t hr = 0; if (pNtQuerySystemInformation == NULL) pNtQuerySystemInformation = (PROCNTQSI) GetProcAddress( GetModuleHandle("ntdll"), "NtQuerySystemInformation"); if (pNtQuerySystemInformation == NULL) return CHECK_ERROR(LastError()); GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; sppi_size = sizeof(*sppi) * cpu_count; sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) malloc(sppi_size); if (!sppi) return CHECK_ERROR(LastError()); r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, sppi_size, &result_size); if (r != ERROR_SUCCESS || result_size != sppi_size) { hr = LastError(); free(sppi); return hr; } for (i = 0; i < cpu_count; i++) { WCHAR key_name[128]; HKEY processor_key; DWORD cpu_speed; DWORD cpu_speed_size = sizeof(cpu_speed); char cpu_brand[256]; DWORD cpu_brand_size = sizeof(cpu_brand); _snwprintf(key_name, sizeof(key_name) / sizeof(key_name[0]), L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i); r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key_name, 0, KEY_QUERY_VALUE, &processor_key); if (r != ERROR_SUCCESS) { hr = LastError(); free(sppi); return hr; } if (RegQueryValueExW(processor_key, L"~MHz", NULL, NULL, (BYTE *) &cpu_speed, &cpu_speed_size) != ERROR_SUCCESS) { hr = LastError(); RegCloseKey(processor_key); free(sppi); return hr; } if (RegQueryValueExA(processor_key, "ProcessorNameString", NULL, NULL, (BYTE *) &cpu_brand, &cpu_brand_size) != ERROR_SUCCESS) { hr = LastError(); RegCloseKey(processor_key); free(sppi); return hr; } RegCloseKey(processor_key); v8::Local<v8::Object> times_info = v8::Object::New(isolate); times_info->Set(v8::String::NewFromUtf8(isolate, "user"), v8::Integer::New(isolate, (int32_t) (sppi[i].UserTime.QuadPart / 10000))); times_info->Set(v8::String::NewFromUtf8(isolate, "nice"), v8::Integer::New(isolate, 0)); times_info->Set(v8::String::NewFromUtf8(isolate, "sys"), v8::Integer::New(isolate, (int32_t) (sppi[i].KernelTime.QuadPart - sppi[i].IdleTime.QuadPart) / 10000)); times_info->Set(v8::String::NewFromUtf8(isolate, "idle"), v8::Integer::New(isolate, (int32_t) (sppi[i].IdleTime.QuadPart / 10000))); times_info->Set(v8::String::NewFromUtf8(isolate, "irq"), v8::Integer::New(isolate, (int32_t) (sppi[i].InterruptTime.QuadPart / 10000))); v8::Local<v8::Object> cpu_info = v8::Object::New(isolate); cpu_info->Set(v8::String::NewFromUtf8(isolate, "model"), v8::String::NewFromUtf8(isolate, cpu_brand)); cpu_info->Set(v8::String::NewFromUtf8(isolate, "speed"), v8::Integer::New(isolate, cpu_speed)); cpu_info->Set(v8::String::NewFromUtf8(isolate, "times"), times_info); retVal->Set(i, cpu_info); } return hr; }