mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
fix(npauthdialog): restore parameter validation and lifecycle
This commit is contained in:
1 parent
2a8c0f82ab
commit
a159f77523
5 files changed
+88
-21
No files matched your search
@@ -12,6 +12,24 @@ struct CommonDialogBaseParam {
|
||||
std::uint32_t magic;
|
||||
};
|
||||
|
||||
struct NpAuthAuthorizedAppDialogParam {
|
||||
CommonDialogBaseParam base;
|
||||
std::uint64_t size;
|
||||
std::int32_t userId;
|
||||
std::uint32_t padding60;
|
||||
const char* application;
|
||||
const char* text;
|
||||
std::uint32_t mode;
|
||||
std::uint32_t padding84;
|
||||
std::uint8_t reserved[32];
|
||||
};
|
||||
|
||||
static_assert(sizeof(NpAuthAuthorizedAppDialogParam) == 120);
|
||||
static_assert(offsetof(NpAuthAuthorizedAppDialogParam, application) == 64);
|
||||
static_assert(offsetof(NpAuthAuthorizedAppDialogParam, text) == 72);
|
||||
static_assert(offsetof(NpAuthAuthorizedAppDialogParam, mode) == 80);
|
||||
static_assert(offsetof(NpAuthAuthorizedAppDialogParam, reserved) == 88);
|
||||
|
||||
struct G2PDialogParam {
|
||||
CommonDialogBaseParam base;
|
||||
std::int32_t userId;
|
||||
|
||||
@@ -2,10 +2,12 @@ add_library(libSceNpAuthAuthorizedAppDialog SHARED EXCLUDE_FROM_ALL Export.cpp)
|
||||
target_include_directories(libSceNpAuthAuthorizedAppDialog PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
configure_windows_unwind(libSceNpAuthAuthorizedAppDialog)
|
||||
|
||||
target_link_libraries(libSceNpAuthAuthorizedAppDialog PRIVATE libSceUserService)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_np_auth_authorized_app_dialog_tests ${LIBS_INCLUDE_DIR}/tests/GuestNpAuthAuthorizedAppDialog.cpp)
|
||||
target_include_directories(guest_np_auth_authorized_app_dialog_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_np_auth_authorized_app_dialog_tests PRIVATE libSceNpAuthAuthorizedAppDialog)
|
||||
target_link_libraries(guest_np_auth_authorized_app_dialog_tests PRIVATE libSceNpAuthAuthorizedAppDialog libSceUserService)
|
||||
add_test(NAME guest_np_auth_authorized_app_dialog COMMAND guest_np_auth_authorized_app_dialog_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_np_auth_authorized_app_dialog PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include "SceTypes.hpp"
|
||||
#include "prx/libSceCommonDialog/CommonDialog.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
|
||||
extern "C" int APS5_VABI sceUserServiceGetLoginUserIdList(UserServiceLoginUserIdList* users);
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int COMMON_DIALOG_STATUS_NONE = 0;
|
||||
@@ -12,7 +15,8 @@ constexpr int COMMON_DIALOG_STATUS_INITIALIZED = 1;
|
||||
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_INVALID_ARGUMENT = static_cast<int>(0x80B8000Au);
|
||||
constexpr int COMMON_DIALOG_ERROR_NOT_RUNNING = static_cast<int>(0x80B8000Bu);
|
||||
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);
|
||||
@@ -30,11 +34,17 @@ int APS5_VABI sceNpAuthAuthorizedAppDialogInitialize(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogOpen(const void* param) {
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogOpen(const NpAuthAuthorizedAppDialogParam* param) {
|
||||
if (param == nullptr) return COMMON_DIALOG_ERROR_ARG_NULL;
|
||||
if (!ValidateCommonDialogBaseParam(param->base)) return COMMON_DIALOG_ERROR_INVALID_ARGUMENT;
|
||||
if (param->size != sizeof(*param) || param->userId == -1) return COMMON_DIALOG_ERROR_INVALID_ARGUMENT;
|
||||
UserServiceLoginUserIdList users{};
|
||||
if (sceUserServiceGetLoginUserIdList(&users) != 0 || std::find(std::begin(users.user_id), std::end(users.user_id), param->userId) == std::end(users.user_id)) return COMMON_DIALOG_ERROR_INVALID_ARGUMENT;
|
||||
if (param->application == nullptr || param->application[0] == 0 || param->text == nullptr || param->text[0] == 0) return COMMON_DIALOG_ERROR_INVALID_ARGUMENT;
|
||||
if (std::strlen(param->text) > 1024 || param->mode > 1 || !std::all_of(std::begin(param->reserved), std::end(param->reserved), [](std::uint8_t value) { return value == 0; })) return COMMON_DIALOG_ERROR_INVALID_ARGUMENT;
|
||||
const int status = g_status.load();
|
||||
if (status == COMMON_DIALOG_STATUS_NONE) return COMMON_DIALOG_ERROR_NOT_INITIALIZED;
|
||||
if (status == COMMON_DIALOG_STATUS_RUNNING) return COMMON_DIALOG_ERROR_BUSY;
|
||||
if (param == nullptr) return COMMON_DIALOG_ERROR_ARG_NULL;
|
||||
g_status = COMMON_DIALOG_STATUS_FINISHED;
|
||||
return 0;
|
||||
}
|
||||
@@ -47,18 +57,18 @@ int APS5_VABI sceNpAuthAuthorizedAppDialogGetStatus(void) {
|
||||
return g_status.load();
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogGetResult(void* result) {
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogGetResult(std::int32_t* result) {
|
||||
if (result == nullptr) return COMMON_DIALOG_ERROR_ARG_NULL;
|
||||
const int status = g_status.load();
|
||||
if (status == COMMON_DIALOG_STATUS_NONE) return COMMON_DIALOG_ERROR_NOT_INITIALIZED;
|
||||
if (result == nullptr) return COMMON_DIALOG_ERROR_ARG_NULL;
|
||||
if (status != COMMON_DIALOG_STATUS_FINISHED) return COMMON_DIALOG_ERROR_NOT_FINISHED;
|
||||
const std::int32_t canceled = COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
std::memcpy(result, &canceled, sizeof(canceled));
|
||||
return 0;
|
||||
*result = COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
return COMMON_DIALOG_RESULT_USER_CANCELED;
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogClose(void) {
|
||||
if (g_status.load() == COMMON_DIALOG_STATUS_NONE) return COMMON_DIALOG_ERROR_NOT_INITIALIZED;
|
||||
if (g_status.load() != COMMON_DIALOG_STATUS_RUNNING) return COMMON_DIALOG_ERROR_NOT_RUNNING;
|
||||
g_status = COMMON_DIALOG_STATUS_FINISHED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include "prx/libSceCommonDialog/CommonDialog.hpp"
|
||||
#include "prx/libSceUserService/UserService.hpp"
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI sceUserServiceInitialize(const UserServiceInitParam* param);
|
||||
int APS5_VABI sceUserServiceTerminate();
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogInitialize(void);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogOpen(const void* param);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogOpen(const NpAuthAuthorizedAppDialogParam* param);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogUpdateStatus(void);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogGetStatus(void);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogGetResult(void* result);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogGetResult(std::int32_t* result);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogClose(void);
|
||||
int APS5_VABI sceNpAuthAuthorizedAppDialogTerminate(void);
|
||||
}
|
||||
@@ -28,7 +33,16 @@ constexpr int kResultUserCanceled = 1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::int64_t param = 0;
|
||||
Require(sceUserServiceInitialize(nullptr) == 0);
|
||||
NpAuthAuthorizedAppDialogParam param{};
|
||||
param.base.size = sizeof(param.base);
|
||||
param.base.magic = static_cast<std::uint32_t>(reinterpret_cast<std::uintptr_t>(¶m)) - 1060003575u;
|
||||
param.size = sizeof(param);
|
||||
param.userId = USER_SERVICE_INITIAL_USER_ID;
|
||||
char application[136] = "test";
|
||||
std::string text(1024, 'a');
|
||||
param.application = application;
|
||||
param.text = text.c_str();
|
||||
std::int32_t result[2] = {-1, -1};
|
||||
|
||||
Require(sceNpAuthAuthorizedAppDialogGetStatus() == kStatusNone);
|
||||
@@ -45,27 +59,51 @@ int main() {
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(nullptr) == kErrArgNull);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(result) == kErrNotFinished);
|
||||
|
||||
constexpr int invalidArgument = static_cast<int>(0x80B8000Au);
|
||||
param.size = 119;
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
param.size = sizeof(param);
|
||||
param.userId = 42;
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
param.userId = USER_SERVICE_INITIAL_USER_ID;
|
||||
param.application = nullptr;
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
param.application = application;
|
||||
param.text = "";
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
text.push_back('a');
|
||||
param.text = text.c_str();
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
text.pop_back();
|
||||
param.text = text.c_str();
|
||||
param.mode = 2;
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
param.mode = 1;
|
||||
param.reserved[31] = 1;
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == invalidArgument);
|
||||
param.reserved[31] = 0;
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(¶m) == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogUpdateStatus() == kStatusFinished);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetStatus() == kStatusFinished);
|
||||
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(nullptr) == kErrArgNull);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(result) == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(result) == kResultUserCanceled);
|
||||
Require(result[0] == kResultUserCanceled);
|
||||
Require(result[1] == -1);
|
||||
|
||||
Require(sceNpAuthAuthorizedAppDialogClose() == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogClose() == static_cast<int>(0x80B8000Bu));
|
||||
Require(sceNpAuthAuthorizedAppDialogTerminate() == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogTerminate() == kErrNotInitialized);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetStatus() == kStatusNone);
|
||||
|
||||
Require(sceNpAuthAuthorizedAppDialogInitialize() == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetStatus() == kStatusInitialized);
|
||||
Require(sceNpAuthAuthorizedAppDialogClose() == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetStatus() == kStatusFinished);
|
||||
result[0] = -1;
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(result) == 0);
|
||||
Require(result[0] == kResultUserCanceled);
|
||||
Require(sceNpAuthAuthorizedAppDialogClose() == static_cast<int>(0x80B8000Bu));
|
||||
Require(sceNpAuthAuthorizedAppDialogGetStatus() == kStatusInitialized);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(result) == kErrNotFinished);
|
||||
Require(sceNpAuthAuthorizedAppDialogTerminate() == 0);
|
||||
Require(sceNpAuthAuthorizedAppDialogOpen(nullptr) == kErrArgNull);
|
||||
Require(sceNpAuthAuthorizedAppDialogGetResult(nullptr) == kErrArgNull);
|
||||
Require(sceUserServiceTerminate() == 0);
|
||||
return 0;
|
||||
}
|
||||
@@ -2,5 +2,4 @@
|
||||
|
||||
### Silent stubs
|
||||
|
||||
- [libSceNpAuthAuthorizedAppDialog](../../../core/libs/prx/libSceNpAuthAuthorizedAppDialog/Export.cpp) - the authorized-app dialog runs the common-dialog state machine but shows nothing and reports the user as having cancelled, as there is no PSN sign-in to authorize an app against. The signatures follow the other common dialogs (`Open` takes a parameter block, `GetResult` writes a 32-bit result); Minecraft (PPSA17221) imports the seven functions and fails to load without them.
|
||||
- [sceNpAuthAuthorizedAppDialogClose](../../../core/libs/prx/libSceNpAuthAuthorizedAppDialog/Export.cpp) - `sceNpAuthAuthorizedAppDialogClose` moves an initialized dialog straight to `COMMON_DIALOG_STATUS_FINISHED`, also when called before `Open`, following the Signin / NetCtlAp dialogs; MsgDialog / SaveDataDialog / ErrorDialog return NOT_RUNNING or INVALID_STATE for that case, and which one the real library does is unverified.
|
||||
- [libSceNpAuthAuthorizedAppDialog](../../../core/libs/prx/libSceNpAuthAuthorizedAppDialog/Export.cpp) - the authorized-app dialog runs the common-dialog state machine but shows nothing and reports the user as having cancelled, as there is no PSN sign-in to authorize an app against. Parameter fields at offsets 64 and 72 feed a 136-byte application record and a text value of at most 1024 bytes; their service-side meaning remains incomplete.
|
||||
Reference in new issue
Block a user