From 833e36e051123f8142c214f2d5abe4449ffe1611 Mon Sep 17 00:00:00 2001 From: emoose Date: Sat, 11 Jan 2020 18:40:40 +0000 Subject: [PATCH] [Kernel/VFS] Write more fields in STFS headers when creating --- src/xenia/kernel/xam/content_manager.cc | 47 +++++++++++++++---- src/xenia/vfs/devices/stfs_container_device.h | 15 ++++++ 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/xenia/kernel/xam/content_manager.cc b/src/xenia/kernel/xam/content_manager.cc index 51f5a97e2..1e529577e 100644 --- a/src/xenia/kernel/xam/content_manager.cc +++ b/src/xenia/kernel/xam/content_manager.cc @@ -13,6 +13,7 @@ #include "xenia/base/filesystem.h" #include "xenia/base/string.h" +#include "xenia/emulator.h" #include "xenia/kernel/kernel_state.h" #include "xenia/kernel/user_module.h" #include "xenia/kernel/xam/content_package.h" @@ -194,16 +195,42 @@ X_RESULT ContentManager::CreateContent(std::string root_name, return X_ERROR_FUNCTION_FAILED; // failed to create headers file :( } - // Set headers using data from XCONTENT_DATA - vfs::StfsHeader* header = new vfs::StfsHeader(); - // TODO: set title_id, title_name & publisher from XDBF info - header->metadata.content_type = (xe::vfs::XContentType)data.content_type; - header->metadata.set_display_name(data.display_name, - (XLanguage)cvars::user_language); - // TODO: set display name locale that's currently in use - fwrite(header, sizeof(vfs::StfsHeader), 1, file); - fclose(file); - delete header; + // Setup package headers! + { + // TODO: set publisher from XDBF info (but most saves don't have this set?) + + // Set header defaults... + vfs::StfsHeader* header = new vfs::StfsHeader(); + header->set_defaults(); + + // Try copying execution info from XEX opt headers + auto exe_module = kernel_state_->GetExecutableModule(); + if (exe_module) { + xex2_opt_execution_info* exec_info = 0; + exe_module->GetOptHeader(XEX_HEADER_EXECUTION_INFO, &exec_info); + if (exec_info) { + memcpy(&header->metadata.execution_info, exec_info, + sizeof(xex2_opt_execution_info)); + } + } + + // Copy game title in the games default language + // TODO: should this get the title in the users chosen lang instead? + header->metadata.set_title_name(kernel_state_->emulator()->game_title()); + + // TODO: + // Set package profile id (should be the offline XUID, 0xE0....) + // header->metadata.profile_id = kernel_state_->user_profile()->xuid(); + + // Now copy data from XCONTENT_DATA into package headers + header->metadata.content_type = (xe::vfs::XContentType)data.content_type; + header->metadata.set_display_name(data.display_name, + (XLanguage)cvars::user_language); + + fwrite(header, sizeof(vfs::StfsHeader), 1, file); + fclose(file); + delete header; + } if (!package->Mount(root_name)) { return X_ERROR_DEVICE_NOT_CONNECTED; diff --git a/src/xenia/vfs/devices/stfs_container_device.h b/src/xenia/vfs/devices/stfs_container_device.h index dd9c9a62c..430a3321d 100644 --- a/src/xenia/vfs/devices/stfs_container_device.h +++ b/src/xenia/vfs/devices/stfs_container_device.h @@ -381,6 +381,21 @@ struct StfsHeader { XContentMetadata metadata; XContentInstaller installer; uint8_t padding[0x2F2]; + + void set_defaults() { + memset(this, 0, sizeof(StfsHeader)); + + header.magic = xe::vfs::XContentPackageType::kPackageTypeCon; + header.licenses[0].licensee_id = + -1; // X360 gamesaves seem to set licenses like this + header.header_size = 0x971A; + + metadata.metadata_version = 2; + memcpy(metadata.console_id, "XENIA", 5); + + // Saves always have this set? How do titles choose this? + metadata.flags.bits.device_transfer = true; + } }; static_assert_size(StfsHeader, 0xB000); #pragma pack(pop)