Skip to content

Fix install destination detection for CXI-based game files - #953

Merged
d0k3 merged 3 commits into
d0k3:masterfrom
ZeroSkill1:install-dest-fix
May 24, 2026
Merged

Fix install destination detection for CXI-based game files#953
d0k3 merged 3 commits into
d0k3:masterfrom
ZeroSkill1:install-dest-fix

Conversation

@ZeroSkill1

@ZeroSkill1 ZeroSkill1 commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Should fix #952. GodMode9 currently does not properly detect the install destination drive for certain (CXI-based) titles. For instance, it is possible for a NAND title to have an SD-looking title ID, e.g. 000400000ff40002 (DevMenu).

Under HOS, this does not matter because the destination is determined by the "is SD app" flag in the ExHeader.

I have reworked the game file installation & title uninstallation process to honor this bit (when applicable). That is:

  • TWL titles will always be installed to (Sys/Emu)NAND TWLNAND.
  • NCCHs that are CFAs will keep using the original detect-by-titleID method as there is no real way to detect their destination otherwise.
  • NCCHs that are CXIs, or containers that have CXIs as their first content (.cxi/.ncch/.app/.cia/cdn contents + tmd) will be installed to the destination indicated by the "is SD app" flag.
  • DLC titles and gamecart (image)s will always be installed to (Emu/Sys)NAND SD.
  • During title uninstallation, the current mount path and the title ID will be used to determine the uninstallation source path.

I have tested this to be working with all major types of content.

Comment thread arm9/source/utils/gameutil.c
@d0k3

d0k3 commented Mar 28, 2026

Copy link
Copy Markdown
Owner

@ZeroSkill1 - this pull request won't make the anniversary release, I'll just need some more time to properly understand and review the changes. Will get bakc about that, and thank you!

@d0k3
d0k3 requested a review from Wolfvak May 9, 2026 11:54

@d0k3 d0k3 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I finally got around to do a proper review. @ZeroSkill1 - thank you for that, it's highly appreciated. Bear with us for a bit, it seems we're a bit slower in reviewing than you are in doing pull requests.

Comment thread arm9/source/utils/gameutil.c
Comment thread arm9/source/utils/gameutil.c
Comment thread arm9/source/utils/gameutil.c Outdated
Comment thread arm9/source/utils/gameutil.c Outdated
if (is_twl)
drv[0] = from_emunand ? '5' : '2';
else
drv[0] = GetMountPath()[0];

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if I understand what this is supposed to do. The whole fucntion is meant only for tie, so what cases is that block meant for?

@ZeroSkill1 ZeroSkill1 May 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought too, but it turns out this function is the main one used for uninstalling anything, really. As for the drive selection, I've used this "shortcut" of sorts by looking at all possible uninstall locations:

. SysNAND CTRNAND SysNAND TWLNAND SysNAND SD EmuNAND CTRNAND EmuNAND TWLNAND EmuNAND SD
Title path T:/... T:/00048... T:/... T:/... T:/00048... T:/...
Mount path 1:/dbs/title.db 1:/dbs/title.db A:/dbs/title.db 4:/dbs/title.db 4:/dbs/title.db B:/dbs/title.db
Uninstall drive 1:/ 2:/ A:/ 4:/ 5:/ B:/

For all uninstall locations other than for TWL titles, the mountpath of the mounted .db file is the same as the uninstall drive, and for TWL titles, the uninstall drive is the equivalent TWLNAND drive depending on SysNAND/EmuNAND.

I can add a comment explaining this briefly.

@d0k3 d0k3 May 21, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that explains it, I've got one last round of nitpicking, though. I'm currently wondering if it is ever possible for GetMountPath()[0] to be zero here, and to be blunt, I don't know. NULL for GetMountPath() should be impossible here, but maybe it makes sense to guard an empty string here (because that's a plausible return value here). Other than that, this one is good to be merged 👍

@ZeroSkill1 ZeroSkill1 May 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That NULL check is already performed earlier in the function. I guess I could just use the existing mntpath instead of using GetMountPath() again, and use a simple empty string check in the earlier check.

Comment thread arm9/source/utils/gameutil.c
@d0k3
d0k3 merged commit 4058c9c into d0k3:master May 24, 2026
1 check passed
@d0k3

d0k3 commented May 24, 2026

Copy link
Copy Markdown
Owner

All good, thank you @ZeroSkill1 !

@ZeroSkill1
ZeroSkill1 deleted the install-dest-fix branch July 14, 2026 06:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] incorrect nand/sd app detection

2 participants