mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Stub some missing AM Ticket functions (#7172)
This commit is contained in:
		
							parent
							
								
									ba702043f0
								
							
						
					
					
						commit
						b6acebcb11
					
				
					 5 changed files with 224 additions and 10 deletions
				
			
		|  | @ -50,6 +50,9 @@ public: | |||
| 
 | ||||
|     Loader::ResultStatus Load(std::span<const u8> file_data, std::size_t offset = 0); | ||||
|     std::optional<std::array<u8, 16>> GetTitleKey() const; | ||||
|     u64 GetTitleID() const { | ||||
|         return ticket_body.title_id; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     Body ticket_body; | ||||
|  |  | |||
|  | @ -374,6 +374,45 @@ bool CIAFile::Close() const { | |||
| 
 | ||||
| void CIAFile::Flush() const {} | ||||
| 
 | ||||
| TicketFile::TicketFile() {} | ||||
| 
 | ||||
| TicketFile::~TicketFile() { | ||||
|     Close(); | ||||
| } | ||||
| 
 | ||||
| ResultVal<std::size_t> TicketFile::Read(u64 offset, std::size_t length, u8* buffer) const { | ||||
|     UNIMPLEMENTED(); | ||||
|     return length; | ||||
| } | ||||
| 
 | ||||
| ResultVal<std::size_t> TicketFile::Write(u64 offset, std::size_t length, bool flush, | ||||
|                                          const u8* buffer) { | ||||
|     written += length; | ||||
|     data.resize(written); | ||||
|     std::memcpy(data.data() + offset, buffer, length); | ||||
|     return length; | ||||
| } | ||||
| 
 | ||||
| u64 TicketFile::GetSize() const { | ||||
|     return written; | ||||
| } | ||||
| 
 | ||||
| bool TicketFile::SetSize(u64 size) const { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| bool TicketFile::Close() const { | ||||
|     FileSys::Ticket ticket; | ||||
|     if (ticket.Load(data, 0) == Loader::ResultStatus::Success) { | ||||
|         LOG_WARNING(Service_AM, "Discarding ticket for {:#016X}.", ticket.GetTitleID()); | ||||
|     } else { | ||||
|         LOG_ERROR(Service_AM, "Invalid ticket provided to TicketFile."); | ||||
|     } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void TicketFile::Flush() const {} | ||||
| 
 | ||||
| InstallStatus InstallCIA(const std::string& path, | ||||
|                          std::function<ProgressCallback>&& update_callback) { | ||||
|     LOG_INFO(Service_AM, "Installing {}...", path); | ||||
|  | @ -942,6 +981,10 @@ void Module::Interface::GetProgramInfos(Kernel::HLERequestContext& ctx) { | |||
|     rb.PushMappedBuffer(title_info_out); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::GetProgramInfosIgnorePlatform(Kernel::HLERequestContext& ctx) { | ||||
|     GetProgramInfos(ctx); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::DeleteUserProgram(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     auto media_type = rp.PopEnum<FS::MediaType>(); | ||||
|  | @ -1177,6 +1220,16 @@ void Module::Interface::NeedsCleanup(Kernel::HLERequestContext& ctx) { | |||
|     rb.Push<bool>(false); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::DoCleanup(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     const auto media_type = rp.Pop<u8>(); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_AM, "(STUBBED) called, media_type={:#02x}", media_type); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::QueryAvailableTitleDatabase(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     u8 media_type = rp.Pop<u8>(); | ||||
|  | @ -1188,6 +1241,45 @@ void Module::Interface::QueryAvailableTitleDatabase(Kernel::HLERequestContext& c | |||
|     LOG_WARNING(Service_AM, "(STUBBED) media_type={}", media_type); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::GetPersonalizedTicketInfoList(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     [[maybe_unused]] u32 ticket_count = rp.Pop<u32>(); | ||||
|     [[maybe_unused]] auto& buffer = rp.PopMappedBuffer(); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||
|     rb.Push(RESULT_SUCCESS); // No error
 | ||||
|     rb.Push(0); | ||||
| 
 | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called, ticket_count={}", ticket_count); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::GetNumImportTitleContextsFiltered(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     u8 media_type = rp.Pop<u8>(); | ||||
|     u8 filter = rp.Pop<u8>(); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 0); | ||||
|     rb.Push(RESULT_SUCCESS); // No error
 | ||||
|     rb.Push(0); | ||||
| 
 | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called, media_type={}, filter={}", media_type, filter); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::GetImportTitleContextListFiltered(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     [[maybe_unused]] const u32 count = rp.Pop<u32>(); | ||||
|     const u8 media_type = rp.Pop<u8>(); | ||||
|     const u8 filter = rp.Pop<u8>(); | ||||
|     auto& buffer = rp.PopMappedBuffer(); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | ||||
|     rb.Push(RESULT_SUCCESS); // No error
 | ||||
|     rb.Push(0); | ||||
|     rb.PushMappedBuffer(buffer); | ||||
| 
 | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called, media_type={}, filter={}", media_type, filter); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::CheckContentRights(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     u64 tid = rp.Pop<u64>(); | ||||
|  | @ -1674,6 +1766,30 @@ void Module::Interface::GetMetaDataFromCia(Kernel::HLERequestContext& ctx) { | |||
|     rb.PushMappedBuffer(output_buffer); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::BeginImportTicket(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
| 
 | ||||
|     // Create our TicketFile handle for the app to write to
 | ||||
|     auto file = std::make_shared<Service::FS::File>(am->kernel, std::make_unique<TicketFile>(), | ||||
|                                                     FileSys::Path{}); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 2); | ||||
|     rb.Push(RESULT_SUCCESS); // No error
 | ||||
|     rb.PushCopyObjects(file->Connect()); | ||||
| 
 | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
| } | ||||
| 
 | ||||
| void Module::Interface::EndImportTicket(Kernel::HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp(ctx); | ||||
|     [[maybe_unused]] const auto ticket = rp.PopObject<Kernel::ClientSession>(); | ||||
| 
 | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
| 
 | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
| } | ||||
| 
 | ||||
| Module::Module(Core::System& system) : kernel(system.Kernel()) { | ||||
|     ScanForAllTitles(); | ||||
|     system_updater_mutex = system.Kernel().CreateMutex(false, "AM::SystemUpdaterMutex"); | ||||
|  |  | |||
|  | @ -109,6 +109,25 @@ private: | |||
|     std::unique_ptr<DecryptionState> decryption_state; | ||||
| }; | ||||
| 
 | ||||
| // A file handled returned for Tickets to be written into and subsequently installed.
 | ||||
| class TicketFile final : public FileSys::FileBackend { | ||||
| public: | ||||
|     explicit TicketFile(); | ||||
|     ~TicketFile(); | ||||
| 
 | ||||
|     ResultVal<std::size_t> Read(u64 offset, std::size_t length, u8* buffer) const override; | ||||
|     ResultVal<std::size_t> Write(u64 offset, std::size_t length, bool flush, | ||||
|                                  const u8* buffer) override; | ||||
|     u64 GetSize() const override; | ||||
|     bool SetSize(u64 size) const override; | ||||
|     bool Close() const override; | ||||
|     void Flush() const override; | ||||
| 
 | ||||
| private: | ||||
|     u64 written = 0; | ||||
|     std::vector<u8> data; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * Installs a CIA file from a specified file path. | ||||
|  * @param path file path of the CIA file to install | ||||
|  | @ -272,6 +291,18 @@ public: | |||
|          */ | ||||
|         void GetProgramInfos(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::GetProgramInfosIgnorePlatform service function | ||||
|          *  Inputs: | ||||
|          *      1 : u8 Mediatype | ||||
|          *      2 : Total titles | ||||
|          *      4 : TitleIDList pointer | ||||
|          *      6 : TitleList pointer | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          */ | ||||
|         void GetProgramInfosIgnorePlatform(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::DeleteUserProgram service function | ||||
|          * Deletes a user program | ||||
|  | @ -389,6 +420,15 @@ public: | |||
|          */ | ||||
|         void NeedsCleanup(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::DoCleanup service function | ||||
|          *  Inputs: | ||||
|          *      1 : Media Type | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          */ | ||||
|         void DoCleanup(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::QueryAvailableTitleDatabase service function | ||||
|          *  Inputs: | ||||
|  | @ -399,6 +439,42 @@ public: | |||
|          */ | ||||
|         void QueryAvailableTitleDatabase(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::GetPersonalizedTicketInfoList service function | ||||
|          *  Inputs: | ||||
|          *      1 : Count | ||||
|          *      2-3 : Buffer | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          *      2 : Out count | ||||
|          */ | ||||
|         void GetPersonalizedTicketInfoList(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::GetNumImportTitleContextsFiltered service function | ||||
|          *  Inputs: | ||||
|          *      1 : Count | ||||
|          *      2 : Filter | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          *      2 : Num import titles | ||||
|          */ | ||||
|         void GetNumImportTitleContextsFiltered(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::GetImportTitleContextListFiltered service function | ||||
|          *  Inputs: | ||||
|          *      1 : Count | ||||
|          *      2 : Media type | ||||
|          *      3 : filter | ||||
|          *      4-5 : Buffer | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          *      2 : Out count | ||||
|          *      3-4 : Out buffer | ||||
|          */ | ||||
|         void GetImportTitleContextListFiltered(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::CheckContentRights service function | ||||
|          *  Inputs: | ||||
|  | @ -602,6 +678,25 @@ public: | |||
|          */ | ||||
|         void GetMetaDataFromCia(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::BeginImportTicket service function | ||||
|          *  Inputs: | ||||
|          *      1 : Media type to install title to | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          *      2-3 : TicketHandle handle for application to write to | ||||
|          */ | ||||
|         void BeginImportTicket(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|         /**
 | ||||
|          * AM::EndImportTicket service function | ||||
|          *  Inputs: | ||||
|          *      1-2 : TicketHandle handle application wrote to | ||||
|          *  Outputs: | ||||
|          *      1 : Result, 0 on success, otherwise error code | ||||
|          */ | ||||
|         void EndImportTicket(Kernel::HLERequestContext& ctx); | ||||
| 
 | ||||
|     protected: | ||||
|         std::shared_ptr<Module> am; | ||||
|     }; | ||||
|  |  | |||
|  | @ -42,19 +42,19 @@ AM_NET::AM_NET(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a | |||
|         {0x001E, nullptr, "ReadTwlBackupInfo"}, | ||||
|         {0x001F, nullptr, "DeleteAllExpiredUserPrograms"}, | ||||
|         {0x0020, nullptr, "GetTwlArchiveResourceInfo"}, | ||||
|         {0x0021, nullptr, "GetPersonalizedTicketInfoList"}, | ||||
|         {0x0021, &AM_NET::GetPersonalizedTicketInfoList, "GetPersonalizedTicketInfoList"}, | ||||
|         {0x0022, nullptr, "DeleteAllImportContextsFiltered"}, | ||||
|         {0x0023, nullptr, "GetNumImportTitleContextsFiltered"}, | ||||
|         {0x0024, nullptr, "GetImportTitleContextListFiltered"}, | ||||
|         {0x0025, nullptr, "CheckContentRights"}, | ||||
|         {0x0023, &AM_NET::GetNumImportTitleContextsFiltered, "GetNumImportTitleContextsFiltered"}, | ||||
|         {0x0024, &AM_NET::GetImportTitleContextListFiltered, "GetImportTitleContextListFiltered"}, | ||||
|         {0x0025, &AM_NET::CheckContentRights, "CheckContentRights"}, | ||||
|         {0x0026, nullptr, "GetTicketLimitInfos"}, | ||||
|         {0x0027, nullptr, "GetDemoLaunchInfos"}, | ||||
|         {0x0028, nullptr, "ReadTwlBackupInfoEx"}, | ||||
|         {0x0029, nullptr, "DeleteUserProgramsAtomically"}, | ||||
|         {0x002A, nullptr, "GetNumExistingContentInfosSystem"}, | ||||
|         {0x002B, nullptr, "ListExistingContentInfosSystem"}, | ||||
|         {0x002C, nullptr, "GetProgramInfosIgnorePlatform"}, | ||||
|         {0x002D, nullptr, "CheckContentRightsIgnorePlatform"}, | ||||
|         {0x002C, &AM_NET::GetProgramInfosIgnorePlatform, "GetProgramInfosIgnorePlatform"}, | ||||
|         {0x002D, &AM_NET::CheckContentRightsIgnorePlatform, "CheckContentRightsIgnorePlatform"}, | ||||
|         {0x0401, nullptr, "UpdateFirmwareTo"}, | ||||
|         {0x0402, &AM_NET::BeginImportProgram, "BeginImportProgram"}, | ||||
|         {0x0403, nullptr, "BeginImportProgramTemporarily"}, | ||||
|  | @ -72,7 +72,7 @@ AM_NET::AM_NET(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a | |||
|         {0x040F, nullptr, "UpdateFirmwareAuto"}, | ||||
|         {0x0410, &AM_NET::DeleteProgram, "DeleteProgram"}, | ||||
|         {0x0411, nullptr, "GetTwlProgramListForReboot"}, | ||||
|         {0x0412, nullptr, "GetSystemUpdaterMutex"}, | ||||
|         {0x0412, &AM_NET::GetSystemUpdaterMutex, "GetSystemUpdaterMutex"}, | ||||
|         {0x0413, &AM_NET::GetMetaSizeFromCia, "GetMetaSizeFromCia"}, | ||||
|         {0x0414, &AM_NET::GetMetaDataFromCia, "GetMetaDataFromCia"}, | ||||
|         {0x0415, nullptr, "CheckDemoLaunchRights"}, | ||||
|  | @ -80,9 +80,9 @@ AM_NET::AM_NET(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a | |||
|         {0x0417, nullptr, "PerpetuateAgbSaveData"}, | ||||
|         {0x0418, nullptr, "BeginImportProgramForOverWrite"}, | ||||
|         {0x0419, nullptr, "BeginImportSystemProgram"}, | ||||
|         {0x0801, nullptr, "BeginImportTicket"}, | ||||
|         {0x0801, &AM_NET::BeginImportTicket, "BeginImportTicket"}, | ||||
|         {0x0802, nullptr, "CancelImportTicket"}, | ||||
|         {0x0803, nullptr, "EndImportTicket"}, | ||||
|         {0x0803, &AM_NET::EndImportTicket, "EndImportTicket"}, | ||||
|         {0x0804, nullptr, "BeginImportTitle"}, | ||||
|         {0x0805, nullptr, "StopImportTitle"}, | ||||
|         {0x0806, nullptr, "ResumeImportTitle"}, | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ AM_SYS::AM_SYS(std::shared_ptr<Module> am) : Module::Interface(std::move(am), "a | |||
|         {0x0011, nullptr, "GetImportContentContexts"}, | ||||
|         {0x0012, nullptr, "DeleteImportContentContexts"}, | ||||
|         {0x0013, &AM_SYS::NeedsCleanup, "NeedsCleanup"}, | ||||
|         {0x0014, nullptr, "DoCleanup"}, | ||||
|         {0x0014, &AM_SYS::DoCleanup, "DoCleanup"}, | ||||
|         {0x0015, nullptr, "DeleteAllImportContexts"}, | ||||
|         {0x0016, nullptr, "DeleteAllTemporaryPrograms"}, | ||||
|         {0x0017, nullptr, "ImportTwlBackupLegacy"}, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue