mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 08:33:12 -05:00
199 lines
8.5 KiB
C++
199 lines
8.5 KiB
C++
#include "ProcessParametersFixture.hpp"
|
|
#include "prx/libSceUserService/UserService.hpp"
|
|
#include <array>
|
|
#include <stdexcept>
|
|
#include "SceTypes.hpp"
|
|
#include "prx/libSceCommonDialog/CommonDialog.hpp"
|
|
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
extern "C" {
|
|
int APS5_VABI sceUserServiceInitialize(const UserServiceInitParam* param);
|
|
int APS5_VABI sceUserServiceTerminate();
|
|
int APS5_VABI sceNpCommerceDialogInitialize();
|
|
int APS5_VABI sceNpCommerceDialogOpen(const NpCommerceDialogParam* param);
|
|
int APS5_VABI sceNpCommerceDialogOpen2(const NpCommerceDialogParam2* param);
|
|
int APS5_VABI sceNpCommerceDialogUpdateStatus(void);
|
|
int APS5_VABI sceNpCommerceDialogGetStatus(void);
|
|
int APS5_VABI sceNpCommerceDialogGetResult(NpCommerceDialogResult* result);
|
|
int APS5_VABI sceNpCommerceDialogClose(void);
|
|
int APS5_VABI sceNpCommerceDialogTerminate();
|
|
}
|
|
|
|
namespace {
|
|
|
|
void Require(bool value) { if (!value) std::abort(); }
|
|
|
|
alignas(16) std::array<std::byte, 64> process{};
|
|
|
|
constexpr int statusNone = 0;
|
|
constexpr int statusInitialized = 1;
|
|
constexpr int statusFinished = 3;
|
|
constexpr std::int32_t resultUserCanceled = 1;
|
|
|
|
void RequireCanceledResult(std::uint64_t userData, bool clearsReserved) {
|
|
NpCommerceDialogResult result;
|
|
std::memset(&result, 0x33, sizeof(result));
|
|
Require(sceNpCommerceDialogGetResult(&result) == resultUserCanceled);
|
|
Require(result.result == resultUserCanceled);
|
|
Require(result.authorized == 0);
|
|
Require(result.userData == userData);
|
|
for (const auto value : result.padding) Require(value == 0x33);
|
|
for (const auto value : result.reserved) Require(value == (clearsReserved ? 0 : 0x33));
|
|
}
|
|
|
|
}
|
|
|
|
int main() {
|
|
Require(ProcessParametersFixture::Install(process.data(), process.size()));
|
|
std::uint32_t sdkVersion = 0x03500000;
|
|
std::memcpy(process.data() + 16, &sdkVersion, sizeof(sdkVersion));
|
|
Require(sceUserServiceInitialize(nullptr) == 0);
|
|
NpCommerceDialogParam2 param2{};
|
|
param2.base.size = sizeof(param2.base);
|
|
param2.base.magic = static_cast<std::uint32_t>(reinterpret_cast<std::uintptr_t>(¶m2)) - 1060003575u;
|
|
param2.size = sizeof(param2);
|
|
param2.userId = USER_SERVICE_INITIAL_USER_ID;
|
|
param2.userData = 0x123456789abcdef0;
|
|
Require(sceNpCommerceDialogGetStatus() == statusNone);
|
|
Require(sceNpCommerceDialogOpen(nullptr) == static_cast<int>(0x80B8000Du));
|
|
Require(sceNpCommerceDialogOpen2(nullptr) == static_cast<int>(0x80B8000Du));
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B80003u));
|
|
param2.base.magic = 0;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B8000Au));
|
|
param2.base.magic = static_cast<std::uint32_t>(reinterpret_cast<std::uintptr_t>(¶m2)) - 1060003575u;
|
|
param2.base.reserved[35] = 1;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B8000Au));
|
|
param2.base.reserved[35] = 0;
|
|
Require(sceNpCommerceDialogTerminate() == static_cast<int>(0x80B80003u));
|
|
Require(sceNpCommerceDialogClose() == static_cast<int>(0x80B80003u));
|
|
Require(sceNpCommerceDialogGetResult(nullptr) == static_cast<int>(0x80B8000Du));
|
|
NpCommerceDialogResult result{};
|
|
Require(sceNpCommerceDialogGetResult(&result) == static_cast<int>(0x80B80003u));
|
|
Require(sceNpCommerceDialogInitialize() == 0);
|
|
Require(sceNpCommerceDialogClose() == static_cast<int>(0x80B8000Bu));
|
|
Require(sceNpCommerceDialogGetResult(&result) == static_cast<int>(0x80B80005u));
|
|
Require(sceNpCommerceDialogGetResult(nullptr) == static_cast<int>(0x80B8000Du));
|
|
Require(sceNpCommerceDialogGetStatus() == statusInitialized);
|
|
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == 0);
|
|
Require(sceNpCommerceDialogUpdateStatus() == statusFinished);
|
|
Require(sceNpCommerceDialogGetStatus() == statusFinished);
|
|
RequireCanceledResult(param2.userData, true);
|
|
|
|
Require(sceNpCommerceDialogClose() == static_cast<int>(0x80B8000Bu));
|
|
Require(sceNpCommerceDialogGetStatus() == statusFinished);
|
|
Require(sceNpCommerceDialogTerminate() == 0);
|
|
Require(sceNpCommerceDialogGetStatus() == statusNone);
|
|
|
|
NpCommerceDialogParam 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;
|
|
Require(sceNpCommerceDialogInitialize() == 0);
|
|
param.base.size = 0;
|
|
Require(sceNpCommerceDialogOpen(¶m) == static_cast<int>(0x80B8000Au));
|
|
param.base.size = sizeof(param.base);
|
|
param.size = 0;
|
|
Require(sceNpCommerceDialogOpen(¶m) == static_cast<int>(0x80B8000Au));
|
|
param.size = sizeof(param);
|
|
param.option = 8;
|
|
Require(sceNpCommerceDialogOpen(¶m) == static_cast<int>(0x80B8000Au));
|
|
param.option = 0;
|
|
param.reserved[31] = 1;
|
|
Require(sceNpCommerceDialogOpen(¶m) == static_cast<int>(0x80B8000Au));
|
|
param.reserved[31] = 0;
|
|
param.userId = -1;
|
|
Require(sceNpCommerceDialogOpen(¶m) == static_cast<int>(0x80B8000Au));
|
|
param.userId = USER_SERVICE_INITIAL_USER_ID;
|
|
const char* products[11]{};
|
|
for (std::uint32_t mode = 0; mode <= 6; ++mode) {
|
|
param.mode = mode;
|
|
for (std::uint32_t count = 0; count <= 11; ++count) {
|
|
param.productCount = count;
|
|
for (bool hasProducts : {false, true}) {
|
|
param.products = hasProducts ? products : nullptr;
|
|
bool valid = false;
|
|
if (mode == 0 || mode == 2) valid = count <= 1 && hasProducts == (count != 0);
|
|
if (mode == 1) valid = count == 1 && hasProducts;
|
|
if (mode == 3) valid = count >= 1 && count <= 10 && hasProducts;
|
|
if (mode == 4) valid = count <= 10 && hasProducts == (count != 0);
|
|
Require(sceNpCommerceDialogOpen(¶m) == (valid ? 0 : static_cast<int>(0x80B8000Au)));
|
|
param2.mode = mode;
|
|
param2.productCount = count;
|
|
param2.products = param.products;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == (valid ? 0 : static_cast<int>(0x80B8000Au)));
|
|
}
|
|
}
|
|
}
|
|
param2.mode = 1;
|
|
param2.contentMode = 1;
|
|
param2.productCount = 1;
|
|
param2.products = products;
|
|
param2.option = 99;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == 0);
|
|
param2.option = 100;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B8000Au));
|
|
param2.option = 0;
|
|
param2.mode = 2;
|
|
bool threw = false;
|
|
try {
|
|
sceNpCommerceDialogOpen2(¶m2);
|
|
} catch (const std::runtime_error&) {
|
|
threw = true;
|
|
}
|
|
Require(threw);
|
|
param2.contentMode = 0;
|
|
param2.mode = 0;
|
|
param2.productCount = 0;
|
|
param2.products = nullptr;
|
|
param2.reserved[31] = 1;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B8000Au));
|
|
param2.reserved[31] = 0;
|
|
param2.size = 0;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B8000Au));
|
|
param2.size = sizeof(param2);
|
|
param2.userId = -1;
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == static_cast<int>(0x80B8000Au));
|
|
param2.userId = USER_SERVICE_INITIAL_USER_ID;
|
|
param2.userData = 0x123456789abcdef0;
|
|
for (std::uint32_t mode : {1000u, 1001u}) {
|
|
param.mode = mode;
|
|
param.productCount = 0;
|
|
param.argument = 1;
|
|
Require(sceNpCommerceDialogOpen(¶m) == static_cast<int>(0x80B8000Au));
|
|
}
|
|
param.mode = 5;
|
|
param.productCount = 0;
|
|
param.products = nullptr;
|
|
for (std::uint64_t argument = 0; argument <= 4; ++argument) {
|
|
param.argument = argument;
|
|
Require(sceNpCommerceDialogOpen(¶m) == (argument == 1 ? 0 : static_cast<int>(0x80B8000Au)));
|
|
}
|
|
sdkVersion = 0x01700000;
|
|
std::memcpy(process.data() + 16, &sdkVersion, sizeof(sdkVersion));
|
|
param.argument = 3;
|
|
param.userData = 0xfedcba9876543210;
|
|
Require(sceNpCommerceDialogOpen(¶m) == 0);
|
|
RequireCanceledResult(param.userData, true);
|
|
sdkVersion = 0x01600000;
|
|
std::memcpy(process.data() + 16, &sdkVersion, sizeof(sdkVersion));
|
|
param.size = 0;
|
|
param.option = 100;
|
|
param.userId = -1;
|
|
param.reserved[31] = 1;
|
|
param.argument = 7;
|
|
Require(sceNpCommerceDialogOpen(¶m) == 0);
|
|
RequireCanceledResult(param.userData, false);
|
|
Require(sceNpCommerceDialogOpen2(¶m2) == 0);
|
|
Require(sceNpCommerceDialogUpdateStatus() == statusFinished);
|
|
RequireCanceledResult(param2.userData, false);
|
|
Require(sceNpCommerceDialogTerminate() == 0);
|
|
Require(sceNpCommerceDialogGetStatus() == statusNone);
|
|
Require(sceUserServiceTerminate() == 0);
|
|
return 0;
|
|
}
|