From f691d1d4e0e71717d83bfca8d8acb3d0a620126f Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 22:19:09 +0000 Subject: [PATCH 01/16] feat(libkernel): implement sceKernelGetEventError --- core/libs/prx/libkernel/Equeue/src/EventAccessors.cpp | 6 +++--- core/libs/tests/GuestEqueueEvents.cpp | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/libs/prx/libkernel/Equeue/src/EventAccessors.cpp b/core/libs/prx/libkernel/Equeue/src/EventAccessors.cpp index 2cce0e556b9..e72bfe3900c 100644 --- a/core/libs/prx/libkernel/Equeue/src/EventAccessors.cpp +++ b/core/libs/prx/libkernel/Equeue/src/EventAccessors.cpp @@ -4,6 +4,7 @@ #include #include "SceTypes.hpp" #include "prx/libc/include/General.hpp" +#include "prx/libkernel/Equeue/Equeue.hpp" static const KernelEvent& requireEvent(const KernelEvent* ev, const char* caller) { if (ev == nullptr) { @@ -19,9 +20,8 @@ intptr_t APS5_VABI sceKernelGetEventData(const KernelEvent* ev) { } int APS5_VABI sceKernelGetEventError(const KernelEvent* ev) { - (void)ev; - NotImplemented_nid_no_patch(__func__); - return 0; + const KernelEvent& event = requireEvent(ev, __func__); + return (event.flags & EV_ERROR) != 0 ? static_cast(event.data) : 0; } intptr_t APS5_VABI sceKernelGetEventFflags(const KernelEvent* ev) { diff --git a/core/libs/tests/GuestEqueueEvents.cpp b/core/libs/tests/GuestEqueueEvents.cpp index 56819452f38..0cb518a592e 100644 --- a/core/libs/tests/GuestEqueueEvents.cpp +++ b/core/libs/tests/GuestEqueueEvents.cpp @@ -24,6 +24,7 @@ intptr_t APS5_VABI sceKernelGetEventFflags(const KernelEvent* ev); int APS5_VABI sceKernelGetEventFilter(const KernelEvent* ev); uintptr_t APS5_VABI sceKernelGetEventId(const KernelEvent* ev); void* APS5_VABI sceKernelGetEventUserData(const KernelEvent* ev); +int APS5_VABI sceKernelGetEventError(const KernelEvent* ev); } static constexpr int SCE_OK = 0; @@ -288,10 +289,16 @@ int main() { Require(sceKernelGetEventFflags(&rawEvent) == static_cast(0x80000001LL)); Require(sceKernelGetEventData(&rawEvent) == -5); Require(sceKernelGetEventUserData(&rawEvent) == nullptr); + Require(sceKernelGetEventError(&rawEvent) == 0); + KernelEvent errorEvent{}; + errorEvent.flags = 0x4000; + errorEvent.data = -13; + Require(sceKernelGetEventError(&errorEvent) == -13); Require(RejectsNull(sceKernelGetEventData)); Require(RejectsNull(sceKernelGetEventFflags)); Require(RejectsNull(sceKernelGetEventFilter)); Require(RejectsNull(sceKernelGetEventId)); Require(RejectsNull(sceKernelGetEventUserData)); + Require(RejectsNull(sceKernelGetEventError)); } From 2f60f5513b2914bbe291fc2968dbbaac8391dc98 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 22:19:09 +0000 Subject: [PATCH 02/16] feat(libSceNpEntitlementAccess): report signed-out for entitlement flag queries --- core/libs/prx/libSceNpEntitlementAccess/Export.cpp | 6 ++---- core/libs/tests/GuestOfflineImports.cpp | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/core/libs/prx/libSceNpEntitlementAccess/Export.cpp b/core/libs/prx/libSceNpEntitlementAccess/Export.cpp index 90aeb0b06a5..d2feb03c9f6 100644 --- a/core/libs/prx/libSceNpEntitlementAccess/Export.cpp +++ b/core/libs/prx/libSceNpEntitlementAccess/Export.cpp @@ -151,13 +151,11 @@ int APS5_VABI sceNpEntitlementAccessRequestUnifiedEntitlementInfo(void) { } int APS5_VABI sceNpEntitlementAccessGetPftFlag(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return SCE_NP_ERROR_SIGNED_OUT; } int APS5_VABI sceNpEntitlementAccessGetGameTrialsFlag(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return SCE_NP_ERROR_SIGNED_OUT; } int APS5_VABI sceNpEntitlementAccessPollServiceEntitlementInfoList() { diff --git a/core/libs/tests/GuestOfflineImports.cpp b/core/libs/tests/GuestOfflineImports.cpp index 6f064ed6261..5e2cc1218dc 100644 --- a/core/libs/tests/GuestOfflineImports.cpp +++ b/core/libs/tests/GuestOfflineImports.cpp @@ -21,6 +21,8 @@ int APS5_VABI sceNpEntitlementAccessRequestUnifiedEntitlementInfo(); int APS5_VABI sceNpEntitlementAccessPollUnifiedEntitlementInfo(); int APS5_VABI sceNpEntitlementAccessRequestServiceEntitlementInfo(); int APS5_VABI sceNpEntitlementAccessPollServiceEntitlementInfo(); +int APS5_VABI sceNpEntitlementAccessGetPftFlag(); +int APS5_VABI sceNpEntitlementAccessGetGameTrialsFlag(); int APS5_VABI sceRudpInit_nid_postfix(void*, int); int APS5_VABI sceRudpActivate(); int APS5_VABI sceRudpGetStatus(void*, std::size_t); @@ -75,6 +77,8 @@ int main() { Require(sceNpEntitlementAccessPollUnifiedEntitlementInfo() == signedOut); Require(sceNpEntitlementAccessRequestServiceEntitlementInfo() == signedOut); Require(sceNpEntitlementAccessPollServiceEntitlementInfo() == signedOut); + Require(sceNpEntitlementAccessGetPftFlag() == signedOut); + Require(sceNpEntitlementAccessGetGameTrialsFlag() == signedOut); Require(sceRudpActivate() == 0); std::array status; From 22e96c516eb17aaaea61f56cacfdc1fffef57a26 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:52:12 +0000 Subject: [PATCH 03/16] feat(libSceNpSessionSignaling): report unavailable for connection queries --- .../prx/libSceNpSessionSignaling/Export.cpp | 22 ++++++++----------- core/libs/tests/GuestNpSessionSignaling.cpp | 12 ++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/core/libs/prx/libSceNpSessionSignaling/Export.cpp b/core/libs/prx/libSceNpSessionSignaling/Export.cpp index b694abb6f27..3db7293f64a 100644 --- a/core/libs/prx/libSceNpSessionSignaling/Export.cpp +++ b/core/libs/prx/libSceNpSessionSignaling/Export.cpp @@ -58,13 +58,12 @@ int APS5_VABI sceNpSessionSignalingTerminate(void) { } int32_t APS5_VABI sceNpSessionSignalingGetConnectionStatus(int32_t context_id, int32_t connection_id, int32_t* status, void* peer_address, uint16_t* peer_port) { - (void)context_id; - (void)connection_id; - (void)status; - (void)peer_address; - (void)peer_port; - NotImplemented_nid_no_patch(__func__); - return 0; + (void)context_id; + (void)connection_id; + (void)peer_address; + (void)peer_port; + if (!status) return SCE_NP_SESSION_SIGNALING_ERROR_INVALID_ARGUMENT; + return SCE_NP_SESSION_SIGNALING_ERROR_UNAVAILABLE; } int32_t APS5_VABI sceNpSessionSignalingGetLocalNetInfo(int32_t context_id, void* info) { @@ -80,18 +79,15 @@ int APS5_VABI sceNpSessionSignalingRequestPrepare(uint32_t contextId, uint32_t* } int APS5_VABI sceNpSessionSignalingGetMemoryInfo(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return SCE_NP_SESSION_SIGNALING_ERROR_UNAVAILABLE; } int APS5_VABI sceNpSessionSignalingGetConnectionStatistics(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return SCE_NP_SESSION_SIGNALING_ERROR_UNAVAILABLE; } int APS5_VABI sceNpSessionSignalingGetConnectionFromPeerAddress(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return SCE_NP_SESSION_SIGNALING_ERROR_UNAVAILABLE; } int APS5_VABI sceNpSessionSignalingGetGroupFromSessionId(void) { diff --git a/core/libs/tests/GuestNpSessionSignaling.cpp b/core/libs/tests/GuestNpSessionSignaling.cpp index 834f15fb467..4a910f4ed45 100644 --- a/core/libs/tests/GuestNpSessionSignaling.cpp +++ b/core/libs/tests/GuestNpSessionSignaling.cpp @@ -9,6 +9,10 @@ int APS5_VABI sceNpSessionSignalingInitialize(void* param); int APS5_VABI sceNpSessionSignalingCreateContext2(const void* param, std::uint32_t* contextId); std::int32_t APS5_VABI sceNpSessionSignalingGetLocalNetInfo(std::int32_t contextId, void* info); int APS5_VABI sceNpSessionSignalingRequestPrepare(std::uint32_t contextId, std::uint32_t* requestId); +std::int32_t APS5_VABI sceNpSessionSignalingGetConnectionStatus(std::int32_t contextId, std::int32_t connectionId, std::int32_t* status, void* peerAddress, std::uint16_t* peerPort); +int APS5_VABI sceNpSessionSignalingGetMemoryInfo(); +int APS5_VABI sceNpSessionSignalingGetConnectionStatistics(); +int APS5_VABI sceNpSessionSignalingGetConnectionFromPeerAddress(); int APS5_VABI sceNpSessionSignalingTerminate(void); } @@ -47,5 +51,13 @@ int main() { Require(sceNpSessionSignalingGetLocalNetInfo(netContextId, info) == Unavailable, "local net info without network"); Require(std::memcmp(info, untouched, sizeof(info)) == 0, "failed query modified the info"); + std::int32_t status = 0x5a5a5a5a; + Require(sceNpSessionSignalingGetConnectionStatus(netContextId, 0, nullptr, nullptr, nullptr) == InvalidArgument, "null status"); + Require(sceNpSessionSignalingGetConnectionStatus(netContextId, 0, &status, nullptr, nullptr) == Unavailable, "connection status without network"); + Require(status == 0x5a5a5a5a, "failed status query modified the status"); + Require(sceNpSessionSignalingGetMemoryInfo() == Unavailable, "memory info without network"); + Require(sceNpSessionSignalingGetConnectionStatistics() == Unavailable, "connection statistics without network"); + Require(sceNpSessionSignalingGetConnectionFromPeerAddress() == Unavailable, "connection from peer without network"); + Require(sceNpSessionSignalingTerminate() == 0, "terminate failed"); } From dabc0dc32c7f56f744eb7aef738cd4373f09e1b6 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:52:59 +0000 Subject: [PATCH 04/16] feat(libSceGameUpdate): reject null entitlement label as invalid argument --- core/libs/prx/libSceGameUpdate/Export.cpp | 5 +---- core/libs/tests/GuestGameUpdate.cpp | 6 +----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/core/libs/prx/libSceGameUpdate/Export.cpp b/core/libs/prx/libSceGameUpdate/Export.cpp index 4c0d0bb575f..f5a4741dba5 100644 --- a/core/libs/prx/libSceGameUpdate/Export.cpp +++ b/core/libs/prx/libSceGameUpdate/Export.cpp @@ -40,12 +40,9 @@ int APS5_VABI sceGameUpdateGetAddcontLatestVersion(uint32_t service_label, const if (!g_initialized.load()) { return SCE_GAME_UPDATE_ERROR_NOT_INITIALIZED; } - if (info == nullptr) { + if (info == nullptr || entitlement_label == nullptr) { return SCE_GAME_UPDATE_ERROR_INVALID_ARGUMENT; } - if (entitlement_label == nullptr) { - NotImplemented_nid_no_patch(__func__); - } if (info->size < sizeof(GameUpdateAddcontVersionInfo)) { return SCE_GAME_UPDATE_ERROR_INVALID_SIZE; } diff --git a/core/libs/tests/GuestGameUpdate.cpp b/core/libs/tests/GuestGameUpdate.cpp index 12aa20e5970..29d45bc6403 100644 --- a/core/libs/tests/GuestGameUpdate.cpp +++ b/core/libs/tests/GuestGameUpdate.cpp @@ -26,11 +26,7 @@ int main() { Require(sceGameUpdateGetAddcontLatestVersion(0, label, &info) == notInitialized); Require(sceGameUpdateInitialize() == 0); Require(sceGameUpdateGetAddcontLatestVersion(0, label, nullptr) == invalidArgument); - - bool threw = false; - try { sceGameUpdateGetAddcontLatestVersion(0, nullptr, &info); } - catch (const std::runtime_error&) { threw = true; } - Require(threw); + Require(sceGameUpdateGetAddcontLatestVersion(0, nullptr, &info) == invalidArgument); info.size = sizeof(info) - 1; Require(sceGameUpdateGetAddcontLatestVersion(0, label, &info) == invalidSize); From 0d5bacd791378a661d685c668fe89aafe3c8dcff Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:53:18 +0000 Subject: [PATCH 05/16] feat(libSceNpAuth): implement id-token, wait-async and request creation --- core/libs/prx/libSceNpAuth/CMakeLists.txt | 14 +++++++ core/libs/prx/libSceNpAuth/Export.cpp | 14 +++---- core/libs/tests/GuestNpAuth.cpp | 46 +++++++++++++++++++++++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 core/libs/prx/libSceNpAuth/CMakeLists.txt create mode 100644 core/libs/tests/GuestNpAuth.cpp diff --git a/core/libs/prx/libSceNpAuth/CMakeLists.txt b/core/libs/prx/libSceNpAuth/CMakeLists.txt new file mode 100644 index 00000000000..ba05a11bc37 --- /dev/null +++ b/core/libs/prx/libSceNpAuth/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(libSceNpAuth SHARED EXCLUDE_FROM_ALL Export.cpp) +target_include_directories(libSceNpAuth PRIVATE ${LIBS_INCLUDE_DIR}) +configure_windows_unwind(libSceNpAuth) + +if(BUILD_TESTING) + add_test_executable(guest_np_auth_tests ${LIBS_INCLUDE_DIR}/tests/GuestNpAuth.cpp) + target_include_directories(guest_np_auth_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_np_auth_tests PRIVATE libSceNpAuth) + add_test(NAME guest_np_auth COMMAND guest_np_auth_tests) + if(WIN32) + set_tests_properties(guest_np_auth PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() +endif() diff --git a/core/libs/prx/libSceNpAuth/Export.cpp b/core/libs/prx/libSceNpAuth/Export.cpp index 1ef3f03a69f..0de3af5d1ed 100644 --- a/core/libs/prx/libSceNpAuth/Export.cpp +++ b/core/libs/prx/libSceNpAuth/Export.cpp @@ -23,8 +23,7 @@ int APS5_VABI sceNpAuthCreateAsyncRequest(const void* param) { } int APS5_VABI sceNpAuthCreateRequest(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return g_nextRequest.fetch_add(1, std::memory_order_relaxed); } int APS5_VABI sceNpAuthDeleteRequest(int req_id) { @@ -41,10 +40,8 @@ int APS5_VABI sceNpAuthGetAuthorizationCodeV3(int req_id, const void* param, voi int APS5_VABI sceNpAuthGetIdTokenV3(int req_id, const void* param, void* id_token) { (void)req_id; - (void)param; - (void)id_token; - NotImplemented_nid_no_patch(__func__); - return 0; + if (!param || !id_token) return SCE_NP_ERROR_INVALID_ARGUMENT; + return SCE_NP_ERROR_SIGNED_OUT; } int APS5_VABI sceNpAuthPollAsync(int req_id, int* result) { @@ -55,9 +52,8 @@ int APS5_VABI sceNpAuthPollAsync(int req_id, int* result) { int APS5_VABI sceNpAuthWaitAsync(int req_id, int* result) { (void)req_id; - (void)result; - NotImplemented_nid_no_patch(__func__); - return 0; + if (result) *result = SCE_NP_ERROR_SIGNED_OUT; + return NP_POLL_ASYNC_FINISHED; } } diff --git a/core/libs/tests/GuestNpAuth.cpp b/core/libs/tests/GuestNpAuth.cpp new file mode 100644 index 00000000000..91fe22e365c --- /dev/null +++ b/core/libs/tests/GuestNpAuth.cpp @@ -0,0 +1,46 @@ +#include "SceTypes.hpp" +#include +#include + +extern "C" { +int APS5_VABI sceNpAuthCreateRequest(); +int APS5_VABI sceNpAuthDeleteRequest(int reqId); +int APS5_VABI sceNpAuthGetIdTokenV3(int reqId, const void* param, void* idToken); +int APS5_VABI sceNpAuthPollAsync(int reqId, int* result); +int APS5_VABI sceNpAuthWaitAsync(int reqId, int* result); +} + +namespace { + +void Require(bool value) { if (!value) std::abort(); } + +constexpr int kInvalidArgument = static_cast(0x80550003); +constexpr int kSignedOut = static_cast(0x80550006); +constexpr int kPollFinished = 0; + +} + +int main() { + const int request = sceNpAuthCreateRequest(); + const int other = sceNpAuthCreateRequest(); + Require(request > 0 && other > 0 && request != other); + + std::uint64_t param = 0; + std::uint64_t token = 0; + Require(sceNpAuthGetIdTokenV3(request, nullptr, &token) == kInvalidArgument); + Require(sceNpAuthGetIdTokenV3(request, ¶m, nullptr) == kInvalidArgument); + Require(sceNpAuthGetIdTokenV3(request, ¶m, &token) == kSignedOut); + + int result = 0x5a5a5a5a; + Require(sceNpAuthPollAsync(request, nullptr) == kPollFinished); + Require(sceNpAuthPollAsync(request, &result) == kPollFinished); + Require(result == kSignedOut); + result = 0x5a5a5a5a; + Require(sceNpAuthWaitAsync(request, nullptr) == kPollFinished); + Require(sceNpAuthWaitAsync(request, &result) == kPollFinished); + Require(result == kSignedOut); + + Require(sceNpAuthDeleteRequest(request) == 0); + Require(sceNpAuthDeleteRequest(other) == 0); + return 0; +} From f4b4b3ab2b9c2ebd74b55ea8352f5c95ccc8abf4 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:53:46 +0000 Subject: [PATCH 06/16] feat(libSceNpManager): accept presence callback and content restriction --- core/libs/prx/libSceNpManager/Export.cpp | 5 ++--- core/libs/tests/GuestNpManager.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/core/libs/prx/libSceNpManager/Export.cpp b/core/libs/prx/libSceNpManager/Export.cpp index a384c220231..0cce4e5be4e 100644 --- a/core/libs/prx/libSceNpManager/Export.cpp +++ b/core/libs/prx/libSceNpManager/Export.cpp @@ -4,6 +4,7 @@ #include "prx/libc/include/General.hpp" #include #include +#include #include // PSN is not emulated: the user is reported as signed out and online queries fail. @@ -138,9 +139,8 @@ int APS5_VABI sceNpPollAsync(int req_id, int* result) { } void APS5_VABI sceNpRegisterGamePresenceCallback(void* callback, void* userdata) { - (void)callback; (void)userdata; - NotImplemented_nid_no_patch(__func__); + if (!callback) throw std::invalid_argument("sceNpRegisterGamePresenceCallback: null callback"); } int APS5_VABI sceNpRegisterNpReachabilityStateCallback(void* callback, void* userdata) { @@ -180,7 +180,6 @@ int APS5_VABI sceNpRegisterStateCallback(void* callback, void* userdata) { int APS5_VABI sceNpSetContentRestriction(const NpContentRestriction* restriction) { (void)restriction; - NotImplemented_nid_no_patch(__func__); return 0; } diff --git a/core/libs/tests/GuestNpManager.cpp b/core/libs/tests/GuestNpManager.cpp index eaa8a77d45d..614a24bddd4 100644 --- a/core/libs/tests/GuestNpManager.cpp +++ b/core/libs/tests/GuestNpManager.cpp @@ -4,11 +4,17 @@ #include #include #include +#include extern "C" { int APS5_VABI sceNpGetNpId(int user_id, NpId* np_id); } +extern "C" { +void APS5_VABI sceNpRegisterGamePresenceCallback(void* callback, void* userdata); +int APS5_VABI sceNpSetContentRestriction(const NpContentRestriction* restriction); +} + extern "C" { int APS5_VABI sceNpCreateRequest(void); int APS5_VABI sceNpCreateAsyncRequest(const NpCreateAsyncRequestParameter* param); @@ -67,5 +73,16 @@ int main() { Require(sceNpGetNpId(0x10000, &npId) == SignedOut, "sceNpGetNpId must report the user as signed out"); Require(std::memcmp(&npId, &untouched, sizeof(npId)) == 0, "sceNpGetNpId must leave the NpId untouched"); Require(sceNpGetNpId(0x10000, nullptr) == InvalidArgument, "sceNpGetNpId must reject a null NpId"); + bool presenceRejectedNull = false; + try { + sceNpRegisterGamePresenceCallback(nullptr, nullptr); + } catch (const std::invalid_argument&) { + presenceRejectedNull = true; + } + Require(presenceRejectedNull, "sceNpRegisterGamePresenceCallback must reject a null callback"); + sceNpRegisterGamePresenceCallback(reinterpret_cast(&presenceRejectedNull), nullptr); + NpContentRestriction restriction{}; + Require(sceNpSetContentRestriction(nullptr) == 0, "sceNpSetContentRestriction must accept a null restriction"); + Require(sceNpSetContentRestriction(&restriction) == 0, "sceNpSetContentRestriction must accept a restriction"); return 0; } From b6300b963eada4717234745f416056d1855fd6db Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:54:35 +0000 Subject: [PATCH 07/16] feat(libSceShare.native): mirror no-capture status model from libSceShare --- .../prx/libSceShare.native/CMakeLists.txt | 14 ++++++ core/libs/prx/libSceShare.native/Export.cpp | 33 ++++++++----- core/libs/tests/GuestShareNative.cpp | 47 +++++++++++++++++++ 3 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 core/libs/prx/libSceShare.native/CMakeLists.txt create mode 100644 core/libs/tests/GuestShareNative.cpp diff --git a/core/libs/prx/libSceShare.native/CMakeLists.txt b/core/libs/prx/libSceShare.native/CMakeLists.txt new file mode 100644 index 00000000000..848cafa5220 --- /dev/null +++ b/core/libs/prx/libSceShare.native/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(libSceShare.native SHARED EXCLUDE_FROM_ALL Export.cpp) +target_include_directories(libSceShare.native PRIVATE ${LIBS_INCLUDE_DIR}) +configure_windows_unwind(libSceShare.native) + +if(BUILD_TESTING) + add_test_executable(guest_share_native_tests ${LIBS_INCLUDE_DIR}/tests/GuestShareNative.cpp) + target_include_directories(guest_share_native_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_share_native_tests PRIVATE libSceShare.native) + add_test(NAME guest_share_native COMMAND guest_share_native_tests) + if(WIN32) + set_tests_properties(guest_share_native PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() +endif() diff --git a/core/libs/prx/libSceShare.native/Export.cpp b/core/libs/prx/libSceShare.native/Export.cpp index 2d8f2cf3613..82e491b3df6 100644 --- a/core/libs/prx/libSceShare.native/Export.cpp +++ b/core/libs/prx/libSceShare.native/Export.cpp @@ -1,24 +1,35 @@ #include #include +#include #include "SceTypes.hpp" #include "prx/libc/include/General.hpp" // Capture and sharing are not emulated; policy and parameter calls are accepted. +namespace { + +constexpr std::int32_t ERROR_INVALID_PARAM = static_cast(0x81960002); +constexpr std::int32_t ERROR_NOT_SUPPORTED = static_cast(0x81960007); +constexpr std::int32_t REQUEST_ID_INVALID = -1; + +} + extern "C" { int APS5_VABI sceShareCaptureScreenshot(const void* param, int32_t* req_id) { (void)param; - (void)req_id; - NotImplemented_nid_no_patch(__func__); - return 0; + if (req_id != nullptr) { + *req_id = REQUEST_ID_INVALID; + } + return ERROR_NOT_SUPPORTED; } int APS5_VABI sceShareCaptureVideoClip(const void* param, int32_t* req_id) { (void)param; - (void)req_id; - NotImplemented_nid_no_patch(__func__); - return 0; + if (req_id != nullptr) { + *req_id = REQUEST_ID_INVALID; + } + return ERROR_NOT_SUPPORTED; } int APS5_VABI sceShareFeaturePermit(uint32_t feature_flags) { @@ -32,9 +43,10 @@ int APS5_VABI sceShareFeatureProhibit(uint32_t feature_flags) { } int APS5_VABI sceShareGetCurrentStatus(uint32_t feature_flag, ShareCurrentStatus* status) { - (void)feature_flag; - (void)status; - NotImplemented_nid_no_patch(__func__); + if (feature_flag == 0 || status == nullptr) { + return ERROR_INVALID_PARAM; + } + std::memset(status, 0, sizeof(*status)); return 0; } @@ -47,8 +59,7 @@ int APS5_VABI sceShareInitialize(size_t heap_size, int thread_priority, uint64_t int APS5_VABI sceShareOpenMenuForContent(const void* content_id) { (void)content_id; - NotImplemented_nid_no_patch(__func__); - return 0; + return ERROR_NOT_SUPPORTED; } int APS5_VABI sceShareRegisterContentEventCallback(void* callback, void* user_data) { diff --git a/core/libs/tests/GuestShareNative.cpp b/core/libs/tests/GuestShareNative.cpp new file mode 100644 index 00000000000..bcdcc6ba0d7 --- /dev/null +++ b/core/libs/tests/GuestShareNative.cpp @@ -0,0 +1,47 @@ +#include "prx/libc/include/general/VabiMacros.hpp" +#include +#include +#include + +extern "C" { +int APS5_VABI sceShareCaptureScreenshot(const void* param, std::int32_t* req_id); +int APS5_VABI sceShareCaptureVideoClip(const void* param, std::int32_t* req_id); +int APS5_VABI sceShareGetCurrentStatus(std::uint32_t feature_flag, void* status); +int APS5_VABI sceShareOpenMenuForContent(const void* content_id); +} + +namespace { + +void Require(bool value) { if (!value) std::abort(); } + +} + +int main() { + constexpr std::int32_t notSupported = static_cast(0x81960007); + std::uint8_t param[64]{}; + + using Capture = int (APS5_VABI*)(const void*, std::int32_t*); + for (Capture capture : {sceShareCaptureScreenshot, sceShareCaptureVideoClip}) { + std::int32_t reqId = 7; + Require(capture(param, &reqId) == notSupported); + Require(reqId == -1); + reqId = 7; + Require(capture(nullptr, &reqId) == notSupported); + Require(reqId == -1); + Require(capture(param, nullptr) == notSupported); + } + + Require(sceShareOpenMenuForContent(param) == notSupported); + Require(sceShareOpenMenuForContent(nullptr) == notSupported); + + constexpr std::int32_t invalidParam = static_cast(0x81960002); + std::uint8_t status[18]; + std::memset(status, 0x5a, sizeof(status)); + Require(sceShareGetCurrentStatus(1, status) == 0); + for (std::size_t index = 0; index < sizeof(status); ++index) Require(status[index] == (index < 16 ? 0 : 0x5a)); + std::memset(status, 0x5a, sizeof(status)); + Require(sceShareGetCurrentStatus(0, status) == invalidParam); + Require(status[0] == 0x5a); + Require(sceShareGetCurrentStatus(1, nullptr) == invalidParam); + return 0; +} From 12f2904e5676784875d169f17460c8e54224a20b Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:54:35 +0000 Subject: [PATCH 08/16] feat(libSceShare): report extended video-clip capture unsupported --- core/libs/prx/libSceShare/Export.cpp | 3 +-- core/libs/tests/GuestShare.cpp | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/libs/prx/libSceShare/Export.cpp b/core/libs/prx/libSceShare/Export.cpp index 0c609afb1d6..4d01fd3ce37 100644 --- a/core/libs/prx/libSceShare/Export.cpp +++ b/core/libs/prx/libSceShare/Export.cpp @@ -106,8 +106,7 @@ int APS5_VABI sceShareCaptureScreenshotExtended(const void* extended_param, int3 int APS5_VABI sceShareCaptureVideoClipExtended(void) { - NotImplemented_nid_no_patch(__func__); - return 0; + return ERROR_NOT_SUPPORTED; } int APS5_VABI sceShareGetRunningStatus(uint32_t* status) { diff --git a/core/libs/tests/GuestShare.cpp b/core/libs/tests/GuestShare.cpp index 400e2f5a734..231e5071615 100644 --- a/core/libs/tests/GuestShare.cpp +++ b/core/libs/tests/GuestShare.cpp @@ -10,6 +10,7 @@ int APS5_VABI sceShareCaptureScreenshot(const void* param, std::int32_t* req_id) int APS5_VABI sceShareCaptureVideoClip(const void* param, std::int32_t* req_id); int APS5_VABI sceShareGetCurrentStatus(std::uint32_t feature_flag, void* status); int APS5_VABI sceShareOpenMenuForContent(const void* content_id); +int APS5_VABI sceShareCaptureVideoClipExtended(void); int APS5_VABI sceShareGetRunningStatus(std::uint32_t* status); int APS5_VABI sceShareSetContentParamForApplicationTitle(const char* application_title); } @@ -48,6 +49,7 @@ int main() { Require(sceShareOpenMenuForContent(param) == notSupported); Require(sceShareOpenMenuForContent(nullptr) == notSupported); + Require(sceShareCaptureVideoClipExtended() == notSupported); constexpr std::int32_t invalidParam = static_cast(0x81960002); std::uint8_t status[18]; From 2e1f7019ec4333b304e09ad4bdc01d5c1c13e60c Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:54:53 +0000 Subject: [PATCH 09/16] feat(libSceIme): validate open parameters, report panel unavailable --- core/libs/prx/libSceIme/Export.cpp | 7 ++++--- core/libs/tests/GuestImeParameters.cpp | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/core/libs/prx/libSceIme/Export.cpp b/core/libs/prx/libSceIme/Export.cpp index 4675c980f53..c0db798ff98 100644 --- a/core/libs/prx/libSceIme/Export.cpp +++ b/core/libs/prx/libSceIme/Export.cpp @@ -87,10 +87,11 @@ int APS5_VABI sceImeKeyboardSetMode(int32_t user_id, uint32_t mode) { } int APS5_VABI sceImeOpen_nid_postfix(const Param* param, const ExtendedParam* extended) { - (void)param; (void)extended; - NotImplemented_nid_no_patch(__func__); - return 0; + if (param == nullptr) return ErrorInvalidAddress; + if (param->type > TypeNumber) return ErrorInvalidType; + if ((param->option & ~ValidOptions) != 0) return ErrorInvalidOption; + return ErrorNotOpened; } void APS5_VABI sceImeParamInit(Param* param) { diff --git a/core/libs/tests/GuestImeParameters.cpp b/core/libs/tests/GuestImeParameters.cpp index 23f590a389c..5f2590b3260 100644 --- a/core/libs/tests/GuestImeParameters.cpp +++ b/core/libs/tests/GuestImeParameters.cpp @@ -15,6 +15,7 @@ int APS5_VABI sceImeSetTextGeometry(TextAreaMode mode, const TextGeometry* geome int APS5_VABI sceImeKeyboardOpen(int32_t user_id, const KeyboardParam* param); int APS5_VABI sceImeKeyboardClose(int32_t user_id); int APS5_VABI sceImeKeyboardGetResourceId(int32_t user_id, KeyboardResourceIdArray* resource_ids); +int APS5_VABI sceImeOpen_nid_postfix(const Param* param, const void* extended); } static_assert(sizeof(Param) == 96); @@ -154,10 +155,27 @@ static void CheckKeyboardResourceIds() { Require(sceImeKeyboardGetResourceId(1, &ids) == NotOpened, "closed keyboard reported as opened"); } +static void CheckOpen() { + constexpr int NotOpened = static_cast(0x80bc0002u); + constexpr int InvalidAddress = static_cast(0x80bc0031u); + constexpr int InvalidType = static_cast(0x80bc0011u); + constexpr int InvalidOption = static_cast(0x80bc0015u); + Param param{}; + Require(sceImeOpen_nid_postfix(nullptr, nullptr) == InvalidAddress, "null open parameter"); + param.type = 5; + Require(sceImeOpen_nid_postfix(¶m, nullptr) == InvalidType, "invalid open type"); + param.type = 0; + param.option = 0x8000; + Require(sceImeOpen_nid_postfix(¶m, nullptr) == InvalidOption, "invalid open option"); + param.option = 0; + Require(sceImeOpen_nid_postfix(¶m, nullptr) == NotOpened, "open needs a panel backend"); +} + int main() { CheckInitialization(); CheckPanelSizes(); CheckErrors(); CheckClosedPanel(); CheckKeyboardResourceIds(); + CheckOpen(); } From 992799b38b24cb10f8f96ada8e3138a6c2303454 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:55:02 +0000 Subject: [PATCH 10/16] feat(libSceNpPartner001): track EA access initialization state --- .../prx/libSceNpPartner001/CMakeLists.txt | 14 +++++++++++ core/libs/prx/libSceNpPartner001/Export.cpp | 13 ++++++++-- core/libs/tests/GuestNpPartner.cpp | 24 +++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 core/libs/prx/libSceNpPartner001/CMakeLists.txt create mode 100644 core/libs/tests/GuestNpPartner.cpp diff --git a/core/libs/prx/libSceNpPartner001/CMakeLists.txt b/core/libs/prx/libSceNpPartner001/CMakeLists.txt new file mode 100644 index 00000000000..72d8983ef73 --- /dev/null +++ b/core/libs/prx/libSceNpPartner001/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(libSceNpPartner001 SHARED EXCLUDE_FROM_ALL Export.cpp) +target_include_directories(libSceNpPartner001 PRIVATE ${LIBS_INCLUDE_DIR}) +configure_windows_unwind(libSceNpPartner001) + +if(BUILD_TESTING) + add_test_executable(guest_np_partner_tests ${LIBS_INCLUDE_DIR}/tests/GuestNpPartner.cpp) + target_include_directories(guest_np_partner_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_np_partner_tests PRIVATE libSceNpPartner001) + add_test(NAME guest_np_partner COMMAND guest_np_partner_tests) + if(WIN32) + set_tests_properties(guest_np_partner PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() +endif() diff --git a/core/libs/prx/libSceNpPartner001/Export.cpp b/core/libs/prx/libSceNpPartner001/Export.cpp index 74e81b2df47..5dc24a6e656 100644 --- a/core/libs/prx/libSceNpPartner001/Export.cpp +++ b/core/libs/prx/libSceNpPartner001/Export.cpp @@ -1,14 +1,23 @@ #include "prx/libc/include/General.hpp" +#include + +namespace { + +constexpr int SCE_NP_PARTNER_ERROR_NOT_INITIALIZED = static_cast(0x819d0001); + +std::atomic g_initialized{false}; + +} extern "C" { int APS5_VABI sceNpEAAccessInitialize(void) { - NotImplemented_nid_no_patch(__func__); + g_initialized.store(true, std::memory_order_relaxed); return 0; } int APS5_VABI sceNpEAAccessTerminate(void) { - NotImplemented_nid_no_patch(__func__); + if (!g_initialized.exchange(false, std::memory_order_relaxed)) return SCE_NP_PARTNER_ERROR_NOT_INITIALIZED; return 0; } diff --git a/core/libs/tests/GuestNpPartner.cpp b/core/libs/tests/GuestNpPartner.cpp new file mode 100644 index 00000000000..0765a06b9ca --- /dev/null +++ b/core/libs/tests/GuestNpPartner.cpp @@ -0,0 +1,24 @@ +#include "prx/libc/include/general/VabiMacros.hpp" +#include + +extern "C" { +int APS5_VABI sceNpEAAccessInitialize(); +int APS5_VABI sceNpEAAccessTerminate(); +} + +namespace { + +void Require(bool value) { if (!value) std::abort(); } + +constexpr int kNotInitialized = static_cast(0x819d0001); + +} + +int main() { + Require(sceNpEAAccessTerminate() == kNotInitialized); + Require(sceNpEAAccessInitialize() == 0); + Require(sceNpEAAccessInitialize() == 0); + Require(sceNpEAAccessTerminate() == 0); + Require(sceNpEAAccessTerminate() == kNotInitialized); + return 0; +} From 50cb224ab63419c4b3f99ac53764646e1505ccb0 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:55:53 +0000 Subject: [PATCH 11/16] feat(libSceSystemGesture): report no-touch results for id and info queries --- core/libs/prx/libSceSystemGesture/Export.cpp | 29 +++++++++----------- core/libs/tests/GuestSystemGesture.cpp | 14 ++++++++++ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/core/libs/prx/libSceSystemGesture/Export.cpp b/core/libs/prx/libSceSystemGesture/Export.cpp index 9c71e1031b6..e57413e3bc4 100644 --- a/core/libs/prx/libSceSystemGesture/Export.cpp +++ b/core/libs/prx/libSceSystemGesture/Export.cpp @@ -42,11 +42,10 @@ int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByIndex(int32_t gesture_hand } int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(int32_t gesture_handle, uint16_t primitiveId, SystemGesturePrimitiveTouchEvent* event) { - (void)gesture_handle; - (void)primitiveId; - (void)event; - NotImplemented_nid_no_patch(__func__); - return 0; + (void)primitiveId; + (void)event; + if (gesture_handle != GESTURE_HANDLE) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE; + return SCE_SYSTEM_GESTURE_ERROR_INDEX_OUT_OF_ARRAY; } int APS5_VABI sceSystemGestureGetPrimitiveTouchEvents(int32_t gesture_handle, SystemGesturePrimitiveTouchEvent* event_buffer, uint32_t capacity_of_buffer, uint32_t* number_of_event) { @@ -63,12 +62,11 @@ int APS5_VABI sceSystemGestureGetPrimitiveTouchEventsCount(int32_t gesture_handl } int APS5_VABI sceSystemGestureGetTouchEventByEventID(int32_t gesture_handle, const SystemGestureTouchRecognizer* recognizer, uint32_t eventId, SystemGestureTouchEvent* event) { - (void)gesture_handle; - (void)recognizer; - (void)eventId; - (void)event; - NotImplemented_nid_no_patch(__func__); - return 0; + (void)recognizer; + (void)eventId; + (void)event; + if (gesture_handle != GESTURE_HANDLE) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE; + return SCE_SYSTEM_GESTURE_ERROR_INDEX_OUT_OF_ARRAY; } int APS5_VABI sceSystemGestureGetTouchEventByIndex(int32_t gesture_handle, const SystemGestureTouchRecognizer* recognizer, uint32_t index, SystemGestureTouchEvent* event) { @@ -95,11 +93,10 @@ int APS5_VABI sceSystemGestureGetTouchEventsCount(int32_t gesture_handle, const } int APS5_VABI sceSystemGestureGetTouchRecognizerInformation(int32_t gesture_handle, const SystemGestureTouchRecognizer* recognizer, SystemGestureTouchRecognizerInformation* information) { - (void)gesture_handle; - (void)recognizer; - (void)information; - NotImplemented_nid_no_patch(__func__); - return 0; + if (gesture_handle != GESTURE_HANDLE) return SCE_SYSTEM_GESTURE_ERROR_INVALID_HANDLE; + if (!recognizer || !information) return SCE_SYSTEM_GESTURE_ERROR_INVALID_ARGUMENT; + *information = SystemGestureTouchRecognizerInformation{}; + return 0; } int APS5_VABI sceSystemGestureInitializePrimitiveTouchRecognizer(const void* param) { diff --git a/core/libs/tests/GuestSystemGesture.cpp b/core/libs/tests/GuestSystemGesture.cpp index 037b9e885ac..dcffa8c4277 100644 --- a/core/libs/tests/GuestSystemGesture.cpp +++ b/core/libs/tests/GuestSystemGesture.cpp @@ -10,6 +10,9 @@ int APS5_VABI sceSystemGestureGetPrimitiveTouchEvents(std::int32_t, void*, std:: int APS5_VABI sceSystemGestureGetPrimitiveTouchEventsCount(std::int32_t); int APS5_VABI sceSystemGestureGetTouchEvents(std::int32_t, const void*, void*, std::uint32_t, std::uint32_t*); int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByIndex(std::int32_t, std::uint32_t, void*); +int APS5_VABI sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(std::int32_t, std::uint16_t, void*); +int APS5_VABI sceSystemGestureGetTouchEventByEventID(std::int32_t, const void*, std::uint32_t, void*); +int APS5_VABI sceSystemGestureGetTouchRecognizerInformation(std::int32_t, const void*, void*); int APS5_VABI sceSystemGestureAppendTouchRecognizer(std::int32_t, void*); int APS5_VABI sceSystemGestureRemoveTouchRecognizer(std::int32_t, void*); int APS5_VABI sceSystemGestureResetTouchRecognizer(std::int32_t, void*); @@ -52,6 +55,17 @@ int main() { Require(sceSystemGestureGetTouchEvents(handle + 1, &recognizer, buffer.data(), 4, &count) == invalidHandle); Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle, 0, buffer.data()) == indexOutOfArray); Require(sceSystemGestureGetPrimitiveTouchEventByIndex(handle + 1, 0, buffer.data()) == invalidHandle); + Require(sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(handle, 0, buffer.data()) == indexOutOfArray); + Require(sceSystemGestureGetPrimitiveTouchEventByPrimitiveID(handle + 1, 0, buffer.data()) == invalidHandle); + Require(sceSystemGestureGetTouchEventByEventID(handle, &recognizer, 0, buffer.data()) == indexOutOfArray); + Require(sceSystemGestureGetTouchEventByEventID(handle + 1, &recognizer, 0, buffer.data()) == invalidHandle); + std::array info; + info.fill(0x5a); + Require(sceSystemGestureGetTouchRecognizerInformation(handle, &recognizer, info.data()) == 0); + for (unsigned char byte : info) Require(byte == 0); + Require(sceSystemGestureGetTouchRecognizerInformation(handle + 1, &recognizer, info.data()) == invalidHandle); + Require(sceSystemGestureGetTouchRecognizerInformation(handle, nullptr, info.data()) == invalidArgument); + Require(sceSystemGestureGetTouchRecognizerInformation(handle, &recognizer, nullptr) == invalidArgument); Require(buffer == original); Require(sceSystemGestureAppendTouchRecognizer(handle, &recognizer) == 0); From 779e394d673051d9aaac4f404afcd0c07d064e4c Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:57:25 +0000 Subject: [PATCH 12/16] feat(libSceAudioOut): accept system debug state without backend --- core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp | 1 - core/libs/prx/libSceAudioOut/tests/AudioOut2Latency.cpp | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp b/core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp index dff79652802..b04a042f61c 100644 --- a/core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp +++ b/core/libs/prx/libSceAudioOut/src/AudioOut2System.cpp @@ -25,7 +25,6 @@ int APS5_VABI sceAudioOut2GetSystemState(AudioOut2SystemState* state) { int APS5_VABI sceAudioOut2SetSystemDebugState(const AudioOut2SystemDebugStateParam* param) { (void)param; - NotImplemented_nid_no_patch(__func__); return 0; } diff --git a/core/libs/prx/libSceAudioOut/tests/AudioOut2Latency.cpp b/core/libs/prx/libSceAudioOut/tests/AudioOut2Latency.cpp index 5f6eea7b10e..46935eedde7 100644 --- a/core/libs/prx/libSceAudioOut/tests/AudioOut2Latency.cpp +++ b/core/libs/prx/libSceAudioOut/tests/AudioOut2Latency.cpp @@ -11,6 +11,7 @@ int APS5_VABI sceAudioOut2Set3DLatency(int, std::uint32_t); int APS5_VABI sceAudioOut2MasteringInit(std::uint32_t); int APS5_VABI sceAudioOut2MasteringTerm(); int APS5_VABI sceAudioOut2MasteringSetParam(const void*, std::uint32_t, std::uint32_t); +int APS5_VABI sceAudioOut2SetSystemDebugState(const void*); } static void Require(bool value, const char* message) { @@ -60,6 +61,12 @@ void TestMasteringSetParam() { Require(ThrowsRuntimeError([] { sceAudioOut2MasteringSetParam(nullptr, 0, 0); }), "null mastering parameters must throw"); } +void TestSystemDebugState() { + const std::uint32_t param[4] = {0u, 0u, 0u, 0u}; + Require(sceAudioOut2SetSystemDebugState(param) == 0, "debug state must be accepted"); + Require(sceAudioOut2SetSystemDebugState(nullptr) == 0, "null debug state must be accepted"); +} + } int main() { @@ -68,5 +75,6 @@ int main() { TestMasteringInit(); TestMasteringTerm(); TestMasteringSetParam(); + TestSystemDebugState(); return 0; } From 1864ee4ea08b1552500a7a4f147756b42b955e5d Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 14:57:53 +0000 Subject: [PATCH 13/16] feat(libSceNpWebApi2): accept request timeout without backend --- core/libs/prx/libSceNpWebApi2/Export.cpp | 1 - core/libs/tests/GuestNpWebApi2.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceNpWebApi2/Export.cpp b/core/libs/prx/libSceNpWebApi2/Export.cpp index 75c95918794..d694a1c8894 100644 --- a/core/libs/prx/libSceNpWebApi2/Export.cpp +++ b/core/libs/prx/libSceNpWebApi2/Export.cpp @@ -186,7 +186,6 @@ int APS5_VABI sceNpWebApi2PushEventUnregisterPushContextCallback() { } int APS5_VABI sceNpWebApi2SetRequestTimeout() { - NotImplemented_nid_no_patch(__func__); return 0; } diff --git a/core/libs/tests/GuestNpWebApi2.cpp b/core/libs/tests/GuestNpWebApi2.cpp index ea167e65481..841eaf64605 100644 --- a/core/libs/tests/GuestNpWebApi2.cpp +++ b/core/libs/tests/GuestNpWebApi2.cpp @@ -15,6 +15,7 @@ extern "C" { int APS5_VABI sceNpWebApi2Initialize(int, std::size_t); int APS5_VABI sceNpWebApi2Terminate(int); int APS5_VABI sceNpWebApi2GetMemoryPoolStats(int, NpWebApi2MemoryPoolStats*); +int APS5_VABI sceNpWebApi2SetRequestTimeout(); } static void Require(bool value) { if (!value) std::abort(); } @@ -40,6 +41,7 @@ int main() { Require(Throws([&] { sceNpWebApi2GetMemoryPoolStats(context, nullptr); })); Require(sceNpWebApi2Terminate(context) == 0); Require(Throws([&] { sceNpWebApi2GetMemoryPoolStats(context, &stats); })); + Require(sceNpWebApi2SetRequestTimeout() == 0); Require(sceNpWebApi2Terminate(other) == 0); return 0; } From 63f8d15e209a55e905424d00b91b2fb317a59270 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 22:01:46 +0000 Subject: [PATCH 14/16] feat(libSceNet): complete synchronous resolver abort as no-op --- core/libs/prx/libSceNet/Export.cpp | 1 - core/libs/tests/GuestSceNet.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/core/libs/prx/libSceNet/Export.cpp b/core/libs/prx/libSceNet/Export.cpp index 3bfaa1229ac..d0795f7bc25 100644 --- a/core/libs/prx/libSceNet/Export.cpp +++ b/core/libs/prx/libSceNet/Export.cpp @@ -1257,7 +1257,6 @@ int APS5_VABI sceNetResolverGetError(int rid, int* status) { } int APS5_VABI sceNetResolverAbort(void) { - NotImplemented_nid_no_patch(__func__); return 0; } diff --git a/core/libs/tests/GuestSceNet.cpp b/core/libs/tests/GuestSceNet.cpp index 1579e664560..a2d6823bdba 100644 --- a/core/libs/tests/GuestSceNet.cpp +++ b/core/libs/tests/GuestSceNet.cpp @@ -52,6 +52,7 @@ int APS5_VABI sceNetResolverStartNtoa(int, const char*, void*, int, int, int); int APS5_VABI sceNetResolverStartNtoaMultipleRecordsEx(int, const char*, void*, int, int, int); int APS5_VABI sceNetResolverDestroy(int); int APS5_VABI sceNetResolverGetError(int, int*); +int APS5_VABI sceNetResolverAbort(); int APS5_VABI sceNetCtlGetState(int*); int APS5_VABI select_nid_postfix(int, void*, void*, void*, const void*); int APS5_VABI open_nid_postfix(const char*, int, int); @@ -505,6 +506,7 @@ int main() { static_cast(0x804101E1) && records == resolved); Require(sceNetResolverGetError(resolver, nullptr) == static_cast(0x80410116) && *sceNetErrnoLoc() == 22); Require(sceNetResolverDestroy(resolver) == 0); + Require(sceNetResolverAbort() == 0); resolver_error = -1; Require(sceNetResolverGetError(resolver, &resolver_error) == static_cast(0x80410109) && *sceNetErrnoLoc() == 9 && resolver_error == -1); From 9e3cb3f58f622b6ec83f66e7a66eb99cd9fb1074 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 22:15:12 +0000 Subject: [PATCH 15/16] revert(libSceNpAuth): drop offline auth requests, covered by #3604 --- core/libs/prx/libSceNpAuth/CMakeLists.txt | 14 ------- core/libs/prx/libSceNpAuth/Export.cpp | 14 ++++--- core/libs/tests/GuestNpAuth.cpp | 46 ----------------------- 3 files changed, 9 insertions(+), 65 deletions(-) delete mode 100644 core/libs/prx/libSceNpAuth/CMakeLists.txt delete mode 100644 core/libs/tests/GuestNpAuth.cpp diff --git a/core/libs/prx/libSceNpAuth/CMakeLists.txt b/core/libs/prx/libSceNpAuth/CMakeLists.txt deleted file mode 100644 index ba05a11bc37..00000000000 --- a/core/libs/prx/libSceNpAuth/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -add_library(libSceNpAuth SHARED EXCLUDE_FROM_ALL Export.cpp) -target_include_directories(libSceNpAuth PRIVATE ${LIBS_INCLUDE_DIR}) -configure_windows_unwind(libSceNpAuth) - -if(BUILD_TESTING) - add_test_executable(guest_np_auth_tests ${LIBS_INCLUDE_DIR}/tests/GuestNpAuth.cpp) - target_include_directories(guest_np_auth_tests PRIVATE ${LIBS_INCLUDE_DIR}) - target_link_libraries(guest_np_auth_tests PRIVATE libSceNpAuth) - add_test(NAME guest_np_auth COMMAND guest_np_auth_tests) - if(WIN32) - set_tests_properties(guest_np_auth PROPERTIES ENVIRONMENT_MODIFICATION - "PATH=path_list_prepend:$") - endif() -endif() diff --git a/core/libs/prx/libSceNpAuth/Export.cpp b/core/libs/prx/libSceNpAuth/Export.cpp index 0de3af5d1ed..1ef3f03a69f 100644 --- a/core/libs/prx/libSceNpAuth/Export.cpp +++ b/core/libs/prx/libSceNpAuth/Export.cpp @@ -23,7 +23,8 @@ int APS5_VABI sceNpAuthCreateAsyncRequest(const void* param) { } int APS5_VABI sceNpAuthCreateRequest(void) { - return g_nextRequest.fetch_add(1, std::memory_order_relaxed); + NotImplemented_nid_no_patch(__func__); + return 0; } int APS5_VABI sceNpAuthDeleteRequest(int req_id) { @@ -40,8 +41,10 @@ int APS5_VABI sceNpAuthGetAuthorizationCodeV3(int req_id, const void* param, voi int APS5_VABI sceNpAuthGetIdTokenV3(int req_id, const void* param, void* id_token) { (void)req_id; - if (!param || !id_token) return SCE_NP_ERROR_INVALID_ARGUMENT; - return SCE_NP_ERROR_SIGNED_OUT; + (void)param; + (void)id_token; + NotImplemented_nid_no_patch(__func__); + return 0; } int APS5_VABI sceNpAuthPollAsync(int req_id, int* result) { @@ -52,8 +55,9 @@ int APS5_VABI sceNpAuthPollAsync(int req_id, int* result) { int APS5_VABI sceNpAuthWaitAsync(int req_id, int* result) { (void)req_id; - if (result) *result = SCE_NP_ERROR_SIGNED_OUT; - return NP_POLL_ASYNC_FINISHED; + (void)result; + NotImplemented_nid_no_patch(__func__); + return 0; } } diff --git a/core/libs/tests/GuestNpAuth.cpp b/core/libs/tests/GuestNpAuth.cpp deleted file mode 100644 index 91fe22e365c..00000000000 --- a/core/libs/tests/GuestNpAuth.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "SceTypes.hpp" -#include -#include - -extern "C" { -int APS5_VABI sceNpAuthCreateRequest(); -int APS5_VABI sceNpAuthDeleteRequest(int reqId); -int APS5_VABI sceNpAuthGetIdTokenV3(int reqId, const void* param, void* idToken); -int APS5_VABI sceNpAuthPollAsync(int reqId, int* result); -int APS5_VABI sceNpAuthWaitAsync(int reqId, int* result); -} - -namespace { - -void Require(bool value) { if (!value) std::abort(); } - -constexpr int kInvalidArgument = static_cast(0x80550003); -constexpr int kSignedOut = static_cast(0x80550006); -constexpr int kPollFinished = 0; - -} - -int main() { - const int request = sceNpAuthCreateRequest(); - const int other = sceNpAuthCreateRequest(); - Require(request > 0 && other > 0 && request != other); - - std::uint64_t param = 0; - std::uint64_t token = 0; - Require(sceNpAuthGetIdTokenV3(request, nullptr, &token) == kInvalidArgument); - Require(sceNpAuthGetIdTokenV3(request, ¶m, nullptr) == kInvalidArgument); - Require(sceNpAuthGetIdTokenV3(request, ¶m, &token) == kSignedOut); - - int result = 0x5a5a5a5a; - Require(sceNpAuthPollAsync(request, nullptr) == kPollFinished); - Require(sceNpAuthPollAsync(request, &result) == kPollFinished); - Require(result == kSignedOut); - result = 0x5a5a5a5a; - Require(sceNpAuthWaitAsync(request, nullptr) == kPollFinished); - Require(sceNpAuthWaitAsync(request, &result) == kPollFinished); - Require(result == kSignedOut); - - Require(sceNpAuthDeleteRequest(request) == 0); - Require(sceNpAuthDeleteRequest(other) == 0); - return 0; -} From 7b2c5a76a44db8ac2f258eab596b227b1a363102 Mon Sep 17 00:00:00 2001 From: Akram Zekri Date: Sun, 11 Oct 2026 22:15:12 +0000 Subject: [PATCH 16/16] revert(libSceNpPartner001): drop EA access state, covered by #3718 --- .../prx/libSceNpPartner001/CMakeLists.txt | 14 ----------- core/libs/prx/libSceNpPartner001/Export.cpp | 13 ++-------- core/libs/tests/GuestNpPartner.cpp | 24 ------------------- 3 files changed, 2 insertions(+), 49 deletions(-) delete mode 100644 core/libs/prx/libSceNpPartner001/CMakeLists.txt delete mode 100644 core/libs/tests/GuestNpPartner.cpp diff --git a/core/libs/prx/libSceNpPartner001/CMakeLists.txt b/core/libs/prx/libSceNpPartner001/CMakeLists.txt deleted file mode 100644 index 72d8983ef73..00000000000 --- a/core/libs/prx/libSceNpPartner001/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -add_library(libSceNpPartner001 SHARED EXCLUDE_FROM_ALL Export.cpp) -target_include_directories(libSceNpPartner001 PRIVATE ${LIBS_INCLUDE_DIR}) -configure_windows_unwind(libSceNpPartner001) - -if(BUILD_TESTING) - add_test_executable(guest_np_partner_tests ${LIBS_INCLUDE_DIR}/tests/GuestNpPartner.cpp) - target_include_directories(guest_np_partner_tests PRIVATE ${LIBS_INCLUDE_DIR}) - target_link_libraries(guest_np_partner_tests PRIVATE libSceNpPartner001) - add_test(NAME guest_np_partner COMMAND guest_np_partner_tests) - if(WIN32) - set_tests_properties(guest_np_partner PROPERTIES ENVIRONMENT_MODIFICATION - "PATH=path_list_prepend:$") - endif() -endif() diff --git a/core/libs/prx/libSceNpPartner001/Export.cpp b/core/libs/prx/libSceNpPartner001/Export.cpp index 5dc24a6e656..74e81b2df47 100644 --- a/core/libs/prx/libSceNpPartner001/Export.cpp +++ b/core/libs/prx/libSceNpPartner001/Export.cpp @@ -1,23 +1,14 @@ #include "prx/libc/include/General.hpp" -#include - -namespace { - -constexpr int SCE_NP_PARTNER_ERROR_NOT_INITIALIZED = static_cast(0x819d0001); - -std::atomic g_initialized{false}; - -} extern "C" { int APS5_VABI sceNpEAAccessInitialize(void) { - g_initialized.store(true, std::memory_order_relaxed); + NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI sceNpEAAccessTerminate(void) { - if (!g_initialized.exchange(false, std::memory_order_relaxed)) return SCE_NP_PARTNER_ERROR_NOT_INITIALIZED; + NotImplemented_nid_no_patch(__func__); return 0; } diff --git a/core/libs/tests/GuestNpPartner.cpp b/core/libs/tests/GuestNpPartner.cpp deleted file mode 100644 index 0765a06b9ca..00000000000 --- a/core/libs/tests/GuestNpPartner.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "prx/libc/include/general/VabiMacros.hpp" -#include - -extern "C" { -int APS5_VABI sceNpEAAccessInitialize(); -int APS5_VABI sceNpEAAccessTerminate(); -} - -namespace { - -void Require(bool value) { if (!value) std::abort(); } - -constexpr int kNotInitialized = static_cast(0x819d0001); - -} - -int main() { - Require(sceNpEAAccessTerminate() == kNotInitialized); - Require(sceNpEAAccessInitialize() == 0); - Require(sceNpEAAccessInitialize() == 0); - Require(sceNpEAAccessTerminate() == 0); - Require(sceNpEAAccessTerminate() == kNotInitialized); - return 0; -}