loader.h 9.1 KB

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