diff options
author | bunnei <bunneidev@gmail.com> | 2018-07-08 05:24:51 +0200 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2018-07-08 05:24:51 +0200 |
commit | 913896cbd99e414c325c9d47a987376ed6d9fffd (patch) | |
tree | b660920a49f538f0ee00486c50a0d153d53c423d /src/core/loader/deconstructed_rom_directory.cpp | |
parent | Merge pull request #632 from FearlessTobi/add-discord-link (diff) | |
download | yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.gz yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.bz2 yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.lz yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.xz yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.tar.zst yuzu-913896cbd99e414c325c9d47a987376ed6d9fffd.zip |
Diffstat (limited to 'src/core/loader/deconstructed_rom_directory.cpp')
-rw-r--r-- | src/core/loader/deconstructed_rom_directory.cpp | 113 |
1 files changed, 90 insertions, 23 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 0b3b4cd73..eb7feb617 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -4,10 +4,11 @@ #include <cinttypes> #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/content_archive.h" +#include "core/file_sys/romfs_factory.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/hle/service/filesystem/filesystem.h" @@ -45,11 +46,55 @@ static std::string FindRomFS(const std::string& directory) { return filepath_romfs; } -AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file) - : AppLoader(std::move(file)) {} +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); -FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& file) { - if (FileSys::IsDirectoryExeFS(file->GetContainingDirectory())) { + if (is_main_found && is_npdm_found && is_rtld_found && is_sdk_found) { return FileType::DeconstructedRomDirectory; } @@ -61,13 +106,14 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( if (is_loaded) { return ResultStatus::ErrorAlreadyLoaded; } + if (!file.IsOpen()) { + return ResultStatus::Error; + } - const FileSys::VirtualDir dir = file->GetContainingDirectory(); - const FileSys::VirtualFile npdm = dir->GetFile("main.npdm"); - if (npdm == nullptr) - return ResultStatus::ErrorInvalidFormat; + const std::string directory = filepath.substr(0, filepath.find_last_of("/\\")) + DIR_SEP; + const std::string npdm_path = directory + DIR_SEP + "main.npdm"; - ResultStatus result = metadata.Load(npdm); + ResultStatus result = metadata.Load(npdm_path); if (result != ResultStatus::Success) { return result; } @@ -82,10 +128,9 @@ 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; - const FileSys::VirtualFile module_file = dir->GetFile(module); - if (module_file != nullptr) - next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr); + next_load_addr = AppLoader_NSO::LoadModule(path, load_addr); if (next_load_addr) { LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); } else { @@ -102,20 +147,42 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( metadata.GetMainThreadStackSize()); // Find the RomFS by searching for a ".romfs" file in this directory - 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; - }); - - // TODO(DarkLordZach): Identify RomFS if its a subdirectory. - const auto romfs = (romfs_iter == files.end()) ? nullptr : *romfs_iter; + filepath_romfs = FindRomFS(directory); - if (romfs != nullptr) - Service::FileSystem::RegisterRomFS(romfs); + // Register the RomFS if a ".romfs" file was found + if (!filepath_romfs.empty()) { + Service::FileSystem::RegisterFileSystem(std::make_unique<FileSys::RomFS_Factory>(*this), + Service::FileSystem::Type::RomFS); + } is_loaded = true; return ResultStatus::Success; } +ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS( + std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { + + 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<FileUtil::IOFile>(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); + + return ResultStatus::Success; +} + } // namespace Loader |