aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2026-08-18 18:11:33 +0200
committercrueter <crueter@eden-emu.dev>2026-08-18 18:11:33 +0200
commita41a98028a541e8e44d6220d0b58e45017e25c85 (patch)
treea7b42d3220c89a1b555ea24dd2c2684ae083014a /src
parent265c27f3911e427719231a324b30daaba6f10f9f (diff)
[hle/service] stub missing homebrew services, fix NPad/caps crashes (#4264)
Signed-off-by: lizzie <lizzie@eden-emu.dev> - [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- this PR adds various missing services (acc:e, acc:e:u1) to expand homebrew compatibility notably this also fixes NPad related crashes due to nullref Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4264 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt16
-rw-r--r--src/core/hle/service/acc/acc.cpp417
-rw-r--r--src/core/hle/service/acc/acc_aa.cpp25
-rw-r--r--src/core/hle/service/acc/acc_aa.h17
-rw-r--r--src/core/hle/service/acc/acc_su.cpp83
-rw-r--r--src/core/hle/service/acc/acc_su.h17
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp49
-rw-r--r--src/core/hle/service/acc/acc_u0.h17
-rw-r--r--src/core/hle/service/acc/acc_u1.cpp59
-rw-r--r--src/core/hle/service/acc/acc_u1.h17
-rw-r--r--src/core/hle/service/apm/apm_controller.cpp27
-rw-r--r--src/core/hle/service/audio/audio.cpp176
-rw-r--r--src/core/hle/service/audio/audio_renderer_manager.cpp6
-rw-r--r--src/core/hle/service/bpc/bpc.cpp50
-rw-r--r--src/core/hle/service/caps/caps.cpp42
-rw-r--r--src/core/hle/service/caps/caps_manager.cpp18
-rw-r--r--src/core/hle/service/es/es.cpp91
-rw-r--r--src/core/hle/service/friend/friend.cpp79
-rw-r--r--src/core/hle/service/glue/ectx.cpp24
-rw-r--r--src/core/hle/service/glue/ectx.h15
-rw-r--r--src/core/hle/service/glue/glue.cpp34
-rw-r--r--src/core/hle/service/glue/notif.cpp10
-rw-r--r--src/core/hle/service/grc/grc.cpp18
-rw-r--r--src/core/hle/service/hid/hid.cpp73
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp24
-rw-r--r--src/core/hle/service/hle_ipc.h8
-rw-r--r--src/core/hle/service/lm/lm.cpp16
-rw-r--r--src/core/hle/service/mii/mii.cpp6
-rw-r--r--src/core/hle/service/mnpp/mnpp.cpp86
-rw-r--r--src/core/hle/service/mnpp/mnpp.h (renamed from src/core/hle/service/mnpp/mnpp_app.h)3
-rw-r--r--src/core/hle/service/mnpp/mnpp_app.cpp51
-rw-r--r--src/core/hle/service/ncm/ncm.cpp15
-rw-r--r--src/core/hle/service/ngc/ngc.cpp43
-rw-r--r--src/core/hle/service/nim/nim.cpp14
-rw-r--r--src/core/hle/service/ns/ns.cpp55
-rw-r--r--src/core/hle/service/ns/query_service.cpp6
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp85
-rw-r--r--src/core/hle/service/olsc/olsc.cpp30
-rw-r--r--src/core/hle/service/pcie/pcie.cpp26
-rw-r--r--src/core/hle/service/pcv/pcv.cpp26
-rw-r--r--src/core/hle/service/psc/psc.cpp103
-rw-r--r--src/core/hle/service/psc/time/service_manager.cpp2
-rw-r--r--src/core/hle/service/ptm/ptm.cpp35
-rw-r--r--src/core/hle/service/ro/ro.cpp28
-rw-r--r--src/core/hle/service/services.cpp6
-rw-r--r--src/core/hle/service/sockets/bsd.cpp64
-rw-r--r--src/core/hle/service/sockets/bsd.h15
-rw-r--r--src/core/hle/service/sockets/sfdnsres.cpp17
-rw-r--r--src/core/hle/service/sockets/sfdnsres.h9
-rw-r--r--src/core/hle/service/sockets/sockets.cpp66
-rw-r--r--src/core/hle/service/spl/spl.cpp20
-rw-r--r--src/core/hle/service/spl/spl.h3
-rw-r--r--src/core/hle/service/tma/tma.cpp36
-rw-r--r--src/core/hle/service/tma/tma.h15
-rw-r--r--src/core/hle/service/usb/usb.cpp48
-rw-r--r--src/core/hle/service/wlan/wlan.cpp260
-rw-r--r--src/core/hle/service/wlan/wlan.h12
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp5
-rw-r--r--src/hid_core/resources/npad/npad.cpp13
-rw-r--r--src/hid_core/resources/npad/npad_resource.cpp3
60 files changed, 2063 insertions, 571 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 087fd796c6..e04b3dde26 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -388,14 +388,6 @@ add_library(core STATIC
hle/result.h
hle/service/acc/acc.cpp
hle/service/acc/acc.h
- hle/service/acc/acc_aa.cpp
- hle/service/acc/acc_aa.h
- hle/service/acc/acc_su.cpp
- hle/service/acc/acc_su.h
- hle/service/acc/acc_u0.cpp
- hle/service/acc/acc_u0.h
- hle/service/acc/acc_u1.cpp
- hle/service/acc/acc_u1.h
hle/service/acc/async_context.cpp
hle/service/acc/async_context.h
hle/service/acc/errors.h
@@ -768,8 +760,8 @@ add_library(core STATIC
hle/service/mii/types/ver3_store_data.h
hle/service/mm/mm_u.cpp
hle/service/mm/mm_u.h
- hle/service/mnpp/mnpp_app.cpp
- hle/service/mnpp/mnpp_app.h
+ hle/service/mnpp/mnpp.cpp
+ hle/service/mnpp/mnpp.h
hle/service/ncm/ncm.cpp
hle/service/ncm/ncm.h
hle/service/nfc/common/amiibo_crypto.cpp
@@ -1089,6 +1081,8 @@ add_library(core STATIC
hle/service/ssl/ssl.h
hle/service/ssl/ssl_backend.h
hle/service/ssl/ssl_types.h
+ hle/service/tma/tma.cpp
+ hle/service/tma/tma.h
hle/service/usb/usb.cpp
hle/service/usb/usb.h
hle/service/vi/application_display_service.cpp
@@ -1125,6 +1119,8 @@ add_library(core STATIC
hle/service/gpio/gpio.h
hle/service/i2c/i2c.cpp
hle/service/i2c/i2c.h
+ hle/service/wlan/wlan.cpp
+ hle/service/wlan/wlan.h
internal_network/emu_net_state.cpp
internal_network/emu_net_state.h
internal_network/network.cpp
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 9a8324fbf9..37826b0752 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -21,10 +21,6 @@
#include "core/file_sys/control_metadata.h"
#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_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/errors.h"
#include "core/hle/service/acc/profile_manager.h"
@@ -1244,19 +1240,416 @@ Module::Interface::Interface(std::shared_ptr<Module> module_,
Module::Interface::~Interface() = default;
+class ACC_AA final : public Module::Interface {
+public:
+ explicit ACC_AA(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_)
+ : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:aa") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "EnsureCacheAsync"},
+ {1, nullptr, "LoadCache"},
+ {2, nullptr, "GetDeviceAccountId"},
+ {50, nullptr, "RegisterNotificationTokenAsync"}, // 1.0.0 - 6.2.0
+ {51, nullptr, "UnregisterNotificationTokenAsync"}, // 1.0.0 - 6.2.0
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+ ~ACC_AA() override = default;
+};
+
+class ACC_SU final : public Module::Interface {
+public:
+ explicit ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_)
+ : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:su") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &ACC_SU::GetUserCount, "GetUserCount"},
+ {1, &ACC_SU::GetUserExistence, "GetUserExistence"},
+ {2, &ACC_SU::ListAllUsers, "ListAllUsers"},
+ {3, &ACC_SU::ListOpenUsers, "ListOpenUsers"},
+ {4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"},
+ {5, &ACC_SU::GetProfile, "GetProfile"},
+ {6, nullptr, "GetProfileDigest"},
+ {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
+ {51, &ACC_SU::TrySelectUserWithoutInteractionDeprecated, "TrySelectUserWithoutInteractionDeprecated"},
+ {52, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, // 19.0.0+
+ {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
+ {99, nullptr, "DebugActivateOpenContextRetention"},
+ {100, nullptr, "GetUserRegistrationNotifier"},
+ {101, nullptr, "GetUserStateChangeNotifier"},
+ {102, &ACC_SU::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"},
+ {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
+ {104, nullptr, "GetProfileUpdateNotifier"},
+ {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ {106, nullptr, "GetProfileSyncNotifier"},
+ {110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"},
+ {111, nullptr, "ClearSaveDataThumbnail"},
+ {112, nullptr, "LoadSaveDataThumbnail"},
+ {113, nullptr, "GetSaveDataThumbnailExistence"},
+ {120, nullptr, "ListOpenUsersInApplication"},
+ {130, nullptr, "ActivateOpenContextRetention"},
+ {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
+ {150, nullptr, "AuthenticateApplicationAsync"},
+ {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"},
+ {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
+ {190, nullptr, "GetUserLastOpenedApplication"},
+ {191, nullptr, "ActivateOpenContextHolder"},
+ {200, &ACC_SU::BeginUserRegistration, "BeginUserRegistration"},
+ {201, &ACC_SU::CompleteUserRegistration, "CompleteUserRegistration"},
+ {202, nullptr, "CancelUserRegistration"},
+ {203, &ACC_SU::DeleteUser, "DeleteUser"},
+ {204, &ACC_SU::SetUserPosition, "SetUserPosition"},
+ {205, &ACC_SU::GetProfileEditor, "GetProfileEditor"},
+ {206, nullptr, "CompleteUserRegistrationForcibly"},
+ {210, nullptr, "CreateFloatingRegistrationRequest"},
+ {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
+ {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
+ {230, nullptr, "AuthenticateServiceAsync"},
+ {250, &ACC_SU::GetBaasAccountAdministrator, "GetBaasAccountAdministrator"},
+ {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
+ {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
+ {299, nullptr, "SuspendBackgroundDaemon"},
+ {400, nullptr, "SetPinCode"}, // 18.0.0+
+ {401, &ACC_SU::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+
+ {402, nullptr, "GetPinCode"}, // 18.0.0+
+ {403, nullptr, "GetPinCodeParity"},
+ {404, nullptr, "VerifyPinCode"},
+ {405, nullptr, "IsPinCodeVerificationForbidden"},
+ {410, nullptr, "GetPinCodeErrorCount"}, // 18.0.0+
+ {411, nullptr, "ResetPinCodeErrorCount"}, // 18.0.0+
+ {412, nullptr, "IncrementPinCodeErrorCount"}, // 18.0.0+
+ {900, nullptr, "SetUserUnqualifiedForDebug"},
+ {901, nullptr, "UnsetUserUnqualifiedForDebug"},
+ {902, nullptr, "ListUsersUnqualifiedForDebug"},
+ {910, nullptr, "RefreshFirmwareSettingsForDebug"},
+ {997, nullptr, "DebugInvalidateTokenCacheForUser"},
+ {998, nullptr, "DebugSetUserStateClose"},
+ {999, nullptr, "DebugSetUserStateOpen"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+ ~ACC_SU() override = default;
+};
+
+class ACC_U0 final : public Module::Interface {
+public:
+ ACC_U0(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_)
+ : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:u0") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &ACC_U0::GetUserCount, "GetUserCount"},
+ {1, &ACC_U0::GetUserExistence, "GetUserExistence"},
+ {2, &ACC_U0::ListAllUsers, "ListAllUsers"},
+ {3, &ACC_U0::ListOpenUsers, "ListOpenUsers"},
+ {4, &ACC_U0::GetLastOpenedUser, "GetLastOpenedUser"},
+ {5, &ACC_U0::GetProfile, "GetProfile"},
+ {6, nullptr, "GetProfileDigest"}, // 3.0.0+
+ {50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
+ {51, &ACC_U0::TrySelectUserWithoutInteractionDeprecated, "TrySelectUserWithoutInteractionDeprecated"},
+ {52, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
+ {60, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
+ {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
+ {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
+ {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
+ {102, nullptr, "AuthenticateApplicationAsync"},
+ {103, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
+ {110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
+ {111, nullptr, "ClearSaveDataThumbnail"},
+ {120, nullptr, "CreateGuestLoginRequest"},
+ {130, nullptr, "LoadOpenContext"}, // 5.0.0+
+ {131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
+ {140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
+ {141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
+ {150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"}, // 6.0.0+
+ {160, &ACC_U0::InitializeApplicationInfoV2, "InitializeApplicationInfoV2"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+ ~ACC_U0() override = default;
+};
+
+class ACC_U1 final : public Module::Interface {
+public:
+ ACC_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:u1") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &ACC_U1::GetUserCount, "GetUserCount"},
+ {1, &ACC_U1::GetUserExistence, "GetUserExistence"},
+ {2, &ACC_U1::ListAllUsers, "ListAllUsers"},
+ {3, &ACC_U1::ListOpenUsers, "ListOpenUsers"},
+ {4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"},
+ {5, &ACC_U1::GetProfile, "GetProfile"},
+ {6, nullptr, "GetProfileDigest"},
+ {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
+ {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
+ {60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
+ {99, nullptr, "DebugActivateOpenContextRetention"},
+ {100, nullptr, "GetUserRegistrationNotifier"},
+ {101, nullptr, "GetUserStateChangeNotifier"},
+ {102, &ACC_U1::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"},
+ {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
+ {104, nullptr, "GetProfileUpdateNotifier"},
+ {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ {106, nullptr, "GetProfileSyncNotifier"},
+ {110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
+ {111, nullptr, "ClearSaveDataThumbnail"},
+ {112, nullptr, "LoadSaveDataThumbnail"},
+ {113, nullptr, "GetSaveDataThumbnailExistence"},
+ {120, nullptr, "ListOpenUsersInApplication"},
+ {130, nullptr, "ActivateOpenContextRetention"},
+ {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
+ {150, nullptr, "AuthenticateApplicationAsync"},
+ {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"},
+ {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
+ {190, nullptr, "GetUserLastOpenedApplication"},
+ {191, nullptr, "ActivateOpenContextHolder"},
+ {401, &ACC_U1::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+
+ {402, nullptr, "GetPinCode"}, // 18.0.0+
+ {997, nullptr, "DebugInvalidateTokenCacheForUser"},
+ {998, nullptr, "DebugSetUserStateClose"},
+ {999, nullptr, "DebugSetUserStateOpen"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+ ~ACC_U1() override = default;
+};
+
+class DAUTH_0 final : public ServiceFramework<DAUTH_0> {
+public:
+ explicit DAUTH_0(Core::System& system_) : ServiceFramework{system_, "dauth:0"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "EnsureAuthenticationTokenCacheAsync"},
+ {1, nullptr, "LoadAuthenticationTokenCache"},
+ {2, nullptr, "InvalidateAuthenticationTokenCache"},
+ {3, nullptr, "IsDeviceAuthenticationTokenCacheAvailable"},
+ {10, nullptr, "EnsureEdgeTokenCacheAsync"},
+ {11, nullptr, "LoadEdgeTokenCache"},
+ {12, nullptr, "InvalidateEdgeTokenCache"},
+ {13, nullptr, "IsEdgeTokenCacheAvailable"},
+ {20, nullptr, "EnsureApplicationAuthenticationCacheAsync"},
+ {21, nullptr, "LoadApplicationAuthenticationTokenCache"},
+ {22, nullptr, "LoadApplicationNetworkServiceClientConfigCache"},
+ {23, nullptr, "IsApplicationAuthenticationCacheAvailable"},
+ {24, nullptr, "InvalidateApplicationAuthenticationCache"},
+ {30, nullptr, "EnsureGameCardAuthenticationCacheAsync"},
+ {31, nullptr, "LoadGameCardAuthenticationTokenCache"},
+ {32, nullptr, "IsGameCardAuthenticationCacheAvailable"},
+ {33, nullptr, "InvalidateGameCardAuthenticationCache"},
+ {1000, nullptr, "GetInactiveElicenseUsedEvent"},
+ {9000, nullptr, "ImportVirtualClientCertificate"},
+ {9010, nullptr, "DeleteVirtualClientCertificate"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+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_)
+ : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:e") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "GetUserCount"},
+ { 1, nullptr, "GetUserExistence"},
+ { 2, nullptr, "ListAllUsers"},
+ { 3, nullptr, "ListOpenUsers"},
+ { 4, nullptr, "GetLastOpenedUser"},
+ { 5, nullptr, "GetProfile"},
+ { 6, nullptr, "GetProfileDigest"},
+ { 50, nullptr, "IsUserRegistrationRequestPermitted"},
+ { 51, nullptr, "TrySelectUserWithoutInteractionDeprecated"},
+ { 52, nullptr, "TrySelectUserWithoutInteraction"},
+ { 99, nullptr, "DebugActivateOpenContextRetention"},
+ { 100, nullptr, "GetUserRegistrationNotifier"},
+ { 101, nullptr, "GetUserStateChangeNotifier"},
+ { 102, nullptr, "GetBaasAccountManagerForSystemService"},
+ { 103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
+ { 104, nullptr, "GetProfileUpdateNotifier"},
+ { 105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ { 106, nullptr, "GetProfileSyncNotifier"},
+ { 110, nullptr, "StoreSaveDataThumbnail"},
+ { 111, nullptr, "ClearSaveDataThumbnail"},
+ { 112, nullptr, "LoadSaveDataThumbnail"},
+ { 113, nullptr, "GetSaveDataThumbnailExistence"},
+ { 120, nullptr, "ListOpenUsersInApplication"},
+ { 130, nullptr, "ActivateOpenContextRetention"},
+ { 140, nullptr, "ListQualifiedUsers"},
+ { 151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"},
+ { 152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
+ { 170, nullptr, "GetNasOp2MembershipStateChangeNotifier"},
+ { 191, nullptr, "UpdateNotificationReceiverInfo"},
+ { 200, nullptr, "BeginUserRegistration"},
+ { 201, nullptr, "CompleteUserRegistration"},
+ { 202, nullptr, "CancelUserRegistration"},
+ { 203, nullptr, "DeleteUser"},
+ { 204, nullptr, "SetUserPosition"},
+ { 205, nullptr, "GetProfileEditor"},
+ { 206, nullptr, "CompleteUserRegistrationForcibly"},
+ { 210, nullptr, "CreateFloatingRegistrationRequest"},
+ { 211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
+ { 212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
+ { 213, nullptr, "CreateProcedureToCreateUserWithNintendoAccount"},
+ { 214, nullptr, "ResumeProcedureToCreateUserWithNintendoAccount"},
+ { 215, nullptr, "ResumeProcedureToCreateUserWithNintendoAccountAfterApplyResponse"},
+ { 230, nullptr, "AuthenticateServiceAsync"},
+ { 250, nullptr, "GetBaasAccountAdministrator"},
+ { 251, nullptr, "SynchronizeNetworkServiceAccountsSnapshotAsync"},
+ { 290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
+ { 291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
+ { 292, nullptr, "ProxyProcedureForDeviceMigrationAuthenticatingOperatingUser"},
+ { 293, nullptr, "ProxyProcedureForDeviceMigrationDownload"},
+ { 299, nullptr, "SuspendBackgroundDaemon"},
+ { 350, nullptr, "CreateDeviceMigrationUserExportRequest"},
+ { 351, nullptr, "UploadNasCredential"},
+ { 352, nullptr, "CreateDeviceMigrationUserImportRequest"},
+ { 353, nullptr, "DeleteUserMigrationSaveData"},
+ { 400, nullptr, "SetPinCode"},
+ { 401, nullptr, "GetPinCodeLength"},
+ { 402, nullptr, "GetPinCode"},
+ { 403, nullptr, "GetPinCodeParity"},
+ { 404, nullptr, "VerifyPinCode"},
+ { 405, nullptr, "IsPinCodeVerificationForbidden"},
+ { 410, nullptr, "GetPinCodeErrorCount"},
+ { 411, nullptr, "ResetPinCodeErrorCount"},
+ { 412, nullptr, "IncrementPinCodeErrorCount"},
+ { 413, nullptr, "SetPinCodeErrorCount"},
+ { 420, nullptr, "SetStartPenaltyTime"},
+ { 421, nullptr, "GetStartPenaltyTime"},
+ { 900, nullptr, "SetUserUnqualifiedForDebug"},
+ { 901, nullptr, "UnsetUserUnqualifiedForDebug"},
+ { 902, nullptr, "ListUsersUnqualifiedForDebug"},
+ { 910, nullptr, "RefreshFirmwareSettingsForDebug"},
+ { 997, nullptr, "DebugInvalidateTokenCacheForUser"},
+ { 998, nullptr, "DebugSetUserStateClose"},
+ { 999, nullptr, "DebugSetUserStateOpen"},
+ { 1000, nullptr, "CreateIAccountEntityServiceForApplication"},
+ { 1100, nullptr, "CreateIUserStateManager"},
+ { 10050, nullptr, "IsUserRegistrationRequestPermittedForAccountPolicy"},
+ { 10105, nullptr, "CheckNetworkServiceAvailabilityAsyncForAccountPolicy"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+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_)
+ : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:e:u1") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetUserCount"},
+ {1, nullptr, "GetUserExistence"},
+ {2, nullptr, "ListAllUsers"},
+ {3, nullptr, "ListOpenUsers"},
+ {4, nullptr, "GetLastOpenedUser"},
+ {5, nullptr, "GetProfile"},
+ {6, nullptr, "GetProfileDigest"},
+ {50, nullptr, "IsUserRegistrationRequestPermitted"},
+ {51, nullptr, "TrySelectUserWithoutInteractionDeprecated"},
+ {99, nullptr, "DebugActivateOpenContextRetention"},
+ {100, nullptr, "GetUserRegistrationNotifier"},
+ {101, nullptr, "GetUserStateChangeNotifier"},
+ {102, nullptr, "GetBaasAccountManagerForSystemService"},
+ {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
+ {104, nullptr, "GetProfileUpdateNotifier"},
+ {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ {106, nullptr, "GetProfileSyncNotifier"},
+ {110, nullptr, "StoreSaveDataThumbnail"},
+ {111, nullptr, "ClearSaveDataThumbnail"},
+ {112, nullptr, "LoadSaveDataThumbnail"},
+ {113, nullptr, "GetSaveDataThumbnailExistence"},
+ {120, nullptr, "ListOpenUsersInApplication"},
+ {130, nullptr, "ActivateOpenContextRetention"},
+ {140, nullptr, "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);
+ }
+};
+
+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_)
+ : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:e:u2") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetUserCount"},
+ {1, nullptr, "GetUserExistence"},
+ {2, nullptr, "ListAllUsers"},
+ {3, nullptr, "ListOpenUsers"},
+ {4, nullptr, "GetLastOpenedUser"},
+ {5, nullptr, "GetProfile"},
+ {6, nullptr, "GetProfileDigest"},
+ {50, nullptr, "#IsUserRegistrationRequestPermitted"},
+ {51, nullptr, "TrySelectUserWithoutInteractionDeprecated"},
+ {52, nullptr, "TrySelectUserWithoutInteraction"},
+ {99, nullptr, "DebugActivateOpenContextRetention"},
+ {100, nullptr, "GetUserRegistrationNotifier"},
+ {101, nullptr, "GetUserStateChangeNotifier"},
+ {102, nullptr, "GetBaasAccountManagerForSystemService"},
+ {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
+ {104, nullptr, "GetProfileUpdateNotifier"},
+ {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
+ {106, nullptr, "GetProfileSyncNotifier"},
+ {110, nullptr, "StoreSaveDataThumbnail"},
+ {111, nullptr, "ClearSaveDataThumbnail"},
+ {112, nullptr, "LoadSaveDataThumbnail"},
+ {113, nullptr, "GetSaveDataThumbnailExistence"},
+ {120, nullptr, "ListOpenUsersInApplication"},
+ {130, nullptr, "ActivateOpenContextRetention"},
+ {140, nullptr, "ListQualifiedUsers"},
+ {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"},
+ {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
+ {170, nullptr, "GetNasOp2MembershipStateChangeNotifier"},
+ {191, nullptr, "UpdateNotificationReceiverInfo"},
+ {205, nullptr, "GetProfileEditor"},
+ {401, nullptr, "GetPinCodeLength"},
+ {402, nullptr, "GetPinCode"},
+ {403, nullptr, "GetPinCodeParity"},
+ {404, nullptr, "VerifyPinCode"},
+ {405, nullptr, "IsPinCodeVerificationForbidden"},
+ {997, nullptr, "DebugInvalidateTokenCacheForUser"},
+ {998, nullptr, "DebugSetUserStateClose"},
+ {999, nullptr, "DebugSetUserStateOpen"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto module = std::make_shared<Module>();
auto profile_manager = std::make_shared<ProfileManager>();
auto server_manager = std::make_unique<ServerManager>(system);
- server_manager->RegisterNamedService("acc:aa",
- std::make_shared<ACC_AA>(module, profile_manager, system));
- server_manager->RegisterNamedService("acc:su",
- std::make_shared<ACC_SU>(module, profile_manager, system));
- server_manager->RegisterNamedService("acc:u0",
- std::make_shared<ACC_U0>(module, profile_manager, system));
- server_manager->RegisterNamedService("acc:u1",
- std::make_shared<ACC_U1>(module, profile_manager, system));
+ server_manager->RegisterNamedService("acc:aa", std::make_shared<ACC_AA>(module, profile_manager, system));
+ server_manager->RegisterNamedService("acc:su", std::make_shared<ACC_SU>(module, profile_manager, system));
+ server_manager->RegisterNamedService("acc:u0", std::make_shared<ACC_U0>(module, profile_manager, system));
+ server_manager->RegisterNamedService("acc:u1", std::make_shared<ACC_U1>(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("dauth:0", std::make_shared<DAUTH_0>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/acc/acc_aa.cpp b/src/core/hle/service/acc/acc_aa.cpp
deleted file mode 100644
index 90ed0f5197..0000000000
--- a/src/core/hle/service/acc/acc_aa.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/acc/acc_aa.h"
-
-namespace Service::Account {
-
-ACC_AA::ACC_AA(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> profile_manager_,
- Core::System& system_)
- : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:aa") {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, nullptr, "EnsureCacheAsync"},
- {1, nullptr, "LoadCache"},
- {2, nullptr, "GetDeviceAccountId"},
- {50, nullptr, "RegisterNotificationTokenAsync"}, // 1.0.0 - 6.2.0
- {51, nullptr, "UnregisterNotificationTokenAsync"}, // 1.0.0 - 6.2.0
- };
- // clang-format on
- RegisterHandlers(functions);
-}
-
-ACC_AA::~ACC_AA() = default;
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_aa.h b/src/core/hle/service/acc/acc_aa.h
deleted file mode 100644
index 623daeaef0..0000000000
--- a/src/core/hle/service/acc/acc_aa.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/acc/acc.h"
-
-namespace Service::Account {
-
-class ACC_AA final : public Module::Interface {
-public:
- explicit ACC_AA(std::shared_ptr<Module> module_,
- std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
- ~ACC_AA() override;
-};
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
deleted file mode 100644
index 195af7ff69..0000000000
--- a/src/core/hle/service/acc/acc_su.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/acc/acc_su.h"
-
-namespace Service::Account {
-
-ACC_SU::ACC_SU(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> profile_manager_,
- Core::System& system_)
- : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:su") {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &ACC_SU::GetUserCount, "GetUserCount"},
- {1, &ACC_SU::GetUserExistence, "GetUserExistence"},
- {2, &ACC_SU::ListAllUsers, "ListAllUsers"},
- {3, &ACC_SU::ListOpenUsers, "ListOpenUsers"},
- {4, &ACC_SU::GetLastOpenedUser, "GetLastOpenedUser"},
- {5, &ACC_SU::GetProfile, "GetProfile"},
- {6, nullptr, "GetProfileDigest"},
- {50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
- {51, &ACC_SU::TrySelectUserWithoutInteractionDeprecated, "TrySelectUserWithoutInteractionDeprecated"},
- {52, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"}, // 19.0.0+
- {60, &ACC_SU::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
- {99, nullptr, "DebugActivateOpenContextRetention"},
- {100, nullptr, "GetUserRegistrationNotifier"},
- {101, nullptr, "GetUserStateChangeNotifier"},
- {102, &ACC_SU::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"},
- {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
- {104, nullptr, "GetProfileUpdateNotifier"},
- {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
- {106, nullptr, "GetProfileSyncNotifier"},
- {110, &ACC_SU::StoreSaveDataThumbnailSystem, "StoreSaveDataThumbnail"},
- {111, nullptr, "ClearSaveDataThumbnail"},
- {112, nullptr, "LoadSaveDataThumbnail"},
- {113, nullptr, "GetSaveDataThumbnailExistence"},
- {120, nullptr, "ListOpenUsersInApplication"},
- {130, nullptr, "ActivateOpenContextRetention"},
- {140, &ACC_SU::ListQualifiedUsers, "ListQualifiedUsers"},
- {150, nullptr, "AuthenticateApplicationAsync"},
- {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"},
- {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
- {190, nullptr, "GetUserLastOpenedApplication"},
- {191, nullptr, "ActivateOpenContextHolder"},
- {200, &ACC_SU::BeginUserRegistration, "BeginUserRegistration"},
- {201, &ACC_SU::CompleteUserRegistration, "CompleteUserRegistration"},
- {202, nullptr, "CancelUserRegistration"},
- {203, &ACC_SU::DeleteUser, "DeleteUser"},
- {204, &ACC_SU::SetUserPosition, "SetUserPosition"},
- {205, &ACC_SU::GetProfileEditor, "GetProfileEditor"},
- {206, nullptr, "CompleteUserRegistrationForcibly"},
- {210, nullptr, "CreateFloatingRegistrationRequest"},
- {211, nullptr, "CreateProcedureToRegisterUserWithNintendoAccount"},
- {212, nullptr, "ResumeProcedureToRegisterUserWithNintendoAccount"},
- {230, nullptr, "AuthenticateServiceAsync"},
- {250, &ACC_SU::GetBaasAccountAdministrator, "GetBaasAccountAdministrator"},
- {290, nullptr, "ProxyProcedureForGuestLoginWithNintendoAccount"},
- {291, nullptr, "ProxyProcedureForFloatingRegistrationWithNintendoAccount"},
- {299, nullptr, "SuspendBackgroundDaemon"},
- {400, nullptr, "SetPinCode"}, // 18.0.0+
- {401, &ACC_SU::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+
- {402, nullptr, "GetPinCode"}, // 18.0.0+
- {410, nullptr, "GetPinCodeErrorCount"}, // 18.0.0+
- {411, nullptr, "ResetPinCodeErrorCount"}, // 18.0.0+
- {412, nullptr, "IncrementPinCodeErrorCount"}, // 18.0.0+
- {900, nullptr, "SetUserUnqualifiedForDebug"},
- {901, nullptr, "UnsetUserUnqualifiedForDebug"},
- {902, nullptr, "ListUsersUnqualifiedForDebug"},
- {910, nullptr, "RefreshFirmwareSettingsForDebug"},
- {997, nullptr, "DebugInvalidateTokenCacheForUser"},
- {998, nullptr, "DebugSetUserStateClose"},
- {999, nullptr, "DebugSetUserStateOpen"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
-}
-
-ACC_SU::~ACC_SU() = default;
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_su.h b/src/core/hle/service/acc/acc_su.h
deleted file mode 100644
index 8daef38b8b..0000000000
--- a/src/core/hle/service/acc/acc_su.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/acc/acc.h"
-
-namespace Service::Account {
-
-class ACC_SU final : public Module::Interface {
-public:
- explicit ACC_SU(std::shared_ptr<Module> module_,
- std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
- ~ACC_SU() override;
-};
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
deleted file mode 100644
index df4e5ad00b..0000000000
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/acc/acc_u0.h"
-
-namespace Service::Account {
-
-ACC_U0::ACC_U0(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> profile_manager_,
- Core::System& system_)
- : Interface(std::move(module_), std::move(profile_manager_), system_, "acc:u0") {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &ACC_U0::GetUserCount, "GetUserCount"},
- {1, &ACC_U0::GetUserExistence, "GetUserExistence"},
- {2, &ACC_U0::ListAllUsers, "ListAllUsers"},
- {3, &ACC_U0::ListOpenUsers, "ListOpenUsers"},
- {4, &ACC_U0::GetLastOpenedUser, "GetLastOpenedUser"},
- {5, &ACC_U0::GetProfile, "GetProfile"},
- {6, nullptr, "GetProfileDigest"}, // 3.0.0+
- {50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
- {51, &ACC_U0::TrySelectUserWithoutInteractionDeprecated, "TrySelectUserWithoutInteractionDeprecated"},
- {52, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
- {60, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 5.0.0 - 5.1.0
- {99, nullptr, "DebugActivateOpenContextRetention"}, // 6.0.0+
- {100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
- {101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
- {102, nullptr, "AuthenticateApplicationAsync"},
- {103, nullptr, "CheckNetworkServiceAvailabilityAsync"}, // 4.0.0+
- {110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
- {111, nullptr, "ClearSaveDataThumbnail"},
- {120, nullptr, "CreateGuestLoginRequest"},
- {130, nullptr, "LoadOpenContext"}, // 5.0.0+
- {131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
- {140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
- {141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
- {150, &ACC_U0::IsUserAccountSwitchLocked, "IsUserAccountSwitchLocked"}, // 6.0.0+
- {160, &ACC_U0::InitializeApplicationInfoV2, "InitializeApplicationInfoV2"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
-}
-
-ACC_U0::~ACC_U0() = default;
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_u0.h b/src/core/hle/service/acc/acc_u0.h
deleted file mode 100644
index 35cd4b492c..0000000000
--- a/src/core/hle/service/acc/acc_u0.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/acc/acc.h"
-
-namespace Service::Account {
-
-class ACC_U0 final : public Module::Interface {
-public:
- explicit ACC_U0(std::shared_ptr<Module> module_,
- std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
- ~ACC_U0() override;
-};
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp
deleted file mode 100644
index c39e916366..0000000000
--- a/src/core/hle/service/acc/acc_u1.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/service/acc/acc_u1.h"
-
-namespace Service::Account {
-
-ACC_U1::ACC_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:u1") {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &ACC_U1::GetUserCount, "GetUserCount"},
- {1, &ACC_U1::GetUserExistence, "GetUserExistence"},
- {2, &ACC_U1::ListAllUsers, "ListAllUsers"},
- {3, &ACC_U1::ListOpenUsers, "ListOpenUsers"},
- {4, &ACC_U1::GetLastOpenedUser, "GetLastOpenedUser"},
- {5, &ACC_U1::GetProfile, "GetProfile"},
- {6, nullptr, "GetProfileDigest"},
- {50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
- {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
- {60, &ACC_U1::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"},
- {99, nullptr, "DebugActivateOpenContextRetention"},
- {100, nullptr, "GetUserRegistrationNotifier"},
- {101, nullptr, "GetUserStateChangeNotifier"},
- {102, &ACC_U1::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"},
- {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"},
- {104, nullptr, "GetProfileUpdateNotifier"},
- {105, nullptr, "CheckNetworkServiceAvailabilityAsync"},
- {106, nullptr, "GetProfileSyncNotifier"},
- {110, &ACC_U1::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
- {111, nullptr, "ClearSaveDataThumbnail"},
- {112, nullptr, "LoadSaveDataThumbnail"},
- {113, nullptr, "GetSaveDataThumbnailExistence"},
- {120, nullptr, "ListOpenUsersInApplication"},
- {130, nullptr, "ActivateOpenContextRetention"},
- {140, &ACC_U1::ListQualifiedUsers, "ListQualifiedUsers"},
- {150, nullptr, "AuthenticateApplicationAsync"},
- {151, nullptr, "EnsureSignedDeviceIdentifierCacheForNintendoAccountAsync"},
- {152, nullptr, "LoadSignedDeviceIdentifierCacheForNintendoAccount"},
- {190, nullptr, "GetUserLastOpenedApplication"},
- {191, nullptr, "ActivateOpenContextHolder"},
- {401, &ACC_U1::GetPinCodeLength, "GetPinCodeLength"}, // 18.0.0+
- {402, nullptr, "GetPinCode"}, // 18.0.0+
- {997, nullptr, "DebugInvalidateTokenCacheForUser"},
- {998, nullptr, "DebugSetUserStateClose"},
- {999, nullptr, "DebugSetUserStateOpen"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
-}
-
-ACC_U1::~ACC_U1() = default;
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/acc/acc_u1.h b/src/core/hle/service/acc/acc_u1.h
deleted file mode 100644
index e711d39252..0000000000
--- a/src/core/hle/service/acc/acc_u1.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/acc/acc.h"
-
-namespace Service::Account {
-
-class ACC_U1 final : public Module::Interface {
-public:
- explicit ACC_U1(std::shared_ptr<Module> module_,
- std::shared_ptr<ProfileManager> profile_manager_, Core::System& system_);
- ~ACC_U1() override;
-};
-
-} // namespace Service::Account
diff --git a/src/core/hle/service/apm/apm_controller.cpp b/src/core/hle/service/apm/apm_controller.cpp
index 2149af2c3c..651de2493f 100644
--- a/src/core/hle/service/apm/apm_controller.cpp
+++ b/src/core/hle/service/apm/apm_controller.cpp
@@ -26,8 +26,7 @@ Controller::Controller(Core::Timing::CoreTiming& core_timing_)
Controller::~Controller() = default;
-void Controller::SetPerformanceConfiguration(PerformanceMode mode,
- PerformanceConfiguration config) {
+void Controller::SetPerformanceConfiguration(PerformanceMode mode, PerformanceConfiguration config) {
static constexpr std::array<std::pair<PerformanceConfiguration, u32>, 16> config_to_speed{{
{PerformanceConfiguration::Config1, 1020},
{PerformanceConfiguration::Config2, 1020},
@@ -46,17 +45,14 @@ void Controller::SetPerformanceConfiguration(PerformanceMode mode,
{PerformanceConfiguration::Config15, 1020},
{PerformanceConfiguration::Config16, 1020},
}};
-
- const auto iter = std::find_if(config_to_speed.cbegin(), config_to_speed.cend(),
- [config](const auto& entry) { return entry.first == config; });
-
- if (iter == config_to_speed.cend()) {
+ if (auto const it = std::find_if(config_to_speed.cbegin(), config_to_speed.cend(), [config](const auto& e) {
+ return e.first == config;
+ }); it != config_to_speed.cend()) {
+ SetClockSpeed(it->second);
+ configs.insert_or_assign(mode, config);
+ } else {
LOG_ERROR(Service_APM, "Invalid performance configuration value provided: {}", config);
- return;
}
-
- SetClockSpeed(iter->second);
- configs.insert_or_assign(mode, config);
}
void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
@@ -65,9 +61,11 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
PerformanceConfiguration::Config13,
PerformanceConfiguration::Config15,
}};
-
- SetPerformanceConfiguration(PerformanceMode::Boost,
- BOOST_MODE_TO_CONFIG_MAP.at(static_cast<u32>(mode)));
+ if (u32(mode) < BOOST_MODE_TO_CONFIG_MAP.size()) {
+ SetPerformanceConfiguration(PerformanceMode::Boost, BOOST_MODE_TO_CONFIG_MAP[u32(mode)]);
+ } else {
+ LOG_ERROR(Service_APM, "{} invalid mode", mode);
+ }
}
PerformanceMode Controller::GetCurrentPerformanceMode() const {
@@ -78,7 +76,6 @@ PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(Performa
if (configs.find(mode) == configs.end()) {
configs.insert_or_assign(mode, DEFAULT_PERFORMANCE_CONFIGURATION);
}
-
return configs[mode];
}
diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp
index 7637ed5bf5..c433283304 100644
--- a/src/core/hle/service/audio/audio.cpp
+++ b/src/core/hle/service/audio/audio.cpp
@@ -18,16 +18,192 @@
namespace Service::Audio {
+class IAudioOutManagerForApplet final : public ServiceFramework<IAudioOutManagerForApplet> {
+public:
+ explicit IAudioOutManagerForApplet(Core::System& system_)
+ : ServiceFramework{system_, "audout:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ {2, nullptr, "GetProcessMasterVolume"},
+ {3, nullptr, "SetProcessMasterVolume"},
+ {4, nullptr, "GetProcessRecordVolume"},
+ {5, nullptr, "SetProcessRecordVolume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioSnoopManager final : public ServiceFramework<IAudioSnoopManager> {
+public:
+ explicit IAudioSnoopManager(Core::System& system_)
+ : ServiceFramework{system_, "auddev"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetDspStatistics"},
+ {1, nullptr, "GetAppletStateSummaries"},
+ {2, nullptr, "SetDspStatisticsParameter"},
+ {3, nullptr, "GetDspStatisticsParameter"},
+ {6, nullptr, "GetDspUsage"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioInManagerForApplet final : public ServiceFramework<IAudioInManagerForApplet> {
+public:
+ explicit IAudioInManagerForApplet(Core::System& system_)
+ : ServiceFramework{system_, "audin:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ {2, nullptr, "GetProcessMasterVolume"},
+ {3, nullptr, "SetProcessMasterVolume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioRendererManagerForApplet final : public ServiceFramework<IAudioRendererManagerForApplet> {
+public:
+ explicit IAudioRendererManagerForApplet(Core::System& system_)
+ : ServiceFramework{system_, "audren:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ {2, nullptr, "GetProcessMasterVolume"},
+ {3, nullptr, "SetProcessMasterVolume"},
+ {4, nullptr, "RegisterAppletResourceUserId"},
+ {5, nullptr, "UnregisterAppletResourceUserId"},
+ {6, nullptr, "GetProcessRecordVolume"},
+ {7, nullptr, "SetProcessRecordVolume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioOutManagerForDebugger final : public ServiceFramework<IAudioOutManagerForDebugger> {
+public:
+ explicit IAudioOutManagerForDebugger(Core::System& system_)
+ : ServiceFramework{system_, "audout:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioInManagerForDebugger final : public ServiceFramework<IAudioInManagerForDebugger> {
+public:
+ explicit IAudioInManagerForDebugger(Core::System& system_)
+ : ServiceFramework{system_, "audin:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IFinalOutputRecorderManagerForDebugger final : public ServiceFramework<IFinalOutputRecorderManagerForDebugger> {
+public:
+ explicit IFinalOutputRecorderManagerForDebugger(Core::System& system_)
+ : ServiceFramework{system_, "audrec:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioRendererManagerForDebugger final : public ServiceFramework<IAudioRendererManagerForDebugger> {
+public:
+ explicit IAudioRendererManagerForDebugger(Core::System& system_)
+ : ServiceFramework{system_, "audren:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspend"},
+ {1, nullptr, "RequestResume"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioSystemManagerForApplet final : public ServiceFramework<IAudioSystemManagerForApplet> {
+public:
+ explicit IAudioSystemManagerForApplet(Core::System& system_)
+ : ServiceFramework{system_, "aud:a"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RegisterAppletResourceUserId"},
+ {1, nullptr, "UnregisterAppletResourceUserId"},
+ {2, nullptr, "RequestSuspendAudio"},
+ {3, nullptr, "RequestResumeAudio"},
+ {4, nullptr, "GetAudioOutputProcessMasterVolume"},
+ {5, nullptr, "SetAudioOutputProcessMasterVolume"},
+ {6, nullptr, "GetAudioInputProcessMasterVolume"},
+ {7, nullptr, "SetAudioInputProcessMasterVolume"},
+ {8, nullptr, "GetAudioOutputProcessRecordVolume"},
+ {9, nullptr, "SetAudioOutputProcessRecordVolume"},
+ {10, nullptr, "GetAppletStateSummaries"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IAudioSystemManagerForDebugger final : public ServiceFramework<IAudioSystemManagerForDebugger> {
+public:
+ explicit IAudioSystemManagerForDebugger(Core::System& system_)
+ : ServiceFramework{system_, "aud:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RequestSuspendAudioForDebug"},
+ {1, nullptr, "RequestResumeAudioForDebug"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
+ server_manager->RegisterNamedService("aud:a", std::make_shared<IAudioSystemManagerForApplet>(system));
+ server_manager->RegisterNamedService("aud:d", std::make_shared<IAudioSystemManagerForDebugger>(system));
+
+ server_manager->RegisterNamedService("audout:d", std::make_shared<IAudioOutManagerForDebugger>(system));
+ server_manager->RegisterNamedService("audin:d", std::make_shared<IAudioInManagerForDebugger>(system));
+ server_manager->RegisterNamedService("audrec:d", std::make_shared<IFinalOutputRecorderManagerForDebugger>(system));
+ server_manager->RegisterNamedService("audren:d", std::make_shared<IAudioInManager>(system));
+
server_manager->RegisterNamedService("audin:u", std::make_shared<IAudioInManager>(system));
+ server_manager->RegisterNamedService("audin:a", std::make_shared<IAudioInManagerForApplet>(system));
server_manager->RegisterNamedService("audout:u", std::make_shared<IAudioOutManager>(system));
+ server_manager->RegisterNamedService("audout:a", std::make_shared<IAudioOutManagerForApplet>(system));
+ server_manager->RegisterNamedService("auddev", std::make_shared<IAudioSnoopManager>(system));
// Depends on audout:u and audin:u on ctor!
server_manager->RegisterNamedService("audctl", std::make_shared<IAudioController>(system));
server_manager->RegisterNamedService("audrec:a", std::make_shared<IFinalOutputRecorderManagerForApplet>(system));
server_manager->RegisterNamedService("audrec:u", std::make_shared<IFinalOutputRecorderManager>(system));
server_manager->RegisterNamedService("audren:u", std::make_shared<IAudioRendererManager>(system));
+ server_manager->RegisterNamedService("audren:a", std::make_shared<IAudioRendererManagerForApplet>(system));
server_manager->RegisterNamedService("hwopus", std::make_shared<IHardwareOpusDecoderManager>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/audio/audio_renderer_manager.cpp b/src/core/hle/service/audio/audio_renderer_manager.cpp
index 972e930a89..4756802eeb 100644
--- a/src/core/hle/service/audio/audio_renderer_manager.cpp
+++ b/src/core/hle/service/audio/audio_renderer_manager.cpp
@@ -11,6 +11,7 @@
#include "core/hle/service/audio/audio_device.h"
#include "core/hle/service/audio/audio_renderer.h"
#include "core/hle/service/audio/audio_renderer_manager.h"
+#include "core/hle/service/audio/errors.h"
#include "core/hle/service/cmif_serialization.h"
namespace Service::Audio {
@@ -54,6 +55,11 @@ Result IAudioRendererManager::OpenAudioRenderer(
R_THROW(Audio::ResultOutOfSessions);
}
+ if (!process_handle) {
+ LOG_ERROR(Service_Audio, "Invalid handles");
+ R_THROW(Audio::ResultInvalidHandle);
+ }
+
LOG_DEBUG(Service_Audio, "Opened new AudioRenderer session {} sessions open {}", session_id,
impl->GetSessionCount());
diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp
index 91b15e256c..6fd7001821 100644
--- a/src/core/hle/service/bpc/bpc.cpp
+++ b/src/core/hle/service/bpc/bpc.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -54,11 +57,58 @@ public:
}
};
+class BPC_C final : public ServiceFramework<BPC_C> {
+public:
+ explicit BPC_C(Core::System& system_) : ServiceFramework{system_, "bpc:c"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "ShutdownSystem"},
+ {1, nullptr, "RebootSystem"},
+ {2, nullptr, "GetWakeupReason"},
+ {3, nullptr, "GetShutdownReason"},
+ {4, nullptr, "GetAcOk"},
+ {5, nullptr, "GetPowerEvent"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class BPC_B final : public ServiceFramework<BPC_B> {
+public:
+ explicit BPC_B(Core::System& system_) : ServiceFramework{system_, "bpc:b"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetSleepButtonState"},
+ {1, nullptr, "GetPowerButtonEvent"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class BPC_W final : public ServiceFramework<BPC_W> {
+public:
+ explicit BPC_W(Core::System& system_) : ServiceFramework{system_, "bpc:w"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "CreateWakeupTimer"},
+ {1, nullptr, "CancelWakeupTimer"},
+ {2, nullptr, "EnableWakeupTimerOnDevice"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("bpc", std::make_shared<BPC>(system));
server_manager->RegisterNamedService("bpc:r", std::make_shared<BPC_R>(system));
+ server_manager->RegisterNamedService("bpc:c", std::make_shared<BPC_C>(system));
+ server_manager->RegisterNamedService("bpc:b", std::make_shared<BPC_B>(system));
+ server_manager->RegisterNamedService("bpc:w", std::make_shared<BPC_W>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp
index cd1dfe9939..f07fbd2185 100644
--- a/src/core/hle/service/caps/caps.cpp
+++ b/src/core/hle/service/caps/caps.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -11,27 +14,38 @@
#include "core/hle/service/caps/caps_u.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
+#include "frontend_common/firmware_manager.h"
namespace Service::Capture {
+class IDecoderControlService final : public ServiceFramework<IDecoderControlService> {
+public:
+ explicit IDecoderControlService(Core::System& system_) : ServiceFramework{system_, "grc:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {3001, nullptr, "DecodeJpeg"},
+ {4001, nullptr, "ShrinkJpeg"},
+ {4002, nullptr, "ShrinkJpegEx"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
auto album_manager = std::make_shared<AlbumManager>(system);
- server_manager->RegisterNamedService(
- "caps:a", std::make_shared<IAlbumAccessorService>(system, album_manager));
- server_manager->RegisterNamedService(
- "caps:c", std::make_shared<IAlbumControlService>(system, album_manager));
- server_manager->RegisterNamedService(
- "caps:u", std::make_shared<IAlbumApplicationService>(system, album_manager));
-
- server_manager->RegisterNamedService(
- "caps:ss", std::make_shared<IScreenShotService>(system, album_manager));
- server_manager->RegisterNamedService("caps:sc",
- std::make_shared<IScreenShotControlService>(system));
- server_manager->RegisterNamedService(
- "caps:su", std::make_shared<IScreenShotApplicationService>(system, album_manager));
-
+ server_manager->RegisterNamedService("caps:a", std::make_shared<IAlbumAccessorService>(system, album_manager));
+ server_manager->RegisterNamedService("caps:c", std::make_shared<IAlbumControlService>(system, album_manager));
+ server_manager->RegisterNamedService("caps:u", std::make_shared<IAlbumApplicationService>(system, album_manager));
+ server_manager->RegisterNamedService("caps:ss", std::make_shared<IScreenShotService>(system, album_manager));
+ server_manager->RegisterNamedService("caps:sc", std::make_shared<IScreenShotControlService>(system));
+ server_manager->RegisterNamedService("caps:su", std::make_shared<IScreenShotApplicationService>(system, album_manager));
+ // +4.0.0
+ if (FirmwareManager::GetFirmwareVersion(system).first.major >= 4) {
+ server_manager->RegisterNamedService("caps:dc", std::make_shared<IDecoderControlService>(system));
+ }
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/caps/caps_manager.cpp b/src/core/hle/service/caps/caps_manager.cpp
index af0b9b16ad..08725cb565 100644
--- a/src/core/hle/service/caps/caps_manager.cpp
+++ b/src/core/hle/service/caps/caps_manager.cpp
@@ -243,13 +243,10 @@ Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
return SaveScreenShot(out_entry, attribute, report_option, {}, image_data, aruid);
}
-Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
- const ScreenShotAttribute& attribute,
- AlbumReportOption report_option,
- const ApplicationData& app_data, std::span<const u8> image_data,
- u64 aruid) {
- const u64 title_id = system.GetApplicationProcessProgramID();
+Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, AlbumReportOption report_option, const ApplicationData& app_data, std::span<const u8> image_data, u64 aruid) {
+ R_UNLESS(!image_data.empty(), ResultUnknown); //TODO: ???
+ const u64 title_id = system.GetApplicationProcessProgramID();
auto static_service =
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
@@ -264,14 +261,12 @@ Result AlbumManager::SaveScreenShot(ApplicationAlbumEntry& out_entry,
}
const auto date = ConvertToAlbumDateTime(posix_time);
-
return SaveImage(out_entry, image_data, title_id, date);
}
-Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,
- const ScreenShotAttribute& attribute,
- const AlbumFileId& file_id,
- std::span<const u8> image_data) {
+Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry, const ScreenShotAttribute& attribute, const AlbumFileId& file_id, std::span<const u8> image_data) {
+ R_UNLESS(!image_data.empty(), ResultUnknown); //TODO: ???
+
auto static_service =
system.ServiceManager().GetService<Service::Glue::Time::StaticService>("time:u", true);
@@ -286,7 +281,6 @@ Result AlbumManager::SaveEditedScreenShot(ApplicationAlbumEntry& out_entry,
}
const auto date = ConvertToAlbumDateTime(posix_time);
-
return SaveImage(out_entry, image_data, file_id.application_id, date);
}
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp
index 5adf248684..432783f96e 100644
--- a/src/core/hle/service/es/es.cpp
+++ b/src/core/hle/service/es/es.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -9,6 +9,7 @@
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
+#include "frontend_common/firmware_manager.h"
namespace Service::ES {
@@ -319,10 +320,98 @@ private:
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
};
+class NDRM_LU final : public ServiceFramework<NDRM_LU> {
+public:
+ explicit NDRM_LU(Core::System& system_)
+ : ServiceFramework{system_, "ndrm:lu"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {1, nullptr, "Cmd1"},
+ {2, nullptr, "Cmd2"},
+ {3, nullptr, "Cmd3"},
+ {1000, nullptr, "Cmd1000"},
+ {8000, nullptr, "Cmd8000"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class NDRM_LA final : public ServiceFramework<NDRM_LA> {
+public:
+ explicit NDRM_LA(Core::System& system_)
+ : ServiceFramework{system_, "ndrm:la"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {1, nullptr, "Cmd1"},
+ {2, nullptr, "Cmd2"},
+ {3, nullptr, "Cmd3"},
+ {4, nullptr, "Cmd4"},
+ {5, nullptr, "Cmd5"},
+ {6, nullptr, "Cmd6"},
+ {7, nullptr, "Cmd7"},
+ {8, nullptr, "Cmd8"},
+ {9, nullptr, "Cmd9"},
+ {10, nullptr, "Cmd10"},
+ {11, nullptr, "Cmd11"},
+ {12, nullptr, "Cmd12"},
+ {13, nullptr, "Cmd13"},
+ {14, nullptr, "Cmd14"},
+ {15, nullptr, "Cmd15"},
+ {16, nullptr, "Cmd16"},
+ {17, nullptr, "Cmd17"},
+ {18, nullptr, "Cmd18"},
+ {19, nullptr, "Cmd19"},
+ {20, nullptr, "Cmd20"},
+ {21, nullptr, "Cmd21"},
+ {22, nullptr, "Cmd22"},
+ {23, nullptr, "Cmd23"},
+ {24, nullptr, "Cmd24"},
+ {25, nullptr, "Cmd25"},
+ {26, nullptr, "Cmd26"},
+ {27, nullptr, "Cmd27"},
+ {28, nullptr, "Cmd28"},
+ {29, nullptr, "Cmd29"},
+ {30, nullptr, "Cmd30"},
+ {31, nullptr, "Cmd31"},
+ {32, nullptr, "Cmd32"},
+ {33, nullptr, "Cmd33"},
+ {34, nullptr, "Cmd34"},
+ {35, nullptr, "Cmd35"},
+ {36, nullptr, "Cmd36"},
+ {37, nullptr, "Cmd37"},
+ {38, nullptr, "Cmd38"},
+ {39, nullptr, "Cmd39"},
+ {40, nullptr, "Cmd40"},
+ {42, nullptr, "Cmd42"},
+ {43, nullptr, "Cmd43"},
+ {44, nullptr, "Cmd44"},
+ {45, nullptr, "Cmd45"},
+ {46, nullptr, "Cmd46"},
+ {47, nullptr, "Cmd47"},
+ {48, nullptr, "Cmd48"},
+ {49, nullptr, "Cmd49"},
+ {50, nullptr, "Cmd50"},
+ {51, nullptr, "Cmd51"},
+ {8000, nullptr, "Cmd8000"},
+ {8001, nullptr, "Cmd8001"},
+ {8002, nullptr, "Cmd8002"},
+ {8003, nullptr, "Cmd8003"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("es", std::make_shared<ETicket>(system));
+ // +13.0.0
+ if (FirmwareManager::GetFirmwareVersion(system).first.major >= 13) {
+ server_manager->RegisterNamedService("ndrm:lu", std::make_shared<NDRM_LU>(system));
+ server_manager->RegisterNamedService("ndrm:la", std::make_shared<NDRM_LA>(system));
+ }
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index de23185591..f8690dbb8b 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -497,20 +497,79 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst
Module::Interface::~Interface() = default;
+class IServiceForApplication final : public ServiceFramework<IServiceForApplication> {
+public:
+ explicit IServiceForApplication(Core::System& system_)
+ : ServiceFramework{system_, "nd:app"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetReceivableNeighborInfoCountMax"},
+ {10, nullptr, "IsNeighborDetectionEnabled"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class IServiceForSystem final : public ServiceFramework<IServiceForSystem> {
+public:
+ explicit IServiceForSystem(Core::System& system_)
+ : ServiceFramework{system_, "nd:sys"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetReceivableNeighborInfoCountMax"},
+ {10, nullptr, "IsNeighborDetectionEnabled"},
+ {200, nullptr, "SetSystemData"},
+ {201, nullptr, "ClearSystemData"},
+ {203, nullptr, "GetReceivableNeighborInfoCountForSystem"},
+ {204, nullptr, "ReceiveNeighborInfoForSystem"},
+ {205, nullptr, "SetSender"},
+ {206, nullptr, "GetSender"},
+ {207, nullptr, "CreateScannerForSystem"},
+ {208, nullptr, "CreateReceiveEventHolderForSystem"},
+ {223, nullptr, "EnableNeighborDetection"},
+ {224, nullptr, "DisableNeighborDetection"},
+ {226, nullptr, "EnablePowerSave"},
+ {227, nullptr, "DisablePowerSave"},
+ {228, nullptr, "IsPowerSaveEnabled"},
+ {232, nullptr, "ClearBlockedUsers"},
+ {233, nullptr, "GetBlockedUserCount"},
+ {234, nullptr, "BlockUserByLocalUserId"},
+ {235, nullptr, "BlockUserByNetworkUserId"},
+ {236, nullptr, "UnblockUserByLocalUserId"},
+ {237, nullptr, "UnblockUserByNetworkUserId"},
+ {240, nullptr, "DeleteApplication"},
+ {250, nullptr, "InitializeApplicationInfo"},
+ {260, nullptr, "CreateAccountSystemSaveDataAccessSuppressor"},
+ {300, nullptr, "AddReceivedNeighborInfoForSystemForDebug"},
+ {301, nullptr, "GetSendDataForDebug"},
+ {302, nullptr, "ClearReceiveCounterForDebug"},
+ {303, nullptr, "GetNextReceiveCounterForDebug"},
+ {304, nullptr, "ListBlockedUsersForDebug"},
+ {305, nullptr, "RefreshSendDataIdForDebug"},
+ {306, nullptr, "ReloadFwdbgSettingsForDebug"},
+ {307, nullptr, "EnableApplicationForDebug"},
+ {308, nullptr, "GetNextReceiveCountersForDebug"},
+ {309, nullptr, "ListApplicationInfoForDebug"},
+ {310, nullptr, "SetApplicationDataForDebug"},
+ {400, nullptr, "GetNetworkUserId"},
+ {401, nullptr, "DeleteNetworkUserId"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
auto module = std::make_shared<Module>();
- server_manager->RegisterNamedService("friend:a",
- std::make_shared<Friend>(module, system, "friend:a"));
- server_manager->RegisterNamedService("friend:m",
- std::make_shared<Friend>(module, system, "friend:m"));
- server_manager->RegisterNamedService("friend:s",
- std::make_shared<Friend>(module, system, "friend:s"));
- server_manager->RegisterNamedService("friend:u",
- std::make_shared<Friend>(module, system, "friend:u"));
- server_manager->RegisterNamedService("friend:v",
- std::make_shared<Friend>(module, system, "friend:v"));
+ server_manager->RegisterNamedService("nd:app", std::make_shared<IServiceForApplication>(system));
+ server_manager->RegisterNamedService("nd:sys", std::make_shared<IServiceForSystem>(system));
+
+ server_manager->RegisterNamedService("friend:a", std::make_shared<Friend>(module, system, "friend:a"));
+ server_manager->RegisterNamedService("friend:m", std::make_shared<Friend>(module, system, "friend:m"));
+ server_manager->RegisterNamedService("friend:s", std::make_shared<Friend>(module, system, "friend:s"));
+ server_manager->RegisterNamedService("friend:u", std::make_shared<Friend>(module, system, "friend:u"));
+ server_manager->RegisterNamedService("friend:v", std::make_shared<Friend>(module, system, "friend:v"));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/glue/ectx.cpp b/src/core/hle/service/glue/ectx.cpp
index 951f6cfcc8..322ae45254 100644
--- a/src/core/hle/service/glue/ectx.cpp
+++ b/src/core/hle/service/glue/ectx.cpp
@@ -43,6 +43,30 @@ private:
}
};
+ECTX_W::ECTX_W(Core::System& system_) : ServiceFramework{system_, "ectx:w"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "CreateContextRegistrar"},
+ {1, nullptr, "CommitContext"},
+ {2, nullptr, "RemoveContext"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+}
+ECTX_W::~ECTX_W() = default;
+
+ECTX_R::ECTX_R(Core::System& system_) : ServiceFramework{system_, "ectx:r"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetContextInfo"},
+ {1, nullptr, "PullContext"},
+ {2, nullptr, "ListContextDescriptorWithResultForDebug"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+}
+ECTX_R::~ECTX_R() = default;
+
ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} {
// clang-format off
static const FunctionInfo functions[] = {
diff --git a/src/core/hle/service/glue/ectx.h b/src/core/hle/service/glue/ectx.h
index ffa74d8d33..ff48075eda 100644
--- a/src/core/hle/service/glue/ectx.h
+++ b/src/core/hle/service/glue/ectx.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -11,6 +14,18 @@ class System;
namespace Service::Glue {
+class ECTX_W final : public ServiceFramework<ECTX_W> {
+public:
+ explicit ECTX_W(Core::System& system_);
+ ~ECTX_W() override;
+};
+
+class ECTX_R final : public ServiceFramework<ECTX_R> {
+public:
+ explicit ECTX_R(Core::System& system_);
+ ~ECTX_R() override;
+};
+
class ECTX_AW final : public ServiceFramework<ECTX_AW> {
public:
explicit ECTX_AW(Core::System& system_);
diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp
index ea2843462f..46d078d00b 100644
--- a/src/core/hle/service/glue/glue.cpp
+++ b/src/core/hle/service/glue/glue.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -19,40 +22,27 @@ void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
// ARP
- server_manager->RegisterNamedService("arp:r",
- std::make_shared<ARP_R>(system, system.GetARPManager()));
- server_manager->RegisterNamedService("arp:w",
- std::make_shared<ARP_W>(system, system.GetARPManager()));
+ server_manager->RegisterNamedService("arp:r", std::make_shared<ARP_R>(system, system.GetARPManager()));
+ server_manager->RegisterNamedService("arp:w", std::make_shared<ARP_W>(system, system.GetARPManager()));
// BackGround Task Controller
server_manager->RegisterNamedService("bgtc:t", std::make_shared<BGTC_T>(system));
server_manager->RegisterNamedService("bgtc:sc", std::make_shared<BGTC_SC>(system));
// Error Context
+ server_manager->RegisterNamedService("ectx:w", std::make_shared<ECTX_W>(system));
+ server_manager->RegisterNamedService("ectx:r", std::make_shared<ECTX_R>(system));
server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system));
// Notification Services
- server_manager->RegisterNamedService(
- "notif:a", std::make_shared<INotificationServicesForApplication>(system));
- server_manager->RegisterNamedService("notif:s",
- std::make_shared<INotificationServices>(system));
+ server_manager->RegisterNamedService("notif:a", std::make_shared<INotificationServicesForApplication>(system));
+ server_manager->RegisterNamedService("notif:s", std::make_shared<INotificationServices>(system));
// Time
auto time = std::make_shared<Time::TimeManager>(system);
-
- server_manager->RegisterNamedService(
- "time:u",
- std::make_shared<Time::StaticService>(
- system, Service::PSC::Time::StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, time, "time:u"));
- server_manager->RegisterNamedService(
- "time:a",
- std::make_shared<Time::StaticService>(
- system, Service::PSC::Time::StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, time, "time:a"));
- server_manager->RegisterNamedService(
- "time:r",
- std::make_shared<Time::StaticService>(
- system, Service::PSC::Time::StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, time, "time:r"));
-
+ server_manager->RegisterNamedService("time:u", std::make_shared<Time::StaticService>(system, Service::PSC::Time::StaticServiceSetupInfo{0, 0, 0, 0, 0, 0}, time, "time:u"));
+ server_manager->RegisterNamedService("time:a", std::make_shared<Time::StaticService>(system, Service::PSC::Time::StaticServiceSetupInfo{1, 1, 0, 1, 0, 0}, time, "time:a"));
+ server_manager->RegisterNamedService("time:r", std::make_shared<Time::StaticService>(system, Service::PSC::Time::StaticServiceSetupInfo{0, 0, 0, 0, 1, 0}, time, "time:r"));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp
index 49811bff4f..716e4da32d 100644
--- a/src/core/hle/service/glue/notif.cpp
+++ b/src/core/hle/service/glue/notif.cpp
@@ -116,12 +116,10 @@ Result NotificationServiceImpl::Initialize(u64 aruid) {
R_SUCCEED();
}
-std::vector<AlarmSetting>::iterator NotificationServiceImpl::GetAlarmFromId(
- AlarmSettingId alarm_setting_id) {
- return std::find_if(alarms.begin(), alarms.end(),
- [alarm_setting_id](const AlarmSetting& alarm) {
- return alarm.alarm_setting_id == alarm_setting_id;
- });
+std::vector<AlarmSetting>::iterator NotificationServiceImpl::GetAlarmFromId(AlarmSettingId alarm_setting_id) {
+ return std::find_if(alarms.begin(), alarms.end(), [alarm_setting_id](const AlarmSetting& alarm) {
+ return alarm.alarm_setting_id == alarm_setting_id;
+ });
}
INotificationServicesForApplication::INotificationServicesForApplication(Core::System& system_)
diff --git a/src/core/hle/service/grc/grc.cpp b/src/core/hle/service/grc/grc.cpp
index 64275da36d..b3d39a6294 100644
--- a/src/core/hle/service/grc/grc.cpp
+++ b/src/core/hle/service/grc/grc.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -26,10 +29,25 @@ public:
}
};
+class GRC_D final : public ServiceFramework<GRC_D> {
+public:
+ explicit GRC_D(Core::System& system_) : ServiceFramework{system_, "grc:d"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {1, nullptr, "Initialize"},
+ {2, nullptr, "Transfer"},
+ {3, nullptr, "Cmd3"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("grc:c", std::make_shared<GRC>(system));
+ server_manager->RegisterNamedService("grc:d", std::make_shared<GRC_D>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 47eedd73b2..25096ff36f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -16,27 +19,77 @@
namespace Service::HID {
+class IHidTemporaryServer final : public ServiceFramework<IHidTemporaryServer> {
+public:
+ explicit IHidTemporaryServer(Core::System& system_)
+ : ServiceFramework{system_, "hid:tmp"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetConsoleSixAxisSensorCalibrationValues"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+ ~IHidTemporaryServer() override = default;
+};
+
+class AHID_CD final : public ServiceFramework<AHID_CD> {
+public:
+ explicit AHID_CD(Core::System& system_)
+ : ServiceFramework{system_, "ahid:cd"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "AcquireDevice"},
+ {1, nullptr, "ReleaseDevice"},
+ {2, nullptr, "GetCtrlSession"},
+ {3, nullptr, "GetReadSession"},
+ {4, nullptr, "GetWriteSession"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+ ~AHID_CD() override = default;
+};
+
+class AHID_HDR final : public ServiceFramework<AHID_HDR> {
+public:
+ explicit AHID_HDR(Core::System& system_)
+ : ServiceFramework{system_, "ahid:hdr"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetDeviceEntries"},
+ {1, nullptr, "GetDeviceList"},
+ {2, nullptr, "GetDeviceParameters"},
+ {3, nullptr, "AttachDevice"},
+ {4, nullptr, "DetachDevice"},
+ {5, nullptr, "SetDeviceFilter"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+ ~AHID_HDR() override = default;
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- std::shared_ptr<HidFirmwareSettings> firmware_settings =
- std::make_shared<HidFirmwareSettings>(system);
- std::shared_ptr<ResourceManager> resource_manager =
- std::make_shared<ResourceManager>(system, firmware_settings);
+ auto firmware_settings = std::make_shared<HidFirmwareSettings>(system);
+ auto resource_manager = std::make_shared<ResourceManager>(system, firmware_settings);
resource_manager->Initialize();
- server_manager->RegisterNamedService(
- "hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings));
- server_manager->RegisterNamedService(
- "hid:dbg", std::make_shared<IHidDebugServer>(system, resource_manager, firmware_settings));
- server_manager->RegisterNamedService(
- "hid:sys", std::make_shared<IHidSystemServer>(system, resource_manager, firmware_settings));
+ server_manager->RegisterNamedService("hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings));
+ server_manager->RegisterNamedService("hid:dbg", std::make_shared<IHidDebugServer>(system, resource_manager, firmware_settings));
+ server_manager->RegisterNamedService("hid:sys", std::make_shared<IHidSystemServer>(system, resource_manager, firmware_settings));
+ server_manager->RegisterNamedService("hid:tmp", std::make_shared<IHidTemporaryServer>(system));
server_manager->RegisterNamedService("hidbus", std::make_shared<Hidbus>(system));
server_manager->RegisterNamedService("irs", std::make_shared<IRS::IRS>(system));
server_manager->RegisterNamedService("irs:sys", std::make_shared<IRS::IRS_SYS>(system));
+ server_manager->RegisterNamedService("ahid:cd", std::make_shared<AHID_CD>(system));
+ server_manager->RegisterNamedService("ahid:hdr", std::make_shared<AHID_HDR>(system));
+
server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system));
system.RunServer(std::move(server_manager));
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 3820e15c36..f3c01b5d89 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -38,10 +38,30 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{213, nullptr, "ActivateNfc"},
{214, nullptr, "GetXcdHandleForNpadWithNfc"},
{215, nullptr, "IsNfcActivated"},
- {230, nullptr, "AcquireIrSensorEventHandle"},
+ {216, nullptr, "GetAbstractedPadIdForNpadWithNfc"},
+ {217, nullptr, "SetNfcEvent"},
+ {218, nullptr, "GetNfcInfo"},
+ {219, nullptr, "StartNfcDiscovery"},
+ {220, nullptr, "StopNfcDiscovery"},
+ {221, nullptr, "StartNtagRead"},
+ {222, nullptr, "StartNtagWrite"},
+ {223, nullptr, "SendNfcRawData"},
+ {224, nullptr, "RegisterMifareKey"},
+ {225, nullptr, "ClearMifareKey"},
+ {226, nullptr, "StartMifareRead"},
+ {227, nullptr, "StartMifareWrite"},
+ {230, nullptr, "AcquireIrSensorEventHndle" },
{231, nullptr, "ActivateIrSensor"},
{232, nullptr, "GetIrSensorState"},
- {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
+ {233, nullptr, "GetXcdHandleForNpadWihIrSensor" },
+ {234, nullptr, "GetNpadJoyHoldType"},
+ {241, nullptr, "GetDataFormat"},
+ {242, nullptr, "SetDataFormat"},
+ {243, nullptr, "GetMcuState"},
+ {244, nullptr, "SetMcuState"},
+ {245, nullptr, "GetMcuVersionForNfc"},
+ {246, nullptr, "CheckNfcDevicePower"},
+ {247, nullptr, "SetMcuStateImmediate"},
{301, nullptr, "ActivateNpadSystem"},
{303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
{304, &IHidSystemServer::EnableAssigningSingleOnSlSrPress, "EnableAssigningSingleOnSlSrPress"},
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h
index 7387318995..4dee40224a 100644
--- a/src/core/hle/service/hle_ipc.h
+++ b/src/core/hle/service/hle_ipc.h
@@ -330,12 +330,12 @@ public:
/// Helper function to test whether the output buffer at buffer_index can be written
[[nodiscard]] bool CanWriteBuffer(std::size_t buffer_index = 0) const;
- [[nodiscard]] Handle GetCopyHandle(std::size_t index) const {
- return incoming_copy_handles.at(index);
+ [[nodiscard]] Handle GetCopyHandle(std::size_t index) const noexcept {
+ return index >= incoming_copy_handles.size() ? 0 : incoming_copy_handles[index];
}
- [[nodiscard]] Handle GetMoveHandle(std::size_t index) const {
- return incoming_move_handles.at(index);
+ [[nodiscard]] Handle GetMoveHandle(std::size_t index) const noexcept {
+ return index >= incoming_move_handles.size() ? 0 : incoming_move_handles[index];
}
void AddMoveObject(Kernel::KAutoObject* object) {
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 9a45f130df..1d9a610b30 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -357,10 +357,26 @@ private:
}
};
+class LM_GET final : public ServiceFramework<LM_GET> {
+public:
+ explicit LM_GET(Core::System& system_)
+ : ServiceFramework{system_, "lm:get"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "StartLogging"},
+ {1, nullptr, "StopLogging"},
+ {2, nullptr, "GetLog"},
+ {100, nullptr, "CreateDevNotificationReceiver"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("lm", std::make_shared<LM>(system));
+ server_manager->RegisterNamedService("lm:get", std::make_shared<LM_GET>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index 51df5bc628..513bb671f8 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -367,10 +367,8 @@ void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
std::shared_ptr<MiiManager> manager = std::make_shared<MiiManager>();
- server_manager->RegisterNamedService(
- "mii:e", std::make_shared<IStaticService>(system, "mii:e", manager, true));
- server_manager->RegisterNamedService(
- "mii:u", std::make_shared<IStaticService>(system, "mii:u", manager, false));
+ server_manager->RegisterNamedService("mii:e", std::make_shared<IStaticService>(system, "mii:e", manager, true));
+ server_manager->RegisterNamedService("mii:u", std::make_shared<IStaticService>(system, "mii:u", manager, false));
server_manager->RegisterNamedService("miiimg", std::make_shared<IImageDatabaseService>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/mnpp/mnpp.cpp b/src/core/hle/service/mnpp/mnpp.cpp
new file mode 100644
index 0000000000..11b6f3a386
--- /dev/null
+++ b/src/core/hle/service/mnpp/mnpp.cpp
@@ -0,0 +1,86 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/logging.h"
+#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/mnpp/mnpp.h"
+#include "core/hle/service/server_manager.h"
+#include "core/hle/service/service.h"
+
+namespace Service::MNPP {
+
+class MNPP_APP final : public ServiceFramework<MNPP_APP> {
+public:
+ explicit MNPP_APP(Core::System& system_) : ServiceFramework{system_, "mnpp:app"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &MNPP_APP::Cmd0, "Cmd0"},
+ {1, &MNPP_APP::Cmd1, "Cmd1"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+ }
+
+private:
+ void Cmd0(HLERequestContext& ctx) {
+ LOG_WARNING(Service_MNPP, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void Cmd1(HLERequestContext& ctx) {
+ LOG_WARNING(Service_MNPP, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+};
+
+class MNPP_SYS final : public ServiceFramework<MNPP_SYS> {
+public:
+ explicit MNPP_SYS(Core::System& system_) : ServiceFramework{system_, "mnpp:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Cmd0"},
+ {10, nullptr, "Cmd10"},
+ {100, nullptr, "Cmd100"},
+ {200, nullptr, "Cmd200"},
+ {300, nullptr, "Cmd300"},
+ {400, nullptr, "Cmd400"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class MNPP_WEB final : public ServiceFramework<MNPP_WEB> {
+public:
+ explicit MNPP_WEB(Core::System& system_) : ServiceFramework{system_, "mnpp:web"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Cmd0"},
+ {1, nullptr, "Cmd1"},
+ {10, nullptr, "Cmd10"},
+ {20, nullptr, "Cmd20"},
+ {100, nullptr, "Cmd100"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+void LoopProcess(Core::System& system) {
+ auto server_manager = std::make_unique<ServerManager>(system);
+
+ server_manager->RegisterNamedService("mnpp:app", std::make_shared<MNPP_APP>(system));
+ server_manager->RegisterNamedService("mnpp:sys", std::make_shared<MNPP_SYS>(system));
+ server_manager->RegisterNamedService("mnpp:web", std::make_shared<MNPP_WEB>(system));
+ ServerManager::RunServer(std::move(server_manager));
+}
+
+} // namespace Service::MNPP
diff --git a/src/core/hle/service/mnpp/mnpp_app.h b/src/core/hle/service/mnpp/mnpp.h
index 40d0395bdf..3cdcf14cac 100644
--- a/src/core/hle/service/mnpp/mnpp_app.h
+++ b/src/core/hle/service/mnpp/mnpp.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
diff --git a/src/core/hle/service/mnpp/mnpp_app.cpp b/src/core/hle/service/mnpp/mnpp_app.cpp
deleted file mode 100644
index 19bbfd795b..0000000000
--- a/src/core/hle/service/mnpp/mnpp_app.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/logging.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/mnpp/mnpp_app.h"
-#include "core/hle/service/server_manager.h"
-#include "core/hle/service/service.h"
-
-namespace Service::MNPP {
-
-class MNPP_APP final : public ServiceFramework<MNPP_APP> {
-public:
- explicit MNPP_APP(Core::System& system_) : ServiceFramework{system_, "mnpp:app"} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, &MNPP_APP::Unknown0, "unknown0"},
- {1, &MNPP_APP::Unknown1, "unknown1"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
- }
-
-private:
- void Unknown0(HLERequestContext& ctx) {
- LOG_WARNING(Service_MNPP, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
- }
-
- void Unknown1(HLERequestContext& ctx) {
- LOG_WARNING(Service_MNPP, "(STUBBED) called");
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
- }
-};
-
-void LoopProcess(Core::System& system) {
- auto server_manager = std::make_unique<ServerManager>(system);
-
- server_manager->RegisterNamedService("mnpp:app", std::make_shared<MNPP_APP>(system));
- ServerManager::RunServer(std::move(server_manager));
-}
-
-} // namespace Service::MNPP
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
index f787da9825..6c754d5567 100644
--- a/src/core/hle/service/ncm/ncm.cpp
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -427,11 +427,26 @@ private:
}
};
+class NCM_V final : public ServiceFramework<NCM_V> {
+public:
+ explicit NCM_V(Core::System& system_)
+ : ServiceFramework{system_, "ncm:v"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetSystemVersion"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("lr", std::make_shared<LR>(system));
server_manager->RegisterNamedService("ncm", std::make_shared<NCM>(system));
+ if (1 /* not retail */) {
+ server_manager->RegisterNamedService("ncm:v", std::make_shared<NCM_V>(system));
+ }
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/ngc/ngc.cpp b/src/core/hle/service/ngc/ngc.cpp
index 0275ec52e5..0af4a7bd0e 100644
--- a/src/core/hle/service/ngc/ngc.cpp
+++ b/src/core/hle/service/ngc/ngc.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -13,13 +13,13 @@
namespace Service::NGC {
-class NgctServiceImpl final : public ServiceFramework<NgctServiceImpl> {
+class IService final : public ServiceFramework<IService> {
public:
- explicit NgctServiceImpl(Core::System& system_) : ServiceFramework{system_, "ngct:u"} {
+ explicit IService(Core::System& system_) : ServiceFramework{system_, "ngct:u"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, &NgctServiceImpl::Match, "Match"},
- {1, &NgctServiceImpl::Filter, "Filter"},
+ {0, &IService::Match, "Match"},
+ {1, &IService::Filter, "Filter"},
};
// clang-format on
@@ -29,8 +29,9 @@ public:
private:
void Match(HLERequestContext& ctx) {
const auto buffer = ctx.ReadBuffer();
- const auto text = Common::StringFromFixedZeroTerminatedBuffer(
- reinterpret_cast<const char*>(buffer.data()), buffer.size());
+ const auto text = !buffer.empty()
+ ? Common::StringFromFixedZeroTerminatedBuffer(reinterpret_cast<const char*>(buffer.data()), buffer.size())
+ : std::string{};
LOG_WARNING(Service_NGC, "(STUBBED) called, text={}", text);
@@ -42,8 +43,9 @@ private:
void Filter(HLERequestContext& ctx) {
const auto buffer = ctx.ReadBuffer();
- const auto text = Common::StringFromFixedZeroTerminatedBuffer(
- reinterpret_cast<const char*>(buffer.data()), buffer.size());
+ const auto text = !buffer.empty()
+ ? Common::StringFromFixedZeroTerminatedBuffer(reinterpret_cast<const char*>(buffer.data()), buffer.size())
+ : std::string{};
LOG_WARNING(Service_NGC, "(STUBBED) called, text={}", text);
@@ -144,10 +146,31 @@ private:
}
};
+class IServiceWithManagementApi final : public ServiceFramework<IServiceWithManagementApi> {
+public:
+ explicit IServiceWithManagementApi(Core::System& system_) : ServiceFramework(system_, "ngct:s") {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0 , nullptr, "Match"},
+ {1 , nullptr, "Filter"},
+ {100, nullptr, "ConfigureAutoUpdateSetting"},
+ {101, nullptr, "RequestResourceUpdateCheck"},
+ {110, nullptr, "Reload"},
+ {111, nullptr, "IsReloadRequired"},
+ {112, nullptr, "TryAcquireReloadRequestNotifier"},
+ {120, nullptr, "CalculateContentFingerprint"},
+ {130, nullptr, "TryEnableTemporalPassThrough"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- server_manager->RegisterNamedService("ngct:u", std::make_shared<NgctServiceImpl>(system));
+ server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system));
+ server_manager->RegisterNamedService("ngct:s", std::make_shared<IServiceWithManagementApi>(system));
server_manager->RegisterNamedService("ngc:u", std::make_shared<NgcServiceImpl>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index dfea4efa69..661da88b0c 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -519,11 +519,25 @@ private:
}
};
+class NIM_ECAS final : public ServiceFramework<NIM_ECAS> {
+public:
+ explicit NIM_ECAS(Core::System& system_) : ServiceFramework{system_, "nim:ecas"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "RegisterSpecialClient"},
+ {1, nullptr, "UnregisterSpecialClient"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("nim", std::make_shared<NIM>(system));
server_manager->RegisterNamedService("nim:eca", std::make_shared<NIM_ECA>(system));
+ server_manager->RegisterNamedService("nim:ecas", std::make_shared<NIM_ECAS>(system));
server_manager->RegisterNamedService("nim:shp", std::make_shared<NIM_SHP>(system));
server_manager->RegisterNamedService("ntc", std::make_shared<NTC>(system));
ServerManager::RunServer(std::move(server_manager));
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 8402e83cb1..4d6154404e 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -12,32 +15,48 @@
namespace Service::NS {
+class INotifyService final : public ServiceFramework<INotifyService> {
+public:
+ explicit INotifyService(Core::System& system_) : ServiceFramework{system_, "pdm:ntfy"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "NotifyAppletEvent" },
+ { 2, nullptr, "NotifyOperationModeChangeEvent" },
+ { 3, nullptr, "NotifyPowerStateChangeEvent" },
+ { 4, nullptr, "NotifyClearAllEvent" },
+ { 5, nullptr, "NotifyEventForDebug" },
+ { 6, nullptr, "SuspendUserAccountEventService" },
+ { 7, nullptr, "ResumeUserAccountEventService" },
+ { 8, nullptr, "NotifyLibraryAppletEvent" },
+ { 9, nullptr, "Cmd9" },
+ { 20, nullptr, "Cmd20" },
+ { 30, nullptr, "Cmd30" },
+ { 100, nullptr, "Cmd100" },
+ { 101, nullptr, "Cmd101" },
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- server_manager->RegisterNamedService(
- "ns:am2", std::make_shared<IServiceGetterInterface>(system, "ns:am2"));
- server_manager->RegisterNamedService(
- "ns:ec", std::make_shared<IServiceGetterInterface>(system, "ns:ec"));
- server_manager->RegisterNamedService(
- "ns:rid", std::make_shared<IServiceGetterInterface>(system, "ns:rid"));
- server_manager->RegisterNamedService(
- "ns:rt", std::make_shared<IServiceGetterInterface>(system, "ns:rt"));
- server_manager->RegisterNamedService(
- "ns:web", std::make_shared<IServiceGetterInterface>(system, "ns:web"));
- server_manager->RegisterNamedService(
- "ns:ro", std::make_shared<IServiceGetterInterface>(system, "ns:ro"));
+ server_manager->RegisterNamedService("ns:am2", std::make_shared<IServiceGetterInterface>(system, "ns:am2"));
+ server_manager->RegisterNamedService("ns:ec", std::make_shared<IServiceGetterInterface>(system, "ns:ec"));
+ server_manager->RegisterNamedService("ns:rid", std::make_shared<IServiceGetterInterface>(system, "ns:rid"));
+ server_manager->RegisterNamedService("ns:rt", std::make_shared<IServiceGetterInterface>(system, "ns:rt"));
+ server_manager->RegisterNamedService("ns:web", std::make_shared<IServiceGetterInterface>(system, "ns:web"));
+ server_manager->RegisterNamedService("ns:ro", std::make_shared<IServiceGetterInterface>(system, "ns:ro"));
server_manager->RegisterNamedService("ns:dev", std::make_shared<IDevelopInterface>(system));
server_manager->RegisterNamedService("ns:su", std::make_shared<ISystemUpdateInterface>(system));
- server_manager->RegisterNamedService("ns:vm",
- std::make_shared<IVulnerabilityManagerInterface>(system));
+ server_manager->RegisterNamedService("ns:vm", std::make_shared<IVulnerabilityManagerInterface>(system));
+ server_manager->RegisterNamedService("pdm:ntfy", std::make_shared<INotifyService>(system));
server_manager->RegisterNamedService("pdm:qry", std::make_shared<IQueryService>(system));
- server_manager->RegisterNamedService("pl:s",
- std::make_shared<IPlatformServiceManager>(system, "pl:s"));
- server_manager->RegisterNamedService("pl:u",
- std::make_shared<IPlatformServiceManager>(system, "pl:u"));
+ server_manager->RegisterNamedService("pl:s", std::make_shared<IPlatformServiceManager>(system, "pl:s"));
+ server_manager->RegisterNamedService("pl:u", std::make_shared<IPlatformServiceManager>(system, "pl:u"));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/ns/query_service.cpp b/src/core/hle/service/ns/query_service.cpp
index ea605cb831..d22de1d169 100644
--- a/src/core/hle/service/ns/query_service.cpp
+++ b/src/core/hle/service/ns/query_service.cpp
@@ -38,6 +38,12 @@ IQueryService::IQueryService(Core::System& system_) : ServiceFramework{system_,
{17, D<&IQueryService::QueryLastPlayTime>, "QueryLastPlayTime"},
{18, D<&IQueryService::QueryApplicationPlayStatisticsForSystem>, "QueryApplicationPlayStatisticsForSystem"},
{19, D<&IQueryService::QueryApplicationPlayStatisticsByUserAccountIdForSystem>, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"},
+ { 30, nullptr, "Cmd30" },
+ { 31, nullptr, "Cmd31" },
+ { 100, nullptr, "Cmd100" },
+ { 110, nullptr, "Cmd110" },
+ { 118, nullptr, "Cmd118" },
+ { 119, nullptr, "Cmd119" },
};
// clang-format on
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 8c618ca258..cc006bd975 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -25,6 +28,7 @@
#include "core/hle/service/nvdrv/nvmemp.h"
#include "core/hle/service/nvnflinger/nvnflinger.h"
#include "core/hle/service/server_manager.h"
+#include "frontend_common/firmware_manager.h"
#include "video_core/gpu.h"
namespace Service::Nvidia {
@@ -42,26 +46,75 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {
module.service_context.CloseEvent(event);
}
+class NVGEM_C final : public ServiceFramework<NVGEM_C> {
+public:
+ explicit NVGEM_C(Core::System& system_)
+ : ServiceFramework{system_, "nvgem:c"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "GetEventHandle"},
+ {2, nullptr, "ControlNotification"},
+ {3, nullptr, "SetNotificationPerm"},
+ {4, nullptr, "SetCoreDumpPerm"},
+ {5, nullptr, "GetAruid"},
+ {6, nullptr, "Reset"},
+ {7, nullptr, "GetAruid2"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class NVGEM_CD final : public ServiceFramework<NVGEM_CD> {
+public:
+ explicit NVGEM_CD(Core::System& system_)
+ : ServiceFramework{system_, "nvgem:cd"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "GetAruid"},
+ {2, nullptr, "ReadNextBlock"},
+ {3, nullptr, "GetNextBlockSize"},
+ {4, nullptr, "ReadNextBlock2"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class NVDBG_D final : public ServiceFramework<NVDBG_D> {
+public:
+ explicit NVDBG_D(Core::System& system_)
+ : ServiceFramework{system_, "nvdbg:d"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Open"},
+ {1, nullptr, "Ioctl"},
+ {2, nullptr, "Close"},
+ {4, nullptr, "QueryEvent"},
+ {9, nullptr, "DumpStatus"},
+ {10, nullptr, "InitializeDevtools"},
+ {11, nullptr, "Ioctl2"},
+ {12, nullptr, "Ioctl3"},
+ {13, nullptr, "SetConfiguration"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
auto module = std::make_shared<Module>(system);
- const auto NvdrvInterfaceFactoryForApplication = [&, module] {
- return std::make_shared<NVDRV>(system, module, "nvdrv");
- };
- const auto NvdrvInterfaceFactoryForApplets = [&, module] {
- return std::make_shared<NVDRV>(system, module, "nvdrv:a");
- };
- const auto NvdrvInterfaceFactoryForSysmodules = [&, module] {
- return std::make_shared<NVDRV>(system, module, "nvdrv:s");
- };
- const auto NvdrvInterfaceFactoryForTesting = [&, module] {
- return std::make_shared<NVDRV>(system, module, "nvdrv:t");
- };
- server_manager->RegisterNamedService("nvdrv", NvdrvInterfaceFactoryForApplication);
- server_manager->RegisterNamedService("nvdrv:a", NvdrvInterfaceFactoryForApplets);
- server_manager->RegisterNamedService("nvdrv:s", NvdrvInterfaceFactoryForSysmodules);
- server_manager->RegisterNamedService("nvdrv:t", NvdrvInterfaceFactoryForTesting);
+ server_manager->RegisterNamedService("nvdrv", std::make_shared<NVDRV>(system, module, "nvdrv"));
+ server_manager->RegisterNamedService("nvdrv:a", std::make_shared<NVDRV>(system, module, "nvdrv:a"));
+ server_manager->RegisterNamedService("nvdrv:s", std::make_shared<NVDRV>(system, module, "nvdrv:s"));
+ server_manager->RegisterNamedService("nvdrv:t", std::make_shared<NVDRV>(system, module, "nvdrv:t"));
server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system));
+ server_manager->RegisterNamedService("nvgem:c", std::make_shared<NVGEM_C>(system));
+ server_manager->RegisterNamedService("nvgem:cd", std::make_shared<NVGEM_CD>(system));
+ // +10.0.0
+ if (FirmwareManager::GetFirmwareVersion(system).first.major >= 10) {
+ server_manager->RegisterNamedService("nvdbg:d", std::make_shared<NVDBG_D>(system));
+ }
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index 18e5ad43f8..a86c525f9a 100644
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,20 +12,23 @@
namespace Service::OLSC {
+class ISProfileBgAgentForSystemProcess final : public ServiceFramework<ISProfileBgAgentForSystemProcess> {
+public:
+ explicit ISProfileBgAgentForSystemProcess(Core::System& system_)
+ : ServiceFramework{system_, "spbg:sp"}
+ {
+ static const FunctionInfo functions[] = {
+ { 100, nullptr, "OpenBgAgentController" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
-
- const auto OlscFactoryForApplication = [&] {
- return std::make_shared<IOlscServiceForApplication>(system);
- };
-
- const auto OlscFactoryForSystemService = [&] {
- return std::make_shared<IOlscServiceForSystemService>(system);
- };
-
- server_manager->RegisterNamedService("olsc:u", OlscFactoryForApplication);
- server_manager->RegisterNamedService("olsc:s", OlscFactoryForSystemService);
-
+ server_manager->RegisterNamedService("olsc:u", std::make_shared<IOlscServiceForApplication>(system));
+ server_manager->RegisterNamedService("olsc:s", std::make_shared<IOlscServiceForSystemService>(system));
+ server_manager->RegisterNamedService("spbg:sp", std::make_shared<ISProfileBgAgentForSystemProcess>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp
index afb8067cd5..d162881ecf 100644
--- a/src/core/hle/service/pcie/pcie.cpp
+++ b/src/core/hle/service/pcie/pcie.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
@@ -9,6 +9,7 @@
#include "core/hle/service/pcie/pcie.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
+#include "frontend_common/firmware_manager.h"
namespace Service::PCIe {
@@ -48,9 +49,9 @@ public:
}
};
-class PCIe final : public ServiceFramework<PCIe> {
+class PCIE final : public ServiceFramework<PCIE> {
public:
- explicit PCIe(Core::System& system_) : ServiceFramework{system_, "pcie"} {
+ explicit PCIE(Core::System& system_) : ServiceFramework{system_, "pcie"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RegisterClassDriver"},
@@ -62,10 +63,27 @@ public:
}
};
+class PCIE_LOG final : public ServiceFramework<PCIE_LOG> {
+public:
+ explicit PCIE_LOG(Core::System& system_) : ServiceFramework{system_, "pcie:log"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetLoggedState"},
+ {1, nullptr, "GetLoggedStateEvent"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- server_manager->RegisterNamedService("pcie", std::make_shared<PCIe>(system));
+ server_manager->RegisterNamedService("pcie", std::make_shared<PCIE>(system));
+ // +6.0.0
+ if (FirmwareManager::GetFirmwareVersion(system).first.major >= 6) {
+ server_manager->RegisterNamedService("pcie:log", std::make_shared<PCIE_LOG>(system));
+ }
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
index c2f466c90b..1b314f3518 100644
--- a/src/core/hle/service/pcv/pcv.cpp
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -55,6 +55,30 @@ public:
}
};
+class PCV_ARB final : public ServiceFramework<PCV_ARB> {
+public:
+ explicit PCV_ARB(Core::System& system_) : ServiceFramework{system_, "pcv:arb"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "ReleaseControl"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class PCV_IMM final : public ServiceFramework<PCV_IMM> {
+public:
+ explicit PCV_IMM(Core::System& system_) : ServiceFramework{system_, "pcv:imm"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "SetClockRate"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
class IClkrstSession final : public ServiceFramework<IClkrstSession> {
public:
explicit IClkrstSession(Core::System& system_, DeviceCode device_code_)
@@ -148,6 +172,8 @@ void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("pcv", std::make_shared<PCV>(system));
+ server_manager->RegisterNamedService("pcv:arb", std::make_shared<PCV_ARB>(system));
+ server_manager->RegisterNamedService("pcv:imm", std::make_shared<PCV_IMM>(system));
server_manager->RegisterNamedService("clkrst", std::make_shared<CLKRST>(system, "clkrst"));
server_manager->RegisterNamedService("clkrst:i", std::make_shared<CLKRST>(system, "clkrst:i"));
server_manager->RegisterNamedService("clkrst:a", std::make_shared<CLKRST_A>(system));
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp
index e1762d6943..31fb9f0117 100644
--- a/src/core/hle/service/psc/psc.cpp
+++ b/src/core/hle/service/psc/psc.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -14,23 +17,109 @@
namespace Service::PSC {
+class PSC_L final : public ServiceFramework<PSC_L> {
+public:
+ explicit PSC_L(Core::System& system_) : ServiceFramework{system_, "psc:l"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize_3"},
+ {1, nullptr, "Lock"},
+ {2, nullptr, "Unlock"},
+ {3, nullptr, "IsLocked"},
+ {4, nullptr, "GetRelatedState"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class INS_R final : public ServiceFramework<INS_R> {
+public:
+ explicit INS_R(Core::System& system_) : ServiceFramework{system_, "ins:r"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetInputSourceState"},
+ {1, nullptr, "GetTriggerTargetEvent"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class INS_S final : public ServiceFramework<INS_S> {
+public:
+ explicit INS_S(Core::System& system_) : ServiceFramework{system_, "ins:s"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetNotifyEvent"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class HSHL_SYS final : public ServiceFramework<HSHL_SYS> {
+public:
+ explicit HSHL_SYS(Core::System& system_) : ServiceFramework{system_, "hshl:sys"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetBatteryPercentage"},
+ {1, nullptr, "GetChargerType"},
+ {2, nullptr, "OpenChargeSession"},
+ {3, nullptr, "GetRawBatteryPercentage"},
+ {4, nullptr, "GetBatteryVoltageLevel"},
+ {5, nullptr, "OpenThermalSession"},
+ {6, nullptr, "GetAbnormalTemperatureSet"},
+ {7, nullptr, "OpenClockSession"},
+ {8, nullptr, "GetClockRate"},
+ {9, nullptr, "OpenBridgeSession"},
+ {10, nullptr, "GetBridgePowerSupply"},
+ {11, nullptr, "OpenVsysVoltageSession"},
+ {12, nullptr, "GetIsBatteryEnoughForFullAwake"},
+ {13, nullptr, "GetIsCharging"},
+ {14, nullptr, "Cmd14"},
+ {15, nullptr, "Cmd15"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class HSHL_SET final : public ServiceFramework<HSHL_SET> {
+public:
+ explicit HSHL_SET(Core::System& system_) : ServiceFramework{system_, "hshl:set"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "OpenChargeSession_2"},
+ {1, nullptr, "OpenThermalSession_2"},
+ {2, nullptr, "SetClockRate"},
+ {3, nullptr, "SetBridgePowerSupply"},
+ {4, nullptr, "Cmd4"},
+ {5, nullptr, "Cmd5"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("psc:c", std::make_shared<IPmControl>(system));
server_manager->RegisterNamedService("psc:m", std::make_shared<IPmService>(system));
+ server_manager->RegisterNamedService("psc:l", std::make_shared<PSC_L>(system));
+ server_manager->RegisterNamedService("ins:r", std::make_shared<INS_R>(system));
+ server_manager->RegisterNamedService("ins:s", std::make_shared<INS_S>(system));
+ server_manager->RegisterNamedService("hshl:sys", std::make_shared<HSHL_SYS>(system));
+ server_manager->RegisterNamedService("hshl:set", std::make_shared<HSHL_SET>(system));
server_manager->RegisterNamedService("ovln:rcv", std::make_shared<IReceiverService>(system));
server_manager->RegisterNamedService("ovln:snd", std::make_shared<ISenderService>(system));
auto time = std::make_shared<Time::TimeManager>(system);
- server_manager->RegisterNamedService(
- "time:m", std::make_shared<Time::ServiceManager>(system, time, server_manager.get()));
- server_manager->RegisterNamedService(
- "time:su", std::make_shared<Time::StaticService>(
- system, Time::StaticServiceSetupInfo{0, 0, 0, 0, 0, 1}, time, "time:su"));
- server_manager->RegisterNamedService("time:al",
- std::make_shared<Time::IAlarmService>(system, time));
+ server_manager->RegisterNamedService("time:m", std::make_shared<Time::ServiceManager>(system, time, server_manager.get()));
+ server_manager->RegisterNamedService("time:su", std::make_shared<Time::StaticService>(system, Time::StaticServiceSetupInfo{0, 0, 0, 0, 0, 1}, time, "time:su"));
+ server_manager->RegisterNamedService("time:al", std::make_shared<Time::IAlarmService>(system, time));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/psc/time/service_manager.cpp b/src/core/hle/service/psc/time/service_manager.cpp
index 9ef61117a0..e9f1407e4d 100644
--- a/src/core/hle/service/psc/time/service_manager.cpp
+++ b/src/core/hle/service/psc/time/service_manager.cpp
@@ -159,6 +159,8 @@ Result ServiceManager::SetupTimeZoneServiceCore(const LocationName& name,
name, rule_version, location_count, time_point,
time_point.clock_source_id.RawString());
+ R_UNLESS(!rule_buffer.empty(), ResultUnknown); //TODO: ???
+
if (m_time_zone.ParseBinary(name, rule_buffer) != ResultSuccess) {
LOG_ERROR(Service_Time, "Failed to parse time zone binary!");
}
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 6f0cfe04b8..de1d34a688 100644
--- a/src/core/hle/service/ptm/ptm.cpp
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -11,10 +14,42 @@
namespace Service::PTM {
+class PSM_MANU final : public ServiceFramework<PSM_MANU> {
+public:
+ explicit PSM_MANU(Core::System& system_)
+ : ServiceFramework{system_, "psm:manu"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "EnableVdd50StateControl"},
+ {1, nullptr, "DisableVdd50StateControl"},
+ {2, nullptr, "SetVdd50State"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class POWCTL final : public ServiceFramework<POWCTL> {
+public:
+ explicit POWCTL(Core::System& system_)
+ : ServiceFramework{system_, "powctl"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "OpenSession"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService("psm", std::make_shared<PSM>(system));
+ if (1 /* not retail */) {
+ server_manager->RegisterNamedService("psm:manu", std::make_shared<PSM_MANU>(system));
+ server_manager->RegisterNamedService("powctl", std::make_shared<POWCTL>(system));
+ }
server_manager->RegisterNamedService("ts", std::make_shared<TS>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/ro/ro.cpp b/src/core/hle/service/ro/ro.cpp
index 879e51c65e..f0561b19cc 100644
--- a/src/core/hle/service/ro/ro.cpp
+++ b/src/core/hle/service/ro/ro.cpp
@@ -571,22 +571,26 @@ private:
} // namespace
+
+class IDebugMonitorInterface final : public ServiceFramework<IDebugMonitorInterface> {
+public:
+ explicit IDebugMonitorInterface(Core::System& system_)
+ : ServiceFramework{system_, "ro:dmnt"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "GetProcessModuleInfo" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
auto ro = std::make_shared<RoContext>();
-
- const auto RoInterfaceFactoryForUser = [&, ro] {
- return std::make_shared<RoInterface>(system, "ldr:ro", ro, NrrKind::User);
- };
-
- const auto RoInterfaceFactoryForJitPlugin = [&, ro] {
- return std::make_shared<RoInterface>(system, "ro:1", ro, NrrKind::JitPlugin);
- };
-
- server_manager->RegisterNamedService("ldr:ro", std::move(RoInterfaceFactoryForUser));
- server_manager->RegisterNamedService("ro:1", std::move(RoInterfaceFactoryForJitPlugin));
-
+ server_manager->RegisterNamedService("ldr:ro", std::make_shared<RoInterface>(system, "ldr:ro", ro, NrrKind::User));
+ server_manager->RegisterNamedService("ro:1", std::make_shared<RoInterface>(system, "ro:1", ro, NrrKind::JitPlugin));
+ server_manager->RegisterNamedService("ro:dmnt", std::make_shared<IDebugMonitorInterface>(system));
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp
index 28eb618090..b90af960d6 100644
--- a/src/core/hle/service/services.cpp
+++ b/src/core/hle/service/services.cpp
@@ -37,7 +37,7 @@
#include "core/hle/service/mig/mig.h"
#include "core/hle/service/mii/mii.h"
#include "core/hle/service/mm/mm_u.h"
-#include "core/hle/service/mnpp/mnpp_app.h"
+#include "core/hle/service/mnpp/mnpp.h"
#include "core/hle/service/ncm/ncm.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/nfp/nfp.h"
@@ -64,6 +64,8 @@
#include "core/hle/service/sockets/sockets.h"
#include "core/hle/service/spl/spl_module.h"
#include "core/hle/service/ssl/ssl.h"
+#include "core/hle/service/wlan/wlan.h"
+#include "core/hle/service/tma/tma.h"
#include "core/hle/service/usb/usb.h"
#include "core/hle/service/vi/vi.h"
@@ -146,6 +148,8 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
{"ro", &RO::LoopProcess},
{"spl", &SPL::LoopProcess},
{"ssl", &SSL::LoopProcess},
+ {"wlan", &WLAN::LoopProcess},
+ {"tma", &TMA::LoopProcess},
{"usb", &USB::LoopProcess},
{"i2c", &I2C::LoopProcess},
{"gpio", &GPIO::LoopProcess},
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 9ffaeedd4f..1a59444b4f 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -173,8 +173,26 @@ void BSD::Socket(HLERequestContext& ctx) {
LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol);
- const auto [fd, bsd_errno] = SocketImpl(static_cast<Domain>(domain), static_cast<Type>(type),
- static_cast<Protocol>(protocol));
+ const auto [fd, bsd_errno] = SocketImpl(Domain(domain), Type(type), Protocol(protocol));
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<s32>(fd);
+ rb.PushEnum(bsd_errno);
+}
+
+void BSD::SocketExempt(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const u32 domain = rp.Pop<u32>();
+ const u32 type = rp.Pop<u32>();
+ const u32 protocol = rp.Pop<u32>();
+
+ LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol);
+
+ auto [fd, bsd_errno] = SocketImpl(Domain(domain), Type(type), Protocol(protocol));
+ if (bsd_errno == Errno::SUCCESS) {
+ bsd_errno = ShutdownImpl(fd, 0);
+ }
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
@@ -445,6 +463,7 @@ void BSD::Close(HLERequestContext& ctx) {
BuildErrnoResponse(ctx, CloseImpl(fd));
}
+/// @brief Only bsd:s is able to dup()
void BSD::DuplicateSocket(HLERequestContext& ctx) {
struct InputParameters {
s32 fd;
@@ -463,6 +482,13 @@ void BSD::DuplicateSocket(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
+ if (is_user) {
+ rb.PushRaw(OutputParameters{
+ .ret = 0,
+ .bsd_errno = Errno::INVAL,
+ });
+ return;
+ }
auto const res_v = DuplicateSocketImpl(input.fd);
if (auto* res = std::get_if<s32>(&res_v)) {
@@ -496,11 +522,13 @@ void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
}
std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protocol) {
-
- if (type == Type::SEQPACKET) {
- UNIMPLEMENTED_MSG("SOCK_SEQPACKET errno management");
- } else if (type == Type::RAW && (domain != Domain::INET || protocol != Protocol::ICMP)) {
- UNIMPLEMENTED_MSG("SOCK_RAW errno management");
+ // user bsd:u has restrictions on SOCK_SEQPACKET and SOCK_RAW
+ if (is_user && (type == Type::SEQPACKET || type == Type::RAW)) {
+ if (type == Type::RAW && domain == Domain::INET && protocol == Protocol::ICMP) {
+ // fine, can use on bsd:s and bsd:u
+ } else {
+ return {-1, Errno::INVAL};
+ }
}
[[maybe_unused]] const bool unk_flag = (static_cast<u32>(type) & 0x20000000) != 0;
@@ -1052,14 +1080,15 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
}
}
-BSD::BSD(Core::System& system_, const char* name)
- : ServiceFramework{system_, name} {
+BSD::BSD(Core::System& system_, const char* name, bool is_user_)
+ : ServiceFramework{system_, name}
+ , is_user{is_user_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &BSD::RegisterClient, "RegisterClient"},
{1, &BSD::StartMonitoring, "StartMonitoring"},
{2, &BSD::Socket, "Socket"},
- {3, nullptr, "SocketExempt"},
+ {3, &BSD::SocketExempt, "SocketExempt"},
{4, nullptr, "Open"},
{5, &BSD::Select, "Select"},
{6, &BSD::Poll, "Poll"},
@@ -1125,7 +1154,8 @@ std::unique_lock<std::mutex> BSD::LockService() noexcept {
return {};
}
-BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
+BSDCFG::BSDCFG(Core::System& system_, const char *name)
+ : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "SetIfUp"},
@@ -1152,4 +1182,16 @@ BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
BSDCFG::~BSDCFG() = default;
+BSD_NU::BSD_NU(Core::System& system_)
+ : ServiceFramework{system_, "bsd:nu"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "CreateUserService"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+}
+
+BSD_NU::~BSD_NU() = default;
+
} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 15e4a33592..c0c63f7df8 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -29,7 +29,7 @@ namespace Service::Sockets {
class BSD final : public ServiceFramework<BSD> {
public:
- explicit BSD(Core::System& system_, const char* name);
+ explicit BSD(Core::System& system_, const char* name, bool is_user);
~BSD() override;
// These methods are called from SSL; the first two are also called from
@@ -129,6 +129,7 @@ private:
void RegisterClient(HLERequestContext& ctx);
void StartMonitoring(HLERequestContext& ctx);
void Socket(HLERequestContext& ctx);
+ void SocketExempt(HLERequestContext& ctx);
void Select(HLERequestContext& ctx);
void Poll(HLERequestContext& ctx);
void Accept(HLERequestContext& ctx);
@@ -155,8 +156,7 @@ private:
void ExecuteWork(HLERequestContext& ctx, Work work);
std::pair<s32, Errno> SocketImpl(Domain domain, Type type, Protocol protocol);
- std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
- s32 nfds, s32 timeout);
+ std::pair<s32, Errno> PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer, s32 nfds, s32 timeout);
std::pair<s32, Errno> AcceptImpl(s32 fd, std::vector<u8>& write_buffer);
Errno BindImpl(s32 fd, std::span<const u8> addr);
Errno ConnectImpl(s32 fd, std::span<const u8> addr);
@@ -189,12 +189,19 @@ private:
protected:
std::unique_lock<std::mutex> LockService() noexcept override;
+ bool is_user = false;
};
class BSDCFG final : public ServiceFramework<BSDCFG> {
public:
- explicit BSDCFG(Core::System& system_);
+ explicit BSDCFG(Core::System& system_, const char *name);
~BSDCFG() override;
};
+class BSD_NU final : public ServiceFramework<BSD_NU> {
+public:
+ explicit BSD_NU(Core::System& system_);
+ ~BSD_NU() override;
+};
+
} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp
index 9e71be3547..93c01bf786 100644
--- a/src/core/hle/service/sockets/sfdnsres.cpp
+++ b/src/core/hle/service/sockets/sfdnsres.cpp
@@ -406,4 +406,21 @@ void SFDNSRES::ResolverSetOptionRequest(HLERequestContext& ctx) {
rb.Push(ResultSuccess);
rb.Push<s32>(0); // bsd errno
}
+
+
+DNS_PRIV::DNS_PRIV(Core::System& system_)
+ : ServiceFramework{system_, "dns:priv"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Cmd0"},
+ {1, nullptr, "Cmd1"},
+ {2, nullptr, "Cmd2"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+}
+
+DNS_PRIV::~DNS_PRIV() = default;
+
+
} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h
index 282ef9071f..4302edc43e 100644
--- a/src/core/hle/service/sockets/sfdnsres.h
+++ b/src/core/hle/service/sockets/sfdnsres.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -25,4 +28,10 @@ private:
void ResolverSetOptionRequest(HLERequestContext& ctx);
};
+class DNS_PRIV final : public ServiceFramework<DNS_PRIV> {
+public:
+ explicit DNS_PRIV(Core::System& system_);
+ ~DNS_PRIV() override;
+};
+
} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp
index 676d24e036..c3036f9555 100644
--- a/src/core/hle/service/sockets/sockets.cpp
+++ b/src/core/hle/service/sockets/sockets.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -9,15 +12,72 @@
namespace Service::Sockets {
+class ETHC_C final : public ServiceFramework<ETHC_C> {
+public:
+ explicit ETHC_C(Core::System& system_)
+ : ServiceFramework{system_, "ethc:c"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "Initialize"},
+ {1, nullptr, "Cancel"},
+ {2, nullptr, "GetResult"},
+ {3, nullptr, "GetMediaList"},
+ {4, nullptr, "SetMediaType"},
+ {5, nullptr, "GetMediaType"},
+ {6, nullptr, "GetMacAddress"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class ETHC_I final : public ServiceFramework<ETHC_I> {
+public:
+ explicit ETHC_I(Core::System& system_)
+ : ServiceFramework{system_, "ethc:i"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetReadableHandle"},
+ {1, nullptr, "Cancel"},
+ {2, nullptr, "GetResult"},
+ {3, nullptr, "GetInterfaceList"},
+ {4, nullptr, "GetInterfaceCount"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class ISfDriverServiceCreator final : public ServiceFramework<ISfDriverServiceCreator> {
+public:
+ explicit ISfDriverServiceCreator(Core::System& system_)
+ : ServiceFramework{system_, "eth:nd"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "CreateDriverService"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
- server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s"));
- server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u"));
- server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system));
+ server_manager->RegisterNamedService("ethc:c", std::make_shared<ETHC_C>(system));
+ server_manager->RegisterNamedService("ethc:i", std::make_shared<ETHC_I>(system));
+ server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s", false));
+ server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u", true));
+ server_manager->RegisterNamedService("bsd:a", std::make_shared<BSD>(system, "bsd:a", true));
+ server_manager->RegisterNamedService("bsd:nu", std::make_shared<BSD_NU>(system));
+ server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system, "bsdcfg"));
+ server_manager->RegisterNamedService("ifcfg", std::make_shared<BSDCFG>(system, "ifcfg"));
server_manager->RegisterNamedService("nsd:a", std::make_shared<NSD>(system, "nsd:a"));
server_manager->RegisterNamedService("nsd:u", std::make_shared<NSD>(system, "nsd:u"));
server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system));
+ server_manager->RegisterNamedService("dns:priv", std::make_shared<DNS_PRIV>(system));
+ server_manager->RegisterNamedService("eth:nd", std::make_shared<ISfDriverServiceCreator>(system));
+
server_manager->StartAdditionalHostThreads("bsdsocket", 2);
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp
index 377c602610..81be99c360 100644
--- a/src/core/hle/service/spl/spl.cpp
+++ b/src/core/hle/service/spl/spl.cpp
@@ -25,6 +25,8 @@ SPL::SPL(Core::System& system_, std::shared_ptr<Module> module_)
RegisterHandlers(functions);
}
+SPL::~SPL() = default;
+
SPL_MIG::SPL_MIG(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:mig") {
// clang-format off
@@ -51,6 +53,8 @@ SPL_MIG::SPL_MIG(Core::System& system_, std::shared_ptr<Module> module_)
RegisterHandlers(functions);
}
+SPL_MIG::~SPL_MIG() = default;
+
SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:fs") {
// clang-format off
@@ -82,6 +86,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
RegisterHandlers(functions);
}
+SPL_FS::~SPL_FS() = default;
+
SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:ssl") {
// clang-format off
@@ -111,6 +117,8 @@ SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
RegisterHandlers(functions);
}
+SPL_SSL::~SPL_SSL() = default;
+
SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:es") {
// clang-format off
@@ -145,6 +153,8 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
RegisterHandlers(functions);
}
+SPL_ES::~SPL_ES() = default;
+
SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
: Interface(system_, std::move(module_), "spl:manu") {
// clang-format off
@@ -173,16 +183,6 @@ SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
RegisterHandlers(functions);
}
-SPL::~SPL() = default;
-
-SPL_MIG::~SPL_MIG() = default;
-
-SPL_FS::~SPL_FS() = default;
-
-SPL_SSL::~SPL_SSL() = default;
-
-SPL_ES::~SPL_ES() = default;
-
SPL_MANU::~SPL_MANU() = default;
} // namespace Service::SPL
diff --git a/src/core/hle/service/spl/spl.h b/src/core/hle/service/spl/spl.h
index 7b63d8b1a9..83a3cda539 100644
--- a/src/core/hle/service/spl/spl.h
+++ b/src/core/hle/service/spl/spl.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
diff --git a/src/core/hle/service/tma/tma.cpp b/src/core/hle/service/tma/tma.cpp
new file mode 100644
index 0000000000..c2fb33cd16
--- /dev/null
+++ b/src/core/hle/service/tma/tma.cpp
@@ -0,0 +1,36 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core.h"
+#include "core/hle/result.h"
+#include "core/hle/service/tma/tma.h"
+#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/server_manager.h"
+
+namespace Service::TMA {
+
+class HTC_TENV final : public ServiceFramework<HTC_TENV> {
+public:
+ explicit HTC_TENV(Core::System& system_)
+ : ServiceFramework{system_, "htc:tenv"}
+ {
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetServiceInterface"},
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+void LoopProcess(Core::System& system) {
+ auto server_manager = std::make_unique<ServerManager>(system);
+ server_manager->RegisterNamedService("htc:tenv", std::make_shared<HTC_TENV>(system));
+ ServerManager::RunServer(std::move(server_manager));
+}
+
+} // namespace Service::TMA
diff --git a/src/core/hle/service/tma/tma.h b/src/core/hle/service/tma/tma.h
new file mode 100644
index 0000000000..05324eaa1e
--- /dev/null
+++ b/src/core/hle/service/tma/tma.h
@@ -0,0 +1,15 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+namespace Core {
+class System;
+}
+
+namespace Service::TMA {
+void LoopProcess(Core::System& system);
+} // namespace Service::TMA
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index a451d4f783..179d1f7097 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -11,6 +11,7 @@
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
#include "core/hle/service/usb/usb.h"
+#include "frontend_common/firmware_manager.h"
namespace Service::USB {
@@ -221,6 +222,44 @@ public:
}
};
+class IPdManufactureManager final : public ServiceFramework<IPdManufactureManager> {
+public:
+ explicit IPdManufactureManager(Core::System& system_) : ServiceFramework{system_, "usb:pd:m"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "OpenManufactureSession"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IQdbManager final : public ServiceFramework<IQdbManager> {
+public:
+ explicit IQdbManager(Core::System& system_) : ServiceFramework{system_, "usb:qdb"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "ImportQuirkDevices"},
+ {1, nullptr, "HasQuirk"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
+class IPmObserverService final : public ServiceFramework<IPmObserverService> {
+public:
+ explicit IPmObserverService(Core::System& system_) : ServiceFramework{system_, "usb:obsv"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetTopologyChangeEvent"},
+ {1, nullptr, "GetFlattenedTopology"},
+ };
+ // clang-format on
+ RegisterHandlers(functions);
+ }
+};
+
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
@@ -228,7 +267,16 @@ void LoopProcess(Core::System& system) {
server_manager->RegisterNamedService("usb:hs", std::make_shared<IClientRootSession>(system));
server_manager->RegisterNamedService("usb:pd", std::make_shared<IPdManager>(system));
server_manager->RegisterNamedService("usb:pd:c", std::make_shared<IPdCradleManager>(system));
+ server_manager->RegisterNamedService("usb:pd:m", std::make_shared<IPdManufactureManager>(system));
server_manager->RegisterNamedService("usb:pm", std::make_shared<IPmMainService>(system));
+ // +7.0.0
+ if (FirmwareManager::GetFirmwareVersion(system).first.major >= 7) {
+ server_manager->RegisterNamedService("usb:qdb", std::make_shared<IQdbManager>(system));
+ }
+ // +8.0.0
+ if (FirmwareManager::GetFirmwareVersion(system).first.major >= 8) {
+ server_manager->RegisterNamedService("usb:obsv", std::make_shared<IPmObserverService>(system));
+ }
ServerManager::RunServer(std::move(server_manager));
}
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp
new file mode 100644
index 0000000000..7f118c62ba
--- /dev/null
+++ b/src/core/hle/service/wlan/wlan.cpp
@@ -0,0 +1,260 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/core.h"
+#include "core/hle/result.h"
+#include "core/hle/service/wlan/wlan.h"
+#include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+#include "core/hle/service/server_manager.h"
+
+namespace Service::WLAN {
+
+class ILocalManager final : public ServiceFramework<ILocalManager> {
+public:
+ explicit ILocalManager(Core::System& system_)
+ : ServiceFramework{system_, "wlan:lcl"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "OpenMasterMode" },
+ { 0, nullptr, "OpenMode_2" },
+ { 1, nullptr, "CloseMasterMode" },
+ { 1, nullptr, "CloseMode_2" },
+ { 2, nullptr, "OpenClientMode" },
+ { 2, nullptr, "GetMacAddress_2" },
+ { 3, nullptr, "CloseClientMode" },
+ { 3, nullptr, "CreateBss" },
+ { 4, nullptr, "OpenSpectatorMode" },
+ { 4, nullptr, "DestroyBss" },
+ { 5, nullptr, "CloseSpectatorMode" },
+ { 5, nullptr, "StartScan_2" },
+ { 6, nullptr, "GetMacAddress_2" },
+ { 6, nullptr, "StopScan_2" },
+ { 7, nullptr, "CreateBss" },
+ { 7, nullptr, "Connect_2" },
+ { 8, nullptr, "DestroyBss" },
+ { 8, nullptr, "CancelConnect_2" },
+ { 9, nullptr, "StartScan_2" },
+ { 9, nullptr, "Join" },
+ { 10, nullptr, "StopScan_2" },
+ { 10, nullptr, "CancelJoin" },
+ { 11, nullptr, "Connect_2" },
+ { 11, nullptr, "Disconnect_2" },
+ { 12, nullptr, "CancelConnect_2" },
+ { 12, nullptr, "SetBeaconLostCount" },
+ { 13, nullptr, "Join" },
+ { 13, nullptr, "GetSystemEvent_2" },
+ { 14, nullptr, "CancelJoin" },
+ { 14, nullptr, "GetConnectionStatus_2" },
+ { 15, nullptr, "Disconnect_2" },
+ { 15, nullptr, "GetClientStatus" },
+ { 16, nullptr, "SetBeaconLostCount" },
+ { 16, nullptr, "GetBssIndicationEvent" },
+ { 17, nullptr, "GetSystemEvent_2" },
+ { 17, nullptr, "GetBssIndicationInfo" },
+ { 18, nullptr, "GetConnectionStatus_2" },
+ { 18, nullptr, "GetState_2" },
+ { 19, nullptr, "GetClientStatus" },
+ { 19, nullptr, "GetAllowedChannels" },
+ { 20, nullptr, "GetBssIndicationEvent" },
+ { 20, nullptr, "AddIe" },
+ { 21, nullptr, "GetBssIndicationInfo" },
+ { 21, nullptr, "DeleteIe" },
+ { 22, nullptr, "GetState_2" },
+ { 22, nullptr, "PutFrameRaw" },
+ { 23, nullptr, "GetAllowedChannels" },
+ { 23, nullptr, "CancelGetFrame" },
+ { 24, nullptr, "AddIe" },
+ { 24, nullptr, "CreateRxEntry" },
+ { 25, nullptr, "DeleteIe" },
+ { 25, nullptr, "DeleteRxEntry" },
+ { 26, nullptr, "PutFrameRaw" },
+ { 26, nullptr, "AddEthertypeToRxEntry" },
+ { 27, nullptr, "CancelGetFrame" },
+ { 27, nullptr, "DeleteEthertypeFromRxEntry" },
+ { 28, nullptr, "CreateRxEntry" },
+ { 28, nullptr, "AddMatchingDataToRxEntry" },
+ { 29, nullptr, "DeleteRxEntry" },
+ { 29, nullptr, "RemoveMatchingDataFromRxEntry" },
+ { 30, nullptr, "AddEthertypeToRxEntry" },
+ { 30, nullptr, "GetScanResult_2" },
+ { 31, nullptr, "DeleteEthertypeFromRxEntry" },
+ { 31, nullptr, "PutActionFrameOneShot" },
+ { 32, nullptr, "AddMatchingDataToRxEntry" },
+ { 32, nullptr, "SetActionFrameWithBeacon" },
+ { 33, nullptr, "RemoveMatchingDataFromRxEntry" },
+ { 33, nullptr, "CancelActionFrameWithBeacon" },
+ { 34, nullptr, "GetScanResult_2" },
+ { 34, nullptr, "CreateRxEntryForActionFrame" },
+ { 35, nullptr, "PutActionFrameOneShot" },
+ { 35, nullptr, "DeleteRxEntryForActionFrame" },
+ { 36, nullptr, "SetActionFrameWithBeacon" },
+ { 36, nullptr, "AddSubtypeToRxEntryForActionFrame" },
+ { 37, nullptr, "CancelActionFrameWithBeacon" },
+ { 37, nullptr, "DeleteSubtypeFromRxEntryForActionFrame" },
+ { 38, nullptr, "CreateRxEntryForActionFrame" },
+ { 38, nullptr, "CancelGetActionFrame" },
+ { 39, nullptr, "DeleteRxEntryForActionFrame" },
+ { 39, nullptr, "GetRssi_2" },
+ { 40, nullptr, "AddSubtypeToRxEntryForActionFrame" },
+ { 40, nullptr, "SetMaxAssociationNumber" },
+ { 41, nullptr, "DeleteSubtypeFromRxEntryForActionFrame" },
+ { 41, nullptr, "Cmd41" },
+ { 42, nullptr, "CancelGetActionFrame" },
+ { 42, nullptr, "Cmd42" },
+ { 43, nullptr, "GetRssi_2" },
+ { 43, nullptr, "Cmd43" },
+ { 44, nullptr, "SetMaxAssociationNumber" },
+ { 45, nullptr, "OpenLcsMasterMode" },
+ { 46, nullptr, "CloseLcsMasterMode" },
+ { 47, nullptr, "OpenLcsClientMode" },
+ { 48, nullptr, "CloseLcsClientMode" },
+ { 49, nullptr, "GetChannelStats" },
+ { 50, nullptr, "Cmd50" },
+ { 51, nullptr, "Cmd51" },
+ { 52, nullptr, "Cmd52" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class ILocalGetFrame final : public ServiceFramework<ILocalGetFrame> {
+public:
+ explicit ILocalGetFrame(Core::System& system_)
+ : ServiceFramework{system_, "wlan:lg"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "GetFrameRaw" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class ILocalGetActionFrame final : public ServiceFramework<ILocalGetActionFrame> {
+public:
+ explicit ILocalGetActionFrame(Core::System& system_)
+ : ServiceFramework{system_, "wlan:lga"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "GetActionFrame" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class ISocketGetFrame final : public ServiceFramework<ISocketGetFrame> {
+public:
+ explicit ISocketGetFrame(Core::System& system_)
+ : ServiceFramework{system_, "wlan:sg"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "GetFrameRaw" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class ISocketManager final : public ServiceFramework<ISocketManager> {
+public:
+ explicit ISocketManager(Core::System& system_)
+ : ServiceFramework{system_, "wlan:soc"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "PutFrameRaw_2" },
+ { 1, nullptr, "CancelGetFrame_2" },
+ { 2, nullptr, "CreateRxEntry_2" },
+ { 3, nullptr, "DeleteRxEntry_2" },
+ { 4, nullptr, "AddEthertypeToRxEntry_2" },
+ { 5, nullptr, "DeleteEthertypeFromRxEntry_2" },
+ { 6, nullptr, "GetMacAddress_3" },
+ { 7, nullptr, "SwitchTsfTimerFunction" },
+ { 8, nullptr, "GetDeltaTimeBetweenSystemAndTsf" },
+ { 9, nullptr, "RegisterSharedMemory" },
+ { 10, nullptr, "UnregisterSharedMemory" },
+ { 11, nullptr, "EnableSharedMemory" },
+ { 12, nullptr, "SetMulticastFilter" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class IDetectManager final : public ServiceFramework<IDetectManager> {
+public:
+ explicit IDetectManager(Core::System& system_)
+ : ServiceFramework{system_, "wlan:dtc"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "Cmd0" },
+ { 1, nullptr, "Cmd1" },
+ { 2, nullptr, "Cmd2" },
+ { 3, nullptr, "Cmd3" },
+ { 4, nullptr, "Cmd4" },
+ { 5, nullptr, "Cmd5" },
+ { 6, nullptr, "Cmd6" },
+ { 7, nullptr, "Cmd7" },
+ { 8, nullptr, "Cmd8" },
+ { 9, nullptr, "Cmd9" },
+ { 10, nullptr, "Cmd10" },
+ { 11, nullptr, "Cmd11" },
+ { 12, nullptr, "Cmd12" },
+ { 13, nullptr, "Cmd13" },
+ { 14, nullptr, "Cmd14" },
+ { 15, nullptr, "Cmd15" },
+ { 16, nullptr, "Cmd16" },
+ { 17, nullptr, "Cmd17" },
+ { 18, nullptr, "Cmd18" },
+ { 19, nullptr, "Cmd19" },
+ { 20, nullptr, "Cmd20" },
+ { 21, nullptr, "Cmd21" },
+ { 22, nullptr, "Cmd22" },
+ { 23, nullptr, "Cmd23" },
+ { 24, nullptr, "Cmd24" },
+ { 25, nullptr, "Cmd25" },
+ { 26, nullptr, "Cmd26" },
+ { 27, nullptr, "Cmd27" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class IPrivateServiceCreator final : public ServiceFramework<IPrivateServiceCreator> {
+public:
+ explicit IPrivateServiceCreator(Core::System& system_)
+ : ServiceFramework{system_, "wlan:p"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "CreateWirelessCommunicationService" },
+ { 1, nullptr, "CreatePrivateWirelessCommunicationService" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+class ISfDriverServiceCreator final : public ServiceFramework<ISfDriverServiceCreator> {
+public:
+ explicit ISfDriverServiceCreator(Core::System& system_)
+ : ServiceFramework{system_, "wlan:nd"}
+ {
+ static const FunctionInfo functions[] = {
+ { 0, nullptr, "CreateDriverService" },
+ };
+ RegisterHandlers(functions);
+ }
+};
+
+void LoopProcess(Core::System& system) {
+ auto server_manager = std::make_unique<ServerManager>(system);
+ server_manager->RegisterNamedService("wlan:lcl", std::make_shared<ILocalManager>(system));
+ server_manager->RegisterNamedService("wlan:lg", std::make_shared<ILocalGetFrame>(system));
+ server_manager->RegisterNamedService("wlan:lga", std::make_shared<ILocalGetActionFrame>(system));
+ server_manager->RegisterNamedService("wlan:sg", std::make_shared<ISocketGetFrame>(system));
+ server_manager->RegisterNamedService("wlan:soc", std::make_shared<ISocketManager>(system));
+ server_manager->RegisterNamedService("wlan:dtc", std::make_shared<IDetectManager>(system));
+ server_manager->RegisterNamedService("wlan:p", std::make_shared<IPrivateServiceCreator>(system));
+ server_manager->RegisterNamedService("wlan:nd", std::make_shared<ISfDriverServiceCreator>(system));
+ ServerManager::RunServer(std::move(server_manager));
+}
+
+} // namespace Service::WLAN
diff --git a/src/core/hle/service/wlan/wlan.h b/src/core/hle/service/wlan/wlan.h
new file mode 100644
index 0000000000..45589a5ec0
--- /dev/null
+++ b/src/core/hle/service/wlan/wlan.h
@@ -0,0 +1,12 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+namespace Core {
+class System;
+}
+
+namespace Service::WLAN {
+void LoopProcess(Core::System& system);
+} // namespace Service::WLAN
diff --git a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp
index a80f8271f9..e84f38f2e9 100644
--- a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp
+++ b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp
@@ -53,12 +53,11 @@ Result NpadAbstractBatteryHandler::DecrementRefCounter() {
Result NpadAbstractBatteryHandler::UpdateBatteryState(u64 aruid) {
const auto npad_index = NpadIdTypeToIndex(properties_handler->GetNpadId());
AruidData* aruid_data = applet_resource_holder->applet_resource->GetAruidData(aruid);
- if (aruid_data == nullptr) {
+ if (aruid_data == nullptr || aruid_data->shared_memory_format == nullptr) {
return ResultSuccess;
}
- auto& npad_internal_state =
- aruid_data->shared_memory_format->npad.npad_entry[npad_index].internal_state;
+ auto& npad_internal_state = aruid_data->shared_memory_format->npad.npad_entry[npad_index].internal_state;
auto& system_properties = npad_internal_state.system_properties;
system_properties.is_charging_joy_dual.Assign(dual_battery.is_charging);
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index a2fd23b534..e7a1ee2bf3 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -80,7 +80,11 @@ Result NPad::Activate(u64 aruid) {
std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex};
auto* data = applet_resource_holder.applet_resource->GetAruidData(aruid);
- const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
+ auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid);
+ if (aruid_index >= AruidIndexMax) {
+ LOG_ERROR(Service_HID, "Invalid aruid:{:016X}", aruid);
+ aruid_index = 0;
+ }
if (data == nullptr || !data->flag.is_assigned) {
return ResultSuccess;
@@ -1099,13 +1103,16 @@ Result NPad::RegisterAppletResourceUserId(u64 aruid) {
void NPad::UnregisterAppletResourceUserId(u64 aruid) {
// TODO: Remove this once abstract pad is emulated properly
- const auto aruid_index = npad_resource.GetIndexFromAruid(aruid);
+ auto aruid_index = npad_resource.GetIndexFromAruid(aruid);
+ if (aruid_index >= AruidIndexMax) {
+ LOG_ERROR(Service_HID, "Invalid aruid:{:016X}", aruid);
+ aruid_index = 0;
+ }
for (auto& controller : controller_data[aruid_index]) {
controller.is_active = false;
controller.is_connected = false;
controller.shared_memory = nullptr;
}
-
npad_resource.UnregisterAppletResourceUserId(aruid);
}
diff --git a/src/hid_core/resources/npad/npad_resource.cpp b/src/hid_core/resources/npad/npad_resource.cpp
index 54f7acab12..a1b483d7b8 100644
--- a/src/hid_core/resources/npad/npad_resource.cpp
+++ b/src/hid_core/resources/npad/npad_resource.cpp
@@ -71,6 +71,9 @@ Result NPadResource::RegisterAppletResourceUserId(u64 aruid) {
void NPadResource::UnregisterAppletResourceUserId(u64 aruid) {
const u64 aruid_index = GetIndexFromAruid(aruid);
+ if (aruid_index >= AruidIndexMax) {
+ return;
+ }
FreeAppletResourceId(aruid);
if (aruid_index < AruidIndexMax) {