service: nfc: Add backup support
This commit is contained in:
		| @@ -10,6 +10,7 @@ | ||||
|  | ||||
| // Sub-directories contained within a yuzu data directory | ||||
|  | ||||
| #define AMIIBO_DIR "amiibo" | ||||
| #define CACHE_DIR "cache" | ||||
| #define CONFIG_DIR "config" | ||||
| #define DUMP_DIR "dump" | ||||
|   | ||||
| @@ -114,6 +114,7 @@ public: | ||||
| #endif | ||||
|  | ||||
|         GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path); | ||||
|         GenerateYuzuPath(YuzuPath::AmiiboDir, yuzu_path / AMIIBO_DIR); | ||||
|         GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache); | ||||
|         GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config); | ||||
|         GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR); | ||||
|   | ||||
| @@ -12,6 +12,7 @@ namespace Common::FS { | ||||
|  | ||||
| enum class YuzuPath { | ||||
|     YuzuDir,        // Where yuzu stores its data. | ||||
|     AmiiboDir,      // Where Amiibo backups are stored. | ||||
|     CacheDir,       // Where cached filesystem data is stored. | ||||
|     ConfigDir,      // Where config files are stored. | ||||
|     DumpDir,        // Where dumped data is stored. | ||||
|   | ||||
| @@ -12,6 +12,11 @@ | ||||
| #pragma warning(pop) | ||||
| #endif | ||||
|  | ||||
| #include <fmt/format.h> | ||||
|  | ||||
| #include "common/fs/file.h" | ||||
| #include "common/fs/fs.h" | ||||
| #include "common/fs/path_util.h" | ||||
| #include "common/input.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/string_util.h" | ||||
| @@ -136,7 +141,7 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) { | ||||
|     if (!NFP::AmiiboCrypto::IsKeyAvailable()) { | ||||
|         LOG_INFO(Service_NFC, "Loading amiibo without keys"); | ||||
|         memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | ||||
|         BuildAmiiboWithoutKeys(); | ||||
|         BuildAmiiboWithoutKeys(tag_data, encrypted_tag_data); | ||||
|         is_plain_amiibo = true; | ||||
|         is_write_protected = true; | ||||
|         return true; | ||||
| @@ -366,16 +371,25 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target | ||||
|  | ||||
|     // The loaded amiibo is not encrypted | ||||
|     if (is_plain_amiibo) { | ||||
|         std::vector<u8> data(sizeof(NFP::NTAG215File)); | ||||
|         memcpy(data.data(), &tag_data, sizeof(tag_data)); | ||||
|         WriteBackupData(tag_data.uid, data); | ||||
|  | ||||
|         device_state = DeviceState::TagMounted; | ||||
|         mount_target = mount_target_; | ||||
|         return ResultSuccess; | ||||
|     } | ||||
|  | ||||
|     if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) { | ||||
|         LOG_ERROR(Service_NFP, "Can't decode amiibo {}", device_state); | ||||
|         return ResultCorruptedData; | ||||
|         bool has_backup = HasBackup(encrypted_tag_data.uuid.uid).IsSuccess(); | ||||
|         LOG_ERROR(Service_NFP, "Can't decode amiibo, has_backup= {}", has_backup); | ||||
|         return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData; | ||||
|     } | ||||
|  | ||||
|     std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); | ||||
|     memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); | ||||
|     WriteBackupData(encrypted_tag_data.uuid.uid, data); | ||||
|  | ||||
|     device_state = DeviceState::TagMounted; | ||||
|     mount_target = mount_target_; | ||||
|     return ResultSuccess; | ||||
| @@ -470,6 +484,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) { | ||||
|     std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); | ||||
|     if (is_plain_amiibo) { | ||||
|         memcpy(data.data(), &tag_data, sizeof(tag_data)); | ||||
|         WriteBackupData(tag_data.uid, data); | ||||
|     } else { | ||||
|         if (!NFP::AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) { | ||||
|             LOG_ERROR(Service_NFP, "Failed to encode data"); | ||||
| @@ -477,6 +492,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) { | ||||
|         } | ||||
|  | ||||
|         memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); | ||||
|         WriteBackupData(encrypted_tag_data.uuid.uid, data); | ||||
|     } | ||||
|  | ||||
|     if (!npad_device->WriteNfc(data)) { | ||||
| @@ -488,7 +504,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) { | ||||
| } | ||||
|  | ||||
| Result NfcDevice::Restore() { | ||||
|     if (device_state != DeviceState::TagMounted) { | ||||
|     if (device_state != DeviceState::TagFound) { | ||||
|         LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); | ||||
|         if (device_state == DeviceState::TagRemoved) { | ||||
|             return ResultTagRemoved; | ||||
| @@ -496,13 +512,59 @@ Result NfcDevice::Restore() { | ||||
|         return ResultWrongDeviceState; | ||||
|     } | ||||
|  | ||||
|     if (mount_target == NFP::MountTarget::None || mount_target == NFP::MountTarget::Rom) { | ||||
|         LOG_ERROR(Service_NFC, "Amiibo is read only", device_state); | ||||
|         return ResultWrongDeviceState; | ||||
|     NFC::TagInfo tag_info{}; | ||||
|     std::array<u8, sizeof(NFP::EncryptedNTAG215File)> data{}; | ||||
|     Result result = GetTagInfo(tag_info, false); | ||||
|  | ||||
|     if (result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     // TODO: Load amiibo from backup on system | ||||
|     LOG_ERROR(Service_NFP, "Not Implemented"); | ||||
|     result = ReadBackupData(tag_info.uuid, data); | ||||
|  | ||||
|     if (result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     NFP::NTAG215File temporary_tag_data{}; | ||||
|     NFP::EncryptedNTAG215File temporary_encrypted_tag_data{}; | ||||
|  | ||||
|     // Fallback for encrypted amiibos without keys | ||||
|     if (is_write_protected) { | ||||
|         return ResultWriteAmiiboFailed; | ||||
|     } | ||||
|  | ||||
|     // Fallback for plain amiibos | ||||
|     if (is_plain_amiibo) { | ||||
|         LOG_INFO(Service_NFP, "Restoring backup of plain amiibo"); | ||||
|         memcpy(&temporary_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | ||||
|         temporary_encrypted_tag_data = NFP::AmiiboCrypto::EncodedDataToNfcData(temporary_tag_data); | ||||
|     } | ||||
|  | ||||
|     if (!is_plain_amiibo) { | ||||
|         LOG_INFO(Service_NFP, "Restoring backup of encrypted amiibo"); | ||||
|         temporary_tag_data = {}; | ||||
|         memcpy(&temporary_encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File)); | ||||
|     } | ||||
|  | ||||
|     if (!NFP::AmiiboCrypto::IsAmiiboValid(temporary_encrypted_tag_data)) { | ||||
|         return ResultNotAnAmiibo; | ||||
|     } | ||||
|  | ||||
|     if (!is_plain_amiibo) { | ||||
|         if (!NFP::AmiiboCrypto::DecodeAmiibo(temporary_encrypted_tag_data, temporary_tag_data)) { | ||||
|             LOG_ERROR(Service_NFP, "Can't decode amiibo"); | ||||
|             return ResultCorruptedData; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Overwrite tag contents with backup and mount the tag | ||||
|     tag_data = temporary_tag_data; | ||||
|     encrypted_tag_data = temporary_encrypted_tag_data; | ||||
|     device_state = DeviceState::TagMounted; | ||||
|     mount_target = NFP::MountTarget::All; | ||||
|     is_data_moddified = true; | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| @@ -1132,13 +1194,69 @@ Result NfcDevice::BreakTag(NFP::BreakType break_type) { | ||||
|     return FlushWithBreak(break_type); | ||||
| } | ||||
|  | ||||
| Result NfcDevice::ReadBackupData(std::span<u8> data) const { | ||||
|     // Not implemented | ||||
| Result NfcDevice::HasBackup(const NFC::UniqueSerialNumber& uid) const { | ||||
|     constexpr auto backup_dir = "backup"; | ||||
|     const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir); | ||||
|     const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, "")); | ||||
|  | ||||
|     if (!Common::FS::Exists(yuzu_amiibo_dir / backup_dir / file_name)) { | ||||
|         return ResultUnableToAccessBackupFile; | ||||
|     } | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| Result NfcDevice::WriteBackupData(std::span<const u8> data) { | ||||
|     // Not implemented | ||||
| Result NfcDevice::ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const { | ||||
|     constexpr auto backup_dir = "backup"; | ||||
|     const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir); | ||||
|     const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, "")); | ||||
|  | ||||
|     const Common::FS::IOFile keys_file{yuzu_amiibo_dir / backup_dir / file_name, | ||||
|                                        Common::FS::FileAccessMode::Read, | ||||
|                                        Common::FS::FileType::BinaryFile}; | ||||
|  | ||||
|     if (!keys_file.IsOpen()) { | ||||
|         LOG_ERROR(Service_NFP, "Failed to open amiibo backup"); | ||||
|         return ResultUnableToAccessBackupFile; | ||||
|     } | ||||
|  | ||||
|     if (keys_file.Read(data) != data.size()) { | ||||
|         LOG_ERROR(Service_NFP, "Failed to read amiibo backup"); | ||||
|         return ResultUnableToAccessBackupFile; | ||||
|     } | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| Result NfcDevice::WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<const u8> data) { | ||||
|     constexpr auto backup_dir = "backup"; | ||||
|     const auto yuzu_amiibo_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::AmiiboDir); | ||||
|     const auto file_name = fmt::format("{0:02x}.bin", fmt::join(uid, "")); | ||||
|  | ||||
|     if (HasBackup(uid).IsError()) { | ||||
|         if (!Common::FS::CreateDir(yuzu_amiibo_dir / backup_dir)) { | ||||
|             return ResultBackupPathAlreadyExist; | ||||
|         } | ||||
|  | ||||
|         if (!Common::FS::NewFile(yuzu_amiibo_dir / backup_dir / file_name)) { | ||||
|             return ResultBackupPathAlreadyExist; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     const Common::FS::IOFile keys_file{yuzu_amiibo_dir / backup_dir / file_name, | ||||
|                                        Common::FS::FileAccessMode::ReadWrite, | ||||
|                                        Common::FS::FileType::BinaryFile}; | ||||
|  | ||||
|     if (!keys_file.IsOpen()) { | ||||
|         LOG_ERROR(Service_NFP, "Failed to open amiibo backup"); | ||||
|         return ResultUnableToAccessBackupFile; | ||||
|     } | ||||
|  | ||||
|     if (keys_file.Write(data) != data.size()) { | ||||
|         LOG_ERROR(Service_NFP, "Failed to write amiibo backup"); | ||||
|         return ResultUnableToAccessBackupFile; | ||||
|     } | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
|  | ||||
| @@ -1177,7 +1295,8 @@ NFP::AmiiboName NfcDevice::GetAmiiboName(const NFP::AmiiboSettings& settings) co | ||||
|     return amiibo_name; | ||||
| } | ||||
|  | ||||
| void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) { | ||||
| void NfcDevice::SetAmiiboName(NFP::AmiiboSettings& settings, | ||||
|                               const NFP::AmiiboName& amiibo_name) const { | ||||
|     std::array<char16_t, NFP::amiibo_name_length> settings_amiibo_name{}; | ||||
|  | ||||
|     // Convert from utf8 to utf16 | ||||
| @@ -1258,22 +1377,23 @@ void NfcDevice::UpdateRegisterInfoCrc() { | ||||
|     tag_data.register_info_crc = crc.checksum(); | ||||
| } | ||||
|  | ||||
| void NfcDevice::BuildAmiiboWithoutKeys() { | ||||
| void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, | ||||
|                                        const NFP::EncryptedNTAG215File& encrypted_file) const { | ||||
|     Service::Mii::MiiManager manager; | ||||
|     auto& settings = tag_data.settings; | ||||
|     auto& settings = stubbed_tag_data.settings; | ||||
|  | ||||
|     tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_tag_data); | ||||
|     stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file); | ||||
|  | ||||
|     // Common info | ||||
|     tag_data.write_counter = 0; | ||||
|     tag_data.amiibo_version = 0; | ||||
|     stubbed_tag_data.write_counter = 0; | ||||
|     stubbed_tag_data.amiibo_version = 0; | ||||
|     settings.write_date = GetAmiiboDate(GetCurrentPosixTime()); | ||||
|  | ||||
|     // Register info | ||||
|     SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); | ||||
|     settings.settings.font_region.Assign(0); | ||||
|     settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); | ||||
|     tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildDefault(0)); | ||||
|     stubbed_tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildDefault(0)); | ||||
|  | ||||
|     // Admin info | ||||
|     settings.settings.amiibo_initialized.Assign(1); | ||||
|   | ||||
| @@ -86,8 +86,9 @@ public: | ||||
|     Result GetAll(NFP::NfpData& data) const; | ||||
|     Result SetAll(const NFP::NfpData& data); | ||||
|     Result BreakTag(NFP::BreakType break_type); | ||||
|     Result ReadBackupData(std::span<u8> data) const; | ||||
|     Result WriteBackupData(std::span<const u8> data); | ||||
|     Result HasBackup(const NFC::UniqueSerialNumber& uid) const; | ||||
|     Result ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const; | ||||
|     Result WriteBackupData(const NFC::UniqueSerialNumber& uid, std::span<const u8> data); | ||||
|     Result WriteNtf(std::span<const u8> data); | ||||
|  | ||||
|     u64 GetHandle() const; | ||||
| @@ -103,14 +104,15 @@ private: | ||||
|     void CloseNfcTag(); | ||||
|  | ||||
|     NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; | ||||
|     void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name); | ||||
|     void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name) const; | ||||
|     NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const; | ||||
|     u64 GetCurrentPosixTime() const; | ||||
|     u64 RemoveVersionByte(u64 application_id) const; | ||||
|     void UpdateSettingsCrc(); | ||||
|     void UpdateRegisterInfoCrc(); | ||||
|  | ||||
|     void BuildAmiiboWithoutKeys(); | ||||
|     void BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, | ||||
|                                 const NFP::EncryptedNTAG215File& encrypted_file) const; | ||||
|  | ||||
|     bool is_controller_set{}; | ||||
|     int callback_key; | ||||
|   | ||||
| @@ -543,9 +543,14 @@ Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) cons | ||||
|  | ||||
|     std::shared_ptr<NfcDevice> device = nullptr; | ||||
|     auto result = GetDeviceHandle(device_handle, device); | ||||
|     NFC::TagInfo tag_info{}; | ||||
|  | ||||
|     if (result.IsSuccess()) { | ||||
|         result = device->ReadBackupData(data); | ||||
|         result = device->GetTagInfo(tag_info, false); | ||||
|     } | ||||
|  | ||||
|     if (result.IsSuccess()) { | ||||
|         result = device->ReadBackupData(tag_info.uuid, data); | ||||
|         result = VerifyDeviceResult(device, result); | ||||
|     } | ||||
|  | ||||
| @@ -557,9 +562,14 @@ Result DeviceManager::WriteBackupData(u64 device_handle, std::span<const u8> dat | ||||
|  | ||||
|     std::shared_ptr<NfcDevice> device = nullptr; | ||||
|     auto result = GetDeviceHandle(device_handle, device); | ||||
|     NFC::TagInfo tag_info{}; | ||||
|  | ||||
|     if (result.IsSuccess()) { | ||||
|         result = device->WriteBackupData(data); | ||||
|         result = device->GetTagInfo(tag_info, false); | ||||
|     } | ||||
|  | ||||
|     if (result.IsSuccess()) { | ||||
|         result = device->WriteBackupData(tag_info.uuid, data); | ||||
|         result = VerifyDeviceResult(device, result); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -302,7 +302,7 @@ Result NfcInterface::TranslateResultToServiceError(Result result) const { | ||||
|         return TranslateResultToNfp(result); | ||||
|     } | ||||
|     default: | ||||
|         if (result != ResultUnknown216) { | ||||
|         if (result != ResultBackupPathAlreadyExist) { | ||||
|             return result; | ||||
|         } | ||||
|         return ResultUnknown74; | ||||
| @@ -343,6 +343,9 @@ Result NfcInterface::TranslateResultToNfp(Result result) const { | ||||
|     if (result == ResultApplicationAreaIsNotInitialized) { | ||||
|         return NFP::ResultApplicationAreaIsNotInitialized; | ||||
|     } | ||||
|     if (result == ResultCorruptedDataWithBackup) { | ||||
|         return NFP::ResultCorruptedDataWithBackup; | ||||
|     } | ||||
|     if (result == ResultCorruptedData) { | ||||
|         return NFP::ResultCorruptedData; | ||||
|     } | ||||
| @@ -355,6 +358,9 @@ Result NfcInterface::TranslateResultToNfp(Result result) const { | ||||
|     if (result == ResultNotAnAmiibo) { | ||||
|         return NFP::ResultNotAnAmiibo; | ||||
|     } | ||||
|     if (result == ResultUnableToAccessBackupFile) { | ||||
|         return NFP::ResultUnableToAccessBackupFile; | ||||
|     } | ||||
|     LOG_WARNING(Service_NFC, "Result conversion not handled"); | ||||
|     return result; | ||||
| } | ||||
|   | ||||
| @@ -9,20 +9,22 @@ namespace Service::NFC { | ||||
|  | ||||
| constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64); | ||||
| constexpr Result ResultInvalidArgument(ErrorModule::NFC, 65); | ||||
| constexpr Result ResultWrongApplicationAreaSize(ErrorModule::NFP, 68); | ||||
| constexpr Result ResultWrongApplicationAreaSize(ErrorModule::NFC, 68); | ||||
| constexpr Result ResultWrongDeviceState(ErrorModule::NFC, 73); | ||||
| constexpr Result ResultUnknown74(ErrorModule::NFC, 74); | ||||
| constexpr Result ResultUnknown76(ErrorModule::NFC, 76); | ||||
| constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77); | ||||
| constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80); | ||||
| constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFP, 88); | ||||
| constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFC, 88); | ||||
| constexpr Result ResultTagRemoved(ErrorModule::NFC, 97); | ||||
| constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); | ||||
| constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); | ||||
| constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); | ||||
| constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); | ||||
| constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); | ||||
| constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); | ||||
| constexpr Result ResultUnknown216(ErrorModule::NFC, 216); | ||||
| constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113); | ||||
| constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120); | ||||
| constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128); | ||||
| constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136); | ||||
| constexpr Result ResultCorruptedData(ErrorModule::NFC, 144); | ||||
| constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFC, 152); | ||||
| constexpr Result ResultApplicationAreaExist(ErrorModule::NFC, 168); | ||||
| constexpr Result ResultNotAnAmiibo(ErrorModule::NFC, 178); | ||||
| constexpr Result ResultBackupPathAlreadyExist(ErrorModule::NFC, 216); | ||||
|  | ||||
| } // namespace Service::NFC | ||||
|   | ||||
| @@ -126,7 +126,7 @@ void Interface::Flush(HLERequestContext& ctx) { | ||||
| void Interface::Restore(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto device_handle{rp.Pop<u64>()}; | ||||
|     LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); | ||||
|     LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); | ||||
|  | ||||
|     auto result = GetManager()->Restore(device_handle); | ||||
|     result = TranslateResultToServiceError(result); | ||||
| @@ -394,7 +394,7 @@ void Interface::BreakTag(HLERequestContext& ctx) { | ||||
| void Interface::ReadBackupData(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto device_handle{rp.Pop<u64>()}; | ||||
|     LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); | ||||
|     LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); | ||||
|  | ||||
|     std::vector<u8> backup_data{}; | ||||
|     auto result = GetManager()->ReadBackupData(device_handle, backup_data); | ||||
| @@ -412,7 +412,7 @@ void Interface::WriteBackupData(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto device_handle{rp.Pop<u64>()}; | ||||
|     const auto backup_data_buffer{ctx.ReadBuffer()}; | ||||
|     LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle); | ||||
|     LOG_INFO(Service_NFP, "called, device_handle={}", device_handle); | ||||
|  | ||||
|     auto result = GetManager()->WriteBackupData(device_handle, backup_data_buffer); | ||||
|     result = TranslateResultToServiceError(result); | ||||
|   | ||||
| @@ -17,9 +17,11 @@ constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFP, 88); | ||||
| constexpr Result ResultTagRemoved(ErrorModule::NFP, 97); | ||||
| constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120); | ||||
| constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128); | ||||
| constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFP, 136); | ||||
| constexpr Result ResultCorruptedData(ErrorModule::NFP, 144); | ||||
| constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152); | ||||
| constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168); | ||||
| constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178); | ||||
| constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFP, 200); | ||||
|  | ||||
| } // namespace Service::NFP | ||||
|   | ||||
		Reference in New Issue
	
	Block a user