diff options
| author | 2024-02-22 12:34:47 -0500 | |
|---|---|---|
| committer | 2024-02-22 12:34:47 -0500 | |
| commit | d12d9dad4096af6280c6c418cf36a2faacede102 (patch) | |
| tree | ba52bf26efd8b2f7bf282b0564a68870022cccb7 /src/core/hle | |
| parent | Merge pull request #13000 from liamwhite/skip-null-memory (diff) | |
| parent | Address review comments pt. 2 (diff) | |
| download | yuzu-d12d9dad4096af6280c6c418cf36a2faacede102.tar.gz yuzu-d12d9dad4096af6280c6c418cf36a2faacede102.tar.xz yuzu-d12d9dad4096af6280c6c418cf36a2faacede102.zip | |
Merge pull request #12982 from FearlessTobi/fs-rewrite-part0
fs: Add FileSystemAccessor and use cmif serialization
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_directory.cpp | 72 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_directory.h | 13 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_file.cpp | 124 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_file.h | 21 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp | 283 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fs_i_filesystem.h | 60 |
6 files changed, 202 insertions, 371 deletions
diff --git a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp index 39690018b..8483394d0 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.cpp | |||
| @@ -3,82 +3,34 @@ | |||
| 3 | 3 | ||
| 4 | #include "core/file_sys/fs_filesystem.h" | 4 | #include "core/file_sys/fs_filesystem.h" |
| 5 | #include "core/file_sys/savedata_factory.h" | 5 | #include "core/file_sys/savedata_factory.h" |
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 6 | #include "core/hle/service/filesystem/fsp/fs_i_directory.h" | 7 | #include "core/hle/service/filesystem/fsp/fs_i_directory.h" |
| 7 | #include "core/hle/service/ipc_helpers.h" | ||
| 8 | 8 | ||
| 9 | namespace Service::FileSystem { | 9 | namespace Service::FileSystem { |
| 10 | 10 | ||
| 11 | template <typename T> | 11 | IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir directory_, |
| 12 | static void BuildEntryIndex(std::vector<FileSys::DirectoryEntry>& entries, | ||
| 13 | const std::vector<T>& new_data, FileSys::DirectoryEntryType type) { | ||
| 14 | entries.reserve(entries.size() + new_data.size()); | ||
| 15 | |||
| 16 | for (const auto& new_entry : new_data) { | ||
| 17 | auto name = new_entry->GetName(); | ||
| 18 | |||
| 19 | if (type == FileSys::DirectoryEntryType::File && | ||
| 20 | name == FileSys::GetSaveDataSizeFileName()) { | ||
| 21 | continue; | ||
| 22 | } | ||
| 23 | |||
| 24 | entries.emplace_back(name, static_cast<s8>(type), | ||
| 25 | type == FileSys::DirectoryEntryType::Directory ? 0 | ||
| 26 | : new_entry->GetSize()); | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 30 | IDirectory::IDirectory(Core::System& system_, FileSys::VirtualDir backend_, | ||
| 31 | FileSys::OpenDirectoryMode mode) | 12 | FileSys::OpenDirectoryMode mode) |
| 32 | : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) { | 13 | : ServiceFramework{system_, "IDirectory"}, |
| 14 | backend(std::make_unique<FileSys::Fsa::IDirectory>(directory_, mode)) { | ||
| 33 | static const FunctionInfo functions[] = { | 15 | static const FunctionInfo functions[] = { |
| 34 | {0, &IDirectory::Read, "Read"}, | 16 | {0, D<&IDirectory::Read>, "Read"}, |
| 35 | {1, &IDirectory::GetEntryCount, "GetEntryCount"}, | 17 | {1, D<&IDirectory::GetEntryCount>, "GetEntryCount"}, |
| 36 | }; | 18 | }; |
| 37 | RegisterHandlers(functions); | 19 | RegisterHandlers(functions); |
| 38 | |||
| 39 | // TODO(DarkLordZach): Verify that this is the correct behavior. | ||
| 40 | // Build entry index now to save time later. | ||
| 41 | if (True(mode & FileSys::OpenDirectoryMode::Directory)) { | ||
| 42 | BuildEntryIndex(entries, backend->GetSubdirectories(), | ||
| 43 | FileSys::DirectoryEntryType::Directory); | ||
| 44 | } | ||
| 45 | if (True(mode & FileSys::OpenDirectoryMode::File)) { | ||
| 46 | BuildEntryIndex(entries, backend->GetFiles(), FileSys::DirectoryEntryType::File); | ||
| 47 | } | ||
| 48 | } | 20 | } |
| 49 | 21 | ||
| 50 | void IDirectory::Read(HLERequestContext& ctx) { | 22 | Result IDirectory::Read( |
| 23 | Out<s64> out_count, | ||
| 24 | const OutArray<FileSys::DirectoryEntry, BufferAttr_HipcMapAlias> out_entries) { | ||
| 51 | LOG_DEBUG(Service_FS, "called."); | 25 | LOG_DEBUG(Service_FS, "called."); |
| 52 | 26 | ||
| 53 | // Calculate how many entries we can fit in the output buffer | 27 | R_RETURN(backend->Read(out_count, out_entries.data(), out_entries.size())); |
| 54 | const u64 count_entries = ctx.GetWriteBufferNumElements<FileSys::DirectoryEntry>(); | ||
| 55 | |||
| 56 | // Cap at total number of entries. | ||
| 57 | const u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); | ||
| 58 | |||
| 59 | // Determine data start and end | ||
| 60 | const auto* begin = reinterpret_cast<u8*>(entries.data() + next_entry_index); | ||
| 61 | const auto* end = reinterpret_cast<u8*>(entries.data() + next_entry_index + actual_entries); | ||
| 62 | const auto range_size = static_cast<std::size_t>(std::distance(begin, end)); | ||
| 63 | |||
| 64 | next_entry_index += actual_entries; | ||
| 65 | |||
| 66 | // Write the data to memory | ||
| 67 | ctx.WriteBuffer(begin, range_size); | ||
| 68 | |||
| 69 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 70 | rb.Push(ResultSuccess); | ||
| 71 | rb.Push(actual_entries); | ||
| 72 | } | 28 | } |
| 73 | 29 | ||
| 74 | void IDirectory::GetEntryCount(HLERequestContext& ctx) { | 30 | Result IDirectory::GetEntryCount(Out<s64> out_count) { |
| 75 | LOG_DEBUG(Service_FS, "called"); | 31 | LOG_DEBUG(Service_FS, "called"); |
| 76 | 32 | ||
| 77 | u64 count = entries.size() - next_entry_index; | 33 | R_RETURN(backend->GetEntryCount(out_count)); |
| 78 | |||
| 79 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 80 | rb.Push(ResultSuccess); | ||
| 81 | rb.Push(count); | ||
| 82 | } | 34 | } |
| 83 | 35 | ||
| 84 | } // namespace Service::FileSystem | 36 | } // 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 index 793ecfcd7..b6251f7fd 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_directory.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_directory.h | |||
| @@ -3,7 +3,9 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/file_sys/fsa/fs_i_directory.h" | ||
| 6 | #include "core/file_sys/vfs/vfs.h" | 7 | #include "core/file_sys/vfs/vfs.h" |
| 8 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/filesystem/filesystem.h" | 9 | #include "core/hle/service/filesystem/filesystem.h" |
| 8 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 9 | 11 | ||
| @@ -15,16 +17,15 @@ namespace Service::FileSystem { | |||
| 15 | 17 | ||
| 16 | class IDirectory final : public ServiceFramework<IDirectory> { | 18 | class IDirectory final : public ServiceFramework<IDirectory> { |
| 17 | public: | 19 | public: |
| 18 | explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_, | 20 | explicit IDirectory(Core::System& system_, FileSys::VirtualDir directory_, |
| 19 | FileSys::OpenDirectoryMode mode); | 21 | FileSys::OpenDirectoryMode mode); |
| 20 | 22 | ||
| 21 | private: | 23 | private: |
| 22 | FileSys::VirtualDir backend; | 24 | std::unique_ptr<FileSys::Fsa::IDirectory> backend; |
| 23 | std::vector<FileSys::DirectoryEntry> entries; | ||
| 24 | u64 next_entry_index = 0; | ||
| 25 | 25 | ||
| 26 | void Read(HLERequestContext& ctx); | 26 | Result Read(Out<s64> out_count, |
| 27 | void GetEntryCount(HLERequestContext& ctx); | 27 | const OutArray<FileSys::DirectoryEntry, BufferAttr_HipcMapAlias> out_entries); |
| 28 | Result GetEntryCount(Out<s64> out_count); | ||
| 28 | }; | 29 | }; |
| 29 | 30 | ||
| 30 | } // namespace Service::FileSystem | 31 | } // 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 index 9a18f6ec5..a355d46ae 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_file.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.cpp | |||
| @@ -2,126 +2,64 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/file_sys/errors.h" | 4 | #include "core/file_sys/errors.h" |
| 5 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/filesystem/fsp/fs_i_file.h" | 6 | #include "core/hle/service/filesystem/fsp/fs_i_file.h" |
| 6 | #include "core/hle/service/ipc_helpers.h" | ||
| 7 | 7 | ||
| 8 | namespace Service::FileSystem { | 8 | namespace Service::FileSystem { |
| 9 | 9 | ||
| 10 | IFile::IFile(Core::System& system_, FileSys::VirtualFile backend_) | 10 | IFile::IFile(Core::System& system_, FileSys::VirtualFile file_) |
| 11 | : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) { | 11 | : ServiceFramework{system_, "IFile"}, backend{std::make_unique<FileSys::Fsa::IFile>(file_)} { |
| 12 | // clang-format off | ||
| 12 | static const FunctionInfo functions[] = { | 13 | static const FunctionInfo functions[] = { |
| 13 | {0, &IFile::Read, "Read"}, | 14 | {0, D<&IFile::Read>, "Read"}, |
| 14 | {1, &IFile::Write, "Write"}, | 15 | {1, D<&IFile::Write>, "Write"}, |
| 15 | {2, &IFile::Flush, "Flush"}, | 16 | {2, D<&IFile::Flush>, "Flush"}, |
| 16 | {3, &IFile::SetSize, "SetSize"}, | 17 | {3, D<&IFile::SetSize>, "SetSize"}, |
| 17 | {4, &IFile::GetSize, "GetSize"}, | 18 | {4, D<&IFile::GetSize>, "GetSize"}, |
| 18 | {5, nullptr, "OperateRange"}, | 19 | {5, nullptr, "OperateRange"}, |
| 19 | {6, nullptr, "OperateRangeWithBuffer"}, | 20 | {6, nullptr, "OperateRangeWithBuffer"}, |
| 20 | }; | 21 | }; |
| 22 | // clang-format on | ||
| 21 | RegisterHandlers(functions); | 23 | RegisterHandlers(functions); |
| 22 | } | 24 | } |
| 23 | 25 | ||
| 24 | void IFile::Read(HLERequestContext& ctx) { | 26 | Result IFile::Read( |
| 25 | IPC::RequestParser rp{ctx}; | 27 | FileSys::ReadOption option, Out<s64> out_size, s64 offset, |
| 26 | const u64 option = rp.Pop<u64>(); | 28 | const OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer, |
| 27 | const s64 offset = rp.Pop<s64>(); | 29 | s64 size) { |
| 28 | const s64 length = rp.Pop<s64>(); | 30 | LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option.value, offset, |
| 29 | 31 | size); | |
| 30 | LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); | ||
| 31 | |||
| 32 | // Error checking | ||
| 33 | if (length < 0) { | ||
| 34 | LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); | ||
| 35 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 36 | rb.Push(FileSys::ResultInvalidSize); | ||
| 37 | return; | ||
| 38 | } | ||
| 39 | if (offset < 0) { | ||
| 40 | LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); | ||
| 41 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 42 | rb.Push(FileSys::ResultInvalidOffset); | ||
| 43 | return; | ||
| 44 | } | ||
| 45 | 32 | ||
| 46 | // Read the data from the Storage backend | 33 | // Read the data from the Storage backend |
| 47 | std::vector<u8> output = backend->ReadBytes(length, offset); | 34 | R_RETURN( |
| 48 | 35 | backend->Read(reinterpret_cast<size_t*>(out_size.Get()), offset, out_buffer.data(), size)); | |
| 49 | // Write the data to memory | ||
| 50 | ctx.WriteBuffer(output); | ||
| 51 | |||
| 52 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 53 | rb.Push(ResultSuccess); | ||
| 54 | rb.Push(static_cast<u64>(output.size())); | ||
| 55 | } | 36 | } |
| 56 | 37 | ||
| 57 | void IFile::Write(HLERequestContext& ctx) { | 38 | Result IFile::Write( |
| 58 | IPC::RequestParser rp{ctx}; | 39 | const InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> buffer, |
| 59 | const u64 option = rp.Pop<u64>(); | 40 | FileSys::WriteOption option, s64 offset, s64 size) { |
| 60 | const s64 offset = rp.Pop<s64>(); | 41 | LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option.value, offset, |
| 61 | const s64 length = rp.Pop<s64>(); | 42 | size); |
| 62 | |||
| 63 | LOG_DEBUG(Service_FS, "called, option={}, offset=0x{:X}, length={}", option, offset, length); | ||
| 64 | |||
| 65 | // Error checking | ||
| 66 | if (length < 0) { | ||
| 67 | LOG_ERROR(Service_FS, "Length is less than 0, length={}", length); | ||
| 68 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 69 | rb.Push(FileSys::ResultInvalidSize); | ||
| 70 | return; | ||
| 71 | } | ||
| 72 | if (offset < 0) { | ||
| 73 | LOG_ERROR(Service_FS, "Offset is less than 0, offset={}", offset); | ||
| 74 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 75 | rb.Push(FileSys::ResultInvalidOffset); | ||
| 76 | return; | ||
| 77 | } | ||
| 78 | |||
| 79 | const auto data = ctx.ReadBuffer(); | ||
| 80 | 43 | ||
| 81 | ASSERT_MSG(static_cast<s64>(data.size()) <= length, | 44 | R_RETURN(backend->Write(offset, buffer.data(), size, option)); |
| 82 | "Attempting to write more data than requested (requested={:016X}, actual={:016X}).", | ||
| 83 | length, data.size()); | ||
| 84 | |||
| 85 | // Write the data to the Storage backend | ||
| 86 | const auto write_size = | ||
| 87 | static_cast<std::size_t>(std::distance(data.begin(), data.begin() + length)); | ||
| 88 | const std::size_t written = backend->Write(data.data(), write_size, offset); | ||
| 89 | |||
| 90 | ASSERT_MSG(static_cast<s64>(written) == length, | ||
| 91 | "Could not write all bytes to file (requested={:016X}, actual={:016X}).", length, | ||
| 92 | written); | ||
| 93 | |||
| 94 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 95 | rb.Push(ResultSuccess); | ||
| 96 | } | 45 | } |
| 97 | 46 | ||
| 98 | void IFile::Flush(HLERequestContext& ctx) { | 47 | Result IFile::Flush() { |
| 99 | LOG_DEBUG(Service_FS, "called"); | 48 | LOG_DEBUG(Service_FS, "called"); |
| 100 | 49 | ||
| 101 | // Exists for SDK compatibiltity -- No need to flush file. | 50 | R_RETURN(backend->Flush()); |
| 102 | |||
| 103 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 104 | rb.Push(ResultSuccess); | ||
| 105 | } | 51 | } |
| 106 | 52 | ||
| 107 | void IFile::SetSize(HLERequestContext& ctx) { | 53 | Result IFile::SetSize(s64 size) { |
| 108 | IPC::RequestParser rp{ctx}; | ||
| 109 | const u64 size = rp.Pop<u64>(); | ||
| 110 | LOG_DEBUG(Service_FS, "called, size={}", size); | 54 | LOG_DEBUG(Service_FS, "called, size={}", size); |
| 111 | 55 | ||
| 112 | backend->Resize(size); | 56 | R_RETURN(backend->SetSize(size)); |
| 113 | |||
| 114 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 115 | rb.Push(ResultSuccess); | ||
| 116 | } | 57 | } |
| 117 | 58 | ||
| 118 | void IFile::GetSize(HLERequestContext& ctx) { | 59 | Result IFile::GetSize(Out<s64> out_size) { |
| 119 | const u64 size = backend->GetSize(); | 60 | LOG_DEBUG(Service_FS, "called"); |
| 120 | LOG_DEBUG(Service_FS, "called, size={}", size); | ||
| 121 | 61 | ||
| 122 | IPC::ResponseBuilder rb{ctx, 4}; | 62 | R_RETURN(backend->GetSize(out_size)); |
| 123 | rb.Push(ResultSuccess); | ||
| 124 | rb.Push<u64>(size); | ||
| 125 | } | 63 | } |
| 126 | 64 | ||
| 127 | } // namespace Service::FileSystem | 65 | } // 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 index 5e5430c67..e8599ee2f 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_file.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_file.h | |||
| @@ -3,6 +3,8 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "core/file_sys/fsa/fs_i_file.h" | ||
| 7 | #include "core/hle/service/cmif_types.h" | ||
| 6 | #include "core/hle/service/filesystem/filesystem.h" | 8 | #include "core/hle/service/filesystem/filesystem.h" |
| 7 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 8 | 10 | ||
| @@ -10,16 +12,21 @@ namespace Service::FileSystem { | |||
| 10 | 12 | ||
| 11 | class IFile final : public ServiceFramework<IFile> { | 13 | class IFile final : public ServiceFramework<IFile> { |
| 12 | public: | 14 | public: |
| 13 | explicit IFile(Core::System& system_, FileSys::VirtualFile backend_); | 15 | explicit IFile(Core::System& system_, FileSys::VirtualFile file_); |
| 14 | 16 | ||
| 15 | private: | 17 | private: |
| 16 | FileSys::VirtualFile backend; | 18 | std::unique_ptr<FileSys::Fsa::IFile> backend; |
| 17 | 19 | ||
| 18 | void Read(HLERequestContext& ctx); | 20 | Result Read(FileSys::ReadOption option, Out<s64> out_size, s64 offset, |
| 19 | void Write(HLERequestContext& ctx); | 21 | const OutBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> |
| 20 | void Flush(HLERequestContext& ctx); | 22 | out_buffer, |
| 21 | void SetSize(HLERequestContext& ctx); | 23 | s64 size); |
| 22 | void GetSize(HLERequestContext& ctx); | 24 | Result Write( |
| 25 | const InBuffer<BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> buffer, | ||
| 26 | FileSys::WriteOption option, s64 offset, s64 size); | ||
| 27 | Result Flush(); | ||
| 28 | Result SetSize(s64 size); | ||
| 29 | Result GetSize(Out<s64> out_size); | ||
| 23 | }; | 30 | }; |
| 24 | 31 | ||
| 25 | } // namespace Service::FileSystem | 32 | } // 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 index efa394dd1..d881e144d 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.cpp | |||
| @@ -2,261 +2,172 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "common/string_util.h" | 4 | #include "common/string_util.h" |
| 5 | #include "core/file_sys/fssrv/fssrv_sf_path.h" | ||
| 6 | #include "core/hle/service/cmif_serialization.h" | ||
| 5 | #include "core/hle/service/filesystem/fsp/fs_i_directory.h" | 7 | #include "core/hle/service/filesystem/fsp/fs_i_directory.h" |
| 6 | #include "core/hle/service/filesystem/fsp/fs_i_file.h" | 8 | #include "core/hle/service/filesystem/fsp/fs_i_file.h" |
| 7 | #include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" | 9 | #include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" |
| 8 | #include "core/hle/service/ipc_helpers.h" | ||
| 9 | 10 | ||
| 10 | namespace Service::FileSystem { | 11 | namespace Service::FileSystem { |
| 11 | 12 | ||
| 12 | IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) | 13 | IFileSystem::IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_getter_) |
| 13 | : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move( | 14 | : ServiceFramework{system_, "IFileSystem"}, backend{std::make_unique<FileSys::Fsa::IFileSystem>( |
| 14 | size_)} { | 15 | dir_)}, |
| 16 | size_getter{std::move(size_getter_)} { | ||
| 15 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 16 | {0, &IFileSystem::CreateFile, "CreateFile"}, | 18 | {0, D<&IFileSystem::CreateFile>, "CreateFile"}, |
| 17 | {1, &IFileSystem::DeleteFile, "DeleteFile"}, | 19 | {1, D<&IFileSystem::DeleteFile>, "DeleteFile"}, |
| 18 | {2, &IFileSystem::CreateDirectory, "CreateDirectory"}, | 20 | {2, D<&IFileSystem::CreateDirectory>, "CreateDirectory"}, |
| 19 | {3, &IFileSystem::DeleteDirectory, "DeleteDirectory"}, | 21 | {3, D<&IFileSystem::DeleteDirectory>, "DeleteDirectory"}, |
| 20 | {4, &IFileSystem::DeleteDirectoryRecursively, "DeleteDirectoryRecursively"}, | 22 | {4, D<&IFileSystem::DeleteDirectoryRecursively>, "DeleteDirectoryRecursively"}, |
| 21 | {5, &IFileSystem::RenameFile, "RenameFile"}, | 23 | {5, D<&IFileSystem::RenameFile>, "RenameFile"}, |
| 22 | {6, nullptr, "RenameDirectory"}, | 24 | {6, nullptr, "RenameDirectory"}, |
| 23 | {7, &IFileSystem::GetEntryType, "GetEntryType"}, | 25 | {7, D<&IFileSystem::GetEntryType>, "GetEntryType"}, |
| 24 | {8, &IFileSystem::OpenFile, "OpenFile"}, | 26 | {8, D<&IFileSystem::OpenFile>, "OpenFile"}, |
| 25 | {9, &IFileSystem::OpenDirectory, "OpenDirectory"}, | 27 | {9, D<&IFileSystem::OpenDirectory>, "OpenDirectory"}, |
| 26 | {10, &IFileSystem::Commit, "Commit"}, | 28 | {10, D<&IFileSystem::Commit>, "Commit"}, |
| 27 | {11, &IFileSystem::GetFreeSpaceSize, "GetFreeSpaceSize"}, | 29 | {11, D<&IFileSystem::GetFreeSpaceSize>, "GetFreeSpaceSize"}, |
| 28 | {12, &IFileSystem::GetTotalSpaceSize, "GetTotalSpaceSize"}, | 30 | {12, D<&IFileSystem::GetTotalSpaceSize>, "GetTotalSpaceSize"}, |
| 29 | {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"}, | 31 | {13, D<&IFileSystem::CleanDirectoryRecursively>, "CleanDirectoryRecursively"}, |
| 30 | {14, &IFileSystem::GetFileTimeStampRaw, "GetFileTimeStampRaw"}, | 32 | {14, D<&IFileSystem::GetFileTimeStampRaw>, "GetFileTimeStampRaw"}, |
| 31 | {15, nullptr, "QueryEntry"}, | 33 | {15, nullptr, "QueryEntry"}, |
| 32 | {16, &IFileSystem::GetFileSystemAttribute, "GetFileSystemAttribute"}, | 34 | {16, D<&IFileSystem::GetFileSystemAttribute>, "GetFileSystemAttribute"}, |
| 33 | }; | 35 | }; |
| 34 | RegisterHandlers(functions); | 36 | RegisterHandlers(functions); |
| 35 | } | 37 | } |
| 36 | 38 | ||
| 37 | void IFileSystem::CreateFile(HLERequestContext& ctx) { | 39 | Result IFileSystem::CreateFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, |
| 38 | IPC::RequestParser rp{ctx}; | 40 | s32 option, s64 size) { |
| 41 | LOG_DEBUG(Service_FS, "called. file={}, option=0x{:X}, size=0x{:08X}", path->str, option, size); | ||
| 39 | 42 | ||
| 40 | const auto file_buffer = ctx.ReadBuffer(); | 43 | R_RETURN(backend->CreateFile(FileSys::Path(path->str), size)); |
| 41 | const std::string name = Common::StringFromBuffer(file_buffer); | ||
| 42 | |||
| 43 | const u64 file_mode = rp.Pop<u64>(); | ||
| 44 | const u32 file_size = rp.Pop<u32>(); | ||
| 45 | |||
| 46 | LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, file_mode, | ||
| 47 | file_size); | ||
| 48 | |||
| 49 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 50 | rb.Push(backend.CreateFile(name, file_size)); | ||
| 51 | } | 44 | } |
| 52 | 45 | ||
| 53 | void IFileSystem::DeleteFile(HLERequestContext& ctx) { | 46 | Result IFileSystem::DeleteFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { |
| 54 | const auto file_buffer = ctx.ReadBuffer(); | 47 | LOG_DEBUG(Service_FS, "called. file={}", path->str); |
| 55 | const std::string name = Common::StringFromBuffer(file_buffer); | ||
| 56 | 48 | ||
| 57 | LOG_DEBUG(Service_FS, "called. file={}", name); | 49 | R_RETURN(backend->DeleteFile(FileSys::Path(path->str))); |
| 58 | |||
| 59 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 60 | rb.Push(backend.DeleteFile(name)); | ||
| 61 | } | 50 | } |
| 62 | 51 | ||
| 63 | void IFileSystem::CreateDirectory(HLERequestContext& ctx) { | 52 | Result IFileSystem::CreateDirectory( |
| 64 | const auto file_buffer = ctx.ReadBuffer(); | 53 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { |
| 65 | const std::string name = Common::StringFromBuffer(file_buffer); | 54 | LOG_DEBUG(Service_FS, "called. directory={}", path->str); |
| 66 | |||
| 67 | LOG_DEBUG(Service_FS, "called. directory={}", name); | ||
| 68 | 55 | ||
| 69 | IPC::ResponseBuilder rb{ctx, 2}; | 56 | R_RETURN(backend->CreateDirectory(FileSys::Path(path->str))); |
| 70 | rb.Push(backend.CreateDirectory(name)); | ||
| 71 | } | 57 | } |
| 72 | 58 | ||
| 73 | void IFileSystem::DeleteDirectory(HLERequestContext& ctx) { | 59 | Result IFileSystem::DeleteDirectory( |
| 74 | const auto file_buffer = ctx.ReadBuffer(); | 60 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { |
| 75 | const std::string name = Common::StringFromBuffer(file_buffer); | 61 | LOG_DEBUG(Service_FS, "called. directory={}", path->str); |
| 76 | |||
| 77 | LOG_DEBUG(Service_FS, "called. directory={}", name); | ||
| 78 | 62 | ||
| 79 | IPC::ResponseBuilder rb{ctx, 2}; | 63 | R_RETURN(backend->DeleteDirectory(FileSys::Path(path->str))); |
| 80 | rb.Push(backend.DeleteDirectory(name)); | ||
| 81 | } | 64 | } |
| 82 | 65 | ||
| 83 | void IFileSystem::DeleteDirectoryRecursively(HLERequestContext& ctx) { | 66 | Result IFileSystem::DeleteDirectoryRecursively( |
| 84 | const auto file_buffer = ctx.ReadBuffer(); | 67 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { |
| 85 | const std::string name = Common::StringFromBuffer(file_buffer); | 68 | LOG_DEBUG(Service_FS, "called. directory={}", path->str); |
| 86 | 69 | ||
| 87 | LOG_DEBUG(Service_FS, "called. directory={}", name); | 70 | R_RETURN(backend->DeleteDirectoryRecursively(FileSys::Path(path->str))); |
| 88 | |||
| 89 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 90 | rb.Push(backend.DeleteDirectoryRecursively(name)); | ||
| 91 | } | 71 | } |
| 92 | 72 | ||
| 93 | void IFileSystem::CleanDirectoryRecursively(HLERequestContext& ctx) { | 73 | Result IFileSystem::CleanDirectoryRecursively( |
| 94 | const auto file_buffer = ctx.ReadBuffer(); | 74 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { |
| 95 | const std::string name = Common::StringFromBuffer(file_buffer); | 75 | LOG_DEBUG(Service_FS, "called. Directory: {}", path->str); |
| 96 | |||
| 97 | LOG_DEBUG(Service_FS, "called. Directory: {}", name); | ||
| 98 | 76 | ||
| 99 | IPC::ResponseBuilder rb{ctx, 2}; | 77 | R_RETURN(backend->CleanDirectoryRecursively(FileSys::Path(path->str))); |
| 100 | rb.Push(backend.CleanDirectoryRecursively(name)); | ||
| 101 | } | 78 | } |
| 102 | 79 | ||
| 103 | void IFileSystem::RenameFile(HLERequestContext& ctx) { | 80 | Result IFileSystem::RenameFile( |
| 104 | const std::string src_name = Common::StringFromBuffer(ctx.ReadBuffer(0)); | 81 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> old_path, |
| 105 | const std::string dst_name = Common::StringFromBuffer(ctx.ReadBuffer(1)); | 82 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> new_path) { |
| 106 | 83 | LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", old_path->str, new_path->str); | |
| 107 | LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name); | ||
| 108 | 84 | ||
| 109 | IPC::ResponseBuilder rb{ctx, 2}; | 85 | R_RETURN(backend->RenameFile(FileSys::Path(old_path->str), FileSys::Path(new_path->str))); |
| 110 | rb.Push(backend.RenameFile(src_name, dst_name)); | ||
| 111 | } | 86 | } |
| 112 | 87 | ||
| 113 | void IFileSystem::OpenFile(HLERequestContext& ctx) { | 88 | Result IFileSystem::OpenFile(OutInterface<IFile> out_interface, |
| 114 | IPC::RequestParser rp{ctx}; | 89 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, |
| 115 | 90 | u32 mode) { | |
| 116 | const auto file_buffer = ctx.ReadBuffer(); | 91 | LOG_DEBUG(Service_FS, "called. file={}, mode={}", path->str, mode); |
| 117 | const std::string name = Common::StringFromBuffer(file_buffer); | ||
| 118 | |||
| 119 | const auto mode = static_cast<FileSys::OpenMode>(rp.Pop<u32>()); | ||
| 120 | |||
| 121 | LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, mode); | ||
| 122 | 92 | ||
| 123 | FileSys::VirtualFile vfs_file{}; | 93 | FileSys::VirtualFile vfs_file{}; |
| 124 | auto result = backend.OpenFile(&vfs_file, name, mode); | 94 | R_TRY(backend->OpenFile(&vfs_file, FileSys::Path(path->str), |
| 125 | if (result != ResultSuccess) { | 95 | static_cast<FileSys::OpenMode>(mode))); |
| 126 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 127 | rb.Push(result); | ||
| 128 | return; | ||
| 129 | } | ||
| 130 | |||
| 131 | auto file = std::make_shared<IFile>(system, vfs_file); | ||
| 132 | |||
| 133 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 134 | rb.Push(ResultSuccess); | ||
| 135 | rb.PushIpcInterface<IFile>(std::move(file)); | ||
| 136 | } | ||
| 137 | |||
| 138 | void IFileSystem::OpenDirectory(HLERequestContext& ctx) { | ||
| 139 | IPC::RequestParser rp{ctx}; | ||
| 140 | 96 | ||
| 141 | const auto file_buffer = ctx.ReadBuffer(); | 97 | *out_interface = std::make_shared<IFile>(system, vfs_file); |
| 142 | const std::string name = Common::StringFromBuffer(file_buffer); | 98 | R_SUCCEED(); |
| 143 | const auto mode = rp.PopRaw<FileSys::OpenDirectoryMode>(); | 99 | } |
| 144 | 100 | ||
| 145 | LOG_DEBUG(Service_FS, "called. directory={}, mode={}", name, mode); | 101 | Result IFileSystem::OpenDirectory(OutInterface<IDirectory> out_interface, |
| 102 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, | ||
| 103 | u32 mode) { | ||
| 104 | LOG_DEBUG(Service_FS, "called. directory={}, mode={}", path->str, mode); | ||
| 146 | 105 | ||
| 147 | FileSys::VirtualDir vfs_dir{}; | 106 | FileSys::VirtualDir vfs_dir{}; |
| 148 | auto result = backend.OpenDirectory(&vfs_dir, name); | 107 | R_TRY(backend->OpenDirectory(&vfs_dir, FileSys::Path(path->str), |
| 149 | if (result != ResultSuccess) { | 108 | static_cast<FileSys::OpenDirectoryMode>(mode))); |
| 150 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 151 | rb.Push(result); | ||
| 152 | return; | ||
| 153 | } | ||
| 154 | |||
| 155 | auto directory = std::make_shared<IDirectory>(system, vfs_dir, mode); | ||
| 156 | |||
| 157 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 158 | rb.Push(ResultSuccess); | ||
| 159 | rb.PushIpcInterface<IDirectory>(std::move(directory)); | ||
| 160 | } | ||
| 161 | 109 | ||
| 162 | void IFileSystem::GetEntryType(HLERequestContext& ctx) { | 110 | *out_interface = std::make_shared<IDirectory>(system, vfs_dir, |
| 163 | const auto file_buffer = ctx.ReadBuffer(); | 111 | static_cast<FileSys::OpenDirectoryMode>(mode)); |
| 164 | const std::string name = Common::StringFromBuffer(file_buffer); | 112 | R_SUCCEED(); |
| 113 | } | ||
| 165 | 114 | ||
| 166 | LOG_DEBUG(Service_FS, "called. file={}", name); | 115 | Result IFileSystem::GetEntryType( |
| 116 | Out<u32> out_type, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { | ||
| 117 | LOG_DEBUG(Service_FS, "called. file={}", path->str); | ||
| 167 | 118 | ||
| 168 | FileSys::DirectoryEntryType vfs_entry_type{}; | 119 | FileSys::DirectoryEntryType vfs_entry_type{}; |
| 169 | auto result = backend.GetEntryType(&vfs_entry_type, name); | 120 | R_TRY(backend->GetEntryType(&vfs_entry_type, FileSys::Path(path->str))); |
| 170 | if (result != ResultSuccess) { | 121 | |
| 171 | IPC::ResponseBuilder rb{ctx, 2}; | 122 | *out_type = static_cast<u32>(vfs_entry_type); |
| 172 | rb.Push(result); | 123 | R_SUCCEED(); |
| 173 | return; | ||
| 174 | } | ||
| 175 | |||
| 176 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 177 | rb.Push(ResultSuccess); | ||
| 178 | rb.Push<u32>(static_cast<u32>(vfs_entry_type)); | ||
| 179 | } | 124 | } |
| 180 | 125 | ||
| 181 | void IFileSystem::Commit(HLERequestContext& ctx) { | 126 | Result IFileSystem::Commit() { |
| 182 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 127 | LOG_WARNING(Service_FS, "(STUBBED) called"); |
| 183 | 128 | ||
| 184 | IPC::ResponseBuilder rb{ctx, 2}; | 129 | R_SUCCEED(); |
| 185 | rb.Push(ResultSuccess); | ||
| 186 | } | 130 | } |
| 187 | 131 | ||
| 188 | void IFileSystem::GetFreeSpaceSize(HLERequestContext& ctx) { | 132 | Result IFileSystem::GetFreeSpaceSize( |
| 133 | Out<s64> out_size, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { | ||
| 189 | LOG_DEBUG(Service_FS, "called"); | 134 | LOG_DEBUG(Service_FS, "called"); |
| 190 | 135 | ||
| 191 | IPC::ResponseBuilder rb{ctx, 4}; | 136 | *out_size = size_getter.get_free_size(); |
| 192 | rb.Push(ResultSuccess); | 137 | R_SUCCEED(); |
| 193 | rb.Push(size.get_free_size()); | ||
| 194 | } | 138 | } |
| 195 | 139 | ||
| 196 | void IFileSystem::GetTotalSpaceSize(HLERequestContext& ctx) { | 140 | Result IFileSystem::GetTotalSpaceSize( |
| 141 | Out<s64> out_size, const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { | ||
| 197 | LOG_DEBUG(Service_FS, "called"); | 142 | LOG_DEBUG(Service_FS, "called"); |
| 198 | 143 | ||
| 199 | IPC::ResponseBuilder rb{ctx, 4}; | 144 | *out_size = size_getter.get_total_size(); |
| 200 | rb.Push(ResultSuccess); | 145 | R_SUCCEED(); |
| 201 | rb.Push(size.get_total_size()); | ||
| 202 | } | 146 | } |
| 203 | 147 | ||
| 204 | void IFileSystem::GetFileTimeStampRaw(HLERequestContext& ctx) { | 148 | Result IFileSystem::GetFileTimeStampRaw( |
| 205 | const auto file_buffer = ctx.ReadBuffer(); | 149 | Out<FileSys::FileTimeStampRaw> out_timestamp, |
| 206 | const std::string name = Common::StringFromBuffer(file_buffer); | 150 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path) { |
| 207 | 151 | LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", path->str); | |
| 208 | LOG_WARNING(Service_FS, "(Partial Implementation) called. file={}", name); | ||
| 209 | 152 | ||
| 210 | FileSys::FileTimeStampRaw vfs_timestamp{}; | 153 | FileSys::FileTimeStampRaw vfs_timestamp{}; |
| 211 | auto result = backend.GetFileTimeStampRaw(&vfs_timestamp, name); | 154 | R_TRY(backend->GetFileTimeStampRaw(&vfs_timestamp, FileSys::Path(path->str))); |
| 212 | if (result != ResultSuccess) { | 155 | |
| 213 | IPC::ResponseBuilder rb{ctx, 2}; | 156 | *out_timestamp = vfs_timestamp; |
| 214 | rb.Push(result); | 157 | R_SUCCEED(); |
| 215 | return; | ||
| 216 | } | ||
| 217 | |||
| 218 | IPC::ResponseBuilder rb{ctx, 10}; | ||
| 219 | rb.Push(ResultSuccess); | ||
| 220 | rb.PushRaw(vfs_timestamp); | ||
| 221 | } | 158 | } |
| 222 | 159 | ||
| 223 | void IFileSystem::GetFileSystemAttribute(HLERequestContext& ctx) { | 160 | Result IFileSystem::GetFileSystemAttribute(Out<FileSys::FileSystemAttribute> out_attribute) { |
| 224 | LOG_WARNING(Service_FS, "(STUBBED) called"); | 161 | LOG_WARNING(Service_FS, "(STUBBED) called"); |
| 225 | 162 | ||
| 226 | struct FileSystemAttribute { | 163 | FileSys::FileSystemAttribute savedata_attribute{}; |
| 227 | u8 dir_entry_name_length_max_defined; | ||
| 228 | u8 file_entry_name_length_max_defined; | ||
| 229 | u8 dir_path_name_length_max_defined; | ||
| 230 | u8 file_path_name_length_max_defined; | ||
| 231 | INSERT_PADDING_BYTES_NOINIT(0x5); | ||
| 232 | u8 utf16_dir_entry_name_length_max_defined; | ||
| 233 | u8 utf16_file_entry_name_length_max_defined; | ||
| 234 | u8 utf16_dir_path_name_length_max_defined; | ||
| 235 | u8 utf16_file_path_name_length_max_defined; | ||
| 236 | INSERT_PADDING_BYTES_NOINIT(0x18); | ||
| 237 | s32 dir_entry_name_length_max; | ||
| 238 | s32 file_entry_name_length_max; | ||
| 239 | s32 dir_path_name_length_max; | ||
| 240 | s32 file_path_name_length_max; | ||
| 241 | INSERT_PADDING_WORDS_NOINIT(0x5); | ||
| 242 | s32 utf16_dir_entry_name_length_max; | ||
| 243 | s32 utf16_file_entry_name_length_max; | ||
| 244 | s32 utf16_dir_path_name_length_max; | ||
| 245 | s32 utf16_file_path_name_length_max; | ||
| 246 | INSERT_PADDING_WORDS_NOINIT(0x18); | ||
| 247 | INSERT_PADDING_WORDS_NOINIT(0x1); | ||
| 248 | }; | ||
| 249 | static_assert(sizeof(FileSystemAttribute) == 0xc0, "FileSystemAttribute has incorrect size"); | ||
| 250 | |||
| 251 | FileSystemAttribute savedata_attribute{}; | ||
| 252 | savedata_attribute.dir_entry_name_length_max_defined = true; | 164 | savedata_attribute.dir_entry_name_length_max_defined = true; |
| 253 | savedata_attribute.file_entry_name_length_max_defined = true; | 165 | savedata_attribute.file_entry_name_length_max_defined = true; |
| 254 | savedata_attribute.dir_entry_name_length_max = 0x40; | 166 | savedata_attribute.dir_entry_name_length_max = 0x40; |
| 255 | savedata_attribute.file_entry_name_length_max = 0x40; | 167 | savedata_attribute.file_entry_name_length_max = 0x40; |
| 256 | 168 | ||
| 257 | IPC::ResponseBuilder rb{ctx, 50}; | 169 | *out_attribute = savedata_attribute; |
| 258 | rb.Push(ResultSuccess); | 170 | R_SUCCEED(); |
| 259 | rb.PushRaw(savedata_attribute); | ||
| 260 | } | 171 | } |
| 261 | 172 | ||
| 262 | } // namespace Service::FileSystem | 173 | } // 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 index b06b3ef0e..113369203 100644 --- a/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h +++ b/src/core/hle/service/filesystem/fsp/fs_i_filesystem.h | |||
| @@ -3,36 +3,58 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include "common/common_funcs.h" | ||
| 7 | #include "core/file_sys/fs_filesystem.h" | ||
| 8 | #include "core/file_sys/fsa/fs_i_filesystem.h" | ||
| 6 | #include "core/file_sys/vfs/vfs.h" | 9 | #include "core/file_sys/vfs/vfs.h" |
| 10 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/filesystem/filesystem.h" | 11 | #include "core/hle/service/filesystem/filesystem.h" |
| 8 | #include "core/hle/service/filesystem/fsp/fsp_util.h" | 12 | #include "core/hle/service/filesystem/fsp/fsp_util.h" |
| 9 | #include "core/hle/service/service.h" | 13 | #include "core/hle/service/service.h" |
| 10 | 14 | ||
| 15 | namespace FileSys::Sf { | ||
| 16 | struct Path; | ||
| 17 | } | ||
| 18 | |||
| 11 | namespace Service::FileSystem { | 19 | namespace Service::FileSystem { |
| 12 | 20 | ||
| 21 | class IFile; | ||
| 22 | class IDirectory; | ||
| 23 | |||
| 13 | class IFileSystem final : public ServiceFramework<IFileSystem> { | 24 | class IFileSystem final : public ServiceFramework<IFileSystem> { |
| 14 | public: | 25 | public: |
| 15 | explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_); | 26 | explicit IFileSystem(Core::System& system_, FileSys::VirtualDir dir_, SizeGetter size_getter_); |
| 16 | 27 | ||
| 17 | void CreateFile(HLERequestContext& ctx); | 28 | Result CreateFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, s32 option, |
| 18 | void DeleteFile(HLERequestContext& ctx); | 29 | s64 size); |
| 19 | void CreateDirectory(HLERequestContext& ctx); | 30 | Result DeleteFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); |
| 20 | void DeleteDirectory(HLERequestContext& ctx); | 31 | Result CreateDirectory(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); |
| 21 | void DeleteDirectoryRecursively(HLERequestContext& ctx); | 32 | Result DeleteDirectory(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); |
| 22 | void CleanDirectoryRecursively(HLERequestContext& ctx); | 33 | Result DeleteDirectoryRecursively( |
| 23 | void RenameFile(HLERequestContext& ctx); | 34 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); |
| 24 | void OpenFile(HLERequestContext& ctx); | 35 | Result CleanDirectoryRecursively( |
| 25 | void OpenDirectory(HLERequestContext& ctx); | 36 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); |
| 26 | void GetEntryType(HLERequestContext& ctx); | 37 | Result RenameFile(const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> old_path, |
| 27 | void Commit(HLERequestContext& ctx); | 38 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> new_path); |
| 28 | void GetFreeSpaceSize(HLERequestContext& ctx); | 39 | Result OpenFile(OutInterface<IFile> out_interface, |
| 29 | void GetTotalSpaceSize(HLERequestContext& ctx); | 40 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, u32 mode); |
| 30 | void GetFileTimeStampRaw(HLERequestContext& ctx); | 41 | Result OpenDirectory(OutInterface<IDirectory> out_interface, |
| 31 | void GetFileSystemAttribute(HLERequestContext& ctx); | 42 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path, |
| 43 | u32 mode); | ||
| 44 | Result GetEntryType(Out<u32> out_type, | ||
| 45 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); | ||
| 46 | Result Commit(); | ||
| 47 | Result GetFreeSpaceSize(Out<s64> out_size, | ||
| 48 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); | ||
| 49 | Result GetTotalSpaceSize(Out<s64> out_size, | ||
| 50 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); | ||
| 51 | Result GetFileTimeStampRaw(Out<FileSys::FileTimeStampRaw> out_timestamp, | ||
| 52 | const InLargeData<FileSys::Sf::Path, BufferAttr_HipcPointer> path); | ||
| 53 | Result GetFileSystemAttribute(Out<FileSys::FileSystemAttribute> out_attribute); | ||
| 32 | 54 | ||
| 33 | private: | 55 | private: |
| 34 | VfsDirectoryServiceWrapper backend; | 56 | std::unique_ptr<FileSys::Fsa::IFileSystem> backend; |
| 35 | SizeGetter size; | 57 | SizeGetter size_getter; |
| 36 | }; | 58 | }; |
| 37 | 59 | ||
| 38 | } // namespace Service::FileSystem | 60 | } // namespace Service::FileSystem |