#include "stdafx.h" #include "sys_ss.h" #include "sys_process.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUThread.h" #ifdef _WIN32 #include #include #endif template<> void fmt_class_string::format(std::string& out, u64 arg) { format_enum(out, arg, [](auto error) { switch (error) { STR_CASE(SYS_SS_RNG_ERROR_INVALID_PKG); STR_CASE(SYS_SS_RNG_ERROR_ENOMEM); STR_CASE(SYS_SS_RNG_ERROR_EAGAIN); STR_CASE(SYS_SS_RNG_ERROR_EFAULT); } return unknown; }); } LOG_CHANNEL(sys_ss); error_code sys_ss_random_number_generator(u64 pkg_id, vm::ptr buf, u64 size) { sys_ss.warning("sys_ss_random_number_generator(pkg_id=%u, buf=*0x%x, size=0x%x)", pkg_id, buf, size); if (pkg_id != 2) { if (pkg_id == 1) { if (!g_ps3_process_info.has_root_perm()) { return CELL_ENOSYS; } sys_ss.todo("sys_ss_random_number_generator(): pkg_id=1"); std::memset(buf.get_ptr(), 0, 0x18); return CELL_OK; } return SYS_SS_RNG_ERROR_INVALID_PKG; } // TODO if (size > 0x10000000) { return SYS_SS_RNG_ERROR_ENOMEM; } std::unique_ptr temp(new u8[size]); #ifdef _WIN32 if (auto ret = BCryptGenRandom(nullptr, temp.get(), static_cast(size), BCRYPT_USE_SYSTEM_PREFERRED_RNG)) { fmt::throw_exception("sys_ss_random_number_generator(): BCryptGenRandom failed (0x%08x)", ret); } #else fs::file rnd{"/dev/urandom"}; if (!rnd || rnd.read(temp.get(), size) != size) { fmt::throw_exception("sys_ss_random_number_generator(): Failed to generate pseudo-random numbers"); } #endif std::memcpy(buf.get_ptr(), temp.get(), size); return CELL_OK; } error_code sys_ss_access_control_engine(u64 pkg_id, u64 a2, u64 a3) { sys_ss.todo("sys_ss_access_control_engine(pkg_id=0x%llx, a2=0x%llx, a3=0x%llx)", pkg_id, a2, a3); const u64 authid = g_ps3_process_info.self_info.valid ? g_ps3_process_info.self_info.app_info.authid : 0; switch (pkg_id) { case 0x1: { if (!g_ps3_process_info.debug_or_root()) { return CELL_ENOSYS; } if (!a2) { return CELL_ESRCH; } ensure(a2 == static_cast(process_getpid())); vm::write64(vm::cast(a3), authid); break; } case 0x2: { vm::write64(vm::cast(a2), authid); break; } case 0x3: { if (!g_ps3_process_info.debug_or_root()) { return CELL_ENOSYS; } break; } default: return 0x8001051du; } return CELL_OK; } s32 sys_ss_get_console_id(vm::ptr buf) { sys_ss.todo("sys_ss_get_console_id(buf=*0x%x)", buf); // TODO: Return some actual IDPS? *buf = 0; return CELL_OK; } s32 sys_ss_get_open_psid(vm::ptr psid) { sys_ss.warning("sys_ss_get_open_psid(psid=*0x%x)", psid); psid->high = 0; psid->low = 0; return CELL_OK; } error_code sys_ss_appliance_info_manager(u32 code, vm::ptr buffer) { sys_ss.todo("sys_ss_appliance_info_manager(code=0x%x, buffer=*0x%x)", code, buffer); return CELL_OK; } error_code sys_ss_get_cache_of_product_mode(vm::ptr ptr) { sys_ss.todo("sys_ss_get_cache_of_product_mode(ptr=*0x%x)", ptr); return CELL_OK; } error_code sys_ss_secure_rtc(u64 cmd, u64 a2, u64 a3, u64 a4) { sys_ss.todo("sys_ss_secure_rtc(cmd=0x%llx, a2=0x%x, a3=0x%x, a4=0x%x)", cmd, a2, a3, a4); return CELL_OK; } error_code sys_ss_get_cache_of_flash_ext_flag(vm::ptr flag) { sys_ss.todo("sys_ss_get_cache_of_flash_ext_flag(flag=*0x%x)", flag); return CELL_OK; } error_code sys_ss_get_boot_device(vm::ptr dev) { sys_ss.todo("sys_ss_get_boot_device(dev=*0x%x)", dev); return CELL_OK; } error_code sys_ss_update_manager(u64 pkg_id, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6) { sys_ss.todo("sys_ss_update_manager(pkg=0x%llx, a1=0x%x, a2=0x%x, a3=0x%x, a4=0x%x, a5=0x%x, a6=0x%x)", pkg_id, a1, a2, a3, a4, a5, a6); return CELL_OK; } error_code sys_ss_virtual_trm_manager(u64 pkg_id, u64 a1, u64 a2, u64 a3, u64 a4) { sys_ss.todo("sys_ss_virtual_trm_manager(pkg=0x%llx, a1=0x%llx, a2=0x%llx, a3=0x%llx, a4=0x%llx)", pkg_id, a1, a2, a3, a4); return CELL_OK; } error_code sys_ss_individual_info_manager(u64 pkg_id, u64 a2, vm::ptr out_size, u64 a4, u64 a5, u64 a6) { sys_ss.todo("sys_ss_individual_info_manager(pkg=0x%llx, a2=0x%llx, out_size=*0x%llx, a4=0x%llx, a5=0x%llx, a6=0x%llx)", pkg_id, a2, out_size, a4, a5, a6); switch (pkg_id) { // Read EID case 0x17002: { // TODO vm::_ref(a5) = a4; // Write back size of buffer break; } // Get EID size case 0x17001: *out_size = 0x100; break; default: break; } return CELL_OK; }