diff --git a/Makefile b/Makefile index cb9e3a5..329c7a0 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ LIBS := -lctru -lm -lz # list of directories containing libraries, this must be the top level containing # include and lib #--------------------------------------------------------------------------------- -LIBDIRS := $(DEVKITPRO)/ctrulib/libctru $(DEVKITPRO)/portlibs/armv6k +LIBDIRS := $(DEVKITPRO)/ctrulib/libctru $(DEVKITPRO)/portlibs/armv6k $(CTRULIB) #--------------------------------------------------------------------------------- diff --git a/asr.dat b/asr.dat index ceb434b..a095b69 100644 --- a/asr.dat +++ b/asr.dat @@ -1,6 +1,8 @@ CTR-P-EGD /garden.dat 00000000 -CTR-P-NXC /account_data.bin 00000010 -CTR-P-NXC /system_data.bin 00000010 +CTR-P-NXC /save_data/account_data.bin 00000010 +CTR-P-NXC /save_data/system_data.bin 00000010 +CTR-T-AXC /save_data/account_data.bin 00000010 +CTR-T-AXC /save_data/system_data.bin 00000010 CTR-P-EKJ /main 00065400 CTR-P-EK2 /main 00065400 CTR-P-ECL /main 00075e00 diff --git a/source/filesystem.c b/source/filesystem.c index 4855bf8..219fdba 100644 --- a/source/filesystem.c +++ b/source/filesystem.c @@ -1,5 +1,6 @@ -#include -#include +#include +#include +#include #include <3ds.h> @@ -285,3 +286,25 @@ Result doesFileNotExist(const char* filename, Handle* fsHandle, FS_archive archi else return -1; } + +int file_exist(const char * filename) +{ + FILE * pFile; + long lSize; + char * buffer; + size_t result; + + pFile = fopen ( filename , "rb" ); + if (pFile==NULL) return 0; + fseek (pFile , 0 , SEEK_END); + lSize = ftell (pFile); + rewind (pFile); + buffer = (char*) malloc (sizeof(char)*lSize); + if (buffer == NULL) return 0; + result = fread (buffer,1,lSize,pFile); + if (result != lSize) return 0; + fclose (pFile); + free (buffer); + if (lSize > 0) return 1; + return 0; +} diff --git a/source/filesystem.h b/source/filesystem.h index 1f86b36..f0bd6be 100644 --- a/source/filesystem.h +++ b/source/filesystem.h @@ -16,5 +16,6 @@ u64 sizeFile(char* path, FS_archive* archive, Handle* fsHandle); Result readBytesFromSaveFile(const char* filename, u64 offset, u8* buffer, u32 size); Result writeBytesToSaveFile(const char* filename, u64 offset, u8* buffer, u32 size); Result getSaveGameFileSize(const char* filename, u64* size); -Result doesFileNotExist(const char* filename, Handle* fsHandle, FS_archive archive); +Result doesFileNotExist(const char* filename, Handle* fsHandle, FS_archive archive); +int file_exist (const char *filename); #endif diff --git a/source/main.c b/source/main.c index f24ea17..4e8b847 100644 --- a/source/main.c +++ b/source/main.c @@ -525,11 +525,14 @@ int checkInjectDirectory(char* path, lsDir* dir) int main() { filesystemInit(); - if (!doesFileNotExist("/3ds/svdt/no_alpha_sort",&sdmcFsHandle,sdmcArchive)) + //if (!doesFileNotExist("/3ds/svdt/no_alpha_sort",&sdmcFsHandle,sdmcArchive)) + if (file_exist("no_alpha_sort")) alphabetSort = 0; + FSUSER_CreateDirectory(&sdmcFsHandle,sdmcArchive,FS_makePath(PATH_CHAR,"/svdt")); u64 tid; + u64 tid2 = 0; int titleTitles_available; char destPath[MAX_PATH_LENGTH]; char tempStr[16] = {0}; @@ -543,6 +546,23 @@ int main() getTitleTitle(0x0,2,titleTitle); titleTitle_set = 1; } else { + //Fetch title from /svdt/tid.bin + FILE * pFile; + long lSize; + size_t result; + pFile = fopen ( "/svdt/tid.bin" , "rb" ); + if (pFile!=NULL) { + fseek (pFile , 0 , SEEK_END); + lSize = ftell (pFile); + rewind (pFile); + result = fread (&tid2,1,sizeof(tid2),pFile); + if (result == lSize) { + fclose (pFile); + //Make sure we can't load this again without going trough HBL + remove("/svdt/tid.bin"); + } + } + fclose (pFile); secureGameFromFilesystem(); getSecureValue(); } @@ -555,7 +575,8 @@ int main() hidScanInput(); - if ((hidKeysHeld() & KEY_L) != doesFileNotExist("/3ds/svdt/disable_auto_backups",&sdmcFsHandle,sdmcArchive)) + //if ((hidKeysHeld() & KEY_L) != doesFileNotExist("/3ds/svdt/disable_auto_backups",&sdmcFsHandle,sdmcArchive)) + if ((hidKeysHeld() & KEY_L) == file_exist("disable_auto_backups")) { // always back up the data if one and only one of two conditions is met: // no disable_auto_backups file (cannot be empty) @@ -666,7 +687,7 @@ int main() consoleSelect(&titleBar); textcolour(TEAL); - printf("svdt 0.10, meladroit/willidleaway\n"); + printf("svdt 0.10.1, meladroit/willidleaway/suloku\n"); printf("a hacked-together save data explorer/manager\n"); gotoxy(CURSOR_WIDTH,2); textcolour(GREY); @@ -705,7 +726,22 @@ int main() gotoxy(0,10); int i; for (i=0;ithisTitle == tid2){ + titleTitle_set = i; + getTitleTitle(tid2, mediatype, titleTitle); + tid = tid2; + break; + } + currentTitle = currentTitle->nextTitle; + i++; + } + } + if (!titleTitle_set) + nthTitleInList(titleTitle_set,mediatype,titleTitle,&tid); AM_GetTitleProductCode(mediatype,tid,productCodeBuffer); strncpy(productCode,productCodeBuffer,9); gotoxy(1,10); @@ -715,6 +751,10 @@ int main() gotoxy((BOTTOM_WIDTH-strlen(titleTitle))/2,10); textcolour(NEONGREEN); printf(titleTitle); + gotoxy(0,29); + textcolour(WHITE); + printf(productCode); + printf(" - %llx", tid); gotoxy(0,12); textcolour(SALMON); wordwrap("Target app is not on gamecard. Fetching target app titles automatically is not implemented for NAND/SD apps. Use left/right on D-pad with the A button to select the correct target app name. Press B to skip.",BOTTOM_WIDTH); @@ -761,6 +801,9 @@ int main() textcolour(WHITE); AM_GetTitleProductCode(mediatype,tid,productCodeBuffer); strncpy(productCode,productCodeBuffer,9); + gotoxy(0,29); + printf(productCode); + printf(" - %llx", tid); } if(hidKeysDown() & KEY_A) { diff --git a/source/secure_values.c b/source/secure_values.c index 53b5831..6b28cf7 100644 --- a/source/secure_values.c +++ b/source/secure_values.c @@ -15,7 +15,7 @@ u8 secureValue[SECURE_VALUE_SIZE] = {0}; secureGame whichSecureGame = SECURE_UNKNOWN; const u32 const secureOffsets[PRECONF_GAMES] = {ACNL_OFFSET, SSB_OFFSET, POKETORU_OFFSET, POKEXY_OFFSET, POKEXY_OFFSET, POKEORAS_OFFSET, POKEORAS_OFFSET}; -const char const secureFilenames[PRECONF_GAMES][MAX_PATH_LENGTH] = {"/garden.dat", "/account_data.bin", "/savedata.bin", "/main", "/main", "/main", "/main"}; +const char const secureFilenames[PRECONF_GAMES][MAX_PATH_LENGTH] = {"/garden.dat", "/save_data/account_data.bin", "/save_data/savedata.bin", "/main", "/main", "/main", "/main"}; const char const secureProductCodes[PRECONF_GAMES][16] = {"CTR-P-EGD", "CTR-P-NXC", "CTR-N-KRX", "CTR-P-EKJ", "CTR-P-EK2", @@ -26,7 +26,7 @@ char configProductCode[9] = {0}; const char* const POKERW_SVPATH = "/00slot00/00main.dat"; const char* const customSecurePath = "/svdt_sv_data"; -const char* const secureConfigPath = "/3ds/svdt/asr.dat"; +const char* const secureConfigPath = "asr.dat"; const char* const secureConfigBasename = "asr.dat"; int isSecureFile(const char* destPath) @@ -78,7 +78,7 @@ int isSecureFile2(const char* destPath, const char* productCode) { if (!strncmp(productCode,pokeRumbleWorldCode,9)) return (!strcmp(destPath,POKERW_SVPATH)); - if(checkSecureConfig()) + if(!checkSecureConfig()) return -1; if(!secureValueSet) return -1; @@ -98,12 +98,14 @@ int isSecureFile2(const char* destPath, const char* productCode) Result checkCustomSecureGame() { - return doesFileNotExist(customSecurePath,&sdmcFsHandle,sdmcArchive); + //return doesFileNotExist(customSecurePath,&sdmcFsHandle,sdmcArchive); + return file_exist(customSecurePath); } Result checkSecureConfig() { - return doesFileNotExist(secureConfigPath,&sdmcFsHandle,sdmcArchive); + //return doesFileNotExist(secureConfigPath,&sdmcFsHandle,sdmcArchive); + return file_exist(secureConfigPath); } void secureGameFromProductCode(const char* productCode) @@ -117,7 +119,7 @@ void secureGameFromProductCode(const char* productCode) return; } // ideally we actually have asr.dat in /3ds/svdt - if(!checkSecureConfig()) + if(checkSecureConfig()) { // and ideally we actually have the product code in there ... FILE* config = fopen(secureConfigBasename,"rb"); @@ -150,7 +152,7 @@ void secureGameFromProductCode(const char* productCode) } } // custom specifier does not take precedence over having the actual product code - if(!checkCustomSecureGame()) + if(checkCustomSecureGame()) { whichSecureGame = SECURE_EMERGENCY; return; @@ -163,7 +165,7 @@ void secureGameFromFilesystem() u64 size = 0; secureValueSet = 0; // custom specifier absolutely takes precedence over these guesses - if(!checkCustomSecureGame()) + if(checkCustomSecureGame()) { whichSecureGame = SECURE_EMERGENCY; return; @@ -176,9 +178,9 @@ void secureGameFromFilesystem() } // from here, the guesses are much less safe // (there's a reason we override these if we can get to the target title prompt) - if(!getSaveGameFileSize("/account_data.bin",&size)) + if(!getSaveGameFileSize("/save_data/account_data.bin",&size)) { - if(!getSaveGameFileSize("/system_data.bin",&size)) + if(!getSaveGameFileSize("/save_data/system_data.bin",&size)) { whichSecureGame = SECURE_SSB; return; @@ -292,7 +294,7 @@ Result getSecureValue2(const char* productCode) { if (!strncmp(productCode,pokeRumbleWorldCode,9)) return getPokeRumbleSecureValue(); - if(checkSecureConfig()) + if(!checkSecureConfig()) return -1; //printf("\nopening asr.dat\n"); FILE* config = fopen(secureConfigBasename,"rb"); diff --git a/svdt.3dsx b/svdt.3dsx index ace2d6a..258889b 100644 Binary files a/svdt.3dsx and b/svdt.3dsx differ