diff --git a/core/libs/prx/libSceAppContent/Export.cpp b/core/libs/prx/libSceAppContent/Export.cpp index ed74e8f72..d36481e95 100644 --- a/core/libs/prx/libSceAppContent/Export.cpp +++ b/core/libs/prx/libSceAppContent/Export.cpp @@ -93,6 +93,15 @@ int APS5_VABI sceAppContentAppParamGetInt(uint32_t param_id, int32_t* value) { } } +int APS5_VABI sceAppContentDownloadDataFormat(const AppContentMountPoint* mount_point) { + if (!mount_point) return SCE_APP_CONTENT_ERROR_PARAMETER; + if (std::strncmp(mount_point->data, DOWNLOAD_MOUNT_POINT, sizeof(mount_point->data)) != 0) APS5_INVALID_ARG_EX; + const auto directory = ResolvePath_nid_no_patch(DOWNLOAD_MOUNT_POINT); + if (std::filesystem::create_directories(directory)) RecordWrittenPath_nid_no_patch(directory); + ClearDirectory(directory); + return 0; +} + int APS5_VABI sceAppContentDownloadDataGetAvailableSpaceKb(const AppContentMountPoint* mount_point, size_t* available_space_kb) { if (!available_space_kb) return SCE_APP_CONTENT_ERROR_PARAMETER; if (!mount_point || std::strncmp(mount_point->data, DOWNLOAD_MOUNT_POINT, sizeof(mount_point->data)) != 0) APS5_INVALID_ARG_EX; diff --git a/core/libs/prx/libSceAudioOut/src/AudioOut.cpp b/core/libs/prx/libSceAudioOut/src/AudioOut.cpp index c8adb77b2..d607319a3 100644 --- a/core/libs/prx/libSceAudioOut/src/AudioOut.cpp +++ b/core/libs/prx/libSceAudioOut/src/AudioOut.cpp @@ -499,6 +499,11 @@ int APS5_VABI sceAudioOutGetPortState(int handle, AudioOutPortState* state) { return 0; } +int APS5_VABI sceAudioOutDeviceIdOpen() { + NotImplemented_nid_no_patch(__func__); + return 0; +} + int APS5_VABI sceAudioOutSysClose() { NotImplemented_nid_no_patch(__func__); return 0; diff --git a/core/libs/prx/libSceNpAuth/Export.cpp b/core/libs/prx/libSceNpAuth/Export.cpp index 21e28519a..94a17e460 100644 --- a/core/libs/prx/libSceNpAuth/Export.cpp +++ b/core/libs/prx/libSceNpAuth/Export.cpp @@ -110,6 +110,16 @@ int APS5_VABI sceNpAuthPollAsync(int req_id, int* result) { return NP_POLL_ASYNC_FINISHED; } +int APS5_VABI sceNpAuthSetTimeout(int req_id, int resolve_retry, uint32_t resolve_timeout, uint32_t connect_timeout, uint32_t send_timeout, uint32_t receive_timeout) { + (void)resolve_retry; + (void)resolve_timeout; + (void)connect_timeout; + (void)send_timeout; + (void)receive_timeout; + std::lock_guard lock(g_requestMutex); + return g_requests.contains(req_id) ? 0 : ORBIS_NP_AUTH_ERROR_REQUEST_NOT_FOUND; +} + int APS5_VABI sceNpAuthWaitAsync(int req_id, int* result) { if (!result) return ORBIS_NP_AUTH_ERROR_INVALID_ARGUMENT; std::lock_guard lock(g_requestMutex); diff --git a/core/libs/prx/libSceNpWebApi2/Export.cpp b/core/libs/prx/libSceNpWebApi2/Export.cpp index 806accdb3..6bffefa39 100644 --- a/core/libs/prx/libSceNpWebApi2/Export.cpp +++ b/core/libs/prx/libSceNpWebApi2/Export.cpp @@ -174,6 +174,14 @@ int APS5_VABI sceNpWebApi2PushEventDeleteFilter() { return 0; } +int APS5_VABI sceNpWebApi2PushEventSetHandleTimeout(int lib_ctx_id, int handle_id, uint32_t timeout) { + (void)handle_id; + (void)timeout; + std::lock_guard lock(g_poolsMutex); + if (!g_pools.contains(lib_ctx_id)) throw std::invalid_argument("sceNpWebApi2PushEventSetHandleTimeout: unknown context"); + return 0; +} + int APS5_VABI sceNpWebApi2PushEventRegisterPushContextCallback() { return g_nextHandle.fetch_add(1, std::memory_order_relaxed); } diff --git a/core/libs/prx/libScePsml_debug/Export.cpp b/core/libs/prx/libScePsml_debug/Export.cpp index e7326689c..bec0b00b8 100644 --- a/core/libs/prx/libScePsml_debug/Export.cpp +++ b/core/libs/prx/libScePsml_debug/Export.cpp @@ -155,4 +155,16 @@ int APS5_VABI scePsmlMfsr2Init() { return 0; } +APS5_EXPORT("xNZM9Y5lf-M", scePsmlUnknown01); +int APS5_VABI scePsmlUnknown01(void) { + NotImplemented_nid_no_patch("xNZM9Y5lf-M"); + return 0; +} + +APS5_EXPORT("lcZD9tJraAw", scePsmlUnknown02); +int APS5_VABI scePsmlUnknown02(void) { + NotImplemented_nid_no_patch("lcZD9tJraAw"); + return 0; +} + } diff --git a/core/libs/prx/libSceSsl/Export.cpp b/core/libs/prx/libSceSsl/Export.cpp index 4b3e23a4e..85a921b8e 100644 --- a/core/libs/prx/libSceSsl/Export.cpp +++ b/core/libs/prx/libSceSsl/Export.cpp @@ -134,6 +134,26 @@ int APS5_VABI sceSslFreeSslCertName(void) { return 0; } +int APS5_VABI sceSslDisableVerifyOption(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslGetAlpnSelected(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslSetAlpn(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslSetMinSslVersion(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + int APS5_VABI sceSslGetIssuerName(void) { NotImplemented_nid_no_patch(__func__); return 0; diff --git a/core/libs/prx/libSceUsbStorage/Export.cpp b/core/libs/prx/libSceUsbStorage/Export.cpp new file mode 100644 index 000000000..fb34206c2 --- /dev/null +++ b/core/libs/prx/libSceUsbStorage/Export.cpp @@ -0,0 +1,10 @@ +#include +#include +#include "SceTypes.hpp" +#include "prx/libc/include/General.hpp" + +extern "C" { + +APS5_DUMMY_FUN + +} diff --git a/core/libs/prx/libSceUsbStorageDialog/Export.cpp b/core/libs/prx/libSceUsbStorageDialog/Export.cpp new file mode 100644 index 000000000..fb34206c2 --- /dev/null +++ b/core/libs/prx/libSceUsbStorageDialog/Export.cpp @@ -0,0 +1,10 @@ +#include +#include +#include "SceTypes.hpp" +#include "prx/libc/include/General.hpp" + +extern "C" { + +APS5_DUMMY_FUN + +} diff --git a/core/libs/tests/GuestAppContent.cpp b/core/libs/tests/GuestAppContent.cpp index 6780ff814..93154a94e 100644 --- a/core/libs/tests/GuestAppContent.cpp +++ b/core/libs/tests/GuestAppContent.cpp @@ -19,6 +19,7 @@ int* APS5_VABI __error_nid_postfix(); int APS5_VABI sceAppContentGetAddcontInfo(uint32_t, const NpUnifiedEntitlementLabel*, void*); int APS5_VABI sceAppContentGetAddcontInfoList(uint32_t, void*, uint32_t, uint32_t*); int APS5_VABI sceAppContentDownloadDataGetAvailableSpaceKb(const AppContentMountPoint*, size_t*); +int APS5_VABI sceAppContentDownloadDataFormat(const AppContentMountPoint*); int APS5_VABI sceAppContentAppParamGetInt(uint32_t, int32_t*); } @@ -47,6 +48,16 @@ int main() { Require(sceAppContentDownloadDataGetAvailableSpaceKb(&download, &availableKb) == 0); Require(availableKb == 0); Require(sceAppContentDownloadDataGetAvailableSpaceKb(&download, nullptr) == ErrorParameter); + const auto downloadData = ResolvePath_nid_no_patch("/download0"); + Require(sceAppContentDownloadDataFormat(&download) == 0); + Require(std::filesystem::is_directory(downloadData) && std::filesystem::is_empty(downloadData)); + std::filesystem::create_directory(downloadData / "cache"); + { std::ofstream file(downloadData / "cache" / "old.bin"); file << "downloaded"; } + { std::ofstream file(downloadData / "index.dat"); file << "downloaded"; } + Require(sceAppContentDownloadDataFormat(nullptr) == ErrorParameter); + Require(std::filesystem::exists(downloadData / "index.dat")); + Require(sceAppContentDownloadDataFormat(&download) == 0); + Require(std::filesystem::is_directory(downloadData) && std::filesystem::is_empty(downloadData)); const int32_t expectedParams[] = {3, 23566, -7, 0, 2147483647}; for (uint32_t id = 0; id < 5; ++id) { diff --git a/core/libs/tests/GuestNpAuth.cpp b/core/libs/tests/GuestNpAuth.cpp index dea50561d..f99ceafb2 100644 --- a/core/libs/tests/GuestNpAuth.cpp +++ b/core/libs/tests/GuestNpAuth.cpp @@ -11,6 +11,7 @@ int APS5_VABI sceNpAuthDeleteRequest(int req_id); int APS5_VABI sceNpAuthGetAuthorizationCodeV3(int req_id, const void* param, void* auth_code, int* issuer_id); int APS5_VABI sceNpAuthGetIdTokenV3(int req_id, const void* param, void* id_token); int APS5_VABI sceNpAuthPollAsync(int req_id, int* result); +int APS5_VABI sceNpAuthSetTimeout(int req_id, int resolve_retry, uint32_t resolve_timeout, uint32_t connect_timeout, uint32_t send_timeout, uint32_t receive_timeout); int APS5_VABI sceNpAuthWaitAsync(int req_id, int* result); } @@ -42,6 +43,9 @@ int main() { alignas(8) char authCode[16] = {}; int issuerId = 0; + Require(sceNpAuthSetTimeout(syncReq, 2, 5000000, 10000000, 10000000, 10000000) == 0); + Require(sceNpAuthSetTimeout(asyncReq, 0, 0, 0, 0, 0) == 0); + int pollUnprocessed = 0; Require(sceNpAuthPollAsync(asyncReq, &pollUnprocessed) == invalidId); int waitUnprocessed = 0; @@ -79,6 +83,7 @@ int main() { Require(sceNpAuthPollAsync(unknownReq, &pollResult) == requestNotFound); int waitResult = 0; Require(sceNpAuthWaitAsync(unknownReq, &waitResult) == requestNotFound); + Require(sceNpAuthSetTimeout(unknownReq, 2, 5000000, 10000000, 10000000, 10000000) == requestNotFound); Require(sceNpAuthWaitAsync(syncReq, nullptr) == invalidArgument); Require(sceNpAuthWaitAsync(syncReq, &waitResult) == invalidId); @@ -99,6 +104,7 @@ int main() { Require(sceNpAuthDeleteRequest(syncReq) == 0); Require(sceNpAuthGetIdTokenV3(syncReq, param, token) == requestNotFound); Require(sceNpAuthWaitAsync(syncReq, &waitResult) == requestNotFound); + Require(sceNpAuthSetTimeout(syncReq, 2, 5000000, 10000000, 10000000, 10000000) == requestNotFound); return 0; } diff --git a/core/libs/tests/GuestNpWebApi2.cpp b/core/libs/tests/GuestNpWebApi2.cpp index ea167e654..3f31d7d99 100644 --- a/core/libs/tests/GuestNpWebApi2.cpp +++ b/core/libs/tests/GuestNpWebApi2.cpp @@ -15,6 +15,8 @@ extern "C" { int APS5_VABI sceNpWebApi2Initialize(int, std::size_t); int APS5_VABI sceNpWebApi2Terminate(int); int APS5_VABI sceNpWebApi2GetMemoryPoolStats(int, NpWebApi2MemoryPoolStats*); +int APS5_VABI sceNpWebApi2PushEventCreateHandle(int); +int APS5_VABI sceNpWebApi2PushEventSetHandleTimeout(int, int, std::uint32_t); } static void Require(bool value) { if (!value) std::abort(); } @@ -38,8 +40,12 @@ int main() { Require(stats.pool_size == 0x20000 && stats.max_inuse_size == 0 && stats.current_inuse_size == 0 && stats.reserved == 0); Require(sceNpWebApi2GetMemoryPoolStats(other, &stats) == 0 && stats.pool_size == 0x8000); Require(Throws([&] { sceNpWebApi2GetMemoryPoolStats(context, nullptr); })); + const int handle = sceNpWebApi2PushEventCreateHandle(context); + Require(handle > 0); + Require(sceNpWebApi2PushEventSetHandleTimeout(context, handle, 30000) == 0); Require(sceNpWebApi2Terminate(context) == 0); Require(Throws([&] { sceNpWebApi2GetMemoryPoolStats(context, &stats); })); + Require(Throws([&] { sceNpWebApi2PushEventSetHandleTimeout(context, handle, 30000); })); Require(sceNpWebApi2Terminate(other) == 0); return 0; } diff --git a/docs/dev/debt/libSceAppContent.md b/docs/dev/debt/libSceAppContent.md index 8830908bf..b5d7f0010 100644 --- a/docs/dev/debt/libSceAppContent.md +++ b/docs/dev/debt/libSceAppContent.md @@ -4,6 +4,7 @@ - [sceAppContentDownloadDataGetAvailableSpaceKb](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - a title whose `param.json` declares `downloadDataSize` 0 gets 0 KB and OK; the console's behaviour for a title without a download data area is unverified (it may return an error instead). KytyPS5 does not special-case it, and shadPS4 stubs 1048576 KB - [sceAppContentGetAddcontDownloadProgress](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - imported by PPSA08755, which fails to load without it; added without an implementation because its behavior is unverified. [SharpProspero](https://github.com/SvenGDK/SharpProspero) lists `(uint32_t serviceLabel, entitlementLabel, SceAppContentAddcontDownloadProgress*)`, but no PS5 reference gives the progress layout or the error codes +- [sceAppContentDownloadDataFormat](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - empties the `/download0` directory, creating it if needed. Imported by PPSA01317. A null mount point returns `PARAMETER` as `sceAppContentTemporaryDataFormat` does, and another mount point throws as in `sceAppContentDownloadDataGetAvailableSpaceKb`; the console's error codes for both and its behaviour with files still open are unverified ### Functional diff --git a/docs/dev/debt/libSceAudioOut.md b/docs/dev/debt/libSceAudioOut.md index 1903f8dc1..171cf4c46 100644 --- a/docs/dev/debt/libSceAudioOut.md +++ b/docs/dev/debt/libSceAudioOut.md @@ -15,6 +15,7 @@ - [sceAudioOut2PortCreate](../../../core/libs/prx/libSceAudioOut/src/AudioOut2Port.cpp) (libSceAudioOut) - 12 channels are assumed to be L R C LFE Ls Rs Lb Rb Ltf Rtf Ltb Rtb as in KytyPS5's 12-to-8 fold, and 6 and 8 channels to be its first 6 and 8; no title or SDK header confirms the order - [sceAudioOut2PortCreate](../../../core/libs/prx/libSceAudioOut/src/AudioOut2Port.cpp) (libSceAudioOut) - the stereo fold is assumed, not the console's downmix: C at -3 dB into both sides, Ls/Rs, Lb/Rb and Ltf/Rtf at -3 dB and Ltb/Rtb at -6 dB into their own side, LFE dropped - [sceAudioOut2PortSetAttributes](../../../core/libs/prx/libSceAudioOut/src/AudioOut2Port.cpp) (libSceAudioOut) - each PCM buffer set (attribute 0) is taken as one grain: buffers set between two pushes are queued and played one per grain, at most 16 queued. A grain with no new buffer repeats the last one only when the port has always been given that same buffer (rewritten in place); a port whose buffers move on plays silence instead. Inferred from PPSA12544, whose object port (type 6) is given one grain of a 64-grain ring per set, often two or three between pushes and then none for a few; the console behaviour for several sets per push and for a push without a new buffer is not documented +- [sceAudioOutDeviceIdOpen](../../../core/libs/prx/libSceAudioOut/src/AudioOut.cpp) (libSceAudioOut) - imported by PPSA01317, which fails to load without it; declared without parameters, signature unknown. It opens a port on a given audio device; which device ids exist and how they map to host outputs is unknown, so it throws ### Functional diff --git a/docs/dev/debt/libSceNpAuth.md b/docs/dev/debt/libSceNpAuth.md index a4964a44d..8e344dfda 100644 --- a/docs/dev/debt/libSceNpAuth.md +++ b/docs/dev/debt/libSceNpAuth.md @@ -4,3 +4,4 @@ - [sceNpAuthGetAuthorizedAppCode](../../../core/libs/prx/libSceNpAuth/Export.cpp) (libSceNpAuth) - declared without parameters and returns `SCE_NP_ERROR_SIGNED_OUT` without reading them, as there is no PSN sign-in; the request parameter and code output are not known. Minecraft (PPSA17221) imports it, fails to load without it, and after its sign-in dialog treats the signed-out code as offline play. - [sceNpAuthAbortRequest, sceNpAuthGetAuthorizationCodeV3, sceNpAuthGetIdTokenV3, sceNpAuthPollAsync, sceNpAuthWaitAsync](../../../core/libs/prx/libSceNpAuth/Export.cpp) (libSceNpAuth) - request tracking, `ORBIS_NP_AUTH_ERROR_REQUEST_NOT_FOUND` (0x80550306) on unknown request IDs, `ORBIS_NP_AUTH_ERROR_INVALID_ID` (0x80550307) on non-async or unprocessed requests in Poll/Wait, `ORBIS_NP_AUTH_ERROR_INVALID_ARGUMENT` (0x80550301) on null arguments and repeated calls on completed requests, and `ORBIS_NP_AUTH_ERROR_ABORTED` (0x80550304) after an abort follow [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/np/np_auth.cpp) (PS4); async requests return OK and defer `SCE_NP_ERROR_SIGNED_OUT` to `sceNpAuthPollAsync`/`sceNpAuthWaitAsync` while sync requests fail immediately; PlayStation Network is not contacted. The parameter `size` fields are not checked (`ORBIS_NP_AUTH_ERROR_INVALID_SIZE`, structure layouts unknown), the request table has no limit (`ORBIS_NP_AUTH_ERROR_REQUEST_MAX`), and console behavior on PS5 is unverified +- [sceNpAuthSetTimeout](../../../core/libs/prx/libSceNpAuth/Export.cpp) (libSceNpAuth) - imported by PPSA01317, which fails to load without it. The signature `(reqId, resolveRetry, resolveTimeout, connTimeout, sendTimeout, recvTimeout)` follows [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/np/np_auth.cpp) (PS4), which only stubs it. An unknown request ID returns `ORBIS_NP_AUTH_ERROR_REQUEST_NOT_FOUND` like the other request calls; otherwise it returns OK and keeps nothing, as no request reaches the network the timeouts would bound. Argument checks of the console are unverified diff --git a/docs/dev/debt/libSceNpWebApi2.md b/docs/dev/debt/libSceNpWebApi2.md index d42b614ee..148b2634e 100644 --- a/docs/dev/debt/libSceNpWebApi2.md +++ b/docs/dev/debt/libSceNpWebApi2.md @@ -4,3 +4,4 @@ - [sceNpWebApi2PushEventAbortHandle](../../../core/libs/prx/libSceNpWebApi2/Export.cpp) (libSceNpWebApi2, NID `1OLgvahaSco`) is a throwing stub. The two signed 32-bit handle arguments and return type follow [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/443f022450f6857256e780daa3d5a14029a748f7/src/core/libraries/np/np_web_api2/np_web_api2.cpp) (PS4); the PS5 signature and abort behavior are unverified. PPSA01736 imports it. - [sceNpWebApi2GetMemoryPoolStats](../../../core/libs/prx/libSceNpWebApi2/Export.cpp) (libSceNpWebApi2) - imported by PPSA21703's Unity PSN plugin. The signature `(int libCtxId, stats*)` and the layout of the Http2 statistics above (measured on a PS5 for Http2, Ssl and Net) are assumed for this library, not measured. The pool size is the one given to `sceNpWebApi2Initialize`, and the peak and current use are 0. The error codes are unknown, so a null output or an unknown context throws +- [sceNpWebApi2PushEventSetHandleTimeout](../../../core/libs/prx/libSceNpWebApi2/Export.cpp) (libSceNpWebApi2) - imported by PPSA01317, which fails to load without it. The signature `(int libCtxId, int handleId, uint32_t timeout)` follows `sceNpWebApiSetHandleTimeout` of the PS4 libSceNpWebApi in [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/np/np_web_api.cpp) and is unverified on the PS5. An unknown library context throws, as in `sceNpWebApi2GetMemoryPoolStats`, since its error code is unknown. The handle is not checked, as push event handles are not tracked (`sceNpWebApi2PushEventDeleteHandle` accepts any handle), and the timeout is not kept, as nothing waits on a handle offline diff --git a/docs/dev/debt/libScePsml_debug.md b/docs/dev/debt/libScePsml_debug.md index 476e359f8..9dd2ab63c 100644 --- a/docs/dev/debt/libScePsml_debug.md +++ b/docs/dev/debt/libScePsml_debug.md @@ -6,3 +6,4 @@ - [scePsmlMfsrGetContextBufferRequirement1100, scePsmlMfsrCreateContext1100, scePsmlMfsrGetDispatchMfsrPacket1100](../../../core/libs/prx/libScePsml_debug/Export.cpp) (libScePsml_debug) - argument layouts unknown; only 0x8A810001 (not initialized) is returned - [scePsmlMfsrGetDispatchMfsrPacket1000](../../../core/libs/prx/libScePsml_debug/Export.cpp) (libScePsml) - unknown signature, imported by PPSA25344; declared without parameters. libScePsml and libScePsml_debug are built from the same source - [scePsmlMfsrCreateContext1300, scePsmlMfsrGetDispatchMfsrPacket1300](../../../core/libs/prx/libScePsml_debug/Export.cpp) (libScePsml) - unknown signatures, imported by PPSA28416 next to `scePsmlMfsrGetContextBufferRequirement1100`; declared without parameters. The names are not in the aerolib NID list; they hash to the imported NIDs `kLF7WtQ1-Dg` and `DDVUyPyYHTA` (`tools/nid_names.py`) +- [NIDs `xNZM9Y5lf-M` and `lcZD9tJraAw`](../../../core/libs/prx/libScePsml_debug/Export.cpp) (libScePsml_specularAA and libScePsml_quality8K, exported as `scePsmlUnknown01` and `scePsmlUnknown02`) - imported by PPSA01317, which fails to load without them; names and signatures unknown (not in the aerolib NID list), so they throw diff --git a/docs/dev/debt/libSceSsl.md b/docs/dev/debt/libSceSsl.md index 6f5759fbc..202dcbce0 100644 --- a/docs/dev/debt/libSceSsl.md +++ b/docs/dev/debt/libSceSsl.md @@ -5,6 +5,7 @@ - [sceSslClose](../../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl) - unknown signature - [sceSslGetSerialNumber](../../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl) - unknown signature - [sceSslGetCaList, sceSslFreeCaList, sceSslUnloadCert](../../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl) - signatures and the 16-byte `SceSslCaList` layout (an array of certificate handles and a 32-bit count) follow [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/5dfdb4b0b166e83dc9ae275001afb695f12c7174/src/SharpProspero/Interop/Net/Http.cs) and shadPS4's `OrbisSslCaList`, not confirmed for the PS5. On the console the list holds the certificate authorities the SSL service has; [shadPS4](https://github.com/shadps4-emu/shadPS4/pull/4104) returns a placeholder certificate from `sceSslGetCaCerts` because Rise of the Tomb Raider fails its initialization checks without one. No root certificate bundle is shipped and no loaded certificate is kept, so here a context holds none: `sceSslGetCaList` clears the list and returns `NOT_FOUND`, as `sceSslGetCaCerts` does, `sceSslFreeCaList` accepts only that cleared list, and `sceSslUnloadCert` (imported by PPSA15508) has nothing to drop and is assumed to return 0. A null list returns `0x8095177A`, which `sceSslGetCaCerts` and [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/59183dbfa81ed7efdff6069177fed50de0552725/src/libs/network.cpp) return for a null argument (shadPS4, PS4, returns `0x8095F007`). An unknown context throws (KytyPS5 returns `SSL_ERROR_INVALID_ID`, `0x8095F006`, from `sceSslGetCaCerts`), and so does a list `sceSslGetCaList` did not return +- PPSA01317 imports declared without parameters, signatures unknown: [sceSslDisableVerifyOption, sceSslGetAlpnSelected, sceSslSetAlpn, sceSslSetMinSslVersion](../../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl). They act on a connection, which `sceSslCreateConnection` does not create yet, so they throw until connections exist ### Functional