mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Service/AM: Implement DeleteProgram and DeleteUserProgram (#3446)
* Update am.cpp * Update am.h * Update am_net.cpp * Service/AM: Implement DeleteProgram * fix clang * Address comments * Service/AM: DeleteProgram: Scan for all titles after deleting the title * fix * Service/AM: DeleteProgram: return error if the title was not found * fix clang * [skip ci] * [skip ci] * [skip ci] * [skip ci] * Service/AM: Implement DeleteUserProgram * fix clang * FileUtil::DeleteDirRecursively unexpectedly failed
This commit is contained in:
		
							parent
							
								
									0cea9c54ac
								
							
						
					
					
						commit
						ac626edabc
					
				
					 5 changed files with 81 additions and 5 deletions
				
			
		|  | @ -688,6 +688,36 @@ void GetProgramInfos(Service::Interface* self) { | |||
|     rb.PushMappedBuffer(title_info_out, title_info_size, title_info_perms); | ||||
| } | ||||
| 
 | ||||
| void DeleteUserProgram(Service::Interface* self) { | ||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x000400, 3, 0); | ||||
|     auto media_type = rp.PopEnum<FS::MediaType>(); | ||||
|     u32 low = rp.Pop<u32>(); | ||||
|     u32 high = rp.Pop<u32>(); | ||||
|     u64 title_id = static_cast<u64>(low) | (static_cast<u64>(high) << 32); | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     u16 category = static_cast<u16>((title_id >> 32) & 0xFFFF); | ||||
|     u8 variation = static_cast<u8>(title_id & 0xFF); | ||||
|     if (category & CATEGORY_SYSTEM || category & CATEGORY_DLP || variation & VARIATION_SYSTEM) { | ||||
|         LOG_ERROR(Service_AM, "Trying to uninstall system app"); | ||||
|         rb.Push(ResultCode(ErrCodes::TryingToUninstallSystemApp, ErrorModule::AM, | ||||
|                            ErrorSummary::InvalidArgument, ErrorLevel::Usage)); | ||||
|         return; | ||||
|     } | ||||
|     LOG_INFO(Service_AM, "Deleting title 0x%016" PRIx64, title_id); | ||||
|     std::string path = GetTitlePath(media_type, title_id); | ||||
|     if (!FileUtil::Exists(path)) { | ||||
|         rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::AM, ErrorSummary::InvalidState, | ||||
|                            ErrorLevel::Permanent)); | ||||
|         LOG_ERROR(Service_AM, "Title not found"); | ||||
|         return; | ||||
|     } | ||||
|     bool success = FileUtil::DeleteDirRecursively(path); | ||||
|     ScanForAllTitles(); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     if (!success) | ||||
|         LOG_ERROR(Service_AM, "FileUtil::DeleteDirRecursively unexpectedly failed"); | ||||
| } | ||||
| 
 | ||||
| void GetDLCTitleInfos(Service::Interface* self) { | ||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x1005, 2, 4); // 0x10050084
 | ||||
| 
 | ||||
|  | @ -1156,6 +1186,28 @@ void GetRequiredSizeFromCia(Service::Interface* self) { | |||
|     rb.Push(container.GetTitleMetadata().GetContentSizeByIndex(FileSys::TMDContentIndex::Main)); | ||||
| } | ||||
| 
 | ||||
| void DeleteProgram(Service::Interface* self) { | ||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x0410, 3, 0); | ||||
|     auto media_type = rp.PopEnum<FS::MediaType>(); | ||||
|     u32 low = rp.Pop<u32>(); | ||||
|     u32 high = rp.Pop<u32>(); | ||||
|     u64 title_id = static_cast<u64>(low) | (static_cast<u64>(high) << 32); | ||||
|     LOG_INFO(Service_AM, "Deleting title 0x%016" PRIx64, title_id); | ||||
|     std::string path = GetTitlePath(media_type, title_id); | ||||
|     IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); | ||||
|     if (!FileUtil::Exists(path)) { | ||||
|         rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::AM, ErrorSummary::InvalidState, | ||||
|                            ErrorLevel::Permanent)); | ||||
|         LOG_ERROR(Service_AM, "Title not found"); | ||||
|         return; | ||||
|     } | ||||
|     bool success = FileUtil::DeleteDirRecursively(path); | ||||
|     ScanForAllTitles(); | ||||
|     rb.Push(RESULT_SUCCESS); | ||||
|     if (!success) | ||||
|         LOG_ERROR(Service_AM, "FileUtil::DeleteDirRecursively unexpectedly failed"); | ||||
| } | ||||
| 
 | ||||
| void GetMetaSizeFromCia(Service::Interface* self) { | ||||
|     IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x0413, 0, 2); // 0x04130002
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ enum { | |||
|     CIACurrentlyInstalling = 4, | ||||
|     InvalidTID = 31, | ||||
|     EmptyCIA = 32, | ||||
|     TryingToUninstallSystemApp = 44, | ||||
|     InvalidTIDInList = 60, | ||||
|     InvalidCIAHeader = 104, | ||||
| }; | ||||
|  | @ -226,6 +227,17 @@ void GetProgramList(Service::Interface* self); | |||
|  */ | ||||
| void GetProgramInfos(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * AM::DeleteUserProgram service function | ||||
|  * Deletes a user program | ||||
|  *  Inputs: | ||||
|  *      1 : Media Type | ||||
|  *      2-3 : Title ID | ||||
|  *  Outputs: | ||||
|  *      1 : Result, 0 on success, otherwise error code | ||||
|  */ | ||||
| void DeleteUserProgram(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * AM::GetDLCTitleInfos service function | ||||
|  * Wrapper for AM::GetProgramInfos, explicitly checks that TID high value is 0004008C. | ||||
|  | @ -439,6 +451,18 @@ void GetCoreVersionFromCia(Service::Interface* self); | |||
|  */ | ||||
| void GetRequiredSizeFromCia(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * AM::DeleteProgram service function | ||||
|  * Deletes a program | ||||
|  *  Inputs: | ||||
|  *      0 : Command header (0x041000C0) | ||||
|  *      1 : Media type | ||||
|  *      2-3 : Title ID | ||||
|  *  Outputs: | ||||
|  *      1 : Result, 0 on success, otherwise error code | ||||
|  */ | ||||
| void DeleteProgram(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * AM::GetMetaSizeFromCia service function | ||||
|  * Returns the size of a given CIA's meta section | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00010040, GetNumPrograms, "GetNumPrograms"}, | ||||
|     {0x00020082, GetProgramList, "GetProgramList"}, | ||||
|     {0x00030084, GetProgramInfos, "GetProgramInfos"}, | ||||
|     {0x000400C0, nullptr, "DeleteUserProgram"}, | ||||
|     {0x000400C0, DeleteUserProgram, "DeleteUserProgram"}, | ||||
|     {0x000500C0, nullptr, "GetProductCode"}, | ||||
|     {0x000600C0, nullptr, "GetStorageId"}, | ||||
|     {0x00070080, DeleteTicket, "DeleteTicket"}, | ||||
|  | @ -69,7 +69,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x040D0042, GetRequiredSizeFromCia, "GetRequiredSizeFromCia"}, | ||||
|     {0x040E00C2, nullptr, "CommitImportProgramsAndUpdateFirmwareAuto"}, | ||||
|     {0x040F0000, nullptr, "UpdateFirmwareAuto"}, | ||||
|     {0x041000C0, nullptr, "DeleteProgram"}, | ||||
|     {0x041000C0, DeleteProgram, "DeleteProgram"}, | ||||
|     {0x04110044, nullptr, "GetTwlProgramListForReboot"}, | ||||
|     {0x04120000, nullptr, "GetSystemUpdaterMutex"}, | ||||
|     {0x04130002, GetMetaSizeFromCia, "GetMetaSizeFromCia"}, | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00010040, GetNumPrograms, "GetNumPrograms"}, | ||||
|     {0x00020082, GetProgramList, "GetProgramList"}, | ||||
|     {0x00030084, GetProgramInfos, "GetProgramInfos"}, | ||||
|     {0x000400C0, nullptr, "DeleteUserProgram"}, | ||||
|     {0x000400C0, DeleteUserProgram, "DeleteUserProgram"}, | ||||
|     {0x000500C0, nullptr, "GetProductCode"}, | ||||
|     {0x000600C0, nullptr, "GetStorageId"}, | ||||
|     {0x00070080, DeleteTicket, "DeleteTicket"}, | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00010040, GetNumPrograms, "GetNumPrograms"}, | ||||
|     {0x00020082, GetProgramList, "GetProgramList"}, | ||||
|     {0x00030084, GetProgramInfos, "GetProgramInfos"}, | ||||
|     {0x000400C0, nullptr, "DeleteUserProgram"}, | ||||
|     {0x000400C0, DeleteUserProgram, "DeleteUserProgram"}, | ||||
|     {0x000500C0, nullptr, "GetProductCode"}, | ||||
|     {0x000600C0, nullptr, "GetStorageId"}, | ||||
|     {0x00070080, DeleteTicket, "DeleteTicket"}, | ||||
|  | @ -69,7 +69,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x040D0042, GetRequiredSizeFromCia, "GetRequiredSizeFromCia"}, | ||||
|     {0x040E00C2, nullptr, "CommitImportProgramsAndUpdateFirmwareAuto"}, | ||||
|     {0x040F0000, nullptr, "UpdateFirmwareAuto"}, | ||||
|     {0x041000C0, nullptr, "DeleteProgram"}, | ||||
|     {0x041000C0, DeleteProgram, "DeleteProgram"}, | ||||
|     {0x04110044, nullptr, "GetTwlProgramListForReboot"}, | ||||
|     {0x04120000, nullptr, "GetSystemUpdaterMutex"}, | ||||
|     {0x04130002, GetMetaSizeFromCia, "GetMetaSizeFromCia"}, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue