mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Merge fs.mitm and set.mitm.
This commit is contained in:
parent
5f836aca6d
commit
e715197290
50 changed files with 426 additions and 630 deletions
2
Makefile
2
Makefile
|
@ -56,7 +56,7 @@ dist: all
|
||||||
cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches
|
||||||
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
||||||
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/exefs.nsp
|
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/exefs.nsp
|
||||||
cp stratosphere/set_mitm/set_mitm.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
|
cp stratosphere/eclct.stub/eclct.stub.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
|
||||||
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
cp troposphere/reboot_to_payload/reboot_to_payload.nro atmosphere-$(AMSVER)/switch/reboot_to_payload.nro
|
||||||
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags
|
mkdir -p atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags
|
||||||
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags/boot2.flag
|
touch atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/flags/boot2.flag
|
||||||
|
|
|
@ -83,7 +83,7 @@ ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||||
export TOPDIR := $(CURDIR)
|
export TOPDIR := $(CURDIR)
|
||||||
|
|
||||||
export KIPDIRS := $(AMS)/stratosphere/loader $(AMS)/stratosphere/pm $(AMS)/stratosphere/sm $(AMS)/stratosphere/boot $(AMS)/stratosphere/fs_mitm
|
export KIPDIRS := $(AMS)/stratosphere/loader $(AMS)/stratosphere/pm $(AMS)/stratosphere/sm $(AMS)/stratosphere/boot $(AMS)/stratosphere/ams_mitm
|
||||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
|
||||||
$(AMS)/exosphere $(AMS)/exosphere/lp0fw $(AMS)/exosphere/rebootstub \
|
$(AMS)/exosphere $(AMS)/exosphere/lp0fw $(AMS)/exosphere/rebootstub \
|
||||||
|
@ -94,7 +94,7 @@ export DEPSDIR := $(CURDIR)/$(BUILD)
|
||||||
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
|
||||||
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
|
||||||
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
|
||||||
KIPFILES := loader.kip pm.kip sm.kip fs_mitm.kip boot_100.kip boot_200.kip
|
KIPFILES := loader.kip pm.kip sm.kip ams_mitm.kip boot_100.kip boot_200.kip
|
||||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp $(KIPFILES)
|
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp $(KIPFILES)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
|
|
@ -556,7 +556,7 @@ static const kernel_info_t g_kernel_infos[] = {
|
||||||
},
|
},
|
||||||
{ /* 7.0.0. */
|
{ /* 7.0.0. */
|
||||||
.hash = {0xA2, 0x5E, 0x47, 0x0C, 0x8E, 0x6D, 0x2F, 0xD7, 0x5D, 0xAD, 0x24, 0xD7, 0xD8, 0x24, 0x34, 0xFB, 0xCD, 0x77, 0xBB, 0xE6, 0x66, 0x03, 0xCB, 0xAF, 0xAB, 0x85, 0x45, 0xA0, 0x91, 0xAF, 0x34, 0x25},
|
.hash = {0xA2, 0x5E, 0x47, 0x0C, 0x8E, 0x6D, 0x2F, 0xD7, 0x5D, 0xAD, 0x24, 0xD7, 0xD8, 0x24, 0x34, 0xFB, 0xCD, 0x77, 0xBB, 0xE6, 0x66, 0x03, 0xCB, 0xAF, 0xAB, 0x85, 0x45, 0xA0, 0x91, 0xAF, 0x34, 0x25},
|
||||||
.free_code_space_offset = 0x5FE80,
|
.free_code_space_offset = 0x5FEC0,
|
||||||
KERNEL_HOOKS(700)
|
KERNEL_HOOKS(700)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "loader_kip.h"
|
#include "loader_kip.h"
|
||||||
#include "pm_kip.h"
|
#include "pm_kip.h"
|
||||||
#include "sm_kip.h"
|
#include "sm_kip.h"
|
||||||
|
#include "ams_mitm_kip.h"
|
||||||
#include "boot_100_kip.h"
|
#include "boot_100_kip.h"
|
||||||
#include "boot_200_kip.h"
|
#include "boot_200_kip.h"
|
||||||
#undef u8
|
#undef u8
|
||||||
|
@ -43,13 +44,13 @@ static ini1_header_t *g_sd_files_ini1 = NULL;
|
||||||
static bool g_stratosphere_loader_enabled = true;
|
static bool g_stratosphere_loader_enabled = true;
|
||||||
static bool g_stratosphere_sm_enabled = true;
|
static bool g_stratosphere_sm_enabled = true;
|
||||||
static bool g_stratosphere_pm_enabled = true;
|
static bool g_stratosphere_pm_enabled = true;
|
||||||
static bool g_stratosphere_fs_mitm_enabled = true;
|
static bool g_stratosphere_ams_mitm_enabled = true;
|
||||||
static bool g_stratosphere_boot_enabled = false;
|
static bool g_stratosphere_boot_enabled = false;
|
||||||
|
|
||||||
extern const uint8_t boot_100_kip[], boot_200_kip[];
|
extern const uint8_t boot_100_kip[], boot_200_kip[];
|
||||||
extern const uint8_t loader_kip[], pm_kip[], sm_kip[], fs_mitm_kip[];
|
extern const uint8_t loader_kip[], pm_kip[], sm_kip[], ams_mitm_kip[];
|
||||||
extern const uint32_t boot_100_kip_size, boot_200_kip_size;
|
extern const uint32_t boot_100_kip_size, boot_200_kip_size;
|
||||||
extern const uint32_t loader_kip_size, pm_kip_size, sm_kip_size, fs_mitm_kip_size;
|
extern const uint32_t loader_kip_size, pm_kip_size, sm_kip_size, ams_mitm_kip_size;
|
||||||
|
|
||||||
/* GCC doesn't consider the size as const... we have to write it ourselves. */
|
/* GCC doesn't consider the size as const... we have to write it ourselves. */
|
||||||
|
|
||||||
|
@ -89,8 +90,8 @@ ini1_header_t *stratosphere_get_ini1(uint32_t target_firmware) {
|
||||||
num_processes++;
|
num_processes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_stratosphere_fs_mitm_enabled) {
|
if (g_stratosphere_ams_mitm_enabled) {
|
||||||
size += fs_mitm_kip_size;
|
size += ams_mitm_kip_size;
|
||||||
num_processes++;
|
num_processes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,9 +129,9 @@ ini1_header_t *stratosphere_get_ini1(uint32_t target_firmware) {
|
||||||
data += sm_kip_size;
|
data += sm_kip_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_stratosphere_fs_mitm_enabled) {
|
if (g_stratosphere_ams_mitm_enabled) {
|
||||||
memcpy(data, fs_mitm_kip, fs_mitm_kip_size);
|
memcpy(data, ams_mitm_kip, ams_mitm_kip_size);
|
||||||
data += fs_mitm_kip_size;
|
data += ams_mitm_kip_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_stratosphere_boot_enabled) {
|
if (g_stratosphere_boot_enabled) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
MODULES := loader pm sm boot fs_mitm set_mitm creport fatal
|
MODULES := loader pm sm boot ams_mitm eclct.stub creport fatal
|
||||||
|
|
||||||
SUBFOLDERS := libstratosphere $(MODULES)
|
SUBFOLDERS := libstratosphere $(MODULES)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ endif
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := $(notdir $(CURDIR))
|
TARGET := $(notdir $(CURDIR))
|
||||||
BUILD := build
|
BUILD := build
|
||||||
SOURCES := source
|
SOURCES := source source/fs_mitm source/set_mitm
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include ../../common/include
|
INCLUDES := include ../../common/include
|
||||||
EXEFS_SRC := exefs_src
|
EXEFS_SRC := exefs_src
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "fs.mitm",
|
"name": "ams.mitm",
|
||||||
"title_id": "0x010041544D530000",
|
"title_id": "0x010041544D530000",
|
||||||
"main_thread_stack_size": "0x20000",
|
"main_thread_stack_size": "0x20000",
|
||||||
"main_thread_priority": 43,
|
"main_thread_priority": 43,
|
|
@ -23,15 +23,15 @@
|
||||||
#include <atmosphere.h>
|
#include <atmosphere.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#include "setsys_mitm_service.hpp"
|
#include "amsmitm_modules.hpp"
|
||||||
#include "setsys_settings_items.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern u32 __start__;
|
extern u32 __start__;
|
||||||
|
|
||||||
u32 __nx_applet_type = AppletType_None;
|
u32 __nx_applet_type = AppletType_None;
|
||||||
|
|
||||||
#define INNER_HEAP_SIZE 0x50000
|
#define INNER_HEAP_SIZE 0x1000000
|
||||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||||
char nx_inner_heap[INNER_HEAP_SIZE];
|
char nx_inner_heap[INNER_HEAP_SIZE];
|
||||||
|
|
||||||
|
@ -61,9 +61,9 @@ void __appInit(void) {
|
||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
|
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = setsysInitialize();
|
rc = fsInitialize();
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
fatalSimple(rc);
|
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
||||||
|
@ -71,35 +71,26 @@ void __appInit(void) {
|
||||||
|
|
||||||
void __appExit(void) {
|
void __appExit(void) {
|
||||||
/* Cleanup services. */
|
/* Cleanup services. */
|
||||||
setsysExit();
|
fsExit();
|
||||||
smExit();
|
smExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SetSysManagerOptions {
|
|
||||||
static const size_t PointerBufferSize = 0x100;
|
|
||||||
static const size_t MaxDomains = 4;
|
|
||||||
static const size_t MaxDomainObjects = 0x100;
|
|
||||||
};
|
|
||||||
|
|
||||||
using SetMitmManager = WaitableManager<SetSysManagerOptions>;
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
consoleDebugInit(debugDevice_SVC);
|
consoleDebugInit(debugDevice_SVC);
|
||||||
|
HosThread initializer_thread;
|
||||||
|
|
||||||
/* Load settings from SD card. */
|
LaunchAllMitmModules();
|
||||||
SettingsItemManager::RefreshConfiguration();
|
|
||||||
|
|
||||||
/* TODO: What's a good timeout value to use here? */
|
if (R_FAILED(initializer_thread.Initialize(&Utils::InitializeThreadFunc, NULL, 0x4000, 0x15))) {
|
||||||
auto server_manager = new SetMitmManager(3);
|
/* TODO: Panic. */
|
||||||
|
}
|
||||||
|
if (R_FAILED(initializer_thread.Start())) {
|
||||||
|
/* TODO: Panic. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Create set:sys mitm. */
|
/* Wait for all mitm modules to end. */
|
||||||
AddMitmServerToManager<SetSysMitmService>(server_manager, "set:sys", 60);
|
WaitAllMitmModules();
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
|
||||||
server_manager->Process();
|
|
||||||
|
|
||||||
delete server_manager;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
60
stratosphere/ams_mitm/source/amsmitm_modules.cpp
Normal file
60
stratosphere/ams_mitm/source/amsmitm_modules.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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 <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include <cstring>
|
||||||
|
#include "debug.hpp"
|
||||||
|
|
||||||
|
#include "amsmitm_modules.hpp"
|
||||||
|
|
||||||
|
#include "fs_mitm/fsmitm_main.hpp"
|
||||||
|
#include "set_mitm/setmitm_main.hpp"
|
||||||
|
|
||||||
|
static HosThread g_module_threads[MitmModuleId_Count];
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
ThreadFunc main;
|
||||||
|
u32 priority;
|
||||||
|
u32 stack_size;
|
||||||
|
} g_module_definitions[MitmModuleId_Count] = {
|
||||||
|
{ &FsMitmMain, FsMitmPriority, FsMitmStackSize }, /* FsMitm */
|
||||||
|
{ &SetMitmMain, SetMitmPriority, SetMitmStackSize }, /* SetMitm */
|
||||||
|
};
|
||||||
|
|
||||||
|
void LaunchAllMitmModules() {
|
||||||
|
/* Create thread for each module. */
|
||||||
|
for (u32 i = 0; i < static_cast<u32>(MitmModuleId_Count); i++) {
|
||||||
|
const auto cur_module = &g_module_definitions[i];
|
||||||
|
if (R_FAILED(g_module_threads[i].Initialize(cur_module->main, nullptr, cur_module->stack_size, cur_module->priority))) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start thread for each module. */
|
||||||
|
for (u32 i = 0; i < static_cast<u32>(MitmModuleId_Count); i++) {
|
||||||
|
if (R_FAILED(g_module_threads[i].Start())) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaitAllMitmModules() {
|
||||||
|
/* Wait on thread for each module. */
|
||||||
|
for (u32 i = 0; i < static_cast<u32>(MitmModuleId_Count); i++) {
|
||||||
|
g_module_threads[i].Join();
|
||||||
|
}
|
||||||
|
}
|
28
stratosphere/ams_mitm/source/amsmitm_modules.hpp
Normal file
28
stratosphere/ams_mitm/source/amsmitm_modules.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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
|
||||||
|
|
||||||
|
enum MitmModuleId : u32 {
|
||||||
|
MitmModuleId_FsMitm = 0,
|
||||||
|
MitmModuleId_SetMitm = 1,
|
||||||
|
|
||||||
|
MitmModuleId_Count = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
void LaunchAllMitmModules();
|
||||||
|
|
||||||
|
void WaitAllMitmModules();
|
|
@ -19,7 +19,7 @@
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "fs_shim.h"
|
#include "fs_shim.h"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
enum FsIStorageCmd : u32 {
|
enum FsIStorageCmd : u32 {
|
||||||
FsIStorageCmd_Read = 0,
|
FsIStorageCmd_Read = 0,
|
|
@ -18,8 +18,8 @@
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
#include "fsmitm_layeredrom.hpp"
|
#include "fsmitm_layeredrom.hpp"
|
||||||
#include "fsmitm_utils.hpp"
|
#include "../utils.hpp"
|
||||||
#include "debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
IStorage::~IStorage() = default;
|
IStorage::~IStorage() = default;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "fsmitm_romstorage.hpp"
|
#include "fsmitm_romstorage.hpp"
|
||||||
#include "fsmitm_romfsbuild.hpp"
|
#include "fsmitm_romfsbuild.hpp"
|
||||||
#include "fsmitm_utils.hpp"
|
#include "../utils.hpp"
|
||||||
|
|
||||||
|
|
||||||
/* Represents a merged RomFS. */
|
/* Represents a merged RomFS. */
|
50
stratosphere/ams_mitm/source/fs_mitm/fsmitm_main.cpp
Normal file
50
stratosphere/ams_mitm/source/fs_mitm/fsmitm_main.cpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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 "fsmitm_main.hpp"
|
||||||
|
#include "fsmitm_service.hpp"
|
||||||
|
|
||||||
|
#include "../utils.hpp"
|
||||||
|
|
||||||
|
struct FsMitmManagerOptions {
|
||||||
|
static const size_t PointerBufferSize = 0x800;
|
||||||
|
static const size_t MaxDomains = 0x40;
|
||||||
|
static const size_t MaxDomainObjects = 0x4000;
|
||||||
|
};
|
||||||
|
using FsMitmManager = WaitableManager<FsMitmManagerOptions>;
|
||||||
|
|
||||||
|
void FsMitmMain(void *arg) {
|
||||||
|
/* Create server manager. */
|
||||||
|
auto server_manager = new FsMitmManager(5);
|
||||||
|
|
||||||
|
/* Create fsp-srv mitm. */
|
||||||
|
AddMitmServerToManager<FsMitmService>(server_manager, "fsp-srv", 61);
|
||||||
|
|
||||||
|
/* Loop forever, servicing our services. */
|
||||||
|
server_manager->Process();
|
||||||
|
|
||||||
|
delete server_manager;
|
||||||
|
}
|
||||||
|
|
29
stratosphere/ams_mitm/source/fs_mitm/fsmitm_main.hpp
Normal file
29
stratosphere/ams_mitm/source/fs_mitm/fsmitm_main.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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>
|
||||||
|
|
||||||
|
constexpr u32 FsMitmPriority = 43;
|
||||||
|
constexpr u32 FsMitmStackSize = 0x8000;
|
||||||
|
|
||||||
|
void FsMitmMain(void *arg);
|
|
@ -17,10 +17,10 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "fsmitm_utils.hpp"
|
#include "../utils.hpp"
|
||||||
#include "fsmitm_romfsbuild.hpp"
|
#include "fsmitm_romfsbuild.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
void RomFSBuildContext::VisitDirectory(FsFileSystem *filesys, RomFSBuildDirectoryContext *parent) {
|
void RomFSBuildContext::VisitDirectory(FsFileSystem *filesys, RomFSBuildDirectoryContext *parent) {
|
||||||
FsDir dir;
|
FsDir dir;
|
||||||
|
@ -367,7 +367,6 @@ void RomFSBuildContext::Build(std::vector<RomFSSourceInfo> *out_infos) {
|
||||||
cur_entry->name_size = name_size;
|
cur_entry->name_size = name_size;
|
||||||
memset(cur_entry->name, 0, (cur_entry->name_size + 3) & ~3);
|
memset(cur_entry->name, 0, (cur_entry->name_size + 3) & ~3);
|
||||||
memcpy(cur_entry->name, cur_dir->path + cur_dir->cur_path_ofs, name_size);
|
memcpy(cur_entry->name, cur_dir->path + cur_dir->cur_path_ofs, name_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete directories. */
|
/* Delete directories. */
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "fsmitm_romstorage.hpp"
|
#include "fsmitm_romstorage.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
#define ROMFS_ENTRY_EMPTY 0xFFFFFFFF
|
#define ROMFS_ENTRY_EMPTY 0xFFFFFFFF
|
||||||
#define ROMFS_FILEPARTITION_OFS 0x200
|
#define ROMFS_FILEPARTITION_OFS 0x200
|
|
@ -23,12 +23,12 @@
|
||||||
#include "fsmitm_service.hpp"
|
#include "fsmitm_service.hpp"
|
||||||
#include "fs_shim.h"
|
#include "fs_shim.h"
|
||||||
|
|
||||||
#include "fsmitm_utils.hpp"
|
#include "../utils.hpp"
|
||||||
#include "fsmitm_boot0storage.hpp"
|
#include "fsmitm_boot0storage.hpp"
|
||||||
#include "fsmitm_romstorage.hpp"
|
#include "fsmitm_romstorage.hpp"
|
||||||
#include "fsmitm_layeredrom.hpp"
|
#include "fsmitm_layeredrom.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
static HosMutex g_StorageCacheLock;
|
static HosMutex g_StorageCacheLock;
|
||||||
static std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_StorageCache;
|
static std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_StorageCache;
|
|
@ -18,7 +18,7 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "fs_istorage.hpp"
|
#include "fs_istorage.hpp"
|
||||||
#include "fsmitm_utils.hpp"
|
#include "../utils.hpp"
|
||||||
|
|
||||||
enum FspSrvCmd : u32 {
|
enum FspSrvCmd : u32 {
|
||||||
FspSrvCmd_SetCurrentProcess = 1,
|
FspSrvCmd_SetCurrentProcess = 1,
|
59
stratosphere/ams_mitm/source/set_mitm/setmitm_main.cpp
Normal file
59
stratosphere/ams_mitm/source/set_mitm/setmitm_main.cpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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 "setmitm_main.hpp"
|
||||||
|
#include "setsys_mitm_service.hpp"
|
||||||
|
#include "setsys_settings_items.hpp"
|
||||||
|
|
||||||
|
#include "../utils.hpp"
|
||||||
|
|
||||||
|
struct SetSysManagerOptions {
|
||||||
|
static const size_t PointerBufferSize = 0x100;
|
||||||
|
static const size_t MaxDomains = 4;
|
||||||
|
static const size_t MaxDomainObjects = 0x100;
|
||||||
|
};
|
||||||
|
|
||||||
|
using SetMitmManager = WaitableManager<SetSysManagerOptions>;
|
||||||
|
|
||||||
|
void SetMitmMain(void *arg) {
|
||||||
|
/* Wait for SD to initialize. */
|
||||||
|
Utils::WaitSdInitialized();
|
||||||
|
|
||||||
|
/* Load settings */
|
||||||
|
SettingsItemManager::LoadConfiguration();
|
||||||
|
|
||||||
|
/* Create server manager */
|
||||||
|
auto server_manager = new SetMitmManager(3);
|
||||||
|
|
||||||
|
/* Create set:sys mitm. */
|
||||||
|
AddMitmServerToManager<SetSysMitmService>(server_manager, "set:sys", 60);
|
||||||
|
|
||||||
|
/* Loop forever, servicing our services. */
|
||||||
|
server_manager->Process();
|
||||||
|
|
||||||
|
delete server_manager;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
29
stratosphere/ams_mitm/source/set_mitm/setmitm_main.hpp
Normal file
29
stratosphere/ams_mitm/source/set_mitm/setmitm_main.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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>
|
||||||
|
|
||||||
|
constexpr u32 SetMitmPriority = 43;
|
||||||
|
constexpr u32 SetMitmStackSize = 0x8000;
|
||||||
|
|
||||||
|
void SetMitmMain(void *arg);
|
|
@ -24,7 +24,8 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "setsys_settings_items.hpp"
|
#include "setsys_settings_items.hpp"
|
||||||
#include "ini.h"
|
#include "../utils.hpp"
|
||||||
|
#include "../ini.h"
|
||||||
|
|
||||||
struct SettingsItemValue {
|
struct SettingsItemValue {
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -241,32 +242,33 @@ static int SettingsItemIniHandler(void *user, const char *name, const char *key,
|
||||||
return R_SUCCEEDED(rc) ? 1 : 0;
|
return R_SUCCEEDED(rc) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsItemManager::RefreshConfiguration() {
|
void SettingsItemManager::LoadConfiguration() {
|
||||||
/* Mount the SD Card. */
|
/* Open file. */
|
||||||
Result rc = fsInitialize();
|
FsFile config_file;
|
||||||
if (R_SUCCEEDED(rc)) {
|
Result rc = Utils::OpenSdFile("/atmosphere/system_settings.ini", FS_OPEN_READ, &config_file);
|
||||||
rc = fsdevMountSdmc();
|
|
||||||
}
|
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* When we're done, we should stop talking to FS. */
|
|
||||||
ON_SCOPE_EXIT {
|
|
||||||
fsdevUnmountAll();
|
|
||||||
fsExit();
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Open, parse config file. */
|
|
||||||
{
|
|
||||||
FILE *config = fopen("sdmc:/atmosphere/system_settings.ini", "r");
|
|
||||||
if (config == NULL) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT { fclose(config); };
|
ON_SCOPE_EXIT {
|
||||||
|
fsFileClose(&config_file);
|
||||||
|
};
|
||||||
|
|
||||||
Result rc = 0;
|
/* Allocate buffer. */
|
||||||
ini_parse_file(config, SettingsItemIniHandler, &rc);
|
char *config_buf = new char[0x10000];
|
||||||
|
std::memset(config_buf, 0, 0x10000);
|
||||||
|
ON_SCOPE_EXIT {
|
||||||
|
delete config_buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Read from file. */
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
size_t actual_size;
|
||||||
|
rc = fsFileRead(&config_file, 0, config_buf, 0xFFFF, &actual_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
ini_parse_string(config_buf, SettingsItemIniHandler, &rc);
|
||||||
|
}
|
||||||
|
|
||||||
/* Report error if we encountered one. */
|
/* Report error if we encountered one. */
|
||||||
if (R_FAILED(rc) && !g_threw_fatal) {
|
if (R_FAILED(rc) && !g_threw_fatal) {
|
||||||
|
@ -274,7 +276,6 @@ void SettingsItemManager::RefreshConfiguration() {
|
||||||
g_fatal_thread.Initialize(&FatalThreadFunc, reinterpret_cast<void *>(rc), 0x1000, 49);
|
g_fatal_thread.Initialize(&FatalThreadFunc, reinterpret_cast<void *>(rc), 0x1000, 49);
|
||||||
g_fatal_thread.Start();
|
g_fatal_thread.Start();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result SettingsItemManager::GetValueSize(const char *name, const char *key, u64 *out_size) {
|
Result SettingsItemManager::GetValueSize(const char *name, const char *key, u64 *out_size) {
|
|
@ -30,7 +30,7 @@ class SettingsItemManager {
|
||||||
static Result ValidateKey(const char *key, size_t max_size);
|
static Result ValidateKey(const char *key, size_t max_size);
|
||||||
static Result ValidateKey(const char *key);
|
static Result ValidateKey(const char *key);
|
||||||
|
|
||||||
static void RefreshConfiguration();
|
static void LoadConfiguration();
|
||||||
static Result GetValueSize(const char *name, const char *key, u64 *out_size);
|
static Result GetValueSize(const char *name, const char *key, u64 *out_size);
|
||||||
static Result GetValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size);
|
static Result GetValue(const char *name, const char *key, void *out, size_t max_size, u64 *out_size);
|
||||||
};
|
};
|
|
@ -21,11 +21,13 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "fsmitm_utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
#include "sha256.h"
|
#include "sha256.h"
|
||||||
|
|
||||||
static FsFileSystem g_sd_filesystem = {0};
|
static FsFileSystem g_sd_filesystem = {0};
|
||||||
|
static HosSignal g_sd_signal;
|
||||||
|
|
||||||
static std::vector<u64> g_mitm_flagged_tids;
|
static std::vector<u64> g_mitm_flagged_tids;
|
||||||
static std::vector<u64> g_disable_mitm_flagged_tids;
|
static std::vector<u64> g_disable_mitm_flagged_tids;
|
||||||
static std::atomic_bool g_has_initialized = false;
|
static std::atomic_bool g_has_initialized = false;
|
||||||
|
@ -56,7 +58,7 @@ static bool IsHexadecimal(const char *str) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Utils::InitializeSdThreadFunc(void *args) {
|
void Utils::InitializeThreadFunc(void *args) {
|
||||||
/* Get required services. */
|
/* Get required services. */
|
||||||
Handle tmp_hnd = 0;
|
Handle tmp_hnd = 0;
|
||||||
static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"};
|
static const char * const required_active_services[] = {"pcv", "gpio", "pinmux", "psc:c"};
|
||||||
|
@ -180,19 +182,24 @@ void Utils::InitializeSdThreadFunc(void *args) {
|
||||||
|
|
||||||
Utils::RefreshConfiguration();
|
Utils::RefreshConfiguration();
|
||||||
|
|
||||||
|
/* Initialize set:sys. */
|
||||||
|
setsysInitialize();
|
||||||
|
|
||||||
|
/* Signal SD is initialized. */
|
||||||
g_has_initialized = true;
|
g_has_initialized = true;
|
||||||
|
g_sd_signal.Signal();
|
||||||
|
|
||||||
svcExitThread();
|
/* Initialize HID. */
|
||||||
}
|
{
|
||||||
|
|
||||||
void Utils::InitializeHidThreadFunc(void *args) {
|
|
||||||
while (R_FAILED(hidInitialize())) {
|
while (R_FAILED(hidInitialize())) {
|
||||||
svcSleepThread(1000ULL);
|
svcSleepThread(1000000ULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_has_hid_session = true;
|
g_has_hid_session = true;
|
||||||
|
|
||||||
hidExit();
|
hidExit();
|
||||||
|
}
|
||||||
|
|
||||||
svcExitThread();
|
svcExitThread();
|
||||||
}
|
}
|
||||||
|
@ -201,6 +208,10 @@ bool Utils::IsSdInitialized() {
|
||||||
return g_has_initialized;
|
return g_has_initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::WaitSdInitialized() {
|
||||||
|
g_sd_signal.Wait();
|
||||||
|
}
|
||||||
|
|
||||||
bool Utils::IsHidAvailable() {
|
bool Utils::IsHidAvailable() {
|
||||||
return g_has_hid_session;
|
return g_has_hid_session;
|
||||||
}
|
}
|
|
@ -40,6 +40,7 @@ enum BisStorageId : u32 {
|
||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
static bool IsSdInitialized();
|
static bool IsSdInitialized();
|
||||||
|
static void WaitSdInitialized();
|
||||||
|
|
||||||
static Result OpenSdFile(const char *fn, int flags, FsFile *out);
|
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 OpenSdFileForAtmosphere(u64 title_id, const char *fn, int flags, FsFile *out);
|
||||||
|
@ -55,8 +56,8 @@ class Utils {
|
||||||
|
|
||||||
static bool HasSdRomfsContent(u64 title_id);
|
static bool HasSdRomfsContent(u64 title_id);
|
||||||
|
|
||||||
/* SD card Initialization + MitM detection. */
|
/* Delayed Initialization + MitM detection. */
|
||||||
static void InitializeSdThreadFunc(void *args);
|
static void InitializeThreadFunc(void *args);
|
||||||
|
|
||||||
static bool IsHblTid(u64 tid);
|
static bool IsHblTid(u64 tid);
|
||||||
|
|
||||||
|
@ -70,7 +71,6 @@ class Utils {
|
||||||
|
|
||||||
|
|
||||||
static bool IsHidAvailable();
|
static bool IsHidAvailable();
|
||||||
static void InitializeHidThreadFunc(void *args);
|
|
||||||
static Result GetKeysDown(u64 *keys);
|
static Result GetKeysDown(u64 *keys);
|
||||||
static bool HasOverrideButton(u64 tid);
|
static bool HasOverrideButton(u64 tid);
|
||||||
private:
|
private:
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "set.mitm",
|
"name": "eclct.stun",
|
||||||
"title_id": "0x0100000000000032",
|
"title_id": "0x0100000000000032",
|
||||||
"title_id_range_min": "0x0100000000000032",
|
"title_id_range_min": "0x0100000000000032",
|
||||||
"title_id_range_max": "0x0100000000000032",
|
"title_id_range_max": "0x0100000000000032",
|
||||||
|
@ -14,16 +14,8 @@
|
||||||
"filesystem_access": {
|
"filesystem_access": {
|
||||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||||
},
|
},
|
||||||
"service_host": [
|
"service_host": [],
|
||||||
"set:sys"
|
"service_access": [],
|
||||||
],
|
|
||||||
"service_access": [
|
|
||||||
"fatal:u",
|
|
||||||
"fsp-srv",
|
|
||||||
"spl:",
|
|
||||||
"set:sys",
|
|
||||||
"fsp-srv"
|
|
||||||
],
|
|
||||||
"kernel_capabilities": [
|
"kernel_capabilities": [
|
||||||
{
|
{
|
||||||
"type": "kernel_flags",
|
"type": "kernel_flags",
|
65
stratosphere/eclct.stub/source/eclct_stub.cpp
Normal file
65
stratosphere/eclct.stub/source/eclct_stub.cpp
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern u32 __start__;
|
||||||
|
|
||||||
|
u32 __nx_applet_type = AppletType_None;
|
||||||
|
|
||||||
|
#define INNER_HEAP_SIZE 0x8000
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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) {
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
void __appExit(void) {
|
||||||
|
/* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 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 "fsmitm_service.hpp"
|
|
||||||
|
|
||||||
#include "fsmitm_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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) {
|
|
||||||
Result rc;
|
|
||||||
|
|
||||||
rc = smInitialize();
|
|
||||||
if (R_FAILED(rc)) {
|
|
||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = fsInitialize();
|
|
||||||
if (R_FAILED(rc)) {
|
|
||||||
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckAtmosphereVersion(CURRENT_ATMOSPHERE_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __appExit(void) {
|
|
||||||
/* Cleanup services. */
|
|
||||||
fsExit();
|
|
||||||
smExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FsMitmManagerOptions {
|
|
||||||
static const size_t PointerBufferSize = 0x800;
|
|
||||||
static const size_t MaxDomains = 0x40;
|
|
||||||
static const size_t MaxDomainObjects = 0x4000;
|
|
||||||
};
|
|
||||||
using FsMitmManager = WaitableManager<FsMitmManagerOptions>;
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
Thread sd_initializer_thread = {0};
|
|
||||||
Thread hid_initializer_thread = {0};
|
|
||||||
consoleDebugInit(debugDevice_SVC);
|
|
||||||
|
|
||||||
/* TODO: What's a good timeout value to use here? */
|
|
||||||
auto server_manager = new FsMitmManager(5);
|
|
||||||
|
|
||||||
/* Create fsp-srv mitm. */
|
|
||||||
AddMitmServerToManager<FsMitmService>(server_manager, "fsp-srv", 61);
|
|
||||||
|
|
||||||
if (R_FAILED(threadCreate(&sd_initializer_thread, &Utils::InitializeSdThreadFunc, NULL, 0x4000, 0x15, 0))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
if (R_FAILED(threadStart(&sd_initializer_thread))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (R_FAILED(threadCreate(&hid_initializer_thread, &Utils::InitializeHidThreadFunc, NULL, 0x4000, 0x15, 0))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
if (R_FAILED(threadStart(&hid_initializer_thread))) {
|
|
||||||
/* TODO: Panic. */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
|
||||||
server_manager->Process();
|
|
||||||
|
|
||||||
delete server_manager;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,269 +0,0 @@
|
||||||
/* inih -- simple .INI file parser
|
|
||||||
|
|
||||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
|
||||||
home page for more info:
|
|
||||||
|
|
||||||
https://github.com/benhoyt/inih
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "ini.h"
|
|
||||||
|
|
||||||
#if !INI_USE_STACK
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_SECTION 50
|
|
||||||
#define MAX_NAME 50
|
|
||||||
|
|
||||||
/* Used by ini_parse_string() to keep track of string parsing state. */
|
|
||||||
typedef struct {
|
|
||||||
const char* ptr;
|
|
||||||
size_t num_left;
|
|
||||||
} ini_parse_string_ctx;
|
|
||||||
|
|
||||||
/* Strip whitespace chars off end of given string, in place. Return s. */
|
|
||||||
static char* rstrip(char* s)
|
|
||||||
{
|
|
||||||
char* p = s + strlen(s);
|
|
||||||
while (p > s && isspace((unsigned char)(*--p)))
|
|
||||||
*p = '\0';
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return pointer to first non-whitespace char in given string. */
|
|
||||||
static char* lskip(const char* s)
|
|
||||||
{
|
|
||||||
while (*s && isspace((unsigned char)(*s)))
|
|
||||||
s++;
|
|
||||||
return (char*)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return pointer to first char (of chars) or inline comment in given string,
|
|
||||||
or pointer to null at end of string if neither found. Inline comment must
|
|
||||||
be prefixed by a whitespace character to register as a comment. */
|
|
||||||
static char* find_chars_or_comment(const char* s, const char* chars)
|
|
||||||
{
|
|
||||||
#if INI_ALLOW_INLINE_COMMENTS
|
|
||||||
int was_space = 0;
|
|
||||||
while (*s && (!chars || !strchr(chars, *s)) &&
|
|
||||||
!(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
|
|
||||||
was_space = isspace((unsigned char)(*s));
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
while (*s && (!chars || !strchr(chars, *s))) {
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return (char*)s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
|
|
||||||
static char* strncpy0(char* dest, const char* src, size_t size)
|
|
||||||
{
|
|
||||||
strncpy(dest, src, size - 1);
|
|
||||||
dest[size - 1] = '\0';
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See documentation in header file. */
|
|
||||||
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
|
|
||||||
void* user)
|
|
||||||
{
|
|
||||||
/* Uses a fair bit of stack (use heap instead if you need to) */
|
|
||||||
#if INI_USE_STACK
|
|
||||||
char line[INI_MAX_LINE];
|
|
||||||
int max_line = INI_MAX_LINE;
|
|
||||||
#else
|
|
||||||
char* line;
|
|
||||||
int max_line = INI_INITIAL_ALLOC;
|
|
||||||
#endif
|
|
||||||
#if INI_ALLOW_REALLOC
|
|
||||||
char* new_line;
|
|
||||||
int offset;
|
|
||||||
#endif
|
|
||||||
char section[MAX_SECTION] = "";
|
|
||||||
char prev_name[MAX_NAME] = "";
|
|
||||||
|
|
||||||
char* start;
|
|
||||||
char* end;
|
|
||||||
char* name;
|
|
||||||
char* value;
|
|
||||||
int lineno = 0;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
#if !INI_USE_STACK
|
|
||||||
line = (char*)malloc(INI_INITIAL_ALLOC);
|
|
||||||
if (!line) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if INI_HANDLER_LINENO
|
|
||||||
#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
|
|
||||||
#else
|
|
||||||
#define HANDLER(u, s, n, v) handler(u, s, n, v)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Scan through stream line by line */
|
|
||||||
while (reader(line, max_line, stream) != NULL) {
|
|
||||||
#if INI_ALLOW_REALLOC
|
|
||||||
offset = strlen(line);
|
|
||||||
while (offset == max_line - 1 && line[offset - 1] != '\n') {
|
|
||||||
max_line *= 2;
|
|
||||||
if (max_line > INI_MAX_LINE)
|
|
||||||
max_line = INI_MAX_LINE;
|
|
||||||
new_line = realloc(line, max_line);
|
|
||||||
if (!new_line) {
|
|
||||||
free(line);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
line = new_line;
|
|
||||||
if (reader(line + offset, max_line - offset, stream) == NULL)
|
|
||||||
break;
|
|
||||||
if (max_line >= INI_MAX_LINE)
|
|
||||||
break;
|
|
||||||
offset += strlen(line + offset);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lineno++;
|
|
||||||
|
|
||||||
start = line;
|
|
||||||
#if INI_ALLOW_BOM
|
|
||||||
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
|
|
||||||
(unsigned char)start[1] == 0xBB &&
|
|
||||||
(unsigned char)start[2] == 0xBF) {
|
|
||||||
start += 3;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
start = lskip(rstrip(start));
|
|
||||||
|
|
||||||
if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
|
|
||||||
/* Start-of-line comment */
|
|
||||||
}
|
|
||||||
#if INI_ALLOW_MULTILINE
|
|
||||||
else if (*prev_name && *start && start > line) {
|
|
||||||
/* Non-blank line with leading whitespace, treat as continuation
|
|
||||||
of previous name's value (as per Python configparser). */
|
|
||||||
if (!HANDLER(user, section, prev_name, start) && !error)
|
|
||||||
error = lineno;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (*start == '[') {
|
|
||||||
/* A "[section]" line */
|
|
||||||
end = find_chars_or_comment(start + 1, "]");
|
|
||||||
if (*end == ']') {
|
|
||||||
*end = '\0';
|
|
||||||
strncpy0(section, start + 1, sizeof(section));
|
|
||||||
*prev_name = '\0';
|
|
||||||
}
|
|
||||||
else if (!error) {
|
|
||||||
/* No ']' found on section line */
|
|
||||||
error = lineno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*start) {
|
|
||||||
/* Not a comment, must be a name[=:]value pair */
|
|
||||||
end = find_chars_or_comment(start, "=:");
|
|
||||||
if (*end == '=' || *end == ':') {
|
|
||||||
*end = '\0';
|
|
||||||
name = rstrip(start);
|
|
||||||
value = end + 1;
|
|
||||||
#if INI_ALLOW_INLINE_COMMENTS
|
|
||||||
end = find_chars_or_comment(value, NULL);
|
|
||||||
if (*end)
|
|
||||||
*end = '\0';
|
|
||||||
#endif
|
|
||||||
value = lskip(value);
|
|
||||||
rstrip(value);
|
|
||||||
|
|
||||||
/* Valid name[=:]value pair found, call handler */
|
|
||||||
strncpy0(prev_name, name, sizeof(prev_name));
|
|
||||||
if (!HANDLER(user, section, name, value) && !error)
|
|
||||||
error = lineno;
|
|
||||||
}
|
|
||||||
else if (!error) {
|
|
||||||
/* No '=' or ':' found on name[=:]value line */
|
|
||||||
error = lineno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if INI_STOP_ON_FIRST_ERROR
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !INI_USE_STACK
|
|
||||||
free(line);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See documentation in header file. */
|
|
||||||
int ini_parse_file(FILE* file, ini_handler handler, void* user)
|
|
||||||
{
|
|
||||||
return ini_parse_stream((ini_reader)fgets, file, handler, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See documentation in header file. */
|
|
||||||
int ini_parse(const char* filename, ini_handler handler, void* user)
|
|
||||||
{
|
|
||||||
FILE* file;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
file = fopen(filename, "r");
|
|
||||||
if (!file)
|
|
||||||
return -1;
|
|
||||||
error = ini_parse_file(file, handler, user);
|
|
||||||
fclose(file);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* An ini_reader function to read the next line from a string buffer. This
|
|
||||||
is the fgets() equivalent used by ini_parse_string(). */
|
|
||||||
static char* ini_reader_string(char* str, int num, void* stream) {
|
|
||||||
ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
|
|
||||||
const char* ctx_ptr = ctx->ptr;
|
|
||||||
size_t ctx_num_left = ctx->num_left;
|
|
||||||
char* strp = str;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
if (ctx_num_left == 0 || num < 2)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while (num > 1 && ctx_num_left != 0) {
|
|
||||||
c = *ctx_ptr++;
|
|
||||||
ctx_num_left--;
|
|
||||||
*strp++ = c;
|
|
||||||
if (c == '\n')
|
|
||||||
break;
|
|
||||||
num--;
|
|
||||||
}
|
|
||||||
|
|
||||||
*strp = '\0';
|
|
||||||
ctx->ptr = ctx_ptr;
|
|
||||||
ctx->num_left = ctx_num_left;
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See documentation in header file. */
|
|
||||||
int ini_parse_string(const char* string, ini_handler handler, void* user) {
|
|
||||||
ini_parse_string_ctx ctx;
|
|
||||||
|
|
||||||
ctx.ptr = string;
|
|
||||||
ctx.num_left = strlen(string);
|
|
||||||
return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
|
|
||||||
user);
|
|
||||||
}
|
|
|
@ -226,7 +226,6 @@ void EmbeddedBoot2::Main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Launch set:mitm, wait for it. */
|
/* Launch set:mitm, wait for it. */
|
||||||
LaunchTitle(Boot2KnownTitleId::ams_set_mitm, FsStorageId_None, 0, NULL);
|
|
||||||
WaitForMitm("set:sys");
|
WaitForMitm("set:sys");
|
||||||
|
|
||||||
/* Launch usb. */
|
/* Launch usb. */
|
||||||
|
|
|
@ -1,130 +0,0 @@
|
||||||
/* inih -- simple .INI file parser
|
|
||||||
|
|
||||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
|
||||||
home page for more info:
|
|
||||||
|
|
||||||
https://github.com/benhoyt/inih
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __INI_H__
|
|
||||||
#define __INI_H__
|
|
||||||
|
|
||||||
/* Make this header file easier to include in C++ code */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* Nonzero if ini_handler callback should accept lineno parameter. */
|
|
||||||
#ifndef INI_HANDLER_LINENO
|
|
||||||
#define INI_HANDLER_LINENO 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Typedef for prototype of handler function. */
|
|
||||||
#if INI_HANDLER_LINENO
|
|
||||||
typedef int (*ini_handler)(void* user, const char* section,
|
|
||||||
const char* name, const char* value,
|
|
||||||
int lineno);
|
|
||||||
#else
|
|
||||||
typedef int (*ini_handler)(void* user, const char* section,
|
|
||||||
const char* name, const char* value);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Typedef for prototype of fgets-style reader function. */
|
|
||||||
typedef char* (*ini_reader)(char* str, int num, void* stream);
|
|
||||||
|
|
||||||
/* Parse given INI-style file. May have [section]s, name=value pairs
|
|
||||||
(whitespace stripped), and comments starting with ';' (semicolon). Section
|
|
||||||
is "" if name=value pair parsed before any section heading. name:value
|
|
||||||
pairs are also supported as a concession to Python's configparser.
|
|
||||||
|
|
||||||
For each name=value pair parsed, call handler function with given user
|
|
||||||
pointer as well as section, name, and value (data only valid for duration
|
|
||||||
of handler call). Handler should return nonzero on success, zero on error.
|
|
||||||
|
|
||||||
Returns 0 on success, line number of first error on parse error (doesn't
|
|
||||||
stop on first error), -1 on file open error, or -2 on memory allocation
|
|
||||||
error (only when INI_USE_STACK is zero).
|
|
||||||
*/
|
|
||||||
int ini_parse(const char* filename, ini_handler handler, void* user);
|
|
||||||
|
|
||||||
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
|
|
||||||
close the file when it's finished -- the caller must do that. */
|
|
||||||
int ini_parse_file(FILE* file, ini_handler handler, void* user);
|
|
||||||
|
|
||||||
/* Same as ini_parse(), but takes an ini_reader function pointer instead of
|
|
||||||
filename. Used for implementing custom or string-based I/O (see also
|
|
||||||
ini_parse_string). */
|
|
||||||
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
|
|
||||||
void* user);
|
|
||||||
|
|
||||||
/* Same as ini_parse(), but takes a zero-terminated string with the INI data
|
|
||||||
instead of a file. Useful for parsing INI data from a network socket or
|
|
||||||
already in memory. */
|
|
||||||
int ini_parse_string(const char* string, ini_handler handler, void* user);
|
|
||||||
|
|
||||||
/* Nonzero to allow multi-line value parsing, in the style of Python's
|
|
||||||
configparser. If allowed, ini_parse() will call the handler with the same
|
|
||||||
name for each subsequent line parsed. */
|
|
||||||
#ifndef INI_ALLOW_MULTILINE
|
|
||||||
#define INI_ALLOW_MULTILINE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
|
|
||||||
the file. See http://code.google.com/p/inih/issues/detail?id=21 */
|
|
||||||
#ifndef INI_ALLOW_BOM
|
|
||||||
#define INI_ALLOW_BOM 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Chars that begin a start-of-line comment. Per Python configparser, allow
|
|
||||||
both ; and # comments at the start of a line by default. */
|
|
||||||
#ifndef INI_START_COMMENT_PREFIXES
|
|
||||||
#define INI_START_COMMENT_PREFIXES ";#"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Nonzero to allow inline comments (with valid inline comment characters
|
|
||||||
specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
|
|
||||||
Python 3.2+ configparser behaviour. */
|
|
||||||
#ifndef INI_ALLOW_INLINE_COMMENTS
|
|
||||||
#define INI_ALLOW_INLINE_COMMENTS 1
|
|
||||||
#endif
|
|
||||||
#ifndef INI_INLINE_COMMENT_PREFIXES
|
|
||||||
#define INI_INLINE_COMMENT_PREFIXES ";"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
|
|
||||||
#ifndef INI_USE_STACK
|
|
||||||
#define INI_USE_STACK 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Maximum line length for any line in INI file (stack or heap). Note that
|
|
||||||
this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
|
|
||||||
#ifndef INI_MAX_LINE
|
|
||||||
#define INI_MAX_LINE 200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Nonzero to allow heap line buffer to grow via realloc(), zero for a
|
|
||||||
fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
|
|
||||||
zero. */
|
|
||||||
#ifndef INI_ALLOW_REALLOC
|
|
||||||
#define INI_ALLOW_REALLOC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
|
|
||||||
is zero. */
|
|
||||||
#ifndef INI_INITIAL_ALLOC
|
|
||||||
#define INI_INITIAL_ALLOC 200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Stop parsing on first error (default is to keep parsing). */
|
|
||||||
#ifndef INI_STOP_ON_FIRST_ERROR
|
|
||||||
#define INI_STOP_ON_FIRST_ERROR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __INI_H__ */
|
|
Loading…
Reference in a new issue