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