Commit Graph
40 Commits
Author SHA1 Message Date
Yunus Shaikh 842f75d7e0 Merge main into feat/savedata-backup-progress-sourced
JJenkx's #13324 gives isMountedDirectory an std::error_code parameter.
The merge passes one in checkBackupData and restoreBackupData and
returns SAVE_DATA_ERROR_INTERNAL on a host error, as main's callers do.

GuestSaveDataMountStatus.cpp: CheckBackups writes param.json where
ResolvePath_nid_no_patch puts /app0/sce_sys/param.json, not under the
working directory. #13324's CheckHostMountFailures now resolves the
first guest path from its mount-host-failures subdirectory, so /app0
maps there, and checkBackupData didn't find the title's param.json.
2026-10-30 23:09:34 +00:00
JJenkx 8086a37957 test(savedata): avoid unrelated mount fixture conflicts 2026-10-30 08:41:15 -04:00
JJenkx 0c110bdf8e fix(savedata): keep failed host mounts unpublished 2026-10-30 08:12:24 -04:00
Yunus Shaikh 46c8ff27a6 Merge main into feat/savedata-backup-progress-sourced
# Conflicts:
#	core/libs/tests/GuestSaveDataMountStatus.cpp
#	docs/dev/debt/libSceSaveData.native.md
2026-10-29 22:05:12 -07:00
Adrià 0d62a3e0db Merge pull request #12699 from SnekPolylepis/feat/savedata-mounted-count-and-lifecycle
feat(libSceSaveData): add provisional abort and clear progress stubs
2026-10-30 05:51:21 +01:00
Yunus Shaikh 22291cddd8 Merge main into feat/savedata-backup-progress-sourced
# Conflicts:
#	core/libs/tests/GuestSaveDataMountStatus.cpp
#	docs/dev/debt/libSceSaveData.native.md
2026-10-29 18:59:33 -07:00
Adrià f67988f8e8 Merge pull request #12644 from slopgobblercobbler/fix/savedata-backup-dir-name-validation
fix(libSceSaveData.native): validate directory name in sceSaveDataBackup
2026-10-30 02:52:13 +01:00
SnekPolylepis 8436d54350 fix(savedata): leave mounted count unimplemented 2026-10-29 09:52:50 -05:00
slopgobblercobbler 43dc8a75c7 fix(libSceSaveData.native): validate directory name in sceSaveDataBackup 2026-10-29 11:34:09 +01:00
Yunus Shaikh eff8683d05 test(libSceSaveData): cover the backup calls' guest errors and rotation
Checks behaviour 5fed277cf2 already has: a second
sceSaveDataUmountWithBackup replaces the first backup; a backup copy
that fails still unmounts and returns 0, with SAVE_DATA_ERROR_INTERNAL
in its event and the previous backup kept; another title's titleId is
SAVE_DATA_ERROR_NOT_FOUND for the check and the restore; ".." and "a/b"
are SAVE_DATA_ERROR_PARAMETER for the check, the restore and the mount a
backup needs, and as mount points sceSaveDataUmountWithBackup reports
them SAVE_DATA_ERROR_NOT_MOUNTED, as it does for any unknown mount
point. The sizes and field offsets of SaveDataCheckBackupData and
SaveDataRestoreBackupData are checked with static_assert.
2026-10-29 10:17:06 +00:00
Yunus Shaikh 9429d8395b fix(libSceSaveData): keep save and backup paths inside their roots
Before any copy or delete, the backup and the restore check the roots
they use (_sd, _sd_backup and their staging and old directories) and
every entry under them for the save: each must be a plain directory or
file, not a symbolic link, or on Windows a reparse point such as a
junction, and must stay under its root after weakly_canonical. Anything
else makes the restore return SAVE_DATA_ERROR_INTERNAL, and the backup
report it in its event, with nothing changed. sceSaveDataCheckBackupData
checks the backup the same way. The copies walk the tree themselves and
refuse a link instead of following it.
2026-10-29 10:13:16 +00:00
Yunus Shaikh 1744dbf5ab fix(libSceSaveData): put the old backup back when the backup swap fails, and flush before removing it
backupSave moved the previous backup to _sd_backup_old and then renamed
the new copy into place; when that rename failed, the save had no
backup until the next one. A failed rename now moves the previous
backup back into _sd_backup and removes the staged copy. Every staged
file is flushed before the swap (FlushFileBuffers on Windows, fsync on
POSIX, as libc does), and on POSIX the directories on both sides of
each rename are flushed too, all before the previous backup is removed.
2026-10-29 10:09:29 +00:00
Yunus Shaikh 637b601bfb fix(libSceSaveData): restore a backup through a staged copy and roll back a failed swap
sceSaveDataRestoreBackupData used to remove the live save's files and
copy the backup over them, so a copy that failed half way left neither.
It now copies the backup, its .param and its blocks file to
_sd_restore_tmp/<dir>, checks that the copy has every entry at its size,
and flushes it. Then it moves the live save, .param and blocks file to
_sd_restore_old/<dir>, moves the staged copy into place and removes the
old one. A failed move puts back everything already moved, so the live
save stays as it was. The staging roots sit next to _sd, not in it,
where sceSaveDataDirNameSearch would list them.

SaveDataSetFileStepHook_nid_no_patch sets a function that is called
before each copy and rename of the backup and restore paths with a step
name and the path written; when it returns false that step fails. It
does nothing unless a test sets it.
2026-10-29 10:08:24 +00:00
Yunus Shaikh 26a50dd0fd fix(libSceSaveData): validate backup metadata before Check and Restore read it
sceSaveDataCheckBackupData and sceSaveDataRestoreBackupData now read a
backup through one check that runs before anything in the live save
changes. A backup directory without a save inside, a missing .param, a
.param that is not exactly one SaveDataParam, or a blocks entry that is
not a file returns SAVE_DATA_ERROR_INTERNAL, whether or not the caller
asked for param. Before, the check threw on a wrong-sized .param, and
the restore removed the live save's files before finding the .param
missing.
2026-10-29 10:06:11 +00:00
Zain 0dabb5f793 test(savedata): cover mount count capacity and failures 2026-10-28 22:26:58 -05:00
Zain 7016a894f7 feat(libSceSaveData): implement sceSaveDataGetMountedSaveDataCount, sceSaveDataAbort, and sceSaveDataClearProgress 2026-10-28 21:39:18 -05:00
Yunus Shaikh 5fed277cf2 feat(libSceSaveData): implement sceSaveDataCheckBackupData, sceSaveDataRestoreBackupData and sceSaveDataUmountWithBackup 2026-10-28 21:18:18 +00:00
al3w0f205 21771c59d6 test(libSceSaveData.native): cover unmounted mount point in icon operations 2026-10-27 23:38:08 -05:00
PrivacyOnion 91eabe97cb test(libSceSaveData.native): cover empty queue and null result in sceSaveDataGetEventResult 2026-10-26 12:15:16 +01:00
Dean f822d74d42 Merge pull request #10281 from al3w0f205/test/savedata-sync-memory-null-parameter
test(libSceSaveData.native): cover null parameter validation in sceSaveDataSyncSaveDataMemory
2026-10-26 16:22:35 +13:00
slopggobblercobbler81 9c232b38fe fix(savedata): validate null arguments in delete, search, and mount3 2026-10-25 20:07:59 +01:00
Adrià 160f6592b5 Merge pull request #9409 from cadenasynyster/test/windows-savedata-link-alias
test(libSceSaveData): create the mount identity link with CreateSymbolicLinkW on Windows
2026-10-25 16:50:05 +01:00
Dean Galvin 5d86ed499d Merge main into pr/10281
Take main's header declarations over the local extern block; use the implementation's error value in the test.
2026-10-25 21:06:47 +13:00
boykopovar f38d29fd08 refactor(sdk): add canonical headers for remaining libraries 2026-10-24 23:17:42 +03:00
al3w0f205 07198e1e6a test(libSceSaveData.native): cover null parameter validation in sceSaveDataSyncSaveDataMemory 2026-10-23 11:31:30 -05:00
Dean 7c9d3a005e Merge pull request #8990 from voidlakhan/fix/savedata-null-argument-parameter-error
fix(savedata): validate backup and event result arguments
2026-10-24 01:29:00 +13:00
cadenasynysterandClaude Opus 5.5 587cd64331 test(libSceSaveData): create the mount identity link with CreateSymbolicLinkW on Windows
MinGW's std::filesystem::create_directory_symlink always fails on Windows, so CheckEquivalentMounts never ran its symbolic link alias there and only checked the case alias. It now creates and removes the link with CreateSymbolicLinkW and RemoveDirectoryW, as SaveDataFileWriteFailure.cpp does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01GtXavMkgCTCdmRpweviHcQ
2026-10-22 21:05:57 +02:00
lakhantheboss 2b1eb36139 fix(savedata): validate backup and event result arguments 2026-10-21 14:06:38 +05:30
lakhantheboss d3542d5eed fix(savedata): return parameter errors for null arguments 2026-10-21 13:23:15 +05:30
al3w0f205 27badc2c3a test(libSceSaveData.native): cover sceSaveDataSaveIconByPath execution 2026-10-20 19:09:56 -05:00
pushkarreddyy 3bb39053ae fix(savedata): return parameter error on null arguments in umount2, loadIcon and saveIcon 2026-10-20 12:54:28 +02:00
Adrià 4f99cbffd7 Merge pull request #7536 from voidlakhan/fix/savedata-setparam-null-arguments
fix(savedata): return parameter error on null arguments in setParam
2026-10-20 12:18:56 +02:00
Adrià fb106a7e9a Merge pull request #6724 from Ondra97/codex/fix-savedata-mount-identity
fix(savedata): prevent duplicate mounts of one backing directory
2026-10-19 12:09:57 +02:00
lakhantheboss a605f94732 fix(savedata): return parameter error on null arguments in setParam 2026-10-18 18:06:26 +05:30
lakhantheboss 0936fe9b53 fix(savedata): return parameter error on null arguments in getMountInfo and getParam 2026-10-17 19:07:36 +05:30
Ondra97 37e62ddb3b fix(savedata): skip identity comparisons for missing paths 2026-10-16 14:16:07 +02:00
Ondra97 fcf65455f5 fix(savedata): prevent duplicate mounts of one backing directory 2026-10-16 08:53:05 +02:00
SandstromPLandClaude Opus 5.5 c73e9720ae fix(savedata): return a parameter error from sceSaveDataMount3 for an invalid directory name
An unterminated or empty directory name, "." or "..", or a name
containing "/", "\" or ":" now returns SAVE_DATA_ERROR_PARAMETER and
leaves the mount result unchanged. The SDK 12.000 reference lists that
code for an invalid parameter of sceSaveDataMount3, KytyPS5's
SaveDataMount3 returns it for an invalid name, and sceSaveDataDelete
and sceSaveDataConvert already return it here for the same check.
It threw before, which stopped Minecraft Preview (PPSA19639) on
entering a world.

The Mount3 trace now prints at most the 32 bytes of the directory name
and the 16 bytes of the mount point, since both can be unterminated
when the mount fails.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 12:19:09 +05:30
Yunus Shaikh 4ccf888291 fix(savedata): leave the mount result untouched when sceSaveDataMount3 fails
Animal Well (PPSA22520) checks for its save with a CREATE2 mount it never
unmounts, then saves with a second mount of the same directory. That
mount returns BUSY, and the title keeps using the first mount point for
sceSaveDataPrepare, its save file and sceSaveDataUmount2.
sceSaveDataMount3 cleared the result before its checks, so the save was
written to "/save" in the game folder instead of the save directory, and
the first mount was never released. The result is now written only when
the mount succeeds, as shadPS4 does.
2026-10-12 17:47:46 -07:00
TideOPL c9685e47e4 fix(savedata): report a CREATE2 mount of an existing save as not created
sceSaveDataMount3 with SCE_SAVE_DATA_MOUNT_MODE_CREATE2 opens a save that
already exists, so its mount status is 0 rather than CREATED, as shadPS4's
savedata.cpp reports. A CREATE mount still reports CREATED.
2026-10-08 19:46:23 +01:00