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;
}