From bb411e7c351c71590804e3f81a036b8c1b9a0be0 Mon Sep 17 00:00:00 2001 From: LightningMods <34066913+LightningMods@users.noreply.github.com> Date: Sat, 25 Dec 2021 19:20:55 -0500 Subject: [PATCH] STORE Version: 2.1-V-2021-12-26T00:15:33 --- README.md | 4 +- Store/Makefile | 8 +- Store/build.sh | 1 + Store/include/GLES2_common.h | 3 +- Store/include/Header.h | 5 +- Store/include/defines.h | 31 +- Store/include/memory.h | 4 +- Store/include/utils.h | 101 +++++- Store/source/GLES2_atlas.c | 7 +- Store/source/GLES2_badges.c | 76 ++--- Store/source/GLES2_dump_frame.c | 2 +- Store/source/GLES2_itemzflow.c | 291 ++++++++--------- Store/source/GLES2_layout.c | 12 +- Store/source/GLES2_layout_actions.c | 17 + Store/source/GLES2_menu.c | 1 + Store/source/GLES2_panel.c | 5 +- Store/source/GLES2_q.c | 33 +- Store/source/GLES2_scene_v2.c | 117 +++++-- Store/source/asm.s | 23 ++ Store/source/common_init.c | 242 ++++++++++++-- Store/source/demo-font.c | 2 +- Store/source/dump_and_decrypt.c | 4 +- Store/source/fileIO.c | 2 +- Store/source/http.c | 88 +++-- Store/source/installpkg.c | 10 +- Store/source/ipc.c | 108 ++++++ Store/source/json_simple.c | 1 + Store/source/ls_dir.c | 488 +++++++++++++++------------- Store/source/main.c | 202 ++++++------ Store/source/pixelshader.c | 16 +- Store/source/png.c | 4 +- Store/source/sfo.c | 1 + Store/source/sig_handler.c | 115 ++++++- Store/source/unpfs.c | 37 ++- Store/source/unpkg.c | 21 +- Store/source/utils.c | 332 +++++++++++++++++-- itemz-daemon/Makefile | 27 ++ itemz-daemon/include/defines.h | 183 +++++++++++ itemz-daemon/include/log.h | 49 +++ itemz-daemon/include/utils.h | 98 ++++++ itemz-daemon/source/asm.s | 105 ++++++ itemz-daemon/source/log.c | 173 ++++++++++ itemz-daemon/source/main.c | 144 ++++++++ itemz-daemon/source/net.c | 152 +++++++++ itemz-daemon/source/rpc.c | 118 +++++++ itemz-daemon/source/utils.c | 246 ++++++++++++++ 46 files changed, 2952 insertions(+), 757 deletions(-) create mode 100644 Store/build.sh create mode 100644 Store/source/ipc.c create mode 100644 itemz-daemon/Makefile create mode 100644 itemz-daemon/include/defines.h create mode 100644 itemz-daemon/include/log.h create mode 100644 itemz-daemon/include/utils.h create mode 100644 itemz-daemon/source/asm.s create mode 100644 itemz-daemon/source/log.c create mode 100644 itemz-daemon/source/main.c create mode 100644 itemz-daemon/source/net.c create mode 100644 itemz-daemon/source/rpc.c create mode 100644 itemz-daemon/source/utils.c diff --git a/README.md b/README.md index fd8a335..635396a 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,9 @@ StoreOnUSB=0 //store pkgs on usb OPTIONAL BETA_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxx //for Beta Builds (define) Adavnced_Enabled=1 // need it for advanced settings optional CDN_For_Devkit_Modules=CDN_FOR_ONLY_DEVKIT_MODULES //optional -Legacy=0 //enables old Store APIs +Legacy=0 // Enables old Store APIs +Home_Redirection=1 // Enables the Home Menu Redirect +Daemon_on_start=0 // Disables the Daemon from auto starting with the app ``` ## App details diff --git a/Store/Makefile b/Store/Makefile index a7b3114..9912d10 100644 --- a/Store/Makefile +++ b/Store/Makefile @@ -7,13 +7,9 @@ TargetFile=homebrew.elf include $(ORBISDEV)/make/ps4sdk.mk -LinkerFlags += -lkernel_stub -lSceLibcInternal_stub -lSceSysmodule_stub -lSceSystemService_stub -lSceNet_stub -lSceUserService_stub -lScePigletv2VSH_stub -lSceVideoOut_stub -lSceImeDialog_stub -lSceGnmDriver_stub -lorbisGl -lorbis -lScePad_stub -lSceCommonDialog_stub -lSceMsgDialog_stub -lSceAudioOut_stub -lSceIme_stub -lSceAppInstUtil_stub -lSceBgft_stub -lSceSysUtil_stub -lSceHttp_stub -lSceSsl_stub -lSceNetCtl_stub -LinkerFlags += -lfreetype-gl -lSceFreeTypeOl_stub -LinkerFlags += -lkernel_sys_stub -# testing exports -LinkerFlags += -lSceLncUtil_stub +LinkerFlags += -luser_mem_sys -lkernel_stub -lSceLibcInternal_stub -lSceSysmodule_stub -lSceSystemService_stub -lSceNet_stub -lSceUserService_stub -lScePigletv2VSH_stub -lSceVideoOut_stub -lSceImeDialog_stub -lSceGnmDriver_stub -lorbis -lorbisGl -lScePad_stub -lSceCommonDialog_stub -lSceMsgDialog_stub -lSceAudioOut_stub -lSceIme_stub -lSceAppInstUtil_stub -lSceBgft_stub -lSceSysUtil_stub -lSceHttp_stub -lSceSsl_stub -lSceNetCtl_stub -lfreetype-gl -lSceFreeTypeOl_stub -lkernel_sys_stub -lSceLncUtil_stub -CompilerFlags += -D__PS4__ -D__ORBIS__ +CompilerFlags += -D__PS4__ -D__ORBIS__ -fstack-protector-all IncludePath += -I$(ORBISDEV)/usr/include -I$(ORBISDEV)/usr/include/c++/v1 -I$(ORBISDEV)/usr/include/orbis IncludePath += -I$(ORBISDEV)/usr/include/orbis/freetype-gl diff --git a/Store/build.sh b/Store/build.sh new file mode 100644 index 0000000..9ed43b0 --- /dev/null +++ b/Store/build.sh @@ -0,0 +1 @@ +cd ../itemz-daemon/ && make clean && make -j8 && make oelf && make eboot && cd ../Store/ && make clean && make -j8 && make oelf && make eboot \ No newline at end of file diff --git a/Store/include/GLES2_common.h b/Store/include/GLES2_common.h index 980cd2c..73af7e2 100644 --- a/Store/include/GLES2_common.h +++ b/Store/include/GLES2_common.h @@ -41,7 +41,7 @@ extern layout_t *active_p, // the active panel moves selector around */ extern item_t *games, *groups, - *i_apps; // Installed_Apps + *all_apps; // Installed_Apps /* auxiliary array of item_index_t: - shared for Search/Groups @@ -68,6 +68,7 @@ extern dl_arg_t *pt_info; // GLES2_layout void layout_update_fsize(layout_t *l); void layout_update_sele (layout_t *l, int movement); +void GLES2_Refresh_for_settings(); void layout_set_active (layout_t *l); void swap_panels(void); void GLES2_render_layout_v2(layout_t *l, int unused); diff --git a/Store/include/Header.h b/Store/include/Header.h index 78d3665..bbca072 100644 --- a/Store/include/Header.h +++ b/Store/include/Header.h @@ -14,6 +14,7 @@ #include #include #include //O_CEAT +#include #define SCE_KERNEL_MAX_MODULES 256 #define SCE_KERNEL_MAX_NAME_LENGTH 256 @@ -27,7 +28,7 @@ #define IS_INTERNAL 0 -int loadmsg(char* format, ...); + int pingtest(int libnetMemId, int libhttpCtxId, const char* src); int32_t netInit(void); #define DIFFERENT_HASH 1 @@ -103,7 +104,7 @@ void logshit(char* format, ...); #define VERSION_MAJOR 2 -#define VERSION_MINOR 00 +#define VERSION_MINOR 01 #define BUILD_YEAR_CH0 (__DATE__[ 7]) #define BUILD_YEAR_CH1 (__DATE__[ 8]) diff --git a/Store/include/defines.h b/Store/include/defines.h index 5742d2b..86c14aa 100644 --- a/Store/include/defines.h +++ b/Store/include/defines.h @@ -28,6 +28,7 @@ #include #include #include "log.h" +#include #if defined (__ORBIS__) @@ -89,6 +90,10 @@ #define SCE_SYSCORE_ERROR_LNC_INVALID_STATE 0x80aa000a #define SCE_LNC_UTIL_ERROR_NOT_INITIALIZED 0x80940001 +#define APP_HOME_DATA_FOLDER "/user/app/NPXS29998" +#define APP_HOME_DATA_TID "NPXS29998" +#define STORE_TID "NPXS39041" + /// from fileIO.c unsigned char *orbisFileGetFileContent( const char *filename ); extern size_t _orbisFile_lastopenFile_size; @@ -188,18 +193,15 @@ void filledRect(int x1, int y1, int x2, int y2, unsigned char r, unsigned char g #define NUM_OF_SPRITES (6) /// from ls_dir() -int ls_dir(char *dirpath); bool if_exists(const char *path); int check_stat(const char *filepath); -int get_item_count(void); // to remove typedef struct { char *name; - //size_t size; } entry_t; entry_t *get_item_entries(const char *dirpath, int *count); -void free_item_entries(entry_t *e); +void free_item_entries(entry_t* e, int num); // from my_rects.c vec2 px_pos_to_normalized(vec2 *pos); @@ -237,6 +239,7 @@ void ORBIS_RenderFillRects(enum SH_type SL_program, const vec4 *rgba, const vec4 void ORBIS_RenderDrawBox (enum SH_type SL_program, const vec4 *rgba, const vec4 *rect); void GLES2_DrawFillingRect(vec4 *frect, vec4 *color, double *percentage); + // reuse this type to index texts around! typedef struct { @@ -245,6 +248,7 @@ typedef struct } item_idx_t; + enum views { ON_TEST_ANI = -2, @@ -319,7 +323,7 @@ int sceKernelAvailableFlexibleMemorySize(size_t *free_mem); int notify(char *message); void escalate_priv(void); -int initGL_for_the_store(void); +int initGL_for_the_store(bool reload_apps,int ref_pages); int pingtest(int libnetMemId, int libhttpCtxId, const char* src); /* @@ -349,6 +353,21 @@ typedef enum badge_t NUM_OF_BADGES } badge_t; + +#define ARRAYSIZE(a) ((sizeof(a) / sizeof(*(a))) / ((size_t)(!(sizeof(a) % sizeof(*(a)))))) + +struct _ent { + char fname[4096]; + uint32_t sz; +}; + +struct CVec +{ + uint32_t sz, cur; // In BYTES + void* ptr; + +}; + typedef struct { item_idx_t *token_d; // data @@ -387,7 +406,7 @@ typedef struct item_idx_t *analyze_item_t (item_t *items, int item_count); item_t *analyze_item_t_v2 (item_t *items, int item_count); item_idx_t *search_item_t (item_t *items, int item_count, enum token_name TN, char *pattern); -item_t *index_items_from_dir(const char *dirpath); +item_t *index_items_from_dir(const char *dirpath, const char* dirpath2); void build_char_from_items(char **data, item_idx_t *filter); item_idx_t *build_item_list(item_t *items, int item_count, enum token_name TN); diff --git a/Store/include/memory.h b/Store/include/memory.h index 7e2f2c8..d405331 100644 --- a/Store/include/memory.h +++ b/Store/include/memory.h @@ -1,8 +1,6 @@ #ifndef _USER_MEM_H #define _USER_MEM_H - -void* lmalloc(unsigned long size); -void *lrealloc(void *ptr,size_t size); +#include #endif diff --git a/Store/include/utils.h b/Store/include/utils.h index dafe3e7..3a5f511 100644 --- a/Store/include/utils.h +++ b/Store/include/utils.h @@ -9,6 +9,8 @@ #include #include // MIN #include "log.h" +#include +#include #define DIM(x) (sizeof(x)/sizeof(*(x))) #define KB(x) ((size_t) (x) << 10) @@ -20,7 +22,61 @@ enum MSG_DIALOG { WARNING }; + +enum IPC_Errors +{ + INVALID = -1, + NO_ERROR = 0, + REDIRECT_OPERATION_FAILED = 1, + DEAMON_UPDATING = 100 +}; + + +enum IPC_Commands +{ + CONNECTION_TEST = 1, + ENABLE_HOME_REDIRECT = 2, + DISABLE_HOME_REDIRECT = 3, + DEAMON_UPDATE = 100 +}; + + + + +typedef struct SceNetEtherAddr { + uint8_t data[6]; +} SceNetEtherAddr; + +typedef union SceNetCtlInfo { + uint32_t device; + SceNetEtherAddr ether_addr; + uint32_t mtu; + uint32_t link; + SceNetEtherAddr bssid; + char ssid[33]; + uint32_t wifi_security; + int32_t rssi_dbm; + uint8_t rssi_percentage; + uint8_t channel; + uint32_t ip_config; + char dhcp_hostname[256]; + char pppoe_auth_name[128]; + char ip_address[16]; + char netmask[16]; + char default_route[16]; + char primary_dns[16]; + char secondary_dns[16]; + uint32_t http_proxy_config; + char http_proxy_server[256]; + uint16_t http_proxy_port; +} SceNetCtlInfo; + + + #define STORE_LOG "/user/app/NPXS39041/logs/log.txt" +#define STANDALONE_APP 0 +#define DAEMON_PATH "/system/vsh/app/ITEM00002" +#define DAEMON_INI_DOESNT_EXIST 0 //#define assert(expr) if (!(expr)) msgok(FATAL, "Assertion Failed!"); @@ -50,7 +106,7 @@ static const char *option_panel_text[] = { "Content Delivery Network", "Temporary Path", - "Detected USB", + "Set as Home Menu(XMB)", "INI Path", "Custom FreeType font Path", // following doesn't store strings for any Paths... @@ -78,6 +134,23 @@ enum STR_type }; +enum Settings_options +{ + CDN_SETTING, + TMP__SETTING, + HOME_MENU_SETTING, + INI_SETTING, + FNT__SETTING, + STORE_USB_SETTING, + CLEAR_CACHE_SETTING, + USE_REFLECTION_SETTING, + USE_PIXELSHADER_SETTING, + SAVE_SETTINGS, + NUM_OF_SETTINGS +}; + + +extern int HDD_count; enum CHECK_OPTS { MD5_HASH, @@ -89,12 +162,14 @@ enum CHECK_OPTS NUM_OF_STRING }; +#define SCE_SYSMODULE_INTERNAL_COMMON_DIALOG 0x80000018 +#define SCE_SYSMODULE_INTERNAL_SYSUTIL 0x80000018 + // indexed options typedef struct { char *opt[ NUM_OF_STRINGS ]; - int StoreOnUSB; - int Legacy; + bool StoreOnUSB, Legacy, HomeMenu_Redirection, Daemon_on_start; // more options } StoreOptions; @@ -110,9 +185,9 @@ uint32_t SysctlByName_get_sdk_version(void); char *calculateSize(uint64_t size); - -int msgok(enum MSG_DIALOG level, char* format, ...); -int loadmsg(char* format, ...); +extern bool is_connected_app; +void msgok(enum MSG_DIALOG level, char* format, ...); +void loadmsg(char* format, ...); long CalcAppsize(char *path); char* cutoff(const char* str, int from, int to); @@ -128,6 +203,20 @@ int check_download_counter(StoreOptions* set, char* title_id); bool rmtree(const char path[]); void setup_store_assets(StoreOptions* get); void refresh_apps_for_cf(void); +int64_t sys_dynlib_load_prx(char* prxPath, int* moduleID); +int64_t sys_dynlib_unload_prx(int64_t prxID); +int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void* destFuncOffset); +struct sockaddr_in IPCAddress(uint16_t port); +int OpenConnection(const char* name); +bool IPCOpenConnection(); +int IPCReceiveData(uint8_t* buffer, int32_t size); +int IPCSendData(uint8_t* buffer, int32_t size); +int IPCCloseConnection(); +#define DAEMON_BUFF_MAX 100 +void GetIPCMessageWithoutError(uint8_t* buf, uint32_t sz); +uint32_t Launch_App(char* TITLE_ID, bool silent); +int mountfs(const char* device, const char* mountpoint, const char* fstype, const char* mode, uint64_t flags); + //int check_store_from_url(char* cdn, enum CHECK_OPTS opt, int *page_number); extern bool dump; diff --git a/Store/source/GLES2_atlas.c b/Store/source/GLES2_atlas.c index e5c1de6..3344a12 100644 --- a/Store/source/GLES2_atlas.c +++ b/Store/source/GLES2_atlas.c @@ -9,15 +9,16 @@ */ #include "defines.h" - +#include #include // lmalloc() + extern vec4 c[8]; // palette extern vec2 resolution; extern int *dump_buffer; // import Installed_Apps AOS extern layout_t *icon_panel; -extern item_t *i_apps; +extern item_t *all_apps; extern double u_t; extern GLuint fallback_t; // fallback texture @@ -128,7 +129,7 @@ void create_tcache(layout_t *l) if( ! dump_buffer ) { #if defined __ORBIS__ - dump_buffer = lmalloc(resolution.x * resolution.y * sizeof(int)); + dump_buffer = malloc(resolution.x * resolution.y * sizeof(int)); #else dump_buffer = calloc(resolution.x * resolution.y, sizeof(int)); #endif diff --git a/Store/source/GLES2_badges.c b/Store/source/GLES2_badges.c index 3387ac4..8243ed7 100644 --- a/Store/source/GLES2_badges.c +++ b/Store/source/GLES2_badges.c @@ -485,73 +485,73 @@ static unsigned char Item_Selected[] = { }; static unsigned int Item_Selected_len = 1606; -static GLuint *badge; -static vec2 *t_size; +static GLuint* badge; +static vec2* t_size; // turn png_data into OpenGL textures void GLES2_Init_badge(void) { - badge = calloc(NUM_OF_BADGES -1, sizeof(GLuint)); - t_size = calloc(NUM_OF_BADGES -1, sizeof(vec2)); + badge = calloc(NUM_OF_BADGES - 1, sizeof(GLuint)); + t_size = calloc(NUM_OF_BADGES - 1, sizeof(vec2)); // just reuse those - unsigned char *png_data = NULL; + unsigned char* png_data = NULL; size_t png_size = 0; - for(int i=0; iitem_c; i++) + for (int i = 0; i < l->item_c; i++) { // stride by 1 due first reserved index ! - for(int j = 1; j < apps->token_c +1; j++) + for (int j = 1; j < apps->token_c + 1; j++) { - if( ! strcmp(l->item_d[ i ].token_d[ ID ].off, - apps[ j ].token_d[ ID ].off) ) + if (!strcmp(l->item_d[i].token_d[ID].off, + apps[j].token_d[ID].off)) { // hit found - apps[ j ].badge = AVAILABLE; - log_info("i_apps[%.3d] '%s' is Available at item[%.3d]", j, apps[ j ].token_d[ ID ].off, i); + apps[j].badge = AVAILABLE; + log_info("i_apps[%.3d] '%s' is Available at item[%.3d]", j, apps[j].token_d[ID].off, i); continue; } } diff --git a/Store/source/GLES2_dump_frame.c b/Store/source/GLES2_dump_frame.c index 378003e..c4d3c86 100644 --- a/Store/source/GLES2_dump_frame.c +++ b/Store/source/GLES2_dump_frame.c @@ -71,7 +71,7 @@ void dump_frame(void) if( ! dump_buffer ) { #if defined __ORBIS__ - dump_buffer = lmalloc(resolution.x * resolution.y * sizeof(int)); + dump_buffer = calloc(resolution.x * resolution.y * sizeof(int), sizeof(resolution.x * resolution.y * sizeof(int))); #else dump_buffer = calloc(resolution.x * resolution.y, sizeof(int)); #endif diff --git a/Store/source/GLES2_itemzflow.c b/Store/source/GLES2_itemzflow.c index 78c460a..f1ec35b 100644 --- a/Store/source/GLES2_itemzflow.c +++ b/Store/source/GLES2_itemzflow.c @@ -381,9 +381,9 @@ void InitScene_5(int width, int height) } - // we will need at max i_apps count coverbox + // we will need at max all_apps count coverbox if(!cf_tex) - cf_tex = calloc(i_apps->token_c +1 /* 1st is reseved */, sizeof(retry_t)); + cf_tex = calloc(all_apps->token_c /* 1st is reseved */+ 1, sizeof(retry_t)); // all done } @@ -457,7 +457,7 @@ bool use_reflection = true, use_pixelshader = true; extern layout_t *icon_panel; -extern item_t *i_apps; +extern item_t *all_apps; extern ivec4 menu_pos; @@ -466,20 +466,20 @@ static bool reset_tex_slot(int idx) bool res = false; if(cf_tex[ idx ].tex > 0) { -// log_debug( "%s[%3d]: %3d, %3d", __FUNCTION__, idx, cf_tex[ idx ].tex, i_apps[ idx ].texture); +// log_debug( "%s[%3d]: %3d, %3d", __FUNCTION__, idx, cf_tex[ idx ].tex, all_apps[ idx ].texture); if(cf_tex[ idx ].tex != cb_tex) // keep the coverbox template { -// log_debug( "%s[%3d]: (%d) %d ", __FUNCTION__, idx, cf_tex[ idx ].tex, i_apps[ idx ].texture); +// log_debug( "%s[%3d]: (%d) %d ", __FUNCTION__, idx, cf_tex[ idx ].tex, all_apps[ idx ].texture); glDeleteTextures(1, &cf_tex[ idx ].tex), cf_tex[ idx ].tex = 0; res = true; } else { - if(i_apps[ idx ].texture > 0 - && i_apps[ idx ].texture != fallback_t) // keep icon0 template + if(all_apps[ idx ].texture > 0 + && all_apps[ idx ].texture != fallback_t) // keep icon0 template { // discard icon0.png -// log_debug( "%s[%3d]: %d (%d)", __FUNCTION__, idx, cf_tex[ idx ].tex, i_apps[ idx ].texture); - glDeleteTextures(1, &i_apps[ idx ].texture), i_apps[ idx ].texture = 0; +// log_debug( "%s[%3d]: %d (%d)", __FUNCTION__, idx, cf_tex[ idx ].tex, all_apps[ idx ].texture); + glDeleteTextures(1, &all_apps[ idx ].texture), all_apps[ idx ].texture = 0; res = true; } } @@ -493,7 +493,7 @@ void drop_some_coverbox(void) { int count = 0; - for (int i = 0; i < i_apps->token_c; i++) + for (int i = 1; i < all_apps->token_c + 1; i++) { if(i > g_idx - pm_r -1 && i < g_idx + pm_r +1) continue; @@ -506,17 +506,31 @@ void drop_some_coverbox(void) } + void check_tex_for_reload(int idx) { + + char* id = all_apps[idx].token_d[ID].off, + cb_path[256]; + + snprintf(cb_path, 255, "/user/app/NPXS39041/covers/%s.png", id); + + if (!if_exists(cb_path)) // download + { + cf_tex[idx].exists = false; + + } + else + cf_tex[idx].exists = true; + +} + static void download_texture(int idx) { if (!cf_tex[idx].tex) { - char* id = i_apps[idx].token_d[ID].off, + char* id = all_apps[idx].token_d[ID].off, cb_path[256]; snprintf(cb_path, 255, "/user/app/NPXS39041/covers/%s.png", id); - - mkdir("/user/app/NPXS39041/covers", 0777); - //DONT CARE IF IT ALREADY EXISTS log_info("Trying to Download cover for %s", id); loadmsg("Trying to Download cover for %s", id); @@ -545,44 +559,44 @@ static void download_texture(int idx) } } -static void check_n_load_texture(int idx) +void check_n_load_textures(int idx) { if( ! cf_tex[ idx ].tex ) { - char *id = i_apps[ idx ].token_d[ ID ].off, + char *id = all_apps[ idx ].token_d[ ID ].off, cb_path[256]; snprintf(cb_path, 255, "/user/app/NPXS39041/covers/%s.png", id); cf_tex[idx].tex = cb_tex; - if(cf_tex[idx].exists) - cf_tex[ idx ].tex = load_png_asset_into_texture(cb_path); - + if (cf_tex[idx].exists) + cf_tex[idx].tex = load_png_asset_into_texture(cb_path); } - // as final fallback - if( cf_tex[ idx ].tex == 0 ) cf_tex[ idx ].tex = cb_tex; + if( cf_tex[ idx ].tex == 0 ) cf_tex[ idx ].tex = cb_tex; // as final fallback } -static void check_n_draw_texture(int idx, int SH_type, vec4 col) +static void check_n_draw_textures(int idx, int SH_type, vec4 col) { + if( cf_tex[ idx ].tex == cb_tex ) // craft a coverbox stretching the icon0 { + render_tex( cb_tex, /* template */ SH_type, cover_t, col ); - if( i_apps[ idx ].texture == 0 ) - i_apps[ idx ].texture = load_png_asset_into_texture( i_apps[ idx ].token_d[ PICPATH ].off ); - // fallback icon0 - if( i_apps[ idx ].texture == 0 ) - i_apps[ idx ].texture = fallback_t; + if(all_apps[idx].texture == NULL) + all_apps[ idx ].texture = load_png_asset_into_texture( all_apps[ idx ].token_d[ PICPATH ].off ); + + if(all_apps[idx].texture == NULL) + all_apps[idx].texture = fallback_t; // fallback icon0 + // overlayed stretched icon0 - render_tex( i_apps[ idx ].texture, SH_type, cover_i, col ); + render_tex( all_apps[ idx ].texture, SH_type, cover_i, col ); } else // available cover box texture - { - render_tex( cf_tex[ idx ].tex, SH_type, cover_t, col ); - } + render_tex( cf_tex[ idx ].tex, SH_type, cover_t, col ); + } @@ -616,9 +630,9 @@ static void send_cf_action(int plus_or_minus_one, int type) xoff = plus_or_minus_one * off.x; // set total x offset with sign! log_info("%d, %s, %s, %d", g_idx, - i_apps[ g_idx ].token_d[ NAME ].off, - i_apps[ g_idx ].token_d[ ID ].off, - i_apps[ g_idx ].texture); + all_apps[ g_idx ].token_d[ NAME ].off, + all_apps[ g_idx ].token_d[ ID ].off, + all_apps[ g_idx ].texture); } typedef enum view_t @@ -674,10 +688,6 @@ layout_t *gm_p = NULL, // game_option_panel extern char* title[300]; extern char* title_id[30]; -bool IS_ERROR(uint32_t a1) -{ - return a1 & 0x80000000; -} static void X_action_dispatch(int action, layout_t *l) { @@ -687,11 +697,11 @@ static void X_action_dispatch(int action, layout_t *l) // selected item from active panel log_info( "execute %d -> '%s' for '%s'", l->curr_item, l->item_d[ l->curr_item ].token_d[ 0 ].off, - i_apps[ g_idx ].token_d[ NAME ].off); + all_apps[ g_idx ].token_d[ NAME ].off); - snprintf(title, 400, "%s", i_apps[ g_idx ].token_d[ NAME ].off); - snprintf(title_id, 30, "%s", i_apps[ g_idx ].token_d[ ID ].off); + snprintf(title, 400, "%s", all_apps[ g_idx ].token_d[ NAME ].off); + snprintf(title_id, 30, "%s", all_apps[ g_idx ].token_d[ ID ].off); log_info("title_id: %s, title: %s",title_id, title); @@ -699,89 +709,20 @@ static void X_action_dispatch(int action, layout_t *l) { case Dump_Game_opt: { - dump = true; - - msgok(NORMAL, "AFTER the Game launches when you press OK wait few seconds then go back to the Store\n\nand the game will be begin dumping DO NOT CLOSE THE GAME OR STORE UNTIL THE DUMP IS COMPLETE"); - } - case Launch_Game_opt: - { - libcmi = sceKernelLoadStartModule("/system/common/lib/libSceSystemService.sprx", 0, NULL, 0, 0, 0); - if (libcmi > 0) + + if (strstr(usbpath(), "/mnt/usb") == NULL) { - log_info("Starting action Launch_Game_opt"); - - - OrbisUserServiceLoginUserIdList userIdList; - - log_info("ret %x", sceUserServiceGetLoginUserIdList(&userIdList)); - - for (int i = 0; i < 4; i++) - { - if (userIdList.userId[i] != 0xFF) - { - log_info("[%i] User ID 0x%x", i, userIdList.userId[i]); - } - } - - - LncAppParam param; - param.sz = sizeof(LncAppParam); - - if(userIdList.userId[0] != 0xFF) - param.user_id = userIdList.userId[0]; - else if (userIdList.userId[1] != 0xFF) - param.user_id = userIdList.userId[1]; - - param.app_opt = 0; - param.crash_report = 0; - param.check_flag = SkipSystemUpdateCheck; - - log_info( "l1 %x", sceLncUtilInitialize()); - - - uint32_t sys_res = sceLncUtilLaunchApp(title_id, 0, ¶m); - if (IS_ERROR(sys_res)) - { - log_info("Switch 0x%x", sys_res); - switch (sys_res) { - case SCE_LNC_ERROR_APP_NOT_FOUND: { - msgok(WARNING, "App is NOT Found ref: SCE_LNC_ERROR_APP_NOT_FOUND"); - break; - } - case SCE_LNC_UTIL_ERROR_ALREADY_RUNNING: { - msgok(WARNING, "App is already running ref: SCE_LNC_UTIL_ERROR_ALREADY_RUNNING"); - break; - } - case SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_KILL_NEEDED: { - log_debug("ALREADY RUNNING KILL NEEDED"); - break; - } - case SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_SUSPEND_NEEDED: { - log_debug("ALREADY RUNNING SUSPEND NEEDED"); - break; - } - case SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX: { - msgok(WARNING, "App is NOT Launchable ref: SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX"); - break; - } - case SCE_LNC_UTIL_ERROR_INVALID_TITLE_ID: { - msgok(WARNING, "TITLE_ID IS NOT VAILED ref: SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX"); - break; - } - - default:{ - msgok(WARNING, "App Launch has failed with error code: 0x%x", sys_res); - break; - } - } - } - - log_info("launch ret 0x%x", sys_res); - + msgok(WARNING, "No USB Detected, Exiting..."); + break; } else - msgok(WARNING, "Game Launch has failed with 0x%X", libcmi); + dump = true; + + msgok(NORMAL, "AFTER the Game launches when you press OK wait few seconds then go back to the Store\n\nand the game will be begin dumping DO NOT CLOSE THE GAME OR STORE UNTIL THE DUMP IS COMPLETE"); + } + case Launch_Game_opt: { + Launch_App(title_id, false); break; } case Uninstall_Update_opt: { @@ -799,8 +740,8 @@ static void X_action_dispatch(int action, layout_t *l) { msgok(NORMAL, "Game Uninstalled successfully, the installed App list will now reload"); + fw_action_to_cf(0x1337); refresh_apps_for_cf(); - fw_action_to_cf(CIR); } else msgok(WARNING, "Game Uninstall failed with code: %x (%i)", error, error); @@ -843,7 +784,6 @@ void fw_action_to_cf(int button) case TRI: { //REFRESH APP //tell the user msgok(NORMAL, "The Installed Apps list will now Reload"); - //refresh app list refresh_apps_for_cf(); //go back to main menu goto refresh_apps; @@ -877,7 +817,20 @@ void fw_action_to_cf(int button) case CIR: v2 = set_view(ITEMzFLOW); break; - case TRI: break;//goto back_to_Store; + case TRI: { + break;//goto back_to_Store; + } + + case 0x1337: { + log_info("called 0x1337"); + v2 = set_view(ITEMzFLOW); + drop_some_coverbox(); + menu_pos.z = ON_MAIN_SCREEN; + active_p = icon_panel; + if (active_p->vbo_s < ASK_REFRESH) active_p->vbo_s = ASK_REFRESH; + break; + } + } } } @@ -946,8 +899,8 @@ void DrawScene_4(void) { // ani ended, move global index by sign! g_idx += (xoff > 0) ? 1 : -1; // L:-1, R:+1 // bounds checking on item count - if(g_idx < 1) g_idx = i_apps[0].token_c; - if(g_idx > i_apps[0].token_c) g_idx = 1; + if(g_idx < 1) g_idx = all_apps[0].token_c; + if(g_idx > all_apps[0].token_c) g_idx = 1; } if(ani->handle == &v_curr) @@ -1015,15 +968,16 @@ void DrawScene_4(void) vec3 pos, rot; draw_item: - + // next item position pos = j * offset; + // set -DEFAULT_Z_CAMERA pos.z -= testoff; // adjust testoff - + rot = (vec3) { gx, 90. / (float)pm_r, 0. }; rot *= -j; - + //if(pr_dbg) if(0) { @@ -1035,22 +989,22 @@ void DrawScene_4(void) if( !j ) // means the selected, last one { + colo = (1.); if( !xoff ) rot.y = ani_ratio * 360; // coverbox backflip effect + } // adjust on l/r action - if(xoff > 0) - { + if (xoff > 0) { pos -= ani_p; rot += ani_r; // right } - else - if(xoff < 0) - { + else if (xoff < 0) { pos += ani_p; rot -= ani_r; // left } + - // ... + // ... glUseProgram( sh_prog1 ); glEnable ( GL_BLEND ); @@ -1083,43 +1037,50 @@ void DrawScene_4(void) } vertex_buffer_render( cover_o, GL_TRIANGLES ); } - - /* index texture from i_apps array */ + + /* index texture from all_apps array */ int tex_idx = g_idx + j; + // check bounds: skip first if( tex_idx < 1) - tex_idx += i_apps[0].token_c; + tex_idx += all_apps[0].token_c; else - if( tex_idx > i_apps[0].token_c) - tex_idx -= i_apps[0].token_c; - + if( tex_idx > all_apps[0].token_c) + tex_idx -= all_apps[0].token_c; + - if (i_apps[0].token_c < 4) msgok(FATAL, "This Game Launcher has a Requirement of min. 4 Apps\nTo use it you need to install: %i More apps\n", i_apps[0].token_c - 4); + if (all_apps[0].token_c < 4) msgok(FATAL, "This Game Launcher has a Requirement of min. 4 Apps\nTo use it you need to install: %i More apps\n", 4 - all_apps[0].token_c); + if (Download_icons) { loadmsg("Downloading Covers from the server"); - - for (int i = 1; i <= i_apps[0].token_c; i++) + + for (int i = 1; i < all_apps[0].token_c + 1; i++) download_texture(i); Download_icons = false; sceMsgDialogTerminate(); - log_info("i_apps[0].token_c: %i", i_apps[0].token_c); + log_info("all_apps[0].token_c: %i", all_apps[0].token_c); } + // load textures (once) - check_n_load_texture(tex_idx); + check_n_load_textures(tex_idx); + // draw coverbox, if not avail craft coverbox from icon - check_n_draw_texture( tex_idx, +1, colo ); - + check_n_draw_textures( tex_idx, +1, colo ); + + // reflection option if(use_reflection) { /* reflect on the Y, actual position matters! */ mat4_scale( &model, 1, -1, 1 ); + // draw coverbox reflection, if not avail craft coverbox from icon - check_n_draw_texture( tex_idx, -1, colo ); + check_n_draw_textures( tex_idx, -1, colo ); + } /* set title */ if(! j // last drawn one, the selected in the center @@ -1129,16 +1090,28 @@ void DrawScene_4(void) // vec2 pen = (vec2){ (float)l->bound_box.x - 20., resolution.y - 140. }; - item_t *li = &i_apps[ tex_idx ]; + item_t *li = &all_apps[ tex_idx ]; title_vbo = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); - // NAME, is size checked + // NAME, is size checked size_t len = strlen(li->token_d[NAME].off); - if(len < 30) - strcpy(&tmp[0], li->token_d[NAME].off); + if (len < 30) + { + if (tex_idx <= HDD_count) + strcpy(&tmp[0], li->token_d[NAME].off); + else + snprintf(&tmp[0], 127, "%s (Ext. HDD)", li->token_d[NAME].off); + } else - snprintf(&tmp[0], 127, "%.26s..." , li->token_d[NAME].off); + { + if (tex_idx <= HDD_count) + snprintf(&tmp[0], 127, "%.26s...", li->token_d[NAME].off); + else + snprintf(&tmp[0], 127, "%.26s... (Ext. HDD)", li->token_d[NAME].off); + } + + // we need to know Text_Length_in_px in advance, so we call this: texture_font_load_glyphs( titl_font, &tmp[0] ); @@ -1146,12 +1119,12 @@ void DrawScene_4(void) vec2 pen = (vec2) { (resolution.x - tl) /2., (resolution.y /10.) *2. }; //Game Options Pen vec2 pen_game_options = (vec2){ 100., resolution.y - 150. }; - + if (v_curr == ITEM_PAGE) add_text( title_vbo, titl_font, &tmp[0], &col, &pen_game_options); else // fill the vbo add_text( title_vbo, titl_font, &tmp[0], &col, &pen); - + // ID // we need to know Text_Length_in_px in advance, so we call this: texture_font_load_glyphs( sub_font, li->token_d[ID].off); @@ -1171,7 +1144,7 @@ void DrawScene_4(void) else // fill the vbo add_text( title_vbo, sub_font, li->token_d[ID].off, &c, &pen); - + // we eventually added glyphs... (todo: glyph cache) refresh_atlas(); } @@ -1180,7 +1153,7 @@ void DrawScene_4(void) // count: index is outer (+R, -L) to inner! c += 1; - + // flip sign, get mirrored if(j > 0) { j *= -1; goto draw_item; } @@ -1201,8 +1174,8 @@ void DrawScene_4(void) if(pr_dbg) { log_info("%d,\t%s\t%s", g_idx, - i_apps[ g_idx ].token_d[ NAME ].off, - i_apps[ g_idx ].token_d[ ID ].off); + all_apps[ g_idx ].token_d[ NAME ].off, + all_apps[ g_idx ].token_d[ ID ].off); } draw_additions(); // texts out of VBO diff --git a/Store/source/GLES2_layout.c b/Store/source/GLES2_layout.c index 204bf5f..df1b8bd 100644 --- a/Store/source/GLES2_layout.c +++ b/Store/source/GLES2_layout.c @@ -175,7 +175,7 @@ static void layout_compose_text(layout_t *l, int idx, vec2 *pen, bool save_text) switch( idx ) { case 0: ret = games->token_c; break; - case 1: ret = i_apps->token_c; break; // Installed_Apps has first reserved + case 1: ret = all_apps->token_c; break; // Installed_Apps has first reserved case 2: ret = groups->token_c; break; // Groups case 3: req_status = COMPLETED; break; // Ready_to_install case 4: req_status = RUNNING; break; // Queue @@ -240,7 +240,7 @@ static void layout_compose_text(layout_t *l, int idx, vec2 *pen, bool save_text) // zerofill for second line memset(&tmp[0], 0, sizeof(tmp)); // get the option value - if(idx < NUM_OF_STRINGS) + if(idx < NUM_OF_STRINGS && idx != HOME_MENU_SETTING) { // shorten any entry longer than n chars if(strlen(get->opt[ idx ]) > 40) format = "%.40s..."; @@ -250,10 +250,10 @@ static void layout_compose_text(layout_t *l, int idx, vec2 *pen, bool save_text) { // to extend for more options switch(idx) { - case 5: snprintf(&tmp[0], 63, format, get->StoreOnUSB ? "True" : "False"); break; - case 6: break; - case 7: snprintf(&tmp[0], 63, format, use_reflection ? "True" : "False"); break; - case 8: snprintf(&tmp[0], 63, format, use_pixelshader ? "True" : "False"); break; + case STORE_USB_SETTING: snprintf(&tmp[0], 63, format, get->StoreOnUSB ? "True" : "False"); break; + case HOME_MENU_SETTING: snprintf(&tmp[0], 63, format, get->HomeMenu_Redirection ? "ItemzFlow (ON)" : "Orbis (OFF)"); break; + case USE_REFLECTION_SETTING: snprintf(&tmp[0], 63, format, use_reflection ? "True" : "False"); break; + case USE_PIXELSHADER_SETTING: snprintf(&tmp[0], 63, format, use_pixelshader ? "True" : "False"); break; default: break; } } diff --git a/Store/source/GLES2_layout_actions.c b/Store/source/GLES2_layout_actions.c index aebb2a3..beef4a2 100644 --- a/Store/source/GLES2_layout_actions.c +++ b/Store/source/GLES2_layout_actions.c @@ -413,3 +413,20 @@ void GLES2_scene_on_pressed_button(int button) GLES2_refresh_common(); } + +void GLES2_Refresh_for_settings() +{ + + if (!active_p) active_p = left_panel2; + + GLES2_refresh_sysinfo(); + + layout_t* l = active_p; + + + layout_update_sele(l, 0); + + + GLES2_refresh_common(); +} + diff --git a/Store/source/GLES2_menu.c b/Store/source/GLES2_menu.c index ce53877..4d7f017 100644 --- a/Store/source/GLES2_menu.c +++ b/Store/source/GLES2_menu.c @@ -5,6 +5,7 @@ #include "defines.h" #include "GLES2_common.h" + // the Settings extern StoreOptions set, * get; diff --git a/Store/source/GLES2_panel.c b/Store/source/GLES2_panel.c index b53f4c2..131d4c9 100644 --- a/Store/source/GLES2_panel.c +++ b/Store/source/GLES2_panel.c @@ -11,6 +11,7 @@ #include #include + #if defined(__ORBIS__) #include #endif @@ -111,11 +112,11 @@ item_t *analyze_item_t_v2(item_t *items, int item_count) log_info("%d %s: %d", i, ret[i].token_d[0].off, ret[i].token_c); // shrink buffers, remember +1 !!! - ret[i].token_d = realloc(ret[i].token_d, (ret[i].token_c +1) + ret[i].token_d = realloc(ret[i].token_d, (ret[i].token_c + 1) * sizeof(item_idx_t)); check += ret[i].token_c; } - log_info("Sorted %d items across %d Groups", check, ret[0].token_c); + log_info("Sorted %d items across %d Groups", check, ret[0].token_c + 1); #endif return ret; diff --git a/Store/source/GLES2_q.c b/Store/source/GLES2_q.c index 1439851..9d59c21 100644 --- a/Store/source/GLES2_q.c +++ b/Store/source/GLES2_q.c @@ -300,15 +300,14 @@ void *start_routine2(void *argument) while (1) { int read = sceHttpReadData(i->req, buf, sizeof(buf)); - if (read < 0) { i->status = read; return read; } + if (read < 0) { i->status = read; goto cleanup; } if (read == 0) { i->status = CANCELED; break; } ret = sceKernelWrite(fd, buf, read); if (ret < 0 || ret != read) { - if (ret < 0) { i->status = CANCELED; return ret; }; i->status = CANCELED; - return -1; + goto cleanup; } total_read += read; @@ -326,12 +325,34 @@ void *start_routine2(void *argument) if(total_read %(4096*128) == 0) log_debug( "%s, thread[%d] reading data, %lub / %lub (%.2f%%)", __FUNCTION__, i->idx, total_read, i->contentLength, i->progress); } - ret = sceKernelClose(fd); // don't wait before returning - // clean thread / reset - if(i->req) sceHttpDeleteRequest(i->req); +cleanup: + if (i->req > 0) { + ret = sceHttpDeleteRequest(i->req); + if (ret < 0) { + log_error("sceHttpDeleteRequest(%i) error: 0x%08X\n", i->req, ret); + } + } + if (i->connid > 0) { + ret = sceHttpDeleteConnection(i->connid); + if (ret < 0) { + log_error("sceHttpDeleteConnection(%i) error: 0x%08X\n", i->connid, ret); + } + } + if (i->tmpid > 0) { + ret = sceHttpDeleteTemplate(i->tmpid); + if (ret < 0) { + log_error("sceHttpDeleteTemplate(%i) error: 0x%08X\n", i->tmpid, ret); + } + } + if (fd > 0) { + ret = sceKernelClose(fd); + if (ret < 0) { + log_error("sceKernelClose(%i) error: 0x%08X\n", fd, ret); + } + } // trigger refresh of Queue active count left_panel2->vbo_s = ASK_REFRESH; diff --git a/Store/source/GLES2_scene_v2.c b/Store/source/GLES2_scene_v2.c index 691e83f..d007069 100644 --- a/Store/source/GLES2_scene_v2.c +++ b/Store/source/GLES2_scene_v2.c @@ -15,6 +15,7 @@ #include #include + #if defined(__ORBIS__) #include extern OrbisPadConfig *confPad; @@ -104,9 +105,9 @@ layout_t *active_p = NULL, // the one we control /* array for Special cases */ -item_t *games = NULL, - *groups = NULL, - *i_apps = NULL; // Installed_Apps +item_t* games = NULL, +* groups = NULL, +* all_apps = NULL; /* auxiliary array of item_index_t: - shared for Search/Groups @@ -348,7 +349,7 @@ void recreate_item_t(item_t **i) if( *i ) { log_info("%s destroy %p, %p, %p", __FUNCTION__, i, *i, **i); - for(int j = 0; j < i[0]->token_c +1; j++) + for(int j = 0; j < i[0]->token_c + 1; j++) { log_info("destroy %i %p %d", j, &groups[j].token_d, groups[j].token_c); } @@ -373,8 +374,8 @@ void GLES2_scene_init( int w, int h ) // build an array of indexes for each one entry there mkdir("/user/app/", 0777); - if( ! i_apps ) i_apps = index_items_from_dir("/user/app"); - + log_info("Searching for Apps"); + if (!all_apps) all_apps = index_items_from_dir("/user/app", "/mnt/ext0/user/app"); /* now, scan .json files, populate main icon panel */ // try to compose any page, count available ones @@ -382,7 +383,13 @@ void GLES2_scene_init( int w, int h ) log_info( "%d available json!", json_c); // setup one for all missing, the fallback icon0 - if( ! fallback_t ) fallback_t = load_png_asset_into_texture("/user/appmeta/NPXS39041/icon0.png"); + if (!fallback_t) + { + if(if_exists("/user/appmeta/NPXS39041/icon0.png")) + fallback_t = load_png_asset_into_texture("/user/appmeta/NPXS39041/icon0.png"); + else + fallback_t = load_png_asset_into_texture("/user/appmeta/external/NPXS39041/icon0.png"); + } /* icon panel setup */ @@ -425,7 +432,7 @@ void GLES2_scene_init( int w, int h ) //qsort(icon_panel->item_d, icon_panel->item_c, sizeof(item_t), struct_cmp_by_token); /* now check for badges: scan items for Installed_Apps */ - scan_for_badges(icon_panel, i_apps); + scan_for_badges(icon_panel, all_apps); #define HAVE_ATLAS (0) /// main #if HAVE_ATLAS @@ -543,6 +550,7 @@ void GLES2_UpdateVboForLayout(layout_t *l) } + // not used #if _DEBUG && 0 void _prt() { @@ -672,15 +680,21 @@ void X_action_dispatch(int action, layout_t *l) char API_BUF[300]; //New Download API #if LOCALHOST_WINDOWS + snprintf(API_BUF, sizeof(API_BUF), "%s/00/download.php?tid=%s", get->opt[CDN_URL], t[ID].off); #else snprintf(API_BUF, sizeof(API_BUF), "%s/download.php?tid=%s", get->opt[CDN_URL], t[ID].off); #endif - //Check for the Legacy INI Setting, its a Bool, and check to be Sure its not trying to download a direct DL (.pkg) - if (!get->Legacy || (strstr(t[label].off, ".pkg") == NULL && strstr(t[label].off, ".PKG") == NULL)) - http_ret = dl_from_url_v2(API_BUF, &tmp[0], t); //Download from New API + if (strcmp(t[ID].off, STORE_TID) != NULL) + { + //Check for the Legacy INI Setting, its a Bool, and check to be Sure its not trying to download a direct DL (.pkg) + if (!get->Legacy || (strstr(t[label].off, ".pkg") == NULL && strstr(t[label].off, ".PKG") == NULL)) + http_ret = dl_from_url_v2(API_BUF, &tmp[0], t); //Download from New API + else + http_ret = dl_from_url_v2(t[label].off, &tmp[0], t); //Download from Legacy + } else - http_ret = dl_from_url_v2(t[label].off, &tmp[0], t); //Download from Legacy + msgok(WARNING, "HB Store is Not Available for PS4 Download, it is a Website Only Download"); } break; /* Install */ @@ -709,10 +723,10 @@ void X_action_dispatch(int action, layout_t *l) switch(action) { // use sceKbd to edit related field - case CDN_URL : - case TMP_PATH: - case INI_PATH: - case FNT_PATH: + case CDN_SETTING : + case TMP__SETTING: + case INI_SETTING: + case FNT__SETTING: if(action == INI_PATH) msgok(WARNING, "You are making a NEW INI The app WILL NOT use this INI also it will NOT be saved to the INI the app is using!"); @@ -724,7 +738,7 @@ void X_action_dispatch(int action, layout_t *l) // check for valid result if (strlen(tmp) <= 1 || strlen(tmp) >= 255 ) { - msgok(NORMAL, "String is either too long or Invaild Please enter a vaild entry"); goto error; + msgok(NORMAL, "String is either too long or INVALID Please enter a vaild entry"); goto error; } if(action != CDN_URL && strstr(tmp, "/user") == NULL) @@ -735,7 +749,7 @@ void X_action_dispatch(int action, layout_t *l) { if(strstr(tmp, "/system_ex") == NULL) { - msgok(NORMAL, "Invaild Path! enter a vaild path"); goto error; + msgok(NORMAL, "INVALID Path! enter a vaild path"); goto error; } } } @@ -749,7 +763,7 @@ void X_action_dispatch(int action, layout_t *l) // validate result (CDN) if(action == CDN_URL && strstr(tmp, "http://") == NULL) { - msgok(NORMAL, "Invaild CDN make sure its in the format http://CDN/ no Https urls are allowed"); goto error; + msgok(NORMAL, "INVALID CDN make sure its in the format http://CDN/ no Https urls are allowed"); goto error; } // update @@ -765,7 +779,7 @@ void X_action_dispatch(int action, layout_t *l) if(strstr(get->opt[action],".ttf") != NULL) GLES2_fonts_from_ttf(get->opt[action]); else - msgok(NORMAL, "Invaild .ttf path Please ensure the file ext is .ttf"); goto error; + msgok(NORMAL, "INVALID .ttf path Please ensure the file ext is .ttf"); goto error; } strcmp(get->opt[action], tmp); @@ -775,23 +789,21 @@ void X_action_dispatch(int action, layout_t *l) log_info("ERROR: entered %.20s", tmp); break; - case USB_PATH: - msgok(NORMAL, "This is NOT an editable Entry, it is created at App Boot"); - break; - // execute action, set flags - case 5: //STORE_ON_USB - if(get->opt[action]) + case STORE_USB_SETTING: {//STORE_ON_USB + if (get->opt[action]) { - get->opt[action] = 0; + get->opt[action] = 0; snprintf(get->opt[TMP_PATH], 255, "%s", "/user/app"); - } else { - get->opt[action] = 1; + } + else { + get->opt[action] = 1; snprintf(get->opt[TMP_PATH], 255, "%s", "/mnt/usb0"); } break; + } - case 6: { // clear cached images + case CLEAR_CACHE_SETTING: { // clear cached images loadmsg("Clearing Cached contents"); unlink(STORE_LOG); FILE* fp = fopen(STORE_LOG, "w"); @@ -809,29 +821,62 @@ void X_action_dispatch(int action, layout_t *l) break; } - case 7: + case USE_REFLECTION_SETTING: { use_reflection = (use_reflection) ? false : true; log_info("use_reflection: %d", use_reflection); break; - case 8: + } + case USE_PIXELSHADER_SETTING: { use_pixelshader = (use_pixelshader) ? false : true; log_info("use_pixelshader: %d", use_pixelshader); break; - case 9: //SAVE_OPTIONS: + } + case HOME_MENU_SETTING: { + // + if (is_connected_app) { + get->HomeMenu_Redirection = (get->HomeMenu_Redirection) ? false : true; + log_info("Turning Home menu %s", get->HomeMenu_Redirection ? "ON (ItemzFlow)" : "OFF (Orbis)" ); + + uint8_t* IPC_BUFFER = malloc(100); + int error = INVALID, wait = INVALID; + + if (get->HomeMenu_Redirection) + { + error = IPCSendCommand(ENABLE_HOME_REDIRECT, IPC_BUFFER); + if (error == NO_ERROR) + log_debug("HOME MENU REDIRECT IS ENABLED"); + } + else + { + error = IPCSendCommand(DISABLE_HOME_REDIRECT, IPC_BUFFER); + if (error == NO_ERROR) + log_debug("HOME MENU REDIRECT IS DISABLED"); + } + free(IPC_BUFFER); + } + else + msgok(WARNING, "this feature is disabled\n Reason: The ItemzFlow Daemon is NOT connected"); + + + + break; + } + case SAVE_SETTINGS: {//SAVE_OPTIONS: log_info("%p, %d", l, action); - if( ! SaveOptions(get) ) + if (!SaveOptions(get)) msgok(WARNING, "Save error, your changes were NOT saved"); else { msgok(NORMAL, "Your changes were saved successfully"); - log_info( "Settings saved to %s", get->opt[INI_PATH]); + log_info("Settings saved to %s", get->opt[INI_PATH]); // reload settings LoadOptions(get); } break; + } } - + GLES2_Refresh_for_settings(); return; } diff --git a/Store/source/asm.s b/Store/source/asm.s index e3217a8..514a327 100644 --- a/Store/source/asm.s +++ b/Store/source/asm.s @@ -1,9 +1,17 @@ .intel_syntax noprefix .text +.global kernelRdmsr .global cpu_enable_wp .global cpu_disable_wp +.global call_not_RESOLVED_Exception +kernelRdmsr: + mov ecx, edi + rdmsr + shl rdx, 32 + or rax, rdx + ret cpu_enable_wp: mov rax, cr0 @@ -94,4 +102,19 @@ err: ret + .section .rodata + + # elf + .global daemon_eboot + .type daemon_eboot, @object + .align 4 +daemon_eboot: + .incbin "../itemz-daemon/bin/eboot.bin" +daemon_eboot_end: + .global daemon_eboot_size + .type daemon_eboot_size, @object + .align 4 +daemon_eboot_size: + .int daemon_eboot_end - daemon_eboot + diff --git a/Store/source/common_init.c b/Store/source/common_init.c index c68df04..cbcc841 100644 --- a/Store/source/common_init.c +++ b/Store/source/common_init.c @@ -9,7 +9,8 @@ #include #include #include - +#include +#include extern bool dump; #if defined (__ORBIS__) @@ -83,7 +84,6 @@ extern StoreOptions set, *get; - /* XXX: patches below are given for Piglet module from 4.74 Devkit PUP */ static void pgl_patches_cb(void* arg, uint8_t* base, uint64_t size) { @@ -100,30 +100,192 @@ static void pgl_patches_cb(void* arg, uint8_t* base, uint64_t size) /* Inform Piglet that we have shader compiler module loaded */ *(int32_t*)(base + 0xB2E24) = s_shcomp_module; } -// reuses orbislink code from new liborbis (-lorbis) -int initGL_for_the_store(void) + + +bool is_connected_app = false; + +extern uint8_t daemon_eboot[]; +extern int32_t daemon_eboot_size; + + +#define LATEST_DAEMON_VERSION 0x1001 +static int (*rejail_multi)(void) = NULL; + +bool is_daemon_outdated(void) +{ + int daemon_ver = INVALID; + + pl_ini_file file; + if (!if_exists(DAEMON_PATH"/daemon.ini")) + return false; + else + { + log_debug("Daemon INI Does exist"); + pl_ini_load(&file, DAEMON_PATH"/daemon.ini"); + daemon_ver = pl_ini_get_int(&file, "Daemon", "version", 0x1337); + log_info("Daemon Version: %x, Latest Version: %x, Is Outdated?: %s", daemon_ver, LATEST_DAEMON_VERSION, daemon_ver == LATEST_DAEMON_VERSION ? "No" : "Yes"); + + /* Clean up */ + pl_ini_destroy(&file); + } + + return (bool)daemon_ver == LATEST_DAEMON_VERSION; +} + +bool init_daemon_services(bool redirect) +{ + + + uint8_t* IPC_BUFFER = malloc(100); + int fd = -1; + if (!if_exists(DAEMON_PATH) || !is_daemon_outdated()) + { + if (!!mountfs("/dev/da0x4.crypt", "/system", "exfatfs", "511", 0x00010000)) + { + log_error("mounting /system failed with %s", strerror(errno)); + return false; + } + else + { + + log_error("Remount Successful"); + //Delete the folder and all its files + rmtree(DAEMON_PATH); + + mkdir(DAEMON_PATH, 0777); + mkdir(DAEMON_PATH"/Media", 0777); + mkdir(DAEMON_PATH"/sce_sys", 0777); + if (copyFile("/mnt/sandbox/pfsmnt/NPXS39041-app0/Media/jb.prx", DAEMON_PATH"/Media/jb.prx") != -1 && copyFile("/system/vsh/app/NPXS21007/sce_sys/param.sfo", DAEMON_PATH"/sce_sys/param.sfo") != -1) + { + + if ((fd = open(DAEMON_PATH"/eboot.bin", O_WRONLY | O_CREAT | O_TRUNC, 0777)) > 0 && fd != -1) { + write(fd, daemon_eboot, daemon_eboot_size); + close(fd); + + pl_ini_file file; + pl_ini_create(&file); + pl_ini_set_int(&file, "Daemon", "version", LATEST_DAEMON_VERSION); + pl_ini_save(&file, DAEMON_PATH"/daemon.ini"); + chmod(DAEMON_PATH"/daemon.ini", 0777); + } + else + { + log_error("Creating the Daemon eboot failed to create: %s", strerror(errno)); + return false; + } + } + else + { + log_error("Copying Daemon files failed"); + return false; + } + IPCSendCommand(DEAMON_UPDATE, IPC_BUFFER); + } + } + + //Launch Daemon with silent + uint32_t res = Launch_App("ITEM00002", true); + if (res != SCE_LNC_UTIL_ERROR_ALREADY_RUNNING) + { + if (rejail_multi != NULL) + { + int libcmi = 1; + sys_dynlib_load_prx("/system/vsh/app/ITEM00002/Media/jb.prx", &libcmi); + if (!sys_dynlib_dlsym(libcmi, "rejail_multi", &rejail_multi)) + rejail_multi(); + } + sceSystemServiceLoadExec("/data/self/eboot.bin"); + } + + + loadmsg("Waiting for Daemon's Welcome Response (max 1 min)"); + + int error = INVALID, wait = INVALID; + // Wait for the Daemon to respond + do { + + if (wait >= 60) + { + log_error("Daemon timed out"); + return false; + } + else + wait++; + + sleep(1); + + //File Flag the Daemon creates when initialization is complete + // and the Daemon IPC server is active + } while (!if_exists("/system_tmp/IPC_init")); + + error = IPCSendCommand(CONNECTION_TEST, IPC_BUFFER); + log_info("---- Error: %s", error == INVALID ? "Failed to Connect" : "Success"); + if (error == NO_ERROR) { + sceMsgDialogTerminate(); + log_debug("Took the Daemon %i extra commands attempts to respond", wait); + is_connected_app = true; + } + + + + if (is_connected_app) + { + if (redirect) // is setting get->HomeMenu_Redirection enabled + { + log_info("Redirect on with app connected"); + + error = IPCSendCommand(ENABLE_HOME_REDIRECT, IPC_BUFFER); + if (error == NO_ERROR) { + log_debug("HOME MENU REDIRECT IS ENABLED"); + + } + + } + } + else + return false; + + + free(IPC_BUFFER); + + return true; + +} + +int initGL_for_the_store(bool reload_apps, int ref_pages) { int ret = 0; + char tmp[100]; unlink(STORE_LOG); + //Keep people from backing up the Sig file + unlink("/user/app/NPXS39041/homebrew.elf.sig"); /*-- INIT LOGGING FUNCS --*/ log_set_quiet(false); log_set_level(LOG_DEBUG); FILE* fp = fopen(STORE_LOG, "w"); log_add_fp(fp, LOG_DEBUG); + //USB LOGGING + if (usbpath() != NULL) + { + sprintf(&tmp[0], "%s/Store-log.txt", usbpath()); + unlink(tmp); + fp = fopen(tmp, "w"); + log_add_fp(fp, LOG_DEBUG); + } /* -- END OF LOGINIT --*/ log_info("------------------------ Store[GL] Compiled Time: %s @ %s -------------------------", __DATE__, __TIME__); - log_info(" -------------------------------- STORE Version: %s -----------------", completeVersion); - log_info("----------------------------------------------- -------------------------"); + log_info(" --------------------------- STORE Version: %s ------------------------------------", completeVersion); +if(reload_apps) + log_info("---------------------------- reload_apps: %s, Total_pages % i ----------------------", reload_apps ? "true" : "false", ref_pages); get = &set; // internals: net, user_service, system_service ret = loadModulesVanilla(); - // pad ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_PAD); if(ret) return -1; @@ -132,7 +294,7 @@ int initGL_for_the_store(void) if(ret) return -1; //MSGDIALOG ret = sceSysmoduleLoadModule(ORBIS_SYSMODULE_MESSAGE_DIALOG); - if(ret) return -1; + if(ret) return -1; ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NETCTL); if(ret) return -1; @@ -146,24 +308,17 @@ int initGL_for_the_store(void) ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SSL); if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(0x80000018); + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_COMMON_DIALOG); if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(0x80000026); // 0x80000026 + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SYSUTIL); if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_BGFT); // 0x80000026 + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_BGFT); if(ret) return -1; - ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_APPINSTUTIL); // 0x80000026 0x80000037 + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_APPINSTUTIL); if(ret) return -1; - - sceCommonDialogInitialize(); - sceMsgDialogInitialize(); - - ret = orbisPadInit(); - if(ret != 1) return -2; - //Dump code and sig hanlder struct sigaction new_SIG_action; @@ -172,13 +327,22 @@ int initGL_for_the_store(void) sigemptyset(&new_SIG_action.sa_mask); new_SIG_action.sa_flags = 0; - for (int i = 0; i < 43; i++) - { - // if(i != 10 && i != 12) - sigaction(i, &new_SIG_action, NULL); + for (int i = 0; i < 43; i++) { + if(i != SIGUSR2) + sigaction(i, &new_SIG_action, NULL); } + OrbisUserServiceInitializeParams params; + memset(¶ms, 0, sizeof(params)); + params.priority = 700; + + sceCommonDialogInitialize(); + sceMsgDialogInitialize(); + + ret = orbisPadInit(); + if (ret != 1) return -2; + if(MD5_hash_compare("/user/app/NPXS39041/pig.sprx", "854a0e5556eeb68c23a97ba024ed2aca") == SAME_HASH && MD5_hash_compare("/user/app/NPXS39041/shacc.sprx", "8a21eb3ed8a6786d3fa1ebb1dcbb8ed0") == SAME_HASH) @@ -192,9 +356,30 @@ int initGL_for_the_store(void) if(! patch_module("pig.sprx", &pgl_patches_cb, NULL, /*debugnetlevel*/3)) return -3; - ret = LoadOptions(get); - if(!ret) - msgok(WARNING, "Could NOT find/open the INI File"); + if(!LoadOptions(get)) msgok(WARNING, "Could NOT find/open the INI File"); + + if (get->Daemon_on_start) + { + if (!init_daemon_services(get->HomeMenu_Redirection)) + msgok(WARNING, "The Itemzflow init_daemon_services failed\nThis may cause some things not work\nif you have a USB Inserted check the log"); + else + log_debug("The Itemzflow init_daemon_services succeeded"); + } + else + msgok(WARNING, "The Itemzflow Daemon Auto start is turned off\nThis may cause some things not work"); + + + + + if (reload_apps) + { + if (get->Legacy) + sceSystemServiceLoadExec("/data/self/eboot.bin", NULL); + + total_pages = check_store_from_url(0, get->opt[CDN_URL], COUNT); + if(total_pages == ref_pages) + return 0; + } loadmsg("Downloading and Caching Website files...."); @@ -232,7 +417,12 @@ int initGL_for_the_store(void) sceMsgDialogTerminate(); } else + { + //Delete SPRXS with wrong hash, if they dont exist loader will redownload + unlink("/user/app/NPXS39041/pig.sprx"); + unlink("/user/app/NPXS39041/shacc.sprx"); msgok(FATAL, "SPRX ARE NOT THE SAME HASH ABORTING"); + } // all fine. diff --git a/Store/source/demo-font.c b/Store/source/demo-font.c index 1341c8f..51e5332 100644 --- a/Store/source/demo-font.c +++ b/Store/source/demo-font.c @@ -39,7 +39,7 @@ #include #include // links against libfreetype-gl - +#include #if defined (__ORBIS__) diff --git a/Store/source/dump_and_decrypt.c b/Store/source/dump_and_decrypt.c index 7bad310..5937673 100644 --- a/Store/source/dump_and_decrypt.c +++ b/Store/source/dump_and_decrypt.c @@ -7,6 +7,8 @@ #include #include #include "log.h" +#include + #if defined (__ORBIS__) #include @@ -75,8 +77,6 @@ bool is_self(const char* fn) } else { log_error("mmap file %s err : %s", fn, strerror(errno)); - if(strstr(fn, "eboot.bin") != NULL) - return false; } log_info("Close(fd): %x", sceKernelClose(fd)); diff --git a/Store/source/fileIO.c b/Store/source/fileIO.c index 5edf96e..6c21c8c 100644 --- a/Store/source/fileIO.c +++ b/Store/source/fileIO.c @@ -8,7 +8,7 @@ #include #include #include "log.h" - +#include size_t _orbisFile_lastopenFile_size; // --------------------------------------------------------- buf_from_file --- diff --git a/Store/source/http.c b/Store/source/http.c index 1c5562f..675ca02 100644 --- a/Store/source/http.c +++ b/Store/source/http.c @@ -8,6 +8,7 @@ #include "defines.h" #include "Header.h" +#include struct dl_args { const char *src, @@ -40,7 +41,7 @@ void DL_ERROR(const char* name, int statusCode, struct dl_args *i) if (!i->is_threaded) log_warn( "Download Failed with code HEX: %x Int: %i from Function %s src: %s", statusCode, statusCode, name, i->src); else - msgok(WARNING, "Download Failed with codeHEX: %x Int: %ifrom Function %s src: %s", statusCode, statusCode, name, i->src); + msgok(WARNING, "Download Failed with code\n\nHEX: %x Int: %i\nfrom Function %s src: %s", statusCode, statusCode, name, i->src); } @@ -83,15 +84,22 @@ int ini_dl_req(struct dl_args *i) { if(statusCode == 404) { - if(i->is_threaded) - DL_ERROR("sceHttpGetStatusCode()", statusCode, i); - else + if (i->is_threaded) { + DL_ERROR("sceHttpGetStatusCode()", statusCode, i); + goto error; + } + else { + DL_ERROR("sceHttpGetStatusCode()", statusCode, i); goto error; //fail silently (its for JSON Func) + } } else - DL_ERROR("sceHttpGetStatusCode()", statusCode, i); - goto error; + DL_ERROR("sceHttpGetStatusCode()", statusCode, i); + + + goto error; + } log_info( "[%s:%i] ----- statusCode: %i ---", __FUNCTION__, __LINE__, statusCode); @@ -115,6 +123,24 @@ int ini_dl_req(struct dl_args *i) error: log_error( "%s error: %d, 0x%x", __FUNCTION__, statusCode, statusCode); + if (i->req > 0) { + ret = sceHttpDeleteRequest(i->req); + if (ret < 0) { + log_info("sceHttpDeleteRequest() error: 0x%08X\n", ret); + } + } + if (i->connid > 0) { + ret = sceHttpDeleteConnection(i->connid); + if (ret < 0) { + log_info("sceHttpDeleteConnection() error: 0x%08X\n", ret); + } + } + if (i->tmpid > 0) { + ret = sceHttpDeleteTemplate(i->tmpid); + if (ret < 0) { + log_info("sceHttpDeleteTemplate() error: 0x%08X\n", ret); + } + } // failsafe if(statusCode < 1) statusCode = 0x1337; @@ -128,6 +154,7 @@ void *start_routine(void *argument) struct dl_args *i = (struct dl_args*) argument; int ret = -1; + int total_read = 0; log_error( "i->dst %s", i->dst); log_error( "i->url %s", i->src); log_error( "i->req %x", i->req); @@ -137,23 +164,20 @@ void *start_routine(void *argument) unlink(i->dst); int fd = sceKernelOpen(i->dst, O_WRONLY | O_CREAT, 0777); - // fchmod(fd, 777); - int total_read = 0; - if(fd < 0) return (void*)fd; + log_debug("fd %i", fd); + if(fd < 0) + goto cleanup; while (1) { int read = sceHttpReadData(i->req, buf, sizeof(buf)); - if (read < 0) return (void*)read; + if (read < 0) { ret = (void*)read; goto cleanup; } if (read == 0) break; ret = sceKernelWrite(fd, buf, read); if(ret < 0 || ret != read) - { - if(ret < 0) return (void*)ret; - - return -1; - } + goto cleanup; + total_read += read; int prog = (uint32_t)(((float)total_read / i->contentLength) * 100.f); @@ -162,18 +186,34 @@ void *start_routine(void *argument) prog = 100; break;//runn = 0; // stop } } - ret = sceKernelClose(fd); cleanup: - if(i->req) - sceHttpDeleteRequest(i->req); - if(i->connid) - sceHttpDeleteConnection(i->connid); - if(i->tmpid) - sceHttpDeleteTemplate(i->tmpid); + if (i->req > 0) { + ret = sceHttpDeleteRequest(i->req); + if (ret < 0) { + log_error("sceHttpDeleteRequest(%i) error: 0x%08X\n", i->req, ret); + } + } + if (i->connid > 0) { + ret = sceHttpDeleteConnection(i->connid); + if (ret < 0) { + log_error("sceHttpDeleteConnection(%i) error: 0x%08X\n", i->connid, ret); + } + } + if (i->tmpid > 0) { + ret = sceHttpDeleteTemplate(i->tmpid); + if (ret < 0) { + log_error("sceHttpDeleteTemplate(%i) error: 0x%08X\n", i->tmpid, ret); + } + } + if (fd > 0) { + ret = sceKernelClose(fd); + if (ret < 0) { + log_error("sceKernelClose(%i) error: 0x%08X\n", fd, ret); + } + } // leave httpCtx, sslCtx, NetMemId valids to be reused ! - return (void*)ret; } @@ -274,7 +314,7 @@ char *check_from_url(const char *url_, enum CHECK_OPTS opt) while (1) { int read = sceHttpReadData(dl_args.req, JSON, sizeof(JSON)); - if (read < 0) return NULL; + if (read < 0) return NULL; if (read == 0) break; total_read += read; diff --git a/Store/source/installpkg.c b/Store/source/installpkg.c index eb5c3c6..d92438c 100644 --- a/Store/source/installpkg.c +++ b/Store/source/installpkg.c @@ -1,7 +1,7 @@ #include "Header.h" #include -#include // calloc +#include #include #include @@ -10,7 +10,7 @@ int PKG_ERROR(const char* name, int ret) { - msgok(WARNING, "Install Failed with codeHEX: %x Int: %ifrom Function %s", ret, ret, name); + msgok(WARNING, "Install Failed with code\nHEX: %x Int: %i\nfrom Function %s", ret, ret, name); log_error( "%s error: %i", ret); return ret; @@ -135,6 +135,7 @@ void bgft_fini(void) { /* install package wrapper: init, (install), then clean AppInstUtil and BGFT for next install */ +extern bool Download_icons; uint8_t pkginstall(const char *path) { @@ -212,7 +213,10 @@ uint8_t pkginstall(const char *path) log_info( "%s(%s), %s done.", __FUNCTION__, path, title_id); - refresh_apps_for_cf(); + if (!Download_icons) + refresh_apps_for_cf(); + else + log_warn("CF NOT YET INIT"); return 0; } diff --git a/Store/source/ipc.c b/Store/source/ipc.c new file mode 100644 index 0000000..9f41c52 --- /dev/null +++ b/Store/source/ipc.c @@ -0,0 +1,108 @@ +#include +#include +#include "utils.h" +#include +#include +#include +#include +#include +#include + +#define IPC_SOC "/system_tmp/IPC_Socket" + +int DaemonSocket = NULL; +bool is_daemon_connected = false; + +int OpenConnection(const char* path) +{ + struct sockaddr_un server; + int soc = socket(AF_UNIX, SOCK_STREAM, 0); + server.sun_family = AF_UNIX; + strcpy(server.sun_path, path); + connect(soc, (struct sockaddr*)&server, SUN_LEN(&server)); + return soc; +} + +void GetIPCMessageWithoutError(uint8_t* buf, uint32_t sz) +{ + memmove(buf, buf + 1, sz); +} + +bool IPCOpenConnection() +{ + + DaemonSocket = OpenConnection(IPC_SOC); + if (DaemonSocket > 0 && DaemonSocket != -1) + return true; + else + return false; + +} + +int IPCReceiveData(uint8_t* buffer, int32_t size) +{ + return recv(DaemonSocket, buffer, size, MSG_NOSIGNAL); +} + +int IPCSendData(uint8_t* buffer, int32_t size) +{ + return send(DaemonSocket, buffer, size, MSG_NOSIGNAL); +} + +int IPCCloseConnection() +{ + return close(DaemonSocket); +} + +int IPCSendCommand(enum IPC_Commands cmd, uint8_t* IPC_BUFFER) { + + int error = INVALID, wait = INVALID; + + if (!is_daemon_connected) + is_daemon_connected = IPCOpenConnection(); + + + if (is_daemon_connected) + { + + log_debug("[App] IPC Connected via Domain Socket"); + + IPC_BUFFER[0] = cmd; // First byte is always command + + log_debug("[App] Sending IPC Command"); + IPCSendData(IPC_BUFFER, DAEMON_BUFF_MAX-1); + log_debug("[App] Sent IPC Command %i", cmd); + + memset(IPC_BUFFER, 0, DAEMON_BUFF_MAX-1); + + if (cmd == DEAMON_UPDATE) + { + log_debug("[App] Daemon Updating..."); + is_daemon_connected = false; + return DEAMON_UPDATING; + } + + //Get message back from daemon + uint32_t readSize = IPCReceiveData(IPC_BUFFER, DAEMON_BUFF_MAX-1); + if (readSize > 0 && readSize != -1) + { + log_debug("[App] Got message with Size: %i from Daemon", readSize); + //Get IPC Error code + error = IPC_BUFFER[0]; + if (error != INVALID) + { + // Modifies the Buffer to exclude the error code + GetIPCMessageWithoutError(IPC_BUFFER, readSize); + + log_debug("[App] Daemon IPC Response: %s, code: %s, readSize: %i", IPC_BUFFER, error == NO_ERROR ? "NO_ERROR" : "Other", readSize); + } + else + log_error("Daemon returned INVAIL"); + } + else + log_error("IPCReceiveData failed with: %s", strerror(errno)); + } + + + return error; +} \ No newline at end of file diff --git a/Store/source/json_simple.c b/Store/source/json_simple.c index 9e68f7a..1b7bc8b 100644 --- a/Store/source/json_simple.c +++ b/Store/source/json_simple.c @@ -6,6 +6,7 @@ #include "jsmn.h" #include "json.h" +#include /* * A small example of jsmn parsing when JSON structure is known and number of diff --git a/Store/source/ls_dir.c b/Store/source/ls_dir.c index 1ac9a64..9195490 100644 --- a/Store/source/ls_dir.c +++ b/Store/source/ls_dir.c @@ -17,301 +17,321 @@ */ #include // SYS_getdents #include // MIN +#include - -char *entryName(int entryType) +bool if_exists(const char* path) { - switch(entryType) - { - case 4: return "DIR"; - case 8: return "FILE"; - default: return "OTHER"; + int dfd = open(path, O_RDONLY, 0); // try to open dir + if (dfd < 0) { + log_info("path %s, errno %s", path, strerror(errno)); + return false; } -} + else + close(dfd); + -#if 1 -/* - minimal folder listing: - ps4 uses getdents(), - glibc doesn't have so use syscall. - test implementation, now unused (see below) + return true; +} - THIS_WAS_OLD_VER -*/ -int ls_dir(char *dirpath) +bool filter_entry_on_IDs(const char* entry) { - int dfd = open(dirpath, O_RDONLY, 0); // try to open dir - if(dfd < 0) - { log_debug( "Invalid directory. (%s)", dirpath); return -1; } - else - { log_debug( "open(%s)", dirpath); } - - struct dirent *dent; - char buffer[512]; // fixed buffer + if (strlen(entry) != 9) return false; - memset(buffer, 0, sizeof(buffer)); + unsigned int nid; + char id[5], + tmp[32]; - // get directory entries -#if defined (__ORBIS__) - while(getdents(dfd, buffer, sizeof(buffer)) != 0) -#else - while(syscall(SYS_getdents, dfd, buffer, sizeof(buffer)) != 0) -#endif + int ret = sscanf(entry, "%c%c%c%c%5u", + &id[0], &id[1], &id[2], &id[3], &nid); + id[4] = '\0'; + if (ret == 5) { - dent = (struct dirent *)buffer; + int res = strlen(id); // ABCD... + if (res != 4 + || nid > 99999) goto fail; // 01234 - while(dent->d_fileno) - { - log_debug( "[%p]: %lx %2d, type: %4d, '%s'", // report entry - dent, - dent->d_fileno, dent->d_reclen, - dent->d_type, dent->d_name /* on pc we step back by -1 */); + snprintf(&tmp[0], 31, "%s%.5u", id, nid); - dent = (struct dirent *)((void *)dent + dent->d_reclen); + if (strlen(tmp) != 9) goto fail; + // passed +// log_info("%s - %s looks valid", entry, tmp); - if(dent == (void*) &buffer[512]) break; // refill buffer - } - memset(buffer, 0, sizeof(buffer)); + return true; } - close(dfd); - - return 0; +fail: + return false; } -#endif -bool if_exists(const char *path) +void CV_Create(struct CVec** cv, uint32_t size) { - int dfd = open(path, O_RDONLY, 0); // try to open dir + if (cv) { + if (!(*cv)) *cv = (struct CVec*)malloc(sizeof(struct CVec)); - if(dfd < 0) - return false; - else - close(dfd); - - return true; + (*cv)->cur = 0; + (*cv)->sz = (size + 4095) & ~4095; // round to page size + log_info("Allocating %llx", (*cv)->sz); + (*cv)->ptr = malloc((*cv)->sz); + } } - -/* extended: a two-pass folder-parser */ - -/* qsort struct comparison function (C-string field) */ -static int struct_cmp_by_name(const void *a, const void *b) -{ - entry_t *ia = (entry_t *)a; - entry_t *ib = (entry_t *)b; - return strcmp(ia->name, ib->name); -/* strcmp functions works exactly as expected from comparison function */ +void CV_Destroy(struct CVec** cv) { + if (cv) { + if ((*cv)) { + if ((*cv)->ptr) free((*cv)->ptr); + free(*cv); + } + *cv = NULL; + } } -int num = 0; // total item count - -int get_item_count(void) -{ - return num; +void CV_Clear(struct CVec* cv) { + if (cv) { cv->cur = 0; memset(cv->ptr, 0, cv->sz); } } -void free_item_entries(entry_t *e) +void CV_Append(struct CVec* cv, void* data, uint32_t size) { - for (int i = 0; i < num; ++i) + if (!cv) { log_error("Error, null cv!\n"); return; } + + if ((cv->cur + size) > cv->sz) { - if(e->name) free(e->name), e->name = NULL; + cv->sz = (cv->sz + size + 4095) & ~4095; + cv->ptr = realloc(cv->ptr, cv->sz); } - free(e), e = NULL; -} - -entry_t *get_item_entries(const char *dirpath, int *count) -{ - struct dirent *dent; - char buffer[512]; // fixed buffer - - int dfd = 0, - n, r = 1; // item counter, rounds to loop - entry_t *p = NULL; // we fill this struct with items - -loop: - n = 0; - log_debug( "loop: %d, count:%d", r, *count); - // try to open dir - dfd = open(dirpath, O_RDONLY, 0); - if(dfd < 0) - { log_debug( "Invalid directory. (%s)", dirpath); *count = -1; return NULL; } - else - { log_debug( "open(%s)", dirpath); } + if ((cv->cur + size) <= cv->sz) + { + memcpy(((uint8_t*)cv->ptr + cv->cur), data, size); + cv->cur += size; + } +} - memset(buffer, 0, sizeof(buffer)); +bool getEntries(const char* path, struct CVec* cv) +{ + struct dirent* pDirent; + DIR* pDir = NULL; - // get directory entries -#if defined (__ORBIS__) - while(getdents(dfd, buffer, sizeof(buffer)) != 0) -#else - while(syscall(SYS_getdents, dfd, buffer, sizeof(buffer)) != 0) -#endif - { - dent = (struct dirent *)buffer; + if (!strlen(path)) + return false; - while(dent->d_fileno) - { // skip `.` and `..` - if( !strncmp(dent->d_name, "..", 2) - || !strncmp(dent->d_name, ".", 1)) goto skip_dent; + pDir = opendir(path); + if (pDir == NULL) + return false; - // deal with filtering outside of this function, we just skip .., . + while ((pDirent = readdir(pDir)) != NULL) { - switch(r) - { // first round: just count items - case 1: - { - // skip special cases - if(dent->d_fileno == 0) goto skip_dent; - #if 0 - log_debug( "[%p]: %8lx %2d, type: %4d, '%s'", // report entry - dent, - dent->d_fileno, dent->d_reclen, - dent->d_type, dent->d_name /* on pc we step back by -1 */); - #endif - break; - } - // second round: store filenames - case 0: p[n].name = strdup(dent->d_name); break; - } - n++; -skip_dent: + if (strcmp(pDirent->d_name, ".") == 0 || strcmp(pDirent->d_name, "..") == 0) + continue; - dent = (struct dirent *)((void *)dent + dent->d_reclen); + if (pDirent->d_type == DT_DIR) { - if(dent == (void*) &buffer[512]) break; // refill buffer + // Dir is title_id, it WILL go through 3 filters + // so lets assume they are vaild until the filters say otherwise + struct _ent bse; + strcpy(bse.fname, pDirent->d_name); // dir + '/' + dName ? + bse.sz = pDirent->d_namlen + 2; + CV_Append(cv, &bse, sizeof(bse)); } - memset(buffer, 0, sizeof(buffer)); + else + continue; + } - close(dfd); - - // on first round, calloc for our list - if(!p) - { // now n holds total item count, note it - p = calloc(n, sizeof(entry_t)); - *count = n; + if (closedir(pDir) != 0) { + return false; } + return true; +} - // first round passed, loop - r--; if(!r) goto loop; +#include +int HDD_count = -1; - // report count - log_info( "%d items at %p, from 1-%d", *count, (void*)p, *count); +const char* SPECIAL_XMB_ICON_FOLDERS[] = { APP_HOME_DATA_FOLDER }; +const char* SPECIAL_XMB_ICON_TID[] = { APP_HOME_DATA_TID }; - /* resort using custom comparision function */ - qsort(p, *count, sizeof(entry_t), struct_cmp_by_name); +void init_xmb_special_icons(const char* XMB_ICON_PATH) +{ + char buf[255]; - // report items - //for (int i = 0; i < num; ++i) log_error( "%s", p[i].name); + if (!if_exists(XMB_ICON_PATH)) + { + log_info("[XMB OP] Creating %s for XMB", XMB_ICON_PATH); + mkdir(XMB_ICON_PATH, 0777); + snprintf(buf, 254, "%s/app.pkg", XMB_ICON_PATH); + touch_file(buf); + } + else + log_info("[XMB OP] %s already exists", XMB_ICON_PATH); +} - return p; +void info_for_xmb_special_icons(item_t* item, const char* TITLE, const char* TID, const char* VER) +{ + + item_idx_t* t = &item->token_d[0]; + + t[NAME].off = strdup(TITLE); + t[NAME].len = strlen(t[NAME].off); + log_info("[XMB OP] SFO Name: %s:%i", t[NAME].off, t[NAME].len); + t[ID].off = strdup(TID); + t[ID].len = strlen(t[ID].off); + log_info("[XMB OP] SFO ID: %s", t[ID].off); + t[VERSION].off = strdup(VER); + t[VERSION].len = strlen(t[VERSION].off); + log_info("[XMB OP] SFO VERSION: %s", t[VERSION].off); } -bool filter_entry_on_IDs(const char *entry) + +// each token_data is filled by dynalloc'd mem by strdup! +item_t* index_items_from_dir(const char* dirpath, const char* dirpath2) { - if(strlen(entry) != 9) return false; - unsigned int nid; - char id[ 5], - tmp[32]; + uint64_t start = sceKernelGetProcessTime(); - int ret = sscanf( entry, "%c%c%c%c%5u", - &id[0], &id[1], &id[2], &id[3], &nid ); - id[4] = '\0'; - if(ret == 5) - { - int res = strlen(id); // ABCD - if(res != 4 - || nid > 99999) goto fail; // 01234 + log_info("Starting index_items_from_dir ..."); - snprintf(&tmp[0], 31, "%s%.5u", id, nid); + // init_xmb_special_icons(APP_HOME_DATA_FOLDER); - if(strlen(tmp) != 9) goto fail; - // passed -// log_info("%s - %s looks valid", entry, tmp); + struct CVec* cvEntries = NULL; + int ext_count = -1; + CV_Create(&cvEntries, 666666 ^ 222); - return true; + if (!getEntries(dirpath, cvEntries)) + msgok(FATAL, "Unable to Open %s", dirpath); + else + log_debug("[Dir 1] Found %i Apps in: %s", (HDD_count = cvEntries->cur / sizeof(struct _ent)), dirpath); + + if (if_exists(dirpath2)) + { + if (!getEntries(dirpath2, cvEntries)) + log_warn("Unable to locate Apps on %s", dirpath2); + else + { + ext_count = (cvEntries->cur / sizeof(struct _ent) - HDD_count); + log_debug("[Dir 2] Found %i Apps in: %s", ext_count, dirpath2); + } } -fail: - return false; -} -// each token_data is filled by dynalloc'd mem by strdup! -item_t *index_items_from_dir(const char *dirpath) -{ - // grab, count and sort entries by name - int count = -1; - entry_t *e = get_item_entries(dirpath, &count); + uint32_t entCt = cvEntries->cur / sizeof(struct _ent); + log_debug("Have %d entries:", entCt); +#if 0 + for (int ix = 0; ix < entCt; ix++) { + struct _ent* e = &((struct _ent*)cvEntries->ptr)[ix]; + log_debug("ent[%06d] size: %d\t\"%s\"", ix, e->sz, e->fname); + } +#endif // output - item_t *ret = calloc(count +1, sizeof(item_t)); + item_t* ret = calloc(entCt + 1, sizeof(item_t)); char tmp[256]; // skip first reserved: take care int i = 1, j; - for(j = 1; j < count +1; j++) + for (j = 1; j < entCt + 1; j++) { // we use just those token_data - snprintf(&tmp[0], 255, "%s", e[ j -1 ].name); + + struct _ent* e = &((struct _ent*)cvEntries->ptr)[j - 1]; + + snprintf(&tmp[0], 255, "%s", e->fname); // for Installed_Apps - { - if( ! filter_entry_on_IDs(tmp) ) continue; + { + if (!filter_entry_on_IDs(tmp)) + { + log_debug("[F1] Filtered out %s", tmp); + continue; + } - char fullpath[128]; - snprintf(&fullpath[0], 127, "%s/%.9s", dirpath, tmp); - // passed -// log_info( "%3d, %d: %s", i, j, fullpath); + //extra filter: can open app.pkg + char fullpath[128]; + snprintf(&fullpath[0], 127, "%s/%.9s/app.pkg", dirpath, tmp); + + if (!if_exists(fullpath)) + snprintf(&fullpath[0], 127, "%s/%.9s/app.pkg", dirpath2, tmp); - if( check_stat(fullpath) != S_IFDIR ) continue; - } + if (!if_exists(fullpath)) + { + log_debug("[F2] Filtered out %s, %s doesnt exist", tmp, fullpath); + continue; + } + } // dynalloc for user tokens - ret[i].token_c = NUM_OF_USER_TOKENS; - ret[i].token_d = calloc(ret[i].token_c, sizeof(item_idx_t)); + ret[i].token_c = NUM_OF_USER_TOKENS; + ret[i].token_d = calloc(ret[i].token_c, sizeof(item_idx_t)); - ret[i].token_d[ ID ].off = strdup(tmp); - ret[i].token_d[ ID ].len = strlen(tmp); + ret[i].token_d[ID].off = strdup(tmp); + ret[i].token_d[ID].len = strlen(tmp); // replicate for now - ret[i].token_d[ NAME ].off = strdup(tmp), - ret[i].token_d[ NAME ].len = strlen(tmp); + ret[i].token_d[NAME].off = strdup(tmp), + ret[i].token_d[NAME].len = strlen(tmp); #if defined (__ORBIS__) - snprintf(&tmp[0], 255, "/user/appmeta/%s/icon0.png", e[ j -1 ].name); + + snprintf(&tmp[0], 255, "/user/appmeta/%s/icon0.png", e->fname); + + if (!if_exists(tmp)) + snprintf(&tmp[0], 255, "/user/appmeta/external/%s/icon0.png", e->fname); + #else // on pc - snprintf(&tmp[0], 255, "./storedata/%s/icon0.png", e[ j -1 ].name); + snprintf(&tmp[0], 255, "./storedata/%s/icon0.png", e->fname); #endif - - ret[i].token_d[ PICPATH ].off = strdup(tmp), - ret[i].token_d[ PICPATH ].len = strlen(tmp); + ret[i].token_d[PICPATH].off = strdup(tmp), + ret[i].token_d[PICPATH].len = strlen(tmp); // don't try lo load ret[i].texture = 0;// XXX load_png_asset_into_texture(tmp); #if defined (__ORBIS__) - snprintf(&tmp[0], 255, "/system_data/priv/appmeta/%s/param.sfo", e[ j -1 ].name); + + snprintf(&tmp[0], 255, "/system_data/priv/appmeta/%s/param.sfo", e->fname); + + if (!if_exists(tmp)) + snprintf(&tmp[0], 255, "/system_data/priv/appmeta/external/%s/param.sfo", e->fname); #else // on pc - snprintf(&tmp[0], 255, "./storedata/%s/param.sfo", e[ j -1 ].name); -#endif + snprintf(&tmp[0], 255, "./storedata/%s/param.sfo", e->fname); +#endif // read sfo - index_token_from_sfo(&ret[i], &tmp[0]); + // for (int i = 0; sizeof SPECIAL_XMB_ICON_TID / sizeof SPECIAL_XMB_ICON_TID[0] -1; i++) + // { + + + if (strstr(e->fname, APP_HOME_DATA_TID) != NULL) { + + + if (strstr(e->fname, APP_HOME_DATA_TID)) + { + ret[i].token_d[PICPATH].off = strdup("/data/APP_HOME.png"), + ret[i].token_d[PICPATH].len = strlen("/data/APP_HOME.png"); + // info_for_xmb_special_icons(&ret[i], "APP_HOME(Data)", APP_HOME_DATA_TID, "0.00"); + } + + } + else + index_token_from_sfo(&ret[i], &tmp[0]); + // } i++; } + + // save path and counted items in first (reserved) index - ret[0].token_d = calloc(1, sizeof(item_idx_t)); + ret[0].token_d = calloc(1, sizeof(item_idx_t)); ret[0].token_d[0].off = strdup(dirpath); - ret[0].token_c = i -1;// updated count; + ret[0].token_c = i - 1;// updated count; - ret = realloc(ret, i * sizeof(item_t)); - log_info("valid count: %d", i -1); - // all done, release! - free_item_entries(e); + log_info("valid count: %d", i - 1); + HDD_count = i; + HDD_count -= ext_count + 1; + log_info("HDD_count: %i", HDD_count); + + ret = realloc(ret, i * sizeof(item_t)); // report back - if(0){ - for(int i = 1; i < ret[0].token_c +1 /* off by one, skip 0 reserved! */; i++) - log_info( "%3d: %s", i, ret[i].token_d[ ID ].off); + if (0) { + for (int i = 1; i < ret[0].token_c; i++) + log_info("%3d: %s", i, ret[i].token_d[ID].off); } + CV_Destroy(&cvEntries); + + log_debug("Took %lld microsecs to load Apps", (sceKernelGetProcessTime() - start)); return ret; } @@ -320,7 +340,7 @@ item_t *index_items_from_dir(const char *dirpath) #include #include -int df(char *out, const char *mountPoint) +int df(char* out, const char* mountPoint) { struct statfs s; long blocks_used = 0; @@ -336,20 +356,20 @@ int df(char *out, const char *mountPoint) { blocks_used = s.f_blocks - s.f_bfree; blocks_percent_used = (long) - (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); + (blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5); #if 0 - log_info("%-20s %9ld %9ld %9ld %3ld%% %s", - out, - (long) (s.f_blocks * (s.f_bsize / 1024.0)), - (long) ((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)), - (long) (s.f_bavail * (s.f_bsize / 1024.0)), - blocks_percent_used, mountPoint); + log_info("%-20s %9ld %9ld %9ld %3ld%% %s", + out, + (long)(s.f_blocks * (s.f_bsize / 1024.0)), + (long)((s.f_blocks - s.f_bfree) * (s.f_bsize / 1024.0)), + (long)(s.f_bavail * (s.f_bsize / 1024.0)), + blocks_percent_used, mountPoint); #endif } double gb_free = ((long)(s.f_bavail * (s.f_bsize / 1024.0)) - / 1024); + / 1024); gb_free /= 1024.; -// log_info("%s, %3ld%%, %.1f GB free", mountPoint, blocks_percent_used, gb_free); + // log_info("%s, %3ld%%, %.1f GB free", mountPoint, blocks_percent_used, gb_free); snprintf(out, 127, "%s, %3ld%%, %.1f GB free", mountPoint, blocks_percent_used, gb_free); return blocks_percent_used; @@ -357,22 +377,22 @@ int df(char *out, const char *mountPoint) #include // ctime -void get_stat_from_file(char *out, const char *filepath) +void get_stat_from_file(char* out, const char* filepath) { struct stat fileinfo; - if( ! stat(filepath, &fileinfo) ) + if (!stat(filepath, &fileinfo)) { // https://man7.org/linux/man-pages/man2/stat.2.html#EXAMPLES - switch(fileinfo.st_mode & S_IFMT) { - case S_IFBLK: snprintf(out, 127, "Block device"); break; - case S_IFCHR: snprintf(out, 127, "Character device"); break; - case S_IFDIR: snprintf(out, 127, "Directory, %s", ctime(&fileinfo.st_mtime)); break; - case S_IFIFO: snprintf(out, 127, "FIFO/Pipe"); break; - case S_IFLNK: snprintf(out, 127, "Symlink"); break; - case S_IFREG: snprintf(out, 127, "Size: %ld bytes, %s", fileinfo.st_size, ctime(&fileinfo.st_mtime)); break; - case S_IFSOCK: snprintf(out, 127, "Socket"); break; - default: snprintf(out, 127, "Unknown, Mode %o", fileinfo.st_mode); break; + switch (fileinfo.st_mode & S_IFMT) { + case S_IFBLK: snprintf(out, 127, "Block device"); break; + case S_IFCHR: snprintf(out, 127, "Character device"); break; + case S_IFDIR: snprintf(out, 127, "Directory, %s", ctime(&fileinfo.st_mtime)); break; + case S_IFIFO: snprintf(out, 127, "FIFO/Pipe"); break; + case S_IFLNK: snprintf(out, 127, "Symlink"); break; + case S_IFREG: snprintf(out, 127, "Size: %ld bytes, %s", fileinfo.st_size, ctime(&fileinfo.st_mtime)); break; + case S_IFSOCK: snprintf(out, 127, "Socket"); break; + default: snprintf(out, 127, "Unknown, Mode %o", fileinfo.st_mode); break; } } @@ -383,15 +403,15 @@ void get_stat_from_file(char *out, const char *filepath) out[strcspn(out, "\r")] = 0; } -int check_stat(const char *filepath) +int check_stat(const char* filepath) { struct stat fileinfo; - if( ! stat(filepath, &fileinfo) ) + if (!stat(filepath, &fileinfo)) { - switch(fileinfo.st_mode & S_IFMT) + switch (fileinfo.st_mode & S_IFMT) { - case S_IFDIR: return S_IFDIR; - case S_IFREG: return S_IFREG; + case S_IFDIR: return S_IFDIR; + case S_IFREG: return S_IFREG; } } return 0; diff --git a/Store/source/main.c b/Store/source/main.c index 1ff6d51..cbe6e1d 100644 --- a/Store/source/main.c +++ b/Store/source/main.c @@ -1,30 +1,10 @@ - - - #include "defines.h" #include -//extern void *(*libc_memset)(void *, int, size_t); ? +#include int libcmi = -1; -int (*jailbreak_me)(void); - -int64_t sys_dynlib_load_prx(char* prxPath, int* moduleID) -{ - return (int64_t)syscall4(594, prxPath, 0, moduleID, 0); -} - -int64_t sys_dynlib_unload_prx(int64_t prxID) -{ - return (int64_t)syscall1(595, (void*)prxID); -} - - -int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void *destFuncOffset) -{ - return (int64_t)syscall3(591, (void*)moduleHandle, (void*)functionName, destFuncOffset); -} - +//GlConfig* GlConf; OrbisPadConfig *confPad; bool flag=true; @@ -35,7 +15,8 @@ struct timeval t1, t2; #define DELTA (123) // dpad delta movement int* (*crash_test)(); - +static int (*jailbreak_me)(void) = NULL; +static int (*rejail_multi)(void) = NULL; void updateController() { @@ -85,6 +66,7 @@ void updateController() || confPad->padDataCurrent->ly > (127 + DELTA)) { log_info( "Down pressed"); + GLES2_scene_on_pressed_button(116); } else @@ -119,13 +101,12 @@ void updateController() { log_info( "Cross pressed"); GLES2_scene_on_pressed_button(53); - //notify("Notify test:Passed"); } if(orbisPadGetButtonPressed(ORBISPAD_SQUARE)) { + log_info( "Square pressed"); - //crash_test(); GLES2_scene_on_pressed_button(SQU); } if(orbisPadGetButtonPressed(ORBISPAD_L1)) @@ -139,23 +120,22 @@ void updateController() } if(orbisPadGetButtonPressed(ORBISPAD_R1)) { - log_info( "R1 pressed"); - /* int mId, hcId; - int ret = pingtest(mId, hcId, "https://10.0.0.2"); - log_info( "pingtest ret:%d", ret); */ + + } if(orbisPadGetButtonPressed(ORBISPAD_R2)) { - log_info( "R2 pressed"); + } + if (orbisPadGetButtonPressed(ORBISPAD_OPTIONS)) + { + log_info("Exit Called"); + raise(SIGQUIT); } } } void finishApp() { - //orbisAudioFinish(); - //orbisKeyboardFinish(); - //orbisGlFinish(); orbisPadFinish(); orbisNfsFinish(); } @@ -163,22 +143,22 @@ void finishApp() static bool initAppGl() { int ret = orbisGlInit(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT); - if(ret>0) + if (ret > 0) { glViewport(0, 0, ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT); - ret=glGetError(); - if(ret) + ret = glGetError(); + if (ret) { - log_info( "[%s] glViewport failed: 0x%08X",__FUNCTION__,ret); + log_info("[%s] glViewport failed: 0x%08X", __FUNCTION__, ret); return false; } -// glClearColor(0.f, 0.f, 1.f, 1.f); // blue RGBA - glClearColor( 0.1211, 0.1211, 0.1211, 1.); // background color + // glClearColor(0.f, 0.f, 1.f, 1.f); // blue RGBA + glClearColor(0.1211, 0.1211, 0.1211, 1.); // background color - ret=glGetError(); - if(ret) + ret = glGetError(); + if (ret) { - log_info( "[%s] glClearColor failed: 0x%08X",__FUNCTION__,ret); + log_info("[%s] glClearColor failed: 0x%08X", __FUNCTION__, ret); return false; } return true; @@ -188,15 +168,17 @@ static bool initAppGl() bool initApp() { - //orbisNfsInit(NFSEXPORT); - //orbisFileInit(); -// int ret=initOrbisLinkApp(); +#if defined (USE_NFS) + orbisNfsInit(NFSEXPORT); + orbisFileInit(); + int ret = initOrbisLinkApp(); +#endif sceSystemServiceHideSplashScreen(); - confPad = orbisPadGetConf(); + confPad = orbisPadGetConf(); - if( ! initAppGl() ) return false; + if (!initAppGl()) return false; return true; } @@ -204,74 +186,75 @@ bool initApp() /// for timing, fps #define WEN (2048) -unsigned int frame = 1, - time_ms = 0; +unsigned int frame = 1, +time_ms = 0; + -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - + int ret = -1; /* prepare pad and piglet modules in advance, read /data/orbislink/orbislink_config.ini for debugnet - (no nfs, audio init yet...) */ - //debugNetInit("10.0.0.2", 18198, 3); - - // to access /user and notify() we need full privileges... - - /* load some required modules */ #if defined (USE_NFS) + debugNetInit("10.0.0.2", 18198, 3); - // to access /user and notify() we need full privileges -// escalate_priv(); ret = initOrbisLinkAppVanillaGl(); /* some nfs setup */ -// ret = orbisNfsInit("nfs://10.0.0.2/hostapp"); ret = orbisNfsInit("nfs://10.0.0.2/Archive/PS4-work/orbisdev/orbisdev-samples/linux_es2goodness"); -// ret = orbisNfsInit("nfs://192.168.2.61/home/alfa/NFS/hostapp"); - log_info( "orbisNfsInit return: %x", ret); + log_info("orbisNfsInit return: %x", ret); sleep(1); #else /* load custom .prx, resolve and call a function */ - sys_dynlib_load_prx("/app0/Media/jb.prx", &libcmi); + + sys_dynlib_load_prx("/app0/Media/jb.prx", &libcmi); ret = sys_dynlib_dlsym(libcmi, "jailbreak_me", &jailbreak_me); if (!ret) { - log_info( "jailbreak_me resolved from PRX"); + log_info("jailbreak_me resolved from PRX"); - if((ret = jailbreak_me() != 0)) goto error; + if ((ret = jailbreak_me() != 0)) goto error; } else goto error; - if((ret = initGL_for_the_store() < 0)) goto error; + + if (strstr(argv[0], "--reload_games") != NULL) + { + log_debug("arg[1] %s", argv[1]); + if ((ret = initGL_for_the_store(true, atoi(argv[1])) < 0)) goto error; + loadmsg("Loading Installed Apps"); + } + else { + if ((ret = initGL_for_the_store(false, -1) < 0)) goto error; + } + + #endif - //if(!ret) sceKernelIccSetBuzzer(1); // init some libraries flag = initApp(); ret = sceSysmoduleLoadModule(0x009A); // internal FreeType, libSceFreeTypeOl - int moduleId = sceKernelLoadStartModule("/system/common/lib/libSceSysUtil.sprx", 0, NULL, 0, 0, 0); - // more test ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_NETCTL); - log_info( "%s SCE_SYSMODULE_INTERNAL_NETCTL: 0x%08X",__FUNCTION__, ret); + log_info("%s SCE_SYSMODULE_INTERNAL_NETCTL: 0x%08X", __FUNCTION__, ret); ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_HTTP); - log_info( "%s SCE_SYSMODULE_INTERNAL_HTTP: 0x%08X",__FUNCTION__, ret); + log_info("%s SCE_SYSMODULE_INTERNAL_HTTP: 0x%08X", __FUNCTION__, ret); ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SSL); - log_info( "%s SCE_SYSMODULE_INTERNAL_SSL: 0x%08X",__FUNCTION__, ret); + log_info("%s SCE_SYSMODULE_INTERNAL_SSL: 0x%08X", __FUNCTION__, ret); // feedback log_info("Here we are!"); @@ -279,56 +262,63 @@ int main(int argc, char *argv[]) /* init GLES2 stuff */ // demo-font.c init - es2init_text( ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT ); + es2init_text(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT); // ES_UI - GLES2_scene_init( ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT ); + GLES2_scene_init(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT); /// reset timers time_ms = get_time_ms(); gettimeofday(&t1, NULL); t2 = t1; + /// enter main render loop - while(flag) + while (flag) { - updateController(); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ret = glGetError(); - if(ret) { - log_info( "[ORBIS_GL] glClear failed: 0x%08X", ret); - //goto err; - } + updateController(); - /// draw ! + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + ret = glGetError(); + if (ret) { + log_info("[ORBIS_GL] glClear failed: 0x%08X", ret); + //goto err; + } - // ES_UI - GLES2_scene_render(); - /// get timing, fps - if( ! (frame %WEN) ) - { - unsigned int now = get_time_ms(); - log_info( "frame: %d, took: %ums, fps: %.3f", frame, now - time_ms, - ((double)WEN / (double)(now - time_ms) * 1000.f)); - time_ms = now; - } - frame++; + // ES_UI + GLES2_scene_render(); - if(1) // update for the GLES uniform time - { - gettimeofday( &t2, NULL ); - // calculate delta time - dt = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6; + /// get timing, fps + if (!(frame % WEN)) + { + unsigned int now = get_time_ms(); + log_info("frame: %d, took: %ums, fps: %.3f", frame, now - time_ms, + ((double)WEN / (double)(now - time_ms) * 1000.f)); - t1 = t2; - // update total time - u_t += dt; - } + print_memory(); + + time_ms = now; + } + frame++; + + + if (1) // update for the GLES uniform time + { + gettimeofday(&t2, NULL); + // calculate delta time + dt = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6; - orbisGlSwapBuffers(); /// flip frame + t1 = t2; + // update total time + u_t += dt; + } + orbisGlSwapBuffers(); /// flip frame - dump_frame(); + + dump_frame(); + + } error: @@ -342,4 +332,4 @@ int main(int argc, char *argv[]) finishOrbisLinkApp(); exit(EXIT_SUCCESS); -} +} \ No newline at end of file diff --git a/Store/source/pixelshader.c b/Store/source/pixelshader.c index e4431d7..271732d 100644 --- a/Store/source/pixelshader.c +++ b/Store/source/pixelshader.c @@ -84,7 +84,7 @@ static void reshape(int width, int height) #include "p_shaders.h" // actually, just 4 #include "ps_signs_frag.h" -static GLuint CreateProgramFE(int program_num) +static GLuint CreateProgramFE(int program_num, char* path) { GLchar *vShader = vs_s[0]; GLchar *fShader = fs_s[ program_num ]; @@ -96,7 +96,7 @@ static GLuint CreateProgramFE(int program_num) switch(program_num) { case 4: fShader = ps_signs_shader; break; - case 5: fShader = (void*)orbisFileGetFileContent( "/user/app/NPXS39041/shaders/SnowIsFalling.frag" ); break; + case 5: fShader = (void*)orbisFileGetFileContent( path ); break; default: fShader = fs_s[ 2/*iTime*/]; break; } } @@ -169,8 +169,16 @@ void pixelshader_init( int width, int height ) } #endif /* compile, link and use shader */ - mz_shader = CreateProgramFE(0); - shader = CreateProgramFE(4); // test emb2 +#define SNOW_DLC "/mnt/sandbox/NPXS39041_000/app0/assets/snow.frag" + +mz_shader = CreateProgramFE(0, NULL); + +if (if_exists(SNOW_DLC)) { + log_info("Loading...."); + shader = CreateProgramFE(5, SNOW_DLC); +} +else + shader = CreateProgramFE(4, NULL); // test emb2 // feedback log_info( "[%s] program_id=%d (0x%08x)", __FUNCTION__, mz_shader, mz_shader); log_info( "[%s] program_id=%d (0x%08x)", __FUNCTION__, shader, shader); diff --git a/Store/source/png.c b/Store/source/png.c index eaf042f..7197157 100644 --- a/Store/source/png.c +++ b/Store/source/png.c @@ -3,7 +3,7 @@ #include #include - +#include #include "defines.h" /////// png @@ -282,7 +282,7 @@ int writeImage(char* filename, int width, int height, int *buffer, char* title) png_write_info(png_ptr, info_ptr); // Allocate memory for one row (3 bytes per pixel - RGB) - row = (png_bytep) calloc(3 * width +1, sizeof(png_byte)); + row = (png_bytep)calloc(3 * width +1, sizeof(png_byte)); // Write image data int x, y; diff --git a/Store/source/sfo.c b/Store/source/sfo.c index 2df07aa..23cde97 100644 --- a/Store/source/sfo.c +++ b/Store/source/sfo.c @@ -3,6 +3,7 @@ #include #include +#include typedef uint32_t u32; typedef uint8_t u8 ; diff --git a/Store/source/sig_handler.c b/Store/source/sig_handler.c index f645712..1c1f392 100644 --- a/Store/source/sig_handler.c +++ b/Store/source/sig_handler.c @@ -133,10 +133,15 @@ int progstart(char* msg) bool dump = false; -static void touch_file(char* destfile) +bool touch_file(char* destfile) { int fd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0777); - if (fd > 0) close(fd); + if (fd > 0) { + close(fd); + return true; + } + else + return false; } bool decrypt_dir(char *sourcedir, char* destdir, char* gtitle, char* title_id) @@ -268,7 +273,7 @@ int wait_for_bdcopy(char *title_id) return (progress * 100 / (filelen - 0x100)); } - +bool (*Dump_Meta)(char* tid, char* title) = NULL; bool dump_game(char *title_id, char *usb_path, char *gtitle) { @@ -295,7 +300,7 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) mkdir(dst_app, 0777); mkdir(dst_pat, 0777); - + print_memory(); sprintf(src_path, "/user/app/%s/app.pkg", title_id); //notify("Extracting app package..."); @@ -314,6 +319,8 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) log_info("Finished app package..."); + print_memory(); + sprintf(src_path, "/user/patch/%s/patch.pkg", title_id); if (if_exists(src_path)) { @@ -334,6 +341,7 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) copyFile(src_path, dst_file); } + print_memory(); log_info("finished patch package......"); @@ -344,6 +352,8 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) log_info("flag: %i", flag); log_info("finish app image......"); + print_memory(); + sprintf(src_path, "/mnt/sandbox/pfsmnt/%s-patch0-nest/pfs_image.dat", title_id); if (if_exists(src_path)) { @@ -356,6 +366,7 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) log_info("flag: %i", flag); } + print_memory(); sprintf(src_path, "/mnt/sandbox/pfsmnt/%s-app0", title_id); if (if_exists(src_path)) @@ -364,6 +375,8 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) log_info("flag: %i", flag); } + print_memory(); + sprintf(src_path, "/mnt/sandbox/pfsmnt/%s-patch0", title_id); if (if_exists(src_path)) { @@ -372,29 +385,95 @@ bool dump_game(char *title_id, char *usb_path, char *gtitle) log_info("flag: %i", flag); } + snprintf(src_path, 63, "/system_data/priv/appmeta/%s/param.sfo", title_id); + + if (!if_exists(src_path)) + snprintf(src_path, 63, "/system_data/priv/appmeta/external/%s/param.sfo", title_id); + + sprintf(dst_file, "%s/sce_sys/param.sfo", dst_app); + copyFile(src_path, dst_file); + + print_memory(); + + if (if_exists("/mnt/sandbox/pfsmnt/NPXS39041-app0/Media/dump.prx")) + { + SceKernelModule module_id = -1; + sys_dynlib_load_prx("/mnt/sandbox/pfsmnt/NPXS39041-app0/Media/dump.prx", &module_id); + if (module_id >= 0) + { + //PRX_INTERFACE void LaunchGamePRX(); + int ret = sys_dynlib_dlsym(module_id, "Dump_Meta", &Dump_Meta); + if (!ret) + { + if (Dump_Meta != NULL) + { + flag = Dump_Meta(title_id, gtitle); + log_debug("Dump_Meta() returned %s\n", flag ? "true" : "false"); + } + } + else + { + log_debug("failed to resolve\n"); + } + } + else + { + log_debug("failed to load\n"); + } + } unlink(dump_sem); touch_file(comp_sem); sceMsgDialogTerminate(); log_info( "flag = %i", flag); + print_memory(); + return flag; } +static int (*rejail_multi)(void) = NULL; + +void Exit_Success(const char* text) +{ + log_debug(text); + + + + if (rejail_multi != NULL) { + log_debug("Rejailing App >>>"); + rejail_multi(); + log_debug("App ReJailed"); + } + + log_debug("Calling SystemService Exit"); + sceSystemServiceLoadExec("exit", 0); +} + void Exit_App_With_Message(int sig_numb) { msgok(NORMAL, "############# Program has gotten a FATAL Signal/Error: %i ##########\n\n If this continues Contact the PKG-Zone team\n\n", sig_numb); - // trigger_dump_frame(); - // save_dumped_frame(); - copyFile(STORE_LOG, "/mnt/usb0/Store_Crash.log"); - sceSystemServiceLoadExec("exit", 0); + char *buff[100]; + //init srand + srand((unsigned)time(NULL)); + + //try our best to make the name not always the same + snprintf(buff, 99, "%s/Store_Crash_%i.log", usbpath(), rand() % 100); + log_debug("App crashed writing log to %s", buff); + + if(touch_file(buff)) + copyFile(STORE_LOG, buff); + + Exit_Success("Exit_App_With_Message ->"); } void SIG_Handler(int sig_numb) { - + int libcmi = 1; + sys_dynlib_load_prx("/app0/Media/jb.prx", &libcmi); + sys_dynlib_dlsym(libcmi, "rejail_multi", &rejail_multi); void* array[100]; // @@ -411,10 +490,10 @@ void SIG_Handler(int sig_numb) log_debug("TERM called"); break; case SIGQUIT: - log_debug("QUIT called"); + Exit_Success("SIGQUIT Called"); break; case SIGKILL: - log_debug("KILL called"); + Exit_Success("SIGKILL Called"); break; case SIGSTOP: log_debug("App has been suspeneded"); @@ -426,14 +505,15 @@ void SIG_Handler(int sig_numb) break; case SIGSEGV: { log_debug("App has crashed"); - + uint8_t* IPC_BUFFER = malloc(100); + IPCSendCommand(DISABLE_HOME_REDIRECT, IPC_BUFFER); if (dump) { msgok(WARNING, "The Game Dump has failed to the app will now reload\n Press OK to continue"); sceSystemServiceLoadExec("/data/self/eboot.bin", 0); goto App_Resumed; } - + free(IPC_BUFFER); goto backtrace_and_exit; } @@ -519,21 +599,19 @@ log_info("title_id: %s, title: %s", title_id, title); progstart("Starting the Dumper..."); sprintf(notify_buf, "/mnt/usb0/%s-app/", title_id); - if ((fd = sceKernelOpen(notify_buf, 0, 0)) > 0) + if (if_exists(notify_buf)) { ProgSetMessagewText(5, "Folder already Exists..\nDeleting %s", notify_buf); rmtree(notify_buf); sprintf(notify_buf, "/mnt/usb0/%s.complete", title_id); unlink(notify_buf); - sceKernelClose(fd); } sprintf(notify_buf, "/mnt/usb0/%s-patch/", title_id); - if ((fd = sceKernelOpen(notify_buf, 0, 0)) > 0) + if (if_exists(notify_buf)) { ProgSetMessagewText(8, "Folder already Exists..\nDeleting %s", notify_buf); rmtree(notify_buf); - sceKernelClose(fd); } //g @@ -581,12 +659,13 @@ log_info("title_id: %s, title: %s", title_id, title); //dump_game has all the dialoge for copied proc flag_issue = dump_game(title_id, get->opt[ USB_PATH ], title); - + // Dump_Game(title_id, title); if(!flag_issue) msgok(NORMAL, "Dump of %s is Complete without Errors!", title_id); else msgok(WARNING, "Dump of %s Has Completed with Issues NOT all files were dumped!\n\nMake sure your exploit hoster has MMAP patches enabled", title_id); + print_memory(); log_info("finished"); dump = false; diff --git a/Store/source/unpfs.c b/Store/source/unpfs.c index f1dc052..108ed49 100644 --- a/Store/source/unpfs.c +++ b/Store/source/unpfs.c @@ -12,6 +12,7 @@ #include #include #include +#include #if defined (__ORBIS__) @@ -98,17 +99,17 @@ static void parse_directory(int ino, int lev, char *parent_name, bool dry_run, c while (pos < top) { - struct dirent_t *ent = lmalloc (sizeof(struct dirent_t)); + struct dirent_t *ent = malloc(sizeof(struct dirent_t)); lseek(pfs, pos, SEEK_SET); read(pfs, ent, sizeof(struct dirent_t)); if (ent->type == 0) { - lfree(ent); + free(ent); break; } - char *name = lmalloc(ent->namelen + 1); + char *name = malloc(ent->namelen + 1); memset(name, 0, ent->namelen + 1); if (lev > 0) { @@ -117,7 +118,7 @@ static void parse_directory(int ino, int lev, char *parent_name, bool dry_run, c } - char* fname = lmalloc(strlen(parent_name) + ent->namelen + 2); + char* fname = malloc(strlen(parent_name) + ent->namelen + 2); if (parent_name != NULL) sprintf(fname, "%s/%s", parent_name, name); else @@ -125,7 +126,7 @@ static void parse_directory(int ino, int lev, char *parent_name, bool dry_run, c if ((ent->type == 2) && (lev > 0)) { - log_info("%s -- prog %llx", fname, p_progress); + log_info("%s -- prog %.3f", fname, p_progress); if(strstr(fname, "-app")) ProgSetMessagewText(p_progress, "Dump info\nApp name: %s\nTITLE_ID %s\n\nExtracting Base Game files File %s to USB...\n", gtitle, title_id, fname); @@ -147,16 +148,16 @@ static void parse_directory(int ino, int lev, char *parent_name, bool dry_run, c pos += ent->entsize; - lfree(ent); - lfree(name); - lfree(fname); + free(ent); + free(name); + free(fname); } } } int unpfs(char *pfsfn, char *tidpath, char* gtitle, char* title_id) { - copy_buffer = lmalloc(BUFFER_SIZE); + copy_buffer = malloc(BUFFER_SIZE); p_progress = 11; @@ -165,14 +166,18 @@ int unpfs(char *pfsfn, char *tidpath, char* gtitle, char* title_id) pfs = open(pfsfn, O_RDONLY, 0); if (pfs < 0) return -1; - header = lmalloc(sizeof(struct pfs_header_t)); + header = malloc(sizeof(struct pfs_header_t)); lseek(pfs, 0, SEEK_SET); read(pfs, header, sizeof(struct pfs_header_t)); - inodes = lmalloc(sizeof(struct di_d32) * header->ndinode); + inodes = malloc(sizeof(struct di_d32) * header->ndinode); uint32_t ix = 0; + + + ProgSetMessagewText(20, "Dump info\n\nApp name: %s\nTITLE_ID %s\n\n Processing ino(s) ...", gtitle, title_id); + for (uint32_t i = 0; i < header->ndinodeblock; i++) { for (uint32_t j = 0; (j < (header->blocksz / sizeof(struct di_d32))) && (ix < header->ndinode); j++) @@ -180,10 +185,6 @@ int unpfs(char *pfsfn, char *tidpath, char* gtitle, char* title_id) lseek(pfs, (uint64_t)header->blocksz * (i + 1) + sizeof(struct di_d32) * j, SEEK_SET); read(pfs, &inodes[ix], sizeof(struct di_d32)); - - - ProgSetMessagewText(20, "Dump info\n\nApp name: %s\nTITLE_ID %s\n\n Processing ino 0x%x...", gtitle, title_id, ix); - ix++; } } @@ -196,10 +197,10 @@ int unpfs(char *pfsfn, char *tidpath, char* gtitle, char* title_id) notify_buf[0] = '\0'; - lfree(header); - lfree(inodes); + free(header); + free(inodes); close(pfs); - lfree(copy_buffer); + free(copy_buffer); return 0; } diff --git a/Store/source/unpkg.c b/Store/source/unpkg.c index 04c966a..0609f83 100644 --- a/Store/source/unpkg.c +++ b/Store/source/unpkg.c @@ -12,6 +12,7 @@ #include #include #include +#include #if defined (__ORBIS__) @@ -77,7 +78,7 @@ static inline int fgetcc(int fd) char *read_string(int fd) { - char *string = lmalloc(sizeof(char) * 256); + char *string = malloc(sizeof(char) * 256); int c; int length = 0; if (!string) return string; @@ -87,7 +88,7 @@ char *read_string(int fd) } string[length++] = '\0'; - return lrealloc(string, sizeof(char) * length); + return realloc(string, sizeof(char) * length); } static void _mkdir(const char *dir) @@ -115,7 +116,7 @@ static void _mkdir(const char *dir) char *get_entry_name_by_type(uint32_t type) { - char* entry_name = lmalloc(32); + char* entry_name = malloc(32); if ((type >= 0x1201) && (type <= 0x121F)) sprintf(entry_name, "icon0_%02u.png", type - 0x1201); @@ -142,7 +143,7 @@ char *get_entry_name_by_type(uint32_t type) sprintf(entry_name, "keymap_rp/%02u/%03u.png", (type - 0x1610) / 0x10, (type - 0x1610) % 0x10); else { - lfree(entry_name); + free(entry_name); entry_name = NULL; switch (type) { caseentry(0x0400, "license.dat"); @@ -229,7 +230,7 @@ int unpkg(char *pkgfn, char *tidpath) lseek(fdin, bswap_32(m_header.file_table_offset), SEEK_SET); log_info("PS4 PKG table entries:"); - struct cnt_pkg_table_entry *entries = lmalloc(sizeof(struct cnt_pkg_table_entry) * bswap_16(m_header.table_entries_num)); + struct cnt_pkg_table_entry *entries = malloc(sizeof(struct cnt_pkg_table_entry) * bswap_16(m_header.table_entries_num)); memset(entries, 0, sizeof(struct cnt_pkg_table_entry) * bswap_16(m_header.table_entries_num)); int i; for (i = 0; i < bswap_16(m_header.table_entries_num); i++) @@ -243,7 +244,7 @@ int unpkg(char *pkgfn, char *tidpath) } // Vars for file name listing. - struct file_entry *entry_files = lmalloc(sizeof(struct file_entry) * bswap_16(m_header.table_entries_num)); + struct file_entry *entry_files = malloc(sizeof(struct file_entry) * bswap_16(m_header.table_entries_num)); memset(entry_files, 0, sizeof(struct file_entry) * bswap_16(m_header.table_entries_num)); char *file_name_list[256]; int file_name_index = 0; @@ -308,7 +309,7 @@ int unpkg(char *pkgfn, char *tidpath) log_info("Dumping internal PKG files..."); for (i = 0; i < bswap_16(m_header.table_entries_num); i++) { - entry_file_data = (unsigned char *)lmalloc(entry_files[i].size); + entry_file_data = (unsigned char *)malloc(entry_files[i].size); lseek(fdin, entry_files[i].offset, SEEK_SET); read(fdin, entry_file_data, entry_files[i].size); @@ -336,9 +337,9 @@ int unpkg(char *pkgfn, char *tidpath) // Clean up. close(fdin); - lfree(entries); - lfree(entry_files); - lfree(entry_file_data); + free(entries); + free(entry_files); + free(entry_file_data); log_info("Done."); diff --git a/Store/source/utils.c b/Store/source/utils.c index 0f55c54..c8b369a 100644 --- a/Store/source/utils.c +++ b/Store/source/utils.c @@ -1,13 +1,25 @@ - +#include +#include #include "utils.h" #include #include #include +#include StoreOptions set, *get; -extern item_t* i_apps; // Installed_Apps + + +void* __stack_chk_guard = (void*)0xdeadbeef; + +void __stack_chk_fail(void) +{ + log_info("Stack smashing detected."); + msgok(FATAL, "Stack Smashing has been Detected"); +} + +extern item_t* all_apps; // Installed_Apps bool sceAppInst_done = false; int Lastlogcheck = 0; @@ -51,6 +63,22 @@ int copyFile(char* sourcefile, char* destfile) } } +int64_t sys_dynlib_load_prx(char* prxPath, int* moduleID) +{ + return (int64_t)syscall4(594, prxPath, 0, moduleID, 0); +} + +int64_t sys_dynlib_unload_prx(int64_t prxID) +{ + return (int64_t)syscall1(595, (void*)prxID); +} + + +int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void* destFuncOffset) +{ + return (int64_t)syscall3(591, (void*)moduleHandle, (void*)functionName, destFuncOffset); +} + void ProgSetMessagewText(int prog, const char* fmt, ...) { @@ -66,19 +94,26 @@ void ProgSetMessagewText(int prog, const char* fmt, ...) sceMsgDialogProgressBarSetMsg(0, buff); } +static bool touch_file(char* destfile) +{ + int fd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0777); + if (fd > 0) { + close(fd); + return true; + } + else + return false; +} + char* usbpath() { - int usb; static char usbbuf[100]; usbbuf[0] = '\0'; for(int x = 0; x <= 7; x++) { snprintf(usbbuf, sizeof(usbbuf), "/mnt/usb%i/.dirtest", x); - usb = sceKernelOpen(usbbuf, O_WRONLY | O_CREAT | O_TRUNC, 0777); - if(usb > 0) + if(touch_file(usbbuf)) { - sceKernelClose(usb); - snprintf(usbbuf, 100, "/mnt/usb%i", x); log_info("found usb = %s", usbbuf); @@ -117,6 +152,7 @@ int MD5_hash_compare(const char* file1, const char* hash) } log_info( "Input HASH: %s", hash); + fclose(f1); return SAME_HASH; } @@ -235,10 +271,8 @@ int LoadOptions(StoreOptions *set) if (!if_exists(buff)) { log_warn( "No INI on USB"); - if (sceKernelOpen("/user/app/NPXS39041/settings.ini", 0x0000, 0000) > 0) + if (if_exists("/user/app/NPXS39041/settings.ini")) snprintf(set->opt[INI_PATH], 255, "%s", "/user/app/NPXS39041/settings.ini"); - else - return -1; } else { pl_ini_load(&file, buff); log_info( "Loading ini from USB"); @@ -274,6 +308,8 @@ int LoadOptions(StoreOptions *set) // get an ints set->Legacy = pl_ini_get_int(&file, "Settings", "Legacy", 0); set->StoreOnUSB = pl_ini_get_int(&file, "Settings", "StoreOnUSB", 0); + set->HomeMenu_Redirection = pl_ini_get_int(&file, "Settings", "Home_Redirection", 0); + set->Daemon_on_start = pl_ini_get_int(&file, "Settings", "Daemon_on_start", 1); log_info( "set->opt[INI_PATH]: %s", set->opt[INI_PATH]); log_info( "set->opt[USB_PATH]: %s", set->opt[USB_PATH]); @@ -281,6 +317,8 @@ int LoadOptions(StoreOptions *set) log_info( "set->opt[TMP_PATH]: %s", set->opt[TMP_PATH]); log_info( "set->opt[CDN_URL ]: %s", set->opt[CDN_URL]); log_info( "set->legacy : %i", set->Legacy); + log_info( "set->Daemon_... : %s", set->Daemon_on_start ? "ON" : "OFF"); + log_info(" set->HomeMen... : %s", set->HomeMenu_Redirection ? "ItemzFlow (ON)" : "Orbis (OFF)"); log_info( "set->StoreOnUSB : %i", set->StoreOnUSB); /* Clean up */ @@ -326,12 +364,14 @@ int SaveOptions(StoreOptions *set) log_info( "set->opt[FNT_PATH]: %.20s...", set->opt[FNT_PATH]); log_info( "set->opt[CDN_URL ]: %s", set->opt[CDN_URL ]); log_info( "set->StoreOnUSB : %i", set->StoreOnUSB); + log_info( "set->HomeMen... : %s", set->HomeMenu_Redirection ? "ItemzFlow (ON)" : "Orbis (OFF)"); /* Load values */ pl_ini_set_string(&file, "Settings", "CDN", set->opt[CDN_URL ]); pl_ini_set_string(&file, "Settings", "temppath", set->opt[TMP_PATH]); pl_ini_set_string(&file, "Settings", "TTF_Font", set->opt[FNT_PATH]); pl_ini_set_int (&file, "Settings", "StoreOnUSB", set->StoreOnUSB); + pl_ini_set_int (&file, "Settings", "Home_Redirection", set->HomeMenu_Redirection); int ret = pl_ini_save(&file, set->opt[INI_PATH]); chmod(set->opt[INI_PATH], 0777); @@ -383,18 +423,22 @@ long CalcAppsize(char *path) fp = fopen(path, "r"); if (fp == NULL) return 0; - /// log_info("DEBUG: app fd = %s", path); - if (fseek(fp, 0, SEEK_END) == -1) return 0; + if (fseek(fp, 0, SEEK_END) == -1) goto cleanup; off = ftell(fp); - if (off == (long)-1) return 0; - - /// log_info("[*] fseek_filesize - file: %s, size: %ld", path, off); + if (off == (long)-1) goto cleanup; - if (fclose(fp) != 0) return 0; + if (fclose(fp) != 0) goto cleanup; if(off) { checkedsize = calculateSize(off); return off; } else { checkedsize = NULL; return 0; } + +cleanup: + if (fp != NULL) + fclose(fp); + + return 0; + } ////////////////////////////////////////////////////// @@ -421,12 +465,12 @@ void CheckLogSize() void die(char* message) { log_fatal( message); - sceSystemServiceLoadExec("invaild", 0); + sceSystemServiceLoadExec("INVALID", 0); } -int msgok(enum MSG_DIALOG level, char* format, ...) +void msgok(enum MSG_DIALOG level, char* format, ...) { - if(strlen(format) > 301) return 0x1337; + if(strlen(format) > 301) return; int ret = 0; sceSysmoduleLoadModule(ORBIS_SYSMODULE_MESSAGE_DIALOG); @@ -475,7 +519,7 @@ int msgok(enum MSG_DIALOG level, char* format, ...) param.userMsgParam = &userMsgParam; if (sceMsgDialogOpen(¶m) < 0) - log_fatal( "MsgD failed"); ret = -1; // this ret is outer if! + log_fatal( "MsgD failed"); @@ -491,7 +535,7 @@ int msgok(enum MSG_DIALOG level, char* format, ...) memset(&result, 0, sizeof(result)); if (0 > sceMsgDialogGetResult(&result)) - log_fatal( "MsgD failed"); ret = -2; + log_fatal( "MsgD failed"); sceMsgDialogTerminate(); break; @@ -509,12 +553,12 @@ int msgok(enum MSG_DIALOG level, char* format, ...) break; } - return ret; + return; } -int loadmsg(char* format, ...) +void loadmsg(char* format, ...) { - if(strlen(format) > 1024) return 0x1337; + if(strlen(format) > 1024) return; sceSysmoduleLoadModule(ORBIS_SYSMODULE_MESSAGE_DIALOG); @@ -552,12 +596,12 @@ int loadmsg(char* format, ...) while (1) { stat = sceMsgDialogUpdateStatus(); - if (stat == ORBIS_COMMON_DIALOG_STATUS_RUNNING) { - break; - } + if (stat == ORBIS_COMMON_DIALOG_STATUS_RUNNING) + break; + } - return 0; + return; } // @@ -661,7 +705,7 @@ int getjson(int Pagenumb, char* cdn, bool legacy) else { snprintf(http_req, 300, "%s/api.php?page=%i", cdn, Pagenumb); - if (open(destbuf, 0, 0) > 0) + if (if_exists(destbuf)) { log_info("page %i exists", Pagenumb); if (!check_store_from_url(Pagenumb, get->opt[CDN_URL], MD5_HASH)) @@ -769,13 +813,237 @@ void setup_store_assets(StoreOptions* get) log_info("This is the New PKG Assets are already on PS4"); } +bool IS_ERROR(uint32_t a1) +{ + return a1 & 0x80000000; +} + +// sceSystemServiceKillApp(); + + + +uint32_t Launch_App(char* TITLE_ID, bool silent) { + + uint32_t sys_res = -1; + + int libcmi = sceKernelLoadStartModule("/system/common/lib/libSceSystemService.sprx", 0, NULL, 0, 0, 0); + if (libcmi > 0) + { + log_info("Starting action Launch_Game_opt"); + + OrbisUserServiceLoginUserIdList userIdList; + + log_info("ret %x", sceUserServiceGetLoginUserIdList(&userIdList)); + + for (int i = 0; i < 4; i++) + { + if (userIdList.userId[i] != 0xFF) + { + log_info("[%i] User ID 0x%x", i, userIdList.userId[i]); + } + } + + + LncAppParam param; + param.sz = sizeof(LncAppParam); + + if (userIdList.userId[0] != 0xFF) + param.user_id = userIdList.userId[0]; + else if (userIdList.userId[1] != 0xFF) + param.user_id = userIdList.userId[1]; + + param.app_opt = 0; + param.crash_report = 0; + param.check_flag = SkipSystemUpdateCheck; + + log_info("l1 %x", sceLncUtilInitialize()); + + + sys_res = sceLncUtilLaunchApp(TITLE_ID, 0, ¶m); + if (IS_ERROR(sys_res)) + { + if (!silent) { + log_info("Switch 0x%x", sys_res); + switch (sys_res) { + case SCE_LNC_ERROR_APP_NOT_FOUND: { + msgok(WARNING, "App is NOT Found ref: SCE_LNC_ERROR_APP_NOT_FOUND"); + break; + } + case SCE_LNC_UTIL_ERROR_ALREADY_RUNNING: { + msgok(WARNING, "App is already running ref: SCE_LNC_UTIL_ERROR_ALREADY_RUNNING"); + break; + } + case SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_KILL_NEEDED: { + log_debug("ALREADY RUNNING KILL NEEDED"); + break; + } + case SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_SUSPEND_NEEDED: { + log_debug("ALREADY RUNNING SUSPEND NEEDED"); + break; + } + case SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX: { + msgok(WARNING, "App is NOT Launchable ref: SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX"); + break; + } + case SCE_LNC_UTIL_ERROR_INVALID_TITLE_ID: { + msgok(WARNING, "TITLE_ID IS NOT VAILED ref: SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX"); + break; + } + + default: { + msgok(WARNING, "App Launch has failed with error code: 0x%x", sys_res); + break; + } + } + } + } + + log_info("launch ret 0x%x", sys_res); + + } + else { + if(!silent) + msgok(WARNING, "Game Launch has failed with 0x%X", libcmi); + } + + return sys_res; +} + +extern struct retry_t* cf_tex; + +extern int total_pages; + void refresh_apps_for_cf(void) { - int before = i_apps[0].token_c; + +#if STANDALONE_APP==0 + int before = all_apps[0].token_c; loadmsg("Reloading the Installed Apps List ..."); log_debug("Reloading Installed Apps before: %i", before); - i_apps = index_items_from_dir("/user/app"); + if (all_apps) + free(all_apps); + all_apps = index_items_from_dir("/user/app", "/mnt/ext0/user/app"); + InitScene_5(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT); + InitScene_4(ATTR_ORBISGL_WIDTH, ATTR_ORBISGL_HEIGHT); + for (int i = 1; i < all_apps[0].token_c + 1; i++) { + check_tex_for_reload(i); + check_n_load_textures(i); + } + sceMsgDialogTerminate(); - log_debug("Done reloading # of App: %i, # of Apps added/removed: %i", i_apps[0].token_c, i_apps[0].token_c - before); + log_debug("Done reloading # of App: %i, # of Apps added/removed: %i", all_apps[0].token_c, all_apps[0].token_c - before); + +#else + +char page_buf[100]; +snprintf(page_buf, sizeof(total_pages), "%i", total_pages); +char* new_argv[11] = { "--reload_games", page_buf }; + +log_info("reloading the App"); +unlink("/data/self/eboot.bin"); +copyFile("/user/app/NPXS39041/homebrew.elf", "/data/self/eboot.bin"); +sceSystemServiceLoadExec("/data/self/eboot.bin", &new_argv); + +#endif + + + +} + + +void build_iovec(struct iovec** iov, int* iovlen, const char* name, const void* val, size_t len) { + int i; + + if (*iovlen < 0) + return; + + i = *iovlen; + *iov = (struct iovec*)realloc((void*)(*iov), sizeof(struct iovec) * (i + 2)); + if (*iov == NULL) { + *iovlen = -1; + return; + } + + (*iov)[i].iov_base = strdup(name); + (*iov)[i].iov_len = strlen(name) + 1; + ++i; + + (*iov)[i].iov_base = (void*)val; + if (len == (size_t)-1) { + if (val != NULL) + len = strlen((const char*)val) + 1; + else + len = 0; + } + (*iov)[i].iov_len = (int)len; + + *iovlen = ++i; +} + + +int mountfs(const char* device, const char* mountpoint, const char* fstype, const char* mode, uint64_t flags) +{ + struct iovec* iov = NULL; + int iovlen = 0; + int ret; + + build_iovec(&iov, &iovlen, "fstype", fstype, -1); + build_iovec(&iov, &iovlen, "fspath", mountpoint, -1); + build_iovec(&iov, &iovlen, "from", device, -1); + build_iovec(&iov, &iovlen, "large", "yes", -1); + build_iovec(&iov, &iovlen, "timezone", "static", -1); + build_iovec(&iov, &iovlen, "async", "", -1); + build_iovec(&iov, &iovlen, "ignoreacl", "", -1); + + if (mode) { + build_iovec(&iov, &iovlen, "dirmask", mode, -1); + build_iovec(&iov, &iovlen, "mask", mode, -1); + } + + log_info("##^ [I] Mounting %s \"%s\" to \"%s\" \n", fstype, device, mountpoint); + ret = nmount(iov, iovlen, flags); + if (ret < 0) { + log_info("##^ [E] Failed: %d (errno: %d).\n", ret, errno); + goto error; + } + else { + log_info("##^ [I] Success.\n"); + } + +error: + return ret; } + +#define SCE_LIBC_MALLOC_MANAGED_SIZE_VERSION (0x0001U) + +#ifndef SCE_LIBC_INIT_MALLOC_MANAGED_SIZE +#define SCE_LIBC_INIT_MALLOC_MANAGED_SIZE(mmsize) do { \ + mmsize.size = sizeof(mmsize); \ + mmsize.version = SCE_LIBC_MALLOC_MANAGED_SIZE_VERSION; \ + mmsize.reserved1 = 0; \ + mmsize.maxSystemSize = 0; \ + mmsize.currentSystemSize = 0; \ + mmsize.maxInuseSize = 0; \ + mmsize.currentInuseSize = 0; \ +} while (0) +#endif + +typedef struct SceLibcMallocManagedSize { + uint16_t size; + uint16_t version; + uint32_t reserved1; + size_t maxSystemSize; + size_t currentSystemSize; + size_t maxInuseSize; + size_t currentInuseSize; +} SceLibcMallocManagedSize; + +void print_memory() +{ + SceLibcMallocManagedSize ManagedSize; + SCE_LIBC_INIT_MALLOC_MANAGED_SIZE(ManagedSize); + malloc_stats_fast(&ManagedSize); + + log_info("PS4 Memory Stats: CurrentSystemSize: %s, CurrentInUseSize: %s, MaxSystemSize: %s, MaxInUseSize: %s", calculateSize(ManagedSize.currentSystemSize), calculateSize(ManagedSize.currentInuseSize), calculateSize(ManagedSize.maxSystemSize), calculateSize(ManagedSize.maxInuseSize)); +} \ No newline at end of file diff --git a/itemz-daemon/Makefile b/itemz-daemon/Makefile new file mode 100644 index 0000000..ebeb402 --- /dev/null +++ b/itemz-daemon/Makefile @@ -0,0 +1,27 @@ +ifndef ORBISDEV +$(error ORBISDEV, is not set) +endif + +target ?= ps4_elf_sce +TargetFile=daemon.elf + +include $(ORBISDEV)/make/ps4sdk.mk + +LinkerFlags += -lkernel_stub -lSceLibcInternal_stub -lSceSysmodule_stub -lSceSystemService_stub -lSceNet_stub -lSceUserService_stub -lScePigletv2VSH_stub -lSceVideoOut_stub -lSceImeDialog_stub -lSceGnmDriver_stub -lorbis -lorbisGl -lScePad_stub -lSceCommonDialog_stub -lSceMsgDialog_stub -lSceAudioOut_stub -lSceIme_stub -lSceAppInstUtil_stub -lSceBgft_stub -lSceSysUtil_stub -lSceHttp_stub -lSceSsl_stub -lSceNetCtl_stub -lfreetype-gl -lSceFreeTypeOl_stub -lkernel_sys_stub -lSceLncUtil_stub + +CompilerFlags += -D__PS4__ -D__ORBIS__ -fstack-protector-all + +IncludePath += -I$(ORBISDEV)/usr/include -I$(ORBISDEV)/usr/include/c++/v1 -I$(ORBISDEV)/usr/include/orbis +IncludePath += -I$(ORBISDEV)/usr/include/orbis/freetype-gl + + +oelf: + orbis-elf-create bin/daemon.elf bin/daemon.oelf >/dev/null 2>&1 + + +AUTH_INFO = 000000000000000000000000001C004000FF000000000080000000000000000000000000000000000000008000400040000000000000008000000000000000080040FFFF000000F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + +eboot: + python2 $(ORBISDEV)/bin/make_fself.py --auth-info $(AUTH_INFO) bin/daemon.oelf bin/eboot.bin +pkg_build: + cp bin/eboot.bin pkg/eboot.bin && cd pkg && pkgTool pkg_build Project.gp4 . && cp *.pkg ../bin/ diff --git a/itemz-daemon/include/defines.h b/itemz-daemon/include/defines.h new file mode 100644 index 0000000..edcbf2a --- /dev/null +++ b/itemz-daemon/include/defines.h @@ -0,0 +1,183 @@ +#pragma once + +/* + ES2_goodness, a GLES2 playground on EGL + + 2019-2021 masterzorag & LM + + here follows the parts: +*/ + +// nfs or local stdio +//#define USE_NFS (1) +#if defined (USE_NFS) +#include +#endif + +// common +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "log.h" +#include //sceKernelIccSetBuzzer + +#define HOME_TITLE_ID "NPXS39041" +#define PS_BUTTON 0x10000 +#define SCE_LNC_UTIL_ERROR_ALREADY_RUNNING 0x8094000c +#define SCE_SYSMODULE_INTERNAL_COMMON_DIALOG 0x80000018 +#define SCE_SYSMODULE_INTERNAL_SYSUTIL 0x80000018 +#define SCE_LNC_ERROR_APP_NOT_FOUND 0x80940031 // Usually happens if you to launch an app not in app.db +#define SCE_LNC_UTIL_ERROR_ALREADY_INITIALIZED 0x80940018 +#define SCE_LNC_UTIL_ERROR_ALREADY_RUNNING 0x8094000c +#define SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_KILL_NEEDED 0x80940010 +#define SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_SUSPEND_NEEDED 0x80940011 +#define SCE_LNC_UTIL_ERROR_APP_ALREADY_RESUMED 0x8094001e +#define SCE_LNC_UTIL_ERROR_APP_ALREADY_SUSPENDED 0x8094001d +#define SCE_LNC_UTIL_ERROR_APP_NOT_IN_BACKGROUND 0x80940015 +#define SCE_LNC_UTIL_ERROR_APPHOME_EBOOTBIN_NOT_FOUND 0x80940008 +#define SCE_LNC_UTIL_ERROR_APPHOME_PARAMSFO_NOT_FOUND 0x80940009 +#define SCE_LNC_UTIL_ERROR_CANNOT_RESUME_INITIAL_USER_NEEDED 0x80940012 +#define SCE_LNC_UTIL_ERROR_DEVKIT_EXPIRED 0x8094000b +#define SCE_LNC_UTIL_ERROR_IN_LOGOUT_PROCESSING 0x8094001a +#define SCE_LNC_UTIL_ERROR_IN_SPECIAL_RESUME 0x8094001b +#define SCE_LNC_UTIL_ERROR_INVALID_PARAM 0x80940005 +#define SCE_LNC_UTIL_ERROR_INVALID_STATE 0x80940019 +#define SCE_LNC_UTIL_ERROR_INVALID_TITLE_ID 0x8094001c +#define SCE_LNC_UTIL_ERROR_LAUNCH_DISABLED_BY_MEMORY_MODE 0x8094000d +#define SCE_LNC_UTIL_ERROR_NO_APP_INFO 0x80940004 +#define SCE_LNC_UTIL_ERROR_NO_LOGIN_USER 0x8094000a +#define SCE_LNC_UTIL_ERROR_NO_SESSION_MEMORY 0x80940002 +#define SCE_LNC_UTIL_ERROR_NO_SFOKEY_IN_APP_INFO 0x80940014 +#define SCE_LNC_UTIL_ERROR_NO_SHELL_UI 0x8094000e +#define SCE_LNC_UTIL_ERROR_NOT_ALLOWED 0x8094000f +#define SCE_LNC_UTIL_ERROR_NOT_INITIALIZED 0x80940001 +#define SCE_LNC_UTIL_ERROR_OPTICAL_DISC_DRIVE 0x80940013 +#define SCE_LNC_UTIL_ERROR_SETUP_FS_SANDBOX 0x80940006 +#define SCE_LNC_UTIL_ERROR_SUSPEND_BLOCK_TIMEOUT 0x80940017 +#define SCE_LNC_UTIL_ERROR_VIDEOOUT_NOT_SUPPORTED 0x80940016 +#define SCE_LNC_UTIL_ERROR_WAITING_READY_FOR_SUSPEND_TIMEOUT 0x80940021 +#define SCE_SYSCORE_ERROR_LNC_INVALID_STATE 0x80aa000a +#define SCE_LNC_UTIL_ERROR_NOT_INITIALIZED 0x80940001 +#define SCE_SYSMODULE_INTERNAL_SYS_CORE 0x80000004 +#define SCE_SYSMODULE_INTERNAL_NETCTL 0x80000009 +#define SCE_SYSMODULE_INTERNAL_HTTP 0x8000000A +#define SCE_SYSMODULE_INTERNAL_SSL 0x8000000B +#define SCE_SYSMODULE_INTERNAL_NP_COMMON 0x8000000C +#define SCE_SYSMODULE_INTERNAL_SYSTEM_SERVICE 0x80000010 +#define SCE_SYSMODULE_INTERNAL_USER_SERVICE 0x80000011 +#define SCE_SYSMODULE_INTERNAL_APPINSTUTIL 0x80000014 +#define SCE_SYSMODULE_INTERNAL_NET 0x8000001C +#define SCE_SYSMODULE_INTERNAL_IPMI 0x8000001D +#define SCE_SYSMODULE_INTERNAL_VIDEO_OUT 0x80000022 +#define SCE_SYSMODULE_INTERNAL_BGFT 0x8000002A +#define SCE_SYSMODULE_INTERNAL_PRECOMPILED_SHADERS 0x80000064 + + +#define VERSION_MAJOR 1 +#define VERSION_MINOR 00 + +#define BUILD_YEAR_CH0 (__DATE__[ 7]) +#define BUILD_YEAR_CH1 (__DATE__[ 8]) +#define BUILD_YEAR_CH2 (__DATE__[ 9]) +#define BUILD_YEAR_CH3 (__DATE__[10]) + + +#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n') +#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F') +#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r') +#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p') +#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y') +#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n') +#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l') +#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u') +#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S') +#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O') +#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N') +#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D') + + +#define BUILD_MONTH_CH0 \ + ((BUILD_MONTH_IS_OCT || BUILD_MONTH_IS_NOV || BUILD_MONTH_IS_DEC) ? '1' : '0') + +#define BUILD_MONTH_CH1 \ + ( \ + (BUILD_MONTH_IS_JAN) ? '1' : \ + (BUILD_MONTH_IS_FEB) ? '2' : \ + (BUILD_MONTH_IS_MAR) ? '3' : \ + (BUILD_MONTH_IS_APR) ? '4' : \ + (BUILD_MONTH_IS_MAY) ? '5' : \ + (BUILD_MONTH_IS_JUN) ? '6' : \ + (BUILD_MONTH_IS_JUL) ? '7' : \ + (BUILD_MONTH_IS_AUG) ? '8' : \ + (BUILD_MONTH_IS_SEP) ? '9' : \ + (BUILD_MONTH_IS_OCT) ? '0' : \ + (BUILD_MONTH_IS_NOV) ? '1' : \ + (BUILD_MONTH_IS_DEC) ? '2' : \ + /* error default */ '?' \ + ) + +#define BUILD_DAY_CH0 ((__DATE__[4] >= '0') ? (__DATE__[4]) : '0') +#define BUILD_DAY_CH1 (__DATE__[ 5]) + + + +// Example of __TIME__ string: "21:06:19" +// 01234567 + +#define BUILD_HOUR_CH0 (__TIME__[0]) +#define BUILD_HOUR_CH1 (__TIME__[1]) + +#define BUILD_MIN_CH0 (__TIME__[3]) +#define BUILD_MIN_CH1 (__TIME__[4]) + +#define BUILD_SEC_CH0 (__TIME__[6]) +#define BUILD_SEC_CH1 (__TIME__[7]) + + +#if VERSION_MAJOR > 100 + +#define VERSION_MAJOR_INIT \ + ((VERSION_MAJOR / 100) + '0'), \ + (((VERSION_MAJOR % 100) / 10) + '0'), \ + ((VERSION_MAJOR % 10) + '0') + +#elif VERSION_MAJOR > 10 + +#define VERSION_MAJOR_INIT \ + ((VERSION_MAJOR / 10) + '0'), \ + ((VERSION_MAJOR % 10) + '0') + +#else + +#define VERSION_MAJOR_INIT \ + (VERSION_MAJOR + '0') + +#endif + +#if VERSION_MINOR > 100 + +#define VERSION_MINOR_INIT \ + ((VERSION_MINOR / 100) + '0'), \ + (((VERSION_MINOR % 100) / 10) + '0'), \ + ((VERSION_MINOR % 10) + '0') + +#elif VERSION_MINOR > 10 + +#define VERSION_MINOR_INIT \ + ((VERSION_MINOR / 10) + '0'), \ + ((VERSION_MINOR % 10) + '0') + +#else + +#define VERSION_MINOR_INIT \ + (VERSION_MINOR + '0') +#endif diff --git a/itemz-daemon/include/log.h b/itemz-daemon/include/log.h new file mode 100644 index 0000000..99d9e52 --- /dev/null +++ b/itemz-daemon/include/log.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2020 rxi + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the MIT license. See `log.c` for details. + */ + +#ifndef LOG_H +#define LOG_H + +#include +#include +#include +#include + +#define LOG_VERSION "0.1.0" + +typedef struct { + va_list ap; + const char* fmt; + const char* file; + struct tm* time; + void* udata; + int line; + int level; +} log_Event; + +typedef void (*log_LogFn)(log_Event* ev); +typedef void (*log_LockFn)(bool lock, void* udata); + +enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL }; + +#define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__) +#define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__) +#define log_info(...) log_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__) +#define log_warn(...) log_log(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__) +#define log_error(...) log_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__) +#define log_fatal(...) log_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__) + +const char* log_level_string(int level); +void log_set_lock(log_LockFn fn, void* udata); +void log_set_level(int level); +void log_set_quiet(bool enable); +int log_add_callback(log_LogFn fn, void* udata, int level); +int log_add_fp(FILE* fp, int level); + +void log_log(int level, const char* file, int line, const char* fmt, ...); + +#endif \ No newline at end of file diff --git a/itemz-daemon/include/utils.h b/itemz-daemon/include/utils.h new file mode 100644 index 0000000..9813acc --- /dev/null +++ b/itemz-daemon/include/utils.h @@ -0,0 +1,98 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include "defines.h" +#include "log.h" + +#define DIM(x) (sizeof(x)/sizeof(*(x))) +#define KB(x) ((size_t) (x) << 10) +#define MB(x) ((size_t) (x) << 20) + +#define DAEMON_LOG_PS4 "/data/itemzflow_daemon/log.txt" +#define DAEMON_LOG_USB "/mnt/usb0/itemzflow/log.txt" +bool touch_file(char* destfile); +enum IPC_Errors +{ + INVALID = -1, + NO_ERROR = 0, + OPERATION_FAILED = 1 +}; + +enum cmd +{ + CONNECTION_TEST = 1, + ENABLE_HOME_REDIRECT = 2, + DISABLE_HOME_REDIRECT = 3, + DEAMON_UPDATE = 100 +}; + + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + + +struct clientArgs { + char* ip; + int socket; + int cl_nmb; +}; + +enum Flag +{ + Flag_None = 0, + SkipLaunchCheck = 1, + SkipResumeCheck = 1, + SkipSystemUpdateCheck = 2, + RebootPatchInstall = 4, + VRMode = 8, + NonVRMode = 16 +}; + +typedef struct _LncAppParam +{ + uint32_t sz; + uint32_t user_id; + uint32_t app_opt; + uint64_t crash_report; + enum Flag check_flag; +} +LncAppParam; + +typedef struct OrbisUserServiceLoginUserIdList { + int32_t userId[4]; +} OrbisUserServiceLoginUserIdList; + +typedef struct OrbisUserServiceInitializeParams { + int32_t priority; +} OrbisUserServiceInitializeParams; + + +int64_t sys_dynlib_load_prx(char* prxPath, int* moduleID); +int64_t sys_dynlib_unload_prx(int64_t prxID); +int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void* destFuncOffset); + +bool rejail(); +bool jailbreak(const char* prx_path); +bool full_init(); +bool isRestMode(); +bool IsOn(); +void notify(char* message); + +extern int DaemonSocket; + +#define networkSendMessage(socket, format, ...)\ +do {\ + char msgBuffer[512];\ + int msgSize = sprintf(msgBuffer, format, ##__VA_ARGS__);\ + sceNetSend(socket, msgBuffer, msgSize, 0);\ +} while(0) + +void handleIPC(struct clientArgs* client, uint8_t* buffer, uint32_t length); +void* network_loop(); +void* ipc_client(void* args); \ No newline at end of file diff --git a/itemz-daemon/source/asm.s b/itemz-daemon/source/asm.s new file mode 100644 index 0000000..78cd9d5 --- /dev/null +++ b/itemz-daemon/source/asm.s @@ -0,0 +1,105 @@ +.intel_syntax noprefix +.text + +.global kernelRdmsr +.global cpu_enable_wp +.global cpu_disable_wp +.global call_not_RESOLVED_Exception + +kernelRdmsr: + mov ecx, edi + rdmsr + shl rdx, 32 + or rax, rdx + ret + +cpu_enable_wp: + mov rax, cr0 + or rax, 0x10000 + mov cr0, rax + ret + +cpu_disable_wp: + mov rax, cr0 + and rax, ~0x10000 + mov cr0, rax + ret + + .intel_syntax noprefix +.text + +.global syscall, syscall1, syscall2, syscall3, syscall4 ,Sysctl, Fork + + +Fork: + push rbp + mov rbp,rsp + + mov rax,2 + syscall + + leave + ret + +Sysctl: + push rbp + mov rbp,rsp + + mov rax,202 + mov r10, rcx + syscall + + leave + ret + + + +syscall: + mov rax,0 + mov r10,rcx + syscall + jb err + ret + +syscall1: + mov rax,rdi + mov rdi,rsi + syscall + ret + +syscall2: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + syscall + ret + +syscall3: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + mov rdx,rcx + syscall + ret + +syscall4: + mov rax,rdi + mov rdi,rsi + mov rsi,rdx + mov rdx,rcx + mov r10,r8 + syscall + ret + + +err: + push rax + call __error + pop rcx + mov [rax], ecx + mov rax,-1 + mov rdx,-1 + ret + + + diff --git a/itemz-daemon/source/log.c b/itemz-daemon/source/log.c new file mode 100644 index 0000000..07978c9 --- /dev/null +++ b/itemz-daemon/source/log.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2020 rxi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "log.h" + +#define MAX_CALLBACKS 32 + +typedef struct { + log_LogFn fn; + void* udata; + int level; +} Callback; + +static struct { + void* udata; + log_LockFn lock; + int level; + bool quiet; + Callback callbacks[MAX_CALLBACKS]; +} L; + + +static const char* level_strings[] = { + "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" +}; + +#ifdef LOG_USE_COLOR +static const char* level_colors[] = { + "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m" +}; +#endif + +#define __ORBIS__ 1 + +#ifdef __ORBIS__ +#define DGB_CHANNEL_TTYL 0 +int sceKernelDebugOutText(int DBG_CHANNEL, const char *text); +#endif + +static void stdout_callback(log_Event* ev) { + char buf[16]; + char format_buf[400]; + char *print_buf[400]; + buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0'; + + vsnprintf(format_buf, 399, ev->fmt, ev->ap); + + snprintf(print_buf, 399, "%s %-5s %s:%d: %s\n", buf, level_strings[ev->level], ev->file, ev->line, format_buf); + +#ifdef __ORBIS__ + sceKernelDebugOutText(DGB_CHANNEL_TTYL, print_buf); +#else + log_info("%s\n" print_buf); +#endif +} + + +static void file_callback(log_Event* ev) { + char buf[64]; + buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0'; + fprintf( + ev->udata, "%s %-5s %s:%d: ", + buf, level_strings[ev->level], ev->file, ev->line); + vfprintf(ev->udata, ev->fmt, ev->ap); + fprintf(ev->udata, "\n"); + fflush(ev->udata); +} + + +static void lock(void) { + if (L.lock) { L.lock(true, L.udata); } +} + + +static void unlock(void) { + if (L.lock) { L.lock(false, L.udata); } +} + + +const char* log_level_string(int level) { + return level_strings[level]; +} + + +void log_set_lock(log_LockFn fn, void* udata) { + L.lock = fn; + L.udata = udata; +} + + +void log_set_level(int level) { + L.level = level; +} + + +void log_set_quiet(bool enable) { + L.quiet = enable; +} + + +int log_add_callback(log_LogFn fn, void* udata, int level) { + for (int i = 0; i < MAX_CALLBACKS; i++) { + if (!L.callbacks[i].fn) { + L.callbacks[i] = (Callback){ fn, udata, level }; + return 0; + } + } + return -1; +} + + +int log_add_fp(FILE* fp, int level) { + return log_add_callback(file_callback, fp, level); +} + + +static void init_event(log_Event* ev, void* udata) { + if (!ev->time) { + time_t t = time(NULL); + ev->time = localtime(&t); + } + ev->udata = udata; +} + + +void log_log(int level, const char* file, int line, const char* fmt, ...) { + log_Event ev = { + .fmt = fmt, + .file = file, + .line = line, + .level = level, + }; + + lock(); + + if (!L.quiet && level >= L.level) { + init_event(&ev, stderr); + va_start(ev.ap, fmt); + stdout_callback(&ev); + va_end(ev.ap); + } + + for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) { + Callback* cb = &L.callbacks[i]; + if (level >= cb->level) { + init_event(&ev, cb->udata); + va_start(ev.ap, fmt); + cb->fn(&ev); + va_end(ev.ap); + } + } + + unlock(); +} \ No newline at end of file diff --git a/itemz-daemon/source/main.c b/itemz-daemon/source/main.c new file mode 100644 index 0000000..5e84766 --- /dev/null +++ b/itemz-daemon/source/main.c @@ -0,0 +1,144 @@ +#include "defines.h" +#include +#include +#include "log.h" +#include +#include +#include +#include +#include +#include +#include + +bool IS_ERROR(uint32_t a1) +{ + return a1 & 0x80000000; +} + +bool is_enabled = false; +void PS_Button_loop() +{ + OrbisUserServiceInitializeParams params; + memset(¶ms, 0, sizeof(params)); + params.priority = 256; + + log_info("[Daemon] sceUserServiceInitialize %x", sceUserServiceInitialize(¶ms)); + + OrbisUserServiceLoginUserIdList userIdList; + + log_info("[Daemon] sceUserServiceGetLoginUserIdList %x", sceUserServiceGetLoginUserIdList(&userIdList)); + + for (int i = 0; i < 4; i++) { + if (userIdList.userId[i] != -1) { + log_info("[Daemon][%i] User ID 0x%x", i, userIdList.userId[i]); + } + } + + int ret = scePadInit(); + if (ret < 0) + log_info("[Daemon] %s scePadInit return error 0x%8x", __FUNCTION__, ret); + + + log_info("[Daemon] scePadSetProcessPrivilege %x", scePadSetProcessPrivilege(1)); + + + int pad = scePadOpen(userIdList.userId[0], 0, 0, NULL); + if (pad < 0) + log_info("[Daemon] %s scePadOpen return error 0x%8x", __FUNCTION__, pad); + else + log_info("[Daemon] Opened Pad"); + + + ScePadData data; + + log_info("[Daemon] l1 %x", sceLncUtilInitialize()); + + + log_info("[Daemon] Main Loop Started"); + int i = 0; + + while(pad > 0) + { + if (!isRestMode() && is_enabled) + { + //get sample size + scePadReadState(pad, &data); + + if (data.buttons & PS_BUTTON) {//PS_BUTTON from RE + + log_info("[Daemon] PS BUTTON Was Pressed & intercepted"); + log_info("[Daemon] Redirecting Home Menu to ITEMzFlow"); + + LncAppParam param; + param.sz = sizeof(LncAppParam); + + if (userIdList.userId[0] != 0xFF) + param.user_id = userIdList.userId[0]; + else if (userIdList.userId[1] != 0xFF) + param.user_id = userIdList.userId[1]; + + param.app_opt = 0; + param.crash_report = 0; + param.check_flag = SkipSystemUpdateCheck; + log_info("[Daemon] Home menu Boot Option SkipSystemUpdateCheck Applied"); + + uint32_t sys_res = sceLncUtilLaunchApp(HOME_TITLE_ID, 0, ¶m); + if (IS_ERROR(sys_res)) { + if (sys_res == SCE_LNC_UTIL_ERROR_ALREADY_RUNNING || sys_res == SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_SUSPEND_NEEDED || sys_res == SCE_LNC_UTIL_ERROR_ALREADY_RUNNING_KILL_NEEDED) { + log_info("[Daemon] ITEMzFlow Already running, resuming App...."); + log_info("[Daemon] Redirect Successful"); + } + else + log_info("[Daemon] NPXS39041 launch ret 0x%x", sys_res); + } + else + log_info("[Daemon] Redirect Successful"); + + } + } + + + usleep(15000); + + } +} + +#define VERSION_MAJOR 1 +#define VERSION_MINOR 01 + + + +int main(int argc, char* argv[]) +{ + ScePthread thread; + // internals: net, user_service, system_service + loadModulesVanilla(); + + if (!jailbreak("/app0/Media/jb.prx")) goto exit; + + if(!full_init()) goto exit; + + log_info("[Daemon] Registering Daemon..."); + + sceSystemServiceRegisterDaemon(); + + log_info("[Daemon] Starting Network loop Thread..."); + + scePthreadCreate(&thread, NULL, network_loop, NULL, "network_loop_thread"); + + log_info("[Daemon] Starting main PS Button loop..."); + + PS_Button_loop(); + + log_info("[Daemon] WTF the Loop eneded???"); + + +exit: + log_info("[Daemon] Exiting"); + + if (!rejail()) + log_info("[Daemon] rejail failed"); + + sceKernelIccSetBuzzer(2); + return sceSystemServiceLoadExec("exit", 0); +} \ No newline at end of file diff --git a/itemz-daemon/source/net.c b/itemz-daemon/source/net.c new file mode 100644 index 0000000..ca99826 --- /dev/null +++ b/itemz-daemon/source/net.c @@ -0,0 +1,152 @@ +#include "defines.h" +#include +#include +#include "log.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define INVAIL -1 +#define IPC_SOC "/system_tmp/IPC_Socket" +int DaemonSocket = NULL; + +struct sockaddr_in networkAdress(uint16_t port) +{ + struct sockaddr_in address; + address.sin_len = sizeof(address); + address.sin_family = AF_INET; + address.sin_port = sceNetHtons(port); + memset(address.sin_zero, 0, sizeof(address.sin_zero)); + return address; +} + +int networkListen(const char* name, uint16_t port) +{ + struct sockaddr_un server; + + int s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) + { + log_info("[Daemon] Socket failed! %s", strerror(errno)); + return INVAIL; + } + + memset(&server, 0, sizeof(server)); + server.sun_family = AF_UNIX; + strcpy(server.sun_path, IPC_SOC); + + int r = bind(s, (struct sockaddr*)&server, SUN_LEN(&server)); + if (r < 0) + { + log_info("[Daemon] Bind failed! %s", strerror(errno)); + return INVAIL; + } + + log_info("Socket has name %s", server.sun_path); + + r = listen(s, 100); + if (r < 0) + { + log_info("[Daemon] listen failed! %s", strerror(errno)); + return INVAIL; + } + + return s; +} + +int networkAccept(int socket) +{ + touch_file("/system_tmp/IPC_init"); + return accept(socket, 0, 0); +} + + +int networkReceiveData(int socket, uint8_t* buffer, int32_t size) +{ + return recv(socket, buffer, size, 0); +} + +int networkSendData(int socket, uint8_t* buffer, int32_t size) +{ + return send(socket, buffer, size, MSG_NOSIGNAL); +} + +int networkSendDebugData(uint8_t* buffer, int32_t size) +{ + return networkSendData(DaemonSocket, buffer, size); +} + +int networkCloseConnection(int socket) +{ + return close(socket); +} + +int networkCloseDebugConnection() +{ + return networkCloseConnection(DaemonSocket); +} + +bool touch_file(char* destfile) +{ + int fd = open(destfile, O_WRONLY | O_CREAT | O_TRUNC, 0777); + if (fd > 0) { + close(fd); + return true; + } + else + return false; +} + +void *network_loop() +{ + // Listen on port + int serverSocket = networkListen("IPC_SERVER", 420); + if (serverSocket < 0) + { + log_debug("[Daemon IPC] networkListen error 0x%x", serverSocket); + return NULL; + } + + + // Keep accepting client connections + int cli_new = 0; + while (true) + { + // Accept a client connection + int clientSocket = networkAccept(serverSocket); + if (clientSocket < 0) + { + log_debug("[Daemon IPC] networkAccept error 0x%x", clientSocket); + goto clean; + } + + log_debug("[Daemon IPC] Connection Accepted"); + + + log_info("[Daemon IPC] cl_nmb %i", cli_new); + // Build data to send to thread + struct clientArgs* clientParams = (struct clientArgs*)malloc(sizeof(struct clientArgs)); + clientParams->ip = "localhost"; + clientParams->socket = clientSocket; + clientParams->cl_nmb = cli_new; + + log_info("[Daemon IPC] clientParams->cl_nmb %i", clientParams->cl_nmb); + + // Handle client on a thread + ScePthread thread; + scePthreadCreate(&thread, NULL, ipc_client, (void*)clientParams, "IPC_SERVER_THREAD"); + cli_new++; + } + + clean: + // Close Server Socket + networkCloseConnection(serverSocket); + scePthreadExit(NULL); + return NULL; +} diff --git a/itemz-daemon/source/rpc.c b/itemz-daemon/source/rpc.c new file mode 100644 index 0000000..ae0d0d6 --- /dev/null +++ b/itemz-daemon/source/rpc.c @@ -0,0 +1,118 @@ +#include "defines.h" +#include +#include +#include "log.h" +#include +#include +#include +#include +#include +#include +#include + +uint8_t CONNECT_TEST(struct clientArgs* client, uint8_t** mode, uint32_t* length) +{ + // Re-allocate memory + *mode = realloc(*mode, 99); + + sprintf((char*)(*mode), "Connected\0"); + *length = strlen((char*)(*mode)); + + return NO_ERROR; +} + +extern bool is_enabled; + + +void handleIPC(struct clientArgs* client, uint8_t* buffer, uint32_t length) +{ + uint8_t error = NO_ERROR; + uint8_t* outputBuffer = malloc(sizeof(uint8_t*)); + uint32_t outputLength = 0; + + + uint8_t method = buffer[0]; + switch (method) + { + + case CONNECTION_TEST: { + log_info("[Daemon IPC][client %i] command CONNECTION_TEST() called", client->cl_nmb); + error = CONNECT_TEST(client, &outputBuffer, &outputLength); + break; + } + case DISABLE_HOME_REDIRECT: { + log_info("[Daemon IPC][client %i] command DISABLE_HOME_REDIRECT() called", client->cl_nmb); + is_enabled = false; + error = NO_ERROR; + break; + } + case ENABLE_HOME_REDIRECT: { + log_info("[Daemon IPC][client %i] command ENABLE_HOME_REDIRECT() called", client->cl_nmb); + is_enabled = true; + error = NO_ERROR; + break; + } + case DEAMON_UPDATE: { + log_info("[Daemon IPC][client %i] command DEAMON_UPDATE() called", client->cl_nmb); + unlink("/system_tmp/IPC_init"); + unlink("/system_tmp/IPC_Socket"); + log_info("[Daemon IPC][client %i] Reloading Daemon ...", client->cl_nmb); + sceSystemServiceLoadExec("/app0/eboot.bin", 0); + error = NO_ERROR; + break; + } + + default:{ + log_info("[Daemon IPC][client %i] command %i called", client->cl_nmb, buffer[0]); + error = INVALID; + break; + } + + + } + + + uint8_t* outputBufferFull = malloc(outputLength + 1); + + outputBufferFull[0] = error; // First byte is always error byte + + memcpy(&outputBufferFull[1], outputBuffer, outputLength); + + + // Send response + networkSendData(client->socket, outputBufferFull, outputLength + 1); + + + // Free allocated memory + free(outputBuffer); + outputBuffer = NULL; + free(outputBufferFull); + outputBufferFull = NULL; +} + +void* ipc_client(void* args) +{ + struct clientArgs* cArgs = (struct clientArgs*)args; + + + log_debug("[Daemon IPC] Thread created, Socket %i", cArgs->socket); + + + uint32_t readSize = 0; + uint8_t buffer[512]; + while ((readSize = networkReceiveData(cArgs->socket, buffer, 512)) > 0) + { + // Handle buffer + handleIPC(cArgs, buffer, readSize); + memset(buffer, 0, 512); + } + + + log_debug("[Daemon IPC][client %i] IPC Connection disconnected, Shutting down ...", cArgs->cl_nmb); + + + networkCloseConnection(cArgs->socket); + scePthreadExit(NULL); + free(args); + return NULL; +} diff --git a/itemz-daemon/source/utils.c b/itemz-daemon/source/utils.c new file mode 100644 index 0000000..f0e723e --- /dev/null +++ b/itemz-daemon/source/utils.c @@ -0,0 +1,246 @@ +#include "defines.h" +#include +#include +#include "log.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const unsigned char completeVersion[] = { + VERSION_MAJOR_INIT, + '.', + VERSION_MINOR_INIT, + '-', + 'V', + '-', + BUILD_YEAR_CH0, + BUILD_YEAR_CH1, + BUILD_YEAR_CH2, + BUILD_YEAR_CH3, + '-', + BUILD_MONTH_CH0, + BUILD_MONTH_CH1, + '-', + BUILD_DAY_CH0, + BUILD_DAY_CH1, + 'T', + BUILD_HOUR_CH0, + BUILD_HOUR_CH1, + ':', + BUILD_MIN_CH0, + BUILD_MIN_CH1, + ':', + BUILD_SEC_CH0, + BUILD_SEC_CH1, + '\0' +}; + + +static int (*jailbreak_me)(void) = NULL; +static int (*rejail_multi)(void) = NULL; + +int64_t sys_dynlib_load_prx(char* prxPath, int* moduleID) +{ + return (int64_t)syscall4(594, prxPath, 0, moduleID, 0); +} + +int64_t sys_dynlib_unload_prx(int64_t prxID) +{ + return (int64_t)syscall1(595, (void*)prxID); +} + + +int64_t sys_dynlib_dlsym(int64_t moduleHandle, const char* functionName, void* destFuncOffset) +{ + return (int64_t)syscall3(591, (void*)moduleHandle, (void*)functionName, destFuncOffset); +} + + +int libjbc_module = 0; + +bool rejail() +{ + int ret = sys_dynlib_dlsym(libjbc_module, "rejail_multi", &rejail_multi); + if (!ret) + { + log_info("[Daemon] rejail_multi resolved from PRX"); + + if ((ret = rejail_multi() != 0)) return false; + else + return true; + } + else + { + // fail con + log_debug("[Daemon] rejail_multi failed to resolve"); + return false; + } + + return false; +} + +bool jailbreak(const char* prx_path) +{ + sys_dynlib_load_prx(prx_path, &libjbc_module); + int ret = sys_dynlib_dlsym(libjbc_module, "jailbreak_me", &jailbreak_me); + if (!ret) + { + log_info("[Daemon] jailbreak_me resolved from PRX"); + + if ((ret = jailbreak_me() != 0)) + { + log_debug("[Daemon] jailbreak_me returned %i", ret); + return false; + } + else + return true; + } + else + log_debug("[Daemon] jailbreak_me failed to resolve"); + + return false; +} + + +bool if_exists(const char* path) +{ + int dfd = open(path, O_RDONLY, 0); // try to open dir + if (dfd < 0) { + log_info("path %s, errno %s", path, strerror(errno)); + return false; + } + else + close(dfd); + + + return true; +} + +void SIG_Handler(int sig_numb) +{ + char profpath[150]; + void* array[100]; + + sceKernelIccSetBuzzer(2); + + snprintf(profpath, 149, "/mnt/proc/%i/", getpid()); + + if (getuid() == 0 && !if_exists(profpath)) + { + int result = mkdir("/mnt/proc", 0777); + if (result < 0 && errno != 17) + { + log_debug("Failed to create /mnt/proc"); + } + + result = mount("procfs", "/mnt/proc", 0, NULL); + if (result < 0) + { + log_debug("Failed to mount procfs: %s", strerror(errno)); + } + } + // + + log_debug("############# DAEMON HAS CRASHED ##########"); + log_debug("# Thread ID: %i", pthread_getthreadid_np()); + log_debug("# PID: %i", getpid()); + + if (getuid() == 0) + log_debug("# mounted ProcFS to %s", profpath); + + + log_debug("# UID: %i", getuid()); + + char buff[255]; + + if (getuid() == 0) + { + FILE* fp; + + fp = fopen("/mnt/proc/curproc/status", "r"); + fscanf(fp, "%s", buff); + + log_debug("# Reading curproc..."); + + log_debug("# Proc Name: %s", buff); + + fclose(fp); + } + log_debug("################### Backtrace ########################"); + backtrace(array, 100); + + notify("[ITEMZ] Daemon has crashed, Restarting..."); + + sceSystemServiceLoadExec("/app0/eboot.bin", 0); + +} + +bool full_init() +{ + + // pad + int ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_PAD); + if (ret) return false; + + ret = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_SYSUTIL); + if (ret) return false; + + mkdir("/data/itemzflow_daemon", 0777); + mkdir("/mnt/usb0/itemzflow", 0777); + unlink(DAEMON_LOG_PS4); + + /*-- INIT LOGGING FUNCS --*/ + log_set_quiet(false); + log_set_level(LOG_DEBUG); + FILE* fp = fopen(DAEMON_LOG_PS4, "w"); + log_add_fp(fp, LOG_DEBUG); + + if (touch_file(DAEMON_LOG_USB)) + { + fp = fopen(DAEMON_LOG_USB, "w"); + log_add_fp(fp, LOG_DEBUG); + } + /* -- END OF LOGINIT --*/ + + + log_info("------------------------ ItemzFlow[Daemon] Compiled Time: %s @ %s -------------------------", __DATE__, __TIME__); + log_info(" --------------------------- Daemon Version: %s ------------------------------------", completeVersion); + + //Dump code and sig hanlder + struct sigaction new_SIG_action; + + new_SIG_action.sa_handler = SIG_Handler; + sigemptyset(&new_SIG_action.sa_mask); + new_SIG_action.sa_flags = 0; + //for now just SEGSEV + sigaction(11, &new_SIG_action, NULL); + + sceSystemServiceHideSplashScreen(); + + return true; +} + +bool isRestMode() +{ + //return (unsigned int)sceSystemStateMgrGetCurrentState() == MAIN_ON_STANDBY; + return false; +} + +bool IsOn() +{ + //return (unsigned int)sceSystemStateMgrGetCurrentState() == WORKING; + return true; +} + + +void notify(char* message) +{ + sceSysUtilSendSystemNotificationWithText(222, message); +} \ No newline at end of file