Skip to content

feat(appcontent): install additional content from host directories - #1531

Closed
Noface07 wants to merge 1 commit into
boykopovar:mainfrom
Noface07:feat/appcontent-addcont
Closed

Noface07 wants to merge 1 commit into
boykopovar:mainfrom
Noface07:feat/appcontent-addcont

Conversation

@Noface07

@Noface07 Noface07 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

What

Additional content was never available: sceAppContentAddcontMount returned NOT_FOUND for every label, sceAppContentGetAddcontInfo DRM_NO_ENTITLEMENT, and the list was empty (TechnicalDebt, Functional).

  • A catalog in libkernel (AppMetadata/src/Addcont.cpp, AddcontEntries_nid_no_patch) lists the title's add-ons once:
    • add-ons without data: labels from anyps5-entitlements.ini (ANYPS5_ENTITLEMENTS), read as libSceNpEntitlementAccess read them before;
    • add-ons with data: the subdirectories of anyps5-addcont/ beside the executable (ANYPS5_ADDCONT), each named by its entitlement label or its content ID (UP0000-PPSA00000_00-LABEL). A label in both is one add-on with data.
    • Order: ini order, then directories sorted by label. An invalid directory name, two directories with one label, or a missing path named by an environment variable throws. Files in anyps5-addcont/ are ignored.
  • libSceAppContent:
    • GetAddcontInfo / GetAddcontInfoList report the catalog: status 4 (installed) for add-ons with data, 0 (no extra data) without. The list reports the count when called without a buffer, otherwise the entries written.
    • AddcontMount maps an add-on with data to /addcont0 … /addcont63 (lowest free slot) through AddPathAlias_nid_no_patch, as save data does for /savedata0. A second mount of the same add-on returns BUSY, a 65th mount MOUNT_FULL; an add-on without data or an unknown label NOT_FOUND.
    • AddcontUnmount blocks the point again with BlockPathAlias_nid_no_patch (as fix(appcontent): track temporary storage mounts #1320 does for /temp0); a point that is not mounted returns NOT_MOUNTED (was NOT_FOUND). /addcont0 … /addcont63 are blocked from sceAppContentInitialize (or the first mount call) until mounted, so a path under an unmounted point fails instead of reaching the run directory.
  • libSceNpEntitlementAccess reports the same catalog: ini entries as before (package type 3, download status 4), directories as package type 2 (PSAC). A label listed twice in the ini is now listed once.
  • USAGE.md documents both files; the TechnicalDebt entry keeps what is still missing (the mount is the writable host directory; downloads, deletion and progress). The assumptions are recorded under Unknown function info.

Sources: error codes and limits from the PS4 SDK values in ps4-eboot-dlc-patcher; the BUSY / MOUNT_FULL / NOT_MOUNTED cases and package types from the PS5 replacement modules in dlc_emu; /addcontN names, status 0 for license-only add-ons and the list count from shadPS4 (PS4). Where dlc_emu and shadPS4 disagree (hit_num with a short buffer), the choice is recorded in TechnicalDebt.

Tested

  • Windows 11 Home 10.0.26200, MinGW-w64 GCC 15.1.0 (x86_64-ucrt-posix-seh; not the 15.2.0 release from BUILD.md), Ninja Release, BUILD_TESTING=ON: full build and libs target, ctest 445/445 passed on main 33a9199; after the rebase onto 1081602 (no changes to these files), the 150 AppContent and guest tests pass.
  • New guest_appcontent_addcont: ini and directory entries (label and content ID names), list and info results, NpEntitlementAccess package types, mounting and reading a file through /addcont0, busy, not-found, unmount (an unmounted or free point is unavailable), slot reuse, the 64-mount limit and the error for an invalid directory name. guest_appcontent keeps the empty-catalog results.
  • Linux (WSL Ubuntu, GCC 15.2.0, no CMake): the changed sources and libc/src/General.cpp compiled with GuestAppContentAddcont.cpp directly into one executable; it passes. GuestAppContent.cpp crashes in that single-executable setup on main as well, so it was not checked there.
  • tools/check_conventions.py passed. No title with add-ons tested.

Rebased onto #1320, whose SCE_APP_CONTENT_ERROR_BUSY / NOT_MOUNTED constants this PR now uses. tools/pr_overlap.py reports only #1513, which rewrites docs/user/USAGE.md (L1-100); this PR adds a section to that file.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes (Claude Code)

Add-ons were never mounted: every label was not found or had no
entitlement. A catalog in libkernel now lists the add-ons without data
from anyps5-entitlements.ini and the add-ons with data from the
directories in anyps5-addcont/ (ANYPS5_ADDCONT), named by entitlement
label or content ID. AppContent reports them in its info calls and
mounts an add-on with data at /addcont0 to /addcont63 through a path
alias; NpEntitlementAccess reports the same add-ons.
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#1805 docs/dev/TechnicalDebt.md L244-245

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Which title needs its add-on content? Please add the title ID and what goes wrong on main without this (the log line, or what the title is missing). With that this can go in; otherwise I'll close it until a title needs it.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 9, 2026
@Noface07

Noface07 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Which title needs its add-on content? Please add the title ID and what goes wrong on main without this (the log line, or what the title is missing). With that this can go in; otherwise I'll close it until a title needs it.

No title yet. I wrote this from the TechnicalDebt entry and tested it only with the unit tests, not with a game. I don't have a dump with add on content to check it against.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Closing, since no title needs it yet. Please reopen when a title with add-on content shows what goes wrong on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build docs libkernel needs rebase Conflicts with main, rebase needed prx

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants