Create a FAT32 disk image from a directory
(disk_path: impl AsRef<Path>, shared_dir: impl AsRef<Path>)
| 137 | |
| 138 | /// Create a FAT32 disk image from a directory |
| 139 | fn create_shared_disk(disk_path: impl AsRef<Path>, shared_dir: impl AsRef<Path>) -> Result<()> { |
| 140 | use fatfs::{FileSystem, FormatVolumeOptions, FsOptions}; |
| 141 | use std::io::{Cursor, Seek, SeekFrom, Write}; |
| 142 | |
| 143 | let disk_path = disk_path.as_ref(); |
| 144 | let shared_dir = shared_dir.as_ref(); |
| 145 | |
| 146 | const DISK_SIZE: usize = 8 * 1024 * 1024; |
| 147 | let mut disk_data = vec![0u8; DISK_SIZE]; |
| 148 | |
| 149 | { |
| 150 | let cursor = Cursor::new(&mut disk_data); |
| 151 | let mut label_bytes = [b' '; 11]; |
| 152 | let label_str = HOST_SHARED_DISK_LABEL.as_bytes(); |
| 153 | let copy_len = label_str.len().min(11); |
| 154 | label_bytes[..copy_len].copy_from_slice(&label_str[..copy_len]); |
| 155 | let format_opts = FormatVolumeOptions::new() |
| 156 | .fat_type(fatfs::FatType::Fat32) |
| 157 | .volume_label(label_bytes); |
| 158 | fatfs::format_volume(cursor, format_opts).context("Failed to format disk as FAT32")?; |
| 159 | } |
| 160 | |
| 161 | // Open the formatted filesystem in memory and copy files |
| 162 | { |
| 163 | let mut cursor = Cursor::new(&mut disk_data); |
| 164 | cursor |
| 165 | .seek(SeekFrom::Start(0)) |
| 166 | .context("Failed to seek to start")?; |
| 167 | let fs = |
| 168 | FileSystem::new(cursor, FsOptions::new()).context("Failed to open FAT32 filesystem")?; |
| 169 | let root_dir = fs.root_dir(); |
| 170 | |
| 171 | // Copy all files from shared_dir to the FAT32 root |
| 172 | for entry in fs::read_dir(shared_dir).context("Failed to read shared directory")? { |
| 173 | let entry = entry.context("Failed to read directory entry")?; |
| 174 | let path = entry.path(); |
| 175 | |
| 176 | if path.is_file() { |
| 177 | let filename = entry.file_name(); |
| 178 | let filename_str = filename.to_string_lossy(); |
| 179 | |
| 180 | // Read source file |
| 181 | let content = fs::read(&path) |
| 182 | .with_context(|| format!("Failed to read file {}", path.display()))?; |
| 183 | |
| 184 | // Write to FAT32 filesystem |
| 185 | let mut fat_file = root_dir |
| 186 | .create_file(&filename_str) |
| 187 | .with_context(|| format!("Failed to create file {filename_str} in FAT32"))?; |
| 188 | fat_file |
| 189 | .write_all(&content) |
| 190 | .with_context(|| format!("Failed to write file {filename_str} to FAT32"))?; |
| 191 | fat_file.flush().context("Failed to flush FAT32 file")?; |
| 192 | } |
| 193 | } |
| 194 | } |
| 195 | |
| 196 | fs::write(disk_path, &disk_data) |
no test coverage detected