Cleanup UX: slim logging, DBI keep config, no manifest overwrite

- Slim cleanup: one progress line per section (Bereinige: X [p%] (n/n))
  via delete_path_lists_grouped() in clean and update mode
- DBI: remove folder entries from deletion lists; only .nro deleted,
  folder and config preserved
- Remove redundant manifest.ini creation; use manifest from pack config/

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Niklas080208
2026-02-08 00:00:22 +01:00
parent 4a4147686e
commit 4d43ddf1e5
6 changed files with 455 additions and 417 deletions

View File

@@ -138,11 +138,6 @@ static const char* clean_switch_dirs_to_delete[] = {
"sd:/switch/ChoiDujourNX", "sd:/switch/ChoiDujourNX",
"sd:/switch/crash_ams", "sd:/switch/crash_ams",
"sd:/switch/Daybreak", "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/DNS_mitm Tester",
"sd:/switch/EdiZon", "sd:/switch/EdiZon",
"sd:/switch/Fizeau", "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_DE/DBI_810_DE.nro",
"sd:/switch/DBI_810_EN/DBI_810_EN.nro", "sd:/switch/DBI_810_EN/DBI_810_EN.nro",
"sd:/switch/DBI_RU/DBI_RU.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/DNS_mitm Tester.nro",
"sd:/switch/EdiZon.nro", "sd:/switch/EdiZon.nro",
"sd:/switch/Fizeau.nro", "sd:/switch/Fizeau.nro",

View File

@@ -137,11 +137,6 @@ static const char* switch_dirs_to_delete[] = {
"sd:/switch/ChoiDujourNX", "sd:/switch/ChoiDujourNX",
"sd:/switch/crash_ams", "sd:/switch/crash_ams",
"sd:/switch/Daybreak", "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/DNS_mitm Tester",
"sd:/switch/EdiZon", "sd:/switch/EdiZon",
"sd:/switch/Fizeau", "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_DE/DBI_810_DE.nro",
"sd:/switch/DBI_810_EN/DBI_810_EN.nro", "sd:/switch/DBI_810_EN/DBI_810_EN.nro",
"sd:/switch/DBI_RU/DBI_RU.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/DNS_mitm Tester.nro",
"sd:/switch/EdiZon.nro", "sd:/switch/EdiZon.nro",
"sd:/switch/Fizeau.nro", "sd:/switch/Fizeau.nro",

View File

@@ -7,9 +7,12 @@
#include "version.h" #include "version.h"
#include "gfx.h" #include "gfx.h"
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include <utils/sprintf.h> #include <utils/sprintf.h>
#define GROUPED_DELETE_MAX_ENTRIES 512
#ifndef VERSION #ifndef VERSION
#define VERSION "1.0.0" #define VERSION "1.0.0"
#endif #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 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 delete_path_list(const char* paths[], const char* description) {
int res; int res;
int deleted = 0; int deleted = 0;

View File

@@ -36,6 +36,7 @@ bool install_path_exists(const char *path);
int install_count_directory_items(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); 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_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_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_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); int folder_copy_with_progress_v2(const char *src, const char *dst, const char *display_name);

View File

@@ -1,170 +1,165 @@
/* /*
* OmniNX Installer - Clean Install Mode * OmniNX Installer - Clean Install Mode
* Backup, selective cleanup from list, restore, then install when no OmniNX found. * 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. * Does not wipe whole card; only paths in deletion_lists_clean.h are removed.
*/ */
#include "install.h" #include "install.h"
#include "backup.h" #include "backup.h"
#include "deletion_lists_clean.h" #include "deletion_lists_clean.h"
#include "fs.h" #include "fs.h"
#include "gfx.h" #include "gfx.h"
#include "version.h" #include "version.h"
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#include <string.h> #include <string.h>
#undef COLOR_CYAN #undef COLOR_CYAN
#undef COLOR_WHITE #undef COLOR_WHITE
#undef COLOR_GREEN #undef COLOR_GREEN
#undef COLOR_RED #undef COLOR_RED
#undef COLOR_YELLOW #undef COLOR_YELLOW
#undef COLOR_ORANGE #undef COLOR_ORANGE
#define COLOR_CYAN 0xFF00FFFF #define COLOR_CYAN 0xFF00FFFF
#define COLOR_WHITE 0xFFFFFFFF #define COLOR_WHITE 0xFFFFFFFF
#define COLOR_GREEN 0xFF00FF00 #define COLOR_GREEN 0xFF00FF00
#define COLOR_RED 0xFFFF0000 #define COLOR_RED 0xFFFF0000
#define COLOR_YELLOW 0xFFFFDD00 #define COLOR_YELLOW 0xFFFFDD00
#define COLOR_ORANGE 0xFF00A5FF #define COLOR_ORANGE 0xFF00A5FF
#define set_color install_set_color #define set_color install_set_color
#define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed #define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed
#define path_exists install_path_exists #define path_exists install_path_exists
#define count_directory_items install_count_directory_items #define count_directory_items install_count_directory_items
// Clean mode: Backup user data // Clean mode: Backup user data
int clean_mode_backup(void) { int clean_mode_backup(void) {
set_color(COLOR_CYAN); set_color(COLOR_CYAN);
gfx_printf(" Sichere: DBI, Tinfoil, prod.keys\n"); gfx_printf(" Sichere: DBI, Tinfoil, prod.keys\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
int res = backup_user_data(); int res = backup_user_data();
if (res == FR_OK) { if (res == FR_OK) {
set_color(COLOR_GREEN); set_color(COLOR_GREEN);
gfx_printf(" [OK] Sicherung abgeschlossen\n"); gfx_printf(" [OK] Sicherung abgeschlossen\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
} }
return res; return res;
} }
// Clean mode: Wipe using selective deletion list (does not wipe whole card) // Clean mode: Wipe using selective deletion list (does not wipe whole card)
int clean_mode_wipe(void) { int clean_mode_wipe(void) {
check_and_clear_screen_if_needed(); check_and_clear_screen_if_needed();
set_color(COLOR_CYAN); set_color(COLOR_WHITE);
gfx_printf(" Bereinige: atmosphere/\n"); delete_path_lists_grouped("atmosphere/",
set_color(COLOR_WHITE); clean_atmosphere_dirs_to_delete,
delete_path_list(clean_atmosphere_dirs_to_delete, "atmosphere subdirs"); clean_atmosphere_contents_dirs_to_delete,
delete_path_list(clean_atmosphere_contents_dirs_to_delete, "atmosphere contents dirs"); clean_atmosphere_files_to_delete,
delete_path_list(clean_atmosphere_files_to_delete, "atmosphere files"); NULL);
set_color(COLOR_CYAN); delete_path_lists_grouped("bootloader/",
gfx_printf(" Bereinige: bootloader/\n"); clean_bootloader_dirs_to_delete,
set_color(COLOR_WHITE); clean_bootloader_files_to_delete,
delete_path_list(clean_bootloader_dirs_to_delete, "bootloader dirs"); NULL);
delete_path_list(clean_bootloader_files_to_delete, "bootloader files");
delete_path_lists_grouped("config/",
set_color(COLOR_CYAN); clean_config_dirs_to_delete,
gfx_printf(" Bereinige: config/\n"); NULL);
set_color(COLOR_WHITE);
delete_path_list(clean_config_dirs_to_delete, "config dirs"); delete_path_lists_grouped("switch/",
clean_switch_dirs_to_delete,
set_color(COLOR_CYAN); clean_switch_files_to_delete,
gfx_printf(" Bereinige: switch/\n"); NULL);
set_color(COLOR_WHITE);
delete_path_list(clean_switch_dirs_to_delete, "switch dirs"); delete_path_lists_grouped("Root-Dateien",
delete_path_list(clean_switch_files_to_delete, "switch files"); clean_root_files_to_delete,
clean_misc_dirs_to_delete,
set_color(COLOR_CYAN); clean_misc_files_to_delete,
gfx_printf(" Bereinige: Root-Dateien\n"); NULL);
set_color(COLOR_WHITE);
delete_path_list(clean_root_files_to_delete, "root files"); delete_path_lists_grouped("Alte Versionsmarker",
delete_path_list(clean_misc_dirs_to_delete, "misc dirs"); old_version_files_to_delete,
delete_path_list(clean_misc_files_to_delete, "misc files"); NULL);
set_color(COLOR_CYAN); set_color(COLOR_CYAN);
gfx_printf(" Bereinige: Alte Versionsmarker\n"); gfx_printf(" Erstelle: switch/\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
delete_path_list(old_version_files_to_delete, "old version markers"); f_mkdir("sd:/switch");
set_color(COLOR_CYAN); set_color(COLOR_GREEN);
gfx_printf(" Erstelle: switch/\n"); gfx_printf(" Bereinigung abgeschlossen!\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
f_mkdir("sd:/switch");
return FR_OK;
set_color(COLOR_GREEN); }
gfx_printf(" Bereinigung abgeschlossen!\n");
set_color(COLOR_WHITE); // Clean mode: Restore user data
int clean_mode_restore(void) {
return FR_OK; set_color(COLOR_CYAN);
} gfx_printf(" Stelle wieder her: DBI, Tinfoil, prod.keys\n");
set_color(COLOR_WHITE);
// Clean mode: Restore user data int res = restore_user_data();
int clean_mode_restore(void) { if (res == FR_OK) {
set_color(COLOR_CYAN); set_color(COLOR_GREEN);
gfx_printf(" Stelle wieder her: DBI, Tinfoil, prod.keys\n"); gfx_printf(" [OK] Wiederherstellung abgeschlossen\n");
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
int res = restore_user_data(); }
if (res == FR_OK) { cleanup_backup();
set_color(COLOR_GREEN); return res;
gfx_printf(" [OK] Wiederherstellung abgeschlossen\n"); }
set_color(COLOR_WHITE);
} // Clean mode: Install files (reuse update mode install)
cleanup_backup(); int clean_mode_install(omninx_variant_t variant) {
return res; return update_mode_install(variant);
} }
// Clean mode: Install files (reuse update mode install) // Remove other staging directories (OmniNX Standard/Light/OC) that exist on SD
int clean_mode_install(omninx_variant_t variant) { int cleanup_other_staging_directories(omninx_variant_t installed_variant) {
return update_mode_install(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;
// Remove other staging directories (OmniNX Standard/Light/OC) that exist on SD
int cleanup_other_staging_directories(omninx_variant_t installed_variant) { for (int i = 0; i < n; i++) {
static const omninx_variant_t all_variants[] = { VARIANT_STANDARD, VARIANT_LIGHT, VARIANT_OC }; omninx_variant_t v = all_variants[i];
const int n = sizeof(all_variants) / sizeof(all_variants[0]); if (v == installed_variant)
int last_res = FR_OK; continue;
const char *staging = get_staging_path(v);
for (int i = 0; i < n; i++) { if (!staging || !path_exists(staging))
omninx_variant_t v = all_variants[i]; continue;
if (v == installed_variant)
continue; check_and_clear_screen_if_needed();
const char *staging = get_staging_path(v); set_color(COLOR_YELLOW);
if (!staging || !path_exists(staging)) gfx_printf("\nEntferne weiteren Installationsordner...\n");
continue; set_color(COLOR_WHITE);
check_and_clear_screen_if_needed(); int total = count_directory_items(staging);
set_color(COLOR_YELLOW); u32 start_x, start_y;
gfx_printf("\nEntferne weiteren Installationsordner...\n"); gfx_con_getpos(&start_x, &start_y);
set_color(COLOR_WHITE);
const char *folder_name = strrchr(staging, '/');
int total = count_directory_items(staging); if (folder_name) folder_name++;
u32 start_x, start_y; else folder_name = staging;
gfx_con_getpos(&start_x, &start_y);
set_color(COLOR_CYAN);
const char *folder_name = strrchr(staging, '/'); gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total);
if (folder_name) folder_name++; set_color(COLOR_WHITE);
else folder_name = staging;
int deleted = 0;
set_color(COLOR_CYAN); int last_percent = -1;
gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total); int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent);
set_color(COLOR_WHITE);
gfx_con_setpos(start_x, start_y);
int deleted = 0; if (res == FR_OK) {
int last_percent = -1; set_color(COLOR_GREEN);
int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent); gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total);
set_color(COLOR_WHITE);
gfx_con_setpos(start_x, start_y); } else {
if (res == FR_OK) { set_color(COLOR_ORANGE);
set_color(COLOR_GREEN); gfx_printf(" Loesche: %s - Fehlgeschlagen!\n", folder_name);
gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total); gfx_printf(" [WARN] Ordner konnte nicht entfernt werden (err=%d)\n", res);
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
} else { }
set_color(COLOR_ORANGE); last_res = res;
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 last_res;
} }
last_res = res;
}
return last_res;
}

View File

@@ -1,237 +1,199 @@
/* /*
* OmniNX Installer - Update Mode * OmniNX Installer - Update Mode
* Selective cleanup and install when OmniNX is already installed. * Selective cleanup and install when OmniNX is already installed.
*/ */
#include "install.h" #include "install.h"
#include "deletion_lists_update.h" #include "deletion_lists_update.h"
#include "fs.h" #include "fs.h"
#include "version.h" #include "version.h"
#include "gfx.h" #include "gfx.h"
#include <libs/fatfs/ff.h> #include <libs/fatfs/ff.h>
#include <string.h> #include <string.h>
#include <utils/sprintf.h> #include <utils/sprintf.h>
#ifndef VERSION #ifndef VERSION
#define VERSION "1.0.0" #define VERSION "1.0.0"
#endif #endif
#undef COLOR_CYAN #undef COLOR_CYAN
#undef COLOR_WHITE #undef COLOR_WHITE
#undef COLOR_GREEN #undef COLOR_GREEN
#undef COLOR_YELLOW #undef COLOR_YELLOW
#undef COLOR_ORANGE #undef COLOR_ORANGE
#undef COLOR_RED #undef COLOR_RED
#define COLOR_CYAN 0xFF00FFFF #define COLOR_CYAN 0xFF00FFFF
#define COLOR_WHITE 0xFFFFFFFF #define COLOR_WHITE 0xFFFFFFFF
#define COLOR_GREEN 0xFF00FF00 #define COLOR_GREEN 0xFF00FF00
#define COLOR_YELLOW 0xFFFFDD00 #define COLOR_YELLOW 0xFFFFDD00
#define COLOR_ORANGE 0xFF00A5FF #define COLOR_ORANGE 0xFF00A5FF
#define COLOR_RED 0xFFFF0000 #define COLOR_RED 0xFFFF0000
#define set_color install_set_color #define set_color install_set_color
#define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed #define check_and_clear_screen_if_needed install_check_and_clear_screen_if_needed
#define path_exists install_path_exists #define path_exists install_path_exists
#define count_directory_items install_count_directory_items #define count_directory_items install_count_directory_items
// Update mode: Cleanup specific directories/files // Update mode: Cleanup specific directories/files
int update_mode_cleanup(omninx_variant_t variant) { int update_mode_cleanup(omninx_variant_t variant) {
(void)variant; (void)variant;
check_and_clear_screen_if_needed(); check_and_clear_screen_if_needed();
set_color(COLOR_CYAN); set_color(COLOR_WHITE);
gfx_printf(" Bereinige: atmosphere/\n"); delete_path_lists_grouped("atmosphere/",
set_color(COLOR_WHITE); atmosphere_dirs_to_delete,
delete_path_list(atmosphere_dirs_to_delete, "atmosphere subdirs"); atmosphere_contents_dirs_to_delete,
delete_path_list(atmosphere_contents_dirs_to_delete, "atmosphere contents dirs"); atmosphere_files_to_delete,
delete_path_list(atmosphere_files_to_delete, "atmosphere files"); NULL);
set_color(COLOR_CYAN); delete_path_lists_grouped("bootloader/",
gfx_printf(" Bereinige: bootloader/\n"); bootloader_dirs_to_delete,
set_color(COLOR_WHITE); bootloader_files_to_delete,
delete_path_list(bootloader_dirs_to_delete, "bootloader dirs"); NULL);
delete_path_list(bootloader_files_to_delete, "bootloader files");
delete_path_lists_grouped("config/",
set_color(COLOR_CYAN); config_dirs_to_delete,
gfx_printf(" Bereinige: config/\n"); NULL);
set_color(COLOR_WHITE);
delete_path_list(config_dirs_to_delete, "config dirs"); delete_path_lists_grouped("switch/",
switch_dirs_to_delete,
set_color(COLOR_CYAN); switch_files_to_delete,
gfx_printf(" Bereinige: switch/\n"); NULL);
set_color(COLOR_WHITE);
delete_path_list(switch_dirs_to_delete, "switch dirs"); delete_path_lists_grouped("Root-Dateien",
delete_path_list(switch_files_to_delete, "switch files"); root_files_to_delete,
misc_dirs_to_delete,
set_color(COLOR_CYAN); misc_files_to_delete,
gfx_printf(" Bereinige: Root-Dateien\n"); NULL);
set_color(COLOR_WHITE);
delete_path_list(root_files_to_delete, "root files"); set_color(COLOR_GREEN);
delete_path_list(misc_dirs_to_delete, "misc dirs"); gfx_printf(" Bereinigung abgeschlossen!\n");
delete_path_list(misc_files_to_delete, "misc files"); set_color(COLOR_WHITE);
set_color(COLOR_GREEN); return FR_OK;
gfx_printf(" Bereinigung abgeschlossen!\n"); }
set_color(COLOR_WHITE);
// Update mode: Copy files from staging
return FR_OK; int update_mode_install(omninx_variant_t variant) {
} int res;
const char* staging = get_staging_path(variant);
// Update mode: Copy files from staging char src_path[256];
int update_mode_install(omninx_variant_t variant) { char dst_path[256];
int res;
const char* staging = get_staging_path(variant); if (!staging) {
char src_path[256]; return FR_INVALID_PARAMETER;
char dst_path[256]; }
if (!staging) { check_and_clear_screen_if_needed();
return FR_INVALID_PARAMETER;
} set_color(COLOR_YELLOW);
gfx_printf("Dateien werden kopiert...\n");
check_and_clear_screen_if_needed(); set_color(COLOR_WHITE);
set_color(COLOR_YELLOW); s_printf(src_path, "%s/atmosphere", staging);
gfx_printf("Dateien werden kopiert...\n"); res = folder_copy_with_progress_v2(src_path, "sd:/", "atmosphere/");
set_color(COLOR_WHITE); if (res != FR_OK && res != FR_NO_FILE) return res;
s_printf(src_path, "%s/atmosphere", staging); s_printf(src_path, "%s/bootloader", staging);
res = folder_copy_with_progress_v2(src_path, "sd:/", "atmosphere/"); res = folder_copy_with_progress_v2(src_path, "sd:/", "bootloader/");
if (res != FR_OK && res != FR_NO_FILE) return res; if (res != FR_OK && res != FR_NO_FILE) return res;
s_printf(src_path, "%s/bootloader", staging); s_printf(src_path, "%s/config", staging);
res = folder_copy_with_progress_v2(src_path, "sd:/", "bootloader/"); res = folder_copy_with_progress_v2(src_path, "sd:/", "config/");
if (res != FR_OK && res != FR_NO_FILE) return res; if (res != FR_OK && res != FR_NO_FILE) return res;
s_printf(src_path, "%s/config", staging); s_printf(src_path, "%s/switch", staging);
res = folder_copy_with_progress_v2(src_path, "sd:/", "config/"); res = folder_copy_with_progress_v2(src_path, "sd:/", "switch/");
if (res != FR_OK && res != FR_NO_FILE) return res; if (res != FR_OK && res != FR_NO_FILE) return res;
s_printf(src_path, "%s/switch", staging); s_printf(src_path, "%s/warmboot_mariko", staging);
res = folder_copy_with_progress_v2(src_path, "sd:/", "switch/"); res = folder_copy_with_progress_v2(src_path, "sd:/", "warmboot_mariko/");
if (res != FR_OK && res != FR_NO_FILE) return res; if (res != FR_OK && res != FR_NO_FILE) return res;
s_printf(src_path, "%s/warmboot_mariko", staging); if (variant == VARIANT_OC) {
res = folder_copy_with_progress_v2(src_path, "sd:/", "warmboot_mariko/"); s_printf(src_path, "%s/SaltySD", staging);
if (res != FR_OK && res != FR_NO_FILE) return res; res = folder_copy_with_progress_v2(src_path, "sd:/", "SaltySD/");
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/"); set_color(COLOR_CYAN);
if (res != FR_OK && res != FR_NO_FILE) return res; gfx_printf(" Kopiere Root-Dateien...\n");
} set_color(COLOR_WHITE);
set_color(COLOR_CYAN); s_printf(src_path, "%s/boot.dat", staging);
gfx_printf(" Kopiere Root-Dateien...\n"); s_printf(dst_path, "sd:/boot.dat");
set_color(COLOR_WHITE); if (path_exists(src_path)) file_copy(src_path, dst_path);
s_printf(src_path, "%s/boot.dat", staging); s_printf(src_path, "%s/boot.ini", staging);
s_printf(dst_path, "sd:/boot.dat"); s_printf(dst_path, "sd:/boot.ini");
if (path_exists(src_path)) file_copy(src_path, dst_path); if (path_exists(src_path)) file_copy(src_path, dst_path);
s_printf(src_path, "%s/boot.ini", staging); s_printf(src_path, "%s/exosphere.ini", staging);
s_printf(dst_path, "sd:/boot.ini"); s_printf(dst_path, "sd:/exosphere.ini");
if (path_exists(src_path)) file_copy(src_path, dst_path); if (path_exists(src_path)) file_copy(src_path, dst_path);
s_printf(src_path, "%s/exosphere.ini", staging); s_printf(src_path, "%s/hbmenu.nro", staging);
s_printf(dst_path, "sd:/exosphere.ini"); s_printf(dst_path, "sd:/hbmenu.nro");
if (path_exists(src_path)) file_copy(src_path, dst_path); if (path_exists(src_path)) file_copy(src_path, dst_path);
s_printf(src_path, "%s/hbmenu.nro", staging); s_printf(src_path, "%s/loader.bin", staging);
s_printf(dst_path, "sd:/hbmenu.nro"); s_printf(dst_path, "sd:/loader.bin");
if (path_exists(src_path)) file_copy(src_path, dst_path); if (path_exists(src_path)) file_copy(src_path, dst_path);
s_printf(src_path, "%s/loader.bin", staging); s_printf(src_path, "%s/payload.bin", staging);
s_printf(dst_path, "sd:/loader.bin"); s_printf(dst_path, "sd:/payload.bin");
if (path_exists(src_path)) file_copy(src_path, dst_path); if (path_exists(src_path)) file_copy(src_path, dst_path);
s_printf(src_path, "%s/payload.bin", staging); set_color(COLOR_GREEN);
s_printf(dst_path, "sd:/payload.bin"); gfx_printf(" Kopie abgeschlossen!\n");
if (path_exists(src_path)) file_copy(src_path, dst_path); set_color(COLOR_WHITE);
set_color(COLOR_CYAN); return FR_OK;
gfx_printf(" Erstelle manifest.ini...\n"); }
set_color(COLOR_WHITE);
// Remove staging directory after installation
s_printf(dst_path, "sd:/config/omninx"); int cleanup_staging_directory(omninx_variant_t pack_variant) {
f_mkdir(dst_path); const char* staging = get_staging_path(pack_variant);
if (!staging) {
const char* pack_name; return FR_INVALID_PARAMETER;
int update_channel; }
switch (variant) {
case VARIANT_STANDARD: pack_name = "Standard"; update_channel = 2; break; check_and_clear_screen_if_needed();
case VARIANT_LIGHT: pack_name = "Light"; update_channel = 0; break;
case VARIANT_OC: pack_name = "OC"; update_channel = 1; break; if (path_exists(staging)) {
default: pack_name = "unknown"; update_channel = 0; break; set_color(COLOR_YELLOW);
} gfx_printf("\nEntferne Installationsordner...\n");
set_color(COLOR_WHITE);
s_printf(dst_path, "sd:/config/omninx/manifest.ini");
FIL fp; int total = count_directory_items(staging);
if (f_open(&fp, dst_path, FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { u32 start_x, start_y;
f_printf(&fp, "[OmniNX]\n"); gfx_con_getpos(&start_x, &start_y);
f_printf(&fp, "current_pack=%s\n", pack_name);
f_printf(&fp, "version=%s\n", VERSION); const char *folder_name = strrchr(staging, '/');
f_printf(&fp, "update_channel=%d\n", update_channel); if (folder_name) folder_name++;
f_printf(&fp, "channel_pack=%s\n", pack_name); else folder_name = staging;
f_close(&fp);
set_color(COLOR_GREEN); set_color(COLOR_CYAN);
gfx_printf(" [OK] manifest.ini erstellt\n"); gfx_printf(" Loesche: %s [ 0%%] (0/%d)", folder_name, total);
set_color(COLOR_WHITE); set_color(COLOR_WHITE);
} else {
set_color(COLOR_ORANGE); int deleted = 0;
gfx_printf(" [WARN] manifest.ini konnte nicht erstellt werden\n"); int last_percent = -1;
set_color(COLOR_WHITE); int res = folder_delete_progress_recursive(staging, &deleted, total, start_x, start_y, folder_name, &last_percent);
}
gfx_con_setpos(start_x, start_y);
set_color(COLOR_GREEN); if (res == FR_OK) {
gfx_printf(" Kopie abgeschlossen!\n"); set_color(COLOR_GREEN);
set_color(COLOR_WHITE); gfx_printf(" Loesche: %s [100%%] (%d/%d) - Fertig!\n", folder_name, deleted, total);
set_color(COLOR_WHITE);
return FR_OK; } else {
} set_color(COLOR_ORANGE);
gfx_printf(" Loesche: %s - Fehlgeschlagen!\n", folder_name);
// Remove staging directory after installation gfx_printf(" [WARN] Ordner konnte nicht entfernt werden (err=%d)\n", res);
int cleanup_staging_directory(omninx_variant_t pack_variant) { set_color(COLOR_WHITE);
const char* staging = get_staging_path(pack_variant); }
if (!staging) { return res;
return FR_INVALID_PARAMETER; }
}
return FR_OK;
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;
}