Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/xenia/emulator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) {

// Create symlinks to the device.
file_system_->RegisterSymbolicLink("game:", mount_path);
file_system_->RegisterSymbolicLink("update:", mount_path);
file_system_->RegisterSymbolicLink("d:", mount_path);

// Get just the filename (foo.xex).
Expand All @@ -342,6 +343,7 @@ X_STATUS Emulator::LaunchDiscImage(const std::filesystem::path& path) {

// Create symlinks to the device.
file_system_->RegisterSymbolicLink("game:", mount_path);
file_system_->RegisterSymbolicLink("update:", mount_path);
file_system_->RegisterSymbolicLink("d:", mount_path);

// Launch the game.
Expand All @@ -365,6 +367,7 @@ X_STATUS Emulator::LaunchStfsContainer(const std::filesystem::path& path) {
}

file_system_->RegisterSymbolicLink("game:", mount_path);
file_system_->RegisterSymbolicLink("update:", mount_path);
file_system_->RegisterSymbolicLink("d:", mount_path);

// Launch the game.
Expand Down
58 changes: 54 additions & 4 deletions src/xenia/kernel/xam/content_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "xenia/kernel/xfile.h"
#include "xenia/kernel/xobject.h"
#include "xenia/vfs/devices/host_path_device.h"

#include "xenia/vfs/devices/stfs_container_device.h"
namespace xe {
namespace kernel {
namespace xam {
Expand All @@ -32,14 +32,21 @@ static int content_device_id_ = 0;
ContentPackage::ContentPackage(KernelState* kernel_state,
const std::string_view root_name,
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) {
device_path_ = fmt::format("\\Device\\Content\\{0}\\", ++content_device_id_);
content_data_ = data;

auto fs = kernel_state_->file_system();
auto device =
std::make_unique<vfs::HostPathDevice>(device_path_, package_path, false);
std::unique_ptr<vfs::Device> device;
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();
fs->RegisterDevice(std::move(device));
fs->RegisterSymbolicLink(root_name_ + ":", device_path_);
Expand Down Expand Up @@ -153,6 +160,49 @@ X_RESULT ContentManager::CreateContent(const std::string_view root_name,
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,
const XCONTENT_AGGREGATE_DATA& data) {
auto global_lock = global_critical_region_.Acquire();
Expand Down
6 changes: 5 additions & 1 deletion src/xenia/kernel/xam/content_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "xenia/base/mutex.h"
#include "xenia/base/string_key.h"
#include "xenia/base/string_util.h"
#include "xenia/vfs/devices/host_path_device.h"
#include "xenia/xbox.h"

namespace xe {
Expand Down Expand Up @@ -121,7 +122,7 @@ class ContentPackage {
public:
ContentPackage(KernelState* kernel_state, const std::string_view root_name,
const XCONTENT_AGGREGATE_DATA& data,
const std::filesystem::path& package_path);
const std::filesystem::path& package_path, bool stfs = false);
~ContentPackage();

const XCONTENT_AGGREGATE_DATA& GetPackageContentData() const {
Expand Down Expand Up @@ -151,6 +152,9 @@ class ContentManager {
bool ContentExists(const XCONTENT_AGGREGATE_DATA& data);
X_RESULT CreateContent(const std::string_view root_name,
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,
const XCONTENT_AGGREGATE_DATA& data);
X_RESULT CloseContent(const std::string_view root_name);
Expand Down
6 changes: 4 additions & 2 deletions src/xenia/kernel/xam/xam_content.cc
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,10 @@ dword_result_t XamContentOpenFile_entry(dword_t user_index,
lpdword_t disposition_ptr,
lpdword_t license_mask_ptr,
lpvoid_t overlapped_ptr) {
// TODO(gibbed): arguments assumed based on XamContentCreate.
return X_ERROR_FILE_NOT_FOUND;
auto content_manager = kernel_state()->content_manager();
XCONTENT_AGGREGATE_DATA data;
return content_manager->MountContentToHost(path.value(), root_name.value(),
data);
}
DECLARE_XAM_EXPORT1(XamContentOpenFile, kContent, kStub);

Expand Down