Skip to content

Commit

Permalink
Potential workaround for deadlock during startup when DLL injectors a…
Browse files Browse the repository at this point in the history
…re present
  • Loading branch information
Norbyte committed Apr 30, 2024
1 parent ae559cb commit 7f3b26f
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 24 deletions.
12 changes: 6 additions & 6 deletions BG3Updater/BG3Updater.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpplatest</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm;$(SolutionDir)External\SDL2-2.30.1\include;$(SolutionDir)External\Detours\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>detours.lib;SDL2.lib;CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>Exports.def</ModuleDefinitionFile>
<AdditionalLibraryDirectories>$(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Debug;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Debug</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Debug;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Debug;$(SolutionDir)\External\SDL2-2.30.1\lib\x64;$(SolutionDir)\External\Detours\lib.X64</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>copy /Y "$(TargetPath)" "D:\SteamLibrary\steamapps\common\Baldurs Gate 3\bin\DWrite.dll"</Command>
Expand Down Expand Up @@ -154,16 +154,16 @@
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)\BG3Updater;$(SolutionDir)\External\curl\include;$(SolutionDir)\External\ziplib\Source;$(SolutionDir)\External\tinycrypt\lib\include;$(SolutionDir)\External\jsoncpp-master\include;$(SolutionDir)\BG3Extender;$(SolutionDir)\External\glm;$(SolutionDir)External\SDL2-2.30.1\include;$(SolutionDir)External\Detours\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>Exports.def</ModuleDefinitionFile>
<AdditionalDependencies>CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Release;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Release</AdditionalLibraryDirectories>
<AdditionalDependencies>detours.lib;SDL2.lib;CoreLib.lib;version.lib;jsoncpp.lib;TinyCrypt.lib;comctl32.lib;shlwapi.lib;Rpcrt4.lib;dbghelp.lib;ZipLib.lib;bzip2.lib;lzma.lib;zlib.lib;libcurl_a.lib;Normaliz.lib;Wldap32.lib;ws2_32.lib;Crypt32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\External\curl\lib;$(SolutionDir)\External\ziplib\Bin\x64\Release;$(SolutionDir)$(Platform)\$(Configuration);$(SolutionDir)\External\jsoncpp-build\src\lib_json\Release;$(SolutionDir)\External\SDL2-2.30.1\lib\x64;$(SolutionDir)\External\Detours\lib.X64</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>copy /Y "$(TargetPath)" "D:\SteamLibrary\steamapps\common\Baldurs Gate 3\bin\DWrite.dll"</Command>
Expand Down
Binary file modified BG3Updater/Resources.rc
Binary file not shown.
50 changes: 34 additions & 16 deletions BG3Updater/Updater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
#include "HttpFetcher.h"
#include <Shlwapi.h>
#include <CommCtrl.h>
#include <detours.h>
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")


BEGIN_SE()

std::unordered_set<void const*> gRegisteredTrampolines;

WrappableFunction<ScriptExtenderUpdater::SDLInitTag, int(Uint32)>* WrappableFunction<ScriptExtenderUpdater::SDLInitTag, int(Uint32)>::gHook;

ManifestFetcher::ManifestFetcher(HttpFetcher& fetcher, UpdaterConfig const& config)
: fetcher_(fetcher), config_(config)
{}
Expand Down Expand Up @@ -322,6 +327,7 @@ void ScriptExtenderUpdater::Initialize(char const* exeDirOverride)
UpdateExeDir(exeDirOverride);
LoadConfig();
LoadGameVersion();
HookSDL();
}

void ScriptExtenderUpdater::UpdateExeDir(char const* exeDirOverride)
Expand Down Expand Up @@ -377,6 +383,32 @@ void ScriptExtenderUpdater::LoadGameVersion()
}
}

void ScriptExtenderUpdater::HookSDL()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
SDLInitHook.Wrap(ResolveFunctionTrampoline(&SDL_Init));
SDLInitHook.SetPostHook(&ScriptExtenderUpdater::OnSDLInit, this);
DetourTransactionCommit();
}

void ScriptExtenderUpdater::UnhookSDL()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
SDLInitHook.Unwrap();
DetourTransactionCommit();
}

void ScriptExtenderUpdater::OnSDLInit(Uint32, int)
{
while (needsClientSuspend_) {
Sleep(10);
}

UnhookSDL();
}

void ScriptExtenderUpdater::UpdatePaths()
{
auto cacheDir = config_.CachePath;
Expand Down Expand Up @@ -481,28 +513,13 @@ HRESULT UpdaterUI::UICallback(HWND hwnd, UINT uNotification, WPARAM wParam, LPAR
return S_OK;
}

volatile bool NeedsClientSuspend{ false };

DWORD WINAPI DelayedClientSuspenderThread(LPVOID param)
{
Sleep(1000);
if (NeedsClientSuspend) {
DEBUG("Suspending client thread");
gGameHelpers->SuspendClientThread();
}
return 0;
}

DWORD WINAPI UpdaterThread(LPVOID param)
{
gUpdater->InitConsole();
gUpdater->InitUI();
DEBUG("Launch loader");
NeedsClientSuspend = true;
CreateThread(NULL, 0, &DelayedClientSuspenderThread, NULL, 0, NULL);
gUpdater->Run();
NeedsClientSuspend = false;
gGameHelpers->ResumeClientThread();
gUpdater->RequestClientSuspend(false);
DEBUG("Extender launcher thread exiting");
return 0;
}
Expand All @@ -518,6 +535,7 @@ void StartUpdaterThread()

gUpdater = std::make_unique<ScriptExtenderUpdater>();
gUpdater->Initialize(nullptr);
gUpdater->RequestClientSuspend(true);
CreateThread(NULL, 0, &UpdaterThread, NULL, 0, NULL);
}

Expand Down
15 changes: 15 additions & 0 deletions BG3Updater/Updater.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "Cache.h"
#include "HttpFetcher.h"
#include <curl/curl.h>
#include <CoreLib/Wrappers.h>
#include <SDL.h>

BEGIN_SE()

Expand Down Expand Up @@ -125,12 +127,19 @@ class ScriptExtenderUpdater
return cancellingUpdate_;
}

void RequestClientSuspend(bool suspend)
{
needsClientSuspend_ = suspend;
}

void Initialize(char const* exeDirOverride);
void Run();
void LoadCaches();
bool FetchUpdates();
bool LoadExtender();

enum class SDLInitTag {};

private:
VersionNumber gameVersion_;
UpdaterConfig config_;
Expand All @@ -145,11 +154,17 @@ class ScriptExtenderUpdater
bool completed_{ false };
bool cancellingUpdate_{ false };
std::string log_;
volatile bool needsClientSuspend_{ false };

WrappableFunction<SDLInitTag, int (Uint32)> SDLInitHook;

void UpdatePaths();
void UpdateExeDir(char const* exeDirOverride);
void LoadConfig();
void LoadGameVersion();
void HookSDL();
void UnhookSDL();
void OnSDLInit(Uint32, int);
};

void StartUpdaterThread();
Expand Down
4 changes: 2 additions & 2 deletions BG3Updater/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Microsoft Visual C++ generated include file.
// Used by Resources.rc

#define UPDATER_DLL_MAJOR_VERSION 1
#define UPDATER_DLL_VERSION_STRING "1.0.0.0"
#define UPDATER_DLL_MAJOR_VERSION 5
#define UPDATER_DLL_VERSION_STRING "5.0.0.0"

#define IDR_BINARY_MAPPINGS 101

Expand Down

0 comments on commit 7f3b26f

Please sign in to comment.