| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | // Copyright 2018 yuzu emulator team
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <array>
 | 
					
						
							| 
									
										
										
										
											2018-12-19 23:50:20 -05:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:23:48 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | #include "common/bit_field.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-19 00:23:48 -04:00
										 |  |  | #include "common/common_funcs.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | #include "common/common_types.h"
 | 
					
						
							|  |  |  | #include "common/swap.h"
 | 
					
						
							| 
									
										
										
										
											2020-08-23 14:20:37 -04:00
										 |  |  | #include "core/file_sys/vfs_types.h"
 | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Loader { | 
					
						
							| 
									
										
										
										
											2018-08-12 14:56:22 +10:00
										 |  |  | enum class ResultStatus : u16; | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace FileSys { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum class ProgramAddressSpaceType : u8 { | 
					
						
							| 
									
										
										
										
											2018-09-22 20:09:32 -04:00
										 |  |  |     Is32Bit = 0, | 
					
						
							|  |  |  |     Is36Bit = 1, | 
					
						
							|  |  |  |     Is32BitNoMap = 2, | 
					
						
							|  |  |  |     Is39Bit = 3, | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | enum class ProgramFilePermission : u64 { | 
					
						
							|  |  |  |     MountContent = 1ULL << 0, | 
					
						
							|  |  |  |     SaveDataBackup = 1ULL << 5, | 
					
						
							|  |  |  |     SdCard = 1ULL << 21, | 
					
						
							|  |  |  |     Calibration = 1ULL << 34, | 
					
						
							|  |  |  |     Bit62 = 1ULL << 62, | 
					
						
							|  |  |  |     Everything = 1ULL << 63, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Helper which implements an interface to parse Program Description Metadata (NPDM) | 
					
						
							|  |  |  |  * Data can either be loaded from a file path or with data and an offset into it. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class ProgramMetadata { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2018-12-19 23:50:20 -05:00
										 |  |  |     using KernelCapabilityDescriptors = std::vector<u32>; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-19 19:19:05 -04:00
										 |  |  |     ProgramMetadata(); | 
					
						
							|  |  |  |     ~ProgramMetadata(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 09:16:15 -04:00
										 |  |  |     ProgramMetadata(const ProgramMetadata&) = default; | 
					
						
							|  |  |  |     ProgramMetadata& operator=(const ProgramMetadata&) = default; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ProgramMetadata(ProgramMetadata&&) = default; | 
					
						
							|  |  |  |     ProgramMetadata& operator=(ProgramMetadata&&) = default; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 18:15:52 -04:00
										 |  |  |     /// Gets a default ProgramMetadata configuration, should only be used for homebrew formats where
 | 
					
						
							|  |  |  |     /// we do not have an NPDM file
 | 
					
						
							|  |  |  |     static ProgramMetadata GetDefault(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 21:07:11 -04:00
										 |  |  |     Loader::ResultStatus Load(VirtualFile file); | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-20 18:15:52 -04:00
										 |  |  |     /// Load from parameters instead of NPDM file, used for KIP
 | 
					
						
							| 
									
										
										
										
											2019-11-12 05:20:26 -05:00
										 |  |  |     void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, | 
					
						
							|  |  |  |                     u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, | 
					
						
							| 
									
										
										
										
											2021-04-23 09:37:35 -04:00
										 |  |  |                     u64 filesystem_permissions, u32 system_resource_size, | 
					
						
							|  |  |  |                     KernelCapabilityDescriptors capabilities); | 
					
						
							| 
									
										
										
										
											2019-06-05 00:20:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |     bool Is64BitProgram() const; | 
					
						
							|  |  |  |     ProgramAddressSpaceType GetAddressSpaceType() const; | 
					
						
							|  |  |  |     u8 GetMainThreadPriority() const; | 
					
						
							|  |  |  |     u8 GetMainThreadCore() const; | 
					
						
							|  |  |  |     u32 GetMainThreadStackSize() const; | 
					
						
							|  |  |  |     u64 GetTitleID() const; | 
					
						
							|  |  |  |     u64 GetFilesystemPermissions() const; | 
					
						
							| 
									
										
										
										
											2019-07-07 09:42:54 -07:00
										 |  |  |     u32 GetSystemResourceSize() const; | 
					
						
							| 
									
										
										
										
											2018-12-19 23:50:20 -05:00
										 |  |  |     const KernelCapabilityDescriptors& GetKernelCapabilities() const; | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void Print() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |     struct Header { | 
					
						
							|  |  |  |         std::array<char, 4> magic; | 
					
						
							|  |  |  |         std::array<u8, 8> reserved; | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             u8 flags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             BitField<0, 1, u8> has_64_bit_instructions; | 
					
						
							|  |  |  |             BitField<1, 3, ProgramAddressSpaceType> address_space_type; | 
					
						
							|  |  |  |             BitField<4, 4, u8> reserved_2; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         u8 reserved_3; | 
					
						
							|  |  |  |         u8 main_thread_priority; | 
					
						
							|  |  |  |         u8 main_thread_cpu; | 
					
						
							| 
									
										
										
										
											2019-07-07 09:42:54 -07:00
										 |  |  |         std::array<u8, 4> reserved_4; | 
					
						
							|  |  |  |         u32_le system_resource_size; | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |         u32_le process_category; | 
					
						
							|  |  |  |         u32_le main_stack_size; | 
					
						
							|  |  |  |         std::array<u8, 0x10> application_name; | 
					
						
							|  |  |  |         std::array<u8, 0x40> reserved_5; | 
					
						
							|  |  |  |         u32_le aci_offset; | 
					
						
							|  |  |  |         u32_le aci_size; | 
					
						
							|  |  |  |         u32_le acid_offset; | 
					
						
							|  |  |  |         u32_le acid_size; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static_assert(sizeof(Header) == 0x80, "NPDM header structure size is wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct AcidHeader { | 
					
						
							|  |  |  |         std::array<u8, 0x100> signature; | 
					
						
							|  |  |  |         std::array<u8, 0x100> nca_modulus; | 
					
						
							|  |  |  |         std::array<char, 4> magic; | 
					
						
							|  |  |  |         u32_le nca_size; | 
					
						
							|  |  |  |         std::array<u8, 0x4> reserved; | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |             u32 flags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             BitField<0, 1, u32> is_retail; | 
					
						
							|  |  |  |             BitField<1, 31, u32> flags_unk; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         u64_le title_id_min; | 
					
						
							|  |  |  |         u64_le title_id_max; | 
					
						
							|  |  |  |         u32_le fac_offset; | 
					
						
							|  |  |  |         u32_le fac_size; | 
					
						
							|  |  |  |         u32_le sac_offset; | 
					
						
							|  |  |  |         u32_le sac_size; | 
					
						
							|  |  |  |         u32_le kac_offset; | 
					
						
							|  |  |  |         u32_le kac_size; | 
					
						
							| 
									
										
										
										
											2018-02-25 16:18:55 -07:00
										 |  |  |         INSERT_PADDING_BYTES(0x8); | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static_assert(sizeof(AcidHeader) == 0x240, "ACID header structure size is wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct AciHeader { | 
					
						
							|  |  |  |         std::array<char, 4> magic; | 
					
						
							|  |  |  |         std::array<u8, 0xC> reserved; | 
					
						
							|  |  |  |         u64_le title_id; | 
					
						
							| 
									
										
										
										
											2018-02-25 16:18:55 -07:00
										 |  |  |         INSERT_PADDING_BYTES(0x8); | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |         u32_le fah_offset; | 
					
						
							|  |  |  |         u32_le fah_size; | 
					
						
							|  |  |  |         u32_le sac_offset; | 
					
						
							|  |  |  |         u32_le sac_size; | 
					
						
							|  |  |  |         u32_le kac_offset; | 
					
						
							|  |  |  |         u32_le kac_size; | 
					
						
							| 
									
										
										
										
											2018-02-25 16:18:55 -07:00
										 |  |  |         INSERT_PADDING_BYTES(0x8); | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma pack(push, 1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct FileAccessControl { | 
					
						
							|  |  |  |         u8 version; | 
					
						
							| 
									
										
										
										
											2018-02-25 16:18:55 -07:00
										 |  |  |         INSERT_PADDING_BYTES(3); | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |         u64_le permissions; | 
					
						
							|  |  |  |         std::array<u8, 0x20> unknown; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static_assert(sizeof(FileAccessControl) == 0x2C, "FS access control structure size is wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct FileAccessHeader { | 
					
						
							|  |  |  |         u8 version; | 
					
						
							| 
									
										
										
										
											2018-02-25 16:18:55 -07:00
										 |  |  |         INSERT_PADDING_BYTES(3); | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  |         u64_le permissions; | 
					
						
							|  |  |  |         u32_le unk_offset; | 
					
						
							|  |  |  |         u32_le unk_size; | 
					
						
							|  |  |  |         u32_le unk_offset_2; | 
					
						
							|  |  |  |         u32_le unk_size_2; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     static_assert(sizeof(FileAccessHeader) == 0x1C, "FS access header structure size is wrong"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma pack(pop)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Header npdm_header; | 
					
						
							|  |  |  |     AciHeader aci_header; | 
					
						
							|  |  |  |     AcidHeader acid_header; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FileAccessControl acid_file_access; | 
					
						
							|  |  |  |     FileAccessHeader aci_file_access; | 
					
						
							| 
									
										
										
										
											2018-12-19 23:50:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     KernelCapabilityDescriptors aci_kernel_capabilities; | 
					
						
							| 
									
										
										
										
											2018-02-25 03:34:19 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace FileSys
 |