loader.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <functional>
  5. #include <iosfwd>
  6. #include <memory>
  7. #include <optional>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "common/common_funcs.h"
  12. #include "common/common_types.h"
  13. #include "core/file_sys/control_metadata.h"
  14. #include "core/file_sys/vfs/vfs.h"
  15. namespace Core {
  16. class System;
  17. }
  18. namespace FileSys {
  19. class NACP;
  20. } // namespace FileSys
  21. namespace Kernel {
  22. struct AddressMapping;
  23. class KProcess;
  24. } // namespace Kernel
  25. namespace Loader {
  26. /// File types supported by CTR
  27. enum class FileType {
  28. Error,
  29. Unknown,
  30. NSO,
  31. NRO,
  32. NCA,
  33. NSP,
  34. XCI,
  35. NAX,
  36. KIP,
  37. DeconstructedRomDirectory,
  38. };
  39. /**
  40. * Identifies the type of a bootable file based on the magic value in its header.
  41. * @param file open file
  42. * @return FileType of file
  43. */
  44. FileType IdentifyFile(FileSys::VirtualFile file);
  45. /**
  46. * Guess the type of a bootable file from its name
  47. * @param name String name of bootable file
  48. * @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine
  49. * a filetype, and will never return FileType::Error.
  50. */
  51. FileType GuessFromFilename(const std::string& name);
  52. /**
  53. * Convert a FileType into a string which can be displayed to the user.
  54. */
  55. std::string GetFileTypeString(FileType type);
  56. /// Return type for functions in Loader namespace
  57. enum class ResultStatus : u16 {
  58. Success,
  59. ErrorAlreadyLoaded,
  60. ErrorNotImplemented,
  61. ErrorNotInitialized,
  62. ErrorBadNPDMHeader,
  63. ErrorBadACIDHeader,
  64. ErrorBadACIHeader,
  65. ErrorBadFileAccessControl,
  66. ErrorBadFileAccessHeader,
  67. ErrorBadKernelCapabilityDescriptors,
  68. ErrorBadPFSHeader,
  69. ErrorIncorrectPFSFileSize,
  70. ErrorBadNCAHeader,
  71. ErrorMissingProductionKeyFile,
  72. ErrorMissingHeaderKey,
  73. ErrorIncorrectHeaderKey,
  74. ErrorNCA2,
  75. ErrorNCA0,
  76. ErrorMissingTitlekey,
  77. ErrorMissingTitlekek,
  78. ErrorInvalidRightsID,
  79. ErrorMissingKeyAreaKey,
  80. ErrorIncorrectKeyAreaKey,
  81. ErrorIncorrectTitlekeyOrTitlekek,
  82. ErrorXCIMissingProgramNCA,
  83. ErrorNCANotProgram,
  84. ErrorNoExeFS,
  85. ErrorBadXCIHeader,
  86. ErrorXCIMissingPartition,
  87. ErrorNullFile,
  88. ErrorMissingNPDM,
  89. Error32BitISA,
  90. ErrorUnableToParseKernelMetadata,
  91. ErrorNoRomFS,
  92. ErrorIncorrectELFFileSize,
  93. ErrorLoadingNRO,
  94. ErrorLoadingNSO,
  95. ErrorNoIcon,
  96. ErrorNoControl,
  97. ErrorBadNAXHeader,
  98. ErrorIncorrectNAXFileSize,
  99. ErrorNAXKeyHMACFailed,
  100. ErrorNAXValidationHMACFailed,
  101. ErrorNAXKeyDerivationFailed,
  102. ErrorNAXInconvertibleToNCA,
  103. ErrorBadNAXFilePath,
  104. ErrorMissingSDSeed,
  105. ErrorMissingSDKEKSource,
  106. ErrorMissingAESKEKGenerationSource,
  107. ErrorMissingAESKeyGenerationSource,
  108. ErrorMissingSDSaveKeySource,
  109. ErrorMissingSDNCAKeySource,
  110. ErrorNSPMissingProgramNCA,
  111. ErrorBadBKTRHeader,
  112. ErrorBKTRSubsectionNotAfterRelocation,
  113. ErrorBKTRSubsectionNotAtEnd,
  114. ErrorBadRelocationBlock,
  115. ErrorBadSubsectionBlock,
  116. ErrorBadRelocationBuckets,
  117. ErrorBadSubsectionBuckets,
  118. ErrorMissingBKTRBaseRomFS,
  119. ErrorNoPackedUpdate,
  120. ErrorBadKIPHeader,
  121. ErrorBLZDecompressionFailed,
  122. ErrorBadINIHeader,
  123. ErrorINITooManyKIPs,
  124. ErrorIntegrityVerificationNotImplemented,
  125. ErrorIntegrityVerificationFailed,
  126. };
  127. std::string GetResultStatusString(ResultStatus status);
  128. std::ostream& operator<<(std::ostream& os, ResultStatus status);
  129. /// Interface for loading an application
  130. class AppLoader {
  131. public:
  132. YUZU_NON_COPYABLE(AppLoader);
  133. YUZU_NON_MOVEABLE(AppLoader);
  134. struct LoadParameters {
  135. s32 main_thread_priority;
  136. u64 main_thread_stack_size;
  137. };
  138. using LoadResult = std::pair<ResultStatus, std::optional<LoadParameters>>;
  139. explicit AppLoader(FileSys::VirtualFile file_);
  140. virtual ~AppLoader();
  141. /**
  142. * Returns the type of this file
  143. *
  144. * @return FileType corresponding to the loaded file
  145. */
  146. virtual FileType GetFileType() const = 0;
  147. /**
  148. * Load the application and return the created Process instance
  149. *
  150. * @param process The newly created process.
  151. * @param system The system that this process is being loaded under.
  152. *
  153. * @return The status result of the operation.
  154. */
  155. virtual LoadResult Load(Kernel::KProcess& process, Core::System& system) = 0;
  156. /**
  157. * Try to verify the integrity of the file.
  158. */
  159. virtual ResultStatus VerifyIntegrity(std::function<bool(size_t, size_t)> progress_callback) {
  160. return ResultStatus::ErrorIntegrityVerificationNotImplemented;
  161. }
  162. /**
  163. * Get the code (typically .code section) of the application
  164. *
  165. * @param[out] buffer Reference to buffer to store data
  166. *
  167. * @return ResultStatus result of function
  168. */
  169. virtual ResultStatus ReadCode(std::vector<u8>& buffer) {
  170. return ResultStatus::ErrorNotImplemented;
  171. }
  172. /**
  173. * Get the icon (typically icon section) of the application
  174. *
  175. * @param[out] buffer Reference to buffer to store data
  176. *
  177. * @return ResultStatus result of function
  178. */
  179. virtual ResultStatus ReadIcon(std::vector<u8>& buffer) {
  180. return ResultStatus::ErrorNotImplemented;
  181. }
  182. /**
  183. * Get the banner (typically banner section) of the application
  184. * In the context of NX, this is the animation that displays in the bottom right of the screen
  185. * when a game boots. Stored in GIF format.
  186. *
  187. * @param[out] buffer Reference to buffer to store data
  188. *
  189. * @return ResultStatus result of function
  190. */
  191. virtual ResultStatus ReadBanner(std::vector<u8>& buffer) {
  192. return ResultStatus::ErrorNotImplemented;
  193. }
  194. /**
  195. * Get the logo (typically logo section) of the application
  196. * In the context of NX, this is the static image that displays in the top left of the screen
  197. * when a game boots. Stored in JPEG format.
  198. *
  199. * @param[out] buffer Reference to buffer to store data
  200. *
  201. * @return ResultStatus result of function
  202. */
  203. virtual ResultStatus ReadLogo(std::vector<u8>& buffer) {
  204. return ResultStatus::ErrorNotImplemented;
  205. }
  206. /**
  207. * Get the program id of the application
  208. *
  209. * @param[out] out_program_id Reference to store program id into
  210. *
  211. * @return ResultStatus result of function
  212. */
  213. virtual ResultStatus ReadProgramId(u64& out_program_id) {
  214. return ResultStatus::ErrorNotImplemented;
  215. }
  216. /**
  217. * Get the program ids of the application
  218. *
  219. * @param[out] out_program_ids Reference to store program ids into
  220. *
  221. * @return ResultStatus result of function
  222. */
  223. virtual ResultStatus ReadProgramIds(std::vector<u64>& out_program_ids) {
  224. return ResultStatus::ErrorNotImplemented;
  225. }
  226. /**
  227. * Get the RomFS of the application
  228. * Since the RomFS can be huge, we return a file reference instead of copying to a buffer
  229. *
  230. * @param[out] out_file The directory containing the RomFS
  231. *
  232. * @return ResultStatus result of function
  233. */
  234. virtual ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) {
  235. return ResultStatus::ErrorNotImplemented;
  236. }
  237. /**
  238. * Get the raw update of the application, should it come packed with one
  239. *
  240. * @param[out] out_file The raw update NCA file (Program-type)
  241. *
  242. * @return ResultStatus result of function
  243. */
  244. virtual ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) {
  245. return ResultStatus::ErrorNotImplemented;
  246. }
  247. /**
  248. * Get whether or not updates can be applied to the RomFS.
  249. * By default, this is true, however for formats where it cannot be guaranteed that the RomFS is
  250. * the base game it should be set to false.
  251. *
  252. * @return bool indicating whether or not the RomFS is updatable.
  253. */
  254. virtual bool IsRomFSUpdatable() const {
  255. return true;
  256. }
  257. /**
  258. * Get the title of the application
  259. *
  260. * @param[out] title Reference to store the application title into
  261. *
  262. * @return ResultStatus result of function
  263. */
  264. virtual ResultStatus ReadTitle(std::string& title) {
  265. return ResultStatus::ErrorNotImplemented;
  266. }
  267. /**
  268. * Get the control data (CNMT) of the application
  269. *
  270. * @param[out] control Reference to store the application control data into
  271. *
  272. * @return ResultStatus result of function
  273. */
  274. virtual ResultStatus ReadControlData(FileSys::NACP& control) {
  275. return ResultStatus::ErrorNotImplemented;
  276. }
  277. /**
  278. * Get the RomFS of the manual of the application
  279. *
  280. * @param[out] out_file The raw manual RomFS of the game
  281. *
  282. * @return ResultStatus result of function
  283. */
  284. virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) {
  285. return ResultStatus::ErrorNotImplemented;
  286. }
  287. using Modules = std::map<VAddr, std::string>;
  288. virtual ResultStatus ReadNSOModules(Modules& modules) {
  289. return ResultStatus::ErrorNotImplemented;
  290. }
  291. protected:
  292. FileSys::VirtualFile file;
  293. bool is_loaded = false;
  294. };
  295. /**
  296. * Identifies a bootable file and return a suitable loader
  297. *
  298. * @param system The system context.
  299. * @param file The bootable file.
  300. * @param program_index Specifies the index within the container of the program to launch.
  301. *
  302. * @return the best loader for this file.
  303. */
  304. std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
  305. u64 program_id = 0, std::size_t program_index = 0);
  306. } // namespace Loader