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@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 );
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=41800
Your paranoid android.
=== wxppro (32 bit Windows report) ===
ntdll: info.c:2045: Test failed: Expected STATUS_SUCCESS, got c000000d info.c:2048: Test failed: Unexpected thread affinity. Expected 3, got 1 info.c:2052: Test failed: Expected STATUS_SUCCESS, got c000000d info.c:2055: Test failed: Unexpected thread affinity. Expected 2, got 1
=== w2003std (32 bit Windows report) ===
ntdll: info.c:2045: Test failed: Expected STATUS_SUCCESS, got c000000d info.c:2048: Test failed: Unexpected thread affinity. Expected 3, got 1 info.c:2052: Test failed: Expected STATUS_SUCCESS, got c000000d info.c:2055: Test failed: Unexpected thread affinity. Expected 2, got 1