Added patch to fix implementation of K32GetPerformanceInfo.

This commit is contained in:
Sebastian Lackner 2014-11-13 23:15:15 +01:00
parent 917b9ce280
commit c501f9328f
6 changed files with 311 additions and 3 deletions

View File

@ -39,7 +39,7 @@ Wine. All those differences are also documented on the
Included bug fixes and improvements
===================================
**Bugfixes and features included in the next upcoming release [18]:**
**Bugfixes and features included in the next upcoming release [19]:**
* Add stub for NtSetLdtEntries/ZwSetLdtEntries ([Wine Bug #26268](https://bugs.winehq.org/show_bug.cgi?id=26268))
* Allow NULL pointer for optional arguments of D3DXIntersectTri ([Wine Bug #35133](https://bugs.winehq.org/show_bug.cgi?id=35133))
@ -53,6 +53,7 @@ Included bug fixes and improvements
* Fix crash of Trine Demo on start ([Wine Bug #19231](https://bugs.winehq.org/show_bug.cgi?id=19231))
* Fix crash of winedevice when relocation entry crosses page boundary ([Wine Bug #28254](https://bugs.winehq.org/show_bug.cgi?id=28254))
* Fix handling of invert_y in DrawTextExW ([Wine Bug #22109](https://bugs.winehq.org/show_bug.cgi?id=22109))
* Fix implementation of K32GetPerformanceInfo ([Wine Bug #37512](https://bugs.winehq.org/show_bug.cgi?id=37512))
* Fix texture corruption in CSI: Fatal Conspiracy ([Wine Bug #33768](https://bugs.winehq.org/show_bug.cgi?id=33768))
* MSVCRT crashes when NULL is passed as string to atof or strtod ([Wine Bug #32550](https://bugs.winehq.org/show_bug.cgi?id=32550))
* Return correct values for GetThreadTimes function ([Wine Bug #20230](https://bugs.winehq.org/show_bug.cgi?id=20230))

1
debian/changelog vendored
View File

@ -22,6 +22,7 @@ wine-compholio (1.7.31) UNRELEASED; urgency=low
* Added patch to avoid crashing when broken app tries to release surface although refcount is zero.
* Added patch to avoid sending window messages in FindWindowExW.
* Added patch to fix handling of invert_y in DrawTextExW.
* Added patch to fix implementation of K32GetPerformanceInfo.
* Removed patch for iphlpapi stub functions (accepted upstream).
* Removed patches for FindFirstFileExW (accepted upstream).
* Removed patches for TLB dependencies lookup in resources (accepted upstream).

View File

@ -47,6 +47,7 @@ PATCHLIST := \
kernel32-GetNumaProcessorNode.ok \
kernel32-GetSystemTimes.ok \
kernel32-GetVolumePathName.ok \
kernel32-K32GetPerformanceInfo.ok \
kernel32-Named_Pipe.ok \
kernel32-UTF7_Support.ok \
libs-Unicode_Collation.ok \
@ -697,6 +698,24 @@ kernel32-GetVolumePathName.ok:
echo '+ { "kernel32-GetVolumePathName", "Erich E. Hoover", "Implement GetVolumePathName." },'; \
) > kernel32-GetVolumePathName.ok
# Patchset kernel32-K32GetPerformanceInfo
# |
# | Included patches:
# | * Fix implementation of K32GetPerformanceInfo. [by Sebastian Lackner]
# |
# | This patchset fixes the following Wine bugs:
# | * [#37512] Fix implementation of K32GetPerformanceInfo
# |
# | Modified files:
# | * dlls/kernel32/cpu.c, dlls/psapi/tests/psapi_main.c
# |
.INTERMEDIATE: kernel32-K32GetPerformanceInfo.ok
kernel32-K32GetPerformanceInfo.ok:
$(call APPLY_FILE,kernel32-K32GetPerformanceInfo/0001-kernel32-Fix-implementation-of-K32GetPerformanceInfo.patch)
@( \
echo '+ { "kernel32-K32GetPerformanceInfo", "Sebastian Lackner", "Fix implementation of K32GetPerformanceInfo." },'; \
) > kernel32-K32GetPerformanceInfo.ok
# Patchset kernel32-Named_Pipe
# |
# | Included patches:

View File

@ -13,8 +13,7 @@ diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c
index 0ebf8f3..c389898 100644
--- a/dlls/kernel32/cpu.c
+++ b/dlls/kernel32/cpu.c
@@ -229,3 +229,31 @@ BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
}
@@ -230,2 +230,30 @@ BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
return TRUE;
}
+

View File

@ -0,0 +1,284 @@
From 6d0a5dfb47d6f38a7eec61f54b6e95214df3083d Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Thu, 13 Nov 2014 23:06:15 +0100
Subject: kernel32: Fix implementation of K32GetPerformanceInfo.
---
dlls/kernel32/cpu.c | 72 +++++++++++++++++++++-
dlls/psapi/tests/psapi_main.c | 137 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 207 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c
index 0ebf8f3..56cbfd2 100644
--- a/dlls/kernel32/cpu.c
+++ b/dlls/kernel32/cpu.c
@@ -217,10 +217,63 @@ BOOL WINAPI IsProcessorFeaturePresent (
BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
{
+ union
+ {
+ SYSTEM_PERFORMANCE_INFORMATION performance;
+ SYSTEM_BASIC_INFORMATION basic;
+ } sysinfo;
+ SYSTEM_PROCESS_INFORMATION *process_info = NULL, *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;
+ }
+
+ info->cb = sizeof(*info);
+
+ /* SYSTEM_PERFORMANCE_INFORMATION */
+ status = NtQuerySystemInformation( SystemPerformanceInformation, &sysinfo.performance, sizeof(sysinfo.performance), NULL );
+ if (status)
+ {
+ SetLastError( RtlNtStatusToDosError( status ) );
+ return FALSE;
+ }
+ info->CommitTotal = sysinfo.performance.TotalCommittedPages;
+ info->CommitLimit = sysinfo.performance.TotalCommitLimit;
+ info->CommitPeak = sysinfo.performance.PeakCommitment;
+ info->PhysicalAvailable = sysinfo.performance.AvailablePages;
+ info->SystemCache = 0; /* FIXME */
+ info->KernelTotal = sysinfo.performance.PagedPoolUsage + sysinfo.performance.NonPagedPoolUsage;
+ info->KernelPaged = sysinfo.performance.PagedPoolUsage;
+ info->KernelNonpaged = sysinfo.performance.NonPagedPoolUsage;
+
+ /* SYSTEM_BASIC_INFORMATION */
+ status = NtQuerySystemInformation( SystemBasicInformation, &sysinfo.basic, sizeof(sysinfo.basic), NULL );
+ if (status)
+ {
+ SetLastError( RtlNtStatusToDosError( status ) );
+ return FALSE;
+ }
+ info->PhysicalTotal = sysinfo.basic.MmNumberOfPhysicalPages;
+ info->PageSize = sysinfo.basic.PageSize;
+ /* SYSTEM_PROCESS_INFORMATION */
+ status = NtQuerySystemInformation( SystemProcessInformation, NULL, 0, &process_info_size );
+ while (status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ process_info = HeapAlloc( GetProcessHeap(), 0, process_info_size );
+ if (!process_info)
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return FALSE;
+ }
+ status = NtQuerySystemInformation( SystemProcessInformation, process_info, process_info_size, &process_info_size );
+ if (!status) break;
+ HeapFree( GetProcessHeap(), 0, process_info );
+ }
if (status)
{
@@ -228,4 +281,21 @@ BOOL WINAPI K32GetPerformanceInfo(PPERFORMANCE_INFORMATION info, DWORD size)
return FALSE;
}
+
+ info->HandleCount = 0;
+ info->ProcessCount = 0;
+ info->ThreadCount = 0;
+
+ if (process_info)
+ {
+ for (spi = process_info;; spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset))
+ {
+ info->ProcessCount++;
+ info->HandleCount += spi->HandleCount;
+ info->ThreadCount += spi->dwThreadCount;
+ if (spi->NextEntryOffset == 0) break;
+ }
+ }
+
+ HeapFree( GetProcessHeap(), 0, process_info );
return TRUE;
}
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index 62d4f5c..7fa5d26 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -53,14 +53,16 @@ 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);
static BOOL (WINAPI *pGetWsChanges)(HANDLE, PPSAPI_WS_WATCH_INFORMATION, DWORD);
static BOOL (WINAPI *pInitializeProcessForWsWatch)(HANDLE);
static BOOL (WINAPI *pQueryWorkingSet)(HANDLE, PVOID, DWORD);
+static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
static NTSTATUS (WINAPI *pNtQueryVirtualMemory)(HANDLE, LPCVOID, ULONG, PVOID, SIZE_T, SIZE_T *);
-
+
static BOOL InitFunctionPtrs(HMODULE hpsapi)
{
PSAPI_GET_PROC(EmptyWorkingSet);
@@ -77,10 +79,13 @@ static BOOL InitFunctionPtrs(HMODULE hpsapi)
PSAPI_GET_PROC(InitializeProcessForWsWatch);
PSAPI_GET_PROC(QueryWorkingSet);
/* GetProcessImageFileName is not exported on NT4 */
+ pGetPerformanceInfo =
+ (void *)GetProcAddress(hpsapi, "GetPerformanceInfo");
pGetProcessImageFileNameA =
(void *)GetProcAddress(hpsapi, "GetProcessImageFileNameA");
pGetProcessImageFileNameW =
(void *)GetProcAddress(hpsapi, "GetProcessImageFileNameW");
+ pNtQuerySystemInformation = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");
pNtQueryVirtualMemory = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryVirtualMemory");
return TRUE;
}
@@ -184,6 +189,135 @@ static void test_GetModuleInformation(void)
ok(info.lpBaseOfDll == hMod, "lpBaseOfDll=%p hMod=%p\n", info.lpBaseOfDll, hMod);
}
+static void test_GetPerformanceInfo(void)
+{
+ PERFORMANCE_INFORMATION info;
+ NTSTATUS status;
+ DWORD size;
+ BOOL ret;
+
+ if (!pGetPerformanceInfo)
+ {
+ win_skip("GetPerformanceInfo not available, skipping tests\n");
+ return;
+ }
+
+ SetLastError(0xdeadbeef);
+ ret = pGetPerformanceInfo(&info, sizeof(info)-1);
+ ok(!ret, "GetPerformanceInfo unexpectedly succeeded\n");
+ ok(GetLastError() == ERROR_BAD_LENGTH, "expected error=ERROR_BAD_LENGTH but got %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetPerformanceInfo(&info, sizeof(info));
+ ok(ret, "GetPerformanceInfo failed with %d\n", GetLastError());
+ ok(info.cb == sizeof(PERFORMANCE_INFORMATION), "expected info.cb=%d but got %d\n", sizeof(PERFORMANCE_INFORMATION), info.cb);
+
+ /* verify content of the structure */
+ if (!pNtQuerySystemInformation)
+ win_skip("NtQuerySystemInformation not found, unable to verify results\n");
+ else
+ {
+ char performance_buffer[sizeof(SYSTEM_PERFORMANCE_INFORMATION) + 16]; /* larger on w2k8/win7 */
+ SYSTEM_PERFORMANCE_INFORMATION *sys_performance_info = (SYSTEM_PERFORMANCE_INFORMATION *)performance_buffer;
+ SYSTEM_BASIC_INFORMATION sys_basic_info;
+ SYSTEM_PROCESS_INFORMATION *sys_process_info, *spi;
+ DWORD process_count, handle_count, thread_count;
+
+ /* SYSTEM_PERFORMANCE_INFORMATION */
+ size = 0;
+ status = pNtQuerySystemInformation(SystemPerformanceInformation, sys_performance_info, sizeof(performance_buffer), &size);
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ ok(size >= sizeof(SYSTEM_PERFORMANCE_INFORMATION), "incorrect length %d\n", size);
+
+ /* SYSTEM_BASIC_INFORMATION */
+ size = 0;
+ status = pNtQuerySystemInformation(SystemBasicInformation, &sys_basic_info, sizeof(sys_basic_info), &size);
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+ ok(size >= sizeof(SYSTEM_BASIC_INFORMATION), "incorrect length %d\n", size);
+
+ /* SYSTEM_PROCESS_INFORMATION */
+ size = 0;
+ status = pNtQuerySystemInformation(SystemProcessInformation, NULL, 0, &size);
+ ok(status == STATUS_INFO_LENGTH_MISMATCH, "expected STATUS_LENGTH_MISMATCH, got %08x\n", status);
+ ok(size > 0, "incorrect length %d\n", size);
+
+ while (status == STATUS_INFO_LENGTH_MISMATCH)
+ {
+ sys_process_info = HeapAlloc(GetProcessHeap(), 0, size);
+ ok(sys_process_info != NULL, "failed to allocate memory\n");
+ status = pNtQuerySystemInformation(SystemProcessInformation, sys_process_info, size, &size);
+ if (!status) break;
+ HeapFree(GetProcessHeap(), 0, sys_process_info);
+ }
+ ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
+
+ process_count = handle_count = thread_count = 0;
+ for (spi = sys_process_info;; spi = (SYSTEM_PROCESS_INFORMATION *)(((PCHAR)spi) + spi->NextEntryOffset))
+ {
+ process_count++;
+ handle_count += spi->HandleCount;
+ thread_count += spi->dwThreadCount;
+ if (spi->NextEntryOffset == 0) break;
+ }
+
+ ok(info.CommitTotal == sys_performance_info->TotalCommittedPages,
+ "expected info.CommitTotal=%u but got %u\n",
+ sys_performance_info->TotalCommittedPages, (ULONG)info.CommitTotal);
+
+ ok(info.CommitLimit == sys_performance_info->TotalCommitLimit,
+ "expected info.CommitLimit=%u but got %u\n",
+ sys_performance_info->TotalCommitLimit, (ULONG)info.CommitLimit);
+
+ ok(info.CommitPeak == sys_performance_info->PeakCommitment,
+ "expected info.CommitPeak=%u but got %u\n",
+ sys_performance_info->PeakCommitment, (ULONG)info.CommitPeak);
+
+ ok(info.PhysicalTotal == sys_basic_info.MmNumberOfPhysicalPages,
+ "expected info.PhysicalTotal=%u but got %u\n",
+ sys_basic_info.MmNumberOfPhysicalPages, (ULONG)info.PhysicalTotal);
+
+ 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",
+ sys_performance_info->AvailablePages, (ULONG)info.PhysicalAvailable);
+
+ /* ok(info.SystemCache == sys_performance_info->MmSystemCachePage,
+ "expected info.SystemCache=%u but got %u\n",
+ sys_performance_info->MmSystemCachePage, (ULONG)info.SystemCache); */
+
+ 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);
+
+ ok(info.KernelPaged == sys_performance_info->PagedPoolUsage,
+ "expected info.KernelPaged=%u but got %u\n",
+ sys_performance_info->PagedPoolUsage, (ULONG)info.KernelPaged);
+
+ ok(info.KernelNonpaged == sys_performance_info->NonPagedPoolUsage,
+ "expected info.KernelNonpaged=%u but got %u\n",
+ sys_performance_info->NonPagedPoolUsage, (ULONG)info.KernelNonpaged);
+
+ ok(info.PageSize == sys_basic_info.PageSize,
+ "expected info.PageSize=%u but got %u\n",
+ sys_basic_info.PageSize, (ULONG)info.PageSize);
+
+ ok(info.HandleCount == handle_count,
+ "expected info.HandleCount=%u but got %u\n",
+ handle_count, info.HandleCount);
+
+ ok(info.ProcessCount == process_count,
+ "expected info.ProcessCount=%u but got %u\n",
+ process_count, info.ProcessCount);
+
+ ok(info.ThreadCount == thread_count,
+ "expected info.ThreadCount=%u but got %u\n",
+ thread_count, info.ThreadCount);
+
+ HeapFree(GetProcessHeap(), 0, sys_process_info);
+ }
+}
+
+
static void test_GetProcessMemoryInfo(void)
{
PROCESS_MEMORY_COUNTERS pmc;
@@ -677,6 +811,7 @@ START_TEST(psapi_main)
test_EnumProcesses();
test_EnumProcessModules();
test_GetModuleInformation();
+ test_GetPerformanceInfo();
test_GetProcessMemoryInfo();
test_GetMappedFileName();
test_GetProcessImageFileName();
--
2.1.3

View File

@ -0,0 +1,4 @@
Author: Sebastian Lackner
Subject: Fix implementation of K32GetPerformanceInfo.
Revision: 1
Fixes: [37512] Fix implementation of K32GetPerformanceInfo