mirror of
https://github.com/joel16/VitaShell.git
synced 2024-11-23 11:49:40 +00:00
Added user proxy module
This commit is contained in:
parent
a6f3868661
commit
86a4de0271
@ -48,7 +48,7 @@ FUNCTION(ADD_RESOURCES out_var)
|
||||
SET(${out_var} "${result}" PARENT_SCOPE)
|
||||
ENDFUNCTION()
|
||||
|
||||
file(GLOB res_files RELATIVE ${CMAKE_SOURCE_DIR} resources/*.png resources/*.txt resources/*.bin resources/*.skprx)
|
||||
file(GLOB res_files RELATIVE ${CMAKE_SOURCE_DIR} resources/*.png resources/*.txt resources/*.bin resources/*.suprx resources/*.skprx)
|
||||
add_resources(vitashell_res ${res_files})
|
||||
|
||||
add_executable(VitaShell
|
||||
@ -122,7 +122,7 @@ target_link_libraries(VitaShell
|
||||
stdc++
|
||||
taihen_stub
|
||||
HENkaku_stub
|
||||
VitaShellKernel_stub_weak
|
||||
VitaShellUser_stub_weak
|
||||
SceAppMgr_stub
|
||||
SceAppUtil_stub
|
||||
SceAudio_stub
|
||||
|
4
file.c
4
file.c
@ -38,7 +38,7 @@ static char *devices[] = {
|
||||
"vs0:",
|
||||
};
|
||||
|
||||
#define N_DEVICES (sizeof(devices)/sizeof(char **))
|
||||
#define N_DEVICES (sizeof(devices) / sizeof(char **))
|
||||
|
||||
int allocateReadFile(const char *file, void **buffer) {
|
||||
SceUID fd = sceIoOpen(file, SCE_O_RDONLY, 0);
|
||||
@ -604,7 +604,7 @@ int getFileType(const char *file) {
|
||||
char *p = strrchr(file, '.');
|
||||
if (p) {
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(extension_types)/sizeof(ExtensionType)); i++) {
|
||||
for (i = 0; i < (sizeof(extension_types) / sizeof(ExtensionType)); i++) {
|
||||
if (strcasecmp(p, extension_types[i].extension) == 0) {
|
||||
return extension_types[i].type;
|
||||
}
|
||||
|
76
init.c
76
init.c
@ -47,6 +47,7 @@ INCLUDE_EXTERN_RESOURCE(theme_txt);
|
||||
INCLUDE_EXTERN_RESOURCE(colors_txt);
|
||||
INCLUDE_EXTERN_RESOURCE(english_us_txt);
|
||||
|
||||
INCLUDE_EXTERN_RESOURCE(user_suprx);
|
||||
INCLUDE_EXTERN_RESOURCE(usbdevice_skprx);
|
||||
// INCLUDE_EXTERN_RESOURCE(kernel_skprx);
|
||||
// INCLUDE_EXTERN_RESOURCE(umass_skprx);
|
||||
@ -78,6 +79,7 @@ static DefaultFile default_files[] = {
|
||||
DEFAULT_FILE("ux0:VitaShell/theme/Default/fastforward.png", fastforward_png, 0),
|
||||
DEFAULT_FILE("ux0:VitaShell/theme/Default/fastrewind.png", fastrewind_png, 0),
|
||||
|
||||
DEFAULT_FILE("ux0:VitaShell/module/user.suprx", user_suprx, 1),
|
||||
DEFAULT_FILE("ux0:VitaShell/module/usbdevice.skprx", usbdevice_skprx, 1),
|
||||
// DEFAULT_FILE("ux0:VitaShell/module/kernel.skprx", kernel_skprx, 1),
|
||||
// DEFAULT_FILE("ux0:VitaShell/module/umass.skprx", umass_skprx, 1),
|
||||
@ -233,15 +235,31 @@ static void loadScePaf() {
|
||||
sceSysmoduleLoadModuleInternalWithArg(0x80000008, sizeof(scepaf_argp), scepaf_argp, buf);
|
||||
}
|
||||
|
||||
void initVitaShell() {
|
||||
// Load kernel module
|
||||
SceUID modid = taiLoadStartKernelModule("ux0:VitaShell/module/kernel.skprx", 0, NULL, 0);
|
||||
if (modid >= 0) {
|
||||
// Trick
|
||||
const char * const argv[] = { "restart", NULL };
|
||||
sceAppMgrLoadExec("app0:eboot.bin", NULL, NULL);
|
||||
}
|
||||
void installDefaultFiles() {
|
||||
// Make VitaShell folders
|
||||
sceIoMkdir("ux0:VitaShell", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/internal", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/language", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/module", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/theme", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/theme/Default", 0777);
|
||||
|
||||
sceIoMkdir("ux0:patch", 0777);
|
||||
sceIoMkdir("ux0:patch/VITASHELL", 0777);
|
||||
sceIoMkdir("ux0:patch/VITASHELL/sce_sys", 0777);
|
||||
sceIoMkdir("ux0:patch/VITASHELL/sce_sys/changeinfo", 0777);
|
||||
|
||||
// Write default files if they don't exist
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(default_files) / sizeof(DefaultFile)); i++) {
|
||||
SceIoStat stat;
|
||||
memset(&stat, 0, sizeof(stat));
|
||||
if (sceIoGetstat(default_files[i].path, &stat) < 0 || (default_files[i].replace && (int)stat.st_size != default_files[i].size))
|
||||
WriteFile(default_files[i].path, default_files[i].buffer, default_files[i].size);
|
||||
}
|
||||
}
|
||||
|
||||
void initVitaShell() {
|
||||
// Set CPU to 444mhz
|
||||
scePowerSetArmClockFrequency(444);
|
||||
|
||||
@ -287,54 +305,38 @@ void initVitaShell() {
|
||||
sceSysmoduleLoadModule(SCE_SYSMODULE_NET);
|
||||
sceSysmoduleLoadModule(SCE_SYSMODULE_HTTPS);
|
||||
|
||||
// Init audio
|
||||
vitaAudioInit(0x40);
|
||||
|
||||
// Init
|
||||
initSceAppUtil();
|
||||
vitaAudioInit(0x40);
|
||||
initVita2dLib();
|
||||
initSceAppUtil();
|
||||
initNet();
|
||||
|
||||
// Init power tick thread
|
||||
initPowerTickThread();
|
||||
|
||||
// Make VitaShell folders
|
||||
sceIoMkdir("ux0:VitaShell", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/internal", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/language", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/module", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/theme", 0777);
|
||||
sceIoMkdir("ux0:VitaShell/theme/Default", 0777);
|
||||
|
||||
sceIoMkdir("ux0:patch", 0777);
|
||||
sceIoMkdir("ux0:patch/VITASHELL", 0777);
|
||||
sceIoMkdir("ux0:patch/VITASHELL/sce_sys", 0777);
|
||||
sceIoMkdir("ux0:patch/VITASHELL/sce_sys/changeinfo", 0777);
|
||||
|
||||
// Write default files if they don't exist
|
||||
int i;
|
||||
for (i = 0; i < (sizeof(default_files) / sizeof(DefaultFile)); i++) {
|
||||
SceIoStat stat;
|
||||
memset(&stat, 0, sizeof(stat));
|
||||
if (sceIoGetstat(default_files[i].path, &stat) < 0 || (default_files[i].replace && (int)stat.st_size != default_files[i].size))
|
||||
WriteFile(default_files[i].path, default_files[i].buffer, default_files[i].size);
|
||||
}
|
||||
|
||||
// Delete VitaShell updater if available
|
||||
SceIoStat stat;
|
||||
memset(&stat, 0, sizeof(SceIoStat));
|
||||
if (sceIoGetstat("ux0:app/VSUPDATER", &stat) >= 0) {
|
||||
deleteApp("VSUPDATER");
|
||||
}
|
||||
|
||||
// Install default files
|
||||
installDefaultFiles();
|
||||
|
||||
// Load modules
|
||||
SceUID kernel_modid = taiLoadStartKernelModule("ux0:VitaShell/module/kernel.skprx", 0, NULL, 0);
|
||||
SceUID user_modid = sceKernelLoadStartModule("ux0:VitaShell/module/user.suprx", 0, NULL, 0, NULL, NULL);
|
||||
|
||||
debugPrintf("kernel_modid: 0x%08X\n", kernel_modid);
|
||||
debugPrintf("user_modid: 0x%08X\n", user_modid);
|
||||
}
|
||||
|
||||
void finishVitaShell() {
|
||||
// Finish
|
||||
finishNet();
|
||||
finishVita2dLib();
|
||||
finishSceAppUtil();
|
||||
|
||||
// Shutdown audio
|
||||
finishVita2dLib();
|
||||
vitaAudioShutdown();
|
||||
|
||||
// Unload modules
|
||||
|
11
language.c
11
language.c
@ -203,7 +203,6 @@ void loadLanguage(int id) {
|
||||
// USB strings
|
||||
LANGUAGE_ENTRY(USB_CONNECTED),
|
||||
LANGUAGE_ENTRY(USB_NOT_CONNECTED),
|
||||
LANGUAGE_ENTRY(USB_CONNECTION_PERMISSION),
|
||||
LANGUAGE_ENTRY(USB_CONNECTION_NOT_AVAILABLE),
|
||||
LANGUAGE_ENTRY(USB_WAIT_ATTACH),
|
||||
LANGUAGE_ENTRY(USB_UMA0_MOUNTED),
|
||||
@ -213,28 +212,26 @@ void loadLanguage(int id) {
|
||||
// Others
|
||||
LANGUAGE_ENTRY(SAFE_MODE),
|
||||
LANGUAGE_ENTRY(UNSAFE_MODE),
|
||||
LANGUAGE_ENTRY(TOOLBOX),
|
||||
LANGUAGE_ENTRY(SYSINFO_TITLE),
|
||||
LANGUAGE_ENTRY(PLEASE_WAIT),
|
||||
LANGUAGE_ENTRY(SAVE_MODIFICATIONS),
|
||||
LANGUAGE_ENTRY(NO_SPACE_ERROR),
|
||||
LANGUAGE_ENTRY(EXTENDED_PERMISSIONS_REQUIRED),
|
||||
LANGUAGE_ENTRY(WIFI_ERROR),
|
||||
LANGUAGE_ENTRY(FTP_SERVER),
|
||||
LANGUAGE_ENTRY(SYS_INFO),
|
||||
LANGUAGE_ENTRY(UPDATE_QUESTION),
|
||||
LANGUAGE_ENTRY(ARCHIVE_NAME),
|
||||
LANGUAGE_ENTRY(COMPRESSION_LEVEL),
|
||||
};
|
||||
|
||||
// Load default config file
|
||||
readConfigBuffer(&_binary_resources_english_us_txt_start, (int)&_binary_resources_english_us_txt_size, language_entries, sizeof(language_entries)/sizeof(ConfigEntry));
|
||||
readConfigBuffer(&_binary_resources_english_us_txt_start, (int)&_binary_resources_english_us_txt_size, language_entries, sizeof(language_entries) / sizeof(ConfigEntry));
|
||||
|
||||
// Load custom config file
|
||||
if (use_custom_config) {
|
||||
if (id >= 0 && id < (sizeof(lang)/sizeof(char *))) {
|
||||
if (id >= 0 && id < (sizeof(lang) / sizeof(char *))) {
|
||||
char path[MAX_PATH_LENGTH];
|
||||
snprintf(path, MAX_PATH_LENGTH, "ux0:VitaShell/language/%s.txt", lang[id]);
|
||||
readConfig(path, language_entries, sizeof(language_entries)/sizeof(ConfigEntry));
|
||||
readConfig(path, language_entries, sizeof(language_entries) / sizeof(ConfigEntry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,6 @@ enum LanguageContainer {
|
||||
// USB strings
|
||||
USB_CONNECTED,
|
||||
USB_NOT_CONNECTED,
|
||||
USB_CONNECTION_PERMISSION,
|
||||
USB_CONNECTION_NOT_AVAILABLE,
|
||||
USB_WAIT_ATTACH,
|
||||
USB_UMA0_MOUNTED,
|
||||
@ -172,14 +171,12 @@ enum LanguageContainer {
|
||||
// Others
|
||||
SAFE_MODE,
|
||||
UNSAFE_MODE,
|
||||
TOOLBOX,
|
||||
SYSINFO_TITLE,
|
||||
PLEASE_WAIT,
|
||||
SAVE_MODIFICATIONS,
|
||||
NO_SPACE_ERROR,
|
||||
EXTENDED_PERMISSIONS_REQUIRED,
|
||||
WIFI_ERROR,
|
||||
FTP_SERVER,
|
||||
SYS_INFO,
|
||||
UPDATE_QUESTION,
|
||||
ARCHIVE_NAME,
|
||||
COMPRESSION_LEVEL,
|
||||
|
10
main.c
10
main.c
@ -1053,7 +1053,7 @@ static int fileBrowserMenuCtrl() {
|
||||
if (sceKernelGetModel() == SCE_KERNEL_MODEL_VITATV) {
|
||||
infoDialog(language_container[USB_CONNECTION_NOT_AVAILABLE]);
|
||||
} else if (is_safe_mode) {
|
||||
infoDialog(language_container[USB_CONNECTION_PERMISSION]);
|
||||
infoDialog(language_container[EXTENDED_PERMISSIONS_REQUIRED]);
|
||||
} else {
|
||||
SceUdcdDeviceState state;
|
||||
sceUdcdGetDeviceState(&state);
|
||||
@ -1127,11 +1127,9 @@ static int fileBrowserMenuCtrl() {
|
||||
setContextMenuMainVisibilities();
|
||||
setContextMenuMode(CONTEXT_MENU_OPENING);
|
||||
} else {
|
||||
if (sceKernelGetModel() == SCE_KERNEL_MODEL_VITATV) {
|
||||
setContextMenu(&context_menu_home);
|
||||
setContextMenuHomeVisibilities();
|
||||
setContextMenuMode(CONTEXT_MENU_OPENING);
|
||||
}
|
||||
setContextMenu(&context_menu_home);
|
||||
setContextMenuHomeVisibilities();
|
||||
setContextMenuMode(CONTEXT_MENU_OPENING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
main.h
2
main.h
@ -69,7 +69,7 @@
|
||||
|
||||
#include <taihen.h>
|
||||
|
||||
#include <vitashell_kernel.h>
|
||||
#include <vitashell_user.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "vitashell_config.h"
|
||||
|
@ -40,7 +40,7 @@ MenuEntry menu_home_entries[] = {
|
||||
{ UMOUNT_USB_UX0, 3, 0, CTX_INVISIBLE },
|
||||
};
|
||||
|
||||
#define N_MENU_HOME_ENTRIES (sizeof(menu_home_entries)/sizeof(MenuEntry))
|
||||
#define N_MENU_HOME_ENTRIES (sizeof(menu_home_entries) / sizeof(MenuEntry))
|
||||
|
||||
enum MenuMainEntrys {
|
||||
MENU_MAIN_ENTRY_MARK_UNMARK_ALL,
|
||||
@ -68,7 +68,7 @@ MenuEntry menu_main_entries[] = {
|
||||
{ SORT_BY, 13, 1, CTX_VISIBLE },
|
||||
};
|
||||
|
||||
#define N_MENU_MAIN_ENTRIES (sizeof(menu_main_entries)/sizeof(MenuEntry))
|
||||
#define N_MENU_MAIN_ENTRIES (sizeof(menu_main_entries) / sizeof(MenuEntry))
|
||||
|
||||
enum MenuSortEntrys {
|
||||
MENU_SORT_ENTRY_BY_NAME,
|
||||
@ -82,7 +82,7 @@ MenuEntry menu_sort_entries[] = {
|
||||
{ BY_DATE, 15, 0, CTX_INVISIBLE },
|
||||
};
|
||||
|
||||
#define N_MENU_SORT_ENTRIES (sizeof(menu_sort_entries)/sizeof(MenuEntry))
|
||||
#define N_MENU_SORT_ENTRIES (sizeof(menu_sort_entries) / sizeof(MenuEntry))
|
||||
|
||||
enum MenuMoreEntrys {
|
||||
MENU_MORE_ENTRY_COMPRESS,
|
||||
@ -100,7 +100,7 @@ MenuEntry menu_more_entries[] = {
|
||||
{ CALCULATE_SHA1, 16, 0, CTX_INVISIBLE },
|
||||
};
|
||||
|
||||
#define N_MENU_MORE_ENTRIES (sizeof(menu_more_entries)/sizeof(MenuEntry))
|
||||
#define N_MENU_MORE_ENTRIES (sizeof(menu_more_entries) / sizeof(MenuEntry))
|
||||
|
||||
static int contextMenuHomeEnterCallback(int sel, void *context);
|
||||
static int contextMenuMainEnterCallback(int sel, void *context);
|
||||
@ -194,23 +194,25 @@ void setContextMenuHomeVisibilities() {
|
||||
}
|
||||
|
||||
// Invisible if already mounted or if we're not on a Vita TV
|
||||
int uma_exist = 0;
|
||||
|
||||
SceIoStat stat;
|
||||
memset(&stat, 0, sizeof(SceIoStat));
|
||||
if (sceIoGetstat("uma0:", &stat) >= 0)
|
||||
uma_exist = 1;
|
||||
|
||||
if (uma_exist || isUx0Redirected() || sceKernelGetModel() == SCE_KERNEL_MODEL_VITA)
|
||||
if (sceKernelGetModel() == SCE_KERNEL_MODEL_VITA) {
|
||||
menu_home_entries[MENU_HOME_ENTRY_MOUNT_UMA0].visibility = CTX_INVISIBLE;
|
||||
|
||||
if (isUx0Redirected()) {
|
||||
menu_home_entries[MENU_HOME_ENTRY_MOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
} else if (uma_exist) {
|
||||
menu_home_entries[MENU_HOME_ENTRY_UMOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
} else {
|
||||
menu_home_entries[MENU_HOME_ENTRY_MOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
menu_home_entries[MENU_HOME_ENTRY_UMOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
SceIoStat stat;
|
||||
memset(&stat, 0, sizeof(SceIoStat));
|
||||
if (sceIoGetstat("uma0:", &stat) >= 0) {
|
||||
menu_home_entries[MENU_HOME_ENTRY_MOUNT_UMA0].visibility = CTX_INVISIBLE;
|
||||
} else {
|
||||
menu_home_entries[MENU_HOME_ENTRY_MOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
menu_home_entries[MENU_HOME_ENTRY_UMOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
}
|
||||
|
||||
if (shellUserIsUx0Redirected()) {
|
||||
menu_home_entries[MENU_HOME_ENTRY_MOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
} else {
|
||||
menu_home_entries[MENU_HOME_ENTRY_UMOUNT_USB_UX0].visibility = CTX_INVISIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
// Go to first entry
|
||||
|
32
modules/usbdevice/CMakeLists.txt
Normal file
32
modules/usbdevice/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
if(DEFINED ENV{VITASDK})
|
||||
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
|
||||
else()
|
||||
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
project(usbdevice)
|
||||
include("${VITASDK}/share/vita.cmake" REQUIRED)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -O3 -nostdlib")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
|
||||
|
||||
add_executable(usbdevice
|
||||
main.c
|
||||
)
|
||||
|
||||
target_link_libraries(usbdevice
|
||||
SceIofilemgrForDriver_stub
|
||||
SceSysclibForDriver_stub
|
||||
taihenForKernel_stub
|
||||
)
|
||||
|
||||
vita_create_self(usbdevice.skprx usbdevice CONFIG exports.yml UNSAFE)
|
||||
|
||||
add_custom_target(copy
|
||||
COMMAND cp usbdevice.skprx ../../../resources/usbdevice.skprx
|
||||
DEPENDS usbdevice.skprx
|
||||
)
|
8
modules/usbdevice/exports.yml
Normal file
8
modules/usbdevice/exports.yml
Normal file
@ -0,0 +1,8 @@
|
||||
VitaShellUsbDevice:
|
||||
attributes: 0
|
||||
version:
|
||||
major: 1
|
||||
minor: 0
|
||||
main:
|
||||
start: module_start
|
||||
stop: module_stop
|
89
modules/usbdevice/main.c
Normal file
89
modules/usbdevice/main.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
VitaShell
|
||||
Copyright (C) 2015-2017, TheFloW
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <psp2kern/kernel/modulemgr.h>
|
||||
#include <psp2kern/io/fcntl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <taihen.h>
|
||||
|
||||
static tai_hook_ref_t ksceIoOpenRef;
|
||||
static tai_hook_ref_t ksceIoReadRef;
|
||||
|
||||
static SceUID hooks[3];
|
||||
|
||||
static int first = 1;
|
||||
|
||||
static SceUID ksceIoOpenPatched(const char *file, int flags, SceMode mode) {
|
||||
first = 1;
|
||||
return TAI_CONTINUE(SceUID, ksceIoOpenRef, file, flags, mode);
|
||||
}
|
||||
|
||||
static int ksceIoReadPatched(SceUID fd, void *data, SceSize size) {
|
||||
int res = TAI_CONTINUE(int, ksceIoReadRef, fd, data, size);
|
||||
|
||||
if (first) {
|
||||
first = 0;
|
||||
|
||||
// Manipulate boot sector to support exFAT
|
||||
if (memcmp(data + 0x3, "EXFAT", 5) == 0) {
|
||||
// Sector size
|
||||
*(uint16_t *)(data + 0xB) = 1 << *(uint8_t *)(data + 0x6C);
|
||||
|
||||
// Volume size
|
||||
*(uint32_t *)(data + 0x20) = *(uint32_t *)(data + 0x48);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void _start() __attribute__ ((weak, alias("module_start")));
|
||||
int module_start(SceSize args, void *argp) {
|
||||
// Get tai module info
|
||||
tai_module_info_t info;
|
||||
info.size = sizeof(tai_module_info_t);
|
||||
if (taiGetModuleInfoForKernel(KERNEL_PID, "SceUsbstorVStorDriver", &info) < 0)
|
||||
return SCE_KERNEL_START_SUCCESS;
|
||||
|
||||
// Remove image path limitation
|
||||
char zero[0x6E];
|
||||
memset(zero, 0, 0x6E);
|
||||
hooks[0] = taiInjectDataForKernel(KERNEL_PID, info.modid, 0, 0x1738, zero, 0x6E);
|
||||
|
||||
// Add patches to support exFAT
|
||||
hooks[1] = taiHookFunctionImportForKernel(KERNEL_PID, &ksceIoOpenRef, "SceUsbstorVStorDriver", 0x40FD29C7, 0x75192972, ksceIoOpenPatched);
|
||||
hooks[2] = taiHookFunctionImportForKernel(KERNEL_PID, &ksceIoReadRef, "SceUsbstorVStorDriver", 0x40FD29C7, 0xE17EFC03, ksceIoReadPatched);
|
||||
|
||||
return SCE_KERNEL_START_SUCCESS;
|
||||
}
|
||||
|
||||
int module_stop(SceSize args, void *argp) {
|
||||
if (hooks[2] >= 0)
|
||||
taiHookReleaseForKernel(hooks[2], ksceIoReadRef);
|
||||
|
||||
if (hooks[1] >= 0)
|
||||
taiHookReleaseForKernel(hooks[1], ksceIoOpenRef);
|
||||
|
||||
if (hooks[0] >= 0)
|
||||
taiInjectReleaseForKernel(hooks[0]);
|
||||
|
||||
return SCE_KERNEL_STOP_SUCCESS;
|
||||
}
|
43
modules/user/CMakeLists.txt
Normal file
43
modules/user/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||
if(DEFINED ENV{VITASDK})
|
||||
set(CMAKE_TOOLCHAIN_FILE "$ENV{VITASDK}/share/vita.toolchain.cmake" CACHE PATH "toolchain file")
|
||||
else()
|
||||
message(FATAL_ERROR "Please define VITASDK to point to your SDK path!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
project(user)
|
||||
include("${VITASDK}/share/vita.cmake" REQUIRED)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -O3 -nostdlib")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
|
||||
|
||||
add_executable(user
|
||||
main.c
|
||||
)
|
||||
|
||||
target_link_libraries(user
|
||||
SceLibKernel_stub
|
||||
SceIofilemgr_stub
|
||||
VitaShellKernel_stub
|
||||
)
|
||||
|
||||
vita_create_self(user.suprx user CONFIG exports.yml UNSAFE)
|
||||
|
||||
vita_create_stubs(stubs user ${CMAKE_SOURCE_DIR}/exports.yml)
|
||||
|
||||
install(DIRECTORY ${CMAKE_BINARY_DIR}/stubs/
|
||||
DESTINATION lib
|
||||
FILES_MATCHING PATTERN "*.a"
|
||||
)
|
||||
|
||||
install(FILES vitashell_user.h
|
||||
DESTINATION include
|
||||
)
|
||||
|
||||
add_custom_target(copy
|
||||
COMMAND cp user.suprx ../../../resources/user.suprx
|
||||
DEPENDS user.suprx
|
||||
)
|
15
modules/user/exports.yml
Normal file
15
modules/user/exports.yml
Normal file
@ -0,0 +1,15 @@
|
||||
VitaShellUser:
|
||||
attributes: 0
|
||||
version:
|
||||
major: 1
|
||||
minor: 0
|
||||
main:
|
||||
start: module_start
|
||||
stop: module_stop
|
||||
modules:
|
||||
VitaShellUserLibrary:
|
||||
syscall: false
|
||||
functions:
|
||||
- shellUserIsUx0Redirected
|
||||
- shellUserRedirectUx0
|
||||
- shellUserUnredirectUx0
|
48
modules/user/main.c
Normal file
48
modules/user/main.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
VitaShell
|
||||
Copyright (C) 2015-2017, TheFloW
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <psp2/kernel/modulemgr.h>
|
||||
#include <psp2/kernel/sysmem.h>
|
||||
#include <psp2/io/fcntl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <vitashell_kernel.h>
|
||||
|
||||
int shellUserIsUx0Redirected() {
|
||||
return shellKernelIsUx0Redirected();
|
||||
}
|
||||
|
||||
int shellUserRedirectUx0() {
|
||||
return shellKernelRedirectUx0();
|
||||
}
|
||||
|
||||
int shellUserUnredirectUx0() {
|
||||
return shellKernelUnredirectUx0();
|
||||
}
|
||||
|
||||
void _start() __attribute__ ((weak, alias("module_start")));
|
||||
int module_start(SceSize args, void *argp) {
|
||||
return SCE_KERNEL_START_SUCCESS;
|
||||
}
|
||||
|
||||
int module_stop(SceSize args, void *argp) {
|
||||
return SCE_KERNEL_STOP_SUCCESS;
|
||||
}
|
26
modules/user/vitashell_user.h
Normal file
26
modules/user/vitashell_user.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
VitaShell
|
||||
Copyright (C) 2015-2017, TheFloW
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __VITASHELL_USER_H__
|
||||
#define __VITASHELL_USER_H__
|
||||
|
||||
int shellUserIsUx0Redirected();
|
||||
int shellUserRedirectUx0();
|
||||
int shellUserUnredirectUx0();
|
||||
|
||||
#endif
|
@ -32,45 +32,6 @@
|
||||
|
||||
#include "resources/base_head_bin.h"
|
||||
|
||||
static int patchRetailContents() {
|
||||
int res;
|
||||
|
||||
SceIoStat stat;
|
||||
memset(&stat, 0, sizeof(SceIoStat));
|
||||
res = sceIoGetstat(PACKAGE_DIR "/sce_sys/retail/livearea", &stat);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = sceIoRename(PACKAGE_DIR "/sce_sys/livearea", PACKAGE_DIR "/sce_sys/livearea_org");
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = sceIoRename(PACKAGE_DIR "/sce_sys/retail/livearea", PACKAGE_DIR "/sce_sys/livearea");
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int restoreRetailContents(const char *titleid) {
|
||||
int res;
|
||||
char src_path[128], dst_path[128];
|
||||
|
||||
sprintf(src_path, "ux0:app/%s/sce_sys/livearea", titleid);
|
||||
sprintf(dst_path, "ux0:app/%s/sce_sys/retail/livearea", titleid);
|
||||
res = sceIoRename(src_path, dst_path);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
sprintf(src_path, "ux0:app/%s/sce_sys/livearea_org", titleid);
|
||||
sprintf(dst_path, "ux0:app/%s/sce_sys/livearea", titleid);
|
||||
res = sceIoRename(src_path, dst_path);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int promoteUpdate(const char *path, const char *titleid, const char *category, void *sfo_buffer, int sfo_size) {
|
||||
int res;
|
||||
|
||||
@ -102,6 +63,39 @@ int promoteUpdate(const char *path, const char *titleid, const char *category, v
|
||||
return 0;
|
||||
}
|
||||
|
||||
int promotePkg(const char *path) {
|
||||
int res;
|
||||
|
||||
res = scePromoterUtilityInit();
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = scePromoterUtilityPromotePkgWithRif(path, 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
int state = 0;
|
||||
do {
|
||||
res = scePromoterUtilityGetState(&state);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
sceKernelDelayThread(100 * 1000);
|
||||
} while (state);
|
||||
|
||||
int ret = 0;
|
||||
res = scePromoterUtilityGetResult(&ret);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = scePromoterUtilityExit();
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
// Using the promoteUpdate trick, we get 0x80870005 as result, but it installed correctly though, so return ok
|
||||
return ret == 0x80870005 ? 0 : ret;
|
||||
}
|
||||
|
||||
int promoteApp(const char *path) {
|
||||
int res;
|
||||
|
||||
@ -125,41 +119,8 @@ int promoteApp(const char *path) {
|
||||
// Free sfo buffer
|
||||
free(sfo_buffer);
|
||||
|
||||
// Patch to use retail contents so the game is not shown as test version
|
||||
int patch_retail_contents = patchRetailContents();
|
||||
|
||||
res = scePromoterUtilityInit();
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = scePromoterUtilityPromotePkg(path, 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
int state = 0;
|
||||
do {
|
||||
res = scePromoterUtilityGetState(&state);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
sceKernelDelayThread(100 * 1000);
|
||||
} while (state);
|
||||
|
||||
int ret = 0;
|
||||
res = scePromoterUtilityGetResult(&ret);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
res = scePromoterUtilityExit();
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
// Restore
|
||||
if (patch_retail_contents >= 0)
|
||||
restoreRetailContents(titleid);
|
||||
|
||||
// Using the promoteUpdate trick, we get 0x80870005 as result, but it installed correctly though, so return ok
|
||||
return ret == 0x80870005 ? 0 : ret;
|
||||
// Promote pkg
|
||||
return promotePkg(path);
|
||||
}
|
||||
|
||||
int deleteApp(const char *titleid) {
|
||||
@ -183,7 +144,7 @@ int deleteApp(const char *titleid) {
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
sceKernelDelayThread(300 * 1000);
|
||||
sceKernelDelayThread(100 * 1000);
|
||||
} while (state);
|
||||
|
||||
int ret = 0;
|
||||
|
@ -142,7 +142,6 @@ VITASHELL_SETTINGS_SELECT_BUTTON_FTP = "FTP"
|
||||
# USB strings
|
||||
USB_CONNECTED = "USB connected"
|
||||
USB_NOT_CONNECTED = "Connect this system to a PC system using a USB cable."
|
||||
USB_CONNECTION_PERMISSION = "USB connection requires extended permissions.\Please activate 'Enable unsafe homebrew' first."
|
||||
USB_CONNECTION_NOT_AVAILABLE = "USB connection is not available on this device."
|
||||
USB_WAIT_ATTACH = "Please attach an USB flash drive to continue.\If it has already been attached, please detach\and reattach it."
|
||||
USB_UMA0_MOUNTED = "uma0: mounted."
|
||||
@ -155,11 +154,9 @@ UNSAFE_MODE = "UNSAFE MODE"
|
||||
PLEASE_WAIT = "Please wait..."
|
||||
SAVE_MODIFICATIONS = "Do you want to save your modifications?"
|
||||
NO_SPACE_ERROR = "There is not enough free space on the memory\card.\At least %s more space is needed."
|
||||
EXTENDED_PERMISSIONS_REQUIRED = "This feature requires extended permissions.\Please activate 'Enable unsafe homebrew' first."
|
||||
WIFI_ERROR = "You must use Wi-Fi to do this."
|
||||
FTP_SERVER = "FTP server is now running at\ftp://%s:%i\\Press 'OK' to keep it in background.\Press 'Cancel' to disconnect."
|
||||
SYS_INFO = "System software: %s\Model: 0x%08X\MAC address: %s\IP address: %s\Memory card: %s/%s\Battery level: %d%%"
|
||||
UPDATE_QUESTION = "VitaShell %s is now available.\\Do you want to update the application?"
|
||||
TOOLBOX = "Toolbox"
|
||||
SYSINFO_TITLE = "System Information"
|
||||
ARCHIVE_NAME = "Archive name"
|
||||
COMPRESSION_LEVEL = "Compression level (0-9)"
|
||||
|
BIN
resources/user.suprx
Normal file
BIN
resources/user.suprx
Normal file
Binary file not shown.
16
settings.c
16
settings.c
@ -87,7 +87,7 @@ SettingsMenuOption main_settings[] = {
|
||||
// { VITASHELL_SETTINGS_THEME, SETTINGS_OPTION_TYPE_BOOLEAN, NULL, NULL, 0, NULL, 0, &theme },
|
||||
|
||||
{ VITASHELL_SETTINGS_SELECT_BUTTON, SETTINGS_OPTION_TYPE_OPTIONS, NULL, NULL, 0,
|
||||
select_button_options, sizeof(select_button_options)/sizeof(char **),
|
||||
select_button_options, sizeof(select_button_options) / sizeof(char **),
|
||||
&vitashell_config.select_button },
|
||||
{ VITASHELL_SETTINGS_NO_AUTO_UPDATE, SETTINGS_OPTION_TYPE_BOOLEAN, NULL, NULL, 0, NULL, 0, &vitashell_config.disable_autoupdate },
|
||||
};
|
||||
@ -99,14 +99,14 @@ SettingsMenuOption power_settings[] = {
|
||||
};
|
||||
|
||||
SettingsMenuEntry molecularshell_settings_menu_entries[] = {
|
||||
{ HENKAKU_SETTINGS, henkaku_settings, sizeof(henkaku_settings)/sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_MAIN, main_settings, sizeof(main_settings)/sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_POWER, power_settings, sizeof(power_settings)/sizeof(SettingsMenuOption) },
|
||||
{ HENKAKU_SETTINGS, henkaku_settings, sizeof(henkaku_settings) / sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_MAIN, main_settings, sizeof(main_settings) / sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_POWER, power_settings, sizeof(power_settings) / sizeof(SettingsMenuOption) },
|
||||
};
|
||||
|
||||
SettingsMenuEntry vitashell_settings_menu_entries[] = {
|
||||
{ VITASHELL_SETTINGS_MAIN, main_settings, sizeof(main_settings)/sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_POWER, power_settings, sizeof(power_settings)/sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_MAIN, main_settings, sizeof(main_settings) / sizeof(SettingsMenuOption) },
|
||||
{ VITASHELL_SETTINGS_POWER, power_settings, sizeof(power_settings) / sizeof(SettingsMenuOption) },
|
||||
};
|
||||
|
||||
static SettingsMenu settings_menu;
|
||||
@ -114,12 +114,12 @@ static SettingsMenu settings_menu;
|
||||
void loadSettingsConfig() {
|
||||
// Load settings config file
|
||||
memset(&vitashell_config, 0, sizeof(VitaShellConfig));
|
||||
readConfig("ux0:VitaShell/settings.txt", settings_entries, sizeof(settings_entries)/sizeof(ConfigEntry));
|
||||
readConfig("ux0:VitaShell/settings.txt", settings_entries, sizeof(settings_entries) / sizeof(ConfigEntry));
|
||||
}
|
||||
|
||||
void saveSettingsConfig() {
|
||||
// Save settings config file
|
||||
writeConfig("ux0:VitaShell/settings.txt", settings_entries, sizeof(settings_entries)/sizeof(ConfigEntry));
|
||||
writeConfig("ux0:VitaShell/settings.txt", settings_entries, sizeof(settings_entries) / sizeof(ConfigEntry));
|
||||
}
|
||||
|
||||
static void rebootDevice() {
|
||||
|
4
usb.c
4
usb.c
@ -74,7 +74,7 @@ int mountUsbUx0() {
|
||||
sceIoRemove("uma0:VitaShell/internal/lastdir.txt");
|
||||
|
||||
// Redirect ux0: to uma0:
|
||||
redirectUx0();
|
||||
shellUserRedirectUx0();
|
||||
|
||||
// Mount USB ux0:
|
||||
vshIoUmount(0xF00, 0, 0, 0);
|
||||
@ -91,7 +91,7 @@ int umountUsbUx0() {
|
||||
sceAppMgrDestroyOtherApp();
|
||||
|
||||
// Restore ux0: patch
|
||||
unredirectUx0();
|
||||
shellUserUnredirectUx0();
|
||||
|
||||
// Remount and relaunch
|
||||
char * const argv[] = { "umount", NULL };
|
||||
|
1
utils.h
1
utils.h
@ -87,6 +87,7 @@ char *strcasestr(const char *haystack, const char *needle);
|
||||
int vshIoUmount(int id, int a2, int a3, int a4);
|
||||
int _vshIoMount(int id, const char *path, int permission, void *buf);
|
||||
int vshIoMount(int id, const char *path, int permission, int a4, int a5, int a6);
|
||||
|
||||
void remount(int id);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user