mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40: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)) { |         if (!is_dir && HasSupportedFileExtension(physical_name)) { | ||||||
|             std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name); |             std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(physical_name); | ||||||
|             if (!loader) |             if (!loader) | ||||||
|  |             { | ||||||
|                 return true; |                 return true; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             bool executable = false; |             bool executable = false; | ||||||
|             loader->IsExecutable(executable); |             auto res  = loader->IsExecutable(executable); | ||||||
|             if (!executable) |             if (!executable && res != Loader::ResultStatus::ErrorEncrypted) | ||||||
|  |             { | ||||||
|                 return true; |                 return true; | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             u64 program_id = 0; |             u64 program_id = 0; | ||||||
|             loader->ReadProgramId(program_id); |             loader->ReadProgramId(program_id); | ||||||
|  |  | ||||||
|  | @ -133,8 +133,37 @@ Loader::ResultStatus NCCHContainer::OpenFile(const std::string& filepath, u32 nc | ||||||
|     return Loader::ResultStatus::Success; |     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() { | Loader::ResultStatus NCCHContainer::Load() { | ||||||
|     LOG_INFO(Service_FS, "Loading NCCH from file {}", filepath); |  | ||||||
|     if (is_loaded) |     if (is_loaded) | ||||||
|         return Loader::ResultStatus::Success; |         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 NCCHContainer::ReadProgramId(u64_le& program_id) { | ||||||
|     Loader::ResultStatus result = Load(); |     Loader::ResultStatus result = LoadHeader(); | ||||||
|     if (result != Loader::ResultStatus::Success) |     if (result != Loader::ResultStatus::Success) | ||||||
|         return result; |         return result; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -210,6 +210,12 @@ public: | ||||||
| 
 | 
 | ||||||
|     Loader::ResultStatus OpenFile(const std::string& filepath, u32 ncch_offset = 0); |     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 |      * Ensure ExeFS and exheader is loaded and ready for reading sections | ||||||
|      * @return ResultStatus result of function |      * @return ResultStatus result of function | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include <fmt/format.h> | #include <fmt/format.h> | ||||||
| #include "common/file_util.h" | #include "common/file_util.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
|  | #include "common/common_paths.h" | ||||||
| #include "common/string_util.h" | #include "common/string_util.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
| #include "core/file_sys/errors.h" | #include "core/file_sys/errors.h" | ||||||
|  | @ -33,6 +34,16 @@ | ||||||
| #include "core/loader/loader.h" | #include "core/loader/loader.h" | ||||||
| #include "core/loader/smdh.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 { | namespace Service::AM { | ||||||
| 
 | 
 | ||||||
| constexpr u16 PLATFORM_CTR = 0x0004; | constexpr u16 PLATFORM_CTR = 0x0004; | ||||||
|  | @ -373,6 +384,36 @@ InstallStatus InstallCIA(const std::string& path, | ||||||
|         installFile.Close(); |         installFile.Close(); | ||||||
| 
 | 
 | ||||||
|         LOG_INFO(Service_AM, "Installed {} successfully.", path); |         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; |         return InstallStatus::Success; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue