Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion engine/system/sys_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class find_c {
std::filesystem::directory_iterator iter;
};

std::string GetWineHostVersion();
std::tuple<std::string, std::string> GetWineHostVersion();

// ==========
// Interfaces
Expand Down
50 changes: 37 additions & 13 deletions engine/system/win/sys_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,38 +434,62 @@ void sys_main_c::SpawnProcess(std::filesystem::path cmdName, const char* argList
#endif
}

std::string GetWineHostVersion()
// get wine host OS type and x.y.z format version of wine
std::tuple<std::string, std::string> GetWineHostVersion()
{
#ifdef _WIN32
using WineHostVersionFun = void(const char** /*sysname*/, const char** /*release*/);
using WineVersionFun = char *();
HMODULE mod = GetModuleHandleA("ntdll.dll");
if (!mod)
return "";
return {"", ""};
auto ptr = GetProcAddress(mod, "wine_get_host_version");
if (!ptr)
return "";
return {"", ""};
auto verPtr = GetProcAddress(mod, "wine_get_version");
if (!verPtr)
return {"", ""};
auto fun = (WineHostVersionFun*)ptr;
const char* sysname{};
const char* release{};
fun(&sysname, &release);
return sysname ? sysname : "";

auto verFun = (WineVersionFun *)verPtr;
// version in x.y.z format
const char *version = verFun();
if (sysname && version)
{
return {sysname, version};
}
else
{
return {"", ""};
}
#else
return "";
return {"", ""};
#endif
}

#if _WIN32 || __linux__
const char* PlatformOpenURL(const char* url)
{
#ifdef _WIN32
const std::string wineHost = GetWineHostVersion();
/*
Wine has some loosely determined maximum length on how long of an URL
can be, so we pick a "safe" maximum and refuse to open anything longer.
*/
if ((wineHost == "Linux" || wineHost == "Darwin") && strlen(url) > 1500)
return AllocString("Did not open URL, length likely too long for the OS.");
ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWDEFAULT);
auto [wineHost, wineVersion] = GetWineHostVersion();
int major = INT_MAX;
int minor = INT_MAX;
auto match = RE2::PartialMatch(wineVersion, "^(\\d+)\\.(\\d+)", &major, &minor);
// work around a pre-8.17 wine bug where long urls may cause a stack corruption and overflow
bool invalidVersion = (major < 8) || (major == 8 && minor < 17);
if ((wineHost == "Linux" || wineHost == "Darwin") && strlen(url) > 1500 && invalidVersion)
{
return AllocString("Did not open URL, length likely too long for pre-8.17 Wine versions.");
}
auto retVal = (INT_PTR)ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOWDEFAULT);
// "If the function succeeds, it returns a value greater than 32"
if (retVal <= 32)
{
return AllocString("Opening URL failed.");
}
return nullptr;
#else
#warning LV: URL opening not implemented on this OS.
Expand Down
2 changes: 1 addition & 1 deletion engine/system/win/sys_video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ sys_video_c::sys_video_c(sys_IMain* sysHnd)

int platformType = GLFW_ANGLE_PLATFORM_TYPE_NONE;
#ifdef _WIN32
const std::string wineHost = GetWineHostVersion();
auto [wineHost, _] = GetWineHostVersion();
if (wineHost == "Linux")
platformType = GLFW_ANGLE_PLATFORM_TYPE_OPENGL;
else if (wineHost == "Darwin")
Expand Down
Loading