From e8e70828d1a503abbaa3d2633d0c311554bc59e8 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 29 Jun 2022 20:00:32 -0700 Subject: [PATCH] Config: Fixes AppConfig for wine-preloader When wine-preloader is executed it doesn't do an execve to passed in wine program. It will instead map the executable directly in to memory and start executing it. This way we end up with a program executing like `wine-preloader Game.exe` This now handles the wine-preloader case so we can get the correct application profile here. --- Source/Common/Config.cpp | 67 ++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/Source/Common/Config.cpp b/Source/Common/Config.cpp index 21b07f4de..c0421a5c5 100644 --- a/Source/Common/Config.cpp +++ b/Source/Common/Config.cpp @@ -24,20 +24,20 @@ namespace FEX::Config { Dest = json_objOpen(Buffer, nullptr); Dest = json_objOpen(Dest, "Config"); for (auto &it : Layer->GetOptionMap()) { - auto &Name = ConfigToNameLookup.find(it.first)->second; - for (auto &var : it.second) { - Dest = json_str(Dest, Name.c_str(), var.c_str()); - } + auto &Name = ConfigToNameLookup.find(it.first)->second; + for (auto &var : it.second) { + Dest = json_str(Dest, Name.c_str(), var.c_str()); + } } Dest = json_objClose(Dest); Dest = json_objClose(Dest); json_end(Dest); - std::ofstream Output (Filename, std::ios::out | std::ios::binary); - if (Output.is_open()) { - Output.write(Buffer, strlen(Buffer)); - Output.close(); - } + std::ofstream Output (Filename, std::ios::out | std::ios::binary); + if (Output.is_open()) { + Output.write(Buffer, strlen(Buffer)); + Output.close(); + } } std::string LoadConfig( @@ -69,23 +69,42 @@ namespace FEX::Config { std::string Program = Args[0]; - // These layers load on initialization - auto ProgramName = std::filesystem::path(Program).filename(); - if (ProgramName == "wine" || - ProgramName == "wine64") { + bool Wine = false; + std::filesystem::path ProgramName; + for (size_t CurrentProgramNameIndex = 0; CurrentProgramNameIndex < Args.size(); ++CurrentProgramNameIndex) { + auto CurrentProgramName = std::filesystem::path(Args[CurrentProgramNameIndex]).filename(); - // If we are running wine or wine64 then we should check the second argument for the application name instead. - // wine will change the active program name with `setprogname` or `prctl(PR_SET_NAME`. - // Since FEX needs this data far earlier than libraries we need a different check. - if (Args.size() > 1) { - ProgramName = std::filesystem::path(Args[1]).filename(); - - // If this was path separated with '\' then we need to check that. - auto WinSeparator = ProgramName.string().find_last_of('\\'); - if (WinSeparator != ProgramName.string().npos) { - // Used windows separators - ProgramName = ProgramName.string().substr(WinSeparator + 1); + if (CurrentProgramName == "wine-preloader" || + CurrentProgramName == "wine64-preloader") { + // Wine preloader is required to be in the format of `wine-preloader ` + // The preloader doesn't execve the executable, instead maps it directly itself + // Skip the next argument since we know it is wine (potentially with custom wine executable name) + ++CurrentProgramNameIndex; + Wine = true; + } + else if(CurrentProgramName == "wine" || + CurrentProgramName == "wine64") { + // Next argument, this isn't the program we want + // + // If we are running wine or wine64 then we should check the next argument for the application name instead. + // wine will change the active program name with `setprogname` or `prctl(PR_SET_NAME`. + // Since FEX needs this data far earlier than libraries we need a different check. + Wine = true; + } + else { + if (Wine == true) { + // If this was path separated with '\' then we need to check that. + auto WinSeparator = CurrentProgramName.string().find_last_of('\\'); + if (WinSeparator != CurrentProgramName.string().npos) { + // Used windows separators + CurrentProgramName = CurrentProgramName.string().substr(WinSeparator + 1); + } } + + ProgramName = CurrentProgramName; + + // Past any wine program names + break; } }