[XAM] Fixed issue with XamContentCreate reassigning already assigned symlinks
This commit is contained in:
committed by
Radosław Gliński
parent
bc69b95db6
commit
9bfaff5040
@@ -569,7 +569,8 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) {
|
|||||||
auto file_name = path.filename();
|
auto file_name = path.filename();
|
||||||
|
|
||||||
// Launch the game.
|
// Launch the game.
|
||||||
auto fs_path = "game:\\" + xe::path_to_utf8(file_name);
|
auto fs_path = fmt::format("{}\\", kDefaultGameSymbolicLink) +
|
||||||
|
xe::path_to_utf8(file_name);
|
||||||
X_STATUS result = CompleteLaunch(path, fs_path);
|
X_STATUS result = CompleteLaunch(path, fs_path);
|
||||||
|
|
||||||
if (XFAILED(result)) {
|
if (XFAILED(result)) {
|
||||||
@@ -585,9 +586,9 @@ X_STATUS Emulator::LaunchXexFile(const std::filesystem::path& path) {
|
|||||||
const std::string mount_path =
|
const std::string mount_path =
|
||||||
utf8::find_base_guest_path(kernel_state_->GetExecutableModule()->path());
|
utf8::find_base_guest_path(kernel_state_->GetExecutableModule()->path());
|
||||||
|
|
||||||
// System related symlinks
|
// System related symlinks. This should point to dashboard location in the
|
||||||
file_system_->RegisterSymbolicLink("media:", mount_path);
|
// future.
|
||||||
file_system_->RegisterSymbolicLink("font:", mount_path);
|
file_system_->RegisterSymbolicLink("\\SystemRoot", mount_path);
|
||||||
|
|
||||||
auto module = kernel_state_->LoadUserModule("xam.xex");
|
auto module = kernel_state_->LoadUserModule("xam.xex");
|
||||||
|
|
||||||
@@ -1378,7 +1379,7 @@ void Emulator::RemoveGameConfigLoadCallback(GameConfigLoadCallback* callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string Emulator::FindLaunchModule() {
|
std::string Emulator::FindLaunchModule() {
|
||||||
std::string path("game:\\");
|
std::string path(fmt::format("{}\\", kDefaultGameSymbolicLink));
|
||||||
|
|
||||||
auto xam = kernel_state()->GetKernelModule<kernel::xam::XamModule>("xam.xex");
|
auto xam = kernel_state()->GetKernelModule<kernel::xam::XamModule>("xam.xex");
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ namespace xe {
|
|||||||
constexpr fourcc_t kEmulatorSaveSignature = make_fourcc("XSAV");
|
constexpr fourcc_t kEmulatorSaveSignature = make_fourcc("XSAV");
|
||||||
static constexpr std::string_view kDefaultGameSymbolicLink = "GAME:";
|
static constexpr std::string_view kDefaultGameSymbolicLink = "GAME:";
|
||||||
static constexpr std::string_view kDefaultPartitionSymbolicLink = "D:";
|
static constexpr std::string_view kDefaultPartitionSymbolicLink = "D:";
|
||||||
|
static constexpr std::string_view kDefaultUpdateSymbolicLink = "UPDATE:";
|
||||||
|
|
||||||
// The main type that runs the whole emulator.
|
// The main type that runs the whole emulator.
|
||||||
// This is responsible for initializing and managing all the various subsystems.
|
// This is responsible for initializing and managing all the various subsystems.
|
||||||
|
|||||||
@@ -621,7 +621,7 @@ const object_ref<UserModule> KernelState::LoadTitleUpdate(
|
|||||||
"UPDATE", 0, *title_update, content_license, disc_number);
|
"UPDATE", 0, *title_update, content_license, disc_number);
|
||||||
|
|
||||||
std::string mount_path = "";
|
std::string mount_path = "";
|
||||||
if (!file_system()->FindSymbolicLink("game:", mount_path)) {
|
if (!file_system()->FindSymbolicLink(kDefaultGameSymbolicLink, mount_path)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,7 +630,8 @@ const object_ref<UserModule> KernelState::LoadTitleUpdate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string resolved_path = "";
|
std::string resolved_path = "";
|
||||||
if (!file_system()->FindSymbolicLink("UPDATE:", resolved_path)) {
|
if (!file_system()->FindSymbolicLink(kDefaultUpdateSymbolicLink,
|
||||||
|
resolved_path)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -251,8 +251,8 @@ std::vector<XCONTENT_AGGREGATE_DATA> ContentManager::ListContentODD(
|
|||||||
fmt::format("{:08X}", static_cast<uint32_t>(content_type));
|
fmt::format("{:08X}", static_cast<uint32_t>(content_type));
|
||||||
|
|
||||||
const std::filesystem::path game_content_path =
|
const std::filesystem::path game_content_path =
|
||||||
std::filesystem::path("GAME:") / "content" / xuid_str / title_id_str /
|
std::filesystem::path(kDefaultGameSymbolicLink) / "content" / xuid_str /
|
||||||
content_type_str;
|
title_id_str / content_type_str;
|
||||||
|
|
||||||
auto entry = kernel_state_->file_system()->ResolvePath(
|
auto entry = kernel_state_->file_system()->ResolvePath(
|
||||||
xe::path_to_utf8(game_content_path));
|
xe::path_to_utf8(game_content_path));
|
||||||
|
|||||||
@@ -244,6 +244,16 @@ dword_result_t xeXamContentCreate(dword_t user_index, lpstring_t root_name,
|
|||||||
return X_ERROR_INVALID_NAME;
|
return X_ERROR_INVALID_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if we have something under provided symlink.
|
||||||
|
std::string symlink_path = root_name.value();
|
||||||
|
if (!symlink_path.ends_with(':')) {
|
||||||
|
symlink_path += ':';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kernel_state()->file_system()->IsSymbolicLinkRegistered(symlink_path)) {
|
||||||
|
return X_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
XCONTENT_AGGREGATE_DATA content_data;
|
XCONTENT_AGGREGATE_DATA content_data;
|
||||||
if (content_data_size == sizeof(XCONTENT_DATA)) {
|
if (content_data_size == sizeof(XCONTENT_DATA)) {
|
||||||
content_data = *content_data_ptr.as<XCONTENT_DATA*>();
|
content_data = *content_data_ptr.as<XCONTENT_DATA*>();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace xam {
|
|||||||
void AddODDContentTest(object_ref<XStaticEnumerator<XCONTENT_AGGREGATE_DATA>> e,
|
void AddODDContentTest(object_ref<XStaticEnumerator<XCONTENT_AGGREGATE_DATA>> e,
|
||||||
XContentType content_type) {
|
XContentType content_type) {
|
||||||
auto root_entry = kernel_state()->file_system()->ResolvePath(
|
auto root_entry = kernel_state()->file_system()->ResolvePath(
|
||||||
"game:\\Content\\0000000000000000");
|
"GAME:\\Content\\0000000000000000");
|
||||||
if (!root_entry) {
|
if (!root_entry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,8 +116,8 @@ void XamModule::SaveLoaderData() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
remove_prefix("game:\\");
|
remove_prefix(fmt::format("{}\\", kDefaultGameSymbolicLink));
|
||||||
remove_prefix("d:\\");
|
remove_prefix(fmt::format("{}\\", kDefaultPartitionSymbolicLink));
|
||||||
|
|
||||||
if (host_path.extension() == ".xex") {
|
if (host_path.extension() == ".xex") {
|
||||||
host_path.remove_filename();
|
host_path.remove_filename();
|
||||||
|
|||||||
@@ -56,6 +56,15 @@ bool VirtualFileSystem::UnregisterDevice(const std::string_view path) {
|
|||||||
bool VirtualFileSystem::RegisterSymbolicLink(const std::string_view path,
|
bool VirtualFileSystem::RegisterSymbolicLink(const std::string_view path,
|
||||||
const std::string_view target) {
|
const std::string_view target) {
|
||||||
auto global_lock = global_critical_region_.Acquire();
|
auto global_lock = global_critical_region_.Acquire();
|
||||||
|
auto it = std::find_if(
|
||||||
|
symlinks_.cbegin(), symlinks_.cend(),
|
||||||
|
[&](const auto& s) { return xe::utf8::equal_case(path, s.first); });
|
||||||
|
if (it != symlinks_.end()) {
|
||||||
|
XELOGE("Trying to re-register already registered symbolic link: {} => {}",
|
||||||
|
path, target);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
symlinks_.insert({std::string(path), std::string(target)});
|
symlinks_.insert({std::string(path), std::string(target)});
|
||||||
XELOGD("Registered symbolic link: {} => {}", path, target);
|
XELOGD("Registered symbolic link: {} => {}", path, target);
|
||||||
|
|
||||||
@@ -76,6 +85,14 @@ bool VirtualFileSystem::UnregisterSymbolicLink(const std::string_view path) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VirtualFileSystem::IsSymbolicLinkRegistered(const std::string_view path) {
|
||||||
|
auto it = std::find_if(
|
||||||
|
symlinks_.cbegin(), symlinks_.cend(),
|
||||||
|
[&](const auto& s) { return xe::utf8::equal_case(path, s.first); });
|
||||||
|
|
||||||
|
return it != symlinks_.cend();
|
||||||
|
}
|
||||||
|
|
||||||
bool VirtualFileSystem::FindSymbolicLink(const std::string_view path,
|
bool VirtualFileSystem::FindSymbolicLink(const std::string_view path,
|
||||||
std::string& target) {
|
std::string& target) {
|
||||||
auto it = std::find_if(
|
auto it = std::find_if(
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class VirtualFileSystem {
|
|||||||
bool RegisterSymbolicLink(const std::string_view path,
|
bool RegisterSymbolicLink(const std::string_view path,
|
||||||
const std::string_view target);
|
const std::string_view target);
|
||||||
bool UnregisterSymbolicLink(const std::string_view path);
|
bool UnregisterSymbolicLink(const std::string_view path);
|
||||||
|
bool IsSymbolicLinkRegistered(const std::string_view path);
|
||||||
bool FindSymbolicLink(const std::string_view path, std::string& target);
|
bool FindSymbolicLink(const std::string_view path, std::string& target);
|
||||||
|
|
||||||
Entry* ResolvePath(const std::string_view path);
|
Entry* ResolvePath(const std::string_view path);
|
||||||
|
|||||||
Reference in New Issue
Block a user