Commit 4032eef9 authored by Sebastian Lackner's avatar Sebastian Lackner Committed by Alexandre Julliard

kernel32: Fix implementation of K32GetPerformanceInfo.

parent 4297046d
......@@ -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 ) );
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment