archive/pkg install: Add unicode path support

Co-authored-by: Zangetsu38 <Dante38@free.fr>
This commit is contained in:
EXtremeExploit
2020-09-08 02:48:13 +02:00
committed by Francisco José García García
parent 122b594a99
commit 407ea1296e
7 changed files with 38 additions and 34 deletions
+1 -1
View File
@@ -83,4 +83,4 @@
url = https://github.com/jbeder/yaml-cpp
[submodule "external/psvpfstools"]
path = external/psvpfstools
url = https://github.com/korewawatchful/psvpfstools.git
url = https://github.com/Vita3K/psvpfstools.git
+10 -7
View File
@@ -20,12 +20,14 @@
#include <gui/functions.h>
#include <util/string_utils.h>
#include <nfd.h>
namespace gui {
bool delete_archive_file = false;
nfdchar_t *archive_path = nullptr;
static bool delete_archive_file;
static nfdchar_t *archive_path;
void draw_archive_install_dialog(GuiState &gui, HostState &host) {
nfdresult_t result = NFD_CANCEL;
@@ -38,7 +40,7 @@ void draw_archive_install_dialog(GuiState &gui, HostState &host) {
draw_file_dialog = false;
if (result == NFD_OKAY) {
if (install_archive(host, &gui, static_cast<fs::path>(archive_path)))
if (install_archive(host, &gui, fs::path(string_utils::utf_to_wide(archive_path))))
content_install_confirm = true;
else if (!gui.content_reinstall_confirm)
ImGui::OpenPopup("Content installation failed");
@@ -64,7 +66,7 @@ void draw_archive_install_dialog(GuiState &gui, HostState &host) {
ImGui::Spacing();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() / 2 - 65);
if (ImGui::Button("Yes", BUTTON_SIZE))
if (install_archive(host, &gui, static_cast<fs::path>(archive_path))) {
if (install_archive(host, &gui, fs::path(string_utils::utf_to_wide(archive_path)))) {
gui.content_reinstall_confirm = false;
content_install_confirm = true;
}
@@ -94,13 +96,14 @@ void draw_archive_install_dialog(GuiState &gui, HostState &host) {
ImGui::SetCursorPosX(ImGui::GetWindowWidth() / 2 - 30);
if (ImGui::Button("Ok", BUTTON_SIZE)) {
if (delete_archive_file) {
fs::remove(fs::path(archive_path));
fs::remove(fs::path(string_utils::utf_to_wide(archive_path)));
delete_archive_file = false;
}
content_install_confirm = false;
draw_file_dialog = true;
archive_path = nullptr;
refresh_app_list(gui, host);
if (host.app_category == "gd")
refresh_app_list(gui, host);
gui.file_menu.archive_install_dialog = false;
}
ImGui::EndPopup();
@@ -119,7 +122,7 @@ void draw_archive_install_dialog(GuiState &gui, HostState &host) {
ImGui::SetCursorPosX(ImGui::GetWindowWidth() / 2 - 30);
if (ImGui::Button("Ok", BUTTON_SIZE)) {
if (delete_archive_file) {
fs::remove(fs::path(archive_path));
fs::remove(fs::path(string_utils::utf_to_wide(archive_path)));
delete_archive_file = false;
}
draw_file_dialog = true;
+7 -6
View File
@@ -23,15 +23,16 @@
#include <misc/cpp/imgui_stdlib.h>
#include <rif2zrif.h>
#include <util/log.h>
#include <util/string_utils.h>
#include <nfd.h>
namespace gui {
static nfdchar_t *pkg_path, *work_path = nullptr;
static nfdchar_t *pkg_path, *work_path;
static std::string state, title, zRIF;
static bool draw_file_dialog = true;
static bool delete_pkg_file, delete_work_file = false;
static bool delete_pkg_file, delete_work_file;
void draw_pkg_install_dialog(GuiState &gui, HostState &host) {
nfdresult_t result = NFD_CANCEL;
@@ -76,8 +77,8 @@ void draw_pkg_install_dialog(GuiState &gui, HostState &host) {
} else if (state == "work") {
result = NFD_OpenDialog("bin", nullptr, &work_path);
if (result == NFD_OKAY) {
std::string work_path_str = static_cast<std::string>(work_path);
zRIF = rif2zrif(work_path_str);
fs::ifstream binfile(string_utils::utf_to_wide(std::string(work_path)), std::ios::in | std::ios::binary | std::ios::ate);
zRIF = rif2zrif(binfile);
state = "install";
} else
state.clear();
@@ -121,11 +122,11 @@ void draw_pkg_install_dialog(GuiState &gui, HostState &host) {
ImGui::SetCursorPosX((ImGui::GetWindowWidth() / 2.f) - (BUTTON_SIZE.x / 2.f));
if (ImGui::Button("OK", BUTTON_SIZE)) {
if (delete_pkg_file) {
fs::remove(fs::path(pkg_path));
fs::remove(fs::path(string_utils::utf_to_wide(std::string(pkg_path))));
delete_pkg_file = false;
}
if (delete_work_file) {
fs::remove(fs::path(work_path));
fs::remove(fs::path(string_utils::utf_to_wide(std::string(work_path))));
delete_work_file = false;
}
update_notice_info(gui, host, "content");
+1 -1
View File
@@ -76,4 +76,4 @@ struct PkgEntry {
bool install_pkg(const std::string &pkg, HostState &host, std::string &p_zRIF);
bool decrypt_install_nonpdrm(std::string &drmlicpath, const std::string &title_path);
bool decrypt_install_nonpdrm(std::string &drmlicpath, const std::string &title_path);
+13 -13
View File
@@ -32,6 +32,7 @@
#include <util/bytes.h>
#include <util/log.h>
#include <util/string_utils.h>
// Credits to mmozeiko https://github.com/mmozeiko/pkg2zip
@@ -71,16 +72,14 @@ static void aes128_ctr_xor(aes_context *ctx, const uint8_t *iv, uint64_t block,
bool decrypt_install_nonpdrm(std::string &drmlicpath, const std::string &title_path) {
std::string title_id_src = title_path;
std::string title_id_dst = title_path + "_dec";
std::string zRIF = rif2zrif(drmlicpath);
fs::ifstream binfile(string_utils::utf_to_wide(drmlicpath), std::ios::in | std::ios::binary | std::ios::ate);
std::string zRIF = rif2zrif(binfile);
F00DEncryptorTypes f00d_enc_type = F00DEncryptorTypes::native;
std::string f00d_arg = std::string();
if (execute(zRIF, title_id_src, title_id_dst, f00d_enc_type, f00d_arg) < 0) {
if (title_path.find("theme") != std::string::npos)
LOG_WARN("Theme detected, keystone is missing, skip error");
else
return false;
}
if ((execute(zRIF, title_id_src, title_id_dst, f00d_enc_type, f00d_arg) < 0) && (title_path.find("theme") == std::string::npos))
return false;
fs::remove_all(fs::path(title_id_src));
fs::rename(fs::path(title_id_dst), fs::path(title_id_src));
@@ -89,7 +88,7 @@ bool decrypt_install_nonpdrm(std::string &drmlicpath, const std::string &title_p
std::vector<uint8_t> temp_klicensee = get_temp_klicensee(zRIF);
for (const auto &file : fs::recursive_directory_iterator(title_id_src)) {
if (file.path().extension() == ".suprx" || file.path().extension() == ".self" || file.path().filename() == "eboot.bin") {
if ((file.path().extension() == ".suprx") || (file.path().extension() == ".self") || (file.path().filename() == "eboot.bin")) {
self2elf(file.path().string(), file.path().string() + "elf", SCE_KEYS, temp_klicensee.data());
fs::rename(file.path().string() + "elf", file.path().string());
make_fself(file.path().string(), file.path().string() + "fself");
@@ -102,7 +101,8 @@ bool decrypt_install_nonpdrm(std::string &drmlicpath, const std::string &title_p
}
bool install_pkg(const std::string &pkg, HostState &host, std::string &p_zRIF) {
std::ifstream infile(pkg, std::ios::binary);
std::wstring pkg_path = string_utils::utf_to_wide(pkg);
fs::ifstream infile(pkg_path, std::ios::binary);
PkgHeader pkg_header;
PkgExtHeader ext_header;
infile.read(reinterpret_cast<char *>(&pkg_header), sizeof(PkgHeader));
@@ -114,12 +114,12 @@ bool install_pkg(const std::string &pkg, HostState &host, std::string &p_zRIF) {
return false;
}
if (fs::file_size(pkg) < byte_swap(pkg_header.total_size)) {
if (fs::file_size(pkg_path) < byte_swap(pkg_header.total_size)) {
LOG_ERROR("The pkg file is too small");
return false;
}
if (fs::file_size(pkg) < byte_swap(pkg_header.data_offset) + byte_swap(pkg_header.file_count) * 32) {
if (fs::file_size(pkg_path) < byte_swap(pkg_header.data_offset) + byte_swap(pkg_header.file_count) * 32) {
LOG_ERROR("The pkg file is too small");
return false;
}
@@ -248,7 +248,7 @@ bool install_pkg(const std::string &pkg, HostState &host, std::string &p_zRIF) {
infile.read(reinterpret_cast<char *>(&entry), sizeof(PkgEntry));
aes128_ctr_xor(&aes_ctx, pkg_header.pkg_data_iv, file_offset / 16, reinterpret_cast<unsigned char *>(&entry), sizeof(PkgEntry));
if (fs::file_size(pkg) < byte_swap(pkg_header.data_offset) + byte_swap(entry.name_offset) + byte_swap(entry.name_size) || fs::file_size(pkg) < byte_swap(pkg_header.data_offset) + byte_swap(entry.data_offset) + byte_swap(entry.data_size)) {
if (fs::file_size(pkg_path) < byte_swap(pkg_header.data_offset) + byte_swap(entry.name_offset) + byte_swap(entry.name_size) || fs::file_size(pkg_path) < byte_swap(pkg_header.data_offset) + byte_swap(entry.data_offset) + byte_swap(entry.data_size)) {
LOG_ERROR("The pkg file size is too small, possibly corrupted");
return false;
}
@@ -336,4 +336,4 @@ bool install_pkg(const std::string &pkg, HostState &host, std::string &p_zRIF) {
}
return true;
}
}
+5 -5
View File
@@ -71,9 +71,9 @@ static bool read_file_from_zip(vfs::FileBuffer &buf, const fs::path &file, const
return true;
}
bool install_archive(HostState &host, GuiState *gui, const fs::path &path) {
if (!fs::exists(path)) {
LOG_CRITICAL("Failed to load VPK file path: {}", path.generic_path().string());
bool install_archive(HostState &host, GuiState *gui, const fs::path &archive_path) {
if (!fs::exists(archive_path)) {
LOG_CRITICAL("Failed to load archive file in path: {}", archive_path.generic_path().string());
return false;
}
const ZipPtr zip(new mz_zip_archive, delete_zip);
@@ -82,9 +82,9 @@ bool install_archive(HostState &host, GuiState *gui, const fs::path &path) {
FILE *vpk_fp;
#ifdef WIN32
_wfopen_s(&vpk_fp, path.generic_path().wstring().c_str(), L"rb");
_wfopen_s(&vpk_fp, archive_path.generic_path().wstring().c_str(), L"rb");
#else
vpk_fp = fopen(path.generic_path().string().c_str(), "rb");
vpk_fp = fopen(archive_path.generic_path().string().c_str(), "rb");
#endif
if (!mz_zip_reader_init_cfile(zip.get(), vpk_fp, 0, 0)) {