patch_manager: Add support for packed updates

Will prefer any installed update over the packed version.
master
Zach Hilman 2018-09-25 09:19:42 +07:00
parent 5045748829
commit d79d4fd764
4 changed files with 18 additions and 5 deletions

@ -184,8 +184,8 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
romfs = std::move(packed);
}
VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset,
ContentRecordType type) const {
VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, ContentRecordType type,
VirtualFile update_raw) const {
LOG_INFO(Loader, "Patching RomFS for title_id={:016X}, type={:02X}", title_id,
static_cast<u8>(type));
@ -205,6 +205,13 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset,
FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0)));
romfs = new_nca->GetRomFS();
}
} else if (update_raw != nullptr) {
const auto new_nca = std::make_shared<NCA>(update, romfs, ivfc_offset);
if (new_nca->GetStatus() == Loader::ResultStatus::Success &&
new_nca->GetRomFS() != nullptr) {
LOG_INFO(Loader, " RomFS: Update (XCI) applied successfully");
romfs = new_nca->GetRomFS();
}
}
// LayeredFS
@ -224,7 +231,7 @@ static bool IsDirValidAndNonEmpty(const VirtualDir& dir) {
return dir != nullptr && (!dir->GetFiles().empty() || !dir->GetSubdirectories().empty());
}
std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNames() const {
std::map<PatchType, std::string> PatchManager::GetPatchVersionNames(VirtualFile update_raw) const {
std::map<std::string, std::string, std::less<>> out;
const auto installed = Service::FileSystem::GetUnionContents();
@ -245,6 +252,8 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
"Update",
FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements));
}
} else if (update_raw != nullptr) {
out[PatchType::Update] = "XCI";
}
}

@ -46,7 +46,8 @@ public:
// - Game Updates
// - LayeredFS
VirtualFile PatchRomFS(VirtualFile base, u64 ivfc_offset,
ContentRecordType type = ContentRecordType::Program) const;
ContentRecordType type = ContentRecordType::Program,
VirtualFile update_raw = nullptr) const;
// Returns a vector of pairs between patch names and patch versions.
// i.e. Update 3.2.2 will return {"Update", "3.2.2"}

@ -24,6 +24,7 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader) {
LOG_ERROR(Service_FS, "Unable to read RomFS!");
}
app_loader.ReadUpdateRaw(update_raw);
updatable = app_loader.IsRomFSUpdatable();
ivfc_offset = app_loader.ReadRomFSIVFCOffset();
}
@ -35,7 +36,8 @@ ResultVal<VirtualFile> RomFSFactory::OpenCurrentProcess() {
return MakeResult<VirtualFile>(file);
const PatchManager patch_manager(Core::CurrentProcess()->GetTitleID());
return MakeResult<VirtualFile>(patch_manager.PatchRomFS(file, ivfc_offset));
return MakeResult<VirtualFile>(
patch_manager.PatchRomFS(file, ivfc_offset, ContentRecordType::Program, update_raw));
}
ResultVal<VirtualFile> RomFSFactory::Open(u64 title_id, StorageId storage, ContentRecordType type) {

@ -37,6 +37,7 @@ public:
private:
VirtualFile file;
VirtualFile update_raw;
bool updatable;
u64 ivfc_offset;
};