mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-30 18:24:15 +01:00 
			
		
		
		
	fsp: Move ISaveDataInfoReader to a seperate file
This commit is contained in:
		
							parent
							
								
									c9ef2e26ca
								
							
						
					
					
						commit
						380475af32
					
				| @ -585,6 +585,8 @@ add_library(core STATIC | ||||
|     hle/service/filesystem/fsp/fs_i_file.h | ||||
|     hle/service/filesystem/fsp/fs_i_filesystem.cpp | ||||
|     hle/service/filesystem/fsp/fs_i_filesystem.h | ||||
|     hle/service/filesystem/fsp/fs_i_save_data_info_reader.cpp | ||||
|     hle/service/filesystem/fsp/fs_i_save_data_info_reader.h | ||||
|     hle/service/filesystem/fsp/fs_i_storage.cpp | ||||
|     hle/service/filesystem/fsp/fs_i_storage.h | ||||
|     hle/service/filesystem/fsp/fsp_ldr.cpp | ||||
|  | ||||
| @ -0,0 +1,162 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "common/hex_util.h" | ||||
| #include "core/file_sys/savedata_factory.h" | ||||
| #include "core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h" | ||||
| #include "core/hle/service/filesystem/save_data_controller.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| 
 | ||||
| namespace Service::FileSystem { | ||||
| 
 | ||||
| ISaveDataInfoReader::ISaveDataInfoReader(Core::System& system_, | ||||
|                                          std::shared_ptr<SaveDataController> save_data_controller_, | ||||
|                                          FileSys::SaveDataSpaceId space) | ||||
|     : ServiceFramework{system_, "ISaveDataInfoReader"}, | ||||
|       save_data_controller{save_data_controller_} { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"}, | ||||
|     }; | ||||
|     RegisterHandlers(functions); | ||||
| 
 | ||||
|     FindAllSaves(space); | ||||
| } | ||||
| 
 | ||||
| ISaveDataInfoReader::~ISaveDataInfoReader() = default; | ||||
| 
 | ||||
| static u64 stoull_be(std::string_view str) { | ||||
|     if (str.size() != 16) { | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     const auto bytes = Common::HexStringToArray<0x8>(str); | ||||
|     u64 out{}; | ||||
|     std::memcpy(&out, bytes.data(), sizeof(u64)); | ||||
| 
 | ||||
|     return Common::swap64(out); | ||||
| } | ||||
| 
 | ||||
| void ISaveDataInfoReader::ReadSaveDataInfo(HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_FS, "called"); | ||||
| 
 | ||||
|     // Calculate how many entries we can fit in the output buffer
 | ||||
|     const u64 count_entries = ctx.GetWriteBufferNumElements<SaveDataInfo>(); | ||||
| 
 | ||||
|     // Cap at total number of entries.
 | ||||
|     const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index); | ||||
| 
 | ||||
|     // Determine data start and end
 | ||||
|     const auto* begin = reinterpret_cast<u8*>(info.data() + next_entry_index); | ||||
|     const auto* end = reinterpret_cast<u8*>(info.data() + next_entry_index + actual_entries); | ||||
|     const auto range_size = static_cast<std::size_t>(std::distance(begin, end)); | ||||
| 
 | ||||
|     next_entry_index += actual_entries; | ||||
| 
 | ||||
|     // Write the data to memory
 | ||||
|     ctx.WriteBuffer(begin, range_size); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 4}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push<u64>(actual_entries); | ||||
| } | ||||
| 
 | ||||
| void ISaveDataInfoReader::FindAllSaves(FileSys::SaveDataSpaceId space) { | ||||
|     FileSys::VirtualDir save_root{}; | ||||
|     const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space); | ||||
| 
 | ||||
|     if (result != ResultSuccess || save_root == nullptr) { | ||||
|         LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     for (const auto& type : save_root->GetSubdirectories()) { | ||||
|         if (type->GetName() == "save") { | ||||
|             FindNormalSaves(space, type); | ||||
|         } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { | ||||
|             FindTemporaryStorageSaves(space, type); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ISaveDataInfoReader::FindNormalSaves(FileSys::SaveDataSpaceId space, | ||||
|                                           const FileSys::VirtualDir& type) { | ||||
|     for (const auto& save_id : type->GetSubdirectories()) { | ||||
|         for (const auto& user_id : save_id->GetSubdirectories()) { | ||||
|             // Skip non user id subdirectories
 | ||||
|             if (user_id->GetName().size() != 0x20) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             const auto save_id_numeric = stoull_be(save_id->GetName()); | ||||
|             auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); | ||||
|             std::reverse(user_id_numeric.begin(), user_id_numeric.end()); | ||||
| 
 | ||||
|             if (save_id_numeric != 0) { | ||||
|                 // System Save Data
 | ||||
|                 info.emplace_back(SaveDataInfo{ | ||||
|                     0, | ||||
|                     space, | ||||
|                     FileSys::SaveDataType::SystemSaveData, | ||||
|                     {}, | ||||
|                     user_id_numeric, | ||||
|                     save_id_numeric, | ||||
|                     0, | ||||
|                     user_id->GetSize(), | ||||
|                     {}, | ||||
|                     {}, | ||||
|                 }); | ||||
| 
 | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             for (const auto& title_id : user_id->GetSubdirectories()) { | ||||
|                 const auto device = std::all_of(user_id_numeric.begin(), user_id_numeric.end(), | ||||
|                                                 [](u8 val) { return val == 0; }); | ||||
|                 info.emplace_back(SaveDataInfo{ | ||||
|                     0, | ||||
|                     space, | ||||
|                     device ? FileSys::SaveDataType::DeviceSaveData | ||||
|                            : FileSys::SaveDataType::SaveData, | ||||
|                     {}, | ||||
|                     user_id_numeric, | ||||
|                     save_id_numeric, | ||||
|                     stoull_be(title_id->GetName()), | ||||
|                     title_id->GetSize(), | ||||
|                     {}, | ||||
|                     {}, | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ISaveDataInfoReader::FindTemporaryStorageSaves(FileSys::SaveDataSpaceId space, | ||||
|                                                     const FileSys::VirtualDir& type) { | ||||
|     for (const auto& user_id : type->GetSubdirectories()) { | ||||
|         // Skip non user id subdirectories
 | ||||
|         if (user_id->GetName().size() != 0x20) { | ||||
|             continue; | ||||
|         } | ||||
|         for (const auto& title_id : user_id->GetSubdirectories()) { | ||||
|             if (!title_id->GetFiles().empty() || !title_id->GetSubdirectories().empty()) { | ||||
|                 auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); | ||||
|                 std::reverse(user_id_numeric.begin(), user_id_numeric.end()); | ||||
| 
 | ||||
|                 info.emplace_back(SaveDataInfo{ | ||||
|                     0, | ||||
|                     space, | ||||
|                     FileSys::SaveDataType::TemporaryStorage, | ||||
|                     {}, | ||||
|                     user_id_numeric, | ||||
|                     stoull_be(type->GetName()), | ||||
|                     stoull_be(title_id->GetName()), | ||||
|                     title_id->GetSize(), | ||||
|                     {}, | ||||
|                     {}, | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::FileSystem
 | ||||
| @ -0,0 +1,48 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/service/service.h" | ||||
| 
 | ||||
| namespace Service::FileSystem { | ||||
| 
 | ||||
| class SaveDataController; | ||||
| 
 | ||||
| class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> { | ||||
| public: | ||||
|     explicit ISaveDataInfoReader(Core::System& system_, | ||||
|                                  std::shared_ptr<SaveDataController> save_data_controller_, | ||||
|                                  FileSys::SaveDataSpaceId space); | ||||
|     ~ISaveDataInfoReader() override; | ||||
| 
 | ||||
|     void ReadSaveDataInfo(HLERequestContext& ctx); | ||||
| 
 | ||||
| private: | ||||
|     void FindAllSaves(FileSys::SaveDataSpaceId space); | ||||
|     void FindNormalSaves(FileSys::SaveDataSpaceId space, const FileSys::VirtualDir& type); | ||||
|     void FindTemporaryStorageSaves(FileSys::SaveDataSpaceId space, const FileSys::VirtualDir& type); | ||||
| 
 | ||||
|     struct SaveDataInfo { | ||||
|         u64_le save_id_unknown; | ||||
|         FileSys::SaveDataSpaceId space; | ||||
|         FileSys::SaveDataType type; | ||||
|         INSERT_PADDING_BYTES_NOINIT(0x6); | ||||
|         std::array<u8, 0x10> user_id; | ||||
|         u64_le save_id; | ||||
|         u64_le title_id; | ||||
|         u64_le save_image_size; | ||||
|         u16_le index; | ||||
|         FileSys::SaveDataRank rank; | ||||
|         INSERT_PADDING_BYTES_NOINIT(0x25); | ||||
|     }; | ||||
|     static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size."); | ||||
| 
 | ||||
|     std::shared_ptr<SaveDataController> save_data_controller; | ||||
|     std::vector<SaveDataInfo> info; | ||||
|     u64 next_entry_index = 0; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::FileSystem
 | ||||
| @ -29,6 +29,7 @@ | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/filesystem/filesystem.h" | ||||
| #include "core/hle/service/filesystem/fsp/fs_i_filesystem.h" | ||||
| #include "core/hle/service/filesystem/fsp/fs_i_save_data_info_reader.h" | ||||
| #include "core/hle/service/filesystem/fsp/fs_i_storage.h" | ||||
| #include "core/hle/service/filesystem/fsp/fsp_srv.h" | ||||
| #include "core/hle/service/filesystem/romfs_controller.h" | ||||
| @ -39,6 +40,7 @@ | ||||
| #include "core/reporter.h" | ||||
| 
 | ||||
| namespace Service::FileSystem { | ||||
| 
 | ||||
| enum class FileSystemProxyType : u8 { | ||||
|     Code = 0, | ||||
|     Rom = 1, | ||||
| @ -51,171 +53,6 @@ enum class FileSystemProxyType : u8 { | ||||
|     RegisteredUpdate = 8, | ||||
| }; | ||||
| 
 | ||||
| class ISaveDataInfoReader final : public ServiceFramework<ISaveDataInfoReader> { | ||||
| public: | ||||
|     explicit ISaveDataInfoReader(Core::System& system_, | ||||
|                                  std::shared_ptr<SaveDataController> save_data_controller_, | ||||
|                                  FileSys::SaveDataSpaceId space) | ||||
|         : ServiceFramework{system_, "ISaveDataInfoReader"}, save_data_controller{ | ||||
|                                                                 save_data_controller_} { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &ISaveDataInfoReader::ReadSaveDataInfo, "ReadSaveDataInfo"}, | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
| 
 | ||||
|         FindAllSaves(space); | ||||
|     } | ||||
| 
 | ||||
|     void ReadSaveDataInfo(HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_FS, "called"); | ||||
| 
 | ||||
|         // Calculate how many entries we can fit in the output buffer
 | ||||
|         const u64 count_entries = ctx.GetWriteBufferNumElements<SaveDataInfo>(); | ||||
| 
 | ||||
|         // Cap at total number of entries.
 | ||||
|         const u64 actual_entries = std::min(count_entries, info.size() - next_entry_index); | ||||
| 
 | ||||
|         // Determine data start and end
 | ||||
|         const auto* begin = reinterpret_cast<u8*>(info.data() + next_entry_index); | ||||
|         const auto* end = reinterpret_cast<u8*>(info.data() + next_entry_index + actual_entries); | ||||
|         const auto range_size = static_cast<std::size_t>(std::distance(begin, end)); | ||||
| 
 | ||||
|         next_entry_index += actual_entries; | ||||
| 
 | ||||
|         // Write the data to memory
 | ||||
|         ctx.WriteBuffer(begin, range_size); | ||||
| 
 | ||||
|         IPC::ResponseBuilder rb{ctx, 4}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.Push<u64>(actual_entries); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     static u64 stoull_be(std::string_view str) { | ||||
|         if (str.size() != 16) | ||||
|             return 0; | ||||
| 
 | ||||
|         const auto bytes = Common::HexStringToArray<0x8>(str); | ||||
|         u64 out{}; | ||||
|         std::memcpy(&out, bytes.data(), sizeof(u64)); | ||||
| 
 | ||||
|         return Common::swap64(out); | ||||
|     } | ||||
| 
 | ||||
|     void FindAllSaves(FileSys::SaveDataSpaceId space) { | ||||
|         FileSys::VirtualDir save_root{}; | ||||
|         const auto result = save_data_controller->OpenSaveDataSpace(&save_root, space); | ||||
| 
 | ||||
|         if (result != ResultSuccess || save_root == nullptr) { | ||||
|             LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         for (const auto& type : save_root->GetSubdirectories()) { | ||||
|             if (type->GetName() == "save") { | ||||
|                 for (const auto& save_id : type->GetSubdirectories()) { | ||||
|                     for (const auto& user_id : save_id->GetSubdirectories()) { | ||||
|                         // Skip non user id subdirectories
 | ||||
|                         if (user_id->GetName().size() != 0x20) { | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         const auto save_id_numeric = stoull_be(save_id->GetName()); | ||||
|                         auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); | ||||
|                         std::reverse(user_id_numeric.begin(), user_id_numeric.end()); | ||||
| 
 | ||||
|                         if (save_id_numeric != 0) { | ||||
|                             // System Save Data
 | ||||
|                             info.emplace_back(SaveDataInfo{ | ||||
|                                 0, | ||||
|                                 space, | ||||
|                                 FileSys::SaveDataType::SystemSaveData, | ||||
|                                 {}, | ||||
|                                 user_id_numeric, | ||||
|                                 save_id_numeric, | ||||
|                                 0, | ||||
|                                 user_id->GetSize(), | ||||
|                                 {}, | ||||
|                                 {}, | ||||
|                             }); | ||||
| 
 | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         for (const auto& title_id : user_id->GetSubdirectories()) { | ||||
|                             const auto device = | ||||
|                                 std::all_of(user_id_numeric.begin(), user_id_numeric.end(), | ||||
|                                             [](u8 val) { return val == 0; }); | ||||
|                             info.emplace_back(SaveDataInfo{ | ||||
|                                 0, | ||||
|                                 space, | ||||
|                                 device ? FileSys::SaveDataType::DeviceSaveData | ||||
|                                        : FileSys::SaveDataType::SaveData, | ||||
|                                 {}, | ||||
|                                 user_id_numeric, | ||||
|                                 save_id_numeric, | ||||
|                                 stoull_be(title_id->GetName()), | ||||
|                                 title_id->GetSize(), | ||||
|                                 {}, | ||||
|                                 {}, | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { | ||||
|                 // Temporary Storage
 | ||||
|                 for (const auto& user_id : type->GetSubdirectories()) { | ||||
|                     // Skip non user id subdirectories
 | ||||
|                     if (user_id->GetName().size() != 0x20) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     for (const auto& title_id : user_id->GetSubdirectories()) { | ||||
|                         if (!title_id->GetFiles().empty() || | ||||
|                             !title_id->GetSubdirectories().empty()) { | ||||
|                             auto user_id_numeric = | ||||
|                                 Common::HexStringToArray<0x10>(user_id->GetName()); | ||||
|                             std::reverse(user_id_numeric.begin(), user_id_numeric.end()); | ||||
| 
 | ||||
|                             info.emplace_back(SaveDataInfo{ | ||||
|                                 0, | ||||
|                                 space, | ||||
|                                 FileSys::SaveDataType::TemporaryStorage, | ||||
|                                 {}, | ||||
|                                 user_id_numeric, | ||||
|                                 stoull_be(type->GetName()), | ||||
|                                 stoull_be(title_id->GetName()), | ||||
|                                 title_id->GetSize(), | ||||
|                                 {}, | ||||
|                                 {}, | ||||
|                             }); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     struct SaveDataInfo { | ||||
|         u64_le save_id_unknown; | ||||
|         FileSys::SaveDataSpaceId space; | ||||
|         FileSys::SaveDataType type; | ||||
|         INSERT_PADDING_BYTES(0x6); | ||||
|         std::array<u8, 0x10> user_id; | ||||
|         u64_le save_id; | ||||
|         u64_le title_id; | ||||
|         u64_le save_image_size; | ||||
|         u16_le index; | ||||
|         FileSys::SaveDataRank rank; | ||||
|         INSERT_PADDING_BYTES(0x25); | ||||
|     }; | ||||
|     static_assert(sizeof(SaveDataInfo) == 0x60, "SaveDataInfo has incorrect size."); | ||||
| 
 | ||||
|     ProcessId process_id = 0; | ||||
|     std::shared_ptr<SaveDataController> save_data_controller; | ||||
|     std::vector<SaveDataInfo> info; | ||||
|     u64 next_entry_index = 0; | ||||
| }; | ||||
| 
 | ||||
| FSP_SRV::FSP_SRV(Core::System& system_) | ||||
|     : ServiceFramework{system_, "fsp-srv"}, fsc{system.GetFileSystemController()}, | ||||
|       content_provider{system.GetContentProvider()}, reporter{system.GetReporter()} { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user