Exemple #1
0
error_code prx_load_module(std::string path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
{
	if (s_prx_ignore.count(path))
	{
		sys_prx.warning("Ignored module: %s", path);

		const auto prx = idm::make_ptr<lv2_obj, lv2_prx>();

		prx->name = path.substr(path.find_last_of('/') + 1);

		return not_an_error(idm::last_id());
	}

	const auto loadedkeys = fxm::get_always<LoadedNpdrmKeys_t>();

	const ppu_prx_object obj = decrypt_self(fs::file(vfs::get(path)), loadedkeys->devKlic.data());

	if (obj != elf_error::ok)
	{
		return CELL_PRX_ERROR_ILLEGAL_LIBRARY;
	}

	const auto prx = ppu_load_prx(obj, path.substr(path.find_last_of('/') + 1));

	if (!prx)
	{
		return CELL_PRX_ERROR_ILLEGAL_LIBRARY;
	}

	ppu_initialize(*prx);

	sys_prx.success("Loaded module: %s", path);

	return not_an_error(idm::last_id());
}
Exemple #2
0
error_code 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 prm = fxm::get<content_permission>();
	
	if (!prm)
	{
		return CELL_GAME_ERROR_FAILURE;
	}

	const std::string dir = prm->dir.empty() ? "/dev_bdvd/PS3_GAME"s : "/dev_hdd0/game/" + prm->dir;

	if (!prm->temp.empty())
	{
		// Make temporary directory persistent
		const auto vdir = vfs::get(dir);

		if (fs::exists(vdir))
		{
			fmt::throw_exception("cellGameContentPermit(): epic fail: directory '%s' already exists", dir);
		}

		if (fs::rename(prm->temp, vdir))
		{
			cellGame.success("cellGameContentPermit(): directory '%s' has been created", dir);
		}
		else
		{
			fmt::throw_exception("cellGameContentPermit(): failed to initialize directory '%s'", dir);
		}

		// Create PARAM.SFO
		psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), prm->sfo);

		// Disable deletion
		prm->temp.clear();
	}

	strcpy_trunc(*contentInfoPath, dir);
	strcpy_trunc(*usrdirPath, dir + "/USRDIR");
	verify(HERE), fxm::remove<content_permission>();
	
	return CELL_OK;
}
Exemple #3
0
s32 sys_process_exit(ppu_thread& ppu, s32 status)
{
	vm::temporary_unlock(ppu);

	sys_process.warning("sys_process_exit(status=0x%x)", status);

	Emu.CallAfter([]()
	{
		sys_process.success("Process finished");
		Emu.Stop();
	});

	thread_ctrl::eternalize();

	return CELL_OK;
}
Exemple #4
0
error_code 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);

	const auto prm = fxm::get<content_permission>();

	if (!prm || prm->dir.empty())
	{
		return CELL_GAME_ERROR_FAILURE;
	}

	std::string tmp_contentInfo = "/dev_hdd1/game/" + prm->dir;
	std::string tmp_usrdir = "/dev_hdd1/game/" + prm->dir + "/USRDIR";

	if (!fs::create_dir(vfs::get(tmp_contentInfo)))
	{
		cellGame.error("cellGameCreateGameData(): failed to create directory '%s'", tmp_contentInfo);
		return CELL_GAME_ERROR_ACCESS_ERROR; // ???
	}

	if (!fs::create_dir(vfs::get(tmp_usrdir)))
	{
		cellGame.error("cellGameCreateGameData(): failed to create 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);

	prm->temp = vfs::get(tmp_contentInfo);
	cellGame.success("cellGameCreateGameData(): temporary directory '%s' has been created", tmp_contentInfo);

	// Initial PARAM.SFO parameters (overwrite)
	prm->sfo =
	{
		{ "CATEGORY", psf::string(3, "GD") },
		{ "TITLE_ID", psf::string(CELL_GAME_SYSP_TITLEID_SIZE, init->titleId) },
		{ "TITLE", psf::string(CELL_GAME_SYSP_TITLE_SIZE, init->title) },
		{ "VERSION", psf::string(CELL_GAME_SYSP_VERSION_SIZE, init->version) },
	};

	return CELL_OK;
}
Exemple #5
0
void sys_game_process_exitspawn(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.todo("sys_game_process_exitspawn()");
	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.trace("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.trace("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");

	Emu.CallAfter([=, path = vfs::get(_path)]()
	{
		Emu.Stop();
		Emu.BootGame(path, true);
	});
}