patch_manager: Add usages of patches to ExeFS

This commit is contained in:
Zach Hilman 2018-08-25 19:04:48 -04:00
parent 8e900a301a
commit 97bf83bc56
5 changed files with 41 additions and 9 deletions

View file

@ -6,7 +6,10 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h"
#include "core/file_sys/content_archive.h" #include "core/file_sys/content_archive.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h" #include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs_factory.h" #include "core/file_sys/romfs_factory.h"
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
@ -19,10 +22,16 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) {
if (app_loader.ReadRomFS(file) != Loader::ResultStatus::Success) { if (app_loader.ReadRomFS(file) != Loader::ResultStatus::Success) {
LOG_ERROR(Service_FS, "Unable to read RomFS!"); LOG_ERROR(Service_FS, "Unable to read RomFS!");
} }
updatable = app_loader.IsRomFSUpdatable();
} }
ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() { ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
return MakeResult<VirtualFile>(file); if (!updatable)
return MakeResult<VirtualFile>(file);
const PatchManager patch_manager(Core::CurrentProcess()->process_id);
return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file));
} }
ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) { ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) {

View file

@ -36,6 +36,7 @@ public:
private: private:
VirtualFile file; VirtualFile file;
bool updatable;
}; };
} // namespace FileSys } // namespace FileSys

View file

@ -9,6 +9,7 @@
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/content_archive.h" #include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/romfs_factory.h" #include "core/file_sys/romfs_factory.h"
#include "core/gdbstub/gdbstub.h" #include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
@ -21,8 +22,9 @@
namespace Loader { namespace Loader {
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_) AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_,
: AppLoader(std::move(file_)) { bool override_update)
: AppLoader(std::move(file_)), override_update(override_update) {
const auto dir = file->GetContainingDirectory(); const auto dir = file->GetContainingDirectory();
// Icon // Icon
@ -66,8 +68,9 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys
} }
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
FileSys::VirtualDir directory) FileSys::VirtualDir directory, bool override_update)
: AppLoader(directory->GetFile("main")), dir(std::move(directory)) {} : AppLoader(directory->GetFile("main")), dir(std::move(directory)),
override_update(override_update) {}
FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) {
if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) {
@ -89,7 +92,8 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
dir = file->GetContainingDirectory(); dir = file->GetContainingDirectory();
} }
const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); // Read meta to determine title ID
FileSys::VirtualFile npdm = dir->GetFile("main.npdm");
if (npdm == nullptr) if (npdm == nullptr)
return ResultStatus::ErrorMissingNPDM; return ResultStatus::ErrorMissingNPDM;
@ -97,6 +101,21 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
if (result != ResultStatus::Success) { if (result != ResultStatus::Success) {
return result; return result;
} }
if (override_update) {
const FileSys::PatchManager patch_manager(metadata.GetTitleID());
dir = patch_manager.PatchExeFS(dir);
}
// Reread in case PatchExeFS affected the main.npdm
npdm = dir->GetFile("main.npdm");
if (npdm == nullptr)
return ResultStatus::ErrorMissingNPDM;
ResultStatus result2 = metadata.Load(npdm);
if (result2 != ResultStatus::Success) {
return result2;
}
metadata.Print(); metadata.Print();
const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()}; const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};

View file

@ -20,10 +20,12 @@ namespace Loader {
*/ */
class AppLoader_DeconstructedRomDirectory final : public AppLoader { class AppLoader_DeconstructedRomDirectory final : public AppLoader {
public: public:
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file); explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file,
bool override_update = false);
// Overload to accept exefs directory. Must contain 'main' and 'main.npdm' // Overload to accept exefs directory. Must contain 'main' and 'main.npdm'
explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory); explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory,
bool override_update = false);
/** /**
* Returns the type of the file * Returns the type of the file
@ -51,6 +53,7 @@ private:
std::vector<u8> icon_data; std::vector<u8> icon_data;
std::string name; std::string name;
u64 title_id{}; u64 title_id{};
bool override_update;
}; };
} // namespace Loader } // namespace Loader

View file

@ -48,7 +48,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
if (exefs == nullptr) if (exefs == nullptr)
return ResultStatus::ErrorNoExeFS; return ResultStatus::ErrorNoExeFS;
directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs); directory_loader = std::make_unique<AppLoader_DeconstructedRomDirectory>(exefs, true);
const auto load_result = directory_loader->Load(process); const auto load_result = directory_loader->Load(process);
if (load_result != ResultStatus::Success) if (load_result != ResultStatus::Success)