Files
AnyPS5/core/libs/tests/GuestContentDelete.cpp
T
screamm e8627d607b feat(libSceContentDelete): add sceContentDeleteById and sceContentDeleteByPath
Cult of the Lamb (PPSA06465, #2686) stops at start-up on the first one:

    FAIL: unresolved ELF import pXJh3aVk8Ks from libSceContentDelete.prx

Both exports have been on main without an implementation (#2740); the
call itself has not been observed yet.

Orbital (cc408367, tools/ida/db_types.json:541-542) and SharpProspero
(5dfdb4b0, Interop/Content/ContentDelete.cs:25-42) agree on the
signatures: a 64-bit SceContentSearchContentId and a UTF-8 path. The
content library is empty on the host, since libSceContentExport exports
nothing into it, so no id or path can be found. SharpProspero gives only
NoPermission (0x809D5006) and no public source gives the not-found code,
so both calls throw with the id or path named once the null path and the
initialization are checked, like the "not in the host content library"
throws of #3724. sceContentDeleteById moves from
guest_content_unimplemented to the new guest_content_delete test.

NIDs pXJh3aVk8Ks and qC3QW+AltHs match tools/nid_names.py and the shadPS4
aerolib list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 928184824a4acdf36a58287034bff8154c861835)
2026-10-17 14:20:14 +02:00

50 lines
2.1 KiB
C++

#include "SceTypes.hpp"
#include <cstdint>
#include <cstdlib>
#include <stdexcept>
#include <string>
extern "C" int APS5_VABI sceContentDeleteInitialize(const ContentDeleteInitParam* init_param);
extern "C" int APS5_VABI sceContentDeleteTerminate(void);
extern "C" int APS5_VABI sceContentDeleteById(std::int64_t contentId);
extern "C" int APS5_VABI sceContentDeleteByPath(const char* contentPath);
namespace {
void Require(bool value) { if (!value) std::abort(); }
template <typename TAction>
std::string LogicErrorMessage(TAction action) {
try {
action();
} catch (const std::invalid_argument&) {
return "invalid argument";
} catch (const std::logic_error& error) {
return error.what();
}
return "returned";
}
bool Contains(const std::string& text, const std::string& part) { return text.find(part) != std::string::npos; }
}
int main() {
Require(LogicErrorMessage([] { sceContentDeleteById(1); }) == "sceContentDeleteById: not initialized");
Require(LogicErrorMessage([] { sceContentDeleteByPath("/user/av_contents/photo/a.png"); }) == "sceContentDeleteByPath: not initialized");
Require(LogicErrorMessage([] { sceContentDeleteByPath(nullptr); }) == "invalid argument");
ContentDeleteInitParam param{};
param.heap_size = 0x10000;
Require(sceContentDeleteInitialize(&param) == 0);
Require(LogicErrorMessage([] { sceContentDeleteByPath(nullptr); }) == "invalid argument");
Require(Contains(LogicErrorMessage([] { sceContentDeleteByPath("/user/av_contents/photo/a.png"); }), "sceContentDeleteByPath: /user/av_contents/photo/a.png is not in the host content library"));
Require(Contains(LogicErrorMessage([] { sceContentDeleteById(0x123456789); }), "sceContentDeleteById: content id 4886718345 is not in the host content library"));
Require(Contains(LogicErrorMessage([] { sceContentDeleteById(-1); }), "sceContentDeleteById: content id -1 is not in the host content library"));
Require(sceContentDeleteTerminate() == 0);
Require(LogicErrorMessage([] { sceContentDeleteById(1); }) == "sceContentDeleteById: not initialized");
return 0;
}