Module: wine Branch: master Commit: 4032eef90fc9cb6dcd09310a9ed5372e234e7653 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4032eef90fc9cb6dcd09310a9e...
Author: Sebastian Lackner sebastian@fds-team.de Date: Fri Nov 14 08:07:34 2014 +0100
kernel32: Fix implementation of K32GetPerformanceInfo.
---
dlls/kernel32/cpu.c | 64 ++++++++++++++++++++++++++++++++++++++++++- dlls/psapi/tests/psapi_main.c | 14 ---------- 2 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c index 0ebf8f3..f48fcf0 100644 --- a/dlls/kernel32/cpu.c +++ b/dlls/kernel32/cpu.c @@ -216,12 +216,74 @@ BOOL WINAPI IsProcessorFeaturePresent ( */ BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size) { + union + { + SYSTEM_PERFORMANCE_INFORMATION performance; + SYSTEM_PROCESS_INFORMATION process; + SYSTEM_BASIC_INFORMATION basic; + } *sysinfo; + SYSTEM_PROCESS_INFORMATION *spi; + DWORD process_info_size; NTSTATUS status;
TRACE( "(%p, %d)\n", info, size );
- status = NtQuerySystemInformation( SystemPerformanceInformation, info, size, NULL ); + if (size < sizeof(*info)) + { + SetLastError( ERROR_BAD_LENGTH ); + return FALSE; + } + + memset( info, 0, sizeof(*info) ); + info->cb = sizeof(*info); + + /* fields from SYSTEM_PROCESS_INFORMATION */ + NtQuerySystemInformation( SystemProcessInformation, NULL, 0, &process_info_size ); + for (;;) + { + sysinfo = HeapAlloc( GetProcessHeap(), 0, max(process_info_size, sizeof(*sysinfo)) ); + if (!sysinfo) + { + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + status = NtQuerySystemInformation( SystemProcessInformation, &sysinfo->process, + process_info_size, &process_info_size ); + if (!status) break; + if (status != STATUS_INFO_LENGTH_MISMATCH) + goto err; + HeapFree( GetProcessHeap(), 0, sysinfo ); + } + for (spi = &sysinfo->process;; spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset)) + { + info->ProcessCount++; + info->HandleCount += spi->HandleCount; + info->ThreadCount += spi->dwThreadCount; + if (spi->NextEntryOffset == 0) break; + } + + /* fields from SYSTEM_PERFORMANCE_INFORMATION */ + status = NtQuerySystemInformation( SystemPerformanceInformation, &sysinfo->performance, + sizeof(sysinfo->performance), NULL ); + if (status) goto err; + info->CommitTotal = sysinfo->performance.TotalCommittedPages; + info->CommitLimit = sysinfo->performance.TotalCommitLimit; + info->CommitPeak = sysinfo->performance.PeakCommitment; + info->PhysicalAvailable = sysinfo->performance.AvailablePages; + info->KernelTotal = sysinfo->performance.PagedPoolUsage + + sysinfo->performance.NonPagedPoolUsage; + info->KernelPaged = sysinfo->performance.PagedPoolUsage; + info->KernelNonpaged = sysinfo->performance.NonPagedPoolUsage; + + /* fields from SYSTEM_BASIC_INFORMATION */ + status = NtQuerySystemInformation( SystemBasicInformation, &sysinfo->basic, + sizeof(sysinfo->basic), NULL ); + if (status) goto err; + info->PhysicalTotal = sysinfo->basic.MmNumberOfPhysicalPages; + info->PageSize = sysinfo->basic.PageSize;
+err: + HeapFree( GetProcessHeap(), 0, sysinfo ); if (status) { SetLastError( RtlNtStatusToDosError( status ) ); diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c index 7220da9..890b4ac 100644 --- a/dlls/psapi/tests/psapi_main.c +++ b/dlls/psapi/tests/psapi_main.c @@ -203,9 +203,7 @@ static void test_GetPerformanceInfo(void)
SetLastError(0xdeadbeef); ret = pGetPerformanceInfo(&info, sizeof(info)); - todo_wine ok(ret, "GetPerformanceInfo failed with %d\n", GetLastError()); - todo_wine ok(info.cb == sizeof(PERFORMANCE_INFORMATION), "got %d\n", info.cb);
if (!pNtQuerySystemInformation) @@ -224,22 +222,18 @@ static void test_GetPerformanceInfo(void) ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ok(size >= sizeof(SYSTEM_PERFORMANCE_INFORMATION), "incorrect length %d\n", size);
- todo_wine ok(info.CommitTotal == sys_performance_info->TotalCommittedPages, "expected info.CommitTotal=%u but got %u\n", sys_performance_info->TotalCommittedPages, (ULONG)info.CommitTotal);
- todo_wine ok(info.CommitLimit == sys_performance_info->TotalCommitLimit, "expected info.CommitLimit=%u but got %u\n", sys_performance_info->TotalCommitLimit, (ULONG)info.CommitLimit);
- todo_wine ok(info.CommitPeak == sys_performance_info->PeakCommitment, "expected info.CommitPeak=%u but got %u\n", sys_performance_info->PeakCommitment, (ULONG)info.CommitPeak);
- todo_wine ok(info.PhysicalAvailable >= max(sys_performance_info->AvailablePages, 25) - 25 && info.PhysicalAvailable <= sys_performance_info->AvailablePages + 25, "expected approximately info.PhysicalAvailable=%u but got %u\n", @@ -247,17 +241,14 @@ static void test_GetPerformanceInfo(void)
/* TODO: info.SystemCache not checked yet - to which field(s) does this value correspond to? */
- todo_wine ok(info.KernelTotal == sys_performance_info->PagedPoolUsage + sys_performance_info->NonPagedPoolUsage, "expected info.KernelTotal=%u but got %u\n", sys_performance_info->PagedPoolUsage + sys_performance_info->NonPagedPoolUsage, (ULONG)info.KernelTotal);
- todo_wine ok(info.KernelPaged == sys_performance_info->PagedPoolUsage, "expected info.KernelPaged=%u but got %u\n", sys_performance_info->PagedPoolUsage, (ULONG)info.KernelPaged);
- todo_wine ok(info.KernelNonpaged == sys_performance_info->NonPagedPoolUsage, "expected info.KernelNonpaged=%u but got %u\n", sys_performance_info->NonPagedPoolUsage, (ULONG)info.KernelNonpaged); @@ -268,12 +259,10 @@ static void test_GetPerformanceInfo(void) ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status); ok(size >= sizeof(SYSTEM_BASIC_INFORMATION), "incorrect length %d\n", size);
- todo_wine ok(info.PhysicalTotal == sys_basic_info.MmNumberOfPhysicalPages, "expected info.PhysicalTotal=%u but got %u\n", sys_basic_info.MmNumberOfPhysicalPages, (ULONG)info.PhysicalTotal);
- todo_wine ok(info.PageSize == sys_basic_info.PageSize, "expected info.PageSize=%u but got %u\n", sys_basic_info.PageSize, (ULONG)info.PageSize); @@ -303,15 +292,12 @@ static void test_GetPerformanceInfo(void) } HeapFree(GetProcessHeap(), 0, sys_process_info);
- todo_wine ok(info.HandleCount == handle_count, "expected info.HandleCount=%u but got %u\n", handle_count, info.HandleCount);
- todo_wine ok(info.ProcessCount == process_count, "expected info.ProcessCount=%u but got %u\n", process_count, info.ProcessCount);
- todo_wine ok(info.ThreadCount == thread_count, "expected info.ThreadCount=%u but got %u\n", thread_count, info.ThreadCount); }