diff --git a/source/deletion_lists_clean.h b/source/deletion_lists_clean.h index 915b080..b9df07e 100644 --- a/source/deletion_lists_clean.h +++ b/source/deletion_lists_clean.h @@ -138,11 +138,6 @@ static const char* clean_switch_dirs_to_delete[] = { "sd:/switch/ChoiDujourNX", "sd:/switch/crash_ams", "sd:/switch/Daybreak", - "sd:/switch/DBI_658_EN", - "sd:/switch/DBI_810", - "sd:/switch/DBI_810_DE", - "sd:/switch/DBI_810_EN", - "sd:/switch/DBI_RU", "sd:/switch/DNS_mitm Tester", "sd:/switch/EdiZon", "sd:/switch/Fizeau", @@ -208,6 +203,8 @@ static const char* clean_switch_files_to_delete[] = { "sd:/switch/DBI_810_DE/DBI_810_DE.nro", "sd:/switch/DBI_810_EN/DBI_810_EN.nro", "sd:/switch/DBI_RU/DBI_RU.nro", + "sd:/switch/DBI/DBI_EN.nro", + "sd:/switch/DBI_DE/DBI_DE.nro", "sd:/switch/DNS_mitm Tester.nro", "sd:/switch/EdiZon.nro", "sd:/switch/Fizeau.nro", diff --git a/source/deletion_lists_update.h b/source/deletion_lists_update.h index da9cf40..b4e2421 100644 --- a/source/deletion_lists_update.h +++ b/source/deletion_lists_update.h @@ -137,11 +137,6 @@ static const char* switch_dirs_to_delete[] = { "sd:/switch/ChoiDujourNX", "sd:/switch/crash_ams", "sd:/switch/Daybreak", - "sd:/switch/DBI_658_EN", - "sd:/switch/DBI_810", - "sd:/switch/DBI_810_DE", - "sd:/switch/DBI_810_EN", - "sd:/switch/DBI_RU", "sd:/switch/DNS_mitm Tester", "sd:/switch/EdiZon", "sd:/switch/Fizeau", @@ -207,6 +202,8 @@ static const char* switch_files_to_delete[] = { "sd:/switch/DBI_810_DE/DBI_810_DE.nro", "sd:/switch/DBI_810_EN/DBI_810_EN.nro", "sd:/switch/DBI_RU/DBI_RU.nro", + "sd:/switch/DBI/DBI_EN.nro", + "sd:/switch/DBI_DE/DBI_DE.nro", "sd:/switch/DNS_mitm Tester.nro", "sd:/switch/EdiZon.nro", "sd:/switch/Fizeau.nro", diff --git a/source/install.c b/source/install.c index 83d03ce..015b5b6 100644 --- a/source/install.c +++ b/source/install.c @@ -7,9 +7,12 @@ #include "version.h" #include "gfx.h" #include +#include #include #include +#define GROUPED_DELETE_MAX_ENTRIES 512 + #ifndef VERSION #define VERSION "1.0.0" #endif @@ -395,6 +398,89 @@ int folder_delete_single_with_progress(const char *path, const char *display_nam } // Delete a list of paths with progress tracking +// Delete multiple path lists under one label; one progress line "Bereinige: folder/ [p%] (d/t)". +// Varargs: path lists (const char**), terminated by NULL. +int delete_path_lists_grouped(const char *folder_display_name, ...) { + va_list ap; + const char *entries[GROUPED_DELETE_MAX_ENTRIES]; + int n_entries = 0; + int deleted = 0; + int failed = 0; + u32 start_x, start_y; + int last_percent = -1; + int res; + + va_start(ap, folder_display_name); + const char **list; + while (n_entries < GROUPED_DELETE_MAX_ENTRIES && (list = va_arg(ap, const char **)) != NULL) { + for (int i = 0; list[i] != NULL && n_entries < GROUPED_DELETE_MAX_ENTRIES; i++) { + if (install_path_exists(list[i])) + entries[n_entries++] = list[i]; + } + } + va_end(ap); + + if (n_entries == 0) + return FR_OK; + + int total_paths = n_entries; + gfx_con_getpos(&start_x, &start_y); + install_set_color(COLOR_CYAN); + gfx_printf(" Bereinige: %s [ 0%%] (0/%d)", folder_display_name, total_paths); + install_set_color(COLOR_WHITE); + + for (int i = 0; i < n_entries; i++) { + const char *path = entries[i]; + FILINFO fno; + if (f_stat(path, &fno) != FR_OK) + continue; + + const char *item_name = strrchr(path, '/'); + if (item_name) item_name++; + else item_name = path; + + if (fno.fattrib & AM_DIR) { + int item_count = install_count_directory_items(path); + if (item_count > 50) { + gfx_printf("\n"); + res = folder_delete_single_with_progress(path, item_name); + } else { + res = folder_delete(path); + } + } else { + if (fno.fattrib & AM_RDO) + f_chmod(path, fno.fattrib & ~AM_RDO, AM_RDO); + res = f_unlink(path); + } + + if (res == FR_OK || res == FR_NO_FILE) + deleted++; + else + failed++; + + int percent = (deleted * 100) / total_paths; + if (percent != last_percent || deleted % 5 == 0) { + gfx_con_setpos(start_x, start_y); + install_set_color(COLOR_CYAN); + gfx_printf(" Bereinige: %s [%3d%%] (%d/%d)", folder_display_name, percent, deleted, total_paths); + install_set_color(COLOR_WHITE); + last_percent = percent; + } + } + + gfx_con_setpos(start_x, start_y); + if (failed == 0) { + install_set_color(COLOR_GREEN); + gfx_printf(" Bereinige: %s [100%%] (%d/%d) - Fertig!\n", folder_display_name, deleted, total_paths); + install_set_color(COLOR_WHITE); + } else { + install_set_color(COLOR_ORANGE); + gfx_printf(" Bereinige: %s [%3d%%] (%d/%d) - %d Fehler\n", folder_display_name, last_percent, deleted, total_paths, failed); + install_set_color(COLOR_WHITE); + } + return (failed == 0) ? FR_OK : FR_DISK_ERR; +} + int delete_path_list(const char* paths[], const char* description) { int res; int deleted = 0; diff --git a/source/install.h b/source/install.h index 31c660c..d1a86a2 100644 --- a/source/install.h +++ b/source/install.h @@ -36,6 +36,7 @@ bool install_path_exists(const char *path); int install_count_directory_items(const char *path); void install_combine_path(char *result, size_t size, const char *base, const char *add); int delete_path_list(const char* paths[], const char* description); +int delete_path_lists_grouped(const char *folder_display_name, ...); int folder_delete_single_with_progress(const char *path, const char *display_name); int folder_delete_progress_recursive(const char *path, int *deleted, int total, u32 start_x, u32 start_y, const char *display_name, int *last_percent); int folder_copy_with_progress_v2(const char *src, const char *dst, const char *display_name); diff --git a/source/install_clean.c b/source/install_clean.c index 55a8667..40960b3 100644 --- a/source/install_clean.c +++ b/source/install_clean.c @@ -1,170 +1,165 @@ -/* - * OmniNX Installer - Clean Install Mode - * Backup, selective cleanup from list, restore, then install when no OmniNX found. - * Does not wipe whole card; only paths in deletion_lists_clean.h are removed. - */ - -#include "install.h" -#include "backup.h" -#include "deletion_lists_clean.h" -#include "fs.h" -#include "gfx.h" -#include "version.h" -#include -#include - -#undef COLOR_CYAN -#undef COLOR_WHITE -#undef COLOR_GREEN -#undef COLOR_RED -#undef COLOR_YELLOW -#undef COLOR_ORANGE -#define COLOR_CYAN 0xFF00FFFF -#define COLOR_WHITE 0xFFFFFFFF -#define COLOR_GREEN 0xFF00FF00 -#define COLOR_RED 0xFFFF0000 -#define COLOR_YELLOW 0xFFFFDD00 -#define COLOR_ORANGE 0xFF00A5FF - -#define set_color install_set_color -#define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed -#define path_exists install_path_exists -#define count_directory_items install_count_directory_items - -// Clean mode: Backup user data -int clean_mode_backup(void) { - set_color(COLOR_CYAN); - gfx_printf(" Sichere: DBI, Tinfoil, prod.keys\n"); - set_color(COLOR_WHITE); - int res = backup_user_data(); - if (res == FR_OK) { - set_color(COLOR_GREEN); - gfx_printf(" [OK] Sicherung abgeschlossen\n"); - set_color(COLOR_WHITE); - } - return res; -} - -// Clean mode: Wipe using selective deletion list (does not wipe whole card) -int clean_mode_wipe(void) { - check_and_clear_screen_if_needed(); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: atmosphere/\n"); - set_color(COLOR_WHITE); - delete_path_list(clean_atmosphere_dirs_to_delete, "atmosphere subdirs"); - delete_path_list(clean_atmosphere_contents_dirs_to_delete, "atmosphere contents dirs"); - delete_path_list(clean_atmosphere_files_to_delete, "atmosphere files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: bootloader/\n"); - set_color(COLOR_WHITE); - delete_path_list(clean_bootloader_dirs_to_delete, "bootloader dirs"); - delete_path_list(clean_bootloader_files_to_delete, "bootloader files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: config/\n"); - set_color(COLOR_WHITE); - delete_path_list(clean_config_dirs_to_delete, "config dirs"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: switch/\n"); - set_color(COLOR_WHITE); - delete_path_list(clean_switch_dirs_to_delete, "switch dirs"); - delete_path_list(clean_switch_files_to_delete, "switch files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: Root-Dateien\n"); - set_color(COLOR_WHITE); - delete_path_list(clean_root_files_to_delete, "root files"); - delete_path_list(clean_misc_dirs_to_delete, "misc dirs"); - delete_path_list(clean_misc_files_to_delete, "misc files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: Alte Versionsmarker\n"); - set_color(COLOR_WHITE); - delete_path_list(old_version_files_to_delete, "old version markers"); - - set_color(COLOR_CYAN); - gfx_printf(" Erstelle: switch/\n"); - set_color(COLOR_WHITE); - f_mkdir("sd:/switch"); - - set_color(COLOR_GREEN); - gfx_printf(" Bereinigung abgeschlossen!\n"); - set_color(COLOR_WHITE); - - return FR_OK; -} - -// Clean mode: Restore user data -int clean_mode_restore(void) { - set_color(COLOR_CYAN); - gfx_printf(" Stelle wieder her: DBI, Tinfoil, prod.keys\n"); - set_color(COLOR_WHITE); - int res = restore_user_data(); - if (res == FR_OK) { - set_color(COLOR_GREEN); - gfx_printf(" [OK] Wiederherstellung abgeschlossen\n"); - set_color(COLOR_WHITE); - } - cleanup_backup(); - return res; -} - -// Clean mode: Install files (reuse update mode install) -int clean_mode_install(omninx_variant_t variant) { - return update_mode_install(variant); -} - -// Remove other staging directories (OmniNX Standard/Light/OC) that exist on SD -int cleanup_other_staging_directories(omninx_variant_t installed_variant) { - static const omninx_variant_t all_variants[] = { VARIANT_STANDARD, VARIANT_LIGHT, VARIANT_OC }; - const int n = sizeof(all_variants) / sizeof(all_variants[0]); - int last_res = FR_OK; - - for (int i = 0; i < n; i++) { - omninx_variant_t v = all_variants[i]; - if (v == installed_variant) - continue; - const char *staging = get_staging_path(v); - if (!staging || !path_exists(staging)) - continue; - - check_and_clear_screen_if_needed(); - set_color(COLOR_YELLOW); - gfx_printf("\nEntferne weiteren Installationsordner...\n"); - set_color(COLOR_WHITE); - - int total = count_directory_items(staging); - u32 start_x, start_y; - gfx_con_getpos(&start_x, &start_y); - - const char *folder_name = strrchr(staging, '/'); - if (folder_name) folder_name++; - else folder_name = staging; - - set_color(COLOR_CYAN); - gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total); - set_color(COLOR_WHITE); - - int deleted = 0; - int last_percent = -1; - int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent); - - gfx_con_setpos(start_x, start_y); - if (res == FR_OK) { - set_color(COLOR_GREEN); - gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total); - set_color(COLOR_WHITE); - } else { - set_color(COLOR_ORANGE); - gfx_printf(" Loesche: %s - Fehlgeschlagen!\n", folder_name); - gfx_printf(" [WARN] Ordner konnte nicht entfernt werden (err=%d)\n", res); - set_color(COLOR_WHITE); - } - last_res = res; - } - - return last_res; -} +/* + * OmniNX Installer - Clean Install Mode + * Backup, selective cleanup from list, restore, then install when no OmniNX found. + * Does not wipe whole card; only paths in deletion_lists_clean.h are removed. + */ + +#include "install.h" +#include "backup.h" +#include "deletion_lists_clean.h" +#include "fs.h" +#include "gfx.h" +#include "version.h" +#include +#include + +#undef COLOR_CYAN +#undef COLOR_WHITE +#undef COLOR_GREEN +#undef COLOR_RED +#undef COLOR_YELLOW +#undef COLOR_ORANGE +#define COLOR_CYAN 0xFF00FFFF +#define COLOR_WHITE 0xFFFFFFFF +#define COLOR_GREEN 0xFF00FF00 +#define COLOR_RED 0xFFFF0000 +#define COLOR_YELLOW 0xFFFFDD00 +#define COLOR_ORANGE 0xFF00A5FF + +#define set_color install_set_color +#define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed +#define path_exists install_path_exists +#define count_directory_items install_count_directory_items + +// Clean mode: Backup user data +int clean_mode_backup(void) { + set_color(COLOR_CYAN); + gfx_printf(" Sichere: DBI, Tinfoil, prod.keys\n"); + set_color(COLOR_WHITE); + int res = backup_user_data(); + if (res == FR_OK) { + set_color(COLOR_GREEN); + gfx_printf(" [OK] Sicherung abgeschlossen\n"); + set_color(COLOR_WHITE); + } + return res; +} + +// Clean mode: Wipe using selective deletion list (does not wipe whole card) +int clean_mode_wipe(void) { + check_and_clear_screen_if_needed(); + + set_color(COLOR_WHITE); + delete_path_lists_grouped("atmosphere/", + clean_atmosphere_dirs_to_delete, + clean_atmosphere_contents_dirs_to_delete, + clean_atmosphere_files_to_delete, + NULL); + + delete_path_lists_grouped("bootloader/", + clean_bootloader_dirs_to_delete, + clean_bootloader_files_to_delete, + NULL); + + delete_path_lists_grouped("config/", + clean_config_dirs_to_delete, + NULL); + + delete_path_lists_grouped("switch/", + clean_switch_dirs_to_delete, + clean_switch_files_to_delete, + NULL); + + delete_path_lists_grouped("Root-Dateien", + clean_root_files_to_delete, + clean_misc_dirs_to_delete, + clean_misc_files_to_delete, + NULL); + + delete_path_lists_grouped("Alte Versionsmarker", + old_version_files_to_delete, + NULL); + + set_color(COLOR_CYAN); + gfx_printf(" Erstelle: switch/\n"); + set_color(COLOR_WHITE); + f_mkdir("sd:/switch"); + + set_color(COLOR_GREEN); + gfx_printf(" Bereinigung abgeschlossen!\n"); + set_color(COLOR_WHITE); + + return FR_OK; +} + +// Clean mode: Restore user data +int clean_mode_restore(void) { + set_color(COLOR_CYAN); + gfx_printf(" Stelle wieder her: DBI, Tinfoil, prod.keys\n"); + set_color(COLOR_WHITE); + int res = restore_user_data(); + if (res == FR_OK) { + set_color(COLOR_GREEN); + gfx_printf(" [OK] Wiederherstellung abgeschlossen\n"); + set_color(COLOR_WHITE); + } + cleanup_backup(); + return res; +} + +// Clean mode: Install files (reuse update mode install) +int clean_mode_install(omninx_variant_t variant) { + return update_mode_install(variant); +} + +// Remove other staging directories (OmniNX Standard/Light/OC) that exist on SD +int cleanup_other_staging_directories(omninx_variant_t installed_variant) { + static const omninx_variant_t all_variants[] = { VARIANT_STANDARD, VARIANT_LIGHT, VARIANT_OC }; + const int n = sizeof(all_variants) / sizeof(all_variants[0]); + int last_res = FR_OK; + + for (int i = 0; i < n; i++) { + omninx_variant_t v = all_variants[i]; + if (v == installed_variant) + continue; + const char *staging = get_staging_path(v); + if (!staging || !path_exists(staging)) + continue; + + check_and_clear_screen_if_needed(); + set_color(COLOR_YELLOW); + gfx_printf("\nEntferne weiteren Installationsordner...\n"); + set_color(COLOR_WHITE); + + int total = count_directory_items(staging); + u32 start_x, start_y; + gfx_con_getpos(&start_x, &start_y); + + const char *folder_name = strrchr(staging, '/'); + if (folder_name) folder_name++; + else folder_name = staging; + + set_color(COLOR_CYAN); + gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total); + set_color(COLOR_WHITE); + + int deleted = 0; + int last_percent = -1; + int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent); + + gfx_con_setpos(start_x, start_y); + if (res == FR_OK) { + set_color(COLOR_GREEN); + gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total); + set_color(COLOR_WHITE); + } else { + set_color(COLOR_ORANGE); + gfx_printf(" Loesche: %s - Fehlgeschlagen!\n", folder_name); + gfx_printf(" [WARN] Ordner konnte nicht entfernt werden (err=%d)\n", res); + set_color(COLOR_WHITE); + } + last_res = res; + } + + return last_res; +} diff --git a/source/install_update.c b/source/install_update.c index 92ddcb0..3b1e662 100644 --- a/source/install_update.c +++ b/source/install_update.c @@ -1,237 +1,199 @@ -/* - * OmniNX Installer - Update Mode - * Selective cleanup and install when OmniNX is already installed. - */ - -#include "install.h" -#include "deletion_lists_update.h" -#include "fs.h" -#include "version.h" -#include "gfx.h" -#include -#include -#include - -#ifndef VERSION -#define VERSION "1.0.0" -#endif - -#undef COLOR_CYAN -#undef COLOR_WHITE -#undef COLOR_GREEN -#undef COLOR_YELLOW -#undef COLOR_ORANGE -#undef COLOR_RED -#define COLOR_CYAN 0xFF00FFFF -#define COLOR_WHITE 0xFFFFFFFF -#define COLOR_GREEN 0xFF00FF00 -#define COLOR_YELLOW 0xFFFFDD00 -#define COLOR_ORANGE 0xFF00A5FF -#define COLOR_RED 0xFFFF0000 - -#define set_color install_set_color -#define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed -#define path_exists install_path_exists -#define count_directory_items install_count_directory_items - -// Update mode: Cleanup specific directories/files -int update_mode_cleanup(omninx_variant_t variant) { - (void)variant; - check_and_clear_screen_if_needed(); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: atmosphere/\n"); - set_color(COLOR_WHITE); - delete_path_list(atmosphere_dirs_to_delete, "atmosphere subdirs"); - delete_path_list(atmosphere_contents_dirs_to_delete, "atmosphere contents dirs"); - delete_path_list(atmosphere_files_to_delete, "atmosphere files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: bootloader/\n"); - set_color(COLOR_WHITE); - delete_path_list(bootloader_dirs_to_delete, "bootloader dirs"); - delete_path_list(bootloader_files_to_delete, "bootloader files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: config/\n"); - set_color(COLOR_WHITE); - delete_path_list(config_dirs_to_delete, "config dirs"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: switch/\n"); - set_color(COLOR_WHITE); - delete_path_list(switch_dirs_to_delete, "switch dirs"); - delete_path_list(switch_files_to_delete, "switch files"); - - set_color(COLOR_CYAN); - gfx_printf(" Bereinige: Root-Dateien\n"); - set_color(COLOR_WHITE); - delete_path_list(root_files_to_delete, "root files"); - delete_path_list(misc_dirs_to_delete, "misc dirs"); - delete_path_list(misc_files_to_delete, "misc files"); - - set_color(COLOR_GREEN); - gfx_printf(" Bereinigung abgeschlossen!\n"); - set_color(COLOR_WHITE); - - return FR_OK; -} - -// Update mode: Copy files from staging -int update_mode_install(omninx_variant_t variant) { - int res; - const char* staging = get_staging_path(variant); - char src_path[256]; - char dst_path[256]; - - if (!staging) { - return FR_INVALID_PARAMETER; - } - - check_and_clear_screen_if_needed(); - - set_color(COLOR_YELLOW); - gfx_printf("Dateien werden kopiert...\n"); - set_color(COLOR_WHITE); - - s_printf(src_path, "%s/atmosphere", staging); - res = folder_copy_with_progress_v2(src_path, "sd:/", "atmosphere/"); - if (res != FR_OK && res != FR_NO_FILE) return res; - - s_printf(src_path, "%s/bootloader", staging); - res = folder_copy_with_progress_v2(src_path, "sd:/", "bootloader/"); - if (res != FR_OK && res != FR_NO_FILE) return res; - - s_printf(src_path, "%s/config", staging); - res = folder_copy_with_progress_v2(src_path, "sd:/", "config/"); - if (res != FR_OK && res != FR_NO_FILE) return res; - - s_printf(src_path, "%s/switch", staging); - res = folder_copy_with_progress_v2(src_path, "sd:/", "switch/"); - if (res != FR_OK && res != FR_NO_FILE) return res; - - s_printf(src_path, "%s/warmboot_mariko", staging); - res = folder_copy_with_progress_v2(src_path, "sd:/", "warmboot_mariko/"); - if (res != FR_OK && res != FR_NO_FILE) return res; - - if (variant == VARIANT_OC) { - s_printf(src_path, "%s/SaltySD", staging); - res = folder_copy_with_progress_v2(src_path, "sd:/", "SaltySD/"); - if (res != FR_OK && res != FR_NO_FILE) return res; - } - - set_color(COLOR_CYAN); - gfx_printf(" Kopiere Root-Dateien...\n"); - set_color(COLOR_WHITE); - - s_printf(src_path, "%s/boot.dat", staging); - s_printf(dst_path, "sd:/boot.dat"); - if (path_exists(src_path)) file_copy(src_path, dst_path); - - s_printf(src_path, "%s/boot.ini", staging); - s_printf(dst_path, "sd:/boot.ini"); - if (path_exists(src_path)) file_copy(src_path, dst_path); - - s_printf(src_path, "%s/exosphere.ini", staging); - s_printf(dst_path, "sd:/exosphere.ini"); - if (path_exists(src_path)) file_copy(src_path, dst_path); - - s_printf(src_path, "%s/hbmenu.nro", staging); - s_printf(dst_path, "sd:/hbmenu.nro"); - if (path_exists(src_path)) file_copy(src_path, dst_path); - - s_printf(src_path, "%s/loader.bin", staging); - s_printf(dst_path, "sd:/loader.bin"); - if (path_exists(src_path)) file_copy(src_path, dst_path); - - s_printf(src_path, "%s/payload.bin", staging); - s_printf(dst_path, "sd:/payload.bin"); - if (path_exists(src_path)) file_copy(src_path, dst_path); - - set_color(COLOR_CYAN); - gfx_printf(" Erstelle manifest.ini...\n"); - set_color(COLOR_WHITE); - - s_printf(dst_path, "sd:/config/omninx"); - f_mkdir(dst_path); - - const char* pack_name; - int update_channel; - switch (variant) { - case VARIANT_STANDARD: pack_name = "Standard"; update_channel = 2; break; - case VARIANT_LIGHT: pack_name = "Light"; update_channel = 0; break; - case VARIANT_OC: pack_name = "OC"; update_channel = 1; break; - default: pack_name = "unknown"; update_channel = 0; break; - } - - s_printf(dst_path, "sd:/config/omninx/manifest.ini"); - FIL fp; - if (f_open(&fp, dst_path, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { - f_printf(&fp, "[OmniNX]\n"); - f_printf(&fp, "current_pack=%s\n", pack_name); - f_printf(&fp, "version=%s\n", VERSION); - f_printf(&fp, "update_channel=%d\n", update_channel); - f_printf(&fp, "channel_pack=%s\n", pack_name); - f_close(&fp); - set_color(COLOR_GREEN); - gfx_printf(" [OK] manifest.ini erstellt\n"); - set_color(COLOR_WHITE); - } else { - set_color(COLOR_ORANGE); - gfx_printf(" [WARN] manifest.ini konnte nicht erstellt werden\n"); - set_color(COLOR_WHITE); - } - - set_color(COLOR_GREEN); - gfx_printf(" Kopie abgeschlossen!\n"); - set_color(COLOR_WHITE); - - return FR_OK; -} - -// Remove staging directory after installation -int cleanup_staging_directory(omninx_variant_t pack_variant) { - const char* staging = get_staging_path(pack_variant); - if (!staging) { - return FR_INVALID_PARAMETER; - } - - check_and_clear_screen_if_needed(); - - if (path_exists(staging)) { - set_color(COLOR_YELLOW); - gfx_printf("\nEntferne Installationsordner...\n"); - set_color(COLOR_WHITE); - - int total = count_directory_items(staging); - u32 start_x, start_y; - gfx_con_getpos(&start_x, &start_y); - - const char *folder_name = strrchr(staging, '/'); - if (folder_name) folder_name++; - else folder_name = staging; - - set_color(COLOR_CYAN); - gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total); - set_color(COLOR_WHITE); - - int deleted = 0; - int last_percent = -1; - int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent); - - gfx_con_setpos(start_x, start_y); - if (res == FR_OK) { - set_color(COLOR_GREEN); - gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total); - set_color(COLOR_WHITE); - } else { - set_color(COLOR_ORANGE); - gfx_printf(" Loesche: %s - Fehlgeschlagen!\n", folder_name); - gfx_printf(" [WARN] Ordner konnte nicht entfernt werden (err=%d)\n", res); - set_color(COLOR_WHITE); - } - return res; - } - - return FR_OK; -} +/* + * OmniNX Installer - Update Mode + * Selective cleanup and install when OmniNX is already installed. + */ + +#include "install.h" +#include "deletion_lists_update.h" +#include "fs.h" +#include "version.h" +#include "gfx.h" +#include +#include +#include + +#ifndef VERSION +#define VERSION "1.0.0" +#endif + +#undef COLOR_CYAN +#undef COLOR_WHITE +#undef COLOR_GREEN +#undef COLOR_YELLOW +#undef COLOR_ORANGE +#undef COLOR_RED +#define COLOR_CYAN 0xFF00FFFF +#define COLOR_WHITE 0xFFFFFFFF +#define COLOR_GREEN 0xFF00FF00 +#define COLOR_YELLOW 0xFFFFDD00 +#define COLOR_ORANGE 0xFF00A5FF +#define COLOR_RED 0xFFFF0000 + +#define set_color install_set_color +#define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed +#define path_exists install_path_exists +#define count_directory_items install_count_directory_items + +// Update mode: Cleanup specific directories/files +int update_mode_cleanup(omninx_variant_t variant) { + (void)variant; + check_and_clear_screen_if_needed(); + + set_color(COLOR_WHITE); + delete_path_lists_grouped("atmosphere/", + atmosphere_dirs_to_delete, + atmosphere_contents_dirs_to_delete, + atmosphere_files_to_delete, + NULL); + + delete_path_lists_grouped("bootloader/", + bootloader_dirs_to_delete, + bootloader_files_to_delete, + NULL); + + delete_path_lists_grouped("config/", + config_dirs_to_delete, + NULL); + + delete_path_lists_grouped("switch/", + switch_dirs_to_delete, + switch_files_to_delete, + NULL); + + delete_path_lists_grouped("Root-Dateien", + root_files_to_delete, + misc_dirs_to_delete, + misc_files_to_delete, + NULL); + + set_color(COLOR_GREEN); + gfx_printf(" Bereinigung abgeschlossen!\n"); + set_color(COLOR_WHITE); + + return FR_OK; +} + +// Update mode: Copy files from staging +int update_mode_install(omninx_variant_t variant) { + int res; + const char* staging = get_staging_path(variant); + char src_path[256]; + char dst_path[256]; + + if (!staging) { + return FR_INVALID_PARAMETER; + } + + check_and_clear_screen_if_needed(); + + set_color(COLOR_YELLOW); + gfx_printf("Dateien werden kopiert...\n"); + set_color(COLOR_WHITE); + + s_printf(src_path, "%s/atmosphere", staging); + res = folder_copy_with_progress_v2(src_path, "sd:/", "atmosphere/"); + if (res != FR_OK && res != FR_NO_FILE) return res; + + s_printf(src_path, "%s/bootloader", staging); + res = folder_copy_with_progress_v2(src_path, "sd:/", "bootloader/"); + if (res != FR_OK && res != FR_NO_FILE) return res; + + s_printf(src_path, "%s/config", staging); + res = folder_copy_with_progress_v2(src_path, "sd:/", "config/"); + if (res != FR_OK && res != FR_NO_FILE) return res; + + s_printf(src_path, "%s/switch", staging); + res = folder_copy_with_progress_v2(src_path, "sd:/", "switch/"); + if (res != FR_OK && res != FR_NO_FILE) return res; + + s_printf(src_path, "%s/warmboot_mariko", staging); + res = folder_copy_with_progress_v2(src_path, "sd:/", "warmboot_mariko/"); + if (res != FR_OK && res != FR_NO_FILE) return res; + + if (variant == VARIANT_OC) { + s_printf(src_path, "%s/SaltySD", staging); + res = folder_copy_with_progress_v2(src_path, "sd:/", "SaltySD/"); + if (res != FR_OK && res != FR_NO_FILE) return res; + } + + set_color(COLOR_CYAN); + gfx_printf(" Kopiere Root-Dateien...\n"); + set_color(COLOR_WHITE); + + s_printf(src_path, "%s/boot.dat", staging); + s_printf(dst_path, "sd:/boot.dat"); + if (path_exists(src_path)) file_copy(src_path, dst_path); + + s_printf(src_path, "%s/boot.ini", staging); + s_printf(dst_path, "sd:/boot.ini"); + if (path_exists(src_path)) file_copy(src_path, dst_path); + + s_printf(src_path, "%s/exosphere.ini", staging); + s_printf(dst_path, "sd:/exosphere.ini"); + if (path_exists(src_path)) file_copy(src_path, dst_path); + + s_printf(src_path, "%s/hbmenu.nro", staging); + s_printf(dst_path, "sd:/hbmenu.nro"); + if (path_exists(src_path)) file_copy(src_path, dst_path); + + s_printf(src_path, "%s/loader.bin", staging); + s_printf(dst_path, "sd:/loader.bin"); + if (path_exists(src_path)) file_copy(src_path, dst_path); + + s_printf(src_path, "%s/payload.bin", staging); + s_printf(dst_path, "sd:/payload.bin"); + if (path_exists(src_path)) file_copy(src_path, dst_path); + + set_color(COLOR_GREEN); + gfx_printf(" Kopie abgeschlossen!\n"); + set_color(COLOR_WHITE); + + return FR_OK; +} + +// Remove staging directory after installation +int cleanup_staging_directory(omninx_variant_t pack_variant) { + const char* staging = get_staging_path(pack_variant); + if (!staging) { + return FR_INVALID_PARAMETER; + } + + check_and_clear_screen_if_needed(); + + if (path_exists(staging)) { + set_color(COLOR_YELLOW); + gfx_printf("\nEntferne Installationsordner...\n"); + set_color(COLOR_WHITE); + + int total = count_directory_items(staging); + u32 start_x, start_y; + gfx_con_getpos(&start_x, &start_y); + + const char *folder_name = strrchr(staging, '/'); + if (folder_name) folder_name++; + else folder_name = staging; + + set_color(COLOR_CYAN); + gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total); + set_color(COLOR_WHITE); + + int deleted = 0; + int last_percent = -1; + int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent); + + gfx_con_setpos(start_x, start_y); + if (res == FR_OK) { + set_color(COLOR_GREEN); + gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total); + set_color(COLOR_WHITE); + } else { + set_color(COLOR_ORANGE); + gfx_printf(" Loesche: %s - Fehlgeschlagen!\n", folder_name); + gfx_printf(" [WARN] Ordner konnte nicht entfernt werden (err=%d)\n", res); + set_color(COLOR_WHITE); + } + return res; + } + + return FR_OK; +}