diff --git a/core/libs/prx/libSceSystemService/Export.cpp b/core/libs/prx/libSceSystemService/Export.cpp index 6480b49dfc..28df9285a8 100644 --- a/core/libs/prx/libSceSystemService/Export.cpp +++ b/core/libs/prx/libSceSystemService/Export.cpp @@ -390,6 +390,16 @@ int APS5_VABI sceSystemServiceOpenTournamentOccurrence(void) { return 0; } +int APS5_VABI sceSystemServiceAddLocalProcessForPsmKit(const char*, const char* const*, const void*) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSystemServiceKillLocalProcessForPsmKit(int) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + int APS5_VABI sceSystemServiceReenableMusicPlayer(void) { return SYSTEM_SERVICE_OK; } diff --git a/core/libs/tests/GuestSystemService.cpp b/core/libs/tests/GuestSystemService.cpp index e4e181e204..ea1f51b383 100644 --- a/core/libs/tests/GuestSystemService.cpp +++ b/core/libs/tests/GuestSystemService.cpp @@ -8,6 +8,8 @@ extern "C" int APS5_VABI sceSystemServiceGetHdrToneMapLuminance(SystemServiceHdrToneMapLuminance* luminance); extern "C" int APS5_VABI sceSystemServiceParamGetString(int paramId, char* buf, std::size_t bufSize); extern "C" int APS5_VABI sceSystemServiceLaunchApp(const char* titleId, const char* const* arguments, const void* param); +extern "C" int APS5_VABI sceSystemServiceAddLocalProcessForPsmKit(const char* path, const char* const* arguments, const void* param); +extern "C" int APS5_VABI sceSystemServiceKillLocalProcessForPsmKit(int handle); namespace { @@ -24,6 +26,16 @@ bool ParamGetStringThrows(int paramId, char* buf, std::size_t bufSize) { return false; } +template +bool Throws(TCall call) { + try { + static_cast(call()); + } catch (const std::runtime_error&) { + return true; + } + return false; +} + bool LaunchAppThrows(const char* titleId, const char* const* arguments, const void* param) { try { static_cast(sceSystemServiceLaunchApp(titleId, arguments, param)); @@ -76,6 +88,13 @@ int main() { Require(LaunchAppThrows("PPSA99110", launchArguments, launchParam)); for (unsigned char byte : launchParam) Require(byte == 0x5a); Require(std::strcmp(launchArguments[0], "--backup") == 0 && launchArguments[1] == nullptr); + const char* childArguments[] = {"/app0/child.bin", nullptr}; + unsigned char processParam[0x90]; + std::memset(processParam, 0x5a, sizeof(processParam)); + Require(Throws([&] { return sceSystemServiceAddLocalProcessForPsmKit("/app0/child.bin", childArguments, processParam); })); + for (unsigned char byte : processParam) Require(byte == 0x5a); + Require(Throws([] { return sceSystemServiceAddLocalProcessForPsmKit(nullptr, nullptr, nullptr); })); + Require(Throws([] { return sceSystemServiceKillLocalProcessForPsmKit(1); })); Require(sceSystemServiceGetHdrToneMapLuminance(nullptr) == SYSTEM_SERVICE_ERROR_PARAMETER); SystemServiceHdrToneMapLuminance luminance{-1.0f, -1.0f, -1.0f}; Require(sceSystemServiceGetHdrToneMapLuminance(&luminance) == SYSTEM_SERVICE_OK); diff --git a/docs/dev/debt/libSceSystemService.md b/docs/dev/debt/libSceSystemService.md index 8d8ea62347..10a4e0c17c 100644 --- a/docs/dev/debt/libSceSystemService.md +++ b/docs/dev/debt/libSceSystemService.md @@ -9,6 +9,7 @@ ### Unknown function info +- [sceSystemServiceAddLocalProcessForPsmKit, sceSystemServiceKillLocalProcessForPsmKit](../../../core/libs/prx/libSceSystemService/Export.cpp) (libSceSystemService) - AnyPS5 runs one process and starts or stops no other, so both throw without reading their arguments. The parameters follow Forever Launcher's own firmware 5.50 probes (`ps5/probes/localproc` in [bizkut/ps5-forever](https://github.com/bizkut/ps5-forever)): a path, a null-terminated argv and a 0x90-byte parameter block in, a handle out; the kill takes that handle. Their results on the console are unknown. Forever Launcher (PPSA99030) imports both and stops at load without them. - [sceSystemServiceLaunchApp](../../../core/libs/prx/libSceSystemService/Export.cpp) (libSceSystemService) - AnyPS5 runs one title and cannot start another, so every call throws without reading its arguments. The (title ID, null-terminated argv, launch parameters) signature follows [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/5dfdb4b0b166e83dc9ae275001afb695f12c7174/src/SharpProspero/Interop/SystemService/SystemService.cs#L141-L148), whose `AppLauncher` Prospero Explorer (PPSA99109) and Prospero Multi Tools (PPSA99110) import it through and which passes a 0x20-byte launch context or null; the console's argument checks and errors are unknown - [sceSystemServiceLaunchWebBrowser](../../../core/libs/prx/libSceSystemService/Export.cpp) (libSceSystemService) - the console's error for an unavailable web browser is unknown; it returns the kernel's `EOPNOTSUPP` (0x8002002D) for any arguments. The (uri, param) signature follows [RommPS](https://github.com/s0liton/RommPS/blob/754d4d60f25938a5136b9e2efcd074313c4386c5/platform/ps5/app/rommps/examples/rommps/kit/credits.cpp#L86-L95), which passes a URL and a null param and only tests the result for zero; the param layout and the console's argument checks are unknown - [sceSystemServiceParamGetString](../../../core/libs/prx/libSceSystemService/Export.cpp) (libSceSystemService) - the system name (parameter 6) is the fixed `PS5`, not the console's name; other parameters and buffers of 1 to 64 bytes throw. PPSA26344 at `0xA87935` passes parameter 6 with a 65-byte buffer