A bunch of fixes to CIA building

1. Clean stale state
2. DLC CIAs
3. Build content index for ticket better
This commit is contained in:
zhupengfei
2020-08-07 12:28:47 +08:00
parent 26b6aee5ca
commit 66b09ffa27
4 changed files with 23 additions and 13 deletions
+15 -9
View File
@@ -526,12 +526,17 @@ bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, const std::string
return false;
}
ret = FileUtil::ForeachDirectoryEntry(
nullptr, physical_path,
[this, path](u64* /*num_entries_out*/, const std::string& directory,
const std::string& virtual_name) {
const FileUtil::DirectoryEntryCallable DirectoryEntryCallback =
[this, specifier, path, &DirectoryEntryCallback](u64* /*num_entries_out*/,
const std::string& directory,
const std::string& virtual_name) {
if (FileUtil::IsDirectory(directory + virtual_name + "/")) {
return true;
if (virtual_name == "cmd") {
return true; // Skip cmd (not used in Citra)
}
// Recursive call (necessary for DLCs)
return FileUtil::ForeachDirectoryEntry(nullptr, directory + virtual_name + "/",
DirectoryEntryCallback);
}
static const std::regex app_regex{"([0-9a-f]{8})\\.app"};
@@ -543,11 +548,12 @@ bool SDMCImporter::BuildCIA(const ContentSpecifier& specifier, const std::string
ASSERT(match.size() >= 2);
const u32 id = static_cast<u32>(std::stoul(match[1], nullptr, 16));
NCCHContainer ncch(
std::make_shared<SDMCFile>(config.sdmc_path, path + virtual_name, "rb"));
const auto relative_path = directory.substr(config.sdmc_path.size() - 1) + virtual_name;
NCCHContainer ncch(std::make_shared<SDMCFile>(config.sdmc_path, relative_path, "rb"));
return cia_builder->AddContent(id, ncch);
});
if (!ret) {
};
if (!FileUtil::ForeachDirectoryEntry(nullptr, physical_path, DirectoryEntryCallback)) {
return false;
}
+6 -2
View File
@@ -47,6 +47,9 @@ bool CIABuilder::Init(const std::string& destination, TitleMetadata tmd_,
const std::string& certs_db_path, std::size_t total_size_,
const ProgressCallback& callback_) {
header = {};
meta = {};
file = std::make_shared<HashedFile>(destination, "wb");
if (!*file) {
LOG_ERROR(Core, "Could not open file {}", destination);
@@ -165,13 +168,14 @@ bool CIABuilder::AddContent(u16 content_id, NCCHContainer& ncch) {
written = Common::AlignUp(file->Tell(), CIA_ALIGNMENT);
header.content_size = written - content_offset;
header.SetContentPresent(content_id);
auto& tmd_chunk = tmd.GetContentChunkByID(content_id);
header.SetContentPresent(tmd_chunk.index);
file->GetHash(tmd_chunk.hash.data());
file->SetHashEnabled(false);
if (tmd_chunk.index != TMDContentIndex::Main) {
// DLCs do not have a meta
if (tmd_chunk.index != TMDContentIndex::Main || (tmd.GetTitleID() & 0x0004008c'00000000)) {
return true;
}
-1
View File
@@ -97,7 +97,6 @@ private:
std::size_t ticket_offset{};
std::size_t tmd_offset{};
std::size_t content_offset{};
std::size_t metadata_offset{};
std::shared_ptr<HashedFile> file;
std::size_t written{}; // size written (with alignment)
+2 -1
View File
@@ -31,8 +31,9 @@ Ticket BuildFakeTicket(u64 title_id) {
ticket.title_id = title_id;
ticket.common_key_index = 0x00;
ticket.audit = 0x01;
std::memset(ticket.content_index.data(), 0xFF, ticket.content_index.size());
std::memcpy(ticket.content_index.data(), TicketContentIndex.data(), TicketContentIndex.size());
// GodMode9 by default sets all remaining 0x80 bytes to 0xFF, but legit tickets only set 0x20
std::memset(ticket.content_index.data() + TicketContentIndex.size(), 0xFF, 0x20);
return ticket;
}