mirror of
https://github.com/Thesola10/umd-livepatch.git
synced 2025-04-19 22:13:22 +00:00
now catching disc change
This commit is contained in:
parent
8cb83ec37e
commit
0aaa8d5d91
2
Makefile
2
Makefile
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
31
io_funcs.c
31
io_funcs.c
@ -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,
|
||||||
¶m, sizeof param, &hdr, ISO_SECTOR_SIZE);
|
¶m, 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
|
||||||
|
72
io_funcs.h
72
io_funcs.h
@ -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_LSEEK = 0x01F100A6,
|
||||||
lp_UmdIoctl_DISC_TYPE = 0x01F20001,
|
lp_UmdIoctl_READ = 0x01F30003
|
||||||
lp_UmdIoctl_SEEK_RAW = 0x01F100A3,
|
|
||||||
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
83
main.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
rpatch.c
8
rpatch.c
@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user