mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-04 16:59:02 +00:00
[makerom] Fixed makerom ROMFS file limitation. +Several bug fixes.
This commit is contained in:
+1
-1
@@ -5,7 +5,7 @@ OBJS = $(foreach dir,$(SRC_DIR),$(subst .c,.o,$(wildcard $(dir)/*.c)))
|
|||||||
# Compiler Settings
|
# Compiler Settings
|
||||||
LIBS = -static-libgcc
|
LIBS = -static-libgcc
|
||||||
CXXFLAGS = -I.
|
CXXFLAGS = -I.
|
||||||
CFLAGS = --std=c99 -O2 -flto -Wall -Wno-unused-but-set-variable -Wno-unused-value -I. $(MAKEROM_BUILD_FLAGS)
|
CFLAGS = --std=c99 -Wall -Wno-unused-but-set-variable -Wno-unused-value -I. $(MAKEROM_BUILD_FLAGS)
|
||||||
CC = gcc
|
CC = gcc
|
||||||
CXX = g++
|
CXX = g++
|
||||||
|
|
||||||
|
|||||||
+21
-2
@@ -571,16 +571,27 @@ u16 SetupVersion(u16 major, u16 minor, u16 micro)
|
|||||||
|
|
||||||
void GetContentHashes(cia_settings *ciaset)
|
void GetContentHashes(cia_settings *ciaset)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < ciaset->content.count; i++)
|
for (int i = 0; i < ciaset->content.count; i++) {
|
||||||
ShaCalc(ciaset->ciaSections.content.buffer+ciaset->content.offset[i],ciaset->content.size[i],ciaset->content.hash[i],CTR_SHA_256);
|
if (ciaset->verbose)
|
||||||
|
printf("[CIA] Hashing content %d... ", i);
|
||||||
|
ShaCalc(ciaset->ciaSections.content.buffer + ciaset->content.offset[i], ciaset->content.size[i], ciaset->content.hash[i], CTR_SHA_256);
|
||||||
|
if (ciaset->verbose)
|
||||||
|
printf("Done!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EncryptContent(cia_settings *ciaset)
|
void EncryptContent(cia_settings *ciaset)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < ciaset->content.count; i++){
|
for(int i = 0; i < ciaset->content.count; i++){
|
||||||
|
if (ciaset->verbose)
|
||||||
|
printf("[CIA] Encrypting content %d... ", i);
|
||||||
|
|
||||||
ciaset->content.flags[i] |= content_Encrypted;
|
ciaset->content.flags[i] |= content_Encrypted;
|
||||||
u8 *content = ciaset->ciaSections.content.buffer+ciaset->content.offset[i];
|
u8 *content = ciaset->ciaSections.content.buffer+ciaset->content.offset[i];
|
||||||
CryptContent(content, content, ciaset->content.size[i], ciaset->common.titleKey, i, ENC);
|
CryptContent(content, content, ciaset->content.size[i], ciaset->common.titleKey, i, ENC);
|
||||||
|
|
||||||
|
if (ciaset->verbose)
|
||||||
|
printf("Done!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,12 +649,20 @@ int BuildCiaHdr(cia_settings *ciaset)
|
|||||||
|
|
||||||
int WriteCiaToFile(cia_settings *ciaset)
|
int WriteCiaToFile(cia_settings *ciaset)
|
||||||
{
|
{
|
||||||
|
if (ciaset->verbose) {
|
||||||
|
printf("[CIA] Writing to file... ");
|
||||||
|
}
|
||||||
WriteBuffer(ciaset->ciaSections.ciaHdr.buffer,ciaset->ciaSections.ciaHdr.size,0,ciaset->out);
|
WriteBuffer(ciaset->ciaSections.ciaHdr.buffer,ciaset->ciaSections.ciaHdr.size,0,ciaset->out);
|
||||||
WriteBuffer(ciaset->ciaSections.certChain.buffer,ciaset->ciaSections.certChain.size,ciaset->ciaSections.certChainOffset,ciaset->out);
|
WriteBuffer(ciaset->ciaSections.certChain.buffer,ciaset->ciaSections.certChain.size,ciaset->ciaSections.certChainOffset,ciaset->out);
|
||||||
WriteBuffer(ciaset->ciaSections.tik.buffer,ciaset->ciaSections.tik.size,ciaset->ciaSections.tikOffset,ciaset->out);
|
WriteBuffer(ciaset->ciaSections.tik.buffer,ciaset->ciaSections.tik.size,ciaset->ciaSections.tikOffset,ciaset->out);
|
||||||
WriteBuffer(ciaset->ciaSections.tmd.buffer,ciaset->ciaSections.tmd.size,ciaset->ciaSections.tmdOffset,ciaset->out);
|
WriteBuffer(ciaset->ciaSections.tmd.buffer,ciaset->ciaSections.tmd.size,ciaset->ciaSections.tmdOffset,ciaset->out);
|
||||||
WriteBuffer(ciaset->ciaSections.content.buffer,ciaset->ciaSections.content.size,ciaset->ciaSections.contentOffset,ciaset->out);
|
WriteBuffer(ciaset->ciaSections.content.buffer,ciaset->ciaSections.content.size,ciaset->ciaSections.contentOffset,ciaset->out);
|
||||||
WriteBuffer(ciaset->ciaSections.meta.buffer,ciaset->ciaSections.meta.size,ciaset->ciaSections.metaOffset,ciaset->out);
|
WriteBuffer(ciaset->ciaSections.meta.buffer,ciaset->ciaSections.meta.size,ciaset->ciaSections.metaOffset,ciaset->out);
|
||||||
|
|
||||||
|
if (ciaset->verbose) {
|
||||||
|
printf("Done!\n");
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -41,7 +41,7 @@ int ImportExeFsCodeBinaryFromFile(ncch_settings *set)
|
|||||||
u32 size = set->componentFilePtrs.codeSize;
|
u32 size = set->componentFilePtrs.codeSize;
|
||||||
u8 *buffer = malloc(size);
|
u8 *buffer = malloc(size);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
fprintf(stderr, "[ELF ERROR] Not enough memory\n");
|
fprintf(stderr, "[CODE ERROR] Not enough memory\n");
|
||||||
return MEM_ERROR;
|
return MEM_ERROR;
|
||||||
}
|
}
|
||||||
ReadFile64(buffer, size, 0, set->componentFilePtrs.code);
|
ReadFile64(buffer, size, 0, set->componentFilePtrs.code);
|
||||||
@@ -51,10 +51,14 @@ int ImportExeFsCodeBinaryFromFile(ncch_settings *set)
|
|||||||
if (!set->exefsSections.code.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
|
if (!set->exefsSections.code.buffer) { fprintf(stderr, "[ELF ERROR] Not enough memory\n"); return MEM_ERROR; }
|
||||||
ReadFile64(set->exefsSections.code.buffer, set->exefsSections.code.size, 0, set->componentFilePtrs.code);
|
ReadFile64(set->exefsSections.code.buffer, set->exefsSections.code.size, 0, set->componentFilePtrs.code);
|
||||||
if (set->options.CompressCode) {
|
if (set->options.CompressCode) {
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("[CODE] Compressing code... ");
|
||||||
u32 new_len;
|
u32 new_len;
|
||||||
set->exefsSections.code.buffer = BLZ_Code(buffer, size, &new_len, BLZ_NORMAL);
|
set->exefsSections.code.buffer = BLZ_Code(buffer, size, &new_len, BLZ_NORMAL);
|
||||||
set->exefsSections.code.size = new_len;
|
set->exefsSections.code.size = new_len;
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("Done!\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set->exefsSections.code.size = size;
|
set->exefsSections.code.size = size;
|
||||||
@@ -63,12 +67,12 @@ int ImportExeFsCodeBinaryFromFile(ncch_settings *set)
|
|||||||
|
|
||||||
size = set->componentFilePtrs.exhdrSize;
|
size = set->componentFilePtrs.exhdrSize;
|
||||||
if (size < sizeof(extended_hdr)) {
|
if (size < sizeof(extended_hdr)) {
|
||||||
fprintf(stderr, "[ELF ERROR] Exheader code info template is too small\n");
|
fprintf(stderr, "[CODE ERROR] Exheader code info template is too small\n");
|
||||||
return FAILED_TO_IMPORT_FILE;
|
return FAILED_TO_IMPORT_FILE;
|
||||||
}
|
}
|
||||||
extended_hdr *exhdr = malloc(size);
|
extended_hdr *exhdr = malloc(size);
|
||||||
if (!exhdr) {
|
if (!exhdr) {
|
||||||
fprintf(stderr, "[ELF ERROR] Not enough memory\n");
|
fprintf(stderr, "[CODE ERROR] Not enough memory\n");
|
||||||
return MEM_ERROR;
|
return MEM_ERROR;
|
||||||
}
|
}
|
||||||
ReadFile64(exhdr, size, 0, set->componentFilePtrs.exhdr);
|
ReadFile64(exhdr, size, 0, set->componentFilePtrs.exhdr);
|
||||||
@@ -245,10 +249,14 @@ int CreateExeFsCode(elf_context *elf, ncch_settings *set)
|
|||||||
|
|
||||||
/* Compressing If needed */
|
/* Compressing If needed */
|
||||||
if (set->options.CompressCode) {
|
if (set->options.CompressCode) {
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("[CODE] Compressing code... ");
|
||||||
u32 new_len;
|
u32 new_len;
|
||||||
set->exefsSections.code.buffer = BLZ_Code(code, size, &new_len, BLZ_NORMAL);
|
set->exefsSections.code.buffer = BLZ_Code(code, size, &new_len, BLZ_NORMAL);
|
||||||
set->exefsSections.code.size = new_len;
|
set->exefsSections.code.size = new_len;
|
||||||
free(code);
|
free(code);
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("Done!\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set->exefsSections.code.size = size;
|
set->exefsSections.code.size = size;
|
||||||
|
|||||||
+165
-122
@@ -2,31 +2,125 @@
|
|||||||
#include "dir.h"
|
#include "dir.h"
|
||||||
#include "utf.h"
|
#include "utf.h"
|
||||||
|
|
||||||
|
const fs_romfs_char FS_CURRENT_DIR_PATH = 0x2E;
|
||||||
|
const fs_romfs_char FS_PARENT_DIR_PATH[2] = { 0x2E,0x2E };
|
||||||
|
|
||||||
/* This is the FS interface for ROMFS generation */
|
/* This is the FS interface for ROMFS generation */
|
||||||
/* Tested working on Windows/Linux/OSX */
|
/* Tested working on Windows/Linux/OSX */
|
||||||
int fs_InitDir(u16 *path, u32 pathlen, fs_dir *dir);
|
int fs_InitDir(const fs_entry *entry, fs_dir *dir);
|
||||||
int fs_ManageDirSlot(fs_dir *dir);
|
int fs_ManageDirSlot(fs_dir *dir);
|
||||||
int fs_ManageFileSlot(fs_dir *dir);
|
int fs_ManageFileSlot(fs_dir *dir);
|
||||||
void fs_chdirUp(void);
|
void fs_chdirUp(void);
|
||||||
fs_entry* fs_GetEntry(fs_DIR *dp);
|
fs_entry* fs_GetEntry(const fs_char *parent_path, fs_DIR *dp);
|
||||||
void fs_FreeEntry(fs_entry *entry);
|
void fs_FreeEntry(fs_entry *entry);
|
||||||
bool fs_EntryIsDirNav(fs_entry *entry);
|
bool fs_EntryIsDirNav(fs_entry *entry);
|
||||||
int fs_AddDir(fs_entry *entry, fs_dir *dir);
|
int fs_AddDir(fs_entry *entry, fs_dir *dir);
|
||||||
int fs_AddFile(fs_entry *entry, fs_dir *dir);
|
int fs_AddFile(fs_entry *entry, fs_dir *dir);
|
||||||
|
|
||||||
int fs_RomFsStrLen(fs_romfs_char *str)
|
u32 fs_romfs_strlen(const fs_romfs_char *str)
|
||||||
{
|
{
|
||||||
int i;
|
u32 i;
|
||||||
for( i = 0; str[i] != 0x0; i++ );
|
for( i = 0; str[i] != 0x0; i++ );
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_InitDir(u16 *path, u32 pathlen, fs_dir *dir)
|
u32 fs_strlen(const fs_char *str)
|
||||||
{
|
{
|
||||||
dir->name_len = pathlen;
|
u32 i;
|
||||||
dir->name = calloc(dir->name_len+2,1);
|
for (i = 0; str[i] != 0x0; i++);
|
||||||
memcpy(dir->name,path,dir->name_len);
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* fs_fopen(fs_char *path)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return _wfopen(path, L"rb");
|
||||||
|
#else
|
||||||
|
return fopen(path, "rb");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 fs_fsize(fs_char *path)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return wGetFileSize64(path);
|
||||||
|
#else
|
||||||
|
return GetFileSize64(path);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_char* fs_AppendToPath(const fs_char *src, const fs_char *add)
|
||||||
|
{
|
||||||
|
u32 src_len, add_len;
|
||||||
|
fs_char *new_path;
|
||||||
|
|
||||||
|
src_len = fs_strlen(src);
|
||||||
|
add_len = fs_strlen(add);
|
||||||
|
new_path = calloc(src_len + add_len + 0x10, sizeof(fs_char));
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
_snwprintf(new_path, src_len + add_len + 0x10, L"%s%c%s", src, FS_PATH_SEPARATOR, add);
|
||||||
|
#else
|
||||||
|
snprintf(new_path, src_len + add_len + 0x10, "%s%c%s", src, FS_PATH_SEPARATOR, add);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return new_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_char* fs_CopyPath(const fs_char *src)
|
||||||
|
{
|
||||||
|
u32 src_len;
|
||||||
|
fs_char *new_path;
|
||||||
|
|
||||||
|
src_len = fs_strlen(src);
|
||||||
|
new_path = calloc(src_len + 0x10, sizeof(fs_char));
|
||||||
|
|
||||||
|
for (u32 i = 0; i < src_len; i++)
|
||||||
|
new_path[i] = src[i];
|
||||||
|
|
||||||
|
return new_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_romfs_char* fs_CopyRomfsName(const fs_romfs_char *src)
|
||||||
|
{
|
||||||
|
u32 src_len;
|
||||||
|
fs_romfs_char *new_path;
|
||||||
|
|
||||||
|
src_len = fs_strlen(src);
|
||||||
|
new_path = calloc(src_len + 0x10, sizeof(fs_romfs_char));
|
||||||
|
|
||||||
|
for (u32 i = 0; i < src_len; i++)
|
||||||
|
new_path[i] = src[i];
|
||||||
|
|
||||||
|
return new_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fs_fputs(FILE *out, const fs_char *str)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
wprintf(L"%s", str);
|
||||||
|
#else
|
||||||
|
printf("%s", str);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void fs_romfs_fputs(FILE *out, const fs_romfs_char *str)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
wprintf(L"%s", str);
|
||||||
|
#else
|
||||||
|
const char *name = (const char*)str;
|
||||||
|
for (u32 i = 0; i < fs_romfs_strlen(str)*2; i += 2)
|
||||||
|
putchar(name[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int fs_InitDir(const fs_entry *entry, fs_dir *dir)
|
||||||
|
{
|
||||||
|
dir->fs_path = fs_CopyPath(entry->fs_path);
|
||||||
|
|
||||||
|
dir->name_len = entry->name_len;
|
||||||
|
dir->name = fs_CopyRomfsName(entry->name);
|
||||||
|
|
||||||
dir->m_child = 10;
|
dir->m_child = 10;
|
||||||
dir->u_child = 0;
|
dir->u_child = 0;
|
||||||
@@ -65,16 +159,7 @@ int fs_ManageFileSlot(fs_dir *dir)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fs_chdirUp(void)
|
fs_entry* fs_GetEntry(const fs_char *parent_path, fs_DIR *dp)
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
fs_chdir(L"..");
|
|
||||||
#else
|
|
||||||
fs_chdir("..");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
fs_entry* fs_GetEntry(fs_DIR *dp)
|
|
||||||
{
|
{
|
||||||
// Directory structs
|
// Directory structs
|
||||||
struct fs_dirent *tmp_entry;
|
struct fs_dirent *tmp_entry;
|
||||||
@@ -99,9 +184,9 @@ fs_entry* fs_GetEntry(fs_DIR *dp)
|
|||||||
memset(entry,0,sizeof(fs_entry));
|
memset(entry,0,sizeof(fs_entry));
|
||||||
|
|
||||||
//Copy FS compatible Entry name
|
//Copy FS compatible Entry name
|
||||||
entry->fs_name = malloc(sizeof(fs_char)*(namlen+1));
|
fs_char *fs_name = calloc(sizeof(fs_char)*(namlen+1),1);
|
||||||
memset(entry->fs_name,0,sizeof(fs_char)*(namlen+1));
|
memcpy(fs_name,tmp_entry->d_name,sizeof(fs_char)*namlen);
|
||||||
memcpy(entry->fs_name,tmp_entry->d_name,sizeof(fs_char)*namlen);
|
entry->fs_path = fs_AppendToPath(parent_path, fs_name);
|
||||||
|
|
||||||
// Convert Entry name into RomFS u16 char (windows wchar_t, thanks Nintendo)
|
// Convert Entry name into RomFS u16 char (windows wchar_t, thanks Nintendo)
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
@@ -111,45 +196,41 @@ fs_entry* fs_GetEntry(fs_DIR *dp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
//printf("get dir entry from dir ptr to check if dir\n");
|
//printf("get dir entry from dir ptr to check if dir\n");
|
||||||
tmp_dptr = fs_opendir(entry->fs_name);
|
tmp_dptr = fs_opendir(entry->fs_path);
|
||||||
if(tmp_dptr)
|
if(tmp_dptr)
|
||||||
{
|
{
|
||||||
//printf("is dir\n");
|
//printf("is dir\n");
|
||||||
fs_closedir(tmp_dptr);
|
fs_closedir(tmp_dptr);
|
||||||
entry->IsDir = true;
|
entry->IsDir = true;
|
||||||
entry->size = 0;
|
entry->size = 0;
|
||||||
entry->fp = NULL;
|
|
||||||
}
|
}
|
||||||
else // Open file if it is a file
|
else // Open file if it is a file
|
||||||
{
|
{
|
||||||
entry->IsDir = false;
|
entry->IsDir = false;
|
||||||
#ifdef _WIN32
|
entry->size = fs_fsize(entry->fs_path);
|
||||||
entry->size = wGetFileSize64(entry->fs_name);
|
|
||||||
entry->fp = _wfopen(entry->fs_name,L"rb");
|
|
||||||
#else
|
|
||||||
entry->size = GetFileSize64(entry->fs_name);
|
|
||||||
entry->fp = fopen(entry->fs_name,"rb");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
//printf("fs_GetEntry() return\n");
|
|
||||||
|
// Don't bother returning current entry, if it is useless
|
||||||
|
if (fs_EntryIsDirNav(entry)) {
|
||||||
|
fs_FreeEntry(entry);
|
||||||
|
return fs_GetEntry(parent_path, dp);
|
||||||
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fs_FreeEntry(fs_entry *entry)
|
void fs_FreeEntry(fs_entry *entry)
|
||||||
{
|
{
|
||||||
free(entry->fs_name);
|
free(entry->fs_path);
|
||||||
free(entry->name);
|
free(entry->name);
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fs_EntryIsDirNav(fs_entry *entry)
|
bool fs_EntryIsDirNav(fs_entry *entry)
|
||||||
{
|
{
|
||||||
//memdump(stdout,"Entry RomFS Name: ",(u8*)entry->name,entry->name_len);
|
if(entry->name_len == sizeof(fs_romfs_char)*1 && memcmp(entry->name,&FS_CURRENT_DIR_PATH,sizeof(fs_romfs_char)*1) == 0)
|
||||||
const fs_romfs_char currentdir = 0x2E;
|
|
||||||
const fs_romfs_char upperdir[2] = {0x2E,0x2E};
|
|
||||||
if(entry->name_len == sizeof(fs_romfs_char)*1 && memcmp(entry->name,¤tdir,sizeof(fs_romfs_char)*1) == 0)
|
|
||||||
return true;
|
return true;
|
||||||
if(entry->name_len == sizeof(fs_romfs_char)*2 && memcmp(entry->name,upperdir,sizeof(fs_romfs_char)*2) == 0)
|
if(entry->name_len == sizeof(fs_romfs_char)*2 && memcmp(entry->name,FS_PARENT_DIR_PATH,sizeof(fs_romfs_char)*2) == 0)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -159,84 +240,70 @@ int fs_AddDir(fs_entry *entry, fs_dir *dir)
|
|||||||
{
|
{
|
||||||
fs_ManageDirSlot(dir);
|
fs_ManageDirSlot(dir);
|
||||||
u32 current_slot = dir->u_child;
|
u32 current_slot = dir->u_child;
|
||||||
|
|
||||||
dir->u_child++;
|
dir->u_child++;
|
||||||
return fs_OpenDir(entry->fs_name,entry->name,entry->name_len,&dir->child[current_slot]);
|
return fs_OpenDir(entry,&dir->child[current_slot]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_AddFile(fs_entry *entry, fs_dir *dir)
|
int fs_AddFile(fs_entry *entry, fs_dir *dir)
|
||||||
{
|
{
|
||||||
fs_ManageFileSlot(dir);
|
fs_ManageFileSlot(dir);
|
||||||
|
dir->file[dir->u_file].fs_path = fs_CopyPath(entry->fs_path);
|
||||||
dir->file[dir->u_file].name_len = entry->name_len;
|
dir->file[dir->u_file].name_len = entry->name_len;
|
||||||
dir->file[dir->u_file].name = malloc(entry->name_len+2);
|
dir->file[dir->u_file].name = fs_CopyRomfsName(entry->name);
|
||||||
memset(dir->file[dir->u_file].name,0,entry->name_len+2);
|
|
||||||
memcpy(dir->file[dir->u_file].name,entry->name,entry->name_len);
|
|
||||||
|
|
||||||
dir->file[dir->u_file].size = entry->size;
|
dir->file[dir->u_file].size = entry->size;
|
||||||
dir->file[dir->u_file].fp = entry->fp;
|
|
||||||
|
|
||||||
dir->u_file++;
|
dir->u_file++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_OpenDir(fs_char *fs_path, fs_romfs_char *path, u32 pathlen, fs_dir *dir)
|
int fs_OpenRootDir(const char *path, fs_dir *dir)
|
||||||
|
{
|
||||||
|
fs_entry *root = calloc(1, sizeof(fs_entry));
|
||||||
|
u32 nul;
|
||||||
|
|
||||||
|
root->IsDir = true;
|
||||||
|
root->size = 0;
|
||||||
|
|
||||||
|
str_u16_to_u16(&root->name, &root->name_len, ROMFS_EMPTY_PATH, 0);
|
||||||
|
#ifdef _WIN32
|
||||||
|
str_u8_to_u16(&root->fs_path, &nul, (u8*)path, strlen(path));
|
||||||
|
#else
|
||||||
|
str_u8_to_u8(&root->fs_path, &nul, (u8*)path, strlen(path));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int ret = fs_OpenDir(root, dir);
|
||||||
|
|
||||||
|
fs_FreeEntry(root);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fs_OpenDir(fs_entry *curr_dir_entry, fs_dir *dir)
|
||||||
{
|
{
|
||||||
//printf("init open dir\n");
|
//printf("init open dir\n");
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
fs_DIR *dp;
|
fs_DIR *dp;
|
||||||
fs_entry *entry;
|
fs_entry *entry;
|
||||||
|
|
||||||
|
//printf("do some more init\n");
|
||||||
|
fs_InitDir(curr_dir_entry, dir);
|
||||||
|
//wprintf(L" rec: \"%s\" (%d)\n",dir->name,dir->name_len);
|
||||||
|
|
||||||
//printf("check if path exists\n");
|
//printf("check if path exists\n");
|
||||||
dp = fs_opendir(fs_path);
|
dp = fs_opendir(dir->fs_path);
|
||||||
if(!dp)
|
if(!dp)
|
||||||
{
|
{
|
||||||
//wprintf(L"[!] Failed to open directory: \"%s\"\n",path);
|
wprintf(L"[!] Failed to open directory: \"%s\"\n",dir->fs_path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("do some more init\n");
|
|
||||||
fs_InitDir(path,pathlen,dir);
|
|
||||||
//wprintf(L" rec: \"%s\" (%d)\n",dir->name,dir->name_len);
|
|
||||||
|
|
||||||
//printf("chdir\n");
|
|
||||||
fs_chdir(fs_path);
|
|
||||||
|
|
||||||
//printf("read entries\n");
|
//printf("read entries\n");
|
||||||
while((entry = fs_GetEntry(dp)))
|
while((entry = fs_GetEntry(dir->fs_path, dp)) != NULL)
|
||||||
{
|
{
|
||||||
if(!entry)
|
ret = entry->IsDir? fs_AddDir(entry, dir) : fs_AddFile(entry, dir);
|
||||||
{
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(entry->IsDir)
|
|
||||||
{
|
|
||||||
//printf("Found Dir ");
|
|
||||||
if(!fs_EntryIsDirNav(entry))
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
//wprintf(L"is a dir: \"%s\" (%d)\n",entry->fs_name,entry->name_len);
|
|
||||||
#else
|
|
||||||
//printf("is a dir: \"%s\" (%d)\n",entry->fs_name,entry->name_len);
|
|
||||||
#endif
|
|
||||||
ret = fs_AddDir(entry,dir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//printf("Not wanted dir\n");
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
//wprintf(L"is a file: \"%s\" (%d)\n",entry->fs_name,entry->name_len);
|
|
||||||
#else
|
|
||||||
//printf("is a file: \"%s\" (%d)\n",entry->fs_name,entry->name_len);
|
|
||||||
#endif
|
|
||||||
ret = fs_AddFile(entry,dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("free entry\n");
|
//printf("free entry\n");
|
||||||
fs_FreeEntry(entry);
|
fs_FreeEntry(entry);
|
||||||
|
|
||||||
@@ -246,11 +313,7 @@ int fs_OpenDir(fs_char *fs_path, fs_romfs_char *path, u32 pathlen, fs_dir *dir)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//printf("close dir ptr\n");
|
|
||||||
fs_closedir(dp);
|
fs_closedir(dp);
|
||||||
//printf("return up dir\n");
|
|
||||||
fs_chdirUp();
|
|
||||||
//printf("return from fs_OpenDir();\n");
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,14 +323,11 @@ void fs_PrintDir(fs_dir *dir, u32 depth) // This is just for simple debugging, p
|
|||||||
for(u32 i = 0; i < depth; i++)
|
for(u32 i = 0; i < depth; i++)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
|
||||||
#ifdef _WIN32
|
if (depth > 0)
|
||||||
wprintf(L"%s\n",dir->name);
|
fs_romfs_fputs(stdout, dir->name);
|
||||||
#else
|
else
|
||||||
char *name = (char*)dir->name;
|
printf("romfs:");
|
||||||
for(u32 i = 0; i < dir->name_len; i+=2)
|
|
||||||
putchar(name[i]);
|
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
|
||||||
|
|
||||||
if(dir->u_file)
|
if(dir->u_file)
|
||||||
{
|
{
|
||||||
@@ -275,15 +335,8 @@ void fs_PrintDir(fs_dir *dir, u32 depth) // This is just for simple debugging, p
|
|||||||
{
|
{
|
||||||
for(u32 j = 0; j < depth+1; j++)
|
for(u32 j = 0; j < depth+1; j++)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
fs_romfs_fputs(stdout, dir->file[i].name);
|
||||||
#ifdef _WIN32
|
printf(" (0x%"PRIx64")\n", dir->file[i].size);
|
||||||
wprintf(L"%s (0x%lx)\n",dir->file[i].name,dir->file[i].size);
|
|
||||||
#else
|
|
||||||
name = (char*)dir->file[i].name;
|
|
||||||
for(u32 j = 0; j < dir->file[i].name_len; j+=2)
|
|
||||||
putchar(name[j]);
|
|
||||||
printf(" (0x%llx)\n",dir->file[i].size);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(dir->u_child)
|
if(dir->u_child)
|
||||||
@@ -298,6 +351,7 @@ void fs_FreeDir(fs_dir *dir)
|
|||||||
//printf("DIR!! free file names\n");
|
//printf("DIR!! free file names\n");
|
||||||
for(u32 i = 0; i < dir->u_file; i++)
|
for(u32 i = 0; i < dir->u_file; i++)
|
||||||
{
|
{
|
||||||
|
free(dir->file[i].fs_path);
|
||||||
free(dir->file[i].name);
|
free(dir->file[i].name);
|
||||||
}
|
}
|
||||||
//printf("free file struct\n");
|
//printf("free file struct\n");
|
||||||
@@ -307,22 +361,11 @@ void fs_FreeDir(fs_dir *dir)
|
|||||||
//printf("free dir names and\n");
|
//printf("free dir names and\n");
|
||||||
for(u32 i = 0; i < dir->u_child; i++)
|
for(u32 i = 0; i < dir->u_child; i++)
|
||||||
{
|
{
|
||||||
|
free(dir->child[i].fs_path);
|
||||||
free(dir->child[i].name);
|
free(dir->child[i].name);
|
||||||
fs_FreeDir(&dir->child[i]);
|
fs_FreeDir(&dir->child[i]);
|
||||||
}
|
}
|
||||||
//printf("free dir struct\n");
|
//printf("free dir struct\n");
|
||||||
free(dir->child);
|
free(dir->child);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void fs_FreeFiles(fs_dir *dir)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i < dir->u_file; i++)
|
|
||||||
{
|
|
||||||
if(dir->file[i].fp)
|
|
||||||
fclose(dir->file[i].fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(u32 i = 0; i < dir->u_child; i++)
|
|
||||||
fs_FreeFiles(&dir->child[i]);
|
|
||||||
}
|
}
|
||||||
+21
-7
@@ -9,6 +9,7 @@
|
|||||||
#define fs_chdir _wchdir
|
#define fs_chdir _wchdir
|
||||||
#define fs_opendir _wopendir
|
#define fs_opendir _wopendir
|
||||||
#define fs_closedir _wclosedir
|
#define fs_closedir _wclosedir
|
||||||
|
#define FS_PATH_SEPARATOR '\\'
|
||||||
#else
|
#else
|
||||||
#define fs_romfs_char u16
|
#define fs_romfs_char u16
|
||||||
#define fs_char char
|
#define fs_char char
|
||||||
@@ -18,29 +19,30 @@
|
|||||||
#define fs_chdir chdir
|
#define fs_chdir chdir
|
||||||
#define fs_opendir opendir
|
#define fs_opendir opendir
|
||||||
#define fs_closedir closedir
|
#define fs_closedir closedir
|
||||||
|
#define FS_PATH_SEPARATOR '/'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct fs_entry
|
struct fs_entry
|
||||||
{
|
{
|
||||||
bool IsDir;
|
bool IsDir;
|
||||||
fs_char *fs_name;
|
fs_char *fs_path;
|
||||||
fs_romfs_char *name;
|
fs_romfs_char *name;
|
||||||
u32 name_len;
|
u32 name_len;
|
||||||
u64 size;
|
u64 size;
|
||||||
FILE *fp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fs_file
|
struct fs_file
|
||||||
{
|
{
|
||||||
|
fs_char *fs_path;
|
||||||
fs_romfs_char *name;
|
fs_romfs_char *name;
|
||||||
u32 name_len;
|
u32 name_len;
|
||||||
u64 size;
|
u64 size;
|
||||||
FILE *fp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fs_dir
|
struct fs_dir
|
||||||
{
|
{
|
||||||
|
fs_char *fs_path;
|
||||||
fs_romfs_char *name;
|
fs_romfs_char *name;
|
||||||
u32 name_len;
|
u32 name_len;
|
||||||
|
|
||||||
@@ -57,9 +59,21 @@ typedef struct fs_entry fs_entry;
|
|||||||
typedef struct fs_file fs_file;
|
typedef struct fs_file fs_file;
|
||||||
typedef struct fs_dir fs_dir;
|
typedef struct fs_dir fs_dir;
|
||||||
|
|
||||||
int fs_RomFsStrLen(fs_romfs_char *str);
|
static const fs_romfs_char ROMFS_EMPTY_PATH[2] = { 0 };
|
||||||
|
static const fs_char FS_EMPTY_PATH[2] = { 0 };
|
||||||
|
|
||||||
int fs_OpenDir(fs_char *fs_path, fs_romfs_char *path, u32 pathlen, fs_dir *dir);
|
u32 fs_romfs_strlen(const fs_romfs_char *str);
|
||||||
|
u32 fs_strlen(const fs_char *str);
|
||||||
|
FILE* fs_fopen(fs_char *path);
|
||||||
|
u64 fs_fsize(fs_char *path);
|
||||||
|
|
||||||
|
fs_char* fs_AppendToPath(const fs_char *src, const fs_char *add);
|
||||||
|
fs_char* fs_CopyPath(const fs_char *src);
|
||||||
|
fs_romfs_char* fs_CopyRomfsName(const fs_romfs_char *src);
|
||||||
|
void fs_fputs(FILE *out, const fs_char *str);
|
||||||
|
void fs_romfs_fputs(FILE *out, const fs_romfs_char *str);
|
||||||
|
|
||||||
|
int fs_OpenRootDir(const char *path, fs_dir *dir);
|
||||||
|
int fs_OpenDir(fs_entry *entry, fs_dir *dir);
|
||||||
void fs_PrintDir(fs_dir *dir, u32 depth);
|
void fs_PrintDir(fs_dir *dir, u32 depth);
|
||||||
void fs_FreeDir(fs_dir *dir);
|
void fs_FreeDir(fs_dir *dir);
|
||||||
void fs_FreeFiles(fs_dir *dir);
|
|
||||||
+17
-2
@@ -536,12 +536,19 @@ int FinaliseNcch(ncch_settings *set)
|
|||||||
|
|
||||||
// Crypting Exheader/AcexDesc
|
// Crypting Exheader/AcexDesc
|
||||||
if(set->cryptoDetails.exhdrSize){
|
if(set->cryptoDetails.exhdrSize){
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("[NCCH] Encypting Exheader... ");
|
||||||
CryptNcchRegion(exhdr,set->cryptoDetails.exhdrSize,0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exhdr);
|
CryptNcchRegion(exhdr,set->cryptoDetails.exhdrSize,0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exhdr);
|
||||||
CryptNcchRegion(acexDesc,set->cryptoDetails.acexSize,set->cryptoDetails.exhdrSize,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exhdr);
|
CryptNcchRegion(acexDesc,set->cryptoDetails.acexSize,set->cryptoDetails.exhdrSize,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exhdr);
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("Done!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crypting ExeFs Files
|
// Crypting ExeFs Files
|
||||||
if(set->cryptoDetails.exefsSize){
|
if(set->cryptoDetails.exefsSize){
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("[NCCH] Encrypting ExeFS... ");
|
||||||
|
|
||||||
exefs_hdr *exefsHdr = (exefs_hdr*)exefs;
|
exefs_hdr *exefsHdr = (exefs_hdr*)exefs;
|
||||||
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
for(int i = 0; i < MAX_EXEFS_SECTIONS; i++){
|
||||||
u8 *key = NULL;
|
u8 *key = NULL;
|
||||||
@@ -559,11 +566,19 @@ int FinaliseNcch(ncch_settings *set)
|
|||||||
}
|
}
|
||||||
// Crypting ExeFs Header
|
// Crypting ExeFs Header
|
||||||
CryptNcchRegion(exefs,sizeof(exefs_hdr),0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exefs);
|
CryptNcchRegion(exefs,sizeof(exefs_hdr),0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey0,ncch_exefs);
|
||||||
|
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("Done!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Crypting RomFs
|
// Crypting RomFs
|
||||||
if(set->cryptoDetails.romfsSize)
|
if (set->cryptoDetails.romfsSize) {
|
||||||
CryptNcchRegion(romfs,set->cryptoDetails.romfsSize,0x0,set->cryptoDetails.titleId,set->keys->aes.ncchKey1,ncch_romfs);
|
if (set->options.verbose)
|
||||||
|
printf("[NCCH] Encrypting RomFS... ");
|
||||||
|
CryptNcchRegion(romfs, set->cryptoDetails.romfsSize, 0x0, set->cryptoDetails.titleId, set->keys->aes.ncchKey1, ncch_romfs);
|
||||||
|
if (set->options.verbose)
|
||||||
|
printf("Done!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -615,6 +615,10 @@ int CheckRomConfig(cci_settings *set)
|
|||||||
|
|
||||||
void WriteCciDataToOutput(cci_settings *set)
|
void WriteCciDataToOutput(cci_settings *set)
|
||||||
{
|
{
|
||||||
|
if (set->options.verbose) {
|
||||||
|
printf("[CCI] Writing header to file... ");
|
||||||
|
}
|
||||||
|
|
||||||
// NCSD Header
|
// NCSD Header
|
||||||
WriteBuffer(set->headers.ccihdr.buffer, set->headers.ccihdr.size, 0, set->out);
|
WriteBuffer(set->headers.ccihdr.buffer, set->headers.ccihdr.size, 0, set->out);
|
||||||
// Card Info Header
|
// Card Info Header
|
||||||
@@ -629,18 +633,34 @@ void WriteCciDataToOutput(cci_settings *set)
|
|||||||
memset(dummy_data, 0xff, len);
|
memset(dummy_data, 0xff, len);
|
||||||
WriteBuffer(dummy_data, len, (set->headers.ccihdr.size + set->headers.cardinfohdr.size),set->out);
|
WriteBuffer(dummy_data, len, (set->headers.ccihdr.size + set->headers.cardinfohdr.size),set->out);
|
||||||
free(dummy_data);
|
free(dummy_data);
|
||||||
|
|
||||||
|
if (set->options.verbose) {
|
||||||
|
printf("Done!\n");
|
||||||
|
}
|
||||||
|
|
||||||
// NCCH Partitions
|
// NCCH Partitions
|
||||||
u8 *ncch;
|
u8 *ncch;
|
||||||
for(int i = 0; i < CCI_MAX_CONTENT; i++){
|
for(int i = 0; i < CCI_MAX_CONTENT; i++){
|
||||||
if(set->content.active[i]){
|
if(set->content.active[i]){
|
||||||
|
if (set->options.verbose) {
|
||||||
|
printf("[CCI] Writing content %d to file... ", i);
|
||||||
|
}
|
||||||
|
|
||||||
ncch = set->content.data + set->content.dOffset[i];
|
ncch = set->content.data + set->content.dOffset[i];
|
||||||
WriteBuffer(ncch, set->content.dSize[i], set->content.cOffset[i], set->out);
|
WriteBuffer(ncch, set->content.dSize[i], set->content.cOffset[i], set->out);
|
||||||
|
|
||||||
|
if (set->options.verbose) {
|
||||||
|
printf("Done!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cci Padding
|
// Cci Padding
|
||||||
if(set->options.padCci){
|
if(set->options.padCci){
|
||||||
|
if (set->options.verbose) {
|
||||||
|
printf("[CCI] Writing padding to file... ");
|
||||||
|
}
|
||||||
|
|
||||||
fseek_64(set->out,set->romInfo.usedSize);
|
fseek_64(set->out,set->romInfo.usedSize);
|
||||||
|
|
||||||
// Determining Size of Padding
|
// Determining Size of Padding
|
||||||
@@ -655,6 +675,10 @@ void WriteCciDataToOutput(cci_settings *set)
|
|||||||
fwrite(pad,set->romInfo.blockSize,1,set->out);
|
fwrite(pad,set->romInfo.blockSize,1,set->out);
|
||||||
|
|
||||||
free(pad);
|
free(pad);
|
||||||
|
|
||||||
|
if (set->options.verbose) {
|
||||||
|
printf("Done!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
-1
@@ -10,6 +10,7 @@ void FreeRomFsCtx(romfs_buildctx *ctx);
|
|||||||
// RomFs Build Functions
|
// RomFs Build Functions
|
||||||
int SetupRomFs(ncch_settings *ncchset, romfs_buildctx *ctx)
|
int SetupRomFs(ncch_settings *ncchset, romfs_buildctx *ctx)
|
||||||
{
|
{
|
||||||
|
ctx->verbose = ncchset->options.verbose;
|
||||||
ctx->output = NULL;
|
ctx->output = NULL;
|
||||||
ctx->romfsSize = 0;
|
ctx->romfsSize = 0;
|
||||||
|
|
||||||
@@ -46,7 +47,6 @@ int BuildRomFs(romfs_buildctx *ctx)
|
|||||||
void FreeRomFsCtx(romfs_buildctx *ctx)
|
void FreeRomFsCtx(romfs_buildctx *ctx)
|
||||||
{
|
{
|
||||||
if(ctx->fs){
|
if(ctx->fs){
|
||||||
fs_FreeFiles(ctx->fs);
|
|
||||||
fs_FreeDir(ctx->fs);
|
fs_FreeDir(ctx->fs);
|
||||||
free(ctx->fs);
|
free(ctx->fs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
bool verbose;
|
||||||
|
|
||||||
u8 *output;
|
u8 *output;
|
||||||
u64 romfsSize;
|
u64 romfsSize;
|
||||||
u64 romfsHeaderSize;
|
u64 romfsHeaderSize;
|
||||||
|
|||||||
+49
-78
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
const int ROMFS_BLOCK_SIZE = 0x1000;
|
const int ROMFS_BLOCK_SIZE = 0x1000;
|
||||||
const unsigned int ROMFS_UNUSED_ENTRY = 0xffffffff;
|
const unsigned int ROMFS_UNUSED_ENTRY = 0xffffffff;
|
||||||
const fs_romfs_char ROMFS_EMPTY_PATH[2] = {0x0000, 0x0000};
|
|
||||||
|
|
||||||
// Build
|
// Build
|
||||||
bool IsFileWanted(fs_file *file, void *filter_criteria);
|
bool IsFileWanted(fs_file *file, void *filter_criteria);
|
||||||
@@ -21,60 +20,39 @@ void PopulateRomfs(romfs_buildctx *ctx);
|
|||||||
void BuildRomfsHeader(romfs_buildctx *ctx);
|
void BuildRomfsHeader(romfs_buildctx *ctx);
|
||||||
void BuildIvfcHeader(romfs_buildctx *ctx);
|
void BuildIvfcHeader(romfs_buildctx *ctx);
|
||||||
void GenIvfcHashTree(romfs_buildctx *ctx);
|
void GenIvfcHashTree(romfs_buildctx *ctx);
|
||||||
u32 CalcPathHash(u32 parent, fs_romfs_char* path, u32 start, u32 length);
|
u32 CalcPathHash(u32 parent, const fs_romfs_char* path, u32 start, u32 length);
|
||||||
|
|
||||||
|
|
||||||
int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx)
|
int PrepareBuildRomFsBinary(ncch_settings *ncchset, romfs_buildctx *ctx)
|
||||||
{
|
{
|
||||||
/* Input Path */
|
|
||||||
const int CWD_MAX_LEN = 1024;
|
|
||||||
char *cwd = calloc(CWD_MAX_LEN,sizeof(char));
|
|
||||||
getcwd(cwd,CWD_MAX_LEN);
|
|
||||||
|
|
||||||
char *dir = ncchset->rsfSet->RomFs.RootPath;
|
|
||||||
|
|
||||||
fs_char *fs_path;
|
|
||||||
fs_romfs_char *path;
|
|
||||||
u32 path_len;
|
|
||||||
#ifdef _WIN32
|
|
||||||
str_u8_to_u16(&path,&path_len,(u8*)dir,strlen(dir));
|
|
||||||
fs_path = path;
|
|
||||||
#else
|
|
||||||
str_utf8_to_u16(&path,&path_len,(u8*)dir,strlen(dir));
|
|
||||||
fs_path = dir;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* FS Structures */
|
/* FS Structures */
|
||||||
void *filter_criteria = NULL;
|
void *filter_criteria = NULL;
|
||||||
fs_dir *fs_raw = calloc(1,sizeof(fs_dir));
|
fs_dir *fs_raw = calloc(1,sizeof(fs_dir));
|
||||||
ctx->fs = calloc(1,sizeof(fs_dir));
|
ctx->fs = calloc(1,sizeof(fs_dir));
|
||||||
|
|
||||||
/* Import FS and process */
|
/* Import FS and process */
|
||||||
fs_OpenDir(fs_path,path,path_len,fs_raw);
|
fs_OpenRootDir(ncchset->rsfSet->RomFs.RootPath,fs_raw);
|
||||||
FilterRomFS(fs_raw,ctx->fs,filter_criteria);
|
FilterRomFS(fs_raw,ctx->fs,filter_criteria);
|
||||||
|
|
||||||
/* free unfiltered FS */
|
/* free unfiltered FS */
|
||||||
fs_FreeFiles(fs_raw); // All important FPs have been moved with FilterRomFS, so only un-wanted FPs are closed here
|
|
||||||
fs_FreeDir(fs_raw);
|
fs_FreeDir(fs_raw);
|
||||||
free(fs_raw);
|
free(fs_raw);
|
||||||
|
|
||||||
/* Abort romfs making, if no wanted files/directories were found */
|
/* Abort romfs making, if no wanted files/directories were found */
|
||||||
if(ctx->fs->u_file == 0 && ctx->fs->u_child == 0){
|
if(ctx->fs->u_file == 0 && ctx->fs->u_child == 0){
|
||||||
ctx->romfsSize = 0;
|
ctx->romfsSize = 0;
|
||||||
goto finish;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Print Filtered FS */
|
|
||||||
if(ncchset->options.verbose){
|
|
||||||
printf("[ROMFS] File System:\n");
|
|
||||||
fs_PrintDir(ctx->fs,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CalcRomfsSize(ctx);
|
CalcRomfsSize(ctx);
|
||||||
|
|
||||||
finish:
|
if (ctx->verbose) {
|
||||||
chdir(cwd);
|
printf("[ROMFS] File System:\n");
|
||||||
|
printf(" > Size: %"PRIx64"\n", ctx->romfsSize);
|
||||||
|
printf(" > Directories: %d\n", ctx->dirNum);
|
||||||
|
printf(" > Files: %d\n", ctx->fileNum);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,9 +186,10 @@ int FilterRomFS(fs_dir *fs_raw, fs_dir *fs_filtered, void *filter_criteria)
|
|||||||
if(!IsDirWanted(fs_raw,filter_criteria))
|
if(!IsDirWanted(fs_raw,filter_criteria))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fs_filtered->fs_path = fs_CopyPath(fs_raw->fs_path);
|
||||||
|
|
||||||
fs_filtered->name_len = fs_raw->name_len;
|
fs_filtered->name_len = fs_raw->name_len;
|
||||||
fs_filtered->name = calloc(fs_filtered->name_len+2,1);
|
fs_filtered->name = fs_CopyRomfsName(fs_raw->name);
|
||||||
memcpy(fs_filtered->name,fs_raw->name,fs_filtered->name_len);
|
|
||||||
|
|
||||||
fs_filtered->u_child = 0;
|
fs_filtered->u_child = 0;
|
||||||
fs_filtered->m_child = fs_raw->u_child;
|
fs_filtered->m_child = fs_raw->u_child;
|
||||||
@@ -233,16 +212,13 @@ int FilterRomFS(fs_dir *fs_raw, fs_dir *fs_filtered, void *filter_criteria)
|
|||||||
{
|
{
|
||||||
if(IsFileWanted(&fs_raw->file[i],filter_criteria))
|
if(IsFileWanted(&fs_raw->file[i],filter_criteria))
|
||||||
{
|
{
|
||||||
|
fs_filtered->file[fs_filtered->u_file].fs_path = fs_CopyPath(fs_raw->file[i].fs_path);
|
||||||
|
|
||||||
fs_filtered->file[fs_filtered->u_file].name_len = fs_raw->file[i].name_len;
|
fs_filtered->file[fs_filtered->u_file].name_len = fs_raw->file[i].name_len;
|
||||||
fs_filtered->file[fs_filtered->u_file].name = malloc(fs_filtered->file[fs_filtered->u_file].name_len+2);
|
fs_filtered->file[fs_filtered->u_file].name = fs_CopyRomfsName(fs_raw->file[i].name);
|
||||||
memset(fs_filtered->file[fs_filtered->u_file].name,0,fs_filtered->file[fs_filtered->u_file].name_len+2);
|
|
||||||
memcpy(fs_filtered->file[fs_filtered->u_file].name,fs_raw->file[i].name,fs_filtered->file[fs_filtered->u_file].name_len);
|
|
||||||
|
|
||||||
fs_filtered->file[fs_filtered->u_file].size = fs_raw->file[i].size;
|
fs_filtered->file[fs_filtered->u_file].size = fs_raw->file[i].size;
|
||||||
|
|
||||||
fs_filtered->file[fs_filtered->u_file].fp = fs_raw->file[i].fp;
|
|
||||||
fs_raw->file[i].fp = NULL;
|
|
||||||
|
|
||||||
fs_filtered->u_file++;
|
fs_filtered->u_file++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,15 +277,15 @@ void BuildRomfsHeader(romfs_buildctx *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetFileHashTableIndex(romfs_buildctx *ctx, u32 parent, fs_romfs_char *path)
|
u32 GetFileHashTableIndex(romfs_buildctx *ctx, u32 parent, const fs_romfs_char *path)
|
||||||
{
|
{
|
||||||
u32 hash = CalcPathHash(parent, path, 0, fs_RomFsStrLen(path));
|
u32 hash = CalcPathHash(parent, path, 0, fs_romfs_strlen(path));
|
||||||
return hash % ctx->m_fileHashTable;
|
return hash % ctx->m_fileHashTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetDirHashTableIndex(romfs_buildctx *ctx, u32 parent, fs_romfs_char* path)
|
u32 GetDirHashTableIndex(romfs_buildctx *ctx, u32 parent, const fs_romfs_char* path)
|
||||||
{
|
{
|
||||||
u32 hash = CalcPathHash(parent, path, 0, fs_RomFsStrLen(path));
|
u32 hash = CalcPathHash(parent, path, 0, fs_romfs_strlen(path));
|
||||||
return hash % ctx->m_dirHashTable;
|
return hash % ctx->m_dirHashTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +314,21 @@ void AddFileToRomfs(romfs_buildctx *ctx, fs_file *file, u32 parent, u32 sibling)
|
|||||||
u64_to_u8(entry->dataoffset,ctx->u_dataLen,LE);
|
u64_to_u8(entry->dataoffset,ctx->u_dataLen,LE);
|
||||||
u64_to_u8(entry->datasize,file->size,LE);
|
u64_to_u8(entry->datasize,file->size,LE);
|
||||||
u8 *data_pos = (ctx->data + ctx->u_dataLen);
|
u8 *data_pos = (ctx->data + ctx->u_dataLen);
|
||||||
ReadFile64(data_pos,file->size,0,file->fp);
|
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("[ROMFS] Reading \"");
|
||||||
|
fs_fputs(stdout, file->fs_path);
|
||||||
|
printf("\"... ");
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fs_fopen(file->fs_path);
|
||||||
|
fread(data_pos, file->size, 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (ctx->verbose) {
|
||||||
|
printf("Done!\n");
|
||||||
|
}
|
||||||
|
|
||||||
ctx->u_dataLen += file->size; // adding file size
|
ctx->u_dataLen += file->size; // adding file size
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -351,7 +341,6 @@ void AddFileToRomfs(romfs_buildctx *ctx, fs_file *file, u32 parent, u32 sibling)
|
|||||||
void AddDirToRomfs(romfs_buildctx *ctx, fs_dir *fs, u32 parent, u32 sibling)
|
void AddDirToRomfs(romfs_buildctx *ctx, fs_dir *fs, u32 parent, u32 sibling)
|
||||||
{
|
{
|
||||||
u32 offset = ctx->u_dirTableLen;
|
u32 offset = ctx->u_dirTableLen;
|
||||||
u32 hashindex;
|
|
||||||
romfs_direntry *entry = (romfs_direntry*)(ctx->dirTable + offset);
|
romfs_direntry *entry = (romfs_direntry*)(ctx->dirTable + offset);
|
||||||
|
|
||||||
/* Set entry data */
|
/* Set entry data */
|
||||||
@@ -360,37 +349,19 @@ void AddDirToRomfs(romfs_buildctx *ctx, fs_dir *fs, u32 parent, u32 sibling)
|
|||||||
u32_to_u8(entry->childoffset, ROMFS_UNUSED_ENTRY, LE);
|
u32_to_u8(entry->childoffset, ROMFS_UNUSED_ENTRY, LE);
|
||||||
u32_to_u8(entry->fileoffset, ROMFS_UNUSED_ENTRY, LE);
|
u32_to_u8(entry->fileoffset, ROMFS_UNUSED_ENTRY, LE);
|
||||||
|
|
||||||
|
/* Import name */
|
||||||
/* If root dir ... */
|
u32_to_u8(entry->namesize,fs->name_len,LE);
|
||||||
if(offset == 0)
|
u8 *name_pos = (u8*)(ctx->dirTable + ctx->u_dirTableLen + sizeof(romfs_direntry));
|
||||||
{
|
memset(name_pos,0,(u32)align(fs->name_len,4));
|
||||||
/* Import name (root dir has no name) */
|
memcpy(name_pos,(u8*)fs->name,fs->name_len);
|
||||||
u32_to_u8(entry->namesize,0,LE);
|
|
||||||
|
|
||||||
/* Get hash table index */
|
|
||||||
hashindex = GetDirHashTableIndex(ctx, parent, (fs_romfs_char*)ROMFS_EMPTY_PATH);
|
|
||||||
|
|
||||||
/* Increment used dir table length */
|
|
||||||
ctx->u_dirTableLen += sizeof(romfs_direntry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Import name */
|
|
||||||
u32_to_u8(entry->namesize,fs->name_len,LE);
|
|
||||||
u8 *name_pos = (u8*)(ctx->dirTable + ctx->u_dirTableLen + sizeof(romfs_direntry));
|
|
||||||
memset(name_pos,0,(u32)align(fs->name_len,4));
|
|
||||||
memcpy(name_pos,(u8*)fs->name,fs->name_len);
|
|
||||||
|
|
||||||
/* Get hash table index */
|
|
||||||
hashindex = GetDirHashTableIndex(ctx, parent, fs->name);
|
|
||||||
|
|
||||||
/* Increment used dir table length */
|
|
||||||
ctx->u_dirTableLen += sizeof(romfs_direntry) + (u32)align(fs->name_len,4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set hash data */
|
/* Set hash data */
|
||||||
u32_to_u8(entry->hashoffset, u8_to_u32(ctx->dirHashTable + hashindex*4, LE), LE);
|
u32 hashindex = GetDirHashTableIndex(ctx, parent, fs->name);
|
||||||
u32_to_u8(ctx->dirHashTable + hashindex*4, offset, LE);
|
u32_to_u8(entry->hashoffset, u8_to_u32(ctx->dirHashTable + hashindex * 4, LE), LE);
|
||||||
|
u32_to_u8(ctx->dirHashTable + hashindex * 4, offset, LE);
|
||||||
|
|
||||||
|
/* Increment used dir table length */
|
||||||
|
ctx->u_dirTableLen += sizeof(romfs_direntry) + (u32)align(fs->name_len,4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddDirChildrenToRomfs(romfs_buildctx *ctx, fs_dir *fs, u32 parent, u32 dir)
|
void AddDirChildrenToRomfs(romfs_buildctx *ctx, fs_dir *fs, u32 parent, u32 dir)
|
||||||
@@ -425,10 +396,10 @@ void AddDirChildrenToRomfs(romfs_buildctx *ctx, fs_dir *fs, u32 parent, u32 dir)
|
|||||||
u32_to_u8(entry->childoffset, ctx->u_dirTableLen, LE);
|
u32_to_u8(entry->childoffset, ctx->u_dirTableLen, LE);
|
||||||
for (u32 i = 0; i < fs->u_child; i++)
|
for (u32 i = 0; i < fs->u_child; i++)
|
||||||
{
|
{
|
||||||
/* Store address fo child */
|
/* Store address for child */
|
||||||
childs[i] = ctx->u_dirTableLen;
|
childs[i] = ctx->u_dirTableLen;
|
||||||
|
|
||||||
|
/* If is the last child directory, no more siblings */
|
||||||
u32 dir_sibling = 0;
|
u32 dir_sibling = 0;
|
||||||
if (i >= fs->u_child - 1)
|
if (i >= fs->u_child - 1)
|
||||||
dir_sibling = ROMFS_UNUSED_ENTRY;
|
dir_sibling = ROMFS_UNUSED_ENTRY;
|
||||||
@@ -488,7 +459,7 @@ void GenIvfcHashTree(romfs_buildctx *ctx)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CalcPathHash(u32 parent, fs_romfs_char* path, u32 start, u32 length)
|
u32 CalcPathHash(u32 parent, const fs_romfs_char* path, u32 start, u32 length)
|
||||||
{
|
{
|
||||||
u32 hash = parent ^ 123456789;
|
u32 hash = parent ^ 123456789;
|
||||||
for( u32 index = 0; index < length; index++ )
|
for( u32 index = 0; index < length; index++ )
|
||||||
|
|||||||
+9
-5
@@ -2,6 +2,7 @@
|
|||||||
#include "ncch_read.h"
|
#include "ncch_read.h"
|
||||||
#include "titleid.h"
|
#include "titleid.h"
|
||||||
|
|
||||||
|
const u16 DEFAULT_CATEGORY = PROGRAM_ID_CATEGORY_APPLICATION;
|
||||||
const u32 DEFAULT_UNIQUE_ID = 0xff3ff;
|
const u32 DEFAULT_UNIQUE_ID = 0xff3ff;
|
||||||
|
|
||||||
void SetPIDType(u16 *type);
|
void SetPIDType(u16 *type);
|
||||||
@@ -28,7 +29,7 @@ u32 GetTidUniqueId(u64 titleId)
|
|||||||
|
|
||||||
int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader)
|
int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
u32 uniqueId;
|
u32 uniqueId;
|
||||||
u16 type,category;
|
u16 type,category;
|
||||||
u8 variation;
|
u8 variation;
|
||||||
@@ -42,12 +43,15 @@ int GetProgramID(u64 *dest, rsf_settings *rsf, bool IsForExheader)
|
|||||||
SetPIDType(&type);
|
SetPIDType(&type);
|
||||||
|
|
||||||
// Getting Category
|
// Getting Category
|
||||||
if(rsf->TitleInfo.Category)
|
|
||||||
ret = SetPIDCategoryFromName(&category,rsf->TitleInfo.Category);
|
|
||||||
else if(rsf->TitleInfo.CategoryFlags)
|
|
||||||
ret = SetPIDCategoryFromFlags(&category,rsf->TitleInfo.CategoryFlags,rsf->TitleInfo.CategoryFlagsNum);
|
|
||||||
if(IsForExheader && rsf->TitleInfo.TargetCategory)
|
if(IsForExheader && rsf->TitleInfo.TargetCategory)
|
||||||
ret = SetPIDCategoryFromName(&category,rsf->TitleInfo.TargetCategory);
|
ret = SetPIDCategoryFromName(&category,rsf->TitleInfo.TargetCategory);
|
||||||
|
else if (rsf->TitleInfo.Category)
|
||||||
|
ret = SetPIDCategoryFromName(&category, rsf->TitleInfo.Category);
|
||||||
|
else if (rsf->TitleInfo.CategoryFlags)
|
||||||
|
ret = SetPIDCategoryFromFlags(&category, rsf->TitleInfo.CategoryFlags, rsf->TitleInfo.CategoryFlagsNum);
|
||||||
|
else
|
||||||
|
category = DEFAULT_CATEGORY;
|
||||||
|
|
||||||
if(ret == PID_INVALID_CATEGORY) // Error occured
|
if(ret == PID_INVALID_CATEGORY) // Error occured
|
||||||
return PID_BAD_RSF_SET;
|
return PID_BAD_RSF_SET;
|
||||||
|
|
||||||
|
|||||||
+20
-23
@@ -6,6 +6,7 @@ void DisplayExtendedHelp(char *app_name);
|
|||||||
void SetDefaults(user_settings *set);
|
void SetDefaults(user_settings *set);
|
||||||
int SetArgument(int argc, int i, char *argv[], user_settings *set);
|
int SetArgument(int argc, int i, char *argv[], user_settings *set);
|
||||||
int CheckArgumentCombination(user_settings *set);
|
int CheckArgumentCombination(user_settings *set);
|
||||||
|
const char* GetOutputExtention(u8 file_type);
|
||||||
void PrintNeedsArg(char *arg);
|
void PrintNeedsArg(char *arg);
|
||||||
void PrintArgInvalid(char *arg);
|
void PrintArgInvalid(char *arg);
|
||||||
void PrintArgReqParam(char *arg, u32 paramNum);
|
void PrintArgReqParam(char *arg, u32 paramNum);
|
||||||
@@ -75,14 +76,7 @@ int ParseArgs(int argc, char *argv[], user_settings *set)
|
|||||||
source_path = set->common.workingFilePath;
|
source_path = set->common.workingFilePath;
|
||||||
else
|
else
|
||||||
source_path = set->common.contentPath[0];
|
source_path = set->common.contentPath[0];
|
||||||
u16 outfile_len = strlen(source_path) + 0x10;
|
set->common.outFileName = replace_filextention(source_path, GetOutputExtention(set->common.outFormat));
|
||||||
set->common.outFileName = calloc(outfile_len, sizeof(char));
|
|
||||||
if (!set->common.outFileName) {
|
|
||||||
fprintf(stderr, "[SETTING ERROR] Not Enough Memory\n");
|
|
||||||
return USR_MEM_ERROR;
|
|
||||||
}
|
|
||||||
set->common.outFileName_mallocd = true;
|
|
||||||
append_filextention(set->common.outFileName, outfile_len, source_path, (char*)&output_extention[set->common.outFormat - 1]);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -95,7 +89,7 @@ void SetDefaults(user_settings *set)
|
|||||||
|
|
||||||
// Build NCCH Info
|
// Build NCCH Info
|
||||||
set->ncch.useSecCrypto = false;
|
set->ncch.useSecCrypto = false;
|
||||||
set->ncch.buildNcch0 = false;
|
set->ncch.buildNcch0 = true;
|
||||||
set->ncch.includeExefsLogo = false;
|
set->ncch.includeExefsLogo = false;
|
||||||
set->common.outFormat = NCCH;
|
set->common.outFormat = NCCH;
|
||||||
set->ncch.ncchType = format_not_set;
|
set->ncch.ncchType = format_not_set;
|
||||||
@@ -704,22 +698,18 @@ int SetArgument(int argc, int i, char *argv[], user_settings *set)
|
|||||||
|
|
||||||
int CheckArgumentCombination(user_settings *set)
|
int CheckArgumentCombination(user_settings *set)
|
||||||
{
|
{
|
||||||
if (set->ncch.ncchType & (CXI | CFA)) {
|
if (set->common.contentPath[0] == NULL) {
|
||||||
set->ncch.buildNcch0 = true;
|
set->ncch.buildNcch0 = true;
|
||||||
if (set->ncch.ncchType & CXI)
|
if (set->ncch.ncchType & CXI)
|
||||||
set->ncch.ncchType = CXI;
|
set->ncch.ncchType = CXI;
|
||||||
else
|
else
|
||||||
set->ncch.ncchType = CFA;
|
set->ncch.ncchType = CFA;
|
||||||
}
|
|
||||||
|
|
||||||
if (set->common.outFormat == NCCH) {
|
if (set->common.outFormat == NCCH)
|
||||||
set->ncch.buildNcch0 = true;
|
|
||||||
if (set->ncch.ncchType)
|
|
||||||
set->common.outFormat = set->ncch.ncchType;
|
set->common.outFormat = set->ncch.ncchType;
|
||||||
else {
|
}
|
||||||
set->ncch.ncchType = CFA;
|
else {
|
||||||
set->common.outFormat = CFA;
|
set->ncch.buildNcch0 = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < CIA_MAX_CONTENT; i++) {
|
for (int i = 0; i < CIA_MAX_CONTENT; i++) {
|
||||||
@@ -733,11 +723,6 @@ int CheckArgumentCombination(user_settings *set)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set->common.contentPath[0] && set->ncch.buildNcch0) {
|
|
||||||
fprintf(stderr, "[SETTING ERROR] You cannot both import and build content 0\n");
|
|
||||||
return USR_BAD_ARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (set->common.outFormat == CIA && set->cci.cverDataPath) {
|
if (set->common.outFormat == CIA && set->cci.cverDataPath) {
|
||||||
fprintf(stderr, "[SETTING ERROR] You cannot use argument \"-cverinfo\" when generating a CIA\n");
|
fprintf(stderr, "[SETTING ERROR] You cannot use argument \"-cverinfo\" when generating a CIA\n");
|
||||||
return USR_BAD_ARG;
|
return USR_BAD_ARG;
|
||||||
@@ -808,6 +793,18 @@ int CheckArgumentCombination(user_settings *set)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* GetOutputExtention(u8 file_type)
|
||||||
|
{
|
||||||
|
switch (file_type) {
|
||||||
|
case(NCCH) : return ".app";
|
||||||
|
case(CXI) : return ".cxi";
|
||||||
|
case(CFA) : return ".cfa";
|
||||||
|
case(CIA) : return ".cia";
|
||||||
|
case(CCI) : return ".cci";
|
||||||
|
default: return ".bin";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void init_UserSettings(user_settings *set)
|
void init_UserSettings(user_settings *set)
|
||||||
{
|
{
|
||||||
memset(set, 0, sizeof(user_settings));
|
memset(set, 0, sizeof(user_settings));
|
||||||
|
|||||||
+22
-22
@@ -53,27 +53,27 @@ u64 max64(u64 a, u64 b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
int append_filextention(char *output, u16 max_outlen, char *input, char extention[])
|
char* replace_filextention(const char *input, const char *new_ext)
|
||||||
{
|
{
|
||||||
if(output == NULL || input == NULL){
|
if(input == NULL || new_ext == NULL)
|
||||||
printf("[!] Memory Error\n");
|
return NULL;
|
||||||
return Fail;
|
|
||||||
|
char *new_name;
|
||||||
|
char *ext = strrchr(input, '.');
|
||||||
|
|
||||||
|
// If there is no existing extention, just append new_ext
|
||||||
|
if (!ext) {
|
||||||
|
new_name = calloc(strlen(input) + strlen(new_ext), 1);
|
||||||
|
sprintf(new_name, "%s%s", input, new_ext);
|
||||||
}
|
}
|
||||||
memset(output,0,max_outlen);
|
else {
|
||||||
u16 extention_point = strlen(input)+1;
|
u32 size = ext - input;
|
||||||
for(int i = strlen(input)-1; i > 0; i--){
|
new_name = calloc(size + strlen(new_ext), 1);
|
||||||
if(input[i] == '.'){
|
snprintf(new_name, size, "%s", input);
|
||||||
extention_point = i;
|
sprintf(new_name, "%s%s", new_name, new_ext);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(extention_point+strlen(extention) >= max_outlen){
|
|
||||||
printf("[!] Input File Name Too Large for Output buffer\n");
|
return new_name;
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
memcpy(output,input,extention_point);
|
|
||||||
sprintf(output,"%s%s",output,extention);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void memdump(FILE* fout, const char* prefix, const u8* data, u32 size)
|
void memdump(FILE* fout, const char* prefix, const u8* data, u32 size)
|
||||||
@@ -104,7 +104,7 @@ void memdump(FILE* fout, const char* prefix, const u8* data, u32 size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int str_u8_to_u16(u16 **dst, u32 *dst_len, u8 *src, u32 src_len)
|
int str_u8_to_u16(u16 **dst, u32 *dst_len, const u8 *src, u32 src_len)
|
||||||
{
|
{
|
||||||
*dst_len = src_len*sizeof(u16);
|
*dst_len = src_len*sizeof(u16);
|
||||||
*dst = malloc((*dst_len)+sizeof(u16));
|
*dst = malloc((*dst_len)+sizeof(u16));
|
||||||
@@ -117,7 +117,7 @@ int str_u8_to_u16(u16 **dst, u32 *dst_len, u8 *src, u32 src_len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int str_u16_to_u16(u16 **dst, u32 *dst_len, u16 *src, u32 src_len)
|
int str_u16_to_u16(u16 **dst, u32 *dst_len, const u16 *src, u32 src_len)
|
||||||
{
|
{
|
||||||
*dst_len = src_len*sizeof(u16);
|
*dst_len = src_len*sizeof(u16);
|
||||||
*dst = malloc((*dst_len)+sizeof(u16));
|
*dst = malloc((*dst_len)+sizeof(u16));
|
||||||
@@ -130,7 +130,7 @@ int str_u16_to_u16(u16 **dst, u32 *dst_len, u16 *src, u32 src_len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int str_u32_to_u16(u16 **dst, u32 *dst_len, u32 *src, u32 src_len)
|
int str_u32_to_u16(u16 **dst, u32 *dst_len, const u32 *src, u32 src_len)
|
||||||
{
|
{
|
||||||
*dst_len = src_len*sizeof(u16);
|
*dst_len = src_len*sizeof(u16);
|
||||||
*dst = malloc((*dst_len)+sizeof(u16));
|
*dst = malloc((*dst_len)+sizeof(u16));
|
||||||
@@ -144,7 +144,7 @@ int str_u32_to_u16(u16 **dst, u32 *dst_len, u32 *src, u32 src_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int str_utf8_to_u16(u16 **dst, u32 *dst_len, u8 *src, u32 src_len)
|
int str_utf8_to_u16(u16 **dst, u32 *dst_len, const u8 *src, u32 src_len)
|
||||||
{
|
{
|
||||||
*dst_len = src_len*sizeof(u16);
|
*dst_len = src_len*sizeof(u16);
|
||||||
*dst = malloc((*dst_len)+sizeof(u16));
|
*dst = malloc((*dst_len)+sizeof(u16));
|
||||||
|
|||||||
+6
-6
@@ -18,13 +18,13 @@ u64 min64(u64 a, u64 b);
|
|||||||
u64 max64(u64 a, u64 b);
|
u64 max64(u64 a, u64 b);
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
void memdump(FILE* fout, const char* prefix, const u8* data, u32 size);
|
void memdump(FILE* fout, const char* prefix, const const u8* data, u32 size);
|
||||||
int append_filextention(char *output, u16 max_outlen, char *input, char extention[]);
|
char* replace_filextention(const char *input, const char *extention);
|
||||||
int str_u8_to_u16(u16 **dst, u32 *dst_len, u8 *src, u32 src_len);
|
int str_u8_to_u16(u16 **dst, u32 *dst_len, const u8 *src, u32 src_len);
|
||||||
int str_u16_to_u16(u16 **dst, u32 *dst_len, u16 *src, u32 src_len);
|
int str_u16_to_u16(u16 **dst, u32 *dst_len, const u16 *src, u32 src_len);
|
||||||
int str_u32_to_u16(u16 **dst, u32 *dst_len, u32 *src, u32 src_len);
|
int str_u32_to_u16(u16 **dst, u32 *dst_len, const u32 *src, u32 src_len);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int str_utf8_to_u16(u16 **dst, u32 *dst_len, u8 *src, u32 src_len);
|
int str_utf8_to_u16(u16 **dst, u32 *dst_len, const u8 *src, u32 src_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Base64
|
// Base64
|
||||||
|
|||||||
Reference in New Issue
Block a user