Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

Commit

Permalink
Archive: Support viewing Disk Images with Virtual Mount
Browse files Browse the repository at this point in the history
  • Loading branch information
Willy-JL committed Feb 20, 2024
1 parent 39bd3f4 commit e229367
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 8 deletions.
7 changes: 7 additions & 0 deletions applications/main/archive/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ void archive_free(ArchiveApp* archive) {
archive->thread = NULL;
}

if(archive->browser->disk_image) {
storage_virtual_quit(furi_record_open(RECORD_STORAGE));
furi_record_close(RECORD_STORAGE);
storage_file_free(archive->browser->disk_image);
archive->browser->disk_image = NULL;
}

// Loading
loading_free(archive->loading);

Expand Down
9 changes: 6 additions & 3 deletions applications/main/archive/helpers/archive_browser.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ static void
browser->is_root = is_root;
ArchiveTabEnum tab = archive_get_tab(browser);

if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser)) {
if((item_cnt == 0) && (archive_is_home(browser)) && (tab != ArchiveTabBrowser) &&
(tab != ArchiveTabDiskImage || !browser->disk_image)) {
archive_switch_tab(browser, browser->last_tab_switch_dir);
} else if(!furi_string_start_with_str(browser->path, "/app:")) {
with_view_model(
Expand Down Expand Up @@ -512,7 +513,8 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) {

static bool archive_is_dir_exists(FuriString* path) {
if(furi_string_equal(path, STORAGE_INT_PATH_PREFIX) ||
furi_string_equal(path, STORAGE_EXT_PATH_PREFIX)) {
furi_string_equal(path, STORAGE_EXT_PATH_PREFIX) ||
furi_string_equal(path, STORAGE_MNT_PATH_PREFIX)) {
return true;
}
bool state = false;
Expand Down Expand Up @@ -592,7 +594,8 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
}
}

if(tab_empty && tab != ArchiveTabBrowser && tab != ArchiveTabInternal) {
if(tab_empty && tab != ArchiveTabBrowser && tab != ArchiveTabInternal &&
(tab != ArchiveTabDiskImage || !browser->disk_image)) {
archive_switch_tab(browser, key);
} else {
with_view_model(
Expand Down
2 changes: 2 additions & 0 deletions applications/main/archive/helpers/archive_browser.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ static const char* tab_default_paths[] = {
[ArchiveTabU2f] = "/app:u2f",
[ArchiveTabApplications] = EXT_PATH("apps"),
[ArchiveTabSearch] = "/app:search",
[ArchiveTabDiskImage] = STORAGE_MNT_PATH_PREFIX,
[ArchiveTabInternal] = STORAGE_INT_PATH_PREFIX,
[ArchiveTabBrowser] = STORAGE_EXT_PATH_PREFIX,
};
Expand Down Expand Up @@ -54,6 +55,7 @@ static const ArchiveFileTypeEnum known_type[] = {
[ArchiveTabU2f] = ArchiveFileTypeU2f,
[ArchiveTabApplications] = ArchiveFileTypeAppOrJs,
[ArchiveTabSearch] = ArchiveFileTypeSearch,
[ArchiveTabDiskImage] = ArchiveFileTypeUnknown,
[ArchiveTabInternal] = ArchiveFileTypeUnknown,
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
};
Expand Down
55 changes: 52 additions & 3 deletions applications/main/archive/scenes/archive_scene_browser.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,50 @@ static void archive_show_file(Loader* loader, const char* path) {
}
}

static void archive_mount_disk_image(ArchiveBrowserView* browser, ArchiveFile_t* selected) {
Storage* storage = furi_record_open(RECORD_STORAGE);
File* disk_image = NULL;
do {
if(browser->disk_image) {
// Deinit and recycle File object
if(storage_virtual_quit(storage) != FSE_OK) break;
storage_file_close(browser->disk_image);
disk_image = browser->disk_image;
browser->disk_image = NULL;
} else {
disk_image = storage_file_alloc(storage);
}

if(!storage_file_open(
disk_image,
furi_string_get_cstr(selected->path),
FSAM_READ | FSAM_WRITE,
FSOM_OPEN_EXISTING))
break;

FS_Error init = storage_virtual_init(storage, disk_image);
if(init == FSE_ALREADY_OPEN) {
if(storage_virtual_quit(storage) == FSE_OK) {
init = storage_virtual_init(storage, disk_image);
}
}
if(init != FSE_OK) break;

if(storage_virtual_mount(storage) != FSE_OK) {
storage_virtual_quit(storage);
break;
}

browser->disk_image = disk_image;

while(archive_get_tab(browser) != ArchiveTabDiskImage) {
archive_switch_tab(browser, TAB_LEFT);
}
} while(0);
if(disk_image && !browser->disk_image) storage_file_free(disk_image);
furi_record_close(RECORD_STORAGE);
}

static void
archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected, bool favorites) {
Loader* loader = furi_record_open(RECORD_LOADER);
Expand Down Expand Up @@ -226,9 +270,14 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
consumed = true;
break;
case ArchiveBrowserEventFileMenuShow:
archive_show_file(
furi_record_open(RECORD_LOADER), furi_string_get_cstr(selected->path));
furi_record_close(RECORD_LOADER);
if(selected->type == ArchiveFileTypeDiskImage &&
archive_get_tab(browser) != ArchiveTabDiskImage) {
archive_mount_disk_image(browser, selected);
} else {
archive_show_file(
furi_record_open(RECORD_LOADER), furi_string_get_cstr(selected->path));
furi_record_close(RECORD_LOADER);
}
archive_show_file_menu(browser, false, false);
consumed = true;
break;
Expand Down
6 changes: 4 additions & 2 deletions applications/main/archive/views/archive_browser_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ static const char* ArchiveTabNames[] = {
[ArchiveTabU2f] = "U2F",
[ArchiveTabApplications] = "Apps",
[ArchiveTabSearch] = "Search",
[ArchiveTabDiskImage] = "Disk Image",
[ArchiveTabInternal] = "Internal",
[ArchiveTabBrowser] = "Browser",
};
Expand Down Expand Up @@ -119,7 +120,7 @@ static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
if(selected->type != ArchiveFileTypeFolder) {
archive_menu_add_item(
menu_array_push_raw(model->context_menu),
"Show",
selected->type == ArchiveFileTypeDiskImage ? "Mount" : "Show",
ArchiveBrowserEventFileMenuShow);
}
}
Expand Down Expand Up @@ -209,7 +210,8 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
model->files, CLAMP(idx - model->array_offset, (int32_t)(array_size - 1), 0));
file_type = file->type;
bool ext = model->tab_idx == ArchiveTabBrowser ||
model->tab_idx == ArchiveTabInternal || model->tab_idx == ArchiveTabSearch;
model->tab_idx == ArchiveTabInternal ||
model->tab_idx == ArchiveTabDiskImage || model->tab_idx == ArchiveTabSearch;
if(file_type == ArchiveFileTypeApplication) {
if(file->custom_icon_data) {
custom_icon_data = file->custom_icon_data;
Expand Down
2 changes: 2 additions & 0 deletions applications/main/archive/views/archive_browser_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ typedef enum {
ArchiveTabU2f,
ArchiveTabApplications,
ArchiveTabSearch,
ArchiveTabDiskImage,
ArchiveTabInternal,
ArchiveTabBrowser,
ArchiveTabTotal,
Expand Down Expand Up @@ -90,6 +91,7 @@ struct ArchiveBrowserView {
InputKey last_tab_switch_dir;
bool is_root;
FuriTimer* scroll_timer;
File* disk_image;
};

typedef struct {
Expand Down

0 comments on commit e229367

Please sign in to comment.