mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	warn if cia contend is encrypted
This commit is contained in:
		
							parent
							
								
									ad3c464e2d
								
							
						
					
					
						commit
						ae4ba287d5
					
				
					 4 changed files with 84 additions and 4 deletions
				
			
		|  | @ -47,12 +47,16 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign | |||
|         if (!is_dir && HasSupportedFileExtension(physical_name)) { | ||||
|             std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name); | ||||
|             if (!loader) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             bool executable = false; | ||||
|             loader->IsExecutable(executable); | ||||
|             if (!executable) | ||||
|             auto res  = loader->IsExecutable(executable); | ||||
|             if (!executable && res != Loader::ResultStatus::ErrorEncrypted) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             u64 program_id = 0; | ||||
|             loader->ReadProgramId(program_id); | ||||
|  |  | |||
|  | @ -133,8 +133,37 @@ Loader::ResultStatus NCCHContainer::OpenFile(const std::string& filepath, u32 nc | |||
|     return Loader::ResultStatus::Success; | ||||
| } | ||||
| 
 | ||||
| Loader::ResultStatus NCCHContainer::LoadHeader() { | ||||
|     if (has_header) | ||||
|         return Loader::ResultStatus::Success; | ||||
|     if (!file.IsOpen()) { | ||||
| 
 | ||||
|         return Loader::ResultStatus::Error; | ||||
|     } | ||||
| 
 | ||||
|     // Reset read pointer in case this file has been read before.
 | ||||
|     file.Seek(ncch_offset, SEEK_SET); | ||||
| 
 | ||||
|     if (file.ReadBytes(&ncch_header, sizeof(NCCH_Header)) != sizeof(NCCH_Header)) | ||||
|         return Loader::ResultStatus::Error; | ||||
| 
 | ||||
|     // Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)...
 | ||||
|     if (Loader::MakeMagic('N', 'C', 'S', 'D') == ncch_header.magic) { | ||||
|         LOG_DEBUG(Service_FS, "Only loading the first (bootable) NCCH within the NCSD file!"); | ||||
|         ncch_offset += 0x4000; | ||||
|         file.Seek(ncch_offset, SEEK_SET); | ||||
|         file.ReadBytes(&ncch_header, sizeof(NCCH_Header)); | ||||
|     } | ||||
| 
 | ||||
|     // Verify we are loading the correct file type...
 | ||||
|     if (Loader::MakeMagic('N', 'C', 'C', 'H') != ncch_header.magic) | ||||
|         return Loader::ResultStatus::ErrorInvalidFormat; | ||||
| 
 | ||||
|     has_header = true; | ||||
|     return Loader::ResultStatus::Success; | ||||
| } | ||||
| 
 | ||||
| Loader::ResultStatus NCCHContainer::Load() { | ||||
|     LOG_INFO(Service_FS, "Loading NCCH from file {}", filepath); | ||||
|     if (is_loaded) | ||||
|         return Loader::ResultStatus::Success; | ||||
| 
 | ||||
|  | @ -697,7 +726,7 @@ Loader::ResultStatus NCCHContainer::ReadOverrideRomFS(std::shared_ptr<RomFSReade | |||
| } | ||||
| 
 | ||||
| Loader::ResultStatus NCCHContainer::ReadProgramId(u64_le& program_id) { | ||||
|     Loader::ResultStatus result = Load(); | ||||
|     Loader::ResultStatus result = LoadHeader(); | ||||
|     if (result != Loader::ResultStatus::Success) | ||||
|         return result; | ||||
| 
 | ||||
|  |  | |||
|  | @ -210,6 +210,12 @@ public: | |||
| 
 | ||||
|     Loader::ResultStatus OpenFile(const std::string& filepath, u32 ncch_offset = 0); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Ensure NCCH header is loaded and ready for reading sections | ||||
|      * @return ResultStatus result of function | ||||
|      */ | ||||
|     Loader::ResultStatus LoadHeader(); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Ensure ExeFS and exheader is loaded and ready for reading sections | ||||
|      * @return ResultStatus result of function | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
| #include <fmt/format.h> | ||||
| #include "common/file_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/common_paths.h" | ||||
| #include "common/string_util.h" | ||||
| #include "core/core.h" | ||||
| #include "core/file_sys/errors.h" | ||||
|  | @ -33,6 +34,16 @@ | |||
| #include "core/loader/loader.h" | ||||
| #include "core/loader/smdh.h" | ||||
| 
 | ||||
| namespace { | ||||
| bool HasSupportedFileExtension(std::string path) { | ||||
|     static const std::array<std::string, 7> extensions = {{".3ds", ".3dsx", ".elf", ".axf", | ||||
|     ".cci", ".cxi" ".app" | ||||
|     }}; | ||||
|     const auto file_ext = FileUtil::GetExtensionFromFilename(path); | ||||
|     return std::find(extensions.begin(), extensions.end(), file_ext) != extensions.end(); | ||||
| } | ||||
| } | ||||
| 
 | ||||
| namespace Service::AM { | ||||
| 
 | ||||
| constexpr u16 PLATFORM_CTR = 0x0004; | ||||
|  | @ -373,6 +384,36 @@ InstallStatus InstallCIA(const std::string& path, | |||
|         installFile.Close(); | ||||
| 
 | ||||
|         LOG_INFO(Service_AM, "Installed {} successfully.", path); | ||||
| 
 | ||||
|         const FileUtil::DirectoryEntryCallable callback = [&callback](u64* num_entries_out, | ||||
|                                                         const std::string& directory, | ||||
|                                                         const std::string& virtual_name) -> bool { | ||||
|             const std::string physical_name = directory + DIR_SEP + virtual_name; | ||||
|             const bool is_dir = FileUtil::IsDirectory(physical_name); | ||||
|             if (!is_dir && HasSupportedFileExtension(physical_name)) { | ||||
|                 std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name); | ||||
|                 if (!loader) | ||||
|                 { | ||||
|                 return true; | ||||
|                 } | ||||
| 
 | ||||
|                 bool executable = false; | ||||
|                 auto res  = loader->IsExecutable(executable); | ||||
|                 if (res == Loader::ResultStatus::ErrorEncrypted) | ||||
|                 { | ||||
|                     return false; | ||||
|                 } | ||||
|                 return true; | ||||
|             } else { | ||||
|                 return FileUtil::ForeachDirectoryEntry(nullptr, physical_name, callback); | ||||
|             } | ||||
| 
 | ||||
|         }; | ||||
|         if (!FileUtil::ForeachDirectoryEntry(nullptr, path, callback)) | ||||
|         { | ||||
|             LOG_ERROR(Service_AM, "CIA {} contained encrypted files.", path); | ||||
|             return InstallStatus::ErrorEncrypted; | ||||
|         } | ||||
|         return InstallStatus::Success; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue