WiiUPluginLoader/src/main.cpp

329 lines
11 KiB
C++

#include <string>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <malloc.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dynamic_libs/os_functions.h>
#include <dynamic_libs/gx2_functions.h>
#include <dynamic_libs/ax_functions.h>
#include <dynamic_libs/socket_functions.h>
#include <dynamic_libs/sys_functions.h>
#include <dynamic_libs/fs_functions.h>
#include <dynamic_libs/nn_nim_functions.h>
#include <dynamic_libs/vpad_functions.h>
#include <dynamic_libs/padscore_functions.h>
#include <dynamic_libs/proc_ui_functions.h>
#include <fs/FSUtils.h>
#include <fs/sd_fat_devoptab.h>
#include <utils/logger.h>
#include <utils/utils.h>
#include <utils/function_patcher.h>
#include <system/exception_handler.h>
#include <system/memory.h>
#include <kernel/kernel_utils.h>
#include <mykernel/kernel_utils.h>
#include "mymemory/memory_mapping.h"
#include "common/retain_vars.h"
#include "common/common.h"
#include "plugin/PluginLoader.h"
#include "plugin/PluginInformation.h"
#include "plugin/DynamicLinkingHelper.h"
#include <wups.h>
#include <iosuhax.h>
#include <fat.h>
#include <ntfs.h>
#include "main.h"
#include "utils.h"
#include "Application.h"
#include "patcher/function_patcher.h"
#include "patcher/hooks_patcher.h"
#include "patcher/hooks_patcher_static.h"
#include "plugin/dynamic_linking_defines.h"
#include "myutils/mem_utils.h"
#include "myutils/mocha.h"
#include "myutils/libntfs.h"
#include "myutils/libfat.h"
#include "myutils/overlay_helper.h"
#include "myutils/ConfigUtils.h"
#include "version.h"
#include "settings/CSettings.h"
static void ApplyPatchesAndCallHookStartingApp();
static void RestorePatches();
int32_t isInMiiMakerHBL();
void readAndPrintSegmentRegister(CThread *thread, void *arg);
extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
if(gAppStatus == 2) {
//"No, we don't want to patch stuff again.");
return EXIT_RELAUNCH_ON_LOAD;
}
InitOSFunctionPointers();
InitSocketFunctionPointers(); //For logging
InitSysFunctionPointers();
InitFSFunctionPointers();
InitGX2FunctionPointers();
InitSysFunctionPointers();
InitVPadFunctionPointers();
InitPadScoreFunctionPointers();
InitAXFunctionPointers();
InitProcUIFunctionPointers();
log_init();
DEBUG_FUNCTION_LINE("We have %d kb for plugins.\n",(PLUGIN_LOCATION_END_ADDRESS-getApplicationEndAddr())/1024);
//setup_os_exceptions();
DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION);
DEBUG_FUNCTION_LINE("Sizeof dyn_linking_relocation_data_t %d\n",sizeof(dyn_linking_relocation_data_t));
Init();
init_kernel_syscalls();
wups_init_kernel_syscalls();
if(!MemoryMapping::isMemoryMapped()) {
MemoryMapping::setupMemoryMapping();
}
gGameTitleID = OSGetTitleID();
g_vid_ownContextState = NULL;
g_vid_originalContextSave = NULL;
int32_t result = 0;
//Reset everything when were going back to the Mii Maker
if(isInMiiMakerHBL()) {
CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
// Restore patches as the patched functions could change.
RestorePatches();
DynamicLinkingHelper::getInstance()->clearAll();
//PluginLoader * pluginLoader = PluginLoader::getInstance();
//std::vector<PluginInformation *> pluginList = pluginLoader->getPluginInformation("sd:/wiiu/plugins/");
//pluginLoader->loadAndLinkPlugins(pluginList);
//pluginLoader->clearPluginInformation(pluginList);
//!*******************************************************************
//! Initialize heap memory *
//!*******************************************************************
DEBUG_FUNCTION_LINE("Initialize memory management\n");
memoryInitialize();
DEBUG_FUNCTION_LINE("Start main application\n");
result = Application::instance()->exec();
DEBUG_FUNCTION_LINE("Main application stopped result: %d\n",result);
DEBUG_FUNCTION_LINE("Application::destroyInstance\n");
Application::destroyInstance();
DEBUG_FUNCTION_LINE("Release memory\n");
memoryRelease();
CSettings::destroyInstance();
PluginLoader::destroyInstance();
MemoryUtils::init();
// Memory on custon heap is reset anyway so we don't need to free the image buffers.
memset((void*)&g_vid_main_cbuf,0,sizeof(g_vid_main_cbuf));
memset((void*)&g_vid_drcTex,0,sizeof(g_vid_drcTex));
memset((void*)&g_vid_tvTex,0,sizeof(g_vid_tvTex));
g_vid_originalContextSave = NULL;
g_vid_ownContextState = NULL;
g_NotInLoader = false;
} else {
g_NotInLoader = true;
}
DEBUG_FUNCTION_LINE("Patch own stuff\n");
PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static);
DEBUG_FUNCTION_LINE("Do relocations\n");
std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size());
if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)) {
OSFatal("fillRelocations failed.");
}
if(!isInMiiMakerHBL()) {
DEBUG_FUNCTION_LINE("Apply patches.\n");
ApplyPatchesAndCallHookStartingApp();
if(MemoryMapping::isMemoryMapped()) {
DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
readAndPrintSegmentRegister(NULL,NULL);
//MemoryMapping::readTestValuesFromMemory();
} else {
DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
DEBUG_FUNCTION_LINE("<---------------- COPY PASTE ME START-----------------> \n");
DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
DEBUG_FUNCTION_LINE("Mapping was't done. Running %016llX\n",gGameTitleID);
readAndPrintSegmentRegister(NULL,NULL);
DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
DEBUG_FUNCTION_LINE("<----------------- COPY PASTE ME END -----------------> \n");
DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
}
return EXIT_RELAUNCH_ON_LOAD;
}
if(result == APPLICATION_CLOSE_APPLY || result == APPLICATION_CLOSE_APPLY_MEMORY) {
CallHook(WUPS_LOADER_HOOK_INIT_VID_MEM);
CallHook(WUPS_LOADER_HOOK_INIT_KERNEL);
CallHook(WUPS_LOADER_HOOK_INIT_FS);
CallHook(WUPS_LOADER_HOOK_INIT_OVERLAY);
ConfigUtils::loadConfigFromSD();
CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN);
DEBUG_FUNCTION_LINE("Loading the system menu.\n");
DeInit();
SYSLaunchMenu();
return EXIT_RELAUNCH_ON_LOAD;
}
DEBUG_FUNCTION_LINE("Let's go to back to the Homebrew Launcher\n");
DEBUG_FUNCTION_LINE("Restoring the patched functions\n");
RestorePatches();
DEBUG_FUNCTION_LINE("Calling the plugin deinit hook\n");
//CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
DEBUG_FUNCTION_LINE("Unmounting SD/USB devices\n");
DeInit();
DEBUG_FUNCTION_LINE("Bye bye!\n");
return EXIT_SUCCESS;
}
void ApplyPatchesAndCallHookStartingApp() {
PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static);
PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks);
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
CallHookEx(WUPS_LOADER_HOOK_STARTING_APPLICATION,plugin_index);
new_PatchInvidualMethodHooks(&gbl_replacement_data.plugin_data[plugin_index]);
CallHookEx(WUPS_LOADER_HOOK_FUNCTIONS_PATCHED,plugin_index);
}
}
void DeInit() {
DeInit_SD_USB();
}
void RestorePatches() {
for(int32_t plugin_index=gbl_replacement_data.number_used_plugins-1; plugin_index>=0; plugin_index--) {
DEBUG_FUNCTION_LINE("Restoring function for plugin: %d\n",plugin_index);
new_RestoreInvidualInstructions(&gbl_replacement_data.plugin_data[plugin_index]);
}
RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks);
RestoreInvidualInstructions(method_hooks_hooks_static, method_hooks_size_hooks_static);
}
int32_t isInMiiMakerHBL() {
if (OSGetTitleID != 0 && (
OSGetTitleID() == 0x000500101004A200 || // mii maker eur
OSGetTitleID() == 0x000500101004A100 || // mii maker usa
OSGetTitleID() == 0x000500101004A000 ||// mii maker jpn
OSGetTitleID() == 0x0005000013374842)) {
return 1;
}
return 0;
}
void Init() {
memset(&tv_store,0,sizeof(tv_store));
memset(&drc_store,0,sizeof(drc_store));
DEBUG_FUNCTION_LINE("Mount SD partition\n");
Init_SD_USB();
}
void Init_SD_USB() {
int32_t res = IOSUHAX_Open(NULL);
if(res < 0) {
ExecuteIOSExploitWithDefaultConfig();
}
deleteDevTabsNames();
mount_fake();
gSDInitDone |= WUPS_SDUSB_MOUNTED_FAKE;
if(res < 0) {
DEBUG_FUNCTION_LINE("IOSUHAX_open failed\n");
if((res = mount_sd_fat("sd")) >= 0) {
DEBUG_FUNCTION_LINE("mount_sd_fat success\n");
gSDInitDone |= WUPS_SDUSB_MOUNTED_OS_SD;
} else {
DEBUG_FUNCTION_LINE("mount_sd_fat failed %d\n",res);
}
} else {
DEBUG_FUNCTION_LINE("Using IOSUHAX for SD/USB access\n");
gSDInitDone |= WUPS_SDUSB_LIBIOSU_LOADED;
int32_t ntfs_mounts = mountAllNTFS();
if(ntfs_mounts > 0) {
gSDInitDone |= WUPS_USB_MOUNTED_LIBNTFS;
}
if(mount_libfatAll() == 0) {
gSDInitDone |= WUPS_SD_MOUNTED_LIBFAT;
gSDInitDone |= WUPS_USB_MOUNTED_LIBFAT;
}
}
}
void DeInit_SD_USB() {
DEBUG_FUNCTION_LINE("Called this function.\n");
if(gSDInitDone & WUPS_SDUSB_MOUNTED_FAKE) {
DEBUG_FUNCTION_LINE("Unmounting fake\n");
unmount_fake();
gSDInitDone &= ~WUPS_SDUSB_MOUNTED_FAKE;
}
if(gSDInitDone & WUPS_SDUSB_MOUNTED_OS_SD) {
DEBUG_FUNCTION_LINE("Unmounting OS SD\n");
unmount_sd_fat("sd");
gSDInitDone &= ~WUPS_SDUSB_MOUNTED_OS_SD;
}
if(gSDInitDone & WUPS_SD_MOUNTED_LIBFAT) {
DEBUG_FUNCTION_LINE("Unmounting LIBFAT SD\n");
unmount_libfat("sd");
gSDInitDone &= ~WUPS_SD_MOUNTED_LIBFAT;
}
if(gSDInitDone & WUPS_USB_MOUNTED_LIBFAT) {
DEBUG_FUNCTION_LINE("Unmounting LIBFAT USB\n");
unmount_libfat("usb");
gSDInitDone &= ~WUPS_USB_MOUNTED_LIBFAT;
}
if(gSDInitDone & WUPS_USB_MOUNTED_LIBNTFS) {
DEBUG_FUNCTION_LINE("Unmounting LIBNTFS USB\n");
unmountAllNTFS();
gSDInitDone &= ~WUPS_USB_MOUNTED_LIBNTFS;
}
if(gSDInitDone & WUPS_SDUSB_LIBIOSU_LOADED) {
DEBUG_FUNCTION_LINE("Calling IOSUHAX_Close\n");
IOSUHAX_Close();
gSDInitDone &= ~WUPS_SDUSB_LIBIOSU_LOADED;
}
deleteDevTabsNames();
if(gSDInitDone != WUPS_SDUSB_MOUNTED_NONE) {
DEBUG_FUNCTION_LINE("WARNING. Some devices are still mounted.\n");
}
DEBUG_FUNCTION_LINE("Function end.\n");
}