From: Eric Pouech epouech@codeweavers.com
In CreateRemoteThreadEx().
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/kernel32/tests/thread.c | 3 --- dlls/kernelbase/thread.c | 39 ++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index 27a21b1c39c..c3316c3bdf0 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -2701,7 +2701,6 @@ static void test_CreateRemoteThreadEx_affinity(void) ret = WaitForSingleObject(handle, INFINITE) == WAIT_OBJECT_0; ok(ret, "Couldn't wait for thread termination\n"); ok(thread_gaff.Group == gaff.Group, "Unexpected group %x (expecting %x)\n", thread_gaff.Group, gaff.Group); - todo_wine ok(thread_gaff.Mask == gaff.Mask, "Unexpected affinity %Ix (expecting %Ix)\n", thread_gaff.Mask, gaff.Mask); CloseHandle(handle);
@@ -2726,9 +2725,7 @@ static void test_CreateRemoteThreadEx_affinity(void)
SetLastError(0xdeadbeef); handle = pCreateRemoteThreadEx(GetCurrentProcess(), NULL, 0, &thread_ex_proc, &thread_gaff, 0, attr_list, NULL); - todo_wine ok(handle == NULL, "Expecting failure\n"); - todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected gle %lu\n", GetLastError()); if (handle) CloseHandle(handle); pDeleteProcThreadAttributeList(attr_list); diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index dbde4dcfaf3..31100a4bb8b 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -64,6 +64,22 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateRemoteThread( HANDLE process, SECURITY_ATT return CreateRemoteThreadEx( process, sa, stack, start, param, flags, NULL, id ); }
+struct proc_thread_attr +{ + DWORD_PTR attr; + SIZE_T size; + void *value; +}; + +struct _PROC_THREAD_ATTRIBUTE_LIST +{ + DWORD mask; /* bitmask of items in list */ + DWORD size; /* max number of items in list */ + DWORD count; /* number of items in list */ + DWORD pad; + DWORD_PTR unk; + struct proc_thread_attr attrs[1]; +};
/*************************************************************************** * CreateRemoteThreadEx (kernelbase.@) @@ -76,8 +92,22 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateRemoteThreadEx( HANDLE process, SECURITY_A HANDLE handle; CLIENT_ID client_id; SIZE_T stack_reserve = 0, stack_commit = 0; + GROUP_AFFINITY *group_affinity = NULL;
- if (attributes) FIXME("thread attributes ignored\n"); + if (attributes) + { + DWORD i; + for (i = 0; i < attributes->count; i++) + switch (attributes->attrs[i].attr) + { + case PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY: + group_affinity = attributes->attrs[i].value; + break; + default: + FIXME("thread attributes %Ix ignored\n", attributes->attrs[i].attr); + break; + } + }
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack; else stack_commit = stack; @@ -90,7 +120,12 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateRemoteThreadEx( HANDLE process, SECURITY_A if (id) *id = HandleToULong( client_id.UniqueThread ); if (sa && sa->nLength >= sizeof(*sa) && sa->bInheritHandle) SetHandleInformation( handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT ); - if (!(flags & CREATE_SUSPENDED)) + if (group_affinity && !SetThreadGroupAffinity(handle, group_affinity, NULL)) + { + NtClose( handle ); + handle = 0; + } + else if (!(flags & CREATE_SUSPENDED)) { ULONG ret; if (NtResumeThread( handle, &ret ))