mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	service/cecd: Add MBox directory check to OpenAndRead and OpenAndWrite and added a CreateAndPopulateMBoxDirectory function
This commit is contained in:
		
							parent
							
								
									30bbea3f4e
								
							
						
					
					
						commit
						d99585aa53
					
				
					 2 changed files with 171 additions and 15 deletions
				
			
		|  | @ -400,6 +400,18 @@ void Module::Interface::OpenAndWrite(Kernel::HLERequestContext& ctx) { | ||||||
|             rb.Push(RESULT_SUCCESS); |             rb.Push(RESULT_SUCCESS); | ||||||
|         } else { |         } else { | ||||||
|             LOG_ERROR(Service_CECD, "Failed to open file: {}", path.AsString()); |             LOG_ERROR(Service_CECD, "Failed to open file: {}", path.AsString()); | ||||||
|  | 
 | ||||||
|  |             /// We need to check if the MBox /CEC/<id> directory even exists...
 | ||||||
|  |             /// If it doesn't, we create and populate it.
 | ||||||
|  |             const FileSys::Path mbox_path( | ||||||
|  |                 cecd->GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_MBOX_DIR, | ||||||
|  |                                                  ncch_program_id) | ||||||
|  |                     .data()); | ||||||
|  |             auto mbox_result = Service::FS::OpenDirectoryFromArchive( | ||||||
|  |                 cecd->cecd_system_save_data_archive, mbox_path); | ||||||
|  |             if (mbox_result.Failed()) | ||||||
|  |                 cecd->CreateAndPopulateMBoxDirectory(ncch_program_id); | ||||||
|  | 
 | ||||||
|             rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::CEC, ErrorSummary::NotFound, |             rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::CEC, ErrorSummary::NotFound, | ||||||
|                                ErrorLevel::Status)); |                                ErrorLevel::Status)); | ||||||
|         } |         } | ||||||
|  | @ -453,22 +465,19 @@ void Module::Interface::OpenAndRead(Kernel::HLERequestContext& ctx) { | ||||||
|         } else { |         } else { | ||||||
|             LOG_ERROR(Service_CECD, "Failed to open file: {}", path.AsString()); |             LOG_ERROR(Service_CECD, "Failed to open file: {}", path.AsString()); | ||||||
| 
 | 
 | ||||||
|             if (path_type == CecDataPathType::CEC_PATH_MBOX_INFO) { |             /// We need to check if the MBox /CEC/<id> directory even exists...
 | ||||||
|                 const FileSys::Path root_dir_path( |             /// If it doesn't, we create and populate it.
 | ||||||
|                     cecd->GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_ROOT_DIR, |  | ||||||
|                                                      ncch_program_id) |  | ||||||
|                         .data()); |  | ||||||
|             const FileSys::Path mbox_path( |             const FileSys::Path mbox_path( | ||||||
|                 cecd->GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_MBOX_DIR, |                 cecd->GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_MBOX_DIR, | ||||||
|                                                  ncch_program_id) |                                                  ncch_program_id) | ||||||
|                     .data()); |                     .data()); | ||||||
|  |             auto mbox_result = Service::FS::OpenDirectoryFromArchive( | ||||||
|  |                 cecd->cecd_system_save_data_archive, mbox_path); | ||||||
|  |             if (mbox_result.Failed()) | ||||||
|  |                 cecd->CreateAndPopulateMBoxDirectory(ncch_program_id); | ||||||
| 
 | 
 | ||||||
|                 /// Just in case the root dir /CEC doesn't exist, we try to create it first
 |             /// Since the directories/files didn't exist before, we still push a failure
 | ||||||
|                 Service::FS::CreateDirectoryFromArchive(cecd->cecd_system_save_data_archive, |             /// A second attempt will then be called, and now everything exists.
 | ||||||
|                                                         root_dir_path); |  | ||||||
|                 Service::FS::CreateDirectoryFromArchive(cecd->cecd_system_save_data_archive, |  | ||||||
|                                                         mbox_path); |  | ||||||
|             } |  | ||||||
|             rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::CEC, ErrorSummary::NotFound, |             rb.Push(ResultCode(ErrorDescription::NoData, ErrorModule::CEC, ErrorSummary::NotFound, | ||||||
|                                ErrorLevel::Status)); |                                ErrorLevel::Status)); | ||||||
|             rb.Push<u32>(0); /// No bytes read
 |             rb.Push<u32>(0); /// No bytes read
 | ||||||
|  | @ -544,6 +553,151 @@ std::string Module::GetCecDataPathTypeAsString(const CecDataPathType type, const | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Module::CreateAndPopulateMBoxDirectory(const u32 ncch_program_id) { | ||||||
|  |     const FileSys::Path root_dir_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_ROOT_DIR, ncch_program_id).data()); | ||||||
|  |     const FileSys::Path mbox_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_MBOX_DIR, ncch_program_id).data()); | ||||||
|  |     const FileSys::Path inbox_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_INBOX_DIR, ncch_program_id).data()); | ||||||
|  |     const FileSys::Path outbox_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_OUTBOX_DIR, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     /// Just in case the root dir /CEC doesn't exist, we try to create it first
 | ||||||
|  |     Service::FS::CreateDirectoryFromArchive(cecd_system_save_data_archive, root_dir_path); | ||||||
|  |     Service::FS::CreateDirectoryFromArchive(cecd_system_save_data_archive, mbox_path); | ||||||
|  |     Service::FS::CreateDirectoryFromArchive(cecd_system_save_data_archive, inbox_path); | ||||||
|  |     Service::FS::CreateDirectoryFromArchive(cecd_system_save_data_archive, outbox_path); | ||||||
|  | 
 | ||||||
|  |     /// Now that the directories have been created, we can create the required files
 | ||||||
|  |     FileSys::Mode mode; | ||||||
|  |     mode.write_flag.Assign(1); | ||||||
|  |     mode.create_flag.Assign(1); | ||||||
|  | 
 | ||||||
|  |     /// MBoxInfo____ resides in the MBox /CEC/<id> directory,
 | ||||||
|  |     /// The Magic number is 0x6363 'cc', and has size 0x60
 | ||||||
|  |     FileSys::Path mbox_info_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_MBOX_INFO, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto mbox_info_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, mbox_info_path, mode); | ||||||
|  | 
 | ||||||
|  |     constexpr u32 mbox_info_size = 0x60; | ||||||
|  |     auto mbox_info = mbox_info_result.Unwrap(); | ||||||
|  |     std::vector<u8> mbox_info_buffer(mbox_info_size); | ||||||
|  | 
 | ||||||
|  |     std::memset(&mbox_info_buffer[0], 0, mbox_info_size); | ||||||
|  |     mbox_info_buffer[0] = 0x63; | ||||||
|  |     mbox_info_buffer[1] = 0x63; | ||||||
|  | 
 | ||||||
|  |     mbox_info->backend->Write(0, mbox_info_size, true, mbox_info_buffer.data()); | ||||||
|  |     mbox_info->backend->Close(); | ||||||
|  | 
 | ||||||
|  |     /// BoxInfo_____ resides in both the InBox and OutBox directories,
 | ||||||
|  |     /// The Magic number is 0x6262 'bb', and has size 0x20
 | ||||||
|  |     FileSys::Path inbox_info_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_INBOX_INFO, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto inbox_info_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, inbox_info_path, mode); | ||||||
|  | 
 | ||||||
|  |     constexpr u32 inbox_info_size = 0x20; | ||||||
|  |     auto inbox_info = inbox_info_result.Unwrap(); | ||||||
|  |     std::vector<u8> inbox_info_buffer(inbox_info_size); | ||||||
|  | 
 | ||||||
|  |     std::memset(&inbox_info_buffer[0], 0, inbox_info_size); | ||||||
|  |     inbox_info_buffer[0] = 0x62; | ||||||
|  |     inbox_info_buffer[1] = 0x62; | ||||||
|  | 
 | ||||||
|  |     inbox_info->backend->Write(0, inbox_info_size, true, inbox_info_buffer.data()); | ||||||
|  |     inbox_info->backend->Close(); | ||||||
|  | 
 | ||||||
|  |     /// BoxInfo_____ resides in both the InBox and OutBox directories,
 | ||||||
|  |     /// The Magic number is 0x6262 'bb', and has size 0x20-byte header, and an array of 0x70-byte
 | ||||||
|  |     /// entries. Each entry is a copy of the message header.
 | ||||||
|  |     FileSys::Path outbox_info_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_OUTBOX_INFO, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto outbox_info_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, outbox_info_path, mode); | ||||||
|  | 
 | ||||||
|  |     constexpr u32 outbox_info_size = 0x20; | ||||||
|  |     auto outbox_info = outbox_info_result.Unwrap(); | ||||||
|  |     std::vector<u8> outbox_info_buffer(outbox_info_size); | ||||||
|  | 
 | ||||||
|  |     std::memset(&outbox_info_buffer[0], 0, outbox_info_size); | ||||||
|  |     outbox_info_buffer[0] = 0x62; | ||||||
|  |     outbox_info_buffer[1] = 0x62; | ||||||
|  | 
 | ||||||
|  |     outbox_info->backend->Write(0, outbox_info_size, true, outbox_info_buffer.data()); | ||||||
|  |     outbox_info->backend->Close(); | ||||||
|  | 
 | ||||||
|  |     /// OBIndex_____ resides in the OutBox directory,
 | ||||||
|  |     /// Unknown...
 | ||||||
|  |     FileSys::Path outbox_index_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_PATH_OUTBOX_INDEX, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto outbox_index_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, outbox_index_path, mode); | ||||||
|  | 
 | ||||||
|  |     constexpr u32 outbox_index_size = 0x32; | ||||||
|  |     auto outbox_index = outbox_index_result.Unwrap(); | ||||||
|  |     std::vector<u8> outbox_index_buffer(outbox_index_size); | ||||||
|  | 
 | ||||||
|  |     std::memset(&outbox_index_buffer[0], 0, outbox_index_size); | ||||||
|  | 
 | ||||||
|  |     outbox_index->backend->Write(0, outbox_index_size, true, outbox_index_buffer.data()); | ||||||
|  |     outbox_index->backend->Close(); | ||||||
|  | 
 | ||||||
|  |     /// MBoxData.001 resides in the MBox /CEC/<id> directory and contains the icon of the app
 | ||||||
|  |     FileSys::Path mbox_icon_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_MBOX_ICON, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto mbox_icon_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, mbox_icon_path, mode); | ||||||
|  | 
 | ||||||
|  |     constexpr u32 mbox_icon_size = 0x1200; | ||||||
|  |     auto mbox_icon = mbox_icon_result.Unwrap(); | ||||||
|  |     std::vector<u8> mbox_icon_buffer(mbox_icon_size); | ||||||
|  | 
 | ||||||
|  |     std::memset(&mbox_icon_buffer[0], 0, mbox_icon_size); | ||||||
|  | 
 | ||||||
|  |     mbox_icon->backend->Write(0, mbox_icon_size, true, mbox_icon_buffer.data()); | ||||||
|  |     mbox_icon->backend->Close(); | ||||||
|  | 
 | ||||||
|  |     /// MBoxData.010 resides in the MBox /CEC/<id> directory and contains the title of the app
 | ||||||
|  |     /// in null-terminated UTF-16 string.
 | ||||||
|  |     FileSys::Path mbox_title_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_MBOX_TITLE, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto mbox_title_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, mbox_title_path, mode); | ||||||
|  | 
 | ||||||
|  |     constexpr u32 mbox_title_size = 0x32; | ||||||
|  |     auto mbox_title = mbox_title_result.Unwrap(); | ||||||
|  |     std::vector<u8> mbox_title_buffer(mbox_title_size); | ||||||
|  | 
 | ||||||
|  |     std::memset(&mbox_title_buffer[0], 0, mbox_title_size); | ||||||
|  | 
 | ||||||
|  |     mbox_title->backend->Write(0, mbox_title_size, true, mbox_title_buffer.data()); | ||||||
|  |     mbox_title->backend->Close(); | ||||||
|  | 
 | ||||||
|  |     /// MBoxData.050 resides in the MBox /CEC/<id> directory and contains the program id of the app
 | ||||||
|  |     FileSys::Path mbox_program_id_path( | ||||||
|  |         GetCecDataPathTypeAsString(CecDataPathType::CEC_MBOX_PROGRAM_ID, ncch_program_id).data()); | ||||||
|  | 
 | ||||||
|  |     auto mbox_program_id_result = | ||||||
|  |         Service::FS::OpenFileFromArchive(cecd_system_save_data_archive, mbox_program_id_path, mode); | ||||||
|  |     auto mbox_program_id = mbox_program_id_result.Unwrap(); | ||||||
|  | 
 | ||||||
|  |     std::vector<u8> program_id_buffer(8); | ||||||
|  |     u64_le le_program_id = Kernel::g_current_process->codeset->program_id; | ||||||
|  |     std::memcpy(program_id_buffer.data(), &le_program_id, sizeof(u64)); | ||||||
|  | 
 | ||||||
|  |     mbox_program_id->backend->Write(0, sizeof(u64), true, program_id_buffer.data()); | ||||||
|  |     mbox_program_id->backend->Close(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Module::SessionData::SessionData() {} | Module::SessionData::SessionData() {} | ||||||
| 
 | 
 | ||||||
| Module::SessionData::~SessionData() { | Module::SessionData::~SessionData() { | ||||||
|  |  | ||||||
|  | @ -534,6 +534,8 @@ private: | ||||||
|     std::string GetCecDataPathTypeAsString(const CecDataPathType type, const u32 program_id, |     std::string GetCecDataPathTypeAsString(const CecDataPathType type, const u32 program_id, | ||||||
|                                            const std::vector<u8>& msg_id = std::vector<u8>()) const; |                                            const std::vector<u8>& msg_id = std::vector<u8>()) const; | ||||||
| 
 | 
 | ||||||
|  |     void CreateAndPopulateMBoxDirectory(const u32 ncch_program_id); | ||||||
|  | 
 | ||||||
|     Service::FS::ArchiveHandle cecd_system_save_data_archive; |     Service::FS::ArchiveHandle cecd_system_save_data_archive; | ||||||
| 
 | 
 | ||||||
|     Kernel::SharedPtr<Kernel::Event> cecinfo_event; |     Kernel::SharedPtr<Kernel::Event> cecinfo_event; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue