Skip to content

fix(libkernel): stat files under long Windows paths - #7196

Merged
oneandonlydean merged 4 commits into
boykopovar:mainfrom
MarcZX10:codex/stat-long-path-7195
Oct 17, 2026
Merged

oneandonlydean merged 4 commits into
boykopovar:mainfrom
MarcZX10:codex/stat-long-path-7195

Conversation

@MarcZX10

@MarcZX10 MarcZX10 commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

What

Prepare long Windows paths for sceKernelStat metadata lookups using the extended path namespace, and use that same path for the subsequent native stat call. Add a Windows regression test that stats an existing file under a path longer than MAX_PATH through a short guest alias, confirms a missing long path still returns ENOENT, and confirms a trailing-slash directory stat remains a directory.

Tested

  • python3 tools/check_conventions.py --base f51724078f975a60c8f9985e547b6259acdcab64 passed locally.
  • git diff --check passed locally.
  • Windows 11 Enterprise 26200 / WinLibs GCC 15.2.0 r7: an independent run on prior head 3d18c946f7270678256683ec8a5fbf1989c55803 passed the full relinker/system-library build and 30 focused CTest runs, including the ordinary long-path stat fixture. A follow-up now preserves already-extended \\?\ aliases and adds a regression for them; that follow-up has passed MinGW syntax checks, but its Windows runtime rerun is pending.

Checklist

@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 core/libs/prx/libkernel/File/src/Open.cpp
PR 6044 core/libs/tests/GuestFilesystem.cpp
PR 6228 core/libs/prx/libkernel/File/src/Open.cpp
PR 6942 core/libs/prx/libkernel/File/src/Open.cpp
PR 7121 core/libs/prx/libkernel/File/src/Open.cpp
PR 7201 core/libs/prx/libkernel/File/src/Open.cpp

@MarcZX10

Copy link
Copy Markdown
Contributor Author

I manually reviewed the three files the overlap check could not compare. #6484 adds rename-semantics tests in GuestFilesystem.cpp; #6044 reorganizes the filesystem test target/file; neither changes or tests long-path stat behavior. #5021’s Open.cpp change is an Apple-specific O_CREAT directory check, unrelated to Windows extended paths or sceKernelStat. I found no duplicate implementation in those PRs. The Windows runtime check for this PR remains pending because the hosted application lane was skipped and I cannot dispatch that workflow without repository admin rights.

@Amoenus

Amoenus commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

@MarcZX100 retested the published follow-up 28eaa5bdad25ec393110696ec94782bdcf8ea722, based on main66702f1c. The existing-namespace regression is corrected.

  • Full relinker/system-library builds pass on Windows11 Enterprise26200 / WinLibs GCC15.2r7 and Ubuntu24.04 / GCC13.3, Release. Each OS has10 focused groups ×3 = 30 passes, including your updated existing/missing extended-alias cases and archive/plain/mmap controls. No skips or timeouts.
  • The same independent fixture that failed6/6 on the prior head now passes6/6:3 normal and3 cwd-Z:/temp-C: runs. It checks file/directory metadata, identity, POSIX stat, missing-file errors, trailing slash, null output and a relative alias; the drive substitution is removed.
  • The actual Windows sceKernelStat returns ENOENT for an existing file under a long host path (PPSA99902) #7195 game file now succeeds through both ordinary253-character and extended257-character host roots: full filename266/270 characters, result0 and size288 both times. The file hash is unchanged.

No menu/gameplay or whole-title result is implied by these metadata controls. Thank you for the quick correction; our #7187 now has the corresponding prefix preservation and regression too.

Current composed title follow-up: integrationc784, main667 plus retained fixes/#7187cf84/#7196 head28ea, reaches the older GPU stops from long physical roots: NVIDIA28.656s resident8x DCC refusal; AMD70.750s Vulkan device loss-4. Last captures remain NOW LOADING, no timeout/input or protected-file changes. #3036 carries full scope; the independent metadata controls above establish the fix separately.

One source-review error-path point: FilesystemError(error) already returns guest errno, while SceErrorFromErrno maps values above34 to EIO. SceKernelError(FilesystemError(error)) would preserve that mapping (for example guest ENAMETOOLONG63) in the new absolute-resolution failure branch, as the resolver branch just above does. I have not induced that absolute-resolution failure in these runtime tests; this is a source-review edge, separate from the verified success paths.

Earlier validation and failing control at3d18c946

@MarcZX100 Windows validation at exact head 3d18c946f7270678256683ec8a5fbf1989c55803: full relinker/system-library build passes, and 10 relevant CTest groups ×3 = 30 passes, including your guest_filesystem long-path case, timestamps, POSIX I/O and archive/plain/mmap controls. Ubuntu24.04/GCC13.3: the same build and 30 focused passes. Windows11 Enterprise26200, WinLibs GCC15.2.0 r7, Release.

The ordinary-path correction also works on the actual #7195 file: ordinary root253/full266 characters now returns success and size288. However, the already-extended alias regresses: extended root257/full270 returns 0x80020002, size0, whereas it succeeds on main. The same real file is used and its hash is unchanged.

An independent fixture confirms that extended-path failure in 3 same-drive and 3 split-drive runs. A small native control confirms the cause on this toolchain:

input prefix=\?\C:\Users\...  characters=270
std::filesystem::absolute prefix=C:\?\C:\Users\...  characters=271
helper result prefix=\?\C:\?\C:\Users\...  exists=0/error2

Could NativeMetadataPath preserve an existing \?\ or \.\ namespace before calling absolute, and add that alias as a control? The check after absolute is too late here. I found the same operation in our #7187 and am adding the early check there too. This is an additional input case, not a request to duplicate or replace your fix. No menu/gameplay or whole-main title result is implied by the metadata control.

@MarcZX10
MarcZX10 force-pushed the codex/stat-long-path-7195 branch from 3d18c94 to 28eaa5b Compare October 17, 2026 16:16
@MarcZX10

Copy link
Copy Markdown
Contributor Author

Good catch. std::filesystem::absolute was rewriting an already-extended \\?\ spelling before the later prefix check. I pushed a follow-up on this PR that preserves \\?\ and \\.\ inputs before calling absolute, and added an already-extended-alias regression for both existing and missing files. The branch is rebased onto current main (66702f1).

check_conventions.py, git diff --check, and MinGW syntax checks for Open.cpp and GuestFilesystem.cpp pass. Your Windows run covered the prior head; this added Windows regression still needs a runtime rerun. Thanks for providing the independent reproduction and the concrete diagnosis.

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

Labels

fix error Closes an issue (Fixes #N) libkernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows sceKernelStat returns ENOENT for an existing file under a long host path (PPSA99902)

3 participants