diff --git a/loader/launcher/windows/Updater.cpp b/loader/launcher/windows/Updater.cpp index 37fe9fd5..b6c7d8be 100644 --- a/loader/launcher/windows/Updater.cpp +++ b/loader/launcher/windows/Updater.cpp @@ -69,6 +69,14 @@ int main(int argc, char* argv[]) { } } + if (ghc::filesystem::exists(workingDir / "GeodeBootstrapper.dll", error) && !error) { + ghc::filesystem::remove(workingDir / "GeodeBootstrapper.dll", error); + if (error) { + showError("Unable to update Geode: Unable to delete GeodeBootstrapper.dll - " + error.message()); + return error.value(); + } + } + if(argc < 2) return 0; diff --git a/loader/src/main.cpp b/loader/src/main.cpp index 2c27a728..b14026f0 100644 --- a/loader/src/main.cpp +++ b/loader/src/main.cpp @@ -66,14 +66,15 @@ extern "C" [[gnu::visibility("default")]] jint JNI_OnLoad(JavaVM* vm, void* rese #elif defined(GEODE_IS_WINDOWS) #include <Windows.h> -int WINAPI gdMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { +int updateGeode() { auto workingDir = dirs::getGameDir(); auto updatesDir = workingDir / "geode" / "update"; auto error = std::error_code(); - if (ghc::filesystem::exists(updatesDir / "GeodeUpdater.exe", error) && !error) { - ghc::filesystem::rename(updatesDir / "GeodeUpdater.exe", workingDir / "GeodeUpdater.exe", error); + if (!ghc::filesystem::is_empty(updatesDir, error) && !error) { + if (ghc::filesystem::exists(updatesDir / "GeodeUpdater.exe", error) && !error) + ghc::filesystem::rename(updatesDir / "GeodeUpdater.exe", workingDir / "GeodeUpdater.exe", error); if (error) return error.value(); @@ -89,9 +90,21 @@ int WINAPI gdMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd exit(0); return 0; } - int exitCode = geodeEntry(hInstance); + if (error) + return error.value(); + + return 0; +} + +int WINAPI gdMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { + int exitCode = updateGeode(); if (exitCode != 0) return exitCode; + + exitCode = geodeEntry(hInstance); + if (exitCode != 0) + return exitCode; + return reinterpret_cast<decltype(&wWinMain)>(geode::base::get() + 0x260ff8)(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } @@ -128,6 +141,25 @@ extern "C" __declspec(dllexport) DWORD WINAPI loadGeode(void* arg) { return 0; } + +DWORD WINAPI upgradeThread(void*) { + return updateGeode() == 0; +} +BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID) { + if (reason == DLL_PROCESS_ATTACH) { + DisableThreadLibraryCalls(module); + + // if we find the old bootstrapper dll, don't load geode, copy new updater and let it do the rest + auto workingDir = dirs::getGameDir(); + auto error = std::error_code(); + if (ghc::filesystem::exists(workingDir / "GeodeBootstrapper.dll", error) && !error) + CreateThread(nullptr, 0, upgradeThread, nullptr, 0, nullptr); + if (error) + return FALSE; + } + return TRUE; +} + #endif $execute {