mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-11-15 06:20:06 +00:00
fssrv: Add various data types and utility classes
These will be needed to reimplement the filesystem at a later point.
This commit is contained in:
parent
1e0e36c2c2
commit
f9a67ff75d
@ -60,6 +60,7 @@ add_library(core STATIC
|
|||||||
file_sys/fs_path_utility.h
|
file_sys/fs_path_utility.h
|
||||||
file_sys/fs_save_data_types.h
|
file_sys/fs_save_data_types.h
|
||||||
file_sys/fs_string_util.h
|
file_sys/fs_string_util.h
|
||||||
|
file_sys/fs_program_index_map_info.h
|
||||||
file_sys/fsa/fs_i_directory.h
|
file_sys/fsa/fs_i_directory.h
|
||||||
file_sys/fsa/fs_i_file.h
|
file_sys/fsa/fs_i_file.h
|
||||||
file_sys/fsa/fs_i_filesystem.h
|
file_sys/fsa/fs_i_filesystem.h
|
||||||
@ -109,6 +110,19 @@ add_library(core STATIC
|
|||||||
file_sys/fssystem/fssystem_switch_storage.h
|
file_sys/fssystem/fssystem_switch_storage.h
|
||||||
file_sys/fssystem/fssystem_utility.cpp
|
file_sys/fssystem/fssystem_utility.cpp
|
||||||
file_sys/fssystem/fssystem_utility.h
|
file_sys/fssystem/fssystem_utility.h
|
||||||
|
file_sys/fssrv/impl/fssrv_program_info.cpp
|
||||||
|
file_sys/fssrv/impl/fssrv_program_info.h
|
||||||
|
file_sys/fssrv/impl/fssrv_access_control.h
|
||||||
|
file_sys/fssrv/impl/fssrv_access_control.cpp
|
||||||
|
file_sys/fssrv/impl/fssrv_access_control_bits.h
|
||||||
|
file_sys/fssrv/impl/fssrv_program_registry_manager.cpp
|
||||||
|
file_sys/fssrv/impl/fssrv_program_registry_manager.h
|
||||||
|
file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h
|
||||||
|
file_sys/fssrv/impl/fssrv_save_data_properties.h
|
||||||
|
file_sys/fssrv/fssrv_program_registry_impl.h
|
||||||
|
file_sys/fssrv/fssrv_program_registry_impl.cpp
|
||||||
|
file_sys/fssrv/fssrv_program_registry_service.h
|
||||||
|
file_sys/fssrv/fssrv_program_registry_service.cpp
|
||||||
file_sys/ips_layer.cpp
|
file_sys/ips_layer.cpp
|
||||||
file_sys/ips_layer.h
|
file_sys/ips_layer.h
|
||||||
file_sys/kernel_executable.cpp
|
file_sys/kernel_executable.cpp
|
||||||
|
@ -16,11 +16,13 @@ constexpr Result ResultPortSdCardNoDevice{ErrorModule::FS, 2001};
|
|||||||
constexpr Result ResultNotImplemented{ErrorModule::FS, 3001};
|
constexpr Result ResultNotImplemented{ErrorModule::FS, 3001};
|
||||||
constexpr Result ResultUnsupportedVersion{ErrorModule::FS, 3002};
|
constexpr Result ResultUnsupportedVersion{ErrorModule::FS, 3002};
|
||||||
constexpr Result ResultOutOfRange{ErrorModule::FS, 3005};
|
constexpr Result ResultOutOfRange{ErrorModule::FS, 3005};
|
||||||
|
constexpr Result ResultAllocationMemoryFailedInProgramRegistryManagerA{ErrorModule::FS, 3258};
|
||||||
constexpr Result ResultAllocationMemoryFailedInFileSystemBuddyHeapA{ErrorModule::FS, 3294};
|
constexpr Result ResultAllocationMemoryFailedInFileSystemBuddyHeapA{ErrorModule::FS, 3294};
|
||||||
constexpr Result ResultAllocationMemoryFailedInNcaFileSystemDriverI{ErrorModule::FS, 3341};
|
constexpr Result ResultAllocationMemoryFailedInNcaFileSystemDriverI{ErrorModule::FS, 3341};
|
||||||
constexpr Result ResultAllocationMemoryFailedInNcaReaderA{ErrorModule::FS, 3363};
|
constexpr Result ResultAllocationMemoryFailedInNcaReaderA{ErrorModule::FS, 3363};
|
||||||
constexpr Result ResultAllocationMemoryFailedInAesCtrCounterExtendedStorageA{ErrorModule::FS, 3399};
|
constexpr Result ResultAllocationMemoryFailedInAesCtrCounterExtendedStorageA{ErrorModule::FS, 3399};
|
||||||
constexpr Result ResultAllocationMemoryFailedInIntegrityRomFsStorageA{ErrorModule::FS, 3412};
|
constexpr Result ResultAllocationMemoryFailedInIntegrityRomFsStorageA{ErrorModule::FS, 3412};
|
||||||
|
constexpr Result ResultAllocationMemoryFailedNew{ErrorModule::FS, 3420};
|
||||||
constexpr Result ResultAllocationMemoryFailedMakeUnique{ErrorModule::FS, 3422};
|
constexpr Result ResultAllocationMemoryFailedMakeUnique{ErrorModule::FS, 3422};
|
||||||
constexpr Result ResultAllocationMemoryFailedAllocateShared{ErrorModule::FS, 3423};
|
constexpr Result ResultAllocationMemoryFailedAllocateShared{ErrorModule::FS, 3423};
|
||||||
constexpr Result ResultInvalidAesCtrCounterExtendedEntryOffset{ErrorModule::FS, 4012};
|
constexpr Result ResultInvalidAesCtrCounterExtendedEntryOffset{ErrorModule::FS, 4012};
|
||||||
@ -92,6 +94,7 @@ constexpr Result ResultUnsupportedSetSizeForIndirectStorage{ErrorModule::FS, 632
|
|||||||
constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387};
|
constexpr Result ResultUnsupportedWriteForCompressedStorage{ErrorModule::FS, 6387};
|
||||||
constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388};
|
constexpr Result ResultUnsupportedOperateRangeForCompressedStorage{ErrorModule::FS, 6388};
|
||||||
constexpr Result ResultPermissionDenied{ErrorModule::FS, 6400};
|
constexpr Result ResultPermissionDenied{ErrorModule::FS, 6400};
|
||||||
|
constexpr Result ResultProgramInfoNotFound{ErrorModule::FS, 6605};
|
||||||
constexpr Result ResultBufferAllocationFailed{ErrorModule::FS, 6705};
|
constexpr Result ResultBufferAllocationFailed{ErrorModule::FS, 6705};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
20
src/core/file_sys/fs_program_index_map_info.h
Normal file
20
src/core/file_sys/fs_program_index_map_info.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
struct ProgramIndexMapInfo {
|
||||||
|
u64 program_id;
|
||||||
|
u64 base_program_id;
|
||||||
|
u8 program_index;
|
||||||
|
INSERT_PADDING_BYTES(0xF);
|
||||||
|
};
|
||||||
|
static_assert(std::is_trivially_copyable_v<ProgramIndexMapInfo>,
|
||||||
|
"Data type must be trivially copyable.");
|
||||||
|
static_assert(sizeof(ProgramIndexMapInfo) == 0x20, "ProgramIndexMapInfo has invalid size.");
|
||||||
|
|
||||||
|
} // namespace FileSys
|
77
src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp
Normal file
77
src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/errors.h"
|
||||||
|
#include "core/file_sys/fssrv/fssrv_program_registry_impl.h"
|
||||||
|
#include "core/file_sys/fssrv/fssrv_program_registry_service.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_info.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constinit ProgramRegistryServiceImpl* g_impl = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Move this to a common types file
|
||||||
|
constexpr u64 InvalidProcessIdProgramRegistry = 0xffffffffffffffffULL;
|
||||||
|
|
||||||
|
ProgramRegistryImpl::ProgramRegistryImpl(Core::System& system_)
|
||||||
|
: m_process_id(InvalidProcessIdProgramRegistry), system{system_} {}
|
||||||
|
|
||||||
|
ProgramRegistryImpl::~ProgramRegistryImpl() {}
|
||||||
|
|
||||||
|
void ProgramRegistryImpl::Initialize(ProgramRegistryServiceImpl* service) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(g_impl != nullptr);
|
||||||
|
ASSERT(g_impl == nullptr);
|
||||||
|
|
||||||
|
// Set the global service
|
||||||
|
g_impl = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryImpl::RegisterProgram(u64 process_id, u64 program_id, u8 storage_id,
|
||||||
|
const InBuffer<BufferAttr_HipcMapAlias> data,
|
||||||
|
s64 data_size,
|
||||||
|
const InBuffer<BufferAttr_HipcMapAlias> desc,
|
||||||
|
s64 desc_size) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(g_impl != nullptr);
|
||||||
|
|
||||||
|
// Check that we're allowed to register
|
||||||
|
R_UNLESS(FsSrv::Impl::IsInitialProgram(system, m_process_id), ResultPermissionDenied);
|
||||||
|
|
||||||
|
// Check buffer sizes
|
||||||
|
R_UNLESS(data.size() >= static_cast<size_t>(data_size), ResultInvalidSize);
|
||||||
|
R_UNLESS(desc.size() >= static_cast<size_t>(desc_size), ResultInvalidSize);
|
||||||
|
|
||||||
|
// Register the program
|
||||||
|
R_RETURN(g_impl->RegisterProgramInfo(process_id, program_id, storage_id, data.data(), data_size,
|
||||||
|
desc.data(), desc_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryImpl::UnregisterProgram(u64 process_id) {
|
||||||
|
// Check pre-conditions
|
||||||
|
ASSERT(g_impl != nullptr);
|
||||||
|
|
||||||
|
// Check that we're allowed to register
|
||||||
|
R_UNLESS(FsSrv::Impl::IsInitialProgram(system, m_process_id), ResultPermissionDenied);
|
||||||
|
|
||||||
|
// Unregister the program
|
||||||
|
R_RETURN(g_impl->UnregisterProgramInfo(process_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryImpl::SetCurrentProcess(const Service::ClientProcessId& client_pid) {
|
||||||
|
// Set our process id
|
||||||
|
m_process_id = client_pid.pid;
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryImpl::SetEnabledProgramVerification(bool enabled) {
|
||||||
|
// TODO: How to deal with this backwards compat?
|
||||||
|
ASSERT_MSG(false, "TODO: SetEnabledProgramVerification");
|
||||||
|
R_THROW(ResultNotImplemented);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv
|
46
src/core/file_sys/fssrv/fssrv_program_registry_impl.h
Normal file
46
src/core/file_sys/fssrv/fssrv_program_registry_impl.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv {
|
||||||
|
|
||||||
|
using namespace Service;
|
||||||
|
|
||||||
|
class ProgramRegistryServiceImpl;
|
||||||
|
|
||||||
|
namespace Impl {
|
||||||
|
class ProgramInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProgramRegistryImpl {
|
||||||
|
YUZU_NON_COPYABLE(ProgramRegistryImpl);
|
||||||
|
YUZU_NON_MOVEABLE(ProgramRegistryImpl);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProgramRegistryImpl(Core::System& system_);
|
||||||
|
~ProgramRegistryImpl();
|
||||||
|
|
||||||
|
static void Initialize(ProgramRegistryServiceImpl* service);
|
||||||
|
|
||||||
|
Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id,
|
||||||
|
const InBuffer<BufferAttr_HipcMapAlias> data, s64 data_size,
|
||||||
|
const InBuffer<BufferAttr_HipcMapAlias> desc, s64 desc_size);
|
||||||
|
Result UnregisterProgram(u64 process_id);
|
||||||
|
Result SetCurrentProcess(const Service::ClientProcessId& client_pid);
|
||||||
|
Result SetEnabledProgramVerification(bool enabled);
|
||||||
|
|
||||||
|
private:
|
||||||
|
u64 m_process_id;
|
||||||
|
Core::System& system;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv
|
57
src/core/file_sys/fssrv/fssrv_program_registry_service.cpp
Normal file
57
src/core/file_sys/fssrv/fssrv_program_registry_service.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/fssrv/fssrv_program_registry_service.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_index_map_info_manager.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_info.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_registry_manager.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv {
|
||||||
|
|
||||||
|
ProgramRegistryServiceImpl::ProgramRegistryServiceImpl(Core::System& system_,
|
||||||
|
const Configuration& cfg)
|
||||||
|
: m_config(cfg), m_registry_manager(std::make_unique<Impl::ProgramRegistryManager>(system_)),
|
||||||
|
m_index_map_info_manager(std::make_unique<Impl::ProgramIndexMapInfoManager>()) {}
|
||||||
|
|
||||||
|
Result ProgramRegistryServiceImpl::RegisterProgramInfo(u64 process_id, u64 program_id,
|
||||||
|
u8 storage_id, const void* data,
|
||||||
|
s64 data_size, const void* desc,
|
||||||
|
s64 desc_size) {
|
||||||
|
R_RETURN(m_registry_manager->RegisterProgram(process_id, program_id, storage_id, data,
|
||||||
|
data_size, desc, desc_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryServiceImpl::UnregisterProgramInfo(u64 process_id) {
|
||||||
|
R_RETURN(m_registry_manager->UnregisterProgram(process_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryServiceImpl::ResetProgramIndexMapInfo(const ProgramIndexMapInfo* infos,
|
||||||
|
int count) {
|
||||||
|
R_RETURN(m_index_map_info_manager->Reset(infos, count));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryServiceImpl::GetProgramInfo(std::shared_ptr<Impl::ProgramInfo>* out,
|
||||||
|
u64 process_id) {
|
||||||
|
R_RETURN(m_registry_manager->GetProgramInfo(out, process_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryServiceImpl::GetProgramInfoByProgramId(
|
||||||
|
std::shared_ptr<Impl::ProgramInfo>* out, u64 program_id) {
|
||||||
|
R_RETURN(m_registry_manager->GetProgramInfoByProgramId(out, program_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ProgramRegistryServiceImpl::GetProgramIndexMapInfoCount() {
|
||||||
|
return m_index_map_info_manager->GetProgramCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ProgramIndexMapInfo> ProgramRegistryServiceImpl::GetProgramIndexMapInfo(
|
||||||
|
const u64& program_id) {
|
||||||
|
return m_index_map_info_manager->Get(program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 ProgramRegistryServiceImpl::GetProgramIdByIndex(const u64& program_id, u8 index) {
|
||||||
|
return m_index_map_info_manager->GetProgramId(program_id, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv
|
48
src/core/file_sys/fssrv/fssrv_program_registry_service.h
Normal file
48
src/core/file_sys/fssrv/fssrv_program_registry_service.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include "core/file_sys/fs_program_index_map_info.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv {
|
||||||
|
|
||||||
|
namespace Impl {
|
||||||
|
class ProgramInfo;
|
||||||
|
class ProgramRegistryManager;
|
||||||
|
class ProgramIndexMapInfoManager;
|
||||||
|
} // namespace Impl
|
||||||
|
|
||||||
|
class ProgramRegistryServiceImpl {
|
||||||
|
public:
|
||||||
|
struct Configuration {};
|
||||||
|
|
||||||
|
ProgramRegistryServiceImpl(Core::System& system_, const Configuration& cfg);
|
||||||
|
|
||||||
|
Result RegisterProgramInfo(u64 process_id, u64 program_id, u8 storage_id, const void* data,
|
||||||
|
s64 data_size, const void* desc, s64 desc_size);
|
||||||
|
Result UnregisterProgramInfo(u64 process_id);
|
||||||
|
|
||||||
|
Result ResetProgramIndexMapInfo(const ProgramIndexMapInfo* infos, int count);
|
||||||
|
|
||||||
|
Result GetProgramInfo(std::shared_ptr<Impl::ProgramInfo>* out, u64 process_id);
|
||||||
|
Result GetProgramInfoByProgramId(std::shared_ptr<Impl::ProgramInfo>* out, u64 program_id);
|
||||||
|
|
||||||
|
size_t GetProgramIndexMapInfoCount();
|
||||||
|
std::optional<ProgramIndexMapInfo> GetProgramIndexMapInfo(const u64& program_id);
|
||||||
|
|
||||||
|
u64 GetProgramIdByIndex(const u64& program_id, u8 index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Configuration m_config;
|
||||||
|
std::unique_ptr<Impl::ProgramRegistryManager> m_registry_manager;
|
||||||
|
std::unique_ptr<Impl::ProgramIndexMapInfoManager> m_index_map_info_manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv
|
592
src/core/file_sys/fssrv/impl/fssrv_access_control.cpp
Normal file
592
src/core/file_sys/fssrv/impl/fssrv_access_control.cpp
Normal file
@ -0,0 +1,592 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/enum_util.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_access_control.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constinit bool g_is_debug_flag_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDebugFlagEnabled() {
|
||||||
|
return g_is_debug_flag_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDebugFlagEnabled(bool enabled) {
|
||||||
|
// Set global debug flag
|
||||||
|
g_is_debug_flag_enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Impl {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr u8 LatestFsAccessControlInfoVersion = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControl::AccessControl(const void* data, s64 data_size, const void* desc, s64 desc_size)
|
||||||
|
: AccessControl(data, data_size, desc, desc_size,
|
||||||
|
g_is_debug_flag_enabled ? AllFlagBitsMask : DebugFlagDisableMask) {}
|
||||||
|
|
||||||
|
AccessControl::AccessControl(const void* fac_data, s64 data_size, const void* fac_desc,
|
||||||
|
s64 desc_size, u64 flag_mask) {
|
||||||
|
// If either our data or descriptor is null, give no permissions
|
||||||
|
if (fac_data == nullptr || fac_desc == nullptr) {
|
||||||
|
m_flag_bits.emplace(Common::ToUnderlying(AccessControlBits::Bits::None));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that data/desc are big enough
|
||||||
|
ASSERT(data_size >= static_cast<s64>(sizeof(AccessControlDataHeader)));
|
||||||
|
ASSERT(desc_size >= static_cast<s64>(sizeof(AccessControlDescriptor)));
|
||||||
|
|
||||||
|
// Copy in the data/descriptor
|
||||||
|
AccessControlDataHeader data = {};
|
||||||
|
AccessControlDescriptor desc = {};
|
||||||
|
std::memcpy(std::addressof(data), fac_data, sizeof(data));
|
||||||
|
std::memcpy(std::addressof(desc), fac_desc, sizeof(desc));
|
||||||
|
|
||||||
|
// If we don't know how to parse the descriptors, don't
|
||||||
|
if (data.version != desc.version || data.version < LatestFsAccessControlInfoVersion) {
|
||||||
|
m_flag_bits.emplace(Common::ToUnderlying(AccessControlBits::Bits::None));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restrict the descriptor's flag bits
|
||||||
|
desc.flag_bits &= flag_mask;
|
||||||
|
|
||||||
|
// Create our flag bits
|
||||||
|
m_flag_bits.emplace(data.flag_bits & desc.flag_bits);
|
||||||
|
|
||||||
|
// Further check sizes
|
||||||
|
ASSERT(data_size >= data.content_owner_infos_offset + data.content_owner_infos_size);
|
||||||
|
ASSERT(desc_size >= static_cast<s64>(sizeof(AccessControlDescriptor) +
|
||||||
|
desc.content_owner_id_count * sizeof(u64)));
|
||||||
|
|
||||||
|
// Read out the content data owner infos
|
||||||
|
uintptr_t data_start = reinterpret_cast<uintptr_t>(fac_data);
|
||||||
|
uintptr_t desc_start = reinterpret_cast<uintptr_t>(fac_desc);
|
||||||
|
if (data.content_owner_infos_size > 0) {
|
||||||
|
// Get the count
|
||||||
|
const u32 num_content_owner_infos = Common::LoadLittleEndian<u32>(
|
||||||
|
reinterpret_cast<u32*>(data_start + data.content_owner_infos_offset));
|
||||||
|
|
||||||
|
// Validate the id range
|
||||||
|
uintptr_t id_start = data_start + data.content_owner_infos_offset + sizeof(u32);
|
||||||
|
uintptr_t id_end = id_start + sizeof(u64) * num_content_owner_infos;
|
||||||
|
ASSERT(id_end ==
|
||||||
|
data_start + data.content_owner_infos_offset + data.content_owner_infos_size);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < num_content_owner_infos; ++i) {
|
||||||
|
// Read the id
|
||||||
|
const u64 id =
|
||||||
|
Common::LoadLittleEndian<u64>(reinterpret_cast<u64*>(id_start + i * sizeof(u64)));
|
||||||
|
|
||||||
|
// Check that the descriptor allows it
|
||||||
|
bool allowed = false;
|
||||||
|
if (desc.content_owner_id_count != 0) {
|
||||||
|
for (u8 n = 0; n < desc.content_owner_id_count; ++n) {
|
||||||
|
if (id ==
|
||||||
|
Common::LoadLittleEndian<u64>(reinterpret_cast<u64*>(
|
||||||
|
desc_start + sizeof(AccessControlDescriptor) + n * sizeof(u64)))) {
|
||||||
|
allowed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((desc.content_owner_id_min == 0 && desc.content_owner_id_max == 0) ||
|
||||||
|
(desc.content_owner_id_min <= id && id <= desc.content_owner_id_max)) {
|
||||||
|
allowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the id is allowed, create it
|
||||||
|
if (allowed) {
|
||||||
|
if (auto* info = new ContentOwnerInfo(id); info != nullptr) {
|
||||||
|
m_content_owner_infos.push_front(*info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read out the save data owner infos
|
||||||
|
ASSERT(data_size >= data.save_data_owner_infos_offset + data.save_data_owner_infos_size);
|
||||||
|
ASSERT(desc_size >= static_cast<s64>(sizeof(AccessControlDescriptor) +
|
||||||
|
desc.content_owner_id_count * sizeof(u64) +
|
||||||
|
desc.save_data_owner_id_count * sizeof(u64)));
|
||||||
|
if (data.save_data_owner_infos_size > 0) {
|
||||||
|
// Get the count
|
||||||
|
const u32 num_save_data_owner_infos = Common::LoadLittleEndian<u32>(
|
||||||
|
reinterpret_cast<u32*>(data_start + data.save_data_owner_infos_offset));
|
||||||
|
|
||||||
|
// Get accessibility region
|
||||||
|
uintptr_t accessibility_start =
|
||||||
|
data_start + data.save_data_owner_infos_offset + sizeof(u32);
|
||||||
|
|
||||||
|
// Validate the id range
|
||||||
|
uintptr_t id_start =
|
||||||
|
accessibility_start +
|
||||||
|
Common::AlignUp(num_save_data_owner_infos * sizeof(Accessibility), alignof(u32));
|
||||||
|
uintptr_t id_end = id_start + sizeof(u64) * num_save_data_owner_infos;
|
||||||
|
ASSERT(id_end ==
|
||||||
|
data_start + data.save_data_owner_infos_offset + data.save_data_owner_infos_size);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < num_save_data_owner_infos; ++i) {
|
||||||
|
// Read the accessibility/id
|
||||||
|
static_assert(sizeof(Accessibility) == 1);
|
||||||
|
const Accessibility accessibility =
|
||||||
|
*reinterpret_cast<Accessibility*>(accessibility_start + i * sizeof(Accessibility));
|
||||||
|
const u64 id =
|
||||||
|
Common::LoadLittleEndian<u64>(reinterpret_cast<u64*>(id_start + i * sizeof(u64)));
|
||||||
|
|
||||||
|
// Check that the descriptor allows it
|
||||||
|
bool allowed = false;
|
||||||
|
if (desc.save_data_owner_id_count != 0) {
|
||||||
|
for (u8 n = 0; n < desc.save_data_owner_id_count; ++n) {
|
||||||
|
if (id == Common::LoadLittleEndian<u64>(reinterpret_cast<u64*>(
|
||||||
|
desc_start + sizeof(AccessControlDescriptor) +
|
||||||
|
desc.content_owner_id_count * sizeof(u64) + n * sizeof(u64)))) {
|
||||||
|
allowed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((desc.save_data_owner_id_min == 0 && desc.save_data_owner_id_max == 0) ||
|
||||||
|
(desc.save_data_owner_id_min <= id && id <= desc.save_data_owner_id_max)) {
|
||||||
|
allowed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the id is allowed, create it
|
||||||
|
if (allowed) {
|
||||||
|
if (auto* info = new SaveDataOwnerInfo(id, accessibility); info != nullptr) {
|
||||||
|
m_save_data_owner_infos.push_front(*info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessControl::~AccessControl() {
|
||||||
|
// Delete all content owner infos
|
||||||
|
while (!m_content_owner_infos.empty()) {
|
||||||
|
auto* info = std::addressof(*m_content_owner_infos.rbegin());
|
||||||
|
m_content_owner_infos.erase(m_content_owner_infos.iterator_to(*info));
|
||||||
|
delete info;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all save data owner infos
|
||||||
|
while (!m_save_data_owner_infos.empty()) {
|
||||||
|
auto* info = std::addressof(*m_save_data_owner_infos.rbegin());
|
||||||
|
m_save_data_owner_infos.erase(m_save_data_owner_infos.iterator_to(*info));
|
||||||
|
delete info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccessControl::HasContentOwnerId(u64 owner_id) const {
|
||||||
|
// Check if we have a matching id
|
||||||
|
for (const auto& info : m_content_owner_infos) {
|
||||||
|
if (info.GetId() == owner_id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessibility AccessControl::GetAccessibilitySaveDataOwnedBy(u64 owner_id) const {
|
||||||
|
// Find a matching save data owner
|
||||||
|
for (const auto& info : m_save_data_owner_infos) {
|
||||||
|
if (info.GetId() == owner_id) {
|
||||||
|
return info.GetAccessibility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to no accessibility
|
||||||
|
return Accessibility::MakeAccessibility(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessControl::ListContentOwnerId(s32* out_count, u64* out_owner_ids, s32 offset,
|
||||||
|
s32 count) const {
|
||||||
|
// If we have nothing to read, just give the count
|
||||||
|
if (count == 0) {
|
||||||
|
*out_count = static_cast<s32>(m_content_owner_infos.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read out the ids
|
||||||
|
s32 read_offset = 0;
|
||||||
|
s32 read_count = 0;
|
||||||
|
if (out_owner_ids != nullptr) {
|
||||||
|
auto* cur_out = out_owner_ids;
|
||||||
|
for (const auto& info : m_content_owner_infos) {
|
||||||
|
// Skip until we get to the desired offset
|
||||||
|
if (read_offset < offset) {
|
||||||
|
++read_offset;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the output value
|
||||||
|
*cur_out = info.GetId();
|
||||||
|
++cur_out;
|
||||||
|
++read_count;
|
||||||
|
|
||||||
|
// If we've read as many as we can, finish
|
||||||
|
if (read_count == count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the out value
|
||||||
|
*out_count = read_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AccessControl::ListSaveDataOwnedId(s32* out_count, u64* out_owner_ids, s32 offset,
|
||||||
|
s32 count) const {
|
||||||
|
// If we have nothing to read, just give the count
|
||||||
|
if (count == 0) {
|
||||||
|
*out_count = static_cast<s32>(m_save_data_owner_infos.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read out the ids
|
||||||
|
s32 read_offset = 0;
|
||||||
|
s32 read_count = 0;
|
||||||
|
if (out_owner_ids != nullptr) {
|
||||||
|
auto* cur_out = out_owner_ids;
|
||||||
|
for (const auto& info : m_save_data_owner_infos) {
|
||||||
|
// Skip until we get to the desired offset
|
||||||
|
if (read_offset < offset) {
|
||||||
|
++read_offset;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the output value
|
||||||
|
*cur_out = info.GetId();
|
||||||
|
++cur_out;
|
||||||
|
++read_count;
|
||||||
|
|
||||||
|
// If we've read as many as we can, finish
|
||||||
|
if (read_count == count) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the out value
|
||||||
|
*out_count = read_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessibility AccessControl::GetAccessibilityFor(AccessibilityType type) const {
|
||||||
|
switch (type) {
|
||||||
|
using enum AccessibilityType;
|
||||||
|
case MountLogo:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountLogoRead(), false);
|
||||||
|
case MountContentMeta:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentMetaRead(), false);
|
||||||
|
case MountContentControl:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentControlRead(), false);
|
||||||
|
case MountContentManual:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentManualRead(), false);
|
||||||
|
case MountContentData:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentDataRead(), false);
|
||||||
|
case MountApplicationPackage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountApplicationPackageRead(),
|
||||||
|
false);
|
||||||
|
case MountSaveDataStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountSaveDataStorageRead(),
|
||||||
|
m_flag_bits->CanMountSaveDataStorageWrite());
|
||||||
|
case MountContentStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountContentStorageRead(),
|
||||||
|
m_flag_bits->CanMountContentStorageWrite());
|
||||||
|
case MountImageAndVideoStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountImageAndVideoStorageRead(),
|
||||||
|
m_flag_bits->CanMountImageAndVideoStorageWrite());
|
||||||
|
case MountCloudBackupWorkStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountCloudBackupWorkStorageRead(),
|
||||||
|
m_flag_bits->CanMountCloudBackupWorkStorageWrite());
|
||||||
|
case MountCustomStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountCustomStorage0Read(),
|
||||||
|
m_flag_bits->CanMountCustomStorage0Write());
|
||||||
|
case MountBisCalibrationFile:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisCalibrationFileRead(),
|
||||||
|
m_flag_bits->CanMountBisCalibrationFileWrite());
|
||||||
|
case MountBisSafeMode:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisSafeModeRead(),
|
||||||
|
m_flag_bits->CanMountBisSafeModeWrite());
|
||||||
|
case MountBisUser:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisUserRead(),
|
||||||
|
m_flag_bits->CanMountBisUserWrite());
|
||||||
|
case MountBisSystem:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountBisSystemRead(),
|
||||||
|
m_flag_bits->CanMountBisSystemWrite());
|
||||||
|
case MountBisSystemProperEncryption:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanMountBisSystemProperEncryptionRead(),
|
||||||
|
m_flag_bits->CanMountBisSystemProperEncryptionWrite());
|
||||||
|
case MountBisSystemProperPartition:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanMountBisSystemProperPartitionRead(),
|
||||||
|
m_flag_bits->CanMountBisSystemProperPartitionWrite());
|
||||||
|
case MountSdCard:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountSdCardRead(),
|
||||||
|
m_flag_bits->CanMountSdCardWrite());
|
||||||
|
case MountGameCard:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountGameCardRead(), false);
|
||||||
|
case MountDeviceSaveData:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountDeviceSaveDataRead(),
|
||||||
|
m_flag_bits->CanMountDeviceSaveDataWrite());
|
||||||
|
case MountSystemSaveData:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountSystemSaveDataRead(),
|
||||||
|
m_flag_bits->CanMountSystemSaveDataWrite());
|
||||||
|
case MountOthersSaveData:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountOthersSaveDataRead(),
|
||||||
|
m_flag_bits->CanMountOthersSaveDataWrite());
|
||||||
|
case MountOthersSystemSaveData:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountOthersSystemSaveDataRead(),
|
||||||
|
m_flag_bits->CanMountOthersSystemSaveDataWrite());
|
||||||
|
case OpenBisPartitionBootPartition1Root:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootPartition1RootRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootPartition1RootWrite());
|
||||||
|
case OpenBisPartitionBootPartition2Root:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootPartition2RootRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootPartition2RootWrite());
|
||||||
|
case OpenBisPartitionUserDataRoot:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionUserDataRootRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionUserDataRootWrite());
|
||||||
|
case OpenBisPartitionBootConfigAndPackage2Part1:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part1Read(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part1Write());
|
||||||
|
case OpenBisPartitionBootConfigAndPackage2Part2:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part2Read(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part2Write());
|
||||||
|
case OpenBisPartitionBootConfigAndPackage2Part3:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part3Read(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part3Write());
|
||||||
|
case OpenBisPartitionBootConfigAndPackage2Part4:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part4Read(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part4Write());
|
||||||
|
case OpenBisPartitionBootConfigAndPackage2Part5:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part5Read(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part5Write());
|
||||||
|
case OpenBisPartitionBootConfigAndPackage2Part6:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part6Read(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionBootConfigAndPackage2Part6Write());
|
||||||
|
case OpenBisPartitionCalibrationBinary:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionCalibrationBinaryRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionCalibrationBinaryWrite());
|
||||||
|
case OpenBisPartitionCalibrationFile:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionCalibrationFileRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionCalibrationFileWrite());
|
||||||
|
case OpenBisPartitionSafeMode:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionSafeModeRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionSafeModeWrite());
|
||||||
|
case OpenBisPartitionUser:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionUserRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionUserWrite());
|
||||||
|
case OpenBisPartitionSystem:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanOpenBisPartitionSystemRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionSystemWrite());
|
||||||
|
case OpenBisPartitionSystemProperEncryption:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionSystemProperEncryptionRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionSystemProperEncryptionWrite());
|
||||||
|
case OpenBisPartitionSystemProperPartition:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanOpenBisPartitionSystemProperPartitionRead(),
|
||||||
|
m_flag_bits->CanOpenBisPartitionSystemProperPartitionWrite());
|
||||||
|
case OpenSdCardStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanOpenSdCardStorageRead(),
|
||||||
|
m_flag_bits->CanOpenSdCardStorageWrite());
|
||||||
|
case OpenGameCardStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanOpenGameCardStorageRead(),
|
||||||
|
m_flag_bits->CanOpenGameCardStorageWrite());
|
||||||
|
case MountSystemDataPrivate:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountSystemDataPrivateRead(),
|
||||||
|
false);
|
||||||
|
case MountHost:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountHostRead(),
|
||||||
|
m_flag_bits->CanMountHostWrite());
|
||||||
|
case MountRegisteredUpdatePartition:
|
||||||
|
return Accessibility::MakeAccessibility(
|
||||||
|
m_flag_bits->CanMountRegisteredUpdatePartitionRead() && g_is_debug_flag_enabled, false);
|
||||||
|
case MountSaveDataInternalStorage:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanOpenSaveDataInternalStorageRead(),
|
||||||
|
m_flag_bits->CanOpenSaveDataInternalStorageWrite());
|
||||||
|
case MountTemporaryDirectory:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountTemporaryDirectoryRead(),
|
||||||
|
m_flag_bits->CanMountTemporaryDirectoryWrite());
|
||||||
|
case MountAllBaseFileSystem:
|
||||||
|
return Accessibility::MakeAccessibility(m_flag_bits->CanMountAllBaseFileSystemRead(),
|
||||||
|
m_flag_bits->CanMountAllBaseFileSystemWrite());
|
||||||
|
case NotMount:
|
||||||
|
return Accessibility::MakeAccessibility(false, false);
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AccessControl::CanCall(OperationType type) const {
|
||||||
|
switch (type) {
|
||||||
|
using enum OperationType;
|
||||||
|
case InvalidateBisCache:
|
||||||
|
return m_flag_bits->CanInvalidateBisCache();
|
||||||
|
case EraseMmc:
|
||||||
|
return m_flag_bits->CanEraseMmc();
|
||||||
|
case GetGameCardDeviceCertificate:
|
||||||
|
return m_flag_bits->CanGetGameCardDeviceCertificate();
|
||||||
|
case GetGameCardIdSet:
|
||||||
|
return m_flag_bits->CanGetGameCardIdSet();
|
||||||
|
case FinalizeGameCardDriver:
|
||||||
|
return m_flag_bits->CanFinalizeGameCardDriver();
|
||||||
|
case GetGameCardAsicInfo:
|
||||||
|
return m_flag_bits->CanGetGameCardAsicInfo();
|
||||||
|
case CreateSaveData:
|
||||||
|
return m_flag_bits->CanCreateSaveData();
|
||||||
|
case DeleteSaveData:
|
||||||
|
return m_flag_bits->CanDeleteSaveData();
|
||||||
|
case CreateSystemSaveData:
|
||||||
|
return m_flag_bits->CanCreateSystemSaveData();
|
||||||
|
case CreateOthersSystemSaveData:
|
||||||
|
return m_flag_bits->CanCreateOthersSystemSaveData();
|
||||||
|
case DeleteSystemSaveData:
|
||||||
|
return m_flag_bits->CanDeleteSystemSaveData();
|
||||||
|
case OpenSaveDataInfoReader:
|
||||||
|
return m_flag_bits->CanOpenSaveDataInfoReader();
|
||||||
|
case OpenSaveDataInfoReaderForSystem:
|
||||||
|
return m_flag_bits->CanOpenSaveDataInfoReaderForSystem();
|
||||||
|
case OpenSaveDataInfoReaderForInternal:
|
||||||
|
return m_flag_bits->CanOpenSaveDataInfoReaderForInternal();
|
||||||
|
case OpenSaveDataMetaFile:
|
||||||
|
return m_flag_bits->CanOpenSaveDataMetaFile();
|
||||||
|
case SetCurrentPosixTime:
|
||||||
|
return m_flag_bits->CanSetCurrentPosixTime();
|
||||||
|
case ReadSaveDataFileSystemExtraData:
|
||||||
|
return m_flag_bits->CanReadSaveDataFileSystemExtraData();
|
||||||
|
case SetGlobalAccessLogMode:
|
||||||
|
return m_flag_bits->CanSetGlobalAccessLogMode();
|
||||||
|
case SetSpeedEmulationMode:
|
||||||
|
return m_flag_bits->CanSetSpeedEmulationMode();
|
||||||
|
case FillBis:
|
||||||
|
return m_flag_bits->CanFillBis();
|
||||||
|
case CorruptSaveData:
|
||||||
|
return m_flag_bits->CanCorruptSaveData();
|
||||||
|
case CorruptSystemSaveData:
|
||||||
|
return m_flag_bits->CanCorruptSystemSaveData();
|
||||||
|
case VerifySaveData:
|
||||||
|
return m_flag_bits->CanVerifySaveData();
|
||||||
|
case DebugSaveData:
|
||||||
|
return m_flag_bits->CanDebugSaveData();
|
||||||
|
case FormatSdCard:
|
||||||
|
return m_flag_bits->CanFormatSdCard();
|
||||||
|
case GetRightsId:
|
||||||
|
return m_flag_bits->CanGetRightsId();
|
||||||
|
case RegisterExternalKey:
|
||||||
|
return m_flag_bits->CanRegisterExternalKey();
|
||||||
|
case SetEncryptionSeed:
|
||||||
|
return m_flag_bits->CanSetEncryptionSeed();
|
||||||
|
case WriteSaveDataFileSystemExtraDataTimeStamp:
|
||||||
|
return m_flag_bits->CanWriteSaveDataFileSystemExtraDataTimeStamp();
|
||||||
|
case WriteSaveDataFileSystemExtraDataFlags:
|
||||||
|
return m_flag_bits->CanWriteSaveDataFileSystemExtraDataFlags();
|
||||||
|
case WriteSaveDataFileSystemExtraDataCommitId:
|
||||||
|
return m_flag_bits->CanWriteSaveDataFileSystemExtraDataCommitId();
|
||||||
|
case WriteSaveDataFileSystemExtraDataAll:
|
||||||
|
return m_flag_bits->CanWriteSaveDataFileSystemExtraDataAll();
|
||||||
|
case ExtendSaveData:
|
||||||
|
return m_flag_bits->CanExtendSaveData();
|
||||||
|
case ExtendSystemSaveData:
|
||||||
|
return m_flag_bits->CanExtendSystemSaveData();
|
||||||
|
case ExtendOthersSystemSaveData:
|
||||||
|
return m_flag_bits->CanExtendOthersSystemSaveData();
|
||||||
|
case RegisterUpdatePartition:
|
||||||
|
return m_flag_bits->CanRegisterUpdatePartition() && g_is_debug_flag_enabled;
|
||||||
|
case OpenSaveDataTransferManager:
|
||||||
|
return m_flag_bits->CanOpenSaveDataTransferManager();
|
||||||
|
case OpenSaveDataTransferManagerVersion2:
|
||||||
|
return m_flag_bits->CanOpenSaveDataTransferManagerVersion2();
|
||||||
|
case OpenSaveDataTransferManagerForSaveDataRepair:
|
||||||
|
return m_flag_bits->CanOpenSaveDataTransferManagerForSaveDataRepair();
|
||||||
|
case OpenSaveDataTransferManagerForSaveDataRepairTool:
|
||||||
|
return m_flag_bits->CanOpenSaveDataTransferManagerForSaveDataRepairTool();
|
||||||
|
case OpenSaveDataTransferProhibiter:
|
||||||
|
return m_flag_bits->CanOpenSaveDataTransferProhibiter();
|
||||||
|
case OpenSaveDataMover:
|
||||||
|
return m_flag_bits->CanOpenSaveDataMover();
|
||||||
|
case OpenBisWiper:
|
||||||
|
return m_flag_bits->CanOpenBisWiper();
|
||||||
|
case ListAccessibleSaveDataOwnerId:
|
||||||
|
return m_flag_bits->CanListAccessibleSaveDataOwnerId();
|
||||||
|
case ControlMmcPatrol:
|
||||||
|
return m_flag_bits->CanControlMmcPatrol();
|
||||||
|
case OverrideSaveDataTransferTokenSignVerificationKey:
|
||||||
|
return m_flag_bits->CanOverrideSaveDataTransferTokenSignVerificationKey();
|
||||||
|
case OpenSdCardDetectionEventNotifier:
|
||||||
|
return m_flag_bits->CanOpenSdCardDetectionEventNotifier();
|
||||||
|
case OpenGameCardDetectionEventNotifier:
|
||||||
|
return m_flag_bits->CanOpenGameCardDetectionEventNotifier();
|
||||||
|
case OpenSystemDataUpdateEventNotifier:
|
||||||
|
return m_flag_bits->CanOpenSystemDataUpdateEventNotifier();
|
||||||
|
case NotifySystemDataUpdateEvent:
|
||||||
|
return m_flag_bits->CanNotifySystemDataUpdateEvent();
|
||||||
|
case OpenAccessFailureDetectionEventNotifier:
|
||||||
|
return m_flag_bits->CanOpenAccessFailureDetectionEventNotifier();
|
||||||
|
case GetAccessFailureDetectionEvent:
|
||||||
|
return m_flag_bits->CanGetAccessFailureDetectionEvent();
|
||||||
|
case IsAccessFailureDetected:
|
||||||
|
return m_flag_bits->CanIsAccessFailureDetected();
|
||||||
|
case ResolveAccessFailure:
|
||||||
|
return m_flag_bits->CanResolveAccessFailure();
|
||||||
|
case AbandonAccessFailure:
|
||||||
|
return m_flag_bits->CanAbandonAccessFailure();
|
||||||
|
case QuerySaveDataInternalStorageTotalSize:
|
||||||
|
return m_flag_bits->CanQuerySaveDataInternalStorageTotalSize();
|
||||||
|
case GetSaveDataCommitId:
|
||||||
|
return m_flag_bits->CanGetSaveDataCommitId();
|
||||||
|
case SetSdCardAccessibility:
|
||||||
|
return m_flag_bits->CanSetSdCardAccessibility();
|
||||||
|
case SimulateDevice:
|
||||||
|
return m_flag_bits->CanSimulateDevice();
|
||||||
|
case CreateSaveDataWithHashSalt:
|
||||||
|
return m_flag_bits->CanCreateSaveDataWithHashSalt();
|
||||||
|
case RegisterProgramIndexMapInfo:
|
||||||
|
return m_flag_bits->CanRegisterProgramIndexMapInfo();
|
||||||
|
case ChallengeCardExistence:
|
||||||
|
return m_flag_bits->CanChallengeCardExistence();
|
||||||
|
case CreateOwnSaveData:
|
||||||
|
return m_flag_bits->CanCreateOwnSaveData();
|
||||||
|
case DeleteOwnSaveData:
|
||||||
|
return m_flag_bits->CanDeleteOwnSaveData();
|
||||||
|
case ReadOwnSaveDataFileSystemExtraData:
|
||||||
|
return m_flag_bits->CanReadOwnSaveDataFileSystemExtraData();
|
||||||
|
case ExtendOwnSaveData:
|
||||||
|
return m_flag_bits->CanExtendOwnSaveData();
|
||||||
|
case OpenOwnSaveDataTransferProhibiter:
|
||||||
|
return m_flag_bits->CanOpenOwnSaveDataTransferProhibiter();
|
||||||
|
case FindOwnSaveDataWithFilter:
|
||||||
|
return m_flag_bits->CanFindOwnSaveDataWithFilter();
|
||||||
|
case OpenSaveDataTransferManagerForRepair:
|
||||||
|
return m_flag_bits->CanOpenSaveDataTransferManagerForRepair();
|
||||||
|
case SetDebugConfiguration:
|
||||||
|
return m_flag_bits->CanSetDebugConfiguration();
|
||||||
|
case OpenDataStorageByPath:
|
||||||
|
return m_flag_bits->CanOpenDataStorageByPath();
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Impl
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv
|
260
src/core/file_sys/fssrv/impl/fssrv_access_control.h
Normal file
260
src/core/file_sys/fssrv/impl/fssrv_access_control.h
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/enum_util.h"
|
||||||
|
#include "common/intrusive_list.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_access_control_bits.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv {
|
||||||
|
|
||||||
|
bool IsDebugFlagEnabled();
|
||||||
|
void SetDebugFlagEnabled(bool enabled);
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
struct Accessibility {
|
||||||
|
u8 value;
|
||||||
|
|
||||||
|
constexpr bool CanRead() const {
|
||||||
|
return value & (1 << 0);
|
||||||
|
}
|
||||||
|
constexpr bool CanWrite() const {
|
||||||
|
return value & (1 << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr Accessibility MakeAccessibility(bool read, bool write) {
|
||||||
|
return {static_cast<u8>(read * (1 << 0) + write * (1 << 1))};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(std::is_trivial<Accessibility>::value);
|
||||||
|
|
||||||
|
class ContentOwnerInfo : public Common::IntrusiveListBaseNode<ContentOwnerInfo> {
|
||||||
|
private:
|
||||||
|
u64 m_id;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ContentOwnerInfo(u64 id) : m_id(id) {}
|
||||||
|
|
||||||
|
u64 GetId() const {
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SaveDataOwnerInfo : public Common::IntrusiveListBaseNode<SaveDataOwnerInfo> {
|
||||||
|
private:
|
||||||
|
u64 m_id;
|
||||||
|
Accessibility m_accessibility;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SaveDataOwnerInfo(u64 id, Accessibility access) : m_id(id), m_accessibility(access) {}
|
||||||
|
|
||||||
|
u64 GetId() const {
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
Accessibility GetAccessibility() const {
|
||||||
|
return m_accessibility;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AccessControl {
|
||||||
|
public:
|
||||||
|
enum class AccessibilityType : u32 {
|
||||||
|
MountLogo,
|
||||||
|
MountContentMeta,
|
||||||
|
MountContentControl,
|
||||||
|
MountContentManual,
|
||||||
|
MountContentData,
|
||||||
|
MountApplicationPackage,
|
||||||
|
MountSaveDataStorage,
|
||||||
|
MountContentStorage,
|
||||||
|
MountImageAndVideoStorage,
|
||||||
|
MountCloudBackupWorkStorage,
|
||||||
|
MountCustomStorage,
|
||||||
|
MountBisCalibrationFile,
|
||||||
|
MountBisSafeMode,
|
||||||
|
MountBisUser,
|
||||||
|
MountBisSystem,
|
||||||
|
MountBisSystemProperEncryption,
|
||||||
|
MountBisSystemProperPartition,
|
||||||
|
MountSdCard,
|
||||||
|
MountGameCard,
|
||||||
|
MountDeviceSaveData,
|
||||||
|
MountSystemSaveData,
|
||||||
|
MountOthersSaveData,
|
||||||
|
MountOthersSystemSaveData,
|
||||||
|
OpenBisPartitionBootPartition1Root,
|
||||||
|
OpenBisPartitionBootPartition2Root,
|
||||||
|
OpenBisPartitionUserDataRoot,
|
||||||
|
OpenBisPartitionBootConfigAndPackage2Part1,
|
||||||
|
OpenBisPartitionBootConfigAndPackage2Part2,
|
||||||
|
OpenBisPartitionBootConfigAndPackage2Part3,
|
||||||
|
OpenBisPartitionBootConfigAndPackage2Part4,
|
||||||
|
OpenBisPartitionBootConfigAndPackage2Part5,
|
||||||
|
OpenBisPartitionBootConfigAndPackage2Part6,
|
||||||
|
OpenBisPartitionCalibrationBinary,
|
||||||
|
OpenBisPartitionCalibrationFile,
|
||||||
|
OpenBisPartitionSafeMode,
|
||||||
|
OpenBisPartitionUser,
|
||||||
|
OpenBisPartitionSystem,
|
||||||
|
OpenBisPartitionSystemProperEncryption,
|
||||||
|
OpenBisPartitionSystemProperPartition,
|
||||||
|
OpenSdCardStorage,
|
||||||
|
OpenGameCardStorage,
|
||||||
|
MountSystemDataPrivate,
|
||||||
|
MountHost,
|
||||||
|
MountRegisteredUpdatePartition,
|
||||||
|
MountSaveDataInternalStorage,
|
||||||
|
MountTemporaryDirectory,
|
||||||
|
MountAllBaseFileSystem,
|
||||||
|
NotMount,
|
||||||
|
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OperationType : u32 {
|
||||||
|
InvalidateBisCache,
|
||||||
|
EraseMmc,
|
||||||
|
GetGameCardDeviceCertificate,
|
||||||
|
GetGameCardIdSet,
|
||||||
|
FinalizeGameCardDriver,
|
||||||
|
GetGameCardAsicInfo,
|
||||||
|
CreateSaveData,
|
||||||
|
DeleteSaveData,
|
||||||
|
CreateSystemSaveData,
|
||||||
|
CreateOthersSystemSaveData,
|
||||||
|
DeleteSystemSaveData,
|
||||||
|
OpenSaveDataInfoReader,
|
||||||
|
OpenSaveDataInfoReaderForSystem,
|
||||||
|
OpenSaveDataInfoReaderForInternal,
|
||||||
|
OpenSaveDataMetaFile,
|
||||||
|
SetCurrentPosixTime,
|
||||||
|
ReadSaveDataFileSystemExtraData,
|
||||||
|
SetGlobalAccessLogMode,
|
||||||
|
SetSpeedEmulationMode,
|
||||||
|
Debug,
|
||||||
|
FillBis,
|
||||||
|
CorruptSaveData,
|
||||||
|
CorruptSystemSaveData,
|
||||||
|
VerifySaveData,
|
||||||
|
DebugSaveData,
|
||||||
|
FormatSdCard,
|
||||||
|
GetRightsId,
|
||||||
|
RegisterExternalKey,
|
||||||
|
SetEncryptionSeed,
|
||||||
|
WriteSaveDataFileSystemExtraDataTimeStamp,
|
||||||
|
WriteSaveDataFileSystemExtraDataFlags,
|
||||||
|
WriteSaveDataFileSystemExtraDataCommitId,
|
||||||
|
WriteSaveDataFileSystemExtraDataAll,
|
||||||
|
ExtendSaveData,
|
||||||
|
ExtendSystemSaveData,
|
||||||
|
ExtendOthersSystemSaveData,
|
||||||
|
RegisterUpdatePartition,
|
||||||
|
OpenSaveDataTransferManager,
|
||||||
|
OpenSaveDataTransferManagerVersion2,
|
||||||
|
OpenSaveDataTransferManagerForSaveDataRepair,
|
||||||
|
OpenSaveDataTransferManagerForSaveDataRepairTool,
|
||||||
|
OpenSaveDataTransferProhibiter,
|
||||||
|
OpenSaveDataMover,
|
||||||
|
OpenBisWiper,
|
||||||
|
ListAccessibleSaveDataOwnerId,
|
||||||
|
ControlMmcPatrol,
|
||||||
|
OverrideSaveDataTransferTokenSignVerificationKey,
|
||||||
|
OpenSdCardDetectionEventNotifier,
|
||||||
|
OpenGameCardDetectionEventNotifier,
|
||||||
|
OpenSystemDataUpdateEventNotifier,
|
||||||
|
NotifySystemDataUpdateEvent,
|
||||||
|
OpenAccessFailureDetectionEventNotifier,
|
||||||
|
GetAccessFailureDetectionEvent,
|
||||||
|
IsAccessFailureDetected,
|
||||||
|
ResolveAccessFailure,
|
||||||
|
AbandonAccessFailure,
|
||||||
|
QuerySaveDataInternalStorageTotalSize,
|
||||||
|
GetSaveDataCommitId,
|
||||||
|
SetSdCardAccessibility,
|
||||||
|
SimulateDevice,
|
||||||
|
CreateSaveDataWithHashSalt,
|
||||||
|
RegisterProgramIndexMapInfo,
|
||||||
|
ChallengeCardExistence,
|
||||||
|
CreateOwnSaveData,
|
||||||
|
DeleteOwnSaveData,
|
||||||
|
ReadOwnSaveDataFileSystemExtraData,
|
||||||
|
ExtendOwnSaveData,
|
||||||
|
OpenOwnSaveDataTransferProhibiter,
|
||||||
|
FindOwnSaveDataWithFilter,
|
||||||
|
OpenSaveDataTransferManagerForRepair,
|
||||||
|
SetDebugConfiguration,
|
||||||
|
OpenDataStorageByPath,
|
||||||
|
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push, 4)
|
||||||
|
struct AccessControlDataHeader {
|
||||||
|
u8 version;
|
||||||
|
u8 reserved[3];
|
||||||
|
u64 flag_bits;
|
||||||
|
u32 content_owner_infos_offset;
|
||||||
|
u32 content_owner_infos_size;
|
||||||
|
u32 save_data_owner_infos_offset;
|
||||||
|
u32 save_data_owner_infos_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AccessControlDescriptor {
|
||||||
|
u8 version;
|
||||||
|
u8 content_owner_id_count;
|
||||||
|
u8 save_data_owner_id_count;
|
||||||
|
u8 reserved;
|
||||||
|
u64 flag_bits;
|
||||||
|
u64 content_owner_id_min;
|
||||||
|
u64 content_owner_id_max;
|
||||||
|
u64 save_data_owner_id_min;
|
||||||
|
u64 save_data_owner_id_max;
|
||||||
|
// u64 content_owner_ids[ContentOwnerIdCount];
|
||||||
|
// u64 save_data_owner_ids[SaveDataOwnerIdCount];
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
static_assert(std::is_trivially_copyable_v<AccessControlDataHeader>,
|
||||||
|
"Data type must be trivially copyable.");
|
||||||
|
static_assert(std::is_trivially_copyable_v<AccessControlDescriptor>,
|
||||||
|
"Data type must be trivially copyable.");
|
||||||
|
|
||||||
|
static constexpr u64 AllFlagBitsMask = ~static_cast<u64>(0);
|
||||||
|
static constexpr u64 DebugFlagDisableMask =
|
||||||
|
AllFlagBitsMask & ~Common::ToUnderlying(AccessControlBits::Bits::Debug);
|
||||||
|
|
||||||
|
public:
|
||||||
|
AccessControl(const void* data, s64 data_size, const void* desc, s64 desc_size);
|
||||||
|
AccessControl(const void* data, s64 data_size, const void* desc, s64 desc_size, u64 flag_mask);
|
||||||
|
~AccessControl();
|
||||||
|
|
||||||
|
bool HasContentOwnerId(u64 owner_id) const;
|
||||||
|
Accessibility GetAccessibilitySaveDataOwnedBy(u64 owner_id) const;
|
||||||
|
|
||||||
|
void ListContentOwnerId(s32* out_count, u64* out_owner_ids, s32 offset, s32 count) const;
|
||||||
|
void ListSaveDataOwnedId(s32* out_count, u64* out_owner_ids, s32 offset, s32 count) const;
|
||||||
|
|
||||||
|
Accessibility GetAccessibilityFor(AccessibilityType type) const;
|
||||||
|
bool CanCall(OperationType type) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
using ContentOwnerInfoList = Common::IntrusiveListBaseTraits<ContentOwnerInfo>::ListType;
|
||||||
|
using SaveDataOwnerInfoList = Common::IntrusiveListBaseTraits<SaveDataOwnerInfo>::ListType;
|
||||||
|
|
||||||
|
std::optional<AccessControlBits> m_flag_bits;
|
||||||
|
ContentOwnerInfoList m_content_owner_infos;
|
||||||
|
SaveDataOwnerInfoList m_save_data_owner_infos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
u64 GetRawFlagBits() const {
|
||||||
|
return m_flag_bits.value().GetValue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
268
src/core/file_sys/fssrv/impl/fssrv_access_control_bits.h
Normal file
268
src/core/file_sys/fssrv/impl/fssrv_access_control_bits.h
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/enum_util.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
#define YUZU_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(HANDLER, _NS_) \
|
||||||
|
HANDLER(CanAbandonAccessFailure, _NS_::AccessFailureResolution) \
|
||||||
|
HANDLER(CanChallengeCardExistence, _NS_::GameCard) \
|
||||||
|
HANDLER(CanControlMmcPatrol, _NS_::None) \
|
||||||
|
HANDLER(CanCorruptSaveData, _NS_::Debug, _NS_::CorruptSaveData) \
|
||||||
|
HANDLER(CanCorruptSystemSaveData, _NS_::CorruptSaveData, _NS_::SaveDataManagement, \
|
||||||
|
_NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanCreateOthersSystemSaveData, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanCreateOwnSaveData, _NS_::CreateOwnSaveData) \
|
||||||
|
HANDLER(CanCreateSaveData, _NS_::CreateSaveData, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanCreateSaveDataWithHashSalt, _NS_::None) \
|
||||||
|
HANDLER(CanCreateSystemSaveData, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanDebugSaveData, _NS_::Debug, _NS_::SaveDataForDebug) \
|
||||||
|
HANDLER(CanDeleteOwnSaveData, _NS_::CreateOwnSaveData) \
|
||||||
|
HANDLER(CanDeleteSaveData, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanDeleteSystemSaveData, _NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp, \
|
||||||
|
_NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanEraseMmc, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanExtendOthersSystemSaveData, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanExtendOwnSaveData, _NS_::CreateOwnSaveData) \
|
||||||
|
HANDLER(CanExtendSaveData, _NS_::CreateSaveData, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanExtendSystemSaveData, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanFillBis, _NS_::Debug, _NS_::FillBis) \
|
||||||
|
HANDLER(CanFinalizeGameCardDriver, _NS_::GameCardPrivate) \
|
||||||
|
HANDLER(CanFindOwnSaveDataWithFilter, _NS_::CreateOwnSaveData) \
|
||||||
|
HANDLER(CanFormatSdCard, _NS_::FormatSdCard) \
|
||||||
|
HANDLER(CanGetAccessFailureDetectionEvent, _NS_::AccessFailureResolution) \
|
||||||
|
HANDLER(CanGetGameCardAsicInfo, _NS_::GameCardPrivate) \
|
||||||
|
HANDLER(CanGetGameCardDeviceCertificate, _NS_::GameCard) \
|
||||||
|
HANDLER(CanGetGameCardIdSet, _NS_::GameCard) \
|
||||||
|
HANDLER(CanGetRightsId, _NS_::GetRightsId) \
|
||||||
|
HANDLER(CanGetSaveDataCommitId, _NS_::SaveDataTransferVersion2, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanInvalidateBisCache, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanIsAccessFailureDetected, _NS_::AccessFailureResolution) \
|
||||||
|
HANDLER(CanListAccessibleSaveDataOwnerId, _NS_::SaveDataTransferVersion2, \
|
||||||
|
_NS_::SaveDataTransfer, _NS_::CreateSaveData) \
|
||||||
|
HANDLER(CanMountAllBaseFileSystemRead, _NS_::None) \
|
||||||
|
HANDLER(CanMountAllBaseFileSystemWrite, _NS_::None) \
|
||||||
|
HANDLER(CanMountApplicationPackageRead, _NS_::ContentManager, _NS_::ApplicationInfo) \
|
||||||
|
HANDLER(CanMountBisCalibrationFileRead, _NS_::BisAllRaw, _NS_::Calibration) \
|
||||||
|
HANDLER(CanMountBisCalibrationFileWrite, _NS_::BisAllRaw, _NS_::Calibration) \
|
||||||
|
HANDLER(CanMountBisSafeModeRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSafeModeWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSystemProperEncryptionRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSystemProperEncryptionWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSystemProperPartitionRead, _NS_::BisFileSystem, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSystemProperPartitionWrite, _NS_::BisFileSystem, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSystemRead, _NS_::BisFileSystem, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisSystemWrite, _NS_::BisFileSystem, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisUserRead, _NS_::BisFileSystem, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountBisUserWrite, _NS_::BisFileSystem, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanMountCloudBackupWorkStorageRead, _NS_::SaveDataTransferVersion2) \
|
||||||
|
HANDLER(CanMountCloudBackupWorkStorageWrite, _NS_::SaveDataTransferVersion2) \
|
||||||
|
HANDLER(CanMountContentControlRead, _NS_::ContentManager, _NS_::ApplicationInfo) \
|
||||||
|
HANDLER(CanMountContentDataRead, _NS_::ContentManager, _NS_::ApplicationInfo) \
|
||||||
|
HANDLER(CanMountContentManualRead, _NS_::ContentManager, _NS_::ApplicationInfo) \
|
||||||
|
HANDLER(CanMountContentMetaRead, _NS_::ContentManager, _NS_::ApplicationInfo) \
|
||||||
|
HANDLER(CanMountContentStorageRead, _NS_::ContentManager) \
|
||||||
|
HANDLER(CanMountContentStorageWrite, _NS_::ContentManager) \
|
||||||
|
HANDLER(CanMountCustomStorage0Read, _NS_::None) \
|
||||||
|
HANDLER(CanMountCustomStorage0Write, _NS_::None) \
|
||||||
|
HANDLER(CanMountDeviceSaveDataRead, _NS_::DeviceSaveData, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanMountDeviceSaveDataWrite, _NS_::DeviceSaveData, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanMountGameCardRead, _NS_::GameCard) \
|
||||||
|
HANDLER(CanMountHostRead, _NS_::Debug, _NS_::Host) \
|
||||||
|
HANDLER(CanMountHostWrite, _NS_::Debug, _NS_::Host) \
|
||||||
|
HANDLER(CanMountImageAndVideoStorageRead, _NS_::ImageManager) \
|
||||||
|
HANDLER(CanMountImageAndVideoStorageWrite, _NS_::ImageManager) \
|
||||||
|
HANDLER(CanMountLogoRead, _NS_::ContentManager, _NS_::ApplicationInfo) \
|
||||||
|
HANDLER(CanMountOthersSaveDataRead, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanMountOthersSaveDataWrite, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanMountOthersSystemSaveDataRead, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanMountOthersSystemSaveDataWrite, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanMountRegisteredUpdatePartitionRead, _NS_::SystemUpdate) \
|
||||||
|
HANDLER(CanMountSaveDataStorageRead, _NS_::None) \
|
||||||
|
HANDLER(CanMountSaveDataStorageWrite, _NS_::None) \
|
||||||
|
HANDLER(CanMountSdCardRead, _NS_::Debug, _NS_::SdCard) \
|
||||||
|
HANDLER(CanMountSdCardWrite, _NS_::Debug, _NS_::SdCard) \
|
||||||
|
HANDLER(CanMountSystemDataPrivateRead, _NS_::SystemData, _NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanMountSystemSaveDataRead, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanMountSystemSaveDataWrite, _NS_::SaveDataBackUp, _NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanMountTemporaryDirectoryRead, _NS_::Debug) \
|
||||||
|
HANDLER(CanMountTemporaryDirectoryWrite, _NS_::Debug) \
|
||||||
|
HANDLER(CanNotifySystemDataUpdateEvent, _NS_::SystemUpdate) \
|
||||||
|
HANDLER(CanOpenAccessFailureDetectionEventNotifier, _NS_::AccessFailureResolution) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part1Read, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part1Write, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part2Read, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part2Write, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part3Read, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part3Write, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part4Read, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part4Write, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part5Read, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part5Write, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part6Read, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootConfigAndPackage2Part6Write, _NS_::SystemUpdate, \
|
||||||
|
_NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootPartition1RootRead, _NS_::SystemUpdate, _NS_::BisAllRaw, \
|
||||||
|
_NS_::BootModeControl) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootPartition1RootWrite, _NS_::SystemUpdate, _NS_::BisAllRaw, \
|
||||||
|
_NS_::BootModeControl) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootPartition2RootRead, _NS_::SystemUpdate, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionBootPartition2RootWrite, _NS_::SystemUpdate, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionCalibrationBinaryRead, _NS_::BisAllRaw, _NS_::Calibration) \
|
||||||
|
HANDLER(CanOpenBisPartitionCalibrationBinaryWrite, _NS_::BisAllRaw, _NS_::Calibration) \
|
||||||
|
HANDLER(CanOpenBisPartitionCalibrationFileRead, _NS_::BisAllRaw, _NS_::Calibration) \
|
||||||
|
HANDLER(CanOpenBisPartitionCalibrationFileWrite, _NS_::BisAllRaw, _NS_::Calibration) \
|
||||||
|
HANDLER(CanOpenBisPartitionSafeModeRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSafeModeWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSystemProperEncryptionRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSystemProperEncryptionWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSystemProperPartitionRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSystemProperPartitionWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSystemRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionSystemWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionUserDataRootRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionUserDataRootWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionUserRead, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisPartitionUserWrite, _NS_::BisAllRaw) \
|
||||||
|
HANDLER(CanOpenBisWiper, _NS_::ContentManager) \
|
||||||
|
HANDLER(CanOpenDataStorageByPath, _NS_::None) \
|
||||||
|
HANDLER(CanOpenGameCardDetectionEventNotifier, _NS_::DeviceDetection, _NS_::GameCardRaw, \
|
||||||
|
_NS_::GameCard) \
|
||||||
|
HANDLER(CanOpenGameCardStorageRead, _NS_::GameCardRaw) \
|
||||||
|
HANDLER(CanOpenGameCardStorageWrite, _NS_::GameCardRaw) \
|
||||||
|
HANDLER(CanOpenOwnSaveDataTransferProhibiter, _NS_::CreateOwnSaveData) \
|
||||||
|
HANDLER(CanOpenSaveDataInfoReader, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanOpenSaveDataInfoReaderForInternal, _NS_::SaveDataManagement) \
|
||||||
|
HANDLER(CanOpenSaveDataInfoReaderForSystem, _NS_::SystemSaveDataManagement, \
|
||||||
|
_NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanOpenSaveDataInternalStorageRead, _NS_::None) \
|
||||||
|
HANDLER(CanOpenSaveDataInternalStorageWrite, _NS_::None) \
|
||||||
|
HANDLER(CanOpenSaveDataMetaFile, _NS_::SaveDataMeta) \
|
||||||
|
HANDLER(CanOpenSaveDataMover, _NS_::MoveCacheStorage) \
|
||||||
|
HANDLER(CanOpenSaveDataTransferManager, _NS_::SaveDataTransfer) \
|
||||||
|
HANDLER(CanOpenSaveDataTransferManagerForRepair, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanOpenSaveDataTransferManagerForSaveDataRepair, _NS_::SaveDataTransferVersion2) \
|
||||||
|
HANDLER(CanOpenSaveDataTransferManagerForSaveDataRepairTool, _NS_::None) \
|
||||||
|
HANDLER(CanOpenSaveDataTransferManagerVersion2, _NS_::SaveDataTransferVersion2) \
|
||||||
|
HANDLER(CanOpenSaveDataTransferProhibiter, _NS_::SaveDataTransferVersion2, \
|
||||||
|
_NS_::CreateSaveData) \
|
||||||
|
HANDLER(CanOpenSdCardDetectionEventNotifier, _NS_::DeviceDetection, _NS_::SdCard) \
|
||||||
|
HANDLER(CanOpenSdCardStorageRead, _NS_::Debug, _NS_::SdCard) \
|
||||||
|
HANDLER(CanOpenSdCardStorageWrite, _NS_::Debug, _NS_::SdCard) \
|
||||||
|
HANDLER(CanOpenSystemDataUpdateEventNotifier, _NS_::SystemData, _NS_::SystemSaveData) \
|
||||||
|
HANDLER(CanOverrideSaveDataTransferTokenSignVerificationKey, _NS_::None) \
|
||||||
|
HANDLER(CanQuerySaveDataInternalStorageTotalSize, _NS_::SaveDataTransfer) \
|
||||||
|
HANDLER(CanReadOwnSaveDataFileSystemExtraData, _NS_::CreateOwnSaveData) \
|
||||||
|
HANDLER(CanReadSaveDataFileSystemExtraData, _NS_::SystemSaveDataManagement, \
|
||||||
|
_NS_::SaveDataManagement, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanRegisterExternalKey, _NS_::RegisterExternalKey) \
|
||||||
|
HANDLER(CanRegisterProgramIndexMapInfo, _NS_::RegisterProgramIndexMapInfo) \
|
||||||
|
HANDLER(CanRegisterUpdatePartition, _NS_::RegisterUpdatePartition) \
|
||||||
|
HANDLER(CanResolveAccessFailure, _NS_::AccessFailureResolution) \
|
||||||
|
HANDLER(CanSetCurrentPosixTime, _NS_::SetTime) \
|
||||||
|
HANDLER(CanSetDebugConfiguration, _NS_::None) \
|
||||||
|
HANDLER(CanSetEncryptionSeed, _NS_::ContentManager) \
|
||||||
|
HANDLER(CanSetGlobalAccessLogMode, _NS_::SettingsControl) \
|
||||||
|
HANDLER(CanSetSdCardAccessibility, _NS_::SdCard) \
|
||||||
|
HANDLER(CanSetSpeedEmulationMode, _NS_::SettingsControl) \
|
||||||
|
HANDLER(CanSimulateDevice, _NS_::Debug) \
|
||||||
|
HANDLER(CanVerifySaveData, _NS_::SaveDataManagement, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanWriteSaveDataFileSystemExtraDataAll, _NS_::None) \
|
||||||
|
HANDLER(CanWriteSaveDataFileSystemExtraDataCommitId, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanWriteSaveDataFileSystemExtraDataFlags, _NS_::SaveDataTransferVersion2, \
|
||||||
|
_NS_::SystemSaveDataManagement, _NS_::SaveDataBackUp) \
|
||||||
|
HANDLER(CanWriteSaveDataFileSystemExtraDataTimeStamp, _NS_::SaveDataBackUp)
|
||||||
|
|
||||||
|
class AccessControlBits {
|
||||||
|
public:
|
||||||
|
enum class Bits : u64 {
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
ApplicationInfo = UINT64_C(1) << 0,
|
||||||
|
BootModeControl = UINT64_C(1) << 1,
|
||||||
|
Calibration = UINT64_C(1) << 2,
|
||||||
|
SystemSaveData = UINT64_C(1) << 3,
|
||||||
|
GameCard = UINT64_C(1) << 4,
|
||||||
|
SaveDataBackUp = UINT64_C(1) << 5,
|
||||||
|
SaveDataManagement = UINT64_C(1) << 6,
|
||||||
|
BisAllRaw = UINT64_C(1) << 7,
|
||||||
|
GameCardRaw = UINT64_C(1) << 8,
|
||||||
|
GameCardPrivate = UINT64_C(1) << 9,
|
||||||
|
SetTime = UINT64_C(1) << 10,
|
||||||
|
ContentManager = UINT64_C(1) << 11,
|
||||||
|
ImageManager = UINT64_C(1) << 12,
|
||||||
|
CreateSaveData = UINT64_C(1) << 13,
|
||||||
|
SystemSaveDataManagement = UINT64_C(1) << 14,
|
||||||
|
BisFileSystem = UINT64_C(1) << 15,
|
||||||
|
SystemUpdate = UINT64_C(1) << 16,
|
||||||
|
SaveDataMeta = UINT64_C(1) << 17,
|
||||||
|
DeviceSaveData = UINT64_C(1) << 18,
|
||||||
|
SettingsControl = UINT64_C(1) << 19,
|
||||||
|
SystemData = UINT64_C(1) << 20,
|
||||||
|
SdCard = UINT64_C(1) << 21,
|
||||||
|
Host = UINT64_C(1) << 22,
|
||||||
|
FillBis = UINT64_C(1) << 23,
|
||||||
|
CorruptSaveData = UINT64_C(1) << 24,
|
||||||
|
SaveDataForDebug = UINT64_C(1) << 25,
|
||||||
|
FormatSdCard = UINT64_C(1) << 26,
|
||||||
|
GetRightsId = UINT64_C(1) << 27,
|
||||||
|
RegisterExternalKey = UINT64_C(1) << 28,
|
||||||
|
RegisterUpdatePartition = UINT64_C(1) << 29,
|
||||||
|
SaveDataTransfer = UINT64_C(1) << 30,
|
||||||
|
DeviceDetection = UINT64_C(1) << 31,
|
||||||
|
AccessFailureResolution = UINT64_C(1) << 32,
|
||||||
|
SaveDataTransferVersion2 = UINT64_C(1) << 33,
|
||||||
|
RegisterProgramIndexMapInfo = UINT64_C(1) << 34,
|
||||||
|
CreateOwnSaveData = UINT64_C(1) << 35,
|
||||||
|
MoveCacheStorage = UINT64_C(1) << 36,
|
||||||
|
|
||||||
|
Debug = UINT64_C(1) << 62,
|
||||||
|
FullPermission = UINT64_C(1) << 63
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr u64 CombineBits(Bits b) {
|
||||||
|
return Common::ToUnderlying(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
static constexpr u64 CombineBits(Bits b, Args... args) {
|
||||||
|
return CombineBits(b) | CombineBits(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const u64 m_value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
constexpr AccessControlBits(u64 v) : m_value(v) {}
|
||||||
|
|
||||||
|
constexpr u64 GetValue() const {
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_ACCESS_GETTER(name, ...) \
|
||||||
|
constexpr bool name() const { \
|
||||||
|
constexpr u64 Mask = CombineBits(Bits::FullPermission, ##__VA_ARGS__); \
|
||||||
|
return (m_value & Mask); \
|
||||||
|
}
|
||||||
|
|
||||||
|
YUZU_FSSRV_FOR_EACH_ACCESS_CONTROL_CAPABILITY(DEFINE_ACCESS_GETTER, Bits)
|
||||||
|
|
||||||
|
#undef DEFINE_ACCESS_GETTER
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
@ -0,0 +1,155 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/intrusive_list.h"
|
||||||
|
#include "core/file_sys/errors.h"
|
||||||
|
#include "core/file_sys/fs_program_index_map_info.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
struct ProgramIndexMapInfoEntry : public Common::IntrusiveListBaseNode<ProgramIndexMapInfoEntry> {
|
||||||
|
u64 program_id;
|
||||||
|
u64 base_program_id;
|
||||||
|
u8 program_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProgramIndexMapInfoManager {
|
||||||
|
YUZU_NON_COPYABLE(ProgramIndexMapInfoManager);
|
||||||
|
YUZU_NON_MOVEABLE(ProgramIndexMapInfoManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using ProgramIndexMapInfoList =
|
||||||
|
Common::IntrusiveListBaseTraits<ProgramIndexMapInfoEntry>::ListType;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProgramIndexMapInfoList m_list;
|
||||||
|
mutable std::mutex m_mutex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProgramIndexMapInfoManager() : m_list(), m_mutex() {}
|
||||||
|
|
||||||
|
void Clear() {
|
||||||
|
// Acquire exclusive access to the map
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Actually clear
|
||||||
|
this->ClearImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetProgramCount() const {
|
||||||
|
// Acquire exclusive access to the map
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Get the size
|
||||||
|
return m_list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ProgramIndexMapInfo> Get(const u64& program_id) const {
|
||||||
|
// Acquire exclusive access to the map
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Get the entry from the map
|
||||||
|
return this->GetImpl(
|
||||||
|
[&](const ProgramIndexMapInfoEntry& entry) { return entry.program_id == program_id; });
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetProgramId(const u64& program_id, u8 program_index) const {
|
||||||
|
// Acquire exclusive access to the map
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Get the program info for the desired program id
|
||||||
|
const auto base_info = this->GetImpl(
|
||||||
|
[&](const ProgramIndexMapInfoEntry& entry) { return entry.program_id == program_id; });
|
||||||
|
|
||||||
|
// Check that an entry exists for the program id
|
||||||
|
if (!base_info.has_value()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a program info which matches the same base program with the desired index
|
||||||
|
const auto target_info = this->GetImpl([&](const ProgramIndexMapInfoEntry& entry) {
|
||||||
|
return entry.base_program_id == base_info->base_program_id &&
|
||||||
|
entry.program_index == program_index;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Return the desired program id
|
||||||
|
if (target_info.has_value()) {
|
||||||
|
return target_info->program_id;
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Reset(const ProgramIndexMapInfo* infos, int count) {
|
||||||
|
// Acquire exclusive access to the map
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Clear the map, and ensure we remain clear if we fail after this point
|
||||||
|
this->ClearImpl();
|
||||||
|
ON_RESULT_FAILURE {
|
||||||
|
this->ClearImpl();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add each info to the list
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
// Allocate new entry
|
||||||
|
auto* entry = new ProgramIndexMapInfoEntry;
|
||||||
|
R_UNLESS(entry != nullptr, ResultAllocationMemoryFailedNew);
|
||||||
|
|
||||||
|
// Copy over the info
|
||||||
|
entry->program_id = infos[i].program_id;
|
||||||
|
entry->base_program_id = infos[i].base_program_id;
|
||||||
|
entry->program_index = infos[i].program_index;
|
||||||
|
|
||||||
|
// Add to the list
|
||||||
|
m_list.push_back(*entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We successfully imported the map
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ClearImpl() {
|
||||||
|
// Delete all entries
|
||||||
|
while (!m_list.empty()) {
|
||||||
|
// Get the first entry
|
||||||
|
ProgramIndexMapInfoEntry* front = std::addressof(*m_list.begin());
|
||||||
|
|
||||||
|
// Erase it from the list
|
||||||
|
m_list.erase(m_list.iterator_to(*front));
|
||||||
|
|
||||||
|
// Delete the entry
|
||||||
|
delete front;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
std::optional<ProgramIndexMapInfo> GetImpl(F f) const {
|
||||||
|
// Try to find an entry matching the predicate
|
||||||
|
std::optional<ProgramIndexMapInfo> match = std::nullopt;
|
||||||
|
|
||||||
|
for (const auto& entry : m_list) {
|
||||||
|
// If the predicate matches, we want to return the relevant info
|
||||||
|
if (f(entry)) {
|
||||||
|
match.emplace();
|
||||||
|
|
||||||
|
match->program_id = entry.program_id;
|
||||||
|
match->base_program_id = entry.base_program_id;
|
||||||
|
match->program_index = entry.program_index;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
128
src/core/file_sys/fssrv/impl/fssrv_program_info.cpp
Normal file
128
src/core/file_sys/fssrv/impl/fssrv_program_info.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include "common/typed_storage.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_info.h"
|
||||||
|
#include "core/hle/kernel/svc.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constinit std::aligned_storage<0x80>::type g_static_buffer_for_program_info_for_initial_process =
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class StaticAllocatorForProgramInfoForInitialProcess : public std::allocator<T> {
|
||||||
|
public:
|
||||||
|
StaticAllocatorForProgramInfoForInitialProcess() {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
StaticAllocatorForProgramInfoForInitialProcess(
|
||||||
|
const StaticAllocatorForProgramInfoForInitialProcess<U>&) {}
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
struct rebind {
|
||||||
|
using other = StaticAllocatorForProgramInfoForInitialProcess<U>;
|
||||||
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] T* allocate(::std::size_t n) {
|
||||||
|
ASSERT(sizeof(T) * n <= sizeof(g_static_buffer_for_program_info_for_initial_process));
|
||||||
|
return reinterpret_cast<T*>(
|
||||||
|
std::addressof(g_static_buffer_for_program_info_for_initial_process));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate([[maybe_unused]] T* p, [[maybe_unused]] std::size_t n) {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr const u32 FileAccessControlForInitialProgram[0x1C / sizeof(u32)] = {
|
||||||
|
0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
|
||||||
|
constexpr const u32 FileAccessControlDescForInitialProgram[0x2C / sizeof(u32)] = {
|
||||||
|
0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF,
|
||||||
|
0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||||
|
|
||||||
|
constinit bool g_initialized = false;
|
||||||
|
|
||||||
|
constinit u64 g_initial_process_id_min = 0;
|
||||||
|
constinit u64 g_initial_process_id_max = 0;
|
||||||
|
|
||||||
|
constinit u64 g_current_process_id = 0;
|
||||||
|
|
||||||
|
void InitializeInitialAndCurrentProcessId(Core::System& system) {
|
||||||
|
using namespace Kernel;
|
||||||
|
|
||||||
|
if (!g_initialized) {
|
||||||
|
// Get initial process id range
|
||||||
|
ASSERT(Svc::GetSystemInfo(system, std::addressof(g_initial_process_id_min),
|
||||||
|
Svc::SystemInfoType::InitialProcessIdRange, Svc::InvalidHandle,
|
||||||
|
static_cast<u64>(Svc::InitialProcessIdRangeInfo::Minimum)) ==
|
||||||
|
ResultSuccess);
|
||||||
|
ASSERT(Svc::GetSystemInfo(system, std::addressof(g_initial_process_id_max),
|
||||||
|
Svc::SystemInfoType::InitialProcessIdRange, Svc::InvalidHandle,
|
||||||
|
static_cast<u64>(Svc::InitialProcessIdRangeInfo::Maximum)) ==
|
||||||
|
ResultSuccess);
|
||||||
|
|
||||||
|
ASSERT(0 < g_initial_process_id_min);
|
||||||
|
ASSERT(g_initial_process_id_min <= g_initial_process_id_max);
|
||||||
|
|
||||||
|
// Get current procss id
|
||||||
|
ASSERT(Svc::GetProcessId(system, std::addressof(g_current_process_id),
|
||||||
|
Svc::PseudoHandle::CurrentProcess) == ResultSuccess);
|
||||||
|
|
||||||
|
/* Set initialized. */
|
||||||
|
g_initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::shared_ptr<ProgramInfo> ProgramInfo::GetProgramInfoForInitialProcess() {
|
||||||
|
class ProgramInfoHelper : public ProgramInfo {
|
||||||
|
public:
|
||||||
|
ProgramInfoHelper(const void* data, s64 data_size, const void* desc, s64 desc_size)
|
||||||
|
: ProgramInfo(data, data_size, desc, desc_size) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static constinit Common::TypedStorage<std::shared_ptr<ProgramInfo>>
|
||||||
|
s_fls_storage_for_s_initial_program_info{};
|
||||||
|
static constinit bool s_fls_initialized_s_initial_program_info = false;
|
||||||
|
static std::mutex s_fls_init_lock_s_initial_program_info{};
|
||||||
|
if (!(s_fls_initialized_s_initial_program_info)) {
|
||||||
|
std::scoped_lock sl_fls_for_s_initial_program_info{s_fls_init_lock_s_initial_program_info};
|
||||||
|
if (!(s_fls_initialized_s_initial_program_info)) {
|
||||||
|
new (Common::Impl::GetPointerForConstructAt(s_fls_storage_for_s_initial_program_info))
|
||||||
|
std::shared_ptr<ProgramInfo>(std::allocate_shared<ProgramInfoHelper>(
|
||||||
|
StaticAllocatorForProgramInfoForInitialProcess<char>{},
|
||||||
|
FileAccessControlForInitialProgram, sizeof(FileAccessControlForInitialProgram),
|
||||||
|
FileAccessControlDescForInitialProgram,
|
||||||
|
sizeof(FileAccessControlDescForInitialProgram)));
|
||||||
|
s_fls_initialized_s_initial_program_info = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::shared_ptr<ProgramInfo>& s_initial_program_info =
|
||||||
|
Common::GetReference(s_fls_storage_for_s_initial_program_info);
|
||||||
|
|
||||||
|
return s_initial_program_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInitialProgram(Core::System& system, u64 process_id) {
|
||||||
|
// Initialize/sanity check
|
||||||
|
InitializeInitialAndCurrentProcessId(system);
|
||||||
|
ASSERT(g_initial_process_id_min > 0);
|
||||||
|
|
||||||
|
// Check process id in range
|
||||||
|
return g_initial_process_id_min <= process_id && process_id <= g_initial_process_id_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCurrentProcess(Core::System& system, u64 process_id) {
|
||||||
|
// Initialize
|
||||||
|
InitializeInitialAndCurrentProcessId(system);
|
||||||
|
|
||||||
|
return process_id == g_current_process_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
65
src/core/file_sys/fssrv/impl/fssrv_program_info.h
Normal file
65
src/core/file_sys/fssrv/impl/fssrv_program_info.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_access_control.h"
|
||||||
|
#include "core/file_sys/romfs_factory.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
constexpr u64 InvalidProcessId = 0xffffffffffffffffULL;
|
||||||
|
|
||||||
|
class ProgramInfo {
|
||||||
|
private:
|
||||||
|
u64 m_process_id;
|
||||||
|
u64 m_program_id;
|
||||||
|
FileSys::StorageId m_storage_id;
|
||||||
|
AccessControl m_access_control;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProgramInfo(u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size,
|
||||||
|
const void* desc, s64 desc_size)
|
||||||
|
: m_process_id(process_id), m_access_control(data, data_size, desc, desc_size) {
|
||||||
|
m_program_id = program_id;
|
||||||
|
m_storage_id = static_cast<FileSys::StorageId>(storage_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Contains(u64 process_id) const {
|
||||||
|
return m_process_id == process_id;
|
||||||
|
}
|
||||||
|
u64 GetProcessId() const {
|
||||||
|
return m_process_id;
|
||||||
|
}
|
||||||
|
u64 GetProgramId() const {
|
||||||
|
return m_program_id;
|
||||||
|
}
|
||||||
|
FileSys::StorageId GetStorageId() const {
|
||||||
|
return m_storage_id;
|
||||||
|
}
|
||||||
|
AccessControl& GetAccessControl() {
|
||||||
|
return m_access_control;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<ProgramInfo> GetProgramInfoForInitialProcess();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const u64 InvalidProgramId = {};
|
||||||
|
ProgramInfo(const void* data, s64 data_size, const void* desc, s64 desc_size)
|
||||||
|
: m_process_id(InvalidProcessId), m_program_id(InvalidProgramId),
|
||||||
|
m_storage_id(static_cast<FileSys::StorageId>(0)),
|
||||||
|
m_access_control(data, data_size, desc, desc_size, std::numeric_limits<u64>::max()) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProgramInfoNode : public Common::IntrusiveListBaseNode<ProgramInfoNode> {
|
||||||
|
std::shared_ptr<ProgramInfo> program_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool IsInitialProgram(Core::System& system, u64 process_id);
|
||||||
|
bool IsCurrentProcess(Core::System& system, u64 process_id);
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
100
src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp
Normal file
100
src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/errors.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_registry_manager.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
ProgramRegistryManager::ProgramRegistryManager(Core::System& system_) : system{system_} {}
|
||||||
|
|
||||||
|
Result ProgramRegistryManager::RegisterProgram(u64 process_id, u64 program_id, u8 storage_id,
|
||||||
|
const void* data, s64 data_size, const void* desc,
|
||||||
|
s64 desc_size) {
|
||||||
|
// Allocate a new node
|
||||||
|
std::unique_ptr<ProgramInfoNode> new_node(new ProgramInfoNode());
|
||||||
|
R_UNLESS(new_node != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA);
|
||||||
|
|
||||||
|
// Create a new program info
|
||||||
|
{
|
||||||
|
// Allocate the new info
|
||||||
|
std::shared_ptr<ProgramInfo> new_info = std::make_shared<ProgramInfo>(
|
||||||
|
process_id, program_id, storage_id, data, data_size, desc, desc_size);
|
||||||
|
R_UNLESS(new_info != nullptr, ResultAllocationMemoryFailedInProgramRegistryManagerA);
|
||||||
|
|
||||||
|
// Set the info in the node
|
||||||
|
new_node->program_info = std::move(new_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire exclusive access to the registry
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Check that the process isn't already in the registry
|
||||||
|
for (const auto& node : m_program_info_list) {
|
||||||
|
R_UNLESS(!node.program_info->Contains(process_id), ResultInvalidArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the node to the registry
|
||||||
|
m_program_info_list.push_back(*new_node.release());
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryManager::UnregisterProgram(u64 process_id) {
|
||||||
|
// Acquire exclusive access to the registry
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Try to find and remove the process's node
|
||||||
|
for (auto& node : m_program_info_list) {
|
||||||
|
if (node.program_info->Contains(process_id)) {
|
||||||
|
m_program_info_list.erase(m_program_info_list.iterator_to(node));
|
||||||
|
delete std::addressof(node);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We couldn't find/unregister the process's node
|
||||||
|
R_THROW(ResultInvalidArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryManager::GetProgramInfo(std::shared_ptr<ProgramInfo>* out, u64 process_id) {
|
||||||
|
// Acquire exclusive access to the registry
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Check if we're getting permissions for an initial program
|
||||||
|
if (IsInitialProgram(system, process_id)) {
|
||||||
|
*out = ProgramInfo::GetProgramInfoForInitialProcess();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find a matching node
|
||||||
|
for (const auto& node : m_program_info_list) {
|
||||||
|
if (node.program_info->Contains(process_id)) {
|
||||||
|
*out = node.program_info;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We didn't find the program info
|
||||||
|
R_THROW(ResultProgramInfoNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ProgramRegistryManager::GetProgramInfoByProgramId(std::shared_ptr<ProgramInfo>* out,
|
||||||
|
u64 program_id) {
|
||||||
|
// Acquire exclusive access to the registry
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
// Find a matching node
|
||||||
|
for (const auto& node : m_program_info_list) {
|
||||||
|
if (node.program_info->GetProgramId() == program_id) {
|
||||||
|
*out = node.program_info;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We didn't find the program info
|
||||||
|
R_THROW(ResultProgramInfoNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
@ -0,0 +1,39 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include "common/common_funcs.h"
|
||||||
|
#include "common/intrusive_list.h"
|
||||||
|
#include "core/file_sys/fssrv/impl/fssrv_program_info.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
class ProgramRegistryManager {
|
||||||
|
YUZU_NON_COPYABLE(ProgramRegistryManager);
|
||||||
|
YUZU_NON_MOVEABLE(ProgramRegistryManager);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ProgramRegistryManager(Core::System& system_);
|
||||||
|
|
||||||
|
Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const void* data,
|
||||||
|
s64 data_size, const void* desc, s64 desc_size);
|
||||||
|
Result UnregisterProgram(u64 process_id);
|
||||||
|
|
||||||
|
Result GetProgramInfo(std::shared_ptr<ProgramInfo>* out, u64 process_id);
|
||||||
|
Result GetProgramInfoByProgramId(std::shared_ptr<ProgramInfo>* out, u64 program_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using ProgramInfoList = Common::IntrusiveListBaseTraits<ProgramInfoNode>::ListType;
|
||||||
|
|
||||||
|
ProgramInfoList m_program_info_list{};
|
||||||
|
mutable std::mutex m_mutex{};
|
||||||
|
Core::System& system;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
193
src/core/file_sys/fssrv/impl/fssrv_save_data_properties.h
Normal file
193
src/core/file_sys/fssrv/impl/fssrv_save_data_properties.h
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
// TODO: Properly credit LibHac before this gets merged
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/file_sys/savedata_factory.h"
|
||||||
|
|
||||||
|
namespace FileSys::FsSrv::Impl {
|
||||||
|
|
||||||
|
class SaveDataProperties {
|
||||||
|
public:
|
||||||
|
static constexpr s64 DefaultSaveDataBlockSize = 0x4000;
|
||||||
|
static constexpr s64 BcatSaveDataJournalSize = 0x200000;
|
||||||
|
|
||||||
|
static bool IsJournalingSupported(SaveDataFormatType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataFormatType::Normal:
|
||||||
|
return true;
|
||||||
|
case SaveDataFormatType::NoJournal:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsJournalingSupported(SaveDataType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return true;
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsMultiCommitSupported(SaveDataType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
return true;
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsSharedOpenNeeded(SaveDataType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return false;
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CanUseIndexerReservedArea(SaveDataType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
return true;
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsSystemSaveData(SaveDataType type) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
return true;
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsObsoleteSystemSaveData(const SaveDataInfo& info) {
|
||||||
|
constexpr std::array<u64, 2> ObsoleteSystemSaveDataIdList = {0x8000000000000060,
|
||||||
|
0x8000000000000075};
|
||||||
|
return std::find(ObsoleteSystemSaveDataIdList.begin(), ObsoleteSystemSaveDataIdList.end(),
|
||||||
|
info.save_id) != ObsoleteSystemSaveDataIdList.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsWipingNeededAtCleanUp(const SaveDataInfo& info) {
|
||||||
|
switch (info.type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
break;
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr std::array<u64, 28> SystemSaveDataIdWipingExceptionList = {
|
||||||
|
0x8000000000000040, 0x8000000000000041, 0x8000000000000043, 0x8000000000000044,
|
||||||
|
0x8000000000000045, 0x8000000000000046, 0x8000000000000047, 0x8000000000000048,
|
||||||
|
0x8000000000000049, 0x800000000000004A, 0x8000000000000070, 0x8000000000000071,
|
||||||
|
0x8000000000000072, 0x8000000000000074, 0x8000000000000076, 0x8000000000000077,
|
||||||
|
0x8000000000000090, 0x8000000000000091, 0x8000000000000092, 0x80000000000000B0,
|
||||||
|
0x80000000000000C1, 0x80000000000000C2, 0x8000000000000120, 0x8000000000000121,
|
||||||
|
0x8000000000000180, 0x8000000000010003, 0x8000000000010004};
|
||||||
|
|
||||||
|
return std::find(SystemSaveDataIdWipingExceptionList.begin(),
|
||||||
|
SystemSaveDataIdWipingExceptionList.end(),
|
||||||
|
info.save_id) == SystemSaveDataIdWipingExceptionList.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsValidSpaceIdForSaveDataMover(SaveDataType type, SaveDataSpaceId space_id) {
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
return false;
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return space_id == SaveDataSpaceId::NandUser || space_id == SaveDataSpaceId::SdCardUser;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsReconstructible(SaveDataType type, SaveDataSpaceId space_id) {
|
||||||
|
switch (space_id) {
|
||||||
|
case SaveDataSpaceId::NandSystem:
|
||||||
|
case SaveDataSpaceId::NandUser:
|
||||||
|
case SaveDataSpaceId::ProperSystem:
|
||||||
|
case SaveDataSpaceId::SafeMode:
|
||||||
|
switch (type) {
|
||||||
|
case SaveDataType::SystemSaveData:
|
||||||
|
case SaveDataType::SaveData:
|
||||||
|
case SaveDataType::DeviceSaveData:
|
||||||
|
return false;
|
||||||
|
case SaveDataType::BcatDeliveryCacheStorage:
|
||||||
|
case SaveDataType::TemporaryStorage:
|
||||||
|
case SaveDataType::CacheStorage:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case SaveDataSpaceId::SdCardSystem:
|
||||||
|
case SaveDataSpaceId::TemporaryStorage:
|
||||||
|
case SaveDataSpaceId::SdCardUser:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys::FsSrv::Impl
|
Loading…
Reference in New Issue
Block a user