morpheus_core/fs/fat32_ops/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// FAT32 filesystem operations - minimal implementation for bootloader installation

mod context;
mod directory;
mod file_ops;
pub mod filename;
mod types;

use super::Fat32Error;
use context::Fat32Context;
use gpt_disk_io::BlockIo;

extern crate alloc;
use alloc::vec::Vec;

/// Progress callback type: (bytes_written, total_bytes, message)
pub type ProgressCallback<'a> = Option<&'a mut dyn FnMut(usize, usize, &str)>;

/// Write file to FAT32 partition
pub fn write_file<B: BlockIo>(
    block_io: &mut B,
    partition_lba_start: u64,
    path: &str,
    data: &[u8],
) -> Result<(), Fat32Error> {
    write_file_with_progress(block_io, partition_lba_start, path, data, &mut None)
}

/// Write file to FAT32 partition with progress reporting
pub fn write_file_with_progress<B: BlockIo>(
    block_io: &mut B,
    partition_lba_start: u64,
    path: &str,
    data: &[u8],
    progress: &mut ProgressCallback,
) -> Result<(), Fat32Error> {
    let ctx = Fat32Context::from_boot_sector(block_io, partition_lba_start)?;

    // Parse path
    let path = path.trim_start_matches('/');
    let parts: Vec<&str> = path.split('/').collect();

    // Navigate/create directory structure
    let mut current_cluster = ctx.root_cluster;
    for (i, part) in parts.iter().enumerate() {
        let is_last = i == parts.len() - 1;

        if !is_last {
            // This is a directory component
            current_cluster = directory::ensure_directory_exists(
                block_io,
                partition_lba_start,
                &ctx,
                current_cluster,
                part,
            )?;
        } else {
            // This is the file name - create/write it
            file_ops::write_file_in_directory_with_progress(
                block_io,
                partition_lba_start,
                &ctx,
                current_cluster,
                part,
                data,
                progress,
            )?;
        }
    }

    block_io.flush().map_err(|_| Fat32Error::IoError)?;
    Ok(())
}

/// Create directory (creates full path)
pub fn create_directory<B: BlockIo>(
    block_io: &mut B,
    partition_lba_start: u64,
    path: &str,
) -> Result<(), Fat32Error> {
    let ctx = Fat32Context::from_boot_sector(block_io, partition_lba_start)?;
    directory::create_directory(block_io, partition_lba_start, &ctx, path)?;
    block_io.flush().map_err(|_| Fat32Error::IoError)?;
    Ok(())
}

/// Read file data from FAT32 partition
pub fn read_file<B: BlockIo>(
    block_io: &mut B,
    partition_lba_start: u64,
    path: &str,
) -> Result<Vec<u8>, Fat32Error> {
    let ctx = Fat32Context::from_boot_sector(block_io, partition_lba_start)?;
    file_ops::read_file(block_io, partition_lba_start, &ctx, path)
}

/// Check if file exists
pub fn file_exists<B: BlockIo>(
    block_io: &mut B,
    partition_lba_start: u64,
    path: &str,
) -> Result<bool, Fat32Error> {
    let ctx = Fat32Context::from_boot_sector(block_io, partition_lba_start)?;
    file_ops::file_exists(block_io, partition_lba_start, &ctx, path)
}