fbi-i18n-zh/source/fbi/dumpnand.c
2020-08-17 09:24:23 +08:00

170 lines
5.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <3ds.h>
#include "resources.h"
#include "section.h"
#include "task/uitask.h"
#include "../core/core.h"
static Result dumpnand_is_src_directory(void* data, u32 index, bool* isDirectory) {
*isDirectory = false;
return 0;
}
static Result dumpnand_make_dst_directory(void* data, u32 index) {
return 0;
}
static Result dumpnand_open_src(void* data, u32 index, u32* handle) {
return FSUSER_OpenFileDirectly(handle, ARCHIVE_NAND_W_FS, fsMakePath(PATH_EMPTY, ""), fsMakePath(PATH_UTF16, u"/"), FS_OPEN_READ, 0);
}
static Result dumpnand_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
static Result dumpnand_get_src_size(void* data, u32 handle, u64* size) {
return FSFILE_GetSize(handle, size);
}
static Result dumpnand_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
return FSFILE_Read(handle, bytesRead, offset, buffer, size);
}
static Result dumpnand_open_dst(void* data, u32 index, void* initialReadBlock, u64 size, u32* handle) {
Result res = 0;
FS_Archive sdmcArchive = 0;
if(R_SUCCEEDED(res = FSUSER_OpenArchive(&sdmcArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, "")))) {
if(R_SUCCEEDED(res = fs_ensure_dir(sdmcArchive, "/fbi/")) && R_SUCCEEDED(res = fs_ensure_dir(sdmcArchive, "/fbi/nand/"))) {
time_t t = time(NULL);
struct tm* timeInfo = localtime(&t);
char path[FILE_PATH_MAX];
strftime(path, sizeof(path), "/fbi/nand/NAND_%m-%d-%y_%H-%M-%S.bin", timeInfo);
FS_Path* fsPath = fs_make_path_utf8(path);
if(fsPath != NULL) {
res = FSUSER_OpenFileDirectly(handle, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""), *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0);
fs_free_path_utf8(fsPath);
} else {
res = R_APP_OUT_OF_MEMORY;
}
}
FSUSER_CloseArchive(sdmcArchive);
}
return res;
}
static Result dumpnand_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
static Result dumpnand_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
return FSFILE_Write(handle, bytesWritten, offset, buffer, size, 0);
}
static Result dumpnand_suspend(void* data, u32 index) {
return 0;
}
static Result dumpnand_restore(void* data, u32 index) {
return 0;
}
static bool dumpnand_error(void* data, u32 index, Result res, ui_view** errorView) {
*errorView = error_display_res(NULL, NULL, res, "無法導出NAND");
return true;
}
static void dumpnand_update(ui_view* view, void* data, float* progress, char* text) {
data_op_data* dumpData = (data_op_data*) data;
if(dumpData->finished) {
ui_pop();
info_destroy(view);
if(R_SUCCEEDED(dumpData->result)) {
prompt_display_notify("成功", "成功導出NAND", COLOR_TEXT, NULL, NULL, NULL);
}
free(dumpData);
return;
}
if(hidKeysDown() & KEY_B) {
svcSignalEvent(dumpData->cancelEvent);
}
*progress = dumpData->currTotal != 0 ? (float) ((double) dumpData->currProcessed / (double) dumpData->currTotal) : 0;
snprintf(text, PROGRESS_TEXT_MAX, "%.2f %s / %.2f %s\n%.2f %s/s, ETA %s",
ui_get_display_size(dumpData->currProcessed), ui_get_display_size_units(dumpData->currProcessed),
ui_get_display_size(dumpData->currTotal), ui_get_display_size_units(dumpData->currTotal),
ui_get_display_size(dumpData->bytesPerSecond), ui_get_display_size_units(dumpData->bytesPerSecond),
ui_get_display_eta(dumpData->estimatedRemainingSeconds));
}
static void dumpnand_onresponse(ui_view* view, void* data, u32 response) {
if(response == PROMPT_YES) {
data_op_data* dumpData = (data_op_data*) data;
Result res = task_data_op(dumpData);
if(R_SUCCEEDED(res)) {
info_display("導出NAND", "按B鍵停止", true, data, dumpnand_update, NULL);
} else {
error_display_res(NULL, NULL, res, "無法初始化導出NAND");
free(data);
}
} else {
free(data);
}
}
void dumpnand_open() {
data_op_data* data = (data_op_data*) calloc(1, sizeof(data_op_data));
if(data == NULL) {
error_display(NULL, NULL, "無法分配導出NAND數據");
return;
}
data->data = data;
data->op = DATAOP_COPY;
data->bufferSize = 256 * 1024;
data->copyEmpty = true;
data->total = 1;
data->isSrcDirectory = dumpnand_is_src_directory;
data->makeDstDirectory = dumpnand_make_dst_directory;
data->openSrc = dumpnand_open_src;
data->closeSrc = dumpnand_close_src;
data->getSrcSize = dumpnand_get_src_size;
data->readSrc = dumpnand_read_src;
data->openDst = dumpnand_open_dst;
data->closeDst = dumpnand_close_dst;
data->writeDst = dumpnand_write_dst;
data->suspend = dumpnand_suspend;
data->restore = dumpnand_restore;
data->error = dumpnand_error;
data->finished = true;
prompt_display_yes_no("確認", "是否導出原始NAND鏡像", COLOR_TEXT, data, NULL, dumpnand_onresponse);
}
// オケー