diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp index 0ff050611..889195dcf 100644 --- a/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_code.hpp @@ -16,17 +16,10 @@ #pragma once #include #include +#include namespace ams::fs { - struct CodeVerificationData { - u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize]; - u8 target_hash[crypto::Rsa2048PssSha256Verifier::HashSize]; - bool has_data; - u8 reserved[3]; - }; - static_assert(sizeof(CodeVerificationData) == crypto::Rsa2048PssSha256Verifier::SignatureSize + crypto::Rsa2048PssSha256Verifier::HashSize + 4); - Result MountCode(CodeVerificationData *out, const char *name, const char *path, ncm::ProgramId program_id); Result MountCodeForAtmosphereWithRedirection(CodeVerificationData *out, const char *name, const char *path, ncm::ProgramId program_id, bool is_hbl, bool is_specific); diff --git a/libraries/libstratosphere/include/stratosphere/fs/fs_code_verification_data.hpp b/libraries/libstratosphere/include/stratosphere/fs/fs_code_verification_data.hpp new file mode 100644 index 000000000..ef6bcf125 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/fs_code_verification_data.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::fs { + + struct CodeVerificationData : public ams::sf::LargeData { + u8 signature[crypto::Rsa2048PssSha256Verifier::SignatureSize]; + u8 target_hash[crypto::Rsa2048PssSha256Verifier::HashSize]; + bool has_data; + u8 reserved[3]; + }; + static_assert(sizeof(CodeVerificationData) == crypto::Rsa2048PssSha256Verifier::SignatureSize + crypto::Rsa2048PssSha256Verifier::HashSize + 4); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fs/impl/fs_service_name.hpp b/libraries/libstratosphere/include/stratosphere/fs/impl/fs_service_name.hpp new file mode 100644 index 000000000..3dccb28d9 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fs/impl/fs_service_name.hpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include + +namespace ams::fs::impl { + + constexpr inline const sm::ServiceName FileSystemProxyServiceName = sm::ServiceName::Encode("fsp-srv"); + constexpr inline const sm::ServiceName ProgramRegistryServiceName = sm::ServiceName::Encode("fsp-pr"); + constexpr inline const sm::ServiceName FileSystemProxyForLoaderServiceName = sm::ServiceName::Encode("fsp-ldr"); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv.hpp b/libraries/libstratosphere/include/stratosphere/fssrv.hpp index 2c57489ad..a3f4b668c 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -29,4 +28,6 @@ #include #include #include +#include +#include #include diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_api.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_api.hpp index 369e17996..17a1a925d 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_api.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_api.hpp @@ -32,4 +32,6 @@ namespace ams::fssrv { void InitializeForFileSystemProxy(fscreator::FileSystemCreatorInterfaces *fs_creator_interfaces, fssystem::IBufferManager *buffer_manager, bool is_development_function_enabled); + void InitializeFileSystemProxyServer(int threads); + } diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp new file mode 100644 index 000000000..b602797af --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_impl.hpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include + +namespace ams::fssrv { + + namespace impl { + + class FileSystemProxyCoreImpl; + + } + + class FileSystemProxyImpl { + NON_COPYABLE(FileSystemProxyImpl); + NON_MOVEABLE(FileSystemProxyImpl); + private: + impl::FileSystemProxyCoreImpl *m_impl; + /* TODO: service pointers. */ + u64 m_process_id; + public: + FileSystemProxyImpl(); + ~FileSystemProxyImpl(); + + /* TODO */ + }; + static_assert(sf::IsIFileSystemProxy); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_server_session_resource_manager.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_server_session_resource_manager.hpp new file mode 100644 index 000000000..76b5cac33 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/fssrv_file_system_proxy_server_session_resource_manager.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::fssrv { + + enum class FileSystemProxyServerSessionType : s32 { + Any = 0, + Realtime = 1, + Background = 2, + Other = 3, + }; + + constexpr inline auto FileSystemProxyServerActiveSessionCount = 5; + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_file_system_proxy_service_object.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_file_system_proxy_service_object.hpp new file mode 100644 index 000000000..37bb95aee --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/impl/fssrv_file_system_proxy_service_object.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include +#include + +namespace ams::fssrv::impl { + + ams::sf::EmplacedRef GetFileSystemProxyServiceObject(); + + ams::sf::SharedPointer GetProgramRegistryServiceObject(); + ams::sf::SharedPointer GetInvalidProgramRegistryServiceObject(); + + ams::sf::SharedPointer GetFileSystemProxyForLoaderServiceObject(); + ams::sf::SharedPointer GetInvalidFileSystemProxyForLoaderServiceObject(); + +} diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp new file mode 100644 index 000000000..01350ceb3 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_file_system_proxy_for_loader.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include + +#define AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystemDeprecated, (ams::sf::Out> out_fs, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, path, program_id), hos::Version_Min, hos::Version_9_2_0) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, OpenCodeFileSystem, (ams::sf::Out> out_fs, ams::sf::Out out_verif, const fssrv::sf::Path &path, ncm::ProgramId program_id), (out_fs, out_verif, path, program_id), hos::Version_10_0_0) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, IsArchivedProgram, (ams::sf::Out out, u64 process_id), (out, process_id)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid), hos::Version_4_0_0) + +AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IFileSystemProxyForLoader, AMS_FSSRV_I_FILE_SYSTEM_PROXY_FOR_LOADER_INTERFACE_INFO) diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_program_registry.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_program_registry.hpp new file mode 100644 index 000000000..4b0a728ce --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_i_program_registry.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include +#include +#include +#include + +#define AMS_FSSRV_I_PROGRAM_REGISTRY_INTERFACE_INFO(C, H) \ + AMS_SF_METHOD_INFO(C, H, 0, Result, RegisterProgram, (u64 process_id, u64 program_id, u8 storage_id, const ams::sf::InBuffer &data, s64 data_size, const ams::sf::InBuffer &desc, s64 desc_size), (process_id, program_id, storage_id, data, data_size, desc, desc_size)) \ + AMS_SF_METHOD_INFO(C, H, 1, Result, UnregisterProgram, (u64 process_id), (process_id)) \ + AMS_SF_METHOD_INFO(C, H, 2, Result, SetCurrentProcess, (const ams::sf::ClientProcessId &client_pid), (client_pid)) \ + AMS_SF_METHOD_INFO(C, H, 256, Result, SetEnabledProgramVerification, (bool en), (en)) + +AMS_SF_DEFINE_INTERFACE(ams::fssrv::sf, IProgramRegistry, AMS_FSSRV_I_PROGRAM_REGISTRY_INTERFACE_INFO) + diff --git a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_path.hpp b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_path.hpp index a15cd1a6f..d5b3be6d4 100644 --- a/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_path.hpp +++ b/libraries/libstratosphere/include/stratosphere/fssrv/sf/fssrv_sf_path.hpp @@ -20,7 +20,7 @@ namespace ams::fssrv::sf { - struct Path : ams::sf::LargeData { + struct Path : public ams::sf::LargeData { char str[fs::EntryNameLengthMax + 1]; static constexpr Path Encode(const char *p) { diff --git a/libraries/libstratosphere/source/fssrv/fssrv_deferred_process_manager.hpp b/libraries/libstratosphere/source/fssrv/fssrv_deferred_process_manager.hpp new file mode 100644 index 000000000..7914a5c0d --- /dev/null +++ b/libraries/libstratosphere/source/fssrv/fssrv_deferred_process_manager.hpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once +#include + +namespace ams::fssrv { + + using NotifyProcessDeferredFunction = void (*)(u64 process_id); + + struct DeferredProcessEntryForDeviceError : public util::IntrusiveListBaseNode, public fs::impl::Newable { + os::MultiWaitHolderType *process_holder; + u64 process_id; + }; + + class DeferredProcessQueueForDeviceError { + NON_COPYABLE(DeferredProcessQueueForDeviceError); + NON_MOVEABLE(DeferredProcessQueueForDeviceError); + private: + using EntryList = util::IntrusiveListBaseTraits::ListType; + private: + EntryList m_list{}; + os::SdkMutex m_mutex{}; + public: + constexpr DeferredProcessQueueForDeviceError() = default; + }; + + class DeferredProcessEntryForPriority : public util::IntrusiveListBaseNode, public fs::impl::Newable { + private: + os::MultiWaitHolderType *m_process_holder; + FileSystemProxyServerSessionType m_session_type; + }; + + class DeferredProcessQueueForPriority { + NON_COPYABLE(DeferredProcessQueueForPriority); + NON_MOVEABLE(DeferredProcessQueueForPriority); + private: + using EntryList = util::IntrusiveListBaseTraits::ListType; + private: + EntryList m_list{}; + os::SdkRecursiveMutex m_mutex{}; + os::SdkConditionVariable m_cv{}; + public: + constexpr DeferredProcessQueueForPriority() = default; + }; + + template + class DeferredProcessManager { + NON_COPYABLE(DeferredProcessManager); + NON_MOVEABLE(DeferredProcessManager); + private: + DeferredProcessQueueForDeviceError m_queue_for_device_error{}; + os::SdkMutex m_invoke_mutex_for_device_error{}; + DeferredProcessQueueForPriority m_queue_for_priority{}; + std::atomic_bool m_is_invoke_deferred_process_event_linked{}; + os::EventType m_invoke_event{}; + os::MultiWaitHolderType m_invoke_event_holder{}; + bool m_initialized{false}; + public: + constexpr DeferredProcessManager() = default; + + void Initialize() { + /* Check pre-conditions. */ + AMS_ASSERT(!m_initialized); + os::InitializeEvent(std::addressof(m_invoke_event), false, os::EventClearMode_ManualClear); + os::InitializeMultiWaitHolder(std::addressof(m_invoke_event_holder), std::addressof(m_invoke_event)); + m_initialized = true; + } + }; + +} diff --git a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_api.cpp b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_api.cpp index 0a4fe2d63..1eef9815b 100644 --- a/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_api.cpp +++ b/libraries/libstratosphere/source/fssrv/fssrv_file_system_proxy_api.cpp @@ -14,12 +14,123 @@ * along with this program. If not, see . */ #include +#include +#include "fssrv_deferred_process_manager.hpp" namespace ams::fssrv { + namespace { + + struct FileSystemProxyServerOptions { + static constexpr size_t PointerBufferSize = 0x800; + static constexpr size_t MaxDomains = 0x40; + static constexpr size_t MaxDomainObjects = 0x4000; + static constexpr bool CanDeferInvokeRequest = true; + static constexpr bool CanManageMitmServers = false; + }; + + enum PortIndex { + PortIndex_FileSystemProxy, + PortIndex_ProgramRegistry, + PortIndex_FileSystemProxyForLoader, + PortIndex_Count, + }; + + constexpr size_t FileSystemProxyMaxSessions = 59; + constexpr size_t ProgramRegistryMaxSessions = 1; + constexpr size_t FileSystemProxyForLoaderMaxSessions = 1; + + constexpr size_t NumSessions = FileSystemProxyMaxSessions + ProgramRegistryMaxSessions + FileSystemProxyForLoaderMaxSessions; + + constinit os::SemaphoreType g_semaphore_for_file_system_proxy_for_loader; + constinit os::SemaphoreType g_semaphore_for_program_registry; + + class FileSystemProxyServerManager final : public ams::sf::hipc::ServerManager { + private: + virtual ams::Result OnNeedsToAccept(int port_index, Server *server) override { + switch (port_index) { + case PortIndex_FileSystemProxy: + { + return this->AcceptImpl(server, impl::GetFileSystemProxyServiceObject()); + } + break; + case PortIndex_ProgramRegistry: + { + if (os::TryAcquireSemaphore(std::addressof(g_semaphore_for_program_registry))) { + auto sema_guard = SCOPE_GUARD { os::ReleaseSemaphore(std::addressof(g_semaphore_for_program_registry)); }; + + R_TRY(this->AcceptImpl(server, impl::GetProgramRegistryServiceObject())); + + sema_guard.Cancel(); + } else { + R_TRY(this->AcceptImpl(server, impl::GetInvalidProgramRegistryServiceObject())); + } + + return ResultSuccess(); + } + break; + case PortIndex_FileSystemProxyForLoader: + { + if (os::TryAcquireSemaphore(std::addressof(g_semaphore_for_file_system_proxy_for_loader))) { + auto sema_guard = SCOPE_GUARD { os::ReleaseSemaphore(std::addressof(g_semaphore_for_file_system_proxy_for_loader)); }; + + R_TRY(this->AcceptImpl(server, impl::GetFileSystemProxyForLoaderServiceObject())); + + sema_guard.Cancel(); + } else { + R_TRY(this->AcceptImpl(server, impl::GetInvalidFileSystemProxyForLoaderServiceObject())); + } + + return ResultSuccess(); + } + break; + AMS_UNREACHABLE_DEFAULT_CASE(); + } + } + }; + + constinit util::TypedStorage g_server_manager_storage; + constinit FileSystemProxyServerManager *g_server_manager = nullptr; + + constinit os::BarrierType g_server_loop_barrier; + constinit os::EventType g_resume_wait_event; + + constinit bool g_is_suspended = false; + + void TemporaryNotifyProcessDeferred(u64) { /* TODO */ } + + constinit DeferredProcessManager g_deferred_process_manager; + + } + void InitializeForFileSystemProxy(fscreator::FileSystemCreatorInterfaces *fs_creator_interfaces, fssystem::IBufferManager *buffer_manager, bool is_development_function_enabled) { /* TODO FS-REIMPL */ AMS_UNUSED(fs_creator_interfaces, buffer_manager, is_development_function_enabled); } + void InitializeFileSystemProxyServer(int threads) { + /* Initialize synchronization primitives. */ + os::InitializeBarrier(std::addressof(g_server_loop_barrier), threads + 1); + os::InitializeEvent(std::addressof(g_resume_wait_event), false, os::EventClearMode_ManualClear); + g_is_suspended = false; + os::InitializeSemaphore(std::addressof(g_semaphore_for_file_system_proxy_for_loader), 1, 1); + os::InitializeSemaphore(std::addressof(g_semaphore_for_program_registry), 1, 1); + + /* Initialize deferred process manager. */ + g_deferred_process_manager.Initialize(); + + /* Create the server and register our services. */ + AMS_ASSERT(g_server_manager == nullptr); + g_server_manager = util::ConstructAt(g_server_manager_storage); + + /* TODO: Manager handler. */ + + R_ABORT_UNLESS(g_server_manager->RegisterServer(PortIndex_FileSystemProxy, fs::impl::FileSystemProxyServiceName, FileSystemProxyMaxSessions)); + R_ABORT_UNLESS(g_server_manager->RegisterServer(PortIndex_ProgramRegistry, fs::impl::ProgramRegistryServiceName, ProgramRegistryMaxSessions)); + R_ABORT_UNLESS(g_server_manager->RegisterServer(PortIndex_FileSystemProxyForLoader, fs::impl::FileSystemProxyForLoaderServiceName, FileSystemProxyForLoaderMaxSessions)); + + /* Enable processing on server. */ + g_server_manager->ResumeProcessing(); + } + } diff --git a/libraries/libstratosphere/source/fssystem/fssystem_file_system_proxy_api.cpp b/libraries/libstratosphere/source/fssystem/fssystem_file_system_proxy_api.cpp index ebee5e05b..f93d1e6b6 100644 --- a/libraries/libstratosphere/source/fssystem/fssystem_file_system_proxy_api.cpp +++ b/libraries/libstratosphere/source/fssystem/fssystem_file_system_proxy_api.cpp @@ -22,6 +22,8 @@ namespace ams::fssystem { namespace { + constexpr inline auto FileSystemProxyServerThreadCount = 5; + /* TODO: Heap sizes need to match FS, when this is FS in master rather than ams.mitm. */ /* Official FS has a 4.5 MB exp heap, a 6 MB buffer pool, an 8 MB device buffer manager heap, and a 14 MB buffer manager heap. */ @@ -161,9 +163,10 @@ namespace ams::fssystem { /* TODO FS-REIMPL: GetFileSystemProxyServiceObject(), set current process, initialize global service object. */ /* Disable auto-abort in fs library code. */ - /* TODO: fs::SetEnabledAutoAbort(false); */ + fs::SetEnabledAutoAbort(false); - /* TODO FS-REIMPL: Initialize fsp server. */ + /* Initialize fsp server. */ + fssrv::InitializeFileSystemProxyServer(fssrv::FileSystemProxyServerActiveSessionCount); /* TODO FS-REIMPL: Cleanup calls. */