fs.mitm: mitm StorageForBatchRead as well as previously missing FileSystem/DataStorage commands
This commit is contained in:
@@ -67,6 +67,11 @@ namespace ams::mitm::fs {
|
||||
constexpr ALWAYS_INLINE auto MakeSharedStorage(Arguments &&... args) {
|
||||
return sf::CreateSharedObjectEmplaced<ams::fssrv::sf::IStorage, ams::fssrv::impl::StorageInterfaceAdapter>(std::forward<Arguments>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Arguments>
|
||||
constexpr ALWAYS_INLINE auto MakeSharedStorageForBatchRead(Arguments &&... args) {
|
||||
return sf::CreateSharedObjectEmplaced<ams::fssrv::sf::IStorageForBatchRead, ams::fssrv::impl::StorageInterfaceAdapterForBatchRead>(std::forward<Arguments>(args)...);
|
||||
}
|
||||
|
||||
Result OpenHblWebContentFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId program_id) {
|
||||
/* Verify eligibility. */
|
||||
@@ -94,7 +99,7 @@ namespace ams::mitm::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result OpenProgramSpecificWebContentFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id) {
|
||||
Result OpenProgramSpecificWebContentFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id, bool with_attributes) {
|
||||
/* Directory must exist. */
|
||||
R_UNLESS(HasSdManualHtmlContent(program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
@@ -121,8 +126,10 @@ namespace ams::mitm::fs {
|
||||
/* Try to open the existing fs. */
|
||||
FsFileSystem base_fs;
|
||||
bool opened_base_fs = false;
|
||||
if (with_id) {
|
||||
opened_base_fs = R_SUCCEEDED(fsOpenFileSystemWithIdFwd(fwd, std::addressof(base_fs), static_cast<u64>(program_id), filesystem_type, path->str));
|
||||
if (with_attributes) {
|
||||
opened_base_fs = R_SUCCEEDED(fsOpenFileSystemWithIdFwd(fwd, std::addressof(base_fs), path->str, FsContentAttributes_None, static_cast<u64>(program_id), filesystem_type));
|
||||
} else if (with_id) {
|
||||
opened_base_fs = R_SUCCEEDED(fsOpenFileSystemWithIdObsoleteFwd(fwd, std::addressof(base_fs), path->str, static_cast<u64>(program_id), filesystem_type));
|
||||
} else {
|
||||
opened_base_fs = R_SUCCEEDED(fsOpenFileSystemWithPatchFwd(fwd, std::addressof(base_fs), static_cast<u64>(program_id), filesystem_type));
|
||||
}
|
||||
@@ -141,7 +148,7 @@ namespace ams::mitm::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result OpenWebContentFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id, bool try_program_specific) {
|
||||
Result OpenWebContentFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id, bool with_attributes, bool try_program_specific) {
|
||||
/* Check first that we're a web applet opening web content. */
|
||||
R_UNLESS(ncm::IsWebAppletId(client_program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
R_UNLESS(filesystem_type == FsFileSystemType_ContentManual, sm::mitm::ResultShouldForwardToSession());
|
||||
@@ -153,7 +160,7 @@ namespace ams::mitm::fs {
|
||||
R_UNLESS(try_program_specific, sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* If we're not opening a HBL filesystem, just try to open a generic one. */
|
||||
R_RETURN(OpenProgramSpecificWebContentFileSystem(out, program_id, filesystem_type, fwd, path, with_id));
|
||||
R_RETURN(OpenProgramSpecificWebContentFileSystem(out, program_id, filesystem_type, fwd, path, with_id, with_attributes));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -169,12 +176,17 @@ namespace ams::mitm::fs {
|
||||
}
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithPatch(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type) {
|
||||
R_RETURN(OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), m_forward_service.get(), nullptr, false, m_client_info.override_status.IsProgramSpecific()));
|
||||
Result FsMitmService::OpenFileSystemWithPatch(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 file_system_proxy_type) {
|
||||
R_RETURN(OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(file_system_proxy_type), m_forward_service.get(), nullptr, false, false, m_client_info.override_status.IsProgramSpecific()));
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type) {
|
||||
R_RETURN(OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), m_forward_service.get(), std::addressof(path), true, m_client_info.override_status.IsProgramSpecific()));
|
||||
Result FsMitmService::OpenFileSystemWithIdObsolete(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 file_system_proxy_type) {
|
||||
R_RETURN(OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(file_system_proxy_type), m_forward_service.get(), std::addressof(path), true, false, m_client_info.override_status.IsProgramSpecific()));
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, u8 content_attributes, ncm::ProgramId program_id, u32 file_system_proxy_type) {
|
||||
AMS_UNUSED(content_attributes);
|
||||
R_RETURN(OpenWebContentFileSystem(out, m_client_info.program_id, program_id, static_cast<FsFileSystemType>(file_system_proxy_type), m_forward_service.get(), std::addressof(path), true, true, m_client_info.override_status.IsProgramSpecific()));
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenSdCardFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out) {
|
||||
@@ -195,7 +207,7 @@ namespace ams::mitm::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenSaveDataFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, u8 _space_id, const fs::SaveDataAttribute &attribute) {
|
||||
Result FsMitmService::OpenSaveDataFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, u8 space_id, const fs::SaveDataAttribute &attribute) {
|
||||
/* We only want to intercept saves for games, right now. */
|
||||
const bool is_game_or_hbl = m_client_info.override_status.IsHbl() || ncm::IsApplicationId(m_client_info.program_id);
|
||||
R_UNLESS(is_game_or_hbl, sm::mitm::ResultShouldForwardToSession());
|
||||
@@ -210,12 +222,12 @@ namespace ams::mitm::fs {
|
||||
R_UNLESS(attribute.type == fs::SaveDataType::Account, sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Get enum type for space id. */
|
||||
auto space_id = static_cast<FsSaveDataSpaceId>(_space_id);
|
||||
auto _space_id = static_cast<FsSaveDataSpaceId>(space_id);
|
||||
|
||||
/* Verify we can open the save. */
|
||||
static_assert(sizeof(fs::SaveDataAttribute) == sizeof(::FsSaveDataAttribute));
|
||||
FsFileSystem save_fs;
|
||||
R_UNLESS(R_SUCCEEDED(fsOpenSaveDataFileSystemFwd(m_forward_service.get(), std::addressof(save_fs), space_id, reinterpret_cast<const FsSaveDataAttribute *>(std::addressof(attribute)))), sm::mitm::ResultShouldForwardToSession());
|
||||
R_UNLESS(R_SUCCEEDED(fsOpenSaveDataFileSystemFwd(m_forward_service.get(), std::addressof(save_fs), _space_id, reinterpret_cast<const FsSaveDataAttribute *>(std::addressof(attribute)))), sm::mitm::ResultShouldForwardToSession());
|
||||
std::unique_ptr<fs::fsa::IFileSystem> save_ifs = std::make_unique<fs::RemoteFileSystem>(save_fs);
|
||||
|
||||
/* Mount the SD card using fs.mitm's session. */
|
||||
@@ -228,7 +240,7 @@ namespace ams::mitm::fs {
|
||||
const ncm::ProgramId application_id = attribute.program_id == ncm::InvalidProgramId ? m_client_info.program_id : attribute.program_id;
|
||||
|
||||
char save_dir_raw_path[0x100];
|
||||
R_TRY(mitm::fs::SaveUtil::GetDirectorySaveDataPath(save_dir_raw_path, sizeof(save_dir_raw_path), application_id, space_id, attribute));
|
||||
R_TRY(mitm::fs::SaveUtil::GetDirectorySaveDataPath(save_dir_raw_path, sizeof(save_dir_raw_path), application_id, _space_id, attribute));
|
||||
|
||||
ams::fs::Path save_dir_path;
|
||||
R_TRY(save_dir_path.SetShallowBuffer(save_dir_raw_path));
|
||||
@@ -270,12 +282,12 @@ namespace ams::mitm::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenBisStorage(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u32 _bis_partition_id) {
|
||||
const ::FsBisPartitionId bis_partition_id = static_cast<::FsBisPartitionId>(_bis_partition_id);
|
||||
Result FsMitmService::OpenBisStorage(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u32 bis_partition_id) {
|
||||
const ::FsBisPartitionId _bis_partition_id = static_cast<::FsBisPartitionId>(bis_partition_id);
|
||||
|
||||
/* Try to open a storage for the partition. */
|
||||
FsStorage bis_storage;
|
||||
R_TRY(fsOpenBisStorageFwd(m_forward_service.get(), std::addressof(bis_storage), bis_partition_id));
|
||||
R_TRY(fsOpenBisStorageFwd(m_forward_service.get(), std::addressof(bis_storage), _bis_partition_id));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(bis_storage.s))};
|
||||
|
||||
const bool is_sysmodule = ncm::IsSystemProgramId(m_client_info.program_id);
|
||||
@@ -285,18 +297,18 @@ namespace ams::mitm::fs {
|
||||
/* Allow HBL to write to boot1 (safe firm) + package2. */
|
||||
/* This is needed to not break compatibility with ChoiDujourNX, which does not check for write access before beginning an update. */
|
||||
/* TODO: get fixed so that this can be turned off without causing bricks :/ */
|
||||
const bool is_package2 = (FsBisPartitionId_BootConfigAndPackage2Part1 <= bis_partition_id && bis_partition_id <= FsBisPartitionId_BootConfigAndPackage2Part6);
|
||||
const bool is_boot1 = bis_partition_id == FsBisPartitionId_BootPartition2Root;
|
||||
const bool is_package2 = (FsBisPartitionId_BootConfigAndPackage2Part1 <= _bis_partition_id && _bis_partition_id <= FsBisPartitionId_BootConfigAndPackage2Part6);
|
||||
const bool is_boot1 = _bis_partition_id == FsBisPartitionId_BootPartition2Root;
|
||||
const bool can_write_bis_for_choi_support = is_hbl && (is_package2 || is_boot1);
|
||||
|
||||
/* Set output storage. */
|
||||
if (bis_partition_id == FsBisPartitionId_BootPartition1Root) {
|
||||
if (_bis_partition_id == FsBisPartitionId_BootPartition1Root) {
|
||||
if (IsBoot0CustomPublicKey(bis_storage)) {
|
||||
out.SetValue(MakeSharedStorage(std::make_shared<CustomPublicKeyBoot0Storage>(bis_storage, m_client_info, spl::GetSocType())), target_object_id);
|
||||
} else {
|
||||
out.SetValue(MakeSharedStorage(std::make_shared<Boot0Storage>(bis_storage, m_client_info)), target_object_id);
|
||||
}
|
||||
} else if (bis_partition_id == FsBisPartitionId_CalibrationBinary) {
|
||||
} else if (_bis_partition_id == FsBisPartitionId_CalibrationBinary) {
|
||||
out.SetValue(MakeSharedStorage(std::make_shared<CalibrationBinaryStorage>(bis_storage, m_client_info)), target_object_id);
|
||||
} else {
|
||||
if (can_write_bis || can_write_bis_for_choi_support) {
|
||||
@@ -328,24 +340,41 @@ namespace ams::mitm::fs {
|
||||
out.SetValue(MakeSharedStorage(GetLayeredRomfsStorage(m_client_info.program_id, data_storage, true)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByProgramId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::ProgramId program_id) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
Result FsMitmService::OpenDataStorageByDataId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::DataId _data_id, u8 storage_id) {
|
||||
/* Only mitm if there is actually an override romfs for the target program. */
|
||||
R_UNLESS(mitm::fs::HasSdRomfsContent(program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Try to open the program romfs. */
|
||||
FsStorage data_storage;
|
||||
R_TRY(fsOpenDataStorageByProgramIdFwd(m_forward_service.get(), std::addressof(data_storage), static_cast<u64>(program_id)));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
|
||||
|
||||
/* Get a layered storage for the program romfs. */
|
||||
out.SetValue(MakeSharedStorage(GetLayeredRomfsStorage(program_id, data_storage, true)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByDataId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::DataId data_id, u8 storage_id) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* TODO: Decide how to handle DataId vs ProgramId for this API. */
|
||||
const ncm::ProgramId data_id = {_data_id.value};
|
||||
const ncm::ProgramId program_or_data_id = {data_id.value};
|
||||
|
||||
/* Only mitm if there is actually an override romfs. */
|
||||
R_UNLESS(mitm::fs::HasSdRomfsContent(data_id), sm::mitm::ResultShouldForwardToSession());
|
||||
R_UNLESS(mitm::fs::HasSdRomfsContent(program_or_data_id), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Try to open the data id. */
|
||||
FsStorage data_storage;
|
||||
R_TRY(fsOpenDataStorageByDataIdFwd(m_forward_service.get(), std::addressof(data_storage), static_cast<u64>(data_id), static_cast<NcmStorageId>(storage_id)));
|
||||
R_TRY(fsOpenDataStorageByDataIdFwd(m_forward_service.get(), std::addressof(data_storage), static_cast<u64>(program_or_data_id), static_cast<NcmStorageId>(storage_id)));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
|
||||
|
||||
/* Get a layered storage for the data id. */
|
||||
out.SetValue(MakeSharedStorage(GetLayeredRomfsStorage(data_id, data_storage, false)), target_object_id);
|
||||
out.SetValue(MakeSharedStorage(GetLayeredRomfsStorage(program_or_data_id, data_storage, false)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
@@ -369,7 +398,80 @@ namespace ams::mitm::fs {
|
||||
out.SetValue(MakeSharedStorage(GetLayeredRomfsStorage(program_id, data_storage, true)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByPath(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, const fssrv::sf::Path &path, u8 content_attributes, u32 file_system_proxy_type) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* TODO */
|
||||
AMS_UNUSED(out, path, content_attributes, file_system_proxy_type);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByCurrentProcessForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Only mitm if there is actually an override romfs. */
|
||||
R_UNLESS(mitm::fs::HasSdRomfsContent(m_client_info.program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Try to open the process romfs. */
|
||||
FsStorageForBatchRead data_storage;
|
||||
R_TRY(fsOpenDataStorageByCurrentProcessForBatchReadFwd(m_forward_service.get(), std::addressof(data_storage)));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
|
||||
|
||||
/* Get a layered storage for the program romfs (batch read variant). */
|
||||
out.SetValue(MakeSharedStorageForBatchRead(GetLayeredRomfsStorageForBatchRead(m_client_info.program_id, data_storage, true)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByProgramIdForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, ncm::ProgramId program_id) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Only mitm if there is actually an override romfs for the target program. */
|
||||
R_UNLESS(mitm::fs::HasSdRomfsContent(program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Try to open the program romfs. */
|
||||
FsStorageForBatchRead data_storage;
|
||||
R_TRY(fsOpenDataStorageByProgramIdForBatchReadFwd(m_forward_service.get(), std::addressof(data_storage), static_cast<u64>(program_id)));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
|
||||
|
||||
/* Get a layered storage for the program romfs (batch read variant). */
|
||||
out.SetValue(MakeSharedStorageForBatchRead(GetLayeredRomfsStorageForBatchRead(program_id, data_storage, true)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageWithProgramIndexForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, u8 program_index) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Get the relevant program id. */
|
||||
const ncm::ProgramId program_id = g_program_index_map_info_manager.GetProgramId(m_client_info.program_id, program_index);
|
||||
|
||||
/* If we don't know about the program or don't have content, forward. */
|
||||
R_UNLESS(program_id != ncm::InvalidProgramId, sm::mitm::ResultShouldForwardToSession());
|
||||
R_UNLESS(mitm::fs::HasSdRomfsContent(program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* Try to open the process romfs. */
|
||||
FsStorageForBatchRead data_storage;
|
||||
R_TRY(fsOpenDataStorageWithProgramIndexForBatchReadFwd(m_forward_service.get(), std::addressof(data_storage), program_index));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(std::addressof(data_storage.s))};
|
||||
|
||||
/* Get a layered storage for the program romfs (batch read variant). */
|
||||
out.SetValue(MakeSharedStorageForBatchRead(GetLayeredRomfsStorageForBatchRead(program_id, data_storage, true)), target_object_id);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByPathForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, const fssrv::sf::Path &path, u8 content_attributes, u32 file_system_proxy_type) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(m_client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
/* TODO */
|
||||
AMS_UNUSED(out, path, content_attributes, file_system_proxy_type);
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result FsMitmService::RegisterProgramIndexMapInfo(const sf::InBuffer &info_buffer, s32 info_count) {
|
||||
/* Try to register with FS. */
|
||||
R_TRY(fsRegisterProgramIndexMapInfoFwd(m_forward_service.get(), info_buffer.GetPointer(), info_buffer.GetSize(), info_count));
|
||||
|
||||
@@ -17,16 +17,23 @@
|
||||
#include <stratosphere.hpp>
|
||||
#include <stratosphere/fssrv/fssrv_interface_adapters.hpp>
|
||||
|
||||
#define AMS_FS_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, OpenFileSystemWithPatch, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type), (out, program_id, _filesystem_type), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, OpenFileSystemWithId, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type), (out, path, program_id, _filesystem_type), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 18, Result, OpenSdCardFileSystem, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 51, Result, OpenSaveDataFileSystem, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, u8 space_id, const ams::fs::SaveDataAttribute &attribute), (out, space_id, attribute)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, OpenBisStorage, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u32 bis_partition_id), (out, bis_partition_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 200, Result, OpenDataStorageByCurrentProcess, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 202, Result, OpenDataStorageByDataId, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::DataId data_id, u8 storage_id), (out, data_id, storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 205, Result, OpenDataStorageWithProgramIndex, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u8 program_index), (out, program_index), hos::Version_7_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 810, Result, RegisterProgramIndexMapInfo, (const sf::InBuffer &info_buffer, s32 info_count), (info_buffer, info_count), hos::Version_7_0_0)
|
||||
#define AMS_FS_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, OpenFileSystemWithPatch, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 file_system_proxy_type), (out, program_id, file_system_proxy_type), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, OpenFileSystemWithIdObsolete, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 file_system_proxy_type), (out, path, program_id, file_system_proxy_type), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 10, Result, OpenFileSystemWithId, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, u8 content_attributes, ncm::ProgramId program_id, u32 file_system_proxy_type), (out, path, content_attributes, program_id, file_system_proxy_type), hos::Version_16_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 18, Result, OpenSdCardFileSystem, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 51, Result, OpenSaveDataFileSystem, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, u8 space_id, const ams::fs::SaveDataAttribute &attribute), (out, space_id, attribute)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, OpenBisStorage, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u32 bis_partition_id), (out, bis_partition_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 200, Result, OpenDataStorageByCurrentProcess, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 201, Result, OpenDataStorageByProgramId, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::ProgramId program_id), (out, program_id), hos::Version_3_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 202, Result, OpenDataStorageByDataId, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::DataId data_id, u8 storage_id), (out, data_id, storage_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 205, Result, OpenDataStorageWithProgramIndex, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u8 program_index), (out, program_index), hos::Version_7_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 206, Result, OpenDataStorageByPath, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, const fssrv::sf::Path &path, u8 content_attributes, u32 file_system_proxy_type), (out, path, content_attributes, file_system_proxy_type), hos::Version_13_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 210, Result, OpenDataStorageByCurrentProcessForBatchRead, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out), (out), hos::Version_23_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 211, Result, OpenDataStorageByProgramIdForBatchRead, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, ncm::ProgramId program_id), (out, program_id), hos::Version_23_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 212, Result, OpenDataStorageWithProgramIndexForBatchRead, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, u8 program_index), (out, program_index), hos::Version_23_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 213, Result, OpenDataStorageByPathForBatchRead, (sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, const fssrv::sf::Path &path, u8 content_attributes, u32 file_system_proxy_type), (out, path, content_attributes, file_system_proxy_type), hos::Version_23_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 810, Result, RegisterProgramIndexMapInfo, (const sf::InBuffer &info_buffer, s32 info_count), (info_buffer, info_count), hos::Version_7_0_0)
|
||||
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(ams::mitm::fs, IFsMitmInterface, AMS_FS_MITM_INTERFACE_INFO, 0x7DF34ED2)
|
||||
@@ -77,14 +84,21 @@ namespace ams::mitm::fs {
|
||||
}
|
||||
public:
|
||||
/* Overridden commands. */
|
||||
Result OpenFileSystemWithPatch(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type);
|
||||
Result OpenFileSystemWithId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type);
|
||||
Result OpenFileSystemWithPatch(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 file_system_proxy_type);
|
||||
Result OpenFileSystemWithIdObsolete(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 file_system_proxy_type);
|
||||
Result OpenFileSystemWithId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, u8 content_attributes, ncm::ProgramId program_id, u32 file_system_proxy_type);
|
||||
Result OpenSdCardFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out);
|
||||
Result OpenSaveDataFileSystem(sf::Out<sf::SharedPointer<ams::fssrv::sf::IFileSystem>> out, u8 space_id, const ams::fs::SaveDataAttribute &attribute);
|
||||
Result OpenBisStorage(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u32 bis_partition_id);
|
||||
Result OpenDataStorageByCurrentProcess(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out);
|
||||
Result OpenDataStorageByProgramId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::ProgramId program_id);
|
||||
Result OpenDataStorageByDataId(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, ncm::DataId data_id, u8 storage_id);
|
||||
Result OpenDataStorageWithProgramIndex(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, u8 program_index);
|
||||
Result OpenDataStorageByPath(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorage>> out, const fssrv::sf::Path &path, u8 content_attributes, u32 file_system_proxy_type);
|
||||
Result OpenDataStorageByCurrentProcessForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out);
|
||||
Result OpenDataStorageByProgramIdForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, ncm::ProgramId program_id);
|
||||
Result OpenDataStorageWithProgramIndexForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, u8 program_index);
|
||||
Result OpenDataStorageByPathForBatchRead(sf::Out<sf::SharedPointer<ams::fssrv::sf::IStorageForBatchRead>> out, const fssrv::sf::Path &path, u8 content_attributes, u32 file_system_proxy_type);
|
||||
Result RegisterProgramIndexMapInfo(const sf::InBuffer &info_buffer, s32 info_count);
|
||||
};
|
||||
static_assert(IsIFsMitmInterface<FsMitmService>);
|
||||
|
||||
@@ -23,8 +23,46 @@ static Result _fsOpenSession(Service *s, Service* out, u32 cmd_id) {
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenSdCardFileSystemFwd(Service* s, FsFileSystem* out) {
|
||||
return _fsOpenSession(s, &out->s, 18);
|
||||
Result fsOpenFileSystemWithPatchFwd(Service* s, FsFileSystem* out, u64 id, FsFileSystemType fsType) {
|
||||
const struct {
|
||||
u32 fsType;
|
||||
u64 id;
|
||||
} in = { fsType, id };
|
||||
|
||||
return serviceDispatchIn(s, 7, in,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenFileSystemWithIdObsoleteFwd(Service* s, FsFileSystem* out, const char* contentPath, u64 id, FsFileSystemType fsType) {
|
||||
const struct {
|
||||
u32 fsType;
|
||||
u64 id;
|
||||
} in = { fsType, id };
|
||||
|
||||
return serviceDispatchIn(s, 8, in,
|
||||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
|
||||
.buffers = { { contentPath, FS_MAX_PATH } },
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenFileSystemWithIdFwd(Service* s, FsFileSystem* out, const char* contentPath, FsContentAttributes attributes, u64 id, FsFileSystemType fsType) {
|
||||
const struct {
|
||||
u8 attributes;
|
||||
u8 pad[3];
|
||||
u32 fsType;
|
||||
u64 id;
|
||||
} in = { attributes, {0}, fsType, id };
|
||||
|
||||
return serviceDispatchIn(s, 10, in,
|
||||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
|
||||
.buffers = { { contentPath, FS_MAX_PATH } },
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenBisStorageFwd(Service* s, FsStorage* out, FsBisPartitionId partition_id) {
|
||||
@@ -35,10 +73,34 @@ Result fsOpenBisStorageFwd(Service* s, FsStorage* out, FsBisPartitionId partitio
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenSdCardFileSystemFwd(Service* s, FsFileSystem* out) {
|
||||
return _fsOpenSession(s, &out->s, 18);
|
||||
}
|
||||
|
||||
Result fsOpenSaveDataFileSystemFwd(Service* s, FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute *attr) {
|
||||
const struct {
|
||||
u8 save_data_space_id;
|
||||
u8 pad[7];
|
||||
FsSaveDataAttribute attr;
|
||||
} in = { (u8)save_data_space_id, {0}, *attr };
|
||||
|
||||
return serviceDispatchIn(s, 51, in,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s,
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out) {
|
||||
return _fsOpenSession(s, &out->s, 200);
|
||||
}
|
||||
|
||||
Result fsOpenDataStorageByProgramIdFwd(Service* s, FsStorage* out, u64 id) {
|
||||
return serviceDispatchIn(s, 201, id,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s,
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorage* out, u64 data_id, NcmStorageId storage_id) {
|
||||
const struct {
|
||||
u8 storage_id;
|
||||
@@ -58,48 +120,57 @@ Result fsOpenDataStorageWithProgramIndexFwd(Service* s, FsStorage* out, u8 progr
|
||||
);
|
||||
}
|
||||
|
||||
Result fsRegisterProgramIndexMapInfoFwd(Service* s, const void *buf, size_t buf_size, s32 count) {
|
||||
return serviceDispatchIn(s, 810, count,
|
||||
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
|
||||
.buffers = { { buf, buf_size } },
|
||||
Result fsOpenDataStorageByPathFwd(Service* s, FsStorage* out, const char* contentPath, FsContentAttributes attributes, FsFileSystemType fsType) {
|
||||
const struct {
|
||||
u8 attributes;
|
||||
u8 pad[3];
|
||||
u32 fsType;
|
||||
} in = { attributes, {0}, fsType };
|
||||
|
||||
return serviceDispatchIn(s, 206, in,
|
||||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
|
||||
.buffers = { { contentPath, FS_MAX_PATH } },
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenSaveDataFileSystemFwd(Service* s, FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute *attr) {
|
||||
const struct {
|
||||
u8 save_data_space_id;
|
||||
u8 pad[7];
|
||||
FsSaveDataAttribute attr;
|
||||
} in = { (u8)save_data_space_id, {0}, *attr };
|
||||
Result fsOpenDataStorageByCurrentProcessForBatchReadFwd(Service* s, FsStorageForBatchRead* out) {
|
||||
return _fsOpenSession(s, &out->s, 210);
|
||||
}
|
||||
|
||||
return serviceDispatchIn(s, 51, in,
|
||||
Result fsOpenDataStorageByProgramIdForBatchReadFwd(Service* s, FsStorageForBatchRead* out, u64 id) {
|
||||
return serviceDispatchIn(s, 211, id,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s,
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenFileSystemWithPatchFwd(Service* s, FsFileSystem* out, u64 id, FsFileSystemType fsType) {
|
||||
const struct {
|
||||
u32 fsType;
|
||||
u64 id;
|
||||
} in = { fsType, id };
|
||||
Result fsOpenDataStorageWithProgramIndexForBatchReadFwd(Service* s, FsStorageForBatchRead* out, u8 program_index) {
|
||||
return serviceDispatchIn(s, 212, program_index,
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s,
|
||||
);
|
||||
}
|
||||
|
||||
return serviceDispatchIn(s, 7, in,
|
||||
Result fsOpenDataStorageByPathForBatchReadFwd(Service* s, FsStorageForBatchRead* out, const char* contentPath, FsContentAttributes attributes, FsFileSystemType fsType) {
|
||||
const struct {
|
||||
u8 attributes;
|
||||
u8 pad[3];
|
||||
u32 fsType;
|
||||
} in = { attributes, {0}, fsType };
|
||||
|
||||
return serviceDispatchIn(s, 213, in,
|
||||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize },
|
||||
.buffers = { { contentPath, FS_MAX_PATH } },
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s
|
||||
);
|
||||
}
|
||||
|
||||
Result fsOpenFileSystemWithIdFwd(Service* s, FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath) {
|
||||
const struct {
|
||||
u32 fsType;
|
||||
u64 id;
|
||||
} in = { fsType, id };
|
||||
|
||||
return serviceDispatchIn(s, 8, in,
|
||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In },
|
||||
.buffers = { { contentPath, FS_MAX_PATH } },
|
||||
.out_num_objects = 1,
|
||||
.out_objects = &out->s
|
||||
Result fsRegisterProgramIndexMapInfoFwd(Service* s, const void *buf, size_t buf_size, s32 count) {
|
||||
return serviceDispatchIn(s, 810, count,
|
||||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias },
|
||||
.buffers = { { buf, buf_size } },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,18 +12,26 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Missing fsp-srv commands. */
|
||||
Result fsOpenSdCardFileSystemFwd(Service* s, FsFileSystem* out);
|
||||
Result fsOpenFileSystemWithPatchFwd(Service* s, FsFileSystem* out, u64 id, FsFileSystemType fsType);
|
||||
Result fsOpenFileSystemWithIdObsoleteFwd(Service* s, FsFileSystem* out, const char* contentPath, u64 id, FsFileSystemType fsType);
|
||||
Result fsOpenFileSystemWithIdFwd(Service* s, FsFileSystem* out, const char* contentPath, FsContentAttributes attributes, u64 id, FsFileSystemType fsType);
|
||||
|
||||
Result fsOpenBisStorageFwd(Service* s, FsStorage* out, FsBisPartitionId partition_id);
|
||||
Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out);
|
||||
Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorage* out, u64 data_id, NcmStorageId storage_id);
|
||||
Result fsOpenDataStorageWithProgramIndexFwd(Service* s, FsStorage* out, u8 program_index);
|
||||
|
||||
Result fsRegisterProgramIndexMapInfoFwd(Service* s, const void *buf, size_t buf_size, s32 count);
|
||||
|
||||
Result fsOpenSdCardFileSystemFwd(Service* s, FsFileSystem* out);
|
||||
Result fsOpenSaveDataFileSystemFwd(Service* s, FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, const FsSaveDataAttribute *attr);
|
||||
|
||||
Result fsOpenFileSystemWithPatchFwd(Service* s, FsFileSystem* out, u64 id, FsFileSystemType fsType);
|
||||
Result fsOpenFileSystemWithIdFwd(Service* s, FsFileSystem* out, u64 id, FsFileSystemType fsType, const char* contentPath);
|
||||
Result fsOpenDataStorageByCurrentProcessFwd(Service* s, FsStorage* out);
|
||||
Result fsOpenDataStorageByProgramIdFwd(Service* s, FsStorage* out, u64 id);
|
||||
Result fsOpenDataStorageByDataIdFwd(Service* s, FsStorage* out, u64 data_id, NcmStorageId storage_id);
|
||||
Result fsOpenDataStorageWithProgramIndexFwd(Service* s, FsStorage* out, u8 program_index);
|
||||
Result fsOpenDataStorageByPathFwd(Service* s, FsStorage* out, const char* contentPath, FsContentAttributes attributes, FsFileSystemType fsType);
|
||||
|
||||
Result fsOpenDataStorageByCurrentProcessForBatchReadFwd(Service* s, FsStorageForBatchRead* out);
|
||||
Result fsOpenDataStorageByProgramIdForBatchReadFwd(Service* s, FsStorageForBatchRead* out, u64 id);
|
||||
Result fsOpenDataStorageWithProgramIndexForBatchReadFwd(Service* s, FsStorageForBatchRead* out, u8 program_index);
|
||||
Result fsOpenDataStorageByPathForBatchReadFwd(Service* s, FsStorageForBatchRead* out, const char* contentPath, FsContentAttributes attributes, FsFileSystemType fsType);
|
||||
|
||||
Result fsRegisterProgramIndexMapInfoFwd(Service* s, const void *buf, size_t buf_size, s32 count);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -180,33 +180,79 @@ namespace ams::mitm::fs {
|
||||
CloseReference(m_impl);
|
||||
}
|
||||
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
R_RETURN(m_impl->Read(offset, buffer, size));
|
||||
}
|
||||
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
/* TODO: Better result code? */
|
||||
AMS_UNUSED(offset, buffer, size);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation())
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(m_impl->Flush());
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
/* TODO: Better result code? */
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation())
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out_size) override {
|
||||
R_RETURN(m_impl->GetSize(out_size));
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, ams::fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
R_RETURN(m_impl->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
}
|
||||
};
|
||||
|
||||
class LayeredRomfsStorageForBatchRead : public ams::fs::IStorageForBatchRead {
|
||||
private:
|
||||
LayeredRomfsStorageImpl *m_impl;
|
||||
public:
|
||||
LayeredRomfsStorageForBatchRead(LayeredRomfsStorageImpl *impl) : m_impl(impl) {
|
||||
OpenReference(m_impl);
|
||||
}
|
||||
|
||||
virtual ~LayeredRomfsStorageForBatchRead() {
|
||||
CloseReference(m_impl);
|
||||
}
|
||||
|
||||
virtual Result Read(s64 offset, void *buffer, size_t size) override {
|
||||
R_RETURN(m_impl->Read(offset, buffer, size));
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
/* TODO: Better result code? */
|
||||
AMS_UNUSED(offset, buffer, size);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation())
|
||||
}
|
||||
|
||||
virtual Result Flush() override {
|
||||
R_RETURN(m_impl->Flush());
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
/* TODO: Better result code? */
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation())
|
||||
}
|
||||
|
||||
virtual Result GetSize(s64 *out_size) override {
|
||||
R_RETURN(m_impl->GetSize(out_size));
|
||||
}
|
||||
|
||||
virtual Result OperateRange(void *dst, size_t dst_size, ams::fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) override {
|
||||
R_RETURN(m_impl->OperateRange(dst, dst_size, op_id, offset, size, src, src_size));
|
||||
}
|
||||
|
||||
virtual Result Write(s64 offset, const void *buffer, size_t size) override {
|
||||
/* TODO: Better result code? */
|
||||
AMS_UNUSED(offset, buffer, size);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation())
|
||||
}
|
||||
|
||||
virtual Result SetSize(s64 size) override {
|
||||
/* TODO: Better result code? */
|
||||
AMS_UNUSED(size);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation())
|
||||
virtual Result BatchRead(void *out0, void *out1, void *out2, void *out3, void *out4, void *out5, void *out6, const void *in) override {
|
||||
/* TODO */
|
||||
AMS_UNUSED(out0, out1, out2, out3, out4, out5, out6, in);
|
||||
R_THROW(ams::fs::ResultUnsupportedOperation());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -261,6 +307,54 @@ namespace ams::mitm::fs {
|
||||
/* Return a new shared storage for the impl. */
|
||||
return std::make_shared<LayeredRomfsStorage>(impl);
|
||||
}
|
||||
|
||||
std::shared_ptr<ams::fs::IStorageForBatchRead> GetLayeredRomfsStorageForBatchRead(ncm::ProgramId program_id, ::FsStorageForBatchRead &data_storage, bool is_process_romfs) {
|
||||
/*Prepare to find or create a new storage. */
|
||||
LayeredRomfsStorageImpl *impl = nullptr;
|
||||
{
|
||||
std::scoped_lock lk(g_storage_set_mutex);
|
||||
|
||||
/* Find an existing storage. */
|
||||
if (auto it = g_storage_set.find_key(program_id.value); it != g_storage_set.end()) {
|
||||
return std::make_shared<LayeredRomfsStorageForBatchRead>(it->GetImpl());
|
||||
}
|
||||
|
||||
/* We don't have an existing storage. If we're creating process romfs, free any unreferenced process romfs. */
|
||||
/* This should help prevent too much memory in use at any time. */
|
||||
if (is_process_romfs) {
|
||||
auto it = g_storage_set.begin();
|
||||
while (it != g_storage_set.end()) {
|
||||
if (it->GetReferenceCount() > 0 || !it->IsProcessRomfs()) {
|
||||
++it;
|
||||
} else {
|
||||
auto *holder = std::addressof(*it);
|
||||
it = g_storage_set.erase(it);
|
||||
delete holder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new storage. */
|
||||
{
|
||||
::FsFile data_file;
|
||||
if (R_SUCCEEDED(OpenAtmosphereSdFile(std::addressof(data_file), program_id, "romfs.bin", OpenMode_Read))) {
|
||||
impl = new LayeredRomfsStorageImpl(std::make_unique<ReadOnlyStorageAdapterForBatchRead>(new RemoteStorageForBatchRead(data_storage)), std::make_unique<ReadOnlyStorageAdapterForBatchRead>(new FileStorage(new RemoteFile(data_file))), program_id);
|
||||
} else {
|
||||
impl = new LayeredRomfsStorageImpl(std::make_unique<ReadOnlyStorageAdapterForBatchRead>(new RemoteStorageForBatchRead(data_storage)), nullptr, program_id);
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert holder. Reference count will now be one. */
|
||||
g_storage_set.insert(*(new LayeredRomfsStorageHolder(impl, is_process_romfs)));
|
||||
}
|
||||
|
||||
/* Begin initialization. When this finishes, a decref will occur. */
|
||||
AMS_ABORT_UNLESS(impl != nullptr);
|
||||
impl->BeginInitialize();
|
||||
|
||||
/* Return a new shared storage for the impl. */
|
||||
return std::make_shared<LayeredRomfsStorageForBatchRead>(impl);
|
||||
}
|
||||
|
||||
void FinalizeLayeredRomfsStorage(ncm::ProgramId program_id) {
|
||||
std::scoped_lock lk(g_initialization_mutex);
|
||||
@@ -392,6 +486,10 @@ namespace ams::mitm::fs {
|
||||
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LayeredRomfsStorageImpl::Flush() {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LayeredRomfsStorageImpl::GetSize(s64 *out_size) {
|
||||
/* Ensure we're initialized. */
|
||||
@@ -403,10 +501,6 @@ namespace ams::mitm::fs {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LayeredRomfsStorageImpl::Flush() {
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result LayeredRomfsStorageImpl::OperateRange(void *dst, size_t dst_size, OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size) {
|
||||
AMS_UNUSED(offset, src, src_size);
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@ namespace ams::mitm::fs {
|
||||
constexpr ncm::ProgramId GetProgramId() const { return m_program_id; }
|
||||
|
||||
Result Read(s64 offset, void *buffer, size_t size);
|
||||
Result GetSize(s64 *out_size);
|
||||
Result Flush();
|
||||
Result GetSize(s64 *out_size);
|
||||
Result OperateRange(void *dst, size_t dst_size, ams::fs::OperationId op_id, s64 offset, s64 size, const void *src, size_t src_size);
|
||||
};
|
||||
|
||||
std::shared_ptr<ams::fs::IStorage> GetLayeredRomfsStorage(ncm::ProgramId program_id, ::FsStorage &data_storage, bool is_process_romfs);
|
||||
|
||||
std::shared_ptr<ams::fs::IStorageForBatchRead> GetLayeredRomfsStorageForBatchRead(ncm::ProgramId program_id, ::FsStorageForBatchRead &data_storage, bool is_process_romfs);
|
||||
void FinalizeLayeredRomfsStorage(ncm::ProgramId program_id);
|
||||
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ namespace ams::mitm::fs {
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Entry>
|
||||
class TableWriter : public DynamicTableCache {
|
||||
NON_COPYABLE(TableWriter);
|
||||
@@ -727,12 +727,12 @@ namespace ams::mitm::fs {
|
||||
public:
|
||||
DirectoryTableReader(ams::fs::IStorage *s, size_t ofs, size_t sz) : TableReader(s, ofs, sz) { /* ... */ }
|
||||
};
|
||||
|
||||
|
||||
class FileTableReader : public TableReader<FileEntry> {
|
||||
public:
|
||||
FileTableReader(ams::fs::IStorage *s, size_t ofs, size_t sz) : TableReader(s, ofs, sz) { /* ... */ }
|
||||
};
|
||||
|
||||
|
||||
void Builder::VisitDirectory(BuildDirectoryContext *parent, u32 parent_offset, DirectoryTableReader &dir_table, FileTableReader &file_table) {
|
||||
const DirectoryEntry *parent_entry = dir_table.GetEntry(parent_offset);
|
||||
if (AMS_UNLIKELY(parent_entry == nullptr)) {
|
||||
@@ -773,8 +773,7 @@ namespace ams::mitm::fs {
|
||||
cur_child_offset = next_child_offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Builder::AddSdFiles() {
|
||||
/* Open Sd Card filesystem. */
|
||||
FsFileSystem sd_filesystem;
|
||||
|
||||
@@ -361,7 +361,7 @@ namespace ams::mitm::fs::romfs {
|
||||
private:
|
||||
void VisitDirectory(FsFileSystem *fs, BuildDirectoryContext *parent);
|
||||
void VisitDirectory(BuildDirectoryContext *parent, u32 parent_offset, DirectoryTableReader &dir_table, FileTableReader &file_table);
|
||||
|
||||
|
||||
void AddDirectory(BuildDirectoryContext **out, BuildDirectoryContext *parent_ctx, std::unique_ptr<BuildDirectoryContext> file_ctx);
|
||||
void AddFile(BuildDirectoryContext *parent_ctx, std::unique_ptr<BuildFileContext> file_ctx);
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user