am: Properly handle operations involving content indices.
This commit is contained in:
parent
932eeefff0
commit
630a1311ca
|
@ -63,7 +63,7 @@ ResultVal<std::unique_ptr<FileBackend>> NCCHArchive::OpenFile(const Path& path,
|
||||||
std::memcpy(&openfile_path, binary.data(), sizeof(NCCHFilePath));
|
std::memcpy(&openfile_path, binary.data(), sizeof(NCCHFilePath));
|
||||||
|
|
||||||
std::string file_path =
|
std::string file_path =
|
||||||
Service::AM::GetTitleContentPath(media_type, title_id, openfile_path.content_index);
|
Service::AM::GetTitleContentPath(media_type, title_id, openfile_path.content_index, false, true);
|
||||||
auto ncch_container = NCCHContainer(file_path);
|
auto ncch_container = NCCHContainer(file_path);
|
||||||
|
|
||||||
Loader::ResultStatus result;
|
Loader::ResultStatus result;
|
||||||
|
|
|
@ -201,7 +201,7 @@ u64 CIAContainer::GetTotalContentSize() const {
|
||||||
|
|
||||||
u64 CIAContainer::GetContentSize(u16 index) const {
|
u64 CIAContainer::GetContentSize(u16 index) const {
|
||||||
// If the content doesn't exist in the CIA, it doesn't have a size.
|
// If the content doesn't exist in the CIA, it doesn't have a size.
|
||||||
if (!cia_header.isContentPresent(index))
|
if (!cia_header.isContentPresent(cia_tmd.GetContentIndexByIndex(index)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return cia_tmd.GetContentSizeByIndex(index);
|
return cia_tmd.GetContentSizeByIndex(index);
|
||||||
|
|
|
@ -86,6 +86,7 @@ Loader::ResultStatus TitleMetadata::Load(const std::vector<u8> file_data, size_t
|
||||||
memcpy(&chunk, &file_data[offset + body_end + (i * sizeof(ContentChunk))],
|
memcpy(&chunk, &file_data[offset + body_end + (i * sizeof(ContentChunk))],
|
||||||
sizeof(ContentChunk));
|
sizeof(ContentChunk));
|
||||||
tmd_chunks.push_back(chunk);
|
tmd_chunks.push_back(chunk);
|
||||||
|
content_index_to_index[chunk.index] = tmd_chunks.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Loader::ResultStatus::Success;
|
return Loader::ResultStatus::Success;
|
||||||
|
@ -180,6 +181,10 @@ u32 TitleMetadata::GetContentIDByIndex(u16 index) const {
|
||||||
return tmd_chunks[index].id;
|
return tmd_chunks[index].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 TitleMetadata::GetContentIndexByIndex(u16 index) const {
|
||||||
|
return tmd_chunks[index].index;
|
||||||
|
}
|
||||||
|
|
||||||
u16 TitleMetadata::GetContentTypeByIndex(u16 index) const {
|
u16 TitleMetadata::GetContentTypeByIndex(u16 index) const {
|
||||||
return tmd_chunks[index].type;
|
return tmd_chunks[index].type;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +193,14 @@ u64 TitleMetadata::GetContentSizeByIndex(u16 index) const {
|
||||||
return tmd_chunks[index].size;
|
return tmd_chunks[index].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TitleMetadata::ContentIndexExists(u16 contentIndex) const {
|
||||||
|
return content_index_to_index.find(contentIndex) != content_index_to_index.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 TitleMetadata::ContentIndexToIndex(u16 contentIndex) const {
|
||||||
|
return content_index_to_index.at(contentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
void TitleMetadata::SetTitleID(u64 title_id) {
|
void TitleMetadata::SetTitleID(u64 title_id) {
|
||||||
tmd_body.title_id = title_id;
|
tmd_body.title_id = title_id;
|
||||||
}
|
}
|
||||||
|
@ -206,6 +219,7 @@ void TitleMetadata::SetSystemVersion(u64 version) {
|
||||||
|
|
||||||
void TitleMetadata::AddContentChunk(const ContentChunk& chunk) {
|
void TitleMetadata::AddContentChunk(const ContentChunk& chunk) {
|
||||||
tmd_chunks.push_back(chunk);
|
tmd_chunks.push_back(chunk);
|
||||||
|
content_index_to_index[chunk.index] = tmd_chunks.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TitleMetadata::Print() const {
|
void TitleMetadata::Print() const {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -106,8 +107,11 @@ public:
|
||||||
u32 GetManualContentID() const;
|
u32 GetManualContentID() const;
|
||||||
u32 GetDLPContentID() const;
|
u32 GetDLPContentID() const;
|
||||||
u32 GetContentIDByIndex(u16 index) const;
|
u32 GetContentIDByIndex(u16 index) const;
|
||||||
|
u16 GetContentIndexByIndex(u16 index) const;
|
||||||
u16 GetContentTypeByIndex(u16 index) const;
|
u16 GetContentTypeByIndex(u16 index) const;
|
||||||
u64 GetContentSizeByIndex(u16 index) const;
|
u64 GetContentSizeByIndex(u16 index) const;
|
||||||
|
bool ContentIndexExists(u16 contentIndex) const;
|
||||||
|
u16 ContentIndexToIndex(u16 contentIndex) const;
|
||||||
|
|
||||||
void SetTitleID(u64 title_id);
|
void SetTitleID(u64 title_id);
|
||||||
void SetTitleType(u32 type);
|
void SetTitleType(u32 type);
|
||||||
|
@ -122,6 +126,7 @@ private:
|
||||||
u32_be signature_type;
|
u32_be signature_type;
|
||||||
std::vector<u8> tmd_signature;
|
std::vector<u8> tmd_signature;
|
||||||
std::vector<ContentChunk> tmd_chunks;
|
std::vector<ContentChunk> tmd_chunks;
|
||||||
|
std::map<u16, size_t> content_index_to_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -384,7 +384,7 @@ std::string GetTitleMetadataPath(Service::FS::MediaType media_type, u64 tid, boo
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index,
|
std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index,
|
||||||
bool update) {
|
bool update, bool contentIndex) {
|
||||||
std::string content_path = GetTitlePath(media_type, tid) + "content/";
|
std::string content_path = GetTitlePath(media_type, tid) + "content/";
|
||||||
|
|
||||||
if (media_type == Service::FS::MediaType::GameCard) {
|
if (media_type == Service::FS::MediaType::GameCard) {
|
||||||
|
@ -399,6 +399,10 @@ std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16
|
||||||
u32 content_id = 0;
|
u32 content_id = 0;
|
||||||
FileSys::TitleMetadata tmd;
|
FileSys::TitleMetadata tmd;
|
||||||
if (tmd.Load(tmd_path) == Loader::ResultStatus::Success) {
|
if (tmd.Load(tmd_path) == Loader::ResultStatus::Success) {
|
||||||
|
if(contentIndex && tmd.ContentIndexExists(index)) {
|
||||||
|
index = tmd.ContentIndexToIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
content_id = tmd.GetContentIDByIndex(index);
|
content_id = tmd.GetContentIDByIndex(index);
|
||||||
|
|
||||||
// TODO(shinyquagsire23): how does DLC actually get this folder on hardware?
|
// TODO(shinyquagsire23): how does DLC actually get this folder on hardware?
|
||||||
|
@ -525,14 +529,24 @@ void Module::Interface::FindDLCContentInfos(Kernel::HLERequestContext& ctx) {
|
||||||
std::shared_ptr<FileUtil::IOFile> romfs_file;
|
std::shared_ptr<FileUtil::IOFile> romfs_file;
|
||||||
u64 romfs_offset = 0;
|
u64 romfs_offset = 0;
|
||||||
|
|
||||||
|
if (!tmd.ContentIndexExists(content_requested[i])) {
|
||||||
|
IPC::RequestBuilder rb = rp.MakeBuilder(1, 4);
|
||||||
|
rb.Push<u32>(-1); // TODO: Find the right error code
|
||||||
|
rb.PushMappedBuffer(content_requested_in);
|
||||||
|
rb.PushMappedBuffer(content_info_out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 index = tmd.ContentIndexToIndex(content_requested[i]);
|
||||||
|
|
||||||
ContentInfo content_info = {};
|
ContentInfo content_info = {};
|
||||||
content_info.index = static_cast<u16>(i);
|
content_info.index = static_cast<u16>(i);
|
||||||
content_info.type = tmd.GetContentTypeByIndex(content_requested[i]);
|
content_info.type = tmd.GetContentTypeByIndex(index);
|
||||||
content_info.content_id = tmd.GetContentIDByIndex(content_requested[i]);
|
content_info.content_id = tmd.GetContentIDByIndex(index);
|
||||||
content_info.size = tmd.GetContentSizeByIndex(content_requested[i]);
|
content_info.size = tmd.GetContentSizeByIndex(index);
|
||||||
content_info.ownership = OWNERSHIP_OWNED; // TODO: Pull this from the ticket.
|
content_info.ownership = OWNERSHIP_OWNED; // TODO: Pull this from the ticket.
|
||||||
|
|
||||||
if (FileUtil::Exists(GetTitleContentPath(media_type, title_id, content_requested[i]))) {
|
if (FileUtil::Exists(GetTitleContentPath(media_type, title_id, index))) {
|
||||||
content_info.ownership |= OWNERSHIP_DOWNLOADED;
|
content_info.ownership |= OWNERSHIP_DOWNLOADED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +931,7 @@ void Module::Interface::CheckContentRights(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
// TODO(shinyquagsire23): Read tickets for this instead?
|
// TODO(shinyquagsire23): Read tickets for this instead?
|
||||||
bool has_rights =
|
bool has_rights =
|
||||||
FileUtil::Exists(GetTitleContentPath(Service::FS::MediaType::SDMC, tid, content_index));
|
FileUtil::Exists(GetTitleContentPath(Service::FS::MediaType::SDMC, tid, content_index, false, true));
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
rb.Push(RESULT_SUCCESS); // No error
|
rb.Push(RESULT_SUCCESS); // No error
|
||||||
|
@ -933,7 +947,7 @@ void Module::Interface::CheckContentRightsIgnorePlatform(Kernel::HLERequestConte
|
||||||
|
|
||||||
// TODO(shinyquagsire23): Read tickets for this instead?
|
// TODO(shinyquagsire23): Read tickets for this instead?
|
||||||
bool has_rights =
|
bool has_rights =
|
||||||
FileUtil::Exists(GetTitleContentPath(Service::FS::MediaType::SDMC, tid, content_index));
|
FileUtil::Exists(GetTitleContentPath(Service::FS::MediaType::SDMC, tid, content_index, false, true));
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
rb.Push(RESULT_SUCCESS); // No error
|
rb.Push(RESULT_SUCCESS); // No error
|
||||||
|
|
|
@ -124,7 +124,7 @@ std::string GetTitleMetadataPath(Service::FS::MediaType media_type, u64 tid, boo
|
||||||
* @returns string path to the .app file
|
* @returns string path to the .app file
|
||||||
*/
|
*/
|
||||||
std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index = 0,
|
std::string GetTitleContentPath(Service::FS::MediaType media_type, u64 tid, u16 index = 0,
|
||||||
bool update = false);
|
bool update = false, bool contentIndex = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the folder for a title's installed content.
|
* Get the folder for a title's installed content.
|
||||||
|
|
Reference in New Issue