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 <zephyron@citron-emu.org>
This commit is contained in:
Zephyron
2025-05-24 15:42:58 +10:00
parent 1ba7861366
commit 129e76a13c
11 changed files with 260 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project # SPDX-FileCopyrightText: 2018 yuzu Emulator Project
# SPDX-FileCopyrightText: 2025 citron Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
add_library(core STATIC add_library(core STATIC
@@ -384,6 +385,12 @@ add_library(core STATIC
hle/service/acc/acc.h hle/service/acc/acc.h
hle/service/acc/acc_aa.cpp hle/service/acc/acc_aa.cpp
hle/service/acc/acc_aa.h 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.cpp
hle/service/acc/acc_su.h hle/service/acc/acc_su.h
hle/service/acc/acc_u0.cpp hle/service/acc/acc_u0.cpp
@@ -392,6 +399,8 @@ add_library(core STATIC
hle/service/acc/acc_u1.h hle/service/acc/acc_u1.h
hle/service/acc/async_context.cpp hle/service/acc/async_context.cpp
hle/service/acc/async_context.h 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/errors.h
hle/service/acc/profile_manager.cpp hle/service/acc/profile_manager.cpp
hle/service/acc/profile_manager.h hle/service/acc/profile_manager.h

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm> #include <algorithm>
@@ -19,10 +20,14 @@
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc.h"
#include "core/hle/service/acc/acc_aa.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_su.h"
#include "core/hle/service/acc/acc_u0.h" #include "core/hle/service/acc/acc_u0.h"
#include "core/hle/service/acc/acc_u1.h" #include "core/hle/service/acc/acc_u1.h"
#include "core/hle/service/acc/async_context.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/errors.h"
#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/cmif_serialization.h"
@@ -1040,12 +1045,21 @@ void LoopProcess(Core::System& system) {
server_manager->RegisterNamedService("acc:aa", server_manager->RegisterNamedService("acc:aa",
std::make_shared<ACC_AA>(module, profile_manager, system)); std::make_shared<ACC_AA>(module, profile_manager, system));
server_manager->RegisterNamedService("acc:e",
std::make_shared<ACC_E>(module, profile_manager, system));
server_manager->RegisterNamedService("acc:e:u1",
std::make_shared<ACC_E_U1>(module, profile_manager, system));
server_manager->RegisterNamedService("acc:e:u2",
std::make_shared<ACC_E_U2>(module, profile_manager, system));
server_manager->RegisterNamedService("acc:su", server_manager->RegisterNamedService("acc:su",
std::make_shared<ACC_SU>(module, profile_manager, system)); std::make_shared<ACC_SU>(module, profile_manager, system));
server_manager->RegisterNamedService("acc:u0", server_manager->RegisterNamedService("acc:u0",
std::make_shared<ACC_U0>(module, profile_manager, system)); std::make_shared<ACC_U0>(module, profile_manager, system));
server_manager->RegisterNamedService("acc:u1", server_manager->RegisterNamedService("acc:u1",
std::make_shared<ACC_U1>(module, profile_manager, system)); std::make_shared<ACC_U1>(module, profile_manager, system));
server_manager->RegisterNamedService("dauth:0",
std::make_shared<DAUTH_0>(system));
ServerManager::RunServer(std::move(server_manager)); ServerManager::RunServer(std::move(server_manager));
} }

View File

@@ -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> module_, std::shared_ptr<ProfileManager> 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

View File

@@ -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> module_,
std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
~ACC_E() override;
};
} // namespace Service::Account

View File

@@ -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> module_, std::shared_ptr<ProfileManager> 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

View File

@@ -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> module_,
std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
~ACC_E_U1() override;
};
} // namespace Service::Account

View File

@@ -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> module_, std::shared_ptr<ProfileManager> 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

View File

@@ -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> module_,
std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
~ACC_E_U2() override;
};
} // namespace Service::Account

View File

@@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/service/acc/acc_su.h" #include "core/hle/service/acc/acc_su.h"
@@ -18,7 +19,8 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{5, &ACC_SU::GetProfile, "GetProfile"}, {5, &ACC_SU::GetProfile, "GetProfile"},
{6, nullptr, "GetProfileDigest"}, {6, nullptr, "GetProfileDigest"},
{50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"}, {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"}, {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
{99, nullptr, "DebugActivateOpenContextRetention"}, {99, nullptr, "DebugActivateOpenContextRetention"},
{100, nullptr, "GetUserRegistrationNotifier"}, {100, nullptr, "GetUserRegistrationNotifier"},
@@ -50,11 +52,21 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{210, nullptr, "CreateFloatingRegistrationRequest"}, {210, nullptr, "CreateFloatingRegistrationRequest"},
{211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"}, {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
{212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"}, {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
{213, nullptr, "CreateProcedureToCreateUserWithNintendoAccount"}, // [17.0.0+]
{214, nullptr, "ResumeProcedureToCreateUserWithNintendoAccount"}, // [17.0.0+]
{215, nullptr, "ResumeProcedureToCreateUserWithNintendoAccountAfterApplyResponse"}, // [17.0.0+]
{230, nullptr, "AuthenticateServiceAsync"}, {230, nullptr, "AuthenticateServiceAsync"},
{250, nullptr, "GetBaasAccountAdministrator"}, {250, nullptr, "GetBaasAccountAdministrator"},
{251, nullptr, "SynchronizeNetworkServiceAccountsSnapshotAsync"}, // [20.0.0+]
{290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"}, {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
{291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"}, {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
{292, nullptr, "ProxyProcedureForDeviceMigrationAuthenticatingOperatingUser"}, // [20.0.0+]
{293, nullptr, "ProxyProcedureForDeviceMigrationDownload"}, // [20.0.0+]
{299, nullptr, "SuspendBackgroundDaemon"}, {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"}, {900, nullptr, "SetUserUnqualifiedForDebug"},
{901, nullptr, "UnsetUserUnqualifiedForDebug"}, {901, nullptr, "UnsetUserUnqualifiedForDebug"},
{902, nullptr, "ListUsersUnqualifiedForDebug"}, {902, nullptr, "ListUsersUnqualifiedForDebug"},

View File

@@ -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

View File

@@ -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<DAUTH_0> {
public:
explicit DAUTH_0(Core::System& system_);
~DAUTH_0() override;
};
} // namespace Service::Account