plugin.cpp (4083B)
1 #include "version.hpp" 2 #include "vita_plugin/cpk.hpp" 3 4 #include <libshit/except.hpp> 5 #include <libshit/memory_utils.hpp> 6 #include <libshit/options.hpp> 7 #include <libshit/vita_fixup.h> 8 9 #include <fstream> 10 #include <memory> 11 #include <psp2/appmgr.h> 12 #include <psp2/io/dirent.h> 13 #include <psp2/kernel/modulemgr.h> 14 #include <psp2/kernel/processmgr.h> 15 #include <unistd.h> 16 #include <vector> 17 18 #define LIBSHIT_LOG_NAME "tai" 19 #include <libshit/logger_helper.hpp> 20 21 namespace Neptools::VitaPlugin 22 { 23 24 static void Uncaught() 25 { 26 printf("Terminate handler\n"); 27 printf("Caught: %s\n", Libshit::ExceptionToString(false).c_str()); 28 29 abort(); 30 } 31 32 static bool CheckPath(const char* buf, const char*& out) 33 { 34 SceIoStat stat; 35 auto ret = sceIoGetstat(buf, &stat); 36 if (ret == 0 && SCE_S_ISDIR(stat.st_mode)) 37 { 38 out = buf; 39 return true; 40 } 41 return false; 42 } 43 44 static void my_strlcpy(char* dst, const char* str, size_t n) 45 { 46 while (--n && (*dst++ = *str++)); 47 *dst = 0; 48 } 49 50 static int FindDir(char* out_base_fname, char* out_data_fname, char* out_cache_fname) 51 { 52 char log_buf[32]; 53 log_buf[0] = 0; 54 55 char buf[] = "____:neptools/_________"; 56 constexpr size_t off = sizeof("____:neptools/")-1; 57 int ret = sceAppMgrAppParamGetString(sceKernelGetProcessId(), 12, buf+off, 10); 58 if (ret < 0) return ret; // can't log anything here... 59 60 // same order as repatch 61 const char* base_path = nullptr; 62 bool cache_td = false; 63 for (const auto& x : {"ux0", "uma0", "imc0", "grw0", "xmc0"}) 64 { 65 size_t len = strlen(x); 66 memcpy(buf + 4 - len, x, len); 67 if (CheckPath(buf + 4 - len, base_path)) 68 { 69 my_strlcpy(log_buf, base_path, buf+off+1-base_path); 70 break; 71 } 72 } 73 if (!base_path && CheckPath("app0:neptools", base_path)) cache_td = true; 74 if (!base_path) return -1; 75 my_strlcpy(out_data_fname, base_path, 32); 76 77 // check for ioplus bug 78 if (!cache_td) 79 { 80 ret = sceIoDopen(base_path); 81 if (ret >= 0) sceIoDclose(ret); 82 else cache_td = true; 83 } 84 85 char td_buf[16]; 86 if (cache_td) 87 { 88 ret = sceAppMgrWorkDirMount(0xc9, td_buf); 89 if (ret < 0) return ret; 90 } 91 if (!log_buf[0]) strcpy(log_buf, td_buf); 92 93 if (cache_td) 94 { 95 strcpy(out_cache_fname, td_buf); 96 strcat(out_cache_fname, "neptools_cache"); 97 } 98 else 99 { 100 my_strlcpy(out_cache_fname, base_path, strlen(base_path) - 9 + 1); 101 strcat(out_cache_fname, "cache"); 102 } 103 104 strcpy(out_base_fname, log_buf); 105 auto pos = log_buf + strlen(log_buf); 106 strcpy(pos, "log_out.txt"); 107 freopen(log_buf, "w", stdout); 108 strcpy(pos, "log_err.txt"); 109 freopen(log_buf, "w", stderr); 110 111 return 0; 112 } 113 114 extern "C" int _start() __attribute__ ((weak, alias ("module_start"))); 115 116 extern "C" int module_start(SceSize, const void*); 117 extern "C" int module_start(SceSize, const void*) 118 { 119 char base_fname[32], data_fname[32], cache_fname[32]; 120 if (FindDir(base_fname, data_fname, cache_fname) < 0) 121 return SCE_KERNEL_START_FAILED; 122 123 std::set_terminate(Uncaught); 124 125 LibshitInitVita(); 126 127 std::vector<std::string> argv; 128 { 129 strcat(base_fname, "/command_line.txt"); 130 std::ifstream is{base_fname}; 131 while (is.good()) 132 { 133 std::string s; 134 std::getline(is, s); 135 if (!s.empty()) argv.push_back(std::move(s)); 136 } 137 } 138 139 int argc = argv.size() + 1; 140 141 auto cargv = Libshit::MakeUnique<const char*[]>( 142 argc + 2, Libshit::uninitialized); 143 cargv[0] = ""; 144 for (int i = 1; i < argc; ++i) cargv[i] = argv[i-1].c_str(); 145 cargv[argc+1] = nullptr; 146 147 auto& pars = Libshit::OptionParser::GetGlobal(); 148 pars.SetVersion("NepTools vita plugin v" NEPTOOLS_VERSION); 149 pars.SetUsage("[--options]"); 150 pars.FailOnNonArg(); 151 152 try { pars.Run(argc, cargv.get()); } 153 catch (const Libshit::Exit& e) { _exit(!e.success); } 154 155 INF << pars.GetVersion() << " initializing..." << std::endl; 156 Init(data_fname, cache_fname); 157 158 return SCE_KERNEL_START_SUCCESS; 159 } 160 161 }