Add OTG support
This commit is contained in:
parent
558b381a4d
commit
92dab9c400
65
app/sfo.c
65
app/sfo.c
|
@ -1,67 +1,82 @@
|
|||
#include "sfo.h"
|
||||
#include <vitasdk.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static uint8_t SFO_BUFFER[0x10000];
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "sfo.h"
|
||||
#include "io.h"
|
||||
#include "err.h"
|
||||
int read_sfo_key(char* key, char* out, char* sfo) {
|
||||
memset(SFO_BUFFER, 0x00, sizeof(SFO_BUFFER));
|
||||
int ret = 0;
|
||||
|
||||
uint64_t sfo_size = get_file_size(sfo);
|
||||
if(sfo_size <= 0) ERROR(sfo_size);
|
||||
|
||||
char* sfo_buffer = malloc(sfo_size);
|
||||
if(sfo_buffer == NULL) ERROR(-1);
|
||||
|
||||
memset(sfo_buffer, 0x00, sfo_size);
|
||||
|
||||
// open sfo file
|
||||
int sfo_fd = sceIoOpen(sfo, SCE_O_RDONLY, 0777);
|
||||
if(sfo_fd < 0) return sfo_fd;
|
||||
|
||||
if(sfo_fd < 0) ERROR(sfo_fd);
|
||||
// read sfo
|
||||
int sfo_size = sceIoRead(sfo_fd, SFO_BUFFER, sizeof(SFO_BUFFER));
|
||||
|
||||
int rd = sceIoRead(sfo_fd, sfo_buffer, sfo_size);
|
||||
if(rd != sfo_size) ERROR(-2);
|
||||
|
||||
// close sfo
|
||||
sceIoClose(sfo_fd);
|
||||
|
||||
if(sfo_size < 0) return sfo_size;
|
||||
if(sfo_size >= sizeof(SFO_BUFFER)) return -1;
|
||||
if(sfo_size <= sizeof(sfo_header)) return -2;
|
||||
if(sceIoClose(sfo_fd) >= 0)
|
||||
sfo_fd = 0;
|
||||
|
||||
if(sfo_size <= sizeof(sfo_header)) ERROR(-3);
|
||||
|
||||
|
||||
// get sfo header
|
||||
sfo_header header;
|
||||
memcpy(&header, SFO_BUFFER, sizeof(sfo_header));
|
||||
memcpy(&header, sfo_buffer, sizeof(sfo_header));
|
||||
|
||||
if(memcmp(header.magic, "\0PSF", sizeof(header.magic)) != 0) return -3; // check magic
|
||||
if(header.count > 200) return -4; // give up if more than 200 keys
|
||||
if(sfo_size < (sizeof(sfo_header) + (sizeof(sfo_key) * header.count))) return -5; // check if size is enough for keys + sfo header size
|
||||
if(memcmp(header.magic, "\0PSF", sizeof(header.magic)) != 0) ERROR(-4); // check magic
|
||||
if(header.count > 200) ERROR(-5); // give up if more than 200 keys
|
||||
if(sfo_size < (sizeof(sfo_header) + (sizeof(sfo_key) * header.count))) ERROR(-6); // check if size is enough for keys + sfo header size
|
||||
|
||||
uint32_t ptr = sizeof(sfo_header);
|
||||
|
||||
// read keys
|
||||
for(int i = 0; i < header.count; i++)
|
||||
{
|
||||
if(ptr >= sizeof(SFO_BUFFER)) return -6; // check for overflow
|
||||
if(ptr > sfo_size) ERROR(-7); // check for overflow
|
||||
|
||||
char key_name[64];
|
||||
char key_value[64];
|
||||
|
||||
sfo_key s_key;
|
||||
|
||||
memcpy(&s_key, SFO_BUFFER+ptr, sizeof(sfo_key));
|
||||
memcpy(&s_key, sfo_buffer+ptr, sizeof(sfo_key));
|
||||
ptr += sizeof(sfo_key);
|
||||
|
||||
if(s_key.type != PSF_TYPE_STR) continue;
|
||||
|
||||
// calculate location of key in buffer
|
||||
int name_offset = header.key_offset + s_key.name_offset;
|
||||
if(name_offset > sfo_size) return -7;
|
||||
if(name_offset > sfo_size) ERROR(-8);
|
||||
|
||||
int data_offset = header.value_offset + s_key.data_offset;
|
||||
if(data_offset > sfo_size) return -8;
|
||||
if(data_offset > sfo_size) ERROR(-9);
|
||||
|
||||
// copy the key and value into buffers.
|
||||
strncpy(key_name, SFO_BUFFER + name_offset, sizeof(key_name)-1);
|
||||
strncpy(key_value, SFO_BUFFER + data_offset, sizeof(key_value)-1);
|
||||
strncpy(key_name, sfo_buffer + name_offset, sizeof(key_name)-1);
|
||||
strncpy(key_value, sfo_buffer + data_offset, sizeof(key_value)-1);
|
||||
|
||||
if(strncmp(key_name, key, sizeof(key_name)) == 0){
|
||||
strncpy(out, key_value, sizeof(key_value)-1);
|
||||
return 0;
|
||||
ERROR(0);
|
||||
}
|
||||
|
||||
}
|
||||
return -9;
|
||||
error:
|
||||
if(sfo_buffer != NULL)
|
||||
free(sfo_buffer);
|
||||
if(sfo_fd > 0)
|
||||
sceIoClose(sfo_fd);
|
||||
return ret;
|
||||
}
|
|
@ -24,6 +24,7 @@ add_executable(${PROJECT_NAME}
|
|||
f00d.c
|
||||
io.c
|
||||
cobra.c
|
||||
otg.c
|
||||
format.c
|
||||
cmd56.c
|
||||
)
|
||||
|
|
|
@ -10,7 +10,8 @@ void _start() __attribute__((weak, alias("module_start")));
|
|||
int module_start(SceSize argc, const void *args)
|
||||
{
|
||||
cobra_patch(); // revert cobra blackfin patch
|
||||
cmd56_patch(); // patch cmd56 ..
|
||||
otg_patch(); // enable otg
|
||||
cmd56_patch(); // patch cmd56
|
||||
get_module_functions(); // get format stuff
|
||||
|
||||
return SCE_KERNEL_START_SUCCESS;
|
||||
|
@ -20,5 +21,6 @@ int module_stop(SceSize argc, const void *args)
|
|||
{
|
||||
cobra_unpatch();
|
||||
cmd56_unpatch();
|
||||
otg_unpatch();
|
||||
return SCE_KERNEL_STOP_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
#include "log.h"
|
||||
#include <vitasdkkern.h>
|
||||
#include <taihen.h>
|
||||
#include <stdint.h>
|
||||
|
||||
SceUID sceSysconSetOtgPowerLevelHook = -1;
|
||||
static tai_hook_ref_t sceSysconSetOtgPowerLevelHookRef;
|
||||
|
||||
|
||||
static int return_1() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// shamelessly stolen from dots_tb
|
||||
static SceUID sceSysconSetOtgPowerLevel_patched(uint32_t *pwr_val) {
|
||||
SceUID ret, state;
|
||||
ENTER_SYSCALL(state);
|
||||
|
||||
ret = TAI_CONTINUE(SceUID, sceSysconSetOtgPowerLevelHookRef, pwr_val);
|
||||
PRINT_STR("sceSysconSetOtgPowerLevel original %x\n", *pwr_val);
|
||||
if(*pwr_val == 0x700)
|
||||
PRINT_STR("sceSysconSetOtgPowerLevel new %x\n\n", *pwr_val = 0x200);
|
||||
|
||||
EXIT_SYSCALL(state);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
// force load usb mass storage plugin on all devices
|
||||
int load_umass() {
|
||||
if(ksceKernelSearchModuleByName("SceUsbMass") < 0) {
|
||||
tai_hook_ref_t ksceSysrootIsSafeModeHookRef;
|
||||
tai_hook_ref_t ksceSblAimgrIsDolceHookRef;
|
||||
|
||||
// temporarily patch isSafeMode and isDolce
|
||||
SceUID ksceSysrootIsSafeModeHook = taiHookFunctionExportForKernel(KERNEL_PID,
|
||||
&ksceSysrootIsSafeModeHookRef,
|
||||
"SceSysmem",
|
||||
0x2ED7F97A, // SceSysrootForKernel
|
||||
0x834439A7, // ksceSysrootIsSafemode
|
||||
return_1);
|
||||
|
||||
PRINT_STR("ksceSysrootIsSafeModeHook 0x%04X\n", ksceSysrootIsSafeModeHook);
|
||||
PRINT_STR("ksceSysrootIsSafeModeHookRef 0x%04X\n", ksceSysrootIsSafeModeHookRef);
|
||||
|
||||
|
||||
SceUID ksceSblAimgrIsDolceHook = taiHookFunctionExportForKernel(KERNEL_PID,
|
||||
&ksceSblAimgrIsDolceHookRef,
|
||||
"SceSysmem",
|
||||
0xFD00C69A, // SceSblAIMgrForDriver
|
||||
0x71608CA3, // ksceSblAimgrIsDolce
|
||||
return_1);
|
||||
|
||||
PRINT_STR("ksceSblAimgrIsDolceHook 0x%04X\n", ksceSblAimgrIsDolceHook);
|
||||
PRINT_STR("ksceSblAimgrIsDolceHookRef 0x%04X\n", ksceSblAimgrIsDolceHookRef);
|
||||
|
||||
// start from here, technically the module is actually in os0 bootimage
|
||||
// but cannot start after system already started, unfortunately.
|
||||
SceUID umass_modid = ksceKernelLoadStartModule("ux0:VitaShell/module/umass.skprx", 0, NULL, 0, NULL, NULL);
|
||||
PRINT_STR("Load umass.skprx 0x%04X\n", umass_modid);
|
||||
|
||||
// release hooks
|
||||
if(ksceSysrootIsSafeModeHook > 0) taiHookReleaseForKernel(ksceSysrootIsSafeModeHook, ksceSysrootIsSafeModeHookRef);
|
||||
if(ksceSblAimgrIsDolceHook > 0) taiHookReleaseForKernel(ksceSblAimgrIsDolceHook, ksceSblAimgrIsDolceHookRef);
|
||||
if(umass_modid < 0) return umass_modid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int otg_patch() {
|
||||
// improve compatibility with OTG connectors
|
||||
sceSysconSetOtgPowerLevelHook = taiHookFunctionImportForKernel(KERNEL_PID,
|
||||
&sceSysconSetOtgPowerLevelHookRef,
|
||||
"SceUsbServ",
|
||||
TAI_ANY_LIBRARY,
|
||||
0xD6F6D472, // sceSysconSetOtgPowerLevel
|
||||
sceSysconSetOtgPowerLevel_patched);
|
||||
|
||||
PRINT_STR("sceSysconSetOtgPowerLevelHook 0x%04X\n", sceSysconSetOtgPowerLevelHook);
|
||||
PRINT_STR("sceSysconSetOtgPowerLevelHookRef 0x%04X\n", sceSysconSetOtgPowerLevelHookRef);
|
||||
|
||||
// allow loading usb storage on regular vita
|
||||
load_umass();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int otg_unpatch() {
|
||||
if(sceSysconSetOtgPowerLevelHook >= 0) taiHookReleaseForKernel(sceSysconSetOtgPowerLevelHook, sceSysconSetOtgPowerLevelHookRef);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
int otg_patch();
|
||||
int otg_unpatch();
|
Loading…
Reference in New Issue