From fbf9c4630f860d805168f68f76fae2ee7d38a33c Mon Sep 17 00:00:00 2001 From: emoose Date: Tue, 15 Jun 2021 22:24:18 +0100 Subject: [PATCH] [Kernel] Use XCONTENT_AGGREGATE_DATA in all ContentManager funcs Since AGGREGATE_DATA contains extra info about title_id, and can be easily converted to/from XCONTENT_DATA. --- src/xenia/kernel/xam/content_manager.cc | 48 ++++++++++-------- src/xenia/kernel/xam/content_manager.h | 49 +++++++++++++------ src/xenia/kernel/xam/xam_content.cc | 10 ++-- src/xenia/kernel/xam/xam_content_aggregate.cc | 3 +- 4 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/xenia/kernel/xam/content_manager.cc b/src/xenia/kernel/xam/content_manager.cc index 2b3aee4c9..a4367a48b 100644 --- a/src/xenia/kernel/xam/content_manager.cc +++ b/src/xenia/kernel/xam/content_manager.cc @@ -31,7 +31,7 @@ static int content_device_id_ = 0; ContentPackage::ContentPackage(KernelState* kernel_state, const std::string_view root_name, - const XCONTENT_DATA& data, + const XCONTENT_AGGREGATE_DATA& data, const std::filesystem::path& package_path) : kernel_state_(kernel_state), root_name_(root_name) { device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_); @@ -58,8 +58,11 @@ ContentManager::ContentManager(KernelState* kernel_state, ContentManager::~ContentManager() = default; std::filesystem::path ContentManager::ResolvePackageRoot( - XContentType content_type) { - auto title_id_str = fmt::format("{:8X}", kernel_state_->title_id()); + XContentType content_type, uint32_t title_id) { + if (title_id == kCurrentlyRunningTitleId) { + title_id = kernel_state_->title_id(); + } + auto title_id_str = fmt::format("{:08X}", title_id); auto content_type_str = fmt::format("{:08X}", uint32_t(content_type)); // Package root path: @@ -68,31 +71,36 @@ std::filesystem::path ContentManager::ResolvePackageRoot( } std::filesystem::path ContentManager::ResolvePackagePath( - const XCONTENT_DATA& data) { + const XCONTENT_AGGREGATE_DATA& data) { // Content path: // content_root/title_id/content_type/data_file_name/ - auto package_root = ResolvePackageRoot(data.content_type); + auto package_root = ResolvePackageRoot(data.content_type, data.title_id); return package_root / xe::to_path(data.file_name()); } -std::vector ContentManager::ListContent( - uint32_t device_id, XContentType content_type) { - std::vector result; +std::vector ContentManager::ListContent( + uint32_t device_id, XContentType content_type, uint32_t title_id) { + std::vector result; + + if (title_id == kCurrentlyRunningTitleId) { + title_id = kernel_state_->title_id(); + } // Search path: // content_root/title_id/type_name/* - auto package_root = ResolvePackageRoot(content_type); + auto package_root = ResolvePackageRoot(content_type, title_id); auto file_infos = xe::filesystem::ListFiles(package_root); for (const auto& file_info : file_infos) { if (file_info.type != xe::filesystem::FileInfo::Type::kDirectory) { // Directories only. continue; } - XCONTENT_DATA content_data; + XCONTENT_AGGREGATE_DATA content_data; content_data.device_id = device_id; content_data.content_type = content_type; content_data.set_display_name(xe::path_to_utf16(file_info.name)); content_data.set_file_name(xe::path_to_utf8(file_info.name)); + content_data.title_id = title_id; result.emplace_back(std::move(content_data)); } @@ -100,7 +108,7 @@ std::vector ContentManager::ListContent( } std::unique_ptr ContentManager::ResolvePackage( - const std::string_view root_name, const XCONTENT_DATA& data) { + const std::string_view root_name, const XCONTENT_AGGREGATE_DATA& data) { auto package_path = ResolvePackagePath(data); if (!std::filesystem::exists(package_path)) { return nullptr; @@ -113,13 +121,13 @@ std::unique_ptr ContentManager::ResolvePackage( return package; } -bool ContentManager::ContentExists(const XCONTENT_DATA& data) { +bool ContentManager::ContentExists(const XCONTENT_AGGREGATE_DATA& data) { auto path = ResolvePackagePath(data); return std::filesystem::exists(path); } X_RESULT ContentManager::CreateContent(const std::string_view root_name, - const XCONTENT_DATA& data) { + const XCONTENT_AGGREGATE_DATA& data) { auto global_lock = global_critical_region_.Acquire(); if (open_packages_.count(string_key(root_name))) { @@ -146,7 +154,7 @@ X_RESULT ContentManager::CreateContent(const std::string_view root_name, } X_RESULT ContentManager::OpenContent(const std::string_view root_name, - const XCONTENT_DATA& data) { + const XCONTENT_AGGREGATE_DATA& data) { auto global_lock = global_critical_region_.Acquire(); if (open_packages_.count(string_key(root_name))) { @@ -185,8 +193,8 @@ X_RESULT ContentManager::CloseContent(const std::string_view root_name) { return X_ERROR_SUCCESS; } -X_RESULT ContentManager::GetContentThumbnail(const XCONTENT_DATA& data, - std::vector* buffer) { +X_RESULT ContentManager::GetContentThumbnail( + const XCONTENT_AGGREGATE_DATA& data, std::vector* buffer) { auto global_lock = global_critical_region_.Acquire(); auto package_path = ResolvePackagePath(data); auto thumb_path = package_path / kThumbnailFileName; @@ -204,8 +212,8 @@ X_RESULT ContentManager::GetContentThumbnail(const XCONTENT_DATA& data, } } -X_RESULT ContentManager::SetContentThumbnail(const XCONTENT_DATA& data, - std::vector buffer) { +X_RESULT ContentManager::SetContentThumbnail( + const XCONTENT_AGGREGATE_DATA& data, std::vector buffer) { auto global_lock = global_critical_region_.Acquire(); auto package_path = ResolvePackagePath(data); std::filesystem::create_directories(package_path); @@ -220,7 +228,7 @@ X_RESULT ContentManager::SetContentThumbnail(const XCONTENT_DATA& data, } } -X_RESULT ContentManager::DeleteContent(const XCONTENT_DATA& data) { +X_RESULT ContentManager::DeleteContent(const XCONTENT_AGGREGATE_DATA& data) { auto global_lock = global_critical_region_.Acquire(); if (IsContentOpen(data)) { @@ -245,7 +253,7 @@ std::filesystem::path ContentManager::ResolveGameUserContentPath() { return root_path_ / title_id / kGameUserContentDirName / user_name; } -bool ContentManager::IsContentOpen(const XCONTENT_DATA& data) const { +bool ContentManager::IsContentOpen(const XCONTENT_AGGREGATE_DATA& data) const { return std::any_of(open_packages_.cbegin(), open_packages_.cend(), [data](std::pair content) { return data == content.second->GetPackageContentData(); diff --git a/src/xenia/kernel/xam/content_manager.h b/src/xenia/kernel/xam/content_manager.h index f0ff9c5b9..b65c1f22c 100644 --- a/src/xenia/kernel/xam/content_manager.h +++ b/src/xenia/kernel/xam/content_manager.h @@ -31,6 +31,11 @@ namespace xe { namespace kernel { namespace xam { +// If set in XCONTENT_AGGREGATE_DATA, will be substituted with the running +// titles ID +// TODO: check if actual x360 kernel/xam has a value similar to this +constexpr uint32_t kCurrentlyRunningTitleId = 0xFFFFFFFF; + struct XCONTENT_DATA { be device_id; be content_type; @@ -90,6 +95,16 @@ static_assert_size(XCONTENT_DATA, 0x134); struct XCONTENT_AGGREGATE_DATA : XCONTENT_DATA { be title_id; + XCONTENT_AGGREGATE_DATA() = default; + XCONTENT_AGGREGATE_DATA(const XCONTENT_DATA& other) { + device_id = other.device_id; + content_type = other.content_type; + set_display_name(other.display_name()); + set_file_name(other.file_name()); + padding[0] = padding[1] = 0; + title_id = kCurrentlyRunningTitleId; + } + bool operator==(const XCONTENT_AGGREGATE_DATA& other) const { // Package is located via device_id/title_id/content_type/file_name, so only // need to compare those @@ -103,17 +118,19 @@ static_assert_size(XCONTENT_AGGREGATE_DATA, 0x138); class ContentPackage { public: ContentPackage(KernelState* kernel_state, const std::string_view root_name, - const XCONTENT_DATA& data, + const XCONTENT_AGGREGATE_DATA& data, const std::filesystem::path& package_path); ~ContentPackage(); - const XCONTENT_DATA& GetPackageContentData() const { return content_data_; } + const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const { + return content_data_; + } private: KernelState* kernel_state_; std::string root_name_; std::string device_path_; - XCONTENT_DATA content_data_; + XCONTENT_AGGREGATE_DATA content_data_; }; class ContentManager { @@ -122,30 +139,32 @@ class ContentManager { const std::filesystem::path& root_path); ~ContentManager(); - std::vector ListContent(uint32_t device_id, - XContentType content_type); + std::vector ListContent(uint32_t device_id, + XContentType content_type, + uint32_t title_id = -1); std::unique_ptr ResolvePackage( - const std::string_view root_name, const XCONTENT_DATA& data); + const std::string_view root_name, const XCONTENT_AGGREGATE_DATA& data); - bool ContentExists(const XCONTENT_DATA& data); + bool ContentExists(const XCONTENT_AGGREGATE_DATA& data); X_RESULT CreateContent(const std::string_view root_name, - const XCONTENT_DATA& data); + const XCONTENT_AGGREGATE_DATA& data); X_RESULT OpenContent(const std::string_view root_name, - const XCONTENT_DATA& data); + const XCONTENT_AGGREGATE_DATA& data); X_RESULT CloseContent(const std::string_view root_name); - X_RESULT GetContentThumbnail(const XCONTENT_DATA& data, + X_RESULT GetContentThumbnail(const XCONTENT_AGGREGATE_DATA& data, std::vector* buffer); - X_RESULT SetContentThumbnail(const XCONTENT_DATA& data, + X_RESULT SetContentThumbnail(const XCONTENT_AGGREGATE_DATA& data, std::vector buffer); - X_RESULT DeleteContent(const XCONTENT_DATA& data); + X_RESULT DeleteContent(const XCONTENT_AGGREGATE_DATA& data); std::filesystem::path ResolveGameUserContentPath(); - bool IsContentOpen(const XCONTENT_DATA& data) const; + bool IsContentOpen(const XCONTENT_AGGREGATE_DATA& data) const; void CloseOpenedFilesFromContent(const std::string_view root_name); private: - std::filesystem::path ResolvePackageRoot(XContentType content_type); - std::filesystem::path ResolvePackagePath(const XCONTENT_DATA& data); + std::filesystem::path ResolvePackageRoot(XContentType content_type, + uint32_t title_id = -1); + std::filesystem::path ResolvePackagePath(const XCONTENT_AGGREGATE_DATA& data); KernelState* kernel_state_; std::filesystem::path root_path_; diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index 5ba1d99aa..3c52b2cbb 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -124,7 +124,7 @@ dword_result_t XamContentCreateEx(dword_t user_index, lpstring_t root_name, dword_t cache_size, qword_t content_size, lpvoid_t overlapped_ptr) { X_RESULT result = X_ERROR_INVALID_PARAMETER; - auto content_data = *content_data_ptr.as(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); auto content_manager = kernel_state()->content_manager(); bool create = false; @@ -277,7 +277,7 @@ dword_result_t XamContentGetCreator(dword_t user_index, lpunknown_t overlapped_ptr) { auto result = X_ERROR_SUCCESS; - auto content_data = *content_data_ptr.as(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); bool content_exists = kernel_state()->content_manager()->ContentExists(content_data); @@ -315,7 +315,7 @@ dword_result_t XamContentGetThumbnail(dword_t user_index, lpunknown_t overlapped_ptr) { assert_not_null(buffer_size_ptr); uint32_t buffer_size = *buffer_size_ptr; - auto content_data = *content_data_ptr.as(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); // Get thumbnail (if it exists). std::vector buffer; @@ -351,7 +351,7 @@ dword_result_t XamContentSetThumbnail(dword_t user_index, lpvoid_t content_data_ptr, lpvoid_t buffer_ptr, dword_t buffer_size, lpunknown_t overlapped_ptr) { - auto content_data = *content_data_ptr.as(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); // Buffer is PNG data. auto buffer = std::vector((uint8_t*)buffer_ptr, @@ -370,7 +370,7 @@ DECLARE_XAM_EXPORT1(XamContentSetThumbnail, kContent, kImplemented); dword_result_t XamContentDelete(dword_t user_index, lpvoid_t content_data_ptr, lpunknown_t overlapped_ptr) { - auto content_data = *content_data_ptr.as(); + XCONTENT_AGGREGATE_DATA content_data = *content_data_ptr.as(); auto result = kernel_state()->content_manager()->DeleteContent(content_data); diff --git a/src/xenia/kernel/xam/xam_content_aggregate.cc b/src/xenia/kernel/xam/xam_content_aggregate.cc index b7b9ba90b..043018b6c 100644 --- a/src/xenia/kernel/xam/xam_content_aggregate.cc +++ b/src/xenia/kernel/xam/xam_content_aggregate.cc @@ -105,8 +105,7 @@ dword_result_t XamContentAggregateCreateEnumerator(qword_t xuid, for (const auto& content_data : content_datas) { auto item = reinterpret_cast(e->AppendItem()); assert_not_null(item); - *item = {content_data}; - item->title_id = kernel_state()->title_id(); + *item = content_data; } }