#include "SceTypes.hpp" #include "prx/libc/include/general/VabiMacros.hpp" #include #include #include #include #include extern "C" { int APS5_VABI sceGameUpdateInitialize(void); int APS5_VABI sceGameUpdateTerminate(void); int APS5_VABI sceGameUpdateGetAddcontLatestVersion(std::uint32_t, const void*, GameUpdateAddcontVersionInfo*); int APS5_VABI sceGameUpdateCreateRequest(void); int APS5_VABI sceGameUpdateCheck(int, const GameUpdateCheckParam*, GameUpdateCheckResult*); int APS5_VABI sceGameUpdateAbortRequest(int); int APS5_VABI sceGameUpdateDeleteRequest(int); } static void Require(bool value) { if (!value) std::abort(); } static void TestRequestArguments(int notInitialized, int invalidArgument, int invalidSize, int notFound) { GameUpdateCheckParam param{}; param.size = sizeof(param); GameUpdateCheckResult result{}; result.size = sizeof(result); constexpr int requestId = 0x20000000; for (int id : {0, -1}) { Require(sceGameUpdateCheck(id, nullptr, nullptr) == notFound); Require(sceGameUpdateAbortRequest(id) == notFound); Require(sceGameUpdateDeleteRequest(id) == notFound); } Require(sceGameUpdateCheck(requestId, nullptr, &result) == invalidArgument); Require(sceGameUpdateCheck(requestId, ¶m, nullptr) == invalidArgument); param.size = sizeof(param) - 1; Require(sceGameUpdateCheck(requestId, ¶m, &result) == invalidSize); param.size = sizeof(param); result.size = sizeof(result) + 8; Require(sceGameUpdateCheck(requestId, ¶m, &result) == invalidSize); result.size = sizeof(result); param.option = 1; Require(sceGameUpdateCheck(requestId, ¶m, &result) == invalidArgument); param.option = 0; param.reserved[8] = 1; Require(sceGameUpdateCheck(requestId, ¶m, &result) == invalidArgument); param.reserved[8] = 0; Require(sceGameUpdateCreateRequest() == notInitialized); Require(sceGameUpdateCheck(requestId, ¶m, &result) == notInitialized); Require(sceGameUpdateAbortRequest(requestId) == notInitialized); Require(sceGameUpdateDeleteRequest(requestId) == notInitialized); Require(sceGameUpdateInitialize() == 0); Require(sceGameUpdateCheck(requestId, ¶m, &result) == notFound); Require(sceGameUpdateAbortRequest(requestId) == notFound); Require(sceGameUpdateDeleteRequest(requestId) == notFound); Require(sceGameUpdateTerminate() == 0); } int main() { constexpr int notInitialized = static_cast(0x80412801); constexpr int invalidArgument = static_cast(0x80412803); constexpr int invalidSize = static_cast(0x80412804); static_assert(sizeof(GameUpdateAddcontVersionInfo) == 0x30); const std::uint8_t label[16] = {}; GameUpdateAddcontVersionInfo info{}; info.size = sizeof(info); constexpr int alreadyInitialized = static_cast(0x80412802); constexpr int notFound = static_cast(0x80412805); Require(sceGameUpdateTerminate() == notInitialized); TestRequestArguments(notInitialized, invalidArgument, invalidSize, notFound); Require(sceGameUpdateGetAddcontLatestVersion(0, label, &info) == notInitialized); Require(sceGameUpdateGetAddcontLatestVersion(0, label, nullptr) == invalidArgument); Require(sceGameUpdateGetAddcontLatestVersion(0, nullptr, &info) == invalidArgument); Require(sceGameUpdateInitialize() == 0); Require(sceGameUpdateInitialize() == alreadyInitialized); Require(sceGameUpdateGetAddcontLatestVersion(0, label, nullptr) == invalidArgument); Require(sceGameUpdateGetAddcontLatestVersion(0, nullptr, &info) == invalidArgument); info.size = sizeof(info) - 1; Require(sceGameUpdateGetAddcontLatestVersion(0, label, &info) == invalidSize); std::memset(&info, 0xAB, sizeof(info)); info.size = sizeof(info) + 8; Require(sceGameUpdateGetAddcontLatestVersion(0, label, &info) == 0); Require(info.size == sizeof(info) + 8 && !info.found); const auto* bytes = reinterpret_cast(&info); for (std::size_t i = sizeof(info.size); i < sizeof(info); ++i) Require(bytes[i] == 0); Require(sceGameUpdateTerminate() == 0); Require(sceGameUpdateTerminate() == notInitialized); info.size = sizeof(info); Require(sceGameUpdateGetAddcontLatestVersion(0, label, &info) == notInitialized); }