|
@@ -8,11 +8,7 @@
|
|
|
#include "core/core.h"
|
|
#include "core/core.h"
|
|
|
#include "core/file_sys/directory.h"
|
|
#include "core/file_sys/directory.h"
|
|
|
#include "core/file_sys/errors.h"
|
|
#include "core/file_sys/errors.h"
|
|
|
-#include "core/file_sys/filesystem.h"
|
|
|
|
|
-#include "core/file_sys/storage.h"
|
|
|
|
|
#include "core/hle/ipc_helpers.h"
|
|
#include "core/hle/ipc_helpers.h"
|
|
|
-#include "core/hle/kernel/client_port.h"
|
|
|
|
|
-#include "core/hle/kernel/client_session.h"
|
|
|
|
|
#include "core/hle/kernel/process.h"
|
|
#include "core/hle/kernel/process.h"
|
|
|
#include "core/hle/service/filesystem/filesystem.h"
|
|
#include "core/hle/service/filesystem/filesystem.h"
|
|
|
#include "core/hle/service/filesystem/fsp_srv.h"
|
|
#include "core/hle/service/filesystem/fsp_srv.h"
|
|
@@ -25,13 +21,13 @@ enum class StorageId : u8 {
|
|
|
GameCard = 2,
|
|
GameCard = 2,
|
|
|
NandSystem = 3,
|
|
NandSystem = 3,
|
|
|
NandUser = 4,
|
|
NandUser = 4,
|
|
|
- SdCard = 5
|
|
|
|
|
|
|
+ SdCard = 5,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
class IStorage final : public ServiceFramework<IStorage> {
|
|
class IStorage final : public ServiceFramework<IStorage> {
|
|
|
public:
|
|
public:
|
|
|
- IStorage(std::unique_ptr<FileSys::StorageBackend>&& backend)
|
|
|
|
|
- : ServiceFramework("IStorage"), backend(std::move(backend)) {
|
|
|
|
|
|
|
+ IStorage(FileSys::VirtualFile backend_)
|
|
|
|
|
+ : ServiceFramework("IStorage"), backend(std::move(backend_)) {
|
|
|
static const FunctionInfo functions[] = {
|
|
static const FunctionInfo functions[] = {
|
|
|
{0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
|
|
{0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
|
|
|
{3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"},
|
|
{3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"},
|
|
@@ -40,7 +36,7 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- std::unique_ptr<FileSys::StorageBackend> backend;
|
|
|
|
|
|
|
+ FileSys::VirtualFile backend;
|
|
|
|
|
|
|
|
void Read(Kernel::HLERequestContext& ctx) {
|
|
void Read(Kernel::HLERequestContext& ctx) {
|
|
|
IPC::RequestParser rp{ctx};
|
|
IPC::RequestParser rp{ctx};
|
|
@@ -62,14 +58,7 @@ private:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Read the data from the Storage backend
|
|
// Read the data from the Storage backend
|
|
|
- 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());
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ std::vector<u8> output = backend->ReadBytes(length, offset);
|
|
|
// Write the data to memory
|
|
// Write the data to memory
|
|
|
ctx.WriteBuffer(output);
|
|
ctx.WriteBuffer(output);
|
|
|
|
|
|
|
@@ -80,8 +69,8 @@ private:
|
|
|
|
|
|
|
|
class IFile final : public ServiceFramework<IFile> {
|
|
class IFile final : public ServiceFramework<IFile> {
|
|
|
public:
|
|
public:
|
|
|
- explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend)
|
|
|
|
|
- : ServiceFramework("IFile"), backend(std::move(backend)) {
|
|
|
|
|
|
|
+ explicit IFile(FileSys::VirtualFile backend_)
|
|
|
|
|
+ : ServiceFramework("IFile"), backend(std::move(backend_)) {
|
|
|
static const FunctionInfo functions[] = {
|
|
static const FunctionInfo functions[] = {
|
|
|
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
|
|
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
|
|
|
{2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
|
|
{2, &IFile::Flush, "Flush"}, {3, &IFile::SetSize, "SetSize"},
|
|
@@ -91,7 +80,7 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- std::unique_ptr<FileSys::StorageBackend> backend;
|
|
|
|
|
|
|
+ FileSys::VirtualFile backend;
|
|
|
|
|
|
|
|
void Read(Kernel::HLERequestContext& ctx) {
|
|
void Read(Kernel::HLERequestContext& ctx) {
|
|
|
IPC::RequestParser rp{ctx};
|
|
IPC::RequestParser rp{ctx};
|
|
@@ -114,20 +103,14 @@ private:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Read the data from the Storage backend
|
|
// Read the data from the Storage backend
|
|
|
- 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());
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ std::vector<u8> output = backend->ReadBytes(length, offset);
|
|
|
|
|
|
|
|
// Write the data to memory
|
|
// Write the data to memory
|
|
|
ctx.WriteBuffer(output);
|
|
ctx.WriteBuffer(output);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
- rb.Push(static_cast<u64>(*res));
|
|
|
|
|
|
|
+ rb.Push(static_cast<u64>(output.size()));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void Write(Kernel::HLERequestContext& ctx) {
|
|
void Write(Kernel::HLERequestContext& ctx) {
|
|
@@ -150,14 +133,21 @@ private:
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // Write the data to the Storage backend
|
|
|
|
|
std::vector<u8> data = ctx.ReadBuffer();
|
|
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());
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ std::vector<u8> actual_data(length);
|
|
|
|
|
+
|
|
|
|
|
+ ASSERT_MSG(
|
|
|
|
|
+ data.size() <= length,
|
|
|
|
|
+ "Attempting to write more data than requested (requested={:016X}, actual={:016X}).",
|
|
|
|
|
+ length, data.size());
|
|
|
|
|
+
|
|
|
|
|
+ std::copy(data.begin(), data.end(), actual_data.begin());
|
|
|
|
|
+ // Write the data to the Storage backend
|
|
|
|
|
+ auto written = backend->WriteBytes(data, offset);
|
|
|
|
|
+
|
|
|
|
|
+ ASSERT_MSG(written == length,
|
|
|
|
|
+ "Could not write all bytes to file (requested={:016X}, actual={:016X}).", length,
|
|
|
|
|
+ written);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
@@ -165,7 +155,8 @@ private:
|
|
|
|
|
|
|
|
void Flush(Kernel::HLERequestContext& ctx) {
|
|
void Flush(Kernel::HLERequestContext& ctx) {
|
|
|
LOG_DEBUG(Service_FS, "called");
|
|
LOG_DEBUG(Service_FS, "called");
|
|
|
- backend->Flush();
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // Exists for SDK compatibiltity -- No need to flush file.
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
@@ -174,7 +165,7 @@ private:
|
|
|
void SetSize(Kernel::HLERequestContext& ctx) {
|
|
void SetSize(Kernel::HLERequestContext& ctx) {
|
|
|
IPC::RequestParser rp{ctx};
|
|
IPC::RequestParser rp{ctx};
|
|
|
const u64 size = rp.Pop<u64>();
|
|
const u64 size = rp.Pop<u64>();
|
|
|
- backend->SetSize(size);
|
|
|
|
|
|
|
+ backend->Resize(size);
|
|
|
LOG_DEBUG(Service_FS, "called, size={}", size);
|
|
LOG_DEBUG(Service_FS, "called, size={}", size);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
@@ -191,19 +182,39 @@ 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> {
|
|
class IDirectory final : public ServiceFramework<IDirectory> {
|
|
|
public:
|
|
public:
|
|
|
- explicit IDirectory(std::unique_ptr<FileSys::DirectoryBackend>&& backend)
|
|
|
|
|
- : ServiceFramework("IDirectory"), backend(std::move(backend)) {
|
|
|
|
|
|
|
+ explicit IDirectory(FileSys::VirtualDir backend_)
|
|
|
|
|
+ : ServiceFramework("IDirectory"), backend(std::move(backend_)) {
|
|
|
static const FunctionInfo functions[] = {
|
|
static const FunctionInfo functions[] = {
|
|
|
{0, &IDirectory::Read, "Read"},
|
|
{0, &IDirectory::Read, "Read"},
|
|
|
{1, &IDirectory::GetEntryCount, "GetEntryCount"},
|
|
{1, &IDirectory::GetEntryCount, "GetEntryCount"},
|
|
|
};
|
|
};
|
|
|
RegisterHandlers(functions);
|
|
RegisterHandlers(functions);
|
|
|
|
|
+
|
|
|
|
|
+ // TODO(DarkLordZach): Verify that this is the correct behavior.
|
|
|
|
|
+ // Build entry index now to save time later.
|
|
|
|
|
+ BuildEntryIndex(entries, backend->GetFiles(), FileSys::File);
|
|
|
|
|
+ BuildEntryIndex(entries, backend->GetSubdirectories(), FileSys::Directory);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- std::unique_ptr<FileSys::DirectoryBackend> backend;
|
|
|
|
|
|
|
+ FileSys::VirtualDir backend;
|
|
|
|
|
+ std::vector<FileSys::Entry> entries;
|
|
|
|
|
+ u64 next_entry_index = 0;
|
|
|
|
|
|
|
|
void Read(Kernel::HLERequestContext& ctx) {
|
|
void Read(Kernel::HLERequestContext& ctx) {
|
|
|
IPC::RequestParser rp{ctx};
|
|
IPC::RequestParser rp{ctx};
|
|
@@ -214,26 +225,31 @@ private:
|
|
|
// Calculate how many entries we can fit in the output buffer
|
|
// Calculate how many entries we can fit in the output buffer
|
|
|
u64 count_entries = ctx.GetWriteBufferSize() / sizeof(FileSys::Entry);
|
|
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
|
|
// Read the data from the Directory backend
|
|
|
- std::vector<FileSys::Entry> entries(count_entries);
|
|
|
|
|
- u64 read_entries = backend->Read(count_entries, entries.data());
|
|
|
|
|
|
|
+ std::vector<FileSys::Entry> entry_data(entries.begin() + next_entry_index,
|
|
|
|
|
+ entries.begin() + next_entry_index + actual_entries);
|
|
|
|
|
+
|
|
|
|
|
+ next_entry_index += actual_entries;
|
|
|
|
|
|
|
|
// Convert the data into a byte array
|
|
// Convert the data into a byte array
|
|
|
- std::vector<u8> output(entries.size() * sizeof(FileSys::Entry));
|
|
|
|
|
- std::memcpy(output.data(), entries.data(), output.size());
|
|
|
|
|
|
|
+ std::vector<u8> output(entry_data.size() * sizeof(FileSys::Entry));
|
|
|
|
|
+ std::memcpy(output.data(), entry_data.data(), output.size());
|
|
|
|
|
|
|
|
// Write the data to memory
|
|
// Write the data to memory
|
|
|
ctx.WriteBuffer(output);
|
|
ctx.WriteBuffer(output);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
- rb.Push(read_entries);
|
|
|
|
|
|
|
+ rb.Push(actual_entries);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void GetEntryCount(Kernel::HLERequestContext& ctx) {
|
|
void GetEntryCount(Kernel::HLERequestContext& ctx) {
|
|
|
LOG_DEBUG(Service_FS, "called");
|
|
LOG_DEBUG(Service_FS, "called");
|
|
|
|
|
|
|
|
- u64 count = backend->GetEntryCount();
|
|
|
|
|
|
|
+ u64 count = entries.size() - next_entry_index;
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
IPC::ResponseBuilder rb{ctx, 4};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
@@ -243,7 +259,7 @@ private:
|
|
|
|
|
|
|
|
class IFileSystem final : public ServiceFramework<IFileSystem> {
|
|
class IFileSystem final : public ServiceFramework<IFileSystem> {
|
|
|
public:
|
|
public:
|
|
|
- explicit IFileSystem(std::unique_ptr<FileSys::FileSystemBackend>&& backend)
|
|
|
|
|
|
|
+ explicit IFileSystem(FileSys::VirtualDir backend)
|
|
|
: ServiceFramework("IFileSystem"), backend(std::move(backend)) {
|
|
: ServiceFramework("IFileSystem"), backend(std::move(backend)) {
|
|
|
static const FunctionInfo functions[] = {
|
|
static const FunctionInfo functions[] = {
|
|
|
{0, &IFileSystem::CreateFile, "CreateFile"},
|
|
{0, &IFileSystem::CreateFile, "CreateFile"},
|
|
@@ -278,7 +294,7 @@ public:
|
|
|
LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size);
|
|
LOG_DEBUG(Service_FS, "called file {} mode 0x{:X} size 0x{:08X}", name, mode, size);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
- rb.Push(backend->CreateFile(name, size));
|
|
|
|
|
|
|
+ rb.Push(backend.CreateFile(name, size));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void DeleteFile(Kernel::HLERequestContext& ctx) {
|
|
void DeleteFile(Kernel::HLERequestContext& ctx) {
|
|
@@ -290,7 +306,7 @@ public:
|
|
|
LOG_DEBUG(Service_FS, "called file {}", name);
|
|
LOG_DEBUG(Service_FS, "called file {}", name);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
- rb.Push(backend->DeleteFile(name));
|
|
|
|
|
|
|
+ rb.Push(backend.DeleteFile(name));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CreateDirectory(Kernel::HLERequestContext& ctx) {
|
|
void CreateDirectory(Kernel::HLERequestContext& ctx) {
|
|
@@ -302,7 +318,7 @@ public:
|
|
|
LOG_DEBUG(Service_FS, "called directory {}", name);
|
|
LOG_DEBUG(Service_FS, "called directory {}", name);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
- rb.Push(backend->CreateDirectory(name));
|
|
|
|
|
|
|
+ rb.Push(backend.CreateDirectory(name));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RenameFile(Kernel::HLERequestContext& ctx) {
|
|
void RenameFile(Kernel::HLERequestContext& ctx) {
|
|
@@ -320,7 +336,7 @@ public:
|
|
|
LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name);
|
|
LOG_DEBUG(Service_FS, "called file '{}' to file '{}'", src_name, dst_name);
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
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) {
|
|
void OpenFile(Kernel::HLERequestContext& ctx) {
|
|
@@ -333,14 +349,14 @@ public:
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_FS, "called file {} mode {}", name, static_cast<u32>(mode));
|
|
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()) {
|
|
if (result.Failed()) {
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
rb.Push(result.Code());
|
|
rb.Push(result.Code());
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- auto file = std::move(result.Unwrap());
|
|
|
|
|
|
|
+ IFile file(result.Unwrap());
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
@@ -358,14 +374,14 @@ public:
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags);
|
|
LOG_DEBUG(Service_FS, "called directory {} filter {}", name, filter_flags);
|
|
|
|
|
|
|
|
- auto result = backend->OpenDirectory(name);
|
|
|
|
|
|
|
+ auto result = backend.OpenDirectory(name);
|
|
|
if (result.Failed()) {
|
|
if (result.Failed()) {
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
rb.Push(result.Code());
|
|
rb.Push(result.Code());
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- auto directory = std::move(result.Unwrap());
|
|
|
|
|
|
|
+ IDirectory directory(result.Unwrap());
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
@@ -380,7 +396,7 @@ public:
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_FS, "called file {}", name);
|
|
LOG_DEBUG(Service_FS, "called file {}", name);
|
|
|
|
|
|
|
|
- auto result = backend->GetEntryType(name);
|
|
|
|
|
|
|
+ auto result = backend.GetEntryType(name);
|
|
|
if (result.Failed()) {
|
|
if (result.Failed()) {
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
rb.Push(result.Code());
|
|
rb.Push(result.Code());
|
|
@@ -400,7 +416,7 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
|
- std::unique_ptr<FileSys::FileSystemBackend> backend;
|
|
|
|
|
|
|
+ VfsDirectoryServiceWrapper backend;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
|
|
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
|
|
@@ -536,17 +552,19 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
|
|
|
LOG_INFO(Service_FS, "called with unknown={:08X}", unk);
|
|
LOG_INFO(Service_FS, "called with unknown={:08X}", unk);
|
|
|
auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>();
|
|
auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>();
|
|
|
|
|
|
|
|
- auto filesystem = OpenSaveData(space_id, save_struct);
|
|
|
|
|
|
|
+ auto dir = OpenSaveData(space_id, save_struct);
|
|
|
|
|
|
|
|
- if (filesystem.Failed()) {
|
|
|
|
|
|
|
+ if (dir.Failed()) {
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
|
|
- rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::SaveDataNotFound));
|
|
|
|
|
|
|
+ rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::TitleNotFound));
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ IFileSystem filesystem(std::move(dir.Unwrap()));
|
|
|
|
|
+
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
- rb.PushIpcInterface<IFileSystem>(std::move(filesystem.Unwrap()));
|
|
|
|
|
|
|
+ rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
|
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
|
@@ -569,18 +587,11 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- auto storage = romfs.Unwrap()->OpenFile({}, {});
|
|
|
|
|
-
|
|
|
|
|
- if (storage.Failed()) {
|
|
|
|
|
- LOG_CRITICAL(Service_FS, "no storage interface available!");
|
|
|
|
|
- IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
|
- rb.Push(storage.Code());
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ IStorage storage(std::move(romfs.Unwrap()));
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
|
|
rb.Push(RESULT_SUCCESS);
|
|
rb.Push(RESULT_SUCCESS);
|
|
|
- rb.PushIpcInterface<IStorage>(std::move(storage.Unwrap()));
|
|
|
|
|
|
|
+ rb.PushIpcInterface<IStorage>(std::move(storage));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
|
void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
|
@@ -591,33 +602,9 @@ void FSP_SRV::OpenRomStorage(Kernel::HLERequestContext& ctx) {
|
|
|
|
|
|
|
|
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}",
|
|
LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}",
|
|
|
static_cast<u8>(storage_id), title_id);
|
|
static_cast<u8>(storage_id), title_id);
|
|
|
- if (title_id != Core::System::GetInstance().CurrentProcess()->program_id) {
|
|
|
|
|
- LOG_CRITICAL(
|
|
|
|
|
- Service_FS,
|
|
|
|
|
- "Attempting to access RomFS of another title id (current={:016X}, requested={:016X}).",
|
|
|
|
|
- Core::System::GetInstance().CurrentProcess()->program_id, title_id);
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- auto romfs = OpenRomFS(title_id);
|
|
|
|
|
- if (romfs.Failed()) {
|
|
|
|
|
- LOG_CRITICAL(Service_FS, "no file system interface available!");
|
|
|
|
|
- IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
|
- rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::RomFSNotFound));
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- auto storage = romfs.Unwrap()->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.Unwrap()));
|
|
|
|
|
|
|
+ IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
|
+ rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::TitleNotFound));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
} // namespace Service::FileSystem
|
|
} // namespace Service::FileSystem
|