entry.rs 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428
  1. #![allow(dead_code)]
  2. use core::{cmp::min, intrinsics::unlikely};
  3. use crate::{
  4. driver::base::block::{block_device::LBA_SIZE, SeekFrom},
  5. kwarn,
  6. libs::vec_cursor::VecCursor,
  7. syscall::SystemError,
  8. };
  9. use alloc::{
  10. string::{String, ToString},
  11. sync::Arc,
  12. vec::Vec,
  13. };
  14. use super::{
  15. fs::{Cluster, FATFileSystem, MAX_FILE_SIZE},
  16. utils::decode_u8_ascii,
  17. };
  18. #[derive(Debug, Clone, Copy, Default)]
  19. pub struct FileAttributes {
  20. value: u8,
  21. }
  22. /// FAT表中,关于每个簇的信息
  23. #[derive(Debug, Eq, PartialEq)]
  24. pub enum FATEntry {
  25. /// 当前簇未使用
  26. Unused,
  27. /// 当前簇是坏簇
  28. Bad,
  29. /// 当前簇是整个FAT簇链的最后一个簇
  30. EndOfChain,
  31. /// 在整个链中,当前簇的下一个簇的值
  32. Next(Cluster),
  33. }
  34. /// FAT目录项的枚举类型
  35. #[derive(Debug, Clone)]
  36. pub enum FATDirEntry {
  37. File(FATFile),
  38. VolId(FATFile),
  39. Dir(FATDir),
  40. UnInit,
  41. }
  42. /// FAT文件系统中的文件
  43. #[derive(Debug, Default, Clone)]
  44. pub struct FATFile {
  45. /// 文件的第一个簇
  46. pub first_cluster: Cluster,
  47. /// 文件名
  48. pub file_name: String,
  49. /// 文件对应的短目录项
  50. pub short_dir_entry: ShortDirEntry,
  51. /// 文件目录项的起始、终止簇。格式:(簇,簇内偏移量)
  52. pub loc: ((Cluster, u64), (Cluster, u64)),
  53. }
  54. impl FATFile {
  55. /// @brief 获取文件大小
  56. #[inline]
  57. pub fn size(&self) -> u64 {
  58. return self.short_dir_entry.file_size as u64;
  59. }
  60. /// @brief 设置当前文件大小(仅仅更改short_dir_entry内的值)
  61. #[inline]
  62. pub fn set_size(&mut self, size: u32) {
  63. self.short_dir_entry.file_size = size;
  64. }
  65. /// @brief 从文件读取数据。读取的字节数与buf长度相等
  66. ///
  67. /// @param buf 输出缓冲区
  68. /// @param offset 起始位置在文件中的偏移量
  69. ///
  70. /// @return Ok(usize) 成功读取到的字节数
  71. /// @return Err(SystemError) 读取时出现错误,返回错误码
  72. pub fn read(
  73. &self,
  74. fs: &Arc<FATFileSystem>,
  75. buf: &mut [u8],
  76. offset: u64,
  77. ) -> Result<usize, SystemError> {
  78. if offset >= self.size() {
  79. return Ok(0);
  80. }
  81. // 文件内的簇偏移量
  82. let start_cluster_number: u64 = offset / fs.bytes_per_cluster();
  83. // 计算对应在分区内的簇号
  84. let mut current_cluster = if let Some(c) =
  85. fs.get_cluster_by_relative(self.first_cluster, start_cluster_number as usize)
  86. {
  87. c
  88. } else {
  89. return Ok(0);
  90. };
  91. let bytes_remain: u64 = self.size() - offset;
  92. // 计算簇内偏移量
  93. let mut in_cluster_offset: u64 = offset % fs.bytes_per_cluster();
  94. let to_read_size: usize = min(buf.len(), bytes_remain as usize);
  95. let mut start = 0;
  96. let mut read_ok = 0;
  97. loop {
  98. // 当前簇已经读取完,尝试读取下一个簇
  99. if in_cluster_offset >= fs.bytes_per_cluster() {
  100. if let Some(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster).ok() {
  101. current_cluster = c;
  102. in_cluster_offset %= fs.bytes_per_cluster();
  103. } else {
  104. break;
  105. }
  106. }
  107. // 计算下一次读取,能够读多少字节
  108. let end_len: usize = min(
  109. to_read_size - read_ok,
  110. min(
  111. (fs.bytes_per_cluster() - in_cluster_offset) as usize,
  112. buf.len() - read_ok,
  113. ),
  114. );
  115. // 从磁盘上读取数据
  116. let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_offset;
  117. let r = fs.partition.disk().read_at_bytes(
  118. offset as usize,
  119. end_len,
  120. &mut buf[start..start + end_len],
  121. )?;
  122. // 更新偏移量计数信息
  123. read_ok += r;
  124. start += r;
  125. in_cluster_offset += r as u64;
  126. if read_ok == to_read_size {
  127. break;
  128. }
  129. }
  130. // todo: 更新时间信息
  131. return Ok(read_ok);
  132. }
  133. /// @brief 向文件写入数据。写入的字节数与buf长度相等
  134. ///
  135. /// @param buf 输入缓冲区
  136. /// @param offset 起始位置在文件中的偏移量
  137. ///
  138. /// @return Ok(usize) 成功写入的字节数
  139. /// @return Err(SystemError) 写入时出现错误,返回错误码
  140. pub fn write(
  141. &mut self,
  142. fs: &Arc<FATFileSystem>,
  143. buf: &[u8],
  144. offset: u64,
  145. ) -> Result<usize, SystemError> {
  146. self.ensure_len(fs, offset, buf.len() as u64)?;
  147. // 要写入的第一个簇的簇号
  148. let start_cluster_num = offset / fs.bytes_per_cluster();
  149. // 获取要写入的第一个簇
  150. let mut current_cluster: Cluster = if let Some(c) =
  151. fs.get_cluster_by_relative(self.first_cluster, start_cluster_num as usize)
  152. {
  153. c
  154. } else {
  155. return Ok(0);
  156. };
  157. let mut in_cluster_bytes_offset: u64 = offset % fs.bytes_per_cluster();
  158. let mut start: usize = 0;
  159. let mut write_ok: usize = 0;
  160. // 循环写入数据
  161. loop {
  162. if in_cluster_bytes_offset >= fs.bytes_per_cluster() {
  163. if let Some(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster).ok() {
  164. current_cluster = c;
  165. in_cluster_bytes_offset = in_cluster_bytes_offset % fs.bytes_per_cluster();
  166. } else {
  167. break;
  168. }
  169. }
  170. let end_len = min(
  171. (fs.bytes_per_cluster() - in_cluster_bytes_offset) as usize,
  172. buf.len() - write_ok,
  173. );
  174. // 计算本次写入位置在磁盘上的偏移量
  175. let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_bytes_offset;
  176. // 写入磁盘
  177. let w: usize = fs.partition.disk().write_at_bytes(
  178. offset as usize,
  179. end_len,
  180. &buf[start..start + end_len],
  181. )?;
  182. // 更新偏移量数据
  183. write_ok += w;
  184. start += w;
  185. in_cluster_bytes_offset += w as u64;
  186. if write_ok == buf.len() {
  187. break;
  188. }
  189. }
  190. // todo: 更新时间信息
  191. return Ok(write_ok);
  192. }
  193. /// @brief 确保文件从指定偏移量开始,仍有长度为len的空间。
  194. /// 如果文件大小不够,就尝试分配更多的空间给这个文件。
  195. ///
  196. /// @param fs 当前文件所属的文件系统
  197. /// @param offset 起始位置在文件内的字节偏移量
  198. /// @param len 期待的空闲空间长度
  199. ///
  200. /// @return Ok(()) 经过操作后,offset后面具有长度至少为len的空闲空间
  201. /// @return Err(SystemError) 处理过程中出现了异常。
  202. fn ensure_len(
  203. &mut self,
  204. fs: &Arc<FATFileSystem>,
  205. offset: u64,
  206. len: u64,
  207. ) -> Result<(), SystemError> {
  208. // 文件内本身就还有空余的空间
  209. if offset + len <= self.size() {
  210. return Ok(());
  211. }
  212. // 计算文件的最后一个簇中有多少空闲空间
  213. let in_cluster_offset = self.size() % fs.bytes_per_cluster();
  214. let mut bytes_remain_in_cluster = if in_cluster_offset == 0 {
  215. 0
  216. } else {
  217. fs.bytes_per_cluster() - in_cluster_offset
  218. };
  219. // 计算还需要申请多少空间
  220. let extra_bytes = min((offset + len) - self.size(), MAX_FILE_SIZE - self.size());
  221. // 如果文件大小为0,证明它还没有分配簇,因此分配一个簇给它
  222. if self.size() == 0 {
  223. // first_cluster应当为0,否则将产生空间泄露的错误
  224. assert_eq!(self.first_cluster, Cluster::default());
  225. self.first_cluster = fs.allocate_cluster(None)?;
  226. self.short_dir_entry.set_first_cluster(self.first_cluster);
  227. bytes_remain_in_cluster = fs.bytes_per_cluster();
  228. }
  229. // 如果还需要更多的簇
  230. if bytes_remain_in_cluster < extra_bytes {
  231. let clusters_to_allocate =
  232. (extra_bytes - bytes_remain_in_cluster + fs.bytes_per_cluster() - 1)
  233. / fs.bytes_per_cluster();
  234. let last_cluster = if let Some(c) = fs.get_last_cluster(self.first_cluster) {
  235. c
  236. } else {
  237. kwarn!("FAT: last cluster not found, File = {self:?}");
  238. return Err(SystemError::EINVAL);
  239. };
  240. // 申请簇
  241. let mut current_cluster: Cluster = last_cluster;
  242. for _ in 0..clusters_to_allocate {
  243. current_cluster = fs.allocate_cluster(Some(current_cluster))?;
  244. }
  245. }
  246. // 如果文件被扩展,则清空刚刚被扩展的部分的数据
  247. if offset > self.size() {
  248. // 文件内的簇偏移
  249. let start_cluster: u64 = self.size() / fs.bytes_per_cluster();
  250. let start_cluster: Cluster = fs
  251. .get_cluster_by_relative(self.first_cluster, start_cluster as usize)
  252. .unwrap();
  253. // 计算当前文件末尾在磁盘上的字节偏移量
  254. let start_offset: u64 =
  255. fs.cluster_bytes_offset(start_cluster) + self.size() % fs.bytes_per_cluster();
  256. // 扩展之前,最后一个簇内还剩下多少字节的空间
  257. let bytes_remain: u64 = fs.bytes_per_cluster() - (self.size() % fs.bytes_per_cluster());
  258. // 计算在扩展之后的最后一个簇内,文件的终止字节
  259. let cluster_offset_start = offset / fs.bytes_per_cluster();
  260. // 扩展后,文件的最后
  261. let end_cluster: Cluster = fs
  262. .get_cluster_by_relative(self.first_cluster, cluster_offset_start as usize)
  263. .unwrap();
  264. if start_cluster != end_cluster {
  265. self.zero_range(fs, start_offset, start_offset + bytes_remain)?;
  266. } else {
  267. self.zero_range(fs, start_offset, start_offset + offset - self.size())?;
  268. }
  269. }
  270. // 计算文件的新大小
  271. let new_size = self.size() + extra_bytes;
  272. self.set_size(new_size as u32);
  273. // 计算短目录项所在的位置,更新短目录项
  274. let short_entry_offset = fs.cluster_bytes_offset(self.loc.1 .0) + self.loc.1 .1;
  275. // todo: 更新时间信息
  276. // 把短目录项写入磁盘
  277. self.short_dir_entry.flush(fs, short_entry_offset)?;
  278. return Ok(());
  279. }
  280. /// @brief 把磁盘上[range_start, range_end)范围的数据清零
  281. ///
  282. /// @param range_start 磁盘上起始位置(单位:字节)
  283. /// @param range_end 磁盘上终止位置(单位:字节)
  284. fn zero_range(
  285. &self,
  286. fs: &Arc<FATFileSystem>,
  287. range_start: u64,
  288. range_end: u64,
  289. ) -> Result<(), SystemError> {
  290. if range_end <= range_start {
  291. return Ok(());
  292. }
  293. let zeroes: Vec<u8> = vec![0u8; (range_end - range_start) as usize];
  294. fs.partition
  295. .disk()
  296. .write_at(range_start as usize, zeroes.len(), zeroes.as_slice())?;
  297. return Ok(());
  298. }
  299. /// @brief 截断文件的内容,并设置新的文件大小。如果new_size大于当前文件大小,则不做操作。
  300. ///
  301. /// @param new_size 新的文件大小,如果它大于当前文件大小,则不做操作。
  302. ///
  303. /// @return Ok(()) 操作成功
  304. /// @return Err(SystemError) 在操作时出现错误
  305. pub fn truncate(&mut self, fs: &Arc<FATFileSystem>, new_size: u64) -> Result<(), SystemError> {
  306. if new_size >= self.size() {
  307. return Ok(());
  308. }
  309. let new_last_cluster = (new_size + fs.bytes_per_cluster() - 1) / fs.bytes_per_cluster();
  310. if let Some(begin_delete) =
  311. fs.get_cluster_by_relative(self.first_cluster, new_last_cluster as usize)
  312. {
  313. fs.deallocate_cluster_chain(begin_delete)?;
  314. };
  315. if new_size == 0 {
  316. assert!(new_last_cluster == 0);
  317. self.short_dir_entry.set_first_cluster(Cluster::new(0));
  318. self.first_cluster = Cluster::new(0);
  319. }
  320. self.set_size(new_size as u32);
  321. // 计算短目录项在磁盘内的字节偏移量
  322. let short_entry_offset = fs.cluster_bytes_offset((self.loc.1).0) + (self.loc.1).1;
  323. self.short_dir_entry.flush(fs, short_entry_offset)?;
  324. return Ok(());
  325. }
  326. }
  327. /// FAT文件系统中的文件夹
  328. #[derive(Debug, Default, Clone)]
  329. pub struct FATDir {
  330. /// 目录的第一个簇
  331. pub first_cluster: Cluster,
  332. /// 该字段仅对FAT12、FAT16生效
  333. pub root_offset: Option<u64>,
  334. /// 文件夹名称
  335. pub dir_name: String,
  336. pub short_dir_entry: Option<ShortDirEntry>,
  337. /// 文件的起始、终止簇。格式:(簇,簇内偏移量)
  338. pub loc: Option<((Cluster, u64), (Cluster, u64))>,
  339. }
  340. impl FATDir {
  341. /// @brief 获得用于遍历当前目录的迭代器
  342. ///
  343. /// @param fs 当前目录所在的文件系统
  344. pub fn to_iter(&self, fs: Arc<FATFileSystem>) -> FATDirIter {
  345. return FATDirIter {
  346. current_cluster: self.first_cluster,
  347. offset: self.root_offset.unwrap_or(0),
  348. is_root: self.is_root(),
  349. fs: fs,
  350. };
  351. }
  352. /// @brief 判断当前目录是否为根目录(仅对FAT12和FAT16生效)
  353. #[inline]
  354. pub fn is_root(&self) -> bool {
  355. return self.root_offset.is_some();
  356. }
  357. /// @brief 获取当前目录所占用的大小
  358. pub fn size(&self, fs: &Arc<FATFileSystem>) -> u64 {
  359. return fs.num_clusters_chain(self.first_cluster) * fs.bytes_per_cluster();
  360. }
  361. /// @brief 在目录项中,寻找num_free个连续空闲目录项
  362. ///
  363. /// @param num_free 需要的空闲目录项数目.
  364. /// @param fs 当前文件夹属于的文件系统
  365. ///
  366. /// @return Ok(Option<(第一个符合条件的空闲目录项所在的簇,簇内偏移量))
  367. /// @return Err(错误码)
  368. pub fn find_free_entries(
  369. &self,
  370. num_free: u64,
  371. fs: Arc<FATFileSystem>,
  372. ) -> Result<Option<(Cluster, u64)>, SystemError> {
  373. let mut free = 0;
  374. let mut current_cluster: Cluster = self.first_cluster;
  375. let mut offset = self.root_offset.unwrap_or(0);
  376. // 第一个符合条件的空闲目录项
  377. let mut first_free: Option<(Cluster, u64)> = None;
  378. loop {
  379. // 如果当前簇没有空间了,并且当前不是FAT12和FAT16的根目录,那么就读取下一个簇。
  380. if offset >= fs.bytes_per_cluster() && !self.is_root() {
  381. // 成功读取下一个簇
  382. if let Some(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster).ok() {
  383. current_cluster = c;
  384. // 计算簇内偏移量
  385. offset = offset % fs.bytes_per_cluster();
  386. } else {
  387. // 读取失败,当前已经是最后一个簇,退出循环
  388. break;
  389. }
  390. }
  391. // 如果当前目录是FAT12和FAT16的根目录,且已经读取完,就直接返回。
  392. if self.is_root() && offset > fs.root_dir_end_bytes_offset().unwrap() {
  393. return Ok(None);
  394. }
  395. let e_offset = fs.cluster_bytes_offset(current_cluster) + offset;
  396. let entry: FATRawDirEntry = get_raw_dir_entry(&fs, e_offset)?;
  397. match entry {
  398. FATRawDirEntry::Free | FATRawDirEntry::FreeRest => {
  399. if free == 0 {
  400. first_free = Some((current_cluster, offset));
  401. }
  402. free += 1;
  403. if free == num_free {
  404. // kdebug!("first_free = {first_free:?}, current_free = ({current_cluster:?}, {offset})");
  405. return Ok(first_free);
  406. }
  407. }
  408. // 遇到一个不空闲的目录项,那么重新开始计算空闲目录项
  409. _ => {
  410. free = 0;
  411. }
  412. }
  413. offset += FATRawDirEntry::DIR_ENTRY_LEN;
  414. }
  415. // 剩余的需要获取的目录项
  416. let remain_entries = num_free - free;
  417. // 计算需要申请多少个簇
  418. let clusters_required =
  419. (remain_entries * FATRawDirEntry::DIR_ENTRY_LEN + fs.bytes_per_cluster() - 1)
  420. / fs.bytes_per_cluster();
  421. let mut first_cluster = Cluster::default();
  422. let mut prev_cluster = current_cluster;
  423. // kdebug!(
  424. // "clusters_required={clusters_required}, prev_cluster={prev_cluster:?}, free ={free}"
  425. // );
  426. // 申请簇
  427. for i in 0..clusters_required {
  428. let c: Cluster = fs.allocate_cluster(Some(prev_cluster))?;
  429. if i == 0 {
  430. first_cluster = c;
  431. }
  432. prev_cluster = c;
  433. }
  434. if free > 0 {
  435. // 空闲目录项跨越了簇,返回第一个空闲目录项
  436. return Ok(first_free);
  437. } else {
  438. // 空闲目录项是在全新的簇开始的
  439. return Ok(Some((first_cluster, 0)));
  440. }
  441. }
  442. /// @brief 在当前目录中寻找目录项
  443. ///
  444. /// @param name 目录项的名字
  445. /// @param expect_dir 该值为Some时有效。如果期待目标目录项是文件夹,那么值为Some(true), 否则为Some(false).
  446. /// @param short_name_gen 短目录项名称生成器
  447. /// @param fs 当前目录所属的文件系统
  448. ///
  449. /// @return Ok(FATDirEntry) 找到期待的目录项
  450. /// @return Err(SystemError) 错误码
  451. pub fn find_entry(
  452. &self,
  453. name: &str,
  454. expect_dir: Option<bool>,
  455. mut short_name_gen: Option<&mut ShortNameGenerator>,
  456. fs: Arc<FATFileSystem>,
  457. ) -> Result<FATDirEntry, SystemError> {
  458. LongDirEntry::validate_long_name(name)?;
  459. // 迭代当前目录下的文件/文件夹
  460. for e in self.to_iter(fs) {
  461. if e.eq_name(name) {
  462. if expect_dir.is_some() && Some(e.is_dir()) != expect_dir {
  463. if e.is_dir() {
  464. // 期望得到文件,但是是文件夹
  465. return Err(SystemError::EISDIR);
  466. } else {
  467. // 期望得到文件夹,但是是文件
  468. return Err(SystemError::ENOTDIR);
  469. }
  470. }
  471. // 找到期望的目录项
  472. return Ok(e);
  473. }
  474. if let Some(ref mut sng) = short_name_gen {
  475. sng.add_name(&e.short_name_raw())
  476. }
  477. }
  478. // 找不到文件/文件夹
  479. return Err(SystemError::ENOENT);
  480. }
  481. /// @brief 在当前目录下打开文件,获取FATFile结构体
  482. pub fn open_file(&self, name: &str, fs: Arc<FATFileSystem>) -> Result<FATFile, SystemError> {
  483. let f: FATFile = self.find_entry(name, Some(false), None, fs)?.to_file()?;
  484. return Ok(f);
  485. }
  486. /// @brief 在当前目录下打开文件夹,获取FATDir结构体
  487. pub fn open_dir(&self, name: &str, fs: Arc<FATFileSystem>) -> Result<FATDir, SystemError> {
  488. let d: FATDir = self.find_entry(name, Some(true), None, fs)?.to_dir()?;
  489. return Ok(d);
  490. }
  491. /// @brief 在当前文件夹下创建文件。
  492. ///
  493. /// @param name 文件名
  494. /// @param fs 当前文件夹所属的文件系统
  495. pub fn create_file(&self, name: &str, fs: &Arc<FATFileSystem>) -> Result<FATFile, SystemError> {
  496. let r: Result<FATDirEntryOrShortName, SystemError> =
  497. self.check_existence(name, Some(false), fs.clone());
  498. // 检查错误码,如果能够表明目录项已经存在,则返回-EEXIST
  499. if r.is_err() {
  500. let err_val = r.unwrap_err();
  501. if err_val == (SystemError::EISDIR) || err_val == (SystemError::ENOTDIR) {
  502. return Err(SystemError::EEXIST);
  503. } else {
  504. return Err(err_val);
  505. }
  506. }
  507. match r.unwrap() {
  508. FATDirEntryOrShortName::ShortName(short_name) => {
  509. // 确认名称是一个可行的长文件名
  510. LongDirEntry::validate_long_name(name)?;
  511. // 创建目录项
  512. let x: Result<FATFile, SystemError> = self
  513. .create_dir_entries(
  514. name.trim(),
  515. &short_name,
  516. None,
  517. FileAttributes {
  518. value: FileAttributes::ARCHIVE,
  519. },
  520. fs.clone(),
  521. )
  522. .map(|e| e.to_file())?;
  523. return x;
  524. }
  525. FATDirEntryOrShortName::DirEntry(_) => {
  526. // 已经存在这样的一个目录项了
  527. return Err(SystemError::EEXIST);
  528. }
  529. }
  530. }
  531. pub fn create_dir(&self, name: &str, fs: &Arc<FATFileSystem>) -> Result<FATDir, SystemError> {
  532. let r: Result<FATDirEntryOrShortName, SystemError> =
  533. self.check_existence(name, Some(true), fs.clone());
  534. // kdebug!("check existence ok");
  535. // 检查错误码,如果能够表明目录项已经存在,则返回-EEXIST
  536. if r.is_err() {
  537. let err_val = r.unwrap_err();
  538. if err_val == (SystemError::EISDIR) || err_val == (SystemError::ENOTDIR) {
  539. return Err(SystemError::EEXIST);
  540. } else {
  541. return Err(err_val);
  542. }
  543. }
  544. match r.unwrap() {
  545. // 文件夹不存在,创建文件夹
  546. FATDirEntryOrShortName::ShortName(short_name) => {
  547. LongDirEntry::validate_long_name(name)?;
  548. // 目标目录项
  549. let mut short_entry = ShortDirEntry::default();
  550. let first_cluster: Cluster = fs.allocate_cluster(None)?;
  551. short_entry.set_first_cluster(first_cluster);
  552. // === 接下来在子目录中创建'.'目录项和'..'目录项
  553. let mut offset = 0;
  554. // '.'目录项
  555. let mut dot_entry = ShortDirEntry::default();
  556. dot_entry.name = ShortNameGenerator::new(".").generate().unwrap();
  557. dot_entry.attributes.value = FileAttributes::DIRECTORY;
  558. dot_entry.set_first_cluster(first_cluster);
  559. // todo: 设置创建、访问时间
  560. dot_entry.flush(&fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
  561. drop(dot_entry);
  562. // 偏移量加上一个目录项的长度
  563. offset += FATRawDirEntry::DIR_ENTRY_LEN;
  564. // '..'目录项
  565. let mut dot_dot_entry = ShortDirEntry::default();
  566. dot_dot_entry.name = ShortNameGenerator::new("..").generate().unwrap();
  567. dot_dot_entry.attributes.value = FileAttributes::DIRECTORY;
  568. dot_dot_entry.set_first_cluster(self.first_cluster);
  569. // todo: 设置创建、访问时间
  570. dot_dot_entry.flush(&fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
  571. // kdebug!("to create dentries");
  572. // 在当前目录下创建目标目录项
  573. let res = self
  574. .create_dir_entries(
  575. name.trim(),
  576. &short_name,
  577. Some(short_entry),
  578. FileAttributes {
  579. value: FileAttributes::DIRECTORY,
  580. },
  581. fs.clone(),
  582. )
  583. .map(|e| e.to_dir())?;
  584. // kdebug!("create dentries ok");
  585. return res;
  586. }
  587. FATDirEntryOrShortName::DirEntry(_) => {
  588. // 已经存在这样的一个目录项了
  589. return Err(SystemError::EEXIST);
  590. }
  591. }
  592. }
  593. /// @brief 检查目录项在当前文件夹下是否存在
  594. ///
  595. /// @param name 目录项的名字
  596. /// @param expect_dir 该值为Some时有效。如果期待目标目录项是文件夹,那么值为Some(true), 否则为Some(false).
  597. /// @param fs 当前目录所属的文件系统
  598. ///
  599. /// @return Ok(FATDirEntryOrShortName::DirEntry) 找到期待的目录项
  600. /// @return Ok(FATDirEntryOrShortName::ShortName) 当前文件夹下不存在指定的目录项,因此返回一个可行的短文件名
  601. /// @return Err(SystemError) 错误码
  602. pub fn check_existence(
  603. &self,
  604. name: &str,
  605. expect_dir: Option<bool>,
  606. fs: Arc<FATFileSystem>,
  607. ) -> Result<FATDirEntryOrShortName, SystemError> {
  608. let mut sng = ShortNameGenerator::new(name);
  609. loop {
  610. let e: Result<FATDirEntry, SystemError> =
  611. self.find_entry(name, expect_dir, Some(&mut sng), fs.clone());
  612. match e {
  613. Ok(e) => {
  614. // 找到,返回目录项
  615. return Ok(FATDirEntryOrShortName::DirEntry(e));
  616. }
  617. Err(e) => {
  618. // 如果没找到,则不返回错误
  619. if e == SystemError::ENOENT {
  620. } else {
  621. // 其他错误,则返回
  622. return Err(e);
  623. }
  624. }
  625. }
  626. // 没找到文件,则生成短文件名
  627. if let Ok(name) = sng.generate() {
  628. return Ok(FATDirEntryOrShortName::ShortName(name));
  629. }
  630. sng.next_iteration();
  631. }
  632. }
  633. /// @brief 创建一系列的目录项
  634. ///
  635. /// @param long_name 长文件名
  636. /// @param short_name 短文件名
  637. /// @param short_dentry 可选的生成好的短目录项结构体
  638. /// @param attrs FAT目录项的属性
  639. /// @param fs 当前文件夹所属的文件系统
  640. ///
  641. /// @return Ok(FATDirEntry) FAT目录项的枚举类型(目录项链条的最后一个长目录项)
  642. fn create_dir_entries(
  643. &self,
  644. long_name: &str,
  645. short_name: &[u8; 11],
  646. short_dentry: Option<ShortDirEntry>,
  647. attrs: FileAttributes,
  648. fs: Arc<FATFileSystem>,
  649. ) -> Result<FATDirEntry, SystemError> {
  650. let mut short_dentry: ShortDirEntry = short_dentry.unwrap_or(ShortDirEntry::default());
  651. short_dentry.name = short_name.clone();
  652. short_dentry.attributes = attrs;
  653. // todo: 设置创建时间、修改时间
  654. let mut long_name_gen: LongNameEntryGenerator =
  655. LongNameEntryGenerator::new(long_name, short_dentry.checksum());
  656. let num_entries = long_name_gen.num_entries() as u64;
  657. // kdebug!("to find free entries");
  658. let free_entries: Option<(Cluster, u64)> =
  659. self.find_free_entries(num_entries, fs.clone())?;
  660. // 目录项开始位置
  661. let start_loc: (Cluster, u64) = match free_entries {
  662. Some(c) => c,
  663. None => return Err(SystemError::ENOSPC),
  664. };
  665. let offsets: Vec<(Cluster, u64)> =
  666. FATDirEntryOffsetIter::new(fs.clone(), start_loc, num_entries, None).collect();
  667. // 迭代长目录项
  668. for off in &offsets.as_slice()[..offsets.len() - 1] {
  669. // 获取生成的下一个长目录项
  670. let long_entry: LongDirEntry = long_name_gen.next().unwrap();
  671. // 获取这个长目录项在磁盘内的字节偏移量
  672. let bytes_offset = fs.cluster_bytes_offset(off.0) + off.1;
  673. long_entry.flush(fs.clone(), bytes_offset)?;
  674. }
  675. let start: (Cluster, u64) = offsets[0];
  676. let end: (Cluster, u64) = *offsets.last().unwrap();
  677. // 短目录项在磁盘上的字节偏移量
  678. let offset = fs.cluster_bytes_offset(end.0) + end.1;
  679. short_dentry.flush(&fs, offset)?;
  680. return Ok(short_dentry.to_dir_entry_with_long_name(long_name.to_string(), (start, end)));
  681. }
  682. /// @brief 判断当前目录是否为空
  683. ///
  684. /// @return true 当前目录为空
  685. /// @return false 当前目录不为空
  686. pub fn is_empty(&self, fs: Arc<FATFileSystem>) -> bool {
  687. for e in self.to_iter(fs) {
  688. let s = e.short_name();
  689. if s == "." || s == ".." {
  690. continue;
  691. } else {
  692. return false;
  693. }
  694. }
  695. return true;
  696. }
  697. /// @brief 从当前文件夹中删除文件或者文件夹。如果目标文件夹不为空,则不能删除,返回-ENOTEMPTY.
  698. ///
  699. /// @param fs 当前FATDir所属的文件系统
  700. /// @param name 目录项的名字
  701. /// @param remove_clusters 是否删除与指定的目录项相关联的数据簇
  702. ///
  703. /// @return Ok() 成功时无返回值
  704. /// @return Err(SystemError) 如果目标文件夹不为空,则不能删除,返回-ENOTEMPTY. 或者返回底层传上来的错误
  705. pub fn remove(
  706. &self,
  707. fs: Arc<FATFileSystem>,
  708. name: &str,
  709. remove_clusters: bool,
  710. ) -> Result<(), SystemError> {
  711. let e: FATDirEntry = self.find_entry(name, None, None, fs.clone())?;
  712. // 判断文件夹是否为空,如果空,则不删除,报错。
  713. if e.is_dir() && !(e.to_dir().unwrap().is_empty(fs.clone())) {
  714. return Err(SystemError::ENOTEMPTY);
  715. }
  716. if e.first_cluster().cluster_num >= 2 && remove_clusters {
  717. // 删除与指定的目录项相关联的数据簇
  718. fs.deallocate_cluster_chain(e.first_cluster())?;
  719. }
  720. if e.get_dir_range().is_some() {
  721. self.remove_dir_entries(fs, e.get_dir_range().unwrap())?;
  722. }
  723. return Ok(());
  724. }
  725. /// @brief 在当前目录中删除多个目录项
  726. ///
  727. /// @param fs 当前目录所属的文件系统
  728. /// @param cluster_range 要删除的目录项的范围(以簇+簇内偏移量的形式表示)
  729. fn remove_dir_entries(
  730. &self,
  731. fs: Arc<FATFileSystem>,
  732. cluster_range: ((Cluster, u64), (Cluster, u64)),
  733. ) -> Result<(), SystemError> {
  734. // 收集所有的要移除的目录项
  735. let offsets: Vec<(Cluster, u64)> =
  736. FATDirEntryOffsetIter::new(fs.clone(), cluster_range.0, 15, Some(cluster_range.1))
  737. .collect();
  738. // 逐个设置这些目录项为“空闲”状态
  739. for off in offsets {
  740. let disk_bytes_offset = fs.cluster_bytes_offset(off.0) + off.1;
  741. let mut short_entry = ShortDirEntry::default();
  742. short_entry.name[0] = 0xe5;
  743. short_entry.flush(&fs, disk_bytes_offset)?;
  744. }
  745. return Ok(());
  746. }
  747. /// @brief 根据名字在当前文件夹下寻找目录项
  748. ///
  749. /// @return Ok(FATDirEntry) 目标目录项
  750. /// @return Err(SystemError) 底层传上来的错误码
  751. pub fn get_dir_entry(
  752. &self,
  753. fs: Arc<FATFileSystem>,
  754. name: &str,
  755. ) -> Result<FATDirEntry, SystemError> {
  756. if name == "." || name == "/" {
  757. return Ok(FATDirEntry::Dir(self.clone()));
  758. }
  759. LongDirEntry::validate_long_name(name)?;
  760. return self.find_entry(name, None, None, fs);
  761. }
  762. /// @brief 在当前目录内,重命名一个目录项
  763. ///
  764. pub fn rename(
  765. &self,
  766. fs: Arc<FATFileSystem>,
  767. old_name: &str,
  768. new_name: &str,
  769. ) -> Result<FATDirEntry, SystemError> {
  770. // 判断源目录项是否存在
  771. let old_dentry: FATDirEntry = if let FATDirEntryOrShortName::DirEntry(dentry) =
  772. self.check_existence(old_name, None, fs.clone())?
  773. {
  774. dentry
  775. } else {
  776. // 如果目标目录项不存在,则返回错误
  777. return Err(SystemError::ENOENT);
  778. };
  779. let short_name = if let FATDirEntryOrShortName::ShortName(s) =
  780. self.check_existence(new_name, None, fs.clone())?
  781. {
  782. s
  783. } else {
  784. // 如果目标目录项存在,那么就返回错误
  785. return Err(SystemError::EEXIST);
  786. };
  787. let old_short_dentry: Option<ShortDirEntry> = old_dentry.short_dir_entry();
  788. if let Some(se) = old_short_dentry {
  789. // 删除原来的目录项
  790. self.remove(fs.clone(), old_dentry.name().as_str(), false)?;
  791. // 创建新的目录项
  792. let new_dentry: FATDirEntry = self.create_dir_entries(
  793. new_name,
  794. &short_name,
  795. Some(se),
  796. se.attributes,
  797. fs.clone(),
  798. )?;
  799. return Ok(new_dentry);
  800. } else {
  801. // 不允许对根目录项进行重命名
  802. return Err(SystemError::EPERM);
  803. }
  804. }
  805. }
  806. impl FileAttributes {
  807. pub const READ_ONLY: u8 = 1 << 0;
  808. pub const HIDDEN: u8 = 1 << 1;
  809. pub const SYSTEM: u8 = 1 << 2;
  810. pub const VOLUME_ID: u8 = 1 << 3;
  811. pub const DIRECTORY: u8 = 1 << 4;
  812. pub const ARCHIVE: u8 = 1 << 5;
  813. pub const LONG_NAME: u8 = FileAttributes::READ_ONLY
  814. | FileAttributes::HIDDEN
  815. | FileAttributes::SYSTEM
  816. | FileAttributes::VOLUME_ID;
  817. /// @brief 判断属性是否存在
  818. #[inline]
  819. pub fn contains(&self, attr: u8) -> bool {
  820. return (self.value & attr) != 0;
  821. }
  822. pub fn new(attr: u8) -> Self {
  823. return Self { value: attr };
  824. }
  825. }
  826. /// FAT32的短目录项
  827. #[derive(Debug, Clone, Copy, Default)]
  828. pub struct ShortDirEntry {
  829. /// short name
  830. name: [u8; 11],
  831. /// 目录项属性 (见 FileAttributes )
  832. attributes: FileAttributes,
  833. /// Windows NT系统的保留字段。用来表示短目录项文件名。
  834. /// EXT|BASE => 8(BASE).3(EXT)
  835. /// BASE:LowerCase(8),UpperCase(0)
  836. /// EXT:LowerCase(16),UpperCase(0)
  837. nt_res: u8,
  838. /// 文件创建时间的毫秒级时间戳
  839. crt_time_tenth: u8,
  840. /// 创建时间
  841. crt_time: u16,
  842. /// 创建日期
  843. crt_date: u16,
  844. /// 最后一次访问日期
  845. lst_acc_date: u16,
  846. /// High word of first cluster(0 for FAT12 and FAT16)
  847. fst_clus_hi: u16,
  848. /// 最后写入时间
  849. wrt_time: u16,
  850. /// 最后写入日期
  851. wrt_date: u16,
  852. /// Low word of first cluster
  853. fst_clus_lo: u16,
  854. /// 文件大小
  855. file_size: u32,
  856. }
  857. /// FAT32的长目录项
  858. #[derive(Debug, Clone, Copy, Default)]
  859. pub struct LongDirEntry {
  860. /// 长目录项的序号
  861. ord: u8,
  862. /// 长文件名的第1-5个字符,每个字符占2bytes
  863. name1: [u16; 5],
  864. /// 目录项属性必须为ATTR_LONG_NAME
  865. file_attrs: FileAttributes,
  866. /// Entry Type: 如果为0,则说明这是长目录项的子项
  867. /// 非零值是保留的。
  868. dirent_type: u8,
  869. /// 短文件名的校验和
  870. checksum: u8,
  871. /// 长文件名的第6-11个字符,每个字符占2bytes
  872. name2: [u16; 6],
  873. /// 必须为0
  874. first_clus_low: u16,
  875. /// 长文件名的12-13个字符,每个字符占2bytes
  876. name3: [u16; 2],
  877. }
  878. impl LongDirEntry {
  879. /// 长目录项的字符串长度(单位:word)
  880. pub const LONG_NAME_STR_LEN: usize = 13;
  881. /// @brief 初始化一个新的长目录项
  882. ///
  883. /// @param ord 顺序
  884. /// @param name_part 长目录项名称的数组(长度必须为13)
  885. /// @param check_sum 短目录项的校验和
  886. ///
  887. /// @return Self 初始化好的长目录项对象
  888. fn new(ord: u8, name_part: &[u16], check_sum: u8) -> Self {
  889. let mut result = LongDirEntry::default();
  890. result.ord = ord;
  891. result
  892. .insert_name(name_part)
  893. .expect("Name part's len should be equal to 13.");
  894. result.file_attrs.value = FileAttributes::LONG_NAME;
  895. result.dirent_type = 0;
  896. result.checksum = check_sum;
  897. // 该字段需要外层的代码手动赋值
  898. result.first_clus_low = 0;
  899. return result;
  900. }
  901. /// @brief 填写长目录项的名称字段。
  902. ///
  903. /// @param name_part 要被填入当前长目录项的名字(数组长度必须为13)
  904. ///
  905. /// @return Ok(())
  906. /// @return Err(SystemError) 错误码
  907. fn insert_name(&mut self, name_part: &[u16]) -> Result<(), SystemError> {
  908. if name_part.len() != Self::LONG_NAME_STR_LEN {
  909. return Err(SystemError::EINVAL);
  910. }
  911. self.name1.copy_from_slice(&name_part[0..5]);
  912. self.name2.copy_from_slice(&name_part[5..11]);
  913. self.name3.copy_from_slice(&name_part[11..13]);
  914. return Ok(());
  915. }
  916. /// @brief 将当前长目录项的名称字段,原样地拷贝到一个长度为13的u16数组中。
  917. /// @param dst 拷贝的目的地,一个[u16]数组,长度必须为13。
  918. pub fn copy_name_to_slice(&self, dst: &mut [u16]) -> Result<(), SystemError> {
  919. if dst.len() != Self::LONG_NAME_STR_LEN {
  920. return Err(SystemError::EINVAL);
  921. }
  922. dst[0..5].copy_from_slice(&self.name1);
  923. dst[5..11].copy_from_slice(&self.name2);
  924. dst[11..13].copy_from_slice(&self.name3);
  925. return Ok(());
  926. }
  927. /// @brief 是否为最后一个长目录项
  928. ///
  929. /// @return true 是最后一个长目录项
  930. /// @return false 不是最后一个长目录项
  931. pub fn is_last(&self) -> bool {
  932. return self.ord & 0x40 > 0;
  933. }
  934. /// @brief 校验字符串是否符合长目录项的命名要求
  935. ///
  936. /// @return Ok(()) 名称合法
  937. /// @return Err(SystemError) 名称不合法,返回错误码
  938. pub fn validate_long_name(mut name: &str) -> Result<(), SystemError> {
  939. // 去除首尾多余的空格
  940. name = name.trim();
  941. // 名称不能为0
  942. if name.len() == 0 {
  943. return Err(SystemError::EINVAL);
  944. }
  945. // 名称长度不能大于255
  946. if name.len() > 255 {
  947. return Err(SystemError::ENAMETOOLONG);
  948. }
  949. // 检查是否符合命名要求
  950. for c in name.chars() {
  951. match c {
  952. 'a'..='z' | 'A'..='Z' | '0'..='9' => {}
  953. '\u{80}'..='\u{ffff}' => {}
  954. '$' | '%' | '\'' | '-' | '_' | '@' | '~' | '`' | '!' | '(' | ')' | '{' | '}'
  955. | '^' | '#' | '&' => {}
  956. '+' | ',' | ';' | '=' | '[' | ']' | '.' | ' ' => {}
  957. _ => {
  958. return Err(SystemError::EILSEQ);
  959. }
  960. }
  961. }
  962. return Ok(());
  963. }
  964. /// @brief 把当前长目录项写入磁盘
  965. ///
  966. /// @param fs 对应的文件系统
  967. /// @param disk_bytes_offset 长目录项所在位置对应的在磁盘上的字节偏移量
  968. ///
  969. /// @return Ok(())
  970. /// @return Err(SystemError) 错误码
  971. pub fn flush(&self, fs: Arc<FATFileSystem>, disk_bytes_offset: u64) -> Result<(), SystemError> {
  972. // 从磁盘读取数据
  973. let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
  974. let lba = fs.get_lba_from_offset(
  975. fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)),
  976. );
  977. let mut v: Vec<u8> = Vec::new();
  978. v.resize(1 * fs.lba_per_sector() * LBA_SIZE, 0);
  979. fs.partition
  980. .disk()
  981. .read_at(lba, 1 * fs.lba_per_sector(), &mut v)?;
  982. let mut cursor: VecCursor = VecCursor::new(v);
  983. // 切换游标到对应位置
  984. cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
  985. // 写入数据
  986. cursor.write_u8(self.ord)?;
  987. for b in &self.name1 {
  988. cursor.write_u16(*b)?;
  989. }
  990. cursor.write_u8(self.file_attrs.value)?;
  991. cursor.write_u8(self.dirent_type)?;
  992. cursor.write_u8(self.checksum)?;
  993. for b in &self.name2 {
  994. cursor.write_u16(*b)?;
  995. }
  996. cursor.write_u16(self.first_clus_low)?;
  997. for b in &self.name3 {
  998. cursor.write_u16(*b)?;
  999. }
  1000. // 把修改后的长目录项刷入磁盘
  1001. fs.partition
  1002. .disk()
  1003. .write_at(lba, 1 * fs.lba_per_sector(), cursor.as_slice())?;
  1004. fs.partition.disk().sync()?;
  1005. return Ok(());
  1006. }
  1007. }
  1008. impl ShortDirEntry {
  1009. const PADDING: u8 = ' ' as u8;
  1010. /// @brief 判断当前目录项是否为文件夹
  1011. ///
  1012. /// @return true 是文件夹
  1013. /// @return false 不是文件夹
  1014. pub fn is_dir(&self) -> bool {
  1015. return (self.attributes.contains(FileAttributes::DIRECTORY))
  1016. && (!self.attributes.contains(FileAttributes::VOLUME_ID));
  1017. }
  1018. /// @brief 判断当前目录项是否为文件
  1019. ///
  1020. /// @return true 是文件
  1021. /// @return false 不是文件
  1022. pub fn is_file(&self) -> bool {
  1023. return (!self.attributes.contains(FileAttributes::DIRECTORY))
  1024. && (!self.attributes.contains(FileAttributes::VOLUME_ID));
  1025. }
  1026. /// @brief 判断当前目录项是否为卷号
  1027. ///
  1028. /// @return true 是卷号
  1029. /// @return false 不是卷号
  1030. pub fn is_volume_id(&self) -> bool {
  1031. return (!self.attributes.contains(FileAttributes::DIRECTORY))
  1032. && self.attributes.contains(FileAttributes::VOLUME_ID);
  1033. }
  1034. /// @brief 将短目录项的名字转换为String
  1035. fn name_to_string(&self) -> String {
  1036. // 计算基础名的长度
  1037. let base_len = self.name[..8]
  1038. .iter()
  1039. .rposition(|x| *x != ShortDirEntry::PADDING)
  1040. .map(|len| len + 1)
  1041. .unwrap_or(0);
  1042. // 计算扩展名的长度
  1043. let ext_len = self.name[8..]
  1044. .iter()
  1045. .rposition(|x| *x != ShortDirEntry::PADDING)
  1046. .map(|len| len + 1)
  1047. .unwrap_or(0);
  1048. // 声明存储完整名字的数组(包含“.”)
  1049. let mut name = [ShortDirEntry::PADDING; 12];
  1050. // 拷贝基础名
  1051. name[..base_len].copy_from_slice(&self.name[..base_len]);
  1052. // 拷贝扩展名,并计算总的长度
  1053. let total_len = if ext_len > 0 {
  1054. name[base_len] = '.' as u8;
  1055. name[base_len + 1..base_len + 1 + ext_len].copy_from_slice(&self.name[8..8 + ext_len]);
  1056. // 总长度为基础名长度+点号+扩展名长度
  1057. base_len + 1 + ext_len
  1058. } else {
  1059. base_len
  1060. };
  1061. if name[0] == 0x05 {
  1062. name[0] = 0xe5;
  1063. }
  1064. let iter = name[..total_len].iter().map(|c| decode_u8_ascii(*c));
  1065. // 返回最终的字符串
  1066. return String::from_iter(iter);
  1067. }
  1068. /// @brief 将短目录项结构体,转换为FATDirEntry枚举类型
  1069. ///
  1070. /// @param loc 当前文件的起始、终止簇。格式:(簇,簇内偏移量)
  1071. /// @return 生成的FATDirENtry枚举类型
  1072. pub fn to_dir_entry(&self, loc: (Cluster, u64)) -> FATDirEntry {
  1073. // 当前文件的第一个簇
  1074. let first_cluster =
  1075. Cluster::new(((self.fst_clus_hi as u64) << 16) | (self.fst_clus_lo as u64));
  1076. // 当前是文件或卷号
  1077. if self.is_file() || self.is_volume_id() {
  1078. let mut file: FATFile = FATFile::default();
  1079. file.file_name = self.name_to_string();
  1080. file.first_cluster = first_cluster;
  1081. file.short_dir_entry = self.clone();
  1082. file.loc = (loc, loc);
  1083. // 根据当前短目录项的类型的不同,返回对应的枚举类型。
  1084. if self.is_file() {
  1085. return FATDirEntry::File(file);
  1086. } else {
  1087. return FATDirEntry::VolId(file);
  1088. }
  1089. } else {
  1090. // 当前是文件夹
  1091. let mut dir = FATDir::default();
  1092. dir.dir_name = self.name_to_string();
  1093. dir.first_cluster = first_cluster;
  1094. dir.root_offset = None;
  1095. dir.short_dir_entry = Some(self.clone());
  1096. dir.loc = Some((loc, loc));
  1097. return FATDirEntry::Dir(dir);
  1098. }
  1099. }
  1100. /// @brief 将短目录项结构体,转换为FATDirEntry枚举类型. 并且,该短目录项具有对应的长目录项。
  1101. /// 因此,需要传入从长目录项获得的完整的文件名
  1102. ///
  1103. /// @param name 从长目录项获取的完整文件名
  1104. /// @param loc 当前文件的起始、终止簇。格式:(簇,簇内偏移量)
  1105. /// @return 生成的FATDirENtry枚举类型
  1106. pub fn to_dir_entry_with_long_name(
  1107. &self,
  1108. name: String,
  1109. loc: ((Cluster, u64), (Cluster, u64)),
  1110. ) -> FATDirEntry {
  1111. // 当前文件的第一个簇
  1112. let first_cluster =
  1113. Cluster::new(((self.fst_clus_hi as u64) << 16) | (self.fst_clus_lo as u64));
  1114. if self.is_file() || self.is_volume_id() {
  1115. let mut file = FATFile::default();
  1116. file.first_cluster = first_cluster;
  1117. file.file_name = name;
  1118. file.loc = loc;
  1119. file.short_dir_entry = self.clone();
  1120. if self.is_file() {
  1121. return FATDirEntry::File(file);
  1122. } else {
  1123. return FATDirEntry::VolId(file);
  1124. }
  1125. } else {
  1126. let mut dir = FATDir::default();
  1127. dir.first_cluster = first_cluster;
  1128. dir.dir_name = name;
  1129. dir.loc = Some(loc);
  1130. dir.short_dir_entry = Some(self.clone());
  1131. dir.root_offset = None;
  1132. return FATDirEntry::Dir(dir);
  1133. }
  1134. }
  1135. /// @brief 计算短目录项的名称的校验和
  1136. fn checksum(&self) -> u8 {
  1137. let mut result = 0;
  1138. for c in &self.name {
  1139. result = (result << 7) + (result >> 1) + *c;
  1140. }
  1141. return result;
  1142. }
  1143. /// @brief 把当前短目录项写入磁盘
  1144. ///
  1145. /// @param fs 对应的文件系统
  1146. /// @param disk_bytes_offset 短目录项所在位置对应的在磁盘上的字节偏移量
  1147. ///
  1148. /// @return Ok(())
  1149. /// @return Err(SystemError) 错误码
  1150. pub fn flush(
  1151. &self,
  1152. fs: &Arc<FATFileSystem>,
  1153. disk_bytes_offset: u64,
  1154. ) -> Result<(), SystemError> {
  1155. // 从磁盘读取数据
  1156. let blk_offset = fs.get_in_block_offset(disk_bytes_offset);
  1157. let lba = fs.get_lba_from_offset(
  1158. fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)),
  1159. );
  1160. let mut v: Vec<u8> = Vec::new();
  1161. v.resize(1 * fs.lba_per_sector() * LBA_SIZE, 0);
  1162. fs.partition
  1163. .disk()
  1164. .read_at(lba, 1 * fs.lba_per_sector(), &mut v)?;
  1165. let mut cursor: VecCursor = VecCursor::new(v);
  1166. // 切换游标到对应位置
  1167. cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
  1168. cursor.write_exact(&self.name)?;
  1169. cursor.write_u8(self.attributes.value)?;
  1170. cursor.write_u8(self.nt_res)?;
  1171. cursor.write_u8(self.crt_time_tenth)?;
  1172. cursor.write_u16(self.crt_time)?;
  1173. cursor.write_u16(self.crt_date)?;
  1174. cursor.write_u16(self.lst_acc_date)?;
  1175. cursor.write_u16(self.fst_clus_hi)?;
  1176. cursor.write_u16(self.wrt_time)?;
  1177. cursor.write_u16(self.wrt_date)?;
  1178. cursor.write_u16(self.fst_clus_lo)?;
  1179. cursor.write_u32(self.file_size)?;
  1180. // 把修改后的长目录项刷入磁盘
  1181. fs.partition
  1182. .disk()
  1183. .write_at(lba, 1 * fs.lba_per_sector(), cursor.as_slice())?;
  1184. fs.partition.disk().sync()?;
  1185. return Ok(());
  1186. }
  1187. /// @brief 设置短目录项的“第一个簇”字段的值
  1188. pub fn set_first_cluster(&mut self, cluster: Cluster) {
  1189. self.fst_clus_lo = (cluster.cluster_num & 0x0000ffff) as u16;
  1190. self.fst_clus_hi = ((cluster.cluster_num & 0xffff0000) >> 16) as u16;
  1191. }
  1192. }
  1193. /// @brief FAT文件系统标准定义的目录项
  1194. #[derive(Debug, Clone)]
  1195. pub enum FATRawDirEntry {
  1196. /// 短目录项
  1197. Short(ShortDirEntry),
  1198. /// 长目录项
  1199. Long(LongDirEntry),
  1200. /// 当前目录项的Name[0]==0xe5, 是空闲目录项
  1201. Free,
  1202. /// 当前目录项的Name[0]==0xe5, 是空闲目录项,且在这之后没有被分配过的目录项了。
  1203. FreeRest,
  1204. }
  1205. impl FATRawDirEntry {
  1206. /// 每个目录项的长度(单位:字节)
  1207. pub const DIR_ENTRY_LEN: u64 = 32;
  1208. /// @brief 判断当前目录项是否为这个文件的最后一个目录项
  1209. fn is_last(&self) -> bool {
  1210. match self {
  1211. &Self::Short(_) => {
  1212. return true;
  1213. }
  1214. &Self::Long(l) => {
  1215. return l.is_last();
  1216. }
  1217. _ => {
  1218. return false;
  1219. }
  1220. }
  1221. }
  1222. /// @brief 判断当前目录项是否为长目录项
  1223. fn is_long(&self) -> bool {
  1224. if let Self::Long(_) = self {
  1225. return true;
  1226. } else {
  1227. return false;
  1228. }
  1229. }
  1230. /// @brief 判断当前目录项是否为短目录项
  1231. fn is_short(&self) -> bool {
  1232. if let Self::Short(_) = self {
  1233. return true;
  1234. } else {
  1235. return false;
  1236. }
  1237. }
  1238. }
  1239. /// @brief FAT文件系统的目录项迭代器
  1240. #[derive(Debug)]
  1241. pub struct FATDirIter {
  1242. /// 当前正在迭代的簇
  1243. current_cluster: Cluster,
  1244. /// 当前正在迭代的簇的簇内偏移量
  1245. offset: u64,
  1246. /// True for the root directories of FAT12 and FAT16
  1247. is_root: bool,
  1248. /// 指向当前文件系统的指针
  1249. fs: Arc<FATFileSystem>,
  1250. }
  1251. impl FATDirIter {
  1252. /// @brief 迭代当前inode的目录项(获取下一个目录项)
  1253. ///
  1254. /// @return Ok(Cluster, u64, Option<FATDirEntry>)
  1255. /// Cluster: 下一个要读取的簇号
  1256. /// u64: 下一个要读取的簇内偏移量
  1257. /// Option<FATDirEntry>: 读取到的目录项(如果没有读取到,就返回失败)
  1258. /// @return Err(错误码) 可能出现了内部错误,或者是磁盘错误等。具体原因看错误码。
  1259. fn get_dir_entry(&mut self) -> Result<(Cluster, u64, Option<FATDirEntry>), SystemError> {
  1260. loop {
  1261. if unlikely(self.current_cluster.cluster_num < 2) {
  1262. return Ok((self.current_cluster, self.offset, None));
  1263. }
  1264. // 如果当前簇已经被读完,那么尝试获取下一个簇
  1265. if self.offset >= self.fs.bytes_per_cluster() && !self.is_root {
  1266. match self.fs.get_fat_entry(self.current_cluster)? {
  1267. FATEntry::Next(c) => {
  1268. // 获得下一个簇的信息
  1269. self.current_cluster = c;
  1270. self.offset %= self.fs.bytes_per_cluster();
  1271. }
  1272. _ => {
  1273. // 没有下一个簇了,返回None
  1274. return Ok((self.current_cluster, self.offset, None));
  1275. }
  1276. }
  1277. }
  1278. // 如果当前是FAT12/FAT16文件系统,并且当前inode是根目录项。
  1279. // 如果offset大于根目录项的最大大小(已经遍历完根目录),那么就返回None
  1280. if self.is_root && self.offset > self.fs.root_dir_end_bytes_offset().unwrap() {
  1281. return Ok((self.current_cluster, self.offset, None));
  1282. }
  1283. // 获取簇在磁盘内的字节偏移量
  1284. let offset: u64 = self.fs.cluster_bytes_offset(self.current_cluster) + self.offset;
  1285. // 从磁盘读取原始的dentry
  1286. let raw_dentry: FATRawDirEntry = get_raw_dir_entry(&self.fs, offset)?;
  1287. // 由于迭代顺序从前往后,因此:
  1288. // 如果找到1个短目录项,那么证明有一个完整的entry被找到,因此返回。
  1289. // 如果找到1个长目录项,那么,就依次往下迭代查找,直到找到一个短目录项,然后返回结果。这里找到的所有的目录项,都属于同一个文件/文件夹。
  1290. match raw_dentry {
  1291. FATRawDirEntry::Short(s) => {
  1292. // 当前找到一个短目录项,更新offset之后,直接返回
  1293. self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
  1294. return Ok((
  1295. self.current_cluster,
  1296. self.offset,
  1297. Some(s.to_dir_entry((
  1298. self.current_cluster,
  1299. self.offset - FATRawDirEntry::DIR_ENTRY_LEN,
  1300. ))),
  1301. ));
  1302. }
  1303. FATRawDirEntry::Long(_) => {
  1304. // 当前找到一个长目录项
  1305. // 声明一个数组,来容纳所有的entry。(先把最后一个entry放进去)
  1306. let mut long_name_entries: Vec<FATRawDirEntry> = vec![raw_dentry];
  1307. let start_offset: u64 = self.offset;
  1308. let start_cluster: Cluster = self.current_cluster;
  1309. self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
  1310. // 由于在FAT文件系统中,文件名最长为255字节,因此,最多有20个长目录项以及1个短目录项。
  1311. // 由于上面已经塞了1个长目录项,因此接下来最多需要迭代20次
  1312. // 循环查找目录项,直到遇到1个短目录项,或者是空闲目录项
  1313. for _ in 0..20 {
  1314. // 如果当前簇已经被读完,那么尝试获取下一个簇
  1315. if self.offset >= self.fs.bytes_per_cluster() && !self.is_root {
  1316. match self.fs.get_fat_entry(self.current_cluster)? {
  1317. FATEntry::Next(c) => {
  1318. // 获得下一个簇的信息
  1319. self.current_cluster = c;
  1320. self.offset %= self.fs.bytes_per_cluster();
  1321. }
  1322. _ => {
  1323. // 没有下一个簇了,退出迭代
  1324. break;
  1325. }
  1326. }
  1327. }
  1328. // 如果当前是FAT12/FAT16文件系统,并且当前inode是根目录项。
  1329. // 如果offset大于根目录项的最大大小(已经遍历完根目录),那么就退出迭代
  1330. if self.is_root
  1331. && self.offset > self.fs.root_dir_end_bytes_offset().unwrap()
  1332. {
  1333. break;
  1334. }
  1335. // 获取簇在磁盘内的字节偏移量
  1336. let offset: u64 =
  1337. self.fs.cluster_bytes_offset(self.current_cluster) + self.offset;
  1338. // 从磁盘读取原始的dentry
  1339. let raw_dentry: FATRawDirEntry = get_raw_dir_entry(&self.fs, offset)?;
  1340. match raw_dentry {
  1341. FATRawDirEntry::Short(_) => {
  1342. // 当前遇到1个短目录项,证明当前文件/文件夹的所有dentry都被读取完了,因此在将其加入数组后,退出迭代。
  1343. long_name_entries.push(raw_dentry);
  1344. break;
  1345. }
  1346. FATRawDirEntry::Long(_) => {
  1347. // 当前遇到1个长目录项,将其加入数组,然后更新offset,继续迭代。
  1348. long_name_entries.push(raw_dentry);
  1349. self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
  1350. }
  1351. _ => {
  1352. // 遇到了空闲簇,但没遇到短目录项,说明文件系统出错了,退出。
  1353. break;
  1354. }
  1355. }
  1356. }
  1357. // kdebug!("collect dentries done. long_name_entries={long_name_entries:?}");
  1358. let dir_entry: Result<FATDirEntry, SystemError> = FATDirEntry::new(
  1359. long_name_entries,
  1360. (
  1361. (start_cluster, start_offset),
  1362. (self.current_cluster, self.offset),
  1363. ),
  1364. );
  1365. // kdebug!("dir_entry={:?}", dir_entry);
  1366. match dir_entry {
  1367. Ok(d) => {
  1368. // kdebug!("dir_entry ok");
  1369. self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
  1370. return Ok((self.current_cluster, self.offset, Some(d)));
  1371. }
  1372. Err(_) => {
  1373. // kdebug!("dir_entry err, e={}", e);
  1374. self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
  1375. }
  1376. }
  1377. }
  1378. FATRawDirEntry::Free => {
  1379. // 当前目录项是空的
  1380. self.offset += FATRawDirEntry::DIR_ENTRY_LEN;
  1381. }
  1382. FATRawDirEntry::FreeRest => {
  1383. // 当前目录项是空的,且之后都是空的,因此直接返回
  1384. return Ok((self.current_cluster, self.offset, None));
  1385. }
  1386. }
  1387. }
  1388. }
  1389. }
  1390. /// 为DirIter实现迭代器trait
  1391. impl Iterator for FATDirIter {
  1392. type Item = FATDirEntry;
  1393. fn next(&mut self) -> Option<Self::Item> {
  1394. match self.get_dir_entry() {
  1395. Ok((cluster, offset, result)) => {
  1396. self.current_cluster = cluster;
  1397. self.offset = offset;
  1398. return result;
  1399. }
  1400. Err(_) => {
  1401. return None;
  1402. }
  1403. }
  1404. }
  1405. }
  1406. impl FATDirEntry {
  1407. /// @brief 构建FATDirEntry枚举类型
  1408. ///
  1409. /// @param long_name_entries 长目录项的数组。
  1410. /// 格式:[第20个(或者是最大ord的那个), 19, 18, ..., 1, 短目录项]
  1411. ///
  1412. /// @return Ok(FATDirEntry) 构建好的FATDirEntry类型的对象
  1413. /// @return Err(SystemError) 错误码
  1414. pub fn new(
  1415. mut long_name_entries: Vec<FATRawDirEntry>,
  1416. loc: ((Cluster, u64), (Cluster, u64)),
  1417. ) -> Result<Self, SystemError> {
  1418. if long_name_entries.is_empty() {
  1419. return Err(SystemError::EINVAL);
  1420. }
  1421. if !long_name_entries[0].is_last() || !long_name_entries.last().unwrap().is_short() {
  1422. // 存在孤立的目录项,文件系统出现异常,因此返回错误,表明其只读。
  1423. // TODO: 标记整个FAT文件系统为只读的
  1424. return Err(SystemError::EROFS);
  1425. }
  1426. // 取出短目录项(位于vec的末尾)
  1427. let short_dentry: ShortDirEntry = match long_name_entries.pop().unwrap() {
  1428. FATRawDirEntry::Short(s) => s,
  1429. _ => unreachable!(),
  1430. };
  1431. let mut extractor = LongNameExtractor::new();
  1432. for entry in &long_name_entries {
  1433. match entry {
  1434. &FATRawDirEntry::Long(l) => {
  1435. extractor.process(l)?;
  1436. }
  1437. _ => {
  1438. return Err(SystemError::EROFS);
  1439. }
  1440. }
  1441. }
  1442. // 检验校验和是否正确
  1443. if extractor.validate_checksum(&short_dentry) {
  1444. // 校验和正确,返回一个长目录项
  1445. return Ok(short_dentry.to_dir_entry_with_long_name(extractor.to_string(), loc));
  1446. } else {
  1447. // 校验和不相同,认为文件系统出错
  1448. return Err(SystemError::EROFS);
  1449. }
  1450. }
  1451. /// @brief 获取短目录项的名字
  1452. pub fn short_name(&self) -> String {
  1453. match self {
  1454. FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
  1455. return f.short_dir_entry.name_to_string();
  1456. }
  1457. FATDirEntry::Dir(d) => match d.short_dir_entry {
  1458. Some(s) => {
  1459. return s.name_to_string();
  1460. }
  1461. None => {
  1462. return String::from("/");
  1463. }
  1464. },
  1465. FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
  1466. }
  1467. }
  1468. /// @brief 获取短目录项结构体
  1469. pub fn short_dir_entry(&self) -> Option<ShortDirEntry> {
  1470. match &self {
  1471. FATDirEntry::File(f) => {
  1472. return Some(f.short_dir_entry);
  1473. }
  1474. FATDirEntry::Dir(d) => {
  1475. return d.short_dir_entry;
  1476. }
  1477. FATDirEntry::VolId(s) => {
  1478. return Some(s.short_dir_entry);
  1479. }
  1480. FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
  1481. }
  1482. }
  1483. /// @brief 获取目录项的第一个簇的簇号
  1484. pub fn first_cluster(&self) -> Cluster {
  1485. match self {
  1486. FATDirEntry::File(f) => {
  1487. return f.first_cluster;
  1488. }
  1489. FATDirEntry::Dir(d) => {
  1490. return d.first_cluster;
  1491. }
  1492. FATDirEntry::VolId(s) => {
  1493. return s.first_cluster;
  1494. }
  1495. FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
  1496. }
  1497. }
  1498. /// @brief 获取当前目录项所占用的簇的范围
  1499. ///
  1500. /// @return (起始簇,簇内偏移量), (终止簇,簇内偏移量)
  1501. pub fn get_dir_range(&self) -> Option<((Cluster, u64), (Cluster, u64))> {
  1502. match self {
  1503. FATDirEntry::File(f) => Some(f.loc),
  1504. FATDirEntry::Dir(d) => d.loc,
  1505. FATDirEntry::VolId(s) => Some(s.loc),
  1506. FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
  1507. }
  1508. }
  1509. /// @brief 获取原始的短目录项名(FAT标准规定的)
  1510. pub fn short_name_raw(&self) -> [u8; 11] {
  1511. match self {
  1512. FATDirEntry::File(f) => {
  1513. return f.short_dir_entry.name;
  1514. }
  1515. FATDirEntry::Dir(d) => match d.short_dir_entry {
  1516. // 存在短目录项,直接返回
  1517. Some(s) => {
  1518. return s.name;
  1519. }
  1520. // 是根目录项
  1521. None => {
  1522. let mut s = [0x20u8; 11];
  1523. s[0] = '/' as u8;
  1524. return s;
  1525. }
  1526. },
  1527. FATDirEntry::VolId(s) => {
  1528. return s.short_dir_entry.name;
  1529. }
  1530. FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
  1531. }
  1532. }
  1533. /// @brief 获取目录项的名字
  1534. pub fn name(&self) -> String {
  1535. match self {
  1536. FATDirEntry::File(f) => {
  1537. return f.file_name.clone();
  1538. }
  1539. FATDirEntry::VolId(s) => {
  1540. return s.file_name.clone();
  1541. }
  1542. FATDirEntry::Dir(d) => {
  1543. return d.dir_name.clone();
  1544. }
  1545. FATDirEntry::UnInit => unreachable!("FATFS: FATDirEntry uninitialized."),
  1546. }
  1547. }
  1548. /// @brief 判断目录项是否为文件
  1549. pub fn is_file(&self) -> bool {
  1550. match self {
  1551. &FATDirEntry::File(_) | &FATDirEntry::VolId(_) => true,
  1552. _ => false,
  1553. }
  1554. }
  1555. /// @brief 判断目录项是否为文件夹
  1556. pub fn is_dir(&self) -> bool {
  1557. match &self {
  1558. &FATDirEntry::Dir(_) => true,
  1559. _ => false,
  1560. }
  1561. }
  1562. /// @brief 判断目录项是否为Volume id
  1563. pub fn is_vol_id(&self) -> bool {
  1564. match self {
  1565. &FATDirEntry::VolId(_) => true,
  1566. _ => false,
  1567. }
  1568. }
  1569. /// @brief 判断FAT目录项的名字与给定的是否相等
  1570. ///
  1571. /// 由于FAT32对大小写不敏感,因此将字符都转为大写,然后比较
  1572. ///
  1573. /// @return bool 相等 => true
  1574. /// 不相等 => false
  1575. pub fn eq_name(&self, name: &str) -> bool {
  1576. // 由于FAT32对大小写不敏感,因此将字符都转为大写,然后比较。
  1577. let binding = self.short_name();
  1578. let short_name = binding.chars().flat_map(|c| c.to_uppercase());
  1579. let binding = self.name();
  1580. let long_name = binding.chars().flat_map(|c| c.to_uppercase());
  1581. let name = name.chars().flat_map(|c| c.to_uppercase());
  1582. let long_name_matches: bool = long_name.eq(name.clone());
  1583. let short_name_matches: bool = short_name.eq(name);
  1584. return long_name_matches || short_name_matches;
  1585. }
  1586. /// @brief 将FATDirEntry转换为FATFile对象
  1587. pub fn to_file(&self) -> Result<FATFile, SystemError> {
  1588. if self.is_file() == false {
  1589. return Err(SystemError::EISDIR);
  1590. }
  1591. match &self {
  1592. FATDirEntry::File(f) | FATDirEntry::VolId(f) => {
  1593. return Ok(f.clone());
  1594. }
  1595. _ => unreachable!(),
  1596. }
  1597. }
  1598. /// @brief 将FATDirEntry转换为FATDir对象
  1599. pub fn to_dir(&self) -> Result<FATDir, SystemError> {
  1600. if self.is_dir() == false {
  1601. return Err(SystemError::ENOTDIR);
  1602. }
  1603. match &self {
  1604. FATDirEntry::Dir(d) => {
  1605. return Ok(d.clone());
  1606. }
  1607. _ => unreachable!(),
  1608. }
  1609. }
  1610. }
  1611. /// 用于生成短目录项文件名的生成器。
  1612. #[derive(Debug, Default)]
  1613. pub struct ShortNameGenerator {
  1614. /// 短目录项的名字
  1615. name: [u8; 11],
  1616. /// 生成器的标志位(使用impl里面的mask来解析)
  1617. flags: u8,
  1618. /// 基础名的长度
  1619. basename_len: u8,
  1620. /// 对于文件名形如(TE021F~1.TXT)的,短前缀+校验码的短目录项,该字段表示基础名末尾数字的对应位。
  1621. checksum_bitmask: u16,
  1622. /// Fletcher-16 Checksum(与填写到ShortDirEntry里面的不一样)
  1623. checksum: u16,
  1624. /// 对于形如(TEXTFI~1.TXT)的短目录项名称,其中的数字的bitmask(第0位置位则表示这个数字是0)
  1625. suffix_bitmask: u16,
  1626. }
  1627. impl ShortNameGenerator {
  1628. /// 短目录项的名称的长度
  1629. const SHORT_NAME_LEN: usize = 8;
  1630. // ===== flags标志位的含义 =====
  1631. const IS_LOSSY: u8 = (1 << 0);
  1632. const IS_EXACT_MATCH: u8 = (1 << 1);
  1633. const IS_DOT: u8 = (1 << 2);
  1634. const IS_DOTDOT: u8 = (1 << 3);
  1635. /// 名称被完全拷贝
  1636. const NAME_FITS: u8 = (1 << 4);
  1637. /// @brief 初始化一个短目录项名称生成器
  1638. pub fn new(mut name: &str) -> Self {
  1639. name = name.trim();
  1640. let mut short_name: [u8; 11] = [0x20u8; 11];
  1641. if name == "." {
  1642. short_name[0] = '.' as u8;
  1643. }
  1644. if name == ".." {
  1645. short_name[0] = '.' as u8;
  1646. short_name[1] = '.' as u8;
  1647. }
  1648. // @name_fits: 名称是否被完全拷贝
  1649. // @basename_len: 基础名的长度
  1650. // @is_lossy: 是否存在不合法的字符
  1651. let (name_fits, basename_len, is_lossy) = match name.rfind('.') {
  1652. Some(index) => {
  1653. // 文件名里面有".", 且index为最右边的点号所在的下标(bytes index)
  1654. // 拷贝基础名
  1655. let (b_len, fits, b_lossy) =
  1656. Self::copy_part(&mut short_name[..Self::SHORT_NAME_LEN], &name[..index]);
  1657. // 拷贝扩展名
  1658. let (_, ext_fits, ext_lossy) = Self::copy_part(
  1659. &mut short_name[Self::SHORT_NAME_LEN..Self::SHORT_NAME_LEN + 3],
  1660. &name[index + 1..],
  1661. );
  1662. (fits && ext_fits, b_len, b_lossy || ext_lossy)
  1663. }
  1664. None => {
  1665. // 文件名中,不存在"."
  1666. let (b_len, fits, b_lossy) =
  1667. Self::copy_part(&mut short_name[..Self::SHORT_NAME_LEN], &name);
  1668. (fits, b_len, b_lossy)
  1669. }
  1670. };
  1671. let mut flags: u8 = 0;
  1672. // 设置flags
  1673. if is_lossy {
  1674. flags |= Self::IS_LOSSY;
  1675. }
  1676. if name == "." {
  1677. flags |= Self::IS_DOT;
  1678. }
  1679. if name == ".." {
  1680. flags |= Self::IS_DOTDOT;
  1681. }
  1682. if name_fits {
  1683. flags |= Self::NAME_FITS;
  1684. }
  1685. return ShortNameGenerator {
  1686. name: short_name,
  1687. flags: flags,
  1688. basename_len: basename_len,
  1689. checksum: Self::fletcher_16_checksum(name),
  1690. ..Default::default()
  1691. };
  1692. }
  1693. /// @brief 拷贝字符串到一个u8数组
  1694. ///
  1695. /// @return (u8, bool, bool)
  1696. /// return.0: 拷贝了的字符串的长度
  1697. /// return.1: 是否完全拷贝完整个字符串
  1698. /// return.2: 拷贝过程中,是否出现了不合法字符
  1699. fn copy_part(dest: &mut [u8], src: &str) -> (u8, bool, bool) {
  1700. let mut dest_len: usize = 0;
  1701. let mut lossy_conv = false;
  1702. for c in src.chars() {
  1703. // 如果src还有字符,而dest已经满了,那么表示没有完全拷贝完。
  1704. if dest_len == dest.len() {
  1705. return (dest_len as u8, false, lossy_conv);
  1706. }
  1707. if c == ' ' || c == '.' {
  1708. lossy_conv = true;
  1709. continue;
  1710. }
  1711. let cp: char = match c {
  1712. 'a'..='z' | 'A'..='Z' | '0'..='9' => c,
  1713. '$' | '%' | '\'' | '-' | '_' | '@' | '~' | '`' | '!' | '(' | ')' | '{' | '}'
  1714. | '^' | '#' | '&' => c,
  1715. _ => '_',
  1716. };
  1717. // 判断是否存在不符合条件的字符
  1718. lossy_conv = lossy_conv || c != cp;
  1719. // 拷贝字符
  1720. dest[dest_len] = c.to_ascii_uppercase() as u8;
  1721. dest_len += 1;
  1722. }
  1723. // 返回结果
  1724. return (dest_len as u8, true, lossy_conv);
  1725. }
  1726. fn fletcher_16_checksum(name: &str) -> u16 {
  1727. let mut sum1: u16 = 0;
  1728. let mut sum2: u16 = 0;
  1729. for c in name.chars() {
  1730. sum1 = (sum1 + (c as u16)) % 0xff;
  1731. sum2 = (sum1 + sum2) & 0xff;
  1732. }
  1733. return (sum2 << 8) | sum1;
  1734. }
  1735. /// @brief 更新生成器的状态
  1736. /// 当长目录项不存在的时候,需要调用这个函数来更新生成器的状态
  1737. pub fn add_name(&mut self, name: &[u8; 11]) {
  1738. // === 判断名称是否严格的完全匹配
  1739. if name == &self.name {
  1740. self.flags |= Self::IS_EXACT_MATCH;
  1741. }
  1742. // === 检查是否存在长前缀的格式冲突。对于这样的短目录项名称:(TEXTFI~1.TXT)
  1743. // 获取名称前缀
  1744. let prefix_len = min(self.basename_len, 6) as usize;
  1745. // 获取后缀的那个数字
  1746. let num_suffix: Option<u32> = if name[prefix_len] as char == '~' {
  1747. (name[prefix_len + 1] as char).to_digit(10)
  1748. } else {
  1749. None
  1750. };
  1751. // 判断扩展名是否匹配
  1752. let ext_matches: bool = name[8..] == self.name[8..];
  1753. if name[..prefix_len] == self.name[..prefix_len] // 基础名前缀相同
  1754. && num_suffix.is_some() // 基础名具有数字后缀
  1755. && ext_matches
  1756. // 扩展名相匹配
  1757. {
  1758. let num = num_suffix.unwrap();
  1759. self.suffix_bitmask |= 1 << num;
  1760. }
  1761. // === 检查是否存在短前缀+校验和的冲突,文件名形如:(TE021F~1.TXT)
  1762. let prefix_len = min(self.basename_len, 2) as usize;
  1763. let num_suffix: Option<u32> = if name[prefix_len + 4] as char == '~' {
  1764. (name[prefix_len + 1] as char).to_digit(10)
  1765. } else {
  1766. None
  1767. };
  1768. if name[..prefix_len] == self.name[..prefix_len] && num_suffix.is_some() && ext_matches {
  1769. // 获取短文件名中的校验码字段
  1770. let checksum_result: Result<
  1771. Result<u16, core::num::ParseIntError>,
  1772. core::str::Utf8Error,
  1773. > = core::str::from_utf8(&name[prefix_len..prefix_len + 4])
  1774. .map(|s| u16::from_str_radix(s, 16));
  1775. // 如果校验码相同
  1776. if checksum_result == Ok(Ok(self.checksum)) {
  1777. let num = num_suffix.unwrap();
  1778. // 置位checksum_bitmask中,基础名末尾数字的对应位
  1779. self.checksum_bitmask |= 1 << num;
  1780. }
  1781. }
  1782. }
  1783. pub fn generate(&self) -> Result<[u8; 11], SystemError> {
  1784. if self.is_dot() || self.is_dotdot() {
  1785. return Ok(self.name);
  1786. }
  1787. // 如果当前名字不存在不合法的字符,且名称被完整拷贝,但是exact match为false,可以认为名称没有冲突,直接返回
  1788. if !self.is_lossy() && self.name_fits() && !self.is_exact_match() {
  1789. return Ok(self.name);
  1790. }
  1791. // 尝试使用长前缀(6字符)
  1792. for i in 1..5 {
  1793. if self.suffix_bitmask & (1 << i) == 0 {
  1794. return Ok(self.build_prefixed_name(i as u32, false));
  1795. }
  1796. }
  1797. // 尝试使用短前缀+校验码
  1798. for i in 1..10 {
  1799. if self.checksum_bitmask & (1 << i) == 0 {
  1800. return Ok(self.build_prefixed_name(i as u32, true));
  1801. }
  1802. }
  1803. // 由于产生太多的冲突,因此返回错误(“短文件名已经存在”)
  1804. return Err(SystemError::EEXIST);
  1805. }
  1806. pub fn next_iteration(&mut self) {
  1807. // 在下一次迭代中,尝试一个不同的校验和
  1808. self.checksum = (core::num::Wrapping(self.checksum) + core::num::Wrapping(1)).0;
  1809. // 清空bitmask
  1810. self.suffix_bitmask = 0;
  1811. self.checksum_bitmask = 0;
  1812. }
  1813. /// @brief 构造具有前缀的短目录项名称
  1814. ///
  1815. /// @param num 这是第几个重名的前缀名
  1816. /// @param with_checksum 前缀名中是否包含校验码
  1817. ///
  1818. /// @return 构造好的短目录项名称数组
  1819. fn build_prefixed_name(&self, num: u32, with_checksum: bool) -> [u8; 11] {
  1820. let mut buf: [u8; 11] = [0x20u8; 11];
  1821. let prefix_len: usize = if with_checksum {
  1822. let prefix_len: usize = min(self.basename_len as usize, 2);
  1823. buf[..prefix_len].copy_from_slice(&self.name[..prefix_len]);
  1824. buf[prefix_len..prefix_len + 4].copy_from_slice(&Self::u16_to_u8_array(self.checksum));
  1825. prefix_len + 4
  1826. } else {
  1827. let prefix_len = min(self.basename_len as usize, 6);
  1828. buf[..prefix_len].copy_from_slice(&self.name[..prefix_len]);
  1829. prefix_len
  1830. };
  1831. buf[prefix_len] = '~' as u8;
  1832. buf[prefix_len + 1] = char::from_digit(num, 10).unwrap() as u8;
  1833. buf[8..].copy_from_slice(&self.name[8..]);
  1834. return buf;
  1835. }
  1836. /// @brief 将一个u16数字转换为十六进制大写字符串对应的ascii数组。
  1837. /// 举例:将x=12345转换为16进制字符串“3039”对应的ascii码数组:[51,48,51,57]
  1838. fn u16_to_u8_array(x: u16) -> [u8; 4] {
  1839. let c1 = char::from_digit((x as u32 >> 12) & 0xf, 16)
  1840. .unwrap()
  1841. .to_ascii_uppercase() as u8;
  1842. let c2 = char::from_digit((x as u32 >> 8) & 0xf, 16)
  1843. .unwrap()
  1844. .to_ascii_uppercase() as u8;
  1845. let c3 = char::from_digit((x as u32 >> 4) & 0xf, 16)
  1846. .unwrap()
  1847. .to_ascii_uppercase() as u8;
  1848. let c4 = char::from_digit((x as u32 >> 0) & 0xf, 16)
  1849. .unwrap()
  1850. .to_ascii_uppercase() as u8;
  1851. return [c1, c2, c3, c4];
  1852. }
  1853. #[inline]
  1854. fn is_lossy(&self) -> bool {
  1855. return (self.flags & Self::IS_LOSSY) > 0;
  1856. }
  1857. #[inline]
  1858. fn is_exact_match(&self) -> bool {
  1859. return (self.flags & Self::IS_EXACT_MATCH) > 0;
  1860. }
  1861. #[inline]
  1862. fn is_dot(&self) -> bool {
  1863. return (self.flags & Self::IS_DOT) > 0;
  1864. }
  1865. #[inline]
  1866. fn is_dotdot(&self) -> bool {
  1867. return (self.flags & Self::IS_DOTDOT) > 0;
  1868. }
  1869. #[inline]
  1870. fn name_fits(&self) -> bool {
  1871. return (self.flags & Self::NAME_FITS) > 0;
  1872. }
  1873. }
  1874. /// 从多个LongName中提取完整文件名字段的提取器
  1875. struct LongNameExtractor {
  1876. name: Vec<u16>,
  1877. checksum: u8,
  1878. index: u8,
  1879. }
  1880. impl LongNameExtractor {
  1881. fn new() -> Self {
  1882. return LongNameExtractor {
  1883. name: Vec::new(),
  1884. checksum: 0,
  1885. index: 0,
  1886. };
  1887. }
  1888. /// @brief 提取长目录项的名称
  1889. /// @param longname_dentry 长目录项
  1890. /// 请注意,必须倒序输入长目录项对象
  1891. fn process(&mut self, longname_dentry: LongDirEntry) -> Result<(), SystemError> {
  1892. let is_last: bool = longname_dentry.is_last();
  1893. let index: u8 = longname_dentry.ord & 0x1f;
  1894. if index == 0 {
  1895. self.name.clear();
  1896. return Err(SystemError::EROFS);
  1897. }
  1898. // 如果是最后一个LongDirEntry,则初始化当前生成器
  1899. if is_last {
  1900. self.index = index;
  1901. self.checksum = longname_dentry.checksum;
  1902. self.name
  1903. .resize(index as usize * LongDirEntry::LONG_NAME_STR_LEN, 0);
  1904. } else if self.index == 0
  1905. || index != self.index - 1
  1906. || self.checksum != longname_dentry.checksum
  1907. {
  1908. // 如果当前index为0,或者index不连续,或者是校验和不同,那么认为文件系统损坏,清除生成器的名称字段
  1909. // TODO: 对文件系统的变为只读状态状况的拦截
  1910. self.name.clear();
  1911. return Err(SystemError::EROFS);
  1912. } else {
  1913. // 由于dentry倒序输入,因此index是每次减1的
  1914. self.index -= 1;
  1915. }
  1916. let pos: usize = ((index - 1) as usize) * LongDirEntry::LONG_NAME_STR_LEN;
  1917. // 将当前目录项的值,拷贝到生成器的数组中
  1918. longname_dentry
  1919. .copy_name_to_slice(&mut self.name[pos..pos + LongDirEntry::LONG_NAME_STR_LEN])?;
  1920. return Ok(());
  1921. }
  1922. /// @brief 返回名称的长度
  1923. #[inline]
  1924. fn len(&self) -> usize {
  1925. return self.name.len();
  1926. }
  1927. /// @brief 返回抽取得到的名称字符串
  1928. fn to_string(&self) -> String {
  1929. let mut s = String::from_utf16_lossy(self.name.as_slice());
  1930. // 计算字符串的长度。如果字符串中有\0,那么就截取字符串的前面部分
  1931. if let Some(len) = s.find('\u{0}') {
  1932. s.truncate(len);
  1933. }
  1934. return s;
  1935. }
  1936. /// @brief 判断校验码是否与指定的短目录项的校验码相同
  1937. ///
  1938. /// @return bool 相同 => true
  1939. /// 不同 => false
  1940. fn validate_checksum(&self, short_dentry: &ShortDirEntry) -> bool {
  1941. return self.checksum == short_dentry.checksum();
  1942. }
  1943. }
  1944. /// @brief 长目录项生成器
  1945. #[derive(Debug)]
  1946. struct LongNameEntryGenerator {
  1947. name: Vec<u16>,
  1948. // 短目录项的校验和
  1949. checksum: u8,
  1950. // 当前迭代器的索引
  1951. idx: u8,
  1952. /// 最后一个目录项的索引
  1953. last_index: u8,
  1954. }
  1955. impl LongNameEntryGenerator {
  1956. /// @brief 初始化长目录项生成器
  1957. ///
  1958. /// @param name 长文件名数组
  1959. /// @param checksum 短目录项的校验和
  1960. pub fn new(name: &str, checksum: u8) -> Self {
  1961. let mut name: Vec<u16> = name.chars().map(|c| c as u16).collect();
  1962. let padding_bytes: usize = (13 - (name.len() % 13)) % 13;
  1963. // 填充最后一个长目录项的文件名
  1964. for i in 0..padding_bytes {
  1965. if i == 0 {
  1966. name.push(0);
  1967. } else {
  1968. name.push(0xffff);
  1969. }
  1970. }
  1971. // 先从最后一个长目录项开始生成
  1972. let start_index = (name.len() / 13) as u8;
  1973. return LongNameEntryGenerator {
  1974. name: name,
  1975. checksum: checksum,
  1976. idx: start_index,
  1977. last_index: start_index,
  1978. };
  1979. }
  1980. /// @brief 返回要生成的长目录项的总数
  1981. pub fn num_entries(&self) -> u8 {
  1982. return self.last_index + 1;
  1983. }
  1984. }
  1985. impl Iterator for LongNameEntryGenerator {
  1986. type Item = LongDirEntry;
  1987. fn next(&mut self) -> Option<Self::Item> {
  1988. match self.idx {
  1989. 0 => {
  1990. return None;
  1991. }
  1992. // 最后一个长目录项
  1993. n if n == self.last_index => {
  1994. // 最后一个长目录项的ord需要与0x40相或
  1995. let ord: u8 = n | 0x40;
  1996. let start_idx = ((n - 1) * 13) as usize;
  1997. self.idx -= 1;
  1998. return Some(LongDirEntry::new(
  1999. ord,
  2000. &self.name.as_slice()[start_idx..start_idx + 13],
  2001. self.checksum,
  2002. ));
  2003. }
  2004. n => {
  2005. // 其它的长目录项
  2006. let start_idx = ((n - 1) * 13) as usize;
  2007. self.idx -= 1;
  2008. return Some(LongDirEntry::new(
  2009. n,
  2010. &self.name.as_slice()[start_idx..start_idx + 13],
  2011. self.checksum,
  2012. ));
  2013. }
  2014. }
  2015. }
  2016. }
  2017. #[derive(Debug)]
  2018. pub enum FATDirEntryOrShortName {
  2019. DirEntry(FATDirEntry),
  2020. ShortName([u8; 11]),
  2021. }
  2022. /// @brief 对FAT目录项的迭代器(基于簇和簇内偏移量)
  2023. #[derive(Debug)]
  2024. struct FATDirEntryOffsetIter {
  2025. /// 当前迭代的偏移量(下一次迭代要返回的值)
  2026. current_offset: (Cluster, u64),
  2027. /// 截止迭代的位置(end_offset所在的位置也会被迭代器返回)
  2028. end_offset: Option<(Cluster, u64)>,
  2029. /// 属于的文件系统
  2030. fs: Arc<FATFileSystem>,
  2031. /// 当前已经迭代了多少次
  2032. index: u64,
  2033. /// 总共要迭代多少次
  2034. len: u64,
  2035. /// 如果end_offset不为None,该字段表示“是否已经到达了迭代终点”
  2036. fin: bool,
  2037. }
  2038. impl FATDirEntryOffsetIter {
  2039. /// @brief 初始化FAT目录项的迭代器(基于簇和簇内偏移量)
  2040. ///
  2041. /// @param fs 属于的文件系统
  2042. /// @param start 起始偏移量
  2043. /// @param len 要迭代的次数
  2044. /// @param end_offset 截止迭代的位置(end_offset所在的位置也会被迭代器返回)
  2045. ///
  2046. /// @return 构建好的迭代器对象
  2047. pub fn new(
  2048. fs: Arc<FATFileSystem>,
  2049. start: (Cluster, u64),
  2050. len: u64,
  2051. end_offset: Option<(Cluster, u64)>,
  2052. ) -> Self {
  2053. return FATDirEntryOffsetIter {
  2054. current_offset: start,
  2055. end_offset,
  2056. fs,
  2057. index: 0,
  2058. len,
  2059. fin: false,
  2060. };
  2061. }
  2062. }
  2063. impl Iterator for FATDirEntryOffsetIter {
  2064. type Item = (Cluster, u64);
  2065. fn next(&mut self) -> Option<Self::Item> {
  2066. if self.index == self.len || self.fin {
  2067. return None;
  2068. }
  2069. let r: (Cluster, u64) = self.current_offset;
  2070. // 计算新的字节偏移量
  2071. let mut new_offset = r.1 + FATRawDirEntry::DIR_ENTRY_LEN;
  2072. let mut new_cluster: Cluster = r.0;
  2073. // 越过了当前簇,则获取下一个簇
  2074. if new_offset >= self.fs.bytes_per_cluster() {
  2075. new_offset %= self.fs.bytes_per_cluster();
  2076. match self.fs.get_fat_entry(new_cluster) {
  2077. Ok(FATEntry::Next(c)) => {
  2078. new_cluster = c;
  2079. }
  2080. // 没有下一个簇了
  2081. _ => {
  2082. self.fin = true;
  2083. }
  2084. }
  2085. }
  2086. if let Some(off) = self.end_offset {
  2087. // 判断当前簇是否是要求停止搜索的最后一个位置
  2088. self.fin = off == self.current_offset;
  2089. }
  2090. // 更新当前迭代的偏移量
  2091. self.current_offset = (new_cluster, new_offset);
  2092. self.index += 1;
  2093. return Some(r);
  2094. }
  2095. }
  2096. /// @brief 根据磁盘内字节偏移量,读取磁盘,并生成一个FATRawDirEntry对象
  2097. pub fn get_raw_dir_entry(
  2098. fs: &Arc<FATFileSystem>,
  2099. in_disk_bytes_offset: u64,
  2100. ) -> Result<FATRawDirEntry, SystemError> {
  2101. // 块内偏移量
  2102. let blk_offset: u64 = fs.get_in_block_offset(in_disk_bytes_offset);
  2103. let lba = fs.get_lba_from_offset(
  2104. fs.bytes_to_sector(fs.get_in_partition_bytes_offset(in_disk_bytes_offset)),
  2105. );
  2106. // let step1 = fs.get_in_partition_bytes_offset(in_disk_bytes_offset);
  2107. // let step2 = fs.bytes_to_sector(step1);
  2108. // let lba = fs.get_lba_from_offset(step2);
  2109. // kdebug!("step1={step1}, step2={step2}, lba={lba}");
  2110. let mut v: Vec<u8> = Vec::new();
  2111. v.resize(1 * LBA_SIZE, 0);
  2112. fs.partition.disk().read_at(lba, 1, &mut v)?;
  2113. let mut cursor: VecCursor = VecCursor::new(v);
  2114. // 切换游标到对应位置
  2115. cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
  2116. let dir_0 = cursor.read_u8()?;
  2117. match dir_0 {
  2118. 0x00 => {
  2119. return Ok(FATRawDirEntry::FreeRest);
  2120. }
  2121. 0xe5 => {
  2122. return Ok(FATRawDirEntry::Free);
  2123. }
  2124. _ => {
  2125. cursor.seek(SeekFrom::SeekCurrent(10))?;
  2126. let file_attr: FileAttributes = FileAttributes::new(cursor.read_u8()?);
  2127. // 指针回到目录项的开始处
  2128. cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
  2129. if file_attr.contains(FileAttributes::LONG_NAME) {
  2130. // 当前目录项是一个长目录项
  2131. let mut long_dentry = LongDirEntry::default();
  2132. long_dentry.ord = cursor.read_u8()?;
  2133. cursor.read_u16_into(&mut long_dentry.name1)?;
  2134. long_dentry.file_attrs = FileAttributes::new(cursor.read_u8()?);
  2135. long_dentry.dirent_type = cursor.read_u8()?;
  2136. long_dentry.checksum = cursor.read_u8()?;
  2137. cursor.read_u16_into(&mut long_dentry.name2)?;
  2138. long_dentry.first_clus_low = cursor.read_u16()?;
  2139. cursor.read_u16_into(&mut long_dentry.name3)?;
  2140. return Ok(FATRawDirEntry::Long(long_dentry));
  2141. } else {
  2142. // 当前目录项是一个短目录项
  2143. let mut short_dentry = ShortDirEntry::default();
  2144. cursor.read_exact(&mut short_dentry.name)?;
  2145. short_dentry.attributes = FileAttributes::new(cursor.read_u8()?);
  2146. short_dentry.nt_res = cursor.read_u8()?;
  2147. short_dentry.crt_time_tenth = cursor.read_u8()?;
  2148. short_dentry.crt_time = cursor.read_u16()?;
  2149. short_dentry.crt_date = cursor.read_u16()?;
  2150. short_dentry.lst_acc_date = cursor.read_u16()?;
  2151. short_dentry.fst_clus_hi = cursor.read_u16()?;
  2152. short_dentry.wrt_time = cursor.read_u16()?;
  2153. short_dentry.wrt_date = cursor.read_u16()?;
  2154. short_dentry.fst_clus_lo = cursor.read_u16()?;
  2155. short_dentry.file_size = cursor.read_u32()?;
  2156. return Ok(FATRawDirEntry::Short(short_dentry));
  2157. }
  2158. }
  2159. }
  2160. }