diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 114 |
1 files changed, 49 insertions, 65 deletions
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 26e8a8c88..216bfea0a 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -19,8 +19,8 @@ namespace Service::FileSystem { class IStorage final : public ServiceFramework<IStorage> { public: - IStorage(FileSys::VirtualFile backend_) - : ServiceFramework("IStorage"), backend(std::move(backend_)) { + IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend) + : ServiceFramework("IStorage"), backend(std::move(backend)) { static const FunctionInfo functions[] = { {0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"}, {3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"}, @@ -29,7 +29,7 @@ public: } private: - FileSys::VirtualFile backend; + std::unique_ptr<FileSys::StorageBackend> backend; void Read(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; @@ -51,8 +51,8 @@ private: } // Read the data from the Storage backend - std::vector<u8> output = backend->ReadBytes(length, offset); - auto res = MakeResult<size_t>(output.size()); + std::vector<u8> output(length); + ResultVal<size_t> res = backend->Read(offset, length, output.data()); if (res.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); @@ -69,8 +69,8 @@ private: class IFile final : public ServiceFramework<IFile> { public: - explicit IFile(FileSys::VirtualFile backend_) - : ServiceFramework("IFile"), backend(std::move(backend_)) { + explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend) + : ServiceFramework("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"}, @@ -80,7 +80,7 @@ public: } private: - FileSys::VirtualFile backend; + std::unique_ptr<FileSys::StorageBackend> backend; void Read(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; @@ -103,8 +103,8 @@ private: } // Read the data from the Storage backend - std::vector<u8> output = backend->ReadBytes(length, offset); - auto res = MakeResult<size_t>(output.size()); + std::vector<u8> output(length); + ResultVal<size_t> res = backend->Read(offset, length, output.data()); if (res.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); @@ -139,10 +139,9 @@ private: return; } - std::vector<u8> data = ctx.ReadBuffer(); - data.resize(length); // Write the data to the Storage backend - auto res = MakeResult<size_t>(backend->WriteBytes(data, offset)); + std::vector<u8> data = ctx.ReadBuffer(); + ResultVal<size_t> res = backend->Write(offset, length, true, data.data()); if (res.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); @@ -155,8 +154,7 @@ private: void Flush(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); - - // Exists for SDK compatibiltity -- No need to flush file. + backend->Flush(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); @@ -165,7 +163,7 @@ private: void SetSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u64 size = rp.Pop<u64>(); - backend->Resize(size); + backend->SetSize(size); LOG_DEBUG(Service_FS, "called, size={}", size); IPC::ResponseBuilder rb{ctx, 2}; @@ -182,38 +180,19 @@ private: } }; -template <typename T> -static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vector<T>& new_data, - FileSys::EntryType type) { - for (const auto& new_entry : new_data) { - FileSys::Entry entry; - entry.filename[0] = '\0'; - std::strncat(entry.filename, new_entry->GetName().c_str(), FileSys::FILENAME_LENGTH - 1); - entry.type = type; - entry.file_size = new_entry->GetSize(); - entries.emplace_back(std::move(entry)); - } -} - class IDirectory final : public ServiceFramework<IDirectory> { public: - explicit IDirectory(FileSys::VirtualDir backend_) - : ServiceFramework("IDirectory"), backend(std::move(backend_)) { + explicit IDirectory(std::unique_ptr<FileSys::DirectoryBackend>&& backend) + : ServiceFramework("IDirectory"), backend(std::move(backend)) { static const FunctionInfo functions[] = { {0, &IDirectory::Read, "Read"}, {1, &IDirectory::GetEntryCount, "GetEntryCount"}, }; RegisterHandlers(functions); - - // Build entry index now to save time later. - BuildEntryIndex(entries, backend->GetFiles(), FileSys::File); - BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::Directory); } private: - FileSys::VirtualDir backend; - std::vector<FileSys::Entry> entries; - u64 next_entry_index = 0; + std::unique_ptr<FileSys::DirectoryBackend> backend; void Read(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; @@ -224,31 +203,26 @@ private: // Calculate how many entries we can fit in the output buffer u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry); - // Cap at total number of entries. - u64 actual_entries = std::min(count_entries, entries.size() - next_entry_index); - // Read the data from the Directory backend - std::vector<FileSys::Entry> entry_data(entries.begin() + next_entry_index, - entries.begin() + next_entry_index + actual_entries); - - next_entry_index += actual_entries; + std::vector<FileSys::Entry> entries(count_entries); + u64 read_entries = backend->Read(count_entries, entries.data()); // Convert the data into a byte array - std::vector<u8> output(entry_data.size() * sizeof(FileSys::Entry)); - std::memcpy(output.data(), entry_data.data(), output.size()); + std::vector<u8> output(entries.size() * sizeof(FileSys::Entry)); + std::memcpy(output.data(), entries.data(), output.size()); // Write the data to memory ctx.WriteBuffer(output); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push(actual_entries); + rb.Push(read_entries); } void GetEntryCount(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); - u64 count = entries.size() - next_entry_index; + u64 count = backend->GetEntryCount(); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); @@ -258,7 +232,7 @@ private: class IFileSystem final : public ServiceFramework<IFileSystem> { public: - explicit IFileSystem(FileSys::VirtualDir backend) + explicit IFileSystem(std::unique_ptr<FileSys::FileSystemBackend>&& backend) : ServiceFramework("IFileSystem"), backend(std::move(backend)) { static const FunctionInfo functions[] = { {0, &IFileSystem::CreateFile, "CreateFile"}, @@ -293,7 +267,7 @@ public: LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateFile(name, size)); + rb.Push(backend->CreateFile(name, size)); } void DeleteFile(Kernel::HLERequestContext& ctx) { @@ -305,7 +279,7 @@ public: LOG_DEBUG(Service_FS, "called file {}", name); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.DeleteFile(name)); + rb.Push(backend->DeleteFile(name)); } void CreateDirectory(Kernel::HLERequestContext& ctx) { @@ -317,7 +291,7 @@ public: LOG_DEBUG(Service_FS, "called directory {}", name); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateDirectory(name)); + rb.Push(backend->CreateDirectory(name)); } void RenameFile(Kernel::HLERequestContext& ctx) { @@ -335,7 +309,7 @@ public: 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)); + rb.Push(backend->RenameFile(src_name, dst_name)); } void OpenFile(Kernel::HLERequestContext& ctx) { @@ -348,14 +322,14 @@ public: LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode)); - auto result = backend.OpenFile(name, mode); + auto result = backend->OpenFile(name, mode); if (result.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result.Code()); return; } - IFile file(result.Unwrap()); + auto file = std::move(result.Unwrap()); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -373,14 +347,14 @@ public: LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags); - auto result = backend.OpenDirectory(name); + auto result = backend->OpenDirectory(name); if (result.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result.Code()); return; } - IDirectory directory(result.Unwrap()); + auto directory = std::move(result.Unwrap()); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -395,7 +369,7 @@ public: LOG_DEBUG(Service_FS, "called file {}", name); - auto result = backend.GetEntryType(name); + auto result = backend->GetEntryType(name); if (result.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result.Code()); @@ -415,7 +389,7 @@ public: } private: - VfsDirectoryServiceWrapper backend; + std::unique_ptr<FileSys::FileSystemBackend> backend; }; FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { @@ -516,7 +490,8 @@ void FSP_SRV::TryLoadRomFS() { if (romfs) { return; } - auto res = OpenRomFS(); + FileSys::Path unused; + auto res = OpenFileSystem(Type::RomFS, unused); if (res.Succeeded()) { romfs = std::move(res.Unwrap()); } @@ -532,7 +507,8 @@ void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) { void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); - IFileSystem filesystem(OpenFileSystem(Type::SDMC).Unwrap()); + FileSys::Path unused; + auto filesystem = OpenFileSystem(Type::SDMC, unused).Unwrap(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -555,7 +531,8 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) { void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_FS, "(STUBBED) called"); - IFileSystem filesystem(OpenFileSystem(Type::SaveData).Unwrap()); + FileSys::Path unused; + auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap(); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -582,11 +559,18 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { return; } - IStorage storage(romfs); + // Attempt to open a StorageBackend interface to the RomFS + auto storage = romfs->OpenFile({}, {}); + if (storage.Failed()) { + LOG_CRITICAL(Service_FS, "no storage interface available!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(storage.Code()); + return; + } IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface<IStorage>(std::move(storage)); + rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap())); } void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) { |