xref: /DragonOS/kernel/src/filesystem/fat/entry.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
1004e86ffSlogin #![allow(dead_code)]
26d81180bSLoGin use core::{cmp::min, intrinsics::unlikely};
3*2eab6dd7S曾俊 use log::{debug, warn};
491e9d4abSLoGin use system_error::SystemError;
5004e86ffSlogin 
6004e86ffSlogin use crate::{
7b087521eSChiichen     driver::base::block::{block_device::LBA_SIZE, SeekFrom},
8004e86ffSlogin     libs::vec_cursor::VecCursor,
9004e86ffSlogin };
106d81180bSLoGin use alloc::{
116d81180bSLoGin     string::{String, ToString},
126d81180bSLoGin     sync::Arc,
136d81180bSLoGin     vec::Vec,
146d81180bSLoGin };
15004e86ffSlogin 
16004e86ffSlogin use super::{
17004e86ffSlogin     fs::{Cluster, FATFileSystem, MAX_FILE_SIZE},
18004e86ffSlogin     utils::decode_u8_ascii,
19004e86ffSlogin };
20004e86ffSlogin 
21004e86ffSlogin #[derive(Debug, Clone, Copy, Default)]
22004e86ffSlogin pub struct FileAttributes {
23004e86ffSlogin     value: u8,
24004e86ffSlogin }
25004e86ffSlogin 
26004e86ffSlogin /// FAT表中,关于每个簇的信息
27004e86ffSlogin #[derive(Debug, Eq, PartialEq)]
28004e86ffSlogin pub enum FATEntry {
29004e86ffSlogin     /// 当前簇未使用
30004e86ffSlogin     Unused,
31004e86ffSlogin     /// 当前簇是坏簇
32004e86ffSlogin     Bad,
33004e86ffSlogin     /// 当前簇是整个FAT簇链的最后一个簇
34004e86ffSlogin     EndOfChain,
35004e86ffSlogin     /// 在整个链中,当前簇的下一个簇的值
36004e86ffSlogin     Next(Cluster),
37004e86ffSlogin }
38004e86ffSlogin 
39004e86ffSlogin /// FAT目录项的枚举类型
40004e86ffSlogin #[derive(Debug, Clone)]
41004e86ffSlogin pub enum FATDirEntry {
42004e86ffSlogin     File(FATFile),
43004e86ffSlogin     VolId(FATFile),
44004e86ffSlogin     Dir(FATDir),
45004e86ffSlogin     UnInit,
46004e86ffSlogin }
47004e86ffSlogin 
48004e86ffSlogin /// FAT文件系统中的文件
49004e86ffSlogin #[derive(Debug, Default, Clone)]
50004e86ffSlogin pub struct FATFile {
51004e86ffSlogin     /// 文件的第一个簇
52004e86ffSlogin     pub first_cluster: Cluster,
53004e86ffSlogin     /// 文件名
54004e86ffSlogin     pub file_name: String,
55004e86ffSlogin     /// 文件对应的短目录项
56004e86ffSlogin     pub short_dir_entry: ShortDirEntry,
57004e86ffSlogin     /// 文件目录项的起始、终止簇。格式:(簇,簇内偏移量)
58004e86ffSlogin     pub loc: ((Cluster, u64), (Cluster, u64)),
59004e86ffSlogin }
60004e86ffSlogin 
61004e86ffSlogin impl FATFile {
62004e86ffSlogin     /// @brief 获取文件大小
63004e86ffSlogin     #[inline]
64004e86ffSlogin     pub fn size(&self) -> u64 {
65004e86ffSlogin         return self.short_dir_entry.file_size as u64;
66004e86ffSlogin     }
67004e86ffSlogin 
68004e86ffSlogin     /// @brief 设置当前文件大小(仅仅更改short_dir_entry内的值)
69004e86ffSlogin     #[inline]
70004e86ffSlogin     pub fn set_size(&mut self, size: u32) {
71004e86ffSlogin         self.short_dir_entry.file_size = size;
72004e86ffSlogin     }
73004e86ffSlogin 
74004e86ffSlogin     /// @brief 从文件读取数据。读取的字节数与buf长度相等
75004e86ffSlogin     ///
76004e86ffSlogin     /// @param buf 输出缓冲区
77004e86ffSlogin     /// @param offset 起始位置在文件中的偏移量
78004e86ffSlogin     ///
79004e86ffSlogin     /// @return Ok(usize) 成功读取到的字节数
80676b8ef6SMork     /// @return Err(SystemError) 读取时出现错误,返回错误码
8178bf93f0SYJwu2023     pub fn read(
8278bf93f0SYJwu2023         &self,
8378bf93f0SYJwu2023         fs: &Arc<FATFileSystem>,
8478bf93f0SYJwu2023         buf: &mut [u8],
8578bf93f0SYJwu2023         offset: u64,
8678bf93f0SYJwu2023     ) -> Result<usize, SystemError> {
87004e86ffSlogin         if offset >= self.size() {
88004e86ffSlogin             return Ok(0);
89004e86ffSlogin         }
90004e86ffSlogin 
91004e86ffSlogin         // 文件内的簇偏移量
92004e86ffSlogin         let start_cluster_number: u64 = offset / fs.bytes_per_cluster();
93004e86ffSlogin         // 计算对应在分区内的簇号
94004e86ffSlogin         let mut current_cluster = if let Some(c) =
95004e86ffSlogin             fs.get_cluster_by_relative(self.first_cluster, start_cluster_number as usize)
96004e86ffSlogin         {
97004e86ffSlogin             c
98004e86ffSlogin         } else {
99004e86ffSlogin             return Ok(0);
100004e86ffSlogin         };
101004e86ffSlogin 
102004e86ffSlogin         let bytes_remain: u64 = self.size() - offset;
103004e86ffSlogin 
104004e86ffSlogin         // 计算簇内偏移量
105004e86ffSlogin         let mut in_cluster_offset: u64 = offset % fs.bytes_per_cluster();
106004e86ffSlogin         let to_read_size: usize = min(buf.len(), bytes_remain as usize);
107004e86ffSlogin 
108004e86ffSlogin         let mut start = 0;
109004e86ffSlogin         let mut read_ok = 0;
110004e86ffSlogin 
111004e86ffSlogin         loop {
112004e86ffSlogin             // 当前簇已经读取完,尝试读取下一个簇
113004e86ffSlogin             if in_cluster_offset >= fs.bytes_per_cluster() {
114b5b571e0SLoGin                 if let Ok(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster) {
115004e86ffSlogin                     current_cluster = c;
116004e86ffSlogin                     in_cluster_offset %= fs.bytes_per_cluster();
117004e86ffSlogin                 } else {
118004e86ffSlogin                     break;
119004e86ffSlogin                 }
120004e86ffSlogin             }
121004e86ffSlogin 
122004e86ffSlogin             // 计算下一次读取,能够读多少字节
123004e86ffSlogin             let end_len: usize = min(
124004e86ffSlogin                 to_read_size - read_ok,
125004e86ffSlogin                 min(
126004e86ffSlogin                     (fs.bytes_per_cluster() - in_cluster_offset) as usize,
127004e86ffSlogin                     buf.len() - read_ok,
128004e86ffSlogin                 ),
129004e86ffSlogin             );
130004e86ffSlogin 
131004e86ffSlogin             //  从磁盘上读取数据
132004e86ffSlogin             let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_offset;
133b087521eSChiichen             let r = fs.partition.disk().read_at_bytes(
134004e86ffSlogin                 offset as usize,
135004e86ffSlogin                 end_len,
136004e86ffSlogin                 &mut buf[start..start + end_len],
137004e86ffSlogin             )?;
138004e86ffSlogin 
139004e86ffSlogin             // 更新偏移量计数信息
140004e86ffSlogin             read_ok += r;
141004e86ffSlogin             start += r;
142004e86ffSlogin             in_cluster_offset += r as u64;
143004e86ffSlogin             if read_ok == to_read_size {
144004e86ffSlogin                 break;
145004e86ffSlogin             }
146004e86ffSlogin         }
147004e86ffSlogin         // todo: 更新时间信息
148004e86ffSlogin         return Ok(read_ok);
149004e86ffSlogin     }
150004e86ffSlogin 
151004e86ffSlogin     /// @brief 向文件写入数据。写入的字节数与buf长度相等
152004e86ffSlogin     ///
153004e86ffSlogin     /// @param buf 输入缓冲区
154004e86ffSlogin     /// @param offset 起始位置在文件中的偏移量
155004e86ffSlogin     ///
156004e86ffSlogin     /// @return Ok(usize) 成功写入的字节数
157676b8ef6SMork     /// @return Err(SystemError) 写入时出现错误,返回错误码
158004e86ffSlogin     pub fn write(
159004e86ffSlogin         &mut self,
160004e86ffSlogin         fs: &Arc<FATFileSystem>,
161004e86ffSlogin         buf: &[u8],
162004e86ffSlogin         offset: u64,
163676b8ef6SMork     ) -> Result<usize, SystemError> {
164004e86ffSlogin         self.ensure_len(fs, offset, buf.len() as u64)?;
165004e86ffSlogin 
166004e86ffSlogin         // 要写入的第一个簇的簇号
167004e86ffSlogin         let start_cluster_num = offset / fs.bytes_per_cluster();
168004e86ffSlogin         // 获取要写入的第一个簇
169004e86ffSlogin         let mut current_cluster: Cluster = if let Some(c) =
170004e86ffSlogin             fs.get_cluster_by_relative(self.first_cluster, start_cluster_num as usize)
171004e86ffSlogin         {
172004e86ffSlogin             c
173004e86ffSlogin         } else {
174004e86ffSlogin             return Ok(0);
175004e86ffSlogin         };
176004e86ffSlogin 
177004e86ffSlogin         let mut in_cluster_bytes_offset: u64 = offset % fs.bytes_per_cluster();
178004e86ffSlogin 
179004e86ffSlogin         let mut start: usize = 0;
180004e86ffSlogin         let mut write_ok: usize = 0;
181004e86ffSlogin 
182004e86ffSlogin         // 循环写入数据
183004e86ffSlogin         loop {
184004e86ffSlogin             if in_cluster_bytes_offset >= fs.bytes_per_cluster() {
185b5b571e0SLoGin                 if let Ok(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster) {
186004e86ffSlogin                     current_cluster = c;
187b5b571e0SLoGin                     in_cluster_bytes_offset %= fs.bytes_per_cluster();
188004e86ffSlogin                 } else {
189004e86ffSlogin                     break;
190004e86ffSlogin                 }
191004e86ffSlogin             }
192004e86ffSlogin 
193004e86ffSlogin             let end_len = min(
194004e86ffSlogin                 (fs.bytes_per_cluster() - in_cluster_bytes_offset) as usize,
195004e86ffSlogin                 buf.len() - write_ok,
196004e86ffSlogin             );
197004e86ffSlogin 
198004e86ffSlogin             // 计算本次写入位置在磁盘上的偏移量
199004e86ffSlogin             let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_bytes_offset;
200004e86ffSlogin             // 写入磁盘
2010facf623SLoGin             let w: usize = fs.partition.disk().write_at_bytes(
202004e86ffSlogin                 offset as usize,
203004e86ffSlogin                 end_len,
204004e86ffSlogin                 &buf[start..start + end_len],
205004e86ffSlogin             )?;
206004e86ffSlogin 
207004e86ffSlogin             // 更新偏移量数据
208004e86ffSlogin             write_ok += w;
209004e86ffSlogin             start += w;
210004e86ffSlogin             in_cluster_bytes_offset += w as u64;
211004e86ffSlogin 
212004e86ffSlogin             if write_ok == buf.len() {
213004e86ffSlogin                 break;
214004e86ffSlogin             }
215004e86ffSlogin         }
216004e86ffSlogin         // todo: 更新时间信息
217004e86ffSlogin         return Ok(write_ok);
218004e86ffSlogin     }
219004e86ffSlogin 
220004e86ffSlogin     /// @brief 确保文件从指定偏移量开始,仍有长度为len的空间。
221004e86ffSlogin     /// 如果文件大小不够,就尝试分配更多的空间给这个文件。
222004e86ffSlogin     ///
223004e86ffSlogin     /// @param fs 当前文件所属的文件系统
224004e86ffSlogin     /// @param offset 起始位置在文件内的字节偏移量
225004e86ffSlogin     /// @param len 期待的空闲空间长度
226004e86ffSlogin     ///
227004e86ffSlogin     /// @return Ok(()) 经过操作后,offset后面具有长度至少为len的空闲空间
228676b8ef6SMork     /// @return Err(SystemError) 处理过程中出现了异常。
22978bf93f0SYJwu2023     fn ensure_len(
23078bf93f0SYJwu2023         &mut self,
23178bf93f0SYJwu2023         fs: &Arc<FATFileSystem>,
23278bf93f0SYJwu2023         offset: u64,
23378bf93f0SYJwu2023         len: u64,
23478bf93f0SYJwu2023     ) -> Result<(), SystemError> {
235004e86ffSlogin         // 文件内本身就还有空余的空间
236004e86ffSlogin         if offset + len <= self.size() {
237004e86ffSlogin             return Ok(());
238004e86ffSlogin         }
239004e86ffSlogin 
2406d81180bSLoGin         // 计算文件的最后一个簇中有多少空闲空间
2416d81180bSLoGin         let in_cluster_offset = self.size() % fs.bytes_per_cluster();
2426d81180bSLoGin         let mut bytes_remain_in_cluster = if in_cluster_offset == 0 {
2436d81180bSLoGin             0
2446d81180bSLoGin         } else {
2456d81180bSLoGin             fs.bytes_per_cluster() - in_cluster_offset
2466d81180bSLoGin         };
2476d81180bSLoGin 
2486d81180bSLoGin         // 计算还需要申请多少空间
2496d81180bSLoGin         let extra_bytes = min((offset + len) - self.size(), MAX_FILE_SIZE - self.size());
2506d81180bSLoGin 
251004e86ffSlogin         // 如果文件大小为0,证明它还没有分配簇,因此分配一个簇给它
252004e86ffSlogin         if self.size() == 0 {
253004e86ffSlogin             // first_cluster应当为0,否则将产生空间泄露的错误
254004e86ffSlogin             assert_eq!(self.first_cluster, Cluster::default());
255004e86ffSlogin             self.first_cluster = fs.allocate_cluster(None)?;
256004e86ffSlogin             self.short_dir_entry.set_first_cluster(self.first_cluster);
2576d81180bSLoGin             bytes_remain_in_cluster = fs.bytes_per_cluster();
258004e86ffSlogin         }
259004e86ffSlogin 
260004e86ffSlogin         // 如果还需要更多的簇
261004e86ffSlogin         if bytes_remain_in_cluster < extra_bytes {
262004e86ffSlogin             let clusters_to_allocate =
263004e86ffSlogin                 (extra_bytes - bytes_remain_in_cluster + fs.bytes_per_cluster() - 1)
264004e86ffSlogin                     / fs.bytes_per_cluster();
265004e86ffSlogin             let last_cluster = if let Some(c) = fs.get_last_cluster(self.first_cluster) {
266004e86ffSlogin                 c
267004e86ffSlogin             } else {
268*2eab6dd7S曾俊                 warn!("FAT: last cluster not found, File = {self:?}");
269676b8ef6SMork                 return Err(SystemError::EINVAL);
270004e86ffSlogin             };
271004e86ffSlogin             // 申请簇
272004e86ffSlogin             let mut current_cluster: Cluster = last_cluster;
273004e86ffSlogin             for _ in 0..clusters_to_allocate {
274004e86ffSlogin                 current_cluster = fs.allocate_cluster(Some(current_cluster))?;
275004e86ffSlogin             }
276004e86ffSlogin         }
277004e86ffSlogin 
278004e86ffSlogin         // 如果文件被扩展,则清空刚刚被扩展的部分的数据
279004e86ffSlogin         if offset > self.size() {
280004e86ffSlogin             // 文件内的簇偏移
281004e86ffSlogin             let start_cluster: u64 = self.size() / fs.bytes_per_cluster();
282004e86ffSlogin             let start_cluster: Cluster = fs
283004e86ffSlogin                 .get_cluster_by_relative(self.first_cluster, start_cluster as usize)
284004e86ffSlogin                 .unwrap();
285004e86ffSlogin             // 计算当前文件末尾在磁盘上的字节偏移量
286004e86ffSlogin             let start_offset: u64 =
287004e86ffSlogin                 fs.cluster_bytes_offset(start_cluster) + self.size() % fs.bytes_per_cluster();
288004e86ffSlogin             // 扩展之前,最后一个簇内还剩下多少字节的空间
289004e86ffSlogin             let bytes_remain: u64 = fs.bytes_per_cluster() - (self.size() % fs.bytes_per_cluster());
290004e86ffSlogin             // 计算在扩展之后的最后一个簇内,文件的终止字节
291004e86ffSlogin             let cluster_offset_start = offset / fs.bytes_per_cluster();
292004e86ffSlogin             // 扩展后,文件的最后
293004e86ffSlogin             let end_cluster: Cluster = fs
294004e86ffSlogin                 .get_cluster_by_relative(self.first_cluster, cluster_offset_start as usize)
295004e86ffSlogin                 .unwrap();
296004e86ffSlogin 
297004e86ffSlogin             if start_cluster != end_cluster {
298004e86ffSlogin                 self.zero_range(fs, start_offset, start_offset + bytes_remain)?;
299004e86ffSlogin             } else {
300004e86ffSlogin                 self.zero_range(fs, start_offset, start_offset + offset - self.size())?;
301004e86ffSlogin             }
302004e86ffSlogin         }
303004e86ffSlogin         // 计算文件的新大小
304004e86ffSlogin         let new_size = self.size() + extra_bytes;
305004e86ffSlogin         self.set_size(new_size as u32);
306004e86ffSlogin         // 计算短目录项所在的位置,更新短目录项
307004e86ffSlogin         let short_entry_offset = fs.cluster_bytes_offset(self.loc.1 .0) + self.loc.1 .1;
308004e86ffSlogin         // todo: 更新时间信息
309004e86ffSlogin         // 把短目录项写入磁盘
310004e86ffSlogin         self.short_dir_entry.flush(fs, short_entry_offset)?;
311004e86ffSlogin         return Ok(());
312004e86ffSlogin     }
313004e86ffSlogin 
314004e86ffSlogin     /// @brief 把磁盘上[range_start, range_end)范围的数据清零
315004e86ffSlogin     ///
316004e86ffSlogin     /// @param range_start 磁盘上起始位置(单位:字节)
317004e86ffSlogin     /// @param range_end 磁盘上终止位置(单位:字节)
318004e86ffSlogin     fn zero_range(
319004e86ffSlogin         &self,
320004e86ffSlogin         fs: &Arc<FATFileSystem>,
321004e86ffSlogin         range_start: u64,
322004e86ffSlogin         range_end: u64,
323676b8ef6SMork     ) -> Result<(), SystemError> {
324004e86ffSlogin         if range_end <= range_start {
325004e86ffSlogin             return Ok(());
326004e86ffSlogin         }
327004e86ffSlogin 
328004e86ffSlogin         let zeroes: Vec<u8> = vec![0u8; (range_end - range_start) as usize];
329b087521eSChiichen         fs.partition
330b087521eSChiichen             .disk()
331b087521eSChiichen             .write_at(range_start as usize, zeroes.len(), zeroes.as_slice())?;
332004e86ffSlogin         return Ok(());
333004e86ffSlogin     }
334004e86ffSlogin 
335004e86ffSlogin     /// @brief 截断文件的内容,并设置新的文件大小。如果new_size大于当前文件大小,则不做操作。
336004e86ffSlogin     ///
337004e86ffSlogin     /// @param new_size 新的文件大小,如果它大于当前文件大小,则不做操作。
338004e86ffSlogin     ///
339004e86ffSlogin     /// @return Ok(()) 操作成功
340676b8ef6SMork     /// @return Err(SystemError) 在操作时出现错误
341676b8ef6SMork     pub fn truncate(&mut self, fs: &Arc<FATFileSystem>, new_size: u64) -> Result<(), SystemError> {
342004e86ffSlogin         if new_size >= self.size() {
343004e86ffSlogin             return Ok(());
344004e86ffSlogin         }
345004e86ffSlogin 
3466d81180bSLoGin         let new_last_cluster = (new_size + fs.bytes_per_cluster() - 1) / fs.bytes_per_cluster();
347004e86ffSlogin         if let Some(begin_delete) =
3486d81180bSLoGin             fs.get_cluster_by_relative(self.first_cluster, new_last_cluster as usize)
349004e86ffSlogin         {
3506d81180bSLoGin             fs.deallocate_cluster_chain(begin_delete)?;
351004e86ffSlogin         };
352004e86ffSlogin 
3536d81180bSLoGin         if new_size == 0 {
3546d81180bSLoGin             assert!(new_last_cluster == 0);
3556d81180bSLoGin             self.short_dir_entry.set_first_cluster(Cluster::new(0));
3566d81180bSLoGin             self.first_cluster = Cluster::new(0);
3576d81180bSLoGin         }
3586d81180bSLoGin 
359004e86ffSlogin         self.set_size(new_size as u32);
360004e86ffSlogin         // 计算短目录项在磁盘内的字节偏移量
361004e86ffSlogin         let short_entry_offset = fs.cluster_bytes_offset((self.loc.1).0) + (self.loc.1).1;
362004e86ffSlogin         self.short_dir_entry.flush(fs, short_entry_offset)?;
3636d81180bSLoGin 
364004e86ffSlogin         return Ok(());
365004e86ffSlogin     }
366004e86ffSlogin }
367004e86ffSlogin 
368004e86ffSlogin /// FAT文件系统中的文件夹
369004e86ffSlogin #[derive(Debug, Default, Clone)]
370004e86ffSlogin pub struct FATDir {
371004e86ffSlogin     /// 目录的第一个簇
372004e86ffSlogin     pub first_cluster: Cluster,
373004e86ffSlogin     /// 该字段仅对FAT12、FAT16生效
374004e86ffSlogin     pub root_offset: Option<u64>,
375004e86ffSlogin     /// 文件夹名称
376004e86ffSlogin     pub dir_name: String,
377004e86ffSlogin     pub short_dir_entry: Option<ShortDirEntry>,
378004e86ffSlogin     /// 文件的起始、终止簇。格式:(簇,簇内偏移量)
379004e86ffSlogin     pub loc: Option<((Cluster, u64), (Cluster, u64))>,
380004e86ffSlogin }
381004e86ffSlogin 
382004e86ffSlogin impl FATDir {
383004e86ffSlogin     /// @brief 获得用于遍历当前目录的迭代器
384004e86ffSlogin     ///
385004e86ffSlogin     /// @param fs 当前目录所在的文件系统
386004e86ffSlogin     pub fn to_iter(&self, fs: Arc<FATFileSystem>) -> FATDirIter {
387004e86ffSlogin         return FATDirIter {
388004e86ffSlogin             current_cluster: self.first_cluster,
389004e86ffSlogin             offset: self.root_offset.unwrap_or(0),
390004e86ffSlogin             is_root: self.is_root(),
391b5b571e0SLoGin             fs,
392004e86ffSlogin         };
393004e86ffSlogin     }
394004e86ffSlogin 
395004e86ffSlogin     /// @brief 判断当前目录是否为根目录(仅对FAT12和FAT16生效)
396004e86ffSlogin     #[inline]
397004e86ffSlogin     pub fn is_root(&self) -> bool {
398004e86ffSlogin         return self.root_offset.is_some();
399004e86ffSlogin     }
400004e86ffSlogin 
401004e86ffSlogin     /// @brief 获取当前目录所占用的大小
402004e86ffSlogin     pub fn size(&self, fs: &Arc<FATFileSystem>) -> u64 {
403004e86ffSlogin         return fs.num_clusters_chain(self.first_cluster) * fs.bytes_per_cluster();
404004e86ffSlogin     }
405004e86ffSlogin 
406004e86ffSlogin     /// @brief 在目录项中,寻找num_free个连续空闲目录项
407004e86ffSlogin     ///
408004e86ffSlogin     /// @param num_free 需要的空闲目录项数目.
409004e86ffSlogin     /// @param fs 当前文件夹属于的文件系统
410004e86ffSlogin     ///
411004e86ffSlogin     /// @return Ok(Option<(第一个符合条件的空闲目录项所在的簇,簇内偏移量))
412004e86ffSlogin     /// @return Err(错误码)
413004e86ffSlogin     pub fn find_free_entries(
414004e86ffSlogin         &self,
415004e86ffSlogin         num_free: u64,
416004e86ffSlogin         fs: Arc<FATFileSystem>,
417676b8ef6SMork     ) -> Result<Option<(Cluster, u64)>, SystemError> {
418004e86ffSlogin         let mut free = 0;
419004e86ffSlogin         let mut current_cluster: Cluster = self.first_cluster;
420004e86ffSlogin         let mut offset = self.root_offset.unwrap_or(0);
421004e86ffSlogin         // 第一个符合条件的空闲目录项
422004e86ffSlogin         let mut first_free: Option<(Cluster, u64)> = None;
423004e86ffSlogin 
424004e86ffSlogin         loop {
425004e86ffSlogin             // 如果当前簇没有空间了,并且当前不是FAT12和FAT16的根目录,那么就读取下一个簇。
426004e86ffSlogin             if offset >= fs.bytes_per_cluster() && !self.is_root() {
427004e86ffSlogin                 // 成功读取下一个簇
428b5b571e0SLoGin                 if let Ok(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster) {
429004e86ffSlogin                     current_cluster = c;
430004e86ffSlogin                     // 计算簇内偏移量
431b5b571e0SLoGin                     offset %= fs.bytes_per_cluster();
432004e86ffSlogin                 } else {
433004e86ffSlogin                     // 读取失败,当前已经是最后一个簇,退出循环
434004e86ffSlogin                     break;
435004e86ffSlogin                 }
436004e86ffSlogin             }
437004e86ffSlogin             // 如果当前目录是FAT12和FAT16的根目录,且已经读取完,就直接返回。
438004e86ffSlogin             if self.is_root() && offset > fs.root_dir_end_bytes_offset().unwrap() {
439004e86ffSlogin                 return Ok(None);
440004e86ffSlogin             }
441004e86ffSlogin 
442004e86ffSlogin             let e_offset = fs.cluster_bytes_offset(current_cluster) + offset;
443004e86ffSlogin             let entry: FATRawDirEntry = get_raw_dir_entry(&fs, e_offset)?;
444004e86ffSlogin 
445004e86ffSlogin             match entry {
446004e86ffSlogin                 FATRawDirEntry::Free | FATRawDirEntry::FreeRest => {
447004e86ffSlogin                     if free == 0 {
448004e86ffSlogin                         first_free = Some((current_cluster, offset));
449004e86ffSlogin                     }
450004e86ffSlogin 
451004e86ffSlogin                     free += 1;
452004e86ffSlogin                     if free == num_free {
453*2eab6dd7S曾俊                         // debug!("first_free = {first_free:?}, current_free = ({current_cluster:?}, {offset})");
454004e86ffSlogin                         return Ok(first_free);
455004e86ffSlogin                     }
456004e86ffSlogin                 }
457004e86ffSlogin 
458004e86ffSlogin                 // 遇到一个不空闲的目录项,那么重新开始计算空闲目录项
459004e86ffSlogin                 _ => {
460004e86ffSlogin                     free = 0;
461004e86ffSlogin                 }
462004e86ffSlogin             }
463004e86ffSlogin             offset += FATRawDirEntry::DIR_ENTRY_LEN;
464004e86ffSlogin         }
465004e86ffSlogin 
466004e86ffSlogin         // 剩余的需要获取的目录项
467004e86ffSlogin         let remain_entries = num_free - free;
468004e86ffSlogin 
469004e86ffSlogin         // 计算需要申请多少个簇
470004e86ffSlogin         let clusters_required =
471004e86ffSlogin             (remain_entries * FATRawDirEntry::DIR_ENTRY_LEN + fs.bytes_per_cluster() - 1)
472004e86ffSlogin                 / fs.bytes_per_cluster();
473004e86ffSlogin         let mut first_cluster = Cluster::default();
474004e86ffSlogin         let mut prev_cluster = current_cluster;
475*2eab6dd7S曾俊         // debug!(
476004e86ffSlogin         //     "clusters_required={clusters_required}, prev_cluster={prev_cluster:?}, free ={free}"
477004e86ffSlogin         // );
478004e86ffSlogin         // 申请簇
479004e86ffSlogin         for i in 0..clusters_required {
480004e86ffSlogin             let c: Cluster = fs.allocate_cluster(Some(prev_cluster))?;
481004e86ffSlogin             if i == 0 {
482004e86ffSlogin                 first_cluster = c;
483004e86ffSlogin             }
484004e86ffSlogin 
485004e86ffSlogin             prev_cluster = c;
486004e86ffSlogin         }
487004e86ffSlogin 
488004e86ffSlogin         if free > 0 {
489004e86ffSlogin             // 空闲目录项跨越了簇,返回第一个空闲目录项
490004e86ffSlogin             return Ok(first_free);
491004e86ffSlogin         } else {
492004e86ffSlogin             // 空闲目录项是在全新的簇开始的
493004e86ffSlogin             return Ok(Some((first_cluster, 0)));
494004e86ffSlogin         }
495004e86ffSlogin     }
496004e86ffSlogin 
497004e86ffSlogin     /// @brief 在当前目录中寻找目录项
498004e86ffSlogin     ///
499004e86ffSlogin     /// @param name 目录项的名字
500004e86ffSlogin     /// @param expect_dir 该值为Some时有效。如果期待目标目录项是文件夹,那么值为Some(true), 否则为Some(false).
501004e86ffSlogin     /// @param short_name_gen 短目录项名称生成器
502004e86ffSlogin     /// @param fs 当前目录所属的文件系统
503004e86ffSlogin     ///
504004e86ffSlogin     /// @return Ok(FATDirEntry) 找到期待的目录项
505676b8ef6SMork     /// @return Err(SystemError) 错误码
506004e86ffSlogin     pub fn find_entry(
507004e86ffSlogin         &self,
508004e86ffSlogin         name: &str,
509004e86ffSlogin         expect_dir: Option<bool>,
510004e86ffSlogin         mut short_name_gen: Option<&mut ShortNameGenerator>,
511004e86ffSlogin         fs: Arc<FATFileSystem>,
512676b8ef6SMork     ) -> Result<FATDirEntry, SystemError> {
513004e86ffSlogin         LongDirEntry::validate_long_name(name)?;
514004e86ffSlogin         // 迭代当前目录下的文件/文件夹
515004e86ffSlogin         for e in self.to_iter(fs) {
516004e86ffSlogin             if e.eq_name(name) {
517004e86ffSlogin                 if expect_dir.is_some() && Some(e.is_dir()) != expect_dir {
518004e86ffSlogin                     if e.is_dir() {
519004e86ffSlogin                         // 期望得到文件,但是是文件夹
520676b8ef6SMork                         return Err(SystemError::EISDIR);
521004e86ffSlogin                     } else {
522004e86ffSlogin                         // 期望得到文件夹,但是是文件
523676b8ef6SMork                         return Err(SystemError::ENOTDIR);
524004e86ffSlogin                     }
525004e86ffSlogin                 }
526004e86ffSlogin                 // 找到期望的目录项
527004e86ffSlogin                 return Ok(e);
528004e86ffSlogin             }
529004e86ffSlogin 
530004e86ffSlogin             if let Some(ref mut sng) = short_name_gen {
531004e86ffSlogin                 sng.add_name(&e.short_name_raw())
532004e86ffSlogin             }
533004e86ffSlogin         }
534004e86ffSlogin         // 找不到文件/文件夹
535676b8ef6SMork         return Err(SystemError::ENOENT);
536004e86ffSlogin     }
537004e86ffSlogin 
538004e86ffSlogin     /// @brief 在当前目录下打开文件,获取FATFile结构体
539676b8ef6SMork     pub fn open_file(&self, name: &str, fs: Arc<FATFileSystem>) -> Result<FATFile, SystemError> {
540004e86ffSlogin         let f: FATFile = self.find_entry(name, Some(false), None, fs)?.to_file()?;
541004e86ffSlogin         return Ok(f);
542004e86ffSlogin     }
543004e86ffSlogin 
544004e86ffSlogin     /// @brief 在当前目录下打开文件夹,获取FATDir结构体
545676b8ef6SMork     pub fn open_dir(&self, name: &str, fs: Arc<FATFileSystem>) -> Result<FATDir, SystemError> {
546004e86ffSlogin         let d: FATDir = self.find_entry(name, Some(true), None, fs)?.to_dir()?;
547004e86ffSlogin         return Ok(d);
548004e86ffSlogin     }
549004e86ffSlogin 
550004e86ffSlogin     /// @brief 在当前文件夹下创建文件。
551004e86ffSlogin     ///
552004e86ffSlogin     /// @param name 文件名
553004e86ffSlogin     /// @param fs 当前文件夹所属的文件系统
554676b8ef6SMork     pub fn create_file(&self, name: &str, fs: &Arc<FATFileSystem>) -> Result<FATFile, SystemError> {
555676b8ef6SMork         let r: Result<FATDirEntryOrShortName, SystemError> =
556004e86ffSlogin             self.check_existence(name, Some(false), fs.clone());
557004e86ffSlogin         // 检查错误码,如果能够表明目录项已经存在,则返回-EEXIST
558b5b571e0SLoGin         if let Err(err_val) = r {
559676b8ef6SMork             if err_val == (SystemError::EISDIR) || err_val == (SystemError::ENOTDIR) {
560676b8ef6SMork                 return Err(SystemError::EEXIST);
561004e86ffSlogin             } else {
562004e86ffSlogin                 return Err(err_val);
563004e86ffSlogin             }
564004e86ffSlogin         }
565004e86ffSlogin 
566004e86ffSlogin         match r.unwrap() {
567004e86ffSlogin             FATDirEntryOrShortName::ShortName(short_name) => {
568004e86ffSlogin                 // 确认名称是一个可行的长文件名
569004e86ffSlogin                 LongDirEntry::validate_long_name(name)?;
570004e86ffSlogin                 // 创建目录项
571676b8ef6SMork                 let x: Result<FATFile, SystemError> = self
572004e86ffSlogin                     .create_dir_entries(
573004e86ffSlogin                         name.trim(),
574004e86ffSlogin                         &short_name,
575004e86ffSlogin                         None,
576004e86ffSlogin                         FileAttributes {
577004e86ffSlogin                             value: FileAttributes::ARCHIVE,
578004e86ffSlogin                         },
579004e86ffSlogin                         fs.clone(),
580004e86ffSlogin                     )
581004e86ffSlogin                     .map(|e| e.to_file())?;
582004e86ffSlogin                 return x;
583004e86ffSlogin             }
584004e86ffSlogin 
585004e86ffSlogin             FATDirEntryOrShortName::DirEntry(_) => {
586004e86ffSlogin                 // 已经存在这样的一个目录项了
587676b8ef6SMork                 return Err(SystemError::EEXIST);
588004e86ffSlogin             }
589004e86ffSlogin         }
590004e86ffSlogin     }
591004e86ffSlogin 
592676b8ef6SMork     pub fn create_dir(&self, name: &str, fs: &Arc<FATFileSystem>) -> Result<FATDir, SystemError> {
593676b8ef6SMork         let r: Result<FATDirEntryOrShortName, SystemError> =
594004e86ffSlogin             self.check_existence(name, Some(true), fs.clone());
595*2eab6dd7S曾俊         // debug!("check existence ok");
596004e86ffSlogin         // 检查错误码,如果能够表明目录项已经存在,则返回-EEXIST
597b5b571e0SLoGin         if let Err(err_val) = r {
598676b8ef6SMork             if err_val == (SystemError::EISDIR) || err_val == (SystemError::ENOTDIR) {
599676b8ef6SMork                 return Err(SystemError::EEXIST);
600004e86ffSlogin             } else {
601004e86ffSlogin                 return Err(err_val);
602004e86ffSlogin             }
603004e86ffSlogin         }
604004e86ffSlogin 
605004e86ffSlogin         match r.unwrap() {
606004e86ffSlogin             // 文件夹不存在,创建文件夹
607004e86ffSlogin             FATDirEntryOrShortName::ShortName(short_name) => {
608004e86ffSlogin                 LongDirEntry::validate_long_name(name)?;
609004e86ffSlogin                 // 目标目录项
610004e86ffSlogin                 let mut short_entry = ShortDirEntry::default();
611b087521eSChiichen 
612004e86ffSlogin                 let first_cluster: Cluster = fs.allocate_cluster(None)?;
613004e86ffSlogin                 short_entry.set_first_cluster(first_cluster);
614004e86ffSlogin 
615004e86ffSlogin                 // === 接下来在子目录中创建'.'目录项和'..'目录项
616004e86ffSlogin                 let mut offset = 0;
617004e86ffSlogin                 // '.'目录项
618b5b571e0SLoGin                 let mut dot_entry = ShortDirEntry {
619b5b571e0SLoGin                     name: ShortNameGenerator::new(".").generate().unwrap(),
620b5b571e0SLoGin                     attributes: FileAttributes::new(FileAttributes::DIRECTORY),
621b5b571e0SLoGin                     ..Default::default()
622b5b571e0SLoGin                 };
623004e86ffSlogin                 dot_entry.set_first_cluster(first_cluster);
624004e86ffSlogin 
625004e86ffSlogin                 // todo: 设置创建、访问时间
626b5b571e0SLoGin                 dot_entry.flush(fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
627004e86ffSlogin 
628004e86ffSlogin                 // 偏移量加上一个目录项的长度
629004e86ffSlogin                 offset += FATRawDirEntry::DIR_ENTRY_LEN;
630004e86ffSlogin 
631004e86ffSlogin                 // '..'目录项
632b5b571e0SLoGin                 let mut dot_dot_entry = ShortDirEntry {
633b5b571e0SLoGin                     name: ShortNameGenerator::new("..").generate().unwrap(),
634b5b571e0SLoGin                     attributes: FileAttributes::new(FileAttributes::DIRECTORY),
635b5b571e0SLoGin                     ..Default::default()
636b5b571e0SLoGin                 };
637004e86ffSlogin                 dot_dot_entry.set_first_cluster(self.first_cluster);
638004e86ffSlogin                 // todo: 设置创建、访问时间
639004e86ffSlogin 
640b5b571e0SLoGin                 dot_dot_entry.flush(fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
641004e86ffSlogin 
642*2eab6dd7S曾俊                 // debug!("to create dentries");
643004e86ffSlogin                 // 在当前目录下创建目标目录项
644004e86ffSlogin                 let res = self
645004e86ffSlogin                     .create_dir_entries(
646004e86ffSlogin                         name.trim(),
647004e86ffSlogin                         &short_name,
648004e86ffSlogin                         Some(short_entry),
649004e86ffSlogin                         FileAttributes {
650004e86ffSlogin                             value: FileAttributes::DIRECTORY,
651004e86ffSlogin                         },
652004e86ffSlogin                         fs.clone(),
653004e86ffSlogin                     )
654004e86ffSlogin                     .map(|e| e.to_dir())?;
655*2eab6dd7S曾俊                 // debug!("create dentries ok");
656004e86ffSlogin                 return res;
657004e86ffSlogin             }
658004e86ffSlogin             FATDirEntryOrShortName::DirEntry(_) => {
659004e86ffSlogin                 // 已经存在这样的一个目录项了
660676b8ef6SMork                 return Err(SystemError::EEXIST);
661004e86ffSlogin             }
662004e86ffSlogin         }
663004e86ffSlogin     }
664004e86ffSlogin     /// @brief 检查目录项在当前文件夹下是否存在
665004e86ffSlogin     ///
666004e86ffSlogin     /// @param name 目录项的名字
667004e86ffSlogin     /// @param expect_dir 该值为Some时有效。如果期待目标目录项是文件夹,那么值为Some(true), 否则为Some(false).
668004e86ffSlogin     /// @param fs 当前目录所属的文件系统
669004e86ffSlogin     ///
670004e86ffSlogin     /// @return Ok(FATDirEntryOrShortName::DirEntry) 找到期待的目录项
671004e86ffSlogin     /// @return Ok(FATDirEntryOrShortName::ShortName) 当前文件夹下不存在指定的目录项,因此返回一个可行的短文件名
672676b8ef6SMork     /// @return Err(SystemError) 错误码
673004e86ffSlogin     pub fn check_existence(
674004e86ffSlogin         &self,
675004e86ffSlogin         name: &str,
676004e86ffSlogin         expect_dir: Option<bool>,
677004e86ffSlogin         fs: Arc<FATFileSystem>,
678676b8ef6SMork     ) -> Result<FATDirEntryOrShortName, SystemError> {
679004e86ffSlogin         let mut sng = ShortNameGenerator::new(name);
680004e86ffSlogin 
681004e86ffSlogin         loop {
682676b8ef6SMork             let e: Result<FATDirEntry, SystemError> =
683004e86ffSlogin                 self.find_entry(name, expect_dir, Some(&mut sng), fs.clone());
684004e86ffSlogin             match e {
685004e86ffSlogin                 Ok(e) => {
686004e86ffSlogin                     // 找到,返回目录项
687004e86ffSlogin                     return Ok(FATDirEntryOrShortName::DirEntry(e));
688004e86ffSlogin                 }
689004e86ffSlogin                 Err(e) => {
690004e86ffSlogin                     // 如果没找到,则不返回错误
691676b8ef6SMork                     if e == SystemError::ENOENT {
692004e86ffSlogin                     } else {
693004e86ffSlogin                         // 其他错误,则返回
694004e86ffSlogin                         return Err(e);
695004e86ffSlogin                     }
696004e86ffSlogin                 }
697004e86ffSlogin             }
698004e86ffSlogin 
699004e86ffSlogin             // 没找到文件,则生成短文件名
700004e86ffSlogin             if let Ok(name) = sng.generate() {
701004e86ffSlogin                 return Ok(FATDirEntryOrShortName::ShortName(name));
702004e86ffSlogin             }
703004e86ffSlogin 
704004e86ffSlogin             sng.next_iteration();
705004e86ffSlogin         }
706004e86ffSlogin     }
707004e86ffSlogin 
708004e86ffSlogin     /// @brief 创建一系列的目录项
709004e86ffSlogin     ///
710004e86ffSlogin     /// @param long_name 长文件名
711004e86ffSlogin     /// @param short_name 短文件名
712004e86ffSlogin     /// @param short_dentry 可选的生成好的短目录项结构体
713004e86ffSlogin     /// @param attrs FAT目录项的属性
714004e86ffSlogin     /// @param fs 当前文件夹所属的文件系统
715004e86ffSlogin     ///
716004e86ffSlogin     /// @return Ok(FATDirEntry) FAT目录项的枚举类型(目录项链条的最后一个长目录项)
717004e86ffSlogin     fn create_dir_entries(
718004e86ffSlogin         &self,
719004e86ffSlogin         long_name: &str,
720004e86ffSlogin         short_name: &[u8; 11],
721004e86ffSlogin         short_dentry: Option<ShortDirEntry>,
722004e86ffSlogin         attrs: FileAttributes,
723004e86ffSlogin         fs: Arc<FATFileSystem>,
724676b8ef6SMork     ) -> Result<FATDirEntry, SystemError> {
725b5b571e0SLoGin         let mut short_dentry: ShortDirEntry = short_dentry.unwrap_or_default();
726b5b571e0SLoGin         short_dentry.name = *short_name;
727004e86ffSlogin         short_dentry.attributes = attrs;
728004e86ffSlogin 
729004e86ffSlogin         // todo: 设置创建时间、修改时间
730004e86ffSlogin 
731004e86ffSlogin         let mut long_name_gen: LongNameEntryGenerator =
732004e86ffSlogin             LongNameEntryGenerator::new(long_name, short_dentry.checksum());
733004e86ffSlogin         let num_entries = long_name_gen.num_entries() as u64;
734004e86ffSlogin 
735*2eab6dd7S曾俊         // debug!("to find free entries");
736004e86ffSlogin         let free_entries: Option<(Cluster, u64)> =
737004e86ffSlogin             self.find_free_entries(num_entries, fs.clone())?;
738004e86ffSlogin         // 目录项开始位置
739004e86ffSlogin         let start_loc: (Cluster, u64) = match free_entries {
740004e86ffSlogin             Some(c) => c,
741676b8ef6SMork             None => return Err(SystemError::ENOSPC),
742004e86ffSlogin         };
743004e86ffSlogin         let offsets: Vec<(Cluster, u64)> =
744004e86ffSlogin             FATDirEntryOffsetIter::new(fs.clone(), start_loc, num_entries, None).collect();
745004e86ffSlogin 
746004e86ffSlogin         // 迭代长目录项
747004e86ffSlogin         for off in &offsets.as_slice()[..offsets.len() - 1] {
748004e86ffSlogin             // 获取生成的下一个长目录项
749004e86ffSlogin             let long_entry: LongDirEntry = long_name_gen.next().unwrap();
750004e86ffSlogin             // 获取这个长目录项在磁盘内的字节偏移量
751004e86ffSlogin             let bytes_offset = fs.cluster_bytes_offset(off.0) + off.1;
752004e86ffSlogin             long_entry.flush(fs.clone(), bytes_offset)?;
753004e86ffSlogin         }
754004e86ffSlogin 
755004e86ffSlogin         let start: (Cluster, u64) = offsets[0];
756004e86ffSlogin         let end: (Cluster, u64) = *offsets.last().unwrap();
757004e86ffSlogin         // 短目录项在磁盘上的字节偏移量
758004e86ffSlogin         let offset = fs.cluster_bytes_offset(end.0) + end.1;
759004e86ffSlogin         short_dentry.flush(&fs, offset)?;
760004e86ffSlogin 
761b5b571e0SLoGin         return Ok(
762b5b571e0SLoGin             short_dentry.convert_to_dir_entry_with_long_name(long_name.to_string(), (start, end))
763b5b571e0SLoGin         );
764004e86ffSlogin     }
765004e86ffSlogin 
766004e86ffSlogin     /// @brief 判断当前目录是否为空
767004e86ffSlogin     ///
768004e86ffSlogin     /// @return true 当前目录为空
769004e86ffSlogin     /// @return false 当前目录不为空
770004e86ffSlogin     pub fn is_empty(&self, fs: Arc<FATFileSystem>) -> bool {
771004e86ffSlogin         for e in self.to_iter(fs) {
772004e86ffSlogin             let s = e.short_name();
773004e86ffSlogin             if s == "." || s == ".." {
774004e86ffSlogin                 continue;
775004e86ffSlogin             } else {
776004e86ffSlogin                 return false;
777004e86ffSlogin             }
778004e86ffSlogin         }
779004e86ffSlogin         return true;
780004e86ffSlogin     }
781004e86ffSlogin 
782004e86ffSlogin     /// @brief 从当前文件夹中删除文件或者文件夹。如果目标文件夹不为空,则不能删除,返回-ENOTEMPTY.
783004e86ffSlogin     ///
784004e86ffSlogin     /// @param fs 当前FATDir所属的文件系统
785004e86ffSlogin     /// @param name 目录项的名字
786004e86ffSlogin     /// @param remove_clusters 是否删除与指定的目录项相关联的数据簇
787004e86ffSlogin     ///
788004e86ffSlogin     /// @return Ok() 成功时无返回值
789676b8ef6SMork     /// @return Err(SystemError) 如果目标文件夹不为空,则不能删除,返回-ENOTEMPTY. 或者返回底层传上来的错误
790004e86ffSlogin     pub fn remove(
791004e86ffSlogin         &self,
792004e86ffSlogin         fs: Arc<FATFileSystem>,
793004e86ffSlogin         name: &str,
794004e86ffSlogin         remove_clusters: bool,
795676b8ef6SMork     ) -> Result<(), SystemError> {
796004e86ffSlogin         let e: FATDirEntry = self.find_entry(name, None, None, fs.clone())?;
797004e86ffSlogin 
798004e86ffSlogin         // 判断文件夹是否为空,如果空,则不删除,报错。
799004e86ffSlogin         if e.is_dir() && !(e.to_dir().unwrap().is_empty(fs.clone())) {
800676b8ef6SMork             return Err(SystemError::ENOTEMPTY);
801004e86ffSlogin         }
802004e86ffSlogin 
803004e86ffSlogin         if e.first_cluster().cluster_num >= 2 && remove_clusters {
804004e86ffSlogin             // 删除与指定的目录项相关联的数据簇
805004e86ffSlogin             fs.deallocate_cluster_chain(e.first_cluster())?;
806004e86ffSlogin         }
807004e86ffSlogin 
808004e86ffSlogin         if e.get_dir_range().is_some() {
809004e86ffSlogin             self.remove_dir_entries(fs, e.get_dir_range().unwrap())?;
810004e86ffSlogin         }
811004e86ffSlogin 
812004e86ffSlogin         return Ok(());
813004e86ffSlogin     }
814004e86ffSlogin 
815004e86ffSlogin     /// @brief 在当前目录中删除多个目录项
816004e86ffSlogin     ///
817004e86ffSlogin     /// @param fs 当前目录所属的文件系统
818004e86ffSlogin     /// @param cluster_range 要删除的目录项的范围(以簇+簇内偏移量的形式表示)
819004e86ffSlogin     fn remove_dir_entries(
820004e86ffSlogin         &self,
821004e86ffSlogin         fs: Arc<FATFileSystem>,
822004e86ffSlogin         cluster_range: ((Cluster, u64), (Cluster, u64)),
823676b8ef6SMork     ) -> Result<(), SystemError> {
824004e86ffSlogin         // 收集所有的要移除的目录项
825004e86ffSlogin         let offsets: Vec<(Cluster, u64)> =
826004e86ffSlogin             FATDirEntryOffsetIter::new(fs.clone(), cluster_range.0, 15, Some(cluster_range.1))
827004e86ffSlogin                 .collect();
828004e86ffSlogin         // 逐个设置这些目录项为“空闲”状态
829004e86ffSlogin         for off in offsets {
830004e86ffSlogin             let disk_bytes_offset = fs.cluster_bytes_offset(off.0) + off.1;
831004e86ffSlogin             let mut short_entry = ShortDirEntry::default();
832004e86ffSlogin             short_entry.name[0] = 0xe5;
833004e86ffSlogin             short_entry.flush(&fs, disk_bytes_offset)?;
834004e86ffSlogin         }
835004e86ffSlogin         return Ok(());
836004e86ffSlogin     }
837004e86ffSlogin 
838004e86ffSlogin     /// @brief 根据名字在当前文件夹下寻找目录项
839004e86ffSlogin     ///
840004e86ffSlogin     /// @return Ok(FATDirEntry) 目标目录项
841676b8ef6SMork     /// @return Err(SystemError) 底层传上来的错误码
84278bf93f0SYJwu2023     pub fn get_dir_entry(
84378bf93f0SYJwu2023         &self,
84478bf93f0SYJwu2023         fs: Arc<FATFileSystem>,
84578bf93f0SYJwu2023         name: &str,
84678bf93f0SYJwu2023     ) -> Result<FATDirEntry, SystemError> {
847004e86ffSlogin         if name == "." || name == "/" {
848004e86ffSlogin             return Ok(FATDirEntry::Dir(self.clone()));
849004e86ffSlogin         }
850004e86ffSlogin 
851004e86ffSlogin         LongDirEntry::validate_long_name(name)?;
852004e86ffSlogin         return self.find_entry(name, None, None, fs);
853004e86ffSlogin     }
854004e86ffSlogin 
855004e86ffSlogin     /// @brief 在当前目录内,重命名一个目录项
856004e86ffSlogin     ///
857004e86ffSlogin     pub fn rename(
858004e86ffSlogin         &self,
859004e86ffSlogin         fs: Arc<FATFileSystem>,
860004e86ffSlogin         old_name: &str,
861004e86ffSlogin         new_name: &str,
862676b8ef6SMork     ) -> Result<FATDirEntry, SystemError> {
863004e86ffSlogin         // 判断源目录项是否存在
864004e86ffSlogin         let old_dentry: FATDirEntry = if let FATDirEntryOrShortName::DirEntry(dentry) =
865004e86ffSlogin             self.check_existence(old_name, None, fs.clone())?
866004e86ffSlogin         {
867004e86ffSlogin             dentry
868004e86ffSlogin         } else {
869004e86ffSlogin             // 如果目标目录项不存在,则返回错误
870676b8ef6SMork             return Err(SystemError::ENOENT);
871004e86ffSlogin         };
872004e86ffSlogin 
873004e86ffSlogin         let short_name = if let FATDirEntryOrShortName::ShortName(s) =
874004e86ffSlogin             self.check_existence(new_name, None, fs.clone())?
875004e86ffSlogin         {
876004e86ffSlogin             s
877004e86ffSlogin         } else {
878004e86ffSlogin             // 如果目标目录项存在,那么就返回错误
879676b8ef6SMork             return Err(SystemError::EEXIST);
880004e86ffSlogin         };
881004e86ffSlogin 
882004e86ffSlogin         let old_short_dentry: Option<ShortDirEntry> = old_dentry.short_dir_entry();
883004e86ffSlogin         if let Some(se) = old_short_dentry {
884004e86ffSlogin             // 删除原来的目录项
885004e86ffSlogin             self.remove(fs.clone(), old_dentry.name().as_str(), false)?;
886004e86ffSlogin 
887004e86ffSlogin             // 创建新的目录项
888004e86ffSlogin             let new_dentry: FATDirEntry = self.create_dir_entries(
889004e86ffSlogin                 new_name,
890004e86ffSlogin                 &short_name,
891004e86ffSlogin                 Some(se),
892004e86ffSlogin                 se.attributes,
893004e86ffSlogin                 fs.clone(),
894004e86ffSlogin             )?;
895004e86ffSlogin 
896004e86ffSlogin             return Ok(new_dentry);
897004e86ffSlogin         } else {
898004e86ffSlogin             // 不允许对根目录项进行重命名
899676b8ef6SMork             return Err(SystemError::EPERM);
900004e86ffSlogin         }
901004e86ffSlogin     }
9029e481b3bSTTaq 
9039e481b3bSTTaq     /// @brief 跨目录,重命名一个目录项
9049e481b3bSTTaq     ///
9059e481b3bSTTaq     pub fn rename_across(
9069e481b3bSTTaq         &self,
9079e481b3bSTTaq         fs: Arc<FATFileSystem>,
9089e481b3bSTTaq         target: &FATDir,
9099e481b3bSTTaq         old_name: &str,
9109e481b3bSTTaq         new_name: &str,
9119e481b3bSTTaq     ) -> Result<FATDirEntry, SystemError> {
9129e481b3bSTTaq         // 判断源目录项是否存在
9139e481b3bSTTaq         let old_dentry: FATDirEntry = if let FATDirEntryOrShortName::DirEntry(dentry) =
9149e481b3bSTTaq             self.check_existence(old_name, None, fs.clone())?
9159e481b3bSTTaq         {
9169e481b3bSTTaq             dentry
9179e481b3bSTTaq         } else {
9189e481b3bSTTaq             // 如果目标目录项不存在,则返回错误
9199e481b3bSTTaq             return Err(SystemError::ENOENT);
9209e481b3bSTTaq         };
9219e481b3bSTTaq 
9229e481b3bSTTaq         let short_name = if let FATDirEntryOrShortName::ShortName(s) =
9239e481b3bSTTaq             target.check_existence(new_name, None, fs.clone())?
9249e481b3bSTTaq         {
9259e481b3bSTTaq             s
9269e481b3bSTTaq         } else {
9279e481b3bSTTaq             // 如果目标目录项存在,那么就返回错误
9289e481b3bSTTaq             return Err(SystemError::EEXIST);
9299e481b3bSTTaq         };
9309e481b3bSTTaq 
9319e481b3bSTTaq         let old_short_dentry: Option<ShortDirEntry> = old_dentry.short_dir_entry();
9329e481b3bSTTaq         if let Some(se) = old_short_dentry {
9339e481b3bSTTaq             // 删除原来的目录项
9349e481b3bSTTaq             self.remove(fs.clone(), old_dentry.name().as_str(), false)?;
9359e481b3bSTTaq 
9369e481b3bSTTaq             // 创建新的目录项
9379e481b3bSTTaq             let new_dentry: FATDirEntry = target.create_dir_entries(
9389e481b3bSTTaq                 new_name,
9399e481b3bSTTaq                 &short_name,
9409e481b3bSTTaq                 Some(se),
9419e481b3bSTTaq                 se.attributes,
9429e481b3bSTTaq                 fs.clone(),
9439e481b3bSTTaq             )?;
9449e481b3bSTTaq 
9459e481b3bSTTaq             return Ok(new_dentry);
9469e481b3bSTTaq         } else {
9479e481b3bSTTaq             // 不允许对根目录项进行重命名
9489e481b3bSTTaq             return Err(SystemError::EPERM);
9499e481b3bSTTaq         }
9509e481b3bSTTaq     }
951004e86ffSlogin }
952004e86ffSlogin 
953004e86ffSlogin impl FileAttributes {
954004e86ffSlogin     pub const READ_ONLY: u8 = 1 << 0;
955004e86ffSlogin     pub const HIDDEN: u8 = 1 << 1;
956004e86ffSlogin     pub const SYSTEM: u8 = 1 << 2;
957004e86ffSlogin     pub const VOLUME_ID: u8 = 1 << 3;
958004e86ffSlogin     pub const DIRECTORY: u8 = 1 << 4;
959004e86ffSlogin     pub const ARCHIVE: u8 = 1 << 5;
960004e86ffSlogin     pub const LONG_NAME: u8 = FileAttributes::READ_ONLY
961004e86ffSlogin         | FileAttributes::HIDDEN
962004e86ffSlogin         | FileAttributes::SYSTEM
963004e86ffSlogin         | FileAttributes::VOLUME_ID;
964004e86ffSlogin 
965004e86ffSlogin     /// @brief 判断属性是否存在
966004e86ffSlogin     #[inline]
967004e86ffSlogin     pub fn contains(&self, attr: u8) -> bool {
968004e86ffSlogin         return (self.value & attr) != 0;
969004e86ffSlogin     }
970004e86ffSlogin 
971004e86ffSlogin     pub fn new(attr: u8) -> Self {
972004e86ffSlogin         return Self { value: attr };
973004e86ffSlogin     }
974004e86ffSlogin }
975004e86ffSlogin 
976004e86ffSlogin /// FAT32的短目录项
977004e86ffSlogin #[derive(Debug, Clone, Copy, Default)]
978004e86ffSlogin pub struct ShortDirEntry {
979004e86ffSlogin     /// short name
980004e86ffSlogin     name: [u8; 11],
981004e86ffSlogin     /// 目录项属性 (见 FileAttributes )
982004e86ffSlogin     attributes: FileAttributes,
983004e86ffSlogin 
984004e86ffSlogin     /// Windows NT系统的保留字段。用来表示短目录项文件名。
985004e86ffSlogin     /// EXT|BASE => 8(BASE).3(EXT)
986004e86ffSlogin     /// BASE:LowerCase(8),UpperCase(0)
987004e86ffSlogin     /// EXT:LowerCase(16),UpperCase(0)
988004e86ffSlogin     nt_res: u8,
989004e86ffSlogin 
990004e86ffSlogin     /// 文件创建时间的毫秒级时间戳
991004e86ffSlogin     crt_time_tenth: u8,
992004e86ffSlogin     /// 创建时间
993004e86ffSlogin     crt_time: u16,
994004e86ffSlogin     /// 创建日期
995004e86ffSlogin     crt_date: u16,
996004e86ffSlogin     /// 最后一次访问日期
997004e86ffSlogin     lst_acc_date: u16,
998004e86ffSlogin     /// High word of first cluster(0 for FAT12 and FAT16)
999004e86ffSlogin     fst_clus_hi: u16,
1000004e86ffSlogin     /// 最后写入时间
1001004e86ffSlogin     wrt_time: u16,
1002004e86ffSlogin     /// 最后写入日期
1003004e86ffSlogin     wrt_date: u16,
1004004e86ffSlogin     /// Low word of first cluster
1005004e86ffSlogin     fst_clus_lo: u16,
1006004e86ffSlogin     /// 文件大小
1007004e86ffSlogin     file_size: u32,
1008004e86ffSlogin }
1009004e86ffSlogin 
1010004e86ffSlogin /// FAT32的长目录项
1011004e86ffSlogin #[derive(Debug, Clone, Copy, Default)]
1012004e86ffSlogin pub struct LongDirEntry {
1013004e86ffSlogin     /// 长目录项的序号
1014004e86ffSlogin     ord: u8,
1015004e86ffSlogin     /// 长文件名的第1-5个字符,每个字符占2bytes
1016004e86ffSlogin     name1: [u16; 5],
1017004e86ffSlogin     /// 目录项属性必须为ATTR_LONG_NAME
1018004e86ffSlogin     file_attrs: FileAttributes,
1019004e86ffSlogin     /// Entry Type: 如果为0,则说明这是长目录项的子项
1020004e86ffSlogin     /// 非零值是保留的。
1021004e86ffSlogin     dirent_type: u8,
1022004e86ffSlogin     /// 短文件名的校验和
1023004e86ffSlogin     checksum: u8,
1024004e86ffSlogin     /// 长文件名的第6-11个字符,每个字符占2bytes
1025004e86ffSlogin     name2: [u16; 6],
1026004e86ffSlogin     /// 必须为0
1027004e86ffSlogin     first_clus_low: u16,
1028004e86ffSlogin     /// 长文件名的12-13个字符,每个字符占2bytes
1029004e86ffSlogin     name3: [u16; 2],
1030004e86ffSlogin }
1031004e86ffSlogin 
1032004e86ffSlogin impl LongDirEntry {
1033004e86ffSlogin     /// 长目录项的字符串长度(单位:word)
1034004e86ffSlogin     pub const LONG_NAME_STR_LEN: usize = 13;
1035004e86ffSlogin 
1036004e86ffSlogin     /// @brief 初始化一个新的长目录项
1037004e86ffSlogin     ///
1038004e86ffSlogin     /// @param ord 顺序
1039004e86ffSlogin     /// @param name_part 长目录项名称的数组(长度必须为13)
1040004e86ffSlogin     /// @param check_sum 短目录项的校验和
1041004e86ffSlogin     ///
1042004e86ffSlogin     /// @return Self 初始化好的长目录项对象
1043004e86ffSlogin     fn new(ord: u8, name_part: &[u16], check_sum: u8) -> Self {
1044b5b571e0SLoGin         let mut result = LongDirEntry {
1045b5b571e0SLoGin             ord,
1046b5b571e0SLoGin             file_attrs: FileAttributes::new(FileAttributes::LONG_NAME),
1047b5b571e0SLoGin             dirent_type: 0,
1048b5b571e0SLoGin             checksum: check_sum,
1049b5b571e0SLoGin             ..Default::default()
1050b5b571e0SLoGin         };
1051004e86ffSlogin         result
1052004e86ffSlogin             .insert_name(name_part)
1053004e86ffSlogin             .expect("Name part's len should be equal to 13.");
1054004e86ffSlogin         // 该字段需要外层的代码手动赋值
1055004e86ffSlogin         result.first_clus_low = 0;
1056004e86ffSlogin         return result;
1057004e86ffSlogin     }
1058004e86ffSlogin 
1059004e86ffSlogin     /// @brief 填写长目录项的名称字段。
1060004e86ffSlogin     ///
1061004e86ffSlogin     /// @param name_part 要被填入当前长目录项的名字(数组长度必须为13)
1062004e86ffSlogin     ///
1063004e86ffSlogin     /// @return Ok(())
1064676b8ef6SMork     /// @return Err(SystemError) 错误码
1065676b8ef6SMork     fn insert_name(&mut self, name_part: &[u16]) -> Result<(), SystemError> {
1066004e86ffSlogin         if name_part.len() != Self::LONG_NAME_STR_LEN {
1067676b8ef6SMork             return Err(SystemError::EINVAL);
1068004e86ffSlogin         }
1069004e86ffSlogin         self.name1.copy_from_slice(&name_part[0..5]);
1070004e86ffSlogin         self.name2.copy_from_slice(&name_part[5..11]);
1071004e86ffSlogin         self.name3.copy_from_slice(&name_part[11..13]);
1072004e86ffSlogin         return Ok(());
1073004e86ffSlogin     }
1074004e86ffSlogin 
1075004e86ffSlogin     /// @brief 将当前长目录项的名称字段,原样地拷贝到一个长度为13的u16数组中。
1076004e86ffSlogin     /// @param dst 拷贝的目的地,一个[u16]数组,长度必须为13。
1077676b8ef6SMork     pub fn copy_name_to_slice(&self, dst: &mut [u16]) -> Result<(), SystemError> {
1078004e86ffSlogin         if dst.len() != Self::LONG_NAME_STR_LEN {
1079676b8ef6SMork             return Err(SystemError::EINVAL);
1080004e86ffSlogin         }
1081004e86ffSlogin         dst[0..5].copy_from_slice(&self.name1);
1082004e86ffSlogin         dst[5..11].copy_from_slice(&self.name2);
1083004e86ffSlogin         dst[11..13].copy_from_slice(&self.name3);
1084004e86ffSlogin         return Ok(());
1085004e86ffSlogin     }
1086004e86ffSlogin 
1087004e86ffSlogin     /// @brief 是否为最后一个长目录项
1088004e86ffSlogin     ///
1089004e86ffSlogin     /// @return true 是最后一个长目录项
1090004e86ffSlogin     /// @return false 不是最后一个长目录项
1091004e86ffSlogin     pub fn is_last(&self) -> bool {
1092004e86ffSlogin         return self.ord & 0x40 > 0;
1093004e86ffSlogin     }
1094004e86ffSlogin 
1095004e86ffSlogin     /// @brief 校验字符串是否符合长目录项的命名要求
1096004e86ffSlogin     ///
1097004e86ffSlogin     /// @return Ok(()) 名称合法
1098676b8ef6SMork     /// @return Err(SystemError) 名称不合法,返回错误码
1099676b8ef6SMork     pub fn validate_long_name(mut name: &str) -> Result<(), SystemError> {
1100004e86ffSlogin         // 去除首尾多余的空格
1101004e86ffSlogin         name = name.trim();
1102004e86ffSlogin 
1103004e86ffSlogin         // 名称不能为0
1104b5b571e0SLoGin         if name.is_empty() {
1105676b8ef6SMork             return Err(SystemError::EINVAL);
1106004e86ffSlogin         }
1107004e86ffSlogin 
1108004e86ffSlogin         // 名称长度不能大于255
1109004e86ffSlogin         if name.len() > 255 {
1110676b8ef6SMork             return Err(SystemError::ENAMETOOLONG);
1111004e86ffSlogin         }
1112004e86ffSlogin 
1113004e86ffSlogin         // 检查是否符合命名要求
1114004e86ffSlogin         for c in name.chars() {
1115004e86ffSlogin             match c {
1116004e86ffSlogin                 'a'..='z' | 'A'..='Z' | '0'..='9' => {}
1117004e86ffSlogin                 '\u{80}'..='\u{ffff}' => {}
1118004e86ffSlogin                 '$' | '%' | '\'' | '-' | '_' | '@' | '~' | '`' | '!' | '(' | ')' | '{' | '}'
1119004e86ffSlogin                 | '^' | '#' | '&' => {}
1120004e86ffSlogin                 '+' | ',' | ';' | '=' | '[' | ']' | '.' | ' ' => {}
1121004e86ffSlogin                 _ => {
1122*2eab6dd7S曾俊                     debug!("error char: {}", c);
1123676b8ef6SMork                     return Err(SystemError::EILSEQ);
1124004e86ffSlogin                 }
1125004e86ffSlogin             }
1126004e86ffSlogin         }
1127004e86ffSlogin         return Ok(());
1128004e86ffSlogin     }
1129004e86ffSlogin 
1130004e86ffSlogin     /// @brief 把当前长目录项写入磁盘
1131004e86ffSlogin     ///
1132004e86ffSlogin     /// @param fs 对应的文件系统
1133004e86ffSlogin     /// @param disk_bytes_offset 长目录项所在位置对应的在磁盘上的字节偏移量
1134004e86ffSlogin     ///
1135004e86ffSlogin     /// @return Ok(())
1136676b8ef6SMork     /// @return Err(SystemError) 错误码
1137676b8ef6SMork     pub fn flush(&self, fs: Arc<FATFileSystem>, disk_bytes_offset: u64) -> Result<(), SystemError> {
1138004e86ffSlogin         // 从磁盘读取数据
1139004e86ffSlogin         let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
1140004e86ffSlogin         let lba = fs.get_lba_from_offset(
1141004e86ffSlogin             fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)),
1142004e86ffSlogin         );
1143b5b571e0SLoGin         let mut v: Vec<u8> = vec![0; fs.lba_per_sector() * LBA_SIZE];
1144004e86ffSlogin         fs.partition
1145004e86ffSlogin             .disk()
1146b5b571e0SLoGin             .read_at(lba, fs.lba_per_sector(), &mut v)?;
1147004e86ffSlogin 
1148004e86ffSlogin         let mut cursor: VecCursor = VecCursor::new(v);
1149004e86ffSlogin         // 切换游标到对应位置
1150004e86ffSlogin         cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
1151004e86ffSlogin 
1152004e86ffSlogin         // 写入数据
1153004e86ffSlogin         cursor.write_u8(self.ord)?;
1154004e86ffSlogin         for b in &self.name1 {
1155004e86ffSlogin             cursor.write_u16(*b)?;
1156004e86ffSlogin         }
1157004e86ffSlogin 
1158004e86ffSlogin         cursor.write_u8(self.file_attrs.value)?;
1159004e86ffSlogin         cursor.write_u8(self.dirent_type)?;
1160004e86ffSlogin         cursor.write_u8(self.checksum)?;
1161004e86ffSlogin 
1162004e86ffSlogin         for b in &self.name2 {
1163004e86ffSlogin             cursor.write_u16(*b)?;
1164004e86ffSlogin         }
1165004e86ffSlogin 
1166004e86ffSlogin         cursor.write_u16(self.first_clus_low)?;
1167004e86ffSlogin 
1168004e86ffSlogin         for b in &self.name3 {
1169004e86ffSlogin             cursor.write_u16(*b)?;
1170004e86ffSlogin         }
1171004e86ffSlogin 
1172004e86ffSlogin         // 把修改后的长目录项刷入磁盘
1173004e86ffSlogin         fs.partition
1174004e86ffSlogin             .disk()
1175b5b571e0SLoGin             .write_at(lba, fs.lba_per_sector(), cursor.as_slice())?;
1176004e86ffSlogin         fs.partition.disk().sync()?;
1177004e86ffSlogin 
1178004e86ffSlogin         return Ok(());
1179004e86ffSlogin     }
1180004e86ffSlogin }
1181004e86ffSlogin 
1182004e86ffSlogin impl ShortDirEntry {
1183b5b571e0SLoGin     const PADDING: u8 = b' ';
1184004e86ffSlogin 
1185004e86ffSlogin     /// @brief 判断当前目录项是否为文件夹
1186004e86ffSlogin     ///
1187004e86ffSlogin     /// @return true 是文件夹
1188004e86ffSlogin     /// @return false 不是文件夹
1189004e86ffSlogin     pub fn is_dir(&self) -> bool {
1190004e86ffSlogin         return (self.attributes.contains(FileAttributes::DIRECTORY))
1191004e86ffSlogin             && (!self.attributes.contains(FileAttributes::VOLUME_ID));
1192004e86ffSlogin     }
1193004e86ffSlogin 
1194004e86ffSlogin     /// @brief 判断当前目录项是否为文件
1195004e86ffSlogin     ///
1196004e86ffSlogin     /// @return true 是文件
1197004e86ffSlogin     /// @return false 不是文件
1198004e86ffSlogin     pub fn is_file(&self) -> bool {
1199004e86ffSlogin         return (!self.attributes.contains(FileAttributes::DIRECTORY))
1200004e86ffSlogin             && (!self.attributes.contains(FileAttributes::VOLUME_ID));
1201004e86ffSlogin     }
1202004e86ffSlogin 
1203004e86ffSlogin     /// @brief 判断当前目录项是否为卷号
1204004e86ffSlogin     ///
1205004e86ffSlogin     /// @return true 是卷号
1206004e86ffSlogin     /// @return false 不是卷号
1207004e86ffSlogin     pub fn is_volume_id(&self) -> bool {
1208004e86ffSlogin         return (!self.attributes.contains(FileAttributes::DIRECTORY))
1209004e86ffSlogin             && self.attributes.contains(FileAttributes::VOLUME_ID);
1210004e86ffSlogin     }
1211004e86ffSlogin 
1212004e86ffSlogin     /// @brief 将短目录项的名字转换为String
1213004e86ffSlogin     fn name_to_string(&self) -> String {
1214004e86ffSlogin         // 计算基础名的长度
1215004e86ffSlogin         let base_len = self.name[..8]
1216004e86ffSlogin             .iter()
1217004e86ffSlogin             .rposition(|x| *x != ShortDirEntry::PADDING)
1218004e86ffSlogin             .map(|len| len + 1)
1219004e86ffSlogin             .unwrap_or(0);
1220004e86ffSlogin         // 计算扩展名的长度
1221004e86ffSlogin         let ext_len = self.name[8..]
1222004e86ffSlogin             .iter()
1223004e86ffSlogin             .rposition(|x| *x != ShortDirEntry::PADDING)
1224004e86ffSlogin             .map(|len| len + 1)
1225004e86ffSlogin             .unwrap_or(0);
1226004e86ffSlogin 
1227004e86ffSlogin         // 声明存储完整名字的数组(包含“.”)
1228004e86ffSlogin         let mut name = [ShortDirEntry::PADDING; 12];
1229004e86ffSlogin         // 拷贝基础名
1230004e86ffSlogin         name[..base_len].copy_from_slice(&self.name[..base_len]);
1231004e86ffSlogin 
1232004e86ffSlogin         // 拷贝扩展名,并计算总的长度
1233004e86ffSlogin         let total_len = if ext_len > 0 {
1234b5b571e0SLoGin             name[base_len] = b'.';
1235004e86ffSlogin             name[base_len + 1..base_len + 1 + ext_len].copy_from_slice(&self.name[8..8 + ext_len]);
1236004e86ffSlogin             // 总长度为基础名长度+点号+扩展名长度
1237004e86ffSlogin             base_len + 1 + ext_len
1238004e86ffSlogin         } else {
1239004e86ffSlogin             base_len
1240004e86ffSlogin         };
1241004e86ffSlogin 
1242004e86ffSlogin         if name[0] == 0x05 {
1243004e86ffSlogin             name[0] = 0xe5;
1244004e86ffSlogin         }
1245004e86ffSlogin 
1246004e86ffSlogin         let iter = name[..total_len].iter().map(|c| decode_u8_ascii(*c));
1247004e86ffSlogin         // 返回最终的字符串
1248004e86ffSlogin         return String::from_iter(iter);
1249004e86ffSlogin     }
1250004e86ffSlogin 
1251004e86ffSlogin     /// @brief 将短目录项结构体,转换为FATDirEntry枚举类型
1252004e86ffSlogin     ///
1253004e86ffSlogin     /// @param loc 当前文件的起始、终止簇。格式:(簇,簇内偏移量)
1254004e86ffSlogin     /// @return 生成的FATDirENtry枚举类型
1255b5b571e0SLoGin     pub fn convert_to_dir_entry(&self, loc: (Cluster, u64)) -> FATDirEntry {
1256004e86ffSlogin         // 当前文件的第一个簇
1257004e86ffSlogin         let first_cluster =
1258004e86ffSlogin             Cluster::new(((self.fst_clus_hi as u64) << 16) | (self.fst_clus_lo as u64));
1259004e86ffSlogin 
1260004e86ffSlogin         // 当前是文件或卷号
1261004e86ffSlogin         if self.is_file() || self.is_volume_id() {
1262b5b571e0SLoGin             let file: FATFile = FATFile {
1263b5b571e0SLoGin                 file_name: self.name_to_string(),
1264b5b571e0SLoGin                 first_cluster,
1265b5b571e0SLoGin                 short_dir_entry: *self,
1266b5b571e0SLoGin                 loc: (loc, loc),
1267b5b571e0SLoGin             };
1268004e86ffSlogin 
1269004e86ffSlogin             // 根据当前短目录项的类型的不同,返回对应的枚举类型。
1270004e86ffSlogin             if self.is_file() {
1271004e86ffSlogin                 return FATDirEntry::File(file);
1272004e86ffSlogin             } else {
1273004e86ffSlogin                 return FATDirEntry::VolId(file);
1274004e86ffSlogin             }
1275004e86ffSlogin         } else {
1276004e86ffSlogin             // 当前是文件夹
1277b5b571e0SLoGin             let dir = FATDir {
1278b5b571e0SLoGin                 dir_name: self.name_to_string(),
1279b5b571e0SLoGin                 first_cluster,
1280b5b571e0SLoGin                 root_offset: None,
1281b5b571e0SLoGin                 short_dir_entry: Some(*self),
1282b5b571e0SLoGin                 loc: Some((loc, loc)),
1283b5b571e0SLoGin             };
1284004e86ffSlogin 
1285004e86ffSlogin             return FATDirEntry::Dir(dir);
1286004e86ffSlogin         }
1287004e86ffSlogin     }
1288004e86ffSlogin 
1289004e86ffSlogin     /// @brief 将短目录项结构体,转换为FATDirEntry枚举类型. 并且,该短目录项具有对应的长目录项。
1290004e86ffSlogin     /// 因此,需要传入从长目录项获得的完整的文件名
1291004e86ffSlogin     ///
1292004e86ffSlogin     /// @param name 从长目录项获取的完整文件名
1293004e86ffSlogin     /// @param loc 当前文件的起始、终止簇。格式:(簇,簇内偏移量)
1294004e86ffSlogin     /// @return 生成的FATDirENtry枚举类型
1295b5b571e0SLoGin     pub fn convert_to_dir_entry_with_long_name(
1296004e86ffSlogin         &self,
1297004e86ffSlogin         name: String,
1298004e86ffSlogin         loc: ((Cluster, u64), (Cluster, u64)),
1299004e86ffSlogin     ) -> FATDirEntry {
1300004e86ffSlogin         // 当前文件的第一个簇
1301004e86ffSlogin         let first_cluster =
1302004e86ffSlogin             Cluster::new(((self.fst_clus_hi as u64) << 16) | (self.fst_clus_lo as u64));
1303004e86ffSlogin 
1304004e86ffSlogin         if self.is_file() || self.is_volume_id() {
1305b5b571e0SLoGin             let file = FATFile {
1306b5b571e0SLoGin                 first_cluster,
1307b5b571e0SLoGin                 file_name: name,
1308b5b571e0SLoGin                 loc,
1309b5b571e0SLoGin                 short_dir_entry: *self,
1310b5b571e0SLoGin             };
1311004e86ffSlogin 
1312004e86ffSlogin             if self.is_file() {
1313004e86ffSlogin                 return FATDirEntry::File(file);
1314004e86ffSlogin             } else {
1315004e86ffSlogin                 return FATDirEntry::VolId(file);
1316004e86ffSlogin             }
1317004e86ffSlogin         } else {
1318b5b571e0SLoGin             let dir = FATDir {
1319b5b571e0SLoGin                 first_cluster,
1320b5b571e0SLoGin                 dir_name: name,
1321b5b571e0SLoGin                 loc: Some(loc),
1322b5b571e0SLoGin                 short_dir_entry: Some(*self),
1323b5b571e0SLoGin                 root_offset: None,
1324b5b571e0SLoGin             };
1325004e86ffSlogin 
1326004e86ffSlogin             return FATDirEntry::Dir(dir);
1327004e86ffSlogin         }
1328004e86ffSlogin     }
1329004e86ffSlogin 
1330004e86ffSlogin     /// @brief 计算短目录项的名称的校验和
1331004e86ffSlogin     fn checksum(&self) -> u8 {
1332004e86ffSlogin         let mut result = 0;
1333004e86ffSlogin 
1334004e86ffSlogin         for c in &self.name {
1335004e86ffSlogin             result = (result << 7) + (result >> 1) + *c;
1336004e86ffSlogin         }
1337004e86ffSlogin         return result;
1338004e86ffSlogin     }
1339004e86ffSlogin 
1340004e86ffSlogin     /// @brief 把当前短目录项写入磁盘
1341004e86ffSlogin     ///
1342004e86ffSlogin     /// @param fs 对应的文件系统
1343004e86ffSlogin     /// @param disk_bytes_offset 短目录项所在位置对应的在磁盘上的字节偏移量
1344004e86ffSlogin     ///
1345004e86ffSlogin     /// @return Ok(())
1346676b8ef6SMork     /// @return Err(SystemError) 错误码
134778bf93f0SYJwu2023     pub fn flush(
134878bf93f0SYJwu2023         &self,
134978bf93f0SYJwu2023         fs: &Arc<FATFileSystem>,
135078bf93f0SYJwu2023         disk_bytes_offset: u64,
135178bf93f0SYJwu2023     ) -> Result<(), SystemError> {
1352004e86ffSlogin         // 从磁盘读取数据
1353004e86ffSlogin         let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
1354004e86ffSlogin         let lba = fs.get_lba_from_offset(
1355004e86ffSlogin             fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)),
1356004e86ffSlogin         );
1357b5b571e0SLoGin         let mut v: Vec<u8> = vec![0; fs.lba_per_sector() * LBA_SIZE];
1358004e86ffSlogin         fs.partition
1359004e86ffSlogin             .disk()
1360b5b571e0SLoGin             .read_at(lba, fs.lba_per_sector(), &mut v)?;
1361004e86ffSlogin 
1362004e86ffSlogin         let mut cursor: VecCursor = VecCursor::new(v);
1363004e86ffSlogin         // 切换游标到对应位置
1364004e86ffSlogin         cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
1365004e86ffSlogin         cursor.write_exact(&self.name)?;
1366004e86ffSlogin         cursor.write_u8(self.attributes.value)?;
1367004e86ffSlogin         cursor.write_u8(self.nt_res)?;
1368004e86ffSlogin         cursor.write_u8(self.crt_time_tenth)?;
1369004e86ffSlogin         cursor.write_u16(self.crt_time)?;
1370004e86ffSlogin         cursor.write_u16(self.crt_date)?;
1371004e86ffSlogin         cursor.write_u16(self.lst_acc_date)?;
1372004e86ffSlogin         cursor.write_u16(self.fst_clus_hi)?;
1373004e86ffSlogin         cursor.write_u16(self.wrt_time)?;
1374004e86ffSlogin         cursor.write_u16(self.wrt_date)?;
1375004e86ffSlogin         cursor.write_u16(self.fst_clus_lo)?;
1376004e86ffSlogin         cursor.write_u32(self.file_size)?;
1377004e86ffSlogin 
1378004e86ffSlogin         // 把修改后的长目录项刷入磁盘
1379004e86ffSlogin         fs.partition
1380004e86ffSlogin             .disk()
1381b5b571e0SLoGin             .write_at(lba, fs.lba_per_sector(), cursor.as_slice())?;
1382004e86ffSlogin         fs.partition.disk().sync()?;
1383004e86ffSlogin 
1384004e86ffSlogin         return Ok(());
1385004e86ffSlogin     }
1386004e86ffSlogin 
1387004e86ffSlogin     /// @brief 设置短目录项的“第一个簇”字段的值
1388004e86ffSlogin     pub fn set_first_cluster(&mut self, cluster: Cluster) {
1389004e86ffSlogin         self.fst_clus_lo = (cluster.cluster_num & 0x0000ffff) as u16;
1390004e86ffSlogin         self.fst_clus_hi = ((cluster.cluster_num & 0xffff0000) >> 16) as u16;
1391004e86ffSlogin     }
1392004e86ffSlogin }
1393004e86ffSlogin 
1394004e86ffSlogin /// @brief FAT文件系统标准定义的目录项
1395004e86ffSlogin #[derive(Debug, Clone)]
1396004e86ffSlogin pub enum FATRawDirEntry {
1397004e86ffSlogin     /// 短目录项
1398004e86ffSlogin     Short(ShortDirEntry),
1399004e86ffSlogin     /// 长目录项
1400004e86ffSlogin     Long(LongDirEntry),
1401004e86ffSlogin     /// 当前目录项的Name[0]==0xe5, 是空闲目录项
1402004e86ffSlogin     Free,
1403004e86ffSlogin     /// 当前目录项的Name[0]==0xe5, 是空闲目录项,且在这之后没有被分配过的目录项了。
1404004e86ffSlogin     FreeRest,
1405004e86ffSlogin }
1406004e86ffSlogin 
1407004e86ffSlogin impl FATRawDirEntry {
1408004e86ffSlogin     /// 每个目录项的长度(单位:字节)
1409004e86ffSlogin     pub const DIR_ENTRY_LEN: u64 = 32;
1410004e86ffSlogin 
1411004e86ffSlogin     /// @brief 判断当前目录项是否为这个文件的最后一个目录项
1412004e86ffSlogin     fn is_last(&self) -> bool {
1413b5b571e0SLoGin         match *self {
1414b5b571e0SLoGin             Self::Short(_) => {
1415004e86ffSlogin                 return true;
1416004e86ffSlogin             }
1417b5b571e0SLoGin             Self::Long(l) => {
1418004e86ffSlogin                 return l.is_last();
1419004e86ffSlogin             }
1420004e86ffSlogin             _ => {
1421004e86ffSlogin                 return false;
1422004e86ffSlogin             }
1423004e86ffSlogin         }
1424004e86ffSlogin     }
1425004e86ffSlogin 
1426004e86ffSlogin     /// @brief 判断当前目录项是否为长目录项
1427004e86ffSlogin     fn is_long(&self) -> bool {
1428004e86ffSlogin         if let Self::Long(_) = self {
1429004e86ffSlogin             return true;
1430004e86ffSlogin         } else {
1431004e86ffSlogin             return false;
1432004e86ffSlogin         }
1433004e86ffSlogin     }
1434004e86ffSlogin 
1435004e86ffSlogin     /// @brief 判断当前目录项是否为短目录项
1436004e86ffSlogin     fn is_short(&self) -> bool {
1437004e86ffSlogin         if let Self::Short(_) = self {
1438004e86ffSlogin             return true;
1439004e86ffSlogin         } else {
1440004e86ffSlogin             return false;
1441004e86ffSlogin         }
1442004e86ffSlogin     }
1443004e86ffSlogin }
1444004e86ffSlogin 
1445004e86ffSlogin /// @brief FAT文件系统的目录项迭代器
1446004e86ffSlogin #[derive(Debug)]
1447004e86ffSlogin pub struct FATDirIter {
1448004e86ffSlogin     /// 当前正在迭代的簇
1449004e86ffSlogin     current_cluster: Cluster,
1450004e86ffSlogin     /// 当前正在迭代的簇的簇内偏移量
1451004e86ffSlogin     offset: u64,
1452004e86ffSlogin     /// True for the root directories of FAT12 and FAT16
1453004e86ffSlogin     is_root: bool,
1454004e86ffSlogin     /// 指向当前文件系统的指针
1455004e86ffSlogin     fs: Arc<FATFileSystem>,
1456004e86ffSlogin }
1457004e86ffSlogin 
1458004e86ffSlogin impl FATDirIter {
1459004e86ffSlogin     /// @brief 迭代当前inode的目录项(获取下一个目录项)
1460004e86ffSlogin     ///
1461004e86ffSlogin     /// @return Ok(Cluster, u64, Option<FATDirEntry>)
1462004e86ffSlogin     ///             Cluster: 下一个要读取的簇号
1463004e86ffSlogin     ///             u64: 下一个要读取的簇内偏移量
1464004e86ffSlogin     ///             Option<FATDirEntry>: 读取到的目录项(如果没有读取到,就返回失败)
1465004e86ffSlogin     /// @return Err(错误码) 可能出现了内部错误,或者是磁盘错误等。具体原因看错误码。
1466676b8ef6SMork     fn get_dir_entry(&mut self) -> Result<(Cluster, u64, Option<FATDirEntry>), SystemError> {
1467004e86ffSlogin         loop {
14686d81180bSLoGin             if unlikely(self.current_cluster.cluster_num < 2) {
14696d81180bSLoGin                 return Ok((self.current_cluster, self.offset, None));
14706d81180bSLoGin             }
14716d81180bSLoGin 
1472004e86ffSlogin             // 如果当前簇已经被读完,那么尝试获取下一个簇
1473004e86ffSlogin             if self.offset >= self.fs.bytes_per_cluster() && !self.is_root {
1474004e86ffSlogin                 match self.fs.get_fat_entry(self.current_cluster)? {
1475004e86ffSlogin                     FATEntry::Next(c) => {
1476004e86ffSlogin                         // 获得下一个簇的信息
1477004e86ffSlogin                         self.current_cluster = c;
1478004e86ffSlogin                         self.offset %= self.fs.bytes_per_cluster();
1479004e86ffSlogin                     }
1480004e86ffSlogin 
1481004e86ffSlogin                     _ => {
1482004e86ffSlogin                         // 没有下一个簇了,返回None
1483004e86ffSlogin                         return Ok((self.current_cluster, self.offset, None));
1484004e86ffSlogin                     }
1485004e86ffSlogin                 }
1486004e86ffSlogin             }
1487004e86ffSlogin 
1488004e86ffSlogin             // 如果当前是FAT12/FAT16文件系统,并且当前inode是根目录项。
1489004e86ffSlogin             // 如果offset大于根目录项的最大大小(已经遍历完根目录),那么就返回None
1490004e86ffSlogin             if self.is_root && self.offset > self.fs.root_dir_end_bytes_offset().unwrap() {
1491004e86ffSlogin                 return Ok((self.current_cluster, self.offset, None));
1492004e86ffSlogin             }
1493004e86ffSlogin 
1494004e86ffSlogin             // 获取簇在磁盘内的字节偏移量
1495004e86ffSlogin             let offset: u64 = self.fs.cluster_bytes_offset(self.current_cluster) + self.offset;
1496004e86ffSlogin 
1497004e86ffSlogin             // 从磁盘读取原始的dentry
1498004e86ffSlogin             let raw_dentry: FATRawDirEntry = get_raw_dir_entry(&self.fs, offset)?;
1499004e86ffSlogin 
1500004e86ffSlogin             // 由于迭代顺序从前往后,因此:
1501004e86ffSlogin             // 如果找到1个短目录项,那么证明有一个完整的entry被找到,因此返回。
1502004e86ffSlogin             // 如果找到1个长目录项,那么,就依次往下迭代查找,直到找到一个短目录项,然后返回结果。这里找到的所有的目录项,都属于同一个文件/文件夹。
1503004e86ffSlogin             match raw_dentry {
1504004e86ffSlogin                 FATRawDirEntry::Short(s) => {
1505004e86ffSlogin                     // 当前找到一个短目录项,更新offset之后,直接返回
1506004e86ffSlogin                     self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
1507004e86ffSlogin                     return Ok((
1508004e86ffSlogin                         self.current_cluster,
1509004e86ffSlogin                         self.offset,
1510b5b571e0SLoGin                         Some(s.convert_to_dir_entry((
1511004e86ffSlogin                             self.current_cluster,
1512004e86ffSlogin                             self.offset - FATRawDirEntry::DIR_ENTRY_LEN,
1513004e86ffSlogin                         ))),
1514004e86ffSlogin                     ));
1515004e86ffSlogin                 }
1516004e86ffSlogin                 FATRawDirEntry::Long(_) => {
1517004e86ffSlogin                     // 当前找到一个长目录项
1518004e86ffSlogin 
1519004e86ffSlogin                     // 声明一个数组,来容纳所有的entry。(先把最后一个entry放进去)
1520004e86ffSlogin                     let mut long_name_entries: Vec<FATRawDirEntry> = vec![raw_dentry];
1521004e86ffSlogin                     let start_offset: u64 = self.offset;
1522004e86ffSlogin                     let start_cluster: Cluster = self.current_cluster;
1523004e86ffSlogin 
1524004e86ffSlogin                     self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
1525004e86ffSlogin 
1526004e86ffSlogin                     // 由于在FAT文件系统中,文件名最长为255字节,因此,最多有20个长目录项以及1个短目录项。
1527004e86ffSlogin                     // 由于上面已经塞了1个长目录项,因此接下来最多需要迭代20次
1528004e86ffSlogin                     // 循环查找目录项,直到遇到1个短目录项,或者是空闲目录项
1529004e86ffSlogin                     for _ in 0..20 {
1530004e86ffSlogin                         // 如果当前簇已经被读完,那么尝试获取下一个簇
1531004e86ffSlogin                         if self.offset >= self.fs.bytes_per_cluster() && !self.is_root {
1532004e86ffSlogin                             match self.fs.get_fat_entry(self.current_cluster)? {
1533004e86ffSlogin                                 FATEntry::Next(c) => {
1534004e86ffSlogin                                     // 获得下一个簇的信息
1535004e86ffSlogin                                     self.current_cluster = c;
1536004e86ffSlogin                                     self.offset %= self.fs.bytes_per_cluster();
1537004e86ffSlogin                                 }
1538004e86ffSlogin 
1539004e86ffSlogin                                 _ => {
1540004e86ffSlogin                                     // 没有下一个簇了,退出迭代
1541004e86ffSlogin                                     break;
1542004e86ffSlogin                                 }
1543004e86ffSlogin                             }
1544004e86ffSlogin                         }
1545004e86ffSlogin                         // 如果当前是FAT12/FAT16文件系统,并且当前inode是根目录项。
1546004e86ffSlogin                         // 如果offset大于根目录项的最大大小(已经遍历完根目录),那么就退出迭代
1547004e86ffSlogin                         if self.is_root
1548004e86ffSlogin                             && self.offset > self.fs.root_dir_end_bytes_offset().unwrap()
1549004e86ffSlogin                         {
1550004e86ffSlogin                             break;
1551004e86ffSlogin                         }
1552004e86ffSlogin 
1553004e86ffSlogin                         // 获取簇在磁盘内的字节偏移量
1554004e86ffSlogin                         let offset: u64 =
1555004e86ffSlogin                             self.fs.cluster_bytes_offset(self.current_cluster) + self.offset;
1556004e86ffSlogin                         // 从磁盘读取原始的dentry
1557004e86ffSlogin                         let raw_dentry: FATRawDirEntry = get_raw_dir_entry(&self.fs, offset)?;
1558004e86ffSlogin 
1559004e86ffSlogin                         match raw_dentry {
1560004e86ffSlogin                             FATRawDirEntry::Short(_) => {
1561004e86ffSlogin                                 // 当前遇到1个短目录项,证明当前文件/文件夹的所有dentry都被读取完了,因此在将其加入数组后,退出迭代。
1562004e86ffSlogin                                 long_name_entries.push(raw_dentry);
1563004e86ffSlogin                                 break;
1564004e86ffSlogin                             }
1565004e86ffSlogin                             FATRawDirEntry::Long(_) => {
1566004e86ffSlogin                                 // 当前遇到1个长目录项,将其加入数组,然后更新offset,继续迭代。
1567004e86ffSlogin                                 long_name_entries.push(raw_dentry);
1568004e86ffSlogin                                 self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
1569004e86ffSlogin                             }
1570004e86ffSlogin 
1571004e86ffSlogin                             _ => {
1572004e86ffSlogin                                 // 遇到了空闲簇,但没遇到短目录项,说明文件系统出错了,退出。
1573004e86ffSlogin                                 break;
1574004e86ffSlogin                             }
1575004e86ffSlogin                         }
1576004e86ffSlogin                     }
1577*2eab6dd7S曾俊                     // debug!("collect dentries done. long_name_entries={long_name_entries:?}");
1578676b8ef6SMork                     let dir_entry: Result<FATDirEntry, SystemError> = FATDirEntry::new(
1579004e86ffSlogin                         long_name_entries,
1580004e86ffSlogin                         (
1581004e86ffSlogin                             (start_cluster, start_offset),
1582004e86ffSlogin                             (self.current_cluster, self.offset),
1583004e86ffSlogin                         ),
1584004e86ffSlogin                     );
1585*2eab6dd7S曾俊                     // debug!("dir_entry={:?}", dir_entry);
1586004e86ffSlogin                     match dir_entry {
1587004e86ffSlogin                         Ok(d) => {
1588*2eab6dd7S曾俊                             // debug!("dir_entry ok");
1589004e86ffSlogin                             self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
1590004e86ffSlogin                             return Ok((self.current_cluster, self.offset, Some(d)));
1591004e86ffSlogin                         }
1592004e86ffSlogin 
1593004e86ffSlogin                         Err(_) => {
1594*2eab6dd7S曾俊                             // debug!("dir_entry err,  e={}", e);
1595004e86ffSlogin                             self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
1596004e86ffSlogin                         }
1597004e86ffSlogin                     }
1598004e86ffSlogin                 }
1599004e86ffSlogin                 FATRawDirEntry::Free => {
1600004e86ffSlogin                     // 当前目录项是空的
1601004e86ffSlogin                     self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
1602004e86ffSlogin                 }
1603004e86ffSlogin                 FATRawDirEntry::FreeRest => {
1604004e86ffSlogin                     // 当前目录项是空的,且之后都是空的,因此直接返回
1605004e86ffSlogin                     return Ok((self.current_cluster, self.offset, None));
1606004e86ffSlogin                 }
1607004e86ffSlogin             }
1608004e86ffSlogin         }
1609004e86ffSlogin     }
1610004e86ffSlogin }
1611004e86ffSlogin 
1612004e86ffSlogin /// 为DirIter实现迭代器trait
1613004e86ffSlogin impl Iterator for FATDirIter {
1614004e86ffSlogin     type Item = FATDirEntry;
1615004e86ffSlogin 
1616004e86ffSlogin     fn next(&mut self) -> Option<Self::Item> {
1617004e86ffSlogin         match self.get_dir_entry() {
1618004e86ffSlogin             Ok((cluster, offset, result)) => {
1619004e86ffSlogin                 self.current_cluster = cluster;
1620004e86ffSlogin                 self.offset = offset;
1621004e86ffSlogin                 return result;
1622004e86ffSlogin             }
1623004e86ffSlogin             Err(_) => {
1624004e86ffSlogin                 return None;
1625004e86ffSlogin             }
1626004e86ffSlogin         }
1627004e86ffSlogin     }
1628004e86ffSlogin }
1629004e86ffSlogin 
1630004e86ffSlogin impl FATDirEntry {
1631004e86ffSlogin     /// @brief 构建FATDirEntry枚举类型
1632004e86ffSlogin     ///
1633004e86ffSlogin     /// @param long_name_entries 长目录项的数组。
1634004e86ffSlogin     ///         格式:[第20个(或者是最大ord的那个), 19, 18, ..., 1, 短目录项]
1635004e86ffSlogin     ///
1636004e86ffSlogin     /// @return Ok(FATDirEntry) 构建好的FATDirEntry类型的对象
1637676b8ef6SMork     /// @return Err(SystemError) 错误码
1638004e86ffSlogin     pub fn new(
1639004e86ffSlogin         mut long_name_entries: Vec<FATRawDirEntry>,
1640004e86ffSlogin         loc: ((Cluster, u64), (Cluster, u64)),
1641676b8ef6SMork     ) -> Result<Self, SystemError> {
1642004e86ffSlogin         if long_name_entries.is_empty() {
1643676b8ef6SMork             return Err(SystemError::EINVAL);
1644004e86ffSlogin         }
1645004e86ffSlogin 
1646004e86ffSlogin         if !long_name_entries[0].is_last() || !long_name_entries.last().unwrap().is_short() {
1647004e86ffSlogin             // 存在孤立的目录项,文件系统出现异常,因此返回错误,表明其只读。
1648004e86ffSlogin             // TODO: 标记整个FAT文件系统为只读的
1649676b8ef6SMork             return Err(SystemError::EROFS);
1650004e86ffSlogin         }
1651004e86ffSlogin 
1652004e86ffSlogin         // 取出短目录项(位于vec的末尾)
1653004e86ffSlogin         let short_dentry: ShortDirEntry = match long_name_entries.pop().unwrap() {
1654004e86ffSlogin             FATRawDirEntry::Short(s) => s,
1655004e86ffSlogin             _ => unreachable!(),
1656004e86ffSlogin         };
1657004e86ffSlogin 
1658004e86ffSlogin         let mut extractor = LongNameExtractor::new();
1659004e86ffSlogin         for entry in &long_name_entries {
1660004e86ffSlogin             match entry {
1661004e86ffSlogin                 &FATRawDirEntry::Long(l) => {
1662004e86ffSlogin                     extractor.process(l)?;
1663004e86ffSlogin                 }
1664004e86ffSlogin 
1665004e86ffSlogin                 _ => {
1666676b8ef6SMork                     return Err(SystemError::EROFS);
1667004e86ffSlogin                 }
1668004e86ffSlogin             }
1669004e86ffSlogin         }
1670004e86ffSlogin         // 检验校验和是否正确
1671004e86ffSlogin         if extractor.validate_checksum(&short_dentry) {
1672004e86ffSlogin             // 校验和正确,返回一个长目录项
1673b5b571e0SLoGin             return Ok(
1674b5b571e0SLoGin                 short_dentry.convert_to_dir_entry_with_long_name(extractor.extracted_name(), loc)
1675b5b571e0SLoGin             );
1676004e86ffSlogin         } else {
1677004e86ffSlogin             // 校验和不相同,认为文件系统出错
1678676b8ef6SMork             return Err(SystemError::EROFS);
1679004e86ffSlogin         }
1680004e86ffSlogin     }
1681004e86ffSlogin 
1682004e86ffSlogin     /// @brief 获取短目录项的名字
1683004e86ffSlogin     pub fn short_name(&self) -> String {
1684004e86ffSlogin         match self {
1685004e86ffSlogin             FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
1686004e86ffSlogin                 return f.short_dir_entry.name_to_string();
1687004e86ffSlogin             }
1688004e86ffSlogin             FATDirEntry::Dir(d) => match d.short_dir_entry {
1689004e86ffSlogin                 Some(s) => {
1690004e86ffSlogin                     return s.name_to_string();
1691004e86ffSlogin                 }
1692004e86ffSlogin                 None => {
1693004e86ffSlogin                     return String::from("/");
1694004e86ffSlogin                 }
1695004e86ffSlogin             },
1696004e86ffSlogin             FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
1697004e86ffSlogin         }
1698004e86ffSlogin     }
1699004e86ffSlogin 
1700004e86ffSlogin     /// @brief 获取短目录项结构体
1701004e86ffSlogin     pub fn short_dir_entry(&self) -> Option<ShortDirEntry> {
1702004e86ffSlogin         match &self {
1703004e86ffSlogin             FATDirEntry::File(f) => {
1704004e86ffSlogin                 return Some(f.short_dir_entry);
1705004e86ffSlogin             }
1706004e86ffSlogin             FATDirEntry::Dir(d) => {
1707004e86ffSlogin                 return d.short_dir_entry;
1708004e86ffSlogin             }
1709004e86ffSlogin             FATDirEntry::VolId(s) => {
1710004e86ffSlogin                 return Some(s.short_dir_entry);
1711004e86ffSlogin             }
1712004e86ffSlogin             FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
1713004e86ffSlogin         }
1714004e86ffSlogin     }
1715004e86ffSlogin 
1716004e86ffSlogin     /// @brief 获取目录项的第一个簇的簇号
1717004e86ffSlogin     pub fn first_cluster(&self) -> Cluster {
1718004e86ffSlogin         match self {
1719004e86ffSlogin             FATDirEntry::File(f) => {
1720004e86ffSlogin                 return f.first_cluster;
1721004e86ffSlogin             }
1722004e86ffSlogin             FATDirEntry::Dir(d) => {
1723004e86ffSlogin                 return d.first_cluster;
1724004e86ffSlogin             }
1725004e86ffSlogin             FATDirEntry::VolId(s) => {
1726004e86ffSlogin                 return s.first_cluster;
1727004e86ffSlogin             }
1728004e86ffSlogin             FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
1729004e86ffSlogin         }
1730004e86ffSlogin     }
1731004e86ffSlogin 
1732004e86ffSlogin     /// @brief 获取当前目录项所占用的簇的范围
1733004e86ffSlogin     ///
1734004e86ffSlogin     /// @return (起始簇,簇内偏移量), (终止簇,簇内偏移量)
1735004e86ffSlogin     pub fn get_dir_range(&self) -> Option<((Cluster, u64), (Cluster, u64))> {
1736004e86ffSlogin         match self {
1737004e86ffSlogin             FATDirEntry::File(f) => Some(f.loc),
1738004e86ffSlogin             FATDirEntry::Dir(d) => d.loc,
1739004e86ffSlogin             FATDirEntry::VolId(s) => Some(s.loc),
1740004e86ffSlogin             FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
1741004e86ffSlogin         }
1742004e86ffSlogin     }
1743004e86ffSlogin 
1744004e86ffSlogin     /// @brief 获取原始的短目录项名(FAT标准规定的)
1745004e86ffSlogin     pub fn short_name_raw(&self) -> [u8; 11] {
1746004e86ffSlogin         match self {
1747004e86ffSlogin             FATDirEntry::File(f) => {
1748004e86ffSlogin                 return f.short_dir_entry.name;
1749004e86ffSlogin             }
1750004e86ffSlogin             FATDirEntry::Dir(d) => match d.short_dir_entry {
1751004e86ffSlogin                 // 存在短目录项,直接返回
1752004e86ffSlogin                 Some(s) => {
1753004e86ffSlogin                     return s.name;
1754004e86ffSlogin                 }
1755004e86ffSlogin                 // 是根目录项
1756004e86ffSlogin                 None => {
1757004e86ffSlogin                     let mut s = [0x20u8; 11];
1758b5b571e0SLoGin                     s[0] = b'/';
1759004e86ffSlogin                     return s;
1760004e86ffSlogin                 }
1761004e86ffSlogin             },
1762004e86ffSlogin             FATDirEntry::VolId(s) => {
1763004e86ffSlogin                 return s.short_dir_entry.name;
1764004e86ffSlogin             }
1765004e86ffSlogin 
1766004e86ffSlogin             FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
1767004e86ffSlogin         }
1768004e86ffSlogin     }
1769004e86ffSlogin 
1770004e86ffSlogin     /// @brief 获取目录项的名字
1771004e86ffSlogin     pub fn name(&self) -> String {
1772004e86ffSlogin         match self {
1773004e86ffSlogin             FATDirEntry::File(f) => {
1774004e86ffSlogin                 return f.file_name.clone();
1775004e86ffSlogin             }
1776004e86ffSlogin             FATDirEntry::VolId(s) => {
1777004e86ffSlogin                 return s.file_name.clone();
1778004e86ffSlogin             }
1779004e86ffSlogin             FATDirEntry::Dir(d) => {
1780004e86ffSlogin                 return d.dir_name.clone();
1781004e86ffSlogin             }
1782004e86ffSlogin             FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
1783004e86ffSlogin         }
1784004e86ffSlogin     }
1785004e86ffSlogin 
1786004e86ffSlogin     /// @brief 判断目录项是否为文件
1787004e86ffSlogin     pub fn is_file(&self) -> bool {
1788b5b571e0SLoGin         matches!(self, &FATDirEntry::File(_) | &FATDirEntry::VolId(_))
1789004e86ffSlogin     }
1790004e86ffSlogin 
1791004e86ffSlogin     /// @brief 判断目录项是否为文件夹
1792004e86ffSlogin     pub fn is_dir(&self) -> bool {
1793b5b571e0SLoGin         matches!(self, &FATDirEntry::Dir(_))
1794004e86ffSlogin     }
1795004e86ffSlogin 
1796004e86ffSlogin     /// @brief 判断目录项是否为Volume id
1797004e86ffSlogin     pub fn is_vol_id(&self) -> bool {
1798b5b571e0SLoGin         matches!(self, &FATDirEntry::VolId(_))
1799004e86ffSlogin     }
1800004e86ffSlogin 
1801004e86ffSlogin     /// @brief 判断FAT目录项的名字与给定的是否相等
1802004e86ffSlogin     ///
1803004e86ffSlogin     /// 由于FAT32对大小写不敏感,因此将字符都转为大写,然后比较
1804004e86ffSlogin     ///
1805004e86ffSlogin     /// @return bool 相等 => true
1806004e86ffSlogin     ///              不相等 => false
1807004e86ffSlogin     pub fn eq_name(&self, name: &str) -> bool {
1808004e86ffSlogin         // 由于FAT32对大小写不敏感,因此将字符都转为大写,然后比较。
1809004e86ffSlogin         let binding = self.short_name();
1810004e86ffSlogin         let short_name = binding.chars().flat_map(|c| c.to_uppercase());
1811004e86ffSlogin         let binding = self.name();
1812004e86ffSlogin         let long_name = binding.chars().flat_map(|c| c.to_uppercase());
1813004e86ffSlogin         let name = name.chars().flat_map(|c| c.to_uppercase());
1814004e86ffSlogin 
1815004e86ffSlogin         let long_name_matches: bool = long_name.eq(name.clone());
1816004e86ffSlogin         let short_name_matches: bool = short_name.eq(name);
1817004e86ffSlogin 
1818004e86ffSlogin         return long_name_matches || short_name_matches;
1819004e86ffSlogin     }
1820004e86ffSlogin 
1821004e86ffSlogin     /// @brief 将FATDirEntry转换为FATFile对象
1822676b8ef6SMork     pub fn to_file(&self) -> Result<FATFile, SystemError> {
1823b5b571e0SLoGin         if !self.is_file() {
1824676b8ef6SMork             return Err(SystemError::EISDIR);
1825004e86ffSlogin         }
1826004e86ffSlogin 
1827004e86ffSlogin         match &self {
1828004e86ffSlogin             FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
1829004e86ffSlogin                 return Ok(f.clone());
1830004e86ffSlogin             }
1831004e86ffSlogin             _ => unreachable!(),
1832004e86ffSlogin         }
1833004e86ffSlogin     }
1834004e86ffSlogin 
1835004e86ffSlogin     /// @brief 将FATDirEntry转换为FATDir对象
1836676b8ef6SMork     pub fn to_dir(&self) -> Result<FATDir, SystemError> {
1837b5b571e0SLoGin         if !self.is_dir() {
1838676b8ef6SMork             return Err(SystemError::ENOTDIR);
1839004e86ffSlogin         }
1840004e86ffSlogin         match &self {
1841004e86ffSlogin             FATDirEntry::Dir(d) => {
1842004e86ffSlogin                 return Ok(d.clone());
1843004e86ffSlogin             }
1844004e86ffSlogin             _ => unreachable!(),
1845004e86ffSlogin         }
1846004e86ffSlogin     }
1847004e86ffSlogin }
1848004e86ffSlogin 
1849004e86ffSlogin /// 用于生成短目录项文件名的生成器。
1850004e86ffSlogin #[derive(Debug, Default)]
1851004e86ffSlogin pub struct ShortNameGenerator {
1852004e86ffSlogin     /// 短目录项的名字
1853004e86ffSlogin     name: [u8; 11],
1854004e86ffSlogin     /// 生成器的标志位(使用impl里面的mask来解析)
1855004e86ffSlogin     flags: u8,
1856004e86ffSlogin     /// 基础名的长度
1857004e86ffSlogin     basename_len: u8,
1858004e86ffSlogin     /// 对于文件名形如(TE021F~1.TXT)的,短前缀+校验码的短目录项,该字段表示基础名末尾数字的对应位。
1859004e86ffSlogin     checksum_bitmask: u16,
1860004e86ffSlogin     /// Fletcher-16 Checksum(与填写到ShortDirEntry里面的不一样)
1861004e86ffSlogin     checksum: u16,
1862004e86ffSlogin     /// 对于形如(TEXTFI~1.TXT)的短目录项名称,其中的数字的bitmask(第0位置位则表示这个数字是0)
1863004e86ffSlogin     suffix_bitmask: u16,
1864004e86ffSlogin }
1865004e86ffSlogin 
1866004e86ffSlogin impl ShortNameGenerator {
1867004e86ffSlogin     /// 短目录项的名称的长度
1868004e86ffSlogin     const SHORT_NAME_LEN: usize = 8;
1869004e86ffSlogin 
1870004e86ffSlogin     // ===== flags标志位的含义 =====
1871004e86ffSlogin     const IS_LOSSY: u8 = (1 << 0);
1872004e86ffSlogin     const IS_EXACT_MATCH: u8 = (1 << 1);
1873004e86ffSlogin     const IS_DOT: u8 = (1 << 2);
1874004e86ffSlogin     const IS_DOTDOT: u8 = (1 << 3);
1875004e86ffSlogin     /// 名称被完全拷贝
1876004e86ffSlogin     const NAME_FITS: u8 = (1 << 4);
1877004e86ffSlogin 
1878004e86ffSlogin     /// @brief 初始化一个短目录项名称生成器
1879004e86ffSlogin     pub fn new(mut name: &str) -> Self {
1880004e86ffSlogin         name = name.trim();
1881004e86ffSlogin 
1882004e86ffSlogin         let mut short_name: [u8; 11] = [0x20u8; 11];
1883004e86ffSlogin         if name == "." {
1884b5b571e0SLoGin             short_name[0] = b'.';
1885004e86ffSlogin         }
1886004e86ffSlogin 
1887004e86ffSlogin         if name == ".." {
1888b5b571e0SLoGin             short_name[0] = b'.';
1889b5b571e0SLoGin             short_name[1] = b'.';
1890004e86ffSlogin         }
1891004e86ffSlogin 
1892004e86ffSlogin         // @name_fits: 名称是否被完全拷贝
1893004e86ffSlogin         // @basename_len: 基础名的长度
1894004e86ffSlogin         // @is_lossy: 是否存在不合法的字符
1895004e86ffSlogin         let (name_fits, basename_len, is_lossy) = match name.rfind('.') {
1896004e86ffSlogin             Some(index) => {
1897004e86ffSlogin                 // 文件名里面有".", 且index为最右边的点号所在的下标(bytes index)
1898004e86ffSlogin                 // 拷贝基础名
1899004e86ffSlogin                 let (b_len, fits, b_lossy) =
1900004e86ffSlogin                     Self::copy_part(&mut short_name[..Self::SHORT_NAME_LEN], &name[..index]);
1901004e86ffSlogin 
1902004e86ffSlogin                 // 拷贝扩展名
1903004e86ffSlogin                 let (_, ext_fits, ext_lossy) = Self::copy_part(
1904004e86ffSlogin                     &mut short_name[Self::SHORT_NAME_LEN..Self::SHORT_NAME_LEN + 3],
1905004e86ffSlogin                     &name[index + 1..],
1906004e86ffSlogin                 );
1907004e86ffSlogin 
1908004e86ffSlogin                 (fits && ext_fits, b_len, b_lossy || ext_lossy)
1909004e86ffSlogin             }
1910004e86ffSlogin             None => {
1911004e86ffSlogin                 // 文件名中,不存在"."
1912004e86ffSlogin                 let (b_len, fits, b_lossy) =
1913b5b571e0SLoGin                     Self::copy_part(&mut short_name[..Self::SHORT_NAME_LEN], name);
1914004e86ffSlogin                 (fits, b_len, b_lossy)
1915004e86ffSlogin             }
1916004e86ffSlogin         };
1917004e86ffSlogin 
1918004e86ffSlogin         let mut flags: u8 = 0;
1919004e86ffSlogin         // 设置flags
1920004e86ffSlogin         if is_lossy {
1921004e86ffSlogin             flags |= Self::IS_LOSSY;
1922004e86ffSlogin         }
1923004e86ffSlogin         if name == "." {
1924004e86ffSlogin             flags |= Self::IS_DOT;
1925004e86ffSlogin         }
1926004e86ffSlogin         if name == ".." {
1927004e86ffSlogin             flags |= Self::IS_DOTDOT;
1928004e86ffSlogin         }
1929004e86ffSlogin 
1930004e86ffSlogin         if name_fits {
1931004e86ffSlogin             flags |= Self::NAME_FITS;
1932004e86ffSlogin         }
1933004e86ffSlogin 
1934004e86ffSlogin         return ShortNameGenerator {
1935004e86ffSlogin             name: short_name,
1936b5b571e0SLoGin             flags,
1937b5b571e0SLoGin             basename_len,
1938004e86ffSlogin             checksum: Self::fletcher_16_checksum(name),
1939004e86ffSlogin             ..Default::default()
1940004e86ffSlogin         };
1941004e86ffSlogin     }
1942004e86ffSlogin 
1943004e86ffSlogin     /// @brief 拷贝字符串到一个u8数组
1944004e86ffSlogin     ///
1945004e86ffSlogin     /// @return (u8, bool, bool)
1946004e86ffSlogin     ///         return.0: 拷贝了的字符串的长度
1947004e86ffSlogin     ///         return.1: 是否完全拷贝完整个字符串
1948004e86ffSlogin     ///         return.2: 拷贝过程中,是否出现了不合法字符
1949004e86ffSlogin     fn copy_part(dest: &mut [u8], src: &str) -> (u8, bool, bool) {
1950004e86ffSlogin         let mut dest_len: usize = 0;
1951004e86ffSlogin         let mut lossy_conv = false;
1952004e86ffSlogin 
1953004e86ffSlogin         for c in src.chars() {
1954004e86ffSlogin             // 如果src还有字符,而dest已经满了,那么表示没有完全拷贝完。
1955004e86ffSlogin             if dest_len == dest.len() {
1956004e86ffSlogin                 return (dest_len as u8, false, lossy_conv);
1957004e86ffSlogin             }
1958004e86ffSlogin 
1959004e86ffSlogin             if c == ' ' || c == '.' {
1960004e86ffSlogin                 lossy_conv = true;
1961004e86ffSlogin                 continue;
1962004e86ffSlogin             }
1963004e86ffSlogin 
1964004e86ffSlogin             let cp: char = match c {
1965004e86ffSlogin                 'a'..='z' | 'A'..='Z' | '0'..='9' => c,
1966004e86ffSlogin                 '$' | '%' | '\'' | '-' | '_' | '@' | '~' | '`' | '!' | '(' | ')' | '{' | '}'
1967004e86ffSlogin                 | '^' | '#' | '&' => c,
1968004e86ffSlogin                 _ => '_',
1969004e86ffSlogin             };
1970004e86ffSlogin 
1971004e86ffSlogin             // 判断是否存在不符合条件的字符
1972004e86ffSlogin             lossy_conv = lossy_conv || c != cp;
1973004e86ffSlogin 
1974004e86ffSlogin             // 拷贝字符
1975004e86ffSlogin             dest[dest_len] = c.to_ascii_uppercase() as u8;
1976004e86ffSlogin             dest_len += 1;
1977004e86ffSlogin         }
1978004e86ffSlogin 
1979004e86ffSlogin         // 返回结果
1980004e86ffSlogin         return (dest_len as u8, true, lossy_conv);
1981004e86ffSlogin     }
1982004e86ffSlogin 
1983004e86ffSlogin     fn fletcher_16_checksum(name: &str) -> u16 {
1984004e86ffSlogin         let mut sum1: u16 = 0;
1985004e86ffSlogin         let mut sum2: u16 = 0;
1986004e86ffSlogin         for c in name.chars() {
1987004e86ffSlogin             sum1 = (sum1 + (c as u16)) % 0xff;
1988004e86ffSlogin             sum2 = (sum1 + sum2) & 0xff;
1989004e86ffSlogin         }
1990004e86ffSlogin         return (sum2 << 8) | sum1;
1991004e86ffSlogin     }
1992004e86ffSlogin 
1993004e86ffSlogin     /// @brief 更新生成器的状态
1994004e86ffSlogin     /// 当长目录项不存在的时候,需要调用这个函数来更新生成器的状态
1995004e86ffSlogin     pub fn add_name(&mut self, name: &[u8; 11]) {
1996004e86ffSlogin         // === 判断名称是否严格的完全匹配
1997004e86ffSlogin         if name == &self.name {
1998004e86ffSlogin             self.flags |= Self::IS_EXACT_MATCH;
1999004e86ffSlogin         }
2000004e86ffSlogin 
2001004e86ffSlogin         // === 检查是否存在长前缀的格式冲突。对于这样的短目录项名称:(TEXTFI~1.TXT)
2002004e86ffSlogin         // 获取名称前缀
2003004e86ffSlogin         let prefix_len = min(self.basename_len, 6) as usize;
2004004e86ffSlogin         // 获取后缀的那个数字
2005004e86ffSlogin         let num_suffix: Option<u32> = if name[prefix_len] as char == '~' {
2006004e86ffSlogin             (name[prefix_len + 1] as char).to_digit(10)
2007004e86ffSlogin         } else {
2008004e86ffSlogin             None
2009004e86ffSlogin         };
2010004e86ffSlogin 
2011004e86ffSlogin         // 判断扩展名是否匹配
2012004e86ffSlogin         let ext_matches: bool = name[8..] == self.name[8..];
2013004e86ffSlogin 
2014004e86ffSlogin         if name[..prefix_len] == self.name[..prefix_len] // 基础名前缀相同
2015004e86ffSlogin             && num_suffix.is_some() // 基础名具有数字后缀
2016004e86ffSlogin             && ext_matches
2017004e86ffSlogin         // 扩展名相匹配
2018004e86ffSlogin         {
2019b5b571e0SLoGin             if let Some(num) = num_suffix {
2020004e86ffSlogin                 self.suffix_bitmask |= 1 << num;
2021004e86ffSlogin             }
2022b5b571e0SLoGin         }
2023004e86ffSlogin 
2024004e86ffSlogin         // === 检查是否存在短前缀+校验和的冲突,文件名形如:(TE021F~1.TXT)
2025004e86ffSlogin         let prefix_len = min(self.basename_len, 2) as usize;
2026004e86ffSlogin         let num_suffix: Option<u32> = if name[prefix_len + 4] as char == '~' {
2027004e86ffSlogin             (name[prefix_len + 1] as char).to_digit(10)
2028004e86ffSlogin         } else {
2029004e86ffSlogin             None
2030004e86ffSlogin         };
2031004e86ffSlogin 
2032004e86ffSlogin         if name[..prefix_len] == self.name[..prefix_len] && num_suffix.is_some() && ext_matches {
2033004e86ffSlogin             // 获取短文件名中的校验码字段
2034004e86ffSlogin             let checksum_result: Result<
2035004e86ffSlogin                 Result<u16, core::num::ParseIntError>,
2036004e86ffSlogin                 core::str::Utf8Error,
2037004e86ffSlogin             > = core::str::from_utf8(&name[prefix_len..prefix_len + 4])
2038004e86ffSlogin                 .map(|s| u16::from_str_radix(s, 16));
2039004e86ffSlogin             // 如果校验码相同
2040004e86ffSlogin             if checksum_result == Ok(Ok(self.checksum)) {
2041004e86ffSlogin                 // 置位checksum_bitmask中,基础名末尾数字的对应位
2042b5b571e0SLoGin                 if let Some(num) = num_suffix {
2043004e86ffSlogin                     self.checksum_bitmask |= 1 << num;
2044004e86ffSlogin                 }
2045004e86ffSlogin             }
2046004e86ffSlogin         }
2047b5b571e0SLoGin     }
2048004e86ffSlogin 
2049676b8ef6SMork     pub fn generate(&self) -> Result<[u8; 11], SystemError> {
2050004e86ffSlogin         if self.is_dot() || self.is_dotdot() {
2051004e86ffSlogin             return Ok(self.name);
2052004e86ffSlogin         }
2053004e86ffSlogin 
2054004e86ffSlogin         // 如果当前名字不存在不合法的字符,且名称被完整拷贝,但是exact match为false,可以认为名称没有冲突,直接返回
2055004e86ffSlogin         if !self.is_lossy() && self.name_fits() && !self.is_exact_match() {
2056004e86ffSlogin             return Ok(self.name);
2057004e86ffSlogin         }
2058004e86ffSlogin 
2059004e86ffSlogin         // 尝试使用长前缀(6字符)
2060004e86ffSlogin         for i in 1..5 {
2061004e86ffSlogin             if self.suffix_bitmask & (1 << i) == 0 {
2062004e86ffSlogin                 return Ok(self.build_prefixed_name(i as u32, false));
2063004e86ffSlogin             }
2064004e86ffSlogin         }
2065004e86ffSlogin 
2066004e86ffSlogin         // 尝试使用短前缀+校验码
2067004e86ffSlogin         for i in 1..10 {
2068004e86ffSlogin             if self.checksum_bitmask & (1 << i) == 0 {
2069004e86ffSlogin                 return Ok(self.build_prefixed_name(i as u32, true));
2070004e86ffSlogin             }
2071004e86ffSlogin         }
2072004e86ffSlogin         // 由于产生太多的冲突,因此返回错误(“短文件名已经存在”)
2073676b8ef6SMork         return Err(SystemError::EEXIST);
2074004e86ffSlogin     }
2075004e86ffSlogin 
2076004e86ffSlogin     pub fn next_iteration(&mut self) {
2077004e86ffSlogin         // 在下一次迭代中,尝试一个不同的校验和
2078004e86ffSlogin         self.checksum = (core::num::Wrapping(self.checksum) + core::num::Wrapping(1)).0;
2079004e86ffSlogin         // 清空bitmask
2080004e86ffSlogin         self.suffix_bitmask = 0;
2081004e86ffSlogin         self.checksum_bitmask = 0;
2082004e86ffSlogin     }
2083004e86ffSlogin 
2084004e86ffSlogin     /// @brief 构造具有前缀的短目录项名称
2085004e86ffSlogin     ///
2086004e86ffSlogin     /// @param num 这是第几个重名的前缀名
2087004e86ffSlogin     /// @param with_checksum 前缀名中是否包含校验码
2088004e86ffSlogin     ///
2089004e86ffSlogin     /// @return 构造好的短目录项名称数组
2090004e86ffSlogin     fn build_prefixed_name(&self, num: u32, with_checksum: bool) -> [u8; 11] {
2091004e86ffSlogin         let mut buf: [u8; 11] = [0x20u8; 11];
2092004e86ffSlogin         let prefix_len: usize = if with_checksum {
2093004e86ffSlogin             let prefix_len: usize = min(self.basename_len as usize, 2);
2094004e86ffSlogin             buf[..prefix_len].copy_from_slice(&self.name[..prefix_len]);
2095004e86ffSlogin             buf[prefix_len..prefix_len + 4].copy_from_slice(&Self::u16_to_u8_array(self.checksum));
2096004e86ffSlogin             prefix_len + 4
2097004e86ffSlogin         } else {
2098004e86ffSlogin             let prefix_len = min(self.basename_len as usize, 6);
2099004e86ffSlogin             buf[..prefix_len].copy_from_slice(&self.name[..prefix_len]);
2100004e86ffSlogin             prefix_len
2101004e86ffSlogin         };
2102004e86ffSlogin 
2103b5b571e0SLoGin         buf[prefix_len] = b'~';
2104004e86ffSlogin         buf[prefix_len + 1] = char::from_digit(num, 10).unwrap() as u8;
2105004e86ffSlogin         buf[8..].copy_from_slice(&self.name[8..]);
2106004e86ffSlogin         return buf;
2107004e86ffSlogin     }
2108004e86ffSlogin 
2109004e86ffSlogin     /// @brief 将一个u16数字转换为十六进制大写字符串对应的ascii数组。
2110004e86ffSlogin     /// 举例:将x=12345转换为16进制字符串“3039”对应的ascii码数组:[51,48,51,57]
2111004e86ffSlogin     fn u16_to_u8_array(x: u16) -> [u8; 4] {
2112004e86ffSlogin         let c1 = char::from_digit((x as u32 >> 12) & 0xf, 16)
2113004e86ffSlogin             .unwrap()
2114004e86ffSlogin             .to_ascii_uppercase() as u8;
2115004e86ffSlogin         let c2 = char::from_digit((x as u32 >> 8) & 0xf, 16)
2116004e86ffSlogin             .unwrap()
2117004e86ffSlogin             .to_ascii_uppercase() as u8;
2118004e86ffSlogin         let c3 = char::from_digit((x as u32 >> 4) & 0xf, 16)
2119004e86ffSlogin             .unwrap()
2120004e86ffSlogin             .to_ascii_uppercase() as u8;
2121b5b571e0SLoGin         let c4 = char::from_digit((x as u32) & 0xf, 16)
2122004e86ffSlogin             .unwrap()
2123004e86ffSlogin             .to_ascii_uppercase() as u8;
2124004e86ffSlogin         return [c1, c2, c3, c4];
2125004e86ffSlogin     }
2126004e86ffSlogin 
2127004e86ffSlogin     #[inline]
2128004e86ffSlogin     fn is_lossy(&self) -> bool {
2129004e86ffSlogin         return (self.flags & Self::IS_LOSSY) > 0;
2130004e86ffSlogin     }
2131004e86ffSlogin 
2132004e86ffSlogin     #[inline]
2133004e86ffSlogin     fn is_exact_match(&self) -> bool {
2134004e86ffSlogin         return (self.flags & Self::IS_EXACT_MATCH) > 0;
2135004e86ffSlogin     }
2136004e86ffSlogin 
2137004e86ffSlogin     #[inline]
2138004e86ffSlogin     fn is_dot(&self) -> bool {
2139004e86ffSlogin         return (self.flags & Self::IS_DOT) > 0;
2140004e86ffSlogin     }
2141004e86ffSlogin 
2142004e86ffSlogin     #[inline]
2143004e86ffSlogin     fn is_dotdot(&self) -> bool {
2144004e86ffSlogin         return (self.flags & Self::IS_DOTDOT) > 0;
2145004e86ffSlogin     }
2146004e86ffSlogin 
2147004e86ffSlogin     #[inline]
2148004e86ffSlogin     fn name_fits(&self) -> bool {
2149004e86ffSlogin         return (self.flags & Self::NAME_FITS) > 0;
2150004e86ffSlogin     }
2151004e86ffSlogin }
2152004e86ffSlogin 
2153004e86ffSlogin /// 从多个LongName中提取完整文件名字段的提取器
2154004e86ffSlogin struct LongNameExtractor {
2155004e86ffSlogin     name: Vec<u16>,
2156004e86ffSlogin     checksum: u8,
2157004e86ffSlogin     index: u8,
2158004e86ffSlogin }
2159004e86ffSlogin 
2160004e86ffSlogin impl LongNameExtractor {
2161004e86ffSlogin     fn new() -> Self {
2162004e86ffSlogin         return LongNameExtractor {
2163004e86ffSlogin             name: Vec::new(),
2164004e86ffSlogin             checksum: 0,
2165004e86ffSlogin             index: 0,
2166004e86ffSlogin         };
2167004e86ffSlogin     }
2168004e86ffSlogin 
2169004e86ffSlogin     /// @brief 提取长目录项的名称
2170004e86ffSlogin     /// @param longname_dentry 长目录项
2171004e86ffSlogin     /// 请注意,必须倒序输入长目录项对象
2172676b8ef6SMork     fn process(&mut self, longname_dentry: LongDirEntry) -> Result<(), SystemError> {
2173004e86ffSlogin         let is_last: bool = longname_dentry.is_last();
2174004e86ffSlogin         let index: u8 = longname_dentry.ord & 0x1f;
2175004e86ffSlogin 
2176004e86ffSlogin         if index == 0 {
2177004e86ffSlogin             self.name.clear();
2178676b8ef6SMork             return Err(SystemError::EROFS);
2179004e86ffSlogin         }
2180004e86ffSlogin 
2181004e86ffSlogin         // 如果是最后一个LongDirEntry,则初始化当前生成器
2182004e86ffSlogin         if is_last {
2183004e86ffSlogin             self.index = index;
2184004e86ffSlogin             self.checksum = longname_dentry.checksum;
2185004e86ffSlogin             self.name
2186004e86ffSlogin                 .resize(index as usize * LongDirEntry::LONG_NAME_STR_LEN, 0);
2187004e86ffSlogin         } else if self.index == 0
2188004e86ffSlogin             || index != self.index - 1
2189004e86ffSlogin             || self.checksum != longname_dentry.checksum
2190004e86ffSlogin         {
2191004e86ffSlogin             // 如果当前index为0,或者index不连续,或者是校验和不同,那么认为文件系统损坏,清除生成器的名称字段
2192004e86ffSlogin             // TODO: 对文件系统的变为只读状态状况的拦截
2193004e86ffSlogin             self.name.clear();
2194676b8ef6SMork             return Err(SystemError::EROFS);
2195004e86ffSlogin         } else {
2196004e86ffSlogin             // 由于dentry倒序输入,因此index是每次减1的
2197004e86ffSlogin             self.index -= 1;
2198004e86ffSlogin         }
2199004e86ffSlogin 
2200004e86ffSlogin         let pos: usize = ((index - 1) as usize) * LongDirEntry::LONG_NAME_STR_LEN;
2201004e86ffSlogin         // 将当前目录项的值,拷贝到生成器的数组中
2202004e86ffSlogin         longname_dentry
2203004e86ffSlogin             .copy_name_to_slice(&mut self.name[pos..pos + LongDirEntry::LONG_NAME_STR_LEN])?;
2204004e86ffSlogin         return Ok(());
2205004e86ffSlogin     }
2206004e86ffSlogin 
2207b5b571e0SLoGin     /// 返回名称的长度
2208004e86ffSlogin     #[inline]
2209004e86ffSlogin     fn len(&self) -> usize {
2210004e86ffSlogin         return self.name.len();
2211004e86ffSlogin     }
2212004e86ffSlogin 
2213b5b571e0SLoGin     /// 返回抽取得到的名称字符串
2214b5b571e0SLoGin     fn extracted_name(&self) -> String {
2215004e86ffSlogin         let mut s = String::from_utf16_lossy(self.name.as_slice());
2216004e86ffSlogin         // 计算字符串的长度。如果字符串中有\0,那么就截取字符串的前面部分
2217004e86ffSlogin         if let Some(len) = s.find('\u{0}') {
2218004e86ffSlogin             s.truncate(len);
2219004e86ffSlogin         }
2220004e86ffSlogin         return s;
2221004e86ffSlogin     }
2222004e86ffSlogin 
2223004e86ffSlogin     /// @brief 判断校验码是否与指定的短目录项的校验码相同
2224004e86ffSlogin     ///
2225004e86ffSlogin     /// @return bool    相同 => true
2226004e86ffSlogin     ///                 不同 => false
2227004e86ffSlogin     fn validate_checksum(&self, short_dentry: &ShortDirEntry) -> bool {
2228004e86ffSlogin         return self.checksum == short_dentry.checksum();
2229004e86ffSlogin     }
2230004e86ffSlogin }
2231004e86ffSlogin 
2232004e86ffSlogin /// @brief 长目录项生成器
2233004e86ffSlogin #[derive(Debug)]
2234004e86ffSlogin struct LongNameEntryGenerator {
2235004e86ffSlogin     name: Vec<u16>,
2236004e86ffSlogin     // 短目录项的校验和
2237004e86ffSlogin     checksum: u8,
2238004e86ffSlogin     // 当前迭代器的索引
2239004e86ffSlogin     idx: u8,
2240004e86ffSlogin     /// 最后一个目录项的索引
2241004e86ffSlogin     last_index: u8,
2242004e86ffSlogin }
2243004e86ffSlogin 
2244004e86ffSlogin impl LongNameEntryGenerator {
2245004e86ffSlogin     /// @brief 初始化长目录项生成器
2246004e86ffSlogin     ///
2247004e86ffSlogin     /// @param name 长文件名数组
2248004e86ffSlogin     /// @param checksum 短目录项的校验和
2249004e86ffSlogin     pub fn new(name: &str, checksum: u8) -> Self {
2250004e86ffSlogin         let mut name: Vec<u16> = name.chars().map(|c| c as u16).collect();
2251004e86ffSlogin 
2252004e86ffSlogin         let padding_bytes: usize = (13 - (name.len() % 13)) % 13;
2253004e86ffSlogin         // 填充最后一个长目录项的文件名
2254004e86ffSlogin         for i in 0..padding_bytes {
2255004e86ffSlogin             if i == 0 {
2256004e86ffSlogin                 name.push(0);
2257004e86ffSlogin             } else {
2258004e86ffSlogin                 name.push(0xffff);
2259004e86ffSlogin             }
2260004e86ffSlogin         }
2261004e86ffSlogin 
2262004e86ffSlogin         // 先从最后一个长目录项开始生成
2263004e86ffSlogin         let start_index = (name.len() / 13) as u8;
2264004e86ffSlogin         return LongNameEntryGenerator {
2265b5b571e0SLoGin             name,
2266b5b571e0SLoGin             checksum,
2267004e86ffSlogin             idx: start_index,
2268004e86ffSlogin             last_index: start_index,
2269004e86ffSlogin         };
2270004e86ffSlogin     }
2271004e86ffSlogin 
2272004e86ffSlogin     /// @brief 返回要生成的长目录项的总数
2273004e86ffSlogin     pub fn num_entries(&self) -> u8 {
2274004e86ffSlogin         return self.last_index + 1;
2275004e86ffSlogin     }
2276004e86ffSlogin }
2277004e86ffSlogin 
2278004e86ffSlogin impl Iterator for LongNameEntryGenerator {
2279004e86ffSlogin     type Item = LongDirEntry;
2280004e86ffSlogin 
2281004e86ffSlogin     fn next(&mut self) -> Option<Self::Item> {
2282004e86ffSlogin         match self.idx {
2283004e86ffSlogin             0 => {
2284004e86ffSlogin                 return None;
2285004e86ffSlogin             }
2286004e86ffSlogin             // 最后一个长目录项
2287004e86ffSlogin             n if n == self.last_index => {
2288004e86ffSlogin                 // 最后一个长目录项的ord需要与0x40相或
2289004e86ffSlogin                 let ord: u8 = n | 0x40;
2290004e86ffSlogin                 let start_idx = ((n - 1) * 13) as usize;
2291004e86ffSlogin                 self.idx -= 1;
2292004e86ffSlogin                 return Some(LongDirEntry::new(
2293004e86ffSlogin                     ord,
2294004e86ffSlogin                     &self.name.as_slice()[start_idx..start_idx + 13],
2295004e86ffSlogin                     self.checksum,
2296004e86ffSlogin                 ));
2297004e86ffSlogin             }
2298004e86ffSlogin             n => {
2299004e86ffSlogin                 // 其它的长目录项
2300004e86ffSlogin                 let start_idx = ((n - 1) * 13) as usize;
2301004e86ffSlogin                 self.idx -= 1;
2302004e86ffSlogin                 return Some(LongDirEntry::new(
2303004e86ffSlogin                     n,
2304004e86ffSlogin                     &self.name.as_slice()[start_idx..start_idx + 13],
2305004e86ffSlogin                     self.checksum,
2306004e86ffSlogin                 ));
2307004e86ffSlogin             }
2308004e86ffSlogin         }
2309004e86ffSlogin     }
2310004e86ffSlogin }
2311004e86ffSlogin 
2312004e86ffSlogin #[derive(Debug)]
2313004e86ffSlogin pub enum FATDirEntryOrShortName {
2314004e86ffSlogin     DirEntry(FATDirEntry),
2315004e86ffSlogin     ShortName([u8; 11]),
2316004e86ffSlogin }
2317004e86ffSlogin 
2318004e86ffSlogin /// @brief 对FAT目录项的迭代器(基于簇和簇内偏移量)
2319004e86ffSlogin #[derive(Debug)]
2320004e86ffSlogin struct FATDirEntryOffsetIter {
2321004e86ffSlogin     /// 当前迭代的偏移量(下一次迭代要返回的值)
2322004e86ffSlogin     current_offset: (Cluster, u64),
2323004e86ffSlogin     /// 截止迭代的位置(end_offset所在的位置也会被迭代器返回)
2324004e86ffSlogin     end_offset: Option<(Cluster, u64)>,
2325004e86ffSlogin     /// 属于的文件系统
2326004e86ffSlogin     fs: Arc<FATFileSystem>,
2327004e86ffSlogin     /// 当前已经迭代了多少次
2328004e86ffSlogin     index: u64,
2329004e86ffSlogin     /// 总共要迭代多少次
2330004e86ffSlogin     len: u64,
2331004e86ffSlogin     /// 如果end_offset不为None,该字段表示“是否已经到达了迭代终点”
2332004e86ffSlogin     fin: bool,
2333004e86ffSlogin }
2334004e86ffSlogin 
2335004e86ffSlogin impl FATDirEntryOffsetIter {
2336004e86ffSlogin     /// @brief 初始化FAT目录项的迭代器(基于簇和簇内偏移量)
2337004e86ffSlogin     ///
2338004e86ffSlogin     /// @param fs 属于的文件系统
2339004e86ffSlogin     /// @param start 起始偏移量
2340004e86ffSlogin     /// @param len 要迭代的次数
2341004e86ffSlogin     /// @param end_offset 截止迭代的位置(end_offset所在的位置也会被迭代器返回)
2342004e86ffSlogin     ///
2343004e86ffSlogin     /// @return 构建好的迭代器对象
2344004e86ffSlogin     pub fn new(
2345004e86ffSlogin         fs: Arc<FATFileSystem>,
2346004e86ffSlogin         start: (Cluster, u64),
2347004e86ffSlogin         len: u64,
2348004e86ffSlogin         end_offset: Option<(Cluster, u64)>,
2349004e86ffSlogin     ) -> Self {
2350004e86ffSlogin         return FATDirEntryOffsetIter {
2351004e86ffSlogin             current_offset: start,
2352004e86ffSlogin             end_offset,
2353004e86ffSlogin             fs,
2354004e86ffSlogin             index: 0,
2355004e86ffSlogin             len,
2356004e86ffSlogin             fin: false,
2357004e86ffSlogin         };
2358004e86ffSlogin     }
2359004e86ffSlogin }
2360004e86ffSlogin 
2361004e86ffSlogin impl Iterator for FATDirEntryOffsetIter {
2362004e86ffSlogin     type Item = (Cluster, u64);
2363004e86ffSlogin 
2364004e86ffSlogin     fn next(&mut self) -> Option<Self::Item> {
2365004e86ffSlogin         if self.index == self.len || self.fin {
2366004e86ffSlogin             return None;
2367004e86ffSlogin         }
2368004e86ffSlogin 
2369004e86ffSlogin         let r: (Cluster, u64) = self.current_offset;
2370004e86ffSlogin         // 计算新的字节偏移量
2371004e86ffSlogin         let mut new_offset = r.1 + FATRawDirEntry::DIR_ENTRY_LEN;
2372004e86ffSlogin         let mut new_cluster: Cluster = r.0;
2373004e86ffSlogin         // 越过了当前簇,则获取下一个簇
2374004e86ffSlogin         if new_offset >= self.fs.bytes_per_cluster() {
2375004e86ffSlogin             new_offset %= self.fs.bytes_per_cluster();
2376004e86ffSlogin 
2377004e86ffSlogin             match self.fs.get_fat_entry(new_cluster) {
2378004e86ffSlogin                 Ok(FATEntry::Next(c)) => {
2379004e86ffSlogin                     new_cluster = c;
2380004e86ffSlogin                 }
2381004e86ffSlogin                 // 没有下一个簇了
2382004e86ffSlogin                 _ => {
2383004e86ffSlogin                     self.fin = true;
2384004e86ffSlogin                 }
2385004e86ffSlogin             }
2386004e86ffSlogin         }
2387004e86ffSlogin 
2388004e86ffSlogin         if let Some(off) = self.end_offset {
2389004e86ffSlogin             // 判断当前簇是否是要求停止搜索的最后一个位置
2390004e86ffSlogin             self.fin = off == self.current_offset;
2391004e86ffSlogin         }
2392004e86ffSlogin         // 更新当前迭代的偏移量
2393004e86ffSlogin         self.current_offset = (new_cluster, new_offset);
2394004e86ffSlogin         self.index += 1;
2395004e86ffSlogin 
2396004e86ffSlogin         return Some(r);
2397004e86ffSlogin     }
2398004e86ffSlogin }
2399004e86ffSlogin 
2400004e86ffSlogin /// @brief 根据磁盘内字节偏移量,读取磁盘,并生成一个FATRawDirEntry对象
2401004e86ffSlogin pub fn get_raw_dir_entry(
2402004e86ffSlogin     fs: &Arc<FATFileSystem>,
2403004e86ffSlogin     in_disk_bytes_offset: u64,
2404676b8ef6SMork ) -> Result<FATRawDirEntry, SystemError> {
2405004e86ffSlogin     // 块内偏移量
2406004e86ffSlogin     let blk_offset: u64 = fs.get_in_block_offset(in_disk_bytes_offset);
2407004e86ffSlogin     let lba = fs.get_lba_from_offset(
2408004e86ffSlogin         fs.bytes_to_sector(fs.get_in_partition_bytes_offset(in_disk_bytes_offset)),
2409004e86ffSlogin     );
2410004e86ffSlogin 
2411004e86ffSlogin     // let step1 = fs.get_in_partition_bytes_offset(in_disk_bytes_offset);
2412004e86ffSlogin     // let step2 = fs.bytes_to_sector(step1);
2413004e86ffSlogin     // let lba = fs.get_lba_from_offset(step2);
2414*2eab6dd7S曾俊     // debug!("step1={step1}, step2={step2}, lba={lba}");
2415b5b571e0SLoGin     let mut v: Vec<u8> = vec![0; LBA_SIZE];
2416004e86ffSlogin 
2417004e86ffSlogin     fs.partition.disk().read_at(lba, 1, &mut v)?;
2418004e86ffSlogin 
2419004e86ffSlogin     let mut cursor: VecCursor = VecCursor::new(v);
2420004e86ffSlogin     // 切换游标到对应位置
2421004e86ffSlogin     cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
2422004e86ffSlogin 
2423004e86ffSlogin     let dir_0 = cursor.read_u8()?;
2424004e86ffSlogin 
2425004e86ffSlogin     match dir_0 {
2426004e86ffSlogin         0x00 => {
2427004e86ffSlogin             return Ok(FATRawDirEntry::FreeRest);
2428004e86ffSlogin         }
2429004e86ffSlogin         0xe5 => {
2430004e86ffSlogin             return Ok(FATRawDirEntry::Free);
2431004e86ffSlogin         }
2432004e86ffSlogin         _ => {
2433004e86ffSlogin             cursor.seek(SeekFrom::SeekCurrent(10))?;
2434004e86ffSlogin             let file_attr: FileAttributes = FileAttributes::new(cursor.read_u8()?);
2435004e86ffSlogin 
2436004e86ffSlogin             // 指针回到目录项的开始处
2437004e86ffSlogin             cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
2438004e86ffSlogin 
2439004e86ffSlogin             if file_attr.contains(FileAttributes::LONG_NAME) {
2440004e86ffSlogin                 // 当前目录项是一个长目录项
2441b5b571e0SLoGin                 let mut long_dentry = LongDirEntry {
2442b5b571e0SLoGin                     ord: cursor.read_u8()?,
2443b5b571e0SLoGin                     ..Default::default()
2444b5b571e0SLoGin                 };
2445004e86ffSlogin                 cursor.read_u16_into(&mut long_dentry.name1)?;
2446004e86ffSlogin                 long_dentry.file_attrs = FileAttributes::new(cursor.read_u8()?);
2447004e86ffSlogin                 long_dentry.dirent_type = cursor.read_u8()?;
2448004e86ffSlogin                 long_dentry.checksum = cursor.read_u8()?;
2449004e86ffSlogin 
2450004e86ffSlogin                 cursor.read_u16_into(&mut long_dentry.name2)?;
2451004e86ffSlogin                 long_dentry.first_clus_low = cursor.read_u16()?;
2452004e86ffSlogin                 cursor.read_u16_into(&mut long_dentry.name3)?;
2453004e86ffSlogin 
2454004e86ffSlogin                 return Ok(FATRawDirEntry::Long(long_dentry));
2455004e86ffSlogin             } else {
2456004e86ffSlogin                 // 当前目录项是一个短目录项
2457004e86ffSlogin                 let mut short_dentry = ShortDirEntry::default();
2458004e86ffSlogin                 cursor.read_exact(&mut short_dentry.name)?;
2459004e86ffSlogin 
2460004e86ffSlogin                 short_dentry.attributes = FileAttributes::new(cursor.read_u8()?);
2461004e86ffSlogin 
2462004e86ffSlogin                 short_dentry.nt_res = cursor.read_u8()?;
2463004e86ffSlogin                 short_dentry.crt_time_tenth = cursor.read_u8()?;
2464004e86ffSlogin                 short_dentry.crt_time = cursor.read_u16()?;
2465004e86ffSlogin                 short_dentry.crt_date = cursor.read_u16()?;
2466004e86ffSlogin                 short_dentry.lst_acc_date = cursor.read_u16()?;
2467004e86ffSlogin                 short_dentry.fst_clus_hi = cursor.read_u16()?;
2468004e86ffSlogin                 short_dentry.wrt_time = cursor.read_u16()?;
2469004e86ffSlogin                 short_dentry.wrt_date = cursor.read_u16()?;
2470004e86ffSlogin                 short_dentry.fst_clus_lo = cursor.read_u16()?;
2471004e86ffSlogin                 short_dentry.file_size = cursor.read_u32()?;
2472004e86ffSlogin 
2473004e86ffSlogin                 return Ok(FATRawDirEntry::Short(short_dentry));
2474004e86ffSlogin             }
2475004e86ffSlogin         }
2476004e86ffSlogin     }
2477004e86ffSlogin }
2478