From 06fb7f90da0b465e723a562134c12b513aa77dff Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Fri, 5 Jan 2024 05:23:58 +0100 Subject: fs: Move fsp_srv subclasses to separate files fs: Move additional files to the fsp directory --- src/core/CMakeLists.txt | 13 +- src/core/hle/service/filesystem/filesystem.cpp | 6 +- .../hle/service/filesystem/fsp/fs_i_directory.cpp | 79 ++ .../hle/service/filesystem/fsp/fs_i_directory.h | 27 + src/core/hle/service/filesystem/fsp/fs_i_file.cpp | 127 ++ src/core/hle/service/filesystem/fsp/fs_i_file.h | 26 + .../hle/service/filesystem/fsp/fs_i_filesystem.cpp | 262 ++++ .../hle/service/filesystem/fsp/fs_i_filesystem.h | 38 + .../hle/service/filesystem/fsp/fs_i_storage.cpp | 62 + src/core/hle/service/filesystem/fsp/fs_i_storage.h | 23 + src/core/hle/service/filesystem/fsp/fsp_ldr.cpp | 22 + src/core/hle/service/filesystem/fsp/fsp_ldr.h | 20 + src/core/hle/service/filesystem/fsp/fsp_pr.cpp | 23 + src/core/hle/service/filesystem/fsp/fsp_pr.h | 20 + src/core/hle/service/filesystem/fsp/fsp_srv.cpp | 727 +++++++++++ src/core/hle/service/filesystem/fsp/fsp_srv.h | 78 ++ src/core/hle/service/filesystem/fsp/fsp_util.h | 22 + src/core/hle/service/filesystem/fsp_ldr.cpp | 22 - src/core/hle/service/filesystem/fsp_ldr.h | 20 - src/core/hle/service/filesystem/fsp_pr.cpp | 23 - src/core/hle/service/filesystem/fsp_pr.h | 20 - src/core/hle/service/filesystem/fsp_srv.cpp | 1257 -------------------- src/core/hle/service/filesystem/fsp_srv.h | 78 -- 23 files changed, 1570 insertions(+), 1425 deletions(-) create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_directory.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_directory.h create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_file.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_file.h create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_filesystem.h create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_storage.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fs_i_storage.h create mode 100644 src/core/hle/service/filesystem/fsp/fsp_ldr.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fsp_ldr.h create mode 100644 src/core/hle/service/filesystem/fsp/fsp_pr.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fsp_pr.h create mode 100644 src/core/hle/service/filesystem/fsp/fsp_srv.cpp create mode 100644 src/core/hle/service/filesystem/fsp/fsp_srv.h create mode 100644 src/core/hle/service/filesystem/fsp/fsp_util.h delete mode 100644 src/core/hle/service/filesystem/fsp_ldr.cpp delete mode 100644 src/core/hle/service/filesystem/fsp_ldr.h delete mode 100644 src/core/hle/service/filesystem/fsp_pr.cpp delete mode 100644 src/core/hle/service/filesystem/fsp_pr.h delete mode 100644 src/core/hle/service/filesystem/fsp_srv.cpp delete mode 100644 src/core/hle/service/filesystem/fsp_srv.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 45a0d8746..68c430a65 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -488,16 +488,25 @@ add_library(core STATIC hle/service/fatal/fatal_u.h hle/service/filesystem/filesystem.cpp hle/service/filesystem/filesystem.h + hle/service/filesystem/fsp/fs_i_directory.cpp + hle/service/filesystem/fsp/fs_i_directory.h + hle/service/filesystem/fsp/fs_i_file.cpp + hle/service/filesystem/fsp/fs_i_file.h + hle/service/filesystem/fsp/fs_i_filesystem.cpp + hle/service/filesystem/fsp/fs_i_filesystem.h + hle/service/filesystem/fsp/fs_i_storage.cpp + hle/service/filesystem/fsp/fs_i_storage.h + hle/service/filesystem/fsp/fsp_srv.cpp + hle/service/filesystem/fsp/fsp_srv.h hle/service/filesystem/fsp_ldr.cpp hle/service/filesystem/fsp_ldr.h hle/service/filesystem/fsp_pr.cpp hle/service/filesystem/fsp_pr.h - hle/service/filesystem/fsp_srv.cpp - hle/service/filesystem/fsp_srv.h hle/service/filesystem/romfs_controller.cpp hle/service/filesystem/romfs_controller.h hle/service/filesystem/save_data_controller.cpp hle/service/filesystem/save_data_controller.h + hle/service/filesystem/fsp_util.h hle/service/fgm/fgm.cpp hle/service/fgm/fgm.h hle/service/friend/friend.cpp diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index ca6d8d607..ab4974ac5 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -21,9 +21,9 @@ #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_offset.h" #include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/filesystem/fsp_ldr.h" -#include "core/hle/service/filesystem/fsp_pr.h" -#include "core/hle/service/filesystem/fsp_srv.h" +#include "core/hle/service/filesystem/fsp/fsp_ldr.h" +#include "core/hle/service/filesystem/fsp/fsp_pr.h" +#include "core/hle/service/filesystem/fsp/fsp_srv.h" #include "core/hle/service/filesystem/romfs_controller.h" #include "core/hle/service/filesystem/save_data_controller.h" #include "core/hle/service/server_manager.h" diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp new file mode 100644 index 000000000..62512ad0f --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/file_sys/savedata_factory.h" +#include "core/hle/service/filesystem/fsp/fs_i_directory.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::FileSystem { + +template +static void BuildEntryIndex(std::vector& entries, const std::vector& new_data, + FileSys::EntryType type) { + entries.reserve(entries.size() + new_data.size()); + + for (const auto& new_entry : new_data) { + auto name = new_entry->GetName(); + + if (type == FileSys::EntryType::File && name == FileSys::GetSaveDataSizeFileName()) { + continue; + } + + entries.emplace_back(name, type, + type == FileSys::EntryType::Directory ? 0 : new_entry->GetSize()); + } +} + +IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir backend_, OpenDirectoryMode mode) + : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) { + static const FunctionInfo functions[] = { + {0, &IDirectory::Read, "Read"}, + {1, &IDirectory::GetEntryCount, "GetEntryCount"}, + }; + RegisterHandlers(functions); + + // TODO(DarkLordZach): Verify that this is the correct behavior. + // Build entry index now to save time later. + if (True(mode & OpenDirectoryMode::Directory)) { + BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::EntryType::Directory); + } + if (True(mode & OpenDirectoryMode::File)) { + BuildEntryIndex(entries, backend->GetFiles(), FileSys::EntryType::File); + } +} + +void IDirectory::Read(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called."); + + // Calculate how many entries we can fit in the output buffer + const u64 count_entries = ctx.GetWriteBufferNumElements(); + + // Cap at total number of entries. + const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); + + // Determine data start and end + const auto* begin = reinterpret_cast(entries.data() + next_entry_index); + const auto* end = reinterpret_cast(entries.data() + next_entry_index + actual_entries); + const auto range_size = static_cast(std::distance(begin, end)); + + next_entry_index += actual_entries; + + // Write the data to memory + ctx.WriteBuffer(begin, range_size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(actual_entries); +} + +void IDirectory::GetEntryCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + u64 count = entries.size() - next_entry_index; + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(count); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.h b/src/core/hle/service/filesystem/fsp/fs_i_directory.h new file mode 100644 index 000000000..2a28ee496 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/file_sys/vfs.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/filesystem/fsp_util.h" +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +class IDirectory final : public ServiceFramework { +public: + explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_, + OpenDirectoryMode mode); + +private: + FileSys::VirtualDir backend; + std::vector entries; + u64 next_entry_index = 0; + + void Read(HLERequestContext& ctx); + void GetEntryCount(HLERequestContext& ctx); +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_file.cpp b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp new file mode 100644 index 000000000..7e0c90a89 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp @@ -0,0 +1,127 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/file_sys/errors.h" +#include "core/hle/service/filesystem/fsp/fs_i_file.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::FileSystem { + +IFile::IFile(Core::System& system_, FileSys::VirtualFile backend_) + : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) { + static const FunctionInfo functions[] = { + {0, &IFile::Read, "Read"}, + {1, &IFile::Write, "Write"}, + {2, &IFile::Flush, "Flush"}, + {3, &IFile::SetSize, "SetSize"}, + {4, &IFile::GetSize, "GetSize"}, + {5, nullptr, "OperateRange"}, + {6, nullptr, "OperateRangeWithBuffer"}, + }; + RegisterHandlers(functions); +} + +void IFile::Read(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 option = rp.Pop(); + const s64 offset = rp.Pop(); + const s64 length = rp.Pop(); + + LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); + + // Error checking + if (length < 0) { + LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_INVALID_SIZE); + return; + } + if (offset < 0) { + LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_INVALID_OFFSET); + return; + } + + // Read the data from the Storage backend + std::vector output = backend->ReadBytes(length, offset); + + // Write the data to memory + ctx.WriteBuffer(output); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(static_cast(output.size())); +} + +void IFile::Write(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 option = rp.Pop(); + const s64 offset = rp.Pop(); + const s64 length = rp.Pop(); + + LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); + + // Error checking + if (length < 0) { + LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_INVALID_SIZE); + return; + } + if (offset < 0) { + LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_INVALID_OFFSET); + return; + } + + const auto data = ctx.ReadBuffer(); + + ASSERT_MSG(static_cast(data.size()) <= length, + "Attempting to write more data than requested (requested={:016X}, actual={:016X}).", + length, data.size()); + + // Write the data to the Storage backend + const auto write_size = + static_cast(std::distance(data.begin(), data.begin() + length)); + const std::size_t written = backend->Write(data.data(), write_size, offset); + + ASSERT_MSG(static_cast(written) == length, + "Could not write all bytes to file (requested={:016X}, actual={:016X}).", length, + written); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IFile::Flush(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + // Exists for SDK compatibiltity -- No need to flush file. + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IFile::SetSize(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 size = rp.Pop(); + LOG_DEBUG(Service_FS, "called, size={}", size); + + backend->Resize(size); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IFile::GetSize(HLERequestContext& ctx) { + const u64 size = backend->GetSize(); + LOG_DEBUG(Service_FS, "called, size={}", size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(size); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_file.h b/src/core/hle/service/filesystem/fsp/fs_i_file.h new file mode 100644 index 000000000..a7eb1a1e9 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.h @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/file_sys/vfs.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +class IFile final : public ServiceFramework { +public: + explicit IFile(Core::System& system_, FileSys::VirtualFile backend_); + +private: + FileSys::VirtualFile backend; + + void Read(HLERequestContext& ctx); + void Write(HLERequestContext& ctx); + void Flush(HLERequestContext& ctx); + void SetSize(HLERequestContext& ctx); + void GetSize(HLERequestContext& ctx); +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp new file mode 100644 index 000000000..3e72101a4 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp @@ -0,0 +1,262 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/string_util.h" +#include "core/hle/service/filesystem/fsp/fs_i_directory.h" +#include "core/hle/service/filesystem/fsp/fs_i_file.h" +#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::FileSystem { + +IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) + : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, + size{std::move(size_)} { + static const FunctionInfo functions[] = { + {0, &IFileSystem::CreateFile, "CreateFile"}, + {1, &IFileSystem::DeleteFile, "DeleteFile"}, + {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, + {3, &IFileSystem::DeleteDirectory, "DeleteDirectory"}, + {4, &IFileSystem::DeleteDirectoryRecursively, "DeleteDirectoryRecursively"}, + {5, &IFileSystem::RenameFile, "RenameFile"}, + {6, nullptr, "RenameDirectory"}, + {7, &IFileSystem::GetEntryType, "GetEntryType"}, + {8, &IFileSystem::OpenFile, "OpenFile"}, + {9, &IFileSystem::OpenDirectory, "OpenDirectory"}, + {10, &IFileSystem::Commit, "Commit"}, + {11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"}, + {12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"}, + {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, + {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"}, + {15, nullptr, "QueryEntry"}, + {16, &IFileSystem::GetFileSystemAttribute, "GetFileSystemAttribute"}, + }; + RegisterHandlers(functions); +} + +void IFileSystem::CreateFile(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + const u64 file_mode = rp.Pop(); + const u32 file_size = rp.Pop(); + + LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, file_mode, + file_size); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.CreateFile(name, file_size)); +} + +void IFileSystem::DeleteFile(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. file={}", name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.DeleteFile(name)); +} + +void IFileSystem::CreateDirectory(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. directory={}", name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.CreateDirectory(name)); +} + +void IFileSystem::DeleteDirectory(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. directory={}", name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.DeleteDirectory(name)); +} + +void IFileSystem::DeleteDirectoryRecursively(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. directory={}", name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.DeleteDirectoryRecursively(name)); +} + +void IFileSystem::CleanDirectoryRecursively(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. Directory: {}", name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.CleanDirectoryRecursively(name)); +} + +void IFileSystem::RenameFile(HLERequestContext& ctx) { + const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0)); + const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1)); + + LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(backend.RenameFile(src_name, dst_name)); +} + +void IFileSystem::OpenFile(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + const auto mode = static_cast(rp.Pop()); + + LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, mode); + + FileSys::VirtualFile vfs_file{}; + auto result = backend.OpenFile(&vfs_file, name, mode); + if (result != ResultSuccess) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); + return; + } + + auto file = std::make_shared(system, vfs_file); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(file)); +} + +void IFileSystem::OpenDirectory(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + const auto mode = rp.PopRaw(); + + LOG_DEBUG(Service_FS, "called. directory={}, mode={}", name, mode); + + FileSys::VirtualDir vfs_dir{}; + auto result = backend.OpenDirectory(&vfs_dir, name); + if (result != ResultSuccess) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); + return; + } + + auto directory = std::make_shared(system, vfs_dir, mode); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(directory)); +} + +void IFileSystem::GetEntryType(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_DEBUG(Service_FS, "called. file={}", name); + + FileSys::EntryType vfs_entry_type{}; + auto result = backend.GetEntryType(&vfs_entry_type, name); + if (result != ResultSuccess) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); + return; + } + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(static_cast(vfs_entry_type)); +} + +void IFileSystem::Commit(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IFileSystem::GetFreeSpaceSize(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(size.get_free_size()); +} + +void IFileSystem::GetTotalSpaceSize(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(size.get_total_size()); +} + +void IFileSystem::GetFileTimeStampRaw(HLERequestContext& ctx) { + const auto file_buffer = ctx.ReadBuffer(); + const std::string name = Common::StringFromBuffer(file_buffer); + + LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", name); + + FileSys::FileTimeStampRaw vfs_timestamp{}; + auto result = backend.GetFileTimeStampRaw(&vfs_timestamp, name); + if (result != ResultSuccess) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); + return; + } + + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(ResultSuccess); + rb.PushRaw(vfs_timestamp); +} + +void IFileSystem::GetFileSystemAttribute(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + struct FileSystemAttribute { + u8 dir_entry_name_length_max_defined; + u8 file_entry_name_length_max_defined; + u8 dir_path_name_length_max_defined; + u8 file_path_name_length_max_defined; + INSERT_PADDING_BYTES_NOINIT(0x5); + u8 utf16_dir_entry_name_length_max_defined; + u8 utf16_file_entry_name_length_max_defined; + u8 utf16_dir_path_name_length_max_defined; + u8 utf16_file_path_name_length_max_defined; + INSERT_PADDING_BYTES_NOINIT(0x18); + s32 dir_entry_name_length_max; + s32 file_entry_name_length_max; + s32 dir_path_name_length_max; + s32 file_path_name_length_max; + INSERT_PADDING_WORDS_NOINIT(0x5); + s32 utf16_dir_entry_name_length_max; + s32 utf16_file_entry_name_length_max; + s32 utf16_dir_path_name_length_max; + s32 utf16_file_path_name_length_max; + INSERT_PADDING_WORDS_NOINIT(0x18); + INSERT_PADDING_WORDS_NOINIT(0x1); + }; + static_assert(sizeof(FileSystemAttribute) == 0xc0, "FileSystemAttribute has incorrect size"); + + FileSystemAttribute savedata_attribute{}; + savedata_attribute.dir_entry_name_length_max_defined = true; + savedata_attribute.file_entry_name_length_max_defined = true; + savedata_attribute.dir_entry_name_length_max = 0x40; + savedata_attribute.file_entry_name_length_max = 0x40; + + IPC::ResponseBuilder rb{ctx, 50}; + rb.Push(ResultSuccess); + rb.PushRaw(savedata_attribute); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h new file mode 100644 index 000000000..c9e94c911 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/file_sys/vfs.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/filesystem/fsp/fsp_util.h" +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +class IFileSystem final : public ServiceFramework { +public: + explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_); + + void CreateFile(HLERequestContext& ctx); + void DeleteFile(HLERequestContext& ctx); + void CreateDirectory(HLERequestContext& ctx); + void DeleteDirectory(HLERequestContext& ctx); + void DeleteDirectoryRecursively(HLERequestContext& ctx); + void CleanDirectoryRecursively(HLERequestContext& ctx); + void RenameFile(HLERequestContext& ctx); + void OpenFile(HLERequestContext& ctx); + void OpenDirectory(HLERequestContext& ctx); + void GetEntryType(HLERequestContext& ctx); + void Commit(HLERequestContext& ctx); + void GetFreeSpaceSize(HLERequestContext& ctx); + void GetTotalSpaceSize(HLERequestContext& ctx); + void GetFileTimeStampRaw(HLERequestContext& ctx); + void GetFileSystemAttribute(HLERequestContext& ctx); + +private: + VfsDirectoryServiceWrapper backend; + SizeGetter size; +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp b/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp new file mode 100644 index 000000000..9fe36f31a --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_storage.cpp @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/file_sys/errors.h" +#include "core/hle/service/filesystem/fsp/fs_i_storage.h" +#include "core/hle/service/ipc_helpers.h" + +namespace Service::FileSystem { + +IStorage::IStorage(Core::System& system_, FileSys::VirtualFile backend_) + : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) { + static const FunctionInfo functions[] = { + {0, &IStorage::Read, "Read"}, + {1, nullptr, "Write"}, + {2, nullptr, "Flush"}, + {3, nullptr, "SetSize"}, + {4, &IStorage::GetSize, "GetSize"}, + {5, nullptr, "OperateRange"}, + }; + RegisterHandlers(functions); +} + +void IStorage::Read(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const s64 offset = rp.Pop(); + const s64 length = rp.Pop(); + + LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); + + // Error checking + if (length < 0) { + LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_INVALID_SIZE); + return; + } + if (offset < 0) { + LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_INVALID_OFFSET); + return; + } + + // Read the data from the Storage backend + std::vector output = backend->ReadBytes(length, offset); + // Write the data to memory + ctx.WriteBuffer(output); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IStorage::GetSize(HLERequestContext& ctx) { + const u64 size = backend->GetSize(); + LOG_DEBUG(Service_FS, "called, size={}", size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(size); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fs_i_storage.h b/src/core/hle/service/filesystem/fsp/fs_i_storage.h new file mode 100644 index 000000000..48d059874 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fs_i_storage.h @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/file_sys/vfs.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/service.h" + +namespace Service::FileSystem { + +class IStorage final : public ServiceFramework { +public: + explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_); + +private: + FileSys::VirtualFile backend; + + void Read(HLERequestContext& ctx); + void GetSize(HLERequestContext& ctx); +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp/fsp_ldr.cpp new file mode 100644 index 000000000..8ee733f47 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_ldr.cpp @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/filesystem/fsp/fsp_ldr.h" + +namespace Service::FileSystem { + +FSP_LDR::FSP_LDR(Core::System& system_) : ServiceFramework{system_, "fsp:ldr"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "OpenCodeFileSystem"}, + {1, nullptr, "IsArchivedProgram"}, + {2, nullptr, "SetCurrentProcess"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +FSP_LDR::~FSP_LDR() = default; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_ldr.h b/src/core/hle/service/filesystem/fsp/fsp_ldr.h new file mode 100644 index 000000000..358739a87 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_ldr.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::FileSystem { + +class FSP_LDR final : public ServiceFramework { +public: + explicit FSP_LDR(Core::System& system_); + ~FSP_LDR() override; +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp/fsp_pr.cpp new file mode 100644 index 000000000..7c03ebaea --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_pr.cpp @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/filesystem/fsp/fsp_pr.h" + +namespace Service::FileSystem { + +FSP_PR::FSP_PR(Core::System& system_) : ServiceFramework{system_, "fsp:pr"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "RegisterProgram"}, + {1, nullptr, "UnregisterProgram"}, + {2, nullptr, "SetCurrentProcess"}, + {256, nullptr, "SetEnabledProgramVerification"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +FSP_PR::~FSP_PR() = default; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_pr.h b/src/core/hle/service/filesystem/fsp/fsp_pr.h new file mode 100644 index 000000000..bd4e0a730 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_pr.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::FileSystem { + +class FSP_PR final : public ServiceFramework { +public: + explicit FSP_PR(Core::System& system_); + ~FSP_PR() override; +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp new file mode 100644 index 000000000..85ab75517 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp @@ -0,0 +1,727 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/common_types.h" +#include "common/hex_util.h" +#include "common/logging/log.h" +#include "common/settings.h" +#include "common/string_util.h" +#include "core/core.h" +#include "core/file_sys/directory.h" +#include "core/file_sys/errors.h" +#include "core/file_sys/mode.h" +#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/patch_manager.h" +#include "core/file_sys/romfs_factory.h" +#include "core/file_sys/savedata_factory.h" +#include "core/file_sys/system_archive/system_archive.h" +#include "core/file_sys/vfs.h" +#include "core/hle/result.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" +#include "core/hle/service/filesystem/fsp/fs_i_storage.h" +#include "core/hle/service/filesystem/fsp/fsp_srv.h" +#include "core/hle/service/filesystem/romfs_controller.h" +#include "core/hle/service/filesystem/save_data_controller.h" +#include "core/hle/service/hle_ipc.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/reporter.h" + +namespace Service::FileSystem { +enum class FileSystemType : u8 { + Invalid0 = 0, + Invalid1 = 1, + Logo = 2, + ContentControl = 3, + ContentManual = 4, + ContentMeta = 5, + ContentData = 6, + ApplicationPackage = 7, +}; + +class ISaveDataInfoReader final : public ServiceFramework { +public: + explicit ISaveDataInfoReader(Core::System& system_, + std::shared_ptr save_data_controller_, + FileSys::SaveDataSpaceId space) + : ServiceFramework{system_, "ISaveDataInfoReader"}, + save_data_controller{save_data_controller_} { + static const FunctionInfo functions[] = { + {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"}, + }; + RegisterHandlers(functions); + + FindAllSaves(space); + } + + void ReadSaveDataInfo(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + // Calculate how many entries we can fit in the output buffer + const u64 count_entries = ctx.GetWriteBufferNumElements(); + + // Cap at total number of entries. + const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index); + + // Determine data start and end + const auto* begin = reinterpret_cast(info.data() + next_entry_index); + const auto* end = reinterpret_cast(info.data() + next_entry_index + actual_entries); + const auto range_size = static_cast(std::distance(begin, end)); + + next_entry_index += actual_entries; + + // Write the data to memory + ctx.WriteBuffer(begin, range_size); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.Push(actual_entries); + } + +private: + static u64 stoull_be(std::string_view str) { + if (str.size() != 16) + return 0; + + const auto bytes = Common::HexStringToArray<0x8>(str); + u64 out{}; + std::memcpy(&out, bytes.data(), sizeof(u64)); + + return Common::swap64(out); + } + + void FindAllSaves(FileSys::SaveDataSpaceId space) { + FileSys::VirtualDir save_root{}; + const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space); + + if (result != ResultSuccess || save_root == nullptr) { + LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space); + return; + } + + for (const auto& type : save_root->GetSubdirectories()) { + if (type->GetName() == "save") { + for (const auto& save_id : type->GetSubdirectories()) { + for (const auto& user_id : save_id->GetSubdirectories()) { + const auto save_id_numeric = stoull_be(save_id->GetName()); + auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); + std::reverse(user_id_numeric.begin(), user_id_numeric.end()); + + if (save_id_numeric != 0) { + // System Save Data + info.emplace_back(SaveDataInfo{ + 0, + space, + FileSys::SaveDataType::SystemSaveData, + {}, + user_id_numeric, + save_id_numeric, + 0, + user_id->GetSize(), + {}, + {}, + }); + + continue; + } + + for (const auto& title_id : user_id->GetSubdirectories()) { + const auto device = + std::all_of(user_id_numeric.begin(), user_id_numeric.end(), + [](u8 val) { return val == 0; }); + info.emplace_back(SaveDataInfo{ + 0, + space, + device ? FileSys::SaveDataType::DeviceSaveData + : FileSys::SaveDataType::SaveData, + {}, + user_id_numeric, + save_id_numeric, + stoull_be(title_id->GetName()), + title_id->GetSize(), + {}, + {}, + }); + } + } + } + } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { + // Temporary Storage + for (const auto& user_id : type->GetSubdirectories()) { + for (const auto& title_id : user_id->GetSubdirectories()) { + if (!title_id->GetFiles().empty() || + !title_id->GetSubdirectories().empty()) { + auto user_id_numeric = + Common::HexStringToArray<0x10>(user_id->GetName()); + std::reverse(user_id_numeric.begin(), user_id_numeric.end()); + + info.emplace_back(SaveDataInfo{ + 0, + space, + FileSys::SaveDataType::TemporaryStorage, + {}, + user_id_numeric, + stoull_be(type->GetName()), + stoull_be(title_id->GetName()), + title_id->GetSize(), + {}, + {}, + }); + } + } + } + } + } + } + + struct SaveDataInfo { + u64_le save_id_unknown; + FileSys::SaveDataSpaceId space; + FileSys::SaveDataType type; + INSERT_PADDING_BYTES(0x6); + std::array user_id; + u64_le save_id; + u64_le title_id; + u64_le save_image_size; + u16_le index; + FileSys::SaveDataRank rank; + INSERT_PADDING_BYTES(0x25); + }; + static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size."); + + ProcessId process_id = 0; + std::shared_ptr save_data_controller; + std::vector info; + u64 next_entry_index = 0; +}; + +FSP_SRV::FSP_SRV(Core::System& system_) + : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()}, + content_provider{system.GetContentProvider()}, reporter{system.GetReporter()} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "OpenFileSystem"}, + {1, &FSP_SRV::SetCurrentProcess, "SetCurrentProcess"}, + {2, nullptr, "OpenDataFileSystemByCurrentProcess"}, + {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"}, + {8, nullptr, "OpenFileSystemWithId"}, + {9, nullptr, "OpenDataFileSystemByApplicationId"}, + {11, nullptr, "OpenBisFileSystem"}, + {12, nullptr, "OpenBisStorage"}, + {13, nullptr, "InvalidateBisCache"}, + {17, nullptr, "OpenHostFileSystem"}, + {18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"}, + {19, nullptr, "FormatSdCardFileSystem"}, + {21, nullptr, "DeleteSaveDataFileSystem"}, + {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"}, + {23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"}, + {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"}, + {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"}, + {26, nullptr, "FormatSdCardDryRun"}, + {27, nullptr, "IsExFatSupported"}, + {28, nullptr, "DeleteSaveDataFileSystemBySaveDataAttribute"}, + {30, nullptr, "OpenGameCardStorage"}, + {31, nullptr, "OpenGameCardFileSystem"}, + {32, nullptr, "ExtendSaveDataFileSystem"}, + {33, nullptr, "DeleteCacheStorage"}, + {34, &FSP_SRV::GetCacheStorageSize, "GetCacheStorageSize"}, + {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, + {36, nullptr, "OpenHostFileSystemWithOption"}, + {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"}, + {52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"}, + {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, + {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, + {58, nullptr, "ReadSaveDataFileSystemExtraData"}, + {59, nullptr, "WriteSaveDataFileSystemExtraData"}, + {60, nullptr, "OpenSaveDataInfoReader"}, + {61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, + {62, &FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage, "OpenSaveDataInfoReaderOnlyCacheStorage"}, + {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, + {65, nullptr, "UpdateSaveDataMacForDebug"}, + {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, + {67, nullptr, "FindSaveDataWithFilter"}, + {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, + {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, + {70, &FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"}, + {71, &FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, + {80, nullptr, "OpenSaveDataMetaFile"}, + {81, nullptr, "OpenSaveDataTransferManager"}, + {82, nullptr, "OpenSaveDataTransferManagerVersion2"}, + {83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"}, + {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"}, + {85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"}, + {86, nullptr, "OpenSaveDataMover"}, + {87, nullptr, "OpenSaveDataTransferManagerForRepair"}, + {100, nullptr, "OpenImageDirectoryFileSystem"}, + {101, nullptr, "OpenBaseFileSystem"}, + {102, nullptr, "FormatBaseFileSystem"}, + {110, nullptr, "OpenContentStorageFileSystem"}, + {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, + {130, nullptr, "OpenCustomStorageFileSystem"}, + {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, + {201, nullptr, "OpenDataStorageByProgramId"}, + {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"}, + {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"}, + {204, nullptr, "OpenDataFileSystemByProgramIndex"}, + {205, &FSP_SRV::OpenDataStorageWithProgramIndex, "OpenDataStorageWithProgramIndex"}, + {206, nullptr, "OpenDataStorageByPath"}, + {400, nullptr, "OpenDeviceOperator"}, + {500, nullptr, "OpenSdCardDetectionEventNotifier"}, + {501, nullptr, "OpenGameCardDetectionEventNotifier"}, + {510, nullptr, "OpenSystemDataUpdateEventNotifier"}, + {511, nullptr, "NotifySystemDataUpdateEvent"}, + {520, nullptr, "SimulateGameCardDetectionEvent"}, + {600, nullptr, "SetCurrentPosixTime"}, + {601, nullptr, "QuerySaveDataTotalSize"}, + {602, nullptr, "VerifySaveDataFileSystem"}, + {603, nullptr, "CorruptSaveDataFileSystem"}, + {604, nullptr, "CreatePaddingFile"}, + {605, nullptr, "DeleteAllPaddingFiles"}, + {606, nullptr, "GetRightsId"}, + {607, nullptr, "RegisterExternalKey"}, + {608, nullptr, "UnregisterAllExternalKey"}, + {609, nullptr, "GetRightsIdByPath"}, + {610, nullptr, "GetRightsIdAndKeyGenerationByPath"}, + {611, nullptr, "SetCurrentPosixTimeWithTimeDifference"}, + {612, nullptr, "GetFreeSpaceSizeForSaveData"}, + {613, nullptr, "VerifySaveDataFileSystemBySaveDataSpaceId"}, + {614, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId"}, + {615, nullptr, "QuerySaveDataInternalStorageTotalSize"}, + {616, nullptr, "GetSaveDataCommitId"}, + {617, nullptr, "UnregisterExternalKey"}, + {620, nullptr, "SetSdCardEncryptionSeed"}, + {630, nullptr, "SetSdCardAccessibility"}, + {631, nullptr, "IsSdCardAccessible"}, + {640, nullptr, "IsSignedSystemPartitionOnSdCardValid"}, + {700, nullptr, "OpenAccessFailureResolver"}, + {701, nullptr, "GetAccessFailureDetectionEvent"}, + {702, nullptr, "IsAccessFailureDetected"}, + {710, nullptr, "ResolveAccessFailure"}, + {720, nullptr, "AbandonAccessFailure"}, + {800, nullptr, "GetAndClearFileSystemProxyErrorInfo"}, + {810, nullptr, "RegisterProgramIndexMapInfo"}, + {1000, nullptr, "SetBisRootForHost"}, + {1001, nullptr, "SetSaveDataSize"}, + {1002, nullptr, "SetSaveDataRootPath"}, + {1003, &FSP_SRV::DisableAutoSaveDataCreation, "DisableAutoSaveDataCreation"}, + {1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"}, + {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"}, + {1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"}, + {1007, nullptr, "RegisterUpdatePartition"}, + {1008, nullptr, "OpenRegisteredUpdatePartition"}, + {1009, nullptr, "GetAndClearMemoryReportInfo"}, + {1010, nullptr, "SetDataStorageRedirectTarget"}, + {1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"}, + {1012, nullptr, "GetFsStackUsage"}, + {1013, nullptr, "UnsetSaveDataRootPath"}, + {1014, nullptr, "OutputMultiProgramTagAccessLog"}, + {1016, nullptr, "FlushAccessLogOnSdCard"}, + {1017, nullptr, "OutputApplicationInfoAccessLog"}, + {1018, nullptr, "SetDebugOption"}, + {1019, nullptr, "UnsetDebugOption"}, + {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, + {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, + {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"}, + {1300, nullptr, "OpenBisWiper"}, + }; + // clang-format on + RegisterHandlers(functions); + + if (Settings::values.enable_fs_access_log) { + access_log_mode = AccessLogMode::SdCard; + } +} + +FSP_SRV::~FSP_SRV() = default; + +void FSP_SRV::SetCurrentProcess(HLERequestContext& ctx) { + current_process_id = ctx.GetPID(); + + LOG_DEBUG(Service_FS, "called. current_process_id=0x{:016X}", current_process_id); + + const auto res = + fsc.OpenProcess(&program_id, &save_data_controller, &romfs_controller, current_process_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res); +} + +void FSP_SRV::OpenFileSystemWithPatch(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto type = rp.PopRaw(); + const auto title_id = rp.PopRaw(); + LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}", type, title_id); + + IPC::ResponseBuilder rb{ctx, 2, 0, 0}; + rb.Push(ResultUnknown); +} + +void FSP_SRV::OpenSdCardFileSystem(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + FileSys::VirtualDir sdmc_dir{}; + fsc.OpenSDMC(&sdmc_dir); + + auto filesystem = std::make_shared( + system, sdmc_dir, SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard)); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(filesystem)); +} + +void FSP_SRV::CreateSaveDataFileSystem(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto save_struct = rp.PopRaw(); + [[maybe_unused]] auto save_create_struct = rp.PopRaw>(); + u128 uid = rp.PopRaw(); + + LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(), + uid[1], uid[0]); + + FileSys::VirtualDir save_data_dir{}; + save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandUser, + save_struct); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + auto save_struct = rp.PopRaw(); + [[maybe_unused]] auto save_create_struct = rp.PopRaw>(); + + LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo()); + + FileSys::VirtualDir save_data_dir{}; + save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandSystem, + save_struct); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + struct Parameters { + FileSys::SaveDataSpaceId space_id; + FileSys::SaveDataAttribute attribute; + }; + + const auto parameters = rp.PopRaw(); + + LOG_INFO(Service_FS, "called."); + + FileSys::VirtualDir dir{}; + auto result = + save_data_controller->OpenSaveData(&dir, parameters.space_id, parameters.attribute); + if (result != ResultSuccess) { + IPC::ResponseBuilder rb{ctx, 2, 0, 0}; + rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); + return; + } + + FileSys::StorageId id{}; + switch (parameters.space_id) { + case FileSys::SaveDataSpaceId::NandUser: + id = FileSys::StorageId::NandUser; + break; + case FileSys::SaveDataSpaceId::SdCardSystem: + case FileSys::SaveDataSpaceId::SdCardUser: + id = FileSys::StorageId::SdCard; + break; + case FileSys::SaveDataSpaceId::NandSystem: + id = FileSys::StorageId::NandSystem; + break; + case FileSys::SaveDataSpaceId::TemporaryStorage: + case FileSys::SaveDataSpaceId::ProperSystem: + case FileSys::SaveDataSpaceId::SafeMode: + ASSERT(false); + } + + auto filesystem = + std::make_shared(system, std::move(dir), SizeGetter::FromStorageId(fsc, id)); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(filesystem)); +} + +void FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); + OpenSaveDataFileSystem(ctx); +} + +void FSP_SRV::OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); + OpenSaveDataFileSystem(ctx); +} + +void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto space = rp.PopRaw(); + LOG_INFO(Service_FS, "called, space={}", space); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface( + std::make_shared(system, save_data_controller, space)); +} + +void FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system, save_data_controller, + FileSys::SaveDataSpaceId::TemporaryStorage); +} + +void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called."); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + struct Parameters { + FileSys::SaveDataSpaceId space_id; + FileSys::SaveDataAttribute attribute; + }; + + const auto parameters = rp.PopRaw(); + // Stub this to None for now, backend needs an impl to read/write the SaveDataExtraData + constexpr auto flags = static_cast(FileSys::SaveDataFlags::None); + + LOG_WARNING(Service_FS, + "(STUBBED) called, flags={}, space_id={}, attribute.title_id={:016X}\n" + "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" + "attribute.type={}, attribute.rank={}, attribute.index={}", + flags, parameters.space_id, parameters.attribute.title_id, + parameters.attribute.user_id[1], parameters.attribute.user_id[0], + parameters.attribute.save_id, parameters.attribute.type, parameters.attribute.rank, + parameters.attribute.index); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(flags); +} + +void FSP_SRV::OpenDataStorageByCurrentProcess(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + if (!romfs) { + auto current_romfs = romfs_controller->OpenRomFSCurrentProcess(); + if (!current_romfs) { + // TODO (bunnei): Find the right error code to use here + LOG_CRITICAL(Service_FS, "no file system interface available!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + + romfs = current_romfs; + } + + auto storage = std::make_shared(system, romfs); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(storage)); +} + +void FSP_SRV::OpenDataStorageByDataId(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto storage_id = rp.PopRaw(); + const auto unknown = rp.PopRaw(); + const auto title_id = rp.PopRaw(); + + LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}", + storage_id, unknown, title_id); + + auto data = romfs_controller->OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data); + + if (!data) { + const auto archive = FileSys::SystemArchive::SynthesizeSystemArchive(title_id); + + if (archive != nullptr) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::make_shared(system, archive)); + return; + } + + // TODO(DarkLordZach): Find the right error code to use here + LOG_ERROR(Service_FS, + "could not open data storage with title_id={:016X}, storage_id={:02X}", title_id, + storage_id); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + + const FileSys::PatchManager pm{title_id, fsc, content_provider}; + + auto base = + romfs_controller->OpenBaseNca(title_id, storage_id, FileSys::ContentRecordType::Data); + auto storage = std::make_shared( + system, pm.PatchRomFS(base.get(), std::move(data), FileSys::ContentRecordType::Data)); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(storage)); +} + +void FSP_SRV::OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto storage_id = rp.PopRaw(); + const auto title_id = rp.PopRaw(); + + LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}", storage_id, title_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); +} + +void FSP_SRV::OpenDataStorageWithProgramIndex(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + + const auto program_index = rp.PopRaw(); + + LOG_DEBUG(Service_FS, "called, program_index={}", program_index); + + auto patched_romfs = romfs_controller->OpenPatchedRomFSWithProgramIndex( + program_id, program_index, FileSys::ContentRecordType::Program); + + if (!patched_romfs) { + // TODO: Find the right error code to use here + LOG_ERROR(Service_FS, "could not open storage with program_index={}", program_index); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + + auto storage = std::make_shared(system, std::move(patched_romfs)); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::move(storage)); +} + +void FSP_SRV::DisableAutoSaveDataCreation(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + save_data_controller->SetAutoCreate(false); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void FSP_SRV::SetGlobalAccessLogMode(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + access_log_mode = rp.PopEnum(); + + LOG_DEBUG(Service_FS, "called, access_log_mode={}", access_log_mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void FSP_SRV::GetGlobalAccessLogMode(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(access_log_mode); +} + +void FSP_SRV::OutputAccessLogToSdCard(HLERequestContext& ctx) { + const auto raw = ctx.ReadBufferCopy(); + auto log = Common::StringFromFixedZeroTerminatedBuffer( + reinterpret_cast(raw.data()), raw.size()); + + LOG_DEBUG(Service_FS, "called"); + + reporter.SaveFSAccessLog(log); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void FSP_SRV::GetProgramIndexForAccessLog(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(ResultSuccess); + rb.PushEnum(AccessLogVersion::Latest); + rb.Push(access_log_program_index); +} + +void FSP_SRV::GetCacheStorageSize(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto index{rp.Pop()}; + + LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index); + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.Push(s64{0}); + rb.Push(s64{0}); +} + +class IMultiCommitManager final : public ServiceFramework { +public: + explicit IMultiCommitManager(Core::System& system_) + : ServiceFramework{system_, "IMultiCommitManager"} { + static const FunctionInfo functions[] = { + {1, &IMultiCommitManager::Add, "Add"}, + {2, &IMultiCommitManager::Commit, "Commit"}, + }; + RegisterHandlers(functions); + } + +private: + FileSys::VirtualFile backend; + + void Add(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Commit(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } +}; + +void FSP_SRV::OpenMultiCommitManager(HLERequestContext& ctx) { + LOG_DEBUG(Service_FS, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(std::make_shared(system)); +} + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h new file mode 100644 index 000000000..26980af99 --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "core/hle/service/service.h" + +namespace Core { +class Reporter; +} + +namespace FileSys { +class ContentProvider; +class FileSystemBackend; +} // namespace FileSys + +namespace Service::FileSystem { + +class RomFsController; +class SaveDataController; + +enum class AccessLogVersion : u32 { + V7_0_0 = 2, + + Latest = V7_0_0, +}; + +enum class AccessLogMode : u32 { + None, + Log, + SdCard, +}; + +class FSP_SRV final : public ServiceFramework { +public: + explicit FSP_SRV(Core::System& system_); + ~FSP_SRV() override; + +private: + void SetCurrentProcess(HLERequestContext& ctx); + void OpenFileSystemWithPatch(HLERequestContext& ctx); + void OpenSdCardFileSystem(HLERequestContext& ctx); + void CreateSaveDataFileSystem(HLERequestContext& ctx); + void CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); + void OpenSaveDataFileSystem(HLERequestContext& ctx); + void OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); + void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); + void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); + void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); + void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx); + void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx); + void OpenDataStorageByCurrentProcess(HLERequestContext& ctx); + void OpenDataStorageByDataId(HLERequestContext& ctx); + void OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx); + void OpenDataStorageWithProgramIndex(HLERequestContext& ctx); + void DisableAutoSaveDataCreation(HLERequestContext& ctx); + void SetGlobalAccessLogMode(HLERequestContext& ctx); + void GetGlobalAccessLogMode(HLERequestContext& ctx); + void OutputAccessLogToSdCard(HLERequestContext& ctx); + void GetProgramIndexForAccessLog(HLERequestContext& ctx); + void OpenMultiCommitManager(HLERequestContext& ctx); + void GetCacheStorageSize(HLERequestContext& ctx); + + FileSystemController& fsc; + const FileSys::ContentProvider& content_provider; + const Core::Reporter& reporter; + + FileSys::VirtualFile romfs; + u64 current_process_id = 0; + u32 access_log_program_index = 0; + AccessLogMode access_log_mode = AccessLogMode::None; + u64 program_id = 0; + std::shared_ptr save_data_controller; + std::shared_ptr romfs_controller; +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp/fsp_util.h b/src/core/hle/service/filesystem/fsp/fsp_util.h new file mode 100644 index 000000000..253f866db --- /dev/null +++ b/src/core/hle/service/filesystem/fsp/fsp_util.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/filesystem/filesystem.h" + +namespace Service::FileSystem { + +struct SizeGetter { + std::function get_free_size; + std::function get_total_size; + + static SizeGetter FromStorageId(const FileSystemController& fsc, FileSys::StorageId id) { + return { + [&fsc, id] { return fsc.GetFreeSpaceSize(id); }, + [&fsc, id] { return fsc.GetTotalSpaceSize(id); }, + }; + } +}; + +} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp deleted file mode 100644 index 1e3366e71..000000000 --- a/src/core/hle/service/filesystem/fsp_ldr.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/filesystem/fsp_ldr.h" - -namespace Service::FileSystem { - -FSP_LDR::FSP_LDR(Core::System& system_) : ServiceFramework{system_, "fsp:ldr"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "OpenCodeFileSystem"}, - {1, nullptr, "IsArchivedProgram"}, - {2, nullptr, "SetCurrentProcess"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -FSP_LDR::~FSP_LDR() = default; - -} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_ldr.h b/src/core/hle/service/filesystem/fsp_ldr.h deleted file mode 100644 index 358739a87..000000000 --- a/src/core/hle/service/filesystem/fsp_ldr.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service::FileSystem { - -class FSP_LDR final : public ServiceFramework { -public: - explicit FSP_LDR(Core::System& system_); - ~FSP_LDR() override; -}; - -} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp deleted file mode 100644 index 4ffc31977..000000000 --- a/src/core/hle/service/filesystem/fsp_pr.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/filesystem/fsp_pr.h" - -namespace Service::FileSystem { - -FSP_PR::FSP_PR(Core::System& system_) : ServiceFramework{system_, "fsp:pr"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "RegisterProgram"}, - {1, nullptr, "UnregisterProgram"}, - {2, nullptr, "SetCurrentProcess"}, - {256, nullptr, "SetEnabledProgramVerification"}, - }; - // clang-format on - - RegisterHandlers(functions); -} - -FSP_PR::~FSP_PR() = default; - -} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_pr.h b/src/core/hle/service/filesystem/fsp_pr.h deleted file mode 100644 index bd4e0a730..000000000 --- a/src/core/hle/service/filesystem/fsp_pr.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Service::FileSystem { - -class FSP_PR final : public ServiceFramework { -public: - explicit FSP_PR(Core::System& system_); - ~FSP_PR() override; -}; - -} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp deleted file mode 100644 index a2397bec4..000000000 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ /dev/null @@ -1,1257 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include -#include -#include - -#include "common/assert.h" -#include "common/common_types.h" -#include "common/hex_util.h" -#include "common/logging/log.h" -#include "common/settings.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/file_sys/directory.h" -#include "core/file_sys/errors.h" -#include "core/file_sys/mode.h" -#include "core/file_sys/nca_metadata.h" -#include "core/file_sys/patch_manager.h" -#include "core/file_sys/romfs_factory.h" -#include "core/file_sys/savedata_factory.h" -#include "core/file_sys/system_archive/system_archive.h" -#include "core/file_sys/vfs.h" -#include "core/hle/result.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/filesystem/fsp_srv.h" -#include "core/hle/service/filesystem/romfs_controller.h" -#include "core/hle/service/filesystem/save_data_controller.h" -#include "core/hle/service/hle_ipc.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/reporter.h" - -namespace Service::FileSystem { - -struct SizeGetter { - std::function get_free_size; - std::function get_total_size; - - static SizeGetter FromStorageId(const FileSystemController& fsc, FileSys::StorageId id) { - return { - [&fsc, id] { return fsc.GetFreeSpaceSize(id); }, - [&fsc, id] { return fsc.GetTotalSpaceSize(id); }, - }; - } -}; - -enum class FileSystemType : u8 { - Invalid0 = 0, - Invalid1 = 1, - Logo = 2, - ContentControl = 3, - ContentManual = 4, - ContentMeta = 5, - ContentData = 6, - ApplicationPackage = 7, -}; - -class IStorage final : public ServiceFramework { -public: - explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_) - : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) { - static const FunctionInfo functions[] = { - {0, &IStorage::Read, "Read"}, - {1, nullptr, "Write"}, - {2, nullptr, "Flush"}, - {3, nullptr, "SetSize"}, - {4, &IStorage::GetSize, "GetSize"}, - {5, nullptr, "OperateRange"}, - }; - RegisterHandlers(functions); - } - -private: - FileSys::VirtualFile backend; - - void Read(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const s64 offset = rp.Pop(); - const s64 length = rp.Pop(); - - LOG_DEBUG(Service_FS, "called, offset=0x{:X}, length={}", offset, length); - - // Error checking - if (length < 0) { - LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_INVALID_SIZE); - return; - } - if (offset < 0) { - LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_INVALID_OFFSET); - return; - } - - // Read the data from the Storage backend - std::vector output = backend->ReadBytes(length, offset); - // Write the data to memory - ctx.WriteBuffer(output); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetSize(HLERequestContext& ctx) { - const u64 size = backend->GetSize(); - LOG_DEBUG(Service_FS, "called, size={}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(size); - } -}; - -class IFile final : public ServiceFramework { -public: - explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) - : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) { - static const FunctionInfo functions[] = { - {0, &IFile::Read, "Read"}, - {1, &IFile::Write, "Write"}, - {2, &IFile::Flush, "Flush"}, - {3, &IFile::SetSize, "SetSize"}, - {4, &IFile::GetSize, "GetSize"}, - {5, nullptr, "OperateRange"}, - {6, nullptr, "OperateRangeWithBuffer"}, - }; - RegisterHandlers(functions); - } - -private: - FileSys::VirtualFile backend; - - void Read(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const u64 option = rp.Pop(); - const s64 offset = rp.Pop(); - const s64 length = rp.Pop(); - - LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, - length); - - // Error checking - if (length < 0) { - LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_INVALID_SIZE); - return; - } - if (offset < 0) { - LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_INVALID_OFFSET); - return; - } - - // Read the data from the Storage backend - std::vector output = backend->ReadBytes(length, offset); - - // Write the data to memory - ctx.WriteBuffer(output); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(static_cast(output.size())); - } - - void Write(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const u64 option = rp.Pop(); - const s64 offset = rp.Pop(); - const s64 length = rp.Pop(); - - LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, - length); - - // Error checking - if (length < 0) { - LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_INVALID_SIZE); - return; - } - if (offset < 0) { - LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_INVALID_OFFSET); - return; - } - - const auto data = ctx.ReadBuffer(); - - ASSERT_MSG( - static_cast(data.size()) <= length, - "Attempting to write more data than requested (requested={:016X}, actual={:016X}).", - length, data.size()); - - // Write the data to the Storage backend - const auto write_size = - static_cast(std::distance(data.begin(), data.begin() + length)); - const std::size_t written = backend->Write(data.data(), write_size, offset); - - ASSERT_MSG(static_cast(written) == length, - "Could not write all bytes to file (requested={:016X}, actual={:016X}).", length, - written); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void Flush(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - // Exists for SDK compatibiltity -- No need to flush file. - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void SetSize(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const u64 size = rp.Pop(); - LOG_DEBUG(Service_FS, "called, size={}", size); - - backend->Resize(size); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetSize(HLERequestContext& ctx) { - const u64 size = backend->GetSize(); - LOG_DEBUG(Service_FS, "called, size={}", size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(size); - } -}; - -template -static void BuildEntryIndex(std::vector& entries, const std::vector& new_data, - FileSys::EntryType type) { - entries.reserve(entries.size() + new_data.size()); - - for (const auto& new_entry : new_data) { - auto name = new_entry->GetName(); - - if (type == FileSys::EntryType::File && name == FileSys::GetSaveDataSizeFileName()) { - continue; - } - - entries.emplace_back(name, type, - type == FileSys::EntryType::Directory ? 0 : new_entry->GetSize()); - } -} - -class IDirectory final : public ServiceFramework { -public: - explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_, OpenDirectoryMode mode) - : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) { - static const FunctionInfo functions[] = { - {0, &IDirectory::Read, "Read"}, - {1, &IDirectory::GetEntryCount, "GetEntryCount"}, - }; - RegisterHandlers(functions); - - // TODO(DarkLordZach): Verify that this is the correct behavior. - // Build entry index now to save time later. - if (True(mode & OpenDirectoryMode::Directory)) { - BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::EntryType::Directory); - } - if (True(mode & OpenDirectoryMode::File)) { - BuildEntryIndex(entries, backend->GetFiles(), FileSys::EntryType::File); - } - } - -private: - FileSys::VirtualDir backend; - std::vector entries; - u64 next_entry_index = 0; - - void Read(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called."); - - // Calculate how many entries we can fit in the output buffer - const u64 count_entries = ctx.GetWriteBufferNumElements(); - - // Cap at total number of entries. - const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); - - // Determine data start and end - const auto* begin = reinterpret_cast(entries.data() + next_entry_index); - const auto* end = reinterpret_cast(entries.data() + next_entry_index + actual_entries); - const auto range_size = static_cast(std::distance(begin, end)); - - next_entry_index += actual_entries; - - // Write the data to memory - ctx.WriteBuffer(begin, range_size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(actual_entries); - } - - void GetEntryCount(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - u64 count = entries.size() - next_entry_index; - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(count); - } -}; - -class IFileSystem final : public ServiceFramework { -public: - explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) - : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move( - size_)} { - static const FunctionInfo functions[] = { - {0, &IFileSystem::CreateFile, "CreateFile"}, - {1, &IFileSystem::DeleteFile, "DeleteFile"}, - {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, - {3, &IFileSystem::DeleteDirectory, "DeleteDirectory"}, - {4, &IFileSystem::DeleteDirectoryRecursively, "DeleteDirectoryRecursively"}, - {5, &IFileSystem::RenameFile, "RenameFile"}, - {6, nullptr, "RenameDirectory"}, - {7, &IFileSystem::GetEntryType, "GetEntryType"}, - {8, &IFileSystem::OpenFile, "OpenFile"}, - {9, &IFileSystem::OpenDirectory, "OpenDirectory"}, - {10, &IFileSystem::Commit, "Commit"}, - {11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"}, - {12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"}, - {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, - {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"}, - {15, nullptr, "QueryEntry"}, - {16, &IFileSystem::GetFileSystemAttribute, "GetFileSystemAttribute"}, - }; - RegisterHandlers(functions); - } - - void CreateFile(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - const u64 file_mode = rp.Pop(); - const u32 file_size = rp.Pop(); - - LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, file_mode, - file_size); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateFile(name, file_size)); - } - - void DeleteFile(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. file={}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteFile(name)); - } - - void CreateDirectory(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. directory={}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateDirectory(name)); - } - - void DeleteDirectory(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. directory={}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteDirectory(name)); - } - - void DeleteDirectoryRecursively(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. directory={}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteDirectoryRecursively(name)); - } - - void CleanDirectoryRecursively(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. Directory: {}", name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CleanDirectoryRecursively(name)); - } - - void RenameFile(HLERequestContext& ctx) { - const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0)); - const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1)); - - LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.RenameFile(src_name, dst_name)); - } - - void OpenFile(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - const auto mode = static_cast(rp.Pop()); - - LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, mode); - - FileSys::VirtualFile vfs_file{}; - auto result = backend.OpenFile(&vfs_file, name, mode); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - auto file = std::make_shared(system, vfs_file); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(file)); - } - - void OpenDirectory(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - const auto mode = rp.PopRaw(); - - LOG_DEBUG(Service_FS, "called. directory={}, mode={}", name, mode); - - FileSys::VirtualDir vfs_dir{}; - auto result = backend.OpenDirectory(&vfs_dir, name); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - auto directory = std::make_shared(system, vfs_dir, mode); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(directory)); - } - - void GetEntryType(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_DEBUG(Service_FS, "called. file={}", name); - - FileSys::EntryType vfs_entry_type{}; - auto result = backend.GetEntryType(&vfs_entry_type, name); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(vfs_entry_type)); - } - - void Commit(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetFreeSpaceSize(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(size.get_free_size()); - } - - void GetTotalSpaceSize(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(size.get_total_size()); - } - - void GetFileTimeStampRaw(HLERequestContext& ctx) { - const auto file_buffer = ctx.ReadBuffer(); - const std::string name = Common::StringFromBuffer(file_buffer); - - LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", name); - - FileSys::FileTimeStampRaw vfs_timestamp{}; - auto result = backend.GetFileTimeStampRaw(&vfs_timestamp, name); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result); - return; - } - - IPC::ResponseBuilder rb{ctx, 10}; - rb.Push(ResultSuccess); - rb.PushRaw(vfs_timestamp); - } - - void GetFileSystemAttribute(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); - - struct FileSystemAttribute { - u8 dir_entry_name_length_max_defined; - u8 file_entry_name_length_max_defined; - u8 dir_path_name_length_max_defined; - u8 file_path_name_length_max_defined; - INSERT_PADDING_BYTES_NOINIT(0x5); - u8 utf16_dir_entry_name_length_max_defined; - u8 utf16_file_entry_name_length_max_defined; - u8 utf16_dir_path_name_length_max_defined; - u8 utf16_file_path_name_length_max_defined; - INSERT_PADDING_BYTES_NOINIT(0x18); - s32 dir_entry_name_length_max; - s32 file_entry_name_length_max; - s32 dir_path_name_length_max; - s32 file_path_name_length_max; - INSERT_PADDING_WORDS_NOINIT(0x5); - s32 utf16_dir_entry_name_length_max; - s32 utf16_file_entry_name_length_max; - s32 utf16_dir_path_name_length_max; - s32 utf16_file_path_name_length_max; - INSERT_PADDING_WORDS_NOINIT(0x18); - INSERT_PADDING_WORDS_NOINIT(0x1); - }; - static_assert(sizeof(FileSystemAttribute) == 0xc0, - "FileSystemAttribute has incorrect size"); - - FileSystemAttribute savedata_attribute{}; - savedata_attribute.dir_entry_name_length_max_defined = true; - savedata_attribute.file_entry_name_length_max_defined = true; - savedata_attribute.dir_entry_name_length_max = 0x40; - savedata_attribute.file_entry_name_length_max = 0x40; - - IPC::ResponseBuilder rb{ctx, 50}; - rb.Push(ResultSuccess); - rb.PushRaw(savedata_attribute); - } - -private: - VfsDirectoryServiceWrapper backend; - SizeGetter size; -}; - -class ISaveDataInfoReader final : public ServiceFramework { -public: - explicit ISaveDataInfoReader(Core::System& system_, - std::shared_ptr save_data_controller_, - FileSys::SaveDataSpaceId space) - : ServiceFramework{system_, "ISaveDataInfoReader"}, save_data_controller{ - save_data_controller_} { - static const FunctionInfo functions[] = { - {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"}, - }; - RegisterHandlers(functions); - - FindAllSaves(space); - } - - void ReadSaveDataInfo(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - // Calculate how many entries we can fit in the output buffer - const u64 count_entries = ctx.GetWriteBufferNumElements(); - - // Cap at total number of entries. - const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index); - - // Determine data start and end - const auto* begin = reinterpret_cast(info.data() + next_entry_index); - const auto* end = reinterpret_cast(info.data() + next_entry_index + actual_entries); - const auto range_size = static_cast(std::distance(begin, end)); - - next_entry_index += actual_entries; - - // Write the data to memory - ctx.WriteBuffer(begin, range_size); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.Push(actual_entries); - } - -private: - static u64 stoull_be(std::string_view str) { - if (str.size() != 16) - return 0; - - const auto bytes = Common::HexStringToArray<0x8>(str); - u64 out{}; - std::memcpy(&out, bytes.data(), sizeof(u64)); - - return Common::swap64(out); - } - - void FindAllSaves(FileSys::SaveDataSpaceId space) { - FileSys::VirtualDir save_root{}; - const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space); - - if (result != ResultSuccess || save_root == nullptr) { - LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space); - return; - } - - for (const auto& type : save_root->GetSubdirectories()) { - if (type->GetName() == "save") { - for (const auto& save_id : type->GetSubdirectories()) { - for (const auto& user_id : save_id->GetSubdirectories()) { - const auto save_id_numeric = stoull_be(save_id->GetName()); - auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); - std::reverse(user_id_numeric.begin(), user_id_numeric.end()); - - if (save_id_numeric != 0) { - // System Save Data - info.emplace_back(SaveDataInfo{ - 0, - space, - FileSys::SaveDataType::SystemSaveData, - {}, - user_id_numeric, - save_id_numeric, - 0, - user_id->GetSize(), - {}, - {}, - }); - - continue; - } - - for (const auto& title_id : user_id->GetSubdirectories()) { - const auto device = - std::all_of(user_id_numeric.begin(), user_id_numeric.end(), - [](u8 val) { return val == 0; }); - info.emplace_back(SaveDataInfo{ - 0, - space, - device ? FileSys::SaveDataType::DeviceSaveData - : FileSys::SaveDataType::SaveData, - {}, - user_id_numeric, - save_id_numeric, - stoull_be(title_id->GetName()), - title_id->GetSize(), - {}, - {}, - }); - } - } - } - } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { - // Temporary Storage - for (const auto& user_id : type->GetSubdirectories()) { - for (const auto& title_id : user_id->GetSubdirectories()) { - if (!title_id->GetFiles().empty() || - !title_id->GetSubdirectories().empty()) { - auto user_id_numeric = - Common::HexStringToArray<0x10>(user_id->GetName()); - std::reverse(user_id_numeric.begin(), user_id_numeric.end()); - - info.emplace_back(SaveDataInfo{ - 0, - space, - FileSys::SaveDataType::TemporaryStorage, - {}, - user_id_numeric, - stoull_be(type->GetName()), - stoull_be(title_id->GetName()), - title_id->GetSize(), - {}, - {}, - }); - } - } - } - } - } - } - - struct SaveDataInfo { - u64_le save_id_unknown; - FileSys::SaveDataSpaceId space; - FileSys::SaveDataType type; - INSERT_PADDING_BYTES(0x6); - std::array user_id; - u64_le save_id; - u64_le title_id; - u64_le save_image_size; - u16_le index; - FileSys::SaveDataRank rank; - INSERT_PADDING_BYTES(0x25); - }; - static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size."); - - ProcessId process_id = 0; - std::shared_ptr save_data_controller; - std::vector info; - u64 next_entry_index = 0; -}; - -FSP_SRV::FSP_SRV(Core::System& system_) - : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()}, - content_provider{system.GetContentProvider()}, reporter{system.GetReporter()} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "OpenFileSystem"}, - {1, &FSP_SRV::SetCurrentProcess, "SetCurrentProcess"}, - {2, nullptr, "OpenDataFileSystemByCurrentProcess"}, - {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"}, - {8, nullptr, "OpenFileSystemWithId"}, - {9, nullptr, "OpenDataFileSystemByApplicationId"}, - {11, nullptr, "OpenBisFileSystem"}, - {12, nullptr, "OpenBisStorage"}, - {13, nullptr, "InvalidateBisCache"}, - {17, nullptr, "OpenHostFileSystem"}, - {18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"}, - {19, nullptr, "FormatSdCardFileSystem"}, - {21, nullptr, "DeleteSaveDataFileSystem"}, - {22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"}, - {23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"}, - {24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"}, - {25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"}, - {26, nullptr, "FormatSdCardDryRun"}, - {27, nullptr, "IsExFatSupported"}, - {28, nullptr, "DeleteSaveDataFileSystemBySaveDataAttribute"}, - {30, nullptr, "OpenGameCardStorage"}, - {31, nullptr, "OpenGameCardFileSystem"}, - {32, nullptr, "ExtendSaveDataFileSystem"}, - {33, nullptr, "DeleteCacheStorage"}, - {34, &FSP_SRV::GetCacheStorageSize, "GetCacheStorageSize"}, - {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, - {36, nullptr, "OpenHostFileSystemWithOption"}, - {51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"}, - {52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"}, - {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"}, - {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, - {58, nullptr, "ReadSaveDataFileSystemExtraData"}, - {59, nullptr, "WriteSaveDataFileSystemExtraData"}, - {60, nullptr, "OpenSaveDataInfoReader"}, - {61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, - {62, &FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage, "OpenSaveDataInfoReaderOnlyCacheStorage"}, - {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, - {65, nullptr, "UpdateSaveDataMacForDebug"}, - {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, - {67, nullptr, "FindSaveDataWithFilter"}, - {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, - {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, - {70, &FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"}, - {71, &FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, - {80, nullptr, "OpenSaveDataMetaFile"}, - {81, nullptr, "OpenSaveDataTransferManager"}, - {82, nullptr, "OpenSaveDataTransferManagerVersion2"}, - {83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"}, - {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"}, - {85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"}, - {86, nullptr, "OpenSaveDataMover"}, - {87, nullptr, "OpenSaveDataTransferManagerForRepair"}, - {100, nullptr, "OpenImageDirectoryFileSystem"}, - {101, nullptr, "OpenBaseFileSystem"}, - {102, nullptr, "FormatBaseFileSystem"}, - {110, nullptr, "OpenContentStorageFileSystem"}, - {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, - {130, nullptr, "OpenCustomStorageFileSystem"}, - {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, - {201, nullptr, "OpenDataStorageByProgramId"}, - {202, &FSP_SRV::OpenDataStorageByDataId, "OpenDataStorageByDataId"}, - {203, &FSP_SRV::OpenPatchDataStorageByCurrentProcess, "OpenPatchDataStorageByCurrentProcess"}, - {204, nullptr, "OpenDataFileSystemByProgramIndex"}, - {205, &FSP_SRV::OpenDataStorageWithProgramIndex, "OpenDataStorageWithProgramIndex"}, - {206, nullptr, "OpenDataStorageByPath"}, - {400, nullptr, "OpenDeviceOperator"}, - {500, nullptr, "OpenSdCardDetectionEventNotifier"}, - {501, nullptr, "OpenGameCardDetectionEventNotifier"}, - {510, nullptr, "OpenSystemDataUpdateEventNotifier"}, - {511, nullptr, "NotifySystemDataUpdateEvent"}, - {520, nullptr, "SimulateGameCardDetectionEvent"}, - {600, nullptr, "SetCurrentPosixTime"}, - {601, nullptr, "QuerySaveDataTotalSize"}, - {602, nullptr, "VerifySaveDataFileSystem"}, - {603, nullptr, "CorruptSaveDataFileSystem"}, - {604, nullptr, "CreatePaddingFile"}, - {605, nullptr, "DeleteAllPaddingFiles"}, - {606, nullptr, "GetRightsId"}, - {607, nullptr, "RegisterExternalKey"}, - {608, nullptr, "UnregisterAllExternalKey"}, - {609, nullptr, "GetRightsIdByPath"}, - {610, nullptr, "GetRightsIdAndKeyGenerationByPath"}, - {611, nullptr, "SetCurrentPosixTimeWithTimeDifference"}, - {612, nullptr, "GetFreeSpaceSizeForSaveData"}, - {613, nullptr, "VerifySaveDataFileSystemBySaveDataSpaceId"}, - {614, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId"}, - {615, nullptr, "QuerySaveDataInternalStorageTotalSize"}, - {616, nullptr, "GetSaveDataCommitId"}, - {617, nullptr, "UnregisterExternalKey"}, - {620, nullptr, "SetSdCardEncryptionSeed"}, - {630, nullptr, "SetSdCardAccessibility"}, - {631, nullptr, "IsSdCardAccessible"}, - {640, nullptr, "IsSignedSystemPartitionOnSdCardValid"}, - {700, nullptr, "OpenAccessFailureResolver"}, - {701, nullptr, "GetAccessFailureDetectionEvent"}, - {702, nullptr, "IsAccessFailureDetected"}, - {710, nullptr, "ResolveAccessFailure"}, - {720, nullptr, "AbandonAccessFailure"}, - {800, nullptr, "GetAndClearFileSystemProxyErrorInfo"}, - {810, nullptr, "RegisterProgramIndexMapInfo"}, - {1000, nullptr, "SetBisRootForHost"}, - {1001, nullptr, "SetSaveDataSize"}, - {1002, nullptr, "SetSaveDataRootPath"}, - {1003, &FSP_SRV::DisableAutoSaveDataCreation, "DisableAutoSaveDataCreation"}, - {1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"}, - {1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"}, - {1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"}, - {1007, nullptr, "RegisterUpdatePartition"}, - {1008, nullptr, "OpenRegisteredUpdatePartition"}, - {1009, nullptr, "GetAndClearMemoryReportInfo"}, - {1010, nullptr, "SetDataStorageRedirectTarget"}, - {1011, &FSP_SRV::GetProgramIndexForAccessLog, "GetProgramIndexForAccessLog"}, - {1012, nullptr, "GetFsStackUsage"}, - {1013, nullptr, "UnsetSaveDataRootPath"}, - {1014, nullptr, "OutputMultiProgramTagAccessLog"}, - {1016, nullptr, "FlushAccessLogOnSdCard"}, - {1017, nullptr, "OutputApplicationInfoAccessLog"}, - {1018, nullptr, "SetDebugOption"}, - {1019, nullptr, "UnsetDebugOption"}, - {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, - {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, - {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"}, - {1300, nullptr, "OpenBisWiper"}, - }; - // clang-format on - RegisterHandlers(functions); - - if (Settings::values.enable_fs_access_log) { - access_log_mode = AccessLogMode::SdCard; - } -} - -FSP_SRV::~FSP_SRV() = default; - -void FSP_SRV::SetCurrentProcess(HLERequestContext& ctx) { - current_process_id = ctx.GetPID(); - - LOG_DEBUG(Service_FS, "called. current_process_id=0x{:016X}", current_process_id); - - const auto res = - fsc.OpenProcess(&program_id, &save_data_controller, &romfs_controller, current_process_id); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(res); -} - -void FSP_SRV::OpenFileSystemWithPatch(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto type = rp.PopRaw(); - const auto title_id = rp.PopRaw(); - LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}", type, title_id); - - IPC::ResponseBuilder rb{ctx, 2, 0, 0}; - rb.Push(ResultUnknown); -} - -void FSP_SRV::OpenSdCardFileSystem(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - FileSys::VirtualDir sdmc_dir{}; - fsc.OpenSDMC(&sdmc_dir); - - auto filesystem = std::make_shared( - system, sdmc_dir, SizeGetter::FromStorageId(fsc, FileSys::StorageId::SdCard)); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(filesystem)); -} - -void FSP_SRV::CreateSaveDataFileSystem(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto save_struct = rp.PopRaw(); - [[maybe_unused]] auto save_create_struct = rp.PopRaw>(); - u128 uid = rp.PopRaw(); - - LOG_DEBUG(Service_FS, "called save_struct = {}, uid = {:016X}{:016X}", save_struct.DebugInfo(), - uid[1], uid[0]); - - FileSys::VirtualDir save_data_dir{}; - save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandUser, - save_struct); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - auto save_struct = rp.PopRaw(); - [[maybe_unused]] auto save_create_struct = rp.PopRaw>(); - - LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo()); - - FileSys::VirtualDir save_data_dir{}; - save_data_controller->CreateSaveData(&save_data_dir, FileSys::SaveDataSpaceId::NandSystem, - save_struct); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void FSP_SRV::OpenSaveDataFileSystem(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - struct Parameters { - FileSys::SaveDataSpaceId space_id; - FileSys::SaveDataAttribute attribute; - }; - - const auto parameters = rp.PopRaw(); - - LOG_INFO(Service_FS, "called."); - - FileSys::VirtualDir dir{}; - auto result = - save_data_controller->OpenSaveData(&dir, parameters.space_id, parameters.attribute); - if (result != ResultSuccess) { - IPC::ResponseBuilder rb{ctx, 2, 0, 0}; - rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); - return; - } - - FileSys::StorageId id{}; - switch (parameters.space_id) { - case FileSys::SaveDataSpaceId::NandUser: - id = FileSys::StorageId::NandUser; - break; - case FileSys::SaveDataSpaceId::SdCardSystem: - case FileSys::SaveDataSpaceId::SdCardUser: - id = FileSys::StorageId::SdCard; - break; - case FileSys::SaveDataSpaceId::NandSystem: - id = FileSys::StorageId::NandSystem; - break; - case FileSys::SaveDataSpaceId::TemporaryStorage: - case FileSys::SaveDataSpaceId::ProperSystem: - case FileSys::SaveDataSpaceId::SafeMode: - ASSERT(false); - } - - auto filesystem = - std::make_shared(system, std::move(dir), SizeGetter::FromStorageId(fsc, id)); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(filesystem)); -} - -void FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); - OpenSaveDataFileSystem(ctx); -} - -void FSP_SRV::OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem"); - OpenSaveDataFileSystem(ctx); -} - -void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto space = rp.PopRaw(); - LOG_INFO(Service_FS, "called, space={}", space); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface( - std::make_shared(system, save_data_controller, space)); -} - -void FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system, save_data_controller, - FileSys::SaveDataSpaceId::TemporaryStorage); -} - -void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called."); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - struct Parameters { - FileSys::SaveDataSpaceId space_id; - FileSys::SaveDataAttribute attribute; - }; - - const auto parameters = rp.PopRaw(); - // Stub this to None for now, backend needs an impl to read/write the SaveDataExtraData - constexpr auto flags = static_cast(FileSys::SaveDataFlags::None); - - LOG_WARNING(Service_FS, - "(STUBBED) called, flags={}, space_id={}, attribute.title_id={:016X}\n" - "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" - "attribute.type={}, attribute.rank={}, attribute.index={}", - flags, parameters.space_id, parameters.attribute.title_id, - parameters.attribute.user_id[1], parameters.attribute.user_id[0], - parameters.attribute.save_id, parameters.attribute.type, parameters.attribute.rank, - parameters.attribute.index); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(flags); -} - -void FSP_SRV::OpenDataStorageByCurrentProcess(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - if (!romfs) { - auto current_romfs = romfs_controller->OpenRomFSCurrentProcess(); - if (!current_romfs) { - // TODO (bunnei): Find the right error code to use here - LOG_CRITICAL(Service_FS, "no file system interface available!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultUnknown); - return; - } - - romfs = current_romfs; - } - - auto storage = std::make_shared(system, romfs); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(storage)); -} - -void FSP_SRV::OpenDataStorageByDataId(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto storage_id = rp.PopRaw(); - const auto unknown = rp.PopRaw(); - const auto title_id = rp.PopRaw(); - - LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}", - storage_id, unknown, title_id); - - auto data = romfs_controller->OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data); - - if (!data) { - const auto archive = FileSys::SystemArchive::SynthesizeSystemArchive(title_id); - - if (archive != nullptr) { - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::make_shared(system, archive)); - return; - } - - // TODO(DarkLordZach): Find the right error code to use here - LOG_ERROR(Service_FS, - "could not open data storage with title_id={:016X}, storage_id={:02X}", title_id, - storage_id); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultUnknown); - return; - } - - const FileSys::PatchManager pm{title_id, fsc, content_provider}; - - auto base = - romfs_controller->OpenBaseNca(title_id, storage_id, FileSys::ContentRecordType::Data); - auto storage = std::make_shared( - system, pm.PatchRomFS(base.get(), std::move(data), FileSys::ContentRecordType::Data)); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(storage)); -} - -void FSP_SRV::OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto storage_id = rp.PopRaw(); - const auto title_id = rp.PopRaw(); - - LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}", storage_id, title_id); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); -} - -void FSP_SRV::OpenDataStorageWithProgramIndex(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto program_index = rp.PopRaw(); - - LOG_DEBUG(Service_FS, "called, program_index={}", program_index); - - auto patched_romfs = romfs_controller->OpenPatchedRomFSWithProgramIndex( - program_id, program_index, FileSys::ContentRecordType::Program); - - if (!patched_romfs) { - // TODO: Find the right error code to use here - LOG_ERROR(Service_FS, "could not open storage with program_index={}", program_index); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultUnknown); - return; - } - - auto storage = std::make_shared(system, std::move(patched_romfs)); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::move(storage)); -} - -void FSP_SRV::DisableAutoSaveDataCreation(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - save_data_controller->SetAutoCreate(false); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void FSP_SRV::SetGlobalAccessLogMode(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - access_log_mode = rp.PopEnum(); - - LOG_DEBUG(Service_FS, "called, access_log_mode={}", access_log_mode); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void FSP_SRV::GetGlobalAccessLogMode(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(access_log_mode); -} - -void FSP_SRV::OutputAccessLogToSdCard(HLERequestContext& ctx) { - const auto raw = ctx.ReadBufferCopy(); - auto log = Common::StringFromFixedZeroTerminatedBuffer( - reinterpret_cast(raw.data()), raw.size()); - - LOG_DEBUG(Service_FS, "called"); - - reporter.SaveFSAccessLog(log); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void FSP_SRV::GetProgramIndexForAccessLog(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.PushEnum(AccessLogVersion::Latest); - rb.Push(access_log_program_index); -} - -void FSP_SRV::GetCacheStorageSize(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto index{rp.Pop()}; - - LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index); - - IPC::ResponseBuilder rb{ctx, 6}; - rb.Push(ResultSuccess); - rb.Push(s64{0}); - rb.Push(s64{0}); -} - -class IMultiCommitManager final : public ServiceFramework { -public: - explicit IMultiCommitManager(Core::System& system_) - : ServiceFramework{system_, "IMultiCommitManager"} { - static const FunctionInfo functions[] = { - {1, &IMultiCommitManager::Add, "Add"}, - {2, &IMultiCommitManager::Commit, "Commit"}, - }; - RegisterHandlers(functions); - } - -private: - FileSys::VirtualFile backend; - - void Add(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void Commit(HLERequestContext& ctx) { - LOG_WARNING(Service_FS, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } -}; - -void FSP_SRV::OpenMultiCommitManager(HLERequestContext& ctx) { - LOG_DEBUG(Service_FS, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(std::make_shared(system)); -} - -} // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h deleted file mode 100644 index 26980af99..000000000 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "core/hle/service/service.h" - -namespace Core { -class Reporter; -} - -namespace FileSys { -class ContentProvider; -class FileSystemBackend; -} // namespace FileSys - -namespace Service::FileSystem { - -class RomFsController; -class SaveDataController; - -enum class AccessLogVersion : u32 { - V7_0_0 = 2, - - Latest = V7_0_0, -}; - -enum class AccessLogMode : u32 { - None, - Log, - SdCard, -}; - -class FSP_SRV final : public ServiceFramework { -public: - explicit FSP_SRV(Core::System& system_); - ~FSP_SRV() override; - -private: - void SetCurrentProcess(HLERequestContext& ctx); - void OpenFileSystemWithPatch(HLERequestContext& ctx); - void OpenSdCardFileSystem(HLERequestContext& ctx); - void CreateSaveDataFileSystem(HLERequestContext& ctx); - void CreateSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); - void OpenSaveDataFileSystem(HLERequestContext& ctx); - void OpenSaveDataFileSystemBySystemSaveDataId(HLERequestContext& ctx); - void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); - void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); - void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); - void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx); - void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx); - void OpenDataStorageByCurrentProcess(HLERequestContext& ctx); - void OpenDataStorageByDataId(HLERequestContext& ctx); - void OpenPatchDataStorageByCurrentProcess(HLERequestContext& ctx); - void OpenDataStorageWithProgramIndex(HLERequestContext& ctx); - void DisableAutoSaveDataCreation(HLERequestContext& ctx); - void SetGlobalAccessLogMode(HLERequestContext& ctx); - void GetGlobalAccessLogMode(HLERequestContext& ctx); - void OutputAccessLogToSdCard(HLERequestContext& ctx); - void GetProgramIndexForAccessLog(HLERequestContext& ctx); - void OpenMultiCommitManager(HLERequestContext& ctx); - void GetCacheStorageSize(HLERequestContext& ctx); - - FileSystemController& fsc; - const FileSys::ContentProvider& content_provider; - const Core::Reporter& reporter; - - FileSys::VirtualFile romfs; - u64 current_process_id = 0; - u32 access_log_program_index = 0; - AccessLogMode access_log_mode = AccessLogMode::None; - u64 program_id = 0; - std::shared_ptr save_data_controller; - std::shared_ptr romfs_controller; -}; - -} // namespace Service::FileSystem -- cgit v1.2.3