mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Add options for building / decrypting / encrypting aeskeydb.bin
This commit is contained in:
parent
679d90dea7
commit
b278be0b49
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// GodMode9 version
|
// GodMode9 version
|
||||||
#define VERSION "1.0.9"
|
#define VERSION "1.1.0"
|
||||||
|
|
||||||
// Maximum payload size (arbitrary value!)
|
// Maximum payload size (arbitrary value!)
|
||||||
#define SELF_MAX_SIZE (320 * 1024) // 320kB
|
#define SELF_MAX_SIZE (320 * 1024) // 320kB
|
||||||
|
@ -19,4 +19,5 @@ typedef struct {
|
|||||||
} __attribute__((packed)) AesKeyInfo;
|
} __attribute__((packed)) AesKeyInfo;
|
||||||
|
|
||||||
u32 GetUnitKeysType(void);
|
u32 GetUnitKeysType(void);
|
||||||
|
void CryptAesKeyInfo(AesKeyInfo* info);
|
||||||
u32 LoadKeyFromFile(u8* key, u32 keyslot, char type, char* id);
|
u32 LoadKeyFromFile(u8* key, u32 keyslot, char type, char* id);
|
||||||
|
@ -32,11 +32,12 @@
|
|||||||
|
|
||||||
#define FTYPE_MOUNTABLE(tp) (tp&(IMG_FAT|IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_EXEFS|GAME_ROMFS|SYS_FIRM|SYS_TICKDB))
|
#define FTYPE_MOUNTABLE(tp) (tp&(IMG_FAT|IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_EXEFS|GAME_ROMFS|SYS_FIRM|SYS_TICKDB))
|
||||||
#define FYTPE_VERIFICABLE(tp) (tp&(IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_TMD|GAME_BOSS|SYS_FIRM))
|
#define FYTPE_VERIFICABLE(tp) (tp&(IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_TMD|GAME_BOSS|SYS_FIRM))
|
||||||
#define FYTPE_DECRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|GAME_NUSCDN|SYS_FIRM))
|
#define FYTPE_DECRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|GAME_NUSCDN|SYS_FIRM|BIN_KEYDB))
|
||||||
#define FYTPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS))
|
#define FYTPE_ENCRYPTABLE(tp) (tp&(GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_BOSS|BIN_KEYDB))
|
||||||
#define FTYPE_CIABUILD(tp) (tp&(GAME_NCSD|GAME_NCCH|GAME_TMD))
|
#define FTYPE_CIABUILD(tp) (tp&(GAME_NCSD|GAME_NCCH|GAME_TMD))
|
||||||
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD)))
|
#define FTYPE_CIABUILD_L(tp) (FTYPE_CIABUILD(tp) && (tp&(GAME_TMD)))
|
||||||
#define FTYPE_TIKBUILD(tp) (tp&(GAME_TICKET|SYS_TICKDB|BIN_TIKDB))
|
#define FTYPE_TIKBUILD(tp) (tp&(GAME_TICKET|SYS_TICKDB|BIN_TIKDB))
|
||||||
|
#define FTYPE_KEYBUILD(tp) (tp&(BIN_KEYDB|BIN_LEGKEY))
|
||||||
#define FTYPE_TITLEINFO(tp) (tp&(GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS))
|
#define FTYPE_TITLEINFO(tp) (tp&(GAME_SMDH|GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_TMD|GAME_NDS))
|
||||||
#define FTYPE_TRANSFERABLE(tp) ((u32) (tp&(IMG_FAT|FLAG_CTR)) == (u32) (IMG_FAT|FLAG_CTR))
|
#define FTYPE_TRANSFERABLE(tp) ((u32) (tp&(IMG_FAT|FLAG_CTR)) == (u32) (IMG_FAT|FLAG_CTR))
|
||||||
#define FTYPE_HSINJECTABLE(tp) ((u32) (tp&(GAME_NCCH|FLAG_CXI)) == (u32) (GAME_NCCH|FLAG_CXI))
|
#define FTYPE_HSINJECTABLE(tp) ((u32) (tp&(GAME_NCCH|FLAG_CXI)) == (u32) (GAME_NCCH|FLAG_CXI))
|
||||||
|
119
source/game/keydbutil.c
Normal file
119
source/game/keydbutil.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#include "keydbutil.h"
|
||||||
|
#include "fsperm.h"
|
||||||
|
#include "filetype.h"
|
||||||
|
#include "unittype.h"
|
||||||
|
#include "vff.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
#define MAX_KEYDB_SIZE (TEMP_BUFFER_SIZE)
|
||||||
|
|
||||||
|
u32 CryptAesKeyDb(const char* path, bool inplace, bool encrypt) {
|
||||||
|
AesKeyInfo* keydb = (AesKeyInfo*) MAIN_BUFFER;
|
||||||
|
const char* path_out = (inplace) ? path : OUTPUT_PATH "/" KEYDB_NAME;
|
||||||
|
u32 n_keys;
|
||||||
|
UINT bt, btw;
|
||||||
|
|
||||||
|
// write permissions
|
||||||
|
if (!CheckWritePermissions(path_out))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// load key database
|
||||||
|
if ((fvx_qread(path, keydb, 0, MAIN_BUFFER_SIZE, &bt) != FR_OK) ||
|
||||||
|
(bt % sizeof(AesKeyInfo)) || (bt >= MAIN_BUFFER_SIZE))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// en-/decrypt keys
|
||||||
|
n_keys = bt / sizeof(AesKeyInfo);
|
||||||
|
for (u32 i = 0; i < n_keys; i++) {
|
||||||
|
if ((bool) keydb[i].isEncrypted == !encrypt)
|
||||||
|
CryptAesKeyInfo(&(keydb[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// dump key database
|
||||||
|
if (!inplace) f_unlink(path_out);
|
||||||
|
if ((fvx_qwrite(path_out, keydb, 0, bt, &btw) != FR_OK) || (bt != btw))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 AddKeyToDb(AesKeyInfo* key_info, AesKeyInfo* key_entry) {
|
||||||
|
AesKeyInfo* key = key_info;
|
||||||
|
if (key_entry) { // key entry provided
|
||||||
|
for (; key->slot < 0x40; key++) {
|
||||||
|
if ((u8*) key - (u8*) key_info >= MAX_KEYDB_SIZE) return 1;
|
||||||
|
if ((key_entry->slot == key->slot) && (key_entry->type == key->type) &&
|
||||||
|
(strncasecmp(key_entry->id, key->id, 10) == 0) &&
|
||||||
|
((bool) key_entry->isDevkitKey == (bool) key->isDevkitKey))
|
||||||
|
return 0; // key already in db
|
||||||
|
}
|
||||||
|
memcpy(key++, key_entry, sizeof(AesKeyInfo));
|
||||||
|
}
|
||||||
|
if ((u8*) key - (u8*) key_info >= MAX_KEYDB_SIZE) return 1;
|
||||||
|
memset(key, 0xFF, sizeof(AesKeyInfo)); // this used to signal keydb end
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 BuildKeyDb(const char* path, bool dump) {
|
||||||
|
AesKeyInfo* key_info = (AesKeyInfo*) MAIN_BUFFER;
|
||||||
|
const char* path_out = OUTPUT_PATH "/" KEYDB_NAME;
|
||||||
|
const char* path_in = path;
|
||||||
|
UINT br;
|
||||||
|
|
||||||
|
// write permissions
|
||||||
|
if (!CheckWritePermissions(path_out))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!path_in && !dump) { // no input path given - initialize
|
||||||
|
AddKeyToDb(key_info, NULL);
|
||||||
|
if ((fvx_stat(path_out, NULL) == FR_OK) &&
|
||||||
|
(ShowPrompt(true, "%s\nOutput file already exists.\nUpdate this?", path_out)))
|
||||||
|
path_in = path_out;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 filetype = path_in ? IdentifyFileType(path_in) : 0;
|
||||||
|
if (filetype & BIN_KEYDB) { // AES key database
|
||||||
|
AesKeyInfo* key_info_merge = (AesKeyInfo*) TEMP_BUFFER;
|
||||||
|
if ((fvx_qread(path_in, key_info_merge, 0, TEMP_BUFFER_SIZE, &br) != FR_OK) ||
|
||||||
|
(br % sizeof(AesKeyInfo)) || (br >= MAIN_BUFFER_SIZE)) return 1;
|
||||||
|
u32 n_keys = br / sizeof(AesKeyInfo);
|
||||||
|
for (u32 i = 0; i < n_keys; i++) {
|
||||||
|
if (key_info_merge[i].isEncrypted) // build an unencrypted db
|
||||||
|
CryptAesKeyInfo(&(key_info_merge[i]));
|
||||||
|
if (AddKeyToDb(key_info, key_info_merge + i) != 0) return 1;
|
||||||
|
}
|
||||||
|
} else if (filetype & BIN_LEGKEY) { // legacy key file
|
||||||
|
AesKeyInfo key;
|
||||||
|
unsigned int keyslot = 0xFF;
|
||||||
|
char typestr[16] = { 0 };
|
||||||
|
char* name_in = strrchr(path_in, '/');
|
||||||
|
memset(&key, 0, sizeof(AesKeyInfo));
|
||||||
|
key.type = 'N';
|
||||||
|
if (!name_in || (strnlen(++name_in, 32) > 24)) return 1; // safety
|
||||||
|
if ((sscanf(name_in, "slot0x%02XKey%s", &keyslot, typestr) != 2) &&
|
||||||
|
(sscanf(name_in, "slot0x%02Xkey%s", &keyslot, typestr) != 2)) return 1;
|
||||||
|
char* dot = strrchr(typestr, '.');
|
||||||
|
if (!dot) return 1;
|
||||||
|
*dot = '\0';
|
||||||
|
if ((typestr[1] == '\0') && ((*typestr == 'X') || (*typestr == 'Y'))) key.type = *typestr;
|
||||||
|
else strncpy(key.id, typestr, 10);
|
||||||
|
key.slot = keyslot;
|
||||||
|
key.isDevkitKey = (IS_DEVKIT) ? 1 : 0; // just assume it's a devkit key on devkit
|
||||||
|
if ((fvx_qread(path_in, key.key, 0, 16, &br) != FR_OK) || (br != 16)) return 1;
|
||||||
|
if (AddKeyToDb(key_info, &key) != 0) return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dump) {
|
||||||
|
u32 dump_size = 0;
|
||||||
|
for (AesKeyInfo* key = key_info; key->slot <= 0x40; key++) {
|
||||||
|
dump_size += sizeof(AesKeyInfo);
|
||||||
|
if (dump_size >= MAX_KEYDB_SIZE) return 1;
|
||||||
|
}
|
||||||
|
f_unlink(path_out);
|
||||||
|
if (!dump_size || (fvx_qwrite(path_out, key_info, 0, dump_size, &br) != FR_OK) || (br != dump_size))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
8
source/game/keydbutil.h
Normal file
8
source/game/keydbutil.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "keydb.h"
|
||||||
|
|
||||||
|
u32 CryptAesKeyDb(const char* path, bool inplace, bool encrypt);
|
||||||
|
u32 AddKeyToDb(AesKeyInfo* key_info, AesKeyInfo* key_entry);
|
||||||
|
u32 BuildKeyDb(const char* path, bool dump);
|
@ -6,6 +6,7 @@
|
|||||||
#include "fsutil.h"
|
#include "fsutil.h"
|
||||||
#include "fsperm.h"
|
#include "fsperm.h"
|
||||||
#include "gameutil.h"
|
#include "gameutil.h"
|
||||||
|
#include "keydbutil.h"
|
||||||
#include "nandutil.h"
|
#include "nandutil.h"
|
||||||
#include "filetype.h"
|
#include "filetype.h"
|
||||||
#include "unittype.h"
|
#include "unittype.h"
|
||||||
@ -655,6 +656,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
bool cia_buildable = (FTYPE_CIABUILD(filetype));
|
bool cia_buildable = (FTYPE_CIABUILD(filetype));
|
||||||
bool cia_buildable_legit = (FTYPE_CIABUILD_L(filetype));
|
bool cia_buildable_legit = (FTYPE_CIABUILD_L(filetype));
|
||||||
bool tik_buildable = (FTYPE_TIKBUILD(filetype)) && !in_output_path;
|
bool tik_buildable = (FTYPE_TIKBUILD(filetype)) && !in_output_path;
|
||||||
|
bool key_buildable = (FTYPE_KEYBUILD(filetype)) && !in_output_path;
|
||||||
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
bool titleinfo = (FTYPE_TITLEINFO(filetype));
|
||||||
bool transferable = (FTYPE_TRANSFERABLE(filetype) && IS_A9LH && (drvtype & DRV_FAT));
|
bool transferable = (FTYPE_TRANSFERABLE(filetype) && IS_A9LH && (drvtype & DRV_FAT));
|
||||||
bool hsinjectable = (FTYPE_HSINJECTABLE(filetype));
|
bool hsinjectable = (FTYPE_HSINJECTABLE(filetype));
|
||||||
@ -663,7 +665,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
bool xorpadable = (FTYPE_XORPAD(filetype));
|
bool xorpadable = (FTYPE_XORPAD(filetype));
|
||||||
bool launchable = ((FTYPE_PAYLOAD(filetype)) && (drvtype & DRV_FAT));
|
bool launchable = ((FTYPE_PAYLOAD(filetype)) && (drvtype & DRV_FAT));
|
||||||
bool special_opt = mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit ||
|
bool special_opt = mountable || verificable || decryptable || encryptable || cia_buildable || cia_buildable_legit ||
|
||||||
tik_buildable || titleinfo || hsinjectable || restorable || xorpadable || launchable || ebackupable;
|
tik_buildable || key_buildable || titleinfo || hsinjectable || restorable || xorpadable || launchable || ebackupable;
|
||||||
|
|
||||||
char pathstr[32+1];
|
char pathstr[32+1];
|
||||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
TruncateString(pathstr, curr_entry->path, 32, 8);
|
||||||
@ -704,6 +706,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
(filetype & SYS_FIRM ) ? "FIRM image options..." :
|
(filetype & SYS_FIRM ) ? "FIRM image options..." :
|
||||||
(filetype & SYS_TICKDB) ? (tik_buildable) ? "Ticket.db options..." : "Mount as ticket.db" :
|
(filetype & SYS_TICKDB) ? (tik_buildable) ? "Ticket.db options..." : "Mount as ticket.db" :
|
||||||
(filetype & BIN_TIKDB) ? "Titlekey options..." :
|
(filetype & BIN_TIKDB) ? "Titlekey options..." :
|
||||||
|
(filetype & BIN_KEYDB) ? "AESkeydb options..." :
|
||||||
|
(filetype & BIN_LEGKEY) ? "Build " KEYDB_NAME :
|
||||||
(filetype & BIN_NCCHNFO)? "NCCHinfo options..." :
|
(filetype & BIN_NCCHNFO)? "NCCHinfo options..." :
|
||||||
(filetype & BIN_LAUNCH) ? "Launch as arm9 payload" : "???";
|
(filetype & BIN_LAUNCH) ? "Launch as arm9 payload" : "???";
|
||||||
optionstr[hexviewer-1] = "Show in Hexeditor";
|
optionstr[hexviewer-1] = "Show in Hexeditor";
|
||||||
@ -803,6 +807,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
int cia_build_legit = (cia_buildable_legit) ? ++n_opt : -1;
|
int cia_build_legit = (cia_buildable_legit) ? ++n_opt : -1;
|
||||||
int tik_build_enc = (tik_buildable) ? ++n_opt : -1;
|
int tik_build_enc = (tik_buildable) ? ++n_opt : -1;
|
||||||
int tik_build_dec = (tik_buildable) ? ++n_opt : -1;
|
int tik_build_dec = (tik_buildable) ? ++n_opt : -1;
|
||||||
|
int key_build = (key_buildable) ? ++n_opt : -1;
|
||||||
int verify = (verificable) ? ++n_opt : -1;
|
int verify = (verificable) ? ++n_opt : -1;
|
||||||
int ctrtransfer = (transferable) ? ++n_opt : -1;
|
int ctrtransfer = (transferable) ? ++n_opt : -1;
|
||||||
int hsinject = (hsinjectable) ? ++n_opt : -1;
|
int hsinject = (hsinjectable) ? ++n_opt : -1;
|
||||||
@ -819,6 +824,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
if (cia_build_legit > 0) optionstr[cia_build_legit-1] = "Build CIA (legit)";
|
if (cia_build_legit > 0) optionstr[cia_build_legit-1] = "Build CIA (legit)";
|
||||||
if (tik_build_enc > 0) optionstr[tik_build_enc-1] = "Build " TIKDB_NAME_ENC;
|
if (tik_build_enc > 0) optionstr[tik_build_enc-1] = "Build " TIKDB_NAME_ENC;
|
||||||
if (tik_build_dec > 0) optionstr[tik_build_dec-1] = "Build " TIKDB_NAME_DEC;
|
if (tik_build_dec > 0) optionstr[tik_build_dec-1] = "Build " TIKDB_NAME_DEC;
|
||||||
|
if (key_build > 0) optionstr[key_build-1] = "Build " KEYDB_NAME;
|
||||||
if (verify > 0) optionstr[verify-1] = "Verify file";
|
if (verify > 0) optionstr[verify-1] = "Verify file";
|
||||||
if (ctrtransfer > 0) optionstr[ctrtransfer-1] = "Transfer image to CTRNAND";
|
if (ctrtransfer > 0) optionstr[ctrtransfer-1] = "Transfer image to CTRNAND";
|
||||||
if (hsinject > 0) optionstr[hsinject-1] = "Inject to H&S";
|
if (hsinject > 0) optionstr[hsinject-1] = "Inject to H&S";
|
||||||
@ -873,12 +879,13 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
n_other++;
|
n_other++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (CheckEncryptedGameFile(path) != 0) {
|
if (!(filetype & BIN_KEYDB) && (CheckEncryptedGameFile(path) != 0)) {
|
||||||
n_unencrypted++;
|
n_unencrypted++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
current_dir->entry[i].marked = false;
|
current_dir->entry[i].marked = false;
|
||||||
if (CryptGameFile(path, inplace, false) == 0) n_success++;
|
if (!(filetype & BIN_KEYDB) && (CryptGameFile(path, inplace, false) == 0)) n_success++;
|
||||||
|
else if ((filetype & BIN_KEYDB) && (CryptAesKeyDb(path, inplace, false) == 0)) n_success++;
|
||||||
else { // on failure: set cursor on failed title, break;
|
else { // on failure: set cursor on failed title, break;
|
||||||
*cursor = i;
|
*cursor = i;
|
||||||
break;
|
break;
|
||||||
@ -890,10 +897,11 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
} else ShowPrompt(false, "%lu/%lu files decrypted ok", n_success, n_marked);
|
} else ShowPrompt(false, "%lu/%lu files decrypted ok", n_success, n_marked);
|
||||||
if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH);
|
if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH);
|
||||||
} else {
|
} else {
|
||||||
if (CheckEncryptedGameFile(curr_entry->path) != 0) {
|
if (!(filetype & BIN_KEYDB) && (CheckEncryptedGameFile(curr_entry->path) != 0)) {
|
||||||
ShowPrompt(false, "%s\nFile is not encrypted", pathstr);
|
ShowPrompt(false, "%s\nFile is not encrypted", pathstr);
|
||||||
} else {
|
} else {
|
||||||
u32 ret = CryptGameFile(curr_entry->path, inplace, false);
|
u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(curr_entry->path, inplace, false) :
|
||||||
|
CryptGameFile(curr_entry->path, inplace, false);
|
||||||
if (inplace || (ret != 0)) ShowPrompt(false, "%s\nDecryption %s", pathstr, (ret == 0) ? "success" : "failed");
|
if (inplace || (ret != 0)) ShowPrompt(false, "%s\nDecryption %s", pathstr, (ret == 0) ? "success" : "failed");
|
||||||
else ShowPrompt(false, "%s\nDecrypted to %s", pathstr, OUTPUT_PATH);
|
else ShowPrompt(false, "%s\nDecrypted to %s", pathstr, OUTPUT_PATH);
|
||||||
}
|
}
|
||||||
@ -921,7 +929,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
current_dir->entry[i].marked = false;
|
current_dir->entry[i].marked = false;
|
||||||
if (CryptGameFile(path, inplace, true) == 0) n_success++;
|
if (!(filetype & BIN_KEYDB) && (CryptGameFile(path, inplace, true) == 0)) n_success++;
|
||||||
|
else if ((filetype & BIN_KEYDB) && (CryptAesKeyDb(path, inplace, true) == 0)) n_success++;
|
||||||
else { // on failure: set cursor on failed title, break;
|
else { // on failure: set cursor on failed title, break;
|
||||||
*cursor = i;
|
*cursor = i;
|
||||||
break;
|
break;
|
||||||
@ -933,7 +942,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
} else ShowPrompt(false, "%lu/%lu files encrypted ok", n_success, n_marked);
|
} else ShowPrompt(false, "%lu/%lu files encrypted ok", n_success, n_marked);
|
||||||
if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH);
|
if (!inplace && n_success) ShowPrompt(false, "%lu files written to %s", n_success, OUTPUT_PATH);
|
||||||
} else {
|
} else {
|
||||||
u32 ret = CryptGameFile(curr_entry->path, inplace, true);
|
u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(curr_entry->path, inplace, true) :
|
||||||
|
CryptGameFile(curr_entry->path, inplace, true);
|
||||||
if (inplace || (ret != 0)) ShowPrompt(false, "%s\nEncryption %s", pathstr, (ret == 0) ? "success" : "failed");
|
if (inplace || (ret != 0)) ShowPrompt(false, "%s\nEncryption %s", pathstr, (ret == 0) ? "success" : "failed");
|
||||||
else ShowPrompt(false, "%s\nEncrypted to %s", pathstr, OUTPUT_PATH);
|
else ShowPrompt(false, "%s\nEncrypted to %s", pathstr, OUTPUT_PATH);
|
||||||
}
|
}
|
||||||
@ -1029,10 +1039,36 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored",
|
if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored",
|
||||||
path_out, n_success, n_marked, n_other, n_marked);
|
path_out, n_success, n_marked, n_other, n_marked);
|
||||||
else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked);
|
else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked);
|
||||||
} else ShowPrompt(false, "%s\nBuild database failed.");
|
} else ShowPrompt(false, "%s\nBuild database failed.", path_out);
|
||||||
} else ShowPrompt(false, "%s\nBuild database %s.", path_out,
|
} else ShowPrompt(false, "%s\nBuild database %s.", path_out,
|
||||||
(BuildTitleKeyInfo(curr_entry->path, dec, true) == 0) ? "success" : "failed");
|
(BuildTitleKeyInfo(curr_entry->path, dec, true) == 0) ? "success" : "failed");
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (user_select == key_build) { // -> (Re)Build AES key database
|
||||||
|
const char* path_out = OUTPUT_PATH "/" KEYDB_NAME;
|
||||||
|
if (BuildKeyDb(NULL, false) != 0) return 1; // init database
|
||||||
|
ShowString("Building %s...", KEYDB_NAME);
|
||||||
|
if (n_marked > 1) {
|
||||||
|
u32 n_success = 0;
|
||||||
|
u32 n_other = 0;
|
||||||
|
for (u32 i = 0; i < current_dir->n_entries; i++) {
|
||||||
|
const char* path = current_dir->entry[i].path;
|
||||||
|
if (!current_dir->entry[i].marked)
|
||||||
|
continue;
|
||||||
|
if (!FTYPE_KEYBUILD(IdentifyFileType(path))) {
|
||||||
|
n_other++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current_dir->entry[i].marked = false;
|
||||||
|
if (BuildKeyDb(path, false) == 0) n_success++; // ignore failures for now
|
||||||
|
}
|
||||||
|
if (BuildKeyDb(NULL, true) == 0) {
|
||||||
|
if (n_other) ShowPrompt(false, "%s\n%lu/%lu files processed\n%lu/%lu files ignored",
|
||||||
|
path_out, n_success, n_marked, n_other, n_marked);
|
||||||
|
else ShowPrompt(false, "%s\n%lu/%lu files processed", path_out, n_success, n_marked);
|
||||||
|
} else ShowPrompt(false, "%s\nBuild database failed.", path_out);
|
||||||
|
} else ShowPrompt(false, "%s\nBuild database %s.", path_out,
|
||||||
|
(BuildKeyDb(curr_entry->path, true) == 0) ? "success" : "failed");
|
||||||
|
return 0;
|
||||||
} else if (user_select == show_info) { // -> Show title info
|
} else if (user_select == show_info) { // -> Show title info
|
||||||
if (ShowGameFileTitleInfo(curr_entry->path) != 0)
|
if (ShowGameFileTitleInfo(curr_entry->path) != 0)
|
||||||
ShowPrompt(false, "Title info: not found");
|
ShowPrompt(false, "Title info: not found");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user