s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CELL_GAME_PATH_MAX]> tmp_contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> tmp_usrdirPath) { cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath); std::string dir = init->titleId; std::string tmp_contentInfo = "/dev_hdd0/game/TMP_" + dir; std::string tmp_usrdir = "/dev_hdd0/game/TMP_" + dir + "/USRDIR"; if (!Emu.GetVFS().CreateDir(tmp_contentInfo)) { cellGame.Error("cellGameCreateGameData(): failed to create content directory ('%s')", tmp_contentInfo); return CELL_GAME_ERROR_ACCESS_ERROR; // ??? } if (!Emu.GetVFS().CreateDir(tmp_usrdir)) { cellGame.Error("cellGameCreateGameData(): failed to create USRDIR directory ('%s')", tmp_usrdir); return CELL_GAME_ERROR_ACCESS_ERROR; // ??? } // cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo); strcpy_trunc(*tmp_usrdirPath, tmp_usrdir); contentInfo = dir; usrdir.clear(); path_set = true; cellGame.Success("cellGameCreateGameData(): temporary gamedata directory created ('%s')", tmp_contentInfo); // TODO: set initial PARAM.SFO parameters return CELL_OK; }
s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> usrdirPath) { cellGame.Warning("cellGameContentPermit(contentInfoPath=*0x%x, usrdirPath=*0x%x)", contentInfoPath, usrdirPath); if (!contentInfoPath && !usrdirPath) { return CELL_GAME_ERROR_PARAM; } const auto path_set = fxm::withdraw<content_permission_t>(); if (!path_set) { return CELL_GAME_ERROR_FAILURE; } if (path_set->is_temporary) { const std::string dir = "/dev_hdd0/game/" + path_set->dir; // make temporary directory persistent if (Emu.GetVFS().Rename("/dev_hdd1/game/" + path_set->dir, dir)) { cellGame.Success("cellGameContentPermit(): '%s' directory created", dir); } else { throw EXCEPTION("Cannot create gamedata directory"); } // prevent deleting directory path_set->is_temporary = false; strcpy_trunc(*contentInfoPath, dir); strcpy_trunc(*usrdirPath, dir + "/USRDIR"); } else { strcpy_trunc(*contentInfoPath, path_set->dir); strcpy_trunc(*usrdirPath, path_set->dir + "/USRDIR"); } return CELL_OK; }
s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> usrdirPath) { cellGame.Warning("cellGameContentPermit(contentInfoPath=*0x%x, usrdirPath=*0x%x)", contentInfoPath, usrdirPath); if (!contentInfoPath && !usrdirPath) { return CELL_GAME_ERROR_PARAM; } cellGame.Warning("cellGameContentPermit(): path_set=%d, contentInfo='%s', usrdir='%s'", path_set, contentInfo, usrdir); if (!path_set) { return CELL_GAME_ERROR_FAILURE; } if (contentInfo.size() == 9 && usrdir.empty()) { if (Emu.GetVFS().RenameDir("/dev_hdd0/game/TMP_" + contentInfo, "/dev_hdd0/game/" + contentInfo)) { cellGame.Success("cellGameContentPermit(): gamedata directory created ('/dev_hdd0/game/%s')", contentInfo); } contentInfo = "/dev_hdd0/game/" + contentInfo; usrdir = contentInfo + "/USRDIR"; } strcpy_trunc(*contentInfoPath, contentInfo); strcpy_trunc(*usrdirPath, usrdir); contentInfo = ""; usrdir = ""; path_set = false; return CELL_GAME_RET_OK; }
void sys_game_process_exitspawn2(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { std::string _path = path.get_ptr(); const std::string& from = "//"; const std::string& to = "/"; size_t start_pos = 0; while ((start_pos = _path.find(from, start_pos)) != std::string::npos) { _path.replace(start_pos, from.length(), to); start_pos += to.length(); } sysPrxForUser.Warning("sys_game_process_exitspawn2()"); sysPrxForUser.Warning("path: %s", _path.c_str()); sysPrxForUser.Warning("argv: 0x%x", argv_addr); sysPrxForUser.Warning("envp: 0x%x", envp_addr); sysPrxForUser.Warning("data: 0x%x", data_addr); sysPrxForUser.Warning("data_size: 0x%x", data_size); sysPrxForUser.Warning("prio: %d", prio); sysPrxForUser.Warning("flags: %d", flags); std::vector<std::string> argv; std::vector<std::string> env; if (argv_addr) { auto argvp = vm::cpptr<char>::make(argv_addr); while (argvp && *argvp) { argv.push_back(argvp[0].get_ptr()); argvp++; } for (auto &arg : argv) { sysPrxForUser.Log("argument: %s", arg.c_str()); } } if (envp_addr) { auto envp = vm::cpptr<char>::make(envp_addr); while (envp && *envp) { env.push_back(envp[0].get_ptr()); envp++; } for (auto &en : env) { sysPrxForUser.Log("env_argument: %s", en.c_str()); } } // TODO: execute the file in <path> with the args in argv // and the environment parameters in envp and copy the data // from data_addr into the adress space of the new process // then kill the current process Emu.Pause(); sysPrxForUser.Success("Process finished"); CallAfter([=]() { Emu.Stop(); std::string real_path; Emu.GetVFS().GetDevice(_path.c_str(), real_path); Emu.BootGame(real_path, true); }); return; }