mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-11-16 15:49:23 +01:00
[Loader] A single plugin can be loaded via wiiload.
Now more sd swapping for ftpiiu while developing plugins! Simply use the normal wiiload to send a plugin (.mod) file to the Wii U while the plugin loader in running. This requires zlib, don't forget to add it to your portlib. It can be found in the "libs" folder.
This commit is contained in:
parent
0b6d578e27
commit
36f4b1f350
@ -44,6 +44,7 @@ install:
|
|||||||
- tar -xzvf libiosuhax.tar.gz
|
- tar -xzvf libiosuhax.tar.gz
|
||||||
- tar -xzvf fs_wrapper.tar.gz
|
- tar -xzvf fs_wrapper.tar.gz
|
||||||
- tar -xzvf controller_patcher.tar.gz
|
- tar -xzvf controller_patcher.tar.gz
|
||||||
|
- 7z x -y ./libs/portlibs.zip -o${DEVKITPRO}
|
||||||
- 7z x -y ./dynamic_libs-lib/libs/portlibs.zip -o${DEVKITPRO}
|
- 7z x -y ./dynamic_libs-lib/libs/portlibs.zip -o${DEVKITPRO}
|
||||||
- 7z x -y ./libgui-master/libs/portlibs.zip -o${DEVKITPRO}
|
- 7z x -y ./libgui-master/libs/portlibs.zip -o${DEVKITPRO}
|
||||||
- (cd libiosuhax-master && make -j8 && make install)
|
- (cd libiosuhax-master && make -j8 && make install)
|
||||||
|
20
README.MD
20
README.MD
@ -47,11 +47,23 @@ For building the loader you need:
|
|||||||
- [libutils](https://github.com/Maschell/libutils) for common functions.
|
- [libutils](https://github.com/Maschell/libutils) for common functions.
|
||||||
- [libgui](https://github.com/Maschell/libgui) for the gui elements.
|
- [libgui](https://github.com/Maschell/libgui) for the gui elements.
|
||||||
|
|
||||||
|
Install the according to their readmes. Don't forget to install their dependencies.
|
||||||
|
|
||||||
|
**Dependencies**
|
||||||
|
|
||||||
|
All needed dependencies are in the "libs" folder of this repository. Extract the "portlibs.zip" archive into your devkitPro directory.
|
||||||
|
The archive includes:
|
||||||
|
|
||||||
|
- zlib
|
||||||
|
|
||||||
|
**Compiling**
|
||||||
|
|
||||||
Then call the following command in the "loader" directory.
|
Then call the following command in the "loader" directory.
|
||||||
|
|
||||||
```
|
```
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
This should create an "wiiupluginloader.elf" which can be loaded with the Homebrew Launcher.
|
This should create an "wiiupluginloader.elf" which can be loaded with the Homebrew Launcher.
|
||||||
|
|
||||||
### Plugins
|
### Plugins
|
||||||
@ -70,6 +82,12 @@ You can also check out the travis script for needed dependencies of the library,
|
|||||||
For logging (for example of the loader) you need to start the UdpDebugReader on a computer in the same network.
|
For logging (for example of the loader) you need to start the UdpDebugReader on a computer in the same network.
|
||||||
This has been created by @dimok789 and can be found in the tools folder.
|
This has been created by @dimok789 and can be found in the tools folder.
|
||||||
|
|
||||||
|
# Load plugin via network
|
||||||
|
While the loader is running, it's possible to load a single plugin via wiiload.
|
||||||
|
When using this feature, **only** this plugin will be loaded. The plugin will copied to the SDCard, this mean a SDCard is required.
|
||||||
|
A windows executable can be found in `tools/wiiload.exe`
|
||||||
|
More information about wiiload and alternatives can be found here: http://wiibrew.org/wiki/Wiiload
|
||||||
|
|
||||||
# Future
|
# Future
|
||||||
Checkout the PLANS.MD for goals, issues and future plans.
|
Checkout the PLANS.MD for goals, issues and future plans.
|
||||||
|
|
||||||
@ -78,3 +96,5 @@ Some files are based on brainslug by Chadderz:
|
|||||||
https://github.com/Chadderz121/brainslug-wii
|
https://github.com/Chadderz121/brainslug-wii
|
||||||
Much stuff also wouldn't be possible without dimok789. He made many great tools and homebrew this stuff in based on (Makefiles, Mocha, homebrew channel, udp logger, dynamic_libs etc.)
|
Much stuff also wouldn't be possible without dimok789. He made many great tools and homebrew this stuff in based on (Makefiles, Mocha, homebrew channel, udp logger, dynamic_libs etc.)
|
||||||
Also thanks to everyone who made actual exploits.
|
Also thanks to everyone who made actual exploits.
|
||||||
|
Thanks to dhewg for wiiload:
|
||||||
|
http://wiibrew.org/wiki/Wiiload
|
BIN
loader/libs/portlibs.zip
Normal file
BIN
loader/libs/portlibs.zip
Normal file
Binary file not shown.
@ -25,6 +25,7 @@
|
|||||||
#include <sounds/SoundHandler.hpp>
|
#include <sounds/SoundHandler.hpp>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
#include "settings/CSettings.h"
|
#include "settings/CSettings.h"
|
||||||
|
#include "myutils/TcpReceiver.h"
|
||||||
|
|
||||||
Application *Application::applicationInstance = NULL;
|
Application *Application::applicationInstance = NULL;
|
||||||
bool Application::exitApplication = false;
|
bool Application::exitApplication = false;
|
||||||
@ -169,6 +170,8 @@ void Application::executeThread(void) {
|
|||||||
DEBUG_FUNCTION_LINE("Entering main loop\n");
|
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)
|
||||||
|
|
||||||
|
TcpReceiver pluginReceiver(4299);
|
||||||
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++) {
|
||||||
|
@ -29,6 +29,9 @@ extern "C" {
|
|||||||
#define DEFAULT_LANG_PATH DEFAULT_WUPSLOADER_PATH "/languages"
|
#define DEFAULT_LANG_PATH DEFAULT_WUPSLOADER_PATH "/languages"
|
||||||
#define LANGUAGE_FILE_EXT ".lang"
|
#define LANGUAGE_FILE_EXT ".lang"
|
||||||
|
|
||||||
|
#define WUPS_TEMP_PLUGIN_PATH SD_PATH WIIU_PATH "/plugins/temp"
|
||||||
|
#define WUPS_TEMP_PLUGIN_FILE WUPS_TEMP_PLUGIN_PATH "/temp.mod"
|
||||||
|
|
||||||
#define WUPS_SDUSB_MOUNTED_NONE 0
|
#define WUPS_SDUSB_MOUNTED_NONE 0
|
||||||
#define WUPS_SDUSB_MOUNTED_FAKE (1<<0)
|
#define WUPS_SDUSB_MOUNTED_FAKE (1<<0)
|
||||||
#define WUPS_SDUSB_MOUNTED_OS_SD (1<<1)
|
#define WUPS_SDUSB_MOUNTED_OS_SD (1<<1)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
@ -10,7 +12,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
#include <dynamic_libs/os_functions.h>
|
||||||
#include "dynamic_libs/gx2_functions.h"
|
#include "dynamic_libs/gx2_functions.h"
|
||||||
#include "dynamic_libs/ax_functions.h"
|
#include "dynamic_libs/ax_functions.h"
|
||||||
#include "dynamic_libs/socket_functions.h"
|
#include "dynamic_libs/socket_functions.h"
|
||||||
@ -19,7 +21,7 @@
|
|||||||
#include "dynamic_libs/nn_nim_functions.h"
|
#include "dynamic_libs/nn_nim_functions.h"
|
||||||
#include "dynamic_libs/vpad_functions.h"
|
#include "dynamic_libs/vpad_functions.h"
|
||||||
#include "dynamic_libs/padscore_functions.h"
|
#include "dynamic_libs/padscore_functions.h"
|
||||||
#include "dynamic_libs/proc_ui_functions.h"
|
#include <dynamic_libs/proc_ui_functions.h>
|
||||||
|
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
#include <fs/FSUtils.h>
|
#include <fs/FSUtils.h>
|
||||||
@ -80,7 +82,7 @@ extern "C" int Menu_Main(int argc, char **argv) {
|
|||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION);
|
DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION);
|
||||||
|
|
||||||
//setup_os_exceptions();
|
setup_os_exceptions();
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
|
|
||||||
|
236
loader/src/myutils/TcpReceiver.cpp
Normal file
236
loader/src/myutils/TcpReceiver.cpp
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <string.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "TcpReceiver.h"
|
||||||
|
#include <dynamic_libs/os_functions.h>
|
||||||
|
#include <dynamic_libs/socket_functions.h>
|
||||||
|
#include <fs/CFile.hpp>
|
||||||
|
#include <fs/FSUtils.h>
|
||||||
|
#include <utils/logger.h>
|
||||||
|
#include <utils/StringTools.h>
|
||||||
|
#include <utils/net.h>
|
||||||
|
#include "Application.h"
|
||||||
|
#include "plugin/PluginLoader.h"
|
||||||
|
#include "plugin/PluginInformation.h"
|
||||||
|
|
||||||
|
TcpReceiver::TcpReceiver(int port)
|
||||||
|
: CThread(CThread::eAttributeAffCore0 | CThread::eAttributePinnedAff)
|
||||||
|
, exitRequested(false)
|
||||||
|
, serverPort(port)
|
||||||
|
, serverSocket(-1) {
|
||||||
|
|
||||||
|
resumeThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpReceiver::~TcpReceiver() {
|
||||||
|
exitRequested = true;
|
||||||
|
|
||||||
|
if(serverSocket > 0) {
|
||||||
|
shutdown(serverSocket, SHUT_RDWR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TcpReceiver::executeThread() {
|
||||||
|
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||||
|
if (serverSocket < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 enable = 1;
|
||||||
|
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||||
|
|
||||||
|
struct sockaddr_in bindAddress;
|
||||||
|
memset(&bindAddress, 0, sizeof(bindAddress));
|
||||||
|
bindAddress.sin_family = AF_INET;
|
||||||
|
bindAddress.sin_port = serverPort;
|
||||||
|
bindAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
s32 ret;
|
||||||
|
if ((ret = bind(serverSocket, (struct sockaddr *)&bindAddress, sizeof(bindAddress))) < 0) {
|
||||||
|
socketclose(serverSocket);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ret = listen(serverSocket, 3)) < 0) {
|
||||||
|
socketclose(serverSocket);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in clientAddr;
|
||||||
|
s32 addrlen = sizeof(struct sockaddr);
|
||||||
|
|
||||||
|
while(!exitRequested) {
|
||||||
|
s32 clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &addrlen);
|
||||||
|
if(clientSocket >= 0) {
|
||||||
|
u32 ipAddress = clientAddr.sin_addr.s_addr;
|
||||||
|
//serverReceiveStart(this, ipAddress);
|
||||||
|
int result = loadToMemory(clientSocket, ipAddress);
|
||||||
|
//serverReceiveFinished(this, ipAddress, result);
|
||||||
|
socketclose(clientSocket);
|
||||||
|
|
||||||
|
if(result > 0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
os_usleep(100000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socketclose(serverSocket);
|
||||||
|
}
|
||||||
|
|
||||||
|
int TcpReceiver::loadToMemory(s32 clientSocket, u32 ipAddress) {
|
||||||
|
DEBUG_FUNCTION_LINE("Loading file from ip %08X\n", ipAddress);
|
||||||
|
|
||||||
|
u32 fileSize = 0;
|
||||||
|
u32 fileSizeUnc = 0;
|
||||||
|
unsigned char haxx[8];
|
||||||
|
memset(haxx, 0, sizeof(haxx));
|
||||||
|
//skip haxx
|
||||||
|
recvwait(clientSocket, haxx, sizeof(haxx));
|
||||||
|
recvwait(clientSocket, (unsigned char*)&fileSize, sizeof(fileSize));
|
||||||
|
|
||||||
|
if (haxx[4] > 0 || haxx[5] > 4) {
|
||||||
|
recvwait(clientSocket, (unsigned char*)&fileSizeUnc, sizeof(fileSizeUnc)); // Compressed protocol, read another 4 bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 bytesRead = 0;
|
||||||
|
struct in_addr in;
|
||||||
|
in.s_addr = ipAddress;
|
||||||
|
|
||||||
|
DEBUG_FUNCTION_LINE("transfer start\n");
|
||||||
|
|
||||||
|
unsigned char* loadAddress = (unsigned char*)memalign(0x40, fileSize);
|
||||||
|
if(!loadAddress) {
|
||||||
|
os_sleep(1);
|
||||||
|
return NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy rpl in memory
|
||||||
|
while(bytesRead < fileSize) {
|
||||||
|
|
||||||
|
u32 blockSize = 0x1000;
|
||||||
|
if(blockSize > (fileSize - bytesRead))
|
||||||
|
blockSize = fileSize - bytesRead;
|
||||||
|
|
||||||
|
int ret = recv(clientSocket, loadAddress + bytesRead, blockSize, 0);
|
||||||
|
if(ret <= 0) {
|
||||||
|
DEBUG_FUNCTION_LINE("Failure on reading file\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesRead += ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bytesRead != fileSize) {
|
||||||
|
free(loadAddress);
|
||||||
|
DEBUG_FUNCTION_LINE("File loading not finished, %i of %i bytes received\n", bytesRead, fileSize);
|
||||||
|
os_sleep(1);
|
||||||
|
return FILE_READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool res = false;
|
||||||
|
|
||||||
|
// Do we need to unzip this thing?
|
||||||
|
if (haxx[4] > 0 || haxx[5] > 4) {
|
||||||
|
unsigned char* inflatedData = NULL;
|
||||||
|
|
||||||
|
// We need to unzip...
|
||||||
|
if (loadAddress[0] == 'P' && loadAddress[1] == 'K' && loadAddress[2] == 0x03 && loadAddress[3] == 0x04) {
|
||||||
|
//! TODO:
|
||||||
|
//! mhmm this is incorrect, it has to parse the zip
|
||||||
|
|
||||||
|
// Section is compressed, inflate
|
||||||
|
inflatedData = (unsigned char*)malloc(fileSizeUnc);
|
||||||
|
if(!inflatedData) {
|
||||||
|
free(loadAddress);
|
||||||
|
os_sleep(1);
|
||||||
|
return NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
z_stream s;
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
|
||||||
|
s.zalloc = Z_NULL;
|
||||||
|
s.zfree = Z_NULL;
|
||||||
|
s.opaque = Z_NULL;
|
||||||
|
|
||||||
|
ret = inflateInit(&s);
|
||||||
|
if (ret != Z_OK) {
|
||||||
|
free(loadAddress);
|
||||||
|
free(inflatedData);
|
||||||
|
os_sleep(1);
|
||||||
|
return FILE_READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.avail_in = fileSize;
|
||||||
|
s.next_in = (Bytef *)(&loadAddress[0]);
|
||||||
|
|
||||||
|
s.avail_out = fileSizeUnc;
|
||||||
|
s.next_out = (Bytef *)&inflatedData[0];
|
||||||
|
|
||||||
|
ret = inflate(&s, Z_FINISH);
|
||||||
|
if (ret != Z_OK && ret != Z_STREAM_END) {
|
||||||
|
free(loadAddress);
|
||||||
|
free(inflatedData);
|
||||||
|
os_sleep(1);
|
||||||
|
return FILE_READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
inflateEnd(&s);
|
||||||
|
fileSize = fileSizeUnc;
|
||||||
|
} else {
|
||||||
|
// Section is compressed, inflate
|
||||||
|
inflatedData = (unsigned char*)malloc(fileSizeUnc);
|
||||||
|
if(!inflatedData) {
|
||||||
|
free(loadAddress);
|
||||||
|
os_sleep(1);
|
||||||
|
return NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
uLongf f = fileSizeUnc;
|
||||||
|
int result = uncompress((Bytef*)&inflatedData[0], &f, (Bytef*)loadAddress, fileSize);
|
||||||
|
if(result != Z_OK) {
|
||||||
|
DEBUG_FUNCTION_LINE("uncompress failed %i\n", result);
|
||||||
|
os_sleep(1);
|
||||||
|
return FILE_READ_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSizeUnc = f;
|
||||||
|
fileSize = fileSizeUnc;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSUtils::CreateSubfolder(WUPS_TEMP_PLUGIN_PATH);
|
||||||
|
res = FSUtils::saveBufferToFile(WUPS_TEMP_PLUGIN_FILE,inflatedData, fileSize);
|
||||||
|
free(inflatedData);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
FSUtils::CreateSubfolder(WUPS_TEMP_PLUGIN_PATH);
|
||||||
|
res = FSUtils::saveBufferToFile(WUPS_TEMP_PLUGIN_FILE,loadAddress, fileSize);
|
||||||
|
free(loadAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!res) {
|
||||||
|
os_sleep(1);
|
||||||
|
return NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginInformation * plugin = PluginInformation::loadPluginInformation(WUPS_TEMP_PLUGIN_FILE);
|
||||||
|
if(plugin == NULL) {
|
||||||
|
return NOT_A_VALID_PLUGIN;
|
||||||
|
}
|
||||||
|
PluginLoader * pluginLoader = PluginLoader::getInstance();
|
||||||
|
pluginLoader->resetPluginLoader();
|
||||||
|
std::vector<PluginInformation* > pluginList = pluginLoader->getPluginInformation(WUPS_TEMP_PLUGIN_PATH);
|
||||||
|
if(pluginList.size() == 0) {
|
||||||
|
return NOT_A_VALID_PLUGIN;
|
||||||
|
}
|
||||||
|
pluginLoader->loadAndLinkPlugins(pluginList);
|
||||||
|
Application::instance()->quit(APPLICATION_CLOSE_APPLY);
|
||||||
|
|
||||||
|
return fileSize;
|
||||||
|
}
|
43
loader/src/myutils/TcpReceiver.h
Normal file
43
loader/src/myutils/TcpReceiver.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef TCP_RECEIVER_H_
|
||||||
|
#define TCP_RECEIVER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <dynamic_libs/os_types.h>
|
||||||
|
|
||||||
|
#include <system/CThread.h>
|
||||||
|
#include <gui/sigslot.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
|
||||||
|
class TcpReceiver : public CThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum eLoadResults
|
||||||
|
{
|
||||||
|
SUCCESS = 0,
|
||||||
|
INVALID_INPUT = -1,
|
||||||
|
FILE_OPEN_FAILURE = -2,
|
||||||
|
FILE_READ_ERROR = -3,
|
||||||
|
NOT_ENOUGH_MEMORY = -4,
|
||||||
|
NOT_A_VALID_PLUGIN = -5,
|
||||||
|
};
|
||||||
|
|
||||||
|
TcpReceiver(int port);
|
||||||
|
~TcpReceiver();
|
||||||
|
|
||||||
|
sigslot::signal2<GuiElement *, u32> serverReceiveStart;
|
||||||
|
sigslot::signal3<GuiElement *, u32, int> serverReceiveFinished;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void executeThread();
|
||||||
|
int loadToMemory(s32 clientSocket, u32 ipAddress);
|
||||||
|
bool saveFileToSDCard(const char * path, void * buffer,u32 size);
|
||||||
|
|
||||||
|
bool exitRequested;
|
||||||
|
s32 serverPort;
|
||||||
|
s32 serverSocket;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -37,7 +37,7 @@ struct rpl_handling {
|
|||||||
#define FUNCTION_PATCHER_METHOD_STORE_SIZE 7
|
#define FUNCTION_PATCHER_METHOD_STORE_SIZE 7
|
||||||
#define MAXIMUM_PLUGIN_PATH_NAME_LENGTH 256
|
#define MAXIMUM_PLUGIN_PATH_NAME_LENGTH 256
|
||||||
#define MAXIMUM_PLUGIN_NAME_LENGTH 51
|
#define MAXIMUM_PLUGIN_NAME_LENGTH 51
|
||||||
#define MAXIMUM_FUNCTION_NAME_LENGTH 51
|
#define MAXIMUM_FUNCTION_NAME_LENGTH 61
|
||||||
|
|
||||||
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 */
|
||||||
|
@ -105,6 +105,9 @@ void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInf
|
|||||||
|
|
||||||
copyPluginDataIntoGlobalStruct(loadedPlugins);
|
copyPluginDataIntoGlobalStruct(loadedPlugins);
|
||||||
clearPluginData(loadedPlugins);
|
clearPluginData(loadedPlugins);
|
||||||
|
|
||||||
|
DCFlushRange((void*)this->startAddress,(u32)this->endAddress - (u32)this->startAddress);
|
||||||
|
ICInvalidateRange((void*)this->startAddress,(u32)this->endAddress - (u32)this->startAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginLoader::clearPluginData(std::vector<PluginData *> pluginData) {
|
void PluginLoader::clearPluginData(std::vector<PluginData *> pluginData) {
|
||||||
@ -392,11 +395,17 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
|
|||||||
|
|
||||||
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];
|
||||||
|
|
||||||
|
if(strlen(cur_function->getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH-1){
|
||||||
|
DEBUG_FUNCTION_LINE("Couldn not add function \"%s\" for plugin \"%s\" function name is too long.\n",cur_function->getName().c_str(),plugin_data->plugin_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Adding function \"%s\" for plugin \"%s\"\n",cur_function->getName().c_str(),plugin_data->plugin_name);
|
DEBUG_FUNCTION_LINE("Adding function \"%s\" for plugin \"%s\"\n",cur_function->getName().c_str(),plugin_data->plugin_name);
|
||||||
|
|
||||||
//TODO: Warning/Error if string is too long.
|
//TODO: Warning/Error if string is too long.
|
||||||
|
|
||||||
strncpy(function_data->function_name,cur_function->getName().c_str(),MAXIMUM_FUNCTION_NAME_LENGTH-1);
|
strncpy(function_data->function_name,cur_function->getName().c_str(),MAXIMUM_FUNCTION_NAME_LENGTH-1);
|
||||||
|
|
||||||
function_data->library = cur_function->getLibrary();
|
function_data->library = cur_function->getLibrary();
|
||||||
@ -424,4 +433,6 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
|
|||||||
plugin_index++;
|
plugin_index++;
|
||||||
gbl_replacement_data.number_used_plugins++;
|
gbl_replacement_data.number_used_plugins++;
|
||||||
}
|
}
|
||||||
|
DCFlushRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data));
|
||||||
|
ICInvalidateRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data));
|
||||||
}
|
}
|
||||||
|
@ -107,6 +107,10 @@ public:
|
|||||||
return getTotalSpace() - getAvailableSpace();
|
return getTotalSpace() - getAvailableSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetPluginLoader() {
|
||||||
|
this->currentStoreAddress = endAddress;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PluginLoader(void * startAddress, void * endAddress) {
|
PluginLoader(void * startAddress, void * endAddress) {
|
||||||
// TODO: Check if endAddress > startAddress.
|
// TODO: Check if endAddress > startAddress.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
@ -9,40 +10,11 @@
|
|||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include <utils/logger.h>
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "common/retain_vars.h"
|
#include "common/retain_vars.h"
|
||||||
#include "myutils/overlay_helper.h"
|
#include "myutils/overlay_helper.h"
|
||||||
|
|
||||||
// https://gist.github.com/ccbrown/9722406
|
|
||||||
void dumpHex(const void* data, size_t size) {
|
|
||||||
char ascii[17];
|
|
||||||
size_t i, j;
|
|
||||||
ascii[16] = '\0';
|
|
||||||
for (i = 0; i < size; ++i) {
|
|
||||||
log_printf("%02X ", ((unsigned char*)data)[i]);
|
|
||||||
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
|
|
||||||
ascii[i % 16] = ((unsigned char*)data)[i];
|
|
||||||
} else {
|
|
||||||
ascii[i % 16] = '.';
|
|
||||||
}
|
|
||||||
if ((i+1) % 8 == 0 || i+1 == size) {
|
|
||||||
log_printf(" ");
|
|
||||||
if ((i+1) % 16 == 0) {
|
|
||||||
log_printf("| %s \n", ascii);
|
|
||||||
} else if (i+1 == size) {
|
|
||||||
ascii[(i+1) % 16] = '\0';
|
|
||||||
if ((i+1) % 16 <= 8) {
|
|
||||||
log_printf(" ");
|
|
||||||
}
|
|
||||||
for (j = (i+1) % 16; j < 16; ++j) {
|
|
||||||
log_printf(" ");
|
|
||||||
}
|
|
||||||
log_printf("| %s \n", ascii);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallHook(wups_loader_hook_type_t hook_type) {
|
void CallHook(wups_loader_hook_type_t hook_type) {
|
||||||
CallHookEx(hook_type,-1);
|
CallHookEx(hook_type,-1);
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
void dumpHex(const void* data, size_t size);
|
|
||||||
void CallHook(wups_loader_hook_type_t hook_type);
|
void CallHook(wups_loader_hook_type_t hook_type);
|
||||||
|
|
||||||
void CallHookEx(wups_loader_hook_type_t hook_type, s32 plugin_index_needed);
|
void CallHookEx(wups_loader_hook_type_t hook_type, s32 plugin_index_needed);
|
||||||
|
BIN
tools/wiiload.exe
Normal file
BIN
tools/wiiload.exe
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user