This commit is contained in:
BalkoBalkho 2025-09-26 22:37:01 +01:00 committed by GitHub
commit b28c7c8401
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 66 additions and 7 deletions

View file

@ -316,6 +316,7 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) {
// Create symlinks to the device. // Create symlinks to the device.
file_system_->RegisterSymbolicLink("game:", mount_path); file_system_->RegisterSymbolicLink("game:", mount_path);
file_system_->RegisterSymbolicLink("update:", mount_path);
file_system_->RegisterSymbolicLink("d:", mount_path); file_system_->RegisterSymbolicLink("d:", mount_path);
// Get just the filename (foo.xex). // Get just the filename (foo.xex).
@ -342,6 +343,7 @@ X_STATUS Emulator::LaunchDiscImage(const std::filesystem::path& path) {
// Create symlinks to the device. // Create symlinks to the device.
file_system_->RegisterSymbolicLink("game:", mount_path); file_system_->RegisterSymbolicLink("game:", mount_path);
file_system_->RegisterSymbolicLink("update:", mount_path);
file_system_->RegisterSymbolicLink("d:", mount_path); file_system_->RegisterSymbolicLink("d:", mount_path);
// Launch the game. // Launch the game.
@ -365,6 +367,7 @@ X_STATUS Emulator::LaunchStfsContainer(const std::filesystem::path& path) {
} }
file_system_->RegisterSymbolicLink("game:", mount_path); file_system_->RegisterSymbolicLink("game:", mount_path);
file_system_->RegisterSymbolicLink("update:", mount_path);
file_system_->RegisterSymbolicLink("d:", mount_path); file_system_->RegisterSymbolicLink("d:", mount_path);
// Launch the game. // Launch the game.

View file

@ -18,7 +18,7 @@
#include "xenia/kernel/xfile.h" #include "xenia/kernel/xfile.h"
#include "xenia/kernel/xobject.h" #include "xenia/kernel/xobject.h"
#include "xenia/vfs/devices/host_path_device.h" #include "xenia/vfs/devices/host_path_device.h"
#include "xenia/vfs/devices/stfs_container_device.h"
namespace xe { namespace xe {
namespace kernel { namespace kernel {
namespace xam { namespace xam {
@ -32,14 +32,21 @@ static int content_device_id_ = 0;
ContentPackage::ContentPackage(KernelState* kernel_state, ContentPackage::ContentPackage(KernelState* kernel_state,
const std::string_view root_name, const std::string_view root_name,
const XCONTENT_AGGREGATE_DATA& data, const XCONTENT_AGGREGATE_DATA& data,
const std::filesystem::path& package_path) const std::filesystem::path& package_path,
bool stfs)
: kernel_state_(kernel_state), root_name_(root_name) { : kernel_state_(kernel_state), root_name_(root_name) {
device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_); device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_);
content_data_ = data; content_data_ = data;
auto fs = kernel_state_->file_system(); auto fs = kernel_state_->file_system();
auto device = std::unique_ptr<vfs::Device> device;
std::make_unique<vfs::HostPathDevice>(device_path_, package_path, false); if (stfs)
device =
std::make_unique<vfs::StfsContainerDevice>(device_path_, package_path);
else
device = std::make_unique<vfs::HostPathDevice>(device_path_, package_path,
false);
device->Initialize(); device->Initialize();
fs->RegisterDevice(std::move(device)); fs->RegisterDevice(std::move(device));
fs->RegisterSymbolicLink(root_name_ + ":", device_path_); fs->RegisterSymbolicLink(root_name_ + ":", device_path_);
@ -153,6 +160,49 @@ X_RESULT ContentManager::CreateContent(const std::string_view root_name,
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
// saves content from vfs to host
// if successful, initlisised data thats passed.
X_RESULT ContentManager::MountContentToHost(const std::string_view vpath,
const std::string_view root_name,
XCONTENT_AGGREGATE_DATA& data) {
data.content_type =
XContentType::kAvatarItem; //? this is what velocity says for
// Database,NuiIdentity
data.device_id = 4; // DeviceType::ODD;
data.set_display_name(to_utf16(root_name));
data.title_id = kernel_state_->title_id();
data.set_file_name(root_name);
auto path = ResolvePackagePath(data);
if (!std::filesystem::exists(path)) {
std::filesystem::create_directories(path.parent_path());
auto fs = kernel_state_->file_system();
auto hostfile = xe::filesystem::OpenFile(path, "wb");
xe::vfs::FileAction action;
xe::vfs::File* guestFile;
fs->OpenFile(nullptr, vpath, xe::vfs::FileDisposition::kOpen,
xe::vfs::FileAccess::kGenericRead, false, true, &guestFile,
&action);
auto size = guestFile->entry()->size();
std::vector<uint8_t> buffer(size);
size_t read;
guestFile->ReadSync(buffer.data(), size, 0, &read);
fwrite(buffer.data(), 1, size, hostfile);
fclose(hostfile);
}
if (open_packages_.count(string_key(root_name))) {
return X_ERROR_ALREADY_EXISTS;
}
auto global_lock = global_critical_region_.Acquire();
auto package = std::make_unique<ContentPackage>(kernel_state_, root_name,
data, path, true);
open_packages_.insert({string_key::create(root_name), package.release()});
return X_E_SUCCESS;
}
X_RESULT ContentManager::OpenContent(const std::string_view root_name, X_RESULT ContentManager::OpenContent(const std::string_view root_name,
const XCONTENT_AGGREGATE_DATA& data) { const XCONTENT_AGGREGATE_DATA& data) {
auto global_lock = global_critical_region_.Acquire(); auto global_lock = global_critical_region_.Acquire();

View file

@ -19,6 +19,7 @@
#include "xenia/base/mutex.h" #include "xenia/base/mutex.h"
#include "xenia/base/string_key.h" #include "xenia/base/string_key.h"
#include "xenia/base/string_util.h" #include "xenia/base/string_util.h"
#include "xenia/vfs/devices/host_path_device.h"
#include "xenia/xbox.h" #include "xenia/xbox.h"
namespace xe { namespace xe {
@ -121,7 +122,7 @@ class ContentPackage {
public: public:
ContentPackage(KernelState* kernel_state, const std::string_view root_name, ContentPackage(KernelState* kernel_state, const std::string_view root_name,
const XCONTENT_AGGREGATE_DATA& data, const XCONTENT_AGGREGATE_DATA& data,
const std::filesystem::path& package_path); const std::filesystem::path& package_path, bool stfs = false);
~ContentPackage(); ~ContentPackage();
const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const { const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const {
@ -151,6 +152,9 @@ class ContentManager {
bool ContentExists(const XCONTENT_AGGREGATE_DATA& data); bool ContentExists(const XCONTENT_AGGREGATE_DATA& data);
X_RESULT CreateContent(const std::string_view root_name, X_RESULT CreateContent(const std::string_view root_name,
const XCONTENT_AGGREGATE_DATA& data); const XCONTENT_AGGREGATE_DATA& data);
X_RESULT MountContentToHost(const std::string_view vpath,
const std::string_view root_name,
XCONTENT_AGGREGATE_DATA& data);
X_RESULT OpenContent(const std::string_view root_name, X_RESULT OpenContent(const std::string_view root_name,
const XCONTENT_AGGREGATE_DATA& data); const XCONTENT_AGGREGATE_DATA& data);
X_RESULT CloseContent(const std::string_view root_name); X_RESULT CloseContent(const std::string_view root_name);

View file

@ -259,8 +259,10 @@ dword_result_t XamContentOpenFile_entry(dword_t user_index,
lpdword_t disposition_ptr, lpdword_t disposition_ptr,
lpdword_t license_mask_ptr, lpdword_t license_mask_ptr,
lpvoid_t overlapped_ptr) { lpvoid_t overlapped_ptr) {
// TODO(gibbed): arguments assumed based on XamContentCreate. auto content_manager = kernel_state()->content_manager();
return X_ERROR_FILE_NOT_FOUND; XCONTENT_AGGREGATE_DATA data;
return content_manager->MountContentToHost(path.value(), root_name.value(),
data);
} }
DECLARE_XAM_EXPORT1(XamContentOpenFile, kContent, kStub); DECLARE_XAM_EXPORT1(XamContentOpenFile, kContent, kStub);