mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-03 05:09:41 +00:00
@@ -444,8 +444,6 @@ add_library(core STATIC
|
|||||||
hle/service/am/process_creation.h
|
hle/service/am/process_creation.h
|
||||||
hle/service/am/process_holder.cpp
|
hle/service/am/process_holder.cpp
|
||||||
hle/service/am/process_holder.h
|
hle/service/am/process_holder.h
|
||||||
hle/service/am/service/applet_common_functions.cpp
|
|
||||||
hle/service/am/service/applet_common_functions.h
|
|
||||||
hle/service/am/service/application_accessor.cpp
|
hle/service/am/service/application_accessor.cpp
|
||||||
hle/service/am/service/application_accessor.h
|
hle/service/am/service/application_accessor.h
|
||||||
hle/service/am/service/application_creator.cpp
|
hle/service/am/service/application_creator.cpp
|
||||||
@@ -458,8 +456,6 @@ add_library(core STATIC
|
|||||||
hle/service/am/service/common_state_getter.h
|
hle/service/am/service/common_state_getter.h
|
||||||
hle/service/am/service/cradle_firmware_updater.cpp
|
hle/service/am/service/cradle_firmware_updater.cpp
|
||||||
hle/service/am/service/cradle_firmware_updater.h
|
hle/service/am/service/cradle_firmware_updater.h
|
||||||
hle/service/am/service/debug_functions.cpp
|
|
||||||
hle/service/am/service/debug_functions.h
|
|
||||||
hle/service/am/service/display_controller.cpp
|
hle/service/am/service/display_controller.cpp
|
||||||
hle/service/am/service/display_controller.h
|
hle/service/am/service/display_controller.h
|
||||||
hle/service/am/service/global_state_controller.cpp
|
hle/service/am/service/global_state_controller.cpp
|
||||||
@@ -476,8 +472,6 @@ add_library(core STATIC
|
|||||||
hle/service/am/service/self_controller.h
|
hle/service/am/service/self_controller.h
|
||||||
hle/service/am/service/storage.cpp
|
hle/service/am/service/storage.cpp
|
||||||
hle/service/am/service/storage.h
|
hle/service/am/service/storage.h
|
||||||
hle/service/am/service/storage_accessor.cpp
|
|
||||||
hle/service/am/service/storage_accessor.h
|
|
||||||
hle/service/am/service/window_controller.cpp
|
hle/service/am/service/window_controller.cpp
|
||||||
hle/service/am/service/window_controller.h
|
hle/service/am/service/window_controller.h
|
||||||
hle/service/am/window_system.cpp
|
hle/service/am/window_system.cpp
|
||||||
@@ -564,8 +558,6 @@ add_library(core STATIC
|
|||||||
hle/service/btm/btm.h
|
hle/service/btm/btm.h
|
||||||
hle/service/caps/caps.cpp
|
hle/service/caps/caps.cpp
|
||||||
hle/service/caps/caps.h
|
hle/service/caps/caps.h
|
||||||
hle/service/caps/caps_a.cpp
|
|
||||||
hle/service/caps/caps_a.h
|
|
||||||
hle/service/caps/caps_c.cpp
|
hle/service/caps/caps_c.cpp
|
||||||
hle/service/caps/caps_c.h
|
hle/service/caps/caps_c.h
|
||||||
hle/service/caps/caps_manager.cpp
|
hle/service/caps/caps_manager.cpp
|
||||||
@@ -621,8 +613,6 @@ add_library(core STATIC
|
|||||||
hle/service/filesystem/save_data_controller.h
|
hle/service/filesystem/save_data_controller.h
|
||||||
hle/service/friend/friend.cpp
|
hle/service/friend/friend.cpp
|
||||||
hle/service/friend/friend.h
|
hle/service/friend/friend.h
|
||||||
hle/service/friend/friend_interface.cpp
|
|
||||||
hle/service/friend/friend_interface.h
|
|
||||||
hle/service/glue/arp.cpp
|
hle/service/glue/arp.cpp
|
||||||
hle/service/glue/arp.h
|
hle/service/glue/arp.h
|
||||||
hle/service/glue/bgtc.cpp
|
hle/service/glue/bgtc.cpp
|
||||||
@@ -691,8 +681,6 @@ add_library(core STATIC
|
|||||||
hle/service/ldn/monitor_service.h
|
hle/service/ldn/monitor_service.h
|
||||||
hle/service/ldn/sf_monitor_service.cpp
|
hle/service/ldn/sf_monitor_service.cpp
|
||||||
hle/service/ldn/sf_monitor_service.h
|
hle/service/ldn/sf_monitor_service.h
|
||||||
hle/service/ldn/sf_service.cpp
|
|
||||||
hle/service/ldn/sf_service.h
|
|
||||||
hle/service/ldn/sf_service_monitor.cpp
|
hle/service/ldn/sf_service_monitor.cpp
|
||||||
hle/service/ldn/sf_service_monitor.h
|
hle/service/ldn/sf_service_monitor.h
|
||||||
hle/service/ldn/system_local_communication_service.cpp
|
hle/service/ldn/system_local_communication_service.cpp
|
||||||
@@ -921,16 +909,8 @@ add_library(core STATIC
|
|||||||
hle/service/psc/ovln/ovln_types.h
|
hle/service/psc/ovln/ovln_types.h
|
||||||
hle/service/psc/ovln/receiver_service.cpp
|
hle/service/psc/ovln/receiver_service.cpp
|
||||||
hle/service/psc/ovln/receiver_service.h
|
hle/service/psc/ovln/receiver_service.h
|
||||||
hle/service/psc/ovln/receiver.cpp
|
|
||||||
hle/service/psc/ovln/receiver.h
|
|
||||||
hle/service/psc/ovln/sender_service.cpp
|
hle/service/psc/ovln/sender_service.cpp
|
||||||
hle/service/psc/ovln/sender_service.h
|
hle/service/psc/ovln/sender_service.h
|
||||||
hle/service/psc/ovln/sender.cpp
|
|
||||||
hle/service/psc/ovln/sender.h
|
|
||||||
hle/service/psc/pm_control.cpp
|
|
||||||
hle/service/psc/pm_control.h
|
|
||||||
hle/service/psc/pm_module.cpp
|
|
||||||
hle/service/psc/pm_module.h
|
|
||||||
hle/service/psc/psc.cpp
|
hle/service/psc/psc.cpp
|
||||||
hle/service/psc/psc.h
|
hle/service/psc/psc.h
|
||||||
hle/service/psc/time/alarms.cpp
|
hle/service/psc/time/alarms.cpp
|
||||||
@@ -981,10 +961,6 @@ add_library(core STATIC
|
|||||||
hle/service/ptm/ts.h
|
hle/service/ptm/ts.h
|
||||||
hle/service/ro/ro.cpp
|
hle/service/ro/ro.cpp
|
||||||
hle/service/ro/ro.h
|
hle/service/ro/ro.h
|
||||||
hle/service/ro/ro_nro_utils.cpp
|
|
||||||
hle/service/ro/ro_nro_utils.h
|
|
||||||
hle/service/ro/ro_results.h
|
|
||||||
hle/service/ro/ro_types.h
|
|
||||||
hle/service/server_manager.cpp
|
hle/service/server_manager.cpp
|
||||||
hle/service/server_manager.h
|
hle/service/server_manager.h
|
||||||
hle/service/service.cpp
|
hle/service/service.cpp
|
||||||
@@ -1013,8 +989,6 @@ add_library(core STATIC
|
|||||||
hle/service/set/system_settings_server.h
|
hle/service/set/system_settings_server.h
|
||||||
hle/service/sm/sm.cpp
|
hle/service/sm/sm.cpp
|
||||||
hle/service/sm/sm.h
|
hle/service/sm/sm.h
|
||||||
hle/service/sm/sm_controller.cpp
|
|
||||||
hle/service/sm/sm_controller.h
|
|
||||||
hle/service/sockets/bsd.cpp
|
hle/service/sockets/bsd.cpp
|
||||||
hle/service/sockets/bsd.h
|
hle/service/sockets/bsd.h
|
||||||
hle/service/sockets/nsd.cpp
|
hle/service/sockets/nsd.cpp
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/common_funcs.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/romfs_factory.h"
|
#include "core/file_sys/romfs_factory.h"
|
||||||
#include "core/file_sys/control_metadata.h"
|
#include "core/file_sys/control_metadata.h"
|
||||||
@@ -17,11 +18,9 @@
|
|||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/am/button_poller.h"
|
#include "core/hle/service/am/button_poller.h"
|
||||||
#include "core/hle/service/am/event_observer.h"
|
#include "core/hle/service/am/event_observer.h"
|
||||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
|
||||||
#include "core/hle/service/am/service/application_creator.h"
|
#include "core/hle/service/am/service/application_creator.h"
|
||||||
#include "core/hle/service/am/service/audio_controller.h"
|
#include "core/hle/service/am/service/audio_controller.h"
|
||||||
#include "core/hle/service/am/service/common_state_getter.h"
|
#include "core/hle/service/am/service/common_state_getter.h"
|
||||||
#include "core/hle/service/am/service/debug_functions.h"
|
|
||||||
#include "core/hle/service/am/service/display_controller.h"
|
#include "core/hle/service/am/service/display_controller.h"
|
||||||
#include "core/hle/service/am/service/global_state_controller.h"
|
#include "core/hle/service/am/service/global_state_controller.h"
|
||||||
#include "core/hle/service/am/service/home_menu_functions.h"
|
#include "core/hle/service/am/service/home_menu_functions.h"
|
||||||
@@ -62,6 +61,41 @@ class ISelfController;
|
|||||||
class IWindowController;
|
class IWindowController;
|
||||||
class WindowSystem;
|
class WindowSystem;
|
||||||
|
|
||||||
|
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
|
||||||
|
public:
|
||||||
|
explicit IDebugFunctions(Core::System& system_) : ServiceFramework{system_, "IDebugFunctions"} {}
|
||||||
|
~IDebugFunctions() override = default;
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, nullptr, "NotifyMessageToHomeMenuForDebug"},
|
||||||
|
FunctionInfo{1, nullptr, "OpenMainApplication"},
|
||||||
|
FunctionInfo{10, nullptr, "PerformSystemButtonPressing"},
|
||||||
|
FunctionInfo{20, nullptr, "InvalidateTransitionLayer"},
|
||||||
|
FunctionInfo{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
|
||||||
|
FunctionInfo{31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
|
||||||
|
FunctionInfo{40, nullptr, "GetAppletResourceUsageInfo"},
|
||||||
|
FunctionInfo{50, nullptr, "AddSystemProgramIdAndAppletIdForDebug"},
|
||||||
|
FunctionInfo{51, nullptr, "AddOperationConfirmedLibraryAppletIdForDebug"},
|
||||||
|
FunctionInfo{100, nullptr, "SetCpuBoostModeForApplet"},
|
||||||
|
FunctionInfo{101, nullptr, "CancelCpuBoostModeForApplet"},
|
||||||
|
FunctionInfo{110, nullptr, "PushToAppletBoundChannelForDebug"},
|
||||||
|
FunctionInfo{111, nullptr, "TryPopFromAppletBoundChannelForDebug"},
|
||||||
|
FunctionInfo{120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"},
|
||||||
|
FunctionInfo{121, nullptr, "AlarmSettingNotificationDisableAppEventReserve"},
|
||||||
|
FunctionInfo{122, nullptr, "AlarmSettingNotificationPushAppEventNotify"},
|
||||||
|
FunctionInfo{130, nullptr, "FriendInvitationSetApplicationParameter"},
|
||||||
|
FunctionInfo{131, nullptr, "FriendInvitationClearApplicationParameter"},
|
||||||
|
FunctionInfo{132, nullptr, "FriendInvitationPushApplicationParameter"},
|
||||||
|
FunctionInfo{140, nullptr, "RestrictPowerOperationForSecureLaunchModeForDebug"},
|
||||||
|
FunctionInfo{200, nullptr, "CreateFloatingLibraryAppletAccepterForDebug"},
|
||||||
|
FunctionInfo{300, nullptr, "TerminateAllRunningApplicationsForDebug"},
|
||||||
|
FunctionInfo{900, nullptr, "GetGrcProcessLaunchedSystemEvent"}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
|
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
|
||||||
public:
|
public:
|
||||||
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
@@ -193,6 +227,87 @@ public:
|
|||||||
WindowSystem& m_window_system;
|
WindowSystem& m_window_system;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> {
|
||||||
|
public:
|
||||||
|
explicit IAppletCommonFunctions(Core::System& system_, std::shared_ptr<Applet> applet_) : ServiceFramework{system_, "IAppletCommonFunctions"}, applet{std::move(applet_)} {}
|
||||||
|
~IAppletCommonFunctions() override = default;
|
||||||
|
|
||||||
|
Result SetHomeButtonDoubleClickEnabled(
|
||||||
|
bool home_button_double_click_enabled) {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called, home_button_double_click_enabled={}", home_button_double_click_enabled);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetHomeButtonDoubleClickEnabled(
|
||||||
|
Out<bool> out_home_button_double_click_enabled) {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
*out_home_button_double_click_enabled = false;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height) {
|
||||||
|
LOG_DEBUG(Service_AM, "(STUBBED) called, x={}, y={}, width={}, height={}", x, y, width, height);
|
||||||
|
std::scoped_lock lk{applet->lock};
|
||||||
|
applet->display_magnification = Common::Rectangle<f32>{x, y, x + width, y + height};
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result SetCpuBoostRequestPriority(s32 priority) {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
std::scoped_lock lk{applet->lock};
|
||||||
|
applet->cpu_boost_request_priority = priority;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetCurrentApplicationId(Out<u64> out_application_id) {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
*out_application_id = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID());
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result SetGpuTimeSliceBoost(s64 time_span) {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called, time_span={}", time_span);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Unknown350(Out<u16> out_unknown) {
|
||||||
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
*out_unknown = 0;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, nullptr, "SetTerminateResult"},
|
||||||
|
FunctionInfo{10, nullptr, "ReadThemeStorage"},
|
||||||
|
FunctionInfo{11, nullptr, "WriteThemeStorage"},
|
||||||
|
FunctionInfo{20, nullptr, "PushToAppletBoundChannel"},
|
||||||
|
FunctionInfo{21, nullptr, "TryPopFromAppletBoundChannel"},
|
||||||
|
FunctionInfo{40, nullptr, "GetDisplayLogicalResolution"},
|
||||||
|
FunctionInfo{42, D<&IAppletCommonFunctions::SetDisplayMagnification>, "SetDisplayMagnification"},
|
||||||
|
FunctionInfo{50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"},
|
||||||
|
FunctionInfo{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
|
||||||
|
FunctionInfo{52, nullptr, "IsHomeButtonShortPressedBlocked"},
|
||||||
|
FunctionInfo{60, nullptr, "IsVrModeCurtainRequired"},
|
||||||
|
FunctionInfo{61, nullptr, "IsSleepRequiredByHighTemperature"},
|
||||||
|
FunctionInfo{62, nullptr, "IsSleepRequiredByLowBattery"},
|
||||||
|
FunctionInfo{70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"},
|
||||||
|
FunctionInfo{80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"},
|
||||||
|
FunctionInfo{81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"},
|
||||||
|
FunctionInfo{90, nullptr, "OpenNamedChannelAsParent"},
|
||||||
|
FunctionInfo{91, nullptr, "OpenNamedChannelAsChild"},
|
||||||
|
FunctionInfo{100, nullptr, "SetApplicationCoreUsageMode"},
|
||||||
|
FunctionInfo{300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"},
|
||||||
|
FunctionInfo{310, nullptr, "IsSystemAppletHomeMenu"}, //19.0.0+
|
||||||
|
FunctionInfo{320, D<&IAppletCommonFunctions::SetGpuTimeSliceBoost>, "SetGpuTimeSliceBoost"}, //19.0.0+
|
||||||
|
FunctionInfo{321, nullptr, "SetGpuTimeSliceBoostDueToApplication"}, //19.0.0+
|
||||||
|
FunctionInfo{350, D<&IAppletCommonFunctions::Unknown350>, "Unknown350"} //20.0.0+
|
||||||
|
);
|
||||||
|
const std::shared_ptr<Applet> applet;
|
||||||
|
};
|
||||||
|
|
||||||
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
|
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
|
||||||
public:
|
public:
|
||||||
explicit ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, Kernel::KProcess* process, WindowSystem& window_system)
|
explicit ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet, Kernel::KProcess* process, WindowSystem& window_system)
|
||||||
|
|||||||
@@ -1,98 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/file_sys/common_funcs.h"
|
|
||||||
#include "core/hle/service/am/applet.h"
|
|
||||||
#include "core/hle/service/am/service/applet_common_functions.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAppletCommonFunctions::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, nullptr, "SetTerminateResult"},
|
|
||||||
FunctionInfo{10, nullptr, "ReadThemeStorage"},
|
|
||||||
FunctionInfo{11, nullptr, "WriteThemeStorage"},
|
|
||||||
FunctionInfo{20, nullptr, "PushToAppletBoundChannel"},
|
|
||||||
FunctionInfo{21, nullptr, "TryPopFromAppletBoundChannel"},
|
|
||||||
FunctionInfo{40, nullptr, "GetDisplayLogicalResolution"},
|
|
||||||
FunctionInfo{42, D<&IAppletCommonFunctions::SetDisplayMagnification>, "SetDisplayMagnification"},
|
|
||||||
FunctionInfo{50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"},
|
|
||||||
FunctionInfo{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
|
|
||||||
FunctionInfo{52, nullptr, "IsHomeButtonShortPressedBlocked"},
|
|
||||||
FunctionInfo{60, nullptr, "IsVrModeCurtainRequired"},
|
|
||||||
FunctionInfo{61, nullptr, "IsSleepRequiredByHighTemperature"},
|
|
||||||
FunctionInfo{62, nullptr, "IsSleepRequiredByLowBattery"},
|
|
||||||
FunctionInfo{70, D<&IAppletCommonFunctions::SetCpuBoostRequestPriority>, "SetCpuBoostRequestPriority"},
|
|
||||||
FunctionInfo{80, nullptr, "SetHandlingCaptureButtonShortPressedMessageEnabledForApplet"},
|
|
||||||
FunctionInfo{81, nullptr, "SetHandlingCaptureButtonLongPressedMessageEnabledForApplet"},
|
|
||||||
FunctionInfo{90, nullptr, "OpenNamedChannelAsParent"},
|
|
||||||
FunctionInfo{91, nullptr, "OpenNamedChannelAsChild"},
|
|
||||||
FunctionInfo{100, nullptr, "SetApplicationCoreUsageMode"},
|
|
||||||
FunctionInfo{300, D<&IAppletCommonFunctions::GetCurrentApplicationId>, "GetCurrentApplicationId"},
|
|
||||||
FunctionInfo{310, nullptr, "IsSystemAppletHomeMenu"}, //19.0.0+
|
|
||||||
FunctionInfo{320, D<&IAppletCommonFunctions::SetGpuTimeSliceBoost>, "SetGpuTimeSliceBoost"}, //19.0.0+
|
|
||||||
FunctionInfo{321, nullptr, "SetGpuTimeSliceBoostDueToApplication"}, //19.0.0+
|
|
||||||
FunctionInfo{350, D<&IAppletCommonFunctions::Unknown350>, "Unknown350"} //20.0.0+
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
|
|
||||||
std::shared_ptr<Applet> applet_)
|
|
||||||
: ServiceFramework{system_, "IAppletCommonFunctions"}, applet{std::move(applet_)} {
|
|
||||||
}
|
|
||||||
|
|
||||||
IAppletCommonFunctions::~IAppletCommonFunctions() = default;
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled(
|
|
||||||
bool home_button_double_click_enabled) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called, home_button_double_click_enabled={}",
|
|
||||||
home_button_double_click_enabled);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled(
|
|
||||||
Out<bool> out_home_button_double_click_enabled) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
|
||||||
*out_home_button_double_click_enabled = false;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height) {
|
|
||||||
LOG_DEBUG(Service_AM, "(STUBBED) called, x={}, y={}, width={}, height={}", x, y, width,
|
|
||||||
height);
|
|
||||||
std::scoped_lock lk{applet->lock};
|
|
||||||
applet->display_magnification = Common::Rectangle<f32>{x, y, x + width, y + height};
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::SetCpuBoostRequestPriority(s32 priority) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
|
||||||
std::scoped_lock lk{applet->lock};
|
|
||||||
applet->cpu_boost_request_priority = priority;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::GetCurrentApplicationId(Out<u64> out_application_id) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
|
||||||
*out_application_id = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID());
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::SetGpuTimeSliceBoost(s64 time_span) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called, time_span={}", time_span);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::Unknown350(Out<u16> out_unknown) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
|
||||||
*out_unknown = 0;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
struct Applet;
|
|
||||||
|
|
||||||
class IAppletCommonFunctions final : public ServiceFramework<IAppletCommonFunctions> {
|
|
||||||
public:
|
|
||||||
explicit IAppletCommonFunctions(Core::System& system_, std::shared_ptr<Applet> applet_);
|
|
||||||
~IAppletCommonFunctions() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Result SetHomeButtonDoubleClickEnabled(bool home_button_double_click_enabled);
|
|
||||||
Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled);
|
|
||||||
Result SetDisplayMagnification(f32 x, f32 y, f32 width, f32 height);
|
|
||||||
Result SetCpuBoostRequestPriority(s32 priority);
|
|
||||||
Result GetCurrentApplicationId(Out<u64> out_application_id);
|
|
||||||
Result SetGpuTimeSliceBoost(s64 time_span);
|
|
||||||
Result Unknown350(Out<u16> out_unknown);
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
const std::shared_ptr<Applet> applet;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/am/service/debug_functions.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
IDebugFunctions::IDebugFunctions(Core::System& system_)
|
|
||||||
: ServiceFramework{system_, "IDebugFunctions"} {
|
|
||||||
}
|
|
||||||
|
|
||||||
IDebugFunctions::~IDebugFunctions() = default;
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
class IDebugFunctions final : public ServiceFramework<IDebugFunctions> {
|
|
||||||
public:
|
|
||||||
explicit IDebugFunctions(Core::System& system_);
|
|
||||||
~IDebugFunctions() override;
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, nullptr, "NotifyMessageToHomeMenuForDebug"},
|
|
||||||
FunctionInfo{1, nullptr, "OpenMainApplication"},
|
|
||||||
FunctionInfo{10, nullptr, "PerformSystemButtonPressing"},
|
|
||||||
FunctionInfo{20, nullptr, "InvalidateTransitionLayer"},
|
|
||||||
FunctionInfo{30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
|
|
||||||
FunctionInfo{31, nullptr, "RequestLaunchApplicationByApplicationLaunchInfoForDebug"},
|
|
||||||
FunctionInfo{40, nullptr, "GetAppletResourceUsageInfo"},
|
|
||||||
FunctionInfo{50, nullptr, "AddSystemProgramIdAndAppletIdForDebug"},
|
|
||||||
FunctionInfo{51, nullptr, "AddOperationConfirmedLibraryAppletIdForDebug"},
|
|
||||||
FunctionInfo{100, nullptr, "SetCpuBoostModeForApplet"},
|
|
||||||
FunctionInfo{101, nullptr, "CancelCpuBoostModeForApplet"},
|
|
||||||
FunctionInfo{110, nullptr, "PushToAppletBoundChannelForDebug"},
|
|
||||||
FunctionInfo{111, nullptr, "TryPopFromAppletBoundChannelForDebug"},
|
|
||||||
FunctionInfo{120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"},
|
|
||||||
FunctionInfo{121, nullptr, "AlarmSettingNotificationDisableAppEventReserve"},
|
|
||||||
FunctionInfo{122, nullptr, "AlarmSettingNotificationPushAppEventNotify"},
|
|
||||||
FunctionInfo{130, nullptr, "FriendInvitationSetApplicationParameter"},
|
|
||||||
FunctionInfo{131, nullptr, "FriendInvitationClearApplicationParameter"},
|
|
||||||
FunctionInfo{132, nullptr, "FriendInvitationPushApplicationParameter"},
|
|
||||||
FunctionInfo{140, nullptr, "RestrictPowerOperationForSecureLaunchModeForDebug"},
|
|
||||||
FunctionInfo{200, nullptr, "CreateFloatingLibraryAppletAccepterForDebug"},
|
|
||||||
FunctionInfo{300, nullptr, "TerminateAllRunningApplicationsForDebug"},
|
|
||||||
FunctionInfo{900, nullptr, "GetGrcProcessLaunchedSystemEvent"}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
||||||
@@ -4,14 +4,76 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_transfer_memory.h"
|
||||||
#include "core/hle/service/am/am_results.h"
|
#include "core/hle/service/am/am_results.h"
|
||||||
#include "core/hle/service/am/library_applet_storage.h"
|
#include "core/hle/service/am/library_applet_storage.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
#include "core/hle/service/am/service/storage_accessor.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
|
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||||
|
public:
|
||||||
|
explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl) : ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} {}
|
||||||
|
~IStorageAccessor() override = default;
|
||||||
|
|
||||||
|
Result GetSize(Out<s64> out_size) {
|
||||||
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
*out_size = m_impl->GetSize();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) {
|
||||||
|
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size());
|
||||||
|
R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) {
|
||||||
|
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size());
|
||||||
|
R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, D<&IStorageAccessor::GetSize>, "GetSize"},
|
||||||
|
FunctionInfo{10, D<&IStorageAccessor::Write>, "Write"},
|
||||||
|
FunctionInfo{11, D<&IStorageAccessor::Read>, "Read"}
|
||||||
|
);
|
||||||
|
|
||||||
|
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> {
|
||||||
|
public:
|
||||||
|
explicit ITransferStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl) : ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} {}
|
||||||
|
~ITransferStorageAccessor() override = default;
|
||||||
|
|
||||||
|
Result GetSize(Out<s64> out_size) {
|
||||||
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
*out_size = m_impl->GetSize();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle) {
|
||||||
|
LOG_INFO(Service_AM, "called");
|
||||||
|
*out_size = m_impl->GetSize();
|
||||||
|
*out_handle = m_impl->GetHandle();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, D<&ITransferStorageAccessor::GetSize>, "GetSize"},
|
||||||
|
FunctionInfo{1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"}
|
||||||
|
);
|
||||||
|
|
||||||
|
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IStorage::FindRequest(u32 key) {
|
std::optional<ServiceFrameworkBase::FunctionInfoBase> IStorage::FindRequest(u32 key) {
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, D<&IStorage::Open>, "Open"},
|
FunctionInfo{0, D<&IStorage::Open>, "Open"},
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/kernel/k_transfer_memory.h"
|
|
||||||
#include "core/hle/service/am/library_applet_storage.h"
|
|
||||||
#include "core/hle/service/am/service/storage_accessor.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IStorageAccessor::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, D<&IStorageAccessor::GetSize>, "GetSize"},
|
|
||||||
FunctionInfo{10, D<&IStorageAccessor::Write>, "Write"},
|
|
||||||
FunctionInfo{11, D<&IStorageAccessor::Read>, "Read"}
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
IStorageAccessor::IStorageAccessor(Core::System& system_,
|
|
||||||
std::shared_ptr<LibraryAppletStorage> impl)
|
|
||||||
: ServiceFramework{system_, "IStorageAccessor"}, m_impl{std::move(impl)} {
|
|
||||||
}
|
|
||||||
|
|
||||||
IStorageAccessor::~IStorageAccessor() = default;
|
|
||||||
|
|
||||||
Result IStorageAccessor::GetSize(Out<s64> out_size) {
|
|
||||||
LOG_DEBUG(Service_AM, "called");
|
|
||||||
*out_size = m_impl->GetSize();
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IStorageAccessor::Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset) {
|
|
||||||
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, buffer.size());
|
|
||||||
R_RETURN(m_impl->Write(offset, buffer.data(), buffer.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IStorageAccessor::Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset) {
|
|
||||||
LOG_DEBUG(Service_AM, "called, offset={} size={}", offset, out_buffer.size());
|
|
||||||
R_RETURN(m_impl->Read(offset, out_buffer.data(), out_buffer.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ITransferStorageAccessor::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, D<&ITransferStorageAccessor::GetSize>, "GetSize"},
|
|
||||||
FunctionInfo{1, D<&ITransferStorageAccessor::GetHandle>, "GetHandle"}
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
ITransferStorageAccessor::ITransferStorageAccessor(Core::System& system_,
|
|
||||||
std::shared_ptr<LibraryAppletStorage> impl)
|
|
||||||
: ServiceFramework{system_, "ITransferStorageAccessor"}, m_impl{std::move(impl)} {
|
|
||||||
}
|
|
||||||
|
|
||||||
ITransferStorageAccessor::~ITransferStorageAccessor() = default;
|
|
||||||
|
|
||||||
Result ITransferStorageAccessor::GetSize(Out<s64> out_size) {
|
|
||||||
LOG_DEBUG(Service_AM, "called");
|
|
||||||
*out_size = m_impl->GetSize();
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result ITransferStorageAccessor::GetHandle(Out<s64> out_size,
|
|
||||||
OutCopyHandle<Kernel::KTransferMemory> out_handle) {
|
|
||||||
LOG_INFO(Service_AM, "called");
|
|
||||||
*out_size = m_impl->GetSize();
|
|
||||||
*out_handle = m_impl->GetHandle();
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/am/library_applet_storage.h"
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
|
||||||
|
|
||||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
|
||||||
public:
|
|
||||||
explicit IStorageAccessor(Core::System& system_, std::shared_ptr<LibraryAppletStorage> impl);
|
|
||||||
~IStorageAccessor() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Result GetSize(Out<s64> out_size);
|
|
||||||
Result Write(InBuffer<BufferAttr_HipcAutoSelect> buffer, s64 offset);
|
|
||||||
Result Read(OutBuffer<BufferAttr_HipcAutoSelect> out_buffer, s64 offset);
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ITransferStorageAccessor final : public ServiceFramework<ITransferStorageAccessor> {
|
|
||||||
public:
|
|
||||||
explicit ITransferStorageAccessor(Core::System& system_,
|
|
||||||
std::shared_ptr<LibraryAppletStorage> impl);
|
|
||||||
~ITransferStorageAccessor() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Result GetSize(Out<s64> out_size);
|
|
||||||
Result GetHandle(Out<s64> out_size, OutCopyHandle<Kernel::KTransferMemory> out_handle);
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
const std::shared_ptr<LibraryAppletStorage> m_impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
|
||||||
@@ -5,7 +5,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/caps/caps.h"
|
#include "core/hle/service/caps/caps.h"
|
||||||
#include "core/hle/service/caps/caps_a.h"
|
|
||||||
#include "core/hle/service/caps/caps_c.h"
|
#include "core/hle/service/caps/caps_c.h"
|
||||||
#include "core/hle/service/caps/caps_manager.h"
|
#include "core/hle/service/caps/caps_manager.h"
|
||||||
#include "core/hle/service/caps/caps_sc.h"
|
#include "core/hle/service/caps/caps_sc.h"
|
||||||
@@ -14,7 +13,11 @@
|
|||||||
#include "core/hle/service/caps/caps_u.h"
|
#include "core/hle/service/caps/caps_u.h"
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "common/logging.h"
|
||||||
#include "frontend_common/firmware_manager.h"
|
#include "frontend_common/firmware_manager.h"
|
||||||
|
#include "core/hle/service/caps/caps_result.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
|
||||||
namespace Service::Capture {
|
namespace Service::Capture {
|
||||||
|
|
||||||
@@ -32,6 +35,201 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IAlbumAccessorService final : public ServiceFramework<IAlbumAccessorService> {
|
||||||
|
public:
|
||||||
|
explicit IAlbumAccessorService(Core::System& system_, std::shared_ptr<AlbumManager> album_manager) : ServiceFramework{system_, "caps:a"}, manager{album_manager} {}
|
||||||
|
~IAlbumAccessorService() override = default;
|
||||||
|
|
||||||
|
Result GetAlbumFileList(
|
||||||
|
Out<u64> out_count, AlbumStorage storage,
|
||||||
|
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
|
||||||
|
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
||||||
|
|
||||||
|
const Result result = manager->GetAlbumFileList(out_entries, *out_count, storage, 0);
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result DeleteAlbumFile(AlbumFileId file_id) {
|
||||||
|
LOG_INFO(Service_Capture, "called, application_id={:#0x}, storage={}, type={}",
|
||||||
|
file_id.application_id, file_id.storage, file_id.type);
|
||||||
|
|
||||||
|
const Result result = manager->DeleteAlbumFile(file_id);
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage) {
|
||||||
|
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
||||||
|
|
||||||
|
const Result result = manager->IsAlbumMounted(storage);
|
||||||
|
*out_is_mounted = result.IsSuccess();
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Unknown18(
|
||||||
|
Out<u32> out_buffer_size,
|
||||||
|
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer) {
|
||||||
|
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
||||||
|
*out_buffer_size = 0;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetAlbumFileListEx0(
|
||||||
|
Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
|
||||||
|
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
|
||||||
|
LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags);
|
||||||
|
|
||||||
|
const Result result = manager->GetAlbumFileList(out_entries, *out_entries_size, storage, flags);
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetAutoSavingStorage(Out<bool> out_is_autosaving) {
|
||||||
|
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
||||||
|
|
||||||
|
const Result result = manager->GetAutoSavingStorage(*out_is_autosaving);
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result LoadAlbumScreenShotImageEx1(
|
||||||
|
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
|
||||||
|
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
|
||||||
|
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
|
||||||
|
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
|
||||||
|
LOG_INFO(Service_Capture, "called, application_id={:#0x}, storage={}, type={}, flags={}",
|
||||||
|
file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
|
||||||
|
|
||||||
|
const Result result =
|
||||||
|
manager->LoadAlbumScreenShotImage(*out_image_output, out_image, file_id, decoder_options);
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result LoadAlbumScreenShotThumbnailImageEx1(
|
||||||
|
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
|
||||||
|
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
|
||||||
|
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
|
||||||
|
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
|
||||||
|
LOG_INFO(Service_Capture, "called, application_id={:#0x}, storage={}, type={}, flags={}",
|
||||||
|
file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
|
||||||
|
|
||||||
|
const Result result = manager->LoadAlbumScreenShotThumbnail(*out_image_output, out_image,
|
||||||
|
file_id, decoder_options);
|
||||||
|
R_RETURN(TranslateResult(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result TranslateResult(Result in_result) {
|
||||||
|
if (in_result.IsSuccess()) {
|
||||||
|
return in_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((in_result.raw & 0x3801ff) == ResultUnknown1024.raw) {
|
||||||
|
if (in_result.GetDescription() - 0x514 < 100) {
|
||||||
|
return ResultInvalidFileData;
|
||||||
|
}
|
||||||
|
if (in_result.GetDescription() - 0x5dc < 100) {
|
||||||
|
return ResultInvalidFileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_result.GetDescription() - 0x578 < 100) {
|
||||||
|
if (in_result == ResultFileCountLimit) {
|
||||||
|
return ResultUnknown22;
|
||||||
|
}
|
||||||
|
return ResultUnknown25;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_result.raw < ResultUnknown1801.raw) {
|
||||||
|
if (in_result == ResultUnknown1202) {
|
||||||
|
return ResultUnknown810;
|
||||||
|
}
|
||||||
|
if (in_result == ResultUnknown1203) {
|
||||||
|
return ResultUnknown810;
|
||||||
|
}
|
||||||
|
if (in_result == ResultUnknown1701) {
|
||||||
|
return ResultUnknown5;
|
||||||
|
}
|
||||||
|
} else if (in_result.raw < ResultUnknown1803.raw) {
|
||||||
|
if (in_result == ResultUnknown1801) {
|
||||||
|
return ResultUnknown5;
|
||||||
|
}
|
||||||
|
if (in_result == ResultUnknown1802) {
|
||||||
|
return ResultUnknown6;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (in_result == ResultUnknown1803) {
|
||||||
|
return ResultUnknown7;
|
||||||
|
}
|
||||||
|
if (in_result == ResultUnknown1804) {
|
||||||
|
return ResultOutOfRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResultUnknown1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_result.GetModule() == ErrorModule::FS) {
|
||||||
|
if ((in_result.GetDescription() >> 0xc < 0x7d) ||
|
||||||
|
(in_result.GetDescription() - 1000 < 2000) ||
|
||||||
|
(((in_result.GetDescription() - 3000) >> 3) < 0x271)) {
|
||||||
|
// TODO: Translate FS error
|
||||||
|
return in_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetAlbumAccessResultForDebug(Out<Result> out_result) {
|
||||||
|
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
||||||
|
*out_result = ResultSuccess;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, nullptr, "GetAlbumFileCount"},
|
||||||
|
FunctionInfo{1, C<&IAlbumAccessorService::GetAlbumFileList>, "GetAlbumFileList"},
|
||||||
|
FunctionInfo{2, nullptr, "LoadAlbumFile"},
|
||||||
|
FunctionInfo{3, C<&IAlbumAccessorService::DeleteAlbumFile>, "DeleteAlbumFile"},
|
||||||
|
FunctionInfo{4, nullptr, "StorageCopyAlbumFile"},
|
||||||
|
FunctionInfo{5, C<&IAlbumAccessorService::IsAlbumMounted>, "IsAlbumMounted"},
|
||||||
|
FunctionInfo{6, nullptr, "GetAlbumUsage"},
|
||||||
|
FunctionInfo{7, nullptr, "GetAlbumFileSize"},
|
||||||
|
FunctionInfo{8, nullptr, "LoadAlbumFileThumbnail"},
|
||||||
|
FunctionInfo{9, nullptr, "LoadAlbumScreenShotImage"},
|
||||||
|
FunctionInfo{10, nullptr, "LoadAlbumScreenShotThumbnailImage"},
|
||||||
|
FunctionInfo{11, nullptr, "GetAlbumEntryFromApplicationAlbumEntry"},
|
||||||
|
FunctionInfo{12, nullptr, "LoadAlbumScreenShotImageEx"},
|
||||||
|
FunctionInfo{13, nullptr, "LoadAlbumScreenShotThumbnailImageEx"},
|
||||||
|
FunctionInfo{14, nullptr, "LoadAlbumScreenShotImageEx0"},
|
||||||
|
FunctionInfo{15, nullptr, "GetAlbumUsage3"},
|
||||||
|
FunctionInfo{16, nullptr, "GetAlbumMountResult"},
|
||||||
|
FunctionInfo{17, nullptr, "GetAlbumUsage16"},
|
||||||
|
FunctionInfo{18, C<&IAlbumAccessorService::Unknown18>, "Unknown18"},
|
||||||
|
FunctionInfo{19, nullptr, "Unknown19"},
|
||||||
|
FunctionInfo{100, nullptr, "GetAlbumFileCountEx0"},
|
||||||
|
FunctionInfo{101, C<&IAlbumAccessorService::GetAlbumFileListEx0>, "GetAlbumFileListEx0"},
|
||||||
|
FunctionInfo{202, nullptr, "SaveEditedScreenShot"},
|
||||||
|
FunctionInfo{301, nullptr, "GetLastThumbnail"},
|
||||||
|
FunctionInfo{302, nullptr, "GetLastOverlayMovieThumbnail"},
|
||||||
|
FunctionInfo{401, C<&IAlbumAccessorService::GetAutoSavingStorage>, "GetAutoSavingStorage"},
|
||||||
|
FunctionInfo{501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"},
|
||||||
|
FunctionInfo{1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"},
|
||||||
|
FunctionInfo{1002, C<&IAlbumAccessorService::LoadAlbumScreenShotImageEx1>, "LoadAlbumScreenShotImageEx1"},
|
||||||
|
FunctionInfo{1003, C<&IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1>, "LoadAlbumScreenShotThumbnailImageEx1"},
|
||||||
|
FunctionInfo{8001, nullptr, "ForceAlbumUnmounted"},
|
||||||
|
FunctionInfo{8002, nullptr, "ResetAlbumMountStatus"},
|
||||||
|
FunctionInfo{8011, nullptr, "RefreshAlbumCache"},
|
||||||
|
FunctionInfo{8012, nullptr, "GetAlbumCache"},
|
||||||
|
FunctionInfo{8013, nullptr, "GetAlbumCacheEx"},
|
||||||
|
FunctionInfo{8021, nullptr, "GetAlbumEntryFromApplicationAlbumEntryAruid"},
|
||||||
|
FunctionInfo{10011, nullptr, "SetInternalErrorConversionEnabled"},
|
||||||
|
FunctionInfo{50000, nullptr, "LoadMakerNoteInfoForDebug"},
|
||||||
|
FunctionInfo{50011, C<&IAlbumAccessorService::GetAlbumAccessResultForDebug>, "GetAlbumAccessResultForDebug"},
|
||||||
|
FunctionInfo{60002, nullptr, "OpenAccessorSession"}
|
||||||
|
);
|
||||||
|
|
||||||
|
std::shared_ptr<AlbumManager> manager = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
void LoopProcess(Core::System& system) {
|
void LoopProcess(Core::System& system) {
|
||||||
auto server_manager = std::make_unique<ServerManager>(system);
|
auto server_manager = std::make_unique<ServerManager>(system);
|
||||||
auto album_manager = std::make_shared<AlbumManager>(system);
|
auto album_manager = std::make_shared<AlbumManager>(system);
|
||||||
|
|||||||
@@ -1,211 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
#include "common/logging.h"
|
|
||||||
#include "core/hle/service/caps/caps_a.h"
|
|
||||||
#include "core/hle/service/caps/caps_manager.h"
|
|
||||||
#include "core/hle/service/caps/caps_result.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
|
||||||
|
|
||||||
namespace Service::Capture {
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IAlbumAccessorService::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, nullptr, "GetAlbumFileCount"},
|
|
||||||
FunctionInfo{1, C<&IAlbumAccessorService::GetAlbumFileList>, "GetAlbumFileList"},
|
|
||||||
FunctionInfo{2, nullptr, "LoadAlbumFile"},
|
|
||||||
FunctionInfo{3, C<&IAlbumAccessorService::DeleteAlbumFile>, "DeleteAlbumFile"},
|
|
||||||
FunctionInfo{4, nullptr, "StorageCopyAlbumFile"},
|
|
||||||
FunctionInfo{5, C<&IAlbumAccessorService::IsAlbumMounted>, "IsAlbumMounted"},
|
|
||||||
FunctionInfo{6, nullptr, "GetAlbumUsage"},
|
|
||||||
FunctionInfo{7, nullptr, "GetAlbumFileSize"},
|
|
||||||
FunctionInfo{8, nullptr, "LoadAlbumFileThumbnail"},
|
|
||||||
FunctionInfo{9, nullptr, "LoadAlbumScreenShotImage"},
|
|
||||||
FunctionInfo{10, nullptr, "LoadAlbumScreenShotThumbnailImage"},
|
|
||||||
FunctionInfo{11, nullptr, "GetAlbumEntryFromApplicationAlbumEntry"},
|
|
||||||
FunctionInfo{12, nullptr, "LoadAlbumScreenShotImageEx"},
|
|
||||||
FunctionInfo{13, nullptr, "LoadAlbumScreenShotThumbnailImageEx"},
|
|
||||||
FunctionInfo{14, nullptr, "LoadAlbumScreenShotImageEx0"},
|
|
||||||
FunctionInfo{15, nullptr, "GetAlbumUsage3"},
|
|
||||||
FunctionInfo{16, nullptr, "GetAlbumMountResult"},
|
|
||||||
FunctionInfo{17, nullptr, "GetAlbumUsage16"},
|
|
||||||
FunctionInfo{18, C<&IAlbumAccessorService::Unknown18>, "Unknown18"},
|
|
||||||
FunctionInfo{19, nullptr, "Unknown19"},
|
|
||||||
FunctionInfo{100, nullptr, "GetAlbumFileCountEx0"},
|
|
||||||
FunctionInfo{101, C<&IAlbumAccessorService::GetAlbumFileListEx0>, "GetAlbumFileListEx0"},
|
|
||||||
FunctionInfo{202, nullptr, "SaveEditedScreenShot"},
|
|
||||||
FunctionInfo{301, nullptr, "GetLastThumbnail"},
|
|
||||||
FunctionInfo{302, nullptr, "GetLastOverlayMovieThumbnail"},
|
|
||||||
FunctionInfo{401, C<&IAlbumAccessorService::GetAutoSavingStorage>, "GetAutoSavingStorage"},
|
|
||||||
FunctionInfo{501, nullptr, "GetRequiredStorageSpaceSizeToCopyAll"},
|
|
||||||
FunctionInfo{1001, nullptr, "LoadAlbumScreenShotThumbnailImageEx0"},
|
|
||||||
FunctionInfo{1002, C<&IAlbumAccessorService::LoadAlbumScreenShotImageEx1>, "LoadAlbumScreenShotImageEx1"},
|
|
||||||
FunctionInfo{1003, C<&IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1>, "LoadAlbumScreenShotThumbnailImageEx1"},
|
|
||||||
FunctionInfo{8001, nullptr, "ForceAlbumUnmounted"},
|
|
||||||
FunctionInfo{8002, nullptr, "ResetAlbumMountStatus"},
|
|
||||||
FunctionInfo{8011, nullptr, "RefreshAlbumCache"},
|
|
||||||
FunctionInfo{8012, nullptr, "GetAlbumCache"},
|
|
||||||
FunctionInfo{8013, nullptr, "GetAlbumCacheEx"},
|
|
||||||
FunctionInfo{8021, nullptr, "GetAlbumEntryFromApplicationAlbumEntryAruid"},
|
|
||||||
FunctionInfo{10011, nullptr, "SetInternalErrorConversionEnabled"},
|
|
||||||
FunctionInfo{50000, nullptr, "LoadMakerNoteInfoForDebug"},
|
|
||||||
FunctionInfo{50011, C<&IAlbumAccessorService::GetAlbumAccessResultForDebug>, "GetAlbumAccessResultForDebug"},
|
|
||||||
FunctionInfo{60002, nullptr, "OpenAccessorSession"}
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
IAlbumAccessorService::IAlbumAccessorService(Core::System& system_,
|
|
||||||
std::shared_ptr<AlbumManager> album_manager)
|
|
||||||
: ServiceFramework{system_, "caps:a"}, manager{album_manager} {
|
|
||||||
}
|
|
||||||
|
|
||||||
IAlbumAccessorService::~IAlbumAccessorService() = default;
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::GetAlbumFileList(
|
|
||||||
Out<u64> out_count, AlbumStorage storage,
|
|
||||||
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
|
|
||||||
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
|
||||||
|
|
||||||
const Result result = manager->GetAlbumFileList(out_entries, *out_count, storage, 0);
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::DeleteAlbumFile(AlbumFileId file_id) {
|
|
||||||
LOG_INFO(Service_Capture, "called, application_id={:#0x}, storage={}, type={}",
|
|
||||||
file_id.application_id, file_id.storage, file_id.type);
|
|
||||||
|
|
||||||
const Result result = manager->DeleteAlbumFile(file_id);
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage) {
|
|
||||||
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
|
||||||
|
|
||||||
const Result result = manager->IsAlbumMounted(storage);
|
|
||||||
*out_is_mounted = result.IsSuccess();
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::Unknown18(
|
|
||||||
Out<u32> out_buffer_size,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_buffer) {
|
|
||||||
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
|
||||||
*out_buffer_size = 0;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::GetAlbumFileListEx0(
|
|
||||||
Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
|
|
||||||
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries) {
|
|
||||||
LOG_INFO(Service_Capture, "called, storage={}, flags={}", storage, flags);
|
|
||||||
|
|
||||||
const Result result = manager->GetAlbumFileList(out_entries, *out_entries_size, storage, flags);
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::GetAutoSavingStorage(Out<bool> out_is_autosaving) {
|
|
||||||
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
|
||||||
|
|
||||||
const Result result = manager->GetAutoSavingStorage(*out_is_autosaving);
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::LoadAlbumScreenShotImageEx1(
|
|
||||||
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
|
|
||||||
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
|
|
||||||
LOG_INFO(Service_Capture, "called, application_id={:#0x}, storage={}, type={}, flags={}",
|
|
||||||
file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
|
|
||||||
|
|
||||||
const Result result =
|
|
||||||
manager->LoadAlbumScreenShotImage(*out_image_output, out_image, file_id, decoder_options);
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::LoadAlbumScreenShotThumbnailImageEx1(
|
|
||||||
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
|
|
||||||
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer) {
|
|
||||||
LOG_INFO(Service_Capture, "called, application_id={:#0x}, storage={}, type={}, flags={}",
|
|
||||||
file_id.application_id, file_id.storage, file_id.type, decoder_options.flags);
|
|
||||||
|
|
||||||
const Result result = manager->LoadAlbumScreenShotThumbnail(*out_image_output, out_image,
|
|
||||||
file_id, decoder_options);
|
|
||||||
R_RETURN(TranslateResult(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::TranslateResult(Result in_result) {
|
|
||||||
if (in_result.IsSuccess()) {
|
|
||||||
return in_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((in_result.raw & 0x3801ff) == ResultUnknown1024.raw) {
|
|
||||||
if (in_result.GetDescription() - 0x514 < 100) {
|
|
||||||
return ResultInvalidFileData;
|
|
||||||
}
|
|
||||||
if (in_result.GetDescription() - 0x5dc < 100) {
|
|
||||||
return ResultInvalidFileData;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_result.GetDescription() - 0x578 < 100) {
|
|
||||||
if (in_result == ResultFileCountLimit) {
|
|
||||||
return ResultUnknown22;
|
|
||||||
}
|
|
||||||
return ResultUnknown25;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_result.raw < ResultUnknown1801.raw) {
|
|
||||||
if (in_result == ResultUnknown1202) {
|
|
||||||
return ResultUnknown810;
|
|
||||||
}
|
|
||||||
if (in_result == ResultUnknown1203) {
|
|
||||||
return ResultUnknown810;
|
|
||||||
}
|
|
||||||
if (in_result == ResultUnknown1701) {
|
|
||||||
return ResultUnknown5;
|
|
||||||
}
|
|
||||||
} else if (in_result.raw < ResultUnknown1803.raw) {
|
|
||||||
if (in_result == ResultUnknown1801) {
|
|
||||||
return ResultUnknown5;
|
|
||||||
}
|
|
||||||
if (in_result == ResultUnknown1802) {
|
|
||||||
return ResultUnknown6;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (in_result == ResultUnknown1803) {
|
|
||||||
return ResultUnknown7;
|
|
||||||
}
|
|
||||||
if (in_result == ResultUnknown1804) {
|
|
||||||
return ResultOutOfRange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ResultUnknown1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_result.GetModule() == ErrorModule::FS) {
|
|
||||||
if ((in_result.GetDescription() >> 0xc < 0x7d) ||
|
|
||||||
(in_result.GetDescription() - 1000 < 2000) ||
|
|
||||||
(((in_result.GetDescription() - 3000) >> 3) < 0x271)) {
|
|
||||||
// TODO: Translate FS error
|
|
||||||
return in_result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return in_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Result IAlbumAccessorService::GetAlbumAccessResultForDebug(Out<Result> out_result) {
|
|
||||||
LOG_WARNING(Service_Capture, "(STUBBED) called");
|
|
||||||
*out_result = ResultSuccess;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::Capture
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/caps/caps_types.h"
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::Capture {
|
|
||||||
class AlbumManager;
|
|
||||||
|
|
||||||
class IAlbumAccessorService final : public ServiceFramework<IAlbumAccessorService> {
|
|
||||||
public:
|
|
||||||
explicit IAlbumAccessorService(Core::System& system_,
|
|
||||||
std::shared_ptr<AlbumManager> album_manager);
|
|
||||||
~IAlbumAccessorService() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Result GetAlbumFileList(Out<u64> out_count, AlbumStorage storage,
|
|
||||||
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries);
|
|
||||||
|
|
||||||
Result DeleteAlbumFile(AlbumFileId file_id);
|
|
||||||
|
|
||||||
Result IsAlbumMounted(Out<bool> out_is_mounted, AlbumStorage storage);
|
|
||||||
|
|
||||||
Result Unknown18(
|
|
||||||
Out<u32> out_buffer_size,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure>
|
|
||||||
out_buffer);
|
|
||||||
|
|
||||||
Result GetAlbumFileListEx0(Out<u64> out_entries_size, AlbumStorage storage, u8 flags,
|
|
||||||
OutArray<AlbumEntry, BufferAttr_HipcMapAlias> out_entries);
|
|
||||||
|
|
||||||
Result GetAutoSavingStorage(Out<bool> out_is_autosaving);
|
|
||||||
|
|
||||||
Result LoadAlbumScreenShotImageEx1(
|
|
||||||
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
|
|
||||||
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
|
|
||||||
|
|
||||||
Result LoadAlbumScreenShotThumbnailImageEx1(
|
|
||||||
const AlbumFileId& file_id, const ScreenShotDecodeOption& decoder_options,
|
|
||||||
OutLargeData<LoadAlbumScreenShotImageOutput, BufferAttr_HipcMapAlias> out_image_output,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias | BufferAttr_HipcMapTransferAllowsNonSecure> out_image,
|
|
||||||
OutArray<u8, BufferAttr_HipcMapAlias> out_buffer);
|
|
||||||
|
|
||||||
Result TranslateResult(Result in_result);
|
|
||||||
|
|
||||||
Result GetAlbumAccessResultForDebug(Out<Result> out_result);
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
std::shared_ptr<AlbumManager> manager = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::Capture
|
|
||||||
@@ -11,13 +11,27 @@
|
|||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
#include "core/hle/service/acc/errors.h"
|
#include "core/hle/service/acc/errors.h"
|
||||||
#include "core/hle/service/friend/friend.h"
|
#include "core/hle/service/friend/friend.h"
|
||||||
#include "core/hle/service/friend/friend_interface.h"
|
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
|
|
||||||
namespace Service::Friend {
|
namespace Service::Friend {
|
||||||
|
|
||||||
|
class Friend final : public Module::Interface {
|
||||||
|
public:
|
||||||
|
explicit Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name) : Interface(std::move(module_), system_, name) {}
|
||||||
|
~Friend() override = default;
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, &Friend::CreateFriendService, "CreateFriendService"},
|
||||||
|
FunctionInfo{1, &Friend::CreateNotificationService, "CreateNotificationService"},
|
||||||
|
FunctionInfo{2, nullptr, "CreateDaemonSuspendSessionService"}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
class IFriendService final : public ServiceFramework<IFriendService> {
|
class IFriendService final : public ServiceFramework<IFriendService> {
|
||||||
public:
|
public:
|
||||||
explicit IFriendService(Core::System& system_)
|
explicit IFriendService(Core::System& system_)
|
||||||
|
|||||||
@@ -1,17 +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/friend/friend_interface.h"
|
|
||||||
|
|
||||||
namespace Service::Friend {
|
|
||||||
|
|
||||||
Friend::Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name)
|
|
||||||
: Interface(std::move(module_), system_, name) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Friend::~Friend() = default;
|
|
||||||
|
|
||||||
} // namespace Service::Friend
|
|
||||||
@@ -1,28 +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
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/friend/friend.h"
|
|
||||||
|
|
||||||
namespace Service::Friend {
|
|
||||||
|
|
||||||
class Friend final : public Module::Interface {
|
|
||||||
public:
|
|
||||||
explicit Friend(std::shared_ptr<Module> module_, Core::System& system_, const char* name);
|
|
||||||
~Friend() override;
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, &Friend::CreateFriendService, "CreateFriendService"},
|
|
||||||
FunctionInfo{1, &Friend::CreateNotificationService, "CreateNotificationService"},
|
|
||||||
FunctionInfo{2, nullptr, "CreateDaemonSuspendSessionService"}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::Friend
|
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "core/hle/service/ldn/ldn.h"
|
#include "core/hle/service/ldn/ldn.h"
|
||||||
#include "core/hle/service/ldn/monitor_service.h"
|
#include "core/hle/service/ldn/monitor_service.h"
|
||||||
#include "core/hle/service/ldn/sf_monitor_service.h"
|
#include "core/hle/service/ldn/sf_monitor_service.h"
|
||||||
#include "core/hle/service/ldn/sf_service.h"
|
|
||||||
#include "core/hle/service/ldn/sf_service_monitor.h"
|
#include "core/hle/service/ldn/sf_service_monitor.h"
|
||||||
#include "core/hle/service/ldn/system_local_communication_service.h"
|
#include "core/hle/service/ldn/system_local_communication_service.h"
|
||||||
#include "core/hle/service/ldn/user_local_communication_service.h"
|
#include "core/hle/service/ldn/user_local_communication_service.h"
|
||||||
@@ -116,6 +115,36 @@ private:
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ISfService final : public ServiceFramework<ISfService> {
|
||||||
|
public:
|
||||||
|
explicit ISfService(Core::System& system_) : ServiceFramework{system_, "ISfService"} {}
|
||||||
|
~ISfService() override = default;
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, nullptr, "Initialize"},
|
||||||
|
FunctionInfo{256, nullptr, "AttachNetworkInterfaceStateChangeEvent"},
|
||||||
|
FunctionInfo{264, nullptr, "GetNetworkInterfaceLastError"},
|
||||||
|
FunctionInfo{272, nullptr, "GetRole"},
|
||||||
|
FunctionInfo{280, nullptr, "GetAdvertiseData"},
|
||||||
|
FunctionInfo{288, nullptr, "GetGroupInfo"},
|
||||||
|
FunctionInfo{296, nullptr, "GetGroupInfo2"},
|
||||||
|
FunctionInfo{304, nullptr, "GetGroupOwner"},
|
||||||
|
FunctionInfo{312, nullptr, "GetIpConfig"},
|
||||||
|
FunctionInfo{320, nullptr, "GetLinkLevel"},
|
||||||
|
FunctionInfo{512, nullptr, "Scan"},
|
||||||
|
FunctionInfo{768, nullptr, "CreateGroup"},
|
||||||
|
FunctionInfo{776, nullptr, "DestroyGroup"},
|
||||||
|
FunctionInfo{784, nullptr, "SetAdvertiseData"},
|
||||||
|
FunctionInfo{1536, nullptr, "SendToOtherGroup"},
|
||||||
|
FunctionInfo{1544, nullptr, "RecvFromOtherGroup"},
|
||||||
|
FunctionInfo{1552, nullptr, "AddAcceptableGroupId"},
|
||||||
|
FunctionInfo{1560, nullptr, "ClearAcceptableGroupId"}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
class ISfServiceCreator final : public ServiceFramework<ISfServiceCreator> {
|
class ISfServiceCreator final : public ServiceFramework<ISfServiceCreator> {
|
||||||
public:
|
public:
|
||||||
explicit ISfServiceCreator(Core::System& system_, bool is_system_, const char* name_) : ServiceFramework{system_, name_}, is_system{is_system_} {}
|
explicit ISfServiceCreator(Core::System& system_, bool is_system_, const char* name_) : ServiceFramework{system_, name_}, is_system{is_system_} {}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/ldn/sf_service.h"
|
|
||||||
|
|
||||||
namespace Service::LDN {
|
|
||||||
|
|
||||||
ISfService::ISfService(Core::System& system_) : ServiceFramework{system_, "ISfService"} {
|
|
||||||
}
|
|
||||||
|
|
||||||
ISfService::~ISfService() = default;
|
|
||||||
|
|
||||||
} // namespace Service::LDN
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::LDN {
|
|
||||||
|
|
||||||
class ISfService final : public ServiceFramework<ISfService> {
|
|
||||||
public:
|
|
||||||
explicit ISfService(Core::System& system_);
|
|
||||||
~ISfService() override;
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, nullptr, "Initialize"},
|
|
||||||
FunctionInfo{256, nullptr, "AttachNetworkInterfaceStateChangeEvent"},
|
|
||||||
FunctionInfo{264, nullptr, "GetNetworkInterfaceLastError"},
|
|
||||||
FunctionInfo{272, nullptr, "GetRole"},
|
|
||||||
FunctionInfo{280, nullptr, "GetAdvertiseData"},
|
|
||||||
FunctionInfo{288, nullptr, "GetGroupInfo"},
|
|
||||||
FunctionInfo{296, nullptr, "GetGroupInfo2"},
|
|
||||||
FunctionInfo{304, nullptr, "GetGroupOwner"},
|
|
||||||
FunctionInfo{312, nullptr, "GetIpConfig"},
|
|
||||||
FunctionInfo{320, nullptr, "GetLinkLevel"},
|
|
||||||
FunctionInfo{512, nullptr, "Scan"},
|
|
||||||
FunctionInfo{768, nullptr, "CreateGroup"},
|
|
||||||
FunctionInfo{776, nullptr, "DestroyGroup"},
|
|
||||||
FunctionInfo{784, nullptr, "SetAdvertiseData"},
|
|
||||||
FunctionInfo{1536, nullptr, "SendToOtherGroup"},
|
|
||||||
FunctionInfo{1544, nullptr, "RecvFromOtherGroup"},
|
|
||||||
FunctionInfo{1552, nullptr, "AddAcceptableGroupId"},
|
|
||||||
FunctionInfo{1560, nullptr, "ClearAcceptableGroupId"}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::LDN
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/psc/ovln/receiver.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IReceiver::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, D<&IReceiver::AddSource>, "AddSource"},
|
|
||||||
FunctionInfo{1, D<&IReceiver::RemoveSource>, "RemoveSource"},
|
|
||||||
FunctionInfo{2, D<&IReceiver::GetReceiveEventHandle>, "GetReceiveEventHandle"},
|
|
||||||
FunctionInfo{3, D<&IReceiver::Receive>, "Receive"},
|
|
||||||
FunctionInfo{4, D<&IReceiver::ReceiveWithTick>, "ReceiveWithTick"}
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
IReceiver::IReceiver(Core::System& system_)
|
|
||||||
: ServiceFramework{system_, "IReceiver"}, service_context{system_, "IReceiver"} {
|
|
||||||
receive_event = service_context.CreateEvent("IReceiver::ReceiveEvent");
|
|
||||||
}
|
|
||||||
|
|
||||||
IReceiver::~IReceiver() {
|
|
||||||
service_context.CloseEvent(receive_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IReceiver::AddSource(SourceName source_name) {
|
|
||||||
const std::string name = source_name.GetString();
|
|
||||||
LOG_INFO(Service_PSC, "called: source_name={}", name);
|
|
||||||
|
|
||||||
// Add source if it doesn't already exist
|
|
||||||
if (message_sources.find(name) == message_sources.end()) {
|
|
||||||
message_sources[name] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IReceiver::RemoveSource(SourceName source_name) {
|
|
||||||
const std::string name = source_name.GetString();
|
|
||||||
LOG_INFO(Service_PSC, "called: source_name={}", name);
|
|
||||||
|
|
||||||
// Remove source if it exists
|
|
||||||
message_sources.erase(name);
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IReceiver::GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
|
||||||
LOG_INFO(Service_PSC, "called");
|
|
||||||
*out_event = &receive_event->GetReadableEvent();
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IReceiver::Receive(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags) {
|
|
||||||
u64 tick;
|
|
||||||
return ReceiveWithTick(out_notification, out_flags, Out<u64>(&tick));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IReceiver::ReceiveWithTick(Out<OverlayNotification> out_notification,
|
|
||||||
Out<MessageFlags> out_flags, Out<u64> out_tick) {
|
|
||||||
LOG_DEBUG(Service_PSC, "called");
|
|
||||||
|
|
||||||
// Find the message with the lowest ID across all sources
|
|
||||||
const std::string* target_source = nullptr;
|
|
||||||
size_t target_index = 0;
|
|
||||||
|
|
||||||
for (const auto& [source_name, messages] : message_sources) {
|
|
||||||
if (!messages.empty()) {
|
|
||||||
if (target_source == nullptr) {
|
|
||||||
target_source = &source_name;
|
|
||||||
target_index = 0;
|
|
||||||
}
|
|
||||||
// Note: In the real implementation, we would track message IDs
|
|
||||||
// For now, just use FIFO order
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_source != nullptr) {
|
|
||||||
auto& messages = message_sources[*target_source];
|
|
||||||
*out_notification = messages[target_index].first;
|
|
||||||
*out_flags = messages[target_index].second;
|
|
||||||
*out_tick = 0; // TODO: Implement tick tracking
|
|
||||||
|
|
||||||
// Remove the message
|
|
||||||
messages.erase(messages.begin() + target_index);
|
|
||||||
|
|
||||||
// Clear event if no more messages
|
|
||||||
bool has_messages = false;
|
|
||||||
for (const auto& [_, msgs] : message_sources) {
|
|
||||||
if (!msgs.empty()) {
|
|
||||||
has_messages = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!has_messages) {
|
|
||||||
receive_event->Clear(system.Kernel());
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
// No messages available
|
|
||||||
*out_notification = {};
|
|
||||||
*out_flags = {};
|
|
||||||
*out_tick = 0;
|
|
||||||
|
|
||||||
LOG_WARNING(Service_PSC, "No messages available");
|
|
||||||
R_THROW(ResultUnknown); // TODO: Use proper OvlnResult::NoMessages when available
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include "core/hle/result.h"
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
#include "core/hle/service/psc/ovln/ovln_types.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
class KReadableEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
class IReceiver final : public ServiceFramework<IReceiver> {
|
|
||||||
public:
|
|
||||||
explicit IReceiver(Core::System& system_);
|
|
||||||
~IReceiver() override;
|
|
||||||
|
|
||||||
IReceiver(const IReceiver&) = delete;
|
|
||||||
IReceiver& operator=(const IReceiver&) = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Result AddSource(SourceName source_name);
|
|
||||||
Result RemoveSource(SourceName source_name);
|
|
||||||
Result GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
|
||||||
Result Receive(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags);
|
|
||||||
Result ReceiveWithTick(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags,
|
|
||||||
Out<u64> out_tick);
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
|
|
||||||
KernelHelpers::ServiceContext service_context;
|
|
||||||
Kernel::KEvent* receive_event;
|
|
||||||
|
|
||||||
std::map<std::string, std::vector<std::pair<OverlayNotification, MessageFlags>>> message_sources;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -5,17 +5,124 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/psc/ovln/receiver.h"
|
#include "core/hle/service/psc/ovln/ovln_types.h"
|
||||||
#include "core/hle/service/psc/ovln/receiver_service.h"
|
#include "core/hle/service/psc/ovln/receiver_service.h"
|
||||||
|
|
||||||
namespace Service::PSC {
|
namespace Service::PSC {
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IReceiverService::FindRequest(u32 key) {
|
class IReceiver final : public ServiceFramework<IReceiver> {
|
||||||
static constexpr auto functions = CreateStaticMap(
|
public:
|
||||||
FunctionInfo{0, D<&IReceiverService::OpenReceiver>, "OpenReceiver"}
|
explicit IReceiver(Core::System& system_) : ServiceFramework{system_, "IReceiver"}, service_context{system_, "IReceiver"} {
|
||||||
);
|
receive_event = service_context.CreateEvent("IReceiver::ReceiveEvent");
|
||||||
|
}
|
||||||
|
|
||||||
|
~IReceiver() override {
|
||||||
|
service_context.CloseEvent(receive_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result AddSource(SourceName source_name) {
|
||||||
|
const std::string name = source_name.GetString();
|
||||||
|
LOG_INFO(Service_PSC, "called: source_name={}", name);
|
||||||
|
// Add source if it doesn't already exist
|
||||||
|
if (message_sources.find(name) == message_sources.end()) {
|
||||||
|
message_sources[name] = {};
|
||||||
|
}
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result RemoveSource(SourceName source_name) {
|
||||||
|
const std::string name = source_name.GetString();
|
||||||
|
LOG_INFO(Service_PSC, "called: source_name={}", name);
|
||||||
|
// Remove source if it exists
|
||||||
|
message_sources.erase(name);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result GetReceiveEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
|
LOG_INFO(Service_PSC, "called");
|
||||||
|
*out_event = &receive_event->GetReadableEvent();
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result Receive(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags) {
|
||||||
|
u64 tick;
|
||||||
|
return ReceiveWithTick(out_notification, out_flags, Out<u64>(&tick));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ReceiveWithTick(Out<OverlayNotification> out_notification, Out<MessageFlags> out_flags, Out<u64> out_tick) {
|
||||||
|
LOG_DEBUG(Service_PSC, "called");
|
||||||
|
|
||||||
|
// Find the message with the lowest ID across all sources
|
||||||
|
const std::string* target_source = nullptr;
|
||||||
|
size_t target_index = 0;
|
||||||
|
|
||||||
|
for (const auto& [source_name, messages] : message_sources) {
|
||||||
|
if (!messages.empty()) {
|
||||||
|
if (target_source == nullptr) {
|
||||||
|
target_source = &source_name;
|
||||||
|
target_index = 0;
|
||||||
|
}
|
||||||
|
// Note: In the real implementation, we would track message IDs
|
||||||
|
// For now, just use FIFO order
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_source != nullptr) {
|
||||||
|
auto& messages = message_sources[*target_source];
|
||||||
|
*out_notification = messages[target_index].first;
|
||||||
|
*out_flags = messages[target_index].second;
|
||||||
|
*out_tick = 0; // TODO: Implement tick tracking
|
||||||
|
|
||||||
|
// Remove the message
|
||||||
|
messages.erase(messages.begin() + target_index);
|
||||||
|
|
||||||
|
// Clear event if no more messages
|
||||||
|
bool has_messages = false;
|
||||||
|
for (const auto& [_, msgs] : message_sources) {
|
||||||
|
if (!msgs.empty()) {
|
||||||
|
has_messages = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_messages) {
|
||||||
|
receive_event->Clear(system.Kernel());
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
// No messages available
|
||||||
|
*out_notification = {};
|
||||||
|
*out_flags = {};
|
||||||
|
*out_tick = 0;
|
||||||
|
|
||||||
|
LOG_WARNING(Service_PSC, "No messages available");
|
||||||
|
R_THROW(ResultUnknown); // TODO: Use proper OvlnResult::NoMessages when available
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, D<&IReceiver::AddSource>, "AddSource"},
|
||||||
|
FunctionInfo{1, D<&IReceiver::RemoveSource>, "RemoveSource"},
|
||||||
|
FunctionInfo{2, D<&IReceiver::GetReceiveEventHandle>, "GetReceiveEventHandle"},
|
||||||
|
FunctionInfo{3, D<&IReceiver::Receive>, "Receive"},
|
||||||
|
FunctionInfo{4, D<&IReceiver::ReceiveWithTick>, "ReceiveWithTick"}
|
||||||
|
);
|
||||||
|
|
||||||
|
KernelHelpers::ServiceContext service_context;
|
||||||
|
Kernel::KEvent* receive_event;
|
||||||
|
|
||||||
|
std::map<std::string, std::vector<std::pair<OverlayNotification, MessageFlags>>> message_sources;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<ServiceFrameworkBase::FunctionInfoBase> IReceiverService::FindRequest(u32 key) {
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, D<&IReceiverService::OpenReceiver>, "OpenReceiver"}
|
||||||
|
);
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
|
||||||
IReceiverService::IReceiverService(Core::System& system_) : ServiceFramework{system_, "ovln:rcv"} {
|
IReceiverService::IReceiverService(Core::System& system_) : ServiceFramework{system_, "ovln:rcv"} {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
#include "core/hle/service/psc/ovln/sender.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ISender::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, D<&ISender::Send>, "Send"},
|
|
||||||
FunctionInfo{1, nullptr, "GetUnreceivedMessageCount"}
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
ISender::ISender(Core::System& system_) : ServiceFramework{system_, "ISender"} {
|
|
||||||
}
|
|
||||||
|
|
||||||
ISender::~ISender() = default;
|
|
||||||
|
|
||||||
Result ISender::Send(const OverlayNotification& notification, MessageFlags flags) {
|
|
||||||
std::string data;
|
|
||||||
for (const auto m : notification) {
|
|
||||||
data += fmt::format("{:016X} ", m);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_WARNING(Service_PSC, "(STUBBED) called, flags={} notification={}", flags.raw, data);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/psc/ovln/ovln_types.h"
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
class ISender final : public ServiceFramework<ISender> {
|
|
||||||
public:
|
|
||||||
explicit ISender(Core::System& system_);
|
|
||||||
~ISender() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Result Send(const OverlayNotification& notification, MessageFlags flags);
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -5,17 +5,41 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/psc/ovln/sender.h"
|
#include "core/hle/service/psc/ovln/ovln_types.h"
|
||||||
#include "core/hle/service/psc/ovln/sender_service.h"
|
#include "core/hle/service/psc/ovln/sender_service.h"
|
||||||
|
|
||||||
namespace Service::PSC {
|
namespace Service::PSC {
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> ISenderService::FindRequest(u32 key) {
|
class ISender final : public ServiceFramework<ISender> {
|
||||||
static constexpr auto functions = CreateStaticMap(
|
public:
|
||||||
FunctionInfo{0, D<&ISenderService::OpenSender>, "OpenSender"}
|
explicit ISender(Core::System& system_) : ServiceFramework{system_, "ISender"} {}
|
||||||
);
|
~ISender() override = default;
|
||||||
|
|
||||||
|
Result Send(const OverlayNotification& notification, MessageFlags flags) {
|
||||||
|
std::string data;
|
||||||
|
for (const auto m : notification) {
|
||||||
|
data += fmt::format("{:016X} ", m);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_WARNING(Service_PSC, "(STUBBED) called, flags={} notification={}", flags.raw, data);
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, D<&ISender::Send>, "Send"},
|
||||||
|
FunctionInfo{1, nullptr, "GetUnreceivedMessageCount"}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<ServiceFrameworkBase::FunctionInfoBase> ISenderService::FindRequest(u32 key) {
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, D<&ISenderService::OpenSender>, "OpenSender"}
|
||||||
|
);
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
|
||||||
ISenderService::ISenderService(Core::System& system_) : ServiceFramework{system_, "ovln:snd"} {
|
ISenderService::ISenderService(Core::System& system_) : ServiceFramework{system_, "ovln:snd"} {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/psc/pm_control.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
IPmControl::IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} {
|
|
||||||
}
|
|
||||||
|
|
||||||
IPmControl::~IPmControl() = default;
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
class IPmControl final : public ServiceFramework<IPmControl> {
|
|
||||||
public:
|
|
||||||
explicit IPmControl(Core::System& system_);
|
|
||||||
~IPmControl() override;
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, nullptr, "Initialize"},
|
|
||||||
FunctionInfo{1, nullptr, "DispatchRequest"},
|
|
||||||
FunctionInfo{2, nullptr, "GetResult"},
|
|
||||||
FunctionInfo{3, nullptr, "GetState"},
|
|
||||||
FunctionInfo{4, nullptr, "Cancel"},
|
|
||||||
FunctionInfo{5, nullptr, "PrintModuleInformation"},
|
|
||||||
FunctionInfo{6, nullptr, "GetModuleInformation"},
|
|
||||||
FunctionInfo{10, nullptr, "AcquireStateLock"},
|
|
||||||
FunctionInfo{11, nullptr, "HasStateLock"}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/service/psc/pm_module.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
std::optional<ServiceFrameworkBase::FunctionInfoBase> IPmModule::FindRequest(u32 key) {
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, nullptr, "Initialize"},
|
|
||||||
FunctionInfo{1, nullptr, "GetRequest"},
|
|
||||||
FunctionInfo{2, nullptr, "Acknowledge"},
|
|
||||||
FunctionInfo{3, nullptr, "Finalize"},
|
|
||||||
FunctionInfo{4, nullptr, "AcknowledgeEx"}
|
|
||||||
);
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
IPmModule::IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} {
|
|
||||||
}
|
|
||||||
|
|
||||||
IPmModule::~IPmModule() = default;
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Service::PSC {
|
|
||||||
|
|
||||||
class IPmModule final : public ServiceFramework<IPmModule> {
|
|
||||||
public:
|
|
||||||
explicit IPmModule(Core::System& system_);
|
|
||||||
~IPmModule() override;
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::PSC
|
|
||||||
@@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include "core/hle/service/psc/ovln/receiver_service.h"
|
#include "core/hle/service/psc/ovln/receiver_service.h"
|
||||||
#include "core/hle/service/psc/ovln/sender_service.h"
|
#include "core/hle/service/psc/ovln/sender_service.h"
|
||||||
#include "core/hle/service/psc/pm_control.h"
|
|
||||||
#include "core/hle/service/psc/pm_module.h"
|
|
||||||
#include "core/hle/service/psc/psc.h"
|
#include "core/hle/service/psc/psc.h"
|
||||||
#include "core/hle/service/psc/time/manager.h"
|
#include "core/hle/service/psc/time/manager.h"
|
||||||
#include "core/hle/service/psc/time/power_state_service.h"
|
#include "core/hle/service/psc/time/power_state_service.h"
|
||||||
@@ -103,7 +101,22 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class IPmModule;
|
class IPmModule final : public ServiceFramework<IPmModule> {
|
||||||
|
public:
|
||||||
|
explicit IPmModule(Core::System& system_) : ServiceFramework{system_, "IPmModule"} {}
|
||||||
|
~IPmModule() override = default;
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, nullptr, "Initialize"},
|
||||||
|
FunctionInfo{1, nullptr, "GetRequest"},
|
||||||
|
FunctionInfo{2, nullptr, "Acknowledge"},
|
||||||
|
FunctionInfo{3, nullptr, "Finalize"},
|
||||||
|
FunctionInfo{4, nullptr, "AcknowledgeEx"}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
class IPmService final : public ServiceFramework<IPmService> {
|
class IPmService final : public ServiceFramework<IPmService> {
|
||||||
public:
|
public:
|
||||||
@@ -125,6 +138,27 @@ private:
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IPmControl final : public ServiceFramework<IPmControl> {
|
||||||
|
public:
|
||||||
|
explicit IPmControl(Core::System& system_) : ServiceFramework{system_, "psc:c"} {}
|
||||||
|
~IPmControl() override = default;
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, nullptr, "Initialize"},
|
||||||
|
FunctionInfo{1, nullptr, "DispatchRequest"},
|
||||||
|
FunctionInfo{2, nullptr, "GetResult"},
|
||||||
|
FunctionInfo{3, nullptr, "GetState"},
|
||||||
|
FunctionInfo{4, nullptr, "Cancel"},
|
||||||
|
FunctionInfo{5, nullptr, "PrintModuleInformation"},
|
||||||
|
FunctionInfo{6, nullptr, "GetModuleInformation"},
|
||||||
|
FunctionInfo{10, nullptr, "AcquireStateLock"},
|
||||||
|
FunctionInfo{11, nullptr, "HasStateLock"}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
void LoopProcess(Core::System& system) {
|
void LoopProcess(Core::System& system) {
|
||||||
auto server_manager = std::make_unique<ServerManager>(system);
|
auto server_manager = std::make_unique<ServerManager>(system);
|
||||||
|
|
||||||
|
|||||||
@@ -8,21 +8,334 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
|
||||||
#include "core/hle/service/ro/ro.h"
|
#include "core/hle/service/ro/ro.h"
|
||||||
#include "core/hle/service/ro/ro_nro_utils.h"
|
|
||||||
#include "core/hle/service/ro/ro_results.h"
|
|
||||||
#include "core/hle/service/ro/ro_types.h"
|
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#ifdef HAS_NCE
|
#ifdef HAS_NCE
|
||||||
#include "core/arm/nce/patcher.h"
|
#include "core/arm/nce/patcher.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
namespace Service::RO {
|
namespace Service::RO {
|
||||||
|
|
||||||
|
constexpr Result ResultOutOfAddressSpace{ErrorModule::RO, 2};
|
||||||
|
constexpr Result ResultAlreadyLoaded{ErrorModule::RO, 3};
|
||||||
|
constexpr Result ResultInvalidNro{ErrorModule::RO, 4};
|
||||||
|
constexpr Result ResultInvalidNrr{ErrorModule::RO, 6};
|
||||||
|
constexpr Result ResultTooManyNro{ErrorModule::RO, 7};
|
||||||
|
constexpr Result ResultTooManyNrr{ErrorModule::RO, 8};
|
||||||
|
constexpr Result ResultNotAuthorized{ErrorModule::RO, 9};
|
||||||
|
constexpr Result ResultInvalidNrrKind{ErrorModule::RO, 10};
|
||||||
|
constexpr Result ResultInternalError{ErrorModule::RO, 1023};
|
||||||
|
constexpr Result ResultInvalidAddress{ErrorModule::RO, 1025};
|
||||||
|
constexpr Result ResultInvalidSize{ErrorModule::RO, 1026};
|
||||||
|
constexpr Result ResultNotLoaded{ErrorModule::RO, 1028};
|
||||||
|
constexpr Result ResultNotRegistered{ErrorModule::RO, 1029};
|
||||||
|
constexpr Result ResultInvalidSession{ErrorModule::RO, 1030};
|
||||||
|
constexpr Result ResultInvalidProcess{ErrorModule::RO, 1031};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ProcessMemoryRegion {
|
||||||
|
u64 address;
|
||||||
|
u64 size;
|
||||||
|
};
|
||||||
|
|
||||||
|
size_t GetTotalProcessMemoryRegionSize(const ProcessMemoryRegion* regions, size_t num_regions) {
|
||||||
|
size_t total = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_regions; ++i) {
|
||||||
|
total += regions[i].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SetupNroProcessMemoryRegions(ProcessMemoryRegion* regions, u64 nro_heap_address,
|
||||||
|
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) {
|
||||||
|
// Reset region count.
|
||||||
|
size_t num_regions = 0;
|
||||||
|
|
||||||
|
// We always want a region for the nro.
|
||||||
|
regions[num_regions++] = {nro_heap_address, nro_heap_size};
|
||||||
|
|
||||||
|
// If we have bss, create a region for bss.
|
||||||
|
if (bss_heap_size > 0) {
|
||||||
|
regions[num_regions++] = {bss_heap_address, bss_heap_size};
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result SetProcessMemoryPermission(Kernel::KProcess* process, u64 address, u64 size,
|
||||||
|
Kernel::Svc::MemoryPermission permission) {
|
||||||
|
auto& page_table = process->GetPageTable();
|
||||||
|
|
||||||
|
// Set permission.
|
||||||
|
R_RETURN(page_table.SetProcessMemoryPermission(address, size, permission));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result UnmapProcessCodeMemory(Kernel::KProcess* process, u64 process_code_address,
|
||||||
|
const ProcessMemoryRegion* regions, size_t num_regions) {
|
||||||
|
// Get the total process memory region size.
|
||||||
|
const size_t total_size = GetTotalProcessMemoryRegionSize(regions, num_regions);
|
||||||
|
|
||||||
|
auto& page_table = process->GetPageTable();
|
||||||
|
|
||||||
|
// Unmap each region in order.
|
||||||
|
size_t cur_offset = total_size;
|
||||||
|
for (size_t i = 0; i < num_regions; ++i) {
|
||||||
|
// We want to unmap in reverse order.
|
||||||
|
const auto& cur_region = regions[num_regions - 1 - i];
|
||||||
|
|
||||||
|
// Subtract to update the current offset.
|
||||||
|
cur_offset -= cur_region.size;
|
||||||
|
|
||||||
|
// Unmap.
|
||||||
|
R_TRY(page_table.UnmapCodeMemory(process_code_address + cur_offset, cur_region.address,
|
||||||
|
cur_region.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result EnsureGuardPages(Kernel::KProcessPageTable& page_table, u64 map_address, u64 map_size) {
|
||||||
|
Kernel::KMemoryInfo memory_info;
|
||||||
|
Kernel::Svc::PageInfo page_info;
|
||||||
|
|
||||||
|
// Ensure page before mapping is unmapped.
|
||||||
|
R_TRY(page_table.QueryInfo(std::addressof(memory_info), std::addressof(page_info),
|
||||||
|
map_address - 1));
|
||||||
|
R_UNLESS(memory_info.GetSvcState() == Kernel::Svc::MemoryState::Free,
|
||||||
|
Kernel::ResultInvalidState);
|
||||||
|
|
||||||
|
// Ensure page after mapping is unmapped.
|
||||||
|
R_TRY(page_table.QueryInfo(std::addressof(memory_info), std::addressof(page_info),
|
||||||
|
map_address + map_size));
|
||||||
|
R_UNLESS(memory_info.GetSvcState() == Kernel::Svc::MemoryState::Free,
|
||||||
|
Kernel::ResultInvalidState);
|
||||||
|
|
||||||
|
// Successfully verified guard pages.
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result MapProcessCodeMemory(u64* out, Kernel::KProcess* process, const ProcessMemoryRegion* regions,
|
||||||
|
size_t num_regions, std::mt19937_64& generate_random) {
|
||||||
|
auto& page_table = process->GetPageTable();
|
||||||
|
const u64 alias_code_start =
|
||||||
|
GetInteger(page_table.GetAliasCodeRegionStart()) / Kernel::PageSize;
|
||||||
|
const u64 alias_code_size = page_table.GetAliasCodeRegionSize() / Kernel::PageSize;
|
||||||
|
|
||||||
|
for (size_t trial = 0; trial < 64; trial++) {
|
||||||
|
// Generate a new trial address.
|
||||||
|
const u64 mapped_address =
|
||||||
|
(alias_code_start + (generate_random() % alias_code_size)) * Kernel::PageSize;
|
||||||
|
|
||||||
|
const auto MapRegions = [&] {
|
||||||
|
// Map the regions in order.
|
||||||
|
u64 mapped_size = 0;
|
||||||
|
for (size_t i = 0; i < num_regions; ++i) {
|
||||||
|
// If we fail, unmap up to where we've mapped.
|
||||||
|
ON_RESULT_FAILURE {
|
||||||
|
R_ASSERT(UnmapProcessCodeMemory(process, mapped_address, regions, i));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Map the current region.
|
||||||
|
R_TRY(page_table.MapCodeMemory(mapped_address + mapped_size, regions[i].address,
|
||||||
|
regions[i].size));
|
||||||
|
|
||||||
|
mapped_size += regions[i].size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we fail, unmap all mapped regions.
|
||||||
|
ON_RESULT_FAILURE {
|
||||||
|
R_ASSERT(UnmapProcessCodeMemory(process, mapped_address, regions, num_regions));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure guard pages.
|
||||||
|
R_RETURN(EnsureGuardPages(page_table, mapped_address, mapped_size));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(MapRegions())) {
|
||||||
|
// Set the output address.
|
||||||
|
*out = mapped_address;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We failed to map anything.
|
||||||
|
R_THROW(RO::ResultOutOfAddressSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result MapNro(u64* out_base_address, Kernel::KProcess* process, u64 nro_heap_address,
|
||||||
|
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size,
|
||||||
|
std::mt19937_64& generate_random) {
|
||||||
|
// Set up the process memory regions.
|
||||||
|
std::array<ProcessMemoryRegion, 2> regions{};
|
||||||
|
const size_t num_regions = SetupNroProcessMemoryRegions(
|
||||||
|
regions.data(), nro_heap_address, nro_heap_size, bss_heap_address, bss_heap_size);
|
||||||
|
|
||||||
|
// Re-map the nro/bss as code memory in the destination process.
|
||||||
|
R_RETURN(MapProcessCodeMemory(out_base_address, process, regions.data(), num_regions,
|
||||||
|
generate_random));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result SetNroPerms(Kernel::KProcess* process, u64 base_address, u64 rx_size, u64 ro_size,
|
||||||
|
u64 rw_size) {
|
||||||
|
const u64 rx_offset = 0;
|
||||||
|
const u64 ro_offset = rx_offset + rx_size;
|
||||||
|
const u64 rw_offset = ro_offset + ro_size;
|
||||||
|
|
||||||
|
R_TRY(SetProcessMemoryPermission(process, base_address + rx_offset, rx_size,
|
||||||
|
Kernel::Svc::MemoryPermission::ReadExecute));
|
||||||
|
R_TRY(SetProcessMemoryPermission(process, base_address + ro_offset, ro_size,
|
||||||
|
Kernel::Svc::MemoryPermission::Read));
|
||||||
|
R_TRY(SetProcessMemoryPermission(process, base_address + rw_offset, rw_size,
|
||||||
|
Kernel::Svc::MemoryPermission::ReadWrite));
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result UnmapNro(Kernel::KProcess* process, u64 base_address, u64 nro_heap_address,
|
||||||
|
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) {
|
||||||
|
// Set up the process memory regions.
|
||||||
|
std::array<ProcessMemoryRegion, 2> regions{};
|
||||||
|
const size_t num_regions = SetupNroProcessMemoryRegions(
|
||||||
|
regions.data(), nro_heap_address, nro_heap_size, bss_heap_address, bss_heap_size);
|
||||||
|
|
||||||
|
// Unmap the nro/bss.
|
||||||
|
R_RETURN(UnmapProcessCodeMemory(process, base_address, regions.data(), num_regions));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
enum class NrrKind : u8 {
|
||||||
|
User = 0,
|
||||||
|
JitPlugin = 1,
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr size_t ModuleIdSize = 0x20;
|
||||||
|
struct ModuleId {
|
||||||
|
std::array<u8, ModuleIdSize> data;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ModuleId) == ModuleIdSize);
|
||||||
|
|
||||||
|
struct NrrCertification {
|
||||||
|
static constexpr size_t RsaKeySize = 0x100;
|
||||||
|
static constexpr size_t SignedSize = 0x120;
|
||||||
|
|
||||||
|
u64 program_id_mask;
|
||||||
|
u64 program_id_pattern;
|
||||||
|
std::array<u8, 0x10> reserved_10;
|
||||||
|
std::array<u8, RsaKeySize> modulus;
|
||||||
|
std::array<u8, RsaKeySize> signature;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NrrCertification) == NrrCertification::RsaKeySize + NrrCertification::SignedSize);
|
||||||
|
|
||||||
|
class NrrHeader {
|
||||||
|
public:
|
||||||
|
static constexpr u32 Magic = Common::MakeMagic('N', 'R', 'R', '0');
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool IsMagicValid() const {
|
||||||
|
return m_magic == Magic;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsProgramIdValid() const {
|
||||||
|
return (m_program_id & m_certification.program_id_mask) ==
|
||||||
|
m_certification.program_id_pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
NrrKind GetNrrKind() const {
|
||||||
|
const NrrKind kind = static_cast<NrrKind>(m_nrr_kind);
|
||||||
|
ASSERT(kind < NrrKind::Count);
|
||||||
|
return kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetProgramId() const {
|
||||||
|
return m_program_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetSize() const {
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetNumHashes() const {
|
||||||
|
return m_num_hashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetHashesOffset() const {
|
||||||
|
return m_hashes_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetKeyGeneration() const {
|
||||||
|
return m_key_generation;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* GetCertificationSignature() const {
|
||||||
|
return m_certification.signature.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* GetCertificationSignedArea() const {
|
||||||
|
return reinterpret_cast<const u8*>(std::addressof(m_certification));
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* GetCertificationModulus() const {
|
||||||
|
return m_certification.modulus.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* GetSignature() const {
|
||||||
|
return m_signature.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetSignedAreaSize() const {
|
||||||
|
return m_size - GetSignedAreaOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t GetSignedAreaOffset() {
|
||||||
|
return offsetof(NrrHeader, m_program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
u32 m_magic;
|
||||||
|
u32 m_key_generation;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(8);
|
||||||
|
NrrCertification m_certification;
|
||||||
|
std::array<u8, 0x100> m_signature;
|
||||||
|
u64 m_program_id;
|
||||||
|
u32 m_size;
|
||||||
|
u8 m_nrr_kind; // 7.0.0+
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(3);
|
||||||
|
u32 m_hashes_offset;
|
||||||
|
u32 m_num_hashes;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(8);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NrrHeader) == 0x350, "NrrHeader has wrong size");
|
||||||
|
|
||||||
|
static constexpr u32 NRO_HEADER_MAGIC = Common::MakeMagic('N', 'R', 'O', '0');
|
||||||
|
struct NroHeader {
|
||||||
|
u32 m_entrypoint_insn;
|
||||||
|
u32 m_mod_offset;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(0x8);
|
||||||
|
u32 m_magic;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(0x4);
|
||||||
|
u32 m_size;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(0x4);
|
||||||
|
u32 m_text_offset;
|
||||||
|
u32 m_text_size;
|
||||||
|
u32 m_ro_offset;
|
||||||
|
u32 m_ro_size;
|
||||||
|
u32 m_rw_offset;
|
||||||
|
u32 m_rw_size;
|
||||||
|
u32 m_bss_size;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(0x4);
|
||||||
|
ModuleId m_module_id;
|
||||||
|
INSERT_PADDING_BYTES_NOINIT(0x20);
|
||||||
|
};
|
||||||
|
static_assert(sizeof(NroHeader) == 0x80, "NroHeader has wrong size");
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Atmosphere defines as follows:
|
// Atmosphere defines as follows:
|
||||||
|
|||||||
@@ -1,185 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "core/hle/kernel/k_process.h"
|
|
||||||
#include "core/hle/service/ro/ro_nro_utils.h"
|
|
||||||
#include "core/hle/service/ro/ro_results.h"
|
|
||||||
|
|
||||||
namespace Service::RO {
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct ProcessMemoryRegion {
|
|
||||||
u64 address;
|
|
||||||
u64 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t GetTotalProcessMemoryRegionSize(const ProcessMemoryRegion* regions, size_t num_regions) {
|
|
||||||
size_t total = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < num_regions; ++i) {
|
|
||||||
total += regions[i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SetupNroProcessMemoryRegions(ProcessMemoryRegion* regions, u64 nro_heap_address,
|
|
||||||
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) {
|
|
||||||
// Reset region count.
|
|
||||||
size_t num_regions = 0;
|
|
||||||
|
|
||||||
// We always want a region for the nro.
|
|
||||||
regions[num_regions++] = {nro_heap_address, nro_heap_size};
|
|
||||||
|
|
||||||
// If we have bss, create a region for bss.
|
|
||||||
if (bss_heap_size > 0) {
|
|
||||||
regions[num_regions++] = {bss_heap_address, bss_heap_size};
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_regions;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SetProcessMemoryPermission(Kernel::KProcess* process, u64 address, u64 size,
|
|
||||||
Kernel::Svc::MemoryPermission permission) {
|
|
||||||
auto& page_table = process->GetPageTable();
|
|
||||||
|
|
||||||
// Set permission.
|
|
||||||
R_RETURN(page_table.SetProcessMemoryPermission(address, size, permission));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result UnmapProcessCodeMemory(Kernel::KProcess* process, u64 process_code_address,
|
|
||||||
const ProcessMemoryRegion* regions, size_t num_regions) {
|
|
||||||
// Get the total process memory region size.
|
|
||||||
const size_t total_size = GetTotalProcessMemoryRegionSize(regions, num_regions);
|
|
||||||
|
|
||||||
auto& page_table = process->GetPageTable();
|
|
||||||
|
|
||||||
// Unmap each region in order.
|
|
||||||
size_t cur_offset = total_size;
|
|
||||||
for (size_t i = 0; i < num_regions; ++i) {
|
|
||||||
// We want to unmap in reverse order.
|
|
||||||
const auto& cur_region = regions[num_regions - 1 - i];
|
|
||||||
|
|
||||||
// Subtract to update the current offset.
|
|
||||||
cur_offset -= cur_region.size;
|
|
||||||
|
|
||||||
// Unmap.
|
|
||||||
R_TRY(page_table.UnmapCodeMemory(process_code_address + cur_offset, cur_region.address,
|
|
||||||
cur_region.size));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result EnsureGuardPages(Kernel::KProcessPageTable& page_table, u64 map_address, u64 map_size) {
|
|
||||||
Kernel::KMemoryInfo memory_info;
|
|
||||||
Kernel::Svc::PageInfo page_info;
|
|
||||||
|
|
||||||
// Ensure page before mapping is unmapped.
|
|
||||||
R_TRY(page_table.QueryInfo(std::addressof(memory_info), std::addressof(page_info),
|
|
||||||
map_address - 1));
|
|
||||||
R_UNLESS(memory_info.GetSvcState() == Kernel::Svc::MemoryState::Free,
|
|
||||||
Kernel::ResultInvalidState);
|
|
||||||
|
|
||||||
// Ensure page after mapping is unmapped.
|
|
||||||
R_TRY(page_table.QueryInfo(std::addressof(memory_info), std::addressof(page_info),
|
|
||||||
map_address + map_size));
|
|
||||||
R_UNLESS(memory_info.GetSvcState() == Kernel::Svc::MemoryState::Free,
|
|
||||||
Kernel::ResultInvalidState);
|
|
||||||
|
|
||||||
// Successfully verified guard pages.
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result MapProcessCodeMemory(u64* out, Kernel::KProcess* process, const ProcessMemoryRegion* regions,
|
|
||||||
size_t num_regions, std::mt19937_64& generate_random) {
|
|
||||||
auto& page_table = process->GetPageTable();
|
|
||||||
const u64 alias_code_start =
|
|
||||||
GetInteger(page_table.GetAliasCodeRegionStart()) / Kernel::PageSize;
|
|
||||||
const u64 alias_code_size = page_table.GetAliasCodeRegionSize() / Kernel::PageSize;
|
|
||||||
|
|
||||||
for (size_t trial = 0; trial < 64; trial++) {
|
|
||||||
// Generate a new trial address.
|
|
||||||
const u64 mapped_address =
|
|
||||||
(alias_code_start + (generate_random() % alias_code_size)) * Kernel::PageSize;
|
|
||||||
|
|
||||||
const auto MapRegions = [&] {
|
|
||||||
// Map the regions in order.
|
|
||||||
u64 mapped_size = 0;
|
|
||||||
for (size_t i = 0; i < num_regions; ++i) {
|
|
||||||
// If we fail, unmap up to where we've mapped.
|
|
||||||
ON_RESULT_FAILURE {
|
|
||||||
R_ASSERT(UnmapProcessCodeMemory(process, mapped_address, regions, i));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Map the current region.
|
|
||||||
R_TRY(page_table.MapCodeMemory(mapped_address + mapped_size, regions[i].address,
|
|
||||||
regions[i].size));
|
|
||||||
|
|
||||||
mapped_size += regions[i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we fail, unmap all mapped regions.
|
|
||||||
ON_RESULT_FAILURE {
|
|
||||||
R_ASSERT(UnmapProcessCodeMemory(process, mapped_address, regions, num_regions));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ensure guard pages.
|
|
||||||
R_RETURN(EnsureGuardPages(page_table, mapped_address, mapped_size));
|
|
||||||
};
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(MapRegions())) {
|
|
||||||
// Set the output address.
|
|
||||||
*out = mapped_address;
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We failed to map anything.
|
|
||||||
R_THROW(RO::ResultOutOfAddressSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Result MapNro(u64* out_base_address, Kernel::KProcess* process, u64 nro_heap_address,
|
|
||||||
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size,
|
|
||||||
std::mt19937_64& generate_random) {
|
|
||||||
// Set up the process memory regions.
|
|
||||||
std::array<ProcessMemoryRegion, 2> regions{};
|
|
||||||
const size_t num_regions = SetupNroProcessMemoryRegions(
|
|
||||||
regions.data(), nro_heap_address, nro_heap_size, bss_heap_address, bss_heap_size);
|
|
||||||
|
|
||||||
// Re-map the nro/bss as code memory in the destination process.
|
|
||||||
R_RETURN(MapProcessCodeMemory(out_base_address, process, regions.data(), num_regions,
|
|
||||||
generate_random));
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SetNroPerms(Kernel::KProcess* process, u64 base_address, u64 rx_size, u64 ro_size,
|
|
||||||
u64 rw_size) {
|
|
||||||
const u64 rx_offset = 0;
|
|
||||||
const u64 ro_offset = rx_offset + rx_size;
|
|
||||||
const u64 rw_offset = ro_offset + ro_size;
|
|
||||||
|
|
||||||
R_TRY(SetProcessMemoryPermission(process, base_address + rx_offset, rx_size,
|
|
||||||
Kernel::Svc::MemoryPermission::ReadExecute));
|
|
||||||
R_TRY(SetProcessMemoryPermission(process, base_address + ro_offset, ro_size,
|
|
||||||
Kernel::Svc::MemoryPermission::Read));
|
|
||||||
R_TRY(SetProcessMemoryPermission(process, base_address + rw_offset, rw_size,
|
|
||||||
Kernel::Svc::MemoryPermission::ReadWrite));
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result UnmapNro(Kernel::KProcess* process, u64 base_address, u64 nro_heap_address,
|
|
||||||
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size) {
|
|
||||||
// Set up the process memory regions.
|
|
||||||
std::array<ProcessMemoryRegion, 2> regions{};
|
|
||||||
const size_t num_regions = SetupNroProcessMemoryRegions(
|
|
||||||
regions.data(), nro_heap_address, nro_heap_size, bss_heap_address, bss_heap_size);
|
|
||||||
|
|
||||||
// Unmap the nro/bss.
|
|
||||||
R_RETURN(UnmapProcessCodeMemory(process, base_address, regions.data(), num_regions));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::RO
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
class KProcess;
|
|
||||||
}
|
|
||||||
|
|
||||||
union Result;
|
|
||||||
|
|
||||||
namespace Service::RO {
|
|
||||||
|
|
||||||
Result MapNro(u64* out_base_address, Kernel::KProcess* process, u64 nro_heap_address,
|
|
||||||
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size,
|
|
||||||
std::mt19937_64& generate_random);
|
|
||||||
Result SetNroPerms(Kernel::KProcess* process, u64 base_address, u64 rx_size, u64 ro_size,
|
|
||||||
u64 rw_size);
|
|
||||||
Result UnmapNro(Kernel::KProcess* process, u64 base_address, u64 nro_heap_address,
|
|
||||||
u64 nro_heap_size, u64 bss_heap_address, u64 bss_heap_size);
|
|
||||||
|
|
||||||
} // namespace Service::RO
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/result.h"
|
|
||||||
|
|
||||||
namespace Service::RO {
|
|
||||||
|
|
||||||
constexpr Result ResultOutOfAddressSpace{ErrorModule::RO, 2};
|
|
||||||
constexpr Result ResultAlreadyLoaded{ErrorModule::RO, 3};
|
|
||||||
constexpr Result ResultInvalidNro{ErrorModule::RO, 4};
|
|
||||||
constexpr Result ResultInvalidNrr{ErrorModule::RO, 6};
|
|
||||||
constexpr Result ResultTooManyNro{ErrorModule::RO, 7};
|
|
||||||
constexpr Result ResultTooManyNrr{ErrorModule::RO, 8};
|
|
||||||
constexpr Result ResultNotAuthorized{ErrorModule::RO, 9};
|
|
||||||
constexpr Result ResultInvalidNrrKind{ErrorModule::RO, 10};
|
|
||||||
constexpr Result ResultInternalError{ErrorModule::RO, 1023};
|
|
||||||
constexpr Result ResultInvalidAddress{ErrorModule::RO, 1025};
|
|
||||||
constexpr Result ResultInvalidSize{ErrorModule::RO, 1026};
|
|
||||||
constexpr Result ResultNotLoaded{ErrorModule::RO, 1028};
|
|
||||||
constexpr Result ResultNotRegistered{ErrorModule::RO, 1029};
|
|
||||||
constexpr Result ResultInvalidSession{ErrorModule::RO, 1030};
|
|
||||||
constexpr Result ResultInvalidProcess{ErrorModule::RO, 1031};
|
|
||||||
|
|
||||||
} // namespace Service::RO
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/common_funcs.h"
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace Service::RO {
|
|
||||||
|
|
||||||
enum class NrrKind : u8 {
|
|
||||||
User = 0,
|
|
||||||
JitPlugin = 1,
|
|
||||||
Count,
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr size_t ModuleIdSize = 0x20;
|
|
||||||
struct ModuleId {
|
|
||||||
std::array<u8, ModuleIdSize> data;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(ModuleId) == ModuleIdSize);
|
|
||||||
|
|
||||||
struct NrrCertification {
|
|
||||||
static constexpr size_t RsaKeySize = 0x100;
|
|
||||||
static constexpr size_t SignedSize = 0x120;
|
|
||||||
|
|
||||||
u64 program_id_mask;
|
|
||||||
u64 program_id_pattern;
|
|
||||||
std::array<u8, 0x10> reserved_10;
|
|
||||||
std::array<u8, RsaKeySize> modulus;
|
|
||||||
std::array<u8, RsaKeySize> signature;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(NrrCertification) ==
|
|
||||||
NrrCertification::RsaKeySize + NrrCertification::SignedSize);
|
|
||||||
|
|
||||||
class NrrHeader {
|
|
||||||
public:
|
|
||||||
static constexpr u32 Magic = Common::MakeMagic('N', 'R', 'R', '0');
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsMagicValid() const {
|
|
||||||
return m_magic == Magic;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsProgramIdValid() const {
|
|
||||||
return (m_program_id & m_certification.program_id_mask) ==
|
|
||||||
m_certification.program_id_pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
NrrKind GetNrrKind() const {
|
|
||||||
const NrrKind kind = static_cast<NrrKind>(m_nrr_kind);
|
|
||||||
ASSERT(kind < NrrKind::Count);
|
|
||||||
return kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 GetProgramId() const {
|
|
||||||
return m_program_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetSize() const {
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetNumHashes() const {
|
|
||||||
return m_num_hashes;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetHashesOffset() const {
|
|
||||||
return m_hashes_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GetKeyGeneration() const {
|
|
||||||
return m_key_generation;
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* GetCertificationSignature() const {
|
|
||||||
return m_certification.signature.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* GetCertificationSignedArea() const {
|
|
||||||
return reinterpret_cast<const u8*>(std::addressof(m_certification));
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* GetCertificationModulus() const {
|
|
||||||
return m_certification.modulus.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* GetSignature() const {
|
|
||||||
return m_signature.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetSignedAreaSize() const {
|
|
||||||
return m_size - GetSignedAreaOffset();
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr size_t GetSignedAreaOffset() {
|
|
||||||
return offsetof(NrrHeader, m_program_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
u32 m_magic;
|
|
||||||
u32 m_key_generation;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(8);
|
|
||||||
NrrCertification m_certification;
|
|
||||||
std::array<u8, 0x100> m_signature;
|
|
||||||
u64 m_program_id;
|
|
||||||
u32 m_size;
|
|
||||||
u8 m_nrr_kind; // 7.0.0+
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(3);
|
|
||||||
u32 m_hashes_offset;
|
|
||||||
u32 m_num_hashes;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(8);
|
|
||||||
};
|
|
||||||
static_assert(sizeof(NrrHeader) == 0x350, "NrrHeader has wrong size");
|
|
||||||
|
|
||||||
static constexpr u32 NRO_HEADER_MAGIC = Common::MakeMagic('N', 'R', 'O', '0');
|
|
||||||
struct NroHeader {
|
|
||||||
u32 m_entrypoint_insn;
|
|
||||||
u32 m_mod_offset;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(0x8);
|
|
||||||
u32 m_magic;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(0x4);
|
|
||||||
u32 m_size;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(0x4);
|
|
||||||
u32 m_text_offset;
|
|
||||||
u32 m_text_size;
|
|
||||||
u32 m_ro_offset;
|
|
||||||
u32 m_ro_size;
|
|
||||||
u32 m_rw_offset;
|
|
||||||
u32 m_rw_size;
|
|
||||||
u32 m_bss_size;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(0x4);
|
|
||||||
ModuleId m_module_id;
|
|
||||||
INSERT_PADDING_BYTES_NOINIT(0x20);
|
|
||||||
};
|
|
||||||
static_assert(sizeof(NroHeader) == 0x80, "NroHeader has wrong size");
|
|
||||||
|
|
||||||
} // namespace Service::RO
|
|
||||||
@@ -18,7 +18,16 @@
|
|||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/hle/service/sm/sm_controller.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/logging.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/hle/kernel/k_client_port.h"
|
||||||
|
#include "core/hle/kernel/k_port.h"
|
||||||
|
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
|
#include "core/hle/service/server_manager.h"
|
||||||
|
|
||||||
namespace Service::SM {
|
namespace Service::SM {
|
||||||
|
|
||||||
@@ -27,6 +36,116 @@ constexpr Result ResultAlreadyRegistered(ErrorModule::SM, 4);
|
|||||||
constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6);
|
constexpr Result ResultInvalidServiceName(ErrorModule::SM, 6);
|
||||||
constexpr Result ResultNotRegistered(ErrorModule::SM, 7);
|
constexpr Result ResultNotRegistered(ErrorModule::SM, 7);
|
||||||
|
|
||||||
|
class Controller final : public ServiceFramework<Controller> {
|
||||||
|
public:
|
||||||
|
// https://switchbrew.org/wiki/IPC_Marshalling
|
||||||
|
explicit Controller(Core::System& system_) : ServiceFramework{system_, "IpcController"} {}
|
||||||
|
~Controller() override = default;
|
||||||
|
|
||||||
|
void ConvertCurrentObjectToDomain(HLERequestContext& ctx) {
|
||||||
|
ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Session is already a domain");
|
||||||
|
LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
|
||||||
|
ctx.GetManager()->ConvertToDomainOnRequestEnd();
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.Push<u32>(1); // Converted sessions start with 1 request handler
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloneCurrentObject(HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service, "called");
|
||||||
|
|
||||||
|
auto session_manager = ctx.GetManager();
|
||||||
|
|
||||||
|
// FIXME: this is duplicated from the SVC, it should just call it instead
|
||||||
|
// once this is a proper process
|
||||||
|
|
||||||
|
// Reserve a new session from the process resource limit.
|
||||||
|
Kernel::KScopedResourceReservation session_reservation(system.Kernel(), Kernel::GetCurrentProcessPointer(kernel), Kernel::LimitableResource::SessionCountMax);
|
||||||
|
ASSERT(session_reservation.Succeeded());
|
||||||
|
|
||||||
|
// Create the session.
|
||||||
|
Kernel::KSession* session = Kernel::KSession::Create(kernel);
|
||||||
|
ASSERT(session != nullptr);
|
||||||
|
|
||||||
|
// Initialize the session.
|
||||||
|
session->Initialize(kernel, nullptr, 0);
|
||||||
|
|
||||||
|
// Commit the session reservation.
|
||||||
|
session_reservation.Commit();
|
||||||
|
|
||||||
|
// Register the session.
|
||||||
|
Kernel::KSession::Register(kernel, session);
|
||||||
|
|
||||||
|
// Register with server manager.
|
||||||
|
session_manager->GetServerManager().RegisterSession(&session->GetServerSession(),
|
||||||
|
session_manager);
|
||||||
|
|
||||||
|
// We succeeded.
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.PushMoveObjects(ctx, session->GetClientSession());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloneCurrentObjectEx(HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service, "called");
|
||||||
|
|
||||||
|
CloneCurrentObject(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryPointerBufferSize(HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service, "called");
|
||||||
|
|
||||||
|
auto* process = Kernel::GetCurrentProcessPointer(kernel);
|
||||||
|
ASSERT(process != nullptr);
|
||||||
|
|
||||||
|
u32 buffer_size = process->GetPointerBufferSize();
|
||||||
|
if (buffer_size > (std::numeric_limits<u16>::max)()) {
|
||||||
|
LOG_WARNING(Service, "Pointer buffer size exceeds u16 max, clamping");
|
||||||
|
buffer_size = (std::numeric_limits<u16>::max)();
|
||||||
|
}
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
rb.Push<u16>(static_cast<u16>(buffer_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPointerBufferSize(HLERequestContext& ctx) {
|
||||||
|
LOG_DEBUG(Service, "called");
|
||||||
|
|
||||||
|
auto* process = Kernel::GetCurrentProcessPointer(kernel);
|
||||||
|
ASSERT(process != nullptr);
|
||||||
|
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
|
||||||
|
u32 requested_size = rp.PopRaw<u32>();
|
||||||
|
|
||||||
|
if (requested_size > (std::numeric_limits<u16>::max)()) {
|
||||||
|
LOG_WARNING(Service, "Requested pointer buffer size too large, clamping to 0xFFFF");
|
||||||
|
requested_size = (std::numeric_limits<u16>::max)();
|
||||||
|
}
|
||||||
|
|
||||||
|
process->SetPointerBufferSize(requested_size);
|
||||||
|
|
||||||
|
LOG_INFO(Service, "Pointer buffer size dynamically updated to {:#x} bytes by process", requested_size);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
|
}
|
||||||
|
static constexpr auto functions = CreateStaticMap(
|
||||||
|
FunctionInfo{0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"},
|
||||||
|
FunctionInfo{1, nullptr, "CopyFromCurrentDomain"},
|
||||||
|
FunctionInfo{2, &Controller::CloneCurrentObject, "CloneCurrentObject"},
|
||||||
|
FunctionInfo{3, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"},
|
||||||
|
FunctionInfo{4, &Controller::CloneCurrentObjectEx, "CloneCurrentObjectEx"},
|
||||||
|
FunctionInfo{5, &Controller::SetPointerBufferSize, "SetPointerBufferSize"} //TODO: where does this come from
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
|
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
|
||||||
controller_interface = std::make_unique<Controller>(kernel.System());
|
controller_interface = std::make_unique<Controller>(kernel.System());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,119 +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 "common/assert.h"
|
|
||||||
#include "common/logging.h"
|
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/hle/kernel/k_client_port.h"
|
|
||||||
#include "core/hle/kernel/k_port.h"
|
|
||||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
|
||||||
#include "core/hle/kernel/k_server_session.h"
|
|
||||||
#include "core/hle/kernel/k_session.h"
|
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
|
||||||
#include "core/hle/service/server_manager.h"
|
|
||||||
#include "core/hle/service/sm/sm_controller.h"
|
|
||||||
|
|
||||||
namespace Service::SM {
|
|
||||||
|
|
||||||
void Controller::ConvertCurrentObjectToDomain(HLERequestContext& ctx) {
|
|
||||||
ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Session is already a domain");
|
|
||||||
LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
|
|
||||||
ctx.GetManager()->ConvertToDomainOnRequestEnd();
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
|
||||||
rb.Push(ResultSuccess);
|
|
||||||
rb.Push<u32>(1); // Converted sessions start with 1 request handler
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::CloneCurrentObject(HLERequestContext& ctx) {
|
|
||||||
LOG_DEBUG(Service, "called");
|
|
||||||
|
|
||||||
auto session_manager = ctx.GetManager();
|
|
||||||
|
|
||||||
// FIXME: this is duplicated from the SVC, it should just call it instead
|
|
||||||
// once this is a proper process
|
|
||||||
|
|
||||||
// Reserve a new session from the process resource limit.
|
|
||||||
Kernel::KScopedResourceReservation session_reservation(system.Kernel(), Kernel::GetCurrentProcessPointer(kernel), Kernel::LimitableResource::SessionCountMax);
|
|
||||||
ASSERT(session_reservation.Succeeded());
|
|
||||||
|
|
||||||
// Create the session.
|
|
||||||
Kernel::KSession* session = Kernel::KSession::Create(kernel);
|
|
||||||
ASSERT(session != nullptr);
|
|
||||||
|
|
||||||
// Initialize the session.
|
|
||||||
session->Initialize(kernel, nullptr, 0);
|
|
||||||
|
|
||||||
// Commit the session reservation.
|
|
||||||
session_reservation.Commit();
|
|
||||||
|
|
||||||
// Register the session.
|
|
||||||
Kernel::KSession::Register(kernel, session);
|
|
||||||
|
|
||||||
// Register with server manager.
|
|
||||||
session_manager->GetServerManager().RegisterSession(&session->GetServerSession(),
|
|
||||||
session_manager);
|
|
||||||
|
|
||||||
// We succeeded.
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
|
||||||
rb.Push(ResultSuccess);
|
|
||||||
rb.PushMoveObjects(ctx, session->GetClientSession());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::CloneCurrentObjectEx(HLERequestContext& ctx) {
|
|
||||||
LOG_DEBUG(Service, "called");
|
|
||||||
|
|
||||||
CloneCurrentObject(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::QueryPointerBufferSize(HLERequestContext& ctx) {
|
|
||||||
LOG_DEBUG(Service, "called");
|
|
||||||
|
|
||||||
auto* process = Kernel::GetCurrentProcessPointer(kernel);
|
|
||||||
ASSERT(process != nullptr);
|
|
||||||
|
|
||||||
u32 buffer_size = process->GetPointerBufferSize();
|
|
||||||
if (buffer_size > (std::numeric_limits<u16>::max)()) {
|
|
||||||
LOG_WARNING(Service, "Pointer buffer size exceeds u16 max, clamping");
|
|
||||||
buffer_size = (std::numeric_limits<u16>::max)();
|
|
||||||
}
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
|
||||||
rb.Push(ResultSuccess);
|
|
||||||
rb.Push<u16>(static_cast<u16>(buffer_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::SetPointerBufferSize(HLERequestContext& ctx) {
|
|
||||||
LOG_DEBUG(Service, "called");
|
|
||||||
|
|
||||||
auto* process = Kernel::GetCurrentProcessPointer(kernel);
|
|
||||||
ASSERT(process != nullptr);
|
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
|
||||||
|
|
||||||
u32 requested_size = rp.PopRaw<u32>();
|
|
||||||
|
|
||||||
if (requested_size > (std::numeric_limits<u16>::max)()) {
|
|
||||||
LOG_WARNING(Service, "Requested pointer buffer size too large, clamping to 0xFFFF");
|
|
||||||
requested_size = (std::numeric_limits<u16>::max)();
|
|
||||||
}
|
|
||||||
|
|
||||||
process->SetPointerBufferSize(requested_size);
|
|
||||||
|
|
||||||
LOG_INFO(Service, "Pointer buffer size dynamically updated to {:#x} bytes by process", requested_size);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
|
||||||
rb.Push(ResultSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// https://switchbrew.org/wiki/IPC_Marshalling
|
|
||||||
Controller::Controller(Core::System& system_) : ServiceFramework{system_, "IpcController"} {
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller::~Controller() = default;
|
|
||||||
|
|
||||||
} // namespace Service::SM
|
|
||||||
@@ -1,42 +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
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "core/hle/service/service.h"
|
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class System;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::SM {
|
|
||||||
|
|
||||||
class Controller final : public ServiceFramework<Controller> {
|
|
||||||
public:
|
|
||||||
explicit Controller(Core::System& system_);
|
|
||||||
~Controller() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void ConvertCurrentObjectToDomain(HLERequestContext& ctx);
|
|
||||||
void CloneCurrentObject(HLERequestContext& ctx);
|
|
||||||
void CloneCurrentObjectEx(HLERequestContext& ctx);
|
|
||||||
void QueryPointerBufferSize(HLERequestContext& ctx);
|
|
||||||
void SetPointerBufferSize(HLERequestContext& ctx);
|
|
||||||
|
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
|
||||||
}
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
|
||||||
FunctionInfo{0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"},
|
|
||||||
FunctionInfo{1, nullptr, "CopyFromCurrentDomain"},
|
|
||||||
FunctionInfo{2, &Controller::CloneCurrentObject, "CloneCurrentObject"},
|
|
||||||
FunctionInfo{3, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"},
|
|
||||||
FunctionInfo{4, &Controller::CloneCurrentObjectEx, "CloneCurrentObjectEx"},
|
|
||||||
FunctionInfo{5, &Controller::SetPointerBufferSize, "SetPointerBufferSize"} //TODO: where does this come from
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::SM
|
|
||||||
@@ -20,20 +20,20 @@ public:
|
|||||||
explicit IDsInterface(Core::System& system_) : ServiceFramework{system_, "IDsInterface"} {}
|
explicit IDsInterface(Core::System& system_) : ServiceFramework{system_, "IDsInterface"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "AddEndpoint"},
|
FunctionInfo{0, nullptr, "AddEndpoint"},
|
||||||
FunctionInfo{1, nullptr, "GetSetupEvent"},
|
FunctionInfo{1, nullptr, "GetSetupEvent"},
|
||||||
FunctionInfo{2, nullptr, "GetSetupPacket"},
|
FunctionInfo{2, nullptr, "GetSetupPacket"},
|
||||||
FunctionInfo{3, nullptr, "Enable"},
|
FunctionInfo{3, nullptr, "Enable"},
|
||||||
FunctionInfo{4, nullptr, "Disable"},
|
FunctionInfo{4, nullptr, "Disable"},
|
||||||
FunctionInfo{5, nullptr, "CtrlIn"},
|
FunctionInfo{5, nullptr, "CtrlIn"},
|
||||||
FunctionInfo{6, nullptr, "CtrlOut"},
|
FunctionInfo{6, nullptr, "CtrlOut"},
|
||||||
FunctionInfo{7, nullptr, "GetCtrlInCompletionEvent"},
|
FunctionInfo{7, nullptr, "GetCtrlInCompletionEvent"},
|
||||||
FunctionInfo{8, nullptr, "GetCtrlInUrbReport"},
|
FunctionInfo{8, nullptr, "GetCtrlInUrbReport"},
|
||||||
FunctionInfo{9, nullptr, "GetCtrlOutCompletionEvent"},
|
FunctionInfo{9, nullptr, "GetCtrlOutCompletionEvent"},
|
||||||
FunctionInfo{10, nullptr, "GetCtrlOutUrbReport"},
|
FunctionInfo{10, nullptr, "GetCtrlOutUrbReport"},
|
||||||
FunctionInfo{11, nullptr, "CtrlStall"},
|
FunctionInfo{11, nullptr, "CtrlStall"},
|
||||||
FunctionInfo{12, nullptr, "AppendConfigurationData"}
|
FunctionInfo{12, nullptr, "AppendConfigurationData"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -44,8 +44,8 @@ public:
|
|||||||
explicit IDsRootSession(Core::System& system_) : ServiceFramework{system_, "usb:ds"} {}
|
explicit IDsRootSession(Core::System& system_) : ServiceFramework{system_, "usb:ds"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "OpenDsService"}
|
FunctionInfo{0, nullptr, "OpenDsService"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -57,16 +57,16 @@ public:
|
|||||||
: ServiceFramework{system_, "IClientEpSession"} {}
|
: ServiceFramework{system_, "IClientEpSession"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "ReOpen"},
|
FunctionInfo{0, nullptr, "ReOpen"},
|
||||||
FunctionInfo{1, nullptr, "Close"},
|
FunctionInfo{1, nullptr, "Close"},
|
||||||
FunctionInfo{2, nullptr, "GetCompletionEvent"},
|
FunctionInfo{2, nullptr, "GetCompletionEvent"},
|
||||||
FunctionInfo{3, nullptr, "PopulateRing"},
|
FunctionInfo{3, nullptr, "PopulateRing"},
|
||||||
FunctionInfo{4, nullptr, "PostBufferAsync"},
|
FunctionInfo{4, nullptr, "PostBufferAsync"},
|
||||||
FunctionInfo{5, nullptr, "GetXferReport"},
|
FunctionInfo{5, nullptr, "GetXferReport"},
|
||||||
FunctionInfo{6, nullptr, "PostBufferMultiAsync"},
|
FunctionInfo{6, nullptr, "PostBufferMultiAsync"},
|
||||||
FunctionInfo{7, nullptr, "CreateSmmuSpace"},
|
FunctionInfo{7, nullptr, "CreateSmmuSpace"},
|
||||||
FunctionInfo{8, nullptr, "ShareReportRing"}
|
FunctionInfo{8, nullptr, "ShareReportRing"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -78,17 +78,17 @@ public:
|
|||||||
: ServiceFramework{system_, "IClientIfSession"} {}
|
: ServiceFramework{system_, "IClientIfSession"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "GetStateChangeEvent"},
|
FunctionInfo{0, nullptr, "GetStateChangeEvent"},
|
||||||
FunctionInfo{1, nullptr, "SetInterface"},
|
FunctionInfo{1, nullptr, "SetInterface"},
|
||||||
FunctionInfo{2, nullptr, "GetInterface"},
|
FunctionInfo{2, nullptr, "GetInterface"},
|
||||||
FunctionInfo{3, nullptr, "GetAlternateInterface"},
|
FunctionInfo{3, nullptr, "GetAlternateInterface"},
|
||||||
FunctionInfo{4, nullptr, "GetCurrentFrame"},
|
FunctionInfo{4, nullptr, "GetCurrentFrame"},
|
||||||
FunctionInfo{5, nullptr, "CtrlXferAsync"},
|
FunctionInfo{5, nullptr, "CtrlXferAsync"},
|
||||||
FunctionInfo{6, nullptr, "GetCtrlXferCompletionEvent"},
|
FunctionInfo{6, nullptr, "GetCtrlXferCompletionEvent"},
|
||||||
FunctionInfo{7, nullptr, "GetCtrlXferReport"},
|
FunctionInfo{7, nullptr, "GetCtrlXferReport"},
|
||||||
FunctionInfo{8, nullptr, "ResetDevice"},
|
FunctionInfo{8, nullptr, "ResetDevice"},
|
||||||
FunctionInfo{9, nullptr, "OpenUsbEp"}
|
FunctionInfo{9, nullptr, "OpenUsbEp"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -99,16 +99,16 @@ public:
|
|||||||
explicit IClientRootSession(Core::System& system_) : ServiceFramework{system_, "usb:hs"} {}
|
explicit IClientRootSession(Core::System& system_) : ServiceFramework{system_, "usb:hs"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "BindClientProcess"},
|
FunctionInfo{0, nullptr, "BindClientProcess"},
|
||||||
FunctionInfo{1, nullptr, "QueryAllInterfaces"},
|
FunctionInfo{1, nullptr, "QueryAllInterfaces"},
|
||||||
FunctionInfo{2, nullptr, "QueryAvailableInterfaces"},
|
FunctionInfo{2, nullptr, "QueryAvailableInterfaces"},
|
||||||
FunctionInfo{3, nullptr, "QueryAcquiredInterfaces"},
|
FunctionInfo{3, nullptr, "QueryAcquiredInterfaces"},
|
||||||
FunctionInfo{4, nullptr, "CreateInterfaceAvailableEvent"},
|
FunctionInfo{4, nullptr, "CreateInterfaceAvailableEvent"},
|
||||||
FunctionInfo{5, nullptr, "DestroyInterfaceAvailableEvent"},
|
FunctionInfo{5, nullptr, "DestroyInterfaceAvailableEvent"},
|
||||||
FunctionInfo{6, nullptr, "GetInterfaceStateChangeEvent"},
|
FunctionInfo{6, nullptr, "GetInterfaceStateChangeEvent"},
|
||||||
FunctionInfo{7, nullptr, "AcquireUsbIf"},
|
FunctionInfo{7, nullptr, "AcquireUsbIf"},
|
||||||
FunctionInfo{8, nullptr, "SetTestMode"}
|
FunctionInfo{8, nullptr, "SetTestMode"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -119,14 +119,14 @@ public:
|
|||||||
explicit IPdSession(Core::System& system_) : ServiceFramework{system_, "IPdSession"} {}
|
explicit IPdSession(Core::System& system_) : ServiceFramework{system_, "IPdSession"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "BindNoticeEvent"},
|
FunctionInfo{0, nullptr, "BindNoticeEvent"},
|
||||||
FunctionInfo{1, nullptr, "UnbindNoticeEvent"},
|
FunctionInfo{1, nullptr, "UnbindNoticeEvent"},
|
||||||
FunctionInfo{2, nullptr, "GetStatus"},
|
FunctionInfo{2, nullptr, "GetStatus"},
|
||||||
FunctionInfo{3, nullptr, "GetNotice"},
|
FunctionInfo{3, nullptr, "GetNotice"},
|
||||||
FunctionInfo{4, nullptr, "EnablePowerRequestNotice"},
|
FunctionInfo{4, nullptr, "EnablePowerRequestNotice"},
|
||||||
FunctionInfo{5, nullptr, "DisablePowerRequestNotice"},
|
FunctionInfo{5, nullptr, "DisablePowerRequestNotice"},
|
||||||
FunctionInfo{6, nullptr, "ReplyPowerRequest"}
|
FunctionInfo{6, nullptr, "ReplyPowerRequest"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -160,16 +160,16 @@ public:
|
|||||||
: ServiceFramework{system_, "IPdCradleSession"} {}
|
: ServiceFramework{system_, "IPdCradleSession"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "SetCradleVdo"},
|
FunctionInfo{0, nullptr, "SetCradleVdo"},
|
||||||
FunctionInfo{1, nullptr, "GetCradleVdo"},
|
FunctionInfo{1, nullptr, "GetCradleVdo"},
|
||||||
FunctionInfo{2, nullptr, "ResetCradleUsbHub"},
|
FunctionInfo{2, nullptr, "ResetCradleUsbHub"},
|
||||||
FunctionInfo{3, nullptr, "GetHostPdcFirmwareType"},
|
FunctionInfo{3, nullptr, "GetHostPdcFirmwareType"},
|
||||||
FunctionInfo{4, nullptr, "GetHostPdcFirmwareRevision"},
|
FunctionInfo{4, nullptr, "GetHostPdcFirmwareRevision"},
|
||||||
FunctionInfo{5, nullptr, "GetHostPdcManufactureId"},
|
FunctionInfo{5, nullptr, "GetHostPdcManufactureId"},
|
||||||
FunctionInfo{6, nullptr, "GetHostPdcDeviceId"},
|
FunctionInfo{6, nullptr, "GetHostPdcDeviceId"},
|
||||||
FunctionInfo{7, nullptr, "EnableCradleRecovery"},
|
FunctionInfo{7, nullptr, "EnableCradleRecovery"},
|
||||||
FunctionInfo{8, nullptr, "DisableCradleRecovery"}
|
FunctionInfo{8, nullptr, "DisableCradleRecovery"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -202,13 +202,13 @@ public:
|
|||||||
explicit IPmMainService(Core::System& system_) : ServiceFramework{system_, "usb:pm"} {}
|
explicit IPmMainService(Core::System& system_) : ServiceFramework{system_, "usb:pm"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "GetPowerEvent"},
|
FunctionInfo{0, nullptr, "GetPowerEvent"},
|
||||||
FunctionInfo{1, nullptr, "GetPowerState"},
|
FunctionInfo{1, nullptr, "GetPowerState"},
|
||||||
FunctionInfo{2, nullptr, "GetDataEvent"},
|
FunctionInfo{2, nullptr, "GetDataEvent"},
|
||||||
FunctionInfo{3, nullptr, "GetDataRole"},
|
FunctionInfo{3, nullptr, "GetDataRole"},
|
||||||
FunctionInfo{4, nullptr, "SetDiagData"},
|
FunctionInfo{4, nullptr, "SetDiagData"},
|
||||||
FunctionInfo{5, nullptr, "GetDiagData"}
|
FunctionInfo{5, nullptr, "GetDiagData"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -219,8 +219,8 @@ public:
|
|||||||
explicit IPdManufactureManager(Core::System& system_) : ServiceFramework{system_, "usb:pd:m"} {}
|
explicit IPdManufactureManager(Core::System& system_) : ServiceFramework{system_, "usb:pd:m"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "OpenManufactureSession"}
|
FunctionInfo{0, nullptr, "OpenManufactureSession"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -231,9 +231,9 @@ public:
|
|||||||
explicit IQdbManager(Core::System& system_) : ServiceFramework{system_, "usb:qdb"} {}
|
explicit IQdbManager(Core::System& system_) : ServiceFramework{system_, "usb:qdb"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "ImportQuirkDevices"},
|
FunctionInfo{0, nullptr, "ImportQuirkDevices"},
|
||||||
FunctionInfo{1, nullptr, "HasQuirk"}
|
FunctionInfo{1, nullptr, "HasQuirk"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
@@ -244,9 +244,9 @@ public:
|
|||||||
explicit IPmObserverService(Core::System& system_) : ServiceFramework{system_, "usb:obsv"} {}
|
explicit IPmObserverService(Core::System& system_) : ServiceFramework{system_, "usb:obsv"} {}
|
||||||
|
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "GetTopologyChangeEvent"},
|
FunctionInfo{0, nullptr, "GetTopologyChangeEvent"},
|
||||||
FunctionInfo{1, nullptr, "GetFlattenedTopology"}
|
FunctionInfo{1, nullptr, "GetFlattenedTopology"}
|
||||||
);
|
);
|
||||||
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
std::optional<FunctionInfoBase> FindRequest(u32 key) override {
|
||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
|
|||||||
+140
-140
@@ -22,103 +22,103 @@ public:
|
|||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "OpenMasterMode" },
|
FunctionInfo{0, nullptr, "OpenMasterMode"},
|
||||||
FunctionInfo{0, nullptr, "OpenMode_2" },
|
FunctionInfo{0, nullptr, "OpenMode_2"},
|
||||||
FunctionInfo{1, nullptr, "CloseMasterMode" },
|
FunctionInfo{1, nullptr, "CloseMasterMode"},
|
||||||
FunctionInfo{1, nullptr, "CloseMode_2" },
|
FunctionInfo{1, nullptr, "CloseMode_2"},
|
||||||
FunctionInfo{2, nullptr, "OpenClientMode" },
|
FunctionInfo{2, nullptr, "OpenClientMode"},
|
||||||
FunctionInfo{2, nullptr, "GetMacAddress_2" },
|
FunctionInfo{2, nullptr, "GetMacAddress_2"},
|
||||||
FunctionInfo{3, nullptr, "CloseClientMode" },
|
FunctionInfo{3, nullptr, "CloseClientMode"},
|
||||||
FunctionInfo{3, nullptr, "CreateBss" },
|
FunctionInfo{3, nullptr, "CreateBss"},
|
||||||
FunctionInfo{4, nullptr, "OpenSpectatorMode" },
|
FunctionInfo{4, nullptr, "OpenSpectatorMode"},
|
||||||
FunctionInfo{4, nullptr, "DestroyBss" },
|
FunctionInfo{4, nullptr, "DestroyBss"},
|
||||||
FunctionInfo{5, nullptr, "CloseSpectatorMode" },
|
FunctionInfo{5, nullptr, "CloseSpectatorMode"},
|
||||||
FunctionInfo{5, nullptr, "StartScan_2" },
|
FunctionInfo{5, nullptr, "StartScan_2"},
|
||||||
FunctionInfo{6, nullptr, "GetMacAddress_2" },
|
FunctionInfo{6, nullptr, "GetMacAddress_2"},
|
||||||
FunctionInfo{6, nullptr, "StopScan_2" },
|
FunctionInfo{6, nullptr, "StopScan_2"},
|
||||||
FunctionInfo{7, nullptr, "CreateBss" },
|
FunctionInfo{7, nullptr, "CreateBss"},
|
||||||
FunctionInfo{7, nullptr, "Connect_2" },
|
FunctionInfo{7, nullptr, "Connect_2"},
|
||||||
FunctionInfo{8, nullptr, "DestroyBss" },
|
FunctionInfo{8, nullptr, "DestroyBss"},
|
||||||
FunctionInfo{8, nullptr, "CancelConnect_2" },
|
FunctionInfo{8, nullptr, "CancelConnect_2"},
|
||||||
FunctionInfo{9, nullptr, "StartScan_2" },
|
FunctionInfo{9, nullptr, "StartScan_2"},
|
||||||
FunctionInfo{9, nullptr, "Join" },
|
FunctionInfo{9, nullptr, "Join"},
|
||||||
FunctionInfo{10, nullptr, "StopScan_2" },
|
FunctionInfo{10, nullptr, "StopScan_2"},
|
||||||
FunctionInfo{10, nullptr, "CancelJoin" },
|
FunctionInfo{10, nullptr, "CancelJoin"},
|
||||||
FunctionInfo{11, nullptr, "Connect_2" },
|
FunctionInfo{11, nullptr, "Connect_2"},
|
||||||
FunctionInfo{11, nullptr, "Disconnect_2" },
|
FunctionInfo{11, nullptr, "Disconnect_2"},
|
||||||
FunctionInfo{12, nullptr, "CancelConnect_2" },
|
FunctionInfo{12, nullptr, "CancelConnect_2"},
|
||||||
FunctionInfo{12, nullptr, "SetBeaconLostCount" },
|
FunctionInfo{12, nullptr, "SetBeaconLostCount"},
|
||||||
FunctionInfo{13, nullptr, "Join" },
|
FunctionInfo{13, nullptr, "Join"},
|
||||||
FunctionInfo{13, nullptr, "GetSystemEvent_2" },
|
FunctionInfo{13, nullptr, "GetSystemEvent_2"},
|
||||||
FunctionInfo{14, nullptr, "CancelJoin" },
|
FunctionInfo{14, nullptr, "CancelJoin"},
|
||||||
FunctionInfo{14, nullptr, "GetConnectionStatus_2" },
|
FunctionInfo{14, nullptr, "GetConnectionStatus_2"},
|
||||||
FunctionInfo{15, nullptr, "Disconnect_2" },
|
FunctionInfo{15, nullptr, "Disconnect_2"},
|
||||||
FunctionInfo{15, nullptr, "GetClientStatus" },
|
FunctionInfo{15, nullptr, "GetClientStatus"},
|
||||||
FunctionInfo{16, nullptr, "SetBeaconLostCount" },
|
FunctionInfo{16, nullptr, "SetBeaconLostCount"},
|
||||||
FunctionInfo{16, nullptr, "GetBssIndicationEvent" },
|
FunctionInfo{16, nullptr, "GetBssIndicationEvent"},
|
||||||
FunctionInfo{17, nullptr, "GetSystemEvent_2" },
|
FunctionInfo{17, nullptr, "GetSystemEvent_2"},
|
||||||
FunctionInfo{17, nullptr, "GetBssIndicationInfo" },
|
FunctionInfo{17, nullptr, "GetBssIndicationInfo"},
|
||||||
FunctionInfo{18, nullptr, "GetConnectionStatus_2" },
|
FunctionInfo{18, nullptr, "GetConnectionStatus_2"},
|
||||||
FunctionInfo{18, nullptr, "GetState_2" },
|
FunctionInfo{18, nullptr, "GetState_2"},
|
||||||
FunctionInfo{19, nullptr, "GetClientStatus" },
|
FunctionInfo{19, nullptr, "GetClientStatus"},
|
||||||
FunctionInfo{19, nullptr, "GetAllowedChannels" },
|
FunctionInfo{19, nullptr, "GetAllowedChannels"},
|
||||||
FunctionInfo{20, nullptr, "GetBssIndicationEvent" },
|
FunctionInfo{20, nullptr, "GetBssIndicationEvent"},
|
||||||
FunctionInfo{20, nullptr, "AddIe" },
|
FunctionInfo{20, nullptr, "AddIe"},
|
||||||
FunctionInfo{21, nullptr, "GetBssIndicationInfo" },
|
FunctionInfo{21, nullptr, "GetBssIndicationInfo"},
|
||||||
FunctionInfo{21, nullptr, "DeleteIe" },
|
FunctionInfo{21, nullptr, "DeleteIe"},
|
||||||
FunctionInfo{22, nullptr, "GetState_2" },
|
FunctionInfo{22, nullptr, "GetState_2"},
|
||||||
FunctionInfo{22, nullptr, "PutFrameRaw" },
|
FunctionInfo{22, nullptr, "PutFrameRaw"},
|
||||||
FunctionInfo{23, nullptr, "GetAllowedChannels" },
|
FunctionInfo{23, nullptr, "GetAllowedChannels"},
|
||||||
FunctionInfo{23, nullptr, "CancelGetFrame" },
|
FunctionInfo{23, nullptr, "CancelGetFrame"},
|
||||||
FunctionInfo{24, nullptr, "AddIe" },
|
FunctionInfo{24, nullptr, "AddIe"},
|
||||||
FunctionInfo{24, nullptr, "CreateRxEntry" },
|
FunctionInfo{24, nullptr, "CreateRxEntry"},
|
||||||
FunctionInfo{25, nullptr, "DeleteIe" },
|
FunctionInfo{25, nullptr, "DeleteIe"},
|
||||||
FunctionInfo{25, nullptr, "DeleteRxEntry" },
|
FunctionInfo{25, nullptr, "DeleteRxEntry"},
|
||||||
FunctionInfo{26, nullptr, "PutFrameRaw" },
|
FunctionInfo{26, nullptr, "PutFrameRaw"},
|
||||||
FunctionInfo{26, nullptr, "AddEthertypeToRxEntry" },
|
FunctionInfo{26, nullptr, "AddEthertypeToRxEntry"},
|
||||||
FunctionInfo{27, nullptr, "CancelGetFrame" },
|
FunctionInfo{27, nullptr, "CancelGetFrame"},
|
||||||
FunctionInfo{27, nullptr, "DeleteEthertypeFromRxEntry" },
|
FunctionInfo{27, nullptr, "DeleteEthertypeFromRxEntry"},
|
||||||
FunctionInfo{28, nullptr, "CreateRxEntry" },
|
FunctionInfo{28, nullptr, "CreateRxEntry"},
|
||||||
FunctionInfo{28, nullptr, "AddMatchingDataToRxEntry" },
|
FunctionInfo{28, nullptr, "AddMatchingDataToRxEntry"},
|
||||||
FunctionInfo{29, nullptr, "DeleteRxEntry" },
|
FunctionInfo{29, nullptr, "DeleteRxEntry"},
|
||||||
FunctionInfo{29, nullptr, "RemoveMatchingDataFromRxEntry" },
|
FunctionInfo{29, nullptr, "RemoveMatchingDataFromRxEntry"},
|
||||||
FunctionInfo{30, nullptr, "AddEthertypeToRxEntry" },
|
FunctionInfo{30, nullptr, "AddEthertypeToRxEntry"},
|
||||||
FunctionInfo{30, nullptr, "GetScanResult_2" },
|
FunctionInfo{30, nullptr, "GetScanResult_2"},
|
||||||
FunctionInfo{31, nullptr, "DeleteEthertypeFromRxEntry" },
|
FunctionInfo{31, nullptr, "DeleteEthertypeFromRxEntry"},
|
||||||
FunctionInfo{31, nullptr, "PutActionFrameOneShot" },
|
FunctionInfo{31, nullptr, "PutActionFrameOneShot"},
|
||||||
FunctionInfo{32, nullptr, "AddMatchingDataToRxEntry" },
|
FunctionInfo{32, nullptr, "AddMatchingDataToRxEntry"},
|
||||||
FunctionInfo{32, nullptr, "SetActionFrameWithBeacon" },
|
FunctionInfo{32, nullptr, "SetActionFrameWithBeacon"},
|
||||||
FunctionInfo{33, nullptr, "RemoveMatchingDataFromRxEntry" },
|
FunctionInfo{33, nullptr, "RemoveMatchingDataFromRxEntry"},
|
||||||
FunctionInfo{33, nullptr, "CancelActionFrameWithBeacon" },
|
FunctionInfo{33, nullptr, "CancelActionFrameWithBeacon"},
|
||||||
FunctionInfo{34, nullptr, "GetScanResult_2" },
|
FunctionInfo{34, nullptr, "GetScanResult_2"},
|
||||||
FunctionInfo{34, nullptr, "CreateRxEntryForActionFrame" },
|
FunctionInfo{34, nullptr, "CreateRxEntryForActionFrame"},
|
||||||
FunctionInfo{35, nullptr, "PutActionFrameOneShot" },
|
FunctionInfo{35, nullptr, "PutActionFrameOneShot"},
|
||||||
FunctionInfo{35, nullptr, "DeleteRxEntryForActionFrame" },
|
FunctionInfo{35, nullptr, "DeleteRxEntryForActionFrame"},
|
||||||
FunctionInfo{36, nullptr, "SetActionFrameWithBeacon" },
|
FunctionInfo{36, nullptr, "SetActionFrameWithBeacon"},
|
||||||
FunctionInfo{36, nullptr, "AddSubtypeToRxEntryForActionFrame" },
|
FunctionInfo{36, nullptr, "AddSubtypeToRxEntryForActionFrame"},
|
||||||
FunctionInfo{37, nullptr, "CancelActionFrameWithBeacon" },
|
FunctionInfo{37, nullptr, "CancelActionFrameWithBeacon"},
|
||||||
FunctionInfo{37, nullptr, "DeleteSubtypeFromRxEntryForActionFrame" },
|
FunctionInfo{37, nullptr, "DeleteSubtypeFromRxEntryForActionFrame"},
|
||||||
FunctionInfo{38, nullptr, "CreateRxEntryForActionFrame" },
|
FunctionInfo{38, nullptr, "CreateRxEntryForActionFrame"},
|
||||||
FunctionInfo{38, nullptr, "CancelGetActionFrame" },
|
FunctionInfo{38, nullptr, "CancelGetActionFrame"},
|
||||||
FunctionInfo{39, nullptr, "DeleteRxEntryForActionFrame" },
|
FunctionInfo{39, nullptr, "DeleteRxEntryForActionFrame"},
|
||||||
FunctionInfo{39, nullptr, "GetRssi_2" },
|
FunctionInfo{39, nullptr, "GetRssi_2"},
|
||||||
FunctionInfo{40, nullptr, "AddSubtypeToRxEntryForActionFrame" },
|
FunctionInfo{40, nullptr, "AddSubtypeToRxEntryForActionFrame"},
|
||||||
FunctionInfo{40, nullptr, "SetMaxAssociationNumber" },
|
FunctionInfo{40, nullptr, "SetMaxAssociationNumber"},
|
||||||
FunctionInfo{41, nullptr, "DeleteSubtypeFromRxEntryForActionFrame" },
|
FunctionInfo{41, nullptr, "DeleteSubtypeFromRxEntryForActionFrame"},
|
||||||
FunctionInfo{41, nullptr, "Cmd41" },
|
FunctionInfo{41, nullptr, "Cmd41"},
|
||||||
FunctionInfo{42, nullptr, "CancelGetActionFrame" },
|
FunctionInfo{42, nullptr, "CancelGetActionFrame"},
|
||||||
FunctionInfo{42, nullptr, "Cmd42" },
|
FunctionInfo{42, nullptr, "Cmd42"},
|
||||||
FunctionInfo{43, nullptr, "GetRssi_2" },
|
FunctionInfo{43, nullptr, "GetRssi_2"},
|
||||||
FunctionInfo{43, nullptr, "Cmd43" },
|
FunctionInfo{43, nullptr, "Cmd43"},
|
||||||
FunctionInfo{44, nullptr, "SetMaxAssociationNumber" },
|
FunctionInfo{44, nullptr, "SetMaxAssociationNumber"},
|
||||||
FunctionInfo{45, nullptr, "OpenLcsMasterMode" },
|
FunctionInfo{45, nullptr, "OpenLcsMasterMode"},
|
||||||
FunctionInfo{46, nullptr, "CloseLcsMasterMode" },
|
FunctionInfo{46, nullptr, "CloseLcsMasterMode"},
|
||||||
FunctionInfo{47, nullptr, "OpenLcsClientMode" },
|
FunctionInfo{47, nullptr, "OpenLcsClientMode"},
|
||||||
FunctionInfo{48, nullptr, "CloseLcsClientMode" },
|
FunctionInfo{48, nullptr, "CloseLcsClientMode"},
|
||||||
FunctionInfo{49, nullptr, "GetChannelStats" },
|
FunctionInfo{49, nullptr, "GetChannelStats"},
|
||||||
FunctionInfo{50, nullptr, "Cmd50" },
|
FunctionInfo{50, nullptr, "Cmd50"},
|
||||||
FunctionInfo{51, nullptr, "Cmd51" },
|
FunctionInfo{51, nullptr, "Cmd51"},
|
||||||
FunctionInfo{52, nullptr, "Cmd52" }
|
FunctionInfo{52, nullptr, "Cmd52"}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,19 +174,19 @@ public:
|
|||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "PutFrameRaw_2" },
|
FunctionInfo{0, nullptr, "PutFrameRaw_2"},
|
||||||
FunctionInfo{1, nullptr, "CancelGetFrame_2" },
|
FunctionInfo{1, nullptr, "CancelGetFrame_2"},
|
||||||
FunctionInfo{2, nullptr, "CreateRxEntry_2" },
|
FunctionInfo{2, nullptr, "CreateRxEntry_2"},
|
||||||
FunctionInfo{3, nullptr, "DeleteRxEntry_2" },
|
FunctionInfo{3, nullptr, "DeleteRxEntry_2"},
|
||||||
FunctionInfo{4, nullptr, "AddEthertypeToRxEntry_2" },
|
FunctionInfo{4, nullptr, "AddEthertypeToRxEntry_2"},
|
||||||
FunctionInfo{5, nullptr, "DeleteEthertypeFromRxEntry_2" },
|
FunctionInfo{5, nullptr, "DeleteEthertypeFromRxEntry_2"},
|
||||||
FunctionInfo{6, nullptr, "GetMacAddress_3" },
|
FunctionInfo{6, nullptr, "GetMacAddress_3"},
|
||||||
FunctionInfo{7, nullptr, "SwitchTsfTimerFunction" },
|
FunctionInfo{7, nullptr, "SwitchTsfTimerFunction"},
|
||||||
FunctionInfo{8, nullptr, "GetDeltaTimeBetweenSystemAndTsf" },
|
FunctionInfo{8, nullptr, "GetDeltaTimeBetweenSystemAndTsf"},
|
||||||
FunctionInfo{9, nullptr, "RegisterSharedMemory" },
|
FunctionInfo{9, nullptr, "RegisterSharedMemory"},
|
||||||
FunctionInfo{10, nullptr, "UnregisterSharedMemory" },
|
FunctionInfo{10, nullptr, "UnregisterSharedMemory"},
|
||||||
FunctionInfo{11, nullptr, "EnableSharedMemory" },
|
FunctionInfo{11, nullptr, "EnableSharedMemory"},
|
||||||
FunctionInfo{12, nullptr, "SetMulticastFilter" }
|
FunctionInfo{12, nullptr, "SetMulticastFilter"}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -200,34 +200,34 @@ public:
|
|||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "Cmd0" },
|
FunctionInfo{0, nullptr, "Cmd0"},
|
||||||
FunctionInfo{1, nullptr, "Cmd1" },
|
FunctionInfo{1, nullptr, "Cmd1"},
|
||||||
FunctionInfo{2, nullptr, "Cmd2" },
|
FunctionInfo{2, nullptr, "Cmd2"},
|
||||||
FunctionInfo{3, nullptr, "Cmd3" },
|
FunctionInfo{3, nullptr, "Cmd3"},
|
||||||
FunctionInfo{4, nullptr, "Cmd4" },
|
FunctionInfo{4, nullptr, "Cmd4"},
|
||||||
FunctionInfo{5, nullptr, "Cmd5" },
|
FunctionInfo{5, nullptr, "Cmd5"},
|
||||||
FunctionInfo{6, nullptr, "Cmd6" },
|
FunctionInfo{6, nullptr, "Cmd6"},
|
||||||
FunctionInfo{7, nullptr, "Cmd7" },
|
FunctionInfo{7, nullptr, "Cmd7"},
|
||||||
FunctionInfo{8, nullptr, "Cmd8" },
|
FunctionInfo{8, nullptr, "Cmd8"},
|
||||||
FunctionInfo{9, nullptr, "Cmd9" },
|
FunctionInfo{9, nullptr, "Cmd9"},
|
||||||
FunctionInfo{10, nullptr, "Cmd10" },
|
FunctionInfo{10, nullptr, "Cmd10"},
|
||||||
FunctionInfo{11, nullptr, "Cmd11" },
|
FunctionInfo{11, nullptr, "Cmd11"},
|
||||||
FunctionInfo{12, nullptr, "Cmd12" },
|
FunctionInfo{12, nullptr, "Cmd12"},
|
||||||
FunctionInfo{13, nullptr, "Cmd13" },
|
FunctionInfo{13, nullptr, "Cmd13"},
|
||||||
FunctionInfo{14, nullptr, "Cmd14" },
|
FunctionInfo{14, nullptr, "Cmd14"},
|
||||||
FunctionInfo{15, nullptr, "Cmd15" },
|
FunctionInfo{15, nullptr, "Cmd15"},
|
||||||
FunctionInfo{16, nullptr, "Cmd16" },
|
FunctionInfo{16, nullptr, "Cmd16"},
|
||||||
FunctionInfo{17, nullptr, "Cmd17" },
|
FunctionInfo{17, nullptr, "Cmd17"},
|
||||||
FunctionInfo{18, nullptr, "Cmd18" },
|
FunctionInfo{18, nullptr, "Cmd18"},
|
||||||
FunctionInfo{19, nullptr, "Cmd19" },
|
FunctionInfo{19, nullptr, "Cmd19"},
|
||||||
FunctionInfo{20, nullptr, "Cmd20" },
|
FunctionInfo{20, nullptr, "Cmd20"},
|
||||||
FunctionInfo{21, nullptr, "Cmd21" },
|
FunctionInfo{21, nullptr, "Cmd21"},
|
||||||
FunctionInfo{22, nullptr, "Cmd22" },
|
FunctionInfo{22, nullptr, "Cmd22"},
|
||||||
FunctionInfo{23, nullptr, "Cmd23" },
|
FunctionInfo{23, nullptr, "Cmd23"},
|
||||||
FunctionInfo{24, nullptr, "Cmd24" },
|
FunctionInfo{24, nullptr, "Cmd24"},
|
||||||
FunctionInfo{25, nullptr, "Cmd25" },
|
FunctionInfo{25, nullptr, "Cmd25"},
|
||||||
FunctionInfo{26, nullptr, "Cmd26" },
|
FunctionInfo{26, nullptr, "Cmd26"},
|
||||||
FunctionInfo{27, nullptr, "Cmd27" }
|
FunctionInfo{27, nullptr, "Cmd27"}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -241,8 +241,8 @@ public:
|
|||||||
return HandlerTableGenerateWithFind(key, functions);
|
return HandlerTableGenerateWithFind(key, functions);
|
||||||
}
|
}
|
||||||
static constexpr auto functions = CreateStaticMap(
|
static constexpr auto functions = CreateStaticMap(
|
||||||
FunctionInfo{0, nullptr, "CreateWirelessCommunicationService" },
|
FunctionInfo{0, nullptr, "CreateWirelessCommunicationService"},
|
||||||
FunctionInfo{1, nullptr, "CreatePrivateWirelessCommunicationService" }
|
FunctionInfo{1, nullptr, "CreatePrivateWirelessCommunicationService"}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user