From 129e76a13c3958f60e94438301d7b14bf45d1dc0 Mon Sep 17 00:00:00 2001 From: Zephyron Date: Sat, 24 May 2025 15:42:58 +1000 Subject: [PATCH] hle/service/acc: Implement acc:e, acc:e:u1, acc:e:u2, and dauth:0 services - Add acc:e service with full account management functionality - Add acc:e:u1 service (minimal implementation) - Add acc:e:u2 service with extended functionality including PIN code support - Add dauth:0 device authentication service - Update acc_su function mappings to match newer firmware versions - Move TrySelectUserWithoutInteraction from ID 51 to 52 with deprecated fallback These services provide additional account management interfaces used by newer Switch firmware versions and some games that require extended account functionality. Signed-off-by: Zephyron --- src/core/CMakeLists.txt | 9 ++++ src/core/hle/service/acc/acc.cpp | 14 +++++++ src/core/hle/service/acc/acc_e.cpp | 53 ++++++++++++++++++++++++ src/core/hle/service/acc/acc_e.h | 17 ++++++++ src/core/hle/service/acc/acc_e_u1.cpp | 22 ++++++++++ src/core/hle/service/acc/acc_e_u1.h | 17 ++++++++ src/core/hle/service/acc/acc_e_u2.cpp | 59 +++++++++++++++++++++++++++ src/core/hle/service/acc/acc_e_u2.h | 17 ++++++++ src/core/hle/service/acc/acc_su.cpp | 14 ++++++- src/core/hle/service/acc/dauth_0.cpp | 23 +++++++++++ src/core/hle/service/acc/dauth_0.h | 16 ++++++++ 11 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 src/core/hle/service/acc/acc_e.cpp create mode 100644 src/core/hle/service/acc/acc_e.h create mode 100644 src/core/hle/service/acc/acc_e_u1.cpp create mode 100644 src/core/hle/service/acc/acc_e_u1.h create mode 100644 src/core/hle/service/acc/acc_e_u2.cpp create mode 100644 src/core/hle/service/acc/acc_e_u2.h create mode 100644 src/core/hle/service/acc/dauth_0.cpp create mode 100644 src/core/hle/service/acc/dauth_0.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9571c1ad9..cb46c8653 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,4 +1,5 @@ # SPDX-FileCopyrightText: 2018 yuzu Emulator Project +# SPDX-FileCopyrightText: 2025 citron Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later add_library(core STATIC @@ -384,6 +385,12 @@ add_library(core STATIC hle/service/acc/acc.h hle/service/acc/acc_aa.cpp hle/service/acc/acc_aa.h + hle/service/acc/acc_e.cpp + hle/service/acc/acc_e.h + hle/service/acc/acc_e_u1.cpp + hle/service/acc/acc_e_u1.h + hle/service/acc/acc_e_u2.cpp + hle/service/acc/acc_e_u2.h hle/service/acc/acc_su.cpp hle/service/acc/acc_su.h hle/service/acc/acc_u0.cpp @@ -392,6 +399,8 @@ add_library(core STATIC hle/service/acc/acc_u1.h hle/service/acc/async_context.cpp hle/service/acc/async_context.h + hle/service/acc/dauth_0.cpp + hle/service/acc/dauth_0.h hle/service/acc/errors.h hle/service/acc/profile_manager.cpp hle/service/acc/profile_manager.h diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 9f40c5425..9420c7d7d 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -19,10 +20,14 @@ #include "core/file_sys/patch_manager.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc_aa.h" +#include "core/hle/service/acc/acc_e.h" +#include "core/hle/service/acc/acc_e_u1.h" +#include "core/hle/service/acc/acc_e_u2.h" #include "core/hle/service/acc/acc_su.h" #include "core/hle/service/acc/acc_u0.h" #include "core/hle/service/acc/acc_u1.h" #include "core/hle/service/acc/async_context.h" +#include "core/hle/service/acc/dauth_0.h" #include "core/hle/service/acc/errors.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/cmif_serialization.h" @@ -1040,12 +1045,21 @@ void LoopProcess(Core::System& system) { server_manager->RegisterNamedService("acc:aa", std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("acc:e", + std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("acc:e:u1", + std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("acc:e:u2", + std::make_shared(module, profile_manager, system)); server_manager->RegisterNamedService("acc:su", std::make_shared(module, profile_manager, system)); server_manager->RegisterNamedService("acc:u0", std::make_shared(module, profile_manager, system)); server_manager->RegisterNamedService("acc:u1", std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("dauth:0", + std::make_shared(system)); + ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/acc/acc_e.cpp b/src/core/hle/service/acc/acc_e.cpp new file mode 100644 index 000000000..1855b8953 --- /dev/null +++ b/src/core/hle/service/acc/acc_e.cpp @@ -0,0 +1,53 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/acc/acc_e.h" + +namespace Service::Account { + +ACC_E::ACC_E(std::shared_ptr module_, std::shared_ptr profile_manager_, + Core::System& system_) + : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:e") { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ACC_E::GetUserCount, "GetUserCount"}, + {1, &ACC_E::GetUserExistence, "GetUserExistence"}, + {2, &ACC_E::ListAllUsers, "ListAllUsers"}, + {3, &ACC_E::ListOpenUsers, "ListOpenUsers"}, + {4, &ACC_E::GetLastOpenedUser, "GetLastOpenedUser"}, + {5, &ACC_E::GetProfile, "GetProfile"}, + {6, nullptr, "GetProfileDigest"}, + {50, &ACC_E::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, + {51, nullptr, "TrySelectUserWithoutInteractionDeprecated"}, // [1.0.0-18.1.0] + {52, &ACC_E::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, // [19.0.0+] + {99, nullptr, "DebugActivateOpenContextRetention"}, + {100, nullptr, "GetUserRegistrationNotifier"}, + {101, nullptr, "GetUserStateChangeNotifier"}, + {102, &ACC_E::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"}, + {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, + {104, nullptr, "GetProfileUpdateNotifier"}, + {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, + {106, nullptr, "GetProfileSyncNotifier"}, + {110, &ACC_E::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"}, + {111, nullptr, "ClearSaveDataThumbnail"}, + {112, nullptr, "LoadSaveDataThumbnail"}, + {113, nullptr, "GetSaveDataThumbnailExistence"}, + {120, nullptr, "ListOpenUsersInApplication"}, + {130, nullptr, "ActivateOpenContextRetention"}, + {140, &ACC_E::ListQualifiedUsers, "ListQualifiedUsers"}, + {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"}, + {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"}, + {170, nullptr, "GetNasOp2MembershipStateChangeNotifier"}, + {191, nullptr, "UpdateNotificationReceiverInfo"}, + {997, nullptr, "DebugInvalidateTokenCacheForUser"}, + {998, nullptr, "DebugSetUserStateClose"}, + {999, nullptr, "DebugSetUserStateOpen"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ACC_E::~ACC_E() = default; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/acc_e.h b/src/core/hle/service/acc/acc_e.h new file mode 100644 index 000000000..13afe5e14 --- /dev/null +++ b/src/core/hle/service/acc/acc_e.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/acc/acc.h" + +namespace Service::Account { + +class ACC_E final : public Module::Interface { +public: + explicit ACC_E(std::shared_ptr module_, + std::shared_ptr profile_manager_, Core::System& system_); + ~ACC_E() override; +}; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/acc_e_u1.cpp b/src/core/hle/service/acc/acc_e_u1.cpp new file mode 100644 index 000000000..fd2a007ef --- /dev/null +++ b/src/core/hle/service/acc/acc_e_u1.cpp @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/acc/acc_e_u1.h" + +namespace Service::Account { + +ACC_E_U1::ACC_E_U1(std::shared_ptr module_, std::shared_ptr profile_manager_, + Core::System& system_) + : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:e:u1") { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Reserved"}, // Placeholder for empty service + }; + // clang-format on + + RegisterHandlers(functions); +} + +ACC_E_U1::~ACC_E_U1() = default; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/acc_e_u1.h b/src/core/hle/service/acc/acc_e_u1.h new file mode 100644 index 000000000..803604839 --- /dev/null +++ b/src/core/hle/service/acc/acc_e_u1.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/acc/acc.h" + +namespace Service::Account { + +class ACC_E_U1 final : public Module::Interface { +public: + explicit ACC_E_U1(std::shared_ptr module_, + std::shared_ptr profile_manager_, Core::System& system_); + ~ACC_E_U1() override; +}; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/acc_e_u2.cpp b/src/core/hle/service/acc/acc_e_u2.cpp new file mode 100644 index 000000000..a29ce9c45 --- /dev/null +++ b/src/core/hle/service/acc/acc_e_u2.cpp @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/acc/acc_e_u2.h" + +namespace Service::Account { + +ACC_E_U2::ACC_E_U2(std::shared_ptr module_, std::shared_ptr profile_manager_, + Core::System& system_) + : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:e:u2") { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ACC_E_U2::GetUserCount, "GetUserCount"}, + {1, &ACC_E_U2::GetUserExistence, "GetUserExistence"}, + {2, &ACC_E_U2::ListAllUsers, "ListAllUsers"}, + {3, &ACC_E_U2::ListOpenUsers, "ListOpenUsers"}, + {4, &ACC_E_U2::GetLastOpenedUser, "GetLastOpenedUser"}, + {5, &ACC_E_U2::GetProfile, "GetProfile"}, + {6, nullptr, "GetProfileDigest"}, + {50, &ACC_E_U2::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, + {51, nullptr, "TrySelectUserWithoutInteractionDeprecated"}, // [1.0.0-18.1.0] + {52, &ACC_E_U2::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, // [19.0.0+] + {99, nullptr, "DebugActivateOpenContextRetention"}, + {100, nullptr, "GetUserRegistrationNotifier"}, + {101, nullptr, "GetUserStateChangeNotifier"}, + {102, &ACC_E_U2::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"}, + {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, + {104, nullptr, "GetProfileUpdateNotifier"}, + {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, + {106, nullptr, "GetProfileSyncNotifier"}, + {110, &ACC_E_U2::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"}, + {111, nullptr, "ClearSaveDataThumbnail"}, + {112, nullptr, "LoadSaveDataThumbnail"}, + {113, nullptr, "GetSaveDataThumbnailExistence"}, + {120, nullptr, "ListOpenUsersInApplication"}, + {130, nullptr, "ActivateOpenContextRetention"}, + {140, &ACC_E_U2::ListQualifiedUsers, "ListQualifiedUsers"}, + {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"}, + {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"}, + {170, nullptr, "GetNasOp2MembershipStateChangeNotifier"}, + {191, nullptr, "UpdateNotificationReceiverInfo"}, // [13.0.0-19.0.1] + {205, &ACC_E_U2::GetProfileEditor, "GetProfileEditor"}, + {401, nullptr, "GetPinCodeLength"}, // [18.0.0+] + {402, nullptr, "GetPinCode"}, // [18.0.0-19.0.1] + {403, nullptr, "GetPinCodeParity"}, // [20.0.0+] + {404, nullptr, "VerifyPinCode"}, // [20.0.0+] + {405, nullptr, "IsPinCodeVerificationForbidden"}, // [20.0.0+] + {997, nullptr, "DebugInvalidateTokenCacheForUser"}, + {998, nullptr, "DebugSetUserStateClose"}, + {999, nullptr, "DebugSetUserStateOpen"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ACC_E_U2::~ACC_E_U2() = default; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/acc_e_u2.h b/src/core/hle/service/acc/acc_e_u2.h new file mode 100644 index 000000000..d2c93fa41 --- /dev/null +++ b/src/core/hle/service/acc/acc_e_u2.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/acc/acc.h" + +namespace Service::Account { + +class ACC_E_U2 final : public Module::Interface { +public: + explicit ACC_E_U2(std::shared_ptr module_, + std::shared_ptr profile_manager_, Core::System& system_); + ~ACC_E_U2() override; +}; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp index 770d13ec5..5d2fe6720 100644 --- a/src/core/hle/service/acc/acc_su.cpp +++ b/src/core/hle/service/acc/acc_su.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/acc/acc_su.h" @@ -18,7 +19,8 @@ ACC_SU::ACC_SU(std::shared_ptr module_, std::shared_ptr {5, &ACC_SU::GetProfile, "GetProfile"}, {6, nullptr, "GetProfileDigest"}, {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, - {51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, + {51, nullptr, "TrySelectUserWithoutInteractionDeprecated"}, // [1.0.0-18.1.0] + {52, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, // [19.0.0+] {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, {99, nullptr, "DebugActivateOpenContextRetention"}, {100, nullptr, "GetUserRegistrationNotifier"}, @@ -50,11 +52,21 @@ ACC_SU::ACC_SU(std::shared_ptr module_, std::shared_ptr {210, nullptr, "CreateFloatingRegistrationRequest"}, {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, + {213, nullptr, "CreateProcedureToCreateUserWithNintendoAccount"}, // [17.0.0+] + {214, nullptr, "ResumeProcedureToCreateUserWithNintendoAccount"}, // [17.0.0+] + {215, nullptr, "ResumeProcedureToCreateUserWithNintendoAccountAfterApplyResponse"}, // [17.0.0+] {230, nullptr, "AuthenticateServiceAsync"}, {250, nullptr, "GetBaasAccountAdministrator"}, + {251, nullptr, "SynchronizeNetworkServiceAccountsSnapshotAsync"}, // [20.0.0+] {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"}, {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, + {292, nullptr, "ProxyProcedureForDeviceMigrationAuthenticatingOperatingUser"}, // [20.0.0+] + {293, nullptr, "ProxyProcedureForDeviceMigrationDownload"}, // [20.0.0+] {299, nullptr, "SuspendBackgroundDaemon"}, + {350, nullptr, "CreateDeviceMigrationUserExportRequest"}, // [20.0.0+] + {351, nullptr, "UploadNasCredential"}, // [20.0.0+] + {352, nullptr, "CreateDeviceMigrationUserImportRequest"}, // [20.0.0+] + {353, nullptr, "DeleteUserMigrationInfo"}, // [20.0.0+] {900, nullptr, "SetUserUnqualifiedForDebug"}, {901, nullptr, "UnsetUserUnqualifiedForDebug"}, {902, nullptr, "ListUsersUnqualifiedForDebug"}, diff --git a/src/core/hle/service/acc/dauth_0.cpp b/src/core/hle/service/acc/dauth_0.cpp new file mode 100644 index 000000000..b7910e6d6 --- /dev/null +++ b/src/core/hle/service/acc/dauth_0.cpp @@ -0,0 +1,23 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/acc/dauth_0.h" + +namespace Service::Account { + +DAUTH_0::DAUTH_0(Core::System& system_) : ServiceFramework{system_, "dauth:0"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "GetSystemEvent"}, // IAsyncResult interface + {1, nullptr, "Cancel"}, // IAsyncResult interface + {2, nullptr, "IsAvailable"}, // IAsyncResult interface + {3, nullptr, "GetResult"}, // IAsyncResult interface + }; + // clang-format on + + RegisterHandlers(functions); +} + +DAUTH_0::~DAUTH_0() = default; + +} // namespace Service::Account \ No newline at end of file diff --git a/src/core/hle/service/acc/dauth_0.h b/src/core/hle/service/acc/dauth_0.h new file mode 100644 index 000000000..1b4d161ab --- /dev/null +++ b/src/core/hle/service/acc/dauth_0.h @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Account { + +class DAUTH_0 final : public ServiceFramework { +public: + explicit DAUTH_0(Core::System& system_); + ~DAUTH_0() override; +}; + +} // namespace Service::Account \ No newline at end of file