From 161158868220be09401aa0c4d5712acab0200c6c Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 26 Jan 2024 23:39:37 +0100 Subject: [PATCH] sceNpCommerce2: add some error checks --- rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp | 570 +++++++++++++++++++++- rpcs3/Emu/Cell/Modules/sceNpCommerce2.h | 3 +- 2 files changed, 555 insertions(+), 18 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp index f682c7a2c5..4d3c5fe791 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp @@ -6,6 +6,8 @@ #include "sceNp.h" #include "cellSysutil.h" +#include "Emu/Cell/lv2/sys_process.h" + #include "Emu/NP/np_handler.h" #include "Emu/NP/np_contexts.h" @@ -67,15 +69,55 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } +void initialize_common_data(SceNpCommerce2CommonData* common_data, vm::ptr data, u32 internal_data_addr, u32 internal_data_size) +{ + std::memset(common_data, 0, sizeof(SceNpCommerce2CommonData)); + common_data->version = SCE_NP_COMMERCE2_VERSION; + common_data->buf_head = data.addr(); + common_data->data = internal_data_addr; + common_data->data_size = internal_data_size; +} + +error_code check_and_get_data(vm::ptr /*data*/, u32 data_size, u32& /*internal_data_addr*/, u32& /*internal_data_size*/) +{ + if (data_size < 60) + return SCE_NP_COMMERCE2_ERROR_INVALID_RESULT_DATA; + + // TODO: check and extract data + if (true) + return SCE_NP_COMMERCE2_ERROR_INVALID_RESULT_DATA; + + return not_an_error(60); +} + error_code sceNpCommerce2ExecuteStoreBrowse(s32 targetType, vm::cptr targetId, s32 userdata) { sceNpCommerce2.todo("sceNpCommerce2ExecuteStoreBrowse(targetType=%d, targetId=%s, userdata=%d)", targetType, targetId, userdata); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (targetType < SCE_NP_COMMERCE2_STORE_BROWSE_TYPE_CATEGORY || targetType > SCE_NP_COMMERCE2_STORE_BROWSE_TYPE_PRODUCT_CODE) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_TYPE; + + if (targetType < SCE_NP_COMMERCE2_STORE_BROWSE_TYPE_PRODUCT_CODE && (!targetId || !targetId[0])) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_ID; + return CELL_OK; } error_code sceNpCommerce2GetStoreBrowseUserdata(vm::ptr userdata) { sceNpCommerce2.todo("sceNpCommerce2GetStoreBrowseUserdata(userdata=*0x%x)", userdata); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!userdata) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + *userdata = 0; // TODO + return CELL_OK; } @@ -83,6 +125,9 @@ error_code sceNpCommerce2Init() { sceNpCommerce2.warning("sceNpCommerce2Init()"); + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_ALREADY_INITIALIZED; + auto& nph = g_fxo->get>(); if (!nph.is_NP_init) @@ -104,7 +149,22 @@ error_code sceNpCommerce2CreateCtx(u32 version, vm::cptr npId, vm::ptr< { sceNpCommerce2.warning("sceNpCommerce2CreateCtx(version=%d, npId=*0x%x, handler=*0x%x, arg=*0x%x, ctx_id=*0x%x)", version, npId, handler, arg, ctx_id); - *ctx_id = create_commerce2_context(version, npId, handler, arg); + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (version > SCE_NP_COMMERCE2_VERSION) + return SCE_NP_COMMERCE2_ERROR_UNSUPPORTED_VERSION; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_CTX_MAX; + + if (!npId) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + if (ctx_id) + *ctx_id = create_commerce2_context(version, npId, handler, arg); + else + sceNpCommerce2.warning("sceNpCommerce2CreateCtx: ctx_id is null"); return CELL_OK; } @@ -113,18 +173,30 @@ s32 sceNpCommerce2DestroyCtx(u32 ctx_id) { sceNpCommerce2.warning("sceNpCommerce2DestroyCtx(ctx_id=%d)", ctx_id); + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + if (!destroy_commerce2_context(ctx_id)) { - return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; // TODO: verify + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; } return CELL_OK; } -s32 sceNpCommerce2EmptyStoreCheckStart(u32 ctx_id, s32 store_check_type, vm::cptr target_id) +error_code sceNpCommerce2EmptyStoreCheckStart(u32 ctx_id, s32 store_check_type, vm::cptr target_id) { sceNpCommerce2.warning("sceNpCommerce2EmptyStoreCheckStart(ctx_id=%d, store_check_type=%d, target_id=*0x%x(%s))", ctx_id, store_check_type, target_id, target_id); + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!target_id || !target_id[0]) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_ID; + + if (store_check_type != SCE_NP_COMMERCE2_STORE_CHECK_TYPE_CATEGORY) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + const auto ctx = get_commerce2_context(ctx_id); if (!ctx) @@ -147,25 +219,39 @@ s32 sceNpCommerce2EmptyStoreCheckStart(u32 ctx_id, s32 store_check_type, vm::cpt error_code sceNpCommerce2EmptyStoreCheckAbort(u32 ctx_id) { sceNpCommerce2.todo("sceNpCommerce2EmptyStoreCheckAbort(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + return CELL_OK; } -s32 sceNpCommerce2EmptyStoreCheckFinish(u32 ctx_id, vm::ptr is_empty) +error_code sceNpCommerce2EmptyStoreCheckFinish(u32 ctx_id, vm::ptr is_empty) { sceNpCommerce2.warning("sceNpCommerce2EmptyStoreCheckFinish(ctx_id=%d, is_empty=*0x%x)", ctx_id, is_empty); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!is_empty) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + *is_empty = SCE_NP_COMMERCE2_STORE_IS_NOT_EMPTY; return CELL_OK; } -s32 sceNpCommerce2CreateSessionStart(u32 ctx_id) +error_code sceNpCommerce2CreateSessionStart(u32 ctx_id) { sceNpCommerce2.warning("sceNpCommerce2CreateSessionStart(ctx_id=%d)", ctx_id); + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + const auto ctx = get_commerce2_context(ctx_id); if (!ctx) { - return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; // TODO: verify + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; } if (ctx->context_callback) @@ -183,37 +269,135 @@ s32 sceNpCommerce2CreateSessionStart(u32 ctx_id) error_code sceNpCommerce2CreateSessionAbort(u32 ctx_id) { sceNpCommerce2.todo("sceNpCommerce2CreateSessionAbort(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } s32 sceNpCommerce2CreateSessionFinish(u32 ctx_id, vm::ptr sessionInfo) { sceNpCommerce2.warning("sceNpCommerce2CreateSessionFinish(ctx_id=%d, sessionInfo=*0x%x)", ctx_id, sessionInfo); - memset(sessionInfo.get_ptr(), 0, sizeof(sessionInfo)); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + + s32 sdk_ver{}; + [[maybe_unused]] s32 ret = process_get_sdk_version(process_getpid(), sdk_ver); + + if (sdk_ver < 0x300000) + { + std::memset(sessionInfo.get_ptr(), 0, 8); // currencyCode, decimals + } + else + { + std::memset(sessionInfo.get_ptr(), 0, 44); // sizeof(SceNpCommerce2SessionInfo) - reserved + } + + // TODO + if (false) + { + sessionInfo->currencyCode[0] = 'U'; + sessionInfo->currencyCode[1] = 'S'; + sessionInfo->currencyCode[2] = 'D'; + sessionInfo->currencyCode[3] = '\0'; + sessionInfo->decimals = 2; + sessionInfo->currencySymbol[0] = '$'; + sessionInfo->currencySymbol[1] = '\0'; + sessionInfo->currencySymbol[2] = '\0'; + sessionInfo->currencySymbol[3] = '\0'; + sessionInfo->symbolPosition = SCE_NP_COMMERCE2_SYM_POS_PRE; + sessionInfo->symbolWithSpace = false; + sessionInfo->padding1[3]; + sessionInfo->thousandSeparator[0] = ','; + sessionInfo->thousandSeparator[1] = '\0'; + sessionInfo->thousandSeparator[2] = '\0'; + sessionInfo->thousandSeparator[3] = '\0'; + sessionInfo->decimalLetter[0] = '.'; + sessionInfo->decimalLetter[1] = '\0'; + sessionInfo->decimalLetter[2] = '\0'; + sessionInfo->decimalLetter[3] = '\0'; + } + return CELL_OK; } error_code sceNpCommerce2GetCategoryContentsCreateReq(u32 ctx_id, vm::ptr req_id) { sceNpCommerce2.todo("sceNpCommerce2GetCategoryContentsCreateReq(ctx_id=%d, req_id=*0x%x)", ctx_id, req_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!req_id) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetCategoryContentsStart(u32 req_id, vm::cptr categoryId, u32 startPosition, u32 maxCountOfResults) { sceNpCommerce2.todo("sceNpCommerce2GetCategoryContentsStart(req_id=%d, categoryId=%s, startPosition=%d, maxCountOfResults=%d)", req_id, categoryId, startPosition, maxCountOfResults); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!categoryId || maxCountOfResults > SCE_NP_COMMERCE2_GETCAT_MAX_COUNT) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + return CELL_OK; +} + +error_code get_result(u32 req_id, vm::ptr buf, u32 buf_size, vm::ptr fill_size) +{ + if (!buf || !buf_size || ! fill_size) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + // TODO + return CELL_OK; } error_code sceNpCommerce2GetCategoryContentsGetResult(u32 req_id, vm::ptr buf, u32 buf_size, vm::ptr fill_size) { sceNpCommerce2.todo("sceNpCommerce2GetCategoryContentsGetResult(req_id=%d, buf=*0x%x, buf_size=%d, fill_size=*0x%x)", req_id, buf, buf_size, fill_size); - return CELL_OK; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (buf_size < SCE_NP_COMMERCE2_RECV_BUF_SIZE) + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_BUF_SIZE; + + return get_result(req_id, buf, buf_size, fill_size); } error_code sceNpCommerce2InitGetCategoryContentsResult(vm::ptr result, vm::ptr data, u32 data_size) { sceNpCommerce2.todo("sceNpCommerce2InitGetCategoryContentsResult(result=*0x%x, data=*0x%x, data_size=%d)", result, data, data_size); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!result || !data || !data_size) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + u32 internal_data_addr = 0, internal_data_size = 0; + error_code error = check_and_get_data(data, data_size, internal_data_addr, internal_data_size); + if (error < 0) + return error; + + std::memset(result.get_ptr(), 0, sizeof(SceNpCommerce2GetCategoryContentsResult)); + initialize_common_data(&result->commonData, data, internal_data_addr, internal_data_size); + return CELL_OK; } @@ -221,6 +405,12 @@ error_code sceNpCommerce2GetCategoryInfo(vm::cptr result, u32 index, vm::ptr contentInfo) { sceNpCommerce2.todo("sceNpCommerce2GetContentInfo(result=*0x%x, index=%d, contentInfo=*0x%x)", result, index, contentInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!result || !contentInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetCategoryInfoFromContentInfo(vm::cptr contentInfo, vm::ptr categoryInfo) { sceNpCommerce2.todo("sceNpCommerce2GetCategoryInfoFromContentInfo(contentInfo=*0x%x, categoryInfo=*0x%x)", contentInfo, categoryInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!contentInfo || !categoryInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetGameProductInfoFromContentInfo(vm::cptr contentInfo, vm::ptr gameProductInfo) { sceNpCommerce2.todo("sceNpCommerce2GetGameProductInfoFromContentInfo(contentInfo=*0x%x, gameProductInfo=*0x%x)", contentInfo, gameProductInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!contentInfo || !gameProductInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } @@ -252,30 +463,77 @@ error_code sceNpCommerce2DestroyGetCategoryContentsResult(vm::ptr req_id) { sceNpCommerce2.todo("sceNpCommerce2GetProductInfoCreateReq(ctx_id=%d, req_id=*0x%x)", ctx_id, req_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!req_id) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2GetProductInfoStart(u32 req_id, vm::cptr categoryId, vm::cptr productId) { sceNpCommerce2.todo("sceNpCommerce2GetProductInfoStart(req_id=%d, categoryId=%s, productId=%s)", req_id, categoryId, productId); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!productId) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetProductInfoGetResult(u32 req_id, vm::ptr buf, u32 buf_size, vm::ptr fill_size) { sceNpCommerce2.todo("sceNpCommerce2GetProductInfoGetResult(req_id=%d, buf=*0x%x, buf_size=%d, fill_size=*0x%x)", req_id, buf, buf_size, fill_size); - return CELL_OK; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (buf_size < SCE_NP_COMMERCE2_RECV_BUF_SIZE) + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_BUF_SIZE; + + return get_result(req_id, buf, buf_size, fill_size); } error_code sceNpCommerce2InitGetProductInfoResult(vm::ptr result, vm::ptr data, u32 data_size) { sceNpCommerce2.todo("sceNpCommerce2InitGetProductInfoResult(result=*0x%x, data=*0x%x, data_size=%d)", result, data, data_size); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!result || !data || !data_size) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + u32 internal_data_addr = 0, internal_data_size = 0; + error_code error = check_and_get_data(data, data_size, internal_data_addr, internal_data_size); + if (error < 0) + return error; + + std::memset(result.get_ptr(), 0, sizeof(SceNpCommerce2GetProductInfoResult)); + initialize_common_data(&result->commonData, data, internal_data_addr, internal_data_size); + return CELL_OK; } error_code sceNpCommerce2GetGameProductInfo(vm::cptr result, vm::ptr gameProductInfo) { sceNpCommerce2.todo("sceNpCommerce2GetGameProductInfo(result=*0x%x, gameProductInfo=*0x%x)", result, gameProductInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!result || !gameProductInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } @@ -288,30 +546,77 @@ error_code sceNpCommerce2DestroyGetProductInfoResult(vm::ptr req_id) { sceNpCommerce2.todo("sceNpCommerce2GetProductInfoListCreateReq(ctx_id=%d, req_id=*0x%x)", ctx_id, req_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!req_id) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } -error_code sceNpCommerce2GetProductInfoListStart(u32 req_id, vm::cptr productIds, u32 productNum) +error_code sceNpCommerce2GetProductInfoListStart(u32 req_id, vm::cpptr productIds, u32 productNum) { sceNpCommerce2.todo("sceNpCommerce2GetProductInfoListStart(req_id=%d, productIds=*0x%x, productNum=%d)", req_id, productIds, productNum); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!productIds || !productNum || productNum > SCE_NP_COMMERCE2_GETPRODLIST_MAX_COUNT) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetProductInfoListGetResult(u32 req_id, vm::ptr buf, u32 buf_size, vm::ptr fill_size) { sceNpCommerce2.todo("sceNpCommerce2GetProductInfoListGetResult(req_id=%d, buf=*0x%x, buf_size=%d, fill_size=*0x%x)", req_id, buf, buf_size, fill_size); - return CELL_OK; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (buf_size < SCE_NP_COMMERCE2_RECV_BUF_SIZE) + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_BUF_SIZE; + + return get_result(req_id, buf, buf_size, fill_size); } error_code sceNpCommerce2InitGetProductInfoListResult(vm::ptr result, vm::ptr data, u32 data_size) { sceNpCommerce2.todo("sceNpCommerce2InitGetProductInfoListResult(result=*0x%x, data=*0x%x, data_size=%d)", result, data, data_size); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!result || !data || !data_size) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + u32 internal_data_addr = 0, internal_data_size = 0; + error_code error = check_and_get_data(data, data_size, internal_data_addr, internal_data_size); + if (error < 0) + return error; + + std::memset(result.get_ptr(), 0, sizeof(SceNpCommerce2GetProductInfoListResult)); + initialize_common_data(&result->commonData, data, internal_data_addr, internal_data_size); + return CELL_OK; } error_code sceNpCommerce2GetGameProductInfoFromGetProductInfoListResult(vm::cptr result, u32 index, vm::ptr gameProductInfo) { sceNpCommerce2.todo("sceNpCommerce2GetGameProductInfoFromGetProductInfoListResult(result=*0x%x, index=%d, data=*0x%x)", result, index, gameProductInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!result || !gameProductInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } @@ -324,114 +629,345 @@ error_code sceNpCommerce2DestroyGetProductInfoListResult(vm::ptr gameProductInfo, vm::ptr contentRatingInfo) { sceNpCommerce2.todo("sceNpCommerce2GetContentRatingInfoFromGameProductInfo(gameProductInfo=*0x%x, contentRatingInfo=*0x%x)", gameProductInfo, contentRatingInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!gameProductInfo || !contentRatingInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetContentRatingInfoFromCategoryInfo(vm::cptr categoryInfo, vm::ptr contentRatingInfo) { sceNpCommerce2.todo("sceNpCommerce2GetContentRatingInfoFromCategoryInfo(categoryInfo=*0x%x, contentRatingInfo=*0x%x)", categoryInfo, contentRatingInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!categoryInfo || !contentRatingInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetContentRatingDescriptor(vm::cptr contentRatingInfo, u32 index, vm::ptr contentRatingDescriptor) { sceNpCommerce2.todo("sceNpCommerce2GetContentRatingDescriptor(contentRatingInfo=*0x%x, index=%d, contentRatingDescriptor=*0x%x)", contentRatingInfo, index, contentRatingDescriptor); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!contentRatingInfo || !contentRatingDescriptor) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetGameSkuInfoFromGameProductInfo(vm::cptr gameProductInfo, u32 index, vm::ptr gameSkuInfo) { sceNpCommerce2.todo("sceNpCommerce2GetGameSkuInfoFromGameProductInfo(gameProductInfo=*0x%x, index=%d, gameSkuInfo=*0x%x)", gameProductInfo, index, gameSkuInfo); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!gameProductInfo || !gameSkuInfo) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + return CELL_OK; } error_code sceNpCommerce2GetPrice(u32 ctx_id, vm::ptr buf, u32 buflen, u32 price) { sceNpCommerce2.todo("sceNpCommerce2GetPrice(ctx_id=%d, buf=*0x%x, buflen=%d, price=%d)", ctx_id, buf, buflen, price); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } -error_code sceNpCommerce2DoCheckoutStartAsync(u32 ctx_id, vm::cptr sku_ids, u32 sku_num, u32 container) +error_code sceNpCommerce2DoCheckoutStartAsync(u32 ctx_id, vm::cpptr sku_ids, u32 sku_num, u32 container) { sceNpCommerce2.todo("sceNpCommerce2DoCheckoutStartAsync(ctx_id=%d, sku_ids=*0x%x, sku_num=%d, container=%d)", ctx_id, sku_ids, sku_num, container); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (sku_num > SCE_NP_COMMERCE2_SKU_CHECKOUT_MAX) + return SCE_NP_COMMERCE2_ERROR_INVALID_SKU_NUM; + + u32 uvar5 = sku_num; + + for (u32 i = 0; i < sku_num; i++) + { + if (!sku_ids[i] || !sku_ids[i][0]) + return SCE_NP_COMMERCE2_ERROR_INVALID_SKUID; + } + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INVALID_MEMORY_CONTAINER; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_MEMORY_CONTAINER; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2DoCheckoutFinishAsync(u32 ctx_id) { sceNpCommerce2.todo("sceNpCommerce2DoCheckoutFinishAsync(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2DoProductBrowseStartAsync(u32 ctx_id, vm::cptr product_id, u32 container, vm::cptr param) { sceNpCommerce2.todo("sceNpCommerce2DoProductBrowseStartAsync(ctx_id=%d, product_id=%s, container=%d, param=*0x%x)", ctx_id, product_id, container, param); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!product_id || !product_id[0]) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + if (param && param->size != sizeof(SceNpCommerce2ProductBrowseParam)) + return SCE_NP_COMMERCE2_ERROR_INVALID_SIZE; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INVALID_MEMORY_CONTAINER; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_MEMORY_CONTAINER; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2DoProductBrowseFinishAsync(u32 ctx_id) { sceNpCommerce2.todo("sceNpCommerce2DoProductBrowseFinishAsync(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } -error_code sceNpCommerce2DoDlListStartAsync(u32 ctx_id, vm::cptr service_id, vm::cptr sku_ids, u32 sku_num, u32 container) +error_code sceNpCommerce2DoDlListStartAsync(u32 ctx_id, vm::cptr service_id, vm::cpptr sku_ids, u32 sku_num, u32 container) { sceNpCommerce2.todo("sceNpCommerce2DoDlListStartAsync(ctx_id=%d, service_id=%s, sku_ids=*0x%x, sku_num=%d, container=%d)", ctx_id, service_id, sku_ids, sku_num, container); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (sku_num > SCE_NP_COMMERCE2_SKU_CHECKOUT_MAX) + return SCE_NP_COMMERCE2_ERROR_INVALID_SKU_NUM; + + if (sku_num == 0) + { + if (!service_id) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + } + else + { + for (u32 i = 0; i < sku_num; i++) + { + if (!sku_ids[i] || !sku_ids[i][0]) + return SCE_NP_COMMERCE2_ERROR_INVALID_SKUID; + } + } + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INVALID_MEMORY_CONTAINER; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_MEMORY_CONTAINER; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2DoDlListFinishAsync(u32 ctx_id) { sceNpCommerce2.todo("sceNpCommerce2DoDlListFinishAsync(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2DoProductCodeStartAsync(u32 ctx_id, u32 container, vm::cptr param) { sceNpCommerce2.todo("sceNpCommerce2DoProductCodeStartAsync(ctx_id=%d, container=%d, param=*0x%x)", ctx_id, container, param); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!param) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + if (param->size != sizeof(SceNpCommerce2ProductCodeParam)) + return SCE_NP_COMMERCE2_ERROR_INVALID_SIZE; + + if (param->inputMode != SCE_NP_COMMERCE2_PRODUCT_CODE_INPUT_MODE_USER_INPUT) + { + if (param->inputMode != SCE_NP_COMMERCE2_PRODUCT_CODE_INPUT_MODE_CODE_SPECIFIED) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_TYPE; + + if (!param->code1[0] || !param->code2[0] || !param->code3[0]) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_ID; + + for (u32 i = 0; i < SCE_NP_COMMERCE2_PRODUCT_CODE_BLOCK_LEN; i++) + { + if (!isalnum(param->code1[i]) || !isalnum(param->code2[i]) || !isalnum(param->code3[i])) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_ID; + } + } + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INVALID_MEMORY_CONTAINER; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_MEMORY_CONTAINER; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2DoProductCodeFinishAsync(u32 ctx_id) { sceNpCommerce2.todo("sceNpCommerce2DoProductCodeFinishAsync(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } error_code sceNpCommerce2GetBGDLAvailability(vm::ptr bgdlAvailability) { sceNpCommerce2.todo("sceNpCommerce2GetBGDLAvailability(bgdlAvailability=*0x%x)", bgdlAvailability); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!bgdlAvailability) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + *bgdlAvailability = false; // TODO + return CELL_OK; } error_code sceNpCommerce2SetBGDLAvailability(b8 bgdlAvailability) { sceNpCommerce2.todo("sceNpCommerce2SetBGDLAvailability(bgdlAvailability=%d)", bgdlAvailability); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + return CELL_OK; } error_code sceNpCommerce2AbortReq(u32 req_id) { sceNpCommerce2.todo("sceNpCommerce2AbortReq(req_id=%d)", req_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + return CELL_OK; } error_code sceNpCommerce2DestroyReq(u32 req_id) { sceNpCommerce2.todo("sceNpCommerce2DestroyReq(req_id=%d)", req_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + return CELL_OK; } -error_code sceNpCommerce2DoServiceListStartAsync() +error_code sceNpCommerce2DoServiceListStartAsync(u32 ctx_id, vm::ptr serviceId, u32 container, vm::ptr param) { - sceNpCommerce2.todo("sceNpCommerce2DoServiceListStartAsync()"); + sceNpCommerce2.todo("sceNpCommerce2DoServiceListStartAsync(ctx_id=%d, serviceId=*0x%x, container=%d, param=*0x%x)", ctx_id, serviceId, container, param); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + if (!param || !serviceId) + return SCE_NP_COMMERCE2_ERROR_INVALID_ARGUMENT; + + if (param->size != sizeof(SceNpCommerce2ProductBrowseParam)) + return SCE_NP_COMMERCE2_ERROR_INVALID_SIZE; + + if (!serviceId[0]) + return SCE_NP_COMMERCE2_ERROR_INVALID_TARGET_ID; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INVALID_MEMORY_CONTAINER; + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_INSUFFICIENT_MEMORY_CONTAINER; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } -error_code sceNpCommerce2DoServiceListFinishAsync() +error_code sceNpCommerce2DoServiceListFinishAsync(u32 ctx_id) { - sceNpCommerce2.todo("sceNpCommerce2DoServiceListFinishAsync()"); + sceNpCommerce2.todo("sceNpCommerce2DoServiceListFinishAsync(ctx_id=%d)", ctx_id); + + if (false) // TODO + return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; + + const auto ctx = get_commerce2_context(ctx_id); + if (!ctx) + return SCE_NP_COMMERCE2_ERROR_CTX_NOT_FOUND; + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.h b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.h index 98dff3aea1..c6600e9cce 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.h +++ b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.h @@ -265,6 +265,7 @@ struct SceNpCommerce2GameProductInfo struct SceNpCommerce2GetProductInfoListResult { SceNpCommerce2CommonData commonData; + be_t countOfProductInfo; }; // Structure for rating information @@ -316,7 +317,7 @@ struct SceNpCommerce2ProductBrowseParam struct SceNpCommerce2ProductCodeParam { be_t size; - be_t inputMode; // Unsigned ints go into be_t, right? + be_t inputMode; s8 code1[SCE_NP_COMMERCE2_PRODUCT_CODE_BLOCK_LEN + 1]; s8 padding1[3]; s8 code2[SCE_NP_COMMERCE2_PRODUCT_CODE_BLOCK_LEN + 1];