mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
Merge pull request #10573 from akkadbakkad89/feat/np-game-intent-launch-app
feat(libSceNpGameIntent): recover sceNpAppLauncherLaunchApp validation
This commit is contained in:
4 files changed
+59
-5
No files matched your search
@@ -14,12 +14,19 @@ constexpr int NpGameIntentErrorInvalidArgument = -2141898748;
|
||||
constexpr int NpGameIntentErrorIntentNotFound = -2141898746;
|
||||
constexpr int NpGameIntentErrorValueNotFound = -2141898745;
|
||||
constexpr int NpGameIntentUserIdInvalid = -1;
|
||||
constexpr int NpAppLauncherErrorNotInitialized = -2141898238;
|
||||
constexpr int NpAppLauncherErrorInvalidArgument = -2141898236;
|
||||
|
||||
std::atomic_bool& NpGameIntentInitialized() {
|
||||
static std::atomic_bool initialized{false};
|
||||
return initialized;
|
||||
}
|
||||
|
||||
std::atomic_bool& AppLauncherInitialized() {
|
||||
static std::atomic_bool initialized{false};
|
||||
return initialized;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
@@ -91,15 +98,20 @@ int APS5_VABI sceNpGameIntentVshTerminate(void) {
|
||||
|
||||
int APS5_VABI sceNpAppLauncherInitialize(const void* initParam) {
|
||||
(void)initParam;
|
||||
AppLauncherInitialized() = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpAppLauncherLaunchApp() {
|
||||
int APS5_VABI sceNpAppLauncherLaunchApp(std::int32_t arg0, const char* arg2, const char* arg3) {
|
||||
(void)arg0;
|
||||
if (!AppLauncherInitialized()) return NpAppLauncherErrorNotInitialized;
|
||||
if (arg2 == nullptr || *arg2 == '\0' || (arg3 != nullptr && std::memchr(arg3, '\0', 0x2001) == nullptr)) return NpAppLauncherErrorInvalidArgument;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpAppLauncherTerminate() {
|
||||
AppLauncherInitialized() = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ int APS5_VABI sceNpGameIntentInfoInit(NpGameIntentInfo* info);
|
||||
int APS5_VABI sceNpGameIntentVshInitialize(void);
|
||||
int APS5_VABI sceNpGameIntentVshTerminate(void);
|
||||
int APS5_VABI sceNpAppLauncherInitialize(const void* initParam);
|
||||
int APS5_VABI sceNpAppLauncherLaunchApp();
|
||||
int APS5_VABI sceNpAppLauncherLaunchApp(std::int32_t arg0, const char* arg2, const char* arg3);
|
||||
int APS5_VABI sceNpAppLauncherTerminate();
|
||||
int APS5_VABI sceNpGameIntentGetUdsNpComId();
|
||||
int APS5_VABI sceNpGameIntentLaunchApp();
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
static void Require(bool value, const char* what) {
|
||||
if (value) return;
|
||||
@@ -28,6 +32,8 @@ int main() {
|
||||
constexpr int kInvalidArgument = -2141898748;
|
||||
constexpr int kIntentNotFound = -2141898746;
|
||||
constexpr int kValueNotFound = -2141898745;
|
||||
constexpr int kLauncherInvalidArgument = -2141898236;
|
||||
constexpr int kLauncherNotInitialized = -2141898238;
|
||||
|
||||
Require(Throws<std::invalid_argument>([] { sceNpGameIntentInitParamInit(nullptr); }),
|
||||
"null param init did not throw");
|
||||
@@ -112,12 +118,47 @@ int main() {
|
||||
|
||||
unsigned char appLauncherParam[0x28]{};
|
||||
*reinterpret_cast<std::uint64_t*>(appLauncherParam) = 0x28;
|
||||
Require(sceNpAppLauncherLaunchApp(0, "app", nullptr) == kLauncherNotInitialized,
|
||||
"launch before init must report not-initialized");
|
||||
Require(sceNpAppLauncherInitialize(appLauncherParam) == 0, "app launcher init failed");
|
||||
Require(sceNpAppLauncherLaunchApp(0, nullptr, nullptr) == kLauncherInvalidArgument,
|
||||
"null launch argument must be invalid");
|
||||
Require(sceNpAppLauncherLaunchApp(0, "", nullptr) == kLauncherInvalidArgument,
|
||||
"empty launch argument must be invalid");
|
||||
std::vector<char> unterminated(0x2001, 'x');
|
||||
Require(sceNpAppLauncherLaunchApp(0, "app", unterminated.data()) == kLauncherInvalidArgument,
|
||||
"non-terminated 0x2001-byte argument must be invalid");
|
||||
Require(sceNpAppLauncherTerminate() == 0, "app launcher terminate failed");
|
||||
Require(sceNpAppLauncherLaunchApp(0, "app", nullptr) == kLauncherNotInitialized,
|
||||
"launch after terminate must report not-initialized");
|
||||
*reinterpret_cast<std::uint64_t*>(appLauncherParam) = 0x10;
|
||||
Require(sceNpAppLauncherInitialize(appLauncherParam) == 0,
|
||||
"app launcher init must accept any init parameter");
|
||||
|
||||
std::atomic_bool stop{false};
|
||||
std::thread writer([&] {
|
||||
while (!stop.load(std::memory_order_relaxed)) {
|
||||
sceNpAppLauncherInitialize(nullptr);
|
||||
sceNpAppLauncherTerminate();
|
||||
}
|
||||
});
|
||||
std::thread reader([&] {
|
||||
while (!stop.load(std::memory_order_relaxed)) {
|
||||
try {
|
||||
(void)sceNpAppLauncherLaunchApp(0, "app", nullptr);
|
||||
} catch (const std::runtime_error&) {
|
||||
}
|
||||
}
|
||||
});
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
stop.store(true);
|
||||
writer.join();
|
||||
reader.join();
|
||||
|
||||
Require(sceNpAppLauncherTerminate() == 0, "final terminate failed");
|
||||
Require(sceNpAppLauncherLaunchApp(0, "app", nullptr) == kLauncherNotInitialized,
|
||||
"final launch must report not-initialized");
|
||||
|
||||
std::puts("NpGameIntent tests passed");
|
||||
return 0;
|
||||
}
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
### Silent stubs
|
||||
|
||||
- [sceNpGameIntentVshInitialize, sceNpGameIntentVshTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - VSH initialization and termination return 0 without performing shell operations
|
||||
- [sceNpAppLauncherInitialize, sceNpAppLauncherTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - app-launcher lifecycle returns success without tracking launch state; `sceNpAppLauncherInitialize` accepts its init parameter without validation — a title calls it early in boot, and returning success lets it continue
|
||||
- [sceNpGameIntentVshInitialize, sceNpGameIntentVshTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - VSH initialization and termination return 0 without performing shell operations, matching `sceNpGameIntentInitialize` and `sceNpGameIntentTerminate`
|
||||
- [sceNpAppLauncherInitialize, sceNpAppLauncherTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - app-launcher lifecycle returns success without performing launch work; `sceNpAppLauncherInitialize` accepts its init parameter without validation, following the silent-stub precedent of `sceNpGameIntentInitialize` — a title calls it early in boot, and returning success lets it continue; an atomic flag tracks initialized state so `sceNpAppLauncherLaunchApp` can reject calls made outside the lifecycle
|
||||
|
||||
### Unknown function info
|
||||
|
||||
- [sceNpGameIntentReceiveIntent, sceNpGameIntentGetPropertyValueString](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - firmware 13.42 traces report `0x80553802` before `sceNpGameIntentInitialize` (precedence over argument validity), and `0x80553804` for invalid arguments (null pointer, empty key, or zero buffer size); `sceNpGameIntentTerminate` resetting initialized state is modeled lifecycle behavior rather than hardware-verified. `sceNpGameIntentReceiveIntent` reportedly requires `info->size == 0x4140` on firmware 13.42, while AnyPS5 `NpGameIntentInfo` is `0x560` bytes (matching fpPS4) and set by `sceNpGameIntentInfoInit`, so initialized objects are rejected by the receiver's measured size guard. Complete retail layout, output field offsets, and retail behavior of `sceNpGameIntentInfoInit` are unverified; expanding the type with unverified reserved bytes is not an evidence-backed solution.
|
||||
- [sceNpAppLauncherLaunchApp, sceNpGameIntentGetUdsNpComId, sceNpGameIntentLaunchApp, sceNpGameIntentLaunchApp2, sceNpGameIntentNotifyAppLaunched, sceNpSessionServiceGetJoinedPartySession, sceNpSessionServiceGetRunningGamePlayerSession and sceNpSessionServiceSendPlayerSessionInvitations](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpGameIntent.c). Call sites in a title's executable give a partial prototype: `sceNpAppLauncherLaunchApp` takes `(user_id, uri struct, context)` and returns int — throws because no launcher-service semantics are derivable. The rest are declared without parameters solely to resolve known imports and make no ABI claim.
|
||||
- [sceNpAppLauncherLaunchApp](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent, NID `GbayQ7DO8jA`) - its recovered signature is `(int32_t, const char*, const char*)`: an unhandled first argument, a required non-empty string and an optional string rejected past 0x2000 bytes, returning `0x80553A02` before `sceNpAppLauncherInitialize` and `0x80553A04` on invalid arguments. The launch itself is not implemented and throws; the firmware tail calls an internal launch through an extra library context and remaps its `0x805538xx` errors into `0x80553Axx`
|
||||
- [sceNpGameIntentGetUdsNpComId, sceNpGameIntentLaunchApp, sceNpGameIntentLaunchApp2, sceNpGameIntentNotifyAppLaunched, sceNpSessionServiceGetJoinedPartySession, sceNpSessionServiceGetRunningGamePlayerSession and sceNpSessionServiceSendPlayerSessionInvitations](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpGameIntent.c). They are declared without parameters solely to resolve known imports and make no ABI claim.
|
||||
- [sceNpGameIntentInitParamInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L17) `SceNpGameIntentInitParam`; setting `size`, zeroing reserved bytes, and throwing on null pointer follow Sony SDK `*ParamInit` conventions but are unverified on retail hardware
|
||||
- [sceNpGameIntentInfoInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L28) `SceNpGameIntentInfo`; setting `size = 0x560`, `user_id = -1`, zeroing fields, and throwing on null pointer follow fpPS4 defaults, but reported firmware 13.42 behavior requires `0x4140` for `sceNpGameIntentReceiveIntent`, so the helper's `0x560` size does not match retail receiver defaults; the complete retail structure layout and retail behavior of `sceNpGameIntentInfoInit` remain unverified
|
||||
Reference in new issue
Block a user