Merge pull request #1436 from tototomate123/fix/hfw-offline-imports
fix(prx): add missing HFW imports with strict offline handling
This commit is contained in:
commit
461fcfc7f3
|
|
@ -131,6 +131,15 @@ endforeach()
|
|||
add_custom_target(libs DEPENDS ${PATCHED_OUTPUTS})
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_test_executable(guest_offline_imports_tests tests/GuestOfflineImports.cpp)
|
||||
target_include_directories(guest_offline_imports_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_offline_imports_tests PRIVATE libSceHttp libSceNpEntitlementAccess libSceRudp libc)
|
||||
configure_windows_unwind(guest_offline_imports_tests)
|
||||
add_test(NAME guest_offline_imports COMMAND guest_offline_imports_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(guest_offline_imports PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceHttp>")
|
||||
endif()
|
||||
add_test_executable(savedata_memory_metadata_tests tests/SaveDataMemoryMetadata.cpp)
|
||||
target_include_directories(savedata_memory_metadata_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(savedata_memory_metadata_tests PRIVATE libSceSaveData.native)
|
||||
|
|
|
|||
|
|
@ -1276,6 +1276,10 @@ struct NpEntitlementAccessAddcontEntitlementInfo {
|
|||
std::uint32_t download_status;
|
||||
};
|
||||
|
||||
struct NpEntitlementAccessEntitlementKey {
|
||||
std::uint8_t data[16];
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct NpUniversalDataSystemInitParam {
|
||||
|
|
|
|||
|
|
@ -141,6 +141,13 @@ int APS5_VABI sceHttpSetAuthEnabled(int id, int enable) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceHttpSetCookieEnabled(int id, int enable) {
|
||||
(void)id;
|
||||
if (static_cast<uint32_t>(enable) > 1) return ERROR_INVALID_VALUE;
|
||||
if (enable != 0) NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceHttpSetAutoRedirect(int id, int enable) {
|
||||
(void)id;
|
||||
(void)enable;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,16 @@ int APS5_VABI sceNpEntitlementAccessGetSkuFlag(uint32_t* sku_flag) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpEntitlementAccessGetEntitlementKey(
|
||||
uint32_t serviceLabel, const NpUnifiedEntitlementLabel* entitlementLabel,
|
||||
NpEntitlementAccessEntitlementKey* key) {
|
||||
(void)serviceLabel;
|
||||
constexpr int errorParameter = static_cast<int>(0x817D0002);
|
||||
constexpr int errorNoEntitlement = static_cast<int>(0x817D0007);
|
||||
if (!entitlementLabel || !key) return errorParameter;
|
||||
return errorNoEntitlement;
|
||||
}
|
||||
|
||||
int APS5_VABI sceNpEntitlementAccessInitialize(const NpEntitlementAccessInitParam* init_param, NpEntitlementAccessBootParam* boot_param) {
|
||||
(void)init_param;
|
||||
(void)boot_param;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,13 @@ int APS5_VABI sceRudpActivate() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceRudpGetStatus(void* status, std::size_t size) {
|
||||
(void)status;
|
||||
(void)size;
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceRudpEnd(int ctx_id) {
|
||||
std::lock_guard<std::mutex> lk(g_mutex);
|
||||
if (!g_inited) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
#include "SceTypes.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
|
||||
extern "C" {
|
||||
int APS5_VABI sceHttpSetCookieEnabled(int, int);
|
||||
int APS5_VABI sceHttpSendRequest(int, const void*, std::size_t);
|
||||
int APS5_VABI sceNpEntitlementAccessGetEntitlementKey(
|
||||
std::uint32_t, const NpUnifiedEntitlementLabel*, NpEntitlementAccessEntitlementKey*);
|
||||
int APS5_VABI sceRudpInit_nid_postfix(void*, int);
|
||||
int APS5_VABI sceRudpGetStatus(void*, std::size_t);
|
||||
int APS5_VABI sceRudpTerminate();
|
||||
}
|
||||
|
||||
static void Require(bool value) { if (!value) std::abort(); }
|
||||
|
||||
int main() {
|
||||
constexpr int invalidValue = static_cast<int>(0x804311FE);
|
||||
constexpr int network = static_cast<int>(0x80431063);
|
||||
Require(sceHttpSetCookieEnabled(1, 0) == 0);
|
||||
Require(sceHttpSendRequest(1, nullptr, 0) == network);
|
||||
bool cookieUnsupported = false;
|
||||
try {
|
||||
sceHttpSetCookieEnabled(1, 1);
|
||||
} catch (const std::runtime_error& error) {
|
||||
cookieUnsupported = std::string_view(error.what()) == "sceHttpSetCookieEnabled not implemented";
|
||||
}
|
||||
Require(cookieUnsupported);
|
||||
for (int enabled : {-1, 2, 0x100}) {
|
||||
Require(sceHttpSetCookieEnabled(1, enabled) == invalidValue);
|
||||
}
|
||||
|
||||
constexpr int parameter = static_cast<int>(0x817D0002);
|
||||
constexpr int noEntitlement = static_cast<int>(0x817D0007);
|
||||
static_assert(sizeof(NpEntitlementAccessEntitlementKey) == 16);
|
||||
NpUnifiedEntitlementLabel label{};
|
||||
std::memcpy(label.data, "unowned-addon", 14);
|
||||
struct KeyBuffer {
|
||||
std::uint64_t before;
|
||||
NpEntitlementAccessEntitlementKey key;
|
||||
std::uint64_t after;
|
||||
} output;
|
||||
std::memset(&output, 0xa5, sizeof(output));
|
||||
std::array<unsigned char, sizeof(output)> original{};
|
||||
std::memcpy(original.data(), &output, sizeof(output));
|
||||
Require(sceNpEntitlementAccessGetEntitlementKey(0, nullptr, &output.key) == parameter);
|
||||
Require(sceNpEntitlementAccessGetEntitlementKey(0, &label, nullptr) == parameter);
|
||||
Require(sceNpEntitlementAccessGetEntitlementKey(0, nullptr, nullptr) == parameter);
|
||||
for (std::uint32_t serviceLabel : {0u, 1u, 0xffffffffu}) {
|
||||
Require(sceNpEntitlementAccessGetEntitlementKey(serviceLabel, &label, &output.key) == noEntitlement);
|
||||
Require(std::memcmp(&output, original.data(), sizeof(output)) == 0);
|
||||
}
|
||||
|
||||
std::array<unsigned char, 248> status;
|
||||
status.fill(0x5a);
|
||||
const auto originalStatus = status;
|
||||
auto unsupported = [](void* data, std::size_t size) {
|
||||
try {
|
||||
sceRudpGetStatus(data, size);
|
||||
} catch (const std::runtime_error& error) {
|
||||
return std::string_view(error.what()) == "sceRudpGetStatus not implemented";
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Require(unsupported(status.data(), status.size()));
|
||||
Require(status == originalStatus);
|
||||
Require(sceRudpInit_nid_postfix(nullptr, 0) == 0);
|
||||
Require(unsupported(status.data(), status.size()));
|
||||
Require(status == originalStatus);
|
||||
Require(unsupported(nullptr, 0));
|
||||
Require(sceRudpTerminate() == 0);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -38,6 +38,10 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
|
||||
### Unknown function info
|
||||
|
||||
- [sceNpEntitlementAccessGetEntitlementKey](../../core/libs/prx/libSceNpEntitlementAccess/Export.cpp) - the three-argument signature, 16-byte key and errors `0x817D0002`/`0x817D0007` follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libNet.cpp); PPSA01521 passes a service label, entitlement label and output pointer. Only the no-key path is implemented: local entitlement labels carry no keys, and the output is untouched on failure. Console error precedence and key provisioning are unverified
|
||||
- [sceRudpGetStatus](../../core/libs/prx/libSceRudp/Export.cpp) - PPSA01521 passes an output pointer and byte count `0xF8`; the status layout, size rules and error behavior are unknown. The export throws without writing output, including after initialization. [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/rudp/rudp.cpp) declares it without arguments and returns success without writing status
|
||||
- [sceHttpSetCookieEnabled](../../core/libs/prx/libSceHttp/Export.cpp) - the two-argument signature and 0/1 enable values follow [VitaSDK](https://github.com/vitasdk/vita-headers/blob/master/include/psp2/net/http.h) and [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.cpp); PPSA01521 passes 0 to disable cookies. Disabling succeeds because the offline HTTP backend has no cookie engine; enabling throws. Invalid enable values use the same error as `sceHttpSetInflateGZIPEnabled`. Like the existing offline HTTP setters, the handle is not validated; requests still fail with the network error. Console behavior is unverified
|
||||
|
||||
- [sceHmd2Initialize](../../core/libs/prx/libSceHmd2/Export.cpp) (libSceHmd2) - the error the console returns when the PS VR2 runtime is unavailable is unknown; it returns libSceHmd's `UNSUPPORTED_FEATURE` (0x81110016). PPSA01317 passes a pointer to 16 zeroed bytes and only tests the result for non-zero
|
||||
- PPSA01317 imports declared without parameters, signatures unknown: the remaining [libSceHmd2](../../core/libs/prx/libSceHmd2/Export.cpp) and [libSceVrTracker2](../../core/libs/prx/libSceVrTracker2/Export.cpp) exports. Names from the aerolib NID list
|
||||
- [libSceMbus](../../core/libs/prx/libSceMbus/Export.cpp) (`libSceDeviceService`) - signatures taken from PPSA01317, which calls `sceDeviceServiceInitialize(3, 0)`, polls `sceDeviceServiceGetEventState(1)` and queries again when bit 0 or 1 is set, and calls `sceDeviceServiceQueryDeviceInfo_(0x7001, 0, 0, infos, 1, &count, &unknown, 0x70)`, treating a negative result as an error and `count` as the number of entries. The host has no devices: the event state is 0 and a query returns 0 with `count` 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue