mirror of
https://github.com/FEX-Emu/FEX.git
synced 2025-01-09 07:10:39 +00:00
Merge pull request #4030 from bylaws/eccfg
Windows: Load per-application configs
This commit is contained in:
commit
49b40b71a6
@ -337,8 +337,57 @@ fextl::string RecoverGuestProgramFilename(fextl::string Program, bool ExecFDInte
|
||||
return Program;
|
||||
}
|
||||
|
||||
ApplicationNames LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoader, bool LoadProgramConfig, char** const envp,
|
||||
bool ExecFDInterp, int ProgramFDFromEnv, const PortableInformation& PortableInfo) {
|
||||
ApplicationNames GetApplicationNames(fextl::vector<fextl::string> Args, bool ExecFDInterp, int ProgramFDFromEnv) {
|
||||
if (Args.empty()) {
|
||||
// Early exit if we weren't passed an argument
|
||||
return {};
|
||||
}
|
||||
|
||||
fextl::string Program {};
|
||||
fextl::string ProgramName {};
|
||||
|
||||
Args[0] = RecoverGuestProgramFilename(std::move(Args[0]), ExecFDInterp, ProgramFDFromEnv);
|
||||
Program = Args[0];
|
||||
|
||||
bool Wine = false;
|
||||
for (size_t CurrentProgramNameIndex = 0; CurrentProgramNameIndex < Args.size(); ++CurrentProgramNameIndex) {
|
||||
auto CurrentProgramName = FHU::Filesystem::GetFilename(Args[CurrentProgramNameIndex]);
|
||||
|
||||
if (CurrentProgramName == "wine-preloader" || CurrentProgramName == "wine64-preloader") {
|
||||
// Wine preloader is required to be in the format of `wine-preloader <wine executable>`
|
||||
// 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.find_last_of('\\');
|
||||
if (WinSeparator != CurrentProgramName.npos) {
|
||||
// Used windows separators
|
||||
CurrentProgramName = CurrentProgramName.substr(WinSeparator + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ProgramName = CurrentProgramName;
|
||||
|
||||
// Past any wine program names
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ApplicationNames {std::move(Program), std::move(ProgramName)};
|
||||
}
|
||||
|
||||
void LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoader, fextl::string ProgramName, char** const envp,
|
||||
const PortableInformation& PortableInfo) {
|
||||
const bool IsPortable = PortableInfo.IsPortable;
|
||||
FEX::Config::InitializeConfigs(PortableInfo);
|
||||
FEXCore::Config::Initialize();
|
||||
@ -347,53 +396,7 @@ ApplicationNames LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoa
|
||||
}
|
||||
FEXCore::Config::AddLayer(CreateMainLayer());
|
||||
|
||||
auto Args = ArgsLoader->Get();
|
||||
|
||||
fextl::string Program {};
|
||||
fextl::string ProgramName {};
|
||||
if (LoadProgramConfig) {
|
||||
if (Args.empty()) {
|
||||
// Early exit if we weren't passed an argument
|
||||
return {};
|
||||
}
|
||||
|
||||
Args[0] = RecoverGuestProgramFilename(std::move(Args[0]), ExecFDInterp, ProgramFDFromEnv);
|
||||
Program = Args[0];
|
||||
|
||||
bool Wine = false;
|
||||
for (size_t CurrentProgramNameIndex = 0; CurrentProgramNameIndex < Args.size(); ++CurrentProgramNameIndex) {
|
||||
auto CurrentProgramName = FHU::Filesystem::GetFilename(Args[CurrentProgramNameIndex]);
|
||||
|
||||
if (CurrentProgramName == "wine-preloader" || CurrentProgramName == "wine64-preloader") {
|
||||
// Wine preloader is required to be in the format of `wine-preloader <wine executable>`
|
||||
// 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.find_last_of('\\');
|
||||
if (WinSeparator != CurrentProgramName.npos) {
|
||||
// Used windows separators
|
||||
CurrentProgramName = CurrentProgramName.substr(WinSeparator + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ProgramName = CurrentProgramName;
|
||||
|
||||
// Past any wine program names
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ProgramName.empty()) {
|
||||
if (!IsPortable) {
|
||||
FEXCore::Config::AddLayer(CreateAppLayer(ProgramName, FEXCore::Config::LayerType::LAYER_GLOBAL_APP));
|
||||
}
|
||||
@ -411,7 +414,7 @@ ApplicationNames LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoa
|
||||
}
|
||||
}
|
||||
|
||||
if (ArgsLoader->GetLoadType() == FEX::ArgLoader::ArgLoader::LoadType::WITH_FEXLOADER_PARSER) {
|
||||
if (ArgsLoader && ArgsLoader->GetLoadType() == FEX::ArgLoader::ArgLoader::LoadType::WITH_FEXLOADER_PARSER) {
|
||||
FEXCore::Config::AddLayer(std::move(ArgsLoader));
|
||||
}
|
||||
|
||||
@ -422,13 +425,6 @@ ApplicationNames LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgsLoa
|
||||
|
||||
FEXCore::Config::AddLayer(CreateEnvironmentLayer(envp));
|
||||
FEXCore::Config::Load();
|
||||
|
||||
|
||||
if (LoadProgramConfig) {
|
||||
return ApplicationNames {std::move(Program), std::move(ProgramName)};
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@ -35,18 +35,22 @@ struct PortableInformation {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Loads the FEX and application configurations for the application that is getting ready to run.
|
||||
*
|
||||
* @param ArgLoader Argument loader for argument based config options
|
||||
* @param LoadProgramConfig Do we want to load application specific configurations?
|
||||
* @param envp The `envp` passed to main(...)
|
||||
* @param ExecFDInterp If FEX was executed with binfmt_misc FD argument
|
||||
* @param ProgramFDFromEnv The execveat FD argument passed through FEX
|
||||
*
|
||||
* @return The application name and path structure
|
||||
*/
|
||||
ApplicationNames LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgLoader, bool LoadProgramConfig, char** const envp,
|
||||
bool ExecFDInterp, int ProgramFDFromEnv, const PortableInformation& PortableInfo);
|
||||
ApplicationNames GetApplicationNames(fextl::vector<fextl::string> Args, bool ExecFDInterp, int ProgramFDFromEnv);
|
||||
|
||||
/**
|
||||
* @brief Loads the FEX and application configurations for the application that is getting ready to run.
|
||||
*
|
||||
* @param ArgLoader Optional argument loader for argument based config options
|
||||
* @param ProgramName Optional program name, if non-empty application specific configurations will be loaded
|
||||
* @param envp Optional `envp` passed to main(...)
|
||||
*/
|
||||
void LoadConfig(fextl::unique_ptr<FEX::ArgLoader::ArgLoader> ArgLoader = {}, fextl::string ProgramName = {}, char** const envp = nullptr,
|
||||
const PortableInformation& PortableInfo = {});
|
||||
|
||||
const char* GetHomeDirectory();
|
||||
|
||||
|
@ -324,13 +324,14 @@ int main(int argc, char** argv, char** const envp) {
|
||||
argc, argv);
|
||||
auto Args = ArgsLoader->Get();
|
||||
auto ParsedArgs = ArgsLoader->GetParsedArgs();
|
||||
auto Program = FEX::Config::LoadConfig(std::move(ArgsLoader), true, envp, ExecutedWithFD, FEXFD, PortableInfo);
|
||||
|
||||
auto Program = FEX::Config::GetApplicationNames(Args, ExecutedWithFD, FEXFD);
|
||||
if (Program.ProgramPath.empty() && FEXFD == -1) {
|
||||
// Early exit if we weren't passed an argument
|
||||
return 0;
|
||||
}
|
||||
|
||||
FEX::Config::LoadConfig(std::move(ArgsLoader), Program.ProgramName, envp, PortableInfo);
|
||||
|
||||
// Reload the meta layer
|
||||
FEXCore::Config::ReloadMetaLayer();
|
||||
FEXCore::Config::Set(FEXCore::Config::CONFIG_IS_INTERPRETER, IsInterpreter ? "1" : "0");
|
||||
|
@ -1091,7 +1091,7 @@ bool ExtractEroFS(const fextl::string& Path, const fextl::string& RootFS, const
|
||||
|
||||
int main(int argc, char** argv, char** const envp) {
|
||||
auto ArgsLoader = fextl::make_unique<FEX::ArgLoader::ArgLoader>(FEX::ArgLoader::ArgLoader::LoadType::WITHOUT_FEXLOADER_PARSER, argc, argv);
|
||||
FEX::Config::LoadConfig(std::move(ArgsLoader), false, envp, false, false, FEX::Config::PortableInformation {});
|
||||
FEX::Config::LoadConfig(std::move(ArgsLoader), {}, envp);
|
||||
|
||||
// Reload the meta layer
|
||||
FEXCore::Config::ReloadMetaLayer();
|
||||
|
@ -117,7 +117,7 @@ int main(int argc, char** argv, char** const envp) {
|
||||
}
|
||||
|
||||
auto ArgsLoader = fextl::make_unique<FEX::ArgLoader::ArgLoader>(FEX::ArgLoader::ArgLoader::LoadType::WITHOUT_FEXLOADER_PARSER, argc, argv);
|
||||
FEX::Config::LoadConfig(std::move(ArgsLoader), false, envp, false, false, FEX::Config::PortableInformation {});
|
||||
FEX::Config::LoadConfig(std::move(ArgsLoader), {}, envp);
|
||||
|
||||
// Reload the meta layer
|
||||
FEXCore::Config::ReloadMetaLayer();
|
||||
|
@ -24,12 +24,14 @@ $end_info$
|
||||
#include <FEXCore/Utils/MathUtils.h>
|
||||
#include <FEXCore/Utils/TypeDefines.h>
|
||||
|
||||
#include "Common/ArgumentLoader.h"
|
||||
#include "Common/Config.h"
|
||||
#include "Common/Exception.h"
|
||||
#include "Common/InvalidationTracker.h"
|
||||
#include "Common/TSOHandlerConfig.h"
|
||||
#include "Common/CPUFeatures.h"
|
||||
#include "Common/Logging.h"
|
||||
#include "Common/Module.h"
|
||||
#include "Common/CRT/CRT.h"
|
||||
#include "DummyHandlers.h"
|
||||
#include "BTInterface.h"
|
||||
@ -456,11 +458,7 @@ extern "C" void SyncThreadContext(CONTEXT* Context) {
|
||||
|
||||
NTSTATUS ProcessInit() {
|
||||
FEX::Windows::InitCRTProcess();
|
||||
FEX::Config::InitializeConfigs(FEX::Config::PortableInformation {});
|
||||
FEXCore::Config::Initialize();
|
||||
FEXCore::Config::AddLayer(FEX::Config::CreateGlobalMainLayer());
|
||||
FEXCore::Config::AddLayer(FEX::Config::CreateMainLayer());
|
||||
FEXCore::Config::Load();
|
||||
FEX::Config::LoadConfig(nullptr, FEX::Windows::GetExecutableFilePath());
|
||||
FEXCore::Config::ReloadMetaLayer();
|
||||
FEX::Windows::Logging::Init();
|
||||
|
||||
|
24
Source/Windows/Common/Module.h
Normal file
24
Source/Windows/Common/Module.h
Normal file
@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <FEXCore/fextl/string.h>
|
||||
#include <winternl.h>
|
||||
|
||||
namespace FEX::Windows {
|
||||
fextl::string GetExecutableFilePath() {
|
||||
std::array<WCHAR, PATH_MAX> Buf;
|
||||
UNICODE_STRING PathW {.Length = 0, .MaximumLength = Buf.size() * sizeof(WCHAR), .Buffer = Buf.data()};
|
||||
|
||||
if (LdrGetDllFullName(nullptr, &PathW)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
STRING PathA;
|
||||
RtlUnicodeStringToAnsiString(&PathA, &PathW, TRUE);
|
||||
fextl::string Path(PathA.Buffer);
|
||||
RtlFreeAnsiString(&PathA);
|
||||
|
||||
return Path.substr(Path.find_last_of('\\') + 1);
|
||||
}
|
||||
} // namespace FEX::Windows
|
@ -25,12 +25,14 @@ $end_info$
|
||||
#include <FEXCore/Utils/ArchHelpers/Arm64.h>
|
||||
#include <FEXCore/Utils/TypeDefines.h>
|
||||
|
||||
#include "Common/ArgumentLoader.h"
|
||||
#include "Common/Config.h"
|
||||
#include "Common/Exception.h"
|
||||
#include "Common/TSOHandlerConfig.h"
|
||||
#include "Common/InvalidationTracker.h"
|
||||
#include "Common/CPUFeatures.h"
|
||||
#include "Common/Logging.h"
|
||||
#include "Common/Module.h"
|
||||
#include "Common/CRT/CRT.h"
|
||||
#include "DummyHandlers.h"
|
||||
#include "BTInterface.h"
|
||||
@ -424,11 +426,7 @@ public:
|
||||
|
||||
void BTCpuProcessInit() {
|
||||
FEX::Windows::InitCRTProcess();
|
||||
FEX::Config::InitializeConfigs(FEX::Config::PortableInformation {});
|
||||
FEXCore::Config::Initialize();
|
||||
FEXCore::Config::AddLayer(FEX::Config::CreateGlobalMainLayer());
|
||||
FEXCore::Config::AddLayer(FEX::Config::CreateMainLayer());
|
||||
FEXCore::Config::Load();
|
||||
FEX::Config::LoadConfig(nullptr, FEX::Windows::GetExecutableFilePath());
|
||||
FEXCore::Config::ReloadMetaLayer();
|
||||
FEX::Windows::Logging::Init();
|
||||
|
||||
|
@ -433,6 +433,7 @@ typedef struct _KEY_VALUE_PARTIAL_INFORMATION {
|
||||
|
||||
NTSTATUS WINAPIV DbgPrint(LPCSTR fmt, ...);
|
||||
NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
|
||||
NTSTATUS WINAPI LdrGetDllFullName(HMODULE, UNICODE_STRING*);
|
||||
NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*);
|
||||
NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
|
||||
NTSTATUS WINAPI NtAllocateVirtualMemoryEx(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MEM_EXTENDED_PARAMETER*, ULONG);
|
||||
|
Loading…
Reference in New Issue
Block a user