diff --git a/stratosphere/ams_mitm/Makefile b/stratosphere/ams_mitm/Makefile index a29d84a8a..1501fca9e 100644 --- a/stratosphere/ams_mitm/Makefile +++ b/stratosphere/ams_mitm/Makefile @@ -26,7 +26,7 @@ endif #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) BUILD := build -SOURCES := source source/fs_mitm source/set_mitm source/bpc_mitm source/ns_mitm +SOURCES := source source/fs_mitm source/set_mitm source/bpc_mitm source/ns_mitm source/hid_mitm DATA := data INCLUDES := include ../../common/include EXEFS_SRC := exefs_src diff --git a/stratosphere/ams_mitm/source/amsmitm_modules.cpp b/stratosphere/ams_mitm/source/amsmitm_modules.cpp index b91e891b2..03c357b9c 100644 --- a/stratosphere/ams_mitm/source/amsmitm_modules.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_modules.cpp @@ -25,6 +25,7 @@ #include "set_mitm/setmitm_main.hpp" #include "bpc_mitm/bpcmitm_main.hpp" #include "ns_mitm/nsmitm_main.hpp" +#include "hid_mitm/hidmitm_main.hpp" static HosThread g_module_threads[MitmModuleId_Count]; @@ -37,6 +38,7 @@ static const struct { { &SetMitmMain, SetMitmPriority, SetMitmStackSize }, /* SetMitm */ { &BpcMitmMain, BpcMitmPriority, BpcMitmStackSize }, /* BpcMitm */ { &NsMitmMain, NsMitmPriority, NsMitmStackSize }, /* NsMitm */ + { &HidMitmMain, HidMitmPriority, HidMitmStackSize }, /* HidMitm */ }; void LaunchAllMitmModules() { diff --git a/stratosphere/ams_mitm/source/amsmitm_modules.hpp b/stratosphere/ams_mitm/source/amsmitm_modules.hpp index e808248f8..5b3d13d11 100644 --- a/stratosphere/ams_mitm/source/amsmitm_modules.hpp +++ b/stratosphere/ams_mitm/source/amsmitm_modules.hpp @@ -21,6 +21,7 @@ enum MitmModuleId : u32 { MitmModuleId_SetMitm = 1, MitmModuleId_BpcMitm = 2, MitmModuleId_NsMitm = 3, + MitmModuleId_HidMitm = 4, /* Always keep this at the end. */ MitmModuleId_Count, diff --git a/stratosphere/ams_mitm/source/hid_mitm/hid_mitm_service.cpp b/stratosphere/ams_mitm/source/hid_mitm/hid_mitm_service.cpp new file mode 100644 index 000000000..f1c122c85 --- /dev/null +++ b/stratosphere/ams_mitm/source/hid_mitm/hid_mitm_service.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "hid_shim.h" +#include "hid_mitm_service.hpp" + +void HidMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx) { + /* Nothing to do here */ +} + +Result HidMitmService::SetSupportedNpadStyleSet(u64 applet_resource_user_id, u32 style_set, PidDescriptor pid_desc) { + const HidControllerType new_style_set = static_cast(style_set | TYPE_SYSTEM | TYPE_SYSTEM_EXT); + return hidSetSupportedNpadStyleSetFwd(this->forward_service.get(), this->process_id, applet_resource_user_id, new_style_set);; +} diff --git a/stratosphere/ams_mitm/source/hid_mitm/hid_mitm_service.hpp b/stratosphere/ams_mitm/source/hid_mitm/hid_mitm_service.hpp new file mode 100644 index 000000000..33bc075d7 --- /dev/null +++ b/stratosphere/ams_mitm/source/hid_mitm/hid_mitm_service.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once +#include +#include + +#include "../utils.hpp" + +class HidMitmService : public IMitmServiceObject { + private: + enum class CommandId { + SetSupportedNpadStyleSet = 100, + }; + public: + HidMitmService(std::shared_ptr s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) { + /* ... */ + } + + static bool ShouldMitm(u64 pid, sts::ncm::TitleId tid) { + /* TODO: Consider removing in Atmosphere 0.10.0/1.0.0. */ + /* We will mitm: + * - hbl, to help homebrew not need to be recompiled. + */ + return Utils::IsHblTid(static_cast(tid)); + } + + static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx); + + protected: + /* Overridden commands. */ + Result SetSupportedNpadStyleSet(u64 applet_resource_user_id, u32 style_set, PidDescriptor pid_desc); + public: + DEFINE_SERVICE_DISPATCH_TABLE { + MAKE_SERVICE_COMMAND_META(HidMitmService, SetSupportedNpadStyleSet), + }; +}; diff --git a/stratosphere/ams_mitm/source/hid_mitm/hid_shim.c b/stratosphere/ams_mitm/source/hid_mitm/hid_shim.c new file mode 100644 index 000000000..b65c82800 --- /dev/null +++ b/stratosphere/ams_mitm/source/hid_mitm/hid_shim.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include "hid_shim.h" + +/* Command forwarders. */ +Result hidSetSupportedNpadStyleSetFwd(Service* s, u64 process_id, u64 aruid, HidControllerType type) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 type; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 100; + raw->type = type; + raw->AppletResourceUserId = aruid; + + /* Override Process ID. */ + { + u32 *cmd_buf = (u32 *)armGetTls(); + cmd_buf[3] = (u32)(process_id >> 0); + cmd_buf[4] = (u32)((process_id >> 32) & 0xFFFF) | 0xFFFE0000ul; + } + + Result rc = serviceIpcDispatch(s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} diff --git a/stratosphere/ams_mitm/source/hid_mitm/hid_shim.h b/stratosphere/ams_mitm/source/hid_mitm/hid_shim.h new file mode 100644 index 000000000..6a16f8fc5 --- /dev/null +++ b/stratosphere/ams_mitm/source/hid_mitm/hid_shim.h @@ -0,0 +1,19 @@ +/** + * @file hid_shim.h + * @brief Human Interface Devices Services (hid) IPC wrapper. + * @author SciresM + * @copyright libnx Authors + */ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Command forwarders. */ +Result hidSetSupportedNpadStyleSetFwd(Service* s, u64 process_id, u64 aruid, HidControllerType type); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/stratosphere/ams_mitm/source/hid_mitm/hidmitm_main.cpp b/stratosphere/ams_mitm/source/hid_mitm/hidmitm_main.cpp new file mode 100644 index 000000000..578c53d31 --- /dev/null +++ b/stratosphere/ams_mitm/source/hid_mitm/hidmitm_main.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "hidmitm_main.hpp" +#include "hid_mitm_service.hpp" + +#include "../utils.hpp" + +struct HidMitmManagerOptions { + static const size_t PointerBufferSize = 0x200; + static const size_t MaxDomains = 0x0; + static const size_t MaxDomainObjects = 0x0; +}; +using HidMitmManager = WaitableManager; + +void HidMitmMain(void *arg) { + /* This is only necessary on 9.x+ */ + if (GetRuntimeFirmwareVersion() < FirmwareVersion_900) { + return; + } + + /* Ensure we can talk to HID. */ + Utils::WaitHidAvailable(); + + /* Create server manager */ + static auto s_server_manager = HidMitmManager(1); + + /* Create hid mitm. */ + /* Note: official HID passes 100 as sessions, despite this being > 0x40. */ + AddMitmServerToManager(&s_server_manager, "hid", 100); + + /* Loop forever, servicing our services. */ + s_server_manager.Process(); +} diff --git a/stratosphere/ams_mitm/source/hid_mitm/hidmitm_main.hpp b/stratosphere/ams_mitm/source/hid_mitm/hidmitm_main.hpp new file mode 100644 index 000000000..31be7a6d2 --- /dev/null +++ b/stratosphere/ams_mitm/source/hid_mitm/hidmitm_main.hpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +constexpr u32 HidMitmPriority = 47; +constexpr u32 HidMitmStackSize = 0x8000; + +void HidMitmMain(void *arg); \ No newline at end of file diff --git a/stratosphere/ams_mitm/source/utils.cpp b/stratosphere/ams_mitm/source/utils.cpp index f250b2928..6923673c9 100644 --- a/stratosphere/ams_mitm/source/utils.cpp +++ b/stratosphere/ams_mitm/source/utils.cpp @@ -29,7 +29,7 @@ #include "bpc_mitm/bpcmitm_reboot_manager.hpp" static FsFileSystem g_sd_filesystem = {0}; -static HosSignal g_sd_signal; +static HosSignal g_sd_signal, g_hid_signal; static std::vector g_mitm_flagged_tids; static std::vector g_disable_mitm_flagged_tids; @@ -299,6 +299,9 @@ void Utils::InitializeThreadFunc(void *args) { svcSleepThread(1000000ULL); } } + + /* Signal to waiters that we are ready. */ + g_hid_signal.Signal(); } bool Utils::IsSdInitialized() { @@ -313,6 +316,10 @@ bool Utils::IsHidAvailable() { return g_has_hid_session; } +void Utils::WaitHidAvailable() { + g_hid_signal.Wait(); +} + Result Utils::OpenSdFile(const char *fn, int flags, FsFile *out) { if (!IsSdInitialized()) { return ResultFsSdCardNotPresent; diff --git a/stratosphere/ams_mitm/source/utils.hpp b/stratosphere/ams_mitm/source/utils.hpp index 02c300dc4..a86aa98a0 100644 --- a/stratosphere/ams_mitm/source/utils.hpp +++ b/stratosphere/ams_mitm/source/utils.hpp @@ -108,6 +108,7 @@ class Utils { static bool IsHidAvailable(); + static void WaitHidAvailable(); static Result GetKeysHeld(u64 *keys); static OverrideKey GetTitleOverrideKey(u64 tid);