diff --git a/core/libs/prx/libSceConvertKeycode/Export.cpp b/core/libs/prx/libSceConvertKeycode/Export.cpp index 2ac60a0cd..ec43b33b0 100644 --- a/core/libs/prx/libSceConvertKeycode/Export.cpp +++ b/core/libs/prx/libSceConvertKeycode/Export.cpp @@ -27,4 +27,9 @@ int APS5_VABI sceConvertKeycodeGetCharacterFromKeyboardData(void) { return 0; } +int APS5_VABI sceConvertKeycodeGetCharacter(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + } diff --git a/core/libs/prx/libSceJson2/Export.cpp b/core/libs/prx/libSceJson2/Export.cpp index 672d857ee..1a02b97bd 100644 --- a/core/libs/prx/libSceJson2/Export.cpp +++ b/core/libs/prx/libSceJson2/Export.cpp @@ -830,4 +830,25 @@ int APS5_VABI _ZN3sce4Json5Value21setNullAccessCallBackEPFRKS1_NS0_9ValueTypeEPS NotImplemented_nid_no_patch(__func__); return 0; } + +int APS5_VABI _ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI _ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI _ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI _ZNK3sce4Json5ValuecvbEv(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + } diff --git a/core/libs/prx/libSceNpSessionSignaling/Export.cpp b/core/libs/prx/libSceNpSessionSignaling/Export.cpp index b28941f1b..b694abb6f 100644 --- a/core/libs/prx/libSceNpSessionSignaling/Export.cpp +++ b/core/libs/prx/libSceNpSessionSignaling/Export.cpp @@ -93,4 +93,10 @@ int APS5_VABI sceNpSessionSignalingGetConnectionFromPeerAddress(void) { NotImplemented_nid_no_patch(__func__); return 0; } + +int APS5_VABI sceNpSessionSignalingGetGroupFromSessionId(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + } diff --git a/core/libs/prx/libSceSsl/CMakeLists.txt b/core/libs/prx/libSceSsl/CMakeLists.txt index d66b9716e..aa3508b58 100644 --- a/core/libs/prx/libSceSsl/CMakeLists.txt +++ b/core/libs/prx/libSceSsl/CMakeLists.txt @@ -12,4 +12,13 @@ if(BUILD_TESTING) set_tests_properties(guest_ssl PROPERTIES ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$") endif() + add_test_executable(guest_ppsa07411_exports_tests ${LIBS_INCLUDE_DIR}/tests/GuestPPSA07411Exports.cpp) + target_include_directories(guest_ppsa07411_exports_tests PRIVATE ${LIBS_INCLUDE_DIR}) + target_link_libraries(guest_ppsa07411_exports_tests PRIVATE libSceSsl libSceJson2 libSceNpSessionSignaling libSceConvertKeycode libc) + configure_windows_unwind(guest_ppsa07411_exports_tests) + add_test(NAME guest_ppsa07411_exports COMMAND guest_ppsa07411_exports_tests) + if(WIN32) + set_tests_properties(guest_ppsa07411_exports PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() endif() diff --git a/core/libs/prx/libSceSsl/Export.cpp b/core/libs/prx/libSceSsl/Export.cpp index e8fd49499..4b3e23a4e 100644 --- a/core/libs/prx/libSceSsl/Export.cpp +++ b/core/libs/prx/libSceSsl/Export.cpp @@ -159,4 +159,34 @@ int APS5_VABI sceSslGetSubjectName(void) { return 0; } +int APS5_VABI sceSslCreateConnection(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslDeleteConnection(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslEnableVerifyOption(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslConnect(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslRead(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + +int APS5_VABI sceSslWrite(void) { + NotImplemented_nid_no_patch(__func__); + return 0; +} + } diff --git a/core/libs/tests/GuestPPSA07411Exports.cpp b/core/libs/tests/GuestPPSA07411Exports.cpp new file mode 100644 index 000000000..92acb9a86 --- /dev/null +++ b/core/libs/tests/GuestPPSA07411Exports.cpp @@ -0,0 +1,62 @@ +#include "prx/libc/include/general/VabiMacros.hpp" + +#include +#include +#include + +extern "C" { +int APS5_VABI sceSslCreateConnection(); +int APS5_VABI sceSslDeleteConnection(); +int APS5_VABI sceSslEnableVerifyOption(); +int APS5_VABI sceSslConnect(); +int APS5_VABI sceSslRead(); +int APS5_VABI sceSslWrite(); +int APS5_VABI sceConvertKeycodeGetCharacter(); +int APS5_VABI sceNpSessionSignalingGetGroupFromSessionId(); +int APS5_VABI _ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_(); +int APS5_VABI _ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_(); +int APS5_VABI _ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_(); +int APS5_VABI _ZNK3sce4Json5ValuecvbEv(); +} + +namespace { + +struct Export { + const char* name; + int (APS5_VABI *function)(); +}; + +const Export exports[] = { + {"sceSslCreateConnection", sceSslCreateConnection}, + {"sceSslDeleteConnection", sceSslDeleteConnection}, + {"sceSslEnableVerifyOption", sceSslEnableVerifyOption}, + {"sceSslConnect", sceSslConnect}, + {"sceSslRead", sceSslRead}, + {"sceSslWrite", sceSslWrite}, + {"sceConvertKeycodeGetCharacter", sceConvertKeycodeGetCharacter}, + {"sceNpSessionSignalingGetGroupFromSessionId", sceNpSessionSignalingGetGroupFromSessionId}, + {"_ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_", _ZN3sce4Json5Value30setElementAccessFailureHandlerEPFviPKNS0_6StringEPKmPKS1_S8_PvES9_}, + {"_ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_", _ZN3sce4Json5Value22setSpecialFloatHandlerEPFKS1_NS0_12FunctionTypeEdPS2_PvPbES5_}, + {"_ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_", _ZN3sce4Json5Value22setTypeMismatchHandlerEPFRKS1_NS0_9ValueTypeEPS2_S5_PvES6_}, + {"_ZNK3sce4Json5ValuecvbEv", _ZNK3sce4Json5ValuecvbEv}, +}; + +bool ReportsNotImplemented(const Export& entry) { + try { + entry.function(); + } catch (const std::runtime_error& error) { + if (std::string(error.what()) == std::string(entry.name) + " not implemented") return true; + std::fprintf(stderr, "%s threw: %s\n", entry.name, error.what()); + return false; + } + std::fprintf(stderr, "%s returned instead of reporting that it is not implemented\n", entry.name); + return false; +} + +} + +int main() { + bool correct = true; + for (const auto& entry : exports) correct &= ReportsNotImplemented(entry); + return correct ? 0 : 1; +} diff --git a/docs/dev/TechnicalDebt.md b/docs/dev/TechnicalDebt.md index 0c72b62a7..63faecf90 100644 --- a/docs/dev/TechnicalDebt.md +++ b/docs/dev/TechnicalDebt.md @@ -597,3 +597,4 @@ Throughout the project, every function at every stage either **does exactly what - [_fstatfs](../../core/libs/prx/libkernel/File/src/Stdio.cpp) (libkernel) fills the FreeBSD 11 `struct statfs` of the PS5 payload SDK with the host volume that holds the file: block size, transfer size, total, free and available blocks, maximum name length and the read-only, `nosuid` and `noexec` flags (on Windows only read-only, and `f_files` and `f_ffree` are 0, as NTFS has no fixed number of files). The filesystem type number and name, mount paths, owner, filesystem id and I/O counters are left 0 or empty, since they would describe a host mount, not a console one. Sockets and pipes return `EINVAL`, as FreeBSD's `getvnode` does; a Windows descriptor that is neither a file nor a pipe throws. Stremio Plus (PPSA74126) reads the free space before a download and only logs the other fields - [_WStoul](../../core/libs/prx/libc/src/Strings.cpp), [_Iswctype](../../core/libs/prx/libc/src/RuneLocale.cpp) and [swscanf_s](../../core/libs/prx/libc/src/ScanningWide.cpp) (libc) - `_WStoul` is `wcstoul` and throws for a base other than 0 or 2 to 36. `_Iswctype` takes the class numbers of Dinkumware's [xwcc.h](https://github.com/superna9999/ti-cgt6x/blob/cgt6x_7_3_4/include/xwcc.h) (1 `alnum` to 11 `xdigit`, 12 `blank`) and throws for any other value, including the FreeBSD masks `wctype` returns; the numbering is not confirmed on the console's `libc.prx`. `swscanf_s` follows C11 7.29.2.2 and K.3.9.1.5, but reads the size argument as `unsigned int` like `sscanf_s` where K.3.9.1.5 specifies `rsize_t`; the console's width is unverified. A runtime-constraint violation (null buffer, format or receiving pointer) only returns `EOF`, and a too small array gets a null first element as in `sscanf_s`. A literal mismatch is a matching failure and a field that is only a prefix, such as `0x` or `1e`, does not convert, as C11 requires; FreeBSD's `vfwscanf` reports an input failure for the first and converts the second. Integers out of range are truncated from `strtoll`/`strtoull`. It throws for `%p`, `%S`, `%C`, unknown length modifiers, scanset ranges, `%n` with suppression or width, and narrow `%s`, `%c` or `%[` input that the C-locale `wcrtomb` cannot convert - [sceSharePlayGetCurrentConnectionInfoA](../../core/libs/prx/libSceSharePlay/Export.cpp) (libSceSharePlay) - reports no Share Play session, as the library keeps none: status 0 (DORMANT), mode 0, empty online IDs, account IDs 0 and both user IDs -1 (`SCE_USER_SERVICE_USER_ID_INVALID`). A null pointer returns `SCE_SHARE_PLAY_ERROR_INVALID_ARGS` (0x810E0001). The 72-byte `SceSharePlayConnectionInfoA` layout and the error code follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libNet.cpp) and [fpPS4](https://github.com/red-prig/fpPS4/blob/trunk/src/ps4_libsceshareplay.pas), which agree on both; KytyPS5 sets the user IDs to -1 and fpPS4 leaves them 0, and which one the console returns is not verified. KytyPS5 also returns `SCE_SHARE_PLAY_ERROR_NOT_INITIALIZED` before `sceSharePlayInitialize`; this library keeps no initialization state and does not. +- PPSA07411 imports declared without parameters, signatures unknown, added without an implementation because the title fails to load without them: [sceSslCreateConnection, sceSslDeleteConnection, sceSslEnableVerifyOption, sceSslConnect, sceSslRead, sceSslWrite](../../core/libs/prx/libSceSsl/Export.cpp) (libSceSsl), [four sce::Json::Value members (setElementAccessFailureHandler, setSpecialFloatHandler, setTypeMismatchHandler, operator bool)](../../core/libs/prx/libSceJson2/Export.cpp) (libSceJson2), [sceConvertKeycodeGetCharacter](../../core/libs/prx/libSceConvertKeycode/Export.cpp) (libSceConvertKeycode) and [sceNpSessionSignalingGetGroupFromSessionId](../../core/libs/prx/libSceNpSessionSignaling/Export.cpp) (libSceNpSessionSignaling)