The plugin system allows plugins to replace (dynamically) loaded system functions.
Keep in mind that other plugin also could override function and may manipulate the arguments or return values!
Declare function replacement
The function replacement itself is done by a macro:
DECL_FUNCTION( RETURN_TYPE, ARBITRARY_NAME_OF_FUNCTION , ARGS_SEPERATED_BY_COMMA){
//Your code goes here.
}
RETURN_TYPE
is the return type of the function. For examplevoid
orint
ARBITRARY_NAME_OF_FUNCTION
is the name of function replacement. This name can be choosen freely.ARGS_SEPERATED_BY_COMMA
is parameter list, each argument seperated by a comma. Exampleint, int, char
.- Inside macro is the code of the function replacement. The return value corresponds to
RETURN_TYPE
. - Inside the macro the function pointer
my_ARBITRARY_NAME_OF_FUNCTION
andreal_ARBITRARY_NAME_OF_FUNCTION
are avaiable. Callingreal_XXX
will call the original, replaced function.
Example
To replace the function
int FSOpenFile(FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error)
The following macro could be created, which logs all FSOpenFile call via log_printf
:
DECL_FUNCTION(int, FSOpenFile, FSClient *pClient, FSCmdBlock *pCmd, const char *path, const char *mode, int *handle, int error) {
int result = real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
log_printf("FSOpenFile called for folder %s! Result %d\n",path,result);
return result;
}
In this example FSOpenFile
was taken as an function name, but anything would’ve been also fine. In the beginning of the macro, the original function is called via real_FSOpenFile
.
After that, the result and path argument will be logged and the function returns with the original result.
Replace function with a declared function replacement
After defining a function replacement, the plugin needs to tell the plugin system which function of which library should be replaced. This is done by the following macro:
WUPS_MUST_REPLACE(FUNCTION_NAME_IN_THIS_FILE, NAME_OF_LIB_WHICH_CONTAINS_THIS_FUNCTION, NAME_OF_FUNCTION_TO_OVERRIDE)
FUNCTION_NAME_IN_THIS_FILE
corresponds to the function that was set in the declared function replacement (ARBITRARY_NAME_OF_FUNCTION
).NAME_OF_LIB_WHICH_CONTAINS_THIS_FUNCTION
is a value of thewups_loader_library_type_t
enum. Each value corresponds to a system .rpl file.NAME_OF_FUNCTION_TO_OVERRIDE
need to be set to the name of function that should be replaced. This needs to match the name exported in the corresponding .rpl.
Currently it’s only possible to override functions that are loaded from .rpl files of OSv10 (00050010-1000400A). A full list of supported .rpl
with their corresponding enum value can be found here:
Enum value | .rpl file | Description |
---|---|---|
WUPS_LOADER_LIBRARY_AVM | avm.rpl | |
WUPS_LOADER_LIBRARY_CAMERA | camera.rpl | |
WUPS_LOADER_LIBRARY_COREINIT | coreinit.rpl | |
WUPS_LOADER_LIBRARY_DC | dc.rpl | |
WUPS_LOADER_LIBRARY_DMAE | dmae.rpl | |
WUPS_LOADER_LIBRARY_DRMAPP | drmapp.rpl | |
WUPS_LOADER_LIBRARY_ERREULA | erreula.rpl | |
WUPS_LOADER_LIBRARY_GX2 | gx2.rpl | |
WUPS_LOADER_LIBRARY_H264 | h264.rpl | |
WUPS_LOADER_LIBRARY_LZMA920 | lzma920.rpl | |
WUPS_LOADER_LIBRARY_MIC | mic.rpl | |
WUPS_LOADER_LIBRARY_NFC | nfc.rpl | |
WUPS_LOADER_LIBRARY_NIO_PROF | nio_prof.rpl | |
WUPS_LOADER_LIBRARY_NLIBCURL | nlibcurl.rpl | |
WUPS_LOADER_LIBRARY_NLIBNSS | nlibnss.rpl | |
WUPS_LOADER_LIBRARY_NLIBNSS2 | nlibnss2.rpl | |
WUPS_LOADER_LIBRARY_NN_AC | nn_ac.rpl | |
WUPS_LOADER_LIBRARY_NN_ACP | nn_acp.rpl | |
WUPS_LOADER_LIBRARY_NN_ACT | nn_act.rpl | |
WUPS_LOADER_LIBRARY_NN_AOC | nn_aoc.rpl | |
WUPS_LOADER_LIBRARY_NN_BOSS | nn_boss.rpl | |
WUPS_LOADER_LIBRARY_NN_CCR | nn_ccr.rpl | |
WUPS_LOADER_LIBRARY_NN_CMPT | nn_cmpt.rpl | |
WUPS_LOADER_LIBRARY_NN_DLP | nn_dlp.rpl | |
WUPS_LOADER_LIBRARY_NN_EC | nn_ec.rpl | |
WUPS_LOADER_LIBRARY_NN_FP | nn_fp.rpl | |
WUPS_LOADER_LIBRARY_NN_HAI | nn_hai.rpl | |
WUPS_LOADER_LIBRARY_NN_HPAD | nn_hpad.rpl | |
WUPS_LOADER_LIBRARY_NN_IDBE | nn_idbe.rpl | |
WUPS_LOADER_LIBRARY_NN_NDM | nn_ndm.rpl | |
WUPS_LOADER_LIBRARY_NN_NETS2 | nn_nets2.rpl | |
WUPS_LOADER_LIBRARY_NN_NFP | nn_nfp.rpl | |
WUPS_LOADER_LIBRARY_NN_NIM | nn_nim.rpl | |
WUPS_LOADER_LIBRARY_NN_OLV | nn_olv.rpl | |
WUPS_LOADER_LIBRARY_NN_PDM | nn_pdm.rpl | |
WUPS_LOADER_LIBRARY_NN_SAVE | nn_save.rpl | |
WUPS_LOADER_LIBRARY_NN_SL | nn_sl.rpl | |
WUPS_LOADER_LIBRARY_NN_SPM | nn_spm.rpl | |
WUPS_LOADER_LIBRARY_NN_TEMP | nn_temp.rpl | |
WUPS_LOADER_LIBRARY_NN_UDS | nn_uds.rpl | |
WUPS_LOADER_LIBRARY_NN_VCTL | nn_vctl.rpl | |
WUPS_LOADER_LIBRARY_NSYSCCR | nsysccr.rpl | |
WUPS_LOADER_LIBRARY_NSYSHID | nsyshid.rpl | |
WUPS_LOADER_LIBRARY_NSYSKBD | nsyskbd.rpl | |
WUPS_LOADER_LIBRARY_NSYSNET | nsysnet.rpl | |
WUPS_LOADER_LIBRARY_NSYSUHS | nsysuhs.rpl | |
WUPS_LOADER_LIBRARY_NSYSUVD | nsysuvd.rpl | |
WUPS_LOADER_LIBRARY_NTAG | ntag.rpl | |
WUPS_LOADER_LIBRARY_PADSCORE | padscore.rpl | |
WUPS_LOADER_LIBRARY_PROC_UI | proc_ui.rpl | |
WUPS_LOADER_LIBRARY_SNDCORE2 | sndcore2.rpl | |
WUPS_LOADER_LIBRARY_SNDUSER2 | snduser2.rpl | |
WUPS_LOADER_LIBRARY_SND_CORE | snd_core.rpl | |
WUPS_LOADER_LIBRARY_SND_USER | snd_user.rpl | |
WUPS_LOADER_LIBRARY_SWKBD | swkbd.rpl | |
WUPS_LOADER_LIBRARY_SYSAPP | sysapp.rpl | |
WUPS_LOADER_LIBRARY_TCL | tcl.rpl | |
WUPS_LOADER_LIBRARY_TVE | tve.rpl | |
WUPS_LOADER_LIBRARY_UAC | uac.rpl | |
WUPS_LOADER_LIBRARY_UAC_RPL | uac_rpl.rpl | |
WUPS_LOADER_LIBRARY_USB_MIC | usb_mic.rpl | |
WUPS_LOADER_LIBRARY_UVC | uvc.rpl | |
WUPS_LOADER_LIBRARY_UVD | uvd.rpl | |
WUPS_LOADER_LIBRARY_VPAD | vpad.rpl | |
WUPS_LOADER_LIBRARY_VPADBASE | vpadbase.rpl | |
WUPS_LOADER_LIBRARY_ZLIB125 | zlib125.rpl |
Example
To tell the plugin system to replace the FSOpenFile function replacement, the following macro could be used:
WUPS_MUST_REPLACE(FSOpenFile, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile);
This has to be defined in the same file where the function replacement was declared.
Technical information
Within the DECL_FUCTION macro, two more function get declare you can use. my_ARBITRARY_NAME_OF_FUNCTION
and real_ARBITRARY_NAME_OF_FUNCTION
.
RETURN_TYPE my_ARBITRARY_NAME_OF_FUNCTION(ARGS_SEPERATED_BY_COMMA):
is just name of the function that gets declared in this macro.
It has the same effect as calling the overridden function directly.
RETURN_TYPE real_ARBITRARY_NAME_OF_FUNCTION(ARGS_SEPERATED_BY_COMMA):
is the name of the function, that leads to function that was overridden.
Use this to call the original function that will be overridden.
CAUTION: Other plugins may already have manipulated the the return value or arguments.