diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj index a4d025d..3f5d12d 100644 --- a/cnc-ddraw.vcxproj +++ b/cnc-ddraw.vcxproj @@ -27,6 +27,7 @@ + @@ -80,6 +81,7 @@ + diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters index 0f07cb0..b15230e 100644 --- a/cnc-ddraw.vcxproj.filters +++ b/cnc-ddraw.vcxproj.filters @@ -168,6 +168,9 @@ Source Files + + Source Files + @@ -299,6 +302,9 @@ Header Files + + Header Files + diff --git a/inc/delay_imports.h b/inc/delay_imports.h new file mode 100644 index 0000000..ba654ed --- /dev/null +++ b/inc/delay_imports.h @@ -0,0 +1,25 @@ +#ifndef DELAY_IMPORTS_H +#define DELAY_IMPORTS_H + +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#define ThreadQuerySetWin32StartAddress 9 + +typedef NTSTATUS(WINAPI* RTLVERIFYVERSIONINFOPROC)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG); +typedef const char* (CDECL* WINE_GET_VERSIONPROC)(); +typedef void (CDECL* WINE_GET_HOST_VERSIONPROC)(const char** sysname, const char** release); +typedef NTSTATUS(WINAPI* NTQUERYINFORMATIONTHREADPROC)(HANDLE, LONG, PVOID, ULONG, PULONG); + +typedef ULONGLONG(WINAPI* VERSETCONDITIONMASKPROC)(ULONGLONG, DWORD, BYTE); +typedef BOOL(WINAPI* GETMODULEHANDLEEXAPROC)(DWORD, LPCSTR, HMODULE*); + +extern NTQUERYINFORMATIONTHREADPROC delay_NtQueryInformationThread; +extern RTLVERIFYVERSIONINFOPROC delay_RtlVerifyVersionInfo; +extern WINE_GET_VERSIONPROC delay_wine_get_version; +extern WINE_GET_HOST_VERSIONPROC delay_wine_get_host_version; + +extern VERSETCONDITIONMASKPROC delay_VerSetConditionMask; +extern GETMODULEHANDLEEXAPROC delay_GetModuleHandleExA; + +void delay_imports_init(); + +#endif 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/inc/versionhelpers.h b/inc/versionhelpers.h index fa542ac..6c4076d 100644 --- a/inc/versionhelpers.h +++ b/inc/versionhelpers.h @@ -33,7 +33,6 @@ #define VerSetConditionMask verhelp_set_mask #endif -void verhelp_init(); BOOL verhelp_verify_version(PRTL_OSVERSIONINFOEXW versionInfo, ULONG typeMask, ULONGLONG conditionMask); ULONGLONG verhelp_set_mask(ULONGLONG ConditionMask, DWORD TypeMask, BYTE Condition); const char* verhelp_wine_get_version(); diff --git a/src/config.c b/src/config.c index 44b8cb1..7707178 100644 --- a/src/config.c +++ b/src/config.c @@ -392,7 +392,6 @@ static void cfg_create_ini() "; 7th Legion\n" "[legion]\n" "maxgameticks=25\n" - "singlecpu=false\n" "\n" "; Atrox\n" "[Atrox]\n" @@ -430,10 +429,6 @@ static void cfg_create_ini() "nonexclusive=true\n" "adjmouse=true\n" "\n" - "; Abomination - The Nemesis Project\n" - "[abomb]\n" - "singlecpu=false\n" - "\n" "; American Conquest / Cossacks\n" "[DMCR]\n" "resolutions=2\n" @@ -530,10 +525,6 @@ static void cfg_create_ini() "[AN]\n" "adjmouse=true\n" "\n" - "; Another War\n" - "[AnotherWar]\n" - "singlecpu=false\n" - "\n" "; Atlantis\n" "[ATLANTIS]\n" "renderer=opengl\n" @@ -652,10 +643,6 @@ static void cfg_create_ini() "noactivateapp=true\n" "nonexclusive=true\n" "\n" - "; Championship Manager 99-00\n" - "[cm9900]\n" - "singlecpu=false\n" - "\n" "; Command & Conquer: Sole Survivor\n" "[SOLE]\n" "maxgameticks=120\n" @@ -929,10 +916,6 @@ static void cfg_create_ini() "[dominion]\n" "flipclear=true\n" "\n" - "; Excalibur 2555AD\n" - "[_FISH]\n" - "singlecpu=false\n" - "\n" "; Escape Velocity Nova\n" "[EV Nova]\n" "nonexclusive=true\n" @@ -959,10 +942,6 @@ static void cfg_create_ini() "[f-16]\n" "resolutions=1\n" "\n" - "; Fable\n" - "[FABLE]\n" - "singlecpu=false\n" - "\n" "; Fallout Tactics: Brotherhood of Steel\n" "[BOS/2]\n" "checkfile=.\\binkw32.dll\n" @@ -976,10 +955,6 @@ static void cfg_create_ini() "[FT Tools]\n" "hook_peekmessage=true\n" "\n" - "; Falcon 4.0 (Microprose version)\n" - "[falcon4]\n" - "singlecpu=false\n" - "\n" "; Flight Simulator 98\n" "[FLTSIM95]\n" "flightsim98_hack=true\n" @@ -1046,7 +1021,6 @@ static void cfg_create_ini() "; G-Police\n" "[GPOLICE]\n" "maxgameticks=60\n" - "singlecpu=false\n" "\n" "; Gangsters: Organized Crime\n" "[gangsters]\n" @@ -1288,10 +1262,6 @@ static void cfg_create_ini() "[Lionheart]\n" "hook_peekmessage=true\n" "\n" - "; Links Extreme\n" - "[EXTREME]\n" - "singlecpu=false\n" - "\n" "; Lost Vikings 2\n" "[LOSTV95]\n" "fake_mode=320x240x16\n" @@ -1299,7 +1269,6 @@ static void cfg_create_ini() "; Nightmare Creatures\n" "[NC]\n" "maxgameticks=30\n" - "singlecpu=false\n" "\n" "; Moto Racer (software mode)\n" "[moto]\n" @@ -1372,10 +1341,6 @@ static void cfg_create_ini() "maxgameticks=60\n" "limiter_type=4\n" "\n" - "; Mission Deliver Kindness\n" - "[MDK95]\n" - "singlecpu=false\n" - "\n" "; New Robinson\n" "[ROBY]\n" "adjmouse=true\n" @@ -1512,10 +1477,6 @@ static void cfg_create_ini() "[Pax Imperia]\n" "nonexclusive=true\n" "\n" - "; Panzer Dragoon\n" - "[PANZERDG]\n" - "singlecpu=false\n" - "\n" "; Play with the Teletubbies\n" "[PlayWTT]\n" "hook=3\n" @@ -1573,35 +1534,22 @@ static void cfg_create_ini() "[RtK]\n" "fixchilds=3\n" "lock_mouse_top_left=true\n" - "singlecpu=false\n" "limiter_type=2\n" "game_handles_close=true\n" "maxgameticks=59\n" "anti_aliased_fonts_min_size=99\n" "\n" - "; Rent-A-Hero\n" - "[Rent-A-Hero]\n" - "singlecpu=false\n" - "\n" "; ROAD RASH\n" "[RoadRash]\n" "adjmouse=true\n" "nonexclusive=true\n" "\n" - "; Rising Lands (patched)\n" - "[Rising]\n" - "singlecpu=false\n" - "\n" "; Robin Hood - The Legend of Sherwood (GOG)\n" "[Game/4]\n" "checkfile=.\\Robin Hood.exe\n" "singlecpu=false\n" "fix_not_responding=true\n" "\n" - "; Roland Garros 98 (software mode)\n" - "[rg98]\n" - "singlecpu=false\n" - "\n" "; Robin Hood - The Legend of Sherwood (Steam)\n" "[_rh]\n" "singlecpu=false\n" @@ -1625,7 +1573,6 @@ static void cfg_create_ini() "\n" "; Swarog\n" "[Swarog]\n" - "singlecpu=false\n" "maxfps=60\n" "maxgameticks=60\n" "minfps=-1\n" @@ -1744,10 +1691,6 @@ static void cfg_create_ini() "maxgameticks=30\n" "limiter_type=4\n" "\n" - "; The Curse Of Monkey Island\n" - "[COMI]\n" - "singlecpu=false\n" - "\n" "; The Tone Rebellion\n" "[Float]\n" "hook_peekmessage=true\n" @@ -1767,7 +1710,6 @@ static void cfg_create_ini() "; Virtual Springfield\n" "[VIRTUAL]\n" "game_handles_close=true\n" - "singlecpu=false\n" "\n" "; Total Annihilation: Kingdoms\n" "[Kingdoms]\n" @@ -1779,10 +1721,6 @@ static void cfg_create_ini() "lock_mouse_top_left=true\n" "fixchilds=3\n" "\n" - "; The Neverhood\n" - "[nhc]\n" - "singlecpu=false\n" - "\n" "; The X-Files DVD\n" "[XFiles]\n" "windowed=true\n" @@ -1884,10 +1822,6 @@ static void cfg_create_ini() "[WH40K]\n" "maxgameticks=250\n" "\n" - "; Weird War\n" - "[WeirdWar]\n" - "singlecpu=false\n" - "\n" "; Wizardry 8\n" "[Wiz8]\n" "sirtech_hack=true\n" @@ -1914,7 +1848,6 @@ static void cfg_create_ini() "\n" "; Jeff Wayne's 'The War Of The Worlds'\n" "[WoW]\n" - "singlecpu=false\n" "minfps=-1\n" "\n" "; Zeus and Poseidon\n" @@ -1924,7 +1857,6 @@ static void cfg_create_ini() "; Zork Nemesis\n" "[znemesis]\n" "fix_not_responding=true\n" - "singlecpu=false\n" "maxgameticks=60\n" "limiter_type=4\n" "\n" diff --git a/src/dd.c b/src/dd.c index e69063a..fed3f2e 100644 --- a/src/dd.c +++ b/src/dd.c @@ -1824,7 +1824,17 @@ HRESULT dd_CreateEx(GUID* lpGuid, LPVOID* lplpDD, REFIID iid, IUnknown* pUnkOute if (g_config.singlecpu) { - SetProcessAffinityMask(proc, 1); + if (!IsWine() && IsWindows11OrGreater()) + { + if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity)) + SetProcessAffinityMask(proc, system_affinity); + + util_set_process_affinity(); + } + else + { + SetProcessAffinityMask(proc, 1); + } } else if (GetProcessAffinityMask(proc, &proc_affinity, &system_affinity)) { diff --git a/src/debug.c b/src/debug.c index 9d615b5..b030114 100644 --- a/src/debug.c +++ b/src/debug.c @@ -17,6 +17,7 @@ #include "crc32.h" #include "dllmain.h" #include "config.h" +#include "delay_imports.h" double g_dbg_frame_time = 0; @@ -89,10 +90,7 @@ LONG WINAPI dbg_exception_handler(EXCEPTION_POINTERS* exception) HMODULE mod = NULL; char filename[MAX_PATH] = { 0 }; - BOOL(WINAPI * getModuleHandleExA)(DWORD, LPCSTR, HMODULE*) = - (void*)real_GetProcAddress(real_LoadLibraryA("Kernel32.dll"), "GetModuleHandleExA"); - - if (getModuleHandleExA && getModuleHandleExA( + if (delay_GetModuleHandleExA && delay_GetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, exception->ExceptionRecord->ExceptionAddress, &mod)) diff --git a/src/delay_imports.c b/src/delay_imports.c new file mode 100644 index 0000000..2b23dda --- /dev/null +++ b/src/delay_imports.c @@ -0,0 +1,30 @@ +#include +#include "versionhelpers.h" +#include "delay_imports.h" + +NTQUERYINFORMATIONTHREADPROC delay_NtQueryInformationThread; +RTLVERIFYVERSIONINFOPROC delay_RtlVerifyVersionInfo; +WINE_GET_VERSIONPROC delay_wine_get_version; +WINE_GET_HOST_VERSIONPROC delay_wine_get_host_version; + +VERSETCONDITIONMASKPROC delay_VerSetConditionMask; +GETMODULEHANDLEEXAPROC delay_GetModuleHandleExA; + +void delay_imports_init() +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + if (mod) + { + delay_NtQueryInformationThread = (NTQUERYINFORMATIONTHREADPROC)GetProcAddress(mod, "NtQueryInformationThread"); + delay_RtlVerifyVersionInfo = (RTLVERIFYVERSIONINFOPROC)GetProcAddress(mod, "RtlVerifyVersionInfo"); + delay_wine_get_version = (WINE_GET_VERSIONPROC)GetProcAddress(mod, "wine_get_version"); + delay_wine_get_host_version = (WINE_GET_HOST_VERSIONPROC)GetProcAddress(mod, "wine_get_host_version"); + } + + mod = GetModuleHandleA("Kernel32.dll"); + if (mod) + { + delay_VerSetConditionMask = (VERSETCONDITIONMASKPROC)GetProcAddress(mod, "VerSetConditionMask"); + delay_GetModuleHandleExA = (GETMODULEHANDLEEXAPROC)GetProcAddress(mod, "GetModuleHandleExA"); + } +} diff --git a/src/dllmain.c b/src/dllmain.c index 97d675f..adbc8c0 100644 --- a/src/dllmain.c +++ b/src/dllmain.c @@ -12,6 +12,7 @@ #include "indeo.h" #include "utils.h" #include "versionhelpers.h" +#include "delay_imports.h" #include "keyboard.h" @@ -33,7 +34,7 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { g_ddraw_module = hDll; - verhelp_init(); + delay_imports_init(); if (GetEnvironmentVariable("cnc_ddraw_config_init", NULL, 0)) { @@ -180,6 +181,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..ff89aa6 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" @@ -12,6 +13,7 @@ #include "utils.h" #include "config.h" #include "versionhelpers.h" +#include "delay_imports.h" /* @@ -71,6 +73,85 @@ 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) + { + void* start = NULL; + NTSTATUS status = STATUS_PENDING; + + if (delay_NtQueryInformationThread) + { + status = + delay_NtQueryInformationThread(thread, ThreadQuerySetWin32StartAddress, &start, sizeof(start), NULL); + } + + if (status == STATUS_SUCCESS && start && delay_GetModuleHandleExA) + { + char game_exe_path[MAX_PATH] = { 0 }; + char game_dir[MAX_PATH] = { 0 }; + + if (GetModuleFileNameA(NULL, game_exe_path, sizeof(game_exe_path))) + { + _splitpath(game_exe_path, NULL, game_dir, NULL, NULL); + + char mod_path[MAX_PATH] = { 0 }; + char mod_dir[MAX_PATH] = { 0 }; + char mod_filename[MAX_PATH] = { 0 }; + HMODULE mod = NULL; + + if (delay_GetModuleHandleExA( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, start, &mod)) + { + if (GetModuleFileNameA(mod, mod_path, sizeof(mod_path))) + { + _splitpath(mod_path, NULL, mod_dir, mod_filename, NULL); + + if (_strnicmp(game_dir, mod_dir, strlen(game_dir)) == 0 || + _strcmpi(mod_filename, "WINMM") == 0) + { + SetThreadAffinityMask(thread, 1); + } + } + } + } + } + else + { + SetThreadAffinityMask(thread, 1); + } + + CloseHandle(thread); + } +} + void util_pull_messages() { if (g_config.fix_not_responding && @@ -183,10 +264,7 @@ FARPROC util_get_iat_proc(HMODULE mod, char* module_name, char* function_name) BOOL util_caller_is_ddraw_wrapper(void* return_address) { - BOOL (WINAPI *getModuleHandleExA)(DWORD, LPCSTR, HMODULE*) = - (void*)real_GetProcAddress(real_LoadLibraryA("Kernel32.dll"), "GetModuleHandleExA"); - - if (!getModuleHandleExA) + if (!delay_GetModuleHandleExA) return FALSE; void* directDrawCreate = (void*)util_get_iat_proc(GetModuleHandleA(NULL), "ddraw.dll", "DirectDrawCreate"); @@ -200,9 +278,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address) HMODULE D3dHook_dll = GetModuleHandleA("D3dHook.dll"); if (D3dHook_dll) { - if ((getModuleHandleExA(flags, return_address, &mod) && mod == D3dHook_dll) || - (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == D3dHook_dll) || - (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == D3dHook_dll)) + if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == D3dHook_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == D3dHook_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == D3dHook_dll)) { MessageBoxA( NULL, @@ -218,9 +296,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address) HMODULE wndmode_dll = GetModuleHandleA("wndmode.dll"); if (wndmode_dll) { - if ((getModuleHandleExA(flags, return_address, &mod) && mod == wndmode_dll) || - (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == wndmode_dll) || - (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == wndmode_dll)) + if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == wndmode_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == wndmode_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == wndmode_dll)) { MessageBoxA( NULL, @@ -236,9 +314,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address) HMODULE windmode_dll = GetModuleHandleA("windmode.dll"); if (windmode_dll) { - if ((getModuleHandleExA(flags, return_address, &mod) && mod == windmode_dll) || - (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == windmode_dll) || - (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == windmode_dll)) + if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == windmode_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == windmode_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == windmode_dll)) { MessageBoxA( NULL, @@ -254,9 +332,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address) HMODULE dxwnd_dll = GetModuleHandleA("dxwnd.dll"); if (dxwnd_dll) { - if ((getModuleHandleExA(flags, return_address, &mod) && mod == dxwnd_dll) || - (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == dxwnd_dll) || - (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == dxwnd_dll)) + if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == dxwnd_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == dxwnd_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == dxwnd_dll)) { MessageBoxA( NULL, @@ -272,9 +350,9 @@ BOOL util_caller_is_ddraw_wrapper(void* return_address) HMODULE age_dll = GetModuleHandleA("age.dll"); if (age_dll) { - if ((getModuleHandleExA(flags, return_address, &mod) && mod == age_dll) || - (getModuleHandleExA(flags, directDrawCreate, &mod) && mod == age_dll) || - (getModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == age_dll)) + if ((delay_GetModuleHandleExA(flags, return_address, &mod) && mod == age_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreate, &mod) && mod == age_dll) || + (delay_GetModuleHandleExA(flags, directDrawCreateEx, &mod) && mod == age_dll)) { HKEY hkey; LONG status = diff --git a/src/versionhelpers.c b/src/versionhelpers.c index 7c19528..f9f35c2 100644 --- a/src/versionhelpers.c +++ b/src/versionhelpers.c @@ -1,56 +1,30 @@ #include #include "versionhelpers.h" +#include "delay_imports.h" -typedef NTSTATUS(WINAPI* RTLVERIFYVERSIONINFOPROC)(PRTL_OSVERSIONINFOEXW, ULONG, ULONGLONG); -typedef ULONGLONG(WINAPI* VERSETCONDITIONMASKPROC)(ULONGLONG, DWORD, BYTE); -typedef const char* (CDECL* WINE_GET_VERSIONPROC)(); -typedef void (CDECL* WINE_GET_HOST_VERSIONPROC)(const char** sysname, const char** release); - -static RTLVERIFYVERSIONINFOPROC RtlVerifyVersionInfo; -static VERSETCONDITIONMASKPROC VerSetConditionMaskProc; -static WINE_GET_VERSIONPROC wine_get_version; -static WINE_GET_HOST_VERSIONPROC wine_get_host_version; - -/* GetProcAddress is rather slow so we use a function to initialize it once on startup */ -void verhelp_init() -{ - HMODULE mod = GetModuleHandleA("ntdll.dll"); - if (mod) - { - RtlVerifyVersionInfo = (RTLVERIFYVERSIONINFOPROC)GetProcAddress(mod, "RtlVerifyVersionInfo"); - wine_get_version = (WINE_GET_VERSIONPROC)GetProcAddress(mod, "wine_get_version"); - wine_get_host_version = (WINE_GET_HOST_VERSIONPROC)GetProcAddress(mod, "wine_get_host_version"); - } - - mod = GetModuleHandleA("Kernel32.dll"); - if (mod) - { - VerSetConditionMaskProc = (VERSETCONDITIONMASKPROC)GetProcAddress(mod, "VerSetConditionMask"); - } -} BOOL verhelp_verify_version(PRTL_OSVERSIONINFOEXW versionInfo, ULONG typeMask, ULONGLONG conditionMask) { - return RtlVerifyVersionInfo ? - RtlVerifyVersionInfo(versionInfo, typeMask, conditionMask) == 0 : + return delay_RtlVerifyVersionInfo ? + delay_RtlVerifyVersionInfo(versionInfo, typeMask, conditionMask) == 0 : VerifyVersionInfoW(versionInfo, typeMask, conditionMask); } ULONGLONG verhelp_set_mask(ULONGLONG ConditionMask, DWORD TypeMask, BYTE Condition) { - return VerSetConditionMaskProc ? VerSetConditionMaskProc(ConditionMask, TypeMask, Condition) : 0; + return delay_VerSetConditionMask ? delay_VerSetConditionMask(ConditionMask, TypeMask, Condition) : 0; } const char* verhelp_wine_get_version() { - return wine_get_version ? wine_get_version() : NULL; + return delay_wine_get_version ? delay_wine_get_version() : NULL; } void verhelp_wine_get_host_version(const char** sysname, const char** release) { - if (wine_get_host_version) + if (delay_wine_get_host_version) { - wine_get_host_version(sysname, release); + delay_wine_get_host_version(sysname, release); return; }