From 77c684c1140f6bf3fb7d4560d06d2efb1a2ee5e2 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 6 Jul 2018 10:51:32 -0400 Subject: Virtual Filesystem (#597) * Add VfsFile and VfsDirectory classes * Finish abstract Vfs classes * Implement RealVfsFile (computer fs backend) * Finish RealVfsFile and RealVfsDirectory * Finished OffsetVfsFile * More changes * Fix import paths * Major refactor * Remove double const * Use experimental/filesystem or filesystem depending on compiler * Port partition_filesystem * More changes * More Overhaul * FSP_SRV fixes * Fixes and testing * Try to get filesystem to compile * Filesystem on linux * Remove std::filesystem and document/test * Compile fixes * Missing include * Bug fixes * Fixes * Rename v_file and v_dir * clang-format fix * Rename NGLOG_* to LOG_* * Most review changes * Fix TODO * Guess 'main' to be Directory by filename --- src/core/loader/deconstructed_rom_directory.cpp | 113 +++++------------------- 1 file changed, 23 insertions(+), 90 deletions(-) (limited to 'src/core/loader/deconstructed_rom_directory.cpp') diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index eb7feb617..0b3b4cd73 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -4,11 +4,10 @@ #include #include "common/common_funcs.h" -#include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" -#include "core/file_sys/romfs_factory.h" +#include "core/file_sys/content_archive.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/hle/service/filesystem/filesystem.h" @@ -46,55 +45,11 @@ static std::string FindRomFS(const std::string& directory) { return filepath_romfs; } -AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileUtil::IOFile&& file, - std::string filepath) - : AppLoader(std::move(file)), filepath(std::move(filepath)) {} - -FileType AppLoader_DeconstructedRomDirectory::IdentifyType(FileUtil::IOFile& file, - const std::string& filepath) { - bool is_main_found{}; - bool is_npdm_found{}; - bool is_rtld_found{}; - bool is_sdk_found{}; - - const auto callback = [&](unsigned* num_entries_out, const std::string& directory, - const std::string& virtual_name) -> bool { - // Skip directories - std::string physical_name = directory + virtual_name; - if (FileUtil::IsDirectory(physical_name)) { - return true; - } - - // Verify filename - if (Common::ToLower(virtual_name) == "main") { - is_main_found = true; - } else if (Common::ToLower(virtual_name) == "main.npdm") { - is_npdm_found = true; - return true; - } else if (Common::ToLower(virtual_name) == "rtld") { - is_rtld_found = true; - } else if (Common::ToLower(virtual_name) == "sdk") { - is_sdk_found = true; - } else { - // Continue searching - return true; - } - - // Verify file is an NSO - FileUtil::IOFile file(physical_name, "rb"); - if (AppLoader_NSO::IdentifyType(file, physical_name) != FileType::NSO) { - return false; - } - - // We are done if we've found and verified all required NSOs - return !(is_main_found && is_npdm_found && is_rtld_found && is_sdk_found); - }; - - // Search the directory recursively, looking for the required modules - const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP; - FileUtil::ForeachDirectoryEntry(nullptr, directory, callback); +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) + : AppLoader(std::move(file)) {} - if (is_main_found && is_npdm_found && is_rtld_found && is_sdk_found) { +FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { + if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { return FileType::DeconstructedRomDirectory; } @@ -106,14 +61,13 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( if (is_loaded) { return ResultStatus::ErrorAlreadyLoaded; } - if (!file.IsOpen()) { - return ResultStatus::Error; - } - const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP; - const std::string npdm_path = directory + DIR_SEP + "main.npdm"; + const FileSys::VirtualDir dir = file->GetContainingDirectory(); + const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); + if (npdm == nullptr) + return ResultStatus::ErrorInvalidFormat; - ResultStatus result = metadata.Load(npdm_path); + ResultStatus result = metadata.Load(npdm); if (result != ResultStatus::Success) { return result; } @@ -128,9 +82,10 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { - const std::string path = directory + DIR_SEP + module; const VAddr load_addr = next_load_addr; - next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); + const FileSys::VirtualFile module_file = dir->GetFile(module); + if (module_file != nullptr) + next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr); if (next_load_addr) { LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); } else { @@ -147,41 +102,19 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( metadata.GetMainThreadStackSize()); // Find the RomFS by searching for a ".romfs" file in this directory - filepath_romfs = FindRomFS(directory); - - // Register the RomFS if a ".romfs" file was found - if (!filepath_romfs.empty()) { - Service::FileSystem::RegisterFileSystem(std::make_unique(*this), - Service::FileSystem::Type::RomFS); - } - - is_loaded = true; - return ResultStatus::Success; -} + const auto& files = dir->GetFiles(); + const auto romfs_iter = + std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { + return file->GetName().find(".romfs") != std::string::npos; + }); -ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( - std::shared_ptr& romfs_file, u64& offset, u64& size) { + // TODO(DarkLordZach): Identify RomFS if its a subdirectory. + const auto romfs = (romfs_iter == files.end()) ? nullptr : *romfs_iter; - if (filepath_romfs.empty()) { - LOG_DEBUG(Loader, "No RomFS available"); - return ResultStatus::ErrorNotUsed; - } - - // We reopen the file, to allow its position to be independent - romfs_file = std::make_shared(filepath_romfs, "rb"); - if (!romfs_file->IsOpen()) { - return ResultStatus::Error; - } - - offset = 0; - size = romfs_file->GetSize(); - - LOG_DEBUG(Loader, "RomFS offset: 0x{:016X}", offset); - LOG_DEBUG(Loader, "RomFS size: 0x{:016X}", size); - - // Reset read pointer - file.Seek(0, SEEK_SET); + if (romfs != nullptr) + Service::FileSystem::RegisterRomFS(romfs); + is_loaded = true; return ResultStatus::Success; } -- cgit v1.2.3