Use libwupsbackend for wiiloading plugins

This commit is contained in:
Maschell 2020-05-17 20:29:29 +02:00
parent 4c9dd43072
commit 0d33e1a9b6
12 changed files with 53 additions and 980 deletions

4
.gitignore vendored
View File

@ -5,3 +5,7 @@ sysapp.cbp
sysapp.cscope_file_list
*.wps
*.elf
cmake-build-debug/
.idea/
*.rpx
*.txt

View File

@ -23,7 +23,6 @@ TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := src \
src/fs \
src/plugin \
src/utils
DATA := data
INCLUDES := src
@ -36,12 +35,12 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \
CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__
CXXFLAGS := $(CFLAGS)
CXXFLAGS := $(CFLAGS) -std=gnu++17
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(WUPSSPECS) -Wl,-Map,$(notdir $*.map)
LIBS := -lwups -lwut
LIBS := -lwups -lwut -lwupsbackend
#-------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level

View File

@ -1,50 +0,0 @@
# Compiling the projects with libutils logging code?
DO_LOGGING := 1
# Target filename
TARGET := $(notdir $(CURDIR)).mod
# Source directories
SOURCES := src src/utils src/fs src/plugin
# Data directories
DATA :=
# Include directories
INCLUDES := src
#---------------------------------------------------------------------------------
# options for code generation and linking
#---------------------------------------------------------------------------------
# Extra C AND C++ compiler flags
COMMON_CFLAGS :=
# Extra C compiler flags
CFLAGS :=
# Extra C++ compiler flags
CXXFLAGS :=
# Extra linking flags for all linking steps
LDFLAGS :=
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(WUPSDIR) $(WUT_ROOT) $(PORTLIBS)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lwups -lwut
#---------------------------------------------------------------------------------
# Will be added to the final lib paths
# example:
# -L$C:/library1/lib
#---------------------------------------------------------------------------------
EXTERNAL_LIBPATHS :=
#---------------------------------------------------------------------------------
# Will be added to the final include paths
# -IC:/library1/include
#---------------------------------------------------------------------------------
EXTERNAL_INCLUDE :=

View File

@ -1,117 +0,0 @@
/* based on module.c
* by Alex Chadwick
*
* Copyright (C) 2014, Alex Chadwick
* Modified 2018, Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _PLUGIN_INFORMATION_H_
#define _PLUGIN_INFORMATION_H_
#include <string>
#include <vector>
#include "utils/logger.h"
#include "utils/ipcclient.h"
class PluginInformation {
public:
PluginInformation(plugin_information_handle handle, const char * path, const char * name, const char * author) {
this->handle = handle;
this->path = path;
this->name = name;
this->author = author;
}
~PluginInformation() {
IPC_Delete_Plugin_Information(this->handle);
}
std::string getName() {
return this->name;
}
std::string getAuthor() {
return this->author;
}
std::string getVersion() {
return this->version;
}
std::string getLicense() {
return this->license;
}
std::string getBuildTimestamp() {
return this->buildtimestamp;
}
std::string getDescription() {
return this->description;
}
std::string getPath() {
return path;
}
size_t getSize() {
return this->size;
}
plugin_information_handle getHandle() {
return this->handle;
}
private:
void setVersion(const char * version) {
this->version = version;
}
void setLicense(const char * license) {
this->license = license;
}
void setBuildTimestamp(const char * buildtimestamp) {
this->buildtimestamp = buildtimestamp;
}
void setDescription(const char * description) {
this->description = description;
}
void setSize(size_t size) {
this->size = size;
}
plugin_information_handle handle;
std::string path;
std::string name;
std::string author;
std::string version;
std::string license;
std::string buildtimestamp;
std::string description;
size_t size = 0;
};
#endif

View File

@ -1,121 +0,0 @@
#include <string>
#include "PluginInformationUtils.h"
#include "utils/ipcclient.h"
std::vector<PluginInformation *> PluginInformationUtils::getPluginInformationByStruct(plugin_information_handle * handleList, uint32_t handleListSize) {
std::vector<PluginInformation *> result;
if(handleListSize > 0) {
DEBUG_FUNCTION_LINE("Getting details for handles\n");
plugin_information * informationList = NULL;
uint32_t informationListSize = 0;
uint32_t res = IPC_Get_Plugin_Information_Details(handleList, handleListSize, &informationList, &informationListSize);
if(res == 0) {
for(uint32_t i = 0; i<informationListSize; i++) {
DEBUG_FUNCTION_LINE("Adding %08X %s\n", informationList[i].handle, informationList[i].path);
result.push_back(new PluginInformation(informationList[i].handle,informationList[i].path,informationList[i].name,informationList[i].author));
}
} else {
DEBUG_FUNCTION_LINE("IPC_Get_Plugin_Information_Details failed\n");
}
if(informationList != NULL) {
free(informationList);
}
} else {
DEBUG_FUNCTION_LINE("List is empty.\n");
}
return result;
}
void PluginInformationUtils::clearPluginInformation(std::vector<PluginInformation *> pluginInformation) {
for(size_t i = 0; i < pluginInformation.size(); i++) {
PluginInformation * curPluginInformation = pluginInformation[i];
if(curPluginInformation != NULL) {
delete curPluginInformation;
}
}
}
std::vector<PluginInformation *> PluginInformationUtils::getPluginsByPath(std::string path) {
std::vector<PluginInformation *> result;
plugin_information_handle * handleList = NULL;
uint32_t handleListSize = 0;
uint32_t res = IPC_Get_Plugin_Information(path.c_str(), &handleList, &handleListSize);
if(res == 0) {
DEBUG_FUNCTION_LINE("SUCCESS reading plugins from %s. handleListSize %d, handlelist %08X \n",path, handleListSize, handleList);
result = getPluginInformationByStruct(handleList, handleListSize);
}
if(handleList != NULL) {
free(handleList);
}
return result;
}
PluginInformation * PluginInformationUtils::loadPluginInformation(std::string path) {
std::vector<PluginInformation *> result;
plugin_information_handle handle = NULL;
uint32_t res = IPC_Get_Plugin_Information_For_Filepath(path.c_str(), &handle);
if(res == 0 && handle != NULL) {
DEBUG_FUNCTION_LINE("SUCCESS reading plugins from %s. handle %08X \n",path.c_str(), &handle);
result = getPluginInformationByStruct(&handle, 1);
}
if(result.size() > 0){
return result.at(0);
}
return NULL;
}
bool PluginInformationUtils::loadAndLinkPluginsOnRestart(std::vector<PluginInformation *> pluginInformation) {
uint32_t handleListSize = pluginInformation.size();
DEBUG_FUNCTION_LINE("Convert PluginInformation* to plugin_information_handle *\n");
plugin_information_handle * handleList = (plugin_information_handle *) malloc(handleListSize * sizeof(plugin_information_handle));
if(handleList == NULL) {
return false;
}
DEBUG_FUNCTION_LINE("Allocation was okay %08X\n", handleList);
uint32_t cur = 0;
for (std::vector<PluginInformation *>::iterator it = pluginInformation.begin() ; it != pluginInformation.end(); ++it) {
PluginInformation * curPlugin = *it;
handleList[cur] = curPlugin->getHandle();
DEBUG_FUNCTION_LINE("Adding to List %08X\n", handleList[cur]);
cur++;
}
bool result = false;
int32_t res = IPC_Link_Plugin_Information_On_Restart(handleList, handleListSize);
if(res >= 0) {
DEBUG_FUNCTION_LINE("result was %d\n", res);
result = true;
}
free(handleList);
return result;
}
std::vector<PluginInformation *> PluginInformationUtils::getPluginsLoadedInMemory() {
std::vector<PluginInformation *> result;
plugin_information_handle * handleList = NULL;
uint32_t handleListSize = 0;
uint32_t res = IPC_Get_Plugin_Information_Loaded(&handleList, &handleListSize);
if(res == 0) {
result = getPluginInformationByStruct(handleList, handleListSize);
}
if(handleList != NULL) {
free(handleList);
}
return result;
}

View File

@ -1,70 +0,0 @@
/* based on module.c
* by Alex Chadwick
*
* Copyright (C) 2014, Alex Chadwick
* Modified 2018,2019 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _PLUGIN_INFORMATION_UTILS_H_
#define _PLUGIN_INFORMATION_UTILS_H_
#include <string>
#include <vector>
#include "PluginInformation.h"
#include "utils/logger.h"
#include "utils/ipcclient.h"
class PluginInformationUtils {
public:
static PluginInformation * loadPluginInformation(std::string path);
/**
\brief Parses the meta data of all plugins in the given directory.
\param path the path of the directory which should be scanned.
\return a list of PluginInformation objects, one for each valid plugin.
**/
static std::vector<PluginInformation *> getPluginsByPath(std::string path);
/**
\brief Gets plugin information from the global struct.
\return a list of MetaInformation objects for all plugins currently loaded and linked (relocated). Will only contain
plugin which are still on the sd card.
**/
static std::vector<PluginInformation *> getPluginsLoadedInMemory();
static void clearPluginInformation(std::vector<PluginInformation *> pluginInformation) ;
static bool loadAndLinkPluginsOnRestart(std::vector<PluginInformation *> pluginInformation);
static std::vector<PluginInformation *> getPluginInformationByStruct(plugin_information_handle * handleList, uint32_t handleListSize);
};
#endif

View File

@ -1,60 +0,0 @@
#include <string>
#include "PluginLoader.h"
#include "utils/ipcclient.h"
PluginLoader * PluginLoader::createInstance(uint32_t startAddress, uint32_t endAddress) {
plugin_loader_handle handle = IPC_Open_Plugin_Loader(startAddress, endAddress);
if(handle != 0) {
return new PluginLoader(handle, startAddress,endAddress);
}
return NULL;
}
void PluginLoader::destroyInstance(PluginLoader * loader) {
if(loader != NULL) {
delete loader;
}
}
PluginLoader::PluginLoader(plugin_information_handle handle,uint32_t startAddress, uint32_t endAddress) {
this->handle = handle;
this->startAddress = startAddress;
this->endAddress = endAddress;
}
PluginLoader::~PluginLoader() {
IPC_Close_Plugin_Loader(this->handle);
}
bool PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation) {
uint32_t handleListSize = pluginInformation.size();
DEBUG_FUNCTION_LINE("Convert PluginInformation* to plugin_information_handle *\n");
plugin_information_handle * handleList = (plugin_information_handle *) malloc(handleListSize * sizeof(plugin_information_handle));
if(handleList == NULL) {
return false;
}
DEBUG_FUNCTION_LINE("Allocation was okay %08X\n", handleList);
uint32_t cur = 0;
for (std::vector<PluginInformation *>::iterator it = pluginInformation.begin() ; it != pluginInformation.end(); ++it) {
PluginInformation * curPlugin = *it;
handleList[cur] = curPlugin->getHandle();
DEBUG_FUNCTION_LINE("Adding to List %08X\n", handleList[cur]);
cur++;
}
bool result = false;
int32_t res = IPC_Link_Plugin_Information(this->handle, handleList, handleListSize);
if(res >= 0) {
DEBUG_FUNCTION_LINE("result was %d\n", res);
result = true;
}
free(handleList);
return result;
}

View File

@ -1,78 +0,0 @@
#ifndef _PLUGIN_LOADER_H_
#define _PLUGIN_LOADER_H_
#include <vector>
#include "PluginInformation.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <utils/utils.h>
#ifdef __cplusplus
}
#endif
class PluginLoader {
public:
static PluginLoader * createInstance(uint32_t startAddress, uint32_t endAddress);
static void destroyInstance(PluginLoader * loader);
~PluginLoader();
/**
\brief Takes a list of plugins that should be linked (relocated) loaded into the memory.
The function that should be replaced will be replaced in the order of the given plugin list.
So two plugin will override the same function, the plugin first in this list will override the function first.
Also the hooks of the plugins will be called in the order their plugin where passed to this method.
\param A list of plugin that should be linked (relocated) an loaded into memory
\return Returns true if all plugins were linked successfully. Returns false if at least one plugin failed while linking.
**/
bool loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation);
/**
\brief Load
\param pluginInformation a PluginInformation object of the plugin that should be linked (relocated) and loaded.
**/
bool loadAndLinkPlugin(PluginInformation * pluginInformation);
/*
size_t getTotalSpace() {
return ((uint32_t) this->endAddress - (uint32_t) this->startAddress);
}
size_t getAvailableSpace() {
return ((uint32_t) this->endAddress - (uint32_t) this->currentStoreAddress);
}
size_t getUsedSpace() {
return getTotalSpace() - getAvailableSpace();
}
void resetPluginLoader() {
this->currentStoreAddress = ROUNDUP((uint32_t)startAddress, 0x10000);
}*/
private:
PluginLoader(plugin_loader_handle handle, uint32_t startAddress, uint32_t endAddress);
static std::vector<PluginInformation *> getPluginInformationByStruct(plugin_information_handle * handleList, uint32_t handleListSize);
plugin_loader_handle handle = 0;
uint32_t startAddress = 0;
uint32_t endAddress = 0;
uint32_t currentStoreAddress = 0;
};
#endif

View File

@ -1,69 +0,0 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef _CMUTEX_H_
#define _CMUTEX_H_
#include <malloc.h>
#include <coreinit/mutex.h>
class CMutex
{
public:
CMutex() {
pMutex = (OSMutex*) malloc(sizeof(OSMutex));
if(!pMutex)
return;
OSInitMutex(pMutex);
}
virtual ~CMutex() {
if(pMutex)
free(pMutex);
}
void lock(void) {
if(pMutex)
OSLockMutex(pMutex);
}
void unlock(void) {
if(pMutex)
OSUnlockMutex(pMutex);
}
BOOL tryLock(void) {
if(!pMutex)
return false;
return (OSTryLockMutex(pMutex) != 0);
}
private:
OSMutex *pMutex;
};
class CMutexLock
{
public:
CMutexLock() {
mutex.lock();
}
virtual ~CMutexLock() {
mutex.unlock();
}
private:
CMutex mutex;
};
#endif // _CMUTEX_H_

View File

@ -3,23 +3,17 @@
#include <vector>
#include <string.h>
#include <zlib.h>
#include <libgen.h>
#include <sysapp/launch.h>
#include <coreinit/messagequeue.h>
#include <coreinit/ios.h>
#include "TcpReceiver.h"
#include "fs/CFile.hpp"
#include "fs/FSUtils.h"
#include "utils/logger.h"
#include "utils/StringTools.h"
#include "utils/net.h"
#include "utils/utils.h"
#include "plugin/PluginInformationUtils.h"
#define WUPS_TEMP_PLUGIN_PATH "fs:/vol/external01/wiiu/plugins/temp/"
#define WUPS_TEMP_PLUGIN_FILE "fs:/vol/external01/wiiu/plugins/temp/temp.mod"
#include <wups_backend/PluginUtils.h>
#include <coreinit/debug.h>
#define RPX_TEMP_PATH "fs:/vol/external01/wiiu/apps/"
#define RPX_TEMP_FILE "fs:/vol/external01/wiiu/apps/temp.rpx"
@ -241,15 +235,54 @@ int32_t TcpReceiver::loadToMemory(int32_t clientSocket, uint32_t ipAddress) {
fileSize = fileSizeUnc;
}
if(inflatedData[0x7] == 0xCA && inflatedData[0x8] == 0xFE){
if(inflatedData[0x7] == 0xCA && inflatedData[0x8] == 0xFE && inflatedData[0x9] != 0xDE && inflatedData[0xA] != 0xAD){
DEBUG_FUNCTION_LINE("Try to load a rpx\n");
FSUtils::CreateSubfolder(RPX_TEMP_PATH);
res = FSUtils::saveBufferToFile(RPX_TEMP_FILE,inflatedData, fileSize);
free(inflatedData);
loadedRPX = true;
}else{
FSUtils::CreateSubfolder(WUPS_TEMP_PLUGIN_PATH);
res = FSUtils::saveBufferToFile(WUPS_TEMP_PLUGIN_FILE,inflatedData, fileSize);
}else if(inflatedData[0x7] == 0xCA && inflatedData[0x8] == 0xFE && inflatedData[0x9] == 0xDE && inflatedData[0xA] == 0xAD){
auto newContainer = PluginUtils::getPluginForBuffer((char*)inflatedData, fileSize);
if(newContainer){
auto oldPlugins = PluginUtils::getLoadedPlugins(8);
std::vector<PluginContainer> finalList;
finalList.push_back(newContainer.value());
for (auto &plugin : oldPlugins) {
if (plugin.metaInformation.getName().compare(newContainer->metaInformation.getName()) == 0 &&
plugin.metaInformation.getAuthor().compare(newContainer->metaInformation.getAuthor()) == 0
) {
DEBUG_FUNCTION_LINE("Skipping duplicate");
PluginUtils::destroyPluginContainer(plugin);
continue;
}else{
finalList.push_back(plugin);
}
}
for (auto &plugin : finalList) {
DEBUG_FUNCTION_LINE("name: %s\n", plugin.getMetaInformation().getName().c_str());
DEBUG_FUNCTION_LINE("author: %s\n", plugin.getMetaInformation().getAuthor().c_str());
DEBUG_FUNCTION_LINE("handle: %08X\n", plugin.getPluginData().getHandle());
DEBUG_FUNCTION_LINE("====\n");
}
if (PluginUtils::LoadAndLinkOnRestart(finalList) != 0) {
DEBUG_FUNCTION_LINE("Failed to load& link\n");
PluginUtils::destroyPluginContainer(finalList);
}else{
PluginUtils::destroyPluginContainer(finalList);
SYSRelaunchTitle(NULL,NULL);
}
free(inflatedData);
free(loadAddress);
return fileSize;
}else{
DEBUG_FUNCTION_LINE("Failed to parse plugin\n");
}
free(inflatedData);
}
@ -260,9 +293,8 @@ int32_t TcpReceiver::loadToMemory(int32_t clientSocket, uint32_t ipAddress) {
res = FSUtils::saveBufferToFile(RPX_TEMP_FILE,loadAddress, fileSize);
free(loadAddress);
loadedRPX = true;
}else{
FSUtils::CreateSubfolder(WUPS_TEMP_PLUGIN_PATH);
res = FSUtils::saveBufferToFile(WUPS_TEMP_PLUGIN_FILE,loadAddress, fileSize);
}else if(loadAddress[0x7] == 0xCA && loadAddress[0x8] == 0xFE && loadAddress[0x9] == 0xDE){
OSFatal("Not implemented yet");
free(loadAddress);
}
}
@ -298,38 +330,6 @@ int32_t TcpReceiver::loadToMemory(int32_t clientSocket, uint32_t ipAddress) {
return fileSize;
}
PluginInformation * newFile = PluginInformationUtils::loadPluginInformation("sd:/wiiu/plugins/temp/temp.mod");
if(newFile == NULL){
return -1;
}
std::vector<PluginInformation *> alreadyLoaded = PluginInformationUtils::getPluginsLoadedInMemory();
std::vector<PluginInformation *> newList;
newList.push_back(newFile);
for (std::vector<PluginInformation *>::iterator it = alreadyLoaded.begin() ; it != alreadyLoaded.end(); ++it) {
PluginInformation * curPlugin = *it;
if(curPlugin->getPath().compare(newFile->getPath()) != 0){
if(curPlugin->getName().compare(newFile->getName()) == 0 &&
curPlugin->getAuthor().compare(newFile->getAuthor()) == 0
){
DEBUG_FUNCTION_LINE("Name and Author of the new plugin are identical to an old one. Loading the new one! %s %s\n",newFile->getName().c_str(),newFile->getAuthor().c_str());
continue;
}
newList.push_back(curPlugin);
}else{
DEBUG_FUNCTION_LINE("%s was overridden\n",newFile->getPath().c_str());
}
}
PluginInformationUtils::loadAndLinkPluginsOnRestart(newList);
alreadyLoaded.push_back(newFile);
PluginInformationUtils::clearPluginInformation(alreadyLoaded);
SYSRelaunchTitle(NULL,NULL);
return fileSize;

View File

@ -1,294 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "utils/logger.h"
#include "utils/utils.h"
#include "ipcclient.h"
int (*ipc_ioctl)(ipcmessage *message) = (int (*)(ipcmessage*)) *(uint32_t*)0x80800000;
#define ALIGN(align) __attribute__((aligned(align)))
int32_t doIOCTL(int32_t command, uint32_t *in_buf, uint32_t in_length, uint32_t *io_buf, uint32_t io_length) {
ALIGN(0x20) ipcmessage message;
memset(&message,0,sizeof(message));
message.command = command;
message.ioctl.buffer_in = in_buf;
message.ioctl.length_in = in_length;
message.ioctl.buffer_io = io_buf;
message.ioctl.length_io = io_length;
DEBUG_FUNCTION_LINE("command: %d in_buf %08X size: %d io_buf %08X size: %d \n",command, in_buf,in_length,io_buf,io_length);
//DCFlushRange(&message, sizeof(ipcmessage));
//ICInvalidatRange(&message, sizeof(ipcmessage));
return ((int (*)(ipcmessage *))((uint32_t*)*((uint32_t*)0x80800000)) )(&message);
}
plugin_loader_handle IPC_Open_Plugin_Loader(uint32_t startAddress, uint32_t endAddress) {
uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(8,0x20));
if(!io_buf) {
return (plugin_loader_handle) NULL;
}
io_buf[0] = startAddress;
io_buf[1] = endAddress;
int32_t ret = doIOCTL(IOCTL_OPEN_PLUGIN_LOADER, io_buf, 8, io_buf, 4);
if(ret < 0) {
free(io_buf);
return (plugin_loader_handle) NULL;
}
plugin_information_handle result = (plugin_loader_handle) io_buf[0];
free(io_buf);
return result;
}
bool IPC_Close_Plugin_Loader(plugin_loader_handle handle) {
uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(4,0x20));
if(!io_buf) {
return false;
}
io_buf[0] = handle;
int32_t ret = doIOCTL(IOCTL_CLOSE_PLUGIN_LOADER, io_buf, 4, NULL, 0);
if(ret < 0) {
free(io_buf);
return false;
}
free(io_buf);
return true;
}
int32_t IPC_Get_Plugin_Information(const char * path, plugin_information_handle ** handleList, uint32_t * handleListSize) {
uint32_t buffersize = ROUNDUP((128 * sizeof(plugin_information_handle)) + 4,0x20);
uint32_t *io_buf = (uint32_t*)memalign(0x20, buffersize);
if(!io_buf) {
return -1;
}
io_buf[0] = (uint32_t) path;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_GET_INFORMATION_FOR_PATH, io_buf, 4, io_buf, buffersize);
if(ret < 0) {
free(io_buf);
return ret;
}
uint32_t length = io_buf[0];
if(handleListSize != NULL) {
*handleListSize = length;
}
uint32_t result = -1;
if(handleList != NULL) {
// we create a new buffer so the caller can free it properly
uint32_t outbuffersize = ROUNDUP((length * sizeof(plugin_information_handle)),0x20);
*handleList = (uint32_t*)memalign(0x20, outbuffersize);
if(*handleList != NULL) {
result = 0;
memcpy(*handleList, &(io_buf[1]), length * sizeof(plugin_information_handle));
}
}
free(io_buf);
return result;
}
int32_t IPC_Get_Plugin_Information_Loaded(plugin_information_handle ** handleList, uint32_t * handleListSize) {
uint32_t buffersize = ROUNDUP((128 * sizeof(plugin_information_handle)),0x20);
uint32_t *io_buf = (uint32_t*)memalign(0x20, buffersize);
if(!io_buf) {
return -1;
}
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_GET_INFORMATION_LOADED, io_buf, 0, io_buf, buffersize);
if(ret < 0) {
free(io_buf);
return ret;
}
// DEBUG_FUNCTION_LINE("IPC_Get_Plugin_Information_Loaded was fine\n");
uint32_t length = io_buf[0];
if(handleListSize != NULL) {
// DEBUG_FUNCTION_LINE("length set to %d\n", length);
*handleListSize = length;
}
uint32_t result = -1;
if(handleList != NULL && length > 0) {
// we create a new buffer so the caller can free it properly
uint32_t outbuffersize = ROUNDUP((length * sizeof(plugin_information_handle)),0x20);
*handleList = (uint32_t*)memalign(0x20, outbuffersize);
if(*handleList != NULL) {
result = 0;
memcpy(*handleList, &(io_buf[1]), length * sizeof(plugin_information_handle));
}
}
free(io_buf);
return result;
}
int32_t IPC_Get_Plugin_Information_Details(plugin_information_handle * handles, uint32_t handlesize, plugin_information ** informationList, uint32_t * informationListSize) {
uint32_t buffersize = ROUNDUP((handlesize * sizeof(plugin_information)),0x20);
if(buffersize < 8){
buffersize = 8;
}
uint32_t *io_buf = (uint32_t*)memalign(0x20, buffersize);
if(!io_buf) {
if(io_buf != NULL) {
free(io_buf);
}
return -1;
}
io_buf[0] = (uint32_t) handles;
io_buf[1] = handlesize;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_GET_INFORMATION_DETAILS, io_buf, 8, io_buf, buffersize);
if(ret < 0) {
free(io_buf);
return ret;
}
uint32_t result = -1;
if(informationListSize != NULL) {
*informationListSize = handlesize;
}
if(informationList != NULL) {
// we create a new buffer so the caller can free it properly
uint32_t outbuffersize = ROUNDUP((handlesize * sizeof(plugin_information)),0x20);
*informationList = (plugin_information*)memalign(0x20, outbuffersize);
if(*informationList != NULL) {
result = 0;
memcpy(*informationList, &(io_buf[0]), handlesize * sizeof(plugin_information));
}
}
free(io_buf);
return result;
}
int32_t IPC_Delete_Plugin_Information(plugin_information_handle handle) {
uint32_t *io_buf = (uint32_t*)memalign(0x20, ROUNDUP(4,0x20));
if(!io_buf) {
if(io_buf != NULL) {
free(io_buf);
}
return -1;
}
io_buf[0] = (uint32_t) handle;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_DELETE_INFORMATION, io_buf, 4, NULL, 0);
if(ret < 0) {
free(io_buf);
return ret;
}
free(io_buf);
return 0;
}
int32_t IPC_Link_Plugin_Information(plugin_loader_handle handle, plugin_information_handle * handleList, uint32_t listSize) {
uint32_t buffersize = ROUNDUP((listSize * sizeof(plugin_information_handle)),0x20);
uint32_t io_buffersize = ROUNDUP(12,0x20);
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buffersize);
uint32_t * buf = (uint32_t*)memalign(0x20, buffersize);
if(!io_buf || !buf) {
if(buf != NULL) {
free(buf);
}
if(io_buf != NULL) {
free(io_buf);
}
return -1;
}
memcpy(buf, handleList, listSize * sizeof(plugin_information_handle*));
io_buf[0] = handle;
io_buf[1] = (uint32_t) buf;
io_buf[2] = listSize;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION, io_buf, 12, io_buf, io_buffersize);
if(ret < 0) {
free(io_buf);
free(buf);
return ret;
}
int32_t result = (int32_t) io_buf[0];
free(io_buf);
free(buf);
return result;
}
int32_t IPC_Link_Plugin_Information_On_Restart(plugin_information_handle * handleList, uint32_t listSize) {
uint32_t buffersize = ROUNDUP((listSize * sizeof(plugin_information_handle)),0x20);
uint32_t io_buffersize = ROUNDUP(8,0x20);
uint32_t *io_buf = (uint32_t*)memalign(0x20, io_buffersize);
uint32_t * buf = (uint32_t*)memalign(0x20, buffersize);
if(!io_buf || !buf) {
if(buf != NULL) {
free(buf);
}
if(io_buf != NULL) {
free(io_buf);
}
return -1;
}
memcpy(buf, handleList, listSize * sizeof(plugin_information_handle*));
io_buf[0] = (uint32_t) buf;
io_buf[1] = listSize;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION_ON_RESTART, io_buf, 8, io_buf, io_buffersize);
if(ret < 0) {
free(io_buf);
free(buf);
return ret;
}
int32_t result = (int32_t) io_buf[0];
free(io_buf);
free(buf);
return result;
}
int32_t IPC_Get_Plugin_Information_For_Filepath(const char * path, plugin_information_handle * handle) {
uint32_t buffersize = ROUNDUP((sizeof(plugin_information_handle)),0x20);
uint32_t *io_buf = (uint32_t*)memalign(0x20, buffersize);
if(!io_buf) {
return -1;
}
io_buf[0] = (uint32_t) path;
int32_t ret = doIOCTL(IOCTL_PLUGIN_INFORMATION_GET_INFORMATION_FOR_FILEPATH, io_buf, 4, io_buf, 4);
if(ret < 0) {
free(io_buf);
return ret;
}
*handle = io_buf[0];
free(io_buf);
return 0;
}

View File

@ -1,71 +0,0 @@
#ifndef __IPC_UTILS_H_
#define __IPC_UTILS_H_
#include <vector>
#ifdef __cplusplus
extern "C" {
#endif
#define IPC_ERROR_INVALID_NONE 0
#define IPC_ERROR_INVALID_SIZE 0xFFFFFFFF
#define IPC_ERROR_INVALID_ARG 0xFFFFFFFE
#define IPC_ERROR_FAILED_ALLOC 0xFFFFFFFD
#define IOCTL_OPEN_PLUGIN_LOADER 0x01
#define IOCTL_CLOSE_PLUGIN_LOADER 0x02
#define IOCTL_PLUGIN_LOADER_GET_INFORMATION_FOR_PATH 0x03
#define IOCTL_PLUGIN_LOADER_GET_INFORMATION_LOADED 0x04
#define IOCTL_PLUGIN_LOADER_GET_INFORMATION_DETAILS 0x05
#define IOCTL_PLUGIN_LOADER_DELETE_INFORMATION 0x06
#define IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION 0x07
#define IOCTL_PLUGIN_LOADER_LINK_VIA_INFORMATION_ON_RESTART 0x08
#define IOCTL_PLUGIN_INFORMATION_GET_INFORMATION_FOR_FILEPATH 0x09
/* IPC message */
typedef struct ipcmessage {
uint32_t command;
union {
struct {
uint32_t *buffer_in;
uint32_t length_in;
uint32_t *buffer_io;
uint32_t length_io;
} ioctl;
};
} __attribute__((packed)) ipcmessage;
typedef uint32_t plugin_information_handle;
typedef uint32_t plugin_loader_handle;
/* plugin_information message */
typedef struct plugin_information {
plugin_information_handle handle;
char path[256];
char name[256];
char author[256];
} plugin_information;
extern int (*ipc_ioctl)(ipcmessage *message);
plugin_loader_handle IPC_Open_Plugin_Loader(uint32_t startAddress, uint32_t endAddress);
bool IPC_Close_Plugin_Loader(plugin_loader_handle handle);
int32_t IPC_Get_Plugin_Information(const char * path, plugin_information_handle ** handleList, uint32_t * handleListSize);
int32_t IPC_Get_Plugin_Information_For_Filepath(const char * path, plugin_information_handle * handle);
int32_t IPC_Get_Plugin_Information_Loaded(plugin_information_handle ** handleList, uint32_t * handleListSize);
int32_t IPC_Get_Plugin_Information_Details(plugin_information_handle * handles, uint32_t handlesize, plugin_information ** informationList, uint32_t * informationListSize);
int32_t IPC_Delete_Plugin_Information(plugin_information_handle handle);
int32_t IPC_Link_Plugin_Information(plugin_loader_handle handle, plugin_information_handle * handleList, uint32_t listSize);
int32_t IPC_Link_Plugin_Information_On_Restart(plugin_information_handle * handleList, uint32_t listSize);
#ifdef __cplusplus
}
#endif
#endif