feat(libSceAppContent): support download0-2 partitions in format and space query

This commit is contained in:
camezaro-intc committed 2026-10-28 23:41:29 -06:00
1 parent 52c09d567d
commit fe7cf1bee5
3 files changed
+24 -6

No files matched your search

+13 -4
View File
@@ -61,6 +61,14 @@ bool IsTemporaryMountPoint(const AppContentMountPoint* mountPoint) {
return std::strncmp(mountPoint->data, TEMPORARY_MOUNT_POINT, sizeof(mountPoint->data)) == 0;
}
bool IsDownloadMountPoint(const AppContentMountPoint* mountPoint) {
if (!mountPoint) return false;
for (const char* prefix : {"/download0", "/download1", "/download2"}) {
if (std::strncmp(mountPoint->data, prefix, sizeof(mountPoint->data)) == 0) return true;
}
return false;
}
}
static void ClearDirectory(const std::filesystem::path& directory) {
@@ -135,8 +143,8 @@ int APS5_VABI sceAppContentAppParamGetInt(uint32_t param_id, int32_t* value) {
int APS5_VABI sceAppContentDownloadDataFormat(const AppContentMountPoint* mount_point) {
if (!initialized.load()) return SCE_APP_CONTENT_ERROR_NOT_INITIALIZED;
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 (!IsDownloadMountPoint(mount_point)) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
const auto directory = ResolvePath_nid_no_patch(mount_point->data);
if (std::filesystem::create_directories(directory)) RecordWrittenPath_nid_no_patch(directory);
ClearDirectory(directory);
return 0;
@@ -145,13 +153,14 @@ int APS5_VABI sceAppContentDownloadDataFormat(const AppContentMountPoint* mount_
int APS5_VABI sceAppContentDownloadDataGetAvailableSpaceKb(const AppContentMountPoint* mountPoint, size_t* availableSpaceKb) {
if (!initialized.load()) return SCE_APP_CONTENT_ERROR_NOT_INITIALIZED;
if (!mountPoint || !availableSpaceKb) return SCE_APP_CONTENT_ERROR_PARAMETER;
if (std::strncmp(mountPoint->data, DOWNLOAD_MOUNT_POINT, sizeof(mountPoint->data)) != 0) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
if (!IsDownloadMountPoint(mountPoint)) return SCE_APP_CONTENT_ERROR_NOT_MOUNTED;
if (std::strncmp(mountPoint->data, DOWNLOAD_MOUNT_POINT, sizeof(mountPoint->data)) != 0) NotImplemented_nid_no_patch(__func__);
const std::uint64_t quotaKb = GetAppDownloadDataSizeMiB_nid_postfix() * 1024u;
if (quotaKb == 0) {
*availableSpaceKb = 0;
return 0;
}
const auto directory = ResolvePath_nid_no_patch(DOWNLOAD_MOUNT_POINT);
const auto directory = ResolvePath_nid_no_patch(mountPoint->data);
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)) {
+9
View File
@@ -104,6 +104,15 @@ int main() {
Require(std::filesystem::exists(downloadData / "index.dat"));
Require(sceAppContentDownloadDataFormat(&download) == 0);
Require(std::filesystem::is_directory(downloadData) && std::filesystem::is_empty(downloadData));
AppContentMountPoint download2Mount{};
std::memcpy(download2Mount.data, "/download2", 11);
const auto download2Data = ResolvePath_nid_no_patch("/download2");
std::filesystem::create_directories(download2Data);
{ std::ofstream file(downloadData / "preserve.bin"); file << "download0"; }
{ std::ofstream file(download2Data / "old.bin"); file << "download2"; }
Require(sceAppContentDownloadDataFormat(&download2Mount) == 0);
Require(std::filesystem::is_directory(download2Data) && std::filesystem::is_empty(download2Data));
Require(std::filesystem::exists(downloadData / "preserve.bin"));
const int32_t expectedParams[] = {3, 23566, -7, 0, 2147483647};
for (uint32_t id = 0; id < 5; ++id) {
+2 -2
View File
@@ -11,8 +11,8 @@
| `sceAppContentGetGameTrialsFlag` | `1saJukIkcKw` |
| `sceAppContentGetPlayableStatus` | `y8meQn-Qy5c` |
- [sceAppContentDownloadDataGetAvailableSpaceKb](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - a title whose `param.json` declares `downloadDataSize` 0 gets 0 KB and OK; the console's behaviour for a title without a download data area is unverified (it may return an error instead). KytyPS5 does not special-case it, and shadPS4 stubs 1048576 KB. One disassembled title (PPSA15246) calls it with the `/download0` mount point and a zeroed 64-bit output, ignores the return value and multiplies the output by 1024, so for that title an error that leaves the output untouched and an OK with 0 KB look the same
- [sceAppContentDownloadDataFormat](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - empties the `/download0` directory, creating it if needed. Imported by PPSA01317. A null mount point returns `PARAMETER` and another mount point returns `NOT_MOUNTED` as in `sceAppContentTemporaryDataFormat` and `sceAppContentDownloadDataGetAvailableSpaceKb`; the console's error codes for both and its behaviour with files still open are unverified
- [sceAppContentDownloadDataGetAvailableSpaceKb](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - a title whose `param.json` declares `downloadDataSize` 0 gets 0 KB and OK; the console's behaviour for a title without a download data area is unverified (it may return an error instead). KytyPS5 does not special-case it, and shadPS4 stubs 1048576 KB. One disassembled title (PPSA15246) calls it with the `/download0` mount point and a zeroed 64-bit output, ignores the return value and multiplies the output by 1024, so for that title an error that leaves the output untouched and an OK with 0 KB look the same. `/download1` and `/download2` queries remain unimplemented because their quota model is unverified.
- [sceAppContentDownloadDataFormat](../../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - empties the `/download0`, `/download1`, or `/download2` directory, creating it if needed. Imported by PPSA01317. A null mount point returns `PARAMETER` and another mount point returns `NOT_MOUNTED` as in `sceAppContentTemporaryDataFormat` and `sceAppContentDownloadDataGetAvailableSpaceKb`; the console's error codes for both and its behaviour with files still open are unverified
- [libSceAppContent pending exports](../../../core/libs/prx/libSceAppContent/Export.cpp) - 8 named callable exports are listed in the [PS5 3.20 export table](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceAppContent.c) and were cross-checked against the same module in PS5 firmware 13.60. Their signatures and behaviour are unverified; the declarations use the no-parameter unknown-signature convention and throw through `NotImplemented_nid_no_patch`.