Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TAD support #1

Merged
merged 9 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build NAND Title Manager
name: Build TAD Delivery Tool

on:
push:
Expand All @@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v1
- name: Setup environment
run: git config --global safe.directory '*'
- name: Build NAND Title Manager
- name: Build TAD Delivery Tool
run: make
- name: Publish build to GH Actions
uses: actions/upload-artifact@v2
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.o
*.d
*.nds
*.tad
*.dsi
*.elf
*.map
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export TOPDIR := $(CURDIR)
NITRO_FILES :=

# These set the information text in the nds file
GAME_TITLE := NAND Title Manager
GAME_SUBTITLE1 := JeffRuLz, Pk11
GAME_TITLE := TAD Delivery Tool
GAME_SUBTITLE1 := JeffRuLz, Pk11, rmc

GAME_CODE := HTMA
GAME_LABEL := NANDTM
GAME_CODE := 4TDA
GAME_LABEL := TAD_DELIVERY

include $(DEVKITARM)/ds_rules

Expand Down Expand Up @@ -49,7 +49,7 @@ checkarm9:
#---------------------------------------------------------------------------------
$(TARGET).dsi : $(NITRO_FILES) arm7/$(TARGET).elf arm9/$(TARGET).elf
ndstool -c $(TARGET).dsi -7 arm7/$(TARGET).elf -9 arm9/$(TARGET).elf \
-u "00030004" \
-u "00030015" \
-g "$(GAME_CODE)" "00" "$(GAME_LABEL)" \
-b $(GAME_ICON) "$(GAME_TITLE);$(GAME_SUBTITLE1)" \
$(_ADDFILES)
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# NAND Title Manager
A basic title manager for the Nintendo DSi supporting both hiyaCFW's SDNAND and SysNAND, modified from JeffRuLz's Title Manager for HiyaCFW.
This fork has been modified to allow installing TADs, the DSi's version of a WAD. These are typically signed and encrypted for development units. This makes them impossible to install on a retail unit. My NTM fork should let dev TADs install on retail, retail TADs install on dev, etc.

## WARNING
This can modify your internal system NAND! There is *always* a risk of **bricking**, albeit small, when you modify NAND. Please proceed with caution. Having Unlaunch installed is also strongly recommended as it will likely protect you if something manages to go wrong.
Expand Down Expand Up @@ -30,4 +31,4 @@ This can modify your internal system NAND! There is *always* a risk of **brickin
- [Martin Korth (nocash)](https://problemkaputt.de): [GBATEK](https://problemkaputt.de/gbatek.htm)
- [JeffRuLz](https://github.com/JeffRuLz): [TMFH](https://github.com/JeffRuLz/TMFH) (what this is a fork of)
- [DesperateProgrammer](https://github.com/DesperateProgrammer): [DSi Language Patcher](https://github.com/DesperateProgrammer/DSiLanguagePacher) (working NAND writing code)
- [rvtr](https://github.com/rvtr): Adding support for installing dev titles
- [rvtr](https://github.com/rvtr): Adding support for installing TADs and dev titles
7 changes: 1 addition & 6 deletions arm9/src/backupmenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,7 @@ static void generateList(Menu* m)
}
else
{
if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0)
if (strcasecmp(strrchr(ent->d_name, '.'), ".tad") == 0)
{
if (count < m->page * ITEMS_PER_PAGE)
count += 1;
Expand Down
82 changes: 44 additions & 38 deletions arm9/src/install.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "nand/ticket0.h"
#include "rom.h"
#include "storage.h"
#include "tad.h"
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -351,7 +352,7 @@ static void _createTicket(tDSiHeader *h, char* ticketPath)
}
}

bool install(char* fpath, bool systemTitle)
bool install(char* tadPath, bool systemTitle)
{
bool result = false;

Expand All @@ -364,6 +365,7 @@ bool install(char* fpath, bool systemTitle)

//start installation
clearScreen(&bottomScreen);
char* fpath = openTad(tadPath);

tDSiHeader* h = getRomHeader(fpath);

Expand All @@ -372,7 +374,7 @@ bool install(char* fpath, bool systemTitle)
iprintf("\x1B[31m"); //red
iprintf("Error: ");
iprintf("\x1B[33m"); //yellow
iprintf("Could not open file.\n");
iprintf("Could not decrypt TAD.\n");
iprintf("\x1B[47m"); //white
goto error;
}
Expand All @@ -385,35 +387,25 @@ bool install(char* fpath, bool systemTitle)

//title id must be one of these
if (h->tid_high == 0x00030004 || // DSiWare
h->tid_high == 0x00030005 || // "unimportant" system titles
h->tid_high == 0x00030011 || // SRLs in the TWL SDK
h->tid_high == 0x00030015 || // system titles
h->tid_high == 0x00030005 || // "Unimportant" system titles
h->tid_high == 0x0003000f || // Data titles
h->tid_high == 0x00030015 || // System titles
h->tid_high == 0x00030017) // Launcher
{}
else
{
iprintf("\x1B[31m"); //red
iprintf("Error: ");
iprintf("TID Error: ");
iprintf("\x1B[33m"); //yellow
iprintf("This is not a DSi rom.\n");
iprintf("Could not decrypt TAD.\n%s", fpath);
iprintf("\x1B[47m"); //white
goto error;
}

//patch dev titles to system titles on SysNAND.
//
//software released through the TWL SDK usually comes as a TAD and an SRL
//things like NandFiler have a TAD with a TID of 0x00030015 and an SRL with 0x00030011
//the TAD is the installable version, so I'm assuming that 0x00030015 is what the console wants to see on NAND
//this changes the SRL TID accordingly
//not entirely sure why there's even any difference. I think the installed TAD and SRL the same as each other (minus the TID)
if(!sdnandMode && h->tid_high == 0x00030011)
{
h->tid_high = 0x00030015;
fixHeader = true;
}
// I am going to remove patching because it results in bad TMDs that the launcher auto deletes.
// Comment these back in if you really want, but know that 99% of dev apps will not install right with patching.

//offer to patch system titles to normal DSiWare on SysNAND
/*
if(!sdnandMode && h->tid_high != 0x00030004 && h->tid_high != 0x00030017) //do not allow patching home menus to be normal DSiWare! This will trigger "ERROR! - 0x0000000000000008 HWINFO_SECURE" on prototype launchers. May also cause issues on the prod versions.
{
if(choiceBox("This is set as a system/dev\ntitle, would you like to patch\nit to be a normal DSiWare?\n\nThis is safer, but invalidates\nRSA checks and may not work.\n\nIf the title is homebrew this isstrongly recommended.") == YES)
Expand All @@ -422,8 +414,10 @@ bool install(char* fpath, bool systemTitle)
fixHeader = true;
}
}
*/

//offer to patch home menus to be system titles on SysNAND
/*
if(!sdnandMode && h->tid_high == 0x00030017)
{
if(choiceBox("This title is a home menu.\nWould you like to patch it to bea system title?\n\nThis is safer and prevents your\nhome menu from being hidden.") == YES)
Expand All @@ -432,6 +426,7 @@ bool install(char* fpath, bool systemTitle)
fixHeader = true;
}
}
*/

//no system titles without Unlaunch
if (!unlaunchFound && h->tid_high != 0x00030004)
Expand All @@ -450,28 +445,17 @@ bool install(char* fpath, bool systemTitle)
u32 tidLow = (h->tid_low & 0xFFFFFF00);
if (!sdnandMode && (
(h->tid_high == 0x00030005 && (
tidLow == 0x484e4400 || // DS Download Play
tidLow == 0x484e4500 || // PictoChat
tidLow == 0x484e4900 || // Nintendo DSi Camera
tidLow == 0x484e4a00 || // Nintendo Zone
tidLow == 0x484e4b00 // Nintendo DSi Sound
)) || (h->tid_high == 0x00030011 && (
tidLow == 0x30535500 || // Twl SystemUpdater
tidLow == 0x34544e00 || // TwlNmenu
tidLow == 0x54574c00 // TWL EVA
)) || (h->tid_high == 0x00030015 && (
tidLow == 0x484e4200 || // System Settings
tidLow == 0x484e4600 || // Nintendo DSi Shop
tidLow == 0x34544e00 // TwlNmenu
tidLow == 0x484e4600 // Nintendo DSi Shop
)) || (h->tid_high == 0x00030017 && (
tidLow == 0x484e4100 // Launcher
))) && (
(h->tid_low & 0xFF) == region || // Only blacklist console region, or the following programs that have all-region codes:
h->tid_low == 0x484e4541 || // PictoChat
h->tid_low == 0x484e4441 || // Download Play
h->tid_low == 0x30535541 || // Twl SystemUpdater (iirc one version fits in NAND)
h->tid_low == 0x34544e41 || // TwlNmenu (blocking due to potential to uninstall system titles)
h->tid_low == 0x54574c41 || // TWL EVA
region == 0 //if the region check failed somehow, blacklist everything
))
{
Expand All @@ -495,6 +479,9 @@ bool install(char* fpath, bool systemTitle)
{
const char system[] = "\x1B[41mWARNING:\x1B[47m This is a system app,\ninstalling it is potentially\nmore risky than regular DSiWare.\n\x1B[33m";
const char areYouSure[] = "Are you sure you want to install\n";
clearScreen(&topScreen); // Top screen breaks after this for some reason.
printTadInfo(tadPath);
clearScreen(&bottomScreen);
char* msg = (char*)malloc(strlen(system) + strlen(areYouSure) + strlen(fpath) + 2);
if (sdnandMode || h->tid_high == 0x00030004)
sprintf(msg, "%s%s?\n", areYouSure, fpath);
Expand Down Expand Up @@ -556,6 +543,7 @@ bool install(char* fpath, bool systemTitle)
goto error;

//system title patch
/*
if (systemTitle)
{
iprintf("System Title Patch...");
Expand All @@ -567,8 +555,10 @@ bool install(char* fpath, bool systemTitle)

fixHeader = true;
}
*/

//check that there's space on nand
/*
if (!_checkDsiSpace(installSize, (h->tid_high != 0x00030004)))
{
if (sdnandMode && choicePrint("Install as system title?"))
Expand All @@ -581,6 +571,7 @@ bool install(char* fpath, bool systemTitle)
goto error;
}
}
*/

//check for saves
char pubPath[PATH_MAX];
Expand Down Expand Up @@ -682,20 +673,29 @@ bool install(char* fpath, bool systemTitle)

//create 000000##.app
{
iprintf("Creating 000000%02x.app...", appVersion);
// We must get the app name from the TMD (0x1E4-1E8).
// NTM/TMFH did it weirdly before by using a single byte at 0x1E7 called "appVersion"?
// Not sure how that even worked at all. The home menu deleted the incorrectly named apps
// and TwlNmenu showed them as being broken.
//
// This new code should always create valid titles.
FILE *tmd = fopen(tmdPath, "rb");
unsigned char appName[4];
fseek(tmd, 484, SEEK_SET);
fread(appName, 1, 4, tmd);
fclose(tmd);

iprintf("Creating %02x%02x%02x%02x.app...", appName[0], appName[1], appName[2], appName[3]);
swiWaitForVBlank();

char appPath[80];
sprintf(appPath, "%s/000000%02x.app", contentPath, appVersion);
sprintf(appPath, "%s/%02x%02x%02x%02x.app", contentPath, appName[0], appName[1], appName[2], appName[3]);

//copy nds file to app
{
int result = 0;

if (!romIsCia(fpath))
result = copyFile(fpath, appPath);
else
result = copyFilePart(fpath, 0x3900, fileSize, appPath);
result = copyFile(fpath, appPath);

if (result != 0)
{
Expand Down Expand Up @@ -867,5 +867,11 @@ bool install(char* fpath, bool systemTitle)
if (!sdnandMode)
nandio_lock_writing();

remove("sd:/_nds/TADDeliveryTool/tmp/temp.tmd");
remove("sd:/_nds/TADDeliveryTool/tmp/temp.tik");
remove("sd:/_nds/TADDeliveryTool/tmp/temp.srl.enc");
remove("sd:/_nds/TADDeliveryTool/tmp/temp.srl");
rmdir("sd:/_nds/TADDeliveryTool/tmp");

return result;
}
9 changes: 2 additions & 7 deletions arm9/src/installmenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,7 @@ static void generateList(Menu* m)
}
else
{
if (strcasecmp(strrchr(ent->d_name, '.'), ".nds") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".app") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".dsi") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".ids") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".srl") == 0 ||
strcasecmp(strrchr(ent->d_name, '.'), ".cia") == 0)
if (strcasecmp(strrchr(ent->d_name, '.'), ".tad") == 0)
{
if (count < m->page * ITEMS_PER_PAGE)
count += 1;
Expand Down Expand Up @@ -237,7 +232,7 @@ static void printItem(Menu* m)
if (m->items[m->cursor].directory)
clearScreen(&topScreen);
else
printRomInfo(m->items[m->cursor].value);
printTadInfo(m->items[m->cursor].value);
}

static int subMenu()
Expand Down
Loading
Loading