mirror of
				https://github.com/Thesola10/umd-livepatch.git
				synced 2025-08-09 22:02:02 +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