[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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 98 additions and 22 deletions

View file

@ -102,11 +102,6 @@ int32_t storage_srv(void* p) {
Storage* app = storage_app_alloc(); Storage* app = storage_app_alloc();
furi_record_create(RECORD_STORAGE, app); furi_record_create(RECORD_STORAGE, app);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStorageFormatInternal)) {
FURI_LOG_W(TAG, "Format Internal not supported, clearing flag");
furi_hal_rtc_reset_flag(FuriHalRtcFlagStorageFormatInternal);
}
StorageMessage message; StorageMessage message;
while(1) { while(1) {
if(furi_message_queue_get(app->message_queue, &message, STORAGE_TICK) == FuriStatusOk) { if(furi_message_queue_get(app->message_queue, &message, STORAGE_TICK) == FuriStatusOk) {

View file

@ -0,0 +1,3 @@
#pragma once
#define STORAGE_INTERNAL_DIR_NAME ".int"

View file

@ -1,7 +1,9 @@
#include "storage_processing.h"
#include <m-list.h> #include <m-list.h>
#include <m-dict.h> #include <m-dict.h>
#include "storage_processing.h"
#include "storage_internal_dirname_i.h"
#define TAG "Storage" #define TAG "Storage"
#define STORAGE_PATH_PREFIX_LEN 4u #define STORAGE_PATH_PREFIX_LEN 4u
@ -555,9 +557,9 @@ void storage_process_alias(
} else if(furi_string_start_with(path, STORAGE_INT_PATH_PREFIX)) { } else if(furi_string_start_with(path, STORAGE_INT_PATH_PREFIX)) {
furi_string_replace_at( furi_string_replace_at(
path, 0, strlen(STORAGE_INT_PATH_PREFIX), STORAGE_EXT_PATH_PREFIX "/.int"); path, 0, strlen(STORAGE_INT_PATH_PREFIX), EXT_PATH(STORAGE_INTERNAL_DIR_NAME));
FuriString* int_on_ext_path = furi_string_alloc_set(STORAGE_EXT_PATH_PREFIX "/.int"); FuriString* int_on_ext_path = furi_string_alloc_set(EXT_PATH(STORAGE_INTERNAL_DIR_NAME));
if(storage_process_common_stat(app, int_on_ext_path, NULL) != FSE_OK) { if(storage_process_common_stat(app, int_on_ext_path, NULL) != FSE_OK) {
storage_process_common_mkdir(app, int_on_ext_path); storage_process_common_mkdir(app, int_on_ext_path);
} }

View file

@ -1,10 +1,13 @@
#include "fatfs.h" #include <fatfs.h>
#include "../filesystem_api_internal.h"
#include "storage_ext.h"
#include <furi_hal.h> #include <furi_hal.h>
#include "sd_notify.h"
#include <furi_hal_sd.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 FIL SDFile;
typedef DIR SDDir; typedef DIR SDDir;
typedef FILINFO SDFileInfo; typedef FILINFO SDFileInfo;
@ -93,6 +96,64 @@ static bool sd_mount_card_internal(StorageData* storage, bool notify) {
return result; 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) { FS_Error sd_unmount_card(StorageData* storage) {
SDData* sd_data = storage->data; SDData* sd_data = storage->data;
SDError error; SDError error;
@ -112,21 +173,32 @@ FS_Error sd_mount_card(StorageData* storage, bool notify) {
if(storage->status != StorageStatusOK) { if(storage->status != StorageStatusOK) {
FURI_LOG_E(TAG, "sd init error: %s", storage_data_status_text(storage)); 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; error = FSE_INTERNAL;
} else { } else {
FURI_LOG_I(TAG, "card mounted"); 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; 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; 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 // do not notify on first launch, notifications app is waiting for our thread to read settings
storage_ext_tick_internal(storage, false); 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
} }