mirror of
				https://git.h3cjp.net/H3cJP/citra.git
				synced 2025-10-30 22:44:58 +00:00 
			
		
		
		
	glue: Correct missing bytes in ApplicationLaunchParameter
This commit is contained in:
		
							parent
							
								
									d40a38df8d
								
							
						
					
					
						commit
						d10fc2d727
					
				|  | @ -61,8 +61,6 @@ FileSys::StorageId GetStorageIdForFrontendSlot( | |||
|     default: | ||||
|         return FileSys::StorageId::None; | ||||
|     } | ||||
| 
 | ||||
|     UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| } // Anonymous namespace
 | ||||
|  |  | |||
|  | @ -66,6 +66,9 @@ public: | |||
|     std::map<std::string, std::string, std::less<>> GetPatchVersionNames( | ||||
|         VirtualFile update_raw = nullptr) const; | ||||
| 
 | ||||
|     // If the game update exists, returns the u32 version field in its Meta-type NCA. If that fails,
 | ||||
|     // it will fallback to the Meta-type NCA of the base game. If that fails, the result will be
 | ||||
|     // std::nullopt
 | ||||
|     std::optional<u32> GetGameVersion() const; | ||||
| 
 | ||||
|     // Given title_id of the program, attempts to get the control data of the update and parse
 | ||||
|  |  | |||
|  | @ -647,16 +647,16 @@ ContentProviderUnion::ListEntriesFilterOrigin(std::optional<ContentProviderUnion | |||
| 
 | ||||
| std::optional<ContentProviderUnionSlot> ContentProviderUnion::GetSlotForEntry( | ||||
|     u64 title_id, ContentRecordType type) const { | ||||
|     for (const auto& [slot, provider] : providers) { | ||||
|         if (provider == nullptr) | ||||
|             continue; | ||||
|     const auto iter = | ||||
|         std::find_if(providers.begin(), providers.end(), [title_id, type](const auto& provider) { | ||||
|             return provider.second != nullptr && provider.second->HasEntry(title_id, type); | ||||
|         }); | ||||
| 
 | ||||
|         if (provider->HasEntry(title_id, type)) { | ||||
|             return slot; | ||||
|         } | ||||
|     if (iter == providers.end()) { | ||||
|         return std::nullopt; | ||||
|     } | ||||
| 
 | ||||
|     return std::nullopt; | ||||
|     return iter->first; | ||||
| } | ||||
| 
 | ||||
| ManualContentProvider::~ManualContentProvider() = default; | ||||
|  |  | |||
|  | @ -58,7 +58,8 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { | |||
|     if (!title_id.has_value()) { | ||||
|         LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ERR_NONEXISTENT); | ||||
|         rb.Push(ERR_NOT_REGISTERED); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto res = manager.GetLaunchProperty(*title_id); | ||||
|  | @ -67,6 +68,7 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { | |||
|         LOG_ERROR(Service_ARP, "Failed to get launch property!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(res.Code()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 6}; | ||||
|  | @ -86,6 +88,7 @@ void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestCont | |||
|         LOG_ERROR(Service_ARP, "Failed to get launch property!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(res.Code()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 6}; | ||||
|  | @ -103,7 +106,8 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { | |||
|     if (!title_id.has_value()) { | ||||
|         LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ERR_NONEXISTENT); | ||||
|         rb.Push(ERR_NOT_REGISTERED); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto res = manager.GetControlProperty(*title_id); | ||||
|  | @ -112,6 +116,7 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { | |||
|         LOG_ERROR(Service_ARP, "Failed to get control property!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(res.Code()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     ctx.WriteBuffer(*res); | ||||
|  | @ -132,6 +137,7 @@ void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestCon | |||
|         LOG_ERROR(Service_ARP, "Failed to get control property!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(res.Code()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     ctx.WriteBuffer(*res); | ||||
|  | @ -168,14 +174,16 @@ private: | |||
|         if (process_id == 0) { | ||||
|             LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
|             rb.Push(ERR_PROCESS_ID_ZERO); | ||||
|             rb.Push(ERR_INVALID_PROCESS_ID); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (issued) { | ||||
|             LOG_ERROR(Service_ARP, | ||||
|                       "Attempted to issue registrar, but registrar is already issued!"); | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
|             rb.Push(ERR_ALREADY_ISSUED); | ||||
|             rb.Push(ERR_INVALID_ACCESS); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         issue_process_id(process_id, launch, std::move(control)); | ||||
|  | @ -193,7 +201,8 @@ private: | |||
|                 Service_ARP, | ||||
|                 "Attempted to set application launch property, but registrar is already issued!"); | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
|             rb.Push(ERR_ALREADY_ISSUED); | ||||
|             rb.Push(ERR_INVALID_ACCESS); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         IPC::RequestParser rp{ctx}; | ||||
|  | @ -211,7 +220,8 @@ private: | |||
|                 Service_ARP, | ||||
|                 "Attempted to set application control property, but registrar is already issued!"); | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
|             rb.Push(ERR_ALREADY_ISSUED); | ||||
|             rb.Push(ERR_INVALID_ACCESS); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         control = ctx.ReadBuffer(); | ||||
|  | @ -247,7 +257,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { | |||
|         [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { | ||||
|             const auto res = GetTitleIDForProcessID(system, process_id); | ||||
|             if (!res.has_value()) { | ||||
|                 return ERR_NONEXISTENT; | ||||
|                 return ERR_NOT_REGISTERED; | ||||
|             } | ||||
| 
 | ||||
|             return manager.Register(*res, launch, std::move(control)); | ||||
|  | @ -267,7 +277,8 @@ void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { | |||
|     if (process_id == 0) { | ||||
|         LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ERR_PROCESS_ID_ZERO); | ||||
|         rb.Push(ERR_INVALID_PROCESS_ID); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto title_id = GetTitleIDForProcessID(system, process_id); | ||||
|  | @ -275,7 +286,8 @@ void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { | |||
|     if (!title_id.has_value()) { | ||||
|         LOG_ERROR(Service_ARP, "No title ID for process ID!"); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ERR_NONEXISTENT); | ||||
|         rb.Push(ERR_NOT_REGISTERED); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|  |  | |||
|  | @ -8,10 +8,9 @@ | |||
| 
 | ||||
| namespace Service::Glue { | ||||
| 
 | ||||
| constexpr ResultCode ERR_OUTPUT_TOO_SMALL{0x3C9D}; | ||||
| constexpr ResultCode ERR_PROCESS_ID_ZERO{0x3E9D}; | ||||
| constexpr ResultCode ERR_TITLE_ID_ZERO{0x3E9D}; | ||||
| constexpr ResultCode ERR_ALREADY_ISSUED{0x549D}; | ||||
| constexpr ResultCode ERR_NONEXISTENT{0xCC9D}; | ||||
| constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E}; | ||||
| constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F}; | ||||
| constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A}; | ||||
| constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 0x66}; | ||||
| 
 | ||||
| } // namespace Service::Glue
 | ||||
|  |  | |||
|  | @ -7,18 +7,23 @@ | |||
| 
 | ||||
| namespace Service::Glue { | ||||
| 
 | ||||
| struct ARPManager::MapEntry { | ||||
|     ApplicationLaunchProperty launch; | ||||
|     std::vector<u8> control; | ||||
| }; | ||||
| 
 | ||||
| ARPManager::ARPManager() = default; | ||||
| 
 | ||||
| ARPManager::~ARPManager() = default; | ||||
| 
 | ||||
| ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const { | ||||
|     if (title_id == 0) { | ||||
|         return ERR_TITLE_ID_ZERO; | ||||
|         return ERR_INVALID_PROCESS_ID; | ||||
|     } | ||||
| 
 | ||||
|     const auto iter = entries.find(title_id); | ||||
|     if (iter == entries.end()) { | ||||
|         return ERR_NONEXISTENT; | ||||
|         return ERR_NOT_REGISTERED; | ||||
|     } | ||||
| 
 | ||||
|     return MakeResult<ApplicationLaunchProperty>(iter->second.launch); | ||||
|  | @ -26,12 +31,12 @@ ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) | |||
| 
 | ||||
| ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { | ||||
|     if (title_id == 0) { | ||||
|         return ERR_TITLE_ID_ZERO; | ||||
|         return ERR_INVALID_PROCESS_ID; | ||||
|     } | ||||
| 
 | ||||
|     const auto iter = entries.find(title_id); | ||||
|     if (iter == entries.end()) { | ||||
|         return ERR_NONEXISTENT; | ||||
|         return ERR_NOT_REGISTERED; | ||||
|     } | ||||
| 
 | ||||
|     return MakeResult<std::vector<u8>>(iter->second.control); | ||||
|  | @ -40,12 +45,12 @@ ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const { | |||
| ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, | ||||
|                                 std::vector<u8> control) { | ||||
|     if (title_id == 0) { | ||||
|         return ERR_TITLE_ID_ZERO; | ||||
|         return ERR_INVALID_PROCESS_ID; | ||||
|     } | ||||
| 
 | ||||
|     const auto iter = entries.find(title_id); | ||||
|     if (iter != entries.end()) { | ||||
|         return ERR_ALREADY_ISSUED; | ||||
|         return ERR_INVALID_ACCESS; | ||||
|     } | ||||
| 
 | ||||
|     entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); | ||||
|  | @ -54,12 +59,12 @@ ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, | |||
| 
 | ||||
| ResultCode ARPManager::Unregister(u64 title_id) { | ||||
|     if (title_id == 0) { | ||||
|         return ERR_TITLE_ID_ZERO; | ||||
|         return ERR_INVALID_PROCESS_ID; | ||||
|     } | ||||
| 
 | ||||
|     const auto iter = entries.find(title_id); | ||||
|     if (iter == entries.end()) { | ||||
|         return ERR_NONEXISTENT; | ||||
|         return ERR_NOT_REGISTERED; | ||||
|     } | ||||
| 
 | ||||
|     entries.erase(iter); | ||||
|  |  | |||
|  | @ -4,6 +4,9 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <map> | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| #include "core/file_sys/control_metadata.h" | ||||
| #include "core/file_sys/romfs_factory.h" | ||||
| #include "core/hle/result.h" | ||||
|  | @ -15,31 +18,45 @@ struct ApplicationLaunchProperty { | |||
|     u32 version; | ||||
|     FileSys::StorageId base_game_storage_id; | ||||
|     FileSys::StorageId update_storage_id; | ||||
|     INSERT_PADDING_BYTES(0x2); | ||||
|     u8 program_index; | ||||
|     u8 reserved; | ||||
| }; | ||||
| static_assert(sizeof(ApplicationLaunchProperty) == 0x10, | ||||
|               "ApplicationLaunchProperty has incorrect size."); | ||||
| 
 | ||||
| // A class to manage state related to the arp:w and arp:r services, specifically the registration
 | ||||
| // and unregistration of launch and control properties.
 | ||||
| class ARPManager { | ||||
| public: | ||||
|     ARPManager(); | ||||
|     ~ARPManager(); | ||||
| 
 | ||||
|     // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was
 | ||||
|     // previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or
 | ||||
|     // ERR_INVALID_PROCESS_ID if the title ID is 0.
 | ||||
|     ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const; | ||||
| 
 | ||||
|     // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to
 | ||||
|     // the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was
 | ||||
|     // never registered or ERR_INVALID_PROCESS_ID if the title ID is 0.
 | ||||
|     ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const; | ||||
| 
 | ||||
|     // Adds a new entry to the internal database with the provided parameters, returning
 | ||||
|     // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister
 | ||||
|     // step, and ERR_INVALID_PROCESS_ID if the title ID is 0.
 | ||||
|     ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control); | ||||
| 
 | ||||
|     // Removes the registration for the provided title ID from the database, returning
 | ||||
|     // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the
 | ||||
|     // title ID is 0.
 | ||||
|     ResultCode Unregister(u64 title_id); | ||||
| 
 | ||||
|     // Removes all entries from the database, always succeeds. Should only be used when resetting
 | ||||
|     // system state.
 | ||||
|     void ResetAll(); | ||||
| 
 | ||||
| private: | ||||
|     struct MapEntry { | ||||
|         ApplicationLaunchProperty launch; | ||||
|         std::vector<u8> control; | ||||
|     }; | ||||
| 
 | ||||
|     struct MapEntry; | ||||
|     std::map<u64, MapEntry> entries; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue