mirror of
https://github.com/Thesola10/umd-livepatch.git
synced 2025-04-19 22:13: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 "io_funcs.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <pspumd.h>
|
#include <pspumd.h>
|
||||||
|
#include <macros.h>
|
||||||
|
|
||||||
PSP_MODULE_INFO("umd_livepatch", PSP_MODULE_KERNEL, 2, 1);
|
PSP_MODULE_INFO("umd_livepatch", PSP_MODULE_KERNEL, 2, 1);
|
||||||
|
|
||||||
|
|
||||||
void lp_patchFunction(u32 addr, void *newaddr, void *fptr);
|
|
||||||
|
|
||||||
PspIoDrv *umdDriver;
|
PspIoDrv *umdDriver;
|
||||||
PspIoDrvFuncs reserveUmdFuncs;
|
PspIoDrvFuncs reserveUmdFuncs;
|
||||||
|
|
||||||
@ -26,10 +25,28 @@ SceUID vshCallbackId = 0;
|
|||||||
SceUID umdCallbackId;
|
SceUID umdCallbackId;
|
||||||
SceUID umdCallbackThread;
|
SceUID umdCallbackThread;
|
||||||
|
|
||||||
|
u32 reserveRegisterUmdCallback[4];
|
||||||
|
u32 fn_RegisterUmdCallback;
|
||||||
|
|
||||||
#define MAX_MODULE_NUMBER 256
|
#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)
|
int lp_discChangeCallback(int unk, int event, void *data)
|
||||||
{
|
{
|
||||||
if (event == PSP_UMD_NOT_PRESENT)
|
if (event == PSP_UMD_NOT_PRESENT)
|
||||||
@ -39,7 +56,37 @@ int lp_discChangeCallback(int unk, int event, void *data)
|
|||||||
return 0;
|
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)
|
int lp_discChangeWatcher(SceSize argc, void *argp)
|
||||||
{
|
{
|
||||||
SceUID callbacks[50];
|
SceUID callbacks[50];
|
||||||
@ -54,6 +101,10 @@ int lp_discChangeWatcher(SceSize argc, void *argp)
|
|||||||
Kprintf("Found VSH UMD callback: 0x%08x\n", vshCallbackId);
|
Kprintf("Found VSH UMD callback: 0x%08x\n", vshCallbackId);
|
||||||
vshCallbackId = callbacks[i];
|
vshCallbackId = callbacks[i];
|
||||||
break;
|
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);
|
NULL);
|
||||||
sceUmdRegisterUMDCallBack(umdCallbackId);
|
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();
|
sceKernelSleepThreadCB();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +164,10 @@ int module_stop(void)
|
|||||||
sceUmdUnRegisterUMDCallBack(umdCallbackId);
|
sceUmdUnRegisterUMDCallBack(umdCallbackId);
|
||||||
sceKernelDeleteCallback(umdCallbackId);
|
sceKernelDeleteCallback(umdCallbackId);
|
||||||
|
|
||||||
|
// put things back where we found them
|
||||||
|
_sw((u32) &reserveRegisterUmdCallback, fn_RegisterUmdCallback);
|
||||||
|
_sw((u32) &reserveRegisterUmdCallback + 4, fn_RegisterUmdCallback + 4);
|
||||||
|
|
||||||
if (vshCallbackId)
|
if (vshCallbackId)
|
||||||
sceUmdRegisterUMDCallBack(vshCallbackId);
|
sceUmdRegisterUMDCallBack(vshCallbackId);
|
||||||
Kprintf("Disconnected drive state callback.\n");
|
Kprintf("Disconnected drive state callback.\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user