| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856 |
- // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include <utility>
- #include "common/assert.h"
- #include "common/fs/path_util.h"
- #include "common/settings.h"
- #include "core/core.h"
- #include "core/file_sys/bis_factory.h"
- #include "core/file_sys/card_image.h"
- #include "core/file_sys/control_metadata.h"
- #include "core/file_sys/errors.h"
- #include "core/file_sys/mode.h"
- #include "core/file_sys/patch_manager.h"
- #include "core/file_sys/registered_cache.h"
- #include "core/file_sys/romfs_factory.h"
- #include "core/file_sys/savedata_factory.h"
- #include "core/file_sys/sdmc_factory.h"
- #include "core/file_sys/vfs.h"
- #include "core/file_sys/vfs_offset.h"
- #include "core/hle/service/filesystem/filesystem.h"
- #include "core/hle/service/filesystem/fsp_ldr.h"
- #include "core/hle/service/filesystem/fsp_pr.h"
- #include "core/hle/service/filesystem/fsp_srv.h"
- #include "core/hle/service/server_manager.h"
- #include "core/loader/loader.h"
- namespace Service::FileSystem {
- // A default size for normal/journal save data size if application control metadata cannot be found.
- // This should be large enough to satisfy even the most extreme requirements (~4.2GB)
- constexpr u64 SUFFICIENT_SAVE_DATA_SIZE = 0xF0000000;
- static FileSys::VirtualDir GetDirectoryRelativeWrapped(FileSys::VirtualDir base,
- std::string_view dir_name_) {
- std::string dir_name(Common::FS::SanitizePath(dir_name_));
- if (dir_name.empty() || dir_name == "." || dir_name == "/" || dir_name == "\\")
- return base;
- return base->GetDirectoryRelative(dir_name);
- }
- VfsDirectoryServiceWrapper::VfsDirectoryServiceWrapper(FileSys::VirtualDir backing_)
- : backing(std::move(backing_)) {}
- VfsDirectoryServiceWrapper::~VfsDirectoryServiceWrapper() = default;
- std::string VfsDirectoryServiceWrapper::GetName() const {
- return backing->GetName();
- }
- Result VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64 size) const {
- std::string path(Common::FS::SanitizePath(path_));
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
- if (dir == nullptr) {
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- FileSys::EntryType entry_type{};
- if (GetEntryType(&entry_type, path) == ResultSuccess) {
- return FileSys::ERROR_PATH_ALREADY_EXISTS;
- }
- auto file = dir->CreateFile(Common::FS::GetFilename(path));
- if (file == nullptr) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- if (!file->Resize(size)) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const {
- std::string path(Common::FS::SanitizePath(path_));
- if (path.empty()) {
- // TODO(DarkLordZach): Why do games call this and what should it do? Works as is but...
- return ResultSuccess;
- }
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
- if (dir == nullptr || dir->GetFile(Common::FS::GetFilename(path)) == nullptr) {
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- if (!dir->DeleteFile(Common::FS::GetFilename(path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const {
- std::string path(Common::FS::SanitizePath(path_));
- // NOTE: This is inaccurate behavior. CreateDirectory is not recursive.
- // CreateDirectory should return PathNotFound if the parent directory does not exist.
- // This is here temporarily in order to have UMM "work" in the meantime.
- // TODO (Morph): Remove this when a hardware test verifies the correct behavior.
- const auto components = Common::FS::SplitPathComponents(path);
- std::string relative_path;
- for (const auto& component : components) {
- // Skip empty path components
- if (component.empty()) {
- continue;
- }
- relative_path = Common::FS::SanitizePath(relative_path + '/' + component);
- auto new_dir = backing->CreateSubdirectory(relative_path);
- if (new_dir == nullptr) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::DeleteDirectory(const std::string& path_) const {
- std::string path(Common::FS::SanitizePath(path_));
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
- if (!dir->DeleteSubdirectory(Common::FS::GetFilename(path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::string& path_) const {
- std::string path(Common::FS::SanitizePath(path_));
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
- if (!dir->DeleteSubdirectoryRecursive(Common::FS::GetFilename(path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const {
- const std::string sanitized_path(Common::FS::SanitizePath(path));
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(sanitized_path));
- if (!dir->CleanSubdirectoryRecursive(Common::FS::GetFilename(sanitized_path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
- const std::string& dest_path_) const {
- std::string src_path(Common::FS::SanitizePath(src_path_));
- std::string dest_path(Common::FS::SanitizePath(dest_path_));
- auto src = backing->GetFileRelative(src_path);
- if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) {
- // Use more-optimized vfs implementation rename.
- if (src == nullptr)
- return FileSys::ERROR_PATH_NOT_FOUND;
- if (!src->Rename(Common::FS::GetFilename(dest_path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- // Move by hand -- TODO(DarkLordZach): Optimize
- auto c_res = CreateFile(dest_path, src->GetSize());
- if (c_res != ResultSuccess)
- return c_res;
- auto dest = backing->GetFileRelative(dest_path);
- ASSERT_MSG(dest != nullptr, "Newly created file with success cannot be found.");
- ASSERT_MSG(dest->WriteBytes(src->ReadAllBytes()) == src->GetSize(),
- "Could not write all of the bytes but everything else has succeeded.");
- if (!src->GetContainingDirectory()->DeleteFile(Common::FS::GetFilename(src_path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::RenameDirectory(const std::string& src_path_,
- const std::string& dest_path_) const {
- std::string src_path(Common::FS::SanitizePath(src_path_));
- std::string dest_path(Common::FS::SanitizePath(dest_path_));
- auto src = GetDirectoryRelativeWrapped(backing, src_path);
- if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) {
- // Use more-optimized vfs implementation rename.
- if (src == nullptr)
- return FileSys::ERROR_PATH_NOT_FOUND;
- if (!src->Rename(Common::FS::GetFilename(dest_path))) {
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- return ResultSuccess;
- }
- // TODO(DarkLordZach): Implement renaming across the tree (move).
- ASSERT_MSG(false,
- "Could not rename directory with path \"{}\" to new path \"{}\" because parent dirs "
- "don't match -- UNIMPLEMENTED",
- src_path, dest_path);
- // TODO(DarkLordZach): Find a better error code for this
- return ResultUnknown;
- }
- Result VfsDirectoryServiceWrapper::OpenFile(FileSys::VirtualFile* out_file,
- const std::string& path_, FileSys::Mode mode) const {
- const std::string path(Common::FS::SanitizePath(path_));
- std::string_view npath = path;
- while (!npath.empty() && (npath[0] == '/' || npath[0] == '\\')) {
- npath.remove_prefix(1);
- }
- auto file = backing->GetFileRelative(npath);
- if (file == nullptr) {
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- if (mode == FileSys::Mode::Append) {
- *out_file = std::make_shared<FileSys::OffsetVfsFile>(file, 0, file->GetSize());
- } else {
- *out_file = file;
- }
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::OpenDirectory(FileSys::VirtualDir* out_directory,
- const std::string& path_) {
- std::string path(Common::FS::SanitizePath(path_));
- auto dir = GetDirectoryRelativeWrapped(backing, path);
- if (dir == nullptr) {
- // TODO(DarkLordZach): Find a better error code for this
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- *out_directory = dir;
- return ResultSuccess;
- }
- Result VfsDirectoryServiceWrapper::GetEntryType(FileSys::EntryType* out_entry_type,
- const std::string& path_) const {
- std::string path(Common::FS::SanitizePath(path_));
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
- if (dir == nullptr) {
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- auto filename = Common::FS::GetFilename(path);
- // TODO(Subv): Some games use the '/' path, find out what this means.
- if (filename.empty()) {
- *out_entry_type = FileSys::EntryType::Directory;
- return ResultSuccess;
- }
- if (dir->GetFile(filename) != nullptr) {
- *out_entry_type = FileSys::EntryType::File;
- return ResultSuccess;
- }
- if (dir->GetSubdirectory(filename) != nullptr) {
- *out_entry_type = FileSys::EntryType::Directory;
- return ResultSuccess;
- }
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- Result VfsDirectoryServiceWrapper::GetFileTimeStampRaw(
- FileSys::FileTimeStampRaw* out_file_time_stamp_raw, const std::string& path) const {
- auto dir = GetDirectoryRelativeWrapped(backing, Common::FS::GetParentPath(path));
- if (dir == nullptr) {
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- FileSys::EntryType entry_type;
- if (GetEntryType(&entry_type, path) != ResultSuccess) {
- return FileSys::ERROR_PATH_NOT_FOUND;
- }
- *out_file_time_stamp_raw = dir->GetFileTimeStamp(Common::FS::GetFilename(path));
- return ResultSuccess;
- }
- FileSystemController::FileSystemController(Core::System& system_) : system{system_} {}
- FileSystemController::~FileSystemController() = default;
- Result FileSystemController::RegisterRomFS(std::unique_ptr<FileSys::RomFSFactory>&& factory) {
- romfs_factory = std::move(factory);
- LOG_DEBUG(Service_FS, "Registered RomFS");
- return ResultSuccess;
- }
- Result FileSystemController::RegisterSaveData(std::unique_ptr<FileSys::SaveDataFactory>&& factory) {
- ASSERT_MSG(save_data_factory == nullptr, "Tried to register a second save data");
- save_data_factory = std::move(factory);
- LOG_DEBUG(Service_FS, "Registered save data");
- return ResultSuccess;
- }
- Result FileSystemController::RegisterSDMC(std::unique_ptr<FileSys::SDMCFactory>&& factory) {
- ASSERT_MSG(sdmc_factory == nullptr, "Tried to register a second SDMC");
- sdmc_factory = std::move(factory);
- LOG_DEBUG(Service_FS, "Registered SDMC");
- return ResultSuccess;
- }
- Result FileSystemController::RegisterBIS(std::unique_ptr<FileSys::BISFactory>&& factory) {
- ASSERT_MSG(bis_factory == nullptr, "Tried to register a second BIS");
- bis_factory = std::move(factory);
- LOG_DEBUG(Service_FS, "Registered BIS");
- return ResultSuccess;
- }
- void FileSystemController::SetPackedUpdate(FileSys::VirtualFile update_raw) {
- LOG_TRACE(Service_FS, "Setting packed update for romfs");
- if (romfs_factory == nullptr)
- return;
- romfs_factory->SetPackedUpdate(std::move(update_raw));
- }
- FileSys::VirtualFile FileSystemController::OpenRomFSCurrentProcess() const {
- LOG_TRACE(Service_FS, "Opening RomFS for current process");
- if (romfs_factory == nullptr) {
- return nullptr;
- }
- return romfs_factory->OpenCurrentProcess(system.GetApplicationProcessProgramID());
- }
- FileSys::VirtualFile FileSystemController::OpenPatchedRomFS(u64 title_id,
- FileSys::ContentRecordType type) const {
- LOG_TRACE(Service_FS, "Opening patched RomFS for title_id={:016X}", title_id);
- if (romfs_factory == nullptr) {
- return nullptr;
- }
- return romfs_factory->OpenPatchedRomFS(title_id, type);
- }
- FileSys::VirtualFile FileSystemController::OpenPatchedRomFSWithProgramIndex(
- u64 title_id, u8 program_index, FileSys::ContentRecordType type) const {
- LOG_TRACE(Service_FS, "Opening patched RomFS for title_id={:016X}, program_index={}", title_id,
- program_index);
- if (romfs_factory == nullptr) {
- return nullptr;
- }
- return romfs_factory->OpenPatchedRomFSWithProgramIndex(title_id, program_index, type);
- }
- FileSys::VirtualFile FileSystemController::OpenRomFS(u64 title_id, FileSys::StorageId storage_id,
- FileSys::ContentRecordType type) const {
- LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}, storage_id={:02X}, type={:02X}",
- title_id, storage_id, type);
- if (romfs_factory == nullptr) {
- return nullptr;
- }
- return romfs_factory->Open(title_id, storage_id, type);
- }
- std::shared_ptr<FileSys::NCA> FileSystemController::OpenBaseNca(
- u64 title_id, FileSys::StorageId storage_id, FileSys::ContentRecordType type) const {
- return romfs_factory->GetEntry(title_id, storage_id, type);
- }
- Result FileSystemController::CreateSaveData(FileSys::VirtualDir* out_save_data,
- FileSys::SaveDataSpaceId space,
- const FileSys::SaveDataAttribute& save_struct) const {
- LOG_TRACE(Service_FS, "Creating Save Data for space_id={:01X}, save_struct={}", space,
- save_struct.DebugInfo());
- if (save_data_factory == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- auto save_data = save_data_factory->Create(space, save_struct);
- if (save_data == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- *out_save_data = save_data;
- return ResultSuccess;
- }
- Result FileSystemController::OpenSaveData(FileSys::VirtualDir* out_save_data,
- FileSys::SaveDataSpaceId space,
- const FileSys::SaveDataAttribute& attribute) const {
- LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}", space,
- attribute.DebugInfo());
- if (save_data_factory == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- auto save_data = save_data_factory->Open(space, attribute);
- if (save_data == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- *out_save_data = save_data;
- return ResultSuccess;
- }
- Result FileSystemController::OpenSaveDataSpace(FileSys::VirtualDir* out_save_data_space,
- FileSys::SaveDataSpaceId space) const {
- LOG_TRACE(Service_FS, "Opening Save Data Space for space_id={:01X}", space);
- if (save_data_factory == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- auto save_data_space = save_data_factory->GetSaveDataSpaceDirectory(space);
- if (save_data_space == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- *out_save_data_space = save_data_space;
- return ResultSuccess;
- }
- Result FileSystemController::OpenSDMC(FileSys::VirtualDir* out_sdmc) const {
- LOG_TRACE(Service_FS, "Opening SDMC");
- if (sdmc_factory == nullptr) {
- return FileSys::ERROR_SD_CARD_NOT_FOUND;
- }
- auto sdmc = sdmc_factory->Open();
- if (sdmc == nullptr) {
- return FileSys::ERROR_SD_CARD_NOT_FOUND;
- }
- *out_sdmc = sdmc;
- return ResultSuccess;
- }
- Result FileSystemController::OpenBISPartition(FileSys::VirtualDir* out_bis_partition,
- FileSys::BisPartitionId id) const {
- LOG_TRACE(Service_FS, "Opening BIS Partition with id={:08X}", id);
- if (bis_factory == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- auto part = bis_factory->OpenPartition(id);
- if (part == nullptr) {
- return FileSys::ERROR_INVALID_ARGUMENT;
- }
- *out_bis_partition = part;
- return ResultSuccess;
- }
- Result FileSystemController::OpenBISPartitionStorage(
- FileSys::VirtualFile* out_bis_partition_storage, FileSys::BisPartitionId id) const {
- LOG_TRACE(Service_FS, "Opening BIS Partition Storage with id={:08X}", id);
- if (bis_factory == nullptr) {
- return FileSys::ERROR_ENTITY_NOT_FOUND;
- }
- auto part = bis_factory->OpenPartitionStorage(id, system.GetFilesystem());
- if (part == nullptr) {
- return FileSys::ERROR_INVALID_ARGUMENT;
- }
- *out_bis_partition_storage = part;
- return ResultSuccess;
- }
- u64 FileSystemController::GetFreeSpaceSize(FileSys::StorageId id) const {
- switch (id) {
- case FileSys::StorageId::None:
- case FileSys::StorageId::GameCard:
- return 0;
- case FileSys::StorageId::SdCard:
- if (sdmc_factory == nullptr)
- return 0;
- return sdmc_factory->GetSDMCFreeSpace();
- case FileSys::StorageId::Host:
- if (bis_factory == nullptr)
- return 0;
- return bis_factory->GetSystemNANDFreeSpace() + bis_factory->GetUserNANDFreeSpace();
- case FileSys::StorageId::NandSystem:
- if (bis_factory == nullptr)
- return 0;
- return bis_factory->GetSystemNANDFreeSpace();
- case FileSys::StorageId::NandUser:
- if (bis_factory == nullptr)
- return 0;
- return bis_factory->GetUserNANDFreeSpace();
- }
- return 0;
- }
- u64 FileSystemController::GetTotalSpaceSize(FileSys::StorageId id) const {
- switch (id) {
- case FileSys::StorageId::None:
- case FileSys::StorageId::GameCard:
- return 0;
- case FileSys::StorageId::SdCard:
- if (sdmc_factory == nullptr)
- return 0;
- return sdmc_factory->GetSDMCTotalSpace();
- case FileSys::StorageId::Host:
- if (bis_factory == nullptr)
- return 0;
- return bis_factory->GetFullNANDTotalSpace();
- case FileSys::StorageId::NandSystem:
- if (bis_factory == nullptr)
- return 0;
- return bis_factory->GetSystemNANDTotalSpace();
- case FileSys::StorageId::NandUser:
- if (bis_factory == nullptr)
- return 0;
- return bis_factory->GetUserNANDTotalSpace();
- }
- return 0;
- }
- FileSys::SaveDataSize FileSystemController::ReadSaveDataSize(FileSys::SaveDataType type,
- u64 title_id, u128 user_id) const {
- if (save_data_factory == nullptr) {
- return {0, 0};
- }
- const auto value = save_data_factory->ReadSaveDataSize(type, title_id, user_id);
- if (value.normal == 0 && value.journal == 0) {
- FileSys::SaveDataSize new_size{SUFFICIENT_SAVE_DATA_SIZE, SUFFICIENT_SAVE_DATA_SIZE};
- FileSys::NACP nacp;
- const auto res = system.GetAppLoader().ReadControlData(nacp);
- if (res != Loader::ResultStatus::Success) {
- const FileSys::PatchManager pm{system.GetApplicationProcessProgramID(),
- system.GetFileSystemController(),
- system.GetContentProvider()};
- const auto metadata = pm.GetControlMetadata();
- const auto& nacp_unique = metadata.first;
- if (nacp_unique != nullptr) {
- new_size = {nacp_unique->GetDefaultNormalSaveSize(),
- nacp_unique->GetDefaultJournalSaveSize()};
- }
- } else {
- new_size = {nacp.GetDefaultNormalSaveSize(), nacp.GetDefaultJournalSaveSize()};
- }
- WriteSaveDataSize(type, title_id, user_id, new_size);
- return new_size;
- }
- return value;
- }
- void FileSystemController::WriteSaveDataSize(FileSys::SaveDataType type, u64 title_id, u128 user_id,
- FileSys::SaveDataSize new_value) const {
- if (save_data_factory != nullptr)
- save_data_factory->WriteSaveDataSize(type, title_id, user_id, new_value);
- }
- void FileSystemController::SetGameCard(FileSys::VirtualFile file) {
- gamecard = std::make_unique<FileSys::XCI>(file);
- const auto dir = gamecard->ConcatenatedPseudoDirectory();
- gamecard_registered = std::make_unique<FileSys::RegisteredCache>(dir);
- gamecard_placeholder = std::make_unique<FileSys::PlaceholderCache>(dir);
- }
- FileSys::XCI* FileSystemController::GetGameCard() const {
- return gamecard.get();
- }
- FileSys::RegisteredCache* FileSystemController::GetGameCardContents() const {
- return gamecard_registered.get();
- }
- FileSys::PlaceholderCache* FileSystemController::GetGameCardPlaceholder() const {
- return gamecard_placeholder.get();
- }
- FileSys::RegisteredCache* FileSystemController::GetSystemNANDContents() const {
- LOG_TRACE(Service_FS, "Opening System NAND Contents");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetSystemNANDContents();
- }
- FileSys::RegisteredCache* FileSystemController::GetUserNANDContents() const {
- LOG_TRACE(Service_FS, "Opening User NAND Contents");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetUserNANDContents();
- }
- FileSys::RegisteredCache* FileSystemController::GetSDMCContents() const {
- LOG_TRACE(Service_FS, "Opening SDMC Contents");
- if (sdmc_factory == nullptr)
- return nullptr;
- return sdmc_factory->GetSDMCContents();
- }
- FileSys::PlaceholderCache* FileSystemController::GetSystemNANDPlaceholder() const {
- LOG_TRACE(Service_FS, "Opening System NAND Placeholder");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetSystemNANDPlaceholder();
- }
- FileSys::PlaceholderCache* FileSystemController::GetUserNANDPlaceholder() const {
- LOG_TRACE(Service_FS, "Opening User NAND Placeholder");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetUserNANDPlaceholder();
- }
- FileSys::PlaceholderCache* FileSystemController::GetSDMCPlaceholder() const {
- LOG_TRACE(Service_FS, "Opening SDMC Placeholder");
- if (sdmc_factory == nullptr)
- return nullptr;
- return sdmc_factory->GetSDMCPlaceholder();
- }
- FileSys::RegisteredCache* FileSystemController::GetRegisteredCacheForStorage(
- FileSys::StorageId id) const {
- switch (id) {
- case FileSys::StorageId::None:
- case FileSys::StorageId::Host:
- UNIMPLEMENTED();
- return nullptr;
- case FileSys::StorageId::GameCard:
- return GetGameCardContents();
- case FileSys::StorageId::NandSystem:
- return GetSystemNANDContents();
- case FileSys::StorageId::NandUser:
- return GetUserNANDContents();
- case FileSys::StorageId::SdCard:
- return GetSDMCContents();
- }
- return nullptr;
- }
- FileSys::PlaceholderCache* FileSystemController::GetPlaceholderCacheForStorage(
- FileSys::StorageId id) const {
- switch (id) {
- case FileSys::StorageId::None:
- case FileSys::StorageId::Host:
- UNIMPLEMENTED();
- return nullptr;
- case FileSys::StorageId::GameCard:
- return GetGameCardPlaceholder();
- case FileSys::StorageId::NandSystem:
- return GetSystemNANDPlaceholder();
- case FileSys::StorageId::NandUser:
- return GetUserNANDPlaceholder();
- case FileSys::StorageId::SdCard:
- return GetSDMCPlaceholder();
- }
- return nullptr;
- }
- FileSys::VirtualDir FileSystemController::GetSystemNANDContentDirectory() const {
- LOG_TRACE(Service_FS, "Opening system NAND content directory");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetSystemNANDContentDirectory();
- }
- FileSys::VirtualDir FileSystemController::GetUserNANDContentDirectory() const {
- LOG_TRACE(Service_FS, "Opening user NAND content directory");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetUserNANDContentDirectory();
- }
- FileSys::VirtualDir FileSystemController::GetSDMCContentDirectory() const {
- LOG_TRACE(Service_FS, "Opening SDMC content directory");
- if (sdmc_factory == nullptr)
- return nullptr;
- return sdmc_factory->GetSDMCContentDirectory();
- }
- FileSys::VirtualDir FileSystemController::GetNANDImageDirectory() const {
- LOG_TRACE(Service_FS, "Opening NAND image directory");
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetImageDirectory();
- }
- FileSys::VirtualDir FileSystemController::GetSDMCImageDirectory() const {
- LOG_TRACE(Service_FS, "Opening SDMC image directory");
- if (sdmc_factory == nullptr)
- return nullptr;
- return sdmc_factory->GetImageDirectory();
- }
- FileSys::VirtualDir FileSystemController::GetContentDirectory(ContentStorageId id) const {
- switch (id) {
- case ContentStorageId::System:
- return GetSystemNANDContentDirectory();
- case ContentStorageId::User:
- return GetUserNANDContentDirectory();
- case ContentStorageId::SdCard:
- return GetSDMCContentDirectory();
- }
- return nullptr;
- }
- FileSys::VirtualDir FileSystemController::GetImageDirectory(ImageDirectoryId id) const {
- switch (id) {
- case ImageDirectoryId::NAND:
- return GetNANDImageDirectory();
- case ImageDirectoryId::SdCard:
- return GetSDMCImageDirectory();
- }
- return nullptr;
- }
- FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id) const {
- LOG_TRACE(Service_FS, "Opening mod load root for tid={:016X}", title_id);
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetModificationLoadRoot(title_id);
- }
- FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const {
- LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id);
- if (sdmc_factory == nullptr) {
- return nullptr;
- }
- return sdmc_factory->GetSDMCModificationLoadRoot(title_id);
- }
- FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const {
- LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id);
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetModificationDumpRoot(title_id);
- }
- FileSys::VirtualDir FileSystemController::GetBCATDirectory(u64 title_id) const {
- LOG_TRACE(Service_FS, "Opening BCAT root for tid={:016X}", title_id);
- if (bis_factory == nullptr)
- return nullptr;
- return bis_factory->GetBCATDirectory(title_id);
- }
- void FileSystemController::SetAutoSaveDataCreation(bool enable) {
- save_data_factory->SetAutoCreate(enable);
- }
- void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {
- if (overwrite) {
- bis_factory = nullptr;
- save_data_factory = nullptr;
- sdmc_factory = nullptr;
- }
- using YuzuPath = Common::FS::YuzuPath;
- const auto sdmc_dir_path = Common::FS::GetYuzuPath(YuzuPath::SDMCDir);
- const auto sdmc_load_dir_path = sdmc_dir_path / "atmosphere/contents";
- const auto rw_mode = FileSys::Mode::ReadWrite;
- auto nand_directory =
- vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode);
- auto sd_directory = vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_dir_path), rw_mode);
- auto load_directory =
- vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read);
- auto sd_load_directory =
- vfs.OpenDirectory(Common::FS::PathToUTF8String(sdmc_load_dir_path), FileSys::Mode::Read);
- auto dump_directory =
- vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode);
- if (bis_factory == nullptr) {
- bis_factory = std::make_unique<FileSys::BISFactory>(
- nand_directory, std::move(load_directory), std::move(dump_directory));
- system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SysNAND,
- bis_factory->GetSystemNANDContents());
- system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::UserNAND,
- bis_factory->GetUserNANDContents());
- }
- if (save_data_factory == nullptr) {
- save_data_factory =
- std::make_unique<FileSys::SaveDataFactory>(system, std::move(nand_directory));
- }
- if (sdmc_factory == nullptr) {
- sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory),
- std::move(sd_load_directory));
- system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::SDMC,
- sdmc_factory->GetSDMCContents());
- }
- }
- void LoopProcess(Core::System& system) {
- auto server_manager = std::make_unique<ServerManager>(system);
- server_manager->RegisterNamedService("fsp-ldr", std::make_shared<FSP_LDR>(system));
- server_manager->RegisterNamedService("fsp:pr", std::make_shared<FSP_PR>(system));
- server_manager->RegisterNamedService("fsp-srv", std::make_shared<FSP_SRV>(system));
- ServerManager::RunServer(std::move(server_manager));
- }
- } // namespace Service::FileSystem
|