[FL-3883] Remove internal storage folder if corresponding flag set (#3824)

* Remove the .int directory when the flag is set
* Improve error handling and variable naming
* Cleanup the code
* Fix updater build

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Georgii Surkov
2024-08-09 07:40:42 +01:00
committed by GitHub
parent 741329a743
commit 235cb649a6
4 changed files with 98 additions and 22 deletions

View File

@@ -1,10 +1,13 @@
#include "fatfs.h"
#include "../filesystem_api_internal.h"
#include "storage_ext.h"
#include <fatfs.h>
#include <furi_hal.h>
#include "sd_notify.h"
#include <furi_hal_sd.h>
#include "sd_notify.h"
#include "storage_ext.h"
#include "../filesystem_api_internal.h"
#include "../storage_internal_dirname_i.h"
typedef FIL SDFile;
typedef DIR SDDir;
typedef FILINFO SDFileInfo;
@@ -93,6 +96,64 @@ static bool sd_mount_card_internal(StorageData* storage, bool notify) {
return result;
}
static bool sd_remove_recursive(const char* path) {
SDDir* current_dir = malloc(sizeof(DIR));
SDFileInfo* file_info = malloc(sizeof(FILINFO));
FuriString* current_path = furi_string_alloc_set(path);
bool go_deeper = false;
SDError status;
while(true) {
status = f_opendir(current_dir, furi_string_get_cstr(current_path));
if(status != FR_OK) break;
while(true) {
status = f_readdir(current_dir, file_info);
if(status != FR_OK || !strlen(file_info->fname)) break;
if(file_info->fattrib & AM_DIR) {
furi_string_cat_printf(current_path, "/%s", file_info->fname);
go_deeper = true;
break;
} else {
FuriString* file_path = furi_string_alloc_printf(
"%s/%s", furi_string_get_cstr(current_path), file_info->fname);
status = f_unlink(furi_string_get_cstr(file_path));
furi_string_free(file_path);
if(status != FR_OK) break;
}
}
status = f_closedir(current_dir);
if(status != FR_OK) break;
if(go_deeper) {
go_deeper = false;
continue;
}
status = f_unlink(furi_string_get_cstr(current_path));
if(status != FR_OK) break;
if(!furi_string_equal(current_path, path)) {
size_t last_char_pos = furi_string_search_rchar(current_path, '/');
furi_assert(last_char_pos != FURI_STRING_FAILURE);
furi_string_left(current_path, last_char_pos);
} else {
break;
}
}
free(current_dir);
free(file_info);
furi_string_free(current_path);
return status == FR_OK;
}
FS_Error sd_unmount_card(StorageData* storage) {
SDData* sd_data = storage->data;
SDError error;
@@ -112,21 +173,32 @@ FS_Error sd_mount_card(StorageData* storage, bool notify) {
if(storage->status != StorageStatusOK) {
FURI_LOG_E(TAG, "sd init error: %s", storage_data_status_text(storage));
if(notify) {
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
sd_notify_error(notification);
furi_record_close(RECORD_NOTIFICATION);
}
error = FSE_INTERNAL;
} else {
FURI_LOG_I(TAG, "card mounted");
if(notify) {
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
sd_notify_success(notification);
furi_record_close(RECORD_NOTIFICATION);
}
#ifndef FURI_RAM_EXEC
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStorageFormatInternal)) {
FURI_LOG_I(TAG, "deleting internal storage directory");
error = sd_remove_recursive(STORAGE_INTERNAL_DIR_NAME) ? FSE_OK : FSE_INTERNAL;
} else {
error = FSE_OK;
}
#else
UNUSED(sd_remove_recursive);
error = FSE_OK;
#endif
}
if(notify) {
NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION);
if(error != FSE_OK) {
sd_notify_error(notification);
} else {
sd_notify_success(notification);
}
furi_record_close(RECORD_NOTIFICATION);
}
return error;
@@ -654,4 +726,8 @@ void storage_ext_init(StorageData* storage) {
// do not notify on first launch, notifications app is waiting for our thread to read settings
storage_ext_tick_internal(storage, false);
#ifndef FURI_RAM_EXEC
// always reset the flag to prevent accidental wipe on SD card insertion
furi_hal_rtc_reset_flag(FuriHalRtcFlagStorageFormatInternal);
#endif
}