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);