diff --git a/CMakeLists.txt b/CMakeLists.txt index 1554d77..a0ff7cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/file.c b/file.c index 18d7cbe..4532fc9 100644 --- a/file.c +++ b/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; } diff --git a/init.c b/init.c index f040fed..01d2187 100644 --- a/init.c +++ b/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 diff --git a/language.c b/language.c index b88a061..7a1d59e 100644 --- a/language.c +++ b/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)); } } } diff --git a/language.h b/language.h index 7555392..9731ff9 100644 --- a/language.h +++ b/language.h @@ -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, diff --git a/main.c b/main.c index b1c16b3..aa3b135 100644 --- a/main.c +++ b/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); } } } diff --git a/main.h b/main.h index 29a98ea..8d464dd 100644 --- a/main.h +++ b/main.h @@ -69,7 +69,7 @@ #include -#include +#include #include "file.h" #include "vitashell_config.h" diff --git a/main_context.c b/main_context.c index 16a1ae9..09dc1df 100644 --- a/main_context.c +++ b/main_context.c @@ -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 diff --git a/modules/usbdevice/CMakeLists.txt b/modules/usbdevice/CMakeLists.txt new file mode 100644 index 0000000..e4c916d --- /dev/null +++ b/modules/usbdevice/CMakeLists.txt @@ -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 +) \ No newline at end of file diff --git a/modules/usbdevice/exports.yml b/modules/usbdevice/exports.yml new file mode 100644 index 0000000..e8eade1 --- /dev/null +++ b/modules/usbdevice/exports.yml @@ -0,0 +1,8 @@ +VitaShellUsbDevice: + attributes: 0 + version: + major: 1 + minor: 0 + main: + start: module_start + stop: module_stop \ No newline at end of file diff --git a/modules/usbdevice/main.c b/modules/usbdevice/main.c new file mode 100644 index 0000000..f04d9dd --- /dev/null +++ b/modules/usbdevice/main.c @@ -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 . +*/ + +#include +#include + +#include +#include + +#include + +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; +} diff --git a/modules/user/CMakeLists.txt b/modules/user/CMakeLists.txt new file mode 100644 index 0000000..0feeee9 --- /dev/null +++ b/modules/user/CMakeLists.txt @@ -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 +) \ No newline at end of file diff --git a/modules/user/exports.yml b/modules/user/exports.yml new file mode 100644 index 0000000..c22989d --- /dev/null +++ b/modules/user/exports.yml @@ -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 \ No newline at end of file diff --git a/modules/user/main.c b/modules/user/main.c new file mode 100644 index 0000000..e1664d5 --- /dev/null +++ b/modules/user/main.c @@ -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 . +*/ + +#include +#include +#include + +#include +#include +#include + +#include + +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; +} \ No newline at end of file diff --git a/modules/user/vitashell_user.h b/modules/user/vitashell_user.h new file mode 100644 index 0000000..07f8c94 --- /dev/null +++ b/modules/user/vitashell_user.h @@ -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 . +*/ + +#ifndef __VITASHELL_USER_H__ +#define __VITASHELL_USER_H__ + +int shellUserIsUx0Redirected(); +int shellUserRedirectUx0(); +int shellUserUnredirectUx0(); + +#endif \ No newline at end of file diff --git a/package_installer.c b/package_installer.c index 948da6f..032150a 100644 --- a/package_installer.c +++ b/package_installer.c @@ -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; diff --git a/resources/english_us.txt b/resources/english_us.txt index 40c6947..4b78f6a 100644 --- a/resources/english_us.txt +++ b/resources/english_us.txt @@ -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)" diff --git a/resources/user.suprx b/resources/user.suprx new file mode 100644 index 0000000..f94bcbb Binary files /dev/null and b/resources/user.suprx differ diff --git a/settings.c b/settings.c index ac5b515..551a88d 100644 --- a/settings.c +++ b/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() { diff --git a/usb.c b/usb.c index 4fa6950..48d29ab 100644 --- a/usb.c +++ b/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 }; diff --git a/utils.h b/utils.h index 1f7d049..c18af8b 100644 --- a/utils.h +++ b/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 \ No newline at end of file