mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-22 16:43:05 -05:00
AnyPS5 resolves a title's imports by NID, so a title that imports a system function that no AnyPS5 library provides fails to load with an unresolved import. This declares 222 such exports across 11 PS5 system libraries that AnyPS5 implements but does not provide. Each declaration calls NotImplemented_nid_no_patch and returns 0; none of them implements the function. A declaration with a credible prototype uses it and cites the source with a pinned commit; the rest are declared without parameters, which resolves the import without making an ABI claim. The technical-debt files record the limitation per library. The list is the intersection of the export table of the console's library (function symbols only), the pinned aerolib names and the functions not yet defined anywhere in the repo. Every name recomputes to its NID with tools/nid_names.py. libSceAudio3d and libSceVoice are left out because #8331 declares them.
280 lines
10 KiB
C++
280 lines
10 KiB
C++
#include <cstdint>
|
|
#include <cstddef>
|
|
#include "SceTypes.hpp"
|
|
#include "prx/libc/include/General.hpp"
|
|
#include "prx/libc/include/RemoveTree.hpp"
|
|
#include "prx/libkernel/AppMetadata/include/AppMetadata.hpp"
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <filesystem>
|
|
#include <mutex>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
static constexpr int SCE_APP_CONTENT_ERROR_PARAMETER = static_cast<int>(0x80D90002);
|
|
static constexpr int SCE_APP_CONTENT_ERROR_BUSY = static_cast<int>(0x80D90003);
|
|
static constexpr int SCE_APP_CONTENT_ERROR_NOT_MOUNTED = static_cast<int>(0x80D90004);
|
|
static constexpr int SCE_APP_CONTENT_ERROR_NOT_FOUND = static_cast<int>(0x80D90005);
|
|
static constexpr int SCE_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = static_cast<int>(0x80D90007);
|
|
static constexpr uint32_t APPPARAM_ID_SKU_FLAG = 0;
|
|
static constexpr int32_t SKU_FLAG_FULL = 3;
|
|
|
|
static constexpr char TEMPORARY_MOUNT_POINT[] = "/temp0";
|
|
static constexpr char DOWNLOAD_MOUNT_POINT[] = "/download0";
|
|
static constexpr uint32_t TEMPORARY_DATA_OPTION_FORMAT = 1;
|
|
|
|
struct AppContentAddcontInfo {
|
|
NpUnifiedEntitlementLabel entitlement_label;
|
|
uint32_t status;
|
|
};
|
|
|
|
namespace {
|
|
|
|
struct TemporaryData {
|
|
std::mutex mutex;
|
|
const std::filesystem::path directory = ResolvePath_nid_no_patch(TEMPORARY_MOUNT_POINT);
|
|
bool mounted = false;
|
|
|
|
TemporaryData() { BlockPathAlias_nid_no_patch(TEMPORARY_MOUNT_POINT); }
|
|
};
|
|
|
|
TemporaryData& Temporary() {
|
|
static TemporaryData state;
|
|
return state;
|
|
}
|
|
|
|
bool IsTemporaryMountPoint(const AppContentMountPoint* mountPoint) {
|
|
return std::strncmp(mountPoint->data, TEMPORARY_MOUNT_POINT, sizeof(mountPoint->data)) == 0;
|
|
}
|
|
|
|
}
|
|
|
|
static void ClearDirectory(const std::filesystem::path& directory) {
|
|
for (const auto& entry : std::filesystem::directory_iterator(directory)) RemoveTree(entry.path());
|
|
RecordWrittenPath_nid_no_patch(directory);
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
int APS5_VABI sceAppContentAddcontMount(uint32_t service_label, const NpUnifiedEntitlementLabel* entitlement_label, AppContentMountPoint* mount_point) {
|
|
(void)service_label;
|
|
if (!entitlement_label || !mount_point) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
return SCE_APP_CONTENT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAddcontUnmount(const AppContentMountPoint* mount_point) {
|
|
if (!mount_point) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
return SCE_APP_CONTENT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetAddcontInfo(uint32_t service_label, const NpUnifiedEntitlementLabel* entitlement_label, AppContentAddcontInfo* info) {
|
|
(void)service_label;
|
|
if (!entitlement_label || !info) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
return SCE_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetAddcontInfoList(uint32_t service_label, AppContentAddcontInfo* list, uint32_t list_num, uint32_t* hit_num) {
|
|
(void)service_label;
|
|
if ((!list || list_num == 0) && !hit_num) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
if (hit_num) *hit_num = 0;
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAppParamGetInt(uint32_t param_id, int32_t* value) {
|
|
if (!value) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
switch (param_id) {
|
|
case APPPARAM_ID_SKU_FLAG:
|
|
*value = SKU_FLAG_FULL;
|
|
return 0;
|
|
case 1: case 2: case 3: case 4:
|
|
*value = GetAppUserDefinedParam_nid_postfix(param_id - 1);
|
|
return 0;
|
|
default:
|
|
return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
}
|
|
}
|
|
|
|
int APS5_VABI sceAppContentDownloadDataFormat(const AppContentMountPoint* mount_point) {
|
|
if (!mount_point) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
if (std::strncmp(mount_point->data, DOWNLOAD_MOUNT_POINT, sizeof(mount_point->data)) != 0) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
|
|
const auto directory = ResolvePath_nid_no_patch(DOWNLOAD_MOUNT_POINT);
|
|
if (std::filesystem::create_directories(directory)) RecordWrittenPath_nid_no_patch(directory);
|
|
ClearDirectory(directory);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentDownloadDataGetAvailableSpaceKb(const AppContentMountPoint* mount_point, size_t* available_space_kb) {
|
|
if (!mount_point || !available_space_kb) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
if (std::strncmp(mount_point->data, DOWNLOAD_MOUNT_POINT, sizeof(mount_point->data)) != 0) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
|
|
const std::uint64_t quotaKb = GetAppDownloadDataSizeMiB_nid_postfix() * 1024u;
|
|
if (quotaKb == 0) {
|
|
*available_space_kb = 0;
|
|
return 0;
|
|
}
|
|
const auto directory = ResolvePath_nid_no_patch(DOWNLOAD_MOUNT_POINT);
|
|
if (std::filesystem::create_directories(directory)) RecordWrittenPath_nid_no_patch(directory);
|
|
std::uint64_t usedKb = 0;
|
|
for (const auto& entry : std::filesystem::recursive_directory_iterator(directory)) {
|
|
if (entry.is_regular_file()) usedKb += (entry.file_size() + 1023u) / 1024u;
|
|
}
|
|
const std::uint64_t hostKb = std::filesystem::space(directory).available / 1024u;
|
|
*available_space_kb = static_cast<size_t>(std::min(quotaKb - std::min(quotaKb, usedKb), hostKb));
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentInitialize(const AppContentInitParam* init_param, AppContentBootParam* boot_param) {
|
|
(void)init_param;
|
|
if (!boot_param) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
Temporary();
|
|
std::memset(boot_param, 0, sizeof(*boot_param));
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentTemporaryDataFormat(const AppContentMountPoint* mountPoint) {
|
|
if (!mountPoint) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
auto& state = Temporary();
|
|
std::lock_guard lock(state.mutex);
|
|
if (!state.mounted || !IsTemporaryMountPoint(mountPoint)) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
|
|
ClearDirectory(state.directory);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentTemporaryDataGetAvailableSpaceKb(const AppContentMountPoint* mountPoint, size_t* availableSpaceKb) {
|
|
if (!mountPoint || !availableSpaceKb) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
auto& state = Temporary();
|
|
std::lock_guard lock(state.mutex);
|
|
if (!state.mounted || !IsTemporaryMountPoint(mountPoint)) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
|
|
*availableSpaceKb = static_cast<size_t>(std::filesystem::space(state.directory).available / 1024);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentTemporaryDataMount2(uint32_t option, AppContentMountPoint* mountPoint) {
|
|
if (!mountPoint || option > TEMPORARY_DATA_OPTION_FORMAT) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
auto& state = Temporary();
|
|
std::lock_guard lock(state.mutex);
|
|
if (state.mounted) return SCE_APP_CONTENT_ERROR_BUSY;
|
|
if (std::filesystem::create_directories(state.directory)) RecordWrittenPath_nid_no_patch(state.directory);
|
|
if (option == TEMPORARY_DATA_OPTION_FORMAT) ClearDirectory(state.directory);
|
|
AddPathAlias_nid_no_patch(TEMPORARY_MOUNT_POINT, state.directory.string().c_str());
|
|
state.mounted = true;
|
|
std::memset(mountPoint->data, 0, sizeof(mountPoint->data));
|
|
std::memcpy(mountPoint->data, TEMPORARY_MOUNT_POINT, sizeof(TEMPORARY_MOUNT_POINT));
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentTemporaryDataUnmount(const AppContentMountPoint* mountPoint) {
|
|
if (!mountPoint) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
auto& state = Temporary();
|
|
std::lock_guard lock(state.mutex);
|
|
if (!state.mounted || !IsTemporaryMountPoint(mountPoint)) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
|
|
BlockPathAlias_nid_no_patch(TEMPORARY_MOUNT_POINT);
|
|
state.mounted = false;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int APS5_VABI sceAppContentAddcontEnqueueDownload(uint32_t service_label, const NpUnifiedEntitlementLabel* entitlement_label) {
|
|
(void)service_label;
|
|
if (!entitlement_label) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
return SCE_APP_CONTENT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAddcontDelete(uint32_t service_label, const NpUnifiedEntitlementLabel* entitlement_label) {
|
|
(void)service_label;
|
|
if (!entitlement_label) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
return SCE_APP_CONTENT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetAddcontDownloadProgress(uint32_t service_label, const NpUnifiedEntitlementLabel* entitlement_label, void* progress) {
|
|
(void)service_label;
|
|
if (!entitlement_label || !progress) return SCE_APP_CONTENT_ERROR_PARAMETER;
|
|
return SCE_APP_CONTENT_ERROR_NOT_FOUND;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAddcontEnqueueDownloadByEntitlemetId(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAddcontEnqueueDownloadSp(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAddcontMountByEntitlemetId(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAddcontShrink(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentAppParamGetString(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentDownload0Expand(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentDownload0Shrink(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentDownload1Expand(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentDownload1Shrink(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetAddcontInfoByEntitlementId(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetAddcontInfoListByIroTag(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetDownloadedStoreCountry(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetEntitlementKey(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetPftFlag(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentGetRegion(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentRequestPatchInstall(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
int APS5_VABI sceAppContentTemporaryDataMount(void) {
|
|
NotImplemented_nid_no_patch(__func__);
|
|
return 0;
|
|
}
|
|
|
|
}
|