[PATCH] kernel32: Actually return a PERFORMANCE_INFORMATION structure in K32GetPerformanceInfo (try 4)

James Eder jimportal at gmail.com
Wed Apr 24 19:08:06 CDT 2013


try 2: Try harder to get a proc address and alow for skipping in tests.
try 3: Improved FIXME and TRACE.
try 4: Whitespace improvments.
---
 dlls/kernel32/cpu.c           | 30 ++++++++++++++++++++++++------
 dlls/psapi/tests/psapi_main.c | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c
index 0ebf8f3..ecfccd0 100644
--- a/dlls/kernel32/cpu.c
+++ b/dlls/kernel32/cpu.c
@@ -216,16 +216,34 @@ BOOL WINAPI IsProcessorFeaturePresent (
  */
 BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
 {
-    NTSTATUS status;
+    MEMORYSTATUSEX mem_status;
 
-    TRACE( "(%p, %d)\n", info, size );
+    FIXME("(%p, %d): semi-stub\n", info, size);
 
-    status = NtQuerySystemInformation( SystemPerformanceInformation, info, size, NULL );
-
-    if (status)
+    if (size < sizeof(PERFORMANCE_INFORMATION))
     {
-        SetLastError( RtlNtStatusToDosError( status ) );
+        SetLastError(ERROR_BAD_LENGTH);
         return FALSE;
     }
+
+    mem_status.dwLength = sizeof(mem_status);
+    if (!GlobalMemoryStatusEx(&mem_status))
+        return FALSE;
+
+    memset(info, 0, sizeof(PERFORMANCE_INFORMATION));
+
+    info->cb                = sizeof(PERFORMANCE_INFORMATION);
+    info->CommitLimit       = min((mem_status.ullTotalPageFile / system_info.PageSize), MAXDWORD);
+    info->PhysicalTotal     = min((mem_status.ullTotalPhys / system_info.PageSize), MAXDWORD);
+    info->PhysicalAvailable = min((mem_status.ullAvailPhys / system_info.PageSize), MAXDWORD);
+    info->PageSize          = system_info.PageSize;
+
+    TRACE("cb=%d, CommitTotal=0x%lx, CommitLimit=0x%lx, CommitPeak=0x%lx, PhysicalTotal=0x%lx, "
+          "PhysicalAvailable=0x%lx, SystemCache=0x%lx, KernelTotal=0x%lx, KernelPaged=0x%lx, "
+          "KernelNonpaged=0x%lx, PageSize=0x%lx, HandleCount=%d, ProcessCount=%d, ThreadCount=%d\n",
+          info->cb, info->CommitTotal, info->CommitLimit, info->CommitPeak, info->PhysicalTotal,
+          info->PhysicalAvailable, info->SystemCache, info->KernelTotal, info->KernelPaged,
+          info->KernelNonpaged, info->PageSize, info->HandleCount, info->ProcessCount, info->ThreadCount);
+
     return TRUE;
 }
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index b91add6..8fdebc4 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -53,6 +53,7 @@ static DWORD (WINAPI *pGetModuleFileNameExW)(HANDLE, HMODULE, LPWSTR, DWORD);
 static BOOL  (WINAPI *pGetModuleInformation)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
 static DWORD (WINAPI *pGetMappedFileNameA)(HANDLE, LPVOID, LPSTR, DWORD);
 static DWORD (WINAPI *pGetMappedFileNameW)(HANDLE, LPVOID, LPWSTR, DWORD);
+static BOOL  (WINAPI *pGetPerformanceInfo)(PPERFORMANCE_INFORMATION, DWORD);
 static DWORD (WINAPI *pGetProcessImageFileNameA)(HANDLE, LPSTR, DWORD);
 static DWORD (WINAPI *pGetProcessImageFileNameW)(HANDLE, LPWSTR, DWORD);
 static BOOL  (WINAPI *pGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
@@ -82,6 +83,12 @@ static BOOL InitFunctionPtrs(HMODULE hpsapi)
     pGetProcessImageFileNameW =
       (void *)GetProcAddress(hpsapi, "GetProcessImageFileNameW");
     pNtQueryVirtualMemory = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryVirtualMemory");
+
+    /* GetPerformanceInfo can be found in psapi.dll, kernel32.dll (as K32GetPerformanceInfo), both, or nowhere */
+    pGetPerformanceInfo = (void*)GetProcAddress(hpsapi, "GetPerformanceInfo");
+    if(!pGetPerformanceInfo)
+        pGetPerformanceInfo = (void*)GetProcAddress(GetModuleHandle("kernel32.dll"), "K32GetPerformanceInfo");
+
     return TRUE;
 }
 
@@ -648,6 +655,33 @@ free_page:
     VirtualFree(addr, 0, MEM_RELEASE);
 }
 
+static void test_GetPerformanceInfo(void)
+{
+    PERFORMANCE_INFORMATION info;
+    BOOL ret;
+
+    if(!pGetPerformanceInfo)
+    {
+        win_skip("GetPerformanceInfo not implemented.\n");
+        return;
+    }
+
+    SetLastError(0xdeadbeef);
+    ret = pGetPerformanceInfo(&info, sizeof(info) - 1);
+    ok(!ret, "GetPerformanceInfo should fail.\n");
+    ok(GetLastError() == ERROR_BAD_LENGTH, "expected error=ERROR_BAD_LENGTH but got %d\n", GetLastError());
+
+    /* At least XP and 7 crash if a NULL pointer is passed to
+     * GetPerformanceInfo. It's probably unlikely any software depends on
+     * crashing so we don't test it  */
+
+    SetLastError(0xdeadbeef);
+    ret = pGetPerformanceInfo(&info, sizeof(info));
+    ok(ret, "GetPerformanceInfo should have succeeded but failed with %d\n", GetLastError());
+    if(ret)
+        ok(info.cb >= sizeof(info), "expected cb >= %d but got %d\n", sizeof(info), info.cb);
+}
+
 START_TEST(psapi_main)
 {
     HMODULE hpsapi = LoadLibraryA("psapi.dll");
@@ -685,6 +719,8 @@ START_TEST(psapi_main)
 	CloseHandle(hpVR);
 	CloseHandle(hpQV);
 	CloseHandle(hpAA);
+
+        test_GetPerformanceInfo();
     }
     
     FreeLibrary(hpsapi);
-- 
1.8.2.1




More information about the wine-patches mailing list