[Loader] Code formatting and minor logging improvements.

This commit is contained in:
Maschell 2018-02-24 12:35:00 +01:00
parent 409527fb21
commit 55dd57d62f
32 changed files with 1094 additions and 1131 deletions

4
.gitignore vendored
View File

@ -8,7 +8,11 @@ plugins/*/bin/*
plugins/*/build/* plugins/*/build/*
loader/WiiUPluginLoader.cscope_file_list loader/WiiUPluginLoader.cscope_file_list
loader/WiiUPluginLoader.layout loader/WiiUPluginLoader.layout
loader/screenshots/*
release/* release/*
*.mod *.mod
*.cbp *.cbp
*.id*
*.nam
*.til

View File

@ -34,8 +34,7 @@ Application::Application()
, bgMusic(NULL) , bgMusic(NULL)
, video(NULL) , video(NULL)
, mainWindow(NULL) , mainWindow(NULL)
, exitCode(EXIT_RELAUNCH_ON_LOAD) , exitCode(EXIT_RELAUNCH_ON_LOAD) {
{
controller[0] = new VPadController(GuiTrigger::CHANNEL_1); controller[0] = new VPadController(GuiTrigger::CHANNEL_1);
controller[1] = new WPadController(GuiTrigger::CHANNEL_2); controller[1] = new WPadController(GuiTrigger::CHANNEL_2);
controller[2] = new WPadController(GuiTrigger::CHANNEL_3); controller[2] = new WPadController(GuiTrigger::CHANNEL_3);
@ -53,35 +52,35 @@ Application::Application()
exitApplication = false; exitApplication = false;
} }
Application::~Application(){ Application::~Application() {
log_printf("Application::~Application(line %d): Destroy music\n",__LINE__); DEBUG_FUNCTION_LINE("Destroy music\n");
delete bgMusic; delete bgMusic;
log_printf("Application::~Application(line %d): Destroy controller\n",__LINE__); DEBUG_FUNCTION_LINE("Destroy controller\n");
for(s32 i = 0; i < 5; i++) for(s32 i = 0; i < 5; i++)
delete controller[i]; delete controller[i];
//We may have to handle Asyncdelete in the Destructors. //We may have to handle Asyncdelete in the Destructors.
log_printf("Application::~Application(line %d): Destroy async deleter\n",__LINE__); DEBUG_FUNCTION_LINE("Destroy async deleter\n");
do{ do {
log_printf("Application::~Application(line %d): Triggering AsyncDeleter\n",__LINE__); DEBUG_FUNCTION_LINE("Triggering AsyncDeleter\n");
AsyncDeleter::triggerDeleteProcess(); AsyncDeleter::triggerDeleteProcess();
while(!AsyncDeleter::realListEmpty()){ while(!AsyncDeleter::realListEmpty()) {
os_usleep(1000); os_usleep(1000);
} }
}while(!AsyncDeleter::deleteListEmpty()); } while(!AsyncDeleter::deleteListEmpty());
AsyncDeleter::destroyInstance(); AsyncDeleter::destroyInstance();
log_printf("Application::~Application(line %d): Clear resources\n",__LINE__); DEBUG_FUNCTION_LINE("Clear resources\n");
Resources::Clear(); Resources::Clear();
log_printf("Application::~Application(line %d): Stop sound handler\n",__LINE__); DEBUG_FUNCTION_LINE("Stop sound handler\n");
SoundHandler::DestroyInstance(); SoundHandler::DestroyInstance();
} }
s32 Application::exec(){ s32 Application::exec() {
//! start main GX2 thread //! start main GX2 thread
resumeThread(); resumeThread();
//! now wait for thread to finish //! now wait for thread to finish
@ -90,14 +89,15 @@ s32 Application::exec(){
return exitCode; return exitCode;
} }
void Application::reloadUI(){ void Application::reloadUI() {
reloadUIflag = true; reloadUIflag = true;
} }
void Application::fadeOut(){ void Application::fadeOut() {
GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color){ 0, 0, 0, 255 }); GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color) {
0, 0, 0, 255
});
for(s32 i = 0; i < 255; i += 10) for(s32 i = 0; i < 255; i += 10) {
{
if(i > 255) if(i > 255)
i = 255; i = 255;
@ -140,48 +140,47 @@ void Application::fadeOut(){
video->drcEnable(false); video->drcEnable(false);
} }
void Application::executeThread(void){ void Application::executeThread(void) {
log_printf("Application::executeThread(line %d): Initialize video\n",__LINE__); DEBUG_FUNCTION_LINE("Initialize video\n");
video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_SINGLE); video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_SINGLE);
log_printf("Application::executeThread(line %d): Video size %i x %i\n",__LINE__, video->getTvWidth(), video->getTvHeight()); DEBUG_FUNCTION_LINE("Video size %i x %i\n", video->getTvWidth(), video->getTvHeight());
//! setup default Font //! setup default Font
log_printf("Application::executeThread(line %d): Initialize main font system\n",__LINE__); DEBUG_FUNCTION_LINE("Initialize main font system\n");
FreeTypeGX *fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true); FreeTypeGX *fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true);
GuiText::setPresetFont(fontSystem); GuiText::setPresetFont(fontSystem);
reloadUIflag = true; reloadUIflag = true;
if(bgMusic != NULL){ if(bgMusic != NULL) {
bgMusic->SetLoop(true); bgMusic->SetLoop(true);
bgMusic->SetVolume(50); bgMusic->SetVolume(50);
bgMusic->Stop(); //CHANG MEEEEEEEEEEEEEEEEEEE bgMusic->Stop(); //CHANG MEEEEEEEEEEEEEEEEEEE
} }
while(reloadUIflag){ while(reloadUIflag) {
reloadUIflag = false; reloadUIflag = false;
exitCode = EXIT_RELAUNCH_ON_LOAD; exitCode = EXIT_RELAUNCH_ON_LOAD;
log_printf("Application::executeThread(line %d): Initialize the language\n",__LINE__); DEBUG_FUNCTION_LINE("Initialize the language\n");
loadLanguageFromConfig(); loadLanguageFromConfig();
log_printf("Application::executeThread(line %d): Initialize main window\n",__LINE__); DEBUG_FUNCTION_LINE("Initialize main window\n");
mainWindow = MainWindow::getInstance(video->getTvWidth(), video->getTvHeight()); mainWindow = MainWindow::getInstance(video->getTvWidth(), video->getTvHeight());
log_printf("Application::executeThread(line %d): Entering main loop\n",__LINE__); DEBUG_FUNCTION_LINE("Entering main loop\n");
exitApplication = false; exitApplication = false;
//! main GX2 loop (60 Hz cycle with max priority on core 1) //! main GX2 loop (60 Hz cycle with max priority on core 1)
while(!exitApplication && !reloadUIflag){ while(!exitApplication && !reloadUIflag) {
//! Read out inputs //! Read out inputs
for(s32 i = 0; i < 5; i++) for(s32 i = 0; i < 5; i++) {
{
if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false) if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false)
continue; continue;
if(controller[i]->data.buttons_d & VPAD_BUTTON_PLUS){ if(controller[i]->data.buttons_d & VPAD_BUTTON_PLUS) {
exitCode = APPLICATION_CLOSE_APPLY; exitCode = APPLICATION_CLOSE_APPLY;
exitApplication = true; exitApplication = true;
} }
if(controller[i]->data.buttons_d & VPAD_BUTTON_HOME){ if(controller[i]->data.buttons_d & VPAD_BUTTON_HOME) {
exitCode = APPLICATION_CLOSE_MIIMAKER; exitCode = APPLICATION_CLOSE_MIIMAKER;
exitApplication = true; exitApplication = true;
} }
@ -228,8 +227,8 @@ void Application::executeThread(void){
delete video; delete video;
} }
void Application::loadLanguageFromConfig(){ void Application::loadLanguageFromConfig() {
if(!CSettings::getValueAsString(CSettings::AppLanguage).empty()){ if(!CSettings::getValueAsString(CSettings::AppLanguage).empty()) {
std::string languagePath = std::string(DEFAULT_LANG_PATH) + "/" + CSettings::getValueAsString(CSettings::AppLanguage) + std::string(LANGUAGE_FILE_EXT); std::string languagePath = std::string(DEFAULT_LANG_PATH) + "/" + CSettings::getValueAsString(CSettings::AppLanguage) + std::string(LANGUAGE_FILE_EXT);
gettextLoadLanguage(languagePath.c_str()); gettextLoadLanguage(languagePath.c_str());
} }

View File

@ -26,8 +26,7 @@
#define APPLICATION_CLOSE_APPLY 1 #define APPLICATION_CLOSE_APPLY 1
#define APPLICATION_CLOSE_MIIMAKER 2 #define APPLICATION_CLOSE_MIIMAKER 2
class Application : public CThread class Application : public CThread {
{
public: public:
static Application * instance() { static Application * instance() {
if(!applicationInstance) if(!applicationInstance)

View File

@ -1,8 +1,7 @@
#include <string.h> #include <string.h>
#include "main.h" #include "main.h"
int __entry_menu(int argc, char **argv) int __entry_menu(int argc, char **argv) {
{
//! ******************************************************************* //! *******************************************************************
//! * Jump to our application * //! * Jump to our application *
//! ******************************************************************* //! *******************************************************************

View File

@ -58,8 +58,8 @@ static void RestorePatches();
s32 isInMiiMakerHBL(); s32 isInMiiMakerHBL();
/* Entry point */ /* Entry point */
extern "C" int Menu_Main(int argc, char **argv){ extern "C" int Menu_Main(int argc, char **argv) {
if(gAppStatus == 2){ if(gAppStatus == 2) {
//"No, we don't want to patch stuff again."); //"No, we don't want to patch stuff again.");
return EXIT_RELAUNCH_ON_LOAD; return EXIT_RELAUNCH_ON_LOAD;
} }
@ -87,7 +87,7 @@ extern "C" int Menu_Main(int argc, char **argv){
s32 result = 0; s32 result = 0;
//Reset everything when were going back to the Mii Maker //Reset everything when were going back to the Mii Maker
if(isInMiiMakerHBL()){ if(isInMiiMakerHBL()) {
// Restore patches as the patched functions could change. // Restore patches as the patched functions could change.
RestorePatches(); RestorePatches();
@ -115,12 +115,12 @@ extern "C" int Menu_Main(int argc, char **argv){
DEBUG_FUNCTION_LINE("Apply patches.\n"); DEBUG_FUNCTION_LINE("Apply patches.\n");
ApplyPatches(); ApplyPatches();
if(!isInMiiMakerHBL()){ if(!isInMiiMakerHBL()) {
CallHook(WUPS_LOADER_HOOK_INIT_FUNCTION); CallHook(WUPS_LOADER_HOOK_INIT_FUNCTION);
return EXIT_RELAUNCH_ON_LOAD; return EXIT_RELAUNCH_ON_LOAD;
} }
if(result == APPLICATION_CLOSE_APPLY){ if(result == APPLICATION_CLOSE_APPLY) {
DEBUG_FUNCTION_LINE("Loading the system menu.\n"); DEBUG_FUNCTION_LINE("Loading the system menu.\n");
SYSLaunchMenu(); SYSLaunchMenu();
return EXIT_RELAUNCH_ON_LOAD; return EXIT_RELAUNCH_ON_LOAD;
@ -132,28 +132,28 @@ extern "C" int Menu_Main(int argc, char **argv){
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void ApplyPatches(){ void ApplyPatches() {
PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks); PatchInvidualMethodHooks(method_hooks_hooks, method_hooks_size_hooks, method_calls_hooks);
for(int plugin_index=0;plugin_index<gbl_replacement_data.number_used_plugins;plugin_index++){ for(int plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
new_PatchInvidualMethodHooks(&gbl_replacement_data.plugin_data[plugin_index]); new_PatchInvidualMethodHooks(&gbl_replacement_data.plugin_data[plugin_index]);
} }
} }
void CallHook(wups_loader_hook_type_t hook_type){ void CallHook(wups_loader_hook_type_t hook_type) {
for(int plugin_index=0;plugin_index<gbl_replacement_data.number_used_plugins;plugin_index++){ for(int plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index]; replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name); DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",plugin_data->plugin_name);
DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks); DEBUG_FUNCTION_LINE("Found hooks: %d\n",plugin_data->number_used_hooks);
for(int j=0;j<plugin_data->number_used_hooks;j++){ for(int j=0; j<plugin_data->number_used_hooks; j++) {
replacement_data_hook_t * hook_data = &plugin_data->hooks[j]; replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
if(hook_data->type == hook_type){ if(hook_data->type == hook_type) {
DEBUG_FUNCTION_LINE("Calling hook of type %d\n",hook_data->type); DEBUG_FUNCTION_LINE("Calling hook of type %d\n",hook_data->type);
void * func_ptr = hook_data->func_pointer; void * func_ptr = hook_data->func_pointer;
//TODO: Switch cases depending on arguments etc. //TODO: Switch cases depending on arguments etc.
// Adding arguments! // Adding arguments!
if(func_ptr != NULL){ if(func_ptr != NULL) {
if(hook_type == WUPS_LOADER_HOOK_INIT_FUNCTION){ if(hook_type == WUPS_LOADER_HOOK_INIT_FUNCTION) {
DEBUG_FUNCTION_LINE("Calling it! %08X\n",func_ptr); DEBUG_FUNCTION_LINE("Calling it! %08X\n",func_ptr);
wups_loader_init_args_t args; wups_loader_init_args_t args;
args.device_mounted = gSDInitDone; args.device_mounted = gSDInitDone;
@ -171,7 +171,7 @@ void CallHook(wups_loader_hook_type_t hook_type){
( (void (*)(wups_loader_init_args_t *))((unsigned int*)func_ptr) )(&args); ( (void (*)(wups_loader_init_args_t *))((unsigned int*)func_ptr) )(&args);
} }
}else{ } else {
DEBUG_FUNCTION_LINE("Was not defined\n"); DEBUG_FUNCTION_LINE("Was not defined\n");
} }
} }
@ -179,31 +179,30 @@ void CallHook(wups_loader_hook_type_t hook_type){
} }
} }
void DeInit(){ void DeInit() {
DeInit_SD_USB(); DeInit_SD_USB();
} }
void RestorePatches(){ void RestorePatches() {
for(int plugin_index=gbl_replacement_data.number_used_plugins-1;plugin_index>=0;plugin_index--){ for(int 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); DEBUG_FUNCTION_LINE("Restoring function for plugin: %d\n",plugin_index);
new_RestoreInvidualInstructions(&gbl_replacement_data.plugin_data[plugin_index]); new_RestoreInvidualInstructions(&gbl_replacement_data.plugin_data[plugin_index]);
} }
RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks); RestoreInvidualInstructions(method_hooks_hooks, method_hooks_size_hooks);
} }
s32 isInMiiMakerHBL(){ s32 isInMiiMakerHBL() {
if (OSGetTitleID != 0 && ( if (OSGetTitleID != 0 && (
OSGetTitleID() == 0x000500101004A200 || // mii maker eur OSGetTitleID() == 0x000500101004A200 || // mii maker eur
OSGetTitleID() == 0x000500101004A100 || // mii maker usa OSGetTitleID() == 0x000500101004A100 || // mii maker usa
OSGetTitleID() == 0x000500101004A000 ||// mii maker jpn OSGetTitleID() == 0x000500101004A000 ||// mii maker jpn
OSGetTitleID() == 0x0005000013374842)) OSGetTitleID() == 0x0005000013374842)) {
{ return 1;
return 1;
} }
return 0; return 0;
} }
void Init(){ void Init() {
memset(&tv_store,0,sizeof(tv_store)); memset(&tv_store,0,sizeof(tv_store));
memset(&drc_store,0,sizeof(drc_store)); memset(&drc_store,0,sizeof(drc_store));
DEBUG_FUNCTION_LINE("Mount SD partition\n"); DEBUG_FUNCTION_LINE("Mount SD partition\n");
@ -212,30 +211,30 @@ void Init(){
void Init_SD_USB() { void Init_SD_USB() {
int res = IOSUHAX_Open(NULL); int res = IOSUHAX_Open(NULL);
if(res < 0){ if(res < 0) {
ExecuteIOSExploitWithDefaultConfig(); ExecuteIOSExploitWithDefaultConfig();
} }
deleteDevTabsNames(); deleteDevTabsNames();
mount_fake(); mount_fake();
gSDInitDone |= WUPS_SDUSB_MOUNTED_FAKE; gSDInitDone |= WUPS_SDUSB_MOUNTED_FAKE;
if(res < 0){ if(res < 0) {
DEBUG_FUNCTION_LINE("IOSUHAX_open failed\n"); DEBUG_FUNCTION_LINE("IOSUHAX_open failed\n");
if((res = mount_sd_fat("sd")) >= 0){ if((res = mount_sd_fat("sd")) >= 0) {
DEBUG_FUNCTION_LINE("mount_sd_fat success\n"); DEBUG_FUNCTION_LINE("mount_sd_fat success\n");
gSDInitDone |= WUPS_SDUSB_MOUNTED_OS_SD; gSDInitDone |= WUPS_SDUSB_MOUNTED_OS_SD;
}else{ } else {
DEBUG_FUNCTION_LINE("mount_sd_fat failed %d\n",res); DEBUG_FUNCTION_LINE("mount_sd_fat failed %d\n",res);
} }
}else{ } else {
DEBUG_FUNCTION_LINE("Using IOSUHAX for SD/USB access\n"); DEBUG_FUNCTION_LINE("Using IOSUHAX for SD/USB access\n");
gSDInitDone |= WUPS_SDUSB_LIBIOSU_LOADED; gSDInitDone |= WUPS_SDUSB_LIBIOSU_LOADED;
int ntfs_mounts = mountAllNTFS(); int ntfs_mounts = mountAllNTFS();
if(ntfs_mounts > 0){ if(ntfs_mounts > 0) {
gSDInitDone |= WUPS_USB_MOUNTED_LIBNTFS; gSDInitDone |= WUPS_USB_MOUNTED_LIBNTFS;
} }
if(mount_libfatAll() == 0){ if(mount_libfatAll() == 0) {
gSDInitDone |= WUPS_SD_MOUNTED_LIBFAT; gSDInitDone |= WUPS_SD_MOUNTED_LIBFAT;
gSDInitDone |= WUPS_USB_MOUNTED_LIBFAT; gSDInitDone |= WUPS_USB_MOUNTED_LIBFAT;
} }
@ -243,46 +242,46 @@ void Init_SD_USB() {
DEBUG_FUNCTION_LINE("%08X\n",gSDInitDone); DEBUG_FUNCTION_LINE("%08X\n",gSDInitDone);
} }
void DeInit_SD_USB(){ void DeInit_SD_USB() {
DEBUG_FUNCTION_LINE("Called this function.\n"); DEBUG_FUNCTION_LINE("Called this function.\n");
if(gSDInitDone & WUPS_SDUSB_MOUNTED_FAKE){ if(gSDInitDone & WUPS_SDUSB_MOUNTED_FAKE) {
DEBUG_FUNCTION_LINE("Unmounting fake\n"); DEBUG_FUNCTION_LINE("Unmounting fake\n");
unmount_fake(); unmount_fake();
gSDInitDone &= ~WUPS_SDUSB_MOUNTED_FAKE; gSDInitDone &= ~WUPS_SDUSB_MOUNTED_FAKE;
} }
if(gSDInitDone & WUPS_SDUSB_MOUNTED_OS_SD){ if(gSDInitDone & WUPS_SDUSB_MOUNTED_OS_SD) {
DEBUG_FUNCTION_LINE("Unmounting OS SD\n"); DEBUG_FUNCTION_LINE("Unmounting OS SD\n");
unmount_sd_fat("sd"); unmount_sd_fat("sd");
gSDInitDone &= ~WUPS_SDUSB_MOUNTED_OS_SD; gSDInitDone &= ~WUPS_SDUSB_MOUNTED_OS_SD;
} }
if(gSDInitDone & WUPS_SD_MOUNTED_LIBFAT){ if(gSDInitDone & WUPS_SD_MOUNTED_LIBFAT) {
DEBUG_FUNCTION_LINE("Unmounting LIBFAT SD\n"); DEBUG_FUNCTION_LINE("Unmounting LIBFAT SD\n");
unmount_libfat("sd"); unmount_libfat("sd");
gSDInitDone &= ~WUPS_SD_MOUNTED_LIBFAT; gSDInitDone &= ~WUPS_SD_MOUNTED_LIBFAT;
} }
if(gSDInitDone & WUPS_USB_MOUNTED_LIBFAT){ if(gSDInitDone & WUPS_USB_MOUNTED_LIBFAT) {
DEBUG_FUNCTION_LINE("Unmounting LIBFAT USB\n"); DEBUG_FUNCTION_LINE("Unmounting LIBFAT USB\n");
unmount_libfat("usb"); unmount_libfat("usb");
gSDInitDone &= ~WUPS_USB_MOUNTED_LIBFAT; gSDInitDone &= ~WUPS_USB_MOUNTED_LIBFAT;
} }
if(gSDInitDone & WUPS_USB_MOUNTED_LIBNTFS){ if(gSDInitDone & WUPS_USB_MOUNTED_LIBNTFS) {
DEBUG_FUNCTION_LINE("Unmounting LIBNTFS USB\n"); DEBUG_FUNCTION_LINE("Unmounting LIBNTFS USB\n");
unmountAllNTFS(); unmountAllNTFS();
gSDInitDone &= ~WUPS_USB_MOUNTED_LIBNTFS; gSDInitDone &= ~WUPS_USB_MOUNTED_LIBNTFS;
} }
if(gSDInitDone & WUPS_SDUSB_LIBIOSU_LOADED){ if(gSDInitDone & WUPS_SDUSB_LIBIOSU_LOADED) {
DEBUG_FUNCTION_LINE("Calling IOSUHAX_Close\n"); DEBUG_FUNCTION_LINE("Calling IOSUHAX_Close\n");
IOSUHAX_Close(); IOSUHAX_Close();
gSDInitDone &= ~WUPS_SDUSB_LIBIOSU_LOADED; gSDInitDone &= ~WUPS_SDUSB_LIBIOSU_LOADED;
} }
deleteDevTabsNames(); deleteDevTabsNames();
if(gSDInitDone != WUPS_SDUSB_MOUNTED_NONE){ if(gSDInitDone != WUPS_SDUSB_MOUNTED_NONE) {
DEBUG_FUNCTION_LINE("WARNING. Some devices are still mounted.\n"); DEBUG_FUNCTION_LINE("WARNING. Some devices are still mounted.\n");
} }
DEBUG_FUNCTION_LINE("Function end.\n"); DEBUG_FUNCTION_LINE("Function end.\n");

View File

@ -29,8 +29,7 @@ MainWindow * MainWindow::instance = NULL;
MainWindow::MainWindow(s32 w, s32 h) MainWindow::MainWindow(s32 w, s32 h)
: width(w) : width(w)
, height(h) , height(h) {
{
for(s32 i = 0; i < 4; i++) { for(s32 i = 0; i < 4; i++) {
std::string filename = StringTools::strfmt("player%i_point.png", i+1); std::string filename = StringTools::strfmt("player%i_point.png", i+1);
pointerImgData[i] = Resources::GetImageData(filename.c_str()); pointerImgData[i] = Resources::GetImageData(filename.c_str());
@ -42,100 +41,80 @@ MainWindow::MainWindow(s32 w, s32 h)
SetupMainView(); SetupMainView();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow() {
{
while(!tvElements.empty()) while(!tvElements.empty()) {
{
delete tvElements[0]; delete tvElements[0];
remove(tvElements[0]); remove(tvElements[0]);
} }
while(!drcElements.empty()) while(!drcElements.empty()) {
{
delete drcElements[0]; delete drcElements[0];
remove(drcElements[0]); remove(drcElements[0]);
} }
for(s32 i = 0; i < 4; i++) for(s32 i = 0; i < 4; i++) {
{
delete pointerImg[i]; delete pointerImg[i];
Resources::RemoveImageData(pointerImgData[i]); Resources::RemoveImageData(pointerImgData[i]);
} }
} }
void MainWindow::updateEffects() void MainWindow::updateEffects() {
{
//! dont read behind the initial elements in case one was added //! dont read behind the initial elements in case one was added
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
drcElements[i]->updateEffects(); drcElements[i]->updateEffects();
} }
//! only update TV elements that are not updated yet because they are on DRC //! only update TV elements that are not updated yet because they are on DRC
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
u32 n; u32 n;
for(n = 0; (n < drcSize) && (n < drcElements.size()); n++) for(n = 0; (n < drcSize) && (n < drcElements.size()); n++) {
{
if(tvElements[i] == drcElements[n]) if(tvElements[i] == drcElements[n])
break; break;
} }
if(n == drcElements.size()) if(n == drcElements.size()) {
{
tvElements[i]->updateEffects(); tvElements[i]->updateEffects();
} }
} }
} }
void MainWindow::process() void MainWindow::process() {
{
//! dont read behind the initial elements in case one was added //! dont read behind the initial elements in case one was added
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
drcElements[i]->process(); drcElements[i]->process();
} }
//! only update TV elements that are not updated yet because they are on DRC //! only update TV elements that are not updated yet because they are on DRC
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
u32 n; u32 n;
for(n = 0; (n < drcSize) && (n < drcElements.size()); n++) for(n = 0; (n < drcSize) && (n < drcElements.size()); n++) {
{
if(tvElements[i] == drcElements[n]) if(tvElements[i] == drcElements[n])
break; break;
} }
if(n == drcElements.size()) if(n == drcElements.size()) {
{
tvElements[i]->process(); tvElements[i]->process();
} }
} }
} }
void MainWindow::update(GuiController *controller) void MainWindow::update(GuiController *controller) {
{
//! dont read behind the initial elements in case one was added //! dont read behind the initial elements in case one was added
//u32 tvSize = tvElements.size(); //u32 tvSize = tvElements.size();
if(controller->chan & GuiTrigger::CHANNEL_1) if(controller->chan & GuiTrigger::CHANNEL_1) {
{
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
drcElements[i]->update(controller); drcElements[i]->update(controller);
} }
} } else {
else
{
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
tvElements[i]->update(controller); tvElements[i]->update(controller);
} }
} }
@ -155,8 +134,7 @@ void MainWindow::update(GuiController *controller)
// } // }
// } // }
if(controller->chanIdx >= 1 && controller->chanIdx <= 4 && controller->data.validPointer) if(controller->chanIdx >= 1 && controller->chanIdx <= 4 && controller->data.validPointer) {
{
s32 wpadIdx = controller->chanIdx - 1; s32 wpadIdx = controller->chanIdx - 1;
f32 posX = controller->data.x; f32 posX = controller->data.x;
f32 posY = controller->data.y; f32 posY = controller->data.y;
@ -166,17 +144,13 @@ void MainWindow::update(GuiController *controller)
} }
} }
void MainWindow::drawDrc(CVideo *video) void MainWindow::drawDrc(CVideo *video) {
{ for(u32 i = 0; i < drcElements.size(); ++i) {
for(u32 i = 0; i < drcElements.size(); ++i)
{
drcElements[i]->draw(video); drcElements[i]->draw(video);
} }
for(s32 i = 0; i < 4; i++) for(s32 i = 0; i < 4; i++) {
{ if(pointerValid[i]) {
if(pointerValid[i])
{
pointerImg[i]->setAlpha(0.5f); pointerImg[i]->setAlpha(0.5f);
pointerImg[i]->draw(video); pointerImg[i]->draw(video);
pointerImg[i]->setAlpha(1.0f); pointerImg[i]->setAlpha(1.0f);
@ -184,107 +158,94 @@ void MainWindow::drawDrc(CVideo *video)
} }
} }
void MainWindow::drawTv(CVideo *video) void MainWindow::drawTv(CVideo *video) {
{ for(u32 i = 0; i < tvElements.size(); ++i) {
for(u32 i = 0; i < tvElements.size(); ++i)
{
tvElements[i]->draw(video); tvElements[i]->draw(video);
} }
for(s32 i = 0; i < 4; i++) for(s32 i = 0; i < 4; i++) {
{ if(pointerValid[i]) {
if(pointerValid[i])
{
pointerImg[i]->draw(video); pointerImg[i]->draw(video);
pointerValid[i] = false; pointerValid[i] = false;
} }
} }
} }
void MainWindow::SetupMainView(){ void MainWindow::SetupMainView() {
DrcFrame = new MainWindowGUI(width,height); DrcFrame = new MainWindowGUI(width,height);
TvFrame = DrcFrame; TvFrame = DrcFrame;
appendTv(TvFrame); appendTv(TvFrame);
appendDrc(DrcFrame); appendDrc(DrcFrame);
} }
void MainWindow::OnOpenEffectFinish(GuiElement *element) void MainWindow::OnOpenEffectFinish(GuiElement *element) {
{
//! once the menu is open reset its state and allow it to be "clicked/hold" //! once the menu is open reset its state and allow it to be "clicked/hold"
element->effectFinished.disconnect(this); element->effectFinished.disconnect(this);
element->clearState(GuiElement::STATE_DISABLED); element->clearState(GuiElement::STATE_DISABLED);
} }
void MainWindow::appendToAllElements(GuiElement * element){ void MainWindow::appendToAllElements(GuiElement * element) {
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
GuiFrame * realElement = dynamic_cast<GuiFrame*>(drcElements[i]); GuiFrame * realElement = dynamic_cast<GuiFrame*>(drcElements[i]);
if(realElement != NULL){ if(realElement != NULL) {
realElement->append(element); realElement->append(element);
} }
} }
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
GuiFrame * realElement = dynamic_cast<GuiFrame*>(tvElements[i]); GuiFrame * realElement = dynamic_cast<GuiFrame*>(tvElements[i]);
if(realElement != NULL){ if(realElement != NULL) {
realElement->append(element); realElement->append(element);
} }
} }
} }
void MainWindow::removeFromAllElements(GuiElement * element){ void MainWindow::removeFromAllElements(GuiElement * element) {
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
GuiFrame * realElement = dynamic_cast<GuiFrame*>(drcElements[i]); GuiFrame * realElement = dynamic_cast<GuiFrame*>(drcElements[i]);
if(realElement != NULL){ if(realElement != NULL) {
realElement->remove(element); realElement->remove(element);
} }
} }
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
GuiFrame * realElement = dynamic_cast<GuiFrame*>(tvElements[i]); GuiFrame * realElement = dynamic_cast<GuiFrame*>(tvElements[i]);
if(realElement != NULL){ if(realElement != NULL) {
realElement->remove(element); realElement->remove(element);
} }
} }
} }
void MainWindow::setState(s32 val, s32 c){ void MainWindow::setState(s32 val, s32 c) {
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
drcElements[i]->setState(val,c); drcElements[i]->setState(val,c);
} }
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
tvElements[i]->setState(val,c); tvElements[i]->setState(val,c);
} }
} }
void MainWindow::clearState(s32 val, s32 c){ void MainWindow::clearState(s32 val, s32 c) {
u32 drcSize = drcElements.size(); u32 drcSize = drcElements.size();
for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) for(u32 i = 0; (i < drcSize) && (i < drcElements.size()); ++i) {
{
drcElements[i]->clearState(val,c); drcElements[i]->clearState(val,c);
} }
u32 tvSize = tvElements.size(); u32 tvSize = tvElements.size();
for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) for(u32 i = 0; (i < tvSize) && (i < tvElements.size()); ++i) {
{
tvElements[i]->clearState(val,c); tvElements[i]->clearState(val,c);
} }
} }
void MainWindow::OnCloseEffectFinish(GuiElement *element){ void MainWindow::OnCloseEffectFinish(GuiElement *element) {
//! remove element from draw list and push to delete queue //! remove element from draw list and push to delete queue
remove(element); remove(element);

View File

@ -24,15 +24,14 @@
class CVideo; class CVideo;
class MainWindow : public sigslot::has_slots<> class MainWindow : public sigslot::has_slots<> {
{
public: public:
virtual ~MainWindow(); virtual ~MainWindow();
static MainWindow *instance; static MainWindow *instance;
static MainWindow *getInstance(s32 w,s32 h) { static MainWindow *getInstance(s32 w,s32 h) {
if(!instance){ if(!instance) {
instance = new MainWindow(w, h); instance = new MainWindow(w, h);
} }
return instance; return instance;
@ -43,22 +42,20 @@ public:
} }
static void destroyInstance() { static void destroyInstance() {
if(instance){ if(instance) {
delete instance; delete instance;
instance = NULL; instance = NULL;
} }
} }
void appendTv(GuiElement *e) void appendTv(GuiElement *e) {
{
if(!e) if(!e)
return; return;
removeTv(e); removeTv(e);
tvElements.push_back(e); tvElements.push_back(e);
} }
void appendDrc(GuiElement *e) void appendDrc(GuiElement *e) {
{
if(!e) if(!e)
return; return;
@ -66,22 +63,19 @@ public:
drcElements.push_back(e); drcElements.push_back(e);
} }
void append(GuiElement *e) void append(GuiElement *e) {
{
appendTv(e); appendTv(e);
appendDrc(e); appendDrc(e);
} }
void insertTv(u32 pos, GuiElement *e) void insertTv(u32 pos, GuiElement *e) {
{
if(!e) if(!e)
return; return;
removeTv(e); removeTv(e);
tvElements.insert(tvElements.begin() + pos, e); tvElements.insert(tvElements.begin() + pos, e);
} }
void insertDrc(u32 pos, GuiElement *e) void insertDrc(u32 pos, GuiElement *e) {
{
if(!e) if(!e)
return; return;
@ -89,42 +83,33 @@ public:
drcElements.insert(drcElements.begin() + pos, e); drcElements.insert(drcElements.begin() + pos, e);
} }
void insert(u32 pos, GuiElement *e) void insert(u32 pos, GuiElement *e) {
{
insertTv(pos, e); insertTv(pos, e);
insertDrc(pos, e); insertDrc(pos, e);
} }
void removeTv(GuiElement *e) void removeTv(GuiElement *e) {
{ for(u32 i = 0; i < tvElements.size(); ++i) {
for(u32 i = 0; i < tvElements.size(); ++i) if(e == tvElements[i]) {
{
if(e == tvElements[i])
{
tvElements.erase(tvElements.begin() + i); tvElements.erase(tvElements.begin() + i);
break; break;
} }
} }
} }
void removeDrc(GuiElement *e) void removeDrc(GuiElement *e) {
{ for(u32 i = 0; i < drcElements.size(); ++i) {
for(u32 i = 0; i < drcElements.size(); ++i) if(e == drcElements[i]) {
{
if(e == drcElements[i])
{
drcElements.erase(drcElements.begin() + i); drcElements.erase(drcElements.begin() + i);
break; break;
} }
} }
} }
void remove(GuiElement *e) void remove(GuiElement *e) {
{
removeTv(e); removeTv(e);
removeDrc(e); removeDrc(e);
} }
void removeAll() void removeAll() {
{
tvElements.clear(); tvElements.clear();
drcElements.clear(); drcElements.clear();
} }
@ -140,10 +125,10 @@ public:
void setState(s32 i, s32 c = -1 ); void setState(s32 i, s32 c = -1 );
void clearState(s32 i, s32 c = -1); void clearState(s32 i, s32 c = -1);
void lockGUI(){ void lockGUI() {
guiMutex.lock(); guiMutex.lock();
} }
void unlockGUI(){ void unlockGUI() {
guiMutex.unlock(); guiMutex.unlock();
} }

View File

@ -20,25 +20,34 @@ MainWindowContent::MainWindowContent(s32 w, s32 h)
: GuiFrame(w, h) : GuiFrame(w, h)
, width(w) , width(w)
, height(h) , height(h)
, bgImageColor(w, h, (GX2Color){ 0, 0, 0, 0 }) , bgImageColor(w, h, (GX2Color) {
{ 0, 0, 0, 0
bgImageColor.setImageColor((GX2Color){ 248, 249, 248, 255 }, 0); }) {
bgImageColor.setImageColor((GX2Color){ 248, 249, 248, 255 }, 1); bgImageColor.setImageColor((GX2Color) {
bgImageColor.setImageColor((GX2Color){ 248, 249, 248, 255 }, 2); 248, 249, 248, 255
bgImageColor.setImageColor((GX2Color){ 248, 249, 248, 255 }, 3); }, 0);
bgImageColor.setImageColor((GX2Color) {
248, 249, 248, 255
}, 1);
bgImageColor.setImageColor((GX2Color) {
248, 249, 248, 255
}, 2);
bgImageColor.setImageColor((GX2Color) {
248, 249, 248, 255
}, 3);
append(&bgImageColor); append(&bgImageColor);
} }
ContentTemplate * MainWindowContent::getContent(){ ContentTemplate * MainWindowContent::getContent() {
return content; return content;
} }
void MainWindowContent::SetScreen(ContentTemplate * new_content){ void MainWindowContent::SetScreen(ContentTemplate * new_content) {
RemoveScreen(); RemoveScreen();
if(new_content){ if(new_content) {
//while(content != NULL); //hopefully this shit don't kill us. //while(content != NULL); //hopefully this shit don't kill us.
content = new_content; content = new_content;
@ -46,17 +55,17 @@ void MainWindowContent::SetScreen(ContentTemplate * new_content){
} }
} }
void MainWindowContent::RemoveScreen(){ void MainWindowContent::RemoveScreen() {
remove(content); remove(content);
delete content; delete content;
content = NULL; content = NULL;
} }
void MainWindowContent::OnCloseEffectFinish(GuiElement *element){ void MainWindowContent::OnCloseEffectFinish(GuiElement *element) {
} }
MainWindowContent::~MainWindowContent(){ MainWindowContent::~MainWindowContent() {
remove(&bgImageColor); remove(&bgImageColor);
RemoveScreen(); RemoveScreen();
} }

View File

@ -25,9 +25,9 @@
#include "content/ContentHome.h" #include "content/ContentHome.h"
#include "MainWindowContent.h" #include "MainWindowContent.h"
class MainWindowContent : public GuiFrame, public sigslot::has_slots<>{ class MainWindowContent : public GuiFrame, public sigslot::has_slots<> {
public: public:
enum eContentNames{ enum eContentNames {
CONTENT_HOME, CONTENT_HOME,
}; };
@ -38,11 +38,15 @@ public:
void RemoveScreen(); void RemoveScreen();
ContentTemplate * getContent(); ContentTemplate * getContent();
//If you call this function, please also delete the object. This class isn't taking care of it //If you call this function, please also delete the object. This class isn't taking care of it
static ContentTemplate * createNewContent(eContentNames contentName){ static ContentTemplate * createNewContent(eContentNames contentName) {
switch(contentName){ switch(contentName) {
case CONTENT_HOME: { return new ContentHome(); break;} case CONTENT_HOME: {
default: return NULL; return new ContentHome();
break;
}
default:
return NULL;
} }
} }

View File

@ -21,21 +21,21 @@ MainWindowGUI::MainWindowGUI(s32 w, s32 h)
: GuiFrame(w, h) : GuiFrame(w, h)
, width(w) , width(w)
, height(h) , height(h)
, content(SCREEN_WIDTH,h){ , content(SCREEN_WIDTH,h) {
ContentTemplate * curTemplate = content.createNewContent(MainWindowContent::CONTENT_HOME); ContentTemplate * curTemplate = content.createNewContent(MainWindowContent::CONTENT_HOME);
content.SetScreen(curTemplate); content.SetScreen(curTemplate);
append(&content); append(&content);
} }
void MainWindowGUI::setState(s32 i, s32 c){ void MainWindowGUI::setState(s32 i, s32 c) {
GuiFrame::setState(i,c); GuiFrame::setState(i,c);
} }
void MainWindowGUI::process(){ void MainWindowGUI::process() {
GuiFrame::process(); GuiFrame::process();
} }
MainWindowGUI::~MainWindowGUI(){ MainWindowGUI::~MainWindowGUI() {
content.RemoveScreen(); content.RemoveScreen();
remove(&content); remove(&content);
} }

View File

@ -23,7 +23,7 @@
#include "menu/content/ContentTemplate.h" #include "menu/content/ContentTemplate.h"
#include <language/gettext.h> #include <language/gettext.h>
class MainWindowGUI : public GuiFrame, public sigslot::has_slots<>{ class MainWindowGUI : public GuiFrame, public sigslot::has_slots<> {
public: public:
MainWindowGUI(s32 w, s32 h); MainWindowGUI(s32 w, s32 h);
virtual ~MainWindowGUI(); virtual ~MainWindowGUI();

View File

@ -29,8 +29,7 @@ ContentHome::ContentHome():ContentTemplate()
, exitHome(gettext("Exit to HBL ")) , exitHome(gettext("Exit to HBL "))
, plusbutton_imgdata(Resources::GetImageData("PlusButtonIcon.png")) , plusbutton_imgdata(Resources::GetImageData("PlusButtonIcon.png"))
, plusbutton_img(plusbutton_imgdata) , plusbutton_img(plusbutton_imgdata)
, exitPlus(gettext("Apply Patches")) , exitPlus(gettext("Apply Patches")) {
{
glm::vec4 textColor = glm::vec4(1.0f,1.0f,1.0f,1.0f); glm::vec4 textColor = glm::vec4(1.0f,1.0f,1.0f,1.0f);
homebutton_img.setAlignment(ALIGN_LEFT); homebutton_img.setAlignment(ALIGN_LEFT);
@ -82,7 +81,7 @@ ContentHome::ContentHome():ContentTemplate()
append(&exitPlusFrame); append(&exitPlusFrame);
} }
ContentHome::~ContentHome(){ ContentHome::~ContentHome() {
//Resources::RemoveImageData(logoImageData); <-- will reduce lag. Will be deleted at the end anyway //Resources::RemoveImageData(logoImageData); <-- will reduce lag. Will be deleted at the end anyway
remove(&bgImageColor); remove(&bgImageColor);
remove(&welcomeHeadLineLabel); remove(&welcomeHeadLineLabel);

View File

@ -21,7 +21,7 @@
#include "ContentTemplate.h" #include "ContentTemplate.h"
#include "language/gettext.h" #include "language/gettext.h"
class ContentHome : public ContentTemplate{ class ContentHome : public ContentTemplate {
public: public:
ContentHome(); ContentHome();
virtual ~ContentHome(); virtual ~ContentHome();

View File

@ -20,16 +20,25 @@
#include "gui/Gui.h" #include "gui/Gui.h"
#include "menu/MenuCommon.h" #include "menu/MenuCommon.h"
class ContentTemplate : public GuiFrame, public sigslot::has_slots<>{ class ContentTemplate : public GuiFrame, public sigslot::has_slots<> {
public: public:
ContentTemplate() : GuiFrame(SCREEN_WIDTH, SCREEN_HEIGHT) ContentTemplate() : GuiFrame(SCREEN_WIDTH, SCREEN_HEIGHT)
, bgImageColor(SCREEN_WIDTH, SCREEN_HEIGHT, (GX2Color){ 0, 0, 0, 0 }) , bgImageColor(SCREEN_WIDTH, SCREEN_HEIGHT, (GX2Color) {
{ 0, 0, 0, 0
bgImageColor.setImageColor((GX2Color){ 42, 42, 42, 255 }, 0); }) {
bgImageColor.setImageColor((GX2Color){ 42, 42, 42, 255 }, 1); bgImageColor.setImageColor((GX2Color) {
bgImageColor.setImageColor((GX2Color){ 42, 42, 42, 255 }, 2); 42, 42, 42, 255
bgImageColor.setImageColor((GX2Color){ 42, 42, 42, 255 }, 3); }, 0);
bgImageColor.setImageColor((GX2Color) {
42, 42, 42, 255
}, 1);
bgImageColor.setImageColor((GX2Color) {
42, 42, 42, 255
}, 2);
bgImageColor.setImageColor((GX2Color) {
42, 42, 42, 255
}, 3);
append(&bgImageColor); append(&bgImageColor);
} }

View File

@ -4,17 +4,17 @@
#include <fat.h> #include <fat.h>
#include "common/retain_vars.h" #include "common/retain_vars.h"
int mount_libfatAll(){ int mount_libfatAll() {
int res = -1; int res = -1;
if((res = fatInitDefault()) >= 0){ if((res = fatInitDefault()) >= 0) {
DEBUG_FUNCTION_LINE("fatInitDefault success\n"); DEBUG_FUNCTION_LINE("fatInitDefault success\n");
return 0; return 0;
}else{ } else {
DEBUG_FUNCTION_LINE("fatInitDefault failed %d\n",res); DEBUG_FUNCTION_LINE("fatInitDefault failed %d\n",res);
} }
return -1; return -1;
} }
void unmount_libfat(const char * path){ void unmount_libfat(const char * path) {
fatUnmount(path); fatUnmount(path);
} }

View File

@ -7,28 +7,28 @@
#include <ntfs.h> #include <ntfs.h>
#include "common/retain_vars.h" #include "common/retain_vars.h"
int mountAllNTFS(){ int mountAllNTFS() {
int i; int i;
// Mount all NTFS volumes on all inserted block devices // Mount all NTFS volumes on all inserted block devices
ntfs_mount_count = ntfsMountAll((ntfs_md **) &ntfs_mounts, NTFS_DEFAULT | NTFS_RECOVER); ntfs_mount_count = ntfsMountAll((ntfs_md **) &ntfs_mounts, NTFS_DEFAULT | NTFS_RECOVER);
if (ntfs_mount_count == -1){ if (ntfs_mount_count == -1) {
DEBUG_FUNCTION_LINE("Error whilst mounting devices.\n"); DEBUG_FUNCTION_LINE("Error whilst mounting devices.\n");
}else if (ntfs_mount_count == 0){ } else if (ntfs_mount_count == 0) {
DEBUG_FUNCTION_LINE("No NTFS volumes were found and/or mounted.\n"); DEBUG_FUNCTION_LINE("No NTFS volumes were found and/or mounted.\n");
}else{ } else {
DEBUG_FUNCTION_LINE("%i NTFS volumes(s) mounted!\n", ntfs_mount_count); DEBUG_FUNCTION_LINE("%i NTFS volumes(s) mounted!\n", ntfs_mount_count);
} }
// List all mounted NTFS volumes // List all mounted NTFS volumes
for (i = 0; i < ntfs_mount_count; i++){ for (i = 0; i < ntfs_mount_count; i++) {
DEBUG_FUNCTION_LINE("%i - %s:/ (%s)\n", i + 1, ((ntfs_md *)ntfs_mounts)[i].name, ntfsGetVolumeName(((ntfs_md *)ntfs_mounts)[i].name)); DEBUG_FUNCTION_LINE("%i - %s:/ (%s)\n", i + 1, ((ntfs_md *)ntfs_mounts)[i].name, ntfsGetVolumeName(((ntfs_md *)ntfs_mounts)[i].name));
} }
return ntfs_mount_count; return ntfs_mount_count;
} }
int unmountAllNTFS(void){ int unmountAllNTFS(void) {
if (ntfs_mounts) { if (ntfs_mounts) {
int i = 0; int i = 0;
for (i = 0; i < ntfs_mount_count; i++){ for (i = 0; i < ntfs_mount_count; i++) {
ntfsUnmount(((ntfs_md *)ntfs_mounts)[i].name, true); ntfsUnmount(((ntfs_md *)ntfs_mounts)[i].name, true);
} }
free(ntfs_mounts); free(ntfs_mounts);

View File

@ -31,75 +31,75 @@
#define DEBUG_LOG_DYN 0 #define DEBUG_LOG_DYN 0
rpl_handling rpl_handles[] __attribute__((section(".data"))) = { rpl_handling rpl_handles[] __attribute__((section(".data"))) = {
{WUPS_LOADER_LIBRARY_AVM, "avm.rpl" ,0}, {WUPS_LOADER_LIBRARY_AVM, "avm.rpl", 0},
{WUPS_LOADER_LIBRARY_CAMERA, "camera.rpl" ,0}, {WUPS_LOADER_LIBRARY_CAMERA, "camera.rpl", 0},
{WUPS_LOADER_LIBRARY_COREINIT, "coreinit.rpl" ,0}, {WUPS_LOADER_LIBRARY_COREINIT, "coreinit.rpl", 0},
{WUPS_LOADER_LIBRARY_DC, "dc.rpl" ,0}, {WUPS_LOADER_LIBRARY_DC, "dc.rpl", 0},
{WUPS_LOADER_LIBRARY_DMAE, "dmae.rpl" ,0}, {WUPS_LOADER_LIBRARY_DMAE, "dmae.rpl", 0},
{WUPS_LOADER_LIBRARY_DRMAPP, "drmapp.rpl" ,0}, {WUPS_LOADER_LIBRARY_DRMAPP, "drmapp.rpl", 0},
{WUPS_LOADER_LIBRARY_ERREULA, "erreula.rpl" ,0}, {WUPS_LOADER_LIBRARY_ERREULA, "erreula.rpl", 0},
{WUPS_LOADER_LIBRARY_GX2, "gx2.rpl" ,0}, {WUPS_LOADER_LIBRARY_GX2, "gx2.rpl", 0},
{WUPS_LOADER_LIBRARY_H264, "h264.rpl" ,0}, {WUPS_LOADER_LIBRARY_H264, "h264.rpl", 0},
{WUPS_LOADER_LIBRARY_LZMA920, "lzma920.rpl" ,0}, {WUPS_LOADER_LIBRARY_LZMA920, "lzma920.rpl", 0},
{WUPS_LOADER_LIBRARY_MIC, "mic.rpl" ,0}, {WUPS_LOADER_LIBRARY_MIC, "mic.rpl", 0},
{WUPS_LOADER_LIBRARY_NFC, "nfc.rpl" ,0}, {WUPS_LOADER_LIBRARY_NFC, "nfc.rpl", 0},
{WUPS_LOADER_LIBRARY_NIO_PROF, "nio_prof.rpl" ,0}, {WUPS_LOADER_LIBRARY_NIO_PROF, "nio_prof.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBCURL, "nlibcurl.rpl" ,0}, {WUPS_LOADER_LIBRARY_NLIBCURL, "nlibcurl.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBNSS, "nlibnss.rpl" ,0}, {WUPS_LOADER_LIBRARY_NLIBNSS, "nlibnss.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBNSS2, "nlibnss2.rpl" ,0}, {WUPS_LOADER_LIBRARY_NLIBNSS2, "nlibnss2.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_AC, "nn_ac.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_AC, "nn_ac.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_ACP, "nn_acp.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_ACP, "nn_acp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_ACT, "nn_act.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_ACT, "nn_act.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_AOC, "nn_aoc.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_AOC, "nn_aoc.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_BOSS, "nn_boss.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_BOSS, "nn_boss.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_CCR, "nn_ccr.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_CCR, "nn_ccr.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_CMPT, "nn_cmpt.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_CMPT, "nn_cmpt.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_DLP, "nn_dlp.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_DLP, "nn_dlp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_EC, "nn_ec.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_EC, "nn_ec.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_FP, "nn_fp.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_FP, "nn_fp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_HAI, "nn_hai.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_HAI, "nn_hai.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_HPAD, "nn_hpad.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_HPAD, "nn_hpad.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_IDBE, "nn_idbe.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_IDBE, "nn_idbe.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NDM, "nn_ndm.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_NDM, "nn_ndm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NETS2, "nn_nets2.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_NETS2, "nn_nets2.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NFP, "nn_nfp.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_NFP, "nn_nfp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NIM, "nn_nim.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_NIM, "nn_nim.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_OLV, "nn_olv.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_OLV, "nn_olv.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_PDM, "nn_pdm.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_PDM, "nn_pdm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SAVE, "nn_save.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_SAVE, "nn_save.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SL, "nn_sl.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_SL, "nn_sl.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SPM, "nn_spm.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_SPM, "nn_spm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_TEMP, "nn_temp.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_TEMP, "nn_temp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_UDS, "nn_uds.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_UDS, "nn_uds.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_VCTL, "nn_vctl.rpl" ,0}, {WUPS_LOADER_LIBRARY_NN_VCTL, "nn_vctl.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSCCR, "nsysccr.rpl" ,0}, {WUPS_LOADER_LIBRARY_NSYSCCR, "nsysccr.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSHID, "nsyshid.rpl" ,0}, {WUPS_LOADER_LIBRARY_NSYSHID, "nsyshid.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSKBD, "nsyskbd.rpl" ,0}, {WUPS_LOADER_LIBRARY_NSYSKBD, "nsyskbd.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSNET, "nsysnet.rpl" ,0}, {WUPS_LOADER_LIBRARY_NSYSNET, "nsysnet.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSUHS, "nsysuhs.rpl" ,0}, {WUPS_LOADER_LIBRARY_NSYSUHS, "nsysuhs.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSUVD, "nsysuvd.rpl" ,0}, {WUPS_LOADER_LIBRARY_NSYSUVD, "nsysuvd.rpl", 0},
{WUPS_LOADER_LIBRARY_NTAG, "ntag.rpl" ,0}, {WUPS_LOADER_LIBRARY_NTAG, "ntag.rpl", 0},
{WUPS_LOADER_LIBRARY_PADSCORE, "padscore.rpl" ,0}, {WUPS_LOADER_LIBRARY_PADSCORE, "padscore.rpl", 0},
{WUPS_LOADER_LIBRARY_PROC_UI, "proc_ui.rpl" ,0}, {WUPS_LOADER_LIBRARY_PROC_UI, "proc_ui.rpl", 0},
{WUPS_LOADER_LIBRARY_SNDCORE2, "sndcore2.rpl" ,0}, {WUPS_LOADER_LIBRARY_SNDCORE2, "sndcore2.rpl", 0},
{WUPS_LOADER_LIBRARY_SNDUSER2, "snduser2.rpl" ,0}, {WUPS_LOADER_LIBRARY_SNDUSER2, "snduser2.rpl", 0},
{WUPS_LOADER_LIBRARY_SND_CORE, "snd_core.rpl" ,0}, {WUPS_LOADER_LIBRARY_SND_CORE, "snd_core.rpl", 0},
{WUPS_LOADER_LIBRARY_SND_USER, "snd_user.rpl" ,0}, {WUPS_LOADER_LIBRARY_SND_USER, "snd_user.rpl", 0},
{WUPS_LOADER_LIBRARY_SWKBD, "swkbd.rpl" ,0}, {WUPS_LOADER_LIBRARY_SWKBD, "swkbd.rpl", 0},
{WUPS_LOADER_LIBRARY_SYSAPP, "sysapp.rpl" ,0}, {WUPS_LOADER_LIBRARY_SYSAPP, "sysapp.rpl", 0},
{WUPS_LOADER_LIBRARY_TCL, "tcl.rpl" ,0}, {WUPS_LOADER_LIBRARY_TCL, "tcl.rpl", 0},
{WUPS_LOADER_LIBRARY_TVE, "tve.rpl" ,0}, {WUPS_LOADER_LIBRARY_TVE, "tve.rpl", 0},
{WUPS_LOADER_LIBRARY_UAC, "uac.rpl" ,0}, {WUPS_LOADER_LIBRARY_UAC, "uac.rpl", 0},
{WUPS_LOADER_LIBRARY_UAC_RPL, "uac_rpl.rpl" ,0}, {WUPS_LOADER_LIBRARY_UAC_RPL, "uac_rpl.rpl", 0},
{WUPS_LOADER_LIBRARY_USB_MIC, "usb_mic.rpl" ,0}, {WUPS_LOADER_LIBRARY_USB_MIC, "usb_mic.rpl", 0},
{WUPS_LOADER_LIBRARY_UVC, "uvc.rpl" ,0}, {WUPS_LOADER_LIBRARY_UVC, "uvc.rpl", 0},
{WUPS_LOADER_LIBRARY_UVD, "uvd.rpl" ,0}, {WUPS_LOADER_LIBRARY_UVD, "uvd.rpl", 0},
{WUPS_LOADER_LIBRARY_VPAD, "vpad.rpl" ,0}, {WUPS_LOADER_LIBRARY_VPAD, "vpad.rpl", 0},
{WUPS_LOADER_LIBRARY_VPADBASE, "vpadbase.rpl" ,0}, {WUPS_LOADER_LIBRARY_VPADBASE, "vpadbase.rpl", 0},
{WUPS_LOADER_LIBRARY_ZLIB125, "zlib125.rpl" ,0} {WUPS_LOADER_LIBRARY_ZLIB125, "zlib125.rpl", 0}
}; };
void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data){ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data) {
InitAcquireOS(); InitAcquireOS();
new_resetLibs(); new_resetLibs();
@ -111,18 +111,18 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data){
u32 my_instr_len = 6; u32 my_instr_len = 6;
u32 instr_len = my_instr_len + skip_instr; u32 instr_len = my_instr_len + skip_instr;
u32 flush_len = 4*instr_len; u32 flush_len = 4*instr_len;
for(s32 i = 0; i < method_hooks_count; i++){ for(s32 i = 0; i < method_hooks_count; i++) {
replacement_data_function_t * function_data = &plugin_data->functions[i]; replacement_data_function_t * function_data = &plugin_data->functions[i];
/* Patch branches to it. */ /* Patch branches to it. */
volatile u32 *space = function_data->replace_data; volatile u32 *space = function_data->replace_data;
DEBUG_FUNCTION_LINE("Patching %s ...\n",function_data->function_name); DEBUG_FUNCTION_LINE("Patching %s ...\n",function_data->function_name);
if(function_data->functionType == STATIC_FUNCTION && function_data->alreadyPatched == 1){ if(function_data->functionType == STATIC_FUNCTION && function_data->alreadyPatched == 1) {
if(new_isDynamicFunction((u32)OSEffectiveToPhysical((void*)function_data->realAddr))){ if(new_isDynamicFunction((u32)OSEffectiveToPhysical((void*)function_data->realAddr))) {
log_printf("The function %s is a dynamic function. Please fix that <3\n", function_data->function_name); DEBUG_FUNCTION_LINE("INFO: The function %s is a dynamic function.\n", function_data->function_name);
function_data->functionType = DYNAMIC_FUNCTION; function_data->functionType = DYNAMIC_FUNCTION;
}else{ } else {
log_printf("Skipping %s, its already patched\n", function_data->function_name); DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name);
continue; continue;
} }
} }
@ -133,21 +133,25 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data){
u32 real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); u32 real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library);
if(!real_addr){ if(!real_addr) {
log_printf("\n"); log_printf("\n");
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", function_data->function_name); DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", function_data->function_name);
continue; continue;
} }
if(DEBUG_LOG_DYN){DEBUG_FUNCTION_LINE("%s is located at %08X!\n", function_data->function_name,real_addr);} if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s is located at %08X!\n", function_data->function_name,real_addr);
physical = (u32)OSEffectiveToPhysical((void*)real_addr);
if(!physical){
log_printf("Error. Something is wrong with the physical address\n");
continue;
} }
if(DEBUG_LOG_DYN){DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", function_data->function_name,physical);} physical = (u32)OSEffectiveToPhysical((void*)real_addr);
if(!physical) {
log_printf("Error. Something is wrong with the physical address\n");
continue;
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", function_data->function_name,physical);
}
*(volatile u32 *)(call_addr) = (u32)(space); *(volatile u32 *)(call_addr) = (u32)(space);
@ -156,14 +160,17 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data){
space++; space++;
//Only works if skip_instr == 1 //Only works if skip_instr == 1
if(skip_instr == 1){ if(skip_instr == 1) {
// fill the restore instruction section // fill the restore instruction section
function_data->realAddr = real_addr; function_data->realAddr = real_addr;
function_data->restoreInstruction = *(space-1); function_data->restoreInstruction = *(space-1);
if(DEBUG_LOG_DYN){DEBUG_FUNCTION_LINE("function_data->realAddr = %08X!\n", function_data->realAddr);} if(DEBUG_LOG_DYN) {
if(DEBUG_LOG_DYN){DEBUG_FUNCTION_LINE("function_data->restoreInstruction = %08X!\n",function_data->restoreInstruction) ;} DEBUG_FUNCTION_LINE("function_data->realAddr = %08X!\n", function_data->realAddr);
} }
else{ if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("function_data->restoreInstruction = %08X!\n",function_data->restoreInstruction) ;
}
} else {
log_printf("Error. Can't save %s for restoring!\n", function_data->function_name); log_printf("Error. Can't save %s for restoring!\n", function_data->function_name);
} }
@ -209,42 +216,46 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data){
/* ****************************************************************** */ /* ****************************************************************** */
/* RESTORE ORIGINAL INSTRUCTIONS */ /* RESTORE ORIGINAL INSTRUCTIONS */
/* ****************************************************************** */ /* ****************************************************************** */
void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data){ void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data) {
InitAcquireOS(); InitAcquireOS();
new_resetLibs(); new_resetLibs();
DEBUG_FUNCTION_LINE("Restoring given functions!\n"); DEBUG_FUNCTION_LINE("Restoring given functions!\n");
s32 method_hooks_count = plugin_data->number_used_functions; s32 method_hooks_count = plugin_data->number_used_functions;
for(s32 i = 0; i < method_hooks_count; i++){ for(s32 i = 0; i < method_hooks_count; i++) {
replacement_data_function_t * function_data = &plugin_data->functions[i]; replacement_data_function_t * function_data = &plugin_data->functions[i];
DEBUG_FUNCTION_LINE("Restoring %s... ",function_data->function_name); DEBUG_FUNCTION_LINE("Restoring %s... ",function_data->function_name);
if(function_data->restoreInstruction == 0 || function_data->realAddr == 0){ if(function_data->restoreInstruction == 0 || function_data->realAddr == 0) {
log_printf("I dont have the information for the restore =( skip\n"); log_printf("I dont have the information for the restore =( skip\n");
continue; continue;
} }
u32 real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); u32 real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library);
if(!real_addr){ if(!real_addr) {
log_printf("OSDynLoad_FindExport failed for %s\n", function_data->function_name); log_printf("OSDynLoad_FindExport failed for %s\n", function_data->function_name);
continue; continue;
} }
u32 physical = (u32)OSEffectiveToPhysical((void*)real_addr); u32 physical = (u32)OSEffectiveToPhysical((void*)real_addr);
if(!physical){ if(!physical) {
log_printf("Something is wrong with the physical address\n"); log_printf("Something is wrong with the physical address\n");
continue; continue;
} }
if(new_isDynamicFunction(physical)){ if(new_isDynamicFunction(physical)) {
log_printf("Its a dynamic function. We don't need to restore it!\n",function_data->function_name); log_printf("Its a dynamic function. We don't need to restore it!\n",function_data->function_name);
} else { } else {
physical = (u32)OSEffectiveToPhysical((void*)function_data->realAddr); //When its an static function, we need to use the old location physical = (u32)OSEffectiveToPhysical((void*)function_data->realAddr); //When its an static function, we need to use the old location
if(DEBUG_LOG_DYN){DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(u32)function_data->restoreInstruction,physical);} if(DEBUG_LOG_DYN) {
SC0x25_KernelCopyData(physical,(u32)&function_data->restoreInstruction , 4); DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(u32)function_data->restoreInstruction,physical);
if(DEBUG_LOG_DYN){DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)function_data->realAddr);} }
SC0x25_KernelCopyData(physical,(u32)&function_data->restoreInstruction, 4);
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)function_data->realAddr);
}
ICInvalidateRange((void*)function_data->realAddr, 4); ICInvalidateRange((void*)function_data->realAddr, 4);
DCFlushRange((void*)function_data->realAddr, 4); DCFlushRange((void*)function_data->realAddr, 4);
log_printf("done\n"); log_printf("done\n");
@ -255,28 +266,23 @@ void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data){
DEBUG_FUNCTION_LINE("Done with restoring given functions!\n"); DEBUG_FUNCTION_LINE("Done with restoring given functions!\n");
} }
s32 new_isDynamicFunction(u32 physicalAddress){ s32 new_isDynamicFunction(u32 physicalAddress) {
if((physicalAddress & 0x80000000) == 0x80000000){ if((physicalAddress & 0x80000000) == 0x80000000) {
return 1; return 1;
} }
return 0; return 0;
} }
u32 new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_t library){ u32 new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_t library) {
u32 real_addr = 0; u32 real_addr = 0;
if(strcmp(functionName, "OSDynLoad_Acquire") == 0) if(strcmp(functionName, "OSDynLoad_Acquire") == 0) {
{
memcpy(&real_addr, &OSDynLoad_Acquire, 4); memcpy(&real_addr, &OSDynLoad_Acquire, 4);
return real_addr; return real_addr;
} } else if(strcmp(functionName, "LiWaitOneChunk") == 0) {
else if(strcmp(functionName, "LiWaitOneChunk") == 0)
{
real_addr = (u32)addr_LiWaitOneChunk; real_addr = (u32)addr_LiWaitOneChunk;
return real_addr; return real_addr;
} } else if(strcmp(functionName, "LiBounceOneChunk") == 0) {
else if(strcmp(functionName, "LiBounceOneChunk") == 0)
{
//! not required on firmwares above 3.1.0 //! not required on firmwares above 3.1.0
if(OS_FIRMWARE >= 400) if(OS_FIRMWARE >= 400)
return 0; return 0;
@ -290,37 +296,40 @@ u32 new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_
int rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0]; int rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0];
for(int i = 0;i< rpl_handles_size; i++){ for(int i = 0; i< rpl_handles_size; i++) {
if(rpl_handles[i].library == library){ if(rpl_handles[i].library == library) {
if(rpl_handles[i].handle == 0){ if(rpl_handles[i].handle == 0) {
DEBUG_FUNCTION_LINE("Lets acquire handle for rpl: %s\n",rpl_handles[i].rplname); DEBUG_FUNCTION_LINE("Lets acquire handle for rpl: %s\n",rpl_handles[i].rplname);
OSDynLoad_Acquire(rpl_handles[i].rplname, &rpl_handles[i].handle); OSDynLoad_Acquire(rpl_handles[i].rplname, &rpl_handles[i].handle);
}
if(rpl_handles[i].handle == 0) {
log_printf("%s failed to acquire\n",rpl_handles[i].rplname);
return 0;
} }
if(rpl_handles[i].handle == 0){log_printf("%s failed to acquire\n",rpl_handles[i].rplname); return 0;}
rpl_handle = rpl_handles[i].handle; rpl_handle = rpl_handles[i].handle;
break; break;
} }
} }
if(!rpl_handle){ if(!rpl_handle) {
DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s\n", functionName); DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s\n", functionName);
return 0; return 0;
} }
OSDynLoad_FindExport(rpl_handle, 0, functionName, &real_addr); OSDynLoad_FindExport(rpl_handle, 0, functionName, &real_addr);
if(!real_addr){ if(!real_addr) {
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", functionName); DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", functionName);
return 0; return 0;
} }
if((library == WUPS_LOADER_LIBRARY_NN_ACP) && (u32)(*(volatile u32*)(real_addr) & 0x48000002) == 0x48000000){ if((library == WUPS_LOADER_LIBRARY_NN_ACP) && (u32)(*(volatile u32*)(real_addr) & 0x48000002) == 0x48000000) {
u32 address_diff = (u32)(*(volatile u32*)(real_addr) & 0x03FFFFFC); u32 address_diff = (u32)(*(volatile u32*)(real_addr) & 0x03FFFFFC);
if((address_diff & 0x03000000) == 0x03000000) { if((address_diff & 0x03000000) == 0x03000000) {
address_diff |= 0xFC000000; address_diff |= 0xFC000000;
} }
real_addr += (s32)address_diff; real_addr += (s32)address_diff;
if((u32)(*(volatile u32*)(real_addr) & 0x48000002) == 0x48000000){ if((u32)(*(volatile u32*)(real_addr) & 0x48000002) == 0x48000000) {
return 0; return 0;
} }
} }
@ -328,11 +337,11 @@ u32 new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_
return real_addr; return real_addr;
} }
void new_resetLibs(){ void new_resetLibs() {
int rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0]; int rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0];
for(int i = 0;i< rpl_handles_size; i++){ for(int i = 0; i< rpl_handles_size; i++) {
if(rpl_handles[i].handle != 0){ if(rpl_handles[i].handle != 0) {
DEBUG_FUNCTION_LINE("Resetting handle for rpl: %s\n",rpl_handles[i].rplname); DEBUG_FUNCTION_LINE("Resetting handle for rpl: %s\n",rpl_handles[i].rplname);
} }
rpl_handles[i].handle = 0; rpl_handles[i].handle = 0;

View File

@ -42,7 +42,7 @@ struct rpl_handling {
#define MAXIMUM_PLUGIN_NAME_LENGTH 51 #define MAXIMUM_PLUGIN_NAME_LENGTH 51
#define MAXIMUM_FUNCTION_NAME_LENGTH 51 #define MAXIMUM_FUNCTION_NAME_LENGTH 51
struct replacement_data_function_t{ struct replacement_data_function_t {
u32 replaceAddr; /* [needs to be filled] Address of our replacement function */ u32 replaceAddr; /* [needs to be filled] Address of our replacement function */
u32 replaceCall; /* [needs to be filled] Address to access the real_function */ u32 replaceCall; /* [needs to be filled] Address to access the real_function */
wups_loader_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */ wups_loader_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */
@ -54,7 +54,7 @@ struct replacement_data_function_t{
u8 alreadyPatched; /* [will be filled] */ u8 alreadyPatched; /* [will be filled] */
}; };
struct replacement_data_hook_t{ struct replacement_data_hook_t {
void * func_pointer = NULL; /* [will be filled] */ void * func_pointer = NULL; /* [will be filled] */
wups_loader_hook_type_t type; /* [will be filled] */ wups_loader_hook_type_t type; /* [will be filled] */
}; };
@ -62,7 +62,7 @@ struct replacement_data_hook_t{
#define MAXIMUM_HOOKS_PER_PLUGIN 10 #define MAXIMUM_HOOKS_PER_PLUGIN 10
#define MAXIMUM_FUNCTION_PER_PLUGIN 100 #define MAXIMUM_FUNCTION_PER_PLUGIN 100
struct replacement_data_plugin_t{ struct replacement_data_plugin_t {
char path[MAXIMUM_PLUGIN_PATH_NAME_LENGTH] = ""; // Path where the plugin is stored char path[MAXIMUM_PLUGIN_PATH_NAME_LENGTH] = ""; // Path where the plugin is stored
char plugin_name[MAXIMUM_PLUGIN_NAME_LENGTH] = ""; // Name of this plugin char plugin_name[MAXIMUM_PLUGIN_NAME_LENGTH] = ""; // Name of this plugin
int priority; // Priority of this plugin int priority; // Priority of this plugin
@ -75,7 +75,7 @@ struct replacement_data_plugin_t{
#define MAXIMUM_PLUGINS 32 #define MAXIMUM_PLUGINS 32
struct replacement_data_t{ struct replacement_data_t {
int number_used_plugins = 0; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_PLUGIN int number_used_plugins = 0; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_PLUGIN
replacement_data_plugin_t plugin_data[MAXIMUM_PLUGINS]; replacement_data_plugin_t plugin_data[MAXIMUM_PLUGINS];
}; };

View File

@ -5,7 +5,7 @@
#include "myutils/overlay_helper.h" #include "myutils/overlay_helper.h"
#include "main.h" #include "main.h"
DECL(void, __PPCExit, void){ DECL(void, __PPCExit, void) {
DEBUG_FUNCTION_LINE("__PPCExit\n"); DEBUG_FUNCTION_LINE("__PPCExit\n");
DeInit(); DeInit();
@ -13,9 +13,9 @@ DECL(void, __PPCExit, void){
real___PPCExit(); real___PPCExit();
} }
DECL(u32, ProcUIProcessMessages, u32 u){ DECL(u32, ProcUIProcessMessages, u32 u) {
u32 res = real_ProcUIProcessMessages(u); u32 res = real_ProcUIProcessMessages(u);
if(res != gAppStatus){ if(res != gAppStatus) {
DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res); DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res);
gAppStatus = res; gAppStatus = res;
} }
@ -23,7 +23,7 @@ DECL(u32, ProcUIProcessMessages, u32 u){
return res; return res;
} }
DECL(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode){ DECL(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode) {
tv_store.buffer = buffer; tv_store.buffer = buffer;
tv_store.buffer_size = buffer_size; tv_store.buffer_size = buffer_size;
tv_store.mode = tv_render_mode; tv_store.mode = tv_render_mode;
@ -33,7 +33,7 @@ DECL(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s3
return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode); return real_GX2SetTVBuffer(buffer,buffer_size,tv_render_mode,format,buffering_mode);
} }
DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode){ DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode) {
drc_store.buffer = buffer; drc_store.buffer = buffer;
drc_store.buffer_size = buffer_size; drc_store.buffer_size = buffer_size;
drc_store.mode = drc_mode; drc_store.mode = drc_mode;
@ -43,7 +43,7 @@ DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 sur
return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode); return real_GX2SetDRCBuffer(buffer,buffer_size,drc_mode,surface_format,buffering_mode);
} }
DECL(void, GX2WaitForVsync, void){ DECL(void, GX2WaitForVsync, void) {
real_GX2WaitForVsync(); real_GX2WaitForVsync();
} }

View File

@ -30,25 +30,29 @@
#include <utils/logger.h> #include <utils/logger.h>
bool ElfTools::elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination) { bool ElfTools::elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination) {
if (destination == NULL) { return false; } if (destination == NULL) {
return false;
}
switch (shdr->sh_type) { switch (shdr->sh_type) {
case SHT_SYMTAB: case SHT_SYMTAB:
case SHT_PROGBITS: { case SHT_PROGBITS: {
Elf_Data *data; Elf_Data *data;
size_t n; size_t n;
n = 0; n = 0;
for (data = elf_getdata(scn, NULL); data != NULL; data = elf_getdata(scn, data)) { for (data = elf_getdata(scn, NULL); data != NULL; data = elf_getdata(scn, data)) {
memcpy((char *)destination + n, data->d_buf, data->d_size); memcpy((char *)destination + n, data->d_buf, data->d_size);
n += data->d_size; n += data->d_size;
} }
return true; return true;
} case SHT_NOBITS: { }
memset(destination, 0, shdr->sh_size); case SHT_NOBITS: {
return true; memset(destination, 0, shdr->sh_size);
} default: return true;
return false; }
default:
return false;
} }
} }
@ -61,30 +65,30 @@ bool ElfTools::loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count,
Elf32_Shdr *shdr; Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn); shdr = elf32_getshdr(scn);
if (shdr == NULL){ if (shdr == NULL) {
continue; continue;
} }
if (shdr->sh_type == SHT_SYMTAB) { if (shdr->sh_type == SHT_SYMTAB) {
size_t sym; size_t sym;
if (*symtab != NULL){ if (*symtab != NULL) {
continue; continue;
} }
*symtab = (Elf32_Sym *)malloc(shdr->sh_size); *symtab = (Elf32_Sym *)malloc(shdr->sh_size);
if (*symtab == NULL){ if (*symtab == NULL) {
continue; continue;
} }
*symtab_count = shdr->sh_size / sizeof(Elf32_Sym); *symtab_count = shdr->sh_size / sizeof(Elf32_Sym);
*symtab_strndx = shdr->sh_link; *symtab_strndx = shdr->sh_link;
if (!elfLoadSection(elf, scn, shdr, *symtab)){ if (!elfLoadSection(elf, scn, shdr, *symtab)) {
goto exit_error; goto exit_error;
} }
for (sym = 0; sym < *symtab_count; sym++){ for (sym = 0; sym < *symtab_count; sym++) {
(*symtab)[sym].st_other = 0; (*symtab)[sym].st_other = 0;
} }
@ -92,7 +96,7 @@ bool ElfTools::loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count,
} }
} }
if (*symtab == NULL){ if (*symtab == NULL) {
goto exit_error; goto exit_error;
} }
@ -109,7 +113,7 @@ void ElfTools::elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *
* symbol address has been calculated. */ * symbol address has been calculated. */
for (i = 0; i < symtab_count; i++) { for (i = 0; i < symtab_count; i++) {
if (symtab[i].st_shndx == shndx && if (symtab[i].st_shndx == shndx &&
symtab[i].st_other == 0) { symtab[i].st_other == 0) {
symtab[i].st_value += (Elf32_Addr)destination; symtab[i].st_value += (Elf32_Addr)destination;
symtab[i].st_other = 1; symtab[i].st_other = 1;
@ -129,185 +133,192 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
continue; continue;
switch (shdr->sh_type) { switch (shdr->sh_type) {
case SHT_REL: { case SHT_REL: {
const Elf32_Rel *rel; const Elf32_Rel *rel;
Elf_Data *data; Elf_Data *data;
size_t i; size_t i;
if (shdr->sh_info != shndx){ if (shdr->sh_info != shndx) {
continue; continue;
}
data = elf_getdata(scn, NULL);
if (data == NULL){
continue;
}
rel = (const Elf32_Rel *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rel); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rel[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
} case SHN_COMMON: {
return false;
} case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
reloc->module = index;
reloc->address = destination;
reloc->offset = rel[i].r_offset;
reloc->type = ELF32_R_TYPE(rel[i].r_info);
reloc->addend = *(int *)((char *)destination + rel[i].r_offset);
continue;
*/
return false;
} else {
return false;
}
} default: {
if (symtab[symbol].st_other != 1) {
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int *)((char *)destination + rel[i].r_offset), destination, symbol_addr)){
return false;
}
}
break;
} case SHT_RELA: {
const Elf32_Rela *rela;
Elf_Data *data;
size_t i;
if (shdr->sh_info != shndx)
continue;
data = elf_getdata(scn, NULL);
if (data == NULL)
continue;
rela = (const Elf32_Rela *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rela); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rela[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
} case SHN_COMMON: {
return false;
} case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
DEBUG_FUNCTION_LINE("Adding relocation!\n");
reloc->module = index;
reloc->address = destination;
reloc->offset = rela[i].r_offset;
reloc->type = ELF32_R_TYPE(rela[i].r_info);
reloc->addend = rela[i].r_addend;
continue;*/
return false;
} else
return false;
} default: {
if (symtab[symbol].st_other != 1){
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)){
return false;
}
}
break;
} }
data = elf_getdata(scn, NULL);
if (data == NULL) {
continue;
}
rel = (const Elf32_Rel *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rel); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rel[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
}
case SHN_COMMON: {
return false;
}
case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
reloc->module = index;
reloc->address = destination;
reloc->offset = rel[i].r_offset;
reloc->type = ELF32_R_TYPE(rel[i].r_info);
reloc->addend = *(int *)((char *)destination + rel[i].r_offset);
continue;
*/
return false;
} else {
return false;
}
}
default: {
if (symtab[symbol].st_other != 1) {
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int *)((char *)destination + rel[i].r_offset), destination, symbol_addr)) {
return false;
}
}
break;
}
case SHT_RELA: {
const Elf32_Rela *rela;
Elf_Data *data;
size_t i;
if (shdr->sh_info != shndx)
continue;
data = elf_getdata(scn, NULL);
if (data == NULL)
continue;
rela = (const Elf32_Rela *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rela); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rela[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
}
case SHN_COMMON: {
return false;
}
case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
DEBUG_FUNCTION_LINE("Adding relocation!\n");
reloc->module = index;
reloc->address = destination;
reloc->offset = rela[i].r_offset;
reloc->type = ELF32_R_TYPE(rela[i].r_info);
reloc->addend = rela[i].r_addend;
continue;*/
return false;
} else
return false;
}
default: {
if (symtab[symbol].st_other != 1) {
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)) {
return false;
}
}
break;
}
} }
} }
@ -320,104 +331,118 @@ bool ElfTools::elfLinkOne(char type, size_t offset, int addend, void *destinatio
bool result = false; bool result = false;
switch (type) { switch (type) {
case R_PPC_ADDR32: case R_PPC_ADDR32:
case R_PPC_ADDR24: case R_PPC_ADDR24:
case R_PPC_ADDR16: case R_PPC_ADDR16:
case R_PPC_ADDR16_HI: case R_PPC_ADDR16_HI:
case R_PPC_ADDR16_HA: case R_PPC_ADDR16_HA:
case R_PPC_ADDR16_LO: case R_PPC_ADDR16_LO:
case R_PPC_ADDR14: case R_PPC_ADDR14:
case R_PPC_ADDR14_BRTAKEN: case R_PPC_ADDR14_BRTAKEN:
case R_PPC_ADDR14_BRNTAKEN: case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_UADDR32: case R_PPC_UADDR32:
case R_PPC_UADDR16: { case R_PPC_UADDR16: {
value = (int)symbol_addr + addend; value = (int)symbol_addr + addend;
break; break;
} case R_PPC_REL24: }
case R_PPC_PLTREL24: case R_PPC_REL24:
case R_PPC_LOCAL24PC: case R_PPC_PLTREL24:
case R_PPC_REL14: case R_PPC_LOCAL24PC:
case R_PPC_REL14_BRTAKEN: case R_PPC_REL14:
case R_PPC_REL14_BRNTAKEN: case R_PPC_REL14_BRTAKEN:
case R_PPC_REL32: case R_PPC_REL14_BRNTAKEN:
case R_PPC_ADDR30: { case R_PPC_REL32:
value = (int)symbol_addr + addend - (int)target; case R_PPC_ADDR30: {
break; value = (int)symbol_addr + addend - (int)target;
} case R_PPC_SECTOFF: break;
case R_PPC_SECTOFF_LO: }
case R_PPC_SECTOFF_HI: case R_PPC_SECTOFF:
case R_PPC_SECTOFF_HA: { case R_PPC_SECTOFF_LO:
value = offset + addend; case R_PPC_SECTOFF_HI:
break; case R_PPC_SECTOFF_HA: {
} case R_PPC_EMB_NADDR32: value = offset + addend;
case R_PPC_EMB_NADDR16: break;
case R_PPC_EMB_NADDR16_LO: }
case R_PPC_EMB_NADDR16_HI: case R_PPC_EMB_NADDR32:
case R_PPC_EMB_NADDR16_HA: { case R_PPC_EMB_NADDR16:
value = addend - (int)symbol_addr; case R_PPC_EMB_NADDR16_LO:
break; case R_PPC_EMB_NADDR16_HI:
} default: case R_PPC_EMB_NADDR16_HA: {
DEBUG_FUNCTION_LINE("Unknown relocation type: %02X\n",type); value = addend - (int)symbol_addr;
goto exit_error; break;
}
default:
DEBUG_FUNCTION_LINE("Unknown relocation type: %02X\n",type);
goto exit_error;
} }
switch (type) { switch (type) {
case R_PPC_ADDR32: case R_PPC_ADDR32:
case R_PPC_UADDR32: case R_PPC_UADDR32:
case R_PPC_REL32: case R_PPC_REL32:
case R_PPC_SECTOFF: case R_PPC_SECTOFF:
case R_PPC_EMB_NADDR32: { case R_PPC_EMB_NADDR32: {
*(int *)target = value; *(int *)target = value;
break; break;
} case R_PPC_ADDR24: }
case R_PPC_PLTREL24: case R_PPC_ADDR24:
case R_PPC_LOCAL24PC: case R_PPC_PLTREL24:
case R_PPC_REL24: { case R_PPC_LOCAL24PC:
*(int *)target = case R_PPC_REL24: {
(*(int *)target & 0xfc000003) | (value & 0x03fffffc); *(int *)target =
break; (*(int *)target & 0xfc000003) | (value & 0x03fffffc);
} case R_PPC_ADDR16: break;
case R_PPC_UADDR16: }
case R_PPC_EMB_NADDR16: { case R_PPC_ADDR16:
*(short *)target = value; case R_PPC_UADDR16:
break; case R_PPC_EMB_NADDR16: {
} case R_PPC_ADDR16_HI: *(short *)target = value;
case R_PPC_SECTOFF_HI: break;
case R_PPC_EMB_NADDR16_HI: { }
*(short *)target = value >> 16; case R_PPC_ADDR16_HI:
break; case R_PPC_SECTOFF_HI:
} case R_PPC_ADDR16_HA: case R_PPC_EMB_NADDR16_HI: {
case R_PPC_SECTOFF_HA: *(short *)target = value >> 16;
case R_PPC_EMB_NADDR16_HA: { break;
*(short *)target = (value >> 16) + ((value >> 15) & 1); }
break; case R_PPC_ADDR16_HA:
} case R_PPC_ADDR16_LO: case R_PPC_SECTOFF_HA:
case R_PPC_SECTOFF_LO: case R_PPC_EMB_NADDR16_HA: {
case R_PPC_EMB_NADDR16_LO: { *(short *)target = (value >> 16) + ((value >> 15) & 1);
*(short *)target = value & 0xffff; break;
break; }
} case R_PPC_ADDR14: case R_PPC_ADDR16_LO:
case R_PPC_REL14: { case R_PPC_SECTOFF_LO:
*(int *)target = case R_PPC_EMB_NADDR16_LO: {
(*(int *)target & 0xffff0003) | (value & 0x0000fffc); *(short *)target = value & 0xffff;
break; break;
} case R_PPC_ADDR14_BRTAKEN: }
case R_PPC_REL14_BRTAKEN: { case R_PPC_ADDR14:
*(int *)target = case R_PPC_REL14: {
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc) | *(int *)target =
0x00200000; (*(int *)target & 0xffff0003) | (value & 0x0000fffc);
break; break;
} case R_PPC_ADDR14_BRNTAKEN: }
case R_PPC_REL14_BRNTAKEN: { case R_PPC_ADDR14_BRTAKEN:
*(int *)target = case R_PPC_REL14_BRTAKEN: {
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc); *(int *)target =
break; (*(int *)target & 0xffdf0003) | (value & 0x0000fffc) |
} case R_PPC_ADDR30: { 0x00200000;
*(int *)target = break;
(*(int *)target & 0x00000003) | (value & 0xfffffffc); }
break; case R_PPC_ADDR14_BRNTAKEN:
}default: case R_PPC_REL14_BRNTAKEN: {
goto exit_error; *(int *)target =
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc);
break;
}
case R_PPC_ADDR30: {
*(int *)target =
(*(int *)target & 0x00000003) | (value & 0xfffffffc);
break;
}
default:
goto exit_error;
} }
result = true; result = true;

View File

@ -36,7 +36,7 @@ extern "C" {
} }
#endif #endif
class ElfTools{ class ElfTools {
public: public:
static bool elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination); static bool elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination);

View File

@ -21,28 +21,28 @@
#include <wups.h> #include <wups.h>
#include <string> #include <string>
class HookData{ class HookData {
public: public:
HookData(void * function_pointer, wups_loader_hook_type_t type){ HookData(void * function_pointer, wups_loader_hook_type_t type) {
this->function_pointer = function_pointer; this->function_pointer = function_pointer;
this->type = type; this->type = type;
} }
~HookData(){ ~HookData() {
} }
void * getFunctionPointer(){ void * getFunctionPointer() {
return function_pointer; return function_pointer;
} }
wups_loader_hook_type_t getType(){ wups_loader_hook_type_t getType() {
return this->type; return this->type;
} }
private: private:
void * function_pointer; void * function_pointer;
wups_loader_hook_type_t type; wups_loader_hook_type_t type;
}; };

View File

@ -35,52 +35,52 @@ extern "C" {
} }
#endif #endif
class PluginData{ class PluginData {
public: public:
PluginData(PluginInformation * pluginInformation){ PluginData(PluginInformation * pluginInformation) {
this->pluginInformation = pluginInformation; this->pluginInformation = pluginInformation;
} }
~PluginData(){ ~PluginData() {
for(size_t i = 0;i< function_data_list.size();i++){ for(size_t i = 0; i< function_data_list.size(); i++) {
if(function_data_list[i] != NULL){ if(function_data_list[i] != NULL) {
delete function_data_list[i]; delete function_data_list[i];
}
}
for(size_t i = 0;i< hook_data_list.size();i++){
if(hook_data_list[i] != NULL){
delete hook_data_list[i];
}
} }
} }
void addFunctionData(FunctionData * function_data){ for(size_t i = 0; i< hook_data_list.size(); i++) {
function_data_list.push_back(function_data); if(hook_data_list[i] != NULL) {
delete hook_data_list[i];
}
} }
}
std::vector<FunctionData *> getFunctionDataList(){ void addFunctionData(FunctionData * function_data) {
return function_data_list; function_data_list.push_back(function_data);
} }
void addHookData(HookData * hook_data){ std::vector<FunctionData *> getFunctionDataList() {
hook_data_list.push_back(hook_data); return function_data_list;
} }
std::vector<HookData *> getHookDataList(){ void addHookData(HookData * hook_data) {
return hook_data_list; hook_data_list.push_back(hook_data);
} }
PluginInformation * getPluginInformation(){ std::vector<HookData *> getHookDataList() {
return pluginInformation; return hook_data_list;
} }
private: PluginInformation * getPluginInformation() {
return pluginInformation;
}
PluginInformation * pluginInformation; private:
std::vector<FunctionData *> function_data_list; PluginInformation * pluginInformation;
std::vector<HookData *> hook_data_list;
std::vector<FunctionData *> function_data_list;
std::vector<HookData *> hook_data_list;
}; };

View File

@ -37,27 +37,27 @@
#include "ElfTools.h" #include "ElfTools.h"
bool PluginInformation::checkFileExtenstion(const char * path) { bool PluginInformation::checkFileExtenstion(const char * path) {
if(path == NULL){ if(path == NULL) {
return false; return false;
} }
const char *extension; const char *extension;
/* find the file extension */ /* find the file extension */
extension = strrchr(path, '.'); extension = strrchr(path, '.');
if (extension == NULL){ if (extension == NULL) {
extension = strchr(path, '\0'); extension = strchr(path, '\0');
}else{ } else {
extension++; extension++;
} }
if(extension == NULL){ if(extension == NULL) {
return false; return false;
} }
if (strcmp(extension, "mod") == 0 || if (strcmp(extension, "mod") == 0 ||
strcmp(extension, "o") == 0 || strcmp(extension, "o") == 0 ||
strcmp(extension, "a") == 0 || strcmp(extension, "a") == 0 ||
strcmp(extension, "elf") == 0) { strcmp(extension, "elf") == 0) {
return true; return true;
} }
return false; return false;
@ -69,42 +69,42 @@ bool PluginInformation::openAndParseElf() {
Elf *elf = NULL; Elf *elf = NULL;
/* check for compile errors */ /* check for compile errors */
if (elf_version(EV_CURRENT) == EV_NONE){ if (elf_version(EV_CURRENT) == EV_NONE) {
goto exit_error; goto exit_error;
} }
fd = open(getPath().c_str(), O_RDONLY, 0); fd = open(getPath().c_str(), O_RDONLY, 0);
if (fd == -1){ if (fd == -1) {
DEBUG_FUNCTION_LINE("failed to open '%s' \n", getPath().c_str()); DEBUG_FUNCTION_LINE("failed to open '%s' \n", getPath().c_str());
goto exit_error; goto exit_error;
} }
elf = elf_begin(fd, ELF_C_READ, NULL); elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL){ if (elf == NULL) {
DEBUG_FUNCTION_LINE("elf was NULL\n"); DEBUG_FUNCTION_LINE("elf was NULL\n");
goto exit_error; goto exit_error;
} }
switch (elf_kind(elf)) { switch (elf_kind(elf)) {
case ELF_K_AR: case ELF_K_AR:
/* TODO */ /* TODO */
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Archives not yet supported.\n", getPath().c_str()); DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Archives not yet supported.\n", getPath().c_str());
goto exit_error; goto exit_error;
case ELF_K_ELF: case ELF_K_ELF:
result = this->parseElf(elf); result = this->parseElf(elf);
break; break;
default: default:
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF file.\n", getPath().c_str()); DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF file.\n", getPath().c_str());
goto exit_error; goto exit_error;
} }
exit_error: exit_error:
if (elf != NULL){ if (elf != NULL) {
elf_end(elf); elf_end(elf);
} }
if (fd != -1){ if (fd != -1) {
close(fd); close(fd);
} }
return result; return result;
@ -122,8 +122,12 @@ bool PluginInformation::parseElf( Elf *elf) {
const char * path_c = getPath().c_str(); const char * path_c = getPath().c_str();
if(elf == NULL){ goto exit_error; } if(elf == NULL) {
if(elf_kind(elf) != ELF_K_ELF){ goto exit_error; } goto exit_error;
}
if(elf_kind(elf) != ELF_K_ELF) {
goto exit_error;
}
ident = elf_getident(elf, &sz); ident = elf_getident(elf, &sz);
@ -172,9 +176,11 @@ bool PluginInformation::parseElf( Elf *elf) {
goto exit_error; goto exit_error;
} }
if(symtab == NULL){ goto exit_error; } if(symtab == NULL) {
goto exit_error;
}
if(!metadataRead(elf, symtab, symtab_count, symtab_strndx)){ if(!metadataRead(elf, symtab, symtab_count, symtab_strndx)) {
goto exit_error; goto exit_error;
} }
@ -187,17 +193,17 @@ bool PluginInformation::parseElf( Elf *elf) {
Elf32_Shdr *shdr; Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn); shdr = elf32_getshdr(scn);
if (shdr == NULL){ if (shdr == NULL) {
continue; continue;
} }
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
(shdr->sh_flags & SHF_ALLOC)) { (shdr->sh_flags & SHF_ALLOC)) {
const char *name; const char *name;
name = elf_strptr(elf, shstrndx, shdr->sh_name); name = elf_strptr(elf, shstrndx, shdr->sh_name);
if (name == NULL){ if (name == NULL) {
continue; continue;
} }
@ -212,10 +218,10 @@ bool PluginInformation::parseElf( Elf *elf) {
} else { } else {
cur_size += shdr->sh_size; cur_size += shdr->sh_size;
/* add alignment padding to size */ /* add alignment padding to size */
if (shdr->sh_addralign > 3){ if (shdr->sh_addralign > 3) {
/* roundup to multiple of sh_addralign */ /* roundup to multiple of sh_addralign */
cur_size += (-cur_size & (shdr->sh_addralign - 1)); cur_size += (-cur_size & (shdr->sh_addralign - 1));
}else{ } else {
/* roundup to multiple of 4 */ /* roundup to multiple of 4 */
cur_size += (-cur_size & 3); cur_size += (-cur_size & 3);
} }
@ -230,7 +236,7 @@ bool PluginInformation::parseElf( Elf *elf) {
res = true; res = true;
exit_error: exit_error:
if (symtab != NULL){ if (symtab != NULL) {
free(symtab); free(symtab);
} }
@ -254,27 +260,27 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
const char *name; const char *name;
shdr = elf32_getshdr(scn); shdr = elf32_getshdr(scn);
if (shdr == NULL){ if (shdr == NULL) {
continue; continue;
} }
name = elf_strptr(elf, shstrndx, shdr->sh_name); name = elf_strptr(elf, shstrndx, shdr->sh_name);
if (name == NULL){ if (name == NULL) {
continue; continue;
} }
if (strcmp(name, ".wups.meta") == 0) { if (strcmp(name, ".wups.meta") == 0) {
if (shdr->sh_size == 0){ if (shdr->sh_size == 0) {
continue; continue;
} }
if (metadata != NULL){ if (metadata != NULL) {
continue; continue;
} }
metadata = (char*) malloc(shdr->sh_size); metadata = (char*) malloc(shdr->sh_size);
if (metadata == NULL){ if (metadata == NULL) {
continue; continue;
} }
@ -312,16 +318,16 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
char *eq; char *eq;
if(metadata_cur < metadata || metadata_cur >= metadata_end){ if(metadata_cur < metadata || metadata_cur >= metadata_end) {
goto exit_error; goto exit_error;
} }
if (*metadata_cur == '\0'){ if (*metadata_cur == '\0') {
continue; continue;
} }
eq = strchr(metadata_cur, '='); eq = strchr(metadata_cur, '=');
if (eq == NULL){ if (eq == NULL) {
continue; continue;
} }
@ -370,7 +376,7 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
} }
} }
if (description == NULL){ if (description == NULL) {
description = ""; description = "";
} }
@ -410,7 +416,7 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
exit_error: exit_error:
if (metadata != NULL){ if (metadata != NULL) {
free(metadata); free(metadata);
} }
return false; return false;

View File

@ -42,109 +42,109 @@ extern "C" {
} }
#endif #endif
class PluginInformation{ class PluginInformation {
public: public:
/** /**
returns PluginInformation* if a valid plugin was found at the given path. Otherwise returns NULL returns PluginInformation* if a valid plugin was found at the given path. Otherwise returns NULL
**/ **/
static PluginInformation * loadPluginInformation(std::string path){ static PluginInformation * loadPluginInformation(std::string path) {
if(PluginInformation::checkFileExtenstion(path.c_str())){ if(PluginInformation::checkFileExtenstion(path.c_str())) {
DEBUG_FUNCTION_LINE("Checkfile successfully, loading now Plugin Information\n"); DEBUG_FUNCTION_LINE("Checkfile successfully, loading now Plugin Information\n");
PluginInformation * pluginInformation = new PluginInformation(path); PluginInformation * pluginInformation = new PluginInformation(path);
if(pluginInformation->openAndParseElf()){ if(pluginInformation->openAndParseElf()) {
return pluginInformation; return pluginInformation;
}else{
delete pluginInformation;
return NULL;
}
} else { } else {
delete pluginInformation;
return NULL; return NULL;
} }
} else {
return NULL;
} }
}
std::string getName(){ std::string getName() {
return this->name; return this->name;
} }
std::string getAuthor(){ std::string getAuthor() {
return this->author; return this->author;
} }
std::string getVersion(){ std::string getVersion() {
return this->version; return this->version;
} }
std::string getLicense(){ std::string getLicense() {
return this->license; return this->license;
} }
std::string getBuildTimestamp(){ std::string getBuildTimestamp() {
return this->buildtimestamp; return this->buildtimestamp;
} }
std::string getDescription(){ std::string getDescription() {
return this->description; return this->description;
} }
std::string getPath(){ std::string getPath() {
return path; return path;
} }
size_t getSize(){ size_t getSize() {
return this->size; return this->size;
} }
private: private:
PluginInformation(std::string path){ PluginInformation(std::string path) {
this->path = path; this->path = path;
} }
void setName(const char * name){ void setName(const char * name) {
this->name = name; this->name = name;
} }
void setAuthor(const char * author){ void setAuthor(const char * author) {
this->author = author; this->author = author;
} }
void setVersion(const char * version){ void setVersion(const char * version) {
this->version = version; this->version = version;
} }
void setLicense(const char * license){ void setLicense(const char * license) {
this->license = license; this->license = license;
} }
void setBuildTimestamp(const char * buildtimestamp){ void setBuildTimestamp(const char * buildtimestamp) {
this->buildtimestamp = buildtimestamp; this->buildtimestamp = buildtimestamp;
} }
void setDescription(const char * description){ void setDescription(const char * description) {
this->description = description; this->description = description;
} }
void setSize(size_t size){ void setSize(size_t size) {
this->size = size; this->size = size;
} }
static bool checkFileExtenstion(const char * path); static bool checkFileExtenstion(const char * path);
bool openAndParseElf(); bool openAndParseElf();
bool parseElf(Elf *elf); bool parseElf(Elf *elf);
bool metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx); bool metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx);
bool loadedSuccessfully = false; bool loadedSuccessfully = false;
std::string path; std::string path;
std::string name; std::string name;
std::string author; std::string author;
std::string version; std::string version;
std::string license; std::string license;
std::string buildtimestamp; std::string buildtimestamp;
std::string description; std::string description;
size_t size; size_t size;
}; };

View File

@ -36,36 +36,36 @@
PluginLoader * PluginLoader::instance = NULL; PluginLoader * PluginLoader::instance = NULL;
std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char * path){ std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char * path) {
std::vector<PluginInformation *> result; std::vector<PluginInformation *> result;
struct dirent *dp; struct dirent *dp;
DIR *dfd = NULL; DIR *dfd = NULL;
if(path == NULL){ if(path == NULL) {
DEBUG_FUNCTION_LINE("Path was NULL"); DEBUG_FUNCTION_LINE("Path was NULL");
return result; return result;
} }
if ((dfd = opendir(path)) == NULL){ if ((dfd = opendir(path)) == NULL) {
DEBUG_FUNCTION_LINE("Couldn't open dir %s",path); DEBUG_FUNCTION_LINE("Couldn't open dir %s",path);
return result; return result;
} }
while ((dp = readdir(dfd)) != NULL){ while ((dp = readdir(dfd)) != NULL) {
struct stat stbuf ; struct stat stbuf ;
std::string full_file_path = StringTools::strfmt("%s/%s",path,dp->d_name); std::string full_file_path = StringTools::strfmt("%s/%s",path,dp->d_name);
StringTools::RemoveDoubleSlashs(full_file_path); StringTools::RemoveDoubleSlashs(full_file_path);
if( stat(full_file_path.c_str(),&stbuf ) == -1 ){ if( stat(full_file_path.c_str(),&stbuf ) == -1 ) {
DEBUG_FUNCTION_LINE("Unable to stat file: %s\n",full_file_path.c_str()) ; DEBUG_FUNCTION_LINE("Unable to stat file: %s\n",full_file_path.c_str()) ;
continue; continue;
} }
if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ){ // Skip directories if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ) { // Skip directories
continue; continue;
}else{ } else {
DEBUG_FUNCTION_LINE("Found file: %s\n",full_file_path.c_str()) ; DEBUG_FUNCTION_LINE("Found file: %s\n",full_file_path.c_str()) ;
PluginInformation * plugin = PluginInformation::loadPluginInformation(full_file_path); PluginInformation * plugin = PluginInformation::loadPluginInformation(full_file_path);
if(plugin != NULL){ if(plugin != NULL) {
DEBUG_FUNCTION_LINE("Found plugin %s by %s. Built on %s Size: %d kb \n",plugin->getName().c_str(),plugin->getAuthor().c_str(),plugin->getBuildTimestamp().c_str(),plugin->getSize()/1024) ; DEBUG_FUNCTION_LINE("Found plugin %s by %s. Built on %s Size: %d kb \n",plugin->getName().c_str(),plugin->getAuthor().c_str(),plugin->getBuildTimestamp().c_str(),plugin->getSize()/1024) ;
DEBUG_FUNCTION_LINE("Description: %s \n",plugin->getDescription().c_str()) ; DEBUG_FUNCTION_LINE("Description: %s \n",plugin->getDescription().c_str()) ;
result.push_back(plugin); result.push_back(plugin);
@ -78,24 +78,24 @@ std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char *
return result; return result;
} }
std::vector<PluginInformation *> PluginLoader::getPluginsLoadedInMemory(){ std::vector<PluginInformation *> PluginLoader::getPluginsLoadedInMemory() {
std::vector<PluginInformation *> pluginInformation; std::vector<PluginInformation *> pluginInformation;
for(s32 i = 0; i < gbl_replacement_data.number_used_plugins; i++){ for(s32 i = 0; i < gbl_replacement_data.number_used_plugins; i++) {
replacement_data_plugin_t * pluginInfo = &gbl_replacement_data.plugin_data[i]; replacement_data_plugin_t * pluginInfo = &gbl_replacement_data.plugin_data[i];
PluginInformation * curPlugin = PluginInformation::loadPluginInformation(pluginInfo->path); PluginInformation * curPlugin = PluginInformation::loadPluginInformation(pluginInfo->path);
if(curPlugin != NULL){ if(curPlugin != NULL) {
pluginInformation.push_back(curPlugin); pluginInformation.push_back(curPlugin);
} }
} }
return pluginInformation; return pluginInformation;
} }
void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation){ void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation) {
std::vector<PluginData *> loadedPlugins; std::vector<PluginData *> loadedPlugins;
for(size_t i = 0;i < pluginInformation.size(); i++){ for(size_t i = 0; i < pluginInformation.size(); i++) {
PluginInformation * cur_info = pluginInformation[i]; PluginInformation * cur_info = pluginInformation[i];
PluginData * pluginData = loadAndLinkPlugin(cur_info); PluginData * pluginData = loadAndLinkPlugin(cur_info);
if(pluginData == NULL){ if(pluginData == NULL) {
DEBUG_FUNCTION_LINE("loadAndLinkPlugins failed for %d\n",i) ; DEBUG_FUNCTION_LINE("loadAndLinkPlugins failed for %d\n",i) ;
continue; continue;
} else { } else {
@ -107,81 +107,81 @@ void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInf
clearPluginData(loadedPlugins); clearPluginData(loadedPlugins);
} }
void PluginLoader::clearPluginData(std::vector<PluginData *> pluginData){ void PluginLoader::clearPluginData(std::vector<PluginData *> pluginData) {
for(size_t i = 0;i < pluginData.size(); i++){ for(size_t i = 0; i < pluginData.size(); i++) {
PluginData * curPluginData = pluginData[i]; PluginData * curPluginData = pluginData[i];
if(curPluginData != NULL){ if(curPluginData != NULL) {
delete curPluginData; delete curPluginData;
} }
} }
} }
void PluginLoader::clearPluginInformation(std::vector<PluginInformation *> pluginInformation){ void PluginLoader::clearPluginInformation(std::vector<PluginInformation *> pluginInformation) {
for(size_t i = 0;i < pluginInformation.size(); i++){ for(size_t i = 0; i < pluginInformation.size(); i++) {
PluginInformation * curPluginInformation = pluginInformation[i]; PluginInformation * curPluginInformation = pluginInformation[i];
if(curPluginInformation != NULL){ if(curPluginInformation != NULL) {
delete curPluginInformation; delete curPluginInformation;
} }
} }
} }
PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformation){ PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformation) {
PluginData * result = NULL; PluginData * result = NULL;
int fd = -1; int fd = -1;
Elf *elf = NULL; Elf *elf = NULL;
if(pluginInformation == NULL){ if(pluginInformation == NULL) {
DEBUG_FUNCTION_LINE("pluginInformation was NULL\n"); DEBUG_FUNCTION_LINE("pluginInformation was NULL\n");
goto exit_error; goto exit_error;
} }
if(pluginInformation->getSize() > ((u32) this->getCurrentStoreAddress() - (u32) this->startAddress)){ if(pluginInformation->getSize() > ((u32) this->getCurrentStoreAddress() - (u32) this->startAddress)) {
DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory\n"); DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory\n");
goto exit_error; goto exit_error;
} }
/* check for compile errors */ /* check for compile errors */
if (elf_version(EV_CURRENT) == EV_NONE){ if (elf_version(EV_CURRENT) == EV_NONE) {
goto exit_error; goto exit_error;
} }
fd = open(pluginInformation->getPath().c_str(), O_RDONLY, 0); fd = open(pluginInformation->getPath().c_str(), O_RDONLY, 0);
if (fd == -1){ if (fd == -1) {
DEBUG_FUNCTION_LINE("failed to open '%s' \n", pluginInformation->getPath().c_str()); DEBUG_FUNCTION_LINE("failed to open '%s' \n", pluginInformation->getPath().c_str());
goto exit_error; goto exit_error;
} }
elf = elf_begin(fd, ELF_C_READ, NULL); elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL){ if (elf == NULL) {
DEBUG_FUNCTION_LINE("elf was NULL\n"); DEBUG_FUNCTION_LINE("elf was NULL\n");
goto exit_error; goto exit_error;
} }
result = new PluginData(pluginInformation); result = new PluginData(pluginInformation);
if(result == NULL){ if(result == NULL) {
DEBUG_FUNCTION_LINE("Failed to create object\n"); DEBUG_FUNCTION_LINE("Failed to create object\n");
goto exit_error; goto exit_error;
} }
if(!this->loadAndLinkElf(result, elf, this->getCurrentStoreAddress())){ if(!this->loadAndLinkElf(result, elf, this->getCurrentStoreAddress())) {
delete result; delete result;
result = NULL; result = NULL;
} }
exit_error: exit_error:
if (elf != NULL){ if (elf != NULL) {
elf_end(elf); elf_end(elf);
} }
if (fd != -1){ if (fd != -1) {
close(fd); close(fd);
} }
return result; return result;
} }
bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endAddress) { bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endAddress) {
if(pluginData == NULL || elf == NULL || endAddress == NULL){ if(pluginData == NULL || elf == NULL || endAddress == NULL) {
return false; return false;
} }
@ -203,18 +203,18 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
std::vector<FunctionData *> function_data_list; std::vector<FunctionData *> function_data_list;
std::vector<HookData *> hook_data_list; std::vector<HookData *> hook_data_list;
if (!ElfTools::loadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx)){ if (!ElfTools::loadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx)) {
goto exit_error; goto exit_error;
} }
if(symtab == NULL){ if(symtab == NULL) {
goto exit_error;
}
if (elf_getshdrnum(elf, &section_count) != 0){
goto exit_error; goto exit_error;
} }
if (elf_getshdrstrndx(elf, &shstrndx) != 0){
if (elf_getshdrnum(elf, &section_count) != 0) {
goto exit_error;
}
if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
goto exit_error; goto exit_error;
} }
@ -224,85 +224,85 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
Elf32_Shdr *shdr; Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn); shdr = elf32_getshdr(scn);
if (shdr == NULL){ if (shdr == NULL) {
continue; continue;
} }
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
(shdr->sh_flags & SHF_ALLOC)) { (shdr->sh_flags & SHF_ALLOC)) {
const char *name; const char *name;
destinations[elf_ndxscn(scn)] = NULL; destinations[elf_ndxscn(scn)] = NULL;
name = elf_strptr(elf, shstrndx, shdr->sh_name); name = elf_strptr(elf, shstrndx, shdr->sh_name);
if (name == NULL){ if (name == NULL) {
continue; continue;
} }
if (strcmp(name, ".wups.meta") == 0) { if (strcmp(name, ".wups.meta") == 0) {
continue; continue;
} else if (strcmp(name, ".wups.load") == 0) { } else if (strcmp(name, ".wups.load") == 0) {
if (entries != NULL){ if (entries != NULL) {
goto exit_error; goto exit_error;
} }
entries_count = shdr->sh_size / sizeof(wups_loader_entry_t); entries_count = shdr->sh_size / sizeof(wups_loader_entry_t);
entries = (wups_loader_entry_t *) malloc(sizeof(wups_loader_entry_t) * entries_count); entries = (wups_loader_entry_t *) malloc(sizeof(wups_loader_entry_t) * entries_count);
if (entries == NULL){ if (entries == NULL) {
goto exit_error; goto exit_error;
} }
destinations[elf_ndxscn(scn)] = (uint8_t *)entries; destinations[elf_ndxscn(scn)] = (uint8_t *)entries;
if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)){ if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) {
goto exit_error; goto exit_error;
} }
ElfTools::elfLoadSymbols(elf_ndxscn(scn), entries, symtab, symtab_count); ElfTools::elfLoadSymbols(elf_ndxscn(scn), entries, symtab, symtab_count);
for(size_t i = 0;i< entries_count;i++){ for(size_t i = 0; i< entries_count; i++) {
entry_t_list.push_back(&entries[i]); entry_t_list.push_back(&entries[i]);
} }
}else if (strcmp(name, ".wups.hooks") == 0) { } else if (strcmp(name, ".wups.hooks") == 0) {
if (hooks != NULL){ if (hooks != NULL) {
goto exit_error; goto exit_error;
} }
hooks_count = shdr->sh_size / sizeof(wups_loader_hook_t); hooks_count = shdr->sh_size / sizeof(wups_loader_hook_t);
hooks = (wups_loader_hook_t *) malloc(sizeof(wups_loader_hook_t) * hooks_count); hooks = (wups_loader_hook_t *) malloc(sizeof(wups_loader_hook_t) * hooks_count);
if (hooks == NULL){ if (hooks == NULL) {
goto exit_error; goto exit_error;
} }
destinations[elf_ndxscn(scn)] = (uint8_t *)hooks; destinations[elf_ndxscn(scn)] = (uint8_t *)hooks;
if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)){ if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)) {
goto exit_error; goto exit_error;
} }
ElfTools::elfLoadSymbols(elf_ndxscn(scn), hooks, symtab, symtab_count); ElfTools::elfLoadSymbols(elf_ndxscn(scn), hooks, symtab, symtab_count);
for(size_t i = 0;i< hooks_count;i++){ for(size_t i = 0; i< hooks_count; i++) {
hook_t_list.push_back(&hooks[i]); hook_t_list.push_back(&hooks[i]);
} }
} else { } else {
curAddress -= shdr->sh_size; curAddress -= shdr->sh_size;
if (shdr->sh_addralign > 3){ if (shdr->sh_addralign > 3) {
curAddress = (u32)((int)curAddress & ~(shdr->sh_addralign - 1)); curAddress = (u32)((int)curAddress & ~(shdr->sh_addralign - 1));
} else { } else {
curAddress = (u32)((int)curAddress & ~3); curAddress = (u32)((int)curAddress & ~3);
} }
destinations[elf_ndxscn(scn)] = (uint8_t *) curAddress; destinations[elf_ndxscn(scn)] = (uint8_t *) curAddress;
if((u32) curAddress < (u32) this->startAddress){ if((u32) curAddress < (u32) this->startAddress) {
DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,curAddress); DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,curAddress);
goto exit_error; goto exit_error;
} }
//DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,curAddress); //DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,curAddress);
if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)){ if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)) {
goto exit_error; goto exit_error;
} }
ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) curAddress, symtab, symtab_count); ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) curAddress, symtab, symtab_count);
@ -314,21 +314,21 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
Elf32_Shdr *shdr; Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn); shdr = elf32_getshdr(scn);
if (shdr == NULL){ if (shdr == NULL) {
continue; continue;
} }
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) && if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
(shdr->sh_flags & SHF_ALLOC) && (shdr->sh_flags & SHF_ALLOC) &&
destinations[elf_ndxscn(scn)] != NULL) { destinations[elf_ndxscn(scn)] != NULL) {
if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true)){ if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true)) {
goto exit_error; goto exit_error;
} }
} }
} }
for(size_t j=0;j<hook_t_list.size();j++){ for(size_t j=0; j<hook_t_list.size(); j++) {
wups_loader_hook_t * hook = hook_t_list[j]; wups_loader_hook_t * hook = hook_t_list[j];
DEBUG_FUNCTION_LINE("Saving hook of plugin \"%s\". Type: %08X, target: %08X\n",pluginData->getPluginInformation()->getName().c_str(),hook->type,(void*) hook->target); DEBUG_FUNCTION_LINE("Saving hook of plugin \"%s\". Type: %08X, target: %08X\n",pluginData->getPluginInformation()->getName().c_str(),hook->type,(void*) hook->target);
@ -336,7 +336,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
pluginData->addHookData(hook_data); pluginData->addHookData(hook_data);
} }
for(size_t j=0;j<entry_t_list.size();j++){ for(size_t j=0; j<entry_t_list.size(); j++) {
wups_loader_entry_t * cur_function = entry_t_list[j]; wups_loader_entry_t * cur_function = entry_t_list[j];
DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin \"%s\". Library: %08X, target: %08X, call_addr: %08X\n",cur_function->_function.name,pluginData->getPluginInformation()->getName().c_str(),cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr); DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin \"%s\". Library: %08X, target: %08X, call_addr: %08X\n",cur_function->_function.name,pluginData->getPluginInformation()->getName().c_str(),cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr);
FunctionData * function_data = new FunctionData(cur_function->_function.name,cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr); FunctionData * function_data = new FunctionData(cur_function->_function.name,cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr);
@ -348,41 +348,41 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
result = true; result = true;
exit_error: exit_error:
if (!result) DEBUG_FUNCTION_LINE("exit_error\n"); if (!result) DEBUG_FUNCTION_LINE("exit_error\n");
if (destinations != NULL){ if (destinations != NULL) {
free(destinations); free(destinations);
} }
if (symtab != NULL){ if (symtab != NULL) {
free(symtab); free(symtab);
} }
if (hooks != NULL){ if (hooks != NULL) {
free(hooks); free(hooks);
} }
if (entries != NULL){ if (entries != NULL) {
free(entries); free(entries);
} }
return result; return result;
} }
void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins){ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins) {
// Reset data // Reset data
memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data)); memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data));
int plugin_index = 0; int plugin_index = 0;
// Copy data to global struct. // Copy data to global struct.
for(size_t i = 0; i< plugins.size();i++){ for(size_t i = 0; i< plugins.size(); i++) {
PluginData * cur_plugin = plugins.at(i); PluginData * cur_plugin = plugins.at(i);
PluginInformation * cur_pluginInformation = cur_plugin->getPluginInformation(); PluginInformation * cur_pluginInformation = cur_plugin->getPluginInformation();
std::vector<FunctionData *> function_data_list = cur_plugin->getFunctionDataList(); std::vector<FunctionData *> function_data_list = cur_plugin->getFunctionDataList();
std::vector<HookData *> hook_data_list = cur_plugin->getHookDataList(); std::vector<HookData *> hook_data_list = cur_plugin->getHookDataList();
if(plugin_index >= MAXIMUM_PLUGINS ){ if(plugin_index >= MAXIMUM_PLUGINS ) {
DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!\n",MAXIMUM_PLUGINS,cur_pluginInformation->getName().c_str()); DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!\n",MAXIMUM_PLUGINS,cur_pluginInformation->getName().c_str());
continue; continue;
} }
if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN){ if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),function_data_list.size(),MAXIMUM_FUNCTION_PER_PLUGIN); DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),function_data_list.size(),MAXIMUM_FUNCTION_PER_PLUGIN);
continue; continue;
} }
if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN){ if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would set too many hooks (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),hook_data_list.size(),MAXIMUM_HOOKS_PER_PLUGIN); DEBUG_FUNCTION_LINE("Plugin %s would set too many hooks (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),hook_data_list.size(),MAXIMUM_HOOKS_PER_PLUGIN);
continue; continue;
} }
@ -392,7 +392,7 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
strncpy(plugin_data->plugin_name,cur_pluginInformation->getName().c_str(),MAXIMUM_PLUGIN_NAME_LENGTH-1); strncpy(plugin_data->plugin_name,cur_pluginInformation->getName().c_str(),MAXIMUM_PLUGIN_NAME_LENGTH-1);
strncpy(plugin_data->path,cur_pluginInformation->getPath().c_str(),MAXIMUM_PLUGIN_PATH_NAME_LENGTH-1); strncpy(plugin_data->path,cur_pluginInformation->getPath().c_str(),MAXIMUM_PLUGIN_PATH_NAME_LENGTH-1);
for(size_t j = 0; j < function_data_list.size();j++){ for(size_t j = 0; j < function_data_list.size(); j++) {
replacement_data_function_t * function_data = &plugin_data->functions[j]; replacement_data_function_t * function_data = &plugin_data->functions[j];
FunctionData * cur_function = function_data_list[j]; FunctionData * cur_function = function_data_list[j];
@ -410,7 +410,7 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
DEBUG_FUNCTION_LINE("Entries for plugin \"%s\": %d\n",plugin_data->plugin_name,plugin_data->number_used_functions); DEBUG_FUNCTION_LINE("Entries for plugin \"%s\": %d\n",plugin_data->plugin_name,plugin_data->number_used_functions);
for(size_t j = 0; j < hook_data_list.size();j++){ for(size_t j = 0; j < hook_data_list.size(); j++) {
replacement_data_hook_t * hook_data = &plugin_data->hooks[j]; replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
HookData * hook_entry = hook_data_list[j]; HookData * hook_entry = hook_data_list[j];

View File

@ -44,18 +44,18 @@ extern "C" {
#define PLUGIN_LOCATION_END_ADDRESS 0x01000000 #define PLUGIN_LOCATION_END_ADDRESS 0x01000000
class PluginLoader{ class PluginLoader {
public: public:
static PluginLoader *getInstance() { static PluginLoader *getInstance() {
if(!instance){ if(!instance) {
instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS); instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS);
} }
return instance; return instance;
} }
static void destroyInstance() { static void destroyInstance() {
if(instance){ if(instance) {
delete instance; delete instance;
instance = NULL; instance = NULL;
} }
@ -95,27 +95,27 @@ public:
**/ **/
void clearPluginInformation(std::vector<PluginInformation*> PluginInformation); void clearPluginInformation(std::vector<PluginInformation*> PluginInformation);
size_t getTotalSpace(){ size_t getTotalSpace() {
return ((u32) this->endAddress - (u32) this->startAddress); return ((u32) this->endAddress - (u32) this->startAddress);
} }
size_t getAvailableSpace(){ size_t getAvailableSpace() {
return ((u32) this->currentStoreAddress - (u32) this->startAddress); return ((u32) this->currentStoreAddress - (u32) this->startAddress);
} }
size_t getUsedSpace(){ size_t getUsedSpace() {
return getTotalSpace() - getAvailableSpace(); return getTotalSpace() - getAvailableSpace();
} }
private: private:
PluginLoader(void * startAddress, void * endAddress){ PluginLoader(void * startAddress, void * endAddress) {
// TODO: Check if endAddress > startAddress. // TODO: Check if endAddress > startAddress.
this->startAddress = startAddress; this->startAddress = startAddress;
this->endAddress = endAddress; this->endAddress = endAddress;
this->currentStoreAddress = endAddress; this->currentStoreAddress = endAddress;
} }
~PluginLoader(){ ~PluginLoader() {
} }
@ -147,19 +147,19 @@ private:
**/ **/
bool loadAndLinkElf(PluginData * pluginData, Elf *elf, void * storeAddressEnd); bool loadAndLinkElf(PluginData * pluginData, Elf *elf, void * storeAddressEnd);
/** /**
\brief Copies the needed information into a global, persistent struct. This struct holds information on which \brief Copies the needed information into a global, persistent struct. This struct holds information on which
function should be override in which order and which hook should be called. function should be override in which order and which hook should be called.
\param plugins list of plugins that should be used. \param plugins list of plugins that should be used.
**/ **/
void copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins); void copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins);
void * getCurrentStoreAddress(){ void * getCurrentStoreAddress() {
return this->currentStoreAddress; return this->currentStoreAddress;
} }
void setCurrentStoreAddress(void * addr){ void setCurrentStoreAddress(void * addr) {
this->currentStoreAddress = addr; this->currentStoreAddress = addr;
} }

View File

@ -33,27 +33,24 @@
CSettings *CSettings::settingsInstance = NULL; CSettings *CSettings::settingsInstance = NULL;
CSettings::CSettings(){ CSettings::CSettings() {
bChanged = false; bChanged = false;
memset(&nullValue, 0, sizeof(nullValue)); memset(&nullValue, 0, sizeof(nullValue));
nullValue.strValue = new std::string(); nullValue.strValue = new std::string();
configPath = DEFAULT_WUPSLOADER_PATH; configPath = DEFAULT_WUPSLOADER_PATH;
this->SetDefault(); this->SetDefault();
} }
CSettings::~CSettings(){ CSettings::~CSettings() {
for(u32 i = 0; i < settingsValues.size(); i++) for(u32 i = 0; i < settingsValues.size(); i++) {
{
if(settingsValues[i].dataType == TypeString) if(settingsValues[i].dataType == TypeString)
delete settingsValues[i].strValue; delete settingsValues[i].strValue;
} }
delete nullValue.strValue; delete nullValue.strValue;
} }
void CSettings::SetDefault() void CSettings::SetDefault() {
{ for(u32 i = 0; i < settingsValues.size(); i++) {
for(u32 i = 0; i < settingsValues.size(); i++)
{
if(settingsValues[i].dataType == TypeString) if(settingsValues[i].dataType == TypeString)
delete settingsValues[i].strValue; delete settingsValues[i].strValue;
} }
@ -61,23 +58,23 @@ void CSettings::SetDefault()
settingsNames.resize(MAX_VALUE); settingsNames.resize(MAX_VALUE);
settingsValues.resize(MAX_VALUE); settingsValues.resize(MAX_VALUE);
settingsNames[AppLanguage] = "AppLanguage"; settingsNames[AppLanguage] = "AppLanguage";
settingsValues[AppLanguage].dataType = TypeString; settingsValues[AppLanguage].dataType = TypeString;
settingsValues[AppLanguage].strValue = new std::string(); settingsValues[AppLanguage].strValue = new std::string();
} }
bool CSettings::Load(){ bool CSettings::Load() {
//! Reset default path variables to the right device //! Reset default path variables to the right device
SetDefault(); SetDefault();
std::string filepath = configPath; std::string filepath = configPath;
filepath += CONFIG_FILENAME; filepath += CONFIG_FILENAME;
log_printf("CSettings::Load(line %d): Loading Configuration from %s\n",__LINE__,filepath.c_str()); log_printf("CSettings::Load(line %d): Loading Configuration from %s\n",__LINE__,filepath.c_str());
CFile file(filepath, CFile::ReadOnly); CFile file(filepath, CFile::ReadOnly);
if (!file.isOpen()) if (!file.isOpen())
return false; return false;
@ -89,8 +86,7 @@ bool CSettings::Load(){
//! remove all windows crap signs //! remove all windows crap signs
size_t position; size_t position;
while(1 && !strBuffer.empty()) while(1 && !strBuffer.empty()) {
{
position = strBuffer.find('\r'); position = strBuffer.find('\r');
if(position == std::string::npos) if(position == std::string::npos)
break; break;
@ -98,14 +94,13 @@ bool CSettings::Load(){
strBuffer.erase(position, 1); strBuffer.erase(position, 1);
} }
std::vector<std::string> lines = StringTools::stringSplit(strBuffer, "\n"); std::vector<std::string> lines = StringTools::stringSplit(strBuffer, "\n");
if(lines.empty() || !ValidVersion(lines[0])) if(lines.empty() || !ValidVersion(lines[0]))
return false; return false;
for(u32 i = 0; i < lines.size(); ++i) for(u32 i = 0; i < lines.size(); ++i) {
{
std::vector<std::string> valueSplit = StringTools::stringSplit(lines[i], "="); std::vector<std::string> valueSplit = StringTools::stringSplit(lines[i], "=");
if(valueSplit.size() != 2) if(valueSplit.size() != 2)
continue; continue;
@ -116,130 +111,125 @@ bool CSettings::Load(){
while((valueSplit[1].size() > 0) && valueSplit[1][ valueSplit[1].size() - 1 ] == ' ') while((valueSplit[1].size() > 0) && valueSplit[1][ valueSplit[1].size() - 1 ] == ' ')
valueSplit[1].resize(valueSplit[1].size() - 1); valueSplit[1].resize(valueSplit[1].size() - 1);
for(u32 n = 0; n < settingsNames.size(); n++) for(u32 n = 0; n < settingsNames.size(); n++) {
{
if(!settingsNames[n]) if(!settingsNames[n])
continue; continue;
if(valueSplit[0] == settingsNames[n]) if(valueSplit[0] == settingsNames[n]) {
{ switch(settingsValues[n].dataType) {
switch(settingsValues[n].dataType) case TypeBool:
{ settingsValues[n].bValue = atoi(valueSplit[1].c_str());
case TypeBool: break;
settingsValues[n].bValue = atoi(valueSplit[1].c_str()); case TypeS8:
break; settingsValues[n].cValue = atoi(valueSplit[1].c_str());
case TypeS8: break;
settingsValues[n].cValue = atoi(valueSplit[1].c_str()); case TypeU8:
break; settingsValues[n].ucValue = atoi(valueSplit[1].c_str());
case TypeU8: break;
settingsValues[n].ucValue = atoi(valueSplit[1].c_str()); case TypeS16:
break; settingsValues[n].sValue = atoi(valueSplit[1].c_str());
case TypeS16: break;
settingsValues[n].sValue = atoi(valueSplit[1].c_str()); case TypeU16:
break; settingsValues[n].usValue = atoi(valueSplit[1].c_str());
case TypeU16: break;
settingsValues[n].usValue = atoi(valueSplit[1].c_str()); case TypeS32:
break; settingsValues[n].iValue = atoi(valueSplit[1].c_str());
case TypeS32: break;
settingsValues[n].iValue = atoi(valueSplit[1].c_str()); case TypeU32:
break; settingsValues[n].uiValue = strtoul(valueSplit[1].c_str(), 0, 10);
case TypeU32: break;
settingsValues[n].uiValue = strtoul(valueSplit[1].c_str(), 0, 10); case TypeF32:
break; settingsValues[n].fValue = atof(valueSplit[1].c_str());
case TypeF32: break;
settingsValues[n].fValue = atof(valueSplit[1].c_str()); case TypeString:
break; if(settingsValues[n].strValue == NULL)
case TypeString: settingsValues[n].strValue = new std::string();
if(settingsValues[n].strValue == NULL)
settingsValues[n].strValue = new std::string();
*settingsValues[n].strValue = valueSplit[1]; *settingsValues[n].strValue = valueSplit[1];
break; break;
default: default:
break; break;
} }
} }
} }
} }
return true; return true;
} }
bool CSettings::ValidVersion(const std::string & versionString){ bool CSettings::ValidVersion(const std::string & versionString) {
int version = 0; int version = 0;
if(versionString.find(VERSION_LINE) != 0) if(versionString.find(VERSION_LINE) != 0)
return false; return false;
version = atoi(versionString.c_str() + strlen(VERSION_LINE)); version = atoi(versionString.c_str() + strlen(VERSION_LINE));
return version == VALID_VERSION; return version == VALID_VERSION;
} }
bool CSettings::Reset(){ bool CSettings::Reset() {
this->SetDefault(); this->SetDefault();
bChanged = true; bChanged = true;
if (this->Save()) if (this->Save())
return true; return true;
return false; return false;
} }
bool CSettings::Save(){ bool CSettings::Save() {
if(!bChanged) if(!bChanged)
return true; return true;
FSUtils::CreateSubfolder(configPath.c_str()); FSUtils::CreateSubfolder(configPath.c_str());
std::string filepath = configPath; std::string filepath = configPath;
filepath += CONFIG_FILENAME; filepath += CONFIG_FILENAME;
CFile file(filepath, CFile::WriteOnly); CFile file(filepath, CFile::WriteOnly);
if (!file.isOpen()) if (!file.isOpen())
return false; return false;
file.fwrite("%s%i\n", VERSION_LINE, VALID_VERSION); file.fwrite("%s%i\n", VERSION_LINE, VALID_VERSION);
for(u32 i = 0; i < settingsValues.size(); i++) for(u32 i = 0; i < settingsValues.size(); i++) {
{ switch(settingsValues[i].dataType) {
switch(settingsValues[i].dataType) case TypeBool:
{ file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].bValue);
case TypeBool: break;
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].bValue); case TypeS8:
break; file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].cValue);
case TypeS8: break;
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].cValue); case TypeU8:
break; file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].ucValue);
case TypeU8: break;
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].ucValue); case TypeS16:
break; file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].sValue);
case TypeS16: break;
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].sValue); case TypeU16:
break; file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].usValue);
case TypeU16: break;
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].usValue); case TypeS32:
break; file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].iValue);
case TypeS32: break;
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].iValue); case TypeU32:
break; file.fwrite("%s=%u\n", settingsNames[i], settingsValues[i].uiValue);
case TypeU32: break;
file.fwrite("%s=%u\n", settingsNames[i], settingsValues[i].uiValue); case TypeF32:
break; file.fwrite("%s=%f\n", settingsNames[i], settingsValues[i].fValue);
case TypeF32: break;
file.fwrite("%s=%f\n", settingsNames[i], settingsValues[i].fValue); case TypeString:
break; if(settingsValues[i].strValue != NULL)
case TypeString: file.fwrite("%s=%s\n", settingsNames[i], settingsValues[i].strValue->c_str());
if(settingsValues[i].strValue != NULL) break;
file.fwrite("%s=%s\n", settingsNames[i], settingsValues[i].strValue->c_str()); default:
break; break;
default:
break;
} }
} }
file.close(); file.close();
bChanged = false; bChanged = false;
return true; return true;
} }

View File

@ -25,8 +25,7 @@
#include <vector> #include <vector>
#include "SettingsEnums.h" #include "SettingsEnums.h"
class CSettings class CSettings {
{
public: public:
static CSettings *instance() { static CSettings *instance() {
if(!settingsInstance) if(!settingsInstance)
@ -36,7 +35,7 @@ public:
} }
static void destroyInstance() { static void destroyInstance() {
if(settingsInstance){ if(settingsInstance) {
delete settingsInstance; delete settingsInstance;
settingsInstance = NULL; settingsInstance = NULL;
} }
@ -51,7 +50,7 @@ public:
//!Reset Settings //!Reset Settings
bool Reset(); bool Reset();
enum DataTypes{ enum DataTypes {
TypeNone, TypeNone,
TypeBool, TypeBool,
TypeS8, TypeS8,
@ -65,152 +64,124 @@ public:
}; };
enum SettingsIdx{ enum SettingsIdx {
INVALID = -1, INVALID = -1,
AppLanguage, AppLanguage,
MAX_VALUE MAX_VALUE
}; };
static const u8 & getDataType(int idx) static const u8 & getDataType(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE) if(idx > INVALID && idx < MAX_VALUE)
return instance()->settingsValues[idx].dataType; return instance()->settingsValues[idx].dataType;
return instance()->nullValue.dataType; return instance()->nullValue.dataType;
} }
static const bool & getValueAsBool(int idx) static const bool & getValueAsBool(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeBool) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeBool)
return instance()->settingsValues[idx].bValue; return instance()->settingsValues[idx].bValue;
return instance()->nullValue.bValue; return instance()->nullValue.bValue;
} }
static const s8 & getValueAsS8(int idx) static const s8 & getValueAsS8(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS8) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS8)
return instance()->settingsValues[idx].cValue; return instance()->settingsValues[idx].cValue;
return instance()->nullValue.cValue; return instance()->nullValue.cValue;
} }
static const u8 & getValueAsU8(int idx) static const u8 & getValueAsU8(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU8) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU8)
return instance()->settingsValues[idx].ucValue; return instance()->settingsValues[idx].ucValue;
return instance()->nullValue.ucValue; return instance()->nullValue.ucValue;
} }
static const s16 & getValueAsS16(int idx) static const s16 & getValueAsS16(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS16) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS16)
return instance()->settingsValues[idx].sValue; return instance()->settingsValues[idx].sValue;
return instance()->nullValue.sValue; return instance()->nullValue.sValue;
} }
static const u16 & getValueAsU16(int idx) static const u16 & getValueAsU16(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU16) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU16)
return instance()->settingsValues[idx].usValue; return instance()->settingsValues[idx].usValue;
return instance()->nullValue.usValue; return instance()->nullValue.usValue;
} }
static const s32 & getValueAsS32(int idx) static const s32 & getValueAsS32(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS32) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS32)
return instance()->settingsValues[idx].iValue; return instance()->settingsValues[idx].iValue;
return instance()->nullValue.iValue; return instance()->nullValue.iValue;
} }
static const u32 & getValueAsU32(int idx) static const u32 & getValueAsU32(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU32) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU32)
return instance()->settingsValues[idx].uiValue; return instance()->settingsValues[idx].uiValue;
return instance()->nullValue.uiValue; return instance()->nullValue.uiValue;
} }
static const f32 & getValueAsF32(int idx) static const f32 & getValueAsF32(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeF32) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeF32)
return instance()->settingsValues[idx].fValue; return instance()->settingsValues[idx].fValue;
return instance()->nullValue.fValue; return instance()->nullValue.fValue;
} }
static const std::string & getValueAsString(int idx) static const std::string & getValueAsString(int idx) {
{
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeString && instance()->settingsValues[idx].strValue) if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeString && instance()->settingsValues[idx].strValue)
return *(instance()->settingsValues[idx].strValue); return *(instance()->settingsValues[idx].strValue);
return *(instance()->nullValue.strValue); return *(instance()->nullValue.strValue);
} }
static void setValueAsBool(int idx, const bool & val) static void setValueAsBool(int idx, const bool & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeBool) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeBool)
{
instance()->settingsValues[idx].bValue = val; instance()->settingsValues[idx].bValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsS8(int idx, const s8 & val) static void setValueAsS8(int idx, const s8 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS8) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS8)
{
instance()->settingsValues[idx].cValue = val; instance()->settingsValues[idx].cValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsU8(int idx, const u8 & val) static void setValueAsU8(int idx, const u8 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU8) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU8)
{
instance()->settingsValues[idx].ucValue = val; instance()->settingsValues[idx].ucValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsS16(int idx, const s16 & val) static void setValueAsS16(int idx, const s16 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS16) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS16)
{
instance()->settingsValues[idx].sValue = val; instance()->settingsValues[idx].sValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsU16(int idx, const u16 & val) static void setValueAsU16(int idx, const u16 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU16) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU16)
{
instance()->settingsValues[idx].usValue = val; instance()->settingsValues[idx].usValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsS32(int idx, const s32 & val) static void setValueAsS32(int idx, const s32 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS32) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeS32)
{
instance()->settingsValues[idx].iValue = val; instance()->settingsValues[idx].iValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsU32(int idx, const u32 & val) static void setValueAsU32(int idx, const u32 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU32) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeU32)
{
instance()->settingsValues[idx].uiValue = val; instance()->settingsValues[idx].uiValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsF32(int idx, const f32 & val) static void setValueAsF32(int idx, const f32 & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeF32) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeF32)
{
instance()->settingsValues[idx].fValue = val; instance()->settingsValues[idx].fValue = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
} }
static void setValueAsString(int idx, const std::string & val) static void setValueAsString(int idx, const std::string & val) {
{ if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeString && instance()->settingsValues[idx].strValue) {
if(idx > INVALID && idx < MAX_VALUE && instance()->settingsValues[idx].dataType == TypeString && instance()->settingsValues[idx].strValue)
{
*(instance()->settingsValues[idx].strValue) = val; *(instance()->settingsValues[idx].strValue) = val;
instance()->bChanged = true; instance()->bChanged = true;
} }
@ -225,12 +196,10 @@ protected:
static CSettings *settingsInstance; static CSettings *settingsInstance;
typedef struct typedef struct {
{
u8 dataType; u8 dataType;
union union {
{
bool bValue; bool bValue;
s8 cValue; s8 cValue;
u8 ucValue; u8 ucValue;

View File

@ -19,19 +19,16 @@
#ifndef __SETTINGS_DEFS_ #ifndef __SETTINGS_DEFS_
#define __SETTINGS_DEFS_ #define __SETTINGS_DEFS_
typedef struct typedef struct {
{
int value; int value;
const char *name; const char *name;
} ValueString; } ValueString;
typedef struct typedef struct {
{
const char *name; const char *name;
const ValueString *valueStrings; const ValueString *valueStrings;
int type; int type;
int index; int index;
} SettingType; } SettingType;
#endif // __SETTINGS_DEFS_ #endif // __SETTINGS_DEFS_

View File

@ -1,9 +1,9 @@
#ifndef SETTINGS_ENUMS_H_ #ifndef SETTINGS_ENUMS_H_
#define SETTINGS_ENUMS_H_ #define SETTINGS_ENUMS_H_
enum eOnOff{ enum eOnOff {
SETTING_OFF, SETTING_OFF,
SETTING_ON SETTING_ON
}; };
#endif // SETTINGS_ENUMS_H_ #endif // SETTINGS_ENUMS_H_

View File

@ -11,30 +11,30 @@
// https://gist.github.com/ccbrown/9722406 // https://gist.github.com/ccbrown/9722406
void dumpHex(const void* data, size_t size) { void dumpHex(const void* data, size_t size) {
char ascii[17]; char ascii[17];
size_t i, j; size_t i, j;
ascii[16] = '\0'; ascii[16] = '\0';
for (i = 0; i < size; ++i) { for (i = 0; i < size; ++i) {
log_printf("%02X ", ((unsigned char*)data)[i]); log_printf("%02X ", ((unsigned char*)data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i]; ascii[i % 16] = ((unsigned char*)data)[i];
} else { } else {
ascii[i % 16] = '.'; ascii[i % 16] = '.';
} }
if ((i+1) % 8 == 0 || i+1 == size) { if ((i+1) % 8 == 0 || i+1 == size) {
log_printf(" "); log_printf(" ");
if ((i+1) % 16 == 0) { if ((i+1) % 16 == 0) {
log_printf("| %s \n", ascii); log_printf("| %s \n", ascii);
} else if (i+1 == size) { } else if (i+1 == size) {
ascii[(i+1) % 16] = '\0'; ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) { if ((i+1) % 16 <= 8) {
log_printf(" "); log_printf(" ");
} }
for (j = (i+1) % 16; j < 16; ++j) { for (j = (i+1) % 16; j < 16; ++j) {
log_printf(" "); log_printf(" ");
} }
log_printf("| %s \n", ascii); log_printf("| %s \n", ascii);
} }
} }
} }
} }