exfat_fs/
error.rs

1use crate::{
2    boot_sector::UnixEpochDuration,
3    disk::{ReadOffset, WriteSeek},
4};
5use alloc::sync::Arc;
6
7#[derive(Debug, thiserror::Error)]
8pub enum ExfatFormatError<T: UnixEpochDuration> {
9    #[error("Invalid bytes per sector. Must be a power of `2` and between `512` and `4096`: {0}.")]
10    InvalidBytesPerSector(u16),
11    #[error("Invalid volume size: {0}.")]
12    InvalidSize(u64),
13    #[error("Invalid partition offset: {0}.")]
14    InvalidPartitionOffset(u64),
15    #[error("Invalid number of FATs (must be 1 or 2): {0}.")]
16    InvalidNumberOfFats(u8),
17    #[error("Invalid cluster size: {0}. Must be a power of `2` and at most 32MB: {0}")]
18    InvlaidClusterSize(u32),
19    #[error("Boundary alignment is too big: {0}")]
20    BoundaryAlignemntTooBig(u32),
21    #[error("Unable to generate unique serial number. Error: {0}")]
22    NoSerial(#[source] T::Err),
23    #[error("Unable to pack bitmap.")]
24    CannotPackBitmap,
25    #[error("File size does not match exFAT size.")]
26    InvalidFileSize,
27}
28
29#[derive(Debug, thiserror::Error)]
30pub enum ExfatError<T: UnixEpochDuration, O: WriteSeek>
31where
32    T::Err: core::fmt::Debug,
33{
34    #[error("{0}")]
35    Format(#[from] ExfatFormatError<T>),
36    #[error("I/O error: {0}.")]
37    Io(#[source] O::Err),
38}
39
40#[derive(Debug, thiserror::Error)]
41pub enum RootError<O: ReadOffset> {
42    #[error("I/O error: {0}.")]
43    Io(O::Err),
44    #[error("The provided volume is not an exFAT filesystem.")]
45    WrongFs,
46    #[error("Invalid bytes per sector shift detected: {0}. Must be between `9` and `12`")]
47    InvalidBytesPerSectorShift(u8),
48    #[error("Invalid sectors per cluster shift detected: {0}.")]
49    InvalidSectorsPerClusterShift(u8),
50    #[error("Invalid number of FATs detected: {0}. Must be either `1` or `2`.")]
51    InvalidNumberOfFats(u8),
52    #[error("Fat could not be parsed: {0}.")]
53    Fat(#[from] FatLoadError<Arc<O>>),
54    #[error(
55        "Invalid index of root directory cluster detected: {0}. Must be bigger than `2` and at most `cluster_count + 1`"
56    )]
57    InvalidRootDirectoryClusterIndex(u32),
58    #[error("Cluster chain could not be parsed: {0}.")]
59    ClusterChain(#[from] ClusterChainError),
60    #[error("Entry Reader Error: {0}.")]
61    DirEntry(#[from] EntryReaderError<Arc<O>>),
62    #[error(
63        "All directory entries of the root directory must be of type `PRIMARY`. Detected entry type: {0}"
64    )]
65    RootEntryNotPrimary(u8),
66    #[error("More than 2 allocation bitmap root entry fields detected.")]
67    InvalidNumberOfAllocationBitmaps,
68    #[error("Corrupt allocation bitmap entry.")]
69    InvalidAllocationBitmap,
70    #[error("More than 1 upcase table root entry field detected.")]
71    InvalidNumberOfUpcaseTables,
72    #[error("Corrupt upcase table entry.")]
73    InvalidUpcaseTable,
74    #[error("More than 1 volume label root entry field detected.")]
75    InvalidNumberOfVolumeLabels,
76    #[error("Corrupt volume label entry.")]
77    InvalidVolumeLabel,
78    #[error("Unable to parse file entry: {0}")]
79    InvalidFileEntry(#[from] FileParserError<Arc<O>>),
80    #[error("Unexpected directory entry in root directory. Detected entry type: {0}")]
81    UnexpectedRootEntry(u8),
82}
83
84#[derive(Debug, thiserror::Error)]
85pub enum FatLoadError<O: ReadOffset> {
86    #[error("FAT starts at invalid offset.")]
87    InvalidOffset,
88    #[error("Read failed at: {0:#x}.")]
89    ReadFailed(u64, #[source] O::Err),
90}
91
92#[derive(Debug, thiserror::Error)]
93pub enum ClusterChainError {
94    #[error("Invalid starting cluster.")]
95    InvalidFirstCluster,
96    #[error("Invalid data length for cluster chain.")]
97    InvalidDataLength,
98}
99
100#[derive(Debug, thiserror::Error)]
101pub enum EntryReaderError<O: ReadOffset> {
102    #[error("Cannot read entry #{0} on cluster #{1}.")]
103    ReadFailed(usize, u32, #[source] O::Err),
104    #[error("{0}")]
105    Entry(#[from] DirEntryError),
106}
107
108#[derive(Debug, thiserror::Error)]
109pub enum DirEntryError {
110    #[error("Invalid directory entry detected: {0}.")]
111    InvalidEntry(u8),
112}
113
114#[derive(Debug, thiserror::Error)]
115pub enum FileParserError<O: ReadOffset>
116where
117    O::Err: core::fmt::Debug,
118{
119    #[error("File entry is missing stream extension.")]
120    NoStreamExtension,
121    #[error("File entry is missing file name.")]
122    NoFileName,
123    #[error("{0}")]
124    ReadFailed(#[from] EntryReaderError<O>),
125    #[error("Invalid stream extension entry detected.")]
126    InvalidStreamExtension,
127    #[error("Wrong number of file name entries detected.")]
128    WrongFileNameEntries,
129    #[error("Invalid file name entry detected.")]
130    InvalidFileName,
131}
132
133#[derive(Debug, thiserror::Error)]
134pub enum DirectoryError<O: ReadOffset>
135where
136    O::Err: core::fmt::Debug,
137{
138    #[error("Cannot create a clusters reader for allocation: {0}")]
139    CreateClustersReaderFailed(#[from] ClusterChainError),
140    #[error("Cannot read an entry: {0}")]
141    ReadEntryFailed(#[from] EntryReaderError<Arc<O>>),
142    #[error("Detected directory entry that is not `PRIMARY`. Detected entry type: {0}")]
143    NotPrimaryEntry(u8),
144    #[error("Detected directory entry that is not a file entry. Detected entry type: {0}")]
145    NotFileEntry(u8),
146    #[error("Unable to parse file entry: {0}")]
147    InvalidFileEntry(#[from] FileParserError<Arc<O>>),
148}