forked from etc/pineapple-src
early-access version 3646
This commit is contained in:
parent
80bec92d21
commit
b237675917
14 changed files with 194 additions and 47 deletions
|
@ -255,7 +255,7 @@ endif()
|
||||||
# boost asio's concept usage doesn't play nicely with some compilers yet.
|
# boost asio's concept usage doesn't play nicely with some compilers yet.
|
||||||
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
|
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/std:c++latest>)
|
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:/std:c++20>)
|
||||||
|
|
||||||
# boost still makes use of deprecated result_of.
|
# boost still makes use of deprecated result_of.
|
||||||
add_definitions(-D_HAS_DEPRECATED_RESULT_OF)
|
add_definitions(-D_HAS_DEPRECATED_RESULT_OF)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 3645.
|
This is the source code for early-access 3646.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ if (MSVC)
|
||||||
/Zo
|
/Zo
|
||||||
/permissive-
|
/permissive-
|
||||||
/EHsc
|
/EHsc
|
||||||
/std:c++latest
|
/std:c++20
|
||||||
/utf-8
|
/utf-8
|
||||||
/volatile:iso
|
/volatile:iso
|
||||||
/Zc:externConstexpr
|
/Zc:externConstexpr
|
||||||
|
@ -51,8 +51,10 @@ if (MSVC)
|
||||||
/Zc:throwingNew
|
/Zc:throwingNew
|
||||||
/GT
|
/GT
|
||||||
|
|
||||||
|
# Modules
|
||||||
|
/experimental:module- # Disable module support explicitly due to conflicts with precompiled headers
|
||||||
|
|
||||||
# External headers diagnostics
|
# External headers diagnostics
|
||||||
/experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later
|
|
||||||
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
|
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
|
||||||
/external:W0 # Sets the default warning level to 0 for external headers, effectively turning off warnings for external headers
|
/external:W0 # Sets the default warning level to 0 for external headers, effectively turning off warnings for external headers
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
// Sub-directories contained within a yuzu data directory
|
// Sub-directories contained within a yuzu data directory
|
||||||
|
|
||||||
|
#define AMIIBO_DIR "amiibo"
|
||||||
#define CACHE_DIR "cache"
|
#define CACHE_DIR "cache"
|
||||||
#define CONFIG_DIR "config"
|
#define CONFIG_DIR "config"
|
||||||
#define DUMP_DIR "dump"
|
#define DUMP_DIR "dump"
|
||||||
|
|
|
@ -114,6 +114,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
|
GenerateYuzuPath(YuzuPath::YuzuDir, yuzu_path);
|
||||||
|
GenerateYuzuPath(YuzuPath::AmiiboDir, yuzu_path / AMIIBO_DIR);
|
||||||
GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache);
|
GenerateYuzuPath(YuzuPath::CacheDir, yuzu_path_cache);
|
||||||
GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config);
|
GenerateYuzuPath(YuzuPath::ConfigDir, yuzu_path_config);
|
||||||
GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR);
|
GenerateYuzuPath(YuzuPath::DumpDir, yuzu_path / DUMP_DIR);
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Common::FS {
|
||||||
|
|
||||||
enum class YuzuPath {
|
enum class YuzuPath {
|
||||||
YuzuDir, // Where yuzu stores its data.
|
YuzuDir, // Where yuzu stores its data.
|
||||||
|
AmiiboDir, // Where Amiibo backups are stored.
|
||||||
CacheDir, // Where cached filesystem data is stored.
|
CacheDir, // Where cached filesystem data is stored.
|
||||||
ConfigDir, // Where config files are stored.
|
ConfigDir, // Where config files are stored.
|
||||||
DumpDir, // Where dumped data is stored.
|
DumpDir, // Where dumped data is stored.
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#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/input.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
@ -136,7 +141,7 @@ bool NfcDevice::LoadNfcTag(std::span<const u8> data) {
|
||||||
if (!NFP::AmiiboCrypto::IsKeyAvailable()) {
|
if (!NFP::AmiiboCrypto::IsKeyAvailable()) {
|
||||||
LOG_INFO(Service_NFC, "Loading amiibo without keys");
|
LOG_INFO(Service_NFC, "Loading amiibo without keys");
|
||||||
memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
|
memcpy(&encrypted_tag_data, data.data(), sizeof(NFP::EncryptedNTAG215File));
|
||||||
BuildAmiiboWithoutKeys();
|
BuildAmiiboWithoutKeys(tag_data, encrypted_tag_data);
|
||||||
is_plain_amiibo = true;
|
is_plain_amiibo = true;
|
||||||
is_write_protected = true;
|
is_write_protected = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -366,16 +371,25 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
|
||||||
|
|
||||||
// The loaded amiibo is not encrypted
|
// The loaded amiibo is not encrypted
|
||||||
if (is_plain_amiibo) {
|
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;
|
device_state = DeviceState::TagMounted;
|
||||||
mount_target = mount_target_;
|
mount_target = mount_target_;
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) {
|
if (!NFP::AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) {
|
||||||
LOG_ERROR(Service_NFP, "Can't decode amiibo {}", device_state);
|
bool has_backup = HasBackup(encrypted_tag_data.uuid.uid).IsSuccess();
|
||||||
return ResultCorruptedData;
|
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;
|
device_state = DeviceState::TagMounted;
|
||||||
mount_target = mount_target_;
|
mount_target = mount_target_;
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
@ -470,6 +484,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
|
||||||
std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
|
std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
|
||||||
if (is_plain_amiibo) {
|
if (is_plain_amiibo) {
|
||||||
memcpy(data.data(), &tag_data, sizeof(tag_data));
|
memcpy(data.data(), &tag_data, sizeof(tag_data));
|
||||||
|
WriteBackupData(tag_data.uid, data);
|
||||||
} else {
|
} else {
|
||||||
if (!NFP::AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
|
if (!NFP::AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
|
||||||
LOG_ERROR(Service_NFP, "Failed to encode 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));
|
memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
|
||||||
|
WriteBackupData(encrypted_tag_data.uuid.uid, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!npad_device->WriteNfc(data)) {
|
if (!npad_device->WriteNfc(data)) {
|
||||||
|
@ -488,7 +504,7 @@ Result NfcDevice::FlushWithBreak(NFP::BreakType break_type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result NfcDevice::Restore() {
|
Result NfcDevice::Restore() {
|
||||||
if (device_state != DeviceState::TagMounted) {
|
if (device_state != DeviceState::TagFound) {
|
||||||
LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
|
LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
|
||||||
if (device_state == DeviceState::TagRemoved) {
|
if (device_state == DeviceState::TagRemoved) {
|
||||||
return ResultTagRemoved;
|
return ResultTagRemoved;
|
||||||
|
@ -496,13 +512,59 @@ Result NfcDevice::Restore() {
|
||||||
return ResultWrongDeviceState;
|
return ResultWrongDeviceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mount_target == NFP::MountTarget::None || mount_target == NFP::MountTarget::Rom) {
|
NFC::TagInfo tag_info{};
|
||||||
LOG_ERROR(Service_NFC, "Amiibo is read only", device_state);
|
std::array<u8, sizeof(NFP::EncryptedNTAG215File)> data{};
|
||||||
return ResultWrongDeviceState;
|
Result result = GetTagInfo(tag_info, false);
|
||||||
|
|
||||||
|
if (result.IsError()) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Load amiibo from backup on system
|
result = ReadBackupData(tag_info.uuid, data);
|
||||||
LOG_ERROR(Service_NFP, "Not Implemented");
|
|
||||||
|
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;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,13 +1194,69 @@ Result NfcDevice::BreakTag(NFP::BreakType break_type) {
|
||||||
return FlushWithBreak(break_type);
|
return FlushWithBreak(break_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result NfcDevice::ReadBackupData(std::span<u8> data) const {
|
Result NfcDevice::HasBackup(const NFC::UniqueSerialNumber& uid) const {
|
||||||
// Not implemented
|
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;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result NfcDevice::WriteBackupData(std::span<const u8> data) {
|
Result NfcDevice::ReadBackupData(const NFC::UniqueSerialNumber& uid, std::span<u8> data) const {
|
||||||
// Not implemented
|
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;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,7 +1295,8 @@ NFP::AmiiboName NfcDevice::GetAmiiboName(const NFP::AmiiboSettings& settings) co
|
||||||
return amiibo_name;
|
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{};
|
std::array<char16_t, NFP::amiibo_name_length> settings_amiibo_name{};
|
||||||
|
|
||||||
// Convert from utf8 to utf16
|
// Convert from utf8 to utf16
|
||||||
|
@ -1258,22 +1377,23 @@ void NfcDevice::UpdateRegisterInfoCrc() {
|
||||||
tag_data.register_info_crc = crc.checksum();
|
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;
|
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
|
// Common info
|
||||||
tag_data.write_counter = 0;
|
stubbed_tag_data.write_counter = 0;
|
||||||
tag_data.amiibo_version = 0;
|
stubbed_tag_data.amiibo_version = 0;
|
||||||
settings.write_date = GetAmiiboDate(GetCurrentPosixTime());
|
settings.write_date = GetAmiiboDate(GetCurrentPosixTime());
|
||||||
|
|
||||||
// Register info
|
// Register info
|
||||||
SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'});
|
SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'});
|
||||||
settings.settings.font_region.Assign(0);
|
settings.settings.font_region.Assign(0);
|
||||||
settings.init_date = GetAmiiboDate(GetCurrentPosixTime());
|
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
|
// Admin info
|
||||||
settings.settings.amiibo_initialized.Assign(1);
|
settings.settings.amiibo_initialized.Assign(1);
|
||||||
|
|
|
@ -86,8 +86,9 @@ public:
|
||||||
Result GetAll(NFP::NfpData& data) const;
|
Result GetAll(NFP::NfpData& data) const;
|
||||||
Result SetAll(const NFP::NfpData& data);
|
Result SetAll(const NFP::NfpData& data);
|
||||||
Result BreakTag(NFP::BreakType break_type);
|
Result BreakTag(NFP::BreakType break_type);
|
||||||
Result ReadBackupData(std::span<u8> data) const;
|
Result HasBackup(const NFC::UniqueSerialNumber& uid) const;
|
||||||
Result WriteBackupData(std::span<const u8> data);
|
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);
|
Result WriteNtf(std::span<const u8> data);
|
||||||
|
|
||||||
u64 GetHandle() const;
|
u64 GetHandle() const;
|
||||||
|
@ -103,14 +104,15 @@ private:
|
||||||
void CloseNfcTag();
|
void CloseNfcTag();
|
||||||
|
|
||||||
NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const;
|
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;
|
NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const;
|
||||||
u64 GetCurrentPosixTime() const;
|
u64 GetCurrentPosixTime() const;
|
||||||
u64 RemoveVersionByte(u64 application_id) const;
|
u64 RemoveVersionByte(u64 application_id) const;
|
||||||
void UpdateSettingsCrc();
|
void UpdateSettingsCrc();
|
||||||
void UpdateRegisterInfoCrc();
|
void UpdateRegisterInfoCrc();
|
||||||
|
|
||||||
void BuildAmiiboWithoutKeys();
|
void BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data,
|
||||||
|
const NFP::EncryptedNTAG215File& encrypted_file) const;
|
||||||
|
|
||||||
bool is_controller_set{};
|
bool is_controller_set{};
|
||||||
int callback_key;
|
int callback_key;
|
||||||
|
|
|
@ -543,9 +543,14 @@ Result DeviceManager::ReadBackupData(u64 device_handle, std::span<u8> data) cons
|
||||||
|
|
||||||
std::shared_ptr<NfcDevice> device = nullptr;
|
std::shared_ptr<NfcDevice> device = nullptr;
|
||||||
auto result = GetDeviceHandle(device_handle, device);
|
auto result = GetDeviceHandle(device_handle, device);
|
||||||
|
NFC::TagInfo tag_info{};
|
||||||
|
|
||||||
if (result.IsSuccess()) {
|
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);
|
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;
|
std::shared_ptr<NfcDevice> device = nullptr;
|
||||||
auto result = GetDeviceHandle(device_handle, device);
|
auto result = GetDeviceHandle(device_handle, device);
|
||||||
|
NFC::TagInfo tag_info{};
|
||||||
|
|
||||||
if (result.IsSuccess()) {
|
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);
|
result = VerifyDeviceResult(device, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,7 +302,7 @@ Result NfcInterface::TranslateResultToServiceError(Result result) const {
|
||||||
return TranslateResultToNfp(result);
|
return TranslateResultToNfp(result);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (result != ResultUnknown216) {
|
if (result != ResultBackupPathAlreadyExist) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return ResultUnknown74;
|
return ResultUnknown74;
|
||||||
|
@ -343,6 +343,9 @@ Result NfcInterface::TranslateResultToNfp(Result result) const {
|
||||||
if (result == ResultApplicationAreaIsNotInitialized) {
|
if (result == ResultApplicationAreaIsNotInitialized) {
|
||||||
return NFP::ResultApplicationAreaIsNotInitialized;
|
return NFP::ResultApplicationAreaIsNotInitialized;
|
||||||
}
|
}
|
||||||
|
if (result == ResultCorruptedDataWithBackup) {
|
||||||
|
return NFP::ResultCorruptedDataWithBackup;
|
||||||
|
}
|
||||||
if (result == ResultCorruptedData) {
|
if (result == ResultCorruptedData) {
|
||||||
return NFP::ResultCorruptedData;
|
return NFP::ResultCorruptedData;
|
||||||
}
|
}
|
||||||
|
@ -355,6 +358,9 @@ Result NfcInterface::TranslateResultToNfp(Result result) const {
|
||||||
if (result == ResultNotAnAmiibo) {
|
if (result == ResultNotAnAmiibo) {
|
||||||
return NFP::ResultNotAnAmiibo;
|
return NFP::ResultNotAnAmiibo;
|
||||||
}
|
}
|
||||||
|
if (result == ResultUnableToAccessBackupFile) {
|
||||||
|
return NFP::ResultUnableToAccessBackupFile;
|
||||||
|
}
|
||||||
LOG_WARNING(Service_NFC, "Result conversion not handled");
|
LOG_WARNING(Service_NFC, "Result conversion not handled");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,20 +9,22 @@ namespace Service::NFC {
|
||||||
|
|
||||||
constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64);
|
constexpr Result ResultDeviceNotFound(ErrorModule::NFC, 64);
|
||||||
constexpr Result ResultInvalidArgument(ErrorModule::NFC, 65);
|
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 ResultWrongDeviceState(ErrorModule::NFC, 73);
|
||||||
constexpr Result ResultUnknown74(ErrorModule::NFC, 74);
|
constexpr Result ResultUnknown74(ErrorModule::NFC, 74);
|
||||||
constexpr Result ResultUnknown76(ErrorModule::NFC, 76);
|
constexpr Result ResultUnknown76(ErrorModule::NFC, 76);
|
||||||
constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
|
constexpr Result ResultNfcNotInitialized(ErrorModule::NFC, 77);
|
||||||
constexpr Result ResultNfcDisabled(ErrorModule::NFC, 80);
|
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 ResultTagRemoved(ErrorModule::NFC, 97);
|
||||||
constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120);
|
constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFC, 113);
|
||||||
constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128);
|
constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFC, 120);
|
||||||
constexpr Result ResultCorruptedData(ErrorModule::NFP, 144);
|
constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFC, 128);
|
||||||
constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152);
|
constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFC, 136);
|
||||||
constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168);
|
constexpr Result ResultCorruptedData(ErrorModule::NFC, 144);
|
||||||
constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178);
|
constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFC, 152);
|
||||||
constexpr Result ResultUnknown216(ErrorModule::NFC, 216);
|
constexpr Result ResultApplicationAreaExist(ErrorModule::NFC, 168);
|
||||||
|
constexpr Result ResultNotAnAmiibo(ErrorModule::NFC, 178);
|
||||||
|
constexpr Result ResultBackupPathAlreadyExist(ErrorModule::NFC, 216);
|
||||||
|
|
||||||
} // namespace Service::NFC
|
} // namespace Service::NFC
|
||||||
|
|
|
@ -126,7 +126,7 @@ void Interface::Flush(HLERequestContext& ctx) {
|
||||||
void Interface::Restore(HLERequestContext& ctx) {
|
void Interface::Restore(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto device_handle{rp.Pop<u64>()};
|
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);
|
auto result = GetManager()->Restore(device_handle);
|
||||||
result = TranslateResultToServiceError(result);
|
result = TranslateResultToServiceError(result);
|
||||||
|
@ -394,7 +394,7 @@ void Interface::BreakTag(HLERequestContext& ctx) {
|
||||||
void Interface::ReadBackupData(HLERequestContext& ctx) {
|
void Interface::ReadBackupData(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto device_handle{rp.Pop<u64>()};
|
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{};
|
std::vector<u8> backup_data{};
|
||||||
auto result = GetManager()->ReadBackupData(device_handle, backup_data);
|
auto result = GetManager()->ReadBackupData(device_handle, backup_data);
|
||||||
|
@ -412,7 +412,7 @@ void Interface::WriteBackupData(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto device_handle{rp.Pop<u64>()};
|
const auto device_handle{rp.Pop<u64>()};
|
||||||
const auto backup_data_buffer{ctx.ReadBuffer()};
|
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);
|
auto result = GetManager()->WriteBackupData(device_handle, backup_data_buffer);
|
||||||
result = TranslateResultToServiceError(result);
|
result = TranslateResultToServiceError(result);
|
||||||
|
|
|
@ -17,9 +17,11 @@ constexpr Result ResultWriteAmiiboFailed(ErrorModule::NFP, 88);
|
||||||
constexpr Result ResultTagRemoved(ErrorModule::NFP, 97);
|
constexpr Result ResultTagRemoved(ErrorModule::NFP, 97);
|
||||||
constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120);
|
constexpr Result ResultRegistrationIsNotInitialized(ErrorModule::NFP, 120);
|
||||||
constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128);
|
constexpr Result ResultApplicationAreaIsNotInitialized(ErrorModule::NFP, 128);
|
||||||
|
constexpr Result ResultCorruptedDataWithBackup(ErrorModule::NFP, 136);
|
||||||
constexpr Result ResultCorruptedData(ErrorModule::NFP, 144);
|
constexpr Result ResultCorruptedData(ErrorModule::NFP, 144);
|
||||||
constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152);
|
constexpr Result ResultWrongApplicationAreaId(ErrorModule::NFP, 152);
|
||||||
constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168);
|
constexpr Result ResultApplicationAreaExist(ErrorModule::NFP, 168);
|
||||||
constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178);
|
constexpr Result ResultNotAnAmiibo(ErrorModule::NFP, 178);
|
||||||
|
constexpr Result ResultUnableToAccessBackupFile(ErrorModule::NFP, 200);
|
||||||
|
|
||||||
} // namespace Service::NFP
|
} // namespace Service::NFP
|
||||||
|
|
|
@ -85,7 +85,6 @@
|
||||||
|
|
||||||
// Define extensions which must be supported.
|
// Define extensions which must be supported.
|
||||||
#define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \
|
#define FOR_EACH_VK_MANDATORY_EXTENSION(EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
|
|
||||||
EXTENSION_NAME(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME) \
|
||||||
|
@ -105,6 +104,7 @@
|
||||||
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
|
||||||
|
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME) \
|
||||||
|
@ -141,9 +141,6 @@
|
||||||
FEATURE_NAME(features, vertexPipelineStoresAndAtomics) \
|
FEATURE_NAME(features, vertexPipelineStoresAndAtomics) \
|
||||||
FEATURE_NAME(features, wideLines) \
|
FEATURE_NAME(features, wideLines) \
|
||||||
FEATURE_NAME(host_query_reset, hostQueryReset) \
|
FEATURE_NAME(host_query_reset, hostQueryReset) \
|
||||||
FEATURE_NAME(robustness2, nullDescriptor) \
|
|
||||||
FEATURE_NAME(robustness2, robustBufferAccess2) \
|
|
||||||
FEATURE_NAME(robustness2, robustImageAccess2) \
|
|
||||||
FEATURE_NAME(shader_demote_to_helper_invocation, shaderDemoteToHelperInvocation) \
|
FEATURE_NAME(shader_demote_to_helper_invocation, shaderDemoteToHelperInvocation) \
|
||||||
FEATURE_NAME(shader_draw_parameters, shaderDrawParameters) \
|
FEATURE_NAME(shader_draw_parameters, shaderDrawParameters) \
|
||||||
FEATURE_NAME(variable_pointer, variablePointers) \
|
FEATURE_NAME(variable_pointer, variablePointers) \
|
||||||
|
@ -156,6 +153,9 @@
|
||||||
FEATURE_NAME(index_type_uint8, indexTypeUint8) \
|
FEATURE_NAME(index_type_uint8, indexTypeUint8) \
|
||||||
FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \
|
FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \
|
||||||
FEATURE_NAME(provoking_vertex, provokingVertexLast) \
|
FEATURE_NAME(provoking_vertex, provokingVertexLast) \
|
||||||
|
FEATURE_NAME(robustness2, nullDescriptor) \
|
||||||
|
FEATURE_NAME(robustness2, robustBufferAccess2) \
|
||||||
|
FEATURE_NAME(robustness2, robustImageAccess2) \
|
||||||
FEATURE_NAME(shader_float16_int8, shaderFloat16) \
|
FEATURE_NAME(shader_float16_int8, shaderFloat16) \
|
||||||
FEATURE_NAME(shader_float16_int8, shaderInt8) \
|
FEATURE_NAME(shader_float16_int8, shaderInt8) \
|
||||||
FEATURE_NAME(timeline_semaphore, timelineSemaphore) \
|
FEATURE_NAME(timeline_semaphore, timelineSemaphore) \
|
||||||
|
|
Loading…
Reference in a new issue