mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-22 18:26:39 +00:00
Update to v1.1.10.
This commit is contained in:
parent
a999447580
commit
ff3141f5d6
8 changed files with 100 additions and 121 deletions
2
Makefile
2
Makefile
|
@ -33,7 +33,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
||||||
|
|
||||||
VERSION_MAJOR := 1
|
VERSION_MAJOR := 1
|
||||||
VERSION_MINOR := 1
|
VERSION_MINOR := 1
|
||||||
VERSION_MICRO := 9
|
VERSION_MICRO := 10
|
||||||
|
|
||||||
APP_TITLE := nxdumptool
|
APP_TITLE := nxdumptool
|
||||||
APP_AUTHOR := DarkMatterCore
|
APP_AUTHOR := DarkMatterCore
|
||||||
|
|
|
@ -78,6 +78,14 @@ If you like my work and you'd like to support me in any way, it's not necessary,
|
||||||
Changelog
|
Changelog
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
**v1.1.10:**
|
||||||
|
|
||||||
|
* Built using libnx v3.1.0.
|
||||||
|
* Updated save.c/h to reflect changes made by shchmue in Lockpick_RCM. Fixes crashes under HOS 10.0.0.
|
||||||
|
* Fixed a nasty stack corruption issue caused by improper handling of FatFs objects. Fixes ES savefile mounting errors throughout the application (e.g. batch mode, ticket dumping).
|
||||||
|
|
||||||
|
This is only a bugfix release. I don't expect to release any new versions until the rewrite is finished - the only exception being fixing some kind of feature-breaking bug. Please understand.
|
||||||
|
|
||||||
**v1.1.9:**
|
**v1.1.9:**
|
||||||
|
|
||||||
* Built using libnx commit d7e6207.
|
* Built using libnx commit d7e6207.
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#include <switch/arm/atomics.h>
|
|
||||||
#include <switch/services/sm.h>
|
#include <switch/services/sm.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -134,7 +134,7 @@ bool retrieveProcessMemory(keyLocation *location)
|
||||||
u64 pids[300];
|
u64 pids[300];
|
||||||
u32 num_processes;
|
u32 num_processes;
|
||||||
|
|
||||||
result = svcGetProcessList(&num_processes, pids, 300);
|
result = svcGetProcessList((s32*)&num_processes, pids, 300);
|
||||||
if (R_FAILED(result))
|
if (R_FAILED(result))
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: svcGetProcessList failed! (0x%08X)", __func__, result);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: svcGetProcessList failed! (0x%08X)", __func__, result);
|
||||||
|
@ -763,59 +763,6 @@ void mgf1(const u8 *data, size_t data_length, u8 *mask, size_t mask_length)
|
||||||
free(data_counter);
|
free(data_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dumpSharedTikSavedata(void)
|
|
||||||
{
|
|
||||||
FRESULT fr;
|
|
||||||
FIL save;
|
|
||||||
u32 size, blk, i, j;
|
|
||||||
u32 rd_b, wr_b;
|
|
||||||
|
|
||||||
FILE *out;
|
|
||||||
|
|
||||||
for(i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
fr = FR_OK;
|
|
||||||
memset(&save, 0, sizeof(FIL));
|
|
||||||
size = 0;
|
|
||||||
blk = DUMP_BUFFER_SIZE;
|
|
||||||
|
|
||||||
out = NULL;
|
|
||||||
|
|
||||||
fr = f_open(&save, (i == 0 ? "sys:/save/80000000000000e3" : "sys:/save/80000000000000e4"), FA_READ | FA_OPEN_EXISTING);
|
|
||||||
if (fr) continue;
|
|
||||||
|
|
||||||
size = f_size(&save);
|
|
||||||
if (!size)
|
|
||||||
{
|
|
||||||
f_close(&save);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
out = fopen((i == 0 ? "sdmc:/80000000000000e3" : "sdmc:/80000000000000e4"), "wb");
|
|
||||||
if (!out)
|
|
||||||
{
|
|
||||||
f_close(&save);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(j = 0; j < size; j += blk)
|
|
||||||
{
|
|
||||||
if ((size - j) < blk) blk = (size - j);
|
|
||||||
|
|
||||||
rd_b = wr_b = 0;
|
|
||||||
|
|
||||||
fr = f_read(&save, dumpBuf, blk, &rd_b);
|
|
||||||
if (fr || rd_b != blk) break;
|
|
||||||
|
|
||||||
wr_b = fwrite(dumpBuf, 1, blk, out);
|
|
||||||
if (wr_b != blk) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(out);
|
|
||||||
f_close(&save);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_enc_key, u8 *out_dec_key)
|
int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_enc_key, u8 *out_dec_key)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
@ -865,8 +812,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
|
|
||||||
u8 *D = NULL, *N = NULL, *E = NULL;
|
u8 *D = NULL, *N = NULL, *E = NULL;
|
||||||
|
|
||||||
FRESULT fr;
|
FRESULT fr = FR_OK;
|
||||||
FIL eTicketSave;
|
FIL *eTicketSave = NULL;
|
||||||
|
|
||||||
save_ctx_t *save_ctx = NULL;
|
save_ctx_t *save_ctx = NULL;
|
||||||
allocation_table_storage_ctx_t fat_storage;
|
allocation_table_storage_ctx_t fat_storage;
|
||||||
|
@ -984,7 +931,6 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: NCA rights ID unavailable in this console!", __func__);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: NCA rights ID unavailable in this console!", __func__);
|
||||||
ret = -2;
|
ret = -2;
|
||||||
dumpSharedTikSavedata();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1037,11 +983,19 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
setcal_eticket_retrieved = true;
|
setcal_eticket_retrieved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eTicketSave = calloc(1, sizeof(FIL));
|
||||||
|
if (!eTicketSave)
|
||||||
|
{
|
||||||
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to allocate memory for FatFs file descriptor!", __func__);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// FatFs is used to mount the BIS System partition and read the ES savedata files to avoid 0xE02 (file already in use) errors
|
// FatFs is used to mount the BIS System partition and read the ES savedata files to avoid 0xE02 (file already in use) errors
|
||||||
fr = f_open(&eTicketSave, (rightsIdType == 1 ? BIS_COMMON_TIK_SAVE_NAME : BIS_PERSONALIZED_TIK_SAVE_NAME), FA_READ | FA_OPEN_EXISTING);
|
fr = f_open(eTicketSave, (rightsIdType == 1 ? BIS_COMMON_TIK_SAVE_NAME : BIS_PERSONALIZED_TIK_SAVE_NAME), FA_READ | FA_OPEN_EXISTING);
|
||||||
if (fr)
|
if (fr)
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to open ES %s eTicket save! (%u)", __func__, (rightsIdType == 1 ? "common" : "personalized"), fr);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to open ES %s eTicket save! (%u)", __func__, (rightsIdType == 1 ? "common" : "personalized"), fr);
|
||||||
|
free(eTicketSave);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,11 +1003,12 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
if (!save_ctx)
|
if (!save_ctx)
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to allocate memory for ticket savefile context!");
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: failed to allocate memory for ticket savefile context!");
|
||||||
f_close(&eTicketSave);
|
f_close(eTicketSave);
|
||||||
|
free(eTicketSave);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_ctx->file = &eTicketSave;
|
save_ctx->file = eTicketSave;
|
||||||
save_ctx->tool_ctx.action = 0;
|
save_ctx->tool_ctx.action = 0;
|
||||||
|
|
||||||
if (!save_process(save_ctx))
|
if (!save_process(save_ctx))
|
||||||
|
@ -1062,7 +1017,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
strcat(strbuf, tmp);
|
strcat(strbuf, tmp);
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
|
||||||
free(save_ctx);
|
free(save_ctx);
|
||||||
f_close(&eTicketSave);
|
f_close(eTicketSave);
|
||||||
|
free(eTicketSave);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1073,7 +1029,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
|
||||||
save_free_contexts(save_ctx);
|
save_free_contexts(save_ctx);
|
||||||
free(save_ctx);
|
free(save_ctx);
|
||||||
f_close(&eTicketSave);
|
f_close(eTicketSave);
|
||||||
|
free(eTicketSave);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,7 +1041,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, strbuf);
|
||||||
save_free_contexts(save_ctx);
|
save_free_contexts(save_ctx);
|
||||||
free(save_ctx);
|
free(save_ctx);
|
||||||
f_close(&eTicketSave);
|
f_close(eTicketSave);
|
||||||
|
free(eTicketSave);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1156,7 +1114,8 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
|
|
||||||
save_free_contexts(save_ctx);
|
save_free_contexts(save_ctx);
|
||||||
free(save_ctx);
|
free(save_ctx);
|
||||||
f_close(&eTicketSave);
|
f_close(eTicketSave);
|
||||||
|
free(eTicketSave);
|
||||||
|
|
||||||
if (!proceed) return ret;
|
if (!proceed) return ret;
|
||||||
|
|
||||||
|
@ -1164,7 +1123,6 @@ int retrieveNcaTikTitleKey(nca_header_t *dec_nca_header, u8 *out_tik, u8 *out_en
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to find a matching eTicket entry for NCA rights ID!", __func__);
|
uiDrawString(STRING_X_POS, STRING_Y_POS(breaks), FONT_COLOR_ERROR_RGB, "%s: unable to find a matching eTicket entry for NCA rights ID!", __func__);
|
||||||
ret = -2;
|
ret = -2;
|
||||||
dumpSharedTikSavedata();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ remap_segment_ctx_t *save_remap_init_segments(remap_header_t *header, remap_entr
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
remap_segment_ctx_t *segments = calloc(sizeof(remap_segment_ctx_t), header->map_segment_count);
|
remap_segment_ctx_t *segments = calloc(header->map_segment_count, sizeof(remap_segment_ctx_t));
|
||||||
if (!segments)
|
if (!segments)
|
||||||
{
|
{
|
||||||
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate initial memory for remap segments!", __func__);
|
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate initial memory for remap segments!", __func__);
|
||||||
|
@ -164,39 +164,40 @@ remap_segment_ctx_t *save_remap_init_segments(remap_header_t *header, remap_entr
|
||||||
|
|
||||||
for(i = 0; i < header->map_segment_count; i++)
|
for(i = 0; i < header->map_segment_count; i++)
|
||||||
{
|
{
|
||||||
remap_segment_ctx_t *seg = &segments[i];
|
remap_segment_ctx_t *seg = &(segments[i]);
|
||||||
|
|
||||||
seg->entries = calloc(1, sizeof(remap_entry_ctx_t));
|
seg->entry_count = 0;
|
||||||
|
|
||||||
|
seg->entries = calloc(1, sizeof(remap_entry_ctx_t*));
|
||||||
if (!seg->entries)
|
if (!seg->entries)
|
||||||
{
|
{
|
||||||
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate memory for remap segment entry #%u!", __func__, entry_idx);
|
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate memory for remap segment entry #%u!", __func__, entry_idx);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(seg->entries, &map_entries[entry_idx], sizeof(remap_entry_ctx_t));
|
seg->entries[seg->entry_count++] = &map_entries[entry_idx];
|
||||||
seg->offset = map_entries[entry_idx].virtual_offset;
|
seg->offset = map_entries[entry_idx].virtual_offset;
|
||||||
map_entries[entry_idx].segment = seg;
|
map_entries[entry_idx++].segment = seg;
|
||||||
seg->entry_count = 1;
|
|
||||||
entry_idx++;
|
|
||||||
|
|
||||||
while(entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset)
|
while(entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset)
|
||||||
{
|
{
|
||||||
map_entries[entry_idx].segment = seg;
|
map_entries[entry_idx].segment = seg;
|
||||||
map_entries[entry_idx - 1].next = &map_entries[entry_idx];
|
map_entries[entry_idx - 1].next = &map_entries[entry_idx];
|
||||||
|
|
||||||
seg->entries = calloc(1, sizeof(remap_entry_ctx_t));
|
remap_entry_ctx_t **ptr = calloc(sizeof(remap_entry_ctx_t*), seg->entry_count + 1);
|
||||||
if (!seg->entries)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate memory for remap segment entry #%u!", __func__, entry_idx);
|
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to allocate memory for remap segment entry #%u!", __func__, entry_idx);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(seg->entries, &map_entries[entry_idx], sizeof(remap_entry_ctx_t));
|
memcpy(ptr, seg->entries, sizeof(remap_entry_ctx_t*) * seg->entry_count);
|
||||||
seg->entry_count++;
|
free(seg->entries);
|
||||||
entry_idx++;
|
seg->entries = ptr;
|
||||||
|
seg->entries[seg->entry_count++] = &map_entries[entry_idx++];
|
||||||
}
|
}
|
||||||
|
|
||||||
seg->length = (seg->entries[seg->entry_count - 1].virtual_offset_end - seg->entries[0].virtual_offset);
|
seg->length = (seg->entries[seg->entry_count - 1]->virtual_offset_end - seg->entries[0]->virtual_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
|
@ -216,8 +217,7 @@ out:
|
||||||
map_entries[entry_idx].segment->entries = NULL;
|
map_entries[entry_idx].segment->entries = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_entries[entry_idx].segment = NULL;
|
map_entries[entry_idx++].segment = NULL;
|
||||||
entry_idx++;
|
|
||||||
|
|
||||||
while(entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset)
|
while(entry_idx < num_map_entries && map_entries[entry_idx - 1].virtual_offset_end == map_entries[entry_idx].virtual_offset)
|
||||||
{
|
{
|
||||||
|
@ -231,8 +231,7 @@ out:
|
||||||
map_entries[entry_idx].segment->entries = NULL;
|
map_entries[entry_idx].segment->entries = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
map_entries[entry_idx].segment = NULL;
|
map_entries[entry_idx++].segment = NULL;
|
||||||
entry_idx++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +256,7 @@ remap_entry_ctx_t *save_remap_get_map_entry(remap_storage_ctx_t *ctx, u64 offset
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++)
|
for(unsigned int i = 0; i < ctx->segments[segment_idx].entry_count; i++)
|
||||||
{
|
{
|
||||||
if (ctx->segments[segment_idx].entries[i].virtual_offset_end > offset) return (&ctx->segments[segment_idx].entries[i]);
|
if (ctx->segments[segment_idx].entries[i]->virtual_offset_end > offset) return ctx->segments[segment_idx].entries[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +408,7 @@ bool save_ivfc_storage_init(hierarchical_integrity_verification_storage_ctx_t *c
|
||||||
u32 length;
|
u32 length;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct salt_source_t salt_sources[6] = {
|
static const struct salt_source_t salt_sources[6] = {
|
||||||
{"HierarchicalIntegrityVerificationStorage::Master", 48},
|
{"HierarchicalIntegrityVerificationStorage::Master", 48},
|
||||||
{"HierarchicalIntegrityVerificationStorage::L1", 44},
|
{"HierarchicalIntegrityVerificationStorage::L1", 44},
|
||||||
{"HierarchicalIntegrityVerificationStorage::L2", 44},
|
{"HierarchicalIntegrityVerificationStorage::L2", 44},
|
||||||
|
@ -618,7 +617,7 @@ bool save_ivfc_storage_read(integrity_verification_storage_ctx_t *ctx, void *buf
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(data_buffer, ctx->salt, 0x20);
|
memcpy(data_buffer, ctx->salt, 0x20);
|
||||||
memcpy(data_buffer + 0x20, buffer, count);
|
memcpy(data_buffer + 0x20, buffer, ctx->sector_size);
|
||||||
|
|
||||||
sha256CalculateHash(hash, data_buffer, ctx->sector_size + 0x20);
|
sha256CalculateHash(hash, data_buffer, ctx->sector_size + 0x20);
|
||||||
hash[0x1F] |= 0x80;
|
hash[0x1F] |= 0x80;
|
||||||
|
@ -1336,9 +1335,7 @@ bool save_process(save_ctx_t *ctx)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!save_process_header(ctx)) return success;
|
if (!save_process_header(ctx) || ctx->header_hash_validity == VALIDITY_INVALID)
|
||||||
|
|
||||||
if (ctx->header_hash_validity == VALIDITY_INVALID)
|
|
||||||
{
|
{
|
||||||
/* Try to parse Header B. */
|
/* Try to parse Header B. */
|
||||||
fr = f_lseek(ctx->file, 0x4000);
|
fr = f_lseek(ctx->file, 0x4000);
|
||||||
|
@ -1355,9 +1352,7 @@ bool save_process(save_ctx_t *ctx)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!save_process_header(ctx)) return success;
|
if (!save_process_header(ctx) || ctx->header_hash_validity == VALIDITY_INVALID)
|
||||||
|
|
||||||
if (ctx->header_hash_validity == VALIDITY_INVALID)
|
|
||||||
{
|
{
|
||||||
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: savefile header is invalid!", __func__);
|
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: savefile header is invalid!", __func__);
|
||||||
return success;
|
return success;
|
||||||
|
@ -1717,10 +1712,7 @@ void save_free_contexts(save_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++)
|
for(unsigned int i = 0; i < ctx->data_remap_storage.header->map_segment_count; i++)
|
||||||
{
|
{
|
||||||
for(unsigned int j = 0; j < ctx->data_remap_storage.segments[i].entry_count; j++)
|
if (ctx->data_remap_storage.segments[i].entries) free(ctx->data_remap_storage.segments[i].entries);
|
||||||
{
|
|
||||||
if (&(ctx->data_remap_storage.segments[i].entries[j])) free(&(ctx->data_remap_storage.segments[i].entries[j]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1740,10 +1732,7 @@ void save_free_contexts(save_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++)
|
for(unsigned int i = 0; i < ctx->meta_remap_storage.header->map_segment_count; i++)
|
||||||
{
|
{
|
||||||
for(unsigned int j = 0; j < ctx->meta_remap_storage.segments[i].entry_count; j++)
|
if (ctx->meta_remap_storage.segments[i].entries) free(ctx->meta_remap_storage.segments[i].entries);
|
||||||
{
|
|
||||||
if (&(ctx->meta_remap_storage.segments[i].entries[j])) free(&(ctx->meta_remap_storage.segments[i].entries[j]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1846,14 +1835,14 @@ bool readCertsFromSystemSave()
|
||||||
{
|
{
|
||||||
if (loadedCerts) return true;
|
if (loadedCerts) return true;
|
||||||
|
|
||||||
FRESULT fr;
|
FRESULT fr = FR_OK;
|
||||||
FIL certSave;
|
FIL *certSave = NULL;
|
||||||
|
|
||||||
save_ctx_t *save_ctx = NULL;
|
save_ctx_t *save_ctx = NULL;
|
||||||
allocation_table_storage_ctx_t fat_storage;
|
allocation_table_storage_ctx_t fat_storage = {0};
|
||||||
save_fs_list_entry_t entry;
|
save_fs_list_entry_t entry = {0};
|
||||||
|
|
||||||
u64 internalCertSize;
|
u64 internalCertSize = 0;
|
||||||
|
|
||||||
u8 i, j;
|
u8 i, j;
|
||||||
UINT br = 0;
|
UINT br = 0;
|
||||||
|
@ -1863,7 +1852,14 @@ bool readCertsFromSystemSave()
|
||||||
|
|
||||||
bool success = false, openSave = false, initSaveCtx = false;
|
bool success = false, openSave = false, initSaveCtx = false;
|
||||||
|
|
||||||
fr = f_open(&certSave, BIS_CERT_SAVE_NAME, FA_READ | FA_OPEN_EXISTING);
|
certSave = calloc(1, sizeof(FIL));
|
||||||
|
if (!certSave)
|
||||||
|
{
|
||||||
|
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: unable to allocate memory for FatFs file descriptor!", __func__);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fr = f_open(certSave, BIS_CERT_SAVE_NAME, FA_READ | FA_OPEN_EXISTING);
|
||||||
if (fr != FR_OK)
|
if (fr != FR_OK)
|
||||||
{
|
{
|
||||||
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to open \"%s\" savefile from BIS System partition! (%u)", __func__, BIS_CERT_SAVE_NAME, fr);
|
snprintf(strbuf, MAX_CHARACTERS(strbuf), "%s: failed to open \"%s\" savefile from BIS System partition! (%u)", __func__, BIS_CERT_SAVE_NAME, fr);
|
||||||
|
@ -1879,7 +1875,7 @@ bool readCertsFromSystemSave()
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_ctx->file = &certSave;
|
save_ctx->file = certSave;
|
||||||
save_ctx->tool_ctx.action = 0;
|
save_ctx->tool_ctx.action = 0;
|
||||||
|
|
||||||
initSaveCtx = save_process(save_ctx);
|
initSaveCtx = save_process(save_ctx);
|
||||||
|
@ -1987,7 +1983,11 @@ out:
|
||||||
free(save_ctx);
|
free(save_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openSave) f_close(&certSave);
|
if (certSave)
|
||||||
|
{
|
||||||
|
if (openSave) f_close(certSave);
|
||||||
|
free(certSave);
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ struct remap_entry_ctx_t {
|
||||||
struct remap_segment_ctx_t{
|
struct remap_segment_ctx_t{
|
||||||
u64 offset;
|
u64 offset;
|
||||||
u64 length;
|
u64 length;
|
||||||
remap_entry_ctx_t *entries;
|
remap_entry_ctx_t **entries;
|
||||||
u64 entry_count;
|
u64 entry_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4333,7 +4333,7 @@ UIResult uiProcess()
|
||||||
{
|
{
|
||||||
if (scrollAmount > 0)
|
if (scrollAmount > 0)
|
||||||
{
|
{
|
||||||
cursor = ((uiState == stateNspPatchDumpMenu && cursor == 3) ? 4 : 5);
|
cursor = ((uiState == stateNspPatchDumpMenu && cursor <= 3) ? 4 : 5);
|
||||||
} else
|
} else
|
||||||
if (scrollAmount < 0)
|
if (scrollAmount < 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -96,8 +96,8 @@ char strbuf[NAME_BUF_LEN] = {'\0'};
|
||||||
|
|
||||||
static const char *appLaunchPath = NULL;
|
static const char *appLaunchPath = NULL;
|
||||||
|
|
||||||
FsStorage fatFsStorage;
|
FsStorage fatFsStorage = {0};
|
||||||
static bool openBis = false, mountBisFatFs = false;
|
static FATFS *fatFsObj = NULL;
|
||||||
|
|
||||||
u64 freeSpace = 0;
|
u64 freeSpace = 0;
|
||||||
char freeSpaceStr[32] = {'\0'};
|
char freeSpaceStr[32] = {'\0'};
|
||||||
|
@ -353,33 +353,47 @@ static Result getGameCardStoragePartitionSize(u64 *out)
|
||||||
|
|
||||||
bool mountSysEmmcPartition()
|
bool mountSysEmmcPartition()
|
||||||
{
|
{
|
||||||
FATFS fs;
|
Result result = 0;
|
||||||
|
FRESULT fr = FR_OK;
|
||||||
|
|
||||||
Result result = fsOpenBisStorage(&fatFsStorage, FsBisPartitionId_System);
|
result = fsOpenBisStorage(&fatFsStorage, FsBisPartitionId_System);
|
||||||
if (R_FAILED(result))
|
if (R_FAILED(result))
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to open BIS System partition! (0x%08X)", __func__, result);
|
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to open BIS System partition! (0x%08X)", __func__, result);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
openBis = true;
|
fatFsObj = calloc(1, sizeof(FATFS));
|
||||||
|
if (!fatFsObj)
|
||||||
|
{
|
||||||
|
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to allocate memory for FatFs object!", __func__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
FRESULT fr = f_mount(&fs, BIS_MOUNT_NAME, 1);
|
fr = f_mount(fatFsObj, BIS_MOUNT_NAME, 1);
|
||||||
if (fr != FR_OK)
|
if (fr != FR_OK)
|
||||||
{
|
{
|
||||||
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to mount BIS System partition! (%u)", __func__, fr);
|
uiDrawString(STRING_DEFAULT_POS, FONT_COLOR_ERROR_RGB, "%s: failed to mount BIS System partition! (%u)", __func__, fr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mountBisFatFs = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unmountSysEmmcPartition()
|
void unmountSysEmmcPartition()
|
||||||
{
|
{
|
||||||
if (mountBisFatFs) f_unmount(BIS_MOUNT_NAME);
|
if (fatFsObj)
|
||||||
if (openBis) fsStorageClose(&fatFsStorage);
|
{
|
||||||
|
f_unmount(BIS_MOUNT_NAME);
|
||||||
|
free(fatFsObj);
|
||||||
|
fatFsObj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serviceIsActive(&(fatFsStorage.s)))
|
||||||
|
{
|
||||||
|
fsStorageClose(&fatFsStorage);
|
||||||
|
memset(&fatFsStorage, 0, sizeof(FsStorage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isServiceRunning(const char *name)
|
static bool isServiceRunning(const char *name)
|
||||||
|
|
Loading…
Reference in a new issue