mirror of
https://github.com/Thesola10/umd-livepatch.git
synced 2025-04-20 06:23:22 +00:00
Handle catching callbacks after our own
This commit is contained in:
parent
0aaa8d5d91
commit
c584faff09
69
main.c
69
main.c
@ -13,12 +13,11 @@
|
||||
#include "io_funcs.h"
|
||||
#include <string.h>
|
||||
#include <pspumd.h>
|
||||
#include <macros.h>
|
||||
|
||||
PSP_MODULE_INFO("umd_livepatch", PSP_MODULE_KERNEL, 2, 1);
|
||||
|
||||
|
||||
void lp_patchFunction(u32 addr, void *newaddr, void *fptr);
|
||||
|
||||
PspIoDrv *umdDriver;
|
||||
PspIoDrvFuncs reserveUmdFuncs;
|
||||
|
||||
@ -26,10 +25,28 @@ SceUID vshCallbackId = 0;
|
||||
SceUID umdCallbackId;
|
||||
SceUID umdCallbackThread;
|
||||
|
||||
u32 reserveRegisterUmdCallback[4];
|
||||
u32 fn_RegisterUmdCallback;
|
||||
|
||||
#define MAX_MODULE_NUMBER 256
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback handler for UMD events
|
||||
*
|
||||
* In order to obtain the UMD's disc ID and select the correct patch file,
|
||||
* our module keeps track of the first read command sent by the system. However,
|
||||
* without keeping track of drive removal, we might miss a disc change and
|
||||
* wrongly patch a different disc, such as on VSH.
|
||||
*
|
||||
* This callback does two things, in order:
|
||||
* - Reset the first read flag by calling {@ref lp_pingDiscRemoved}
|
||||
* - Call the 'guest callback', the callback that was originally meant to handle
|
||||
* UMD drive events.
|
||||
*
|
||||
* @see lp_discChangeWatcher the entry point for this callback thread
|
||||
* @see lp_catchUmdCallback to intercept a UMD callback register request
|
||||
*/
|
||||
int lp_discChangeCallback(int unk, int event, void *data)
|
||||
{
|
||||
if (event == PSP_UMD_NOT_PRESENT)
|
||||
@ -39,7 +56,37 @@ int lp_discChangeCallback(int unk, int event, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Substitute function for sceUmdRegisterUMDCallBack
|
||||
*
|
||||
* The UMD driver can only handle one callback at once, and we need our callback
|
||||
* to handle switching out discs.
|
||||
* This function is useful if umd_livepatch was loaded at boot, before any app
|
||||
* had a chance to register a callback, as it allows us to store the callback
|
||||
* and call it after our own.
|
||||
*/
|
||||
int lp_catchUmdCallback(int cbid)
|
||||
{
|
||||
Kprintf("Caught request to register UMD callback 0x%08x\n", cbid);
|
||||
vshCallbackId = cbid;
|
||||
sceKernelNotifyCallback(cbid, PSP_UMD_NOT_PRESENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Entry point for UMD callback thread
|
||||
*
|
||||
* This function is the entry point for our UMD callback thread. In order to
|
||||
* keep things in sync, it is also responsible for setting up our callback
|
||||
* redirect system.
|
||||
*
|
||||
* It performs the following tasks, in order:
|
||||
* - Look up a callback named "SceVshMediaDetectUMD" or "DVDUMD", and write it
|
||||
* down as our guest callback.
|
||||
* - Register {@ref lp_discChangeCallback} as the UMD event callback.
|
||||
* - Redirect sceUmdRegisterUMDCallBack to {@ref lp_catchUmdCallback}, taking
|
||||
* care to save the original instructions for cleanup.
|
||||
* - Go to sleep and wait for callbacks.
|
||||
*/
|
||||
int lp_discChangeWatcher(SceSize argc, void *argp)
|
||||
{
|
||||
SceUID callbacks[50];
|
||||
@ -54,6 +101,10 @@ int lp_discChangeWatcher(SceSize argc, void *argp)
|
||||
Kprintf("Found VSH UMD callback: 0x%08x\n", vshCallbackId);
|
||||
vshCallbackId = callbacks[i];
|
||||
break;
|
||||
} else if (!strcmp(cbinfo.name, "DVDUMD")) {
|
||||
Kprintf("Found game UMD callback: 0x%08x\n", vshCallbackId);
|
||||
vshCallbackId = callbacks[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,6 +113,14 @@ int lp_discChangeWatcher(SceSize argc, void *argp)
|
||||
NULL);
|
||||
sceUmdRegisterUMDCallBack(umdCallbackId);
|
||||
|
||||
fn_RegisterUmdCallback = sctrlHENFindFunction("sceUmd_driver", "sceUmdUser", 0xAEE7404D);
|
||||
if (fn_RegisterUmdCallback) {
|
||||
_sw(fn_RegisterUmdCallback, (u32) &reserveRegisterUmdCallback);
|
||||
_sw(fn_RegisterUmdCallback + 4, (u32) &reserveRegisterUmdCallback + 4);
|
||||
REDIRECT_FUNCTION(fn_RegisterUmdCallback, lp_catchUmdCallback);
|
||||
}
|
||||
|
||||
|
||||
sceKernelSleepThreadCB();
|
||||
}
|
||||
|
||||
@ -105,6 +164,10 @@ int module_stop(void)
|
||||
sceUmdUnRegisterUMDCallBack(umdCallbackId);
|
||||
sceKernelDeleteCallback(umdCallbackId);
|
||||
|
||||
// put things back where we found them
|
||||
_sw((u32) &reserveRegisterUmdCallback, fn_RegisterUmdCallback);
|
||||
_sw((u32) &reserveRegisterUmdCallback + 4, fn_RegisterUmdCallback + 4);
|
||||
|
||||
if (vshCallbackId)
|
||||
sceUmdRegisterUMDCallBack(vshCallbackId);
|
||||
Kprintf("Disconnected drive state callback.\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user