ResultStatus LoadFile(const std::string& filename) { FileUtil::IOFile file(filename, "rb"); if (!file.IsOpen()) { LOG_ERROR(Loader, "Failed to load file %s", filename.c_str()); return ResultStatus::Error; } std::string filename_filename, filename_extension; Common::SplitPath(filename, nullptr, &filename_filename, &filename_extension); FileType type = IdentifyFile(file); FileType filename_type = GuessFromExtension(filename_extension); if (type != filename_type) { LOG_WARNING(Loader, "File %s has a different type than its extension.", filename.c_str()); if (FileType::Unknown == type) type = filename_type; } LOG_INFO(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type)); std::unique_ptr<AppLoader> app_loader = GetLoader(std::move(file), type, filename_filename, filename); switch (type) { // 3DSX file format... // or NCCH/NCSD container formats... case FileType::THREEDSX: case FileType::CXI: case FileType::CCI: { // Load application and RomFS ResultStatus result = app_loader->Load(); if (ResultStatus::Success == result) { Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*app_loader), Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } return result; } // Standard ELF file format... case FileType::ELF: return app_loader->Load(); // CIA file format... case FileType::CIA: return ResultStatus::ErrorNotImplemented; // Error occurred durring IdentifyFile... case FileType::Error: // IdentifyFile could know identify file type... case FileType::Unknown: { LOG_CRITICAL(Loader, "File %s is of unknown type.", filename.c_str()); return ResultStatus::ErrorInvalidFormat; } } return ResultStatus::Error; }
/** * Identifies and loads a bootable file * @param filename String filename of bootable file * @return ResultStatus result of function */ ResultStatus LoadFile(const std::string& filename) { INFO_LOG(LOADER, "Loading file %s...", filename.c_str()); switch (IdentifyFile(filename)) { // Standard ELF file format... case FileType::ELF: { return AppLoader_ELF(filename).Load(); } // NCCH/NCSD container formats... case FileType::CXI: case FileType::CCI: { return AppLoader_NCCH(filename).Load(); } // Error occurred durring IdentifyFile... case FileType::Error: // IdentifyFile could know identify file type... case FileType::Unknown: default: return ResultStatus::ErrorInvalidFormat; } return ResultStatus::Error; }
FileType IdentifyFile(const std::string& file_name) { FileUtil::IOFile file(file_name, "rb"); if (!file.IsOpen()) { LOG_ERROR(Loader, "Failed to load file %s", file_name.c_str()); return FileType::Unknown; } return IdentifyFile(file); }
/** * Identifies and loads a bootable file * @param filename String filename of bootable file * @param error_string Point to string to put error message if an error has occurred * @return True on success, otherwise false */ bool LoadFile(std::string &filename, std::string *error_string) { INFO_LOG(LOADER, "Identifying file..."); // Note that this can modify filename! switch (IdentifyFile(filename)) { case FILETYPE_CTR_ELF: return Load_ELF(filename); case FILETYPE_CTR_BIN: return Load_BIN(filename); case FILETYPE_LAUNCHER_DAT: return Load_DAT(filename); case FILETYPE_DIRECTORY_CXI: return LoadDirectory_CXI(filename); case FILETYPE_ERROR: ERROR_LOG(LOADER, "Could not read file"); *error_string = "Error reading file"; break; case FILETYPE_ARCHIVE_RAR: #ifdef WIN32 *error_string = "RAR file detected (Require WINRAR)"; #else *error_string = "RAR file detected (Require UnRAR)"; #endif break; case FILETYPE_ARCHIVE_ZIP: #ifdef WIN32 *error_string = "ZIP file detected (Require WINRAR)"; #else *error_string = "ZIP file detected (Require UnRAR)"; #endif break; case FILETYPE_NORMAL_DIRECTORY: ERROR_LOG(LOADER, "Just a directory."); *error_string = "Just a directory."; break; case FILETYPE_UNKNOWN_BIN: case FILETYPE_UNKNOWN_ELF: case FILETYPE_UNKNOWN: default: ERROR_LOG(LOADER, "Failed to identify file"); *error_string = " Failed to identify file"; break; } return false; }
std::unique_ptr<AppLoader> GetLoader(const std::string& filename) { FileUtil::IOFile file(filename, "rb"); if (!file.IsOpen()) { LOG_ERROR(Loader, "Failed to load file %s", filename.c_str()); return nullptr; } std::string filename_filename, filename_extension; Common::SplitPath(filename, nullptr, &filename_filename, &filename_extension); FileType type = IdentifyFile(file); FileType filename_type = GuessFromExtension(filename_extension); if (type != filename_type) { LOG_WARNING(Loader, "File %s has a different type than its extension.", filename.c_str()); if (FileType::Unknown == type) type = filename_type; } LOG_DEBUG(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type)); return GetFileLoader(std::move(file), type, filename_filename, filename); }