/* * 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; }