fix: a game folder whose deepest file passes 260 characters builds and plays (#1468) #1497

Merged
NotRexed merged 3 commits from fix/long-paths into main 2026-11-10 16:43:23 +00:00
NotRexed commented 2026-11-10 05:11:50 +00:00 (Migrated from github.com)

Fixes #1468: in a deeply nested folder, the unpack stopped with FileNotFoundError on a 262-character path in romfs\Event\EventSetting. Windows' 260-character limit (MAX_PATH) applies unless the program uses extended-length paths or the system's long-paths setting is on, and that setting is off by default.

Builder (Python): the unpack, the damaged-file scan and stand-ins, the romfs links into the game folder and the shader list step use extended-length paths (\?\...) on Windows. nup.long_path() and make_game.long_path() do nothing elsewhere. The scan still returns paths in the form it was given, so callers and tests see no change.

Game (host/nn_fs.c): path buffers go from 260 to 1024 bytes. Each file call (CreateFile, GetFileAttributes, Find*, CreateDirectory, Delete, Move, RemoveDirectory) goes through its wide function. The path is converted with the process code page (UTF-8 under the game's manifest), and a long absolute path gets the extended prefix. Short paths behave exactly as before.

Tested:

  • On this PC (long-paths setting off), the unpack wrote and re-read a 426-character path; the damaged-file scan walked it.
  • test_make_game_cache, test_nup_stand_in, test_nup_verify, test_finish_output and test_shader_census_cmd pass. The last now expects the long form on Windows.
  • nn_fs.c is clean with -Wall -Wextra.
  • Still to run: the game from a folder whose deepest romfs file passes 260 characters, after the next build.

🤖 Generated with Claude Code

Fixes #1468: in a deeply nested folder, the unpack stopped with `FileNotFoundError` on a 262-character path in `romfs\Event\EventSetting`. Windows' 260-character limit (MAX_PATH) applies unless the program uses extended-length paths or the system's long-paths setting is on, and that setting is off by default. **Builder (Python):** the unpack, the damaged-file scan and stand-ins, the romfs links into the game folder and the shader list step use extended-length paths (`\?\...`) on Windows. `nup.long_path()` and `make_game.long_path()` do nothing elsewhere. The scan still returns paths in the form it was given, so callers and tests see no change. **Game (`host/nn_fs.c`):** path buffers go from 260 to 1024 bytes. Each file call (CreateFile, GetFileAttributes, Find*, CreateDirectory, Delete, Move, RemoveDirectory) goes through its wide function. The path is converted with the process code page (UTF-8 under the game's manifest), and a long absolute path gets the extended prefix. Short paths behave exactly as before. **Tested:** - On this PC (long-paths setting off), the unpack wrote and re-read a 426-character path; the damaged-file scan walked it. - `test_make_game_cache`, `test_nup_stand_in`, `test_nup_verify`, `test_finish_output` and `test_shader_census_cmd` pass. The last now expects the long form on Windows. - `nn_fs.c` is clean with `-Wall -Wextra`. - Still to run: the game from a folder whose deepest romfs file passes 260 characters, after the next build. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 16:38:45 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good. The wide-API wrappers in nn_fs.c are a clean way to get long paths without touching every call site, the 1024-byte buffers leave room for the \?\ prefix, and the Python side returns paths in the form it was given so callers don't change. CI is green, including Windows.

Nits only:

  • Paths given the \?\ prefix skip Windows' normalization, so a .., . or doubled backslash in a host path longer than 240 chars would fail where a short one works. I didn't see host_path produce those, so just worth knowing.
  • The new tests/test_fs_path_utf8.py skips on Linux, so only the Windows CI job exercises the conversions (that's fine, just noting).

#1516 also fixes long paths (#1468), so one of the two should land and the other be closed or rebased.

Looks good. The wide-API wrappers in nn_fs.c are a clean way to get long paths without touching every call site, the 1024-byte buffers leave room for the \\?\ prefix, and the Python side returns paths in the form it was given so callers don't change. CI is green, including Windows. Nits only: - Paths given the \\?\ prefix skip Windows' normalization, so a `..`, `.` or doubled backslash in a host path longer than 240 chars would fail where a short one works. I didn't see host_path produce those, so just worth knowing. - The new tests/test_fs_path_utf8.py skips on Linux, so only the Windows CI job exercises the conversions (that's fine, just noting). #1516 also fixes long paths (#1468), so one of the two should land and the other be closed or rebased.
Commenting is not possible because the repository is archived.
No description provided.