Merge pull request #12577 from iAbdulrrahman/feat/libkernel-sys-is-ps4-process

feat(libkernel_sys): implement sceKernelIsPs4Process query
This commit is contained in:
Adrià authored and GitHub committed 2026-10-30 03:03:26 +01:00
commit acf46d4ff8
4 files changed
+55 -9

No files matched your search

@@ -1333,11 +1333,6 @@ int APS5_VABI sceKernelIsNeoMode(void) {
return (attribute & PARAM_SFO_ATTRIBUTE_SUPPORT_NEO_MODE) != 0 ? 1 : 0;
}
int APS5_VABI sceKernelIsPs4Process(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceKernelJitGetSharedMemoryInfo(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
+17
View File
@@ -28,6 +28,7 @@
#include "prx/libc/include/General.hpp"
#include "prx/libc/include/ApplicationHeap.hpp"
#include "prx/libkernel/KernelErrors.hpp"
#include "prx/libkernel/AppMetadata/include/AppMetadata.hpp"
#include "prx/libc/include/FilesystemError.hpp"
#include "prx/libkernel/KernelErrors.hpp"
#include "prx/libkernel/Pthread/include/Pthread.hpp"
@@ -426,6 +427,22 @@ int APS5_VABI sceKernelIsKratos(void) {
return 0;
}
bool IsPs4Process() {
try {
const auto titleId = GetAppTitleId_nid_postfix();
const std::string_view id(titleId.value, strnlen(titleId.value, sizeof(titleId.value)));
return id.starts_with("CUSA");
} catch (const std::runtime_error&) {
return false;
} catch (const std::length_error&) {
return false;
}
}
int APS5_VABI sceKernelIsPs4Process(void) {
return IsPs4Process() ? 1 : 0;
}
int APS5_VABI get_authinfo_nid_postfix(int pid, KernelAuthInfo* info) {
if (info == nullptr) return static_cast<int>(Fail(GuestEperm));
if (pid != 0 && pid != getpid_nid_postfix()) return static_cast<int>(Fail(GuestEsrch));
@@ -6,6 +6,11 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <random>
#include <string>
#include <string_view>
namespace {
@@ -19,7 +24,7 @@ void Require(bool condition, const char* message) {
}
}
void CheckConsoleKind() {
void CheckConsoleKind(bool ps4) {
Require(sceKernelIsCEX() == 1, "the console must be reported as a retail unit");
Require(sceKernelIsDevKit() == 0, "the console must not be reported as a development kit");
Require(sceKernelIsGenuineCEX() == 1, "the console must be reported as a genuine retail unit");
@@ -28,6 +33,11 @@ void CheckConsoleKind() {
Require(sceKernelIsTestKit() == 0, "the console must not be reported as a test kit");
Require(sceKernelIsProspero() == 1, "the architecture must be reported as Prospero");
Require(sceKernelIsKratos() == 0, "the architecture must not be reported as Kratos");
if (ps4) {
Require(sceKernelIsPs4Process() == 1, "a CUSA title must be reported as a PS4 process");
} else {
Require(sceKernelIsPs4Process() == 0, "the default process must not be reported as a PS4 process");
}
}
void CheckAuthInfo() {
@@ -69,9 +79,33 @@ void CheckOpenPsId() {
}
int main() {
CheckConsoleKind();
int main(int argc, char** argv) {
if (argc == 2 && std::string_view(argv[1]) == "ps4-child") {
CheckConsoleKind(true);
return 0;
}
CheckConsoleKind(false);
CheckAuthInfo();
CheckOpenPsId();
const auto directory = std::filesystem::temp_directory_path() / ("ps4-identity-test-" + std::to_string(std::random_device{}()));
std::filesystem::create_directories(directory / "app0" / "sce_sys");
struct Entry { std::uint16_t key, format; std::uint32_t length, maximum, offset; };
const std::uint32_t header[5] = {0x46535000, 0x0101, 52, 72, 2};
const Entry entries[2] = {{0, 0x0204, 8, 8, 0}, {6, 0x0204, 10, 12, 8}};
{
std::ofstream file(directory / "app0/sce_sys/param.sfo", std::ios::binary);
file.write(reinterpret_cast<const char*>(header), sizeof(header));
file.write(reinterpret_cast<const char*>(entries), sizeof(entries));
file << std::string("TITLE\0TITLE_ID\0\0\0\0\0\0", 20) << std::string("Example\0", 8) << "CUSA00000" << std::string("\0\0\0", 3);
}
#ifdef _WIN32
const std::string command = "\"cd /d \"" + directory.string() + "\" && \"" + argv[0] + "\" ps4-child\"";
#else
const std::string command = "cd \"" + directory.string() + "\" && \"" + argv[0] + "\" ps4-child";
#endif
const int status = std::system(command.c_str());
std::filesystem::remove_all(directory);
Require(status == 0, "the PS4 child process must succeed");
return 0;
}