mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-04-06 03:58:02 +08:00
Add various out of memory checks.
This commit is contained in:
parent
0ef50e1f40
commit
08ae582ec3
@ -135,6 +135,11 @@ void screen_init() {
|
||||
|
||||
TGLP_s* glyphInfo = fontGetGlyphInfo();
|
||||
glyphSheets = calloc(glyphInfo->nSheets, sizeof(C3D_Tex));
|
||||
if(glyphSheets == NULL) {
|
||||
util_panic("Failed to allocate font glyph texture data.");
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < glyphInfo->nSheets; i++) {
|
||||
C3D_Tex* tex = &glyphSheets[i];
|
||||
tex->data = fontGetGlyphSheetTex(i);
|
||||
@ -405,6 +410,11 @@ void screen_load_texture_tiled(u32 id, void* tiledData, u32 size, u32 width, u32
|
||||
u32 pixelSize = size / width / height;
|
||||
|
||||
u8* untiledData = (u8*) calloc(1, size);
|
||||
if(untiledData == NULL) {
|
||||
util_panic("Failed to allocate buffer for texture untiling.");
|
||||
return;
|
||||
}
|
||||
|
||||
for(u32 x = 0; x < width; x++) {
|
||||
for(u32 y = 0; y < height; y++) {
|
||||
u32 tiledDataPos = util_tiled_texture_index(x, y, width, height) * pixelSize;
|
||||
|
@ -567,6 +567,11 @@ static void error_onresponse(ui_view* view, void* data, bool response) {
|
||||
|
||||
void error_display(volatile bool* dismissed, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2), const char* text, ...) {
|
||||
error_data* errorData = (error_data*) calloc(1, sizeof(error_data));
|
||||
if(errorData == NULL) {
|
||||
// No use trying to spawn another if we're out of memory.
|
||||
return;
|
||||
}
|
||||
|
||||
errorData->data = data;
|
||||
errorData->dismissed = dismissed;
|
||||
errorData->drawTop = drawTop;
|
||||
@ -581,6 +586,11 @@ void error_display(volatile bool* dismissed, void* data, void (*drawTop)(ui_view
|
||||
|
||||
void error_display_res(volatile bool* dismissed, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2), Result result, const char* text, ...) {
|
||||
error_data* errorData = (error_data*) calloc(1, sizeof(error_data));
|
||||
if(errorData == NULL) {
|
||||
// No use trying to spawn another if we're out of memory.
|
||||
return;
|
||||
}
|
||||
|
||||
errorData->data = data;
|
||||
errorData->dismissed = dismissed;
|
||||
errorData->drawTop = drawTop;
|
||||
@ -602,6 +612,11 @@ void error_display_res(volatile bool* dismissed, void* data, void (*drawTop)(ui_
|
||||
|
||||
void error_display_errno(volatile bool* dismissed, void* data, void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2), int err, const char* text, ...) {
|
||||
error_data* errorData = (error_data*) calloc(1, sizeof(error_data));
|
||||
if(errorData == NULL) {
|
||||
// No use trying to spawn another if we're out of memory.
|
||||
return;
|
||||
}
|
||||
|
||||
errorData->data = data;
|
||||
errorData->dismissed = dismissed;
|
||||
errorData->drawTop = drawTop;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "info.h"
|
||||
#include "../screen.h"
|
||||
|
||||
@ -68,6 +69,12 @@ static void info_draw_bottom(ui_view* view, void* data, float x1, float y1, floa
|
||||
void info_display(const char* name, const char* info, bool bar, void* data, void (*update)(ui_view* view, void* data, float* progress, char* text),
|
||||
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2)) {
|
||||
info_data* infoData = (info_data*) calloc(1, sizeof(info_data));
|
||||
if(infoData == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate info data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
infoData->bar = bar;
|
||||
infoData->data = data;
|
||||
infoData->progress = 0;
|
||||
@ -76,6 +83,13 @@ void info_display(const char* name, const char* info, bool bar, void* data, void
|
||||
infoData->drawTop = drawTop;
|
||||
|
||||
ui_view* view = (ui_view*) calloc(1, sizeof(ui_view));
|
||||
if(view == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate UI view.");
|
||||
|
||||
free(infoData);
|
||||
return;
|
||||
}
|
||||
|
||||
view->name = name;
|
||||
view->info = info;
|
||||
view->data = infoData;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <3ds.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "list.h"
|
||||
#include "../screen.h"
|
||||
|
||||
@ -212,6 +214,12 @@ static void list_draw_bottom(ui_view* view, void* data, float x1, float y1, floa
|
||||
void list_display(const char* name, const char* info, void* data, void (*update)(ui_view* view, void* data, list_item** contents, u32** itemCount, list_item* selected, bool selectedTouched),
|
||||
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2, list_item* selected)) {
|
||||
list_data* listData = (list_data*) calloc(1, sizeof(list_data));
|
||||
if(listData == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate list data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
listData->data = data;
|
||||
listData->items = NULL;
|
||||
listData->itemCount = NULL;
|
||||
@ -224,6 +232,13 @@ void list_display(const char* name, const char* info, void* data, void (*update)
|
||||
listData->drawTop = drawTop;
|
||||
|
||||
ui_view* view = (ui_view*) calloc(1, sizeof(ui_view));
|
||||
if(view == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate UI view.");
|
||||
|
||||
free(listData);
|
||||
return;
|
||||
}
|
||||
|
||||
view->name = name;
|
||||
view->info = info;
|
||||
view->data = listData;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <3ds.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "prompt.h"
|
||||
#include "../screen.h"
|
||||
|
||||
@ -140,6 +142,12 @@ void prompt_display(const char* name, const char* text, u32 rgba, bool option, v
|
||||
void (*drawTop)(ui_view* view, void* data, float x1, float y1, float x2, float y2),
|
||||
void (*onResponse)(ui_view* view, void* data, bool response)) {
|
||||
prompt_data* promptData = (prompt_data*) calloc(1, sizeof(prompt_data));
|
||||
if(promptData == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate prompt data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
promptData->text = text;
|
||||
promptData->rgba = rgba;
|
||||
promptData->option = option;
|
||||
@ -149,6 +157,13 @@ void prompt_display(const char* name, const char* text, u32 rgba, bool option, v
|
||||
promptData->onResponse = onResponse;
|
||||
|
||||
ui_view* view = (ui_view*) calloc(1, sizeof(ui_view));
|
||||
if(view == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate UI view.");
|
||||
|
||||
free(promptData);
|
||||
return;
|
||||
}
|
||||
|
||||
view->name = name;
|
||||
view->info = "";
|
||||
view->data = promptData;
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "clipboard.h"
|
||||
#include "../task/task.h"
|
||||
|
||||
static bool clipboard_has = false;
|
||||
static FS_Archive clipboard_archive;
|
||||
@ -32,6 +33,11 @@ Result clipboard_set_contents(FS_Archive archive, const char* path) {
|
||||
|
||||
if(clipboard_archive.lowPath.size > 0) {
|
||||
clipboard_archive_path = calloc(1, clipboard_archive.lowPath.size);
|
||||
if(clipboard_archive_path == NULL) {
|
||||
clipboard_clear();
|
||||
return R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(clipboard_archive_path, clipboard_archive.lowPath.data, clipboard_archive.lowPath.size);
|
||||
clipboard_archive.lowPath.data = clipboard_archive_path;
|
||||
}
|
||||
|
@ -23,16 +23,20 @@ typedef struct {
|
||||
static Result action_delete_contents_delete(void* data, u32 index) {
|
||||
delete_contents_data* deleteData = (delete_contents_data*) data;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(deleteData->contents[index]);
|
||||
|
||||
Result res = 0;
|
||||
if(util_is_dir(deleteData->base->archive, deleteData->contents[index])) {
|
||||
res = FSUSER_DeleteDirectory(*deleteData->base->archive, *fsPath);
|
||||
} else {
|
||||
res = FSUSER_DeleteFile(*deleteData->base->archive, *fsPath);
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
FS_Path* fsPath = util_make_path_utf8(deleteData->contents[index]);
|
||||
if(fsPath != NULL) {
|
||||
if(util_is_dir(deleteData->base->archive, deleteData->contents[index])) {
|
||||
res = FSUSER_DeleteDirectory(*deleteData->base->archive, *fsPath);
|
||||
} else {
|
||||
res = FSUSER_DeleteFile(*deleteData->base->archive, *fsPath);
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -119,6 +123,12 @@ static void action_delete_contents_onresponse(ui_view* view, void* data, bool re
|
||||
|
||||
static void action_delete_contents_internal(file_info* info, bool* populated, const char* message, bool recursive, void* filterData, bool (*filter)(void* data, FS_Archive* archive, const char* path, u32 attributes)) {
|
||||
delete_contents_data* data = (delete_contents_data*) calloc(1, sizeof(delete_contents_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate delete contents data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->base = info;
|
||||
data->populated = populated;
|
||||
|
||||
|
@ -47,6 +47,12 @@ static void action_delete_ext_save_data_onresponse(ui_view* view, void* data, bo
|
||||
|
||||
void action_delete_ext_save_data(ext_save_data_info* info, bool* populated) {
|
||||
delete_ext_save_data_data* data = (delete_ext_save_data_data*) calloc(1, sizeof(delete_ext_save_data_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate delete ext save data data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
|
@ -109,6 +109,13 @@ static void action_delete_pending_titles_onresponse(ui_view* view, void* data, b
|
||||
|
||||
void action_delete_pending_titles(pending_title_info* info, bool* populated, const char* message, u64* titleIds, u32 sdTotal, u32 nandTotal) {
|
||||
delete_pending_titles_data* data = (delete_pending_titles_data*) calloc(1, sizeof(delete_pending_titles_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate delete pending titles data.");
|
||||
|
||||
free(titleIds);
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
data->titleIds = titleIds;
|
||||
@ -132,6 +139,12 @@ void action_delete_pending_titles(pending_title_info* info, bool* populated, con
|
||||
|
||||
void action_delete_pending_title(pending_title_info* info, bool* populated) {
|
||||
u64* titleIds = (u64*) calloc(1, sizeof(u64));
|
||||
if(titleIds == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate title ID buffer.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
titleIds[0] = info->titleId;
|
||||
u32 sdTotal = info->mediaType == MEDIATYPE_SD ? 1 : 0;
|
||||
u32 nandTotal = info->mediaType == MEDIATYPE_NAND ? 1 : 0;
|
||||
@ -151,6 +164,12 @@ void action_delete_all_pending_titles(pending_title_info* info, bool* populated)
|
||||
}
|
||||
|
||||
u64* titleIds = (u64*) calloc(sdTotal + nandTotal, sizeof(u64));
|
||||
if(titleIds == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate title ID buffer.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(R_FAILED(res = AM_GetPendingTitleList(&sdTotal, sdTotal, MEDIATYPE_SD, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION, titleIds)) || R_FAILED(res = AM_GetPendingTitleList(&nandTotal, nandTotal, MEDIATYPE_NAND, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION, &titleIds[sdTotal]))) {
|
||||
error_display_res(NULL, NULL, NULL, res, "Failed to retrieve pending title list.");
|
||||
|
||||
|
@ -47,6 +47,12 @@ static void action_delete_system_save_data_onresponse(ui_view* view, void* data,
|
||||
|
||||
void action_delete_system_save_data(system_save_data_info* info, bool* populated) {
|
||||
delete_system_save_data_data* data = (delete_system_save_data_data*) calloc(1, sizeof(delete_system_save_data_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate delete system save data data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
|
@ -46,6 +46,12 @@ static void action_delete_ticket_onresponse(ui_view* view, void* data, bool resp
|
||||
|
||||
void action_delete_ticket(ticket_info* info, bool* populated) {
|
||||
delete_ticket_data* data = (delete_ticket_data*) calloc(1, sizeof(delete_ticket_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate delete ticket data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
|
@ -46,6 +46,12 @@ static void action_delete_title_onresponse(ui_view* view, void* data, bool respo
|
||||
|
||||
void action_delete_title(title_info* info, bool* populated) {
|
||||
delete_title_data* data = (delete_title_data*) calloc(1, sizeof(delete_title_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate delete title data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
|
@ -33,15 +33,18 @@ static void action_export_secure_value_update(ui_view* view, void* data, float*
|
||||
snprintf(pathBuf, 64, "/fbi/securevalue/%016llX.dat", info->titleId);
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(pathBuf);
|
||||
if(fsPath != NULL) {
|
||||
Handle fileHandle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenFile(&fileHandle, sdmcArchive, *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0))) {
|
||||
u32 bytesWritten = 0;
|
||||
res = FSFILE_Write(fileHandle, &bytesWritten, 0, &value, sizeof(u64), FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
|
||||
FSFILE_Close(fileHandle);
|
||||
}
|
||||
|
||||
Handle fileHandle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenFile(&fileHandle, sdmcArchive, *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0))) {
|
||||
u32 bytesWritten = 0;
|
||||
res = FSFILE_Write(fileHandle, &bytesWritten, 0, &value, sizeof(u64), FS_WRITE_FLUSH | FS_WRITE_UPDATE_TIME);
|
||||
FSFILE_Close(fileHandle);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
}
|
||||
|
||||
FSUSER_CloseArchive(&sdmcArchive);
|
||||
|
@ -18,21 +18,24 @@ static void action_import_secure_value_update(ui_view* view, void* data, float*
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(pathBuf);
|
||||
if(fsPath != NULL) {
|
||||
FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (void*) ""}};
|
||||
Handle fileHandle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenFileDirectly(&fileHandle, sdmcArchive, *fsPath, FS_OPEN_READ, 0))) {
|
||||
u32 bytesRead = 0;
|
||||
u64 value = 0;
|
||||
if(R_SUCCEEDED(res = FSFILE_Read(fileHandle, &bytesRead, 0, &value, sizeof(u64)))) {
|
||||
res = FSUSER_SetSaveDataSecureValue(value, SECUREVALUE_SLOT_SD, (u32) ((info->titleId >> 8) & 0xFFFFF), (u8) (info->titleId & 0xFF));
|
||||
}
|
||||
|
||||
FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (void*) ""}};
|
||||
Handle fileHandle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenFileDirectly(&fileHandle, sdmcArchive, *fsPath, FS_OPEN_READ, 0))) {
|
||||
u32 bytesRead = 0;
|
||||
u64 value = 0;
|
||||
if(R_SUCCEEDED(res = FSFILE_Read(fileHandle, &bytesRead, 0, &value, sizeof(u64)))) {
|
||||
res = FSUSER_SetSaveDataSecureValue(value, SECUREVALUE_SLOT_SD, (u32) ((info->titleId >> 8) & 0xFFFFF), (u8) (info->titleId & 0xFF));
|
||||
FSFILE_Close(fileHandle);
|
||||
}
|
||||
|
||||
FSFILE_Close(fileHandle);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
|
||||
ui_pop();
|
||||
info_destroy(view);
|
||||
|
||||
|
@ -35,11 +35,16 @@ static Result action_install_cias_make_dst_directory(void* data, u32 index) {
|
||||
static Result action_install_cias_open_src(void* data, u32 index, u32* handle) {
|
||||
install_cias_data* installData = (install_cias_data*) data;
|
||||
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
|
||||
if(fsPath != NULL) {
|
||||
res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0);
|
||||
|
||||
Result res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -50,10 +55,13 @@ static Result action_install_cias_close_src(void* data, u32 index, bool succeede
|
||||
Result res = 0;
|
||||
if(R_SUCCEEDED(res = FSFILE_Close(handle)) && installData->delete && succeeded) {
|
||||
FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
|
||||
if(fsPath != NULL) {
|
||||
FSUSER_DeleteFile(*installData->base->archive, *fsPath);
|
||||
|
||||
FSUSER_DeleteFile(*installData->base->archive, *fsPath);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -210,6 +218,12 @@ static void action_install_cias_onresponse(ui_view* view, void* data, bool respo
|
||||
|
||||
static void action_install_cias_internal(file_info* info, bool* populated, bool delete) {
|
||||
install_cias_data* data = (install_cias_data*) calloc(1, sizeof(install_cias_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate install CIAs data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->base = info;
|
||||
data->delete = delete;
|
||||
data->populated = populated;
|
||||
|
@ -31,11 +31,16 @@ static Result action_install_tickets_make_dst_directory(void* data, u32 index) {
|
||||
static Result action_install_tickets_open_src(void* data, u32 index, u32* handle) {
|
||||
install_tickets_data* installData = (install_tickets_data*) data;
|
||||
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
|
||||
if(fsPath != NULL) {
|
||||
res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0);
|
||||
|
||||
Result res = FSUSER_OpenFile(handle, *installData->base->archive, *fsPath, FS_OPEN_READ, 0);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -144,6 +149,12 @@ static void action_install_tickets_onresponse(ui_view* view, void* data, bool re
|
||||
|
||||
void action_install_tickets(file_info* info, bool* populated) {
|
||||
install_tickets_data* data = (install_tickets_data*) calloc(1, sizeof(install_tickets_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate install tickets data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->base = info;
|
||||
|
||||
data->installInfo.data = data;
|
||||
|
@ -46,11 +46,16 @@ static Result action_paste_files_make_dst_directory(void* data, u32 index) {
|
||||
char dstPath[PATH_MAX];
|
||||
action_paste_files_get_dst_path(pasteData, index, dstPath);
|
||||
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(dstPath);
|
||||
if(fsPath != NULL) {
|
||||
res = FSUSER_CreateDirectory(*pasteData->base->archive, *fsPath, 0);
|
||||
|
||||
Result res = FSUSER_CreateDirectory(*pasteData->base->archive, *fsPath, 0);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -58,11 +63,16 @@ static Result action_paste_files_make_dst_directory(void* data, u32 index) {
|
||||
static Result action_paste_files_open_src(void* data, u32 index, u32* handle) {
|
||||
paste_files_data* pasteData = (paste_files_data*) data;
|
||||
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(pasteData->contents[index]);
|
||||
if(fsPath != NULL) {
|
||||
res = FSUSER_OpenFile(handle, *pasteData->base->archive, *fsPath, FS_OPEN_READ, 0);
|
||||
|
||||
Result res = FSUSER_OpenFile(handle, *pasteData->base->archive, *fsPath, FS_OPEN_READ, 0);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -85,11 +95,16 @@ static Result action_paste_files_open_dst(void* data, u32 index, void* initialRe
|
||||
char dstPath[PATH_MAX];
|
||||
action_paste_files_get_dst_path(pasteData, index, dstPath);
|
||||
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(dstPath);
|
||||
if(fsPath != NULL) {
|
||||
res = FSUSER_OpenFile(handle, *pasteData->base->archive, *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0);
|
||||
|
||||
Result res = FSUSER_OpenFile(handle, *pasteData->base->archive, *fsPath, FS_OPEN_WRITE | FS_OPEN_CREATE, 0);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -186,6 +201,12 @@ void action_paste_contents(file_info* info, bool* populated) {
|
||||
}
|
||||
|
||||
paste_files_data* data = (paste_files_data*) calloc(1, sizeof(paste_files_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate paste files data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->base = info;
|
||||
data->populated = populated;
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "task/task.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../info.h"
|
||||
#include "../prompt.h"
|
||||
@ -104,6 +105,11 @@ static void dumpnand_onresponse(ui_view* view, void* data, bool response) {
|
||||
|
||||
void dump_nand() {
|
||||
dump_nand_data* data = (dump_nand_data*) calloc(1, sizeof(dump_nand_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate dump NAND data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->dumpInfo.data = data;
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "action/action.h"
|
||||
#include "task/task.h"
|
||||
#include "../../screen.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../../screen.h"
|
||||
|
||||
#define EXTSAVEDATA_MAX 512
|
||||
|
||||
@ -68,6 +68,12 @@ static void extsavedata_action_update(ui_view* view, void* data, list_item** ite
|
||||
|
||||
static void extsavedata_action_open(ext_save_data_info* info, bool* populated) {
|
||||
extsavedata_action_data* data = (extsavedata_action_data*) calloc(1, sizeof(extsavedata_action_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate ext save data action data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
@ -128,6 +134,11 @@ static void extsavedata_update(ui_view* view, void* data, list_item** items, u32
|
||||
|
||||
void extsavedata_open() {
|
||||
extsavedata_data* data = (extsavedata_data*) calloc(1, sizeof(extsavedata_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate ext save data data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list_display("Ext Save Data", "A: Select, B: Return, X: Refresh", data, extsavedata_update, extsavedata_draw_top);
|
||||
}
|
@ -6,11 +6,10 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "action/action.h"
|
||||
#include "task/task.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../../screen.h"
|
||||
#include "../../util.h"
|
||||
#include "section.h"
|
||||
|
||||
#define FILES_MAX 1024
|
||||
|
||||
@ -183,6 +182,12 @@ static void files_action_update(ui_view* view, void* data, list_item** items, u3
|
||||
|
||||
static void files_action_open(file_info* info, bool* populated) {
|
||||
files_action_data* data = (files_action_data*) calloc(1, sizeof(files_action_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate files action data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
@ -296,10 +301,23 @@ static void files_update(ui_view* view, void* data, list_item** items, u32** ite
|
||||
|
||||
void files_open(FS_Archive archive) {
|
||||
files_data* data = (files_data*) calloc(1, sizeof(files_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate files data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->archive = archive;
|
||||
|
||||
if(data->archive.lowPath.size > 0) {
|
||||
data->archivePath = calloc(1, data->archive.lowPath.size);
|
||||
if(data->archivePath == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate files archive.");
|
||||
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(data->archivePath, data->archive.lowPath.data, data->archive.lowPath.size);
|
||||
data->archive.lowPath.data = data->archivePath;
|
||||
}
|
||||
|
@ -254,9 +254,18 @@ static void networkinstall_wait_update(ui_view* view, void* data, float* progres
|
||||
}
|
||||
|
||||
void networkinstall_open() {
|
||||
network_install_data* data = (network_install_data*) calloc(1, sizeof(network_install_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate network install data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
if(sock < 0) {
|
||||
error_display_errno(NULL, NULL, NULL, errno, "Failed to open server socket.");
|
||||
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -269,22 +278,23 @@ void networkinstall_open() {
|
||||
server.sin_addr.s_addr = (in_addr_t) gethostid();
|
||||
|
||||
if(bind(sock, (struct sockaddr*) &server, sizeof(server)) < 0) {
|
||||
close(sock);
|
||||
|
||||
error_display_errno(NULL, NULL, NULL, errno, "Failed to bind server socket.");
|
||||
|
||||
close(sock);
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
if(listen(sock, 5) < 0) {
|
||||
close(sock);
|
||||
|
||||
error_display_errno(NULL, NULL, NULL, errno, "Failed to listen on server socket.");
|
||||
|
||||
close(sock);
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
network_install_data* data = (network_install_data*) calloc(1, sizeof(network_install_data));
|
||||
data->serverSocket = sock;
|
||||
data->clientSocket = 0;
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "action/action.h"
|
||||
#include "task/task.h"
|
||||
#include "../../screen.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../../screen.h"
|
||||
|
||||
#define PENDINGTITLES_MAX 1024
|
||||
|
||||
@ -67,6 +67,12 @@ static void pendingtitles_action_update(ui_view* view, void* data, list_item** i
|
||||
|
||||
static void pendingtitles_action_open(pending_title_info* info, bool* populated) {
|
||||
pendingtitles_action_data* data = (pendingtitles_action_data*) calloc(1, sizeof(pendingtitles_action_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate pending titles action data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
@ -127,6 +133,11 @@ static void pendingtitles_update(ui_view* view, void* data, list_item** items, u
|
||||
|
||||
void pendingtitles_open() {
|
||||
pendingtitles_data* data = (pendingtitles_data*) calloc(1, sizeof(pendingtitles_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate pending titles data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list_display("Pending Titles", "A: Select, B: Return, X: Refresh", data, pendingtitles_update, pendingtitles_draw_top);
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "task/task.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../info.h"
|
||||
#include "../prompt.h"
|
||||
@ -45,27 +46,30 @@ static Result qrinstall_make_dst_directory(void* data, u32 index) {
|
||||
static Result qrinstall_open_src(void* data, u32 index, u32* handle) {
|
||||
qr_install_data* qrInstallData = (qr_install_data*) data;
|
||||
|
||||
httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext));
|
||||
|
||||
Result res = 0;
|
||||
|
||||
if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, qrInstallData->urls[index], 1))) {
|
||||
httpcSetSSLOpt(context, SSLCOPT_DisableVerify);
|
||||
if(R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &qrInstallData->responseCode, 0))) {
|
||||
if(qrInstallData->responseCode == 200) {
|
||||
*handle = (u32) context;
|
||||
} else {
|
||||
res = R_FBI_HTTP_RESPONSE_CODE;
|
||||
httpcContext* context = (httpcContext*) calloc(1, sizeof(httpcContext));
|
||||
if(context != NULL) {
|
||||
if(R_SUCCEEDED(res = httpcOpenContext(context, HTTPC_METHOD_GET, qrInstallData->urls[index], 1))) {
|
||||
httpcSetSSLOpt(context, SSLCOPT_DisableVerify);
|
||||
if(R_SUCCEEDED(res = httpcBeginRequest(context)) && R_SUCCEEDED(res = httpcGetResponseStatusCode(context, &qrInstallData->responseCode, 0))) {
|
||||
if(qrInstallData->responseCode == 200) {
|
||||
*handle = (u32) context;
|
||||
} else {
|
||||
res = R_FBI_HTTP_RESPONSE_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
if(R_FAILED(res)) {
|
||||
httpcCloseContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
if(R_FAILED(res)) {
|
||||
httpcCloseContext(context);
|
||||
free(context);
|
||||
}
|
||||
}
|
||||
|
||||
if(R_FAILED(res)) {
|
||||
free(context);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -321,6 +325,11 @@ static void qrinstall_wait_update(ui_view* view, void* data, float* progress, ch
|
||||
|
||||
void qrinstall_open() {
|
||||
qr_install_data* data = (qr_install_data*) calloc(1, sizeof(qr_install_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate QR install data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->qrContext = quirc_new();
|
||||
if(data->qrContext == NULL) {
|
||||
|
@ -4,9 +4,9 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "action/action.h"
|
||||
#include "task/task.h"
|
||||
#include "../../screen.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../../screen.h"
|
||||
|
||||
#define SYSTEMSAVEDATA_MAX 512
|
||||
|
||||
@ -67,6 +67,12 @@ static void systemsavedata_action_update(ui_view* view, void* data, list_item**
|
||||
|
||||
static void systemsavedata_action_open(system_save_data_info* info, bool* populated) {
|
||||
systemsavedata_action_data* data = (systemsavedata_action_data*) calloc(1, sizeof(systemsavedata_action_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate system save data action data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
@ -127,6 +133,11 @@ static void systemsavedata_update(ui_view* view, void* data, list_item** items,
|
||||
|
||||
void systemsavedata_open() {
|
||||
systemsavedata_data* data = (systemsavedata_data*) calloc(1, sizeof(systemsavedata_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate system save data data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list_display("System Save Data", "A: Select, B: Return, X: Refresh", data, systemsavedata_update, systemsavedata_draw_top);
|
||||
}
|
@ -128,6 +128,12 @@ Handle task_capture_cam(Handle* mutex, u16* buffer, s16 width, s16 height) {
|
||||
}
|
||||
|
||||
capture_cam_data* data = (capture_cam_data*) calloc(1, sizeof(capture_cam_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate camera capture data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->buffer = buffer;
|
||||
data->width = width;
|
||||
data->height = height;
|
||||
|
@ -160,24 +160,30 @@ Handle task_data_op(data_op_info* info) {
|
||||
|
||||
task_data_op_reset_info(info);
|
||||
|
||||
data_op_data* installData = (data_op_data*) calloc(1, sizeof(data_op_data));
|
||||
installData->info = info;
|
||||
data_op_data* data = (data_op_data*) calloc(1, sizeof(data_op_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate data operation data.");
|
||||
|
||||
Result eventRes = svcCreateEvent(&installData->cancelEvent, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
|
||||
Result eventRes = svcCreateEvent(&data->cancelEvent, 1);
|
||||
if(R_FAILED(eventRes)) {
|
||||
error_display_res(NULL, NULL, NULL, eventRes, "Failed to create data operation cancel event.");
|
||||
|
||||
free(installData);
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(threadCreate(task_data_op_thread, installData, 0x4000, 0x18, 1, true) == NULL) {
|
||||
if(threadCreate(task_data_op_thread, data, 0x4000, 0x18, 1, true) == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to create data operation thread.");
|
||||
|
||||
svcCloseHandle(installData->cancelEvent);
|
||||
free(installData);
|
||||
svcCloseHandle(data->cancelEvent);
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return installData->cancelEvent;
|
||||
return data->cancelEvent;
|
||||
}
|
@ -145,6 +145,12 @@ Handle task_populate_ext_save_data(list_item* items, u32* count, u32 max) {
|
||||
task_clear_ext_save_data(items, count);
|
||||
|
||||
populate_ext_save_data_data* data = (populate_ext_save_data_data*) calloc(1, sizeof(populate_ext_save_data_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate ext save data list data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->items = items;
|
||||
data->count = count;
|
||||
data->max = max;
|
||||
|
@ -199,6 +199,12 @@ Handle task_populate_files(list_item* items, u32* count, u32 max, file_info* dir
|
||||
task_clear_files(items, count);
|
||||
|
||||
populate_files_data* data = (populate_files_data*) calloc(1, sizeof(populate_files_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate file list data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->items = items;
|
||||
data->count = count;
|
||||
data->max = max;
|
||||
|
@ -115,6 +115,12 @@ Handle task_populate_pending_titles(list_item* items, u32* count, u32 max) {
|
||||
task_clear_pending_titles(items, count);
|
||||
|
||||
populate_pending_titles_data* data = (populate_pending_titles_data*) calloc(1, sizeof(populate_pending_titles_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate pending title list data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->items = items;
|
||||
data->count = count;
|
||||
data->max = max;
|
||||
|
@ -92,6 +92,12 @@ Handle task_populate_system_save_data(list_item* items, u32* count, u32 max) {
|
||||
task_clear_system_save_data(items, count);
|
||||
|
||||
populate_system_save_data_data* data = (populate_system_save_data_data*) calloc(1, sizeof(populate_system_save_data_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate system save data list data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->items = items;
|
||||
data->count = count;
|
||||
data->max = max;
|
||||
|
@ -94,6 +94,12 @@ Handle task_populate_tickets(list_item* items, u32* count, u32 max) {
|
||||
task_clear_tickets(items, count);
|
||||
|
||||
populate_tickets_data* data = (populate_tickets_data*) calloc(1, sizeof(populate_tickets_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate ticket list data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->items = items;
|
||||
data->count = count;
|
||||
data->max = max;
|
||||
|
@ -331,6 +331,12 @@ Handle task_populate_titles(list_item* items, u32* count, u32 max) {
|
||||
task_clear_titles(items, count);
|
||||
|
||||
populate_titles_data* data = (populate_titles_data*) calloc(1, sizeof(populate_titles_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate title list data.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->items = items;
|
||||
data->count = count;
|
||||
data->max = max;
|
||||
|
@ -4,8 +4,9 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "action/action.h"
|
||||
#include "../../screen.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../../screen.h"
|
||||
|
||||
#define TICKETS_MAX 1024
|
||||
|
||||
@ -65,6 +66,12 @@ static void tickets_action_update(ui_view* view, void* data, list_item** items,
|
||||
|
||||
static void tickets_action_open(ticket_info* info, bool* populated) {
|
||||
tickets_action_data* data = (tickets_action_data*) calloc(1, sizeof(tickets_action_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate tickets action data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
@ -125,6 +132,11 @@ static void tickets_update(ui_view* view, void* data, list_item** items, u32** i
|
||||
|
||||
void tickets_open() {
|
||||
tickets_data* data = (tickets_data*) calloc(1, sizeof(tickets_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate tickets data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list_display("Tickets", "A: Select, B: Return, X: Refresh", data, tickets_update, tickets_draw_top);
|
||||
}
|
@ -4,9 +4,9 @@
|
||||
#include <3ds.h>
|
||||
|
||||
#include "action/action.h"
|
||||
#include "task/task.h"
|
||||
#include "../../screen.h"
|
||||
#include "section.h"
|
||||
#include "../error.h"
|
||||
#include "../../screen.h"
|
||||
|
||||
#define TITLES_MAX 1024
|
||||
|
||||
@ -111,6 +111,12 @@ static void titles_action_update(ui_view* view, void* data, list_item** items, u
|
||||
|
||||
static void titles_action_open(title_info* info, bool* populated) {
|
||||
titles_action_data* data = (titles_action_data*) calloc(1, sizeof(titles_action_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate titles action data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
data->info = info;
|
||||
data->populated = populated;
|
||||
|
||||
@ -171,6 +177,11 @@ static void titles_update(ui_view* view, void* data, list_item** items, u32** it
|
||||
|
||||
void titles_open() {
|
||||
titles_data* data = (titles_data*) calloc(1, sizeof(titles_data));
|
||||
if(data == NULL) {
|
||||
error_display(NULL, NULL, NULL, "Failed to allocate titles data.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list_display("Titles", "A: Select, B: Return, X: Refresh", data, titles_update, titles_draw_top);
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <3ds.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "section/task/task.h"
|
||||
#include "../screen.h"
|
||||
#include "ui.h"
|
||||
#include "../screen.h"
|
||||
|
||||
#define MAX_UI_VIEWS 16
|
||||
|
||||
|
148
source/util.c
148
source/util.c
@ -126,15 +126,19 @@ void util_panic(const char* s, ...) {
|
||||
}
|
||||
|
||||
bool util_is_dir(FS_Archive* archive, const char* path) {
|
||||
FS_Path* fsPath = util_make_path_utf8(path);
|
||||
|
||||
Result res = 0;
|
||||
Handle dirHandle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *archive, *fsPath))) {
|
||||
FSDIR_Close(dirHandle);
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
FS_Path* fsPath = util_make_path_utf8(path);
|
||||
if(fsPath != NULL) {
|
||||
Handle dirHandle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&dirHandle, *archive, *fsPath))) {
|
||||
FSDIR_Close(dirHandle);
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return R_SUCCEEDED(res);
|
||||
}
|
||||
@ -144,56 +148,63 @@ static Result util_traverse_dir_internal(FS_Archive* archive, const char* path,
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(path);
|
||||
if(fsPath != NULL) {
|
||||
Handle handle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&handle, *archive, *fsPath))) {
|
||||
size_t pathLen = strlen(path);
|
||||
char* pathBuf = (char*) calloc(1, PATH_MAX);
|
||||
if(pathBuf != NULL) {
|
||||
strncpy(pathBuf, path, PATH_MAX);
|
||||
|
||||
Handle handle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenDirectory(&handle, *archive, *fsPath))) {
|
||||
size_t pathLen = strlen(path);
|
||||
char* pathBuf = (char*) calloc(1, PATH_MAX);
|
||||
strncpy(pathBuf, path, PATH_MAX);
|
||||
u32 entryCount = 0;
|
||||
FS_DirectoryEntry entry;
|
||||
u32 done = 0;
|
||||
while(R_SUCCEEDED(FSDIR_Read(handle, &entryCount, 1, &entry)) && entryCount > 0) {
|
||||
ssize_t units = utf16_to_utf8((uint8_t*) pathBuf + pathLen, entry.name, PATH_MAX - pathLen - 1);
|
||||
if(units > 0) {
|
||||
pathBuf[pathLen + units] = '\0';
|
||||
if(entry.attributes & FS_ATTRIBUTE_DIRECTORY) {
|
||||
if(pathLen + units < PATH_MAX - 2) {
|
||||
pathBuf[pathLen + units] = '/';
|
||||
pathBuf[pathLen + units + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
u32 entryCount = 0;
|
||||
FS_DirectoryEntry entry;
|
||||
u32 done = 0;
|
||||
while(R_SUCCEEDED(FSDIR_Read(handle, &entryCount, 1, &entry)) && entryCount > 0) {
|
||||
ssize_t units = utf16_to_utf8((uint8_t*) pathBuf + pathLen, entry.name, PATH_MAX - pathLen - 1);
|
||||
if(units > 0) {
|
||||
pathBuf[pathLen + units] = '\0';
|
||||
if(entry.attributes & FS_ATTRIBUTE_DIRECTORY) {
|
||||
if(pathLen + units < PATH_MAX - 2) {
|
||||
pathBuf[pathLen + units] = '/';
|
||||
pathBuf[pathLen + units + 1] = '\0';
|
||||
if(dirsFirst) {
|
||||
if(process != NULL && (filter == NULL || filter(data, archive, pathBuf, entry.attributes))) {
|
||||
process(data, archive, pathBuf, entry.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
if((entry.attributes & FS_ATTRIBUTE_DIRECTORY) && recursive) {
|
||||
if(R_FAILED(res = util_traverse_dir_internal(archive, pathBuf, recursive, dirsFirst, data, filter, process))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dirsFirst) {
|
||||
if(process != NULL && (filter == NULL || filter(data, archive, pathBuf, entry.attributes))) {
|
||||
process(data, archive, pathBuf, entry.attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done++;
|
||||
}
|
||||
|
||||
if(dirsFirst) {
|
||||
if(process != NULL && (filter == NULL || filter(data, archive, pathBuf, entry.attributes))) {
|
||||
process(data, archive, pathBuf, entry.attributes);
|
||||
}
|
||||
}
|
||||
|
||||
if((entry.attributes & FS_ATTRIBUTE_DIRECTORY) && recursive) {
|
||||
if(R_FAILED(res = util_traverse_dir_internal(archive, pathBuf, recursive, dirsFirst, data, filter, process))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dirsFirst) {
|
||||
if(process != NULL && (filter == NULL || filter(data, archive, pathBuf, entry.attributes))) {
|
||||
process(data, archive, pathBuf, entry.attributes);
|
||||
}
|
||||
}
|
||||
free(pathBuf);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
done++;
|
||||
FSDIR_Close(handle);
|
||||
}
|
||||
|
||||
free(pathBuf);
|
||||
|
||||
FSDIR_Close(handle);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -221,18 +232,21 @@ static Result util_traverse_file(FS_Archive* archive, const char* path, bool rec
|
||||
Result res = 0;
|
||||
|
||||
FS_Path* fsPath = util_make_path_utf8(path);
|
||||
if(fsPath != NULL) {
|
||||
Handle handle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenFile(&handle, *archive, *fsPath, FS_OPEN_READ, 0))) {
|
||||
if(process != NULL && (filter == NULL || filter(data, archive, path, 0))) {
|
||||
process(data, archive, path, 0);
|
||||
}
|
||||
|
||||
Handle handle = 0;
|
||||
if(R_SUCCEEDED(res = FSUSER_OpenFile(&handle, *archive, *fsPath, FS_OPEN_READ, 0))) {
|
||||
if(process != NULL && (filter == NULL || filter(data, archive, path, 0))) {
|
||||
process(data, archive, path, 0);
|
||||
FSFILE_Close(handle);
|
||||
}
|
||||
|
||||
FSFILE_Close(handle);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -331,6 +345,10 @@ static bool util_populate_contents_filter(void* data, FS_Archive* archive, const
|
||||
static void util_populate_contents_process(void* data, FS_Archive* archive, const char* path, u32 attributes) {
|
||||
u32 currPathSize = strlen(path) + 1;
|
||||
char* currPath = (char*) calloc(1, currPathSize);
|
||||
if(currPath == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy(currPath, path, currPathSize);
|
||||
|
||||
populate_data* populateData = (populate_data*) data;
|
||||
@ -345,6 +363,10 @@ Result util_populate_contents(char*** contentsOut, u32* countOut, FS_Archive* ar
|
||||
util_count_contents(countOut, archive, path, recursive, dirsFirst, data, filter);
|
||||
*contentsOut = (char**) calloc(*countOut, sizeof(char*));
|
||||
|
||||
if(*contentsOut == NULL) {
|
||||
return R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
populate_data populateData;
|
||||
populateData.contents = contentsOut;
|
||||
populateData.index = 0;
|
||||
@ -408,11 +430,14 @@ Result util_ensure_dir(FS_Archive* archive, const char* path) {
|
||||
|
||||
if(!util_is_dir(archive, path)) {
|
||||
FS_Path* fsPath = util_make_path_utf8(path);
|
||||
if(fsPath != NULL) {
|
||||
FSUSER_DeleteFile(*archive, *fsPath);
|
||||
res = FSUSER_CreateDirectory(*archive, *fsPath, 0);
|
||||
|
||||
FSUSER_DeleteFile(*archive, *fsPath);
|
||||
res = FSUSER_CreateDirectory(*archive, *fsPath, 0);
|
||||
|
||||
util_free_path_utf8(fsPath);
|
||||
util_free_path_utf8(fsPath);
|
||||
} else {
|
||||
res = R_FBI_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -422,9 +447,18 @@ FS_Path* util_make_path_utf8(const char* path) {
|
||||
size_t len = strlen(path);
|
||||
|
||||
u16* utf16 = (u16*) calloc(len + 1, sizeof(u16));
|
||||
if(utf16 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssize_t utf16Len = utf8_to_utf16(utf16, (const uint8_t*) path, len);
|
||||
|
||||
FS_Path* fsPath = (FS_Path*) calloc(1, sizeof(FS_Path));
|
||||
if(fsPath == NULL) {
|
||||
free(utf16);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fsPath->type = PATH_UTF16;
|
||||
fsPath->size = (utf16Len + 1) * sizeof(u16);
|
||||
fsPath->data = utf16;
|
||||
|
Loading…
x
Reference in New Issue
Block a user