diff --git a/inc/utils.h b/inc/utils.h index 9f7f0ee..3833ede 100644 --- a/inc/utils.h +++ b/inc/utils.h @@ -6,8 +6,9 @@ HMODULE WINAPI util_enumerate_modules(_In_opt_ HMODULE hModuleLast); +void util_set_process_affinity(); +void util_set_thread_affinity(DWORD tid); void util_pull_messages(); -unsigned long util_get_crc32(char* filename); DWORD util_get_timestamp(HMODULE mod); FARPROC util_get_iat_proc(HMODULE mod, char* module_name, char* function_name); BOOL util_caller_is_ddraw_wrapper(void* return_address); diff --git a/src/dd.c b/src/dd.c index e69063a..883c1e1 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1824,7 +1824,14 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute if (g_config.singlecpu) { - SetProcessAffinityMask(proc, 1); + if (!IsWine() && IsWindows11OrGreater()) + { + util_set_process_affinity(); + } + else + { + SetProcessAffinityMask(proc, 1); + } } else if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity)) { diff --git a/src/dllmain.c b/src/dllmain.c index 97d675f..f3f98b1 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -180,6 +180,13 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) break; } + case DLL_THREAD_ATTACH: + { + if (g_config.singlecpu && !IsWine() && IsWindows11OrGreater()) + { + util_set_thread_affinity(GetCurrentThreadId()); + } + } } return TRUE; diff --git a/src/utils.c b/src/utils.c index d96920b..a6649c4 100644 --- a/src/utils.c +++ b/src/utils.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "ddraw.h" #include "debug.h" #include "dd.h" @@ -71,6 +72,42 @@ HMODULE WINAPI util_enumerate_modules(_In_opt_ HMODULE hModuleLast) return NULL; } +void util_set_process_affinity() +{ + HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (snap == INVALID_HANDLE_VALUE) + return; + + THREADENTRY32 entry = { 0 }; + entry.dwSize = sizeof(THREADENTRY32); + + if (!Thread32First(snap, &entry)) + { + CloseHandle(snap); + return; + } + + do + { + if (entry.th32OwnerProcessID == GetCurrentProcessId()) + { + util_set_thread_affinity(entry.th32ThreadID); + } + } while (Thread32Next(snap, &entry)); + + CloseHandle(snap); +} + +void util_set_thread_affinity(DWORD tid) +{ + HANDLE thread = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, FALSE, tid); + if (thread) + { + SetThreadAffinityMask(thread, 1); + CloseHandle(thread); + } +} + void util_pull_messages() { if (g_config.fix_not_responding &&