1
0
Fork 0

Check Universal CRT version on Windows

Catch older versions of Ucrtbase.dll which can deadlock inside
setlocale() for us.
This commit is contained in:
James Turner 2022-01-20 20:37:44 +00:00
parent fe9aadd8bb
commit 1114d836da
2 changed files with 46 additions and 9 deletions

View file

@ -115,7 +115,7 @@ IF(APPLE)
elseif(WIN32) elseif(WIN32)
set(EVENT_INPUT_DEFAULT 1) set(EVENT_INPUT_DEFAULT 1)
set(ENABLE_VR_DEFAULT 1) set(ENABLE_VR_DEFAULT 1)
list(APPEND PLATFORM_LIBS "Shlwapi.lib") list(APPEND PLATFORM_LIBS "Shlwapi.lib" "Version.lib")
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "bin") set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION "bin")
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)

53
src/Main/bootstrap.cxx Normal file → Executable file
View file

@ -147,6 +147,44 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
main(numArgs, utf8Args.data()); main(numArgs, utf8Args.data());
} }
// see https://stackoverflow.com/questions/35572792/setlocale-stuck-on-windows
// for why we need this
bool checkUniversalCRTVersion()
{
DWORD dwSize = 0;
VS_FIXEDFILEINFO *pFileInfo = NULL;
UINT puLenFileInfo = 0;
// Get the version information for the file requested
dwSize = GetFileVersionInfoSize("ucrtbase.dll", NULL);
if (dwSize == 0) {
return false;
}
std::vector<BYTE> versionInfo;
versionInfo.resize(dwSize);
if (!GetFileVersionInfo("ucrtbase.dll", 0, dwSize, versionInfo.data())) {
return false;
}
if (!VerQueryValue(versionInfo.data(), TEXT("\\"), (LPVOID*)&pFileInfo, &puLenFileInfo)) {
return false;
}
const WORD majorVersion = pFileInfo->dwFileVersionMS >> 16;
const WORD minorVersion = pFileInfo->dwFileVersionMS & 0xffff;
const WORD buildVersion = pFileInfo->dwFileVersionLS >> 16;
const WORD releaseVersion = pFileInfo->dwFileVersionLS & 0xffff;
// char buffer[256];
// snprintf(buffer, 256, "File Version: %d.%d.%d.%d\n",
// majorVersion, minorVersion, buildVersion, releaseVersion);
// OutputDebugString(buffer);
return (buildVersion > 10586);
}
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
@ -255,8 +293,14 @@ int main ( int argc, char **argv )
// See Microsoft MSDN #ms680621: "GUI apps should specify SEM_NOOPENFILEERRORBOX" // See Microsoft MSDN #ms680621: "GUI apps should specify SEM_NOOPENFILEERRORBOX"
SetErrorMode(SEM_NOOPENFILEERRORBOX); SetErrorMode(SEM_NOOPENFILEERRORBOX);
std::cerr << "Boostrap-0" << std::endl;
hostname = ::getenv( "COMPUTERNAME" ); hostname = ::getenv( "COMPUTERNAME" );
if (!checkUniversalCRTVersion()) {
flightgear::fatalMessageBoxThenExit(
"Fatal error",
"The Microsoft Universal CRT on this computer is to old to run FlightGear. "
"Pleaese use Windows Update to update to a more recent Universal CRT version.");
}
#else #else
// Unix(alike) systems // Unix(alike) systems
char _hostname[256]; char _hostname[256];
@ -270,9 +314,7 @@ int main ( int argc, char **argv )
#if defined(HAVE_SENTRY) #if defined(HAVE_SENTRY)
const bool noSentry = flightgear::Options::checkForArg(argc, argv, "disable-sentry"); const bool noSentry = flightgear::Options::checkForArg(argc, argv, "disable-sentry");
if (!noSentry) { if (!noSentry) {
std::cerr << "Will init sentry" << std::endl;
flightgear::initSentry(); flightgear::initSentry();
std::cerr << "Did init sentry" << std::endl;
} }
#endif #endif
@ -287,7 +329,6 @@ int main ( int argc, char **argv )
#endif #endif
initFPE(flightgear::Options::checkForArg(argc, argv, "enable-fpe")); initFPE(flightgear::Options::checkForArg(argc, argv, "enable-fpe"));
std::cerr << "Did init FPE" << std::endl;
// pick up all user locale settings, but force C locale for numerical/sorting // pick up all user locale settings, but force C locale for numerical/sorting
// conversions because we have lots of code which assumes standard // conversions because we have lots of code which assumes standard
@ -300,8 +341,6 @@ int main ( int argc, char **argv )
return fgUninstall(); return fgUninstall();
} }
std::cerr << "Boostrap-1" << std::endl;
bool fgviewer = flightgear::Options::checkForArg(argc, argv, "fgviewer"); bool fgviewer = flightgear::Options::checkForArg(argc, argv, "fgviewer");
int exitStatus = EXIT_FAILURE; int exitStatus = EXIT_FAILURE;
try { try {
@ -326,8 +365,6 @@ int main ( int argc, char **argv )
std::set_terminate(fg_terminate); std::set_terminate(fg_terminate);
atexit(fgExitCleanup); atexit(fgExitCleanup);
std::cerr << "Boostrap-2" << std::endl;
if (fgviewer) { if (fgviewer) {
exitStatus = fgviewerMain(argc, argv); exitStatus = fgviewerMain(argc, argv);
} else { } else {