From: "Erich E. Hoover" Subject: [PATCH 2/2] kernel32: Implement GetSystemTimes (try 3). Message-Id: Date: Tue, 9 Jun 2015 21:47:28 -0600 This patch, inspired by patch 1 from Louis Lenders, fixes Bug #19813. Voddler and WAPT expect GetSystemTimes to actually work, which Louis was kind enough to demonstrate can be performed by querying NtQuerySystemInformation(SystemProcessorPerformanceInformation). From d9ec37db230d5caf7dc68ffec8d34df7140ad49b Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Tue, 9 Jun 2015 21:38:08 -0600 Subject: kernel32: Implement GetSystemTimes. --- dlls/kernel32/tests/time.c | 12 ++++----- dlls/kernel32/time.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c index febe366..838d79c 100644 --- a/dlls/kernel32/tests/time.c +++ b/dlls/kernel32/tests/time.c @@ -820,7 +820,7 @@ static void test_GetSystemTimes(void) return; } - todo_wine ok( pGetSystemTimes(NULL, NULL, NULL), "GetSystemTimes failed unexpectedly\n" ); + ok( pGetSystemTimes(NULL, NULL, NULL), "GetSystemTimes failed unexpectedly\n" ); total_usertime.QuadPart = 0; total_kerneltime.QuadPart = 0; @@ -828,8 +828,8 @@ static void test_GetSystemTimes(void) memset( &idletime, 0x11, sizeof(idletime) ); memset( &kerneltime, 0x11, sizeof(kerneltime) ); memset( &usertime, 0x11, sizeof(usertime) ); - todo_wine ok( pGetSystemTimes(&idletime, &kerneltime , &usertime), - "GetSystemTimes failed unexpectedly\n" ); + ok( pGetSystemTimes(&idletime, &kerneltime , &usertime), + "GetSystemTimes failed unexpectedly\n" ); ul1.LowPart = idletime.dwLowDateTime; ul1.HighPart = idletime.dwHighDateTime; @@ -861,9 +861,9 @@ static void test_GetSystemTimes(void) total_idletime.QuadPart += sppi[i].IdleTime.QuadPart; } - todo_wine ok( total_idletime.QuadPart - ul1.QuadPart < 10000000, "test idletime failed\n" ); - todo_wine ok( total_kerneltime.QuadPart - ul2.QuadPart < 10000000, "test kerneltime failed\n" ); - todo_wine ok( total_usertime.QuadPart - ul3.QuadPart < 10000000, "test usertime failed\n" ); + ok( total_idletime.QuadPart - ul1.QuadPart < 10000000, "test idletime failed\n" ); + ok( total_kerneltime.QuadPart - ul2.QuadPart < 10000000, "test kerneltime failed\n" ); + ok( total_usertime.QuadPart - ul3.QuadPart < 10000000, "test usertime failed\n" ); HeapFree(GetProcessHeap(), 0, sppi); } diff --git a/dlls/kernel32/time.c b/dlls/kernel32/time.c index daafc7f..7dcf71f 100644 --- a/dlls/kernel32/time.c +++ b/dlls/kernel32/time.c @@ -1104,9 +1104,67 @@ BOOL WINAPI FileTimeToDosDateTime( const FILETIME *ft, LPWORD fatdate, */ BOOL WINAPI GetSystemTimes(LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime) { - FIXME("(%p,%p,%p): Stub!\n", lpIdleTime, lpKernelTime, lpUserTime); + LARGE_INTEGER idle_time, kernel_time, user_time; + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi; + SYSTEM_BASIC_INFORMATION sbi; + NTSTATUS status; + ULONG ret_size; + int i; - return FALSE; + TRACE("(%p,%p,%p)\n", lpIdleTime, lpKernelTime, lpUserTime); + + status = NtQuerySystemInformation( SystemBasicInformation, &sbi, sizeof(sbi), &ret_size ); + if (status != STATUS_SUCCESS) + { + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + sppi = HeapAlloc( GetProcessHeap(), 0, + sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * sbi.NumberOfProcessors); + if (!sppi) + { + SetLastError( ERROR_OUTOFMEMORY ); + return FALSE; + } + + status = NtQuerySystemInformation( SystemProcessorPerformanceInformation, sppi, sizeof(*sppi) * sbi.NumberOfProcessors, + &ret_size ); + if (status != STATUS_SUCCESS) + { + HeapFree( GetProcessHeap(), 0, sppi ); + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; + } + + idle_time.QuadPart = 0; + kernel_time.QuadPart = 0; + user_time.QuadPart = 0; + for (i = 0; i < sbi.NumberOfProcessors; i++) + { + idle_time.QuadPart += sppi[i].IdleTime.QuadPart; + kernel_time.QuadPart += sppi[i].KernelTime.QuadPart; + user_time.QuadPart += sppi[i].UserTime.QuadPart; + } + + if (lpIdleTime) + { + lpIdleTime->dwLowDateTime = idle_time.u.LowPart; + lpIdleTime->dwHighDateTime = idle_time.u.HighPart; + } + if (lpKernelTime) + { + lpKernelTime->dwLowDateTime = kernel_time.u.LowPart; + lpKernelTime->dwHighDateTime = kernel_time.u.HighPart; + } + if (lpUserTime) + { + lpUserTime->dwLowDateTime = user_time.u.LowPart; + lpUserTime->dwHighDateTime = user_time.u.HighPart; + } + + HeapFree( GetProcessHeap(), 0, sppi ); + return TRUE; } /*********************************************************************** -- 1.9.1