Extend copy task into a generic data operation task.

This commit is contained in:
Steven Smith 2016-04-18 20:27:49 -07:00
parent 6702f4f267
commit 2c7ff25e78
10 changed files with 444 additions and 322 deletions

View File

@ -1,128 +0,0 @@
#include <malloc.h>
#include <stdio.h>
#include <3ds.h>
#include "action.h"
#include "../../error.h"
#include "../../progressbar.h"
#include "../../prompt.h"
#include "../../../screen.h"
#include "../task/task.h"
typedef struct {
pending_title_info* info;
bool* populated;
u64* titleIds;
u32 processed;
u32 total;
u32 sdTotal;
u32 nandTotal;
} delete_pending_titles_data;
static void action_delete_pending_titles_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
if(deleteData->info != NULL) {
ui_draw_pending_title_info(view, deleteData->info, x1, y1, x2, y2);
}
}
static void action_delete_pending_titles_free_data(delete_pending_titles_data* data) {
free(data->titleIds);
free(data);
}
static void action_delete_pending_titles_success_onresponse(ui_view* view, void* data, bool response) {
prompt_destroy(view);
action_delete_pending_titles_free_data((delete_pending_titles_data*) data);
}
static void action_delete_pending_titles_update(ui_view* view, void* data, float* progress, char* progressText) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
if(deleteData->processed >= deleteData->total) {
progressbar_destroy(view);
ui_pop();
ui_push(prompt_create("Success", "Pending title(s) deleted.", COLOR_TEXT, false, data, NULL, action_delete_pending_titles_draw_top, action_delete_pending_titles_success_onresponse));
return;
} else {
Result res = AM_DeletePendingTitle(deleteData->processed >= deleteData->sdTotal ? MEDIATYPE_NAND : MEDIATYPE_SD, deleteData->titleIds[deleteData->processed]);
if(R_FAILED(res)) {
progressbar_destroy(view);
ui_pop();
error_display_res(NULL, deleteData->info, deleteData->info != NULL ? ui_draw_pending_title_info : NULL, res, "Failed to delete pending title(s).");
action_delete_pending_titles_free_data(deleteData);
return;
} else {
*deleteData->populated = false;
deleteData->processed++;
}
}
*progress = deleteData->total > 0 ? (float) deleteData->processed / (float) deleteData->total : 0;
snprintf(progressText, PROGRESS_TEXT_MAX, "%lu / %lu", deleteData->processed, deleteData->total);
}
static void action_delete_pending_titles_onresponse(ui_view* view, void* data, bool response) {
prompt_destroy(view);
if(response) {
ui_push(progressbar_create("Deleting Pending Title(s)", "", data, action_delete_pending_titles_update, action_delete_pending_titles_draw_top));
} else {
action_delete_pending_titles_free_data((delete_pending_titles_data*) data);
}
}
void action_delete_pending_title(pending_title_info* info, bool* populated) {
delete_pending_titles_data* data = (delete_pending_titles_data*) calloc(1, sizeof(delete_pending_titles_data));
data->info = info;
data->populated = populated;
data->titleIds = (u64*) calloc(1, sizeof(u64));
data->titleIds[0] = info->titleId;
data->processed = 0;
data->total = 1;
data->sdTotal = info->mediaType == MEDIATYPE_SD ? 1 : 0;
data->nandTotal = info->mediaType == MEDIATYPE_NAND ? 1 : 0;
ui_push(prompt_create("Confirmation", "Delete the selected pending title?", COLOR_TEXT, true, data, NULL, action_delete_pending_titles_draw_top, action_delete_pending_titles_onresponse));
}
void action_delete_all_pending_titles(pending_title_info* info, bool* populated) {
delete_pending_titles_data* data = (delete_pending_titles_data*) calloc(1, sizeof(delete_pending_titles_data));
data->info = NULL;
data->populated = populated;
data->titleIds = NULL;
data->processed = 0;
data->total = 0;
data->sdTotal = 0;
data->nandTotal = 0;
Result res = 0;
if(R_FAILED(res = AM_GetPendingTitleCount(&data->sdTotal, MEDIATYPE_SD, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION)) || R_FAILED(res = AM_GetPendingTitleCount(&data->nandTotal, MEDIATYPE_NAND, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION))) {
error_display_res(NULL, NULL, NULL, res, "Failed to retrieve pending title count.");
free(data);
return;
}
data->total = data->sdTotal + data->nandTotal;
data->titleIds = (u64*) calloc(data->total, sizeof(u64));
if(R_FAILED(res = AM_GetPendingTitleList(&data->sdTotal, data->sdTotal, MEDIATYPE_SD, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION, data->titleIds)) || R_FAILED(res = AM_GetPendingTitleList(&data->nandTotal, data->nandTotal, MEDIATYPE_NAND, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION, &data->titleIds[data->sdTotal]))) {
error_display_res(NULL, NULL, NULL, res, "Failed to retrieve pending title list.");
free(data->titleIds);
free(data);
return;
}
ui_push(prompt_create("Confirmation", "Delete all pending titles?", COLOR_TEXT, true, data, NULL, action_delete_pending_titles_draw_top, action_delete_pending_titles_onresponse));
}

View File

@ -10,21 +10,83 @@
#include "../../prompt.h"
#include "../../../screen.h"
#include "../../../util.h"
#include "../task/task.h"
typedef struct {
file_info* base;
bool* populated;
u32 processed;
u32 total;
char** contents;
data_op_info deleteInfo;
Handle cancelEvent;
} delete_contents_data;
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);
return res;
}
static bool action_delete_contents_result_error(void* data, u32 index, Result res) {
delete_contents_data* deleteData = (delete_contents_data*) data;
if(res == MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_CANCEL_REQUESTED)) {
ui_push(prompt_create("Failure", "Delete cancelled.", COLOR_TEXT, false, deleteData->base, NULL, ui_draw_file_info, NULL));
return false;
} else {
char* path = deleteData->contents[index];
volatile bool dismissed = false;
if(strlen(path) > 48) {
error_display_res(&dismissed, deleteData->base, ui_draw_file_info, res, "Failed to delete content.\n%.45s...", path);
} else {
error_display_res(&dismissed, deleteData->base, ui_draw_file_info, res, "Failed to delete content.\n%.48s", path);
}
while(!dismissed) {
svcSleepThread(1000000);
}
}
return index < deleteData->deleteInfo.total - 1;
}
static bool action_delete_contents_io_error(void* data, u32 index, int err) {
delete_contents_data* deleteData = (delete_contents_data*) data;
char* path = deleteData->contents[index];
volatile bool dismissed = false;
if(strlen(path) > 48) {
error_display_errno(&dismissed, deleteData->base, ui_draw_file_info, err, "Failed to delete content.\n%.45s...", path);
} else {
error_display_errno(&dismissed, deleteData->base, ui_draw_file_info, err, "Failed to delete content.\n%.48s", path);
}
while(!dismissed) {
svcSleepThread(1000000);
}
return index < deleteData->deleteInfo.total - 1;
}
static void action_delete_contents_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2) {
ui_draw_file_info(view, ((delete_contents_data*) data)->base, x1, y1, x2, y2);
}
static void action_delete_contents_free_data(delete_contents_data* data) {
util_free_contents(data->contents, data->total);
util_free_contents(data->contents, data->deleteInfo.total);
free(data);
}
@ -37,142 +99,91 @@ static void action_delete_contents_done_onresponse(ui_view* view, void* data, bo
static void action_delete_contents_update(ui_view* view, void* data, float* progress, char* progressText) {
delete_contents_data* deleteData = (delete_contents_data*) data;
if(deleteData->deleteInfo.finished) {
*deleteData->populated = false;
if(deleteData->base->archive->id == ARCHIVE_USER_SAVEDATA) {
FSUSER_ControlArchive(*deleteData->base->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
}
progressbar_destroy(view);
ui_pop();
if(deleteData->deleteInfo.premature) {
action_delete_contents_free_data(deleteData);
} else {
ui_push(prompt_create("Success", "Contents deleted.", COLOR_TEXT, false, data, NULL, action_delete_contents_draw_top, action_delete_contents_done_onresponse));
}
return;
}
if(hidKeysDown() & KEY_B) {
progressbar_destroy(view);
ui_pop();
ui_push(prompt_create("Failure", "Delete cancelled.", COLOR_TEXT, false, data, NULL, action_delete_contents_draw_top, action_delete_contents_done_onresponse));
return;
svcSignalEvent(deleteData->cancelEvent);
}
if(deleteData->processed >= deleteData->total) {
progressbar_destroy(view);
ui_pop();
ui_push(prompt_create("Success", "Contents deleted.", COLOR_TEXT, false, data, NULL, action_delete_contents_draw_top, action_delete_contents_done_onresponse));
return;
} else {
FS_Archive* archive = deleteData->base->archive;
char* path = deleteData->contents[deleteData->processed];
FS_Path* fsPath = util_make_path_utf8(path);
Result res = 0;
if(util_is_dir(archive, path)) {
res = FSUSER_DeleteDirectory(*archive, *fsPath);
} else {
res = FSUSER_DeleteFile(*archive, *fsPath);
}
util_free_path_utf8(fsPath);
if(R_SUCCEEDED(res) && archive->id == ARCHIVE_USER_SAVEDATA) {
res = FSUSER_ControlArchive(*archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
}
if(R_FAILED(res)) {
if(deleteData->processed >= deleteData->total - 1) {
ui_pop();
}
if(strlen(path) > 48) {
error_display_res(NULL, deleteData->base, ui_draw_file_info, res, "Failed to delete content.\n%.45s...", path);
} else {
error_display_res(NULL, deleteData->base, ui_draw_file_info, res, "Failed to delete content.\n%.48s", path);
}
if(deleteData->processed >= deleteData->total - 1) {
action_delete_contents_free_data(deleteData);
progressbar_destroy(view);
return;
}
} else {
*deleteData->populated = false;
}
deleteData->processed++;
}
*progress = deleteData->total > 0 ? (float) deleteData->processed / (float) deleteData->total : 0;
snprintf(progressText, PROGRESS_TEXT_MAX, "%lu / %lu", deleteData->processed, deleteData->total);
*progress = deleteData->deleteInfo.total > 0 ? (float) deleteData->deleteInfo.processed / (float) deleteData->deleteInfo.total : 0;
snprintf(progressText, PROGRESS_TEXT_MAX, "%lu / %lu", deleteData->deleteInfo.processed, deleteData->deleteInfo.total);
}
static void action_delete_contents_onresponse(ui_view* view, void* data, bool response) {
prompt_destroy(view);
delete_contents_data* deleteData = (delete_contents_data*) data;
if(response) {
ui_view* progressView = progressbar_create("Deleting Contents", "Press B to cancel.", data, action_delete_contents_update, action_delete_contents_draw_top);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", ((delete_contents_data*) data)->total);
ui_push(progressView);
deleteData->cancelEvent = task_data_op(&deleteData->deleteInfo);
if(deleteData->cancelEvent != 0) {
ui_view* progressView = progressbar_create("Deleting Contents", "Press B to cancel.", data, action_delete_contents_update, action_delete_contents_draw_top);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", deleteData->deleteInfo.total);
ui_push(progressView);
} else {
error_display(NULL, NULL, NULL, "Failed to initiate delete operation.");
}
} else {
action_delete_contents_free_data((delete_contents_data*) data);
action_delete_contents_free_data(deleteData);
}
}
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));
data->base = info;
data->populated = populated;
data->deleteInfo.data = data;
data->deleteInfo.op = DATAOP_DELETE;
data->deleteInfo.delete = action_delete_contents_delete;
data->deleteInfo.resultError = action_delete_contents_result_error;
data->deleteInfo.ioError = action_delete_contents_io_error;
data->cancelEvent = 0;
Result res = 0;
if(R_FAILED(res = util_populate_contents(&data->contents, &data->deleteInfo.total, info->archive, info->path, recursive, false, filterData, filter))) {
error_display_res(NULL, info, ui_draw_file_info, res, "Failed to retrieve content list.");
free(data);
return;
}
ui_push(prompt_create("Confirmation", message, COLOR_TEXT, true, data, NULL, action_delete_contents_draw_top, action_delete_contents_onresponse));
}
void action_delete_contents(file_info* info, bool* populated) {
delete_contents_data* data = (delete_contents_data*) calloc(1, sizeof(delete_contents_data));
data->base = info;
data->populated = populated;
data->processed = 0;
Result res = 0;
if(R_FAILED(res = util_populate_contents(&data->contents, &data->total, info->archive, info->path, true, false, NULL, NULL))) {
error_display_res(NULL, info, ui_draw_file_info, res, "Failed to retrieve content list.");
free(data);
return;
}
ui_push(prompt_create("Confirmation", "Delete the selected content?", COLOR_TEXT, true, data, NULL, action_delete_contents_draw_top, action_delete_contents_onresponse));
action_delete_contents_internal(info, populated, "Delete the selected content?", true, NULL, NULL);
}
void action_delete_dir(file_info* info, bool* populated) {
delete_contents_data* data = (delete_contents_data*) calloc(1, sizeof(delete_contents_data));
data->base = info;
data->populated = populated;
data->processed = 0;
Result res = 0;
if(R_FAILED(res = util_populate_contents(&data->contents, &data->total, info->archive, info->path, true, false, NULL, NULL))) {
error_display_res(NULL, info, ui_draw_file_info, res, "Failed to retrieve content list.");
free(data);
return;
}
ui_push(prompt_create("Confirmation", "Delete the current directory?", COLOR_TEXT, true, data, NULL, action_delete_contents_draw_top, action_delete_contents_onresponse));
action_delete_contents_internal(info, populated, "Delete the current directory?", true, NULL, NULL);
}
void action_delete_dir_contents(file_info* info, bool* populated) {
delete_contents_data* data = (delete_contents_data*) calloc(1, sizeof(delete_contents_data));
data->base = info;
data->populated = populated;
data->processed = 0;
Result res = 0;
if(R_FAILED(res = util_populate_contents(&data->contents, &data->total, info->archive, info->path, true, false, info->path, util_filter_not_path))) {
error_display_res(NULL, info, ui_draw_file_info, res, "Failed to retrieve content list.");
free(data);
return;
}
ui_push(prompt_create("Confirmation", "Delete all contents of the current directory?", COLOR_TEXT, true, data, NULL, action_delete_contents_draw_top, action_delete_contents_onresponse));
action_delete_contents_internal(info, populated, "Delete all contents of the current directory?", true, info->path, util_filter_not_path);
}
void action_delete_dir_cias(file_info* info, bool* populated) {
delete_contents_data* data = (delete_contents_data*) calloc(1, sizeof(delete_contents_data));
data->base = info;
data->populated = populated;
data->processed = 0;
Result res = 0;
if(R_FAILED(res = util_populate_contents(&data->contents, &data->total, info->archive, info->path, false, false, ".cia", util_filter_file_extension))) {
error_display_res(NULL, info, ui_draw_file_info, res, "Failed to retrieve content list.");
free(data);
return;
}
ui_push(prompt_create("Confirmation", "Delete all CIAs in the current directory?", COLOR_TEXT, true, data, NULL, action_delete_contents_draw_top, action_delete_contents_onresponse));
action_delete_contents_internal(info, populated, "Delete all CIAs in the current directory?", false, ".cia", util_filter_file_extension);
}

View File

@ -0,0 +1,187 @@
#include <malloc.h>
#include <stdio.h>
#include <3ds.h>
#include "action.h"
#include "../../error.h"
#include "../../progressbar.h"
#include "../../prompt.h"
#include "../../../screen.h"
#include "../task/task.h"
typedef struct {
pending_title_info* info;
bool* populated;
u64* titleIds;
u32 sdTotal;
u32 nandTotal;
data_op_info deleteInfo;
Handle cancelEvent;
} delete_pending_titles_data;
static Result action_delete_pending_titles_delete(void* data, u32 index) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
Result res = 0;
if(R_SUCCEEDED(res = AM_DeletePendingTitle(index >= deleteData->sdTotal ? MEDIATYPE_NAND : MEDIATYPE_SD, deleteData->titleIds[index]))) {
*deleteData->populated = false;
}
return res;
}
static bool action_delete_pending_titles_result_error(void* data, u32 index, Result res) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
if(res == MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_CANCEL_REQUESTED)) {
ui_push(prompt_create("Failure", "Delete cancelled.", COLOR_TEXT, false, deleteData->info, NULL, deleteData->info != NULL ? ui_draw_pending_title_info : NULL, NULL));
return false;
} else {
u64 titleId = deleteData->titleIds[index];
volatile bool dismissed = false;
error_display_res(&dismissed, deleteData->info, deleteData->info != NULL ? ui_draw_pending_title_info : NULL, res, "Failed to delete pending title.\n%llX", titleId);
while(!dismissed) {
svcSleepThread(1000000);
}
}
return index < deleteData->deleteInfo.total - 1;
}
static bool action_delete_pending_titles_io_error(void* data, u32 index, int err) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
u64 titleId = deleteData->titleIds[index];
volatile bool dismissed = false;
error_display_errno(&dismissed, deleteData->info, deleteData->info != NULL ? ui_draw_pending_title_info : NULL, err, "Failed to delete pending title.\n%llX", titleId);
while(!dismissed) {
svcSleepThread(1000000);
}
return index < deleteData->deleteInfo.total - 1;
}
static void action_delete_pending_titles_draw_top(ui_view* view, void* data, float x1, float y1, float x2, float y2) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
if(deleteData->info != NULL) {
ui_draw_pending_title_info(view, deleteData->info, x1, y1, x2, y2);
}
}
static void action_delete_pending_titles_free_data(delete_pending_titles_data* data) {
free(data->titleIds);
free(data);
}
static void action_delete_pending_titles_success_onresponse(ui_view* view, void* data, bool response) {
prompt_destroy(view);
action_delete_pending_titles_free_data((delete_pending_titles_data*) data);
}
static void action_delete_pending_titles_update(ui_view* view, void* data, float* progress, char* progressText) {
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
if(deleteData->deleteInfo.finished) {
progressbar_destroy(view);
ui_pop();
if(deleteData->deleteInfo.premature) {
action_delete_pending_titles_free_data(deleteData);
} else {
ui_push(prompt_create("Success", "Pending title(s) deleted.", COLOR_TEXT, false, data, NULL, action_delete_pending_titles_draw_top, action_delete_pending_titles_success_onresponse));
}
return;
}
if(hidKeysDown() & KEY_B) {
svcSignalEvent(deleteData->cancelEvent);
}
*progress = deleteData->deleteInfo.total > 0 ? (float) deleteData->deleteInfo.processed / (float) deleteData->deleteInfo.total : 0;
snprintf(progressText, PROGRESS_TEXT_MAX, "%lu / %lu", deleteData->deleteInfo.processed, deleteData->deleteInfo.total);
}
static void action_delete_pending_titles_onresponse(ui_view* view, void* data, bool response) {
prompt_destroy(view);
delete_pending_titles_data* deleteData = (delete_pending_titles_data*) data;
if(response) {
deleteData->cancelEvent = task_data_op(&deleteData->deleteInfo);
if(deleteData->cancelEvent != 0) {
ui_view* progressView = progressbar_create("Deleting Pending Title(s)", "Press B to cancel.", data, action_delete_pending_titles_update, action_delete_pending_titles_draw_top);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", deleteData->deleteInfo.total);
ui_push(progressView);
} else {
error_display(NULL, NULL, NULL, "Failed to initiate delete operation.");
}
} else {
action_delete_pending_titles_free_data(deleteData);
}
}
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));
data->info = info;
data->populated = populated;
data->titleIds = titleIds;
data->sdTotal = sdTotal;
data->nandTotal = nandTotal;
data->deleteInfo.data = data;
data->deleteInfo.op = DATAOP_DELETE;
data->deleteInfo.total = sdTotal + nandTotal;
data->deleteInfo.delete = action_delete_pending_titles_delete;
data->deleteInfo.resultError = action_delete_pending_titles_result_error;
data->deleteInfo.ioError = action_delete_pending_titles_io_error;
data->cancelEvent = 0;
ui_push(prompt_create("Confirmation", message, COLOR_TEXT, true, data, NULL, action_delete_pending_titles_draw_top, action_delete_pending_titles_onresponse));
}
void action_delete_pending_title(pending_title_info* info, bool* populated) {
u64* titleIds = (u64*) calloc(1, sizeof(u64));
titleIds[0] = info->titleId;
u32 sdTotal = info->mediaType == MEDIATYPE_SD ? 1 : 0;
u32 nandTotal = info->mediaType == MEDIATYPE_NAND ? 1 : 0;
action_delete_pending_titles(info, populated, "Delete the selected pending title?", titleIds, sdTotal, nandTotal);
}
void action_delete_all_pending_titles(pending_title_info* info, bool* populated) {
u32 sdTotal = 0;
u32 nandTotal = 0;
Result res = 0;
if(R_FAILED(res = AM_GetPendingTitleCount(&sdTotal, MEDIATYPE_SD, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION)) || R_FAILED(res = AM_GetPendingTitleCount(&nandTotal, MEDIATYPE_NAND, AM_STATUS_MASK_INSTALLING | AM_STATUS_MASK_AWAITING_FINALIZATION))) {
error_display_res(NULL, NULL, NULL, res, "Failed to retrieve pending title count.");
return;
}
u64* titleIds = (u64*) calloc(sdTotal + nandTotal, sizeof(u64));
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.");
free(titleIds);
return;
}
action_delete_pending_titles(info, populated, "Delete all pending titles?", titleIds, sdTotal, nandTotal);
}

View File

@ -20,20 +20,20 @@ typedef struct {
u64 currTitleId;
copy_data_info installInfo;
data_op_info installInfo;
Handle cancelEvent;
} install_cias_data;
Result action_install_cias_is_src_directory(void* data, u32 index, bool* isDirectory) {
static Result action_install_cias_is_src_directory(void* data, u32 index, bool* isDirectory) {
*isDirectory = false;
return 0;
}
Result action_install_cias_make_dst_directory(void* data, u32 index) {
static Result action_install_cias_make_dst_directory(void* data, u32 index) {
return 0;
}
Result action_install_cias_open_src(void* data, u32 index, u32* handle) {
static Result action_install_cias_open_src(void* data, u32 index, u32* handle) {
install_cias_data* installData = (install_cias_data*) data;
FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
@ -45,7 +45,7 @@ Result action_install_cias_open_src(void* data, u32 index, u32* handle) {
return res;
}
Result action_install_cias_close_src(void* data, u32 index, bool succeeded, u32 handle) {
static Result action_install_cias_close_src(void* data, u32 index, bool succeeded, u32 handle) {
install_cias_data* installData = (install_cias_data*) data;
Result res = 0;
@ -60,15 +60,15 @@ Result action_install_cias_close_src(void* data, u32 index, bool succeeded, u32
return res;
}
Result action_install_cias_get_src_size(void* data, u32 handle, u64* size) {
static Result action_install_cias_get_src_size(void* data, u32 handle, u64* size) {
return FSFILE_GetSize(handle, size);
}
Result action_install_cias_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
static Result action_install_cias_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
return FSFILE_Read(handle, bytesRead, offset, buffer, size);
}
Result action_install_cias_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
static Result action_install_cias_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
install_cias_data* installData = (install_cias_data*) data;
u8* buffer = (u8*) initialReadBlock;
@ -102,7 +102,7 @@ Result action_install_cias_open_dst(void* data, u32 index, void* initialReadBloc
return res;
}
Result action_install_cias_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
static Result action_install_cias_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
if(succeeded) {
install_cias_data* installData = (install_cias_data*) data;
@ -119,7 +119,7 @@ Result action_install_cias_close_dst(void* data, u32 index, bool succeeded, u32
}
}
Result action_install_cias_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
static Result action_install_cias_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
return FSFILE_Write(handle, bytesWritten, offset, buffer, size, 0);
}
@ -223,7 +223,7 @@ static void action_install_cias_onresponse(ui_view* view, void* data, bool respo
install_cias_data* installData = (install_cias_data*) data;
if(response) {
installData->cancelEvent = task_copy_data(&installData->installInfo);
installData->cancelEvent = task_data_op(&installData->installInfo);
if(installData->cancelEvent != 0) {
ui_view* progressView = progressbar_create("Installing CIA(s)", "Press B to cancel.", data, action_install_cias_update, action_install_cias_draw_top);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", installData->installInfo.total);
@ -248,6 +248,8 @@ static void action_install_cias_internal(file_info* info, bool* populated, bool
data->installInfo.data = data;
data->installInfo.op = DATAOP_COPY;
data->installInfo.copyEmpty = false;
data->installInfo.isSrcDirectory = action_install_cias_is_src_directory;

View File

@ -16,20 +16,20 @@ typedef struct {
file_info* base;
char** contents;
copy_data_info installInfo;
data_op_info installInfo;
Handle cancelEvent;
} install_tickets_data;
Result action_install_tickets_is_src_directory(void* data, u32 index, bool* isDirectory) {
static Result action_install_tickets_is_src_directory(void* data, u32 index, bool* isDirectory) {
*isDirectory = false;
return 0;
}
Result action_install_tickets_make_dst_directory(void* data, u32 index) {
static Result action_install_tickets_make_dst_directory(void* data, u32 index) {
return 0;
}
Result action_install_tickets_open_src(void* data, u32 index, u32* handle) {
static Result action_install_tickets_open_src(void* data, u32 index, u32* handle) {
install_tickets_data* installData = (install_tickets_data*) data;
FS_Path* fsPath = util_make_path_utf8(installData->contents[index]);
@ -41,23 +41,23 @@ Result action_install_tickets_open_src(void* data, u32 index, u32* handle) {
return res;
}
Result action_install_tickets_close_src(void* data, u32 index, bool succeeded, u32 handle) {
static Result action_install_tickets_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
Result action_install_tickets_get_src_size(void* data, u32 handle, u64* size) {
static Result action_install_tickets_get_src_size(void* data, u32 handle, u64* size) {
return FSFILE_GetSize(handle, size);
}
Result action_install_tickets_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
static Result action_install_tickets_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
return FSFILE_Read(handle, bytesRead, offset, buffer, size);
}
Result action_install_tickets_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
static Result action_install_tickets_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
return AM_InstallTicketBegin(handle);
}
Result action_install_tickets_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
static Result action_install_tickets_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
if(succeeded) {
return AM_InstallTicketFinalize(handle);
} else {
@ -65,11 +65,11 @@ Result action_install_tickets_close_dst(void* data, u32 index, bool succeeded, u
}
}
Result action_install_tickets_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
static Result action_install_tickets_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
return FSFILE_Write(handle, bytesWritten, offset, buffer, size, 0);
}
bool action_install_tickets_result_error(void* data, u32 index, Result res) {
static bool action_install_tickets_result_error(void* data, u32 index, Result res) {
install_tickets_data* installData = (install_tickets_data*) data;
if(res == MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_CANCEL_REQUESTED)) {
@ -93,7 +93,7 @@ bool action_install_tickets_result_error(void* data, u32 index, Result res) {
return index < installData->installInfo.total - 1;
}
bool action_install_tickets_io_error(void* data, u32 index, int err) {
static bool action_install_tickets_io_error(void* data, u32 index, int err) {
install_tickets_data* installData = (install_tickets_data*) data;
char* path = installData->contents[index];
@ -157,7 +157,7 @@ static void action_install_tickets_onresponse(ui_view* view, void* data, bool re
install_tickets_data* installData = (install_tickets_data*) data;
if(response) {
installData->cancelEvent = task_copy_data(&installData->installInfo);
installData->cancelEvent = task_data_op(&installData->installInfo);
if(installData->cancelEvent != 0) {
ui_view* progressView = progressbar_create("Installing ticket(s)", "Press B to cancel.", data, action_install_tickets_update, action_install_tickets_draw_top);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", installData->installInfo.total);
@ -178,6 +178,8 @@ void action_install_tickets(file_info* info, bool* populated) {
data->installInfo.data = data;
data->installInfo.op = DATAOP_COPY;
data->installInfo.copyEmpty = false;
data->installInfo.isSrcDirectory = action_install_tickets_is_src_directory;

View File

@ -18,7 +18,7 @@ typedef struct {
bool* populated;
char** contents;
copy_data_info pasteInfo;
data_op_info pasteInfo;
Handle cancelEvent;
} paste_files_data;
@ -34,14 +34,14 @@ static void action_paste_files_get_dst_path(paste_files_data* data, u32 index, c
snprintf(dstPath, PATH_MAX, "%s%s", baseDstPath, data->contents[index] + strlen(dstPath));
}
Result action_paste_files_is_src_directory(void* data, u32 index, bool* isDirectory) {
static Result action_paste_files_is_src_directory(void* data, u32 index, bool* isDirectory) {
paste_files_data* pasteData = (paste_files_data*) data;
*isDirectory = util_is_dir(pasteData->base->archive, pasteData->contents[index]);
return 0;
}
Result action_paste_files_make_dst_directory(void* data, u32 index) {
static Result action_paste_files_make_dst_directory(void* data, u32 index) {
paste_files_data* pasteData = (paste_files_data*) data;
char dstPath[PATH_MAX];
@ -56,7 +56,7 @@ Result action_paste_files_make_dst_directory(void* data, u32 index) {
return res;
}
Result action_paste_files_open_src(void* data, u32 index, u32* handle) {
static Result action_paste_files_open_src(void* data, u32 index, u32* handle) {
paste_files_data* pasteData = (paste_files_data*) data;
FS_Path* fsPath = util_make_path_utf8(pasteData->contents[index]);
@ -68,19 +68,19 @@ Result action_paste_files_open_src(void* data, u32 index, u32* handle) {
return res;
}
Result action_paste_files_close_src(void* data, u32 index, bool succeeded, u32 handle) {
static Result action_paste_files_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
Result action_paste_files_get_src_size(void* data, u32 handle, u64* size) {
static Result action_paste_files_get_src_size(void* data, u32 handle, u64* size) {
return FSFILE_GetSize(handle, size);
}
Result action_paste_files_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
static Result action_paste_files_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
return FSFILE_Read(handle, bytesRead, offset, buffer, size);
}
Result action_paste_files_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
static Result action_paste_files_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
paste_files_data* pasteData = (paste_files_data*) data;
char dstPath[PATH_MAX];
@ -95,15 +95,15 @@ Result action_paste_files_open_dst(void* data, u32 index, void* initialReadBlock
return res;
}
Result action_paste_files_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
static Result action_paste_files_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
Result action_paste_files_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
static Result action_paste_files_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
return FSFILE_Write(handle, bytesWritten, offset, buffer, size, 0);
}
bool action_paste_files_result_error(void* data, u32 index, Result res) {
static bool action_paste_files_result_error(void* data, u32 index, Result res) {
paste_files_data* pasteData = (paste_files_data*) data;
if(res == MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_CANCEL_REQUESTED)) {
@ -127,7 +127,7 @@ bool action_paste_files_result_error(void* data, u32 index, Result res) {
return index < pasteData->pasteInfo.total - 1;
}
bool action_paste_files_io_error(void* data, u32 index, int err) {
static bool action_paste_files_io_error(void* data, u32 index, int err) {
paste_files_data* pasteData = (paste_files_data*) data;
char* path = pasteData->contents[index];
@ -171,6 +171,10 @@ static void action_paste_files_update(ui_view* view, void* data, float* progress
if(pasteData->pasteInfo.finished) {
*pasteData->populated = false;
if(pasteData->base->archive->id == ARCHIVE_USER_SAVEDATA) {
FSUSER_ControlArchive(*pasteData->base->archive, ARCHIVE_ACTION_COMMIT_SAVE_DATA, NULL, 0, NULL, 0);
}
ui_pop();
progressbar_destroy(view);
@ -196,7 +200,7 @@ static void action_paste_files_onresponse(ui_view* view, void* data, bool respon
paste_files_data* pasteData = (paste_files_data*) data;
if(response) {
pasteData->cancelEvent = task_copy_data(&pasteData->pasteInfo);
pasteData->cancelEvent = task_data_op(&pasteData->pasteInfo);
if(pasteData->cancelEvent != 0) {
ui_view* progressView = progressbar_create("Pasting Contents", "Press B to cancel.", data, action_paste_files_update, action_paste_files_draw_top);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", ((paste_files_data*) data)->pasteInfo.total);
@ -221,6 +225,8 @@ void action_paste_contents(file_info* info, bool* populated) {
data->pasteInfo.data = data;
data->pasteInfo.op = DATAOP_COPY;
data->pasteInfo.copyEmpty = true;
data->pasteInfo.isSrcDirectory = action_paste_files_is_src_directory;

View File

@ -10,50 +10,50 @@
#include "../../screen.h"
typedef struct {
copy_data_info dumpInfo;
data_op_info dumpInfo;
Handle cancelEvent;
} dump_nand_data;
Result dumpnand_is_src_directory(void* data, u32 index, bool* isDirectory) {
static Result dumpnand_is_src_directory(void* data, u32 index, bool* isDirectory) {
*isDirectory = false;
return 0;
}
Result dumpnand_make_dst_directory(void* data, u32 index) {
static Result dumpnand_make_dst_directory(void* data, u32 index) {
return 0;
}
Result dumpnand_open_src(void* data, u32 index, u32* handle) {
static Result dumpnand_open_src(void* data, u32 index, u32* handle) {
FS_Archive wnandArchive = {ARCHIVE_NAND_W_FS, fsMakePath(PATH_EMPTY, "")};
return FSUSER_OpenFileDirectly(handle, wnandArchive, fsMakePath(PATH_UTF16, u"/"), FS_OPEN_READ, 0);
}
Result dumpnand_close_src(void* data, u32 index, bool succeeded, u32 handle) {
static Result dumpnand_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
Result dumpnand_get_src_size(void* data, u32 handle, u64* size) {
static Result dumpnand_get_src_size(void* data, u32 handle, u64* size) {
return FSFILE_GetSize(handle, size);
}
Result dumpnand_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 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);
}
Result dumpnand_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
static Result dumpnand_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
FS_Archive sdmcArchive = {ARCHIVE_SDMC, {PATH_BINARY, 0, (u8*) ""}};
return FSUSER_OpenFileDirectly(handle, sdmcArchive, fsMakePath(PATH_UTF16, u"/NAND.bin"), FS_OPEN_WRITE | FS_OPEN_CREATE, 0);
}
Result dumpnand_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
static Result dumpnand_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
return FSFILE_Close(handle);
}
Result dumpnand_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
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);
}
bool dumpnand_result_error(void* data, u32 index, Result res) {
static bool dumpnand_result_error(void* data, u32 index, Result res) {
if(res == MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_CANCEL_REQUESTED)) {
ui_push(prompt_create("Failure", "Dump cancelled.", COLOR_TEXT, false, NULL, NULL, NULL, NULL));
} else {
@ -63,7 +63,7 @@ bool dumpnand_result_error(void* data, u32 index, Result res) {
return false;
}
bool dumpnand_io_error(void* data, u32 index, int err) {
static bool dumpnand_io_error(void* data, u32 index, int err) {
error_display_errno(NULL, NULL, NULL, err, "Failed to dump NAND.");
return false;
}
@ -102,7 +102,7 @@ static void dumpnand_onresponse(ui_view* view, void* data, bool response) {
if(response) {
dump_nand_data* dumpData = (dump_nand_data*) data;
dumpData->cancelEvent = task_copy_data(&dumpData->dumpInfo);
dumpData->cancelEvent = task_data_op(&dumpData->dumpInfo);
if(dumpData->cancelEvent != 0) {
ui_push(progressbar_create("Dumping NAND", "Press B to cancel.", data, dumpnand_update, NULL));
} else {
@ -118,6 +118,8 @@ void dump_nand() {
data->dumpInfo.data = data;
data->dumpInfo.op = DATAOP_COPY;
data->dumpInfo.copyEmpty = true;
data->dumpInfo.total = 1;

View File

@ -23,7 +23,7 @@ typedef struct {
u64 currTitleId;
copy_data_info installInfo;
data_op_info installInfo;
Handle cancelEvent;
} network_install_data;
@ -51,16 +51,16 @@ static int sendwait(int sockfd, void* buf, size_t len, int flags) {
return ret < 0 ? ret : (int) written;
}
Result networkinstall_is_src_directory(void* data, u32 index, bool* isDirectory) {
static Result networkinstall_is_src_directory(void* data, u32 index, bool* isDirectory) {
*isDirectory = false;
return 0;
}
Result networkinstall_make_dst_directory(void* data, u32 index) {
static Result networkinstall_make_dst_directory(void* data, u32 index) {
return 0;
}
Result networkinstall_open_src(void* data, u32 index, u32* handle) {
static Result networkinstall_open_src(void* data, u32 index, u32* handle) {
network_install_data* networkInstallData = (network_install_data*) data;
u8 ack = 1;
@ -71,11 +71,11 @@ Result networkinstall_open_src(void* data, u32 index, u32* handle) {
return 0;
}
Result networkinstall_close_src(void* data, u32 index, bool succeeded, u32 handle) {
static Result networkinstall_close_src(void* data, u32 index, bool succeeded, u32 handle) {
return 0;
}
Result networkinstall_get_src_size(void* data, u32 handle, u64* size) {
static Result networkinstall_get_src_size(void* data, u32 handle, u64* size) {
network_install_data* networkInstallData = (network_install_data*) data;
u64 netSize = 0;
@ -87,7 +87,7 @@ Result networkinstall_get_src_size(void* data, u32 handle, u64* size) {
return 0;
}
Result networkinstall_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
static Result networkinstall_read_src(void* data, u32 handle, u32* bytesRead, void* buffer, u64 offset, u32 size) {
network_install_data* networkInstallData = (network_install_data*) data;
int ret = 0;
@ -99,7 +99,7 @@ Result networkinstall_read_src(void* data, u32 handle, u32* bytesRead, void* buf
return 0;
}
Result networkinstall_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
static Result networkinstall_open_dst(void* data, u32 index, void* initialReadBlock, u32* handle) {
network_install_data* networkInstallData = (network_install_data*) data;
u8* buffer = (u8*) initialReadBlock;
@ -133,7 +133,7 @@ Result networkinstall_open_dst(void* data, u32 index, void* initialReadBlock, u3
return res;
}
Result networkinstall_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
static Result networkinstall_close_dst(void* data, u32 index, bool succeeded, u32 handle) {
if(succeeded) {
network_install_data* networkInstallData = (network_install_data*) data;
@ -150,11 +150,11 @@ Result networkinstall_close_dst(void* data, u32 index, bool succeeded, u32 handl
}
}
Result networkinstall_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
static Result networkinstall_write_dst(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size) {
return FSFILE_Write(handle, bytesWritten, offset, buffer, size, 0);
}
bool networkinstall_result_error(void* data, u32 index, Result res) {
static bool networkinstall_result_error(void* data, u32 index, Result res) {
network_install_data* networkInstallData = (network_install_data*) data;
if(res == MAKERESULT(RL_PERMANENT, RS_CANCELED, RM_APPLICATION, RD_CANCEL_REQUESTED)) {
@ -176,7 +176,7 @@ bool networkinstall_result_error(void* data, u32 index, Result res) {
return index < networkInstallData->installInfo.total - 1;
}
bool networkinstall_io_error(void* data, u32 index, int err) {
static bool networkinstall_io_error(void* data, u32 index, int err) {
network_install_data* networkInstallData = (network_install_data*) data;
volatile bool dismissed = false;
@ -232,7 +232,7 @@ static void networkinstall_confirm_onresponse(ui_view* view, void* data, bool re
network_install_data* networkInstallData = (network_install_data*) data;
if(response) {
networkInstallData->cancelEvent = task_copy_data(&networkInstallData->installInfo);
networkInstallData->cancelEvent = task_data_op(&networkInstallData->installInfo);
if(networkInstallData->cancelEvent != 0) {
ui_view* progressView = progressbar_create("Installing CIA(s)", "Press B to cancel.", data, networkinstall_install_update, NULL);
snprintf(progressbar_get_progress_text(progressView), PROGRESS_TEXT_MAX, "0 / %lu", networkInstallData->installInfo.total);
@ -335,6 +335,8 @@ void networkinstall_open() {
data->installInfo.data = data;
data->installInfo.op = DATAOP_COPY;
data->installInfo.copyEmpty = false;
data->installInfo.isSrcDirectory = networkinstall_is_src_directory;

View File

@ -9,12 +9,12 @@
#include "task.h"
typedef struct {
copy_data_info* info;
data_op_info* info;
Handle cancelEvent;
} copy_data_data;
} data_op_data;
static bool task_copy_data_item(copy_data_data* data, u32 index) {
static bool task_data_op_copy(data_op_data* data, u32 index) {
data->info->currProcessed = 0;
data->info->currTotal = 0;
@ -105,8 +105,21 @@ static bool task_copy_data_item(copy_data_data* data, u32 index) {
return true;
}
static void task_copy_data_thread(void* arg) {
copy_data_data* data = (copy_data_data*) arg;
static bool task_data_op_delete(data_op_data* data, u32 index) {
Result res = 0;
if(R_FAILED(res = data->info->delete(data->info->data, index))) {
if(res == -1) {
return data->info->ioError(data->info->data, index, errno);
} else {
return data->info->resultError(data->info->data, index, res);
}
}
return true;
}
static void task_data_op_thread(void* arg) {
data_op_data* data = (data_op_data*) arg;
data->info->finished = false;
data->info->premature = false;
@ -114,7 +127,20 @@ static void task_copy_data_thread(void* arg) {
data->info->processed = 0;
for(data->info->processed = 0; data->info->processed < data->info->total; data->info->processed++) {
if(!task_copy_data_item(data, data->info->processed)) {
bool cont = false;
switch(data->info->op) {
case DATAOP_COPY:
cont = task_data_op_copy(data, data->info->processed);
break;
case DATAOP_DELETE:
cont = task_data_op_delete(data, data->info->processed);
break;
default:
break;
}
if(!cont) {
data->info->premature = true;
break;
}
@ -126,7 +152,7 @@ static void task_copy_data_thread(void* arg) {
free(data);
}
static void task_copy_data_reset_info(copy_data_info* info) {
static void task_data_op_reset_info(data_op_info* info) {
info->finished = false;
info->premature = false;
@ -136,14 +162,14 @@ static void task_copy_data_reset_info(copy_data_info* info) {
info->currTotal = 0;
}
Handle task_copy_data(copy_data_info* info) {
Handle task_data_op(data_op_info* info) {
if(info == NULL) {
return 0;
}
task_copy_data_reset_info(info);
task_data_op_reset_info(info);
copy_data_data* installData = (copy_data_data*) calloc(1, sizeof(copy_data_data));
data_op_data* installData = (data_op_data*) calloc(1, sizeof(data_op_data));
installData->info = info;
Result eventRes = svcCreateEvent(&installData->cancelEvent, 1);
@ -154,7 +180,7 @@ Handle task_copy_data(copy_data_info* info) {
return 0;
}
if(threadCreate(task_copy_data_thread, installData, 0x4000, 0x18, 1, true) == NULL) {
if(threadCreate(task_data_op_thread, installData, 0x4000, 0x18, 1, true) == NULL) {
error_display(NULL, NULL, NULL, "Failed to create CIA installation thread.");
svcCloseHandle(installData->cancelEvent);

View File

@ -68,9 +68,17 @@ typedef struct {
ticket_info ticketInfo;
} file_info;
typedef enum {
DATAOP_COPY,
DATAOP_DELETE
} DataOp;
typedef struct {
void* data;
DataOp op;
// Copy
bool copyEmpty;
bool finished;
@ -96,9 +104,13 @@ typedef struct {
Result (*writeDst)(void* data, u32 handle, u32* bytesWritten, void* buffer, u64 offset, u32 size);
// Delete
Result (*delete)(void* data, u32 index);
// Errors
bool (*resultError)(void* data, u32 index, Result res);
bool (*ioError)(void* data, u32 index, int err);
} copy_data_info;
} data_op_info;
bool task_is_quit_all();
void task_quit_all();
@ -109,4 +121,4 @@ Handle task_populate_pending_titles(list_item* items, u32* count, u32 max);
Handle task_populate_system_save_data(list_item* items, u32* count, u32 max);
Handle task_populate_tickets(list_item* items, u32* count, u32 max);
Handle task_populate_titles(list_item* items, u32* count, u32 max);
Handle task_copy_data(copy_data_info* info);
Handle task_data_op(data_op_info* info);