1use crate::byteorder_ext::{ReadBytesExt, WriteBytesExt};
2use crate::core::cmp;
3use crate::io;
4use byteorder::LittleEndian;
5
6use crate::error::FatfsError;
7use crate::fs::{FatType, FsStatusFlags, ReadSeek, ReadWriteSeek};
8
9struct Fat<T> {
10 #[allow(dead_code)]
11 dummy: [T; 0],
12}
13
14type Fat12 = Fat<u8>;
15type Fat16 = Fat<u16>;
16type Fat32 = Fat<u32>;
17
18pub const RESERVED_FAT_ENTRIES: u32 = 2;
19
20#[derive(Copy, Clone, Eq, PartialEq, Debug)]
21enum FatValue {
22 Free,
23 Data(u32),
24 Bad,
25 EndOfChain,
26}
27
28trait FatTrait {
29 fn get_raw<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<u32>;
30 fn get<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<FatValue>;
31 fn set_raw<T: ReadWriteSeek>(fat: &mut T, cluster: u32, raw_value: u32) -> io::Result<()>;
32 fn set<T: ReadWriteSeek>(fat: &mut T, cluster: u32, value: FatValue) -> io::Result<()>;
33 fn find_free<T: ReadSeek>(fat: &mut T, start_cluster: u32, end_cluster: u32)
34 -> io::Result<u32>;
35 fn count_free<T: ReadSeek>(fat: &mut T, end_cluster: u32) -> io::Result<u32>;
36}
37
38fn read_fat<T: ReadSeek>(fat: &mut T, fat_type: FatType, cluster: u32) -> io::Result<FatValue> {
39 match fat_type {
40 FatType::Fat12 => Fat12::get(fat, cluster),
41 FatType::Fat16 => Fat16::get(fat, cluster),
42 FatType::Fat32 => Fat32::get(fat, cluster),
43 }
44}
45
46fn write_fat<T: ReadWriteSeek>(
47 fat: &mut T,
48 fat_type: FatType,
49 cluster: u32,
50 value: FatValue,
51) -> io::Result<()> {
52 trace!("write FAT - cluster {} value {:?}", cluster, value);
53 match fat_type {
54 FatType::Fat12 => Fat12::set(fat, cluster, value),
55 FatType::Fat16 => Fat16::set(fat, cluster, value),
56 FatType::Fat32 => Fat32::set(fat, cluster, value),
57 }
58}
59
60fn get_next_cluster<T: ReadSeek>(
61 fat: &mut T,
62 fat_type: FatType,
63 cluster: u32,
64) -> io::Result<Option<u32>> {
65 let val = read_fat(fat, fat_type, cluster)?;
66 match val {
67 FatValue::Data(n) => Ok(Some(n)),
68 _ => Ok(None),
69 }
70}
71
72fn find_free_cluster<T: ReadSeek>(
73 fat: &mut T,
74 fat_type: FatType,
75 start_cluster: u32,
76 end_cluster: u32,
77) -> io::Result<u32> {
78 match fat_type {
79 FatType::Fat12 => Fat12::find_free(fat, start_cluster, end_cluster),
80 FatType::Fat16 => Fat16::find_free(fat, start_cluster, end_cluster),
81 FatType::Fat32 => Fat32::find_free(fat, start_cluster, end_cluster),
82 }
83}
84
85pub(crate) fn alloc_cluster<T: ReadWriteSeek>(
86 fat: &mut T,
87 fat_type: FatType,
88 prev_cluster: Option<u32>,
89 hint: Option<u32>,
90 total_clusters: u32,
91) -> io::Result<u32> {
92 let end_cluster = total_clusters + RESERVED_FAT_ENTRIES;
93 let start_cluster = match hint {
94 Some(n) if n < end_cluster => n,
95 _ => RESERVED_FAT_ENTRIES,
96 };
97 let new_cluster = match find_free_cluster(fat, fat_type, start_cluster, end_cluster) {
98 Ok(n) => n,
99 Err(_) if start_cluster > RESERVED_FAT_ENTRIES => {
100 find_free_cluster(fat, fat_type, RESERVED_FAT_ENTRIES, start_cluster)?
101 }
102 Err(e) => return Err(e),
103 };
104 write_fat(fat, fat_type, new_cluster, FatValue::EndOfChain)?;
105 if let Some(n) = prev_cluster {
106 write_fat(fat, fat_type, n, FatValue::Data(new_cluster))?;
107 }
108 trace!("allocated cluster {}", new_cluster);
109 Ok(new_cluster)
110}
111
112pub(crate) fn read_fat_flags<T: ReadSeek>(
113 fat: &mut T,
114 fat_type: FatType,
115) -> io::Result<FsStatusFlags> {
116 let val = match fat_type {
118 FatType::Fat12 => 0xFFF,
119 FatType::Fat16 => Fat16::get_raw(fat, 1)?,
120 FatType::Fat32 => Fat32::get_raw(fat, 1)?,
121 };
122 let dirty = match fat_type {
123 FatType::Fat12 => false,
124 FatType::Fat16 => val & (1 << 15) == 0,
125 FatType::Fat32 => val & (1 << 27) == 0,
126 };
127 let io_error = match fat_type {
128 FatType::Fat12 => false,
129 FatType::Fat16 => val & (1 << 14) == 0,
130 FatType::Fat32 => val & (1 << 26) == 0,
131 };
132 Ok(FsStatusFlags { dirty, io_error })
133}
134
135pub(crate) fn count_free_clusters<T: ReadSeek>(
136 fat: &mut T,
137 fat_type: FatType,
138 total_clusters: u32,
139) -> io::Result<u32> {
140 let end_cluster = total_clusters + RESERVED_FAT_ENTRIES;
141 match fat_type {
142 FatType::Fat12 => Fat12::count_free(fat, end_cluster),
143 FatType::Fat16 => Fat16::count_free(fat, end_cluster),
144 FatType::Fat32 => Fat32::count_free(fat, end_cluster),
145 }
146}
147
148pub(crate) fn format_fat<T: ReadWriteSeek>(
149 fat: &mut T,
150 fat_type: FatType,
151 media: u8,
152 bytes_per_fat: u64,
153 total_clusters: u32,
154) -> io::Result<()> {
155 match fat_type {
157 FatType::Fat12 => {
158 fat.write_u8(media)?;
159 fat.write_u16::<LittleEndian>(0xFFFF)?;
160 }
161 FatType::Fat16 => {
162 fat.write_u16::<LittleEndian>(media as u16 | 0xFF00)?;
163 fat.write_u16::<LittleEndian>(0xFFFF)?;
164 }
165 FatType::Fat32 => {
166 fat.write_u32::<LittleEndian>(media as u32 | 0xFFFFF00)?;
167 fat.write_u32::<LittleEndian>(0xFFFFFFFF)?;
168 }
169 };
170 const BITS_PER_BYTE: u64 = 8;
172 let start_cluster = total_clusters + RESERVED_FAT_ENTRIES;
173 let end_cluster = (bytes_per_fat * BITS_PER_BYTE / fat_type.bits_per_fat_entry() as u64) as u32;
174 for cluster in start_cluster..end_cluster {
175 write_fat(fat, fat_type, cluster, FatValue::EndOfChain)?;
176 }
177 if end_cluster > 0x0FFFFFF0 {
179 let end_bad_cluster = cmp::min(0x0FFFFFFF + 1, end_cluster);
180 for cluster in 0x0FFFFFF0..end_bad_cluster {
181 write_fat(fat, fat_type, cluster, FatValue::Bad)?;
182 }
183 }
184 Ok(())
185}
186
187impl FatTrait for Fat12 {
188 fn get_raw<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<u32> {
189 let fat_offset = cluster + (cluster / 2);
190 fat.seek(io::SeekFrom::Start(fat_offset as u64))?;
191 let packed_val = fat.read_u16::<LittleEndian>()?;
192 Ok(match cluster & 1 {
193 0 => packed_val & 0x0FFF,
194 _ => packed_val >> 4,
195 } as u32)
196 }
197
198 fn get<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<FatValue> {
199 let val = Self::get_raw(fat, cluster)?;
200 Ok(match val {
201 0 => FatValue::Free,
202 0xFF7 => FatValue::Bad,
203 0xFF8..=0xFFF => FatValue::EndOfChain,
204 n => FatValue::Data(n as u32),
205 })
206 }
207
208 fn set<T: ReadWriteSeek>(fat: &mut T, cluster: u32, value: FatValue) -> io::Result<()> {
209 let raw_val = match value {
210 FatValue::Free => 0,
211 FatValue::Bad => 0xFF7,
212 FatValue::EndOfChain => 0xFFF,
213 FatValue::Data(n) => n as u16,
214 };
215 Self::set_raw(fat, cluster, raw_val as u32)
216 }
217
218 fn set_raw<T: ReadWriteSeek>(fat: &mut T, cluster: u32, raw_val: u32) -> io::Result<()> {
219 let fat_offset = cluster + (cluster / 2);
220 fat.seek(io::SeekFrom::Start(fat_offset as u64))?;
221 let old_packed = fat.read_u16::<LittleEndian>()?;
222 fat.seek(io::SeekFrom::Start(fat_offset as u64))?;
223 let new_packed = match cluster & 1 {
224 0 => (old_packed & 0xF000) | raw_val as u16,
225 _ => (old_packed & 0x000F) | ((raw_val as u16) << 4),
226 };
227 fat.write_u16::<LittleEndian>(new_packed)?;
228 Ok(())
229 }
230
231 fn find_free<T: ReadSeek>(
232 fat: &mut T,
233 start_cluster: u32,
234 end_cluster: u32,
235 ) -> io::Result<u32> {
236 let mut cluster = start_cluster;
237 let fat_offset = cluster + (cluster / 2);
238 fat.seek(io::SeekFrom::Start(fat_offset as u64))?;
239 let mut packed_val = fat.read_u16::<LittleEndian>()?;
240 loop {
241 let val = match cluster & 1 {
242 0 => packed_val & 0x0FFF,
243 _ => packed_val >> 4,
244 };
245 if val == 0 {
246 return Ok(cluster);
247 }
248 cluster += 1;
249 if cluster == end_cluster {
250 return Err(io::Error::new(io::ErrorKind::Other, FatfsError::NoSpace));
251 }
252 packed_val = match cluster & 1 {
253 0 => fat.read_u16::<LittleEndian>()?,
254 _ => {
255 let next_byte = fat.read_u8()? as u16;
256 (packed_val >> 8) | (next_byte << 8)
257 }
258 };
259 }
260 }
261
262 fn count_free<T: ReadSeek>(fat: &mut T, end_cluster: u32) -> io::Result<u32> {
263 let mut count = 0;
264 let mut cluster = RESERVED_FAT_ENTRIES;
265 fat.seek(io::SeekFrom::Start((cluster * 3 / 2) as u64))?;
266 let mut prev_packed_val = 0u16;
267 while cluster < end_cluster {
268 let res = match cluster & 1 {
269 0 => fat.read_u16::<LittleEndian>(),
270 _ => fat.read_u8().map(|n| n as u16),
271 };
272 let packed_val = match res {
273 Err(err) => return Err(err),
274 Ok(n) => n,
275 };
276 let val = match cluster & 1 {
277 0 => packed_val & 0x0FFF,
278 _ => (packed_val << 8) | (prev_packed_val >> 12),
279 };
280 prev_packed_val = packed_val;
281 if val == 0 {
282 count += 1;
283 }
284 cluster += 1;
285 }
286 Ok(count)
287 }
288}
289
290impl FatTrait for Fat16 {
291 fn get_raw<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<u32> {
292 fat.seek(io::SeekFrom::Start((cluster * 2) as u64))?;
293 Ok(fat.read_u16::<LittleEndian>()? as u32)
294 }
295
296 fn get<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<FatValue> {
297 let val = Self::get_raw(fat, cluster)?;
298 Ok(match val {
299 0 => FatValue::Free,
300 0xFFF7 => FatValue::Bad,
301 0xFFF8..=0xFFFF => FatValue::EndOfChain,
302 n => FatValue::Data(n as u32),
303 })
304 }
305
306 fn set_raw<T: ReadWriteSeek>(fat: &mut T, cluster: u32, raw_value: u32) -> io::Result<()> {
307 fat.seek(io::SeekFrom::Start((cluster * 2) as u64))?;
308 fat.write_u16::<LittleEndian>(raw_value as u16)?;
309 Ok(())
310 }
311
312 fn set<T: ReadWriteSeek>(fat: &mut T, cluster: u32, value: FatValue) -> io::Result<()> {
313 let raw_value = match value {
314 FatValue::Free => 0,
315 FatValue::Bad => 0xFFF7,
316 FatValue::EndOfChain => 0xFFFF,
317 FatValue::Data(n) => n as u16,
318 };
319 Self::set_raw(fat, cluster, raw_value as u32)
320 }
321
322 fn find_free<T: ReadSeek>(
323 fat: &mut T,
324 start_cluster: u32,
325 end_cluster: u32,
326 ) -> io::Result<u32> {
327 let mut cluster = start_cluster;
328 fat.seek(io::SeekFrom::Start((cluster * 2) as u64))?;
329 while cluster < end_cluster {
330 let val = fat.read_u16::<LittleEndian>()?;
331 if val == 0 {
332 return Ok(cluster);
333 }
334 cluster += 1;
335 }
336 Err(io::Error::new(io::ErrorKind::Other, FatfsError::NoSpace))
337 }
338
339 fn count_free<T: ReadSeek>(fat: &mut T, end_cluster: u32) -> io::Result<u32> {
340 let mut count = 0;
341 let mut cluster = RESERVED_FAT_ENTRIES;
342 fat.seek(io::SeekFrom::Start((cluster * 2) as u64))?;
343 while cluster < end_cluster {
344 let val = fat.read_u16::<LittleEndian>()?;
345 if val == 0 {
346 count += 1;
347 }
348 cluster += 1;
349 }
350 Ok(count)
351 }
352}
353
354impl FatTrait for Fat32 {
355 fn get_raw<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<u32> {
356 fat.seek(io::SeekFrom::Start((cluster * 4) as u64))?;
357 Ok(fat.read_u32::<LittleEndian>()?)
358 }
359
360 fn get<T: ReadSeek>(fat: &mut T, cluster: u32) -> io::Result<FatValue> {
361 let val = Self::get_raw(fat, cluster)? & 0x0FFFFFFF;
362 Ok(match val {
363 0 if cluster >= 0x0FFFFFF7 && cluster <= 0x0FFFFFFF => {
364 let tmp = if cluster == 0x0FFFFFF7 { "BAD_CLUSTER" } else { "end-of-chain" };
365 warn!(
366 "cluster number {} is a special value in FAT to indicate {}; it should never be seen as free",
367 cluster, tmp
368 );
369 FatValue::Bad }
371 0 => FatValue::Free,
372 0x0FFFFFF7 => FatValue::Bad,
373 0x0FFFFFF8..=0x0FFFFFFF => FatValue::EndOfChain,
374 n if cluster >= 0x0FFFFFF7 && cluster <= 0x0FFFFFFF => {
375 let tmp = if cluster == 0x0FFFFFF7 { "BAD_CLUSTER" } else { "end-of-chain" };
376 warn!("cluster number {} is a special value in FAT to indicate {}; hiding potential FAT chain value {} and instead reporting as a bad sector", cluster, tmp, n);
377 FatValue::Bad }
379 n => FatValue::Data(n as u32),
380 })
381 }
382
383 fn set_raw<T: ReadWriteSeek>(fat: &mut T, cluster: u32, raw_value: u32) -> io::Result<()> {
384 fat.seek(io::SeekFrom::Start((cluster * 4) as u64))?;
385 fat.write_u32::<LittleEndian>(raw_value)?;
386 Ok(())
387 }
388
389 fn set<T: ReadWriteSeek>(fat: &mut T, cluster: u32, value: FatValue) -> io::Result<()> {
390 let old_reserved_bits = Self::get_raw(fat, cluster)? & 0xF0000000;
391
392 if value == FatValue::Free && cluster >= 0x0FFFFFF7 && cluster <= 0x0FFFFFFF {
393 let tmp = if cluster == 0x0FFFFFF7 { "BAD_CLUSTER" } else { "end-of-chain" };
397 panic!(
398 "cluster number {} is a special value in FAT to indicate {}; it should never be set as free",
399 cluster, tmp
400 );
401 };
402 let raw_val = match value {
403 FatValue::Free => 0,
404 FatValue::Bad => 0x0FFFFFF7,
405 FatValue::EndOfChain => 0x0FFFFFFF,
406 FatValue::Data(n) => n,
407 };
408 let raw_val = raw_val | old_reserved_bits; Self::set_raw(fat, cluster, raw_val)
410 }
411
412 fn find_free<T: ReadSeek>(
413 fat: &mut T,
414 start_cluster: u32,
415 end_cluster: u32,
416 ) -> io::Result<u32> {
417 let mut cluster = start_cluster;
418 fat.seek(io::SeekFrom::Start((cluster * 4) as u64))?;
419 while cluster < end_cluster {
420 let val = fat.read_u32::<LittleEndian>()? & 0x0FFFFFFF;
421 if val == 0 {
422 return Ok(cluster);
423 }
424 cluster += 1;
425 }
426 Err(io::Error::new(io::ErrorKind::Other, FatfsError::NoSpace))
427 }
428
429 fn count_free<T: ReadSeek>(fat: &mut T, end_cluster: u32) -> io::Result<u32> {
430 let mut count = 0;
431 let mut cluster = RESERVED_FAT_ENTRIES;
432 fat.seek(io::SeekFrom::Start((cluster * 4) as u64))?;
433 while cluster < end_cluster {
434 let val = fat.read_u32::<LittleEndian>()? & 0x0FFFFFFF;
435 if val == 0 {
436 count += 1;
437 }
438 cluster += 1;
439 }
440 Ok(count)
441 }
442}
443
444pub(crate) struct ClusterIterator<T: ReadWriteSeek> {
445 fat: T,
446 fat_type: FatType,
447 cluster: Option<u32>,
448 err: bool,
449}
450
451impl<T: ReadWriteSeek> ClusterIterator<T> {
452 pub(crate) fn new(fat: T, fat_type: FatType, cluster: u32) -> Self {
453 ClusterIterator { fat, fat_type, cluster: Some(cluster), err: false }
454 }
455
456 pub(crate) fn truncate(&mut self) -> io::Result<u32> {
457 match self.cluster {
458 Some(n) => {
459 self.next();
461 write_fat(&mut self.fat, self.fat_type, n, FatValue::EndOfChain)?;
463 self.free()
465 }
466 None => Ok(0),
467 }
468 }
469
470 pub(crate) fn free(&mut self) -> io::Result<u32> {
471 let mut num_free = 0;
472 while let Some(n) = self.cluster {
473 self.next();
474 write_fat(&mut self.fat, self.fat_type, n, FatValue::Free)?;
475 num_free += 1;
476 }
477 Ok(num_free)
478 }
479}
480
481impl<T: ReadWriteSeek> Iterator for ClusterIterator<T> {
482 type Item = io::Result<u32>;
483
484 fn next(&mut self) -> Option<Self::Item> {
485 if self.err {
486 return None;
487 }
488 if let Some(current_cluster) = self.cluster {
489 self.cluster = match get_next_cluster(&mut self.fat, self.fat_type, current_cluster) {
490 Ok(next_cluster) => next_cluster,
491 Err(err) => {
492 self.err = true;
493 return Some(Err(err));
494 }
495 }
496 }
497 self.cluster.map(Ok)
498 }
499}
500
501#[cfg(test)]
502mod tests {
503 use super::*;
504
505 fn test_fat<T: ReadWriteSeek>(fat_type: FatType, mut cur: T) {
506 assert_eq!(read_fat(&mut cur, fat_type, 1).unwrap(), FatValue::EndOfChain);
509 assert_eq!(read_fat(&mut cur, fat_type, 4).unwrap(), FatValue::Data(5));
510 assert_eq!(read_fat(&mut cur, fat_type, 5).unwrap(), FatValue::Data(6));
511 assert_eq!(read_fat(&mut cur, fat_type, 8).unwrap(), FatValue::EndOfChain);
512 assert_eq!(read_fat(&mut cur, fat_type, 9).unwrap(), FatValue::Data(0xA));
513 assert_eq!(read_fat(&mut cur, fat_type, 0xA).unwrap(), FatValue::Data(0x14));
514 assert_eq!(read_fat(&mut cur, fat_type, 0x12).unwrap(), FatValue::Free);
515 assert_eq!(read_fat(&mut cur, fat_type, 0x17).unwrap(), FatValue::Bad);
516 assert_eq!(read_fat(&mut cur, fat_type, 0x18).unwrap(), FatValue::Bad);
517 assert_eq!(read_fat(&mut cur, fat_type, 0x1B).unwrap(), FatValue::Free);
518
519 assert_eq!(find_free_cluster(&mut cur, fat_type, 2, 0x20).unwrap(), 0x12);
520 assert_eq!(find_free_cluster(&mut cur, fat_type, 0x12, 0x20).unwrap(), 0x12);
521 assert_eq!(find_free_cluster(&mut cur, fat_type, 0x13, 0x20).unwrap(), 0x1B);
522 assert!(find_free_cluster(&mut cur, fat_type, 0x13, 0x14).is_err());
523
524 assert_eq!(count_free_clusters(&mut cur, fat_type, 0x1E).unwrap(), 5);
525
526 assert_eq!(alloc_cluster(&mut cur, fat_type, None, Some(0x13), 0x1E).unwrap(), 0x1B);
528 assert_eq!(read_fat(&mut cur, fat_type, 0x1B).unwrap(), FatValue::EndOfChain);
529 assert_eq!(alloc_cluster(&mut cur, fat_type, Some(0x1B), None, 0x1E).unwrap(), 0x12);
530 assert_eq!(read_fat(&mut cur, fat_type, 0x1B).unwrap(), FatValue::Data(0x12));
531 assert_eq!(read_fat(&mut cur, fat_type, 0x12).unwrap(), FatValue::EndOfChain);
532 assert_eq!(count_free_clusters(&mut cur, fat_type, 0x1E).unwrap(), 3);
533 {
535 let iter = ClusterIterator::new(&mut cur, fat_type, 0x9);
536 assert_eq!(
537 iter.map(|r| r.unwrap()).collect::<Vec<_>>(),
538 vec![0xA, 0x14, 0x15, 0x16, 0x19, 0x1A]
539 );
540 }
541 {
543 let mut iter = ClusterIterator::new(&mut cur, fat_type, 0x9);
544 assert_eq!(iter.nth(3).unwrap().unwrap(), 0x16);
545 iter.truncate().unwrap();
546 }
547 assert_eq!(read_fat(&mut cur, fat_type, 0x16).unwrap(), FatValue::EndOfChain);
548 assert_eq!(read_fat(&mut cur, fat_type, 0x19).unwrap(), FatValue::Free);
549 assert_eq!(read_fat(&mut cur, fat_type, 0x1A).unwrap(), FatValue::Free);
550 {
552 let mut iter = ClusterIterator::new(&mut cur, fat_type, 0x9);
553 iter.free().unwrap();
554 }
555 assert_eq!(read_fat(&mut cur, fat_type, 0x9).unwrap(), FatValue::Free);
556 assert_eq!(read_fat(&mut cur, fat_type, 0xA).unwrap(), FatValue::Free);
557 assert_eq!(read_fat(&mut cur, fat_type, 0x14).unwrap(), FatValue::Free);
558 assert_eq!(read_fat(&mut cur, fat_type, 0x15).unwrap(), FatValue::Free);
559 assert_eq!(read_fat(&mut cur, fat_type, 0x16).unwrap(), FatValue::Free);
560 }
561
562 #[test]
563 fn test_fat12() {
564 let fat: Vec<u8> = vec![
565 0xF0, 0xFF, 0xFF, 0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0xFF, 0xAF,
566 0x00, 0x14, 0xC0, 0x00, 0x0D, 0xE0, 0x00, 0x0F, 0x00, 0x01, 0x11, 0xF0, 0xFF, 0x00,
567 0xF0, 0xFF, 0x15, 0x60, 0x01, 0x19, 0x70, 0xFF, 0xF7, 0xAF, 0x01, 0xFF, 0x0F, 0x00,
568 0x00, 0x70, 0xFF, 0x00, 0x00, 0x00,
569 ];
570 test_fat(FatType::Fat12, io::Cursor::new(fat));
571 }
572
573 #[test]
574 fn test_fat16() {
575 let fat: Vec<u8> = vec![
576 0xF0, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00,
577 0x08, 0x00, 0xFF, 0xFF, 0x0A, 0x00, 0x14, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00,
578 0x0F, 0x00, 0x10, 0x00, 0x11, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x15, 0x00,
579 0x16, 0x00, 0x19, 0x00, 0xF7, 0xFF, 0xF7, 0xFF, 0x1A, 0x00, 0xFF, 0xFF, 0x00, 0x00,
580 0x00, 0x00, 0xF7, 0xFF, 0x00, 0x00, 0x00, 0x00,
581 ];
582 test_fat(FatType::Fat16, io::Cursor::new(fat));
583 }
584
585 #[test]
586 fn test_fat32() {
587 let fat: Vec<u8> = vec![
588 0xF0, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x0F, 0x04, 0x00,
589 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
590 0x08, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00,
591 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
592 0x0F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xFF, 0xFF,
593 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x15, 0x00, 0x00, 0x00,
594 0x16, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0x0F, 0xF7, 0xFF,
595 0xFF, 0x0F, 0x1A, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0xF7, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00,
598 ];
599 test_fat(FatType::Fat32, io::Cursor::new(fat));
600 }
601}