mirror of
https://gitlab.com/Theopse/fbi-i18n-zh.git
synced 2025-04-06 03:58:02 +08:00
Load file metadata after populating list.
This commit is contained in:
parent
0404a33a58
commit
cd42e873da
@ -190,7 +190,7 @@ static void action_delete_internal(linked_list* items, list_item* selected, cons
|
||||
data->items = items;
|
||||
|
||||
file_info* targetInfo = (file_info*) selected->data;
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes, true);
|
||||
if(R_FAILED(targetCreateRes)) {
|
||||
error_display_res(NULL, NULL, targetCreateRes, "Failed to create target file item.");
|
||||
|
||||
|
@ -309,7 +309,7 @@ static void action_install_cias_internal(linked_list* items, list_item* selected
|
||||
data->items = items;
|
||||
|
||||
file_info* targetInfo = (file_info*) selected->data;
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes, true);
|
||||
if(R_FAILED(targetCreateRes)) {
|
||||
error_display_res(NULL, NULL, targetCreateRes, "Failed to create target file item.");
|
||||
|
||||
|
@ -285,7 +285,7 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec
|
||||
data->items = items;
|
||||
|
||||
file_info* targetInfo = (file_info*) selected->data;
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes, true);
|
||||
if(R_FAILED(targetCreateRes)) {
|
||||
error_display_res(NULL, NULL, targetCreateRes, "Failed to create target file item.");
|
||||
|
||||
|
@ -192,6 +192,7 @@ static Result action_install_url_open_dst(void* data, u32 index, void* initialRe
|
||||
|
||||
installData->ticketInfo.titleId = ticket_get_title_id((u8*) initialReadBlock);
|
||||
installData->ticketInfo.inUse = false;
|
||||
installData->ticketInfo.loaded = true;
|
||||
|
||||
AM_DeleteTicket(installData->ticketInfo.titleId);
|
||||
res = AM_InstallTicketBegin(handle);
|
||||
|
@ -38,7 +38,7 @@ static void action_new_folder_onresponse(ui_view* view, void* data, SwkbdButton
|
||||
|
||||
if(R_SUCCEEDED(res)) {
|
||||
list_item* folderItem = NULL;
|
||||
if(R_SUCCEEDED(task_create_file_item(&folderItem, parentDir->archive, path, FS_ATTRIBUTE_DIRECTORY))) {
|
||||
if(R_SUCCEEDED(task_create_file_item(&folderItem, parentDir->archive, path, FS_ATTRIBUTE_DIRECTORY, true))) {
|
||||
linked_list_add(newFolderData->items, folderItem);
|
||||
linked_list_sort(newFolderData->items, NULL, task_compare_files);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ static Result action_paste_contents_make_dst_directory(void* data, u32 index) {
|
||||
|
||||
if(strncmp(parentPath, baseDstPath, FILE_PATH_MAX) == 0) {
|
||||
list_item* dstItem = NULL;
|
||||
if(R_SUCCEEDED(res) && R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, attributes))) {
|
||||
if(R_SUCCEEDED(res) && R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, attributes, true))) {
|
||||
linked_list_add(pasteData->items, dstItem);
|
||||
}
|
||||
}
|
||||
@ -189,7 +189,7 @@ static Result action_paste_contents_close_dst(void* data, u32 index, bool succee
|
||||
|
||||
if(strncmp(parentPath, baseDstPath, FILE_PATH_MAX) == 0) {
|
||||
list_item* dstItem = NULL;
|
||||
if(R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes & ~FS_ATTRIBUTE_READ_ONLY))) {
|
||||
if(R_SUCCEEDED(task_create_file_item(&dstItem, pasteData->target->archive, dstPath, ((file_info*) ((list_item*) linked_list_get(&pasteData->contents, index))->data)->attributes & ~FS_ATTRIBUTE_READ_ONLY, true))) {
|
||||
linked_list_add(pasteData->items, dstItem);
|
||||
}
|
||||
}
|
||||
@ -342,7 +342,7 @@ void action_paste_contents(linked_list* items, list_item* selected) {
|
||||
data->items = items;
|
||||
|
||||
file_info* targetInfo = (file_info*) selected->data;
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes);
|
||||
Result targetCreateRes = task_create_file_item(&data->targetItem, targetInfo->archive, targetInfo->path, targetInfo->attributes, true);
|
||||
if(R_FAILED(targetCreateRes)) {
|
||||
error_display_res(NULL, NULL, targetCreateRes, "Failed to create target file item.");
|
||||
|
||||
|
@ -37,7 +37,81 @@ int task_compare_files(void* userData, const void* p1, const void* p2) {
|
||||
}
|
||||
}
|
||||
|
||||
Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes) {
|
||||
static void task_populate_files_retrieve_meta(file_info* fileInfo) {
|
||||
FS_Path* fileFsPath = fs_make_path_utf8(fileInfo->path);
|
||||
if(fileFsPath != NULL) {
|
||||
Handle fileHandle;
|
||||
if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, fileInfo->archive, *fileFsPath, FS_OPEN_READ, 0))) {
|
||||
if(fileInfo->attributes == 0 && R_FAILED(FSFILE_GetAttributes(fileHandle, &fileInfo->attributes))) {
|
||||
fileInfo->attributes = 0;
|
||||
}
|
||||
|
||||
FSFILE_GetSize(fileHandle, &fileInfo->size);
|
||||
|
||||
if(fileInfo->isCia) {
|
||||
AM_TitleEntry titleEntry;
|
||||
if(R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_SD, &titleEntry, fileHandle))) {
|
||||
fileInfo->ciaInfo.titleId = titleEntry.titleID;
|
||||
fileInfo->ciaInfo.version = titleEntry.version;
|
||||
fileInfo->ciaInfo.installedSize = titleEntry.size;
|
||||
fileInfo->ciaInfo.hasMeta = false;
|
||||
|
||||
if(fs_get_title_destination(titleEntry.titleID) != MEDIATYPE_SD && R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_NAND, &titleEntry, fileHandle))) {
|
||||
fileInfo->ciaInfo.installedSize = titleEntry.size;
|
||||
}
|
||||
|
||||
SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
|
||||
if(smdh != NULL) {
|
||||
if(R_SUCCEEDED(cia_file_get_smdh(smdh, fileHandle))) {
|
||||
if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
|
||||
SMDH_title* smdhTitle = smdh_select_title(smdh);
|
||||
|
||||
fileInfo->ciaInfo.hasMeta = true;
|
||||
utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.shortDescription, smdhTitle->shortDescription, sizeof(fileInfo->ciaInfo.meta.shortDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.longDescription, smdhTitle->longDescription, sizeof(fileInfo->ciaInfo.meta.longDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.publisher, smdhTitle->publisher, sizeof(fileInfo->ciaInfo.meta.publisher) - 1);
|
||||
fileInfo->ciaInfo.meta.region = smdh->region;
|
||||
fileInfo->ciaInfo.meta.texture = screen_allocate_free_texture();
|
||||
screen_load_texture_tiled(fileInfo->ciaInfo.meta.texture, smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
|
||||
}
|
||||
}
|
||||
|
||||
free(smdh);
|
||||
}
|
||||
|
||||
fileInfo->ciaInfo.loaded = true;
|
||||
} else {
|
||||
fileInfo->isCia = false;
|
||||
}
|
||||
} else if(fileInfo->isTicket) {
|
||||
u32 bytesRead = 0;
|
||||
|
||||
u8 sigType = 0;
|
||||
if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, 3, &sigType, sizeof(sigType))) && bytesRead == sizeof(sigType) && sigType <= 5) {
|
||||
static u32 dataOffsets[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80};
|
||||
static u32 titleIdOffset = 0x9C;
|
||||
|
||||
u64 titleId = 0;
|
||||
if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, dataOffsets[sigType] + titleIdOffset, &titleId, sizeof(titleId))) && bytesRead == sizeof(titleId)) {
|
||||
fileInfo->ticketInfo.loaded = true;
|
||||
fileInfo->ticketInfo.titleId = __builtin_bswap64(titleId);
|
||||
fileInfo->ticketInfo.inUse = false;
|
||||
} else {
|
||||
fileInfo->isTicket = false;
|
||||
}
|
||||
} else {
|
||||
fileInfo->isTicket = false;
|
||||
}
|
||||
}
|
||||
|
||||
FSFILE_Close(fileHandle);
|
||||
}
|
||||
|
||||
fs_free_path_utf8(fileFsPath);
|
||||
}
|
||||
}
|
||||
|
||||
Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes, bool meta) {
|
||||
Result res = 0;
|
||||
|
||||
list_item* item = (list_item*) calloc(1, sizeof(list_item));
|
||||
@ -46,13 +120,13 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa
|
||||
if(fileInfo != NULL) {
|
||||
fileInfo->archive = archive;
|
||||
string_get_path_file(fileInfo->name, path, FILE_NAME_MAX);
|
||||
fileInfo->attributes = attributes != UINT32_MAX ? attributes : 0;
|
||||
fileInfo->attributes = attributes;
|
||||
|
||||
fileInfo->size = 0;
|
||||
fileInfo->isCia = false;
|
||||
fileInfo->isTicket = false;
|
||||
|
||||
if((attributes != UINT32_MAX && (attributes & FS_ATTRIBUTE_DIRECTORY)) || fs_is_dir(archive, path)) {
|
||||
if((attributes & FS_ATTRIBUTE_DIRECTORY) || fs_is_dir(archive, path)) {
|
||||
item->color = COLOR_DIRECTORY;
|
||||
|
||||
size_t len = strlen(path);
|
||||
@ -62,7 +136,7 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa
|
||||
strncpy(fileInfo->path, path, FILE_PATH_MAX);
|
||||
}
|
||||
|
||||
if(attributes == UINT32_MAX) {
|
||||
if(attributes == 0) {
|
||||
fileInfo->attributes = FS_ATTRIBUTE_DIRECTORY;
|
||||
}
|
||||
} else {
|
||||
@ -70,69 +144,14 @@ Result task_create_file_item(list_item** out, FS_Archive archive, const char* pa
|
||||
|
||||
strncpy(fileInfo->path, path, FILE_PATH_MAX);
|
||||
|
||||
FS_Path* fileFsPath = fs_make_path_utf8(fileInfo->path);
|
||||
if(fileFsPath != NULL) {
|
||||
Handle fileHandle;
|
||||
if(R_SUCCEEDED(FSUSER_OpenFile(&fileHandle, archive, *fileFsPath, FS_OPEN_READ, 0))) {
|
||||
if(attributes == UINT32_MAX && R_FAILED(FSFILE_GetAttributes(fileHandle, &fileInfo->attributes))) {
|
||||
fileInfo->attributes = 0;
|
||||
}
|
||||
if(fs_filter_cias(NULL, fileInfo->path, fileInfo->attributes)) {
|
||||
fileInfo->isCia = true;
|
||||
} else if(fs_filter_tickets(NULL, fileInfo->path, fileInfo->attributes)) {
|
||||
fileInfo->isTicket = true;
|
||||
}
|
||||
|
||||
FSFILE_GetSize(fileHandle, &fileInfo->size);
|
||||
|
||||
if(fs_filter_cias(NULL, fileInfo->path, fileInfo->attributes)) {
|
||||
AM_TitleEntry titleEntry;
|
||||
if(R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_SD, &titleEntry, fileHandle))) {
|
||||
fileInfo->isCia = true;
|
||||
fileInfo->ciaInfo.titleId = titleEntry.titleID;
|
||||
fileInfo->ciaInfo.version = titleEntry.version;
|
||||
fileInfo->ciaInfo.installedSize = titleEntry.size;
|
||||
fileInfo->ciaInfo.hasMeta = false;
|
||||
|
||||
if(fs_get_title_destination(titleEntry.titleID) != MEDIATYPE_SD && R_SUCCEEDED(AM_GetCiaFileInfo(MEDIATYPE_NAND, &titleEntry, fileHandle))) {
|
||||
fileInfo->ciaInfo.installedSize = titleEntry.size;
|
||||
}
|
||||
|
||||
SMDH* smdh = (SMDH*) calloc(1, sizeof(SMDH));
|
||||
if(smdh != NULL) {
|
||||
if(R_SUCCEEDED(cia_file_get_smdh(smdh, fileHandle))) {
|
||||
if(smdh->magic[0] == 'S' && smdh->magic[1] == 'M' && smdh->magic[2] == 'D' && smdh->magic[3] == 'H') {
|
||||
SMDH_title* smdhTitle = smdh_select_title(smdh);
|
||||
|
||||
fileInfo->ciaInfo.hasMeta = true;
|
||||
utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.shortDescription, smdhTitle->shortDescription, sizeof(fileInfo->ciaInfo.meta.shortDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.longDescription, smdhTitle->longDescription, sizeof(fileInfo->ciaInfo.meta.longDescription) - 1);
|
||||
utf16_to_utf8((uint8_t*) fileInfo->ciaInfo.meta.publisher, smdhTitle->publisher, sizeof(fileInfo->ciaInfo.meta.publisher) - 1);
|
||||
fileInfo->ciaInfo.meta.region = smdh->region;
|
||||
fileInfo->ciaInfo.meta.texture = screen_allocate_free_texture();
|
||||
screen_load_texture_tiled(fileInfo->ciaInfo.meta.texture, smdh->largeIcon, sizeof(smdh->largeIcon), 48, 48, GPU_RGB565, false);
|
||||
}
|
||||
}
|
||||
|
||||
free(smdh);
|
||||
}
|
||||
}
|
||||
} else if(fs_filter_tickets(NULL, fileInfo->path, fileInfo->attributes)) {
|
||||
u32 bytesRead = 0;
|
||||
|
||||
u8 sigType = 0;
|
||||
if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, 3, &sigType, sizeof(sigType))) && bytesRead == sizeof(sigType) && sigType <= 5) {
|
||||
static u32 dataOffsets[6] = {0x240, 0x140, 0x80, 0x240, 0x140, 0x80};
|
||||
static u32 titleIdOffset = 0x9C;
|
||||
|
||||
u64 titleId = 0;
|
||||
if(R_SUCCEEDED(FSFILE_Read(fileHandle, &bytesRead, dataOffsets[sigType] + titleIdOffset, &titleId, sizeof(titleId))) && bytesRead == sizeof(titleId)) {
|
||||
fileInfo->isTicket = true;
|
||||
fileInfo->ticketInfo.titleId = __builtin_bswap64(titleId);
|
||||
fileInfo->ticketInfo.inUse = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FSFILE_Close(fileHandle);
|
||||
}
|
||||
|
||||
fs_free_path_utf8(fileFsPath);
|
||||
if(meta) {
|
||||
task_populate_files_retrieve_meta(fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,7 +196,7 @@ static void task_populate_files_thread(void* arg) {
|
||||
Result res = 0;
|
||||
|
||||
list_item* baseItem = NULL;
|
||||
if(R_SUCCEEDED(res = task_create_file_item(&baseItem, data->archive, data->path, UINT32_MAX))) {
|
||||
if(R_SUCCEEDED(res = task_create_file_item(&baseItem, data->archive, data->path, 0, false))) {
|
||||
file_info* baseInfo = (file_info*) baseItem->data;
|
||||
if(baseInfo->attributes & FS_ATTRIBUTE_DIRECTORY) {
|
||||
strncpy(baseItem->name, "<current directory>", LIST_ITEM_NAME_MAX);
|
||||
@ -227,7 +246,7 @@ static void task_populate_files_thread(void* arg) {
|
||||
snprintf(path, FILE_PATH_MAX, "%s%s", curr->path, name);
|
||||
|
||||
list_item* item = NULL;
|
||||
if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path, entries[i].attributes))) {
|
||||
if(R_SUCCEEDED(res = task_create_file_item(&item, curr->archive, path, entries[i].attributes, false))) {
|
||||
if(data->recursive && (((file_info*) item->data)->attributes & FS_ATTRIBUTE_DIRECTORY)) {
|
||||
linked_list_add(&queue, item);
|
||||
} else {
|
||||
@ -260,6 +279,23 @@ static void task_populate_files_thread(void* arg) {
|
||||
}
|
||||
}
|
||||
|
||||
if(R_SUCCEEDED(res)) {
|
||||
linked_list_iter iter;
|
||||
linked_list_iterate(data->items, &iter);
|
||||
|
||||
while(linked_list_iter_has_next(&iter)) {
|
||||
svcWaitSynchronization(task_get_pause_event(), U64_MAX);
|
||||
if(task_is_quit_all() || svcWaitSynchronization(data->cancelEvent, 0) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
list_item* item = (list_item*) linked_list_iter_next(&iter);
|
||||
file_info* fileInfo = (file_info*) item->data;
|
||||
|
||||
task_populate_files_retrieve_meta(fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
svcCloseHandle(data->cancelEvent);
|
||||
|
||||
data->result = res;
|
||||
|
@ -9,6 +9,8 @@ typedef struct linked_list_s linked_list;
|
||||
typedef struct list_item_s list_item;
|
||||
|
||||
typedef struct cia_info_s {
|
||||
bool loaded;
|
||||
|
||||
u64 titleId;
|
||||
u16 version;
|
||||
u64 installedSize;
|
||||
@ -50,5 +52,5 @@ typedef struct populate_files_data_s {
|
||||
int task_compare_files(void* userData, const void* p1, const void* p2);
|
||||
void task_free_file(list_item* item);
|
||||
void task_clear_files(linked_list* items);
|
||||
Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes);
|
||||
Result task_create_file_item(list_item** out, FS_Archive archive, const char* path, u32 attributes, bool meta);
|
||||
Result task_populate_files(populate_files_data* data);
|
@ -58,6 +58,7 @@ static void task_populate_tickets_thread(void* arg) {
|
||||
ticket_info* ticketInfo = (ticket_info*) calloc(1, sizeof(ticket_info));
|
||||
if(ticketInfo != NULL) {
|
||||
ticketInfo->titleId = ticketIds[i];
|
||||
ticketInfo->loaded = true;
|
||||
|
||||
snprintf(item->name, LIST_ITEM_NAME_MAX, "%016llX", ticketIds[i]);
|
||||
item->data = ticketInfo;
|
||||
|
@ -4,6 +4,8 @@ typedef struct linked_list_s linked_list;
|
||||
typedef struct list_item_s list_item;
|
||||
|
||||
typedef struct ticket_info_s {
|
||||
bool loaded;
|
||||
|
||||
u64 titleId;
|
||||
bool inUse;
|
||||
} ticket_info;
|
||||
|
@ -138,7 +138,7 @@ void task_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2
|
||||
infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Size: %.2f %s\n",
|
||||
ui_get_display_size(info->size), ui_get_display_size_units(info->size));
|
||||
|
||||
if(info->isCia) {
|
||||
if(info->isCia && info->ciaInfo.loaded) {
|
||||
char regionString[64];
|
||||
|
||||
if(info->ciaInfo.hasMeta) {
|
||||
@ -159,7 +159,7 @@ void task_draw_file_info(ui_view* view, void* data, float x1, float y1, float x2
|
||||
regionString,
|
||||
ui_get_display_size(info->ciaInfo.installedSize),
|
||||
ui_get_display_size_units(info->ciaInfo.installedSize));
|
||||
} else if(info->isTicket) {
|
||||
} else if(info->isTicket && info->ticketInfo.loaded) {
|
||||
infoTextPos += snprintf(infoText + infoTextPos, sizeof(infoText) - infoTextPos, "Ticket ID: %016llX", info->ticketInfo.titleId);
|
||||
}
|
||||
}
|
||||
@ -211,16 +211,18 @@ void task_draw_system_save_data_info(ui_view* view, void* data, float x1, float
|
||||
void task_draw_ticket_info(ui_view* view, void* data, float x1, float y1, float x2, float y2) {
|
||||
ticket_info* info = (ticket_info*) data;
|
||||
|
||||
char infoText[512];
|
||||
if(info->loaded) {
|
||||
char infoText[512];
|
||||
|
||||
snprintf(infoText, sizeof(infoText), "Title ID: %016llX", info->titleId);
|
||||
snprintf(infoText, sizeof(infoText), "Title ID: %016llX", info->titleId);
|
||||
|
||||
float infoWidth;
|
||||
screen_get_string_size(&infoWidth, NULL, infoText, 0.5f, 0.5f);
|
||||
float infoWidth;
|
||||
screen_get_string_size(&infoWidth, NULL, infoText, 0.5f, 0.5f);
|
||||
|
||||
float infoX = x1 + (x2 - x1 - infoWidth) / 2;
|
||||
float infoY = y1 + (y2 - y1) / 2 - 8;
|
||||
screen_draw_string(infoText, infoX, infoY, 0.5f, 0.5f, COLOR_TEXT, true);
|
||||
float infoX = x1 + (x2 - x1 - infoWidth) / 2;
|
||||
float infoY = y1 + (y2 - y1) / 2 - 8;
|
||||
screen_draw_string(infoText, infoX, infoY, 0.5f, 0.5f, COLOR_TEXT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void task_draw_title_info(ui_view* view, void* data, float x1, float y1, float x2, float y2) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user