[PATCH v2] ntdll: Fix treating valid affinity mask requests as invalid in NtSetInformationThread()
Roger Zoellner
zoellner.roger at gmail.com
Mon Sep 10 10:25:16 CDT 2018
Wine currently treats valid affinity mask requests as invalid. Especially when the requested mask has
one or more higher bits set, that aren't set in the current system/process mask (which mostly means when
requested mask > system mask)
Included are two more test cases, that would fail with the current implementaion, but should succeed on Windows.
This patch supercedes
https://source.winehq.org/patches/data/150846
https://source.winehq.org/patches/data/150824
Signed-off-by: Roger Zoellner <zoellner.roger at gmail.com>
---
dlls/ntdll/tests/info.c | 14 ++++++++++++++
dlls/ntdll/thread.c | 8 +++++---
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 2ab12e4257..e297606ef2 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -2040,6 +2040,20 @@ static void test_affinity(void)
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( tbi.AffinityMask == 1, "Unexpected thread affinity\n" );
+ thread_affinity = (pbi.AffinityMask << 1) | pbi.AffinityMask;
+ status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+ status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
+ ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+ ok( tbi.AffinityMask == pbi.AffinityMask, "Unexpected thread affinity. Expected %lx, got %lx\n", pbi.AffinityMask, tbi.AffinityMask);
+
+ thread_affinity = ~(DWORD_PTR)0 - 1;
+ status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
+ ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+ status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
+ ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+ ok( tbi.AffinityMask == (pbi.AffinityMask & (~(DWORD_PTR)0 - 1)), "Unexpected thread affinity. Expected %lx, got %lx\n", pbi.AffinityMask & (~(DWORD_PTR)0 - 1), tbi.AffinityMask);
+
/* NOTE: Pre-Vista does not recognize the "all processors" flag (all bits set) */
thread_affinity = ~(DWORD_PTR)0;
status = pNtSetInformationThread( GetCurrentThread(), ThreadAffinityMask, &thread_affinity, sizeof(thread_affinity) );
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 59d64e174d..b0ad0e8259 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -1211,6 +1211,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
* NtSetInformationThread (NTDLL.@)
* ZwSetInformationThread (NTDLL.@)
*/
+
NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
LPCVOID data, ULONG length )
{
@@ -1289,9 +1290,10 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
if (length != sizeof(ULONG_PTR)) return STATUS_INVALID_PARAMETER;
req_aff = *(const ULONG_PTR *)data;
- if ((ULONG)req_aff == ~0u) req_aff = affinity_mask;
- else if (req_aff & ~affinity_mask) return STATUS_INVALID_PARAMETER;
- else if (!req_aff) return STATUS_INVALID_PARAMETER;
+
+ if (!(req_aff & affinity_mask)) return STATUS_INVALID_PARAMETER;
+ req_aff = req_aff & affinity_mask;
+
SERVER_START_REQ( set_thread_info )
{
req->handle = wine_server_obj_handle( handle );
--
2.18.0
More information about the wine-devel
mailing list