[PATCH 2/5] ntoskrnl.exe: Add KeSetSystemAffinityThreadEx() function.
Paul Gofman
pgofman at codeweavers.com
Tue May 26 05:05:07 CDT 2020
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 19 +++++++++++++++++++
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 1 +
dlls/ntoskrnl.exe/tests/driver.c | 19 +++++++++++++++++--
include/ddk/wdm.h | 1 +
4 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index c10c830738..dc6bbe866c 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2455,6 +2455,25 @@ VOID WINAPI KeSetSystemAffinityThread(KAFFINITY Affinity)
FIXME("(%lx) stub\n", Affinity);
}
+KAFFINITY WINAPI KeSetSystemAffinityThreadEx(KAFFINITY affinity)
+{
+ DWORD_PTR system_affinity = KeQueryActiveProcessors();
+ GROUP_AFFINITY old, new;
+
+ TRACE("affinity %#lx.\n", affinity);
+
+ affinity &= system_affinity;
+
+ NtQueryInformationThread(GetCurrentThread(), ThreadGroupInformation,
+ &old, sizeof(old), NULL);
+
+ memset(&new, 0, sizeof(new));
+ new.Mask = affinity;
+
+ return NtSetInformationThread(GetCurrentThread(), ThreadGroupInformation, &new, sizeof(new))
+ ? 0 : old.Mask;
+}
+
/***********************************************************************
* KeRevertToUserAffinityThread (NTOSKRNL.EXE.@)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index f25ab9c5e0..e6e641d16c 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -634,6 +634,7 @@
@ stdcall KeSetPriorityThread(ptr long)
@ stub KeSetProfileIrql
@ stdcall KeSetSystemAffinityThread(long)
+@ stdcall KeSetSystemAffinityThreadEx(long)
@ stdcall KeSetTargetProcessorDpc(ptr long)
@ stub KeSetTimeIncrement
@ stub KeSetTimer
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 65be4a8d35..da6b9c1d63 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -1712,10 +1712,11 @@ static void test_executable_pool(void)
static void test_affinity(void)
{
+ KAFFINITY (WINAPI *pKeSetSystemAffinityThreadEx)(KAFFINITY affinity);
ULONG (WINAPI *pKeQueryActiveProcessorCountEx)(USHORT);
KAFFINITY (WINAPI *pKeQueryActiveProcessors)(void);
+ KAFFINITY mask, mask_all_cpus;
ULONG cpu_count, count;
- KAFFINITY mask;
pKeQueryActiveProcessorCountEx = get_proc_address("KeQueryActiveProcessorCountEx");
if (!pKeQueryActiveProcessorCountEx)
@@ -1727,6 +1728,9 @@ static void test_affinity(void)
pKeQueryActiveProcessors = get_proc_address("KeQueryActiveProcessors");
ok(!!pKeQueryActiveProcessors, "KeQueryActiveProcessors is not available.\n");
+ pKeSetSystemAffinityThreadEx = get_proc_address("KeSetSystemAffinityThreadEx");
+ ok(!!pKeSetSystemAffinityThreadEx, "KeSetSystemAffinityThreadEx is not available.\n");
+
count = pKeQueryActiveProcessorCountEx(1);
todo_wine ok(!count, "Got unexpected count %u.\n", count);
@@ -1736,8 +1740,19 @@ static void test_affinity(void)
count = pKeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
ok(count == cpu_count, "Got unexpected count %u.\n", count);
+ mask_all_cpus = ~((~0u) << cpu_count);
+
mask = pKeQueryActiveProcessors();
- ok(mask == ~((~0u) << cpu_count), "Got unexpected mask %#lx.\n", mask);
+ ok(mask == mask_all_cpus, "Got unexpected mask %#lx.\n", mask);
+
+ mask = pKeSetSystemAffinityThreadEx(0);
+ ok(!mask, "Got unexpected mask %#lx.\n", mask);
+
+ mask = pKeSetSystemAffinityThreadEx(0x1);
+ ok(mask == mask_all_cpus, "Got unexpected mask %#lx.\n", mask);
+
+ mask = pKeSetSystemAffinityThreadEx(~0ull);
+ ok(mask == 0x1, "Got unexpected mask %#lx.\n", mask);
}
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 1f80a5af29..42ff0c72b1 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1709,6 +1709,7 @@ void WINAPI KeRevertToUserAffinityThread(void);
LONG WINAPI KeSetEvent(PRKEVENT,KPRIORITY,BOOLEAN);
KPRIORITY WINAPI KeSetPriorityThread(PKTHREAD,KPRIORITY);
void WINAPI KeSetSystemAffinityThread(KAFFINITY);
+KAFFINITY WINAPI KeSetSystemAffinityThreadEx(KAFFINITY affinity);
BOOLEAN WINAPI KeSetTimerEx(KTIMER*,LARGE_INTEGER,LONG,KDPC*);
NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG,void*[],WAIT_TYPE,KWAIT_REASON,KPROCESSOR_MODE,BOOLEAN,LARGE_INTEGER*,KWAIT_BLOCK*);
NTSTATUS WINAPI KeWaitForSingleObject(void*,KWAIT_REASON,KPROCESSOR_MODE,BOOLEAN,LARGE_INTEGER*);
--
2.26.2
More information about the wine-devel
mailing list