Merge pull request #3665 from itsbo5/feat/libSceSigninDialog-completion

feat(libSceSigninDialog): complete offline sign-in dialog lifecycle
This commit is contained in:
Adrià 2026-10-11 23:45:50 +02:00 committed by GitHub
commit 2b988061ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 105 additions and 5 deletions

View File

@ -188,6 +188,16 @@ if(BUILD_TESTING)
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceHttp>")
endif()
add_test_executable(guest_signin_dialog_tests tests/GuestSigninDialog.cpp)
target_include_directories(guest_signin_dialog_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(guest_signin_dialog_tests PRIVATE libSceSigninDialog libc)
configure_windows_unwind(guest_signin_dialog_tests)
add_test(NAME guest_signin_dialog COMMAND guest_signin_dialog_tests)
if(WIN32)
set_tests_properties(guest_signin_dialog PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceSigninDialog>")
endif()
add_test_executable(guest_rudp_status_tests tests/GuestRudpStatus.cpp)
target_include_directories(guest_rudp_status_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(guest_rudp_status_tests PRIVATE libSceRudp libc)

View File

@ -1,6 +1,7 @@
#include <atomic>
#include <cstdint>
#include <cstddef>
#include <cstring>
#include "SceTypes.hpp"
#include "prx/libc/include/General.hpp"
@ -12,8 +13,15 @@ constexpr int COMMON_DIALOG_STATUS_RUNNING = 2;
constexpr int COMMON_DIALOG_STATUS_FINISHED = 3;
constexpr int COMMON_DIALOG_ERROR_NOT_INITIALIZED = static_cast<int>(0x80B80003u);
constexpr int COMMON_DIALOG_ERROR_ALREADY_INITIALIZED = static_cast<int>(0x80B80004u);
constexpr int COMMON_DIALOG_ERROR_NOT_FINISHED = static_cast<int>(0x80B80005u);
constexpr int COMMON_DIALOG_ERROR_BUSY = static_cast<int>(0x80B80007u);
constexpr int COMMON_DIALOG_ERROR_ARG_NULL = static_cast<int>(0x80B8000Du);
constexpr int COMMON_DIALOG_RESULT_USER_CANCELED = 1;
struct SceSigninDialogResult {
std::int32_t result = COMMON_DIALOG_RESULT_USER_CANCELED;
std::int32_t reserved[3] = {};
};
std::atomic<int> g_status{COMMON_DIALOG_STATUS_NONE};
@ -22,19 +30,23 @@ std::atomic<int> g_status{COMMON_DIALOG_STATUS_NONE};
extern "C" {
int APS5_VABI sceSigninDialogClose(void) {
NotImplemented_nid_no_patch(__func__);
if (g_status.load() == COMMON_DIALOG_STATUS_NONE) return COMMON_DIALOG_ERROR_NOT_INITIALIZED;
g_status = COMMON_DIALOG_STATUS_FINISHED;
return 0;
}
int APS5_VABI sceSigninDialogGetResult(void* result) {
(void)result;
NotImplemented_nid_no_patch(__func__);
const int status = g_status.load();
if (status == COMMON_DIALOG_STATUS_NONE) return COMMON_DIALOG_ERROR_NOT_INITIALIZED;
if (status != COMMON_DIALOG_STATUS_FINISHED) return COMMON_DIALOG_ERROR_NOT_FINISHED;
if (result == nullptr) return COMMON_DIALOG_ERROR_ARG_NULL;
const SceSigninDialogResult dialogResult{};
std::memcpy(result, &dialogResult, sizeof(dialogResult));
return 0;
}
int APS5_VABI sceSigninDialogGetStatus(void) {
NotImplemented_nid_no_patch(__func__);
return 0;
return g_status.load();
}
int APS5_VABI sceSigninDialogInitialize(void) {

View File

@ -0,0 +1,77 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdint>
#include <cstdlib>
#include <cstring>
extern "C" {
int APS5_VABI sceSigninDialogInitialize(void);
int APS5_VABI sceSigninDialogOpen(const void* param);
int APS5_VABI sceSigninDialogUpdateStatus(void);
int APS5_VABI sceSigninDialogGetStatus(void);
int APS5_VABI sceSigninDialogGetResult(void* result);
int APS5_VABI sceSigninDialogClose(void);
int APS5_VABI sceSigninDialogTerminate(void);
}
namespace {
void Require(bool value) { if (!value) std::abort(); }
constexpr int kStatusNone = 0;
constexpr int kStatusInitialized = 1;
constexpr int kStatusFinished = 3;
constexpr int kErrNotInitialized = static_cast<int>(0x80B80003);
constexpr int kErrAlreadyInitialized = static_cast<int>(0x80B80004);
constexpr int kErrNotFinished = static_cast<int>(0x80B80005);
constexpr int kErrArgNull = static_cast<int>(0x80B8000D);
constexpr int kResultUserCanceled = 1;
}
int main() {
std::int64_t param = 0;
std::int32_t result[4];
std::memset(result, 0x5a, sizeof(result));
Require(sceSigninDialogTerminate() == kErrNotInitialized);
Require(sceSigninDialogOpen(&param) == kErrNotInitialized);
Require(sceSigninDialogClose() == kErrNotInitialized);
Require(sceSigninDialogGetResult(result) == kErrNotInitialized);
Require(sceSigninDialogGetStatus() == kStatusNone);
Require(sceSigninDialogUpdateStatus() == kStatusNone);
Require(sceSigninDialogInitialize() == 0);
Require(sceSigninDialogInitialize() == kErrAlreadyInitialized);
Require(sceSigninDialogGetStatus() == kStatusInitialized);
Require(sceSigninDialogOpen(nullptr) == kErrArgNull);
Require(sceSigninDialogGetResult(result) == kErrNotFinished);
Require(sceSigninDialogOpen(&param) == 0);
Require(sceSigninDialogGetStatus() == kStatusFinished);
Require(sceSigninDialogUpdateStatus() == kStatusFinished);
Require(sceSigninDialogGetResult(nullptr) == kErrArgNull);
Require(sceSigninDialogGetResult(result) == 0);
Require(result[0] == kResultUserCanceled);
Require(result[1] == 0);
Require(result[2] == 0);
Require(result[3] == 0);
Require(sceSigninDialogClose() == 0);
Require(sceSigninDialogTerminate() == 0);
Require(sceSigninDialogTerminate() == kErrNotInitialized);
Require(sceSigninDialogGetStatus() == kStatusNone);
Require(sceSigninDialogInitialize() == 0);
Require(sceSigninDialogGetStatus() == kStatusInitialized);
Require(sceSigninDialogClose() == 0);
Require(sceSigninDialogGetStatus() == kStatusFinished);
std::memset(result, 0xa5, sizeof(result));
Require(sceSigninDialogGetResult(result) == 0);
Require(result[0] == kResultUserCanceled);
Require(result[1] == 0);
Require(result[2] == 0);
Require(result[3] == 0);
Require(sceSigninDialogTerminate() == 0);
}

View File

@ -82,6 +82,7 @@ Throughout the project, every function at every stage either **does exactly what
- PPSA01341 imports declared without parameters, signatures unknown: [sceAgcSetSemaphoreMemory](../../core/libs/prx/libSceAgc/Unimplemented.cpp). Name from the shadPS4 aerolib NID list
- [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
- [sceNpEAAccessInitialize, sceNpEAAccessTerminate](../../core/libs/prx/libSceNpPartner001/Export.cpp) (libSceNpPartner001) - names and the no-argument signatures follow [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/np/np_partner.cpp); imported by PPSA23566, not confirmed on a PS5 title
- [sceSigninDialogClose, sceSigninDialogGetResult](../../core/libs/prx/libSceSigninDialog/Export.cpp) (libSceSigninDialog) - SceSigninDialogResult layout (int32 result and 3 reserved int32 words, zeroed) follows [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/dialog.cpp) and [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/SigninDialog/SigninDialog.cs); error codes follow libSceLoginDialog's 0x80B8xxxx common-dialog codes rather than KytyPS5's 0x8135xxxx, and offline calls finish as user cancelled without opening a dialog. Neither choice is verified on hardware
- [libSceBluetoothHid](../../core/libs/prx/libSceBluetoothHid/Export.cpp) (libSceBluetoothHid) - signatures taken from PPSA01317: `sceBluetoothHidInit()` and `sceBluetoothHidUnregisterCallback()` without arguments, `sceBluetoothHidRegisterCallback(callback, 0, param)` with a 16-byte param, and `sceBluetoothHidRegisterDevice` / `sceBluetoothHidUnregisterDevice(vendorId, productId)`; the report and device name exports are declared without parameters
- [sceAgcWaitRegMemPatchMask](../../core/libs/prx/libSceAgc/Patch/src/WaitRegMem.cpp) (libSceAgc) - follows `sceAgcWaitRegMemPatchReference`: the mask is taken as a 32-bit value and written to the low mask word of a 32- or 64-bit wait, as [OpenAGC](https://github.com/OpenAGC/OpenAGC/blob/main/src/game_compat.c) does; [sharpemu](https://github.com/sharpemu/sharpemu/blob/main/src/SharpEmu.Libs/Agc/AgcExports.PacketPatching.cs) writes both words of a 64-bit wait's mask. A mask above 32 bits throws
- [scePsmlMfsr2CreateContext, scePsmlMfsr2CreateSharedResources, scePsmlMfsr2GetContextInitRequirement, scePsmlMfsr2GetDispatchPackets, scePsmlMfsr2GetDispatchPacketsSizeInDwords, scePsmlMfsr2GetSharedResourcesInitRequirement, scePsmlMfsr2Init, scePsmlMfsr2ReleaseContext, scePsmlMfsr2ReleaseSharedResources](../../core/libs/prx/libScePsml_debug/Export.cpp) (libScePsml_mfsr2) - unknown signatures, imported by PPSA23566; declared without parameters