ams_mitm: begin skeleton refactor
This commit is contained in:
1 parent
02d4c97c6d
commit
393596ef9a
105 files changed
+1541
-352
No files matched your search
@@ -13,23 +13,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include <atmosphere.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "amsmitm_modules.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "amsmitm_module_management.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern u32 __start__;
|
||||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
u32 __nx_fs_num_sessions = 1;
|
||||
u32 __nx_fsdev_direntry_cache_size = 1;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x1000000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
@@ -43,18 +34,31 @@ extern "C" {
|
||||
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||
}
|
||||
|
||||
ams::ncm::TitleId __stratosphere_title_id = ams::ncm::TitleId::AtmosphereMitm;
|
||||
namespace ams {
|
||||
|
||||
ncm::ProgramId CurrentProgramId = ncm::ProgramId::AtmosphereMitm;
|
||||
|
||||
namespace result {
|
||||
|
||||
bool CallFatalOnResultAssertion = false;
|
||||
|
||||
}
|
||||
|
||||
/* Override. */
|
||||
void ExceptionHandler(FatalErrorContext *ctx) {
|
||||
/* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */
|
||||
/* Utils::RebootToFatalError(ctx); */
|
||||
while (1) { /* ... */ }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace ams;
|
||||
|
||||
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||
StratosphereCrashHandler(ctx);
|
||||
}
|
||||
|
||||
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) {
|
||||
/* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */
|
||||
Utils::RebootToFatalError(ctx);
|
||||
ams::CrashHandler(ctx);
|
||||
}
|
||||
|
||||
void __libnx_initheap(void) {
|
||||
@@ -70,16 +74,16 @@ void __libnx_initheap(void) {
|
||||
}
|
||||
|
||||
void __appInit(void) {
|
||||
SetFirmwareVersionForLibnx();
|
||||
hos::SetVersionForLibnx();
|
||||
|
||||
DoWithSmSession([&]() {
|
||||
sm::DoWithSession([&]() {
|
||||
R_ASSERT(fsInitialize());
|
||||
R_ASSERT(pmdmntInitialize());
|
||||
R_ASSERT(pminfoInitialize());
|
||||
R_ASSERT(splFsInitialize());
|
||||
});
|
||||
|
||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||
ams::CheckApiVersion();
|
||||
}
|
||||
|
||||
void __appExit(void) {
|
||||
@@ -90,18 +94,12 @@ void __appExit(void) {
|
||||
fsExit();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDebugInit(debugDevice_SVC);
|
||||
ams::os::Thread initializer_thread;
|
||||
|
||||
LaunchAllMitmModules();
|
||||
|
||||
R_ASSERT(initializer_thread.Initialize(&Utils::InitializeThreadFunc, NULL, 0x4000, 0x15));
|
||||
R_ASSERT(initializer_thread.Start());
|
||||
int main(int argc, char **argv) {
|
||||
/* Launch all mitm modules in sequence. */
|
||||
mitm::LaunchAllModules();
|
||||
|
||||
/* Wait for all mitm modules to end. */
|
||||
WaitAllMitmModules();
|
||||
mitm::WaitAllModules();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm {
|
||||
|
||||
/* TODO: C++20 Concepts will make this a lot less stupid. */
|
||||
class ModuleBase {};
|
||||
|
||||
#define DEFINE_MITM_MODULE_CLASS(ss, prio) class MitmModule : public ::ams::mitm::ModuleBase { \
|
||||
public: \
|
||||
static constexpr size_t ThreadPriority = prio; \
|
||||
static constexpr size_t StackSize = ss; \
|
||||
alignas(0x1000) static inline u8 Stack[StackSize]; \
|
||||
public: \
|
||||
static void ThreadFunction(void *); \
|
||||
}
|
||||
|
||||
template<class M>
|
||||
struct ModuleTraits {
|
||||
static_assert(std::is_base_of<ModuleBase, M>::value, "Mitm Modules must inherit from ams::mitm::Module");
|
||||
|
||||
static constexpr void *Stack = &M::Stack[0];
|
||||
static constexpr size_t StackSize = M::StackSize;
|
||||
|
||||
static constexpr size_t ThreadPriority = M::ThreadPriority;
|
||||
|
||||
static constexpr ::ThreadFunc ThreadFunction = &M::ThreadFunction;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "amsmitm_module_management.hpp"
|
||||
#include "amsmitm_module.hpp"
|
||||
|
||||
#include "fs_mitm/fsmitm_module.hpp"
|
||||
#include "set_mitm/setmitm_module.hpp"
|
||||
#include "bpc_mitm/bpcmitm_module.hpp"
|
||||
#include "ns_mitm/nsmitm_module.hpp"
|
||||
#include "hid_mitm/hidmitm_module.hpp"
|
||||
|
||||
namespace ams::mitm {
|
||||
|
||||
namespace {
|
||||
|
||||
enum ModuleId : u32 {
|
||||
ModuleId_FsMitm,
|
||||
ModuleId_SetMitm,
|
||||
ModuleId_BpcMitm,
|
||||
ModuleId_NsMitm,
|
||||
ModuleId_HidMitm,
|
||||
|
||||
ModuleId_Count,
|
||||
};
|
||||
|
||||
struct ModuleDefinition {
|
||||
ThreadFunc main;
|
||||
void *stack_mem;
|
||||
u32 priority;
|
||||
u32 stack_size;
|
||||
};
|
||||
|
||||
template<class M>
|
||||
constexpr ModuleDefinition GetModuleDefinition() {
|
||||
using Traits = ModuleTraits<M>;
|
||||
|
||||
return ModuleDefinition {
|
||||
.main = Traits::ThreadFunction,
|
||||
.stack_mem = Traits::Stack,
|
||||
.priority = Traits::ThreadPriority,
|
||||
.stack_size = Traits::StackSize,
|
||||
};
|
||||
}
|
||||
|
||||
ams::os::Thread g_module_threads[ModuleId_Count];
|
||||
|
||||
constexpr ModuleDefinition g_module_definitions[ModuleId_Count] = {
|
||||
GetModuleDefinition<fs::MitmModule>(),
|
||||
GetModuleDefinition<set::MitmModule>(),
|
||||
GetModuleDefinition<bpc::MitmModule>(),
|
||||
GetModuleDefinition<ns::MitmModule>(),
|
||||
GetModuleDefinition<hid::MitmModule>(),
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void LaunchAllModules() {
|
||||
/* Create thread for each module. */
|
||||
for (u32 i = 0; i < static_cast<u32>(ModuleId_Count); i++) {
|
||||
const ModuleDefinition &cur_module = g_module_definitions[i];
|
||||
R_ASSERT(g_module_threads[i].Initialize(cur_module.main, nullptr, cur_module.stack_mem, cur_module.stack_size, cur_module.priority));
|
||||
}
|
||||
|
||||
/* Start thread for each module. */
|
||||
for (u32 i = 0; i < static_cast<u32>(ModuleId_Count); i++) {
|
||||
R_ASSERT(g_module_threads[i].Start());
|
||||
}
|
||||
}
|
||||
|
||||
void WaitAllModules() {
|
||||
/* Wait on thread for each module. */
|
||||
for (u32 i = 0; i < static_cast<u32>(ModuleId_Count); i++) {
|
||||
g_module_threads[i].Join();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm {
|
||||
|
||||
void LaunchAllModules();
|
||||
void WaitAllModules();
|
||||
|
||||
}
|
||||
@@ -13,42 +13,29 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "../utils.hpp"
|
||||
namespace ams::mitm::bpc {
|
||||
|
||||
class BpcMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
ShutdownSystem = 0,
|
||||
RebootSystem = 1,
|
||||
};
|
||||
public:
|
||||
BpcMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
class BpcMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(BpcMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::TitleId tid) {
|
||||
/* We will mitm:
|
||||
* - am, to intercept the Reboot/Power buttons in the overlay menu.
|
||||
* - fatal, to simplify payload reboot logic significantly
|
||||
* - applications, to allow homebrew to take advantage of the feature.
|
||||
*/
|
||||
return tid == ams::ncm::TitleId::Am || tid == ams::ncm::TitleId::Fatal || ams::ncm::IsApplicationTitleId(tid) || Utils::IsHblTid(static_cast<u64>(tid));
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result ShutdownSystem();
|
||||
Result RebootSystem();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(BpcMitmService, ShutdownSystem),
|
||||
MAKE_SERVICE_COMMAND_META(BpcMitmService, RebootSystem),
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "bpcmitm_module.hpp"
|
||||
#include "bpc_mitm_service.hpp"
|
||||
|
||||
namespace ams::mitm::bpc {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr sm::ServiceName MitmServiceName = sm::ServiceName::Encode("bpc");
|
||||
constexpr sm::ServiceName DeprecatedMitmServiceName = sm::ServiceName::Encode("bpc:c");
|
||||
constexpr size_t MitmServiceMaxSessions = 13;
|
||||
|
||||
constexpr size_t MaxServers = 1;
|
||||
constexpr size_t MaxSessions = MitmServiceMaxSessions;
|
||||
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
|
||||
sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions> g_server_manager;
|
||||
|
||||
}
|
||||
|
||||
void MitmModule::ThreadFunction(void *arg) {
|
||||
/* Create bpc mitm. */
|
||||
const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_200) ? MitmServiceName : DeprecatedMitmServiceName;
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<BpcMitmService>(service_name));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "../amsmitm_module.hpp"
|
||||
|
||||
namespace ams::mitm::bpc {
|
||||
|
||||
DEFINE_MITM_MODULE_CLASS(0x8000, 32);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm::fs {
|
||||
|
||||
class FsMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(FsMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "fsmitm_module.hpp"
|
||||
#include "fs_mitm_service.hpp"
|
||||
|
||||
namespace ams::mitm::fs {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr sm::ServiceName MitmServiceName = sm::ServiceName::Encode("fsp-srv");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x800;
|
||||
static constexpr size_t MaxDomains = 0x40;
|
||||
static constexpr size_t MaxDomainObjects = 0x4000;
|
||||
};
|
||||
|
||||
constexpr size_t MaxServers = 1;
|
||||
constexpr size_t MaxSessions = 61;
|
||||
sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions> g_server_manager;
|
||||
|
||||
}
|
||||
|
||||
void MitmModule::ThreadFunction(void *arg) {
|
||||
/* Create fs mitm. */
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<FsMitmService>(MitmServiceName));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "../amsmitm_module.hpp"
|
||||
|
||||
namespace ams::mitm::fs {
|
||||
|
||||
DEFINE_MITM_MODULE_CLASS(0x8000, 43);
|
||||
|
||||
}
|
||||
@@ -15,40 +15,28 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "../utils.hpp"
|
||||
namespace ams::mitm::hid {
|
||||
|
||||
class HidMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
SetSupportedNpadStyleSet = 100,
|
||||
};
|
||||
private:
|
||||
bool should_set_system_ext = false;
|
||||
public:
|
||||
HidMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
class HidMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(HidMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
~HidMitmService();
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::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<u64>(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),
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "hidmitm_module.hpp"
|
||||
#include "hid_mitm_service.hpp"
|
||||
|
||||
namespace ams::mitm::hid {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr sm::ServiceName MitmServiceName = sm::ServiceName::Encode("hid");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x200;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
};
|
||||
|
||||
constexpr size_t MaxServers = 1;
|
||||
sf::hipc::ServerManager<MaxServers, ServerOptions> g_server_manager;
|
||||
|
||||
}
|
||||
|
||||
void MitmModule::ThreadFunction(void *arg) {
|
||||
/* This is only necessary on 9.x+ */
|
||||
if (hos::GetVersion() < hos::Version_900) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create hid mitm. */
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<HidMitmService>(MitmServiceName));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "../amsmitm_module.hpp"
|
||||
|
||||
namespace ams::mitm::hid {
|
||||
|
||||
DEFINE_MITM_MODULE_CLASS(0x8000, 47);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm::ns {
|
||||
|
||||
class NsAmMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(NsAmMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm::ns {
|
||||
|
||||
class NsWebMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(NsWebMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "nsmitm_module.hpp"
|
||||
#include "ns_am_mitm_service.hpp"
|
||||
#include "ns_web_mitm_service.hpp"
|
||||
|
||||
namespace ams::mitm::ns {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr sm::ServiceName NsAmMitmServiceName = sm::ServiceName::Encode("ns:am");
|
||||
constexpr sm::ServiceName NsWebMitmServiceName = sm::ServiceName::Encode("ns:am");
|
||||
|
||||
constexpr size_t MaxServers = 1;
|
||||
constexpr size_t MaxSessions = 5;
|
||||
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
|
||||
sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions> g_server_manager;
|
||||
|
||||
}
|
||||
|
||||
void MitmModule::ThreadFunction(void *arg) {
|
||||
/* Create mitm servers. */
|
||||
if (hos::GetVersion() < hos::Version_300) {
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<NsAmMitmService>(NsAmMitmServiceName));
|
||||
} else {
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<NsWebMitmService>(NsWebMitmServiceName));
|
||||
}
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "../amsmitm_module.hpp"
|
||||
|
||||
namespace ams::mitm::ns {
|
||||
|
||||
DEFINE_MITM_MODULE_CLASS(0x4000, 48);
|
||||
|
||||
}
|
||||
@@ -13,47 +13,29 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "../utils.hpp"
|
||||
namespace ams::mitm::set {
|
||||
|
||||
class SetMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetLanguageCode = 0,
|
||||
GetRegionCode = 4,
|
||||
};
|
||||
private:
|
||||
ams::os::Mutex lock;
|
||||
OverrideLocale locale;
|
||||
bool got_locale;
|
||||
public:
|
||||
SetMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
this->got_locale = false;
|
||||
}
|
||||
class SetMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(SetMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::TitleId tid) {
|
||||
/* Mitm all applications. */
|
||||
return tid == ams::ncm::TitleId::Ns || ams::ncm::IsApplicationTitleId(tid);
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
|
||||
protected:
|
||||
static bool IsValidLanguageCode(u64 lang_code);
|
||||
static bool IsValidRegionCode(u32 region_code);
|
||||
|
||||
Result EnsureLocale();
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result GetLanguageCode(Out<u64> out_lang_code);
|
||||
Result GetRegionCode(Out<u32> out_region_code);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetLanguageCode),
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetRegionCode),
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "setmitm_module.hpp"
|
||||
#include "set_mitm_service.hpp"
|
||||
#include "setsys_mitm_service.hpp"
|
||||
|
||||
namespace ams::mitm::set {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr sm::ServiceName SetMitmServiceName = sm::ServiceName::Encode("set");
|
||||
constexpr sm::ServiceName SetSysMitmServiceName = sm::ServiceName::Encode("set:sys");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x100;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
};
|
||||
|
||||
constexpr size_t MaxServers = 2;
|
||||
constexpr size_t MaxSessions = 60;
|
||||
sf::hipc::ServerManager<MaxServers, ServerOptions, MaxSessions> g_server_manager;
|
||||
|
||||
}
|
||||
|
||||
void MitmModule::ThreadFunction(void *arg) {
|
||||
/* Create mitm servers. */
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<SetMitmService>(SetMitmServiceName));
|
||||
R_ASSERT(g_server_manager.RegisterMitmServer<SetSysMitmService>(SetSysMitmServiceName));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "../amsmitm_module.hpp"
|
||||
|
||||
namespace ams::mitm::set {
|
||||
|
||||
DEFINE_MITM_MODULE_CLASS(0x8000, 43);
|
||||
|
||||
}
|
||||
@@ -13,44 +13,29 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "setsys_shim.h"
|
||||
namespace ams::mitm::set {
|
||||
|
||||
class SetSysMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetFirmwareVersion = 3,
|
||||
GetFirmwareVersion2 = 4,
|
||||
GetSettingsItemValueSize = 37,
|
||||
GetSettingsItemValue = 38,
|
||||
};
|
||||
public:
|
||||
SetSysMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
class SetSysMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* TODO */
|
||||
};
|
||||
public:
|
||||
static bool ShouldMitm(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(SetSysMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* TODO */
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* TODO */
|
||||
};
|
||||
};
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::TitleId tid) {
|
||||
/* Mitm everything. */
|
||||
return true;
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result GetFirmwareVersion(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
Result GetFirmwareVersion2(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
Result GetSettingsItemValueSize(Out<u64> out_size, InPointer<char> name, InPointer<char> key);
|
||||
Result GetSettingsItemValue(Out<u64> out_size, OutBuffer<u8> out_value, InPointer<char> name, InPointer<char> key);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetFirmwareVersion),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetFirmwareVersion2),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetSettingsItemValueSize),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetSettingsItemValue),
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
.SUFFIXES:
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
|
||||
endif
|
||||
|
||||
TOPDIR ?= $(CURDIR)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
|
||||
AMSBRANCH := $(shell git symbolic-ref --short HEAD)
|
||||
AMSREV := $(AMSBRANCH)-$(shell git rev-parse --short HEAD)
|
||||
|
||||
ifneq (, $(strip $(shell git status --porcelain 2>/dev/null)))
|
||||
AMSREV := $(AMSREV)-dirty
|
||||
endif
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# TARGET is the name of the output
|
||||
# BUILD is the directory where object files & intermediate files will be placed
|
||||
# SOURCES is a list of directories containing source code
|
||||
# DATA is a list of directories containing data files
|
||||
# INCLUDES is a list of directories containing header files
|
||||
# EXEFS_SRC is the optional input directory containing data copied into exefs, if anything this normally should only contain "main.npdm".
|
||||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
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
|
||||
|
||||
DEFINES := -DATMOSPHERE_GIT_BRANCH=\"$(AMSBRANCH)\" -DATMOSPHERE_GIT_REV=\"$(AMSREV)\"
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
||||
|
||||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
CXXWRAPS := -Wl,--wrap,__cxa_pure_virtual \
|
||||
-Wl,--wrap,__cxa_throw \
|
||||
-Wl,--wrap,__cxa_rethrow \
|
||||
-Wl,--wrap,__cxa_allocate_exception \
|
||||
-Wl,--wrap,__cxa_begin_catch \
|
||||
-Wl,--wrap,__cxa_end_catch \
|
||||
-Wl,--wrap,__cxa_call_unexpected \
|
||||
-Wl,--wrap,__cxa_call_terminate \
|
||||
-Wl,--wrap,__gxx_personality_v0
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) $(CXXWRAPS) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := -lstratosphere -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
# include and lib
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBDIRS := $(PORTLIBS) $(LIBNX) $(CURDIR)/../libstratosphere
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||
|
||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(BUILD)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||
|
||||
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
.PHONY: $(BUILD) clean all
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(BUILD)
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(BUILD) $(TARGET).kip $(TARGET).elf
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(OUTPUT).kip
|
||||
|
||||
$(OUTPUT).kip : $(OUTPUT).elf
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "ams.mitm",
|
||||
"title_id": "0x010041544D530000",
|
||||
"main_thread_stack_size": "0x20000",
|
||||
"main_thread_priority": 43,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 1,
|
||||
"kernel_capabilities": [
|
||||
{
|
||||
"type": "handle_table_size",
|
||||
"value": 512
|
||||
},
|
||||
{
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcSetHeapSize": "0x01",
|
||||
"svcSetMemoryPermission": "0x02",
|
||||
"svcSetMemoryAttribute": "0x03",
|
||||
"svcMapMemory": "0x04",
|
||||
"svcUnmapMemory": "0x05",
|
||||
"svcQueryMemory": "0x06",
|
||||
"svcExitProcess": "0x07",
|
||||
"svcCreateThread": "0x08",
|
||||
"svcStartThread": "0x09",
|
||||
"svcExitThread": "0x0a",
|
||||
"svcSleepThread": "0x0b",
|
||||
"svcGetThreadPriority": "0x0c",
|
||||
"svcSetThreadPriority": "0x0d",
|
||||
"svcGetThreadCoreMask": "0x0e",
|
||||
"svcSetThreadCoreMask": "0x0f",
|
||||
"svcGetCurrentProcessorNumber": "0x10",
|
||||
"svcSignalEvent": "0x11",
|
||||
"svcClearEvent": "0x12",
|
||||
"svcMapSharedMemory": "0x13",
|
||||
"svcUnmapSharedMemory": "0x14",
|
||||
"svcCreateTransferMemory": "0x15",
|
||||
"svcCloseHandle": "0x16",
|
||||
"svcResetSignal": "0x17",
|
||||
"svcWaitSynchronization": "0x18",
|
||||
"svcCancelSynchronization": "0x19",
|
||||
"svcArbitrateLock": "0x1a",
|
||||
"svcArbitrateUnlock": "0x1b",
|
||||
"svcWaitProcessWideKeyAtomic": "0x1c",
|
||||
"svcSignalProcessWideKey": "0x1d",
|
||||
"svcGetSystemTick": "0x1e",
|
||||
"svcConnectToNamedPort": "0x1f",
|
||||
"svcSendSyncRequestLight": "0x20",
|
||||
"svcSendSyncRequest": "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer": "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer": "0x23",
|
||||
"svcGetProcessId": "0x24",
|
||||
"svcGetThreadId": "0x25",
|
||||
"svcBreak": "0x26",
|
||||
"svcOutputDebugString": "0x27",
|
||||
"svcReturnFromException": "0x28",
|
||||
"svcGetInfo": "0x29",
|
||||
"svcWaitForAddress": "0x34",
|
||||
"svcSignalToAddress": "0x35",
|
||||
"svcCreateSession": "0x40",
|
||||
"svcAcceptSession": "0x41",
|
||||
"svcReplyAndReceiveLight": "0x42",
|
||||
"svcReplyAndReceive": "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||
"svcCreateEvent": "0x45",
|
||||
"svcCreateInterruptEvent": "0x53",
|
||||
"svcReadWriteRegister": "0x4E",
|
||||
"svcQueryIoMapping": "0x55",
|
||||
"svcCreateDeviceAddressSpace": "0x56",
|
||||
"svcAttachDeviceAddressSpace": "0x57",
|
||||
"svcDetachDeviceAddressSpace": "0x58",
|
||||
"svcMapDeviceAddressSpaceAligned": "0x5a",
|
||||
"svcUnmapDeviceAddressSpace": "0x5c",
|
||||
"svcGetSystemInfo": "0x6f",
|
||||
"svcManageNamedPort": "0x71",
|
||||
"svcCallSecureMonitor": "0x7F"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <switch.h>
|
||||
#include <atmosphere.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "amsmitm_modules.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern u32 __start__;
|
||||
|
||||
u32 __nx_applet_type = AppletType_None;
|
||||
|
||||
#define INNER_HEAP_SIZE 0x1000000
|
||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||
char nx_inner_heap[INNER_HEAP_SIZE];
|
||||
|
||||
void __libnx_initheap(void);
|
||||
void __appInit(void);
|
||||
void __appExit(void);
|
||||
|
||||
/* Exception handling. */
|
||||
alignas(16) u8 __nx_exception_stack[0x1000];
|
||||
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx);
|
||||
}
|
||||
|
||||
ams::ncm::ProgramId __stratosphere_program_id = ams::ncm::ProgramId::AtmosphereMitm;
|
||||
|
||||
void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||
StratosphereCrashHandler(ctx);
|
||||
}
|
||||
|
||||
void __libstratosphere_exception_handler(AtmosphereFatalErrorContext *ctx) {
|
||||
/* We're bpc-mitm (or ams_mitm, anyway), so manually reboot to fatal error. */
|
||||
Utils::RebootToFatalError(ctx);
|
||||
}
|
||||
|
||||
void __libnx_initheap(void) {
|
||||
void* addr = nx_inner_heap;
|
||||
size_t size = nx_inner_heap_size;
|
||||
|
||||
/* Newlib */
|
||||
extern char* fake_heap_start;
|
||||
extern char* fake_heap_end;
|
||||
|
||||
fake_heap_start = (char*)addr;
|
||||
fake_heap_end = (char*)addr + size;
|
||||
}
|
||||
|
||||
void __appInit(void) {
|
||||
SetFirmwareVersionForLibnx();
|
||||
|
||||
DoWithSmSession([&]() {
|
||||
R_ASSERT(fsInitialize());
|
||||
R_ASSERT(pmdmntInitialize());
|
||||
R_ASSERT(pminfoInitialize());
|
||||
R_ASSERT(splFsInitialize());
|
||||
});
|
||||
|
||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||
}
|
||||
|
||||
void __appExit(void) {
|
||||
/* Cleanup services. */
|
||||
splFsExit();
|
||||
pminfoExit();
|
||||
pmdmntExit();
|
||||
fsExit();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDebugInit(debugDevice_SVC);
|
||||
ams::os::Thread initializer_thread;
|
||||
|
||||
LaunchAllMitmModules();
|
||||
|
||||
R_ASSERT(initializer_thread.Initialize(&Utils::InitializeThreadFunc, NULL, 0x4000, 0x15));
|
||||
R_ASSERT(initializer_thread.Start());
|
||||
|
||||
/* Wait for all mitm modules to end. */
|
||||
WaitAllMitmModules();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "../utils.hpp"
|
||||
|
||||
class BpcMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
ShutdownSystem = 0,
|
||||
RebootSystem = 1,
|
||||
};
|
||||
public:
|
||||
BpcMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId tid) {
|
||||
/* We will mitm:
|
||||
* - am, to intercept the Reboot/Power buttons in the overlay menu.
|
||||
* - fatal, to simplify payload reboot logic significantly
|
||||
* - applications, to allow homebrew to take advantage of the feature.
|
||||
*/
|
||||
return tid == ams::ncm::ProgramId::Am || tid == ams::ncm::ProgramId::Fatal || ams::ncm::IsApplicationProgramId(tid) || Utils::IsHblTid(static_cast<u64>(tid));
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result ShutdownSystem();
|
||||
Result RebootSystem();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(BpcMitmService, ShutdownSystem),
|
||||
MAKE_SERVICE_COMMAND_META(BpcMitmService, RebootSystem),
|
||||
};
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -98,7 +98,7 @@ Result FsSaveUtils::GetSaveDataTypeString(const char **out_str, u8 save_data_typ
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FsSaveUtils::GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 save_data_type, u64 title_id, u128 user_id, u64 save_id) {
|
||||
Result FsSaveUtils::GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 save_data_type, u64 program_id, u128 user_id, u64 save_id) {
|
||||
const char *space_id_str, *save_type_str;
|
||||
|
||||
/* Get space_id, save_data_type strings. */
|
||||
@@ -114,7 +114,7 @@ Result FsSaveUtils::GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 s
|
||||
space_id_str, save_type_str, save_id));
|
||||
} else {
|
||||
out_path_len = static_cast<size_t>(snprintf(out_path.str, sizeof(out_path.str), "/atmosphere/saves/sysnand/%s/%s/%016lx/%016lx%016lx",
|
||||
space_id_str, save_type_str, title_id, static_cast<u64>(user_id >> 64ul), static_cast<u64>(user_id)));
|
||||
space_id_str, save_type_str, program_id, static_cast<u64>(user_id >> 64ul), static_cast<u64>(user_id)));
|
||||
}
|
||||
if (out_path_len >= sizeof(out_path)) {
|
||||
/* TODO: Should we abort here? */
|
||||
+1
-1
@@ -25,5 +25,5 @@ class FsSaveUtils {
|
||||
static Result GetSaveDataSpaceIdString(const char **out_str, u8 space_id);
|
||||
static Result GetSaveDataTypeString(const char **out_str, u8 save_data_type);
|
||||
public:
|
||||
static Result GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 save_data_type, u64 title_id, u128 user_id, u64 save_id);
|
||||
static Result GetSaveDataDirectoryPath(FsPath &out_path, u8 space_id, u8 save_data_type, u64 program_id, u128 user_id, u64 save_id);
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2
-2
@@ -28,11 +28,11 @@ bool Boot0Storage::CanModifyBctPubks() {
|
||||
/* RCM bug patched. */
|
||||
/* Only allow NS to update the BCT pubks. */
|
||||
/* AutoRCM on a patched unit will cause a brick, so homebrew should NOT be allowed to write. */
|
||||
return this->title_id == ams::ncm::TitleId::Ns;
|
||||
return this->program_id == ams::ncm::ProgramId::Ns;
|
||||
} else {
|
||||
/* RCM bug unpatched. */
|
||||
/* Allow homebrew but not NS to update the BCT pubks. */
|
||||
return this->title_id != ams::ncm::TitleId::Ns;
|
||||
return this->program_id != ams::ncm::ProgramId::Ns;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -131,12 +131,12 @@ class Boot0Storage : public SectoredProxyStorage<0x200> {
|
||||
static constexpr u64 EksSize = 0x4000;
|
||||
static constexpr u64 EksEnd = EksStart + EksSize;
|
||||
private:
|
||||
ams::ncm::TitleId title_id;
|
||||
ams::ncm::ProgramId program_id;
|
||||
private:
|
||||
bool CanModifyBctPubks();
|
||||
public:
|
||||
Boot0Storage(FsStorage *s, ams::ncm::TitleId t) : Base(s), title_id(t) { }
|
||||
Boot0Storage(FsStorage s, ams::ncm::TitleId t) : Base(s), title_id(t) { }
|
||||
Boot0Storage(FsStorage *s, ams::ncm::ProgramId t) : Base(s), program_id(t) { }
|
||||
Boot0Storage(FsStorage s, ams::ncm::ProgramId t) : Base(s), program_id(t) { }
|
||||
public:
|
||||
virtual Result Read(void *_buffer, size_t size, u64 offset) override;
|
||||
virtual Result Write(void *_buffer, size_t size, u64 offset) override;
|
||||
+4
-4
@@ -23,9 +23,9 @@
|
||||
|
||||
IStorage::~IStorage() = default;
|
||||
|
||||
LayeredRomFS::LayeredRomFS(std::shared_ptr<IROStorage> s_r, std::shared_ptr<IROStorage> f_r, u64 tid) : storage_romfs(s_r), file_romfs(f_r), title_id(tid) {
|
||||
LayeredRomFS::LayeredRomFS(std::shared_ptr<IROStorage> s_r, std::shared_ptr<IROStorage> f_r, u64 tid) : storage_romfs(s_r), file_romfs(f_r), program_id(tid) {
|
||||
/* Start building the new virtual romfs. */
|
||||
RomFSBuildContext build_ctx(this->title_id);
|
||||
RomFSBuildContext build_ctx(this->program_id);
|
||||
this->p_source_infos = std::shared_ptr<std::vector<RomFSSourceInfo>>(new std::vector<RomFSSourceInfo>(), [](std::vector<RomFSSourceInfo> *to_delete) {
|
||||
for (unsigned int i = 0; i < to_delete->size(); i++) {
|
||||
(*to_delete)[i].Cleanup();
|
||||
@@ -90,7 +90,7 @@ Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
|
||||
case RomFSDataSource::MetaData:
|
||||
{
|
||||
FsFile file;
|
||||
R_ASSERT(Utils::OpenSdFileForAtmosphere(this->title_id, ROMFS_METADATA_FILE_PATH, FS_OPEN_READ, &file));
|
||||
R_ASSERT(Utils::OpenSdFileForAtmosphere(this->program_id, ROMFS_METADATA_FILE_PATH, FS_OPEN_READ, &file));
|
||||
size_t out_read;
|
||||
R_ASSERT(fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, FS_READOPTION_NONE, &out_read));
|
||||
AMS_ASSERT(out_read == cur_read_size);
|
||||
@@ -100,7 +100,7 @@ Result LayeredRomFS::Read(void *buffer, size_t size, u64 offset) {
|
||||
case RomFSDataSource::LooseFile:
|
||||
{
|
||||
FsFile file;
|
||||
R_ASSERT(Utils::OpenRomFSSdFile(this->title_id, cur_source->loose_source_info.path, FS_OPEN_READ, &file));
|
||||
R_ASSERT(Utils::OpenRomFSSdFile(this->program_id, cur_source->loose_source_info.path, FS_OPEN_READ, &file));
|
||||
size_t out_read;
|
||||
R_ASSERT(fsFileRead(&file, (offset - cur_source->virtual_offset), (void *)((uintptr_t)buffer + read_so_far), cur_read_size, FS_READOPTION_NONE, &out_read));
|
||||
AMS_ASSERT(out_read == cur_read_size);
|
||||
+1
-1
@@ -30,7 +30,7 @@ class LayeredRomFS : public IROStorage {
|
||||
std::shared_ptr<IROStorage> storage_romfs;
|
||||
std::shared_ptr<IROStorage> file_romfs;
|
||||
/* Information about the merged RomFS. */
|
||||
u64 title_id;
|
||||
u64 program_id;
|
||||
std::shared_ptr<std::vector<RomFSSourceInfo>> p_source_infos;
|
||||
|
||||
public:
|
||||
File renamed without changes.
File renamed without changes.
+3
-3
@@ -28,7 +28,7 @@ void RomFSBuildContext::VisitDirectory(FsFileSystem *filesys, RomFSBuildDirector
|
||||
std::vector<RomFSBuildDirectoryContext *> child_dirs;
|
||||
|
||||
/* Open the current parent directory. */
|
||||
R_ASSERT(Utils::OpenRomFSDir(filesys, this->title_id, parent->path, &dir));
|
||||
R_ASSERT(Utils::OpenRomFSDir(filesys, this->program_id, parent->path, &dir));
|
||||
{
|
||||
ON_SCOPE_EXIT { fsDirClose(&dir); };
|
||||
|
||||
@@ -95,7 +95,7 @@ void RomFSBuildContext::MergeSdFiles() {
|
||||
if (!Utils::IsSdInitialized()) {
|
||||
return;
|
||||
}
|
||||
if (R_FAILED((Utils::OpenSdDirForAtmosphere(this->title_id, "/romfs", &dir)))) {
|
||||
if (R_FAILED((Utils::OpenSdDirForAtmosphere(this->program_id, "/romfs", &dir)))) {
|
||||
return;
|
||||
}
|
||||
fsDirClose(&dir);
|
||||
@@ -398,7 +398,7 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||
header->file_table_ofs = header->file_hash_table_ofs + header->file_hash_table_size;
|
||||
|
||||
/* Try to save metadata to the SD card, to save on memory space. */
|
||||
if (R_SUCCEEDED(Utils::SaveSdFileForAtmosphere(this->title_id, ROMFS_METADATA_FILE_PATH, metadata, metadata_size))) {
|
||||
if (R_SUCCEEDED(Utils::SaveSdFileForAtmosphere(this->program_id, ROMFS_METADATA_FILE_PATH, metadata, metadata_size))) {
|
||||
out_infos->emplace_back(header->dir_hash_table_ofs, metadata_size, RomFSDataSource::MetaData);
|
||||
std::free(metadata);
|
||||
} else {
|
||||
+2
-2
@@ -218,7 +218,7 @@ struct RomFSBuildFileContext {
|
||||
|
||||
class RomFSBuildContext {
|
||||
private:
|
||||
u64 title_id;
|
||||
u64 program_id;
|
||||
RomFSBuildDirectoryContext *root;
|
||||
std::map<char *, RomFSBuildDirectoryContext *, build_ctx_cmp> directories;
|
||||
std::map<char *, RomFSBuildFileContext *, build_ctx_cmp> files;
|
||||
@@ -239,7 +239,7 @@ class RomFSBuildContext {
|
||||
bool AddDirectory(RomFSBuildDirectoryContext *parent_dir_ctx, RomFSBuildDirectoryContext *dir_ctx, RomFSBuildDirectoryContext **out_dir_ctx);
|
||||
bool AddFile(RomFSBuildDirectoryContext *parent_dir_ctx, RomFSBuildFileContext *file_ctx);
|
||||
public:
|
||||
RomFSBuildContext(u64 tid) : title_id(tid) {
|
||||
RomFSBuildContext(u64 tid) : program_id(tid) {
|
||||
this->root = new RomFSBuildDirectoryContext({0});
|
||||
this->root->path = new char[1];
|
||||
this->root->path[0] = '\x00';
|
||||
File renamed without changes.
+29
-29
@@ -39,13 +39,13 @@
|
||||
static ams::os::Mutex g_StorageCacheLock;
|
||||
static std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_StorageCache;
|
||||
|
||||
static bool StorageCacheGetEntry(ams::ncm::TitleId title_id, std::shared_ptr<IStorageInterface> *out) {
|
||||
static bool StorageCacheGetEntry(ams::ncm::ProgramId program_id, std::shared_ptr<IStorageInterface> *out) {
|
||||
std::scoped_lock lock(g_StorageCacheLock);
|
||||
if (g_StorageCache.find(static_cast<u64>(title_id)) == g_StorageCache.end()) {
|
||||
if (g_StorageCache.find(static_cast<u64>(program_id)) == g_StorageCache.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto intf = g_StorageCache[static_cast<u64>(title_id)].lock();
|
||||
auto intf = g_StorageCache[static_cast<u64>(program_id)].lock();
|
||||
if (intf != nullptr) {
|
||||
*out = intf;
|
||||
return true;
|
||||
@@ -53,18 +53,18 @@ static bool StorageCacheGetEntry(ams::ncm::TitleId title_id, std::shared_ptr<ISt
|
||||
return false;
|
||||
}
|
||||
|
||||
static void StorageCacheSetEntry(ams::ncm::TitleId title_id, std::shared_ptr<IStorageInterface> *ptr) {
|
||||
static void StorageCacheSetEntry(ams::ncm::ProgramId program_id, std::shared_ptr<IStorageInterface> *ptr) {
|
||||
std::scoped_lock lock(g_StorageCacheLock);
|
||||
|
||||
/* Ensure we always use the cached copy if present. */
|
||||
if (g_StorageCache.find(static_cast<u64>(title_id)) != g_StorageCache.end()) {
|
||||
auto intf = g_StorageCache[static_cast<u64>(title_id)].lock();
|
||||
if (g_StorageCache.find(static_cast<u64>(program_id)) != g_StorageCache.end()) {
|
||||
auto intf = g_StorageCache[static_cast<u64>(program_id)].lock();
|
||||
if (intf != nullptr) {
|
||||
*ptr = intf;
|
||||
}
|
||||
}
|
||||
|
||||
g_StorageCache[static_cast<u64>(title_id)] = *ptr;
|
||||
g_StorageCache[static_cast<u64>(program_id)] = *ptr;
|
||||
}
|
||||
|
||||
void FsMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx) {
|
||||
@@ -95,11 +95,11 @@ Result FsMitmService::OpenHblWebContentFileSystem(Out<std::shared_ptr<IFileSyste
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithPatch(Out<std::shared_ptr<IFileSystemInterface>> out_fs, u64 title_id, u32 filesystem_type) {
|
||||
Result FsMitmService::OpenFileSystemWithPatch(Out<std::shared_ptr<IFileSystemInterface>> out_fs, u64 program_id, u32 filesystem_type) {
|
||||
/* Check for eligibility. */
|
||||
{
|
||||
FsDir d;
|
||||
if (!Utils::IsWebAppletTid(static_cast<u64>(this->title_id)) || filesystem_type != FsFileSystemType_ContentManual || !Utils::IsHblTid(title_id) ||
|
||||
if (!Utils::IsWebAppletTid(static_cast<u64>(this->program_id)) || filesystem_type != FsFileSystemType_ContentManual || !Utils::IsHblTid(program_id) ||
|
||||
R_FAILED(Utils::OpenSdDir(AtmosphereHblWebContentDir, &d))) {
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
@@ -110,7 +110,7 @@ Result FsMitmService::OpenFileSystemWithPatch(Out<std::shared_ptr<IFileSystemInt
|
||||
/* TODO: Multiplex, overriding existing content with HBL content. */
|
||||
{
|
||||
FsFileSystem fs;
|
||||
if (R_SUCCEEDED(fsOpenFileSystemWithPatchFwd(this->forward_service.get(), &fs, title_id, static_cast<FsFileSystemType>(filesystem_type)))) {
|
||||
if (R_SUCCEEDED(fsOpenFileSystemWithPatchFwd(this->forward_service.get(), &fs, program_id, static_cast<FsFileSystemType>(filesystem_type)))) {
|
||||
fsFsClose(&fs);
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
@@ -119,11 +119,11 @@ Result FsMitmService::OpenFileSystemWithPatch(Out<std::shared_ptr<IFileSystemInt
|
||||
return this->OpenHblWebContentFileSystem(out_fs);
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterface>> out_fs, InPointer<char> path, u64 title_id, u32 filesystem_type) {
|
||||
Result FsMitmService::OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterface>> out_fs, InPointer<char> path, u64 program_id, u32 filesystem_type) {
|
||||
/* Check for eligibility. */
|
||||
{
|
||||
FsDir d;
|
||||
if (!Utils::IsWebAppletTid(static_cast<u64>(this->title_id)) || filesystem_type != FsFileSystemType_ContentManual || !Utils::IsHblTid(title_id) ||
|
||||
if (!Utils::IsWebAppletTid(static_cast<u64>(this->program_id)) || filesystem_type != FsFileSystemType_ContentManual || !Utils::IsHblTid(program_id) ||
|
||||
R_FAILED(Utils::OpenSdDir(AtmosphereHblWebContentDir, &d))) {
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ Result FsMitmService::OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterf
|
||||
/* TODO: Multiplex, overriding existing content with HBL content. */
|
||||
{
|
||||
FsFileSystem fs;
|
||||
if (R_SUCCEEDED(fsOpenFileSystemWithIdFwd(this->forward_service.get(), &fs, title_id, static_cast<FsFileSystemType>(filesystem_type), path.pointer))) {
|
||||
if (R_SUCCEEDED(fsOpenFileSystemWithIdFwd(this->forward_service.get(), &fs, program_id, static_cast<FsFileSystemType>(filesystem_type), path.pointer))) {
|
||||
fsFsClose(&fs);
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ Result FsMitmService::OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterf
|
||||
|
||||
Result FsMitmService::OpenSdCardFileSystem(Out<std::shared_ptr<IFileSystemInterface>> out_fs) {
|
||||
/* We only care about redirecting this for NS/Emummc. */
|
||||
if (this->title_id != ams::ncm::TitleId::Ns) {
|
||||
if (this->program_id != ams::ncm::ProgramId::Ns) {
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
if (!IsEmummc()) {
|
||||
@@ -168,7 +168,7 @@ Result FsMitmService::OpenSdCardFileSystem(Out<std::shared_ptr<IFileSystemInterf
|
||||
|
||||
Result FsMitmService::OpenSaveDataFileSystem(Out<std::shared_ptr<IFileSystemInterface>> out_fs, u8 space_id, FsSave save_struct) {
|
||||
bool should_redirect_saves = false;
|
||||
const bool has_redirect_save_flags = Utils::HasFlag(static_cast<u64>(this->title_id), "redirect_save");
|
||||
const bool has_redirect_save_flags = Utils::HasFlag(static_cast<u64>(this->program_id), "redirect_save");
|
||||
if (R_FAILED(Utils::GetSettingsItemBooleanValue("atmosphere", "fsmitm_redirect_saves_to_sd", &should_redirect_saves))) {
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
@@ -193,7 +193,7 @@ Result FsMitmService::OpenSaveDataFileSystem(Out<std::shared_ptr<IFileSystemInte
|
||||
|
||||
|
||||
/* Verify that we can open the save directory, and that it exists. */
|
||||
const u64 target_tid = save_struct.titleID == 0 ? static_cast<u64>(this->title_id) : save_struct.titleID;
|
||||
const u64 target_tid = save_struct.titleID == 0 ? static_cast<u64>(this->program_id) : save_struct.titleID;
|
||||
FsPath save_dir_path;
|
||||
R_TRY(FsSaveUtils::GetSaveDataDirectoryPath(save_dir_path, space_id, save_struct.saveDataType, target_tid, save_struct.userID, save_struct.saveID));
|
||||
|
||||
@@ -234,13 +234,13 @@ Result FsMitmService::OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> out
|
||||
FsStorage bis_storage;
|
||||
R_TRY(fsOpenBisStorageFwd(this->forward_service.get(), &bis_storage, bis_partition_id));
|
||||
|
||||
const bool is_sysmodule = ams::ncm::IsSystemTitleId(this->title_id);
|
||||
const bool has_bis_write_flag = Utils::HasFlag(static_cast<u64>(this->title_id), "bis_write");
|
||||
const bool has_cal0_read_flag = Utils::HasFlag(static_cast<u64>(this->title_id), "cal_read");
|
||||
const bool is_sysmodule = ams::ncm::IsSystemProgramId(this->program_id);
|
||||
const bool has_bis_write_flag = Utils::HasFlag(static_cast<u64>(this->program_id), "bis_write");
|
||||
const bool has_cal0_read_flag = Utils::HasFlag(static_cast<u64>(this->program_id), "cal_read");
|
||||
|
||||
/* Set output storage. */
|
||||
if (bis_partition_id == FsBisStorageId_Boot0) {
|
||||
out_storage.SetValue(std::make_shared<IStorageInterface>(new Boot0Storage(bis_storage, this->title_id)));
|
||||
out_storage.SetValue(std::make_shared<IStorageInterface>(new Boot0Storage(bis_storage, this->program_id)));
|
||||
} else if (bis_partition_id == FsBisStorageId_CalibrationBinary) {
|
||||
/* PRODINFO should *never* be writable. */
|
||||
if (is_sysmodule || has_cal0_read_flag) {
|
||||
@@ -254,7 +254,7 @@ Result FsMitmService::OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> out
|
||||
if (is_sysmodule || has_bis_write_flag) {
|
||||
/* Sysmodules should still be allowed to read and write. */
|
||||
out_storage.SetValue(std::make_shared<IStorageInterface>(new ProxyStorage(bis_storage)));
|
||||
} else if (Utils::IsHblTid(static_cast<u64>(this->title_id)) &&
|
||||
} else if (Utils::IsHblTid(static_cast<u64>(this->program_id)) &&
|
||||
((FsBisStorageId_BootConfigAndPackage2NormalMain <= bis_partition_id && bis_partition_id <= FsBisStorageId_BootConfigAndPackage2RepairSub) ||
|
||||
bis_partition_id == FsBisStorageId_Boot1)) {
|
||||
/* Allow HBL to write to boot1 (safe firm) + package2. */
|
||||
@@ -282,14 +282,14 @@ Result FsMitmService::OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStora
|
||||
}
|
||||
|
||||
/* If we don't have anything to modify, there's no sense in maintaining a copy of the metadata tables. */
|
||||
if (!Utils::HasSdRomfsContent(static_cast<u64>(this->title_id))) {
|
||||
if (!Utils::HasSdRomfsContent(static_cast<u64>(this->program_id))) {
|
||||
return ResultAtmosphereMitmShouldForwardToSession;
|
||||
}
|
||||
|
||||
/* Try to get from the cache. */
|
||||
{
|
||||
std::shared_ptr<IStorageInterface> cached_storage = nullptr;
|
||||
bool has_cache = StorageCacheGetEntry(this->title_id, &cached_storage);
|
||||
bool has_cache = StorageCacheGetEntry(this->program_id, &cached_storage);
|
||||
|
||||
if (has_cache) {
|
||||
if (out_storage.IsDomain()) {
|
||||
@@ -312,13 +312,13 @@ Result FsMitmService::OpenDataStorageByCurrentProcess(Out<std::shared_ptr<IStora
|
||||
std::shared_ptr<IStorageInterface> storage_to_cache = nullptr;
|
||||
/* TODO: Is there a sensible path that ends in ".romfs" we can use?" */
|
||||
FsFile data_file;
|
||||
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(static_cast<u64>(this->title_id), "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||
storage_to_cache = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), std::make_shared<ReadOnlyStorageAdapter>(new FileStorage(new ProxyFile(data_file))), static_cast<u64>(this->title_id)));
|
||||
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(static_cast<u64>(this->program_id), "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||
storage_to_cache = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), std::make_shared<ReadOnlyStorageAdapter>(new FileStorage(new ProxyFile(data_file))), static_cast<u64>(this->program_id)));
|
||||
} else {
|
||||
storage_to_cache = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), nullptr, static_cast<u64>(this->title_id)));
|
||||
storage_to_cache = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), nullptr, static_cast<u64>(this->program_id)));
|
||||
}
|
||||
|
||||
StorageCacheSetEntry(this->title_id, &storage_to_cache);
|
||||
StorageCacheSetEntry(this->program_id, &storage_to_cache);
|
||||
|
||||
out_storage.SetValue(std::move(storage_to_cache));
|
||||
if (out_storage.IsDomain()) {
|
||||
@@ -345,7 +345,7 @@ Result FsMitmService::OpenDataStorageByDataId(Out<std::shared_ptr<IStorageInterf
|
||||
/* Try to get from the cache. */
|
||||
{
|
||||
std::shared_ptr<IStorageInterface> cached_storage = nullptr;
|
||||
bool has_cache = StorageCacheGetEntry(ams::ncm::TitleId{data_id}, &cached_storage);
|
||||
bool has_cache = StorageCacheGetEntry(ams::ncm::ProgramId{data_id}, &cached_storage);
|
||||
|
||||
if (has_cache) {
|
||||
if (out_storage.IsDomain()) {
|
||||
@@ -374,7 +374,7 @@ Result FsMitmService::OpenDataStorageByDataId(Out<std::shared_ptr<IStorageInterf
|
||||
storage_to_cache = std::make_shared<IStorageInterface>(new LayeredRomFS(std::make_shared<ReadOnlyStorageAdapter>(new ProxyStorage(data_storage)), nullptr, data_id));
|
||||
}
|
||||
|
||||
StorageCacheSetEntry(ams::ncm::TitleId{data_id}, &storage_to_cache);
|
||||
StorageCacheSetEntry(ams::ncm::ProgramId{data_id}, &storage_to_cache);
|
||||
|
||||
out_storage.SetValue(std::move(storage_to_cache));
|
||||
if (out_storage.IsDomain()) {
|
||||
+8
-8
@@ -44,15 +44,15 @@ class FsMitmService : public IMitmServiceObject {
|
||||
bool has_initialized = false;
|
||||
bool should_override_contents;
|
||||
public:
|
||||
FsMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
if (Utils::HasSdDisableMitMFlag(static_cast<u64>(this->title_id))) {
|
||||
FsMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
if (Utils::HasSdDisableMitMFlag(static_cast<u64>(this->program_id))) {
|
||||
this->should_override_contents = false;
|
||||
} else {
|
||||
this->should_override_contents = (this->title_id >= ams::ncm::TitleId::ApplicationStart || Utils::HasSdMitMFlag(static_cast<u64>(this->title_id))) && Utils::HasOverrideButton(static_cast<u64>(this->title_id));
|
||||
this->should_override_contents = (this->program_id >= ams::ncm::ProgramId::ApplicationStart || Utils::HasSdMitMFlag(static_cast<u64>(this->program_id))) && Utils::HasOverrideButton(static_cast<u64>(this->program_id));
|
||||
}
|
||||
}
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::TitleId tid) {
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId tid) {
|
||||
/* Don't Mitm KIPs */
|
||||
if (pid < 0x50) {
|
||||
return false;
|
||||
@@ -62,11 +62,11 @@ class FsMitmService : public IMitmServiceObject {
|
||||
|
||||
/* TODO: intercepting everything seems to cause issues with sleep mode, for some reason. */
|
||||
/* Figure out why, and address it. */
|
||||
if (tid == ams::ncm::TitleId::AppletQlaunch || tid == ams::ncm::TitleId::AppletMaintenanceMenu) {
|
||||
if (tid == ams::ncm::ProgramId::AppletQlaunch || tid == ams::ncm::ProgramId::AppletMaintenanceMenu) {
|
||||
has_launched_qlaunch = true;
|
||||
}
|
||||
|
||||
return has_launched_qlaunch || tid == ams::ncm::TitleId::Ns || tid >= ams::ncm::TitleId::ApplicationStart || Utils::HasSdMitMFlag(static_cast<u64>(tid));
|
||||
return has_launched_qlaunch || tid == ams::ncm::ProgramId::Ns || tid >= ams::ncm::ProgramId::ApplicationStart || Utils::HasSdMitMFlag(static_cast<u64>(tid));
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
@@ -74,8 +74,8 @@ class FsMitmService : public IMitmServiceObject {
|
||||
Result OpenHblWebContentFileSystem(Out<std::shared_ptr<IFileSystemInterface>> &out);
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result OpenFileSystemWithPatch(Out<std::shared_ptr<IFileSystemInterface>> out, u64 title_id, u32 filesystem_type);
|
||||
Result OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterface>> out, InPointer<char> path, u64 title_id, u32 filesystem_type);
|
||||
Result OpenFileSystemWithPatch(Out<std::shared_ptr<IFileSystemInterface>> out, u64 program_id, u32 filesystem_type);
|
||||
Result OpenFileSystemWithId(Out<std::shared_ptr<IFileSystemInterface>> out, InPointer<char> path, u64 program_id, u32 filesystem_type);
|
||||
Result OpenSdCardFileSystem(Out<std::shared_ptr<IFileSystemInterface>> out);
|
||||
Result OpenSaveDataFileSystem(Out<std::shared_ptr<IFileSystemInterface>> out, u8 space_id, FsSave save_struct);
|
||||
Result OpenBisStorage(Out<std::shared_ptr<IStorageInterface>> out, u32 bis_partition_id);
|
||||
File renamed without changes.
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "../utils.hpp"
|
||||
|
||||
class HidMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
SetSupportedNpadStyleSet = 100,
|
||||
};
|
||||
private:
|
||||
bool should_set_system_ext = false;
|
||||
public:
|
||||
HidMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
~HidMitmService();
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId 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<u64>(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),
|
||||
};
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+4
-4
@@ -28,14 +28,14 @@ Result NsAmMitmService::GetApplicationContentPath(OutBuffer<u8> out_path, u64 ap
|
||||
return nsamGetApplicationContentPathFwd(this->forward_service.get(), out_path.buffer, out_path.num_elements, app_id, static_cast<FsStorageId>(storage_type));
|
||||
}
|
||||
|
||||
Result NsAmMitmService::ResolveApplicationContentPath(u64 title_id, u8 storage_type) {
|
||||
Result NsAmMitmService::ResolveApplicationContentPath(u64 program_id, u8 storage_type) {
|
||||
/* Always succeed for web applet asking about HBL. */
|
||||
if (Utils::IsWebAppletTid(static_cast<u64>(this->title_id)) && Utils::IsHblTid(title_id)) {
|
||||
nsamResolveApplicationContentPathFwd(this->forward_service.get(), title_id, static_cast<FsStorageId>(storage_type));
|
||||
if (Utils::IsWebAppletTid(static_cast<u64>(this->program_id)) && Utils::IsHblTid(program_id)) {
|
||||
nsamResolveApplicationContentPathFwd(this->forward_service.get(), program_id, static_cast<FsStorageId>(storage_type));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
return nsamResolveApplicationContentPathFwd(this->forward_service.get(), title_id, static_cast<FsStorageId>(storage_type));
|
||||
return nsamResolveApplicationContentPathFwd(this->forward_service.get(), program_id, static_cast<FsStorageId>(storage_type));
|
||||
}
|
||||
|
||||
Result NsAmMitmService::GetRunningApplicationProgramId(Out<u64> out_tid, u64 app_id) {
|
||||
+3
-3
@@ -28,11 +28,11 @@ class NsAmMitmService : public IMitmServiceObject {
|
||||
GetRunningApplicationProgramId = 92,
|
||||
};
|
||||
public:
|
||||
NsAmMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
NsAmMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::TitleId tid) {
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId tid) {
|
||||
/* We will mitm:
|
||||
* - web applets, to facilitate hbl web browser launching.
|
||||
*/
|
||||
@@ -44,7 +44,7 @@ class NsAmMitmService : public IMitmServiceObject {
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result GetApplicationContentPath(OutBuffer<u8> out_path, u64 app_id, u8 storage_type);
|
||||
Result ResolveApplicationContentPath(u64 title_id, u8 storage_type);
|
||||
Result ResolveApplicationContentPath(u64 program_id, u8 storage_type);
|
||||
Result GetRunningApplicationProgramId(Out<u64> out_tid, u64 app_id);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
File renamed without changes.
File renamed without changes.
+5
-5
@@ -29,7 +29,7 @@ Result NsWebMitmService::GetDocumentInterface(Out<std::shared_ptr<NsDocumentServ
|
||||
R_TRY(nsGetDocumentInterfaceFwd(this->forward_service.get(), &doc));
|
||||
|
||||
/* Set output interface. */
|
||||
out_intf.SetValue(std::move(std::make_shared<NsDocumentService>(static_cast<u64>(this->title_id), doc)));
|
||||
out_intf.SetValue(std::move(std::make_shared<NsDocumentService>(static_cast<u64>(this->program_id), doc)));
|
||||
if (out_intf.IsDomain()) {
|
||||
out_intf.ChangeObjectId(doc.s.object_id);
|
||||
}
|
||||
@@ -41,14 +41,14 @@ Result NsDocumentService::GetApplicationContentPath(OutBuffer<u8> out_path, u64
|
||||
return nswebGetApplicationContentPath(this->srv.get(), out_path.buffer, out_path.num_elements, app_id, static_cast<FsStorageId>(storage_type));
|
||||
}
|
||||
|
||||
Result NsDocumentService::ResolveApplicationContentPath(u64 title_id, u8 storage_type) {
|
||||
Result NsDocumentService::ResolveApplicationContentPath(u64 program_id, u8 storage_type) {
|
||||
/* Always succeed for web applet asking about HBL. */
|
||||
if (Utils::IsWebAppletTid(static_cast<u64>(this->title_id)) && Utils::IsHblTid(title_id)) {
|
||||
nswebResolveApplicationContentPath(this->srv.get(), title_id, static_cast<FsStorageId>(storage_type));
|
||||
if (Utils::IsWebAppletTid(static_cast<u64>(this->program_id)) && Utils::IsHblTid(program_id)) {
|
||||
nswebResolveApplicationContentPath(this->srv.get(), program_id, static_cast<FsStorageId>(storage_type));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
return nswebResolveApplicationContentPath(this->srv.get(), title_id, static_cast<FsStorageId>(storage_type));
|
||||
return nswebResolveApplicationContentPath(this->srv.get(), program_id, static_cast<FsStorageId>(storage_type));
|
||||
}
|
||||
|
||||
Result NsDocumentService::GetRunningApplicationProgramId(Out<u64> out_tid, u64 app_id) {
|
||||
+7
-7
@@ -30,18 +30,18 @@ class NsDocumentService : public IServiceObject {
|
||||
GetRunningApplicationProgramId = 92,
|
||||
};
|
||||
private:
|
||||
u64 title_id;
|
||||
u64 program_id;
|
||||
std::unique_ptr<NsDocumentInterface> srv;
|
||||
public:
|
||||
NsDocumentService(u64 t, NsDocumentInterface *s) : title_id(t), srv(s) {
|
||||
NsDocumentService(u64 t, NsDocumentInterface *s) : program_id(t), srv(s) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
NsDocumentService(u64 t, std::unique_ptr<NsDocumentInterface> s) : title_id(t), srv(std::move(s)) {
|
||||
NsDocumentService(u64 t, std::unique_ptr<NsDocumentInterface> s) : program_id(t), srv(std::move(s)) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
NsDocumentService(u64 t, NsDocumentInterface s) : title_id(t) {
|
||||
NsDocumentService(u64 t, NsDocumentInterface s) : program_id(t) {
|
||||
srv = std::make_unique<NsDocumentInterface>(s);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class NsDocumentService : public IServiceObject {
|
||||
private:
|
||||
/* Actual command API. */
|
||||
Result GetApplicationContentPath(OutBuffer<u8> out_path, u64 app_id, u8 storage_type);
|
||||
Result ResolveApplicationContentPath(u64 title_id, u8 storage_type);
|
||||
Result ResolveApplicationContentPath(u64 program_id, u8 storage_type);
|
||||
Result GetRunningApplicationProgramId(Out<u64> out_tid, u64 app_id);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
@@ -67,11 +67,11 @@ class NsWebMitmService : public IMitmServiceObject {
|
||||
GetDocumentInterface = 7999,
|
||||
};
|
||||
public:
|
||||
NsWebMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
NsWebMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::TitleId tid) {
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId tid) {
|
||||
/* We will mitm:
|
||||
* - web applets, to facilitate hbl web browser launching.
|
||||
*/
|
||||
+3
-3
@@ -67,14 +67,14 @@ Result SetMitmService::EnsureLocale() {
|
||||
|
||||
if (!this->got_locale) {
|
||||
std::memset(&this->locale, 0xCC, sizeof(this->locale));
|
||||
if (this->title_id == ams::ncm::TitleId::Ns) {
|
||||
if (this->program_id == ams::ncm::ProgramId::Ns) {
|
||||
u64 app_pid = 0;
|
||||
u64 app_tid = 0;
|
||||
R_TRY(pmdmntGetApplicationPid(&app_pid));
|
||||
R_TRY(pminfoGetTitleId(&app_tid, app_pid));
|
||||
R_TRY(pminfoGetProgramId(&app_tid, app_pid));
|
||||
this->locale = Utils::GetTitleOverrideLocale(app_tid);
|
||||
} else {
|
||||
this->locale = Utils::GetTitleOverrideLocale(static_cast<u64>(this->title_id));
|
||||
this->locale = Utils::GetTitleOverrideLocale(static_cast<u64>(this->program_id));
|
||||
this->got_locale = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "../utils.hpp"
|
||||
|
||||
class SetMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetLanguageCode = 0,
|
||||
GetRegionCode = 4,
|
||||
};
|
||||
private:
|
||||
ams::os::Mutex lock;
|
||||
OverrideLocale locale;
|
||||
bool got_locale;
|
||||
public:
|
||||
SetMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
this->got_locale = false;
|
||||
}
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId tid) {
|
||||
/* Mitm all applications. */
|
||||
return tid == ams::ncm::ProgramId::Ns || ams::ncm::IsApplicationProgramId(tid);
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
|
||||
protected:
|
||||
static bool IsValidLanguageCode(u64 lang_code);
|
||||
static bool IsValidRegionCode(u32 region_code);
|
||||
|
||||
Result EnsureLocale();
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result GetLanguageCode(Out<u64> out_lang_code);
|
||||
Result GetRegionCode(Out<u32> out_region_code);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetLanguageCode),
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetRegionCode),
|
||||
};
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
+3
-3
@@ -32,7 +32,7 @@ void VersionManager::Initialize() {
|
||||
}
|
||||
|
||||
/* Mount firmware version data archive. */
|
||||
R_ASSERT(romfsMountFromDataArchive(static_cast<u64>(ams::ncm::TitleId::ArchiveSystemVersion), FsStorageId_NandSystem, "sysver"));
|
||||
R_ASSERT(romfsMountFromDataArchive(static_cast<u64>(ams::ncm::ProgramId::ArchiveSystemVersion), FsStorageId_NandSystem, "sysver"));
|
||||
{
|
||||
ON_SCOPE_EXIT { romfsUnmount("sysver"); };
|
||||
|
||||
@@ -65,11 +65,11 @@ void VersionManager::Initialize() {
|
||||
g_got_version = true;
|
||||
}
|
||||
|
||||
Result VersionManager::GetFirmwareVersion(ams::ncm::TitleId title_id, SetSysFirmwareVersion *out) {
|
||||
Result VersionManager::GetFirmwareVersion(ams::ncm::ProgramId program_id, SetSysFirmwareVersion *out) {
|
||||
VersionManager::Initialize();
|
||||
|
||||
/* Report atmosphere string to qlaunch, maintenance and nothing else. */
|
||||
if (title_id == ams::ncm::TitleId::AppletQlaunch || title_id == ams::ncm::TitleId::AppletMaintenanceMenu) {
|
||||
if (program_id == ams::ncm::ProgramId::AppletQlaunch || program_id == ams::ncm::ProgramId::AppletMaintenanceMenu) {
|
||||
*out = g_ams_fw_version;
|
||||
} else {
|
||||
*out = g_fw_version;
|
||||
+1
-1
@@ -21,5 +21,5 @@
|
||||
class VersionManager {
|
||||
public:
|
||||
static void Initialize();
|
||||
static Result GetFirmwareVersion(ams::ncm::TitleId title_id, SetSysFirmwareVersion *out);
|
||||
static Result GetFirmwareVersion(ams::ncm::ProgramId program_id, SetSysFirmwareVersion *out);
|
||||
};
|
||||
+2
-2
@@ -27,7 +27,7 @@ void SetSysMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext
|
||||
|
||||
Result SetSysMitmService::GetFirmwareVersion(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out) {
|
||||
/* Get firmware version from manager. */
|
||||
R_TRY(VersionManager::GetFirmwareVersion(this->title_id, out.pointer));
|
||||
R_TRY(VersionManager::GetFirmwareVersion(this->program_id, out.pointer));
|
||||
|
||||
/* GetFirmwareVersion sanitizes these fields. */
|
||||
out.pointer->revision_major = 0;
|
||||
@@ -36,7 +36,7 @@ Result SetSysMitmService::GetFirmwareVersion(OutPointerWithServerSize<SetSysFirm
|
||||
}
|
||||
|
||||
Result SetSysMitmService::GetFirmwareVersion2(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out) {
|
||||
return VersionManager::GetFirmwareVersion(this->title_id, out.pointer);
|
||||
return VersionManager::GetFirmwareVersion(this->program_id, out.pointer);
|
||||
}
|
||||
|
||||
Result SetSysMitmService::GetSettingsItemValueSize(Out<u64> out_size, InPointer<char> in_name, InPointer<char> in_key) {
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "setsys_shim.h"
|
||||
|
||||
class SetSysMitmService : public IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetFirmwareVersion = 3,
|
||||
GetFirmwareVersion2 = 4,
|
||||
GetSettingsItemValueSize = 37,
|
||||
GetSettingsItemValue = 38,
|
||||
};
|
||||
public:
|
||||
SetSysMitmService(std::shared_ptr<Service> s, u64 pid, ams::ncm::ProgramId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
static bool ShouldMitm(u64 pid, ams::ncm::ProgramId tid) {
|
||||
/* Mitm everything. */
|
||||
return true;
|
||||
}
|
||||
|
||||
static void PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx);
|
||||
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result GetFirmwareVersion(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
Result GetFirmwareVersion2(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
Result GetSettingsItemValueSize(Out<u64> out_size, InPointer<char> name, InPointer<char> key);
|
||||
Result GetSettingsItemValue(Out<u64> out_size, OutBuffer<u8> out_value, InPointer<char> name, InPointer<char> key);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetFirmwareVersion),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetFirmwareVersion2),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetSettingsItemValueSize),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetSettingsItemValue),
|
||||
};
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+41
-41
@@ -46,7 +46,7 @@ static OverrideKey g_default_override_key = {
|
||||
|
||||
struct HblOverrideConfig {
|
||||
OverrideKey override_key;
|
||||
u64 title_id;
|
||||
u64 program_id;
|
||||
bool override_any_app;
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ static HblOverrideConfig g_hbl_override_config = {
|
||||
.key_combination = KEY_R,
|
||||
.override_by_default = false
|
||||
},
|
||||
.title_id = static_cast<u64>(ams::ncm::TitleId::AppletPhotoViewer),
|
||||
.program_id = static_cast<u64>(ams::ncm::ProgramId::AppletPhotoViewer),
|
||||
.override_any_app = true
|
||||
};
|
||||
|
||||
@@ -220,13 +220,13 @@ void Utils::InitializeThreadFunc(void *args) {
|
||||
u64 read_entries;
|
||||
while (R_SUCCEEDED((fsDirRead(&titles_dir, 0, &read_entries, 1, &dir_entry))) && read_entries == 1) {
|
||||
if (strlen(dir_entry.name) == 0x10 && IsHexadecimal(dir_entry.name)) {
|
||||
u64 title_id = strtoul(dir_entry.name, NULL, 16);
|
||||
u64 program_id = strtoul(dir_entry.name, NULL, 16);
|
||||
char title_path[FS_MAX_PATH] = {0};
|
||||
strcpy(title_path, "/atmosphere/titles/");
|
||||
strcat(title_path, dir_entry.name);
|
||||
strcat(title_path, "/flags/fsmitm.flag");
|
||||
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, title_path, FS_OPEN_READ, &f))) {
|
||||
g_mitm_flagged_tids.push_back(title_id);
|
||||
g_mitm_flagged_tids.push_back(program_id);
|
||||
fsFileClose(&f);
|
||||
} else {
|
||||
/* TODO: Deprecate. */
|
||||
@@ -235,7 +235,7 @@ void Utils::InitializeThreadFunc(void *args) {
|
||||
strcat(title_path, dir_entry.name);
|
||||
strcat(title_path, "/fsmitm.flag");
|
||||
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, title_path, FS_OPEN_READ, &f))) {
|
||||
g_mitm_flagged_tids.push_back(title_id);
|
||||
g_mitm_flagged_tids.push_back(program_id);
|
||||
fsFileClose(&f);
|
||||
}
|
||||
}
|
||||
@@ -245,7 +245,7 @@ void Utils::InitializeThreadFunc(void *args) {
|
||||
strcat(title_path, dir_entry.name);
|
||||
strcat(title_path, "/flags/fsmitm_disable.flag");
|
||||
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, title_path, FS_OPEN_READ, &f))) {
|
||||
g_disable_mitm_flagged_tids.push_back(title_id);
|
||||
g_disable_mitm_flagged_tids.push_back(program_id);
|
||||
fsFileClose(&f);
|
||||
} else {
|
||||
/* TODO: Deprecate. */
|
||||
@@ -254,7 +254,7 @@ void Utils::InitializeThreadFunc(void *args) {
|
||||
strcat(title_path, dir_entry.name);
|
||||
strcat(title_path, "/fsmitm_disable.flag");
|
||||
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_filesystem, title_path, FS_OPEN_READ, &f))) {
|
||||
g_disable_mitm_flagged_tids.push_back(title_id);
|
||||
g_disable_mitm_flagged_tids.push_back(program_id);
|
||||
fsFileClose(&f);
|
||||
}
|
||||
}
|
||||
@@ -330,26 +330,26 @@ Result Utils::OpenSdFile(const char *fn, int flags, FsFile *out) {
|
||||
return fsFsOpenFile(&g_sd_filesystem, fn, flags, out);
|
||||
}
|
||||
|
||||
Result Utils::OpenSdFileForAtmosphere(u64 title_id, const char *fn, int flags, FsFile *out) {
|
||||
Result Utils::OpenSdFileForAtmosphere(u64 program_id, const char *fn, int flags, FsFile *out) {
|
||||
if (!IsSdInitialized()) {
|
||||
return ResultFsSdCardNotPresent;
|
||||
}
|
||||
|
||||
char path[FS_MAX_PATH];
|
||||
if (*fn == '/') {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx%s", title_id, fn);
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx%s", program_id, fn);
|
||||
} else {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/%s", title_id, fn);
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/%s", program_id, fn);
|
||||
}
|
||||
return fsFsOpenFile(&g_sd_filesystem, path, flags, out);
|
||||
}
|
||||
|
||||
Result Utils::OpenRomFSSdFile(u64 title_id, const char *fn, int flags, FsFile *out) {
|
||||
Result Utils::OpenRomFSSdFile(u64 program_id, const char *fn, int flags, FsFile *out) {
|
||||
if (!IsSdInitialized()) {
|
||||
return ResultFsSdCardNotPresent;
|
||||
}
|
||||
|
||||
return OpenRomFSFile(&g_sd_filesystem, title_id, fn, flags, out);
|
||||
return OpenRomFSFile(&g_sd_filesystem, program_id, fn, flags, out);
|
||||
}
|
||||
|
||||
Result Utils::OpenSdDir(const char *path, FsDir *out) {
|
||||
@@ -360,60 +360,60 @@ Result Utils::OpenSdDir(const char *path, FsDir *out) {
|
||||
return fsFsOpenDirectory(&g_sd_filesystem, path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, out);
|
||||
}
|
||||
|
||||
Result Utils::OpenSdDirForAtmosphere(u64 title_id, const char *path, FsDir *out) {
|
||||
Result Utils::OpenSdDirForAtmosphere(u64 program_id, const char *path, FsDir *out) {
|
||||
if (!IsSdInitialized()) {
|
||||
return ResultFsSdCardNotPresent;
|
||||
}
|
||||
|
||||
char safe_path[FS_MAX_PATH];
|
||||
if (*path == '/') {
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx%s", title_id, path);
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx%s", program_id, path);
|
||||
} else {
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx/%s", title_id, path);
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx/%s", program_id, path);
|
||||
}
|
||||
return fsFsOpenDirectory(&g_sd_filesystem, safe_path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, out);
|
||||
}
|
||||
|
||||
Result Utils::OpenRomFSSdDir(u64 title_id, const char *path, FsDir *out) {
|
||||
Result Utils::OpenRomFSSdDir(u64 program_id, const char *path, FsDir *out) {
|
||||
if (!IsSdInitialized()) {
|
||||
return ResultFsSdCardNotPresent;
|
||||
}
|
||||
|
||||
return OpenRomFSDir(&g_sd_filesystem, title_id, path, out);
|
||||
return OpenRomFSDir(&g_sd_filesystem, program_id, path, out);
|
||||
}
|
||||
|
||||
|
||||
Result Utils::OpenRomFSFile(FsFileSystem *fs, u64 title_id, const char *fn, int flags, FsFile *out) {
|
||||
Result Utils::OpenRomFSFile(FsFileSystem *fs, u64 program_id, const char *fn, int flags, FsFile *out) {
|
||||
char path[FS_MAX_PATH];
|
||||
if (*fn == '/') {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/romfs%s", title_id, fn);
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/romfs%s", program_id, fn);
|
||||
} else {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/romfs/%s", title_id, fn);
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/romfs/%s", program_id, fn);
|
||||
}
|
||||
return fsFsOpenFile(fs, path, flags, out);
|
||||
}
|
||||
|
||||
Result Utils::OpenRomFSDir(FsFileSystem *fs, u64 title_id, const char *path, FsDir *out) {
|
||||
Result Utils::OpenRomFSDir(FsFileSystem *fs, u64 program_id, const char *path, FsDir *out) {
|
||||
char safe_path[FS_MAX_PATH];
|
||||
if (*path == '/') {
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx/romfs%s", title_id, path);
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx/romfs%s", program_id, path);
|
||||
} else {
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx/romfs/%s", title_id, path);
|
||||
snprintf(safe_path, sizeof(safe_path), "/atmosphere/titles/%016lx/romfs/%s", program_id, path);
|
||||
}
|
||||
return fsFsOpenDirectory(fs, safe_path, FS_DIROPEN_DIRECTORY | FS_DIROPEN_FILE, out);
|
||||
}
|
||||
|
||||
bool Utils::HasSdRomfsContent(u64 title_id) {
|
||||
bool Utils::HasSdRomfsContent(u64 program_id) {
|
||||
/* Check for romfs.bin. */
|
||||
FsFile data_file;
|
||||
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(title_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||
if (R_SUCCEEDED(Utils::OpenSdFileForAtmosphere(program_id, "romfs.bin", FS_OPEN_READ, &data_file))) {
|
||||
fsFileClose(&data_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check for romfs folder with non-zero content. */
|
||||
FsDir dir;
|
||||
if (R_FAILED(Utils::OpenRomFSSdDir(title_id, "", &dir))) {
|
||||
if (R_FAILED(Utils::OpenRomFSSdDir(program_id, "", &dir))) {
|
||||
return false;
|
||||
}
|
||||
ON_SCOPE_EXIT {
|
||||
@@ -425,16 +425,16 @@ bool Utils::HasSdRomfsContent(u64 title_id) {
|
||||
return R_SUCCEEDED(fsDirRead(&dir, 0, &read_entries, 1, &dir_entry)) && read_entries == 1;
|
||||
}
|
||||
|
||||
Result Utils::SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, size_t size) {
|
||||
Result Utils::SaveSdFileForAtmosphere(u64 program_id, const char *fn, void *data, size_t size) {
|
||||
if (!IsSdInitialized()) {
|
||||
return ResultFsSdCardNotPresent;
|
||||
}
|
||||
|
||||
char path[FS_MAX_PATH];
|
||||
if (*fn == '/') {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx%s", title_id, fn);
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx%s", program_id, fn);
|
||||
} else {
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/%s", title_id, fn);
|
||||
snprintf(path, sizeof(path), "/atmosphere/titles/%016lx/%s", program_id, fn);
|
||||
}
|
||||
|
||||
/* Unconditionally create. */
|
||||
@@ -455,13 +455,13 @@ Result Utils::SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data,
|
||||
}
|
||||
|
||||
bool Utils::IsHblTid(u64 _tid) {
|
||||
const ams::ncm::TitleId tid{_tid};
|
||||
return (g_hbl_override_config.override_any_app && ams::ncm::IsApplicationTitleId(tid)) || (_tid == g_hbl_override_config.title_id);
|
||||
const ams::ncm::ProgramId tid{_tid};
|
||||
return (g_hbl_override_config.override_any_app && ams::ncm::IsApplicationProgramId(tid)) || (_tid == g_hbl_override_config.program_id);
|
||||
}
|
||||
|
||||
bool Utils::IsWebAppletTid(u64 _tid) {
|
||||
const ams::ncm::TitleId tid{_tid};
|
||||
return tid == ams::ncm::TitleId::AppletWeb || tid == ams::ncm::TitleId::AppletOfflineWeb || tid == ams::ncm::TitleId::AppletLoginShare || tid == ams::ncm::TitleId::AppletWifiWebAuth;
|
||||
const ams::ncm::ProgramId tid{_tid};
|
||||
return tid == ams::ncm::ProgramId::AppletWeb || tid == ams::ncm::ProgramId::AppletOfflineWeb || tid == ams::ncm::ProgramId::AppletLoginShare || tid == ams::ncm::ProgramId::AppletWifiWebAuth;
|
||||
}
|
||||
|
||||
bool Utils::HasTitleFlag(u64 tid, const char *flag) {
|
||||
@@ -550,7 +550,7 @@ static bool HasOverrideKey(OverrideKey *cfg) {
|
||||
|
||||
|
||||
bool Utils::HasOverrideButton(u64 tid) {
|
||||
if ((!ams::ncm::IsApplicationTitleId(ams::ncm::TitleId{tid})) || (!IsSdInitialized())) {
|
||||
if ((!ams::ncm::IsApplicationProgramId(ams::ncm::ProgramId{tid})) || (!IsSdInitialized())) {
|
||||
/* Disable button override disable for non-applications. */
|
||||
return true;
|
||||
}
|
||||
@@ -624,15 +624,15 @@ static OverrideKey ParseOverrideKey(const char *value) {
|
||||
static int FsMitmIniHandler(void *user, const char *section, const char *name, const char *value) {
|
||||
/* Taken and modified, with love, from Rajkosto's implementation. */
|
||||
if (strcasecmp(section, "hbl_config") == 0) {
|
||||
if (strcasecmp(name, "title_id") == 0) {
|
||||
if (strcasecmp(name, "program_id") == 0) {
|
||||
if (strcasecmp(value, "app") == 0) {
|
||||
/* DEPRECATED */
|
||||
g_hbl_override_config.override_any_app = true;
|
||||
g_hbl_override_config.title_id = 0;
|
||||
g_hbl_override_config.program_id = 0;
|
||||
} else {
|
||||
u64 override_tid = strtoul(value, NULL, 16);
|
||||
if (override_tid != 0) {
|
||||
g_hbl_override_config.title_id = override_tid;
|
||||
g_hbl_override_config.program_id = override_tid;
|
||||
}
|
||||
}
|
||||
} else if (strcasecmp(name, "override_key") == 0) {
|
||||
@@ -656,7 +656,7 @@ static int FsMitmIniHandler(void *user, const char *section, const char *name, c
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int FsMitmTitleSpecificIniHandler(void *user, const char *section, const char *name, const char *value) {
|
||||
static int FsMitmContentSpecificIniHandler(void *user, const char *section, const char *name, const char *value) {
|
||||
/* We'll output an override key when relevant. */
|
||||
OverrideKey *user_cfg = reinterpret_cast<OverrideKey *>(user);
|
||||
|
||||
@@ -690,14 +690,14 @@ OverrideKey Utils::GetTitleOverrideKey(u64 tid) {
|
||||
fsFileRead(&cfg_file, 0, config_buf, config_file_size, FS_READOPTION_NONE, &config_file_size);
|
||||
|
||||
/* Parse title ini. */
|
||||
ini_parse_string(config_buf, FsMitmTitleSpecificIniHandler, &cfg);
|
||||
ini_parse_string(config_buf, FsMitmContentSpecificIniHandler, &cfg);
|
||||
}
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static int FsMitmTitleSpecificLocaleIniHandler(void *user, const char *section, const char *name, const char *value) {
|
||||
static int FsMitmContentSpecificLocaleIniHandler(void *user, const char *section, const char *name, const char *value) {
|
||||
/* We'll output an override locale when relevant. */
|
||||
OverrideLocale *user_locale = reinterpret_cast<OverrideLocale *>(user);
|
||||
|
||||
@@ -748,7 +748,7 @@ OverrideLocale Utils::GetTitleOverrideLocale(u64 tid) {
|
||||
fsFileRead(&cfg_file, 0, config_buf, config_file_size, FS_READOPTION_NONE, &config_file_size);
|
||||
|
||||
/* Parse title ini. */
|
||||
ini_parse_string(config_buf, FsMitmTitleSpecificLocaleIniHandler, &locale);
|
||||
ini_parse_string(config_buf, FsMitmContentSpecificLocaleIniHandler, &locale);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,18 +79,18 @@ class Utils {
|
||||
static void WaitSdInitialized();
|
||||
|
||||
static Result OpenSdFile(const char *fn, int flags, FsFile *out);
|
||||
static Result OpenSdFileForAtmosphere(u64 title_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenRomFSSdFile(u64 title_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenSdFileForAtmosphere(u64 program_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenRomFSSdFile(u64 program_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenSdDir(const char *path, FsDir *out);
|
||||
static Result OpenSdDirForAtmosphere(u64 title_id, const char *path, FsDir *out);
|
||||
static Result OpenRomFSSdDir(u64 title_id, const char *path, FsDir *out);
|
||||
static Result OpenSdDirForAtmosphere(u64 program_id, const char *path, FsDir *out);
|
||||
static Result OpenRomFSSdDir(u64 program_id, const char *path, FsDir *out);
|
||||
|
||||
static Result OpenRomFSFile(FsFileSystem *fs, u64 title_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenRomFSDir(FsFileSystem *fs, u64 title_id, const char *path, FsDir *out);
|
||||
static Result OpenRomFSFile(FsFileSystem *fs, u64 program_id, const char *fn, int flags, FsFile *out);
|
||||
static Result OpenRomFSDir(FsFileSystem *fs, u64 program_id, const char *path, FsDir *out);
|
||||
|
||||
static Result SaveSdFileForAtmosphere(u64 title_id, const char *fn, void *data, size_t size);
|
||||
static Result SaveSdFileForAtmosphere(u64 program_id, const char *fn, void *data, size_t size);
|
||||
|
||||
static bool HasSdRomfsContent(u64 title_id);
|
||||
static bool HasSdRomfsContent(u64 program_id);
|
||||
|
||||
/* Delayed Initialization + MitM detection. */
|
||||
static void InitializeThreadFunc(void *args);
|
||||
@@ -162,7 +162,3 @@ extern "C" {
|
||||
void abort() {
|
||||
ams::AbortImpl();
|
||||
}
|
||||
|
||||
void *__cxa_allocate_ecxeption(size_t thrown_size) {
|
||||
abort();
|
||||
}
|
||||
@@ -147,24 +147,32 @@ namespace ams::sf::hipc {
|
||||
/* Iterate over the list of deferred sessions, and see if we can't do anything. */
|
||||
std::scoped_lock lk(this->deferred_session_mutex);
|
||||
|
||||
auto it = this->deferred_session_list.begin();
|
||||
while (it != this->deferred_session_list.end()) {
|
||||
ServerSession *session = static_cast<ServerSession *>(&*it);
|
||||
R_TRY_CATCH(this->ProcessForSession(session)) {
|
||||
R_CATCH(sf::ResultRequestDeferred) {
|
||||
/* Session is still deferred, so let's continue. */
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
R_CATCH(sf::impl::ResultRequestInvalidated) {
|
||||
/* Session is no longer deferred! */
|
||||
it = this->deferred_session_list.erase(it);
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
/* Undeferring a request may undefer another request. We'll continue looping until everything is stable. */
|
||||
bool needs_undefer_all = true;
|
||||
while (needs_undefer_all) {
|
||||
needs_undefer_all = false;
|
||||
|
||||
/* We succeeded! Remove from deferred list. */
|
||||
it = this->deferred_session_list.erase(it);
|
||||
auto it = this->deferred_session_list.begin();
|
||||
while (it != this->deferred_session_list.end()) {
|
||||
ServerSession *session = static_cast<ServerSession *>(&*it);
|
||||
R_TRY_CATCH(this->ProcessForSession(session)) {
|
||||
R_CATCH(sf::ResultRequestDeferred) {
|
||||
/* Session is still deferred, so let's continue. */
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
R_CATCH(sf::impl::ResultRequestInvalidated) {
|
||||
/* Session is no longer deferred! */
|
||||
it = this->deferred_session_list.erase(it);
|
||||
needs_undefer_all = true;
|
||||
continue;
|
||||
}
|
||||
} R_END_TRY_CATCH_WITH_ASSERT;
|
||||
|
||||
/* We succeeded! Remove from deferred list. */
|
||||
it = this->deferred_session_list.erase(it);
|
||||
needs_undefer_all = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user