Paul Gofman : ntoskrnl.exe: Implement KeRevertToUserAffinityThreadEx() function.
Alexandre Julliard
julliard at winehq.org
Tue May 26 17:17:07 CDT 2020
Module: wine
Branch: master
Commit: 7d4f4783a5d166b0d2987ca4c2b9188b405bdcbe
URL: https://source.winehq.org/git/wine.git/?a=commit;h=7d4f4783a5d166b0d2987ca4c2b9188b405bdcbe
Author: Paul Gofman <pgofman at codeweavers.com>
Date: Tue May 26 13:05:09 2020 +0300
ntoskrnl.exe: Implement KeRevertToUserAffinityThreadEx() function.
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 24 +++++++++++++++++++++++-
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 +
dlls/ntoskrnl.exe/ntoskrnl_private.h | 1 +
dlls/ntoskrnl.exe/tests/driver.c | 16 +++++++++++++++-
include/ddk/wdm.h | 1 +
5 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index a0657b52c5..fc7828cf15 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2267,6 +2267,7 @@ static void *create_thread_object( HANDLE handle )
thread->header.Type = 6;
thread->header.WaitListHead.Blink = INVALID_HANDLE_VALUE; /* mark as kernel object */
+ thread->user_affinity = 0;
if (!NtQueryInformationThread( handle, ThreadBasicInformation, &info, sizeof(info), NULL ))
{
@@ -2458,6 +2459,7 @@ VOID WINAPI KeSetSystemAffinityThread(KAFFINITY affinity)
KAFFINITY WINAPI KeSetSystemAffinityThreadEx(KAFFINITY affinity)
{
DWORD_PTR system_affinity = KeQueryActiveProcessors();
+ PKTHREAD thread = KeGetCurrentThread();
GROUP_AFFINITY old, new;
TRACE("affinity %#lx.\n", affinity);
@@ -2467,11 +2469,14 @@ KAFFINITY WINAPI KeSetSystemAffinityThreadEx(KAFFINITY affinity)
NtQueryInformationThread(GetCurrentThread(), ThreadGroupInformation,
&old, sizeof(old), NULL);
+ if (old.Mask != system_affinity)
+ thread->user_affinity = old.Mask;
+
memset(&new, 0, sizeof(new));
new.Mask = affinity;
return NtSetInformationThread(GetCurrentThread(), ThreadGroupInformation, &new, sizeof(new))
- ? 0 : old.Mask;
+ ? 0 : thread->user_affinity;
}
@@ -2483,6 +2488,23 @@ void WINAPI KeRevertToUserAffinityThread(void)
FIXME("() stub\n");
}
+void WINAPI KeRevertToUserAffinityThreadEx(KAFFINITY affinity)
+{
+ DWORD_PTR system_affinity = KeQueryActiveProcessors();
+ PRKTHREAD thread = KeGetCurrentThread();
+ GROUP_AFFINITY new;
+
+ TRACE("affinity %#lx.\n", affinity);
+
+ affinity &= system_affinity;
+
+ memset(&new, 0, sizeof(new));
+ new.Mask = affinity ? affinity
+ : (thread->user_affinity ? thread->user_affinity : system_affinity);
+
+ NtSetInformationThread(GetCurrentThread(), ThreadGroupInformation, &new, sizeof(new));
+ thread->user_affinity = affinity;
+}
/***********************************************************************
* IoRegisterFileSystem (NTOSKRNL.EXE.@)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 01a8e67376..3c7a9d1950 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -619,6 +619,7 @@
@ stdcall KeResetEvent(ptr)
@ stub KeRestoreFloatingPointState
@ stdcall KeRevertToUserAffinityThread()
+@ stdcall KeRevertToUserAffinityThreadEx(long)
@ stub KeRundownQueue
@ stub KeSaveFloatingPointState
@ stub KeSaveStateForHibernate
diff --git a/dlls/ntoskrnl.exe/ntoskrnl_private.h b/dlls/ntoskrnl.exe/ntoskrnl_private.h
index 23f03c336d..a1e1b892e8 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl_private.h
+++ b/dlls/ntoskrnl.exe/ntoskrnl_private.h
@@ -49,6 +49,7 @@ struct _KTHREAD
PEPROCESS process;
CLIENT_ID id;
unsigned int critical_region;
+ KAFFINITY user_affinity;
};
struct _ETHREAD
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index c7b3c93f6d..458815a0f2 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -1713,6 +1713,7 @@ static void test_executable_pool(void)
static void test_affinity(void)
{
KAFFINITY (WINAPI *pKeSetSystemAffinityThreadEx)(KAFFINITY affinity);
+ void (WINAPI *pKeRevertToUserAffinityThreadEx)(KAFFINITY affinity);
ULONG (WINAPI *pKeQueryActiveProcessorCountEx)(USHORT);
KAFFINITY (WINAPI *pKeQueryActiveProcessors)(void);
KAFFINITY mask, mask_all_cpus;
@@ -1731,6 +1732,9 @@ static void test_affinity(void)
pKeSetSystemAffinityThreadEx = get_proc_address("KeSetSystemAffinityThreadEx");
ok(!!pKeSetSystemAffinityThreadEx, "KeSetSystemAffinityThreadEx is not available.\n");
+ pKeRevertToUserAffinityThreadEx = get_proc_address("KeRevertToUserAffinityThreadEx");
+ ok(!!pKeRevertToUserAffinityThreadEx, "KeRevertToUserAffinityThreadEx is not available.\n");
+
count = pKeQueryActiveProcessorCountEx(1);
todo_wine ok(!count, "Got unexpected count %u.\n", count);
@@ -1745,14 +1749,24 @@ static void test_affinity(void)
mask = pKeQueryActiveProcessors();
ok(mask == mask_all_cpus, "Got unexpected mask %#lx.\n", mask);
+ pKeRevertToUserAffinityThreadEx(0x2);
+
mask = pKeSetSystemAffinityThreadEx(0);
ok(!mask, "Got unexpected mask %#lx.\n", mask);
+ pKeRevertToUserAffinityThreadEx(0x2);
+
mask = pKeSetSystemAffinityThreadEx(0x1);
- ok(mask == mask_all_cpus, "Got unexpected mask %#lx.\n", mask);
+ ok(mask == 0x2, "Got unexpected mask %#lx.\n", mask);
mask = pKeSetSystemAffinityThreadEx(~(KAFFINITY)0);
ok(mask == 0x1, "Got unexpected mask %#lx.\n", mask);
+
+ pKeRevertToUserAffinityThreadEx(~(KAFFINITY)0);
+ mask = pKeSetSystemAffinityThreadEx(0x1);
+ ok(mask == mask_all_cpus, "Got unexpected mask %#lx.\n", mask);
+
+ pKeRevertToUserAffinityThreadEx(mask_all_cpus);
}
static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack)
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 42ff0c72b1..b0ad0e70d3 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1706,6 +1706,7 @@ void WINAPI KeReleaseSpinLock(KSPIN_LOCK*,KIRQL);
void WINAPI KeReleaseSpinLockFromDpcLevel(KSPIN_LOCK*);
LONG WINAPI KeResetEvent(PRKEVENT);
void WINAPI KeRevertToUserAffinityThread(void);
+void WINAPI KeRevertToUserAffinityThreadEx(KAFFINITY affinity);
LONG WINAPI KeSetEvent(PRKEVENT,KPRIORITY,BOOLEAN);
KPRIORITY WINAPI KeSetPriorityThread(PKTHREAD,KPRIORITY);
void WINAPI KeSetSystemAffinityThread(KAFFINITY);
More information about the wine-cvs
mailing list