Sebastian Lackner : kernel32: Fix implementation of K32GetPerformanceInfo.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Nov 14 03:22:44 CST 2014
Module: wine
Branch: master
Commit: 4032eef90fc9cb6dcd09310a9ed5372e234e7653
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4032eef90fc9cb6dcd09310a9ed5372e234e7653
Author: Sebastian Lackner <sebastian at 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);
}
More information about the wine-cvs
mailing list