WiiUPluginLoaderGUI/src/utils/ipcclient.cpp
2019-08-14 22:19:46 +02:00

241 lines
7.0 KiB
C++

#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 ipc_ioctl(&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(plugin_loader_handle handle, 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] = handle;
io_buf[1] = (uint32_t) path;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_GET_INFORMATION_FOR_PATH, io_buf, 8, 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_loader_handle handle, 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] = handle;
int32_t ret = doIOCTL(IOCTL_PLUGIN_LOADER_GET_INFORMATION_LOADED, io_buf, 4, 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_loader_handle handle, 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;
}