diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp b/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp index 1bf5055da3..f7da4919fa 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp +++ b/src/core/file_sys/fssrv/fssrv_program_registry_impl.cpp @@ -5,7 +5,6 @@ #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 { @@ -15,7 +14,7 @@ constexpr u64 InvalidProcessIdProgramRegistry = 0xffffffffffffffffULL; ProgramRegistryImpl::ProgramRegistryImpl(Core::System& system_) : m_process_id(InvalidProcessIdProgramRegistry), system{system_}, service_impl{std::make_unique( - system, ProgramRegistryServiceImpl::Configuration{})} {} + system, initial_program_info, ProgramRegistryServiceImpl::Configuration{})} {} ProgramRegistryImpl::~ProgramRegistryImpl() {} @@ -25,7 +24,7 @@ Result ProgramRegistryImpl::RegisterProgram(u64 process_id, u64 program_id, u8 s const InBuffer desc, s64 desc_size) { // Check that we're allowed to register - R_UNLESS(FsSrv::Impl::IsInitialProgram(system, m_process_id), ResultPermissionDenied); + R_UNLESS(initial_program_info.IsInitialProgram(system, m_process_id), ResultPermissionDenied); // Check buffer sizes R_UNLESS(data.size() >= static_cast(data_size), ResultInvalidSize); @@ -38,7 +37,7 @@ Result ProgramRegistryImpl::RegisterProgram(u64 process_id, u64 program_id, u8 s Result ProgramRegistryImpl::UnregisterProgram(u64 process_id) { // Check that we're allowed to register - R_UNLESS(FsSrv::Impl::IsInitialProgram(system, m_process_id), ResultPermissionDenied); + R_UNLESS(initial_program_info.IsInitialProgram(system, m_process_id), ResultPermissionDenied); // Unregister the program R_RETURN(service_impl->UnregisterProgramInfo(process_id)); @@ -58,8 +57,9 @@ Result ProgramRegistryImpl::SetEnabledProgramVerification(bool enabled) { } void ProgramRegistryImpl::Reset() { + initial_program_info = {}; service_impl = std::make_unique( - system, ProgramRegistryServiceImpl::Configuration{}); + system, initial_program_info, ProgramRegistryServiceImpl::Configuration{}); } } // namespace FileSys::FsSrv diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_impl.h b/src/core/file_sys/fssrv/fssrv_program_registry_impl.h index dba7b2531a..e8650884de 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_impl.h +++ b/src/core/file_sys/fssrv/fssrv_program_registry_impl.h @@ -6,6 +6,7 @@ #include "common/common_funcs.h" #include "core/hle/result.h" #include "core/hle/service/cmif_types.h" +#include "core/file_sys/fssrv/impl/fssrv_program_info.h" namespace Core { class System; @@ -17,10 +18,6 @@ using namespace Service; class ProgramRegistryServiceImpl; -namespace Impl { -class ProgramInfo; -} - class ProgramRegistryImpl { YUZU_NON_COPYABLE(ProgramRegistryImpl); YUZU_NON_MOVEABLE(ProgramRegistryImpl); @@ -42,6 +39,7 @@ private: u64 m_process_id; Core::System& system; + Impl::InitialProgramInfo initial_program_info{}; std::unique_ptr service_impl; }; diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp b/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp index f757ffcf3f..8dcd4d61d3 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp +++ b/src/core/file_sys/fssrv/fssrv_program_registry_service.cpp @@ -8,8 +8,10 @@ namespace FileSys::FsSrv { ProgramRegistryServiceImpl::ProgramRegistryServiceImpl(Core::System& system_, + Impl::InitialProgramInfo& program_info, const Configuration& cfg) - : m_config(cfg), m_registry_manager(std::make_unique(system_)), + : m_config(cfg), + m_registry_manager(std::make_unique(system_, program_info)), m_index_map_info_manager(std::make_unique()) {} Result ProgramRegistryServiceImpl::RegisterProgramInfo(u64 process_id, u64 program_id, diff --git a/src/core/file_sys/fssrv/fssrv_program_registry_service.h b/src/core/file_sys/fssrv/fssrv_program_registry_service.h index 50bcec0933..07b444504a 100644 --- a/src/core/file_sys/fssrv/fssrv_program_registry_service.h +++ b/src/core/file_sys/fssrv/fssrv_program_registry_service.h @@ -17,13 +17,15 @@ namespace FileSys::FsSrv { namespace Impl { class ProgramInfo; +class InitialProgramInfo; } // namespace Impl class ProgramRegistryServiceImpl { public: struct Configuration {}; - ProgramRegistryServiceImpl(Core::System& system_, const Configuration& cfg); + ProgramRegistryServiceImpl(Core::System& system_, + Impl::InitialProgramInfo& program_info, 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); diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_info.cpp b/src/core/file_sys/fssrv/impl/fssrv_program_info.cpp index fbffcea568..9f88e628d2 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_info.cpp +++ b/src/core/file_sys/fssrv/impl/fssrv_program_info.cpp @@ -10,82 +10,63 @@ namespace FileSys::FsSrv::Impl { -namespace { - -constinit bool s_fls_initialized_s_initial_program_info = false; - -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(Svc::InitialProcessIdRangeInfo::Minimum)) == - ResultSuccess); - ASSERT(Svc::GetSystemInfo(system, std::addressof(g_initial_process_id_max), - Svc::SystemInfoType::InitialProcessIdRange, Svc::InvalidHandle, - static_cast(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::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) {} - }; - +std::shared_ptr InitialProgramInfo::GetProgramInfoForInitialProcess() { constexpr const std::array FileAccessControlForInitialProgram = { 0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000}; constexpr const std::array FileAccessControlDescForInitialProgram = { 0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF}; - // if (!s_fls_initialized_s_initial_program_info) { - std::shared_ptr s_initial_program_info = std::make_shared( - FileAccessControlForInitialProgram.data(), sizeof(FileAccessControlForInitialProgram), - FileAccessControlDescForInitialProgram.data(), - sizeof(FileAccessControlDescForInitialProgram)); - //} + if (!initial_program_info) { + initial_program_info = std::make_shared( + FileAccessControlForInitialProgram.data(), sizeof(FileAccessControlForInitialProgram), + FileAccessControlDescForInitialProgram.data(), + sizeof(FileAccessControlDescForInitialProgram)); + } - return s_initial_program_info; + return initial_program_info; } -bool IsInitialProgram(Core::System& system, u64 process_id) { +void InitialProgramInfo::InitializeInitialAndCurrentProcessId(Core::System& system) { + using namespace Kernel; + + if (!initialized_ids) { + // Get initial process id range + ASSERT(Svc::GetSystemInfo(system, std::addressof(initial_process_id_min), + Svc::SystemInfoType::InitialProcessIdRange, Svc::InvalidHandle, + static_cast(Svc::InitialProcessIdRangeInfo::Minimum)) == + ResultSuccess); + ASSERT(Svc::GetSystemInfo(system, std::addressof(initial_process_id_max), + Svc::SystemInfoType::InitialProcessIdRange, Svc::InvalidHandle, + static_cast(Svc::InitialProcessIdRangeInfo::Maximum)) == + ResultSuccess); + + ASSERT(0 < initial_process_id_min); + ASSERT(initial_process_id_min <= initial_process_id_max); + + // Get current procss id + ASSERT(Svc::GetProcessId(system, std::addressof(current_process_id), + Svc::PseudoHandle::CurrentProcess) == ResultSuccess); + + // Set initialized + initialized_ids = true; + } +} + +bool InitialProgramInfo::IsInitialProgram(Core::System& system, u64 process_id) { // Initialize/sanity check InitializeInitialAndCurrentProcessId(system); - ASSERT(g_initial_process_id_min > 0); + ASSERT(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; + return initial_process_id_min <= process_id && process_id <= initial_process_id_max; } -bool IsCurrentProcess(Core::System& system, u64 process_id) { +bool InitialProgramInfo::IsCurrentProcess(Core::System& system, u64 process_id) { // Initialize InitializeInitialAndCurrentProcessId(system); - return process_id == g_current_process_id; + return process_id == current_process_id; } } // namespace FileSys::FsSrv::Impl diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_info.h b/src/core/file_sys/fssrv/impl/fssrv_program_info.h index 7ef8bf9a5a..ae26a49b05 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_info.h +++ b/src/core/file_sys/fssrv/impl/fssrv_program_info.h @@ -29,6 +29,11 @@ public: m_storage_id = static_cast(storage_id); } + ProgramInfo(const void* data, s64 data_size, const void* desc, s64 desc_size) + : m_process_id(InvalidProcessId), m_program_id(0), + m_storage_id(static_cast(0)), + m_access_control(data, data_size, desc, desc_size, std::numeric_limits::max()) {} + bool Contains(u64 process_id) const { return m_process_id == process_id; } @@ -44,21 +49,29 @@ public: AccessControl& GetAccessControl() { return m_access_control; } - - static std::shared_ptr GetProgramInfoForInitialProcess(); - -private: - ProgramInfo(const void* data, s64 data_size, const void* desc, s64 desc_size) - : m_process_id(InvalidProcessId), m_program_id(0), - m_storage_id(static_cast(0)), - m_access_control(data, data_size, desc, desc_size, std::numeric_limits::max()) {} }; struct ProgramInfoNode : public Common::IntrusiveListBaseNode { std::shared_ptr program_info; }; -bool IsInitialProgram(Core::System& system, u64 process_id); -bool IsCurrentProcess(Core::System& system, u64 process_id); +class InitialProgramInfo { +private: + void InitializeInitialAndCurrentProcessId(Core::System& system); + +public: + std::shared_ptr GetProgramInfoForInitialProcess(); + bool IsInitialProgram(Core::System& system, u64 process_id); + bool IsCurrentProcess(Core::System& system, u64 process_id); + +private: + std::shared_ptr initial_program_info = nullptr; + + bool initialized_ids = false; + + u64 initial_process_id_min = 0; + u64 initial_process_id_max = 0; + u64 current_process_id = 0; +}; } // namespace FileSys::FsSrv::Impl diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp index f060abfa68..7120e4b8b5 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp +++ b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.cpp @@ -7,7 +7,9 @@ namespace FileSys::FsSrv::Impl { -ProgramRegistryManager::ProgramRegistryManager(Core::System& system_) : system{system_} {} +ProgramRegistryManager::ProgramRegistryManager(Core::System& system_, + InitialProgramInfo& program_info) + : m_initial_program_info{program_info}, system{system_} {} Result ProgramRegistryManager::RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size, const void* desc, @@ -63,8 +65,8 @@ Result ProgramRegistryManager::GetProgramInfo(std::shared_ptr* out, std::scoped_lock lk(m_mutex); // Check if we're getting permissions for an initial program - if (IsInitialProgram(system, process_id)) { - *out = ProgramInfo::GetProgramInfoForInitialProcess(); + if (m_initial_program_info.IsInitialProgram(system, process_id)) { + *out = (m_initial_program_info.GetProgramInfoForInitialProcess()); R_SUCCEED(); } diff --git a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h index 816107ede7..36593244c3 100644 --- a/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h +++ b/src/core/file_sys/fssrv/impl/fssrv_program_registry_manager.h @@ -19,7 +19,7 @@ class ProgramRegistryManager { YUZU_NON_MOVEABLE(ProgramRegistryManager); public: - explicit ProgramRegistryManager(Core::System& system_); + explicit ProgramRegistryManager(Core::System& system_, InitialProgramInfo& program_info); Result RegisterProgram(u64 process_id, u64 program_id, u8 storage_id, const void* data, s64 data_size, const void* desc, s64 desc_size); @@ -32,6 +32,7 @@ private: using ProgramInfoList = Common::IntrusiveListBaseTraits::ListType; ProgramInfoList m_program_info_list{}; + InitialProgramInfo& m_initial_program_info; mutable std::mutex m_mutex{}; Core::System& system; };