now catching disc change

This commit is contained in:
TheSola10 2025-04-04 17:21:25 +02:00
parent 8cb83ec37e
commit 0aaa8d5d91
Signed by: thesola10
GPG Key ID: 89245619BEBB95BA
7 changed files with 145 additions and 61 deletions

View File

@ -10,7 +10,7 @@ CFLAGS += -DDEBUG=$(DEBUG)
endif endif
LDFLAGS = -nostartfiles -L . LDFLAGS = -nostartfiles -L .
LIBS = -lpspsystemctrl_kernel LIBS = -lpspsystemctrl_kernel -lpspumd
PSP_FW_VERSION = 660 PSP_FW_VERSION = 660

View File

@ -7,7 +7,7 @@ PSP_EXPORT_FUNC_HASH(module_stop)
PSP_EXPORT_VAR_HASH(module_info) PSP_EXPORT_VAR_HASH(module_info)
PSP_EXPORT_END PSP_EXPORT_END
# Voluntary collision with Inferno to prevent conflicts # Voluntary collision with Inferno to prevent loading
PSP_EXPORT_START(inferno_driver, 0x0011, 0x0001) PSP_EXPORT_START(inferno_driver, 0x0011, 0x0001)
# inferno_driver_CF8299BE # inferno_driver_CF8299BE
PSP_EXPORT_FUNC(infernoSetDiscType) PSP_EXPORT_FUNC(infernoSetDiscType)
@ -19,4 +19,9 @@ PSP_EXPORT_FUNC(infernoCacheInit)
PSP_EXPORT_FUNC(infernoSetUmdDelay) PSP_EXPORT_FUNC(infernoSetUmdDelay)
PSP_EXPORT_END PSP_EXPORT_END
PSP_EXPORT_START(umd_livepatch, 0x0011, 0x0001)
PSP_EXPORT_FUNC(lp_discChangeCallback)
PSP_EXPORT_FUNC(lp_discChangeWatcher)
PSP_EXPORT_END
PSP_END_EXPORTS PSP_END_EXPORTS

View File

@ -67,7 +67,7 @@ _impl_lp_readDiscHeader(PspIoDrvFileArg *arg, const char *devname)
.byte_size_last = 0 .byte_size_last = 0
}; };
ret = reserveUmdFuncs.IoDevctl(arg, devname, lp_UmdIoctl_READ_SECTORS, ret = reserveUmdFuncs.IoDevctl(arg, devname, lp_UmdDevctl_READ_SECTORS,
&param, sizeof param, &hdr, ISO_SECTOR_SIZE); &param, sizeof param, &hdr, ISO_SECTOR_SIZE);
return ret; return ret;
} }
@ -116,10 +116,10 @@ patched_IoDevctl(PspIoDrvFileArg *arg, const char *devname,
unsigned int cmd, void *indata, int inlen, unsigned int cmd, void *indata, int inlen,
void *outdata, int outlen) void *outdata, int outlen)
{ {
switch ((lp_UmdIoctl) cmd) { switch ((lp_UmdDevctl) cmd) {
case lp_UmdIoctl_READ_GENERAL: case lp_UmdDevctl_READ_GENERAL:
case lp_UmdIoctl_READ_CACHE: case lp_UmdDevctl_READ_CACHE:
case lp_UmdIoctl_READ_SECTORS: case lp_UmdDevctl_READ_SECTORS:
return _impl_lp_devctlRead(arg, devname, cmd, (lp_UmdLba *) indata, return _impl_lp_devctlRead(arg, devname, cmd, (lp_UmdLba *) indata,
inlen, outdata, outlen); inlen, outdata, outlen);
default: default:
@ -130,4 +130,25 @@ passthru:
return reserveUmdFuncs.IoDevctl(arg, devname, cmd, indata, inlen, outdata, outlen); return reserveUmdFuncs.IoDevctl(arg, devname, cmd, indata, inlen, outdata, outlen);
} }
int
patched_IoRead(PspIoDrvFileArg *arg, char *data, int len)
{
Kprintf("Reading UMD data, hum dee dum...\n");
return reserveUmdFuncs.IoRead(arg, data, len);
}
int
patched_IoOpen(PspIoDrvFileArg *arg, char *file, int flags, SceMode mode)
{
Kprintf("Opening UMD.\n");
return reserveUmdFuncs.IoOpen(arg, file, flags, mode);
}
void
lp_pingDiscRemoved(void)
{
first_read = 1;
}
// vim: ft=c.doxygen // vim: ft=c.doxygen

View File

@ -28,32 +28,39 @@
*/ */
typedef enum: int { typedef enum: int {
lp_UmdIoctl_01F00003 = 0x01F00003,
lp_UmdIoctl_01F010DB = 0x01F010DB, lp_UmdIoctl_01F010DB = 0x01F010DB,
lp_UmdIoctl_GET_OFFSET = 0x01D20001,
lp_UmdIoctl_DISC_TYPE = 0x01F20001, lp_UmdIoctl_LSEEK = 0x01F100A6,
lp_UmdIoctl_SEEK_RAW = 0x01F100A3, lp_UmdIoctl_READ = 0x01F30003
lp_UmdIoctl_CACHE_ADD = 0x01F100A4,
lp_UmdIoctl_CACHE_ADD2 = 0x01F300A5,
/* Cache control, worth intercepting */
lp_UmdIoctl_01F300A7 = 0x01F300A7,
lp_UmdIoctl_01F300A8 = 0x01F300A8,
lp_UmdIoctl_01F300A9 = 0x01F300A9,
lp_UmdIoctl_NUM_SECTORS = 0x01F20002,
lp_UmdIoctl_NUM_SECTORS2 = 0x01F20003,
lp_UmdIoctl_01E18030 = 0x01E18030,
lp_UmdIoctl_01E180D3 = 0x01E180D3,
lp_UmdIoctl_01E080A8 = 0x01E080A8,
lp_UmdIoctl_GET_SECTOR_BUF = 0x01E28035,
lp_UmdIoctl_GET_SECTOR_SIZE = 0x01E280A9,
lp_UmdIoctl_01E38034 = 0x01E38034,
lp_UmdIoctl_READ_GENERAL = 0x01E380C0,
lp_UmdIoctl_READ_SECTORS = 0x01F200A1,
lp_UmdIoctl_READ_CACHE = 0x01F200A2,
lp_UmdIoctl_GET_INFO = 0x01E38012
} lp_UmdIoctl; } lp_UmdIoctl;
typedef enum: int {
lp_UmdDevctl_01F00003 = 0x01F00003,
lp_UmdDevctl_01F010DB = 0x01F010DB,
lp_UmdDevctl_DISC_TYPE = 0x01F20001,
lp_UmdDevctl_SEEK_RAW = 0x01F100A3,
lp_UmdDevctl_CACHE_ADD = 0x01F100A4,
lp_UmdDevctl_CACHE_ADD2 = 0x01F300A5,
/* CacDev control, worth intercepting */
lp_UmdDevctl_01F300A7 = 0x01F300A7,
lp_UmdDevctl_01F300A8 = 0x01F300A8,
lp_UmdDevctl_01F300A9 = 0x01F300A9,
lp_UmdDevctl_NUM_SECTORS = 0x01F20002,
lp_UmdDevctl_NUM_SECTORS2 = 0x01F20003,
lp_UmdDevctl_01E18030 = 0x01E18030,
lp_UmdDevctl_01E180D3 = 0x01E180D3,
lp_UmdDevctl_01E080A8 = 0x01E080A8,
lp_UmdDevctl_GET_SECTOR_BUF = 0x01E28035,
lp_UmdDevctl_GET_SECTOR_SIZE = 0x01E280A9,
lp_UmdDevctl_01E38034 = 0x01E38034,
lp_UmdDevctl_READ_GENERAL = 0x01E380C0,
lp_UmdDevctl_READ_SECTORS = 0x01F200A1,
lp_UmdDevctl_READ_CACHE = 0x01F200A2,
lp_UmdDevctl_GET_INFO = 0x01E38012
} lp_UmdDevctl;
typedef struct { typedef struct {
int unknown1; // 0 int unknown1; // 0
int cmd; // 4 int cmd; // 4
@ -81,6 +88,23 @@ patched_IoDevctl(PspIoDrvFileArg *arg, const char *devname,
unsigned int cmd, void *indata, int inlen, unsigned int cmd, void *indata, int inlen,
void *outdata, int outlen); void *outdata, int outlen);
int
patched_IoRead(PspIoDrvFileArg *arg, char *data, int len);
int
patched_IoOpen(PspIoDrvFileArg *arg, char *file, int flags, SceMode mode);
/**
* @brief Tell this module to expect a new disc.
*
* This function resets the "first read" flag which prompts this module to read
* the UMD's disc ID.
* On its own, this function does not invalidate the cache. It will only be
* invalidated if the effective disc ID has changed on the next read devctl.
*/
void
lp_pingDiscRemoved(void);
#endif //__IO_FUNCS_H #endif //__IO_FUNCS_H
// vim: ft=c.doxygen // vim: ft=c.doxygen

83
main.c
View File

@ -12,46 +12,61 @@
#include "io_funcs.h" #include "io_funcs.h"
#include <string.h> #include <string.h>
#include <pspumd.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); void lp_patchFunction(u32 addr, void *newaddr, void *fptr);
PspIoDrv *umdDriver;
PspIoDrvFuncs reserveUmdFuncs; PspIoDrvFuncs reserveUmdFuncs;
PspIoDrvFuncs patchedUmdFuncs; SceUID vshCallbackId = 0;
SceUID umdCallbackId;
PspIoDrv originalUmdDriver; SceUID umdCallbackThread;
PspIoDrv reserveUmdDriver = {
.name = "umdraw",
.dev_type = 4,
.unk2 = 0x800,
.name2 = "UMD_RAW",
.funcs = &reserveUmdFuncs
};
PspIoDrv patchedUmdDriver = {
.name = "umd",
.dev_type = 4, // block device
.unk2 = 0x800,
.name2 = "UMD9660",
.funcs = &patchedUmdFuncs
};
#define MAX_MODULE_NUMBER 256 #define MAX_MODULE_NUMBER 256
// Bogus read to test intercepting
static int patched_IoRead(PspIoDrvFileArg *arg, char *data, int len)
int lp_discChangeCallback(int unk, int event, void *data)
{ {
Kprintf("Reading UMD data, hum dee dum...\n"); if (event == PSP_UMD_NOT_PRESENT)
return reserveUmdFuncs.IoRead(arg, data, len); lp_pingDiscRemoved();
if (vshCallbackId)
sceKernelNotifyCallback(vshCallbackId, event);
return 0;
}
int lp_discChangeWatcher(SceSize argc, void *argp)
{
SceUID callbacks[50];
int count;
SceKernelCallbackInfo cbinfo;
sceKernelGetThreadmanIdList(SCE_KERNEL_TMID_Callback, callbacks, 50, &count);
for (int i = 0; i < count; i++) {
sceKernelReferCallbackStatus(callbacks[i], &cbinfo);
if (!strcmp(cbinfo.name, "SceVshMediaDetectUMD")) {
Kprintf("Found VSH UMD callback: 0x%08x\n", vshCallbackId);
vshCallbackId = callbacks[i];
break;
}
}
umdCallbackId = sceKernelCreateCallback("lp_discChangeCallback",
lp_discChangeCallback,
NULL);
sceUmdRegisterUMDCallBack(umdCallbackId);
sceKernelSleepThreadCB();
} }
int module_start(SceSize argc, void *argp) int module_start(SceSize argc, void *argp)
{ {
PspIoDrv *umdDriver = 0;
int ret; int ret;
Kprintf("------------------\nUMD Livepatch starting...\n"); Kprintf("------------------\nUMD Livepatch starting...\n");
@ -61,7 +76,6 @@ int module_start(SceSize argc, void *argp)
umdDriver = sctrlHENFindDriver("umd"); umdDriver = sctrlHENFindDriver("umd");
if (umdDriver) { if (umdDriver) {
originalUmdDriver = *umdDriver;
reserveUmdFuncs = *umdDriver->funcs; reserveUmdFuncs = *umdDriver->funcs;
Kprintf("Found UMD driver at 0x%08x\n", umdDriver); Kprintf("Found UMD driver at 0x%08x\n", umdDriver);
} else { } else {
@ -69,9 +83,13 @@ int module_start(SceSize argc, void *argp)
return 1; return 1;
} }
patchedUmdFuncs = reserveUmdFuncs; umdCallbackThread = sceKernelCreateThread("lp_discChangeWatcher",
lp_discChangeWatcher,
0x10, 0x1000, 0, NULL);
sceKernelStartThread(umdCallbackThread, 0, NULL);
umdDriver->funcs->IoRead = patched_IoRead; umdDriver->funcs->IoRead = patched_IoRead;
umdDriver->funcs->IoOpen = patched_IoOpen;
umdDriver->funcs->IoDevctl = patched_IoDevctl; umdDriver->funcs->IoDevctl = patched_IoDevctl;
return 0; return 0;
@ -80,11 +98,16 @@ int module_start(SceSize argc, void *argp)
int module_stop(void) int module_stop(void)
{ {
Kprintf("Unloading UMD Livepatch."); Kprintf("Unloading UMD Livepatch.");
sceIoDelDrv("umd");
sceIoAddDrv(&originalUmdDriver); *umdDriver->funcs = reserveUmdFuncs;
sceIoDelDrv("umdraw"); Kprintf("Restored original UMD driver functions.\n");
Kprintf("Restored original UMD driver\n");
sceUmdUnRegisterUMDCallBack(umdCallbackId);
sceKernelDeleteCallback(umdCallbackId);
if (vshCallbackId)
sceUmdRegisterUMDCallBack(vshCallbackId);
Kprintf("Disconnected drive state callback.\n");
return 0; return 0;
} }

View File

@ -1,6 +1,8 @@
#include "io_funcs.h" #include "io_funcs.h"
#include "rpatch.h" #include "rpatch.h"
lp_UMDiffCommand cmd_buffer[1024];
lp_UMDiffFile lp_UMDiffFile
lp_PatchSet_open(const char *path) lp_PatchSet_open(const char *path)
{ {
@ -12,3 +14,9 @@ lp_PatchSet_covered(lp_UMDiffCommand *ps, u32 offset)
{ {
} }
int
lp_loadCmdsForIndex(long sector)
{
}

View File

@ -3,4 +3,7 @@
#include "umdiff/umdiff.h" #include "umdiff/umdiff.h"
int
lp_loadCmdsForIndex(long sector);
#endif //__RPATCH_H #endif //__RPATCH_H