Ditch fs::get_executable_dir

This commit is contained in:
Nekotekina 2017-02-22 16:08:53 +03:00
parent 4cba60b27f
commit baf22527b0
12 changed files with 73 additions and 137 deletions

View file

@ -1125,11 +1125,22 @@ const std::string& fs::get_config_dir()
// Use magic static
static const std::string s_dir = []
{
#ifdef _WIN32
return get_executable_dir(); // ?
#else
std::string dir;
#ifdef _WIN32
wchar_t buf[2048];
if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1)
{
MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR);
return dir; // empty
}
to_utf8(dir, buf); // Convert to UTF-8
std::replace(dir.begin(), dir.end(), '\\', '/');
dir.resize(dir.rfind('/') + 1);
#else
if (const char* home = ::getenv("XDG_CONFIG_HOME"))
dir = home;
else if (const char* home = ::getenv("HOME"))
@ -1142,59 +1153,9 @@ const std::string& fs::get_config_dir()
if (!is_dir(dir) && !create_path(dir))
{
std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno);
return get_executable_dir();
}
return dir;
#endif
}();
return s_dir;
}
const std::string& fs::get_executable_dir()
{
// Use magic static
static const std::string s_dir = []
{
std::string dir;
#ifdef _WIN32
wchar_t buf[2048];
if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1)
{
MessageBoxA(0, fmt::format("GetModuleFileName() failed: error %u.", GetLastError()).c_str(), "fs::get_executable_dir()", MB_ICONERROR);
return dir; // empty
}
to_utf8(dir, buf); // Convert to UTF-8
std::replace(dir.begin(), dir.end(), '\\', '/');
#elif __APPLE__
char buf[4096];
u32 size = sizeof(buf);
if (_NSGetExecutablePath(buf, &size))
{
std::printf("_NSGetExecutablePath() failed (size=0x%x).\n", size);
return dir; // empty
}
dir = buf;
#else
char buf[4096];
const auto size = ::readlink("/proc/self/exe", buf, sizeof(buf));
if (size <= 0 || size >= sizeof(buf))
{
std::printf("readlink(/proc/self/exe) failed (%d).\n", errno);
return dir; // empty
}
dir.assign(buf, size);
#endif
// Leave only path
dir.resize(dir.rfind('/') + 1);
return dir;
}();

View file

@ -444,9 +444,6 @@ namespace fs
// Get configuration directory
const std::string& get_config_dir();
// Get executable directory
const std::string& get_executable_dir();
// Get data/cache directory for specified prefix and suffix
std::string get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix);

View file

@ -38,11 +38,6 @@ namespace rsx
{
std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
std::string old_shaders_cache::shaders_cache::path_to_root()
{
return fs::get_executable_dir() + "data/";
}
void old_shaders_cache::shaders_cache::load(const std::string &path, shader_language lang)
{
const std::string lang_name(lang == shader_language::glsl ? "glsl" : "hlsl");
@ -65,7 +60,6 @@ namespace rsx
}
catch (...)
{
LOG_WARNING(RSX, "Cache file '%s' ignored", entry.name);
continue;
}
@ -87,17 +81,7 @@ namespace rsx
void old_shaders_cache::shaders_cache::load(shader_language lang)
{
std::string root = path_to_root();
//shared cache
load(root + "cache/", lang);
std::string title_id = Emu.GetTitleID();
if (!title_id.empty())
{
load(root + title_id + "/cache/", lang);
}
load(Emu.GetCachePath(), lang);
}
u32 get_address(u32 offset, u32 location)

View file

@ -99,8 +99,6 @@ namespace rsx
void load(const std::string &path, shader_language lang);
void load(shader_language lang);
static std::string path_to_root();
};
}

View file

@ -90,23 +90,8 @@ namespace rsx
programs_cache::programs_cache()
{
std::string path{ fs::get_executable_dir() + "data/cache/" };
std::string title = Emu.GetTitleID();
if (title.empty())
{
path += "temporary/";
fs::remove_all(path, false);
}
else
{
path += title + "/";
}
fs::create_path(path);
m_vertex_shaders_cache.path(path);
m_fragment_shader_cache.path(path);
m_vertex_shaders_cache.path(Emu.GetCachePath());
m_fragment_shader_cache.path(Emu.GetCachePath());
}
programs_cache::~programs_cache()

View file

@ -30,7 +30,7 @@ system_type g_system;
cfg::bool_entry g_cfg_autostart(cfg::root.misc, "Always start after boot", true);
cfg::bool_entry g_cfg_autoexit(cfg::root.misc, "Exit RPCS3 when process finishes");
cfg::string_entry g_cfg_vfs_emulator_dir(cfg::root.vfs, "$(EmulatorDir)"); // Default (empty): taken from fs::get_executable_dir()
cfg::string_entry g_cfg_vfs_emulator_dir(cfg::root.vfs, "$(EmulatorDir)"); // Default (empty): taken from fs::get_config_dir()
cfg::string_entry g_cfg_vfs_dev_hdd0(cfg::root.vfs, "/dev_hdd0/", "$(EmulatorDir)dev_hdd0/");
cfg::string_entry g_cfg_vfs_dev_hdd1(cfg::root.vfs, "/dev_hdd1/", "$(EmulatorDir)dev_hdd1/");
cfg::string_entry g_cfg_vfs_dev_flash(cfg::root.vfs, "/dev_flash/", "$(EmulatorDir)dev_flash/");
@ -131,7 +131,7 @@ bool Emulator::BootGame(const std::string& path, bool direct)
std::string Emulator::GetGameDir()
{
const std::string& emu_dir_ = g_cfg_vfs_emulator_dir;
const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_;
const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
return fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir) + "game/";
}
@ -139,7 +139,7 @@ std::string Emulator::GetGameDir()
std::string Emulator::GetLibDir()
{
const std::string& emu_dir_ = g_cfg_vfs_emulator_dir;
const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_;
const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
return fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir) + "sys/external/";
}
@ -173,12 +173,12 @@ void Emulator::Load()
m_title_id = psf::get_string(_psf, "TITLE_ID");
// Initialize data/cache directory
const std::string data_dir = fs::get_data_dir(m_title_id, m_path);
m_cache_path = fs::get_data_dir(m_title_id, m_path);
// Check SELF header
if (elf_file.size() >= 4 && elf_file.read<u32>() == "SCE\0"_u32)
{
const std::string decrypted_path = data_dir + "boot.elf";
const std::string decrypted_path = m_cache_path + "boot.elf";
fs::stat_t encrypted_stat = elf_file.stat();
fs::stat_t decrypted_stat;
@ -201,13 +201,13 @@ void Emulator::Load()
}
else
{
LOG_ERROR(LOADER, "Failed to create boot.elf", data_dir);
LOG_ERROR(LOADER, "Failed to create boot.elf");
}
}
}
// Load custom config-1
if (fs::file cfg_file{data_dir + "config.yml"})
if (fs::file cfg_file{m_cache_path + "config.yml"})
{
LOG_NOTICE(LOADER, "Applying custom config (config.yml)");
cfg::root.from_string(cfg_file.to_string());
@ -248,7 +248,7 @@ void Emulator::Load()
// Mount all devices
const std::string& emu_dir_ = g_cfg_vfs_emulator_dir;
const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_;
const std::string& emu_dir = emu_dir_.empty() ? fs::get_config_dir() : emu_dir_;
const std::string& bdvd_dir = g_cfg_vfs_dev_bdvd;
const std::string& home_dir = g_cfg_vfs_app_home;

View file

@ -50,6 +50,7 @@ class Emulator final
std::string m_path;
std::string m_elf_path;
std::string m_cache_path;
std::string m_title_id;
std::string m_title;
@ -98,6 +99,11 @@ public:
return m_title;
}
const std::string& GetCachePath() const
{
return m_cache_path;
}
u64 GetPauseTime()
{
return m_pause_amend_time;

View file

@ -234,13 +234,10 @@ void MainFrame::BootGame(wxCommandEvent& WXUNUSED(event))
void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event))
{
const bool paused = Emu.Pause();
wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST);
if (ctrl.ShowModal() == wxID_CANCEL)
{
if (paused) Emu.Resume();
return;
}
@ -372,6 +369,8 @@ void MainFrame::DecryptSPRXLibraries(wxCommandEvent& WXUNUSED(event))
return;
}
Emu.Stop();
wxArrayString modules;
ctrl.GetPaths(modules);
@ -427,9 +426,12 @@ void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event))
return;
}
Emu.Stop();
fs::file pup_f(ctrl.GetPath().ToStdString());
pup_object pup(pup_f);
if (!pup) {
if (!pup)
{
LOG_ERROR(GENERAL, "Error while installing firmware: PUP file is invalid.");
wxMessageBox("Error while installing firmware: PUP file is invalid.", "Failure!", wxOK | wxICON_ERROR, this);
return;
@ -440,7 +442,7 @@ void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event))
auto updatefilenames = update_files.get_filenames();
updatefilenames.erase(std::remove_if(
updatefilenames.begin(), updatefilenames.end(), [](std::string s) {return s.find("dev_flash_") == std::string::npos; }),
updatefilenames.begin(), updatefilenames.end(), [](std::string s) { return s.find("dev_flash_") == std::string::npos; }),
updatefilenames.end());
wxProgressDialog pdlg("Firmware Installer", "Please wait, unpacking...", updatefilenames.size(), this, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
@ -470,7 +472,7 @@ void MainFrame::InstallFirmware(wxCommandEvent& WXUNUSED(event))
}
tar_object dev_flash_tar(dev_flash_tar_f[2]);
if (!dev_flash_tar.extract(fs::get_executable_dir()))
if (!dev_flash_tar.extract(fs::get_config_dir()))
{
LOG_ERROR(GENERAL, "Error while installing firmware: TAR contents are invalid.");
wxMessageBox("Error while installing firmware: TAR contents are invalid.", "Failure!", wxOK | wxICON_ERROR, this);

View file

@ -6,8 +6,8 @@ pup_object::pup_object(const fs::file& file): m_file(file)
{
PUPHeader m_header;
m_file.read(m_header);
if (m_header.magic != "SCEUF\0\0\0"_u64)
{
if (m_header.magic != "SCEUF\0\0\0"_u64)
{
isValid = false;
return;
}
@ -22,7 +22,7 @@ fs::file pup_object::get_file(u64 entry_id)
{
if (!isValid) return fs::file();
for (PUPFileEntry file_entry : m_file_tbl)
for (PUPFileEntry file_entry : m_file_tbl)
{
if (file_entry.entry_id == entry_id)
{

View file

@ -5,29 +5,33 @@
#include <vector>
typedef struct {
struct PUPHeader
{
le_t<u64> magic;
be_t<u64> package_version;
be_t<u64> image_version;
be_t<u64> file_count;
be_t<u64> header_length;
be_t<u64> data_length;
} PUPHeader;
};
typedef struct {
struct PUPFileEntry
{
be_t<u64> entry_id;
be_t<u64> data_offset;
be_t<u64> data_length;
u8 padding[8];
} PUPFileEntry;
};
typedef struct {
struct PUPHashEntry
{
be_t<u64> entry_id;
be_t<u8> hash[20];
be_t<u8> padding[4];
} PUPHashEntry;
u8 hash[20];
u8 padding[4];
};
class pup_object {
class pup_object
{
const fs::file& m_file;
bool isValid = true;
@ -37,7 +41,7 @@ class pup_object {
public:
pup_object(const fs::file& file);
operator bool() const { return isValid; };
explicit operator bool() const { return isValid; };
fs::file get_file(u64 entry_id);
};
};

View file

@ -5,7 +5,9 @@
#include <cmath>
#include <cstdlib>
tar_object::tar_object(const fs::file& file, size_t offset) : m_file(file), initial_offset(offset)
tar_object::tar_object(const fs::file& file, size_t offset)
: m_file(file)
, initial_offset(offset)
{
m_file.seek(initial_offset);
largest_offset = initial_offset;
@ -34,8 +36,6 @@ int octalToDecimal(int octalNumber)
std::vector<std::string> tar_object::get_filenames()
{
if (!isValid) return std::vector<std::string>();
std::vector<std::string> vec;
get_file("");
for (auto it = m_map.cbegin(); it != m_map.cend(); ++it)
@ -47,7 +47,7 @@ std::vector<std::string> tar_object::get_filenames()
fs::file tar_object::get_file(std::string path)
{
if (!isValid || !m_file) return fs::file();
if (!m_file) return fs::file();
auto it = m_map.find(path);
if (it != m_map.end())
@ -62,9 +62,9 @@ fs::file tar_object::get_file(std::string path)
}
else //continue scanning from last file entered
{
while (m_file.pos() < m_file.size()) {
while (m_file.pos() < m_file.size())
{
TARHeader header = read_header(largest_offset);
if (!isValid) return fs::file();
if (std::string(header.magic).find("ustar") != std::string::npos)
m_map[header.name] = largest_offset;
@ -85,7 +85,7 @@ fs::file tar_object::get_file(std::string path)
m_file.seek(offset);
largest_offset = offset;
}
}
}
return fs::file();
}
@ -93,7 +93,7 @@ fs::file tar_object::get_file(std::string path)
bool tar_object::extract(std::string path)
{
if (!isValid || !m_file) return false;
if (!m_file) return false;
get_file(""); //Make sure we have scanned all files
for (auto iter : m_map)
@ -101,7 +101,8 @@ bool tar_object::extract(std::string path)
TARHeader header = read_header(iter.second);
if (std::string(header.name).empty()) continue;
switch (header.filetype) {
switch (header.filetype)
{
case '0':
{
fs::file file(header.name, fs::rewrite);
@ -116,9 +117,9 @@ bool tar_object::extract(std::string path)
}
default:
LOG_ERROR(GENERAL,"Tar loader: unknown file type: "+header.filetype);
LOG_ERROR(GENERAL,"Tar loader: unknown file type: %c", header.filetype);
return false;
}
}
return true;
}
}

View file

@ -2,7 +2,8 @@
#include <map>
typedef struct {
struct TARHeader
{
char name[100];
char dontcare[24];
char size[12];
@ -14,7 +15,7 @@ typedef struct {
char dontcare2[82];
char prefix[155];
char padding[12];
} TARHeader;
};
class tar_object
{
@ -23,18 +24,15 @@ class tar_object
int initial_offset;
int largest_offset; //we store the largest offset so we can continue to scan from there.
std::map<std::string, u64> m_map; //maps path to offset of header of that file, so we only need to scan the entire file once.
bool isValid = true;
TARHeader read_header(u64 offset);
public:
tar_object(const fs::file& file, size_t offset = 0);
operator bool() const { return isValid; };
std::vector<std::string> get_filenames();
fs::file get_file(std::string path);
bool extract(std::string path); // extract all files in archive to path
};
};