Compare commits
7 Commits
revert-115
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
187d5cb60c | ||
|
|
8f05e2258b | ||
|
|
5b3b49b353 | ||
|
|
f4aca09678 | ||
|
|
03c3564af5 | ||
|
|
4f163cf77f | ||
|
|
a0702e2db3 |
@@ -86,6 +86,8 @@ add_library(core STATIC
|
|||||||
file_sys/vfs_offset.h
|
file_sys/vfs_offset.h
|
||||||
file_sys/vfs_real.cpp
|
file_sys/vfs_real.cpp
|
||||||
file_sys/vfs_real.h
|
file_sys/vfs_real.h
|
||||||
|
file_sys/vfs_ro_layer.cpp
|
||||||
|
file_sys/vfs_ro_layer.h
|
||||||
file_sys/vfs_static.h
|
file_sys/vfs_static.h
|
||||||
file_sys/vfs_types.h
|
file_sys/vfs_types.h
|
||||||
file_sys/vfs_vector.cpp
|
file_sys/vfs_vector.cpp
|
||||||
|
|||||||
@@ -172,6 +172,40 @@ u64 XCI::GetProgramTitleID() const {
|
|||||||
return secure_partition->GetProgramTitleID();
|
return secure_partition->GetProgramTitleID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 XCI::GetSystemUpdateVersion() {
|
||||||
|
const auto update = GetPartition(XCIPartition::Update);
|
||||||
|
if (update == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (const auto& file : update->GetFiles()) {
|
||||||
|
NCA nca{file, nullptr, 0, keys};
|
||||||
|
|
||||||
|
if (nca.GetStatus() != Loader::ResultStatus::Success)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nca.GetType() == NCAContentType::Meta && nca.GetTitleId() == 0x0100000000000816) {
|
||||||
|
const auto dir = nca.GetSubdirectories()[0];
|
||||||
|
const auto cnmt = dir->GetFile("SystemUpdate_0100000000000816.cnmt");
|
||||||
|
if (cnmt == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CNMT cnmt_data{cnmt};
|
||||||
|
|
||||||
|
const auto metas = cnmt_data.GetMetaRecords();
|
||||||
|
if (metas.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return metas[0].title_version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 XCI::GetSystemUpdateTitleID() const {
|
||||||
|
return 0x0100000000000816;
|
||||||
|
}
|
||||||
|
|
||||||
bool XCI::HasProgramNCA() const {
|
bool XCI::HasProgramNCA() const {
|
||||||
return program != nullptr;
|
return program != nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
181
src/core/file_sys/vfs_ro_layer.cpp
Normal file
181
src/core/file_sys/vfs_ro_layer.cpp
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/file_sys/vfs_ro_layer.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
ReadOnlyVfsFileLayer::ReadOnlyVfsFileLayer(VirtualFile base) : base(std::move(base)) {}
|
||||||
|
|
||||||
|
ReadOnlyVfsFileLayer::~ReadOnlyVfsFileLayer() = default;
|
||||||
|
|
||||||
|
std::string ReadOnlyVfsFileLayer::GetName() const {
|
||||||
|
return base->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ReadOnlyVfsFileLayer::GetSize() const {
|
||||||
|
return base->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsFileLayer::Resize(std::size_t new_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsFileLayer::GetContainingDirectory() const {
|
||||||
|
// Make containing read-only to prevent escaping the layer by getting containing and then
|
||||||
|
// getting this file again.
|
||||||
|
return std::make_shared<ReadOnlyVfsDirectoryLayer>(base->GetContainingDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsFileLayer::IsWritable() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsFileLayer::IsReadable() const {
|
||||||
|
return base->IsReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ReadOnlyVfsFileLayer::Read(u8* data, std::size_t length, std::size_t offset) const {
|
||||||
|
return base->Read(data, length, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ReadOnlyVfsFileLayer::Write(const u8* data, std::size_t length, std::size_t offset) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsFileLayer::Rename(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ReadOnlyVfsFileLayer::GetFullPath() const {
|
||||||
|
return base->GetFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadOnlyVfsDirectoryLayer::ReadOnlyVfsDirectoryLayer(VirtualDir base) : base(std::move(base)) {}
|
||||||
|
|
||||||
|
ReadOnlyVfsDirectoryLayer::~ReadOnlyVfsDirectoryLayer() = default;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<VfsFile>> ReadOnlyVfsDirectoryLayer::GetFiles() const {
|
||||||
|
std::vector<VirtualFile> out;
|
||||||
|
const auto in = base->GetFiles();
|
||||||
|
std::transform(in.begin(), in.end(), std::back_inserter(out),
|
||||||
|
[](const VirtualFile& i) { return std::make_shared<ReadOnlyVfsFileLayer>(i); });
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<VfsDirectory>> ReadOnlyVfsDirectoryLayer::GetSubdirectories() const {
|
||||||
|
std::vector<VirtualDir> out;
|
||||||
|
const auto in = base->GetSubdirectories();
|
||||||
|
std::transform(in.begin(), in.end(), std::back_inserter(out), [](const VirtualDir& i) {
|
||||||
|
return std::make_shared<ReadOnlyVfsDirectoryLayer>(i);
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ReadOnlyVfsDirectoryLayer::GetName() const {
|
||||||
|
return base->GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetParentDirectory() const {
|
||||||
|
return std::make_shared<ReadOnlyVfsDirectoryLayer>(base->GetParentDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::GetFileRelative(std::string_view path) const {
|
||||||
|
return std::make_shared<ReadOnlyVfsFileLayer>(base->GetFileRelative(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::GetFileAbsolute(std::string_view path) const {
|
||||||
|
return std::make_shared<ReadOnlyVfsFileLayer>(base->GetFileAbsolute(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetDirectoryRelative(
|
||||||
|
std::string_view path) const {
|
||||||
|
return std::make_shared<ReadOnlyVfsDirectoryLayer>(base->GetDirectoryRelative(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetDirectoryAbsolute(
|
||||||
|
std::string_view path) const {
|
||||||
|
return std::make_shared<ReadOnlyVfsDirectoryLayer>(base->GetDirectoryAbsolute(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::GetFile(std::string_view name) const {
|
||||||
|
return std::make_shared<ReadOnlyVfsFileLayer>(base->GetFile(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::GetSubdirectory(
|
||||||
|
std::string_view name) const {
|
||||||
|
return std::make_shared<ReadOnlyVfsDirectoryLayer>(base->GetSubdirectory(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::IsRoot() const {
|
||||||
|
return base->IsRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ReadOnlyVfsDirectoryLayer::GetSize() const {
|
||||||
|
return base->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::Copy(std::string_view src, std::string_view dest) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ReadOnlyVfsDirectoryLayer::GetFullPath() const {
|
||||||
|
return base->GetFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::IsWritable() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::IsReadable() const {
|
||||||
|
return base->IsReadable();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::CreateSubdirectory(std::string_view name) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::CreateFile(std::string_view name) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::CreateFileAbsolute(std::string_view path) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> ReadOnlyVfsDirectoryLayer::CreateFileRelative(std::string_view path) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::CreateDirectoryAbsolute(
|
||||||
|
std::string_view path) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectoryLayer::CreateDirectoryRelative(
|
||||||
|
std::string_view path) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::DeleteSubdirectory(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::DeleteSubdirectoryRecursive(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::CleanSubdirectoryRecursive(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::DeleteFile(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadOnlyVfsDirectoryLayer::Rename(std::string_view name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileSys
|
||||||
73
src/core/file_sys/vfs_ro_layer.h
Normal file
73
src/core/file_sys/vfs_ro_layer.h
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include "core/file_sys/vfs.h"
|
||||||
|
|
||||||
|
namespace FileSys {
|
||||||
|
|
||||||
|
// Class that wraps a VfsFile making it read-only
|
||||||
|
class ReadOnlyVfsFileLayer : public VfsFile {
|
||||||
|
public:
|
||||||
|
explicit ReadOnlyVfsFileLayer(VirtualFile base);
|
||||||
|
~ReadOnlyVfsFileLayer() override;
|
||||||
|
|
||||||
|
std::string GetName() const override;
|
||||||
|
std::size_t GetSize() const override;
|
||||||
|
bool Resize(std::size_t new_size) override;
|
||||||
|
std::shared_ptr<VfsDirectory> GetContainingDirectory() const override;
|
||||||
|
bool IsWritable() const override;
|
||||||
|
bool IsReadable() const override;
|
||||||
|
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
|
||||||
|
std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
|
||||||
|
bool Rename(std::string_view name) override;
|
||||||
|
|
||||||
|
std::string GetFullPath() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VirtualFile base;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Class that wraps a VfsDirectory making it and its children read only.
|
||||||
|
class ReadOnlyVfsDirectoryLayer : public ReadOnlyVfsDirectory {
|
||||||
|
public:
|
||||||
|
explicit ReadOnlyVfsDirectoryLayer(VirtualDir base);
|
||||||
|
~ReadOnlyVfsDirectoryLayer() override;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<VfsFile>> GetFiles() const override;
|
||||||
|
std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override;
|
||||||
|
std::string GetName() const override;
|
||||||
|
std::shared_ptr<VfsDirectory> GetParentDirectory() const override;
|
||||||
|
|
||||||
|
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
|
||||||
|
std::shared_ptr<VfsFile> GetFileAbsolute(std::string_view path) const override;
|
||||||
|
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
|
||||||
|
std::shared_ptr<VfsDirectory> GetDirectoryAbsolute(std::string_view path) const override;
|
||||||
|
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
|
||||||
|
std::shared_ptr<VfsDirectory> GetSubdirectory(std::string_view name) const override;
|
||||||
|
bool IsRoot() const override;
|
||||||
|
std::size_t GetSize() const override;
|
||||||
|
bool Copy(std::string_view src, std::string_view dest) override;
|
||||||
|
std::string GetFullPath() const override;
|
||||||
|
bool IsWritable() const override;
|
||||||
|
bool IsReadable() const override;
|
||||||
|
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
|
||||||
|
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
|
||||||
|
std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override;
|
||||||
|
std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
|
||||||
|
std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override;
|
||||||
|
std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
|
||||||
|
bool DeleteSubdirectory(std::string_view name) override;
|
||||||
|
bool DeleteSubdirectoryRecursive(std::string_view name) override;
|
||||||
|
bool CleanSubdirectoryRecursive(std::string_view name) override;
|
||||||
|
bool DeleteFile(std::string_view name) override;
|
||||||
|
bool Rename(std::string_view name) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VirtualDir base;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace FileSys
|
||||||
@@ -713,8 +713,7 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
|
|||||||
void InstallInterfaces(Core::System& system) {
|
void InstallInterfaces(Core::System& system) {
|
||||||
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
|
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
|
||||||
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
|
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
|
||||||
std::make_shared<FSP_SRV>(system.GetFileSystemController(), system.GetReporter())
|
std::make_shared<FSP_SRV>(system)->InstallAsService(system.ServiceManager());
|
||||||
->InstallAsService(system.ServiceManager());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::FileSystem
|
} // namespace Service::FileSystem
|
||||||
|
|||||||
@@ -14,17 +14,22 @@
|
|||||||
#include "common/hex_util.h"
|
#include "common/hex_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
#include "core/file_sys/content_archive.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/mode.h"
|
#include "core/file_sys/mode.h"
|
||||||
#include "core/file_sys/nca_metadata.h"
|
#include "core/file_sys/nca_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
#include "core/file_sys/romfs.h"
|
||||||
#include "core/file_sys/romfs_factory.h"
|
#include "core/file_sys/romfs_factory.h"
|
||||||
#include "core/file_sys/savedata_factory.h"
|
#include "core/file_sys/savedata_factory.h"
|
||||||
#include "core/file_sys/system_archive/system_archive.h"
|
#include "core/file_sys/system_archive/system_archive.h"
|
||||||
#include "core/file_sys/vfs.h"
|
#include "core/file_sys/vfs.h"
|
||||||
|
#include "core/file_sys/vfs_ro_layer.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
#include "core/hle/kernel/readable_event.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"
|
||||||
#include "core/reporter.h"
|
#include "core/reporter.h"
|
||||||
@@ -54,6 +59,12 @@ enum class FileSystemType : u8 {
|
|||||||
ApplicationPackage = 7,
|
ApplicationPackage = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SaveDataOpenMode {
|
||||||
|
Normal,
|
||||||
|
ReadOnly,
|
||||||
|
System,
|
||||||
|
};
|
||||||
|
|
||||||
class IStorage final : public ServiceFramework<IStorage> {
|
class IStorage final : public ServiceFramework<IStorage> {
|
||||||
public:
|
public:
|
||||||
explicit IStorage(FileSys::VirtualFile backend_)
|
explicit IStorage(FileSys::VirtualFile backend_)
|
||||||
@@ -503,14 +514,17 @@ private:
|
|||||||
|
|
||||||
class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
|
class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> {
|
||||||
public:
|
public:
|
||||||
explicit ISaveDataInfoReader(FileSys::SaveDataSpaceId space, FileSystemController& fsc)
|
explicit ISaveDataInfoReader(FileSystemController& fsc,
|
||||||
|
std::vector<FileSys::SaveDataSpaceId> spaces)
|
||||||
: ServiceFramework("ISaveDataInfoReader"), fsc(fsc) {
|
: ServiceFramework("ISaveDataInfoReader"), fsc(fsc) {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
|
{0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"},
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
FindAllSaves(space);
|
for (const auto& space : spaces) {
|
||||||
|
FindAllSaves(space);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadSaveDataInfo(Kernel::HLERequestContext& ctx) {
|
void ReadSaveDataInfo(Kernel::HLERequestContext& ctx) {
|
||||||
@@ -650,8 +664,31 @@ private:
|
|||||||
u64 next_entry_index = 0;
|
u64 next_entry_index = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
class IEventNotifier final : public ServiceFramework<IEventNotifier> {
|
||||||
: ServiceFramework("fsp-srv"), fsc(fsc), reporter(reporter) {
|
public:
|
||||||
|
explicit IEventNotifier(Kernel::SharedPtr<Kernel::ReadableEvent> event)
|
||||||
|
: ServiceFramework{"IEventNotifier"}, event(std::move(event)) {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, &IEventNotifier::GetEventHandle, "GetEventHandle"},
|
||||||
|
};
|
||||||
|
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GetEventHandle(Kernel::HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_FS, "called");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushCopyObjects(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Kernel::SharedPtr<Kernel::ReadableEvent> event;
|
||||||
|
};
|
||||||
|
|
||||||
|
FSP_SRV::FSP_SRV(Core::System& system)
|
||||||
|
: ServiceFramework("fsp-srv"), system(system), fsc(system.GetFileSystemController()) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "OpenFileSystem"},
|
{0, nullptr, "OpenFileSystem"},
|
||||||
@@ -660,15 +697,15 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
|||||||
{7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"},
|
{7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"},
|
||||||
{8, nullptr, "OpenFileSystemWithId"},
|
{8, nullptr, "OpenFileSystemWithId"},
|
||||||
{9, nullptr, "OpenDataFileSystemByApplicationId"},
|
{9, nullptr, "OpenDataFileSystemByApplicationId"},
|
||||||
{11, nullptr, "OpenBisFileSystem"},
|
{11, &FSP_SRV::OpenBisFileSystem, "OpenBisFileSystem"},
|
||||||
{12, nullptr, "OpenBisStorage"},
|
{12, &FSP_SRV::OpenBisStorage, "OpenBisStorage"},
|
||||||
{13, nullptr, "InvalidateBisCache"},
|
{13, &FSP_SRV::InvalidateBisCache, "InvalidateBisCache"},
|
||||||
{17, nullptr, "OpenHostFileSystem"},
|
{17, nullptr, "OpenHostFileSystem"},
|
||||||
{18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"},
|
{18, &FSP_SRV::OpenSdCardFileSystem, "OpenSdCardFileSystem"},
|
||||||
{19, nullptr, "FormatSdCardFileSystem"},
|
{19, nullptr, "FormatSdCardFileSystem"},
|
||||||
{21, nullptr, "DeleteSaveDataFileSystem"},
|
{21, nullptr, "DeleteSaveDataFileSystem"},
|
||||||
{22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"},
|
{22, &FSP_SRV::CreateSaveDataFileSystem, "CreateSaveDataFileSystem"},
|
||||||
{23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"},
|
{23, &FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId, "CreateSaveDataFileSystemBySystemSaveDataId"},
|
||||||
{24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
|
{24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
|
||||||
{25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
|
{25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
|
||||||
{26, nullptr, "FormatSdCardDryRun"},
|
{26, nullptr, "FormatSdCardDryRun"},
|
||||||
@@ -681,12 +718,12 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
|||||||
{34, nullptr, "GetCacheStorageSize"},
|
{34, nullptr, "GetCacheStorageSize"},
|
||||||
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
|
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
|
||||||
{51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
|
{51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
|
||||||
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
|
{52, &FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId, "OpenSaveDataFileSystemBySystemSaveDataId"},
|
||||||
{53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
|
{53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
|
||||||
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
|
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
|
||||||
{58, nullptr, "ReadSaveDataFileSystemExtraData"},
|
{58, nullptr, "ReadSaveDataFileSystemExtraData"},
|
||||||
{59, nullptr, "WriteSaveDataFileSystemExtraData"},
|
{59, nullptr, "WriteSaveDataFileSystemExtraData"},
|
||||||
{60, nullptr, "OpenSaveDataInfoReader"},
|
{60, &FSP_SRV::OpenSaveDataInfoReader, "OpenSaveDataInfoReader"},
|
||||||
{61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"},
|
{61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"},
|
||||||
{62, nullptr, "OpenCacheStorageList"},
|
{62, nullptr, "OpenCacheStorageList"},
|
||||||
{64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
|
{64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
|
||||||
@@ -699,8 +736,8 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
|||||||
{82, nullptr, "OpenSaveDataTransferManagerVersion2"},
|
{82, nullptr, "OpenSaveDataTransferManagerVersion2"},
|
||||||
{83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
|
{83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
|
||||||
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
|
{84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
|
||||||
{100, nullptr, "OpenImageDirectoryFileSystem"},
|
{100, &FSP_SRV::OpenImageDirectoryFileSystem, "OpenImageDirectoryFileSystem"},
|
||||||
{110, nullptr, "OpenContentStorageFileSystem"},
|
{110, &FSP_SRV::OpenContentStorageFileSystem, "OpenContentStorageFileSystem"},
|
||||||
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
|
{120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
|
||||||
{130, nullptr, "OpenCustomStorageFileSystem"},
|
{130, nullptr, "OpenCustomStorageFileSystem"},
|
||||||
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
|
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
|
||||||
@@ -710,8 +747,8 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
|||||||
{204, nullptr, "OpenDataFileSystemByProgramIndex"},
|
{204, nullptr, "OpenDataFileSystemByProgramIndex"},
|
||||||
{205, nullptr, "OpenDataStorageByProgramIndex"},
|
{205, nullptr, "OpenDataStorageByProgramIndex"},
|
||||||
{400, nullptr, "OpenDeviceOperator"},
|
{400, nullptr, "OpenDeviceOperator"},
|
||||||
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
|
{500, &FSP_SRV::OpenSdCardDetectionEventNotifier, "OpenSdCardDetectionEventNotifier"},
|
||||||
{501, nullptr, "OpenGameCardDetectionEventNotifier"},
|
{501, &FSP_SRV::OpenGameCardDetectionEventNotifier, "OpenGameCardDetectionEventNotifier"},
|
||||||
{510, nullptr, "OpenSystemDataUpdateEventNotifier"},
|
{510, nullptr, "OpenSystemDataUpdateEventNotifier"},
|
||||||
{511, nullptr, "NotifySystemDataUpdateEvent"},
|
{511, nullptr, "NotifySystemDataUpdateEvent"},
|
||||||
{520, nullptr, "SimulateGameCardDetectionEvent"},
|
{520, nullptr, "SimulateGameCardDetectionEvent"},
|
||||||
@@ -733,7 +770,7 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
|||||||
{615, nullptr, "QuerySaveDataInternalStorageTotalSize"},
|
{615, nullptr, "QuerySaveDataInternalStorageTotalSize"},
|
||||||
{616, nullptr, "GetSaveDataCommitId"},
|
{616, nullptr, "GetSaveDataCommitId"},
|
||||||
{617, nullptr, "UnregisterExternalKey"},
|
{617, nullptr, "UnregisterExternalKey"},
|
||||||
{620, nullptr, "SetSdCardEncryptionSeed"},
|
{620, &FSP_SRV::SetSdCardEncryptionSeed, "SetSdCardEncryptionSeed"},
|
||||||
{630, nullptr, "SetSdCardAccessibility"},
|
{630, nullptr, "SetSdCardAccessibility"},
|
||||||
{631, nullptr, "IsSdCardAccessible"},
|
{631, nullptr, "IsSdCardAccessible"},
|
||||||
{640, nullptr, "IsSignedSystemPartitionOnSdCardValid"},
|
{640, nullptr, "IsSignedSystemPartitionOnSdCardValid"},
|
||||||
@@ -762,6 +799,12 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
|
|||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
auto& kernel{system.Kernel()};
|
||||||
|
sd_card_detection_event = Kernel::WritableEvent::CreateEventPair(
|
||||||
|
kernel, Kernel::ResetType::Automatic, "fsp-srv:SdCardDetectionEvent");
|
||||||
|
game_card_detection_event = Kernel::WritableEvent::CreateEventPair(
|
||||||
|
kernel, Kernel::ResetType::Automatic, "fsp-srv:GameCardDetectionEvent");
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_SRV::~FSP_SRV() = default;
|
FSP_SRV::~FSP_SRV() = default;
|
||||||
@@ -781,11 +824,134 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
|
|||||||
|
|
||||||
const auto type = rp.PopRaw<FileSystemType>();
|
const auto type = rp.PopRaw<FileSystemType>();
|
||||||
const auto title_id = rp.PopRaw<u64>();
|
const auto title_id = rp.PopRaw<u64>();
|
||||||
LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}",
|
LOG_DEBUG(Service_FS, "called with type={}, title_id={:016X}", static_cast<u8>(type), title_id);
|
||||||
static_cast<u8>(type), title_id);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
const auto& prov{system.GetContentProvider()};
|
||||||
rb.Push(ResultCode(-1));
|
|
||||||
|
FileSys::PatchManager pm{title_id};
|
||||||
|
FileSys::ContentRecordType cr_type;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case FileSystemType::ApplicationPackage:
|
||||||
|
case FileSystemType::Logo:
|
||||||
|
cr_type = FileSys::ContentRecordType::Program;
|
||||||
|
break;
|
||||||
|
case FileSystemType::ContentControl:
|
||||||
|
cr_type = FileSys::ContentRecordType::Control;
|
||||||
|
break;
|
||||||
|
case FileSystemType::ContentManual:
|
||||||
|
cr_type = FileSys::ContentRecordType::HtmlDocument;
|
||||||
|
break;
|
||||||
|
case FileSystemType::ContentMeta:
|
||||||
|
cr_type = FileSys::ContentRecordType::Meta;
|
||||||
|
break;
|
||||||
|
case FileSystemType::ContentData:
|
||||||
|
cr_type = FileSys::ContentRecordType::Data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_WARNING(Service_FS, "called with invalid filesystem type!");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& nca{prov.GetEntry(title_id, cr_type)};
|
||||||
|
if (nca == nullptr) {
|
||||||
|
LOG_WARNING(Service_FS, "NCA requested doesn't exist in content provider!");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSys::VirtualDir dir;
|
||||||
|
|
||||||
|
if (type == FileSystemType::ApplicationPackage) {
|
||||||
|
dir = nca->GetExeFS();
|
||||||
|
if (dir != nullptr)
|
||||||
|
dir = pm.PatchExeFS(dir);
|
||||||
|
} else if (type == FileSystemType::Logo) {
|
||||||
|
dir = nca->GetSubdirectories()[1];
|
||||||
|
} else if (type == FileSystemType::ContentControl || type == FileSystemType::ContentManual ||
|
||||||
|
type == FileSystemType::ContentData) {
|
||||||
|
if (nca->GetRomFS() != nullptr) {
|
||||||
|
const auto romfs = pm.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), cr_type);
|
||||||
|
if (romfs != nullptr)
|
||||||
|
dir = FileSys::ExtractRomFS(romfs);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dir = nca->GetSubdirectories()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == nullptr) {
|
||||||
|
LOG_WARNING(Service_FS, "couldn't get requested NCA section!");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface(std::make_shared<IFileSystem>(
|
||||||
|
dir, SizeGetter::FromStorageId(fsc, FileSys::StorageId::Host)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenBisFileSystem(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto partition = rp.PopRaw<FileSys::BisPartitionId>();
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_FS, "called with partition_id={:08X}", static_cast<u32>(partition));
|
||||||
|
|
||||||
|
auto dir = fsc.OpenBISPartition(partition);
|
||||||
|
|
||||||
|
if (dir.Failed()) {
|
||||||
|
LOG_ERROR(Service_FS,
|
||||||
|
"Failed to mount BIS filesystem for partition_id={:08X}! Could be invalid "
|
||||||
|
"argument or uninitialized system.",
|
||||||
|
static_cast<u32>(partition));
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(dir.Code());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
|
||||||
|
IFileSystem fs(dir.Unwrap(), SizeGetter::FromStorageId(fsc, FileSys::StorageId::Host));
|
||||||
|
rb.PushIpcInterface<IFileSystem>(std::move(fs));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenBisStorage(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto partition = rp.PopRaw<FileSys::BisPartitionId>();
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_FS, "called with partition_id={:08X}", static_cast<u32>(partition));
|
||||||
|
|
||||||
|
auto file = fsc.OpenBISPartitionStorage(partition);
|
||||||
|
|
||||||
|
if (file.Failed()) {
|
||||||
|
LOG_ERROR(Service_FS,
|
||||||
|
"Failed to mount BIS storage for partition_id={:08X}! Could be invalid "
|
||||||
|
"argument or uninitialized system.",
|
||||||
|
static_cast<u32>(partition));
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(file.Code());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
|
||||||
|
IStorage fs(file.Unwrap());
|
||||||
|
rb.PushIpcInterface<IStorage>(std::move(fs));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::InvalidateBisCache(Kernel::HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_FS, "called");
|
||||||
|
|
||||||
|
// Exists for SDK compatibility -- We do not emulate a BIS cache.
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::OpenSdCardFileSystem(Kernel::HLERequestContext& ctx) {
|
||||||
@@ -815,44 +981,103 @@ void FSP_SRV::CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
|
|||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::CreateSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_INFO(Service_FS, "called.");
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
auto save_struct = rp.PopRaw<FileSys::SaveDataDescriptor>();
|
||||||
|
auto save_create_struct = rp.PopRaw<std::array<u8, 0x40>>();
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_FS, "called save_struct = {}", save_struct.DebugInfo());
|
||||||
|
|
||||||
|
const auto dir = fsc.CreateSaveData(FileSys::SaveDataSpaceId::NandSystem, save_struct);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(dir.Code());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
FileSys::StorageId StorageFromSaveDataSpace(FileSys::SaveDataSpaceId space) {
|
||||||
|
switch (space) {
|
||||||
|
case FileSys::SaveDataSpaceId::NandSystem:
|
||||||
|
case FileSys::SaveDataSpaceId::ProperSystem:
|
||||||
|
case FileSys::SaveDataSpaceId::TemporaryStorage:
|
||||||
|
return FileSys::StorageId::NandSystem;
|
||||||
|
case FileSys::SaveDataSpaceId::NandUser:
|
||||||
|
return FileSys::StorageId::NandUser;
|
||||||
|
case FileSys::SaveDataSpaceId::SdCardSystem:
|
||||||
|
case FileSys::SaveDataSpaceId::SdCardUser:
|
||||||
|
return FileSys::StorageId::SdCard;
|
||||||
|
default:
|
||||||
|
return FileSys::StorageId::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <SaveDataOpenMode mode>
|
||||||
|
void OpenSaveDataFileSystemGeneric(Kernel::HLERequestContext& ctx, FileSystemController& fsc) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
struct Parameters {
|
struct Parameters {
|
||||||
FileSys::SaveDataSpaceId save_data_space_id;
|
FileSys::SaveDataSpaceId save_data_space_id;
|
||||||
FileSys::SaveDataDescriptor descriptor;
|
FileSys::SaveDataDescriptor descriptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
const auto parameters = rp.PopRaw<Parameters>();
|
const auto parameters = rp.PopRaw<Parameters>();
|
||||||
|
|
||||||
auto dir = fsc.OpenSaveData(parameters.save_data_space_id, parameters.descriptor);
|
auto dir = fsc.OpenSaveData(parameters.save_data_space_id, parameters.descriptor);
|
||||||
|
|
||||||
if (dir.Failed()) {
|
if (dir.Failed()) {
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
|
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSys::StorageId id;
|
auto diru = dir.Unwrap();
|
||||||
if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::NandUser) {
|
|
||||||
id = FileSys::StorageId::NandUser;
|
if (diru == nullptr) {
|
||||||
} else if (parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardSystem ||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
parameters.save_data_space_id == FileSys::SaveDataSpaceId::SdCardUser) {
|
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
|
||||||
id = FileSys::StorageId::SdCard;
|
return;
|
||||||
} else {
|
|
||||||
id = FileSys::StorageId::NandSystem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IFileSystem filesystem(std::move(dir.Unwrap()), SizeGetter::FromStorageId(fsc, id));
|
if constexpr (mode == SaveDataOpenMode::ReadOnly) {
|
||||||
|
diru = std::make_shared<FileSys::ReadOnlyVfsDirectoryLayer>(diru);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFileSystem filesystem(
|
||||||
|
std::move(diru),
|
||||||
|
SizeGetter::FromStorageId(fsc, StorageFromSaveDataSpace(parameters.save_data_space_id)));
|
||||||
|
|
||||||
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));
|
rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void FSP_SRV::OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx) {
|
||||||
|
OpenSaveDataFileSystemGeneric<SaveDataOpenMode::Normal>(ctx, fsc);
|
||||||
|
}
|
||||||
|
|
||||||
void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
|
OpenSaveDataFileSystemGeneric<SaveDataOpenMode::ReadOnly>(ctx, fsc);
|
||||||
OpenSaveDataFileSystem(ctx);
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx) {
|
||||||
|
OpenSaveDataFileSystemGeneric<SaveDataOpenMode::System>(ctx, fsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenSaveDataInfoReader(Kernel::HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_FS, "called");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface<ISaveDataInfoReader>(
|
||||||
|
std::make_shared<ISaveDataInfoReader>(fsc, std::vector<FileSys::SaveDataSpaceId>{
|
||||||
|
FileSys::SaveDataSpaceId::NandSystem,
|
||||||
|
FileSys::SaveDataSpaceId::NandUser,
|
||||||
|
FileSys::SaveDataSpaceId::TemporaryStorage,
|
||||||
|
FileSys::SaveDataSpaceId::SdCardUser,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) {
|
||||||
@@ -862,7 +1087,64 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
|
|||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space, fsc));
|
rb.PushIpcInterface<ISaveDataInfoReader>(
|
||||||
|
std::make_shared<ISaveDataInfoReader>(fsc, std::vector<FileSys::SaveDataSpaceId>{space}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenImageDirectoryFileSystem(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto storage = rp.PopRaw<ImageDirectoryId>();
|
||||||
|
LOG_DEBUG(Service_FS, "called, storage={:08X}", static_cast<u32>(storage));
|
||||||
|
|
||||||
|
auto dir = fsc.GetImageDirectory(storage);
|
||||||
|
|
||||||
|
if (dir == nullptr) {
|
||||||
|
LOG_ERROR(Service_FS, "The image directory requested was invalid!");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface(std::make_shared<IFileSystem>(
|
||||||
|
std::move(dir), SizeGetter::FromStorageId(fsc, storage == ImageDirectoryId::NAND
|
||||||
|
? FileSys::StorageId::NandUser
|
||||||
|
: FileSys::StorageId::SdCard)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenContentStorageFileSystem(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto storage = rp.PopRaw<ContentStorageId>();
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_FS, "called, storage={:08X}", static_cast<u32>(storage));
|
||||||
|
|
||||||
|
auto dir = fsc.GetContentDirectory(storage);
|
||||||
|
|
||||||
|
if (dir == nullptr) {
|
||||||
|
LOG_ERROR(Service_FS, "The content storage requested was invalid!");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(FileSys::ERROR_INVALID_ARGUMENT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSys::StorageId storage_id = FileSys::StorageId::None;
|
||||||
|
switch (storage) {
|
||||||
|
case ContentStorageId::SdCard:
|
||||||
|
storage_id = FileSys::StorageId::SdCard;
|
||||||
|
break;
|
||||||
|
case ContentStorageId::User:
|
||||||
|
storage_id = FileSys::StorageId::NandUser;
|
||||||
|
break;
|
||||||
|
case ContentStorageId::System:
|
||||||
|
storage_id = FileSys::StorageId::NandSystem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface(
|
||||||
|
std::make_shared<IFileSystem>(std::move(dir), SizeGetter::FromStorageId(fsc, storage_id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||||
@@ -961,7 +1243,7 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
|
|||||||
|
|
||||||
LOG_DEBUG(Service_FS, "called, log='{}'", log);
|
LOG_DEBUG(Service_FS, "called, log='{}'", log);
|
||||||
|
|
||||||
reporter.SaveFilesystemAccessReport(log_mode, std::move(log));
|
system.GetReporter().SaveFilesystemAccessReport(log_mode, std::move(log));
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
@@ -976,4 +1258,30 @@ void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
|
|||||||
rb.Push(access_log_program_index);
|
rb.Push(access_log_program_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenSdCardDetectionEventNotifier(Kernel::HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_FS, "called");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface(std::make_shared<IEventNotifier>(sd_card_detection_event.readable));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::OpenGameCardDetectionEventNotifier(Kernel::HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service_FS, "called");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
rb.PushIpcInterface(std::make_shared<IEventNotifier>(game_card_detection_event.readable));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSP_SRV::SetSdCardEncryptionSeed(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto seed = rp.PopRaw<u128>();
|
||||||
|
|
||||||
|
LOG_INFO(Service_FS, "called with seed={:016X}{:016X}", seed[1], seed[0]);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::FileSystem
|
} // namespace Service::FileSystem
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "core/hle/kernel/writable_event.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -32,17 +33,25 @@ enum class LogMode : u32 {
|
|||||||
|
|
||||||
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
|
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
|
||||||
public:
|
public:
|
||||||
explicit FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter);
|
explicit FSP_SRV(Core::System& system);
|
||||||
~FSP_SRV() override;
|
~FSP_SRV() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetCurrentProcess(Kernel::HLERequestContext& ctx);
|
void SetCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||||
void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx);
|
void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenBisFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenBisStorage(Kernel::HLERequestContext& ctx);
|
||||||
|
void InvalidateBisCache(Kernel::HLERequestContext& ctx);
|
||||||
void OpenSdCardFileSystem(Kernel::HLERequestContext& ctx);
|
void OpenSdCardFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
void CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
void CreateSaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
|
void CreateSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx);
|
||||||
void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenSaveDataFileSystemBySystemSaveDataId(Kernel::HLERequestContext& ctx);
|
||||||
void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenSaveDataInfoReader(Kernel::HLERequestContext& ctx);
|
||||||
void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
|
void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenImageDirectoryFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenContentStorageFileSystem(Kernel::HLERequestContext& ctx);
|
||||||
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||||
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
|
||||||
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||||
@@ -50,7 +59,11 @@ private:
|
|||||||
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
|
||||||
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
|
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
|
||||||
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
|
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenSdCardDetectionEventNotifier(Kernel::HLERequestContext& ctx);
|
||||||
|
void OpenGameCardDetectionEventNotifier(Kernel::HLERequestContext& ctx);
|
||||||
|
void SetSdCardEncryptionSeed(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
FileSystemController& fsc;
|
FileSystemController& fsc;
|
||||||
|
|
||||||
FileSys::VirtualFile romfs;
|
FileSys::VirtualFile romfs;
|
||||||
@@ -58,7 +71,8 @@ private:
|
|||||||
u32 access_log_program_index = 0;
|
u32 access_log_program_index = 0;
|
||||||
LogMode log_mode = LogMode::LogToSdCard;
|
LogMode log_mode = LogMode::LogToSdCard;
|
||||||
|
|
||||||
const Core::Reporter& reporter;
|
Kernel::EventPair sd_card_detection_event;
|
||||||
|
Kernel::EventPair game_card_detection_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::FileSystem
|
} // namespace Service::FileSystem
|
||||||
|
|||||||
Reference in New Issue
Block a user