[PATCH] kernel32: Actually return a PERFORMANCE_INFORMATION structure in K32GetPerformanceInfo

James Eder jimportal at gmail.com
Tue Apr 23 19:05:06 CDT 2013


---
 dlls/kernel32/cpu.c           | 23 ++++++++++++++++++-----
 dlls/psapi/tests/psapi_main.c | 25 +++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c
index 0ebf8f3..124e5c0 100644
--- a/dlls/kernel32/cpu.c
+++ b/dlls/kernel32/cpu.c
@@ -216,16 +216,29 @@ BOOL WINAPI IsProcessorFeaturePresent (
  */
 BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
 {
-    NTSTATUS status;
+    MEMORYSTATUSEX mem_status;
 
     TRACE( "(%p, %d)\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;
+
+    FIXME("stub\n");
+
     return TRUE;
 }
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index b91add6..cfc5f4f 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);
@@ -72,6 +73,7 @@ static BOOL InitFunctionPtrs(HMODULE hpsapi)
     PSAPI_GET_PROC(GetModuleInformation);
     PSAPI_GET_PROC(GetMappedFileNameA);
     PSAPI_GET_PROC(GetMappedFileNameW);
+    PSAPI_GET_PROC(GetPerformanceInfo);
     PSAPI_GET_PROC(GetProcessMemoryInfo);
     PSAPI_GET_PROC(GetWsChanges);
     PSAPI_GET_PROC(InitializeProcessForWsWatch);
@@ -156,6 +158,27 @@ static void test_EnumProcessModules(void)
     }
 }
 
+static void test_GetPerformanceInfo(void)
+{
+    PERFORMANCE_INFORMATION info;
+    BOOL ret;
+
+    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);
+}
+
 static void test_GetModuleInformation(void)
 {
     HMODULE hMod = GetModuleHandle(NULL);
@@ -685,6 +708,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