My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SdBaseFile.cpp 69KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #if __GNUC__ > 8
  23. #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
  24. #endif
  25. /**
  26. * sd/SdBaseFile.cpp
  27. *
  28. * Arduino SdFat Library
  29. * Copyright (c) 2009 by William Greiman
  30. *
  31. * This file is part of the Arduino Sd2Card Library
  32. */
  33. #include "../inc/MarlinConfig.h"
  34. #if ENABLED(SDSUPPORT)
  35. #include "SdBaseFile.h"
  36. #include "../MarlinCore.h"
  37. SdBaseFile *SdBaseFile::cwd_ = 0; // Pointer to Current Working Directory
  38. // callback function for date/time
  39. void (*SdBaseFile::dateTime_)(uint16_t *date, uint16_t *time) = 0;
  40. // add a cluster to a file
  41. bool SdBaseFile::addCluster() {
  42. if (ENABLED(SDCARD_READONLY)) return false;
  43. if (!vol_->allocContiguous(1, &curCluster_)) return false;
  44. // if first cluster of file link to directory entry
  45. if (firstCluster_ == 0) {
  46. firstCluster_ = curCluster_;
  47. flags_ |= F_FILE_DIR_DIRTY;
  48. }
  49. return true;
  50. }
  51. // Add a cluster to a directory file and zero the cluster.
  52. // return with first block of cluster in the cache
  53. bool SdBaseFile::addDirCluster() {
  54. if (ENABLED(SDCARD_READONLY)) return false;
  55. uint32_t block;
  56. // max folder size
  57. if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false;
  58. if (!addCluster()) return false;
  59. if (!vol_->cacheFlush()) return false;
  60. block = vol_->clusterStartBlock(curCluster_);
  61. // set cache to first block of cluster
  62. vol_->cacheSetBlockNumber(block, true);
  63. // zero first block of cluster
  64. memset(vol_->cacheBuffer_.data, 0, 512);
  65. // zero rest of cluster
  66. for (uint8_t i = 1; i < vol_->blocksPerCluster_; i++) {
  67. if (!vol_->writeBlock(block + i, vol_->cacheBuffer_.data)) return false;
  68. }
  69. // Increase directory file size by cluster size
  70. fileSize_ += 512UL << vol_->clusterSizeShift_;
  71. return true;
  72. }
  73. // cache a file's directory entry
  74. // cache the current "dirBlock_" and return the entry at index "dirIndex_"
  75. // return pointer to cached entry or null for failure
  76. dir_t* SdBaseFile::cacheDirEntry(uint8_t action) {
  77. if (!vol_->cacheRawBlock(dirBlock_, action)) return nullptr;
  78. return vol_->cache()->dir + dirIndex_;
  79. }
  80. /**
  81. * Close a file and force cached data and directory information
  82. * to be written to the storage device.
  83. *
  84. * \return true for success, false for failure.
  85. * Reasons for failure include no file is open or an I/O error.
  86. */
  87. bool SdBaseFile::close() {
  88. bool rtn = sync();
  89. type_ = FAT_FILE_TYPE_CLOSED;
  90. return rtn;
  91. }
  92. /**
  93. * Check for contiguous file and return its raw block range.
  94. *
  95. * \param[out] bgnBlock the first block address for the file.
  96. * \param[out] endBlock the last block address for the file.
  97. *
  98. * \return true for success, false for failure.
  99. * Reasons for failure include file is not contiguous, file has zero length
  100. * or an I/O error occurred.
  101. */
  102. bool SdBaseFile::contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock) {
  103. // error if no blocks
  104. if (firstCluster_ == 0) return false;
  105. for (uint32_t c = firstCluster_; ; c++) {
  106. uint32_t next;
  107. if (!vol_->fatGet(c, &next)) return false;
  108. // check for contiguous
  109. if (next != (c + 1)) {
  110. // error if not end of chain
  111. if (!vol_->isEOC(next)) return false;
  112. *bgnBlock = vol_->clusterStartBlock(firstCluster_);
  113. *endBlock = vol_->clusterStartBlock(c)
  114. + vol_->blocksPerCluster_ - 1;
  115. return true;
  116. }
  117. }
  118. return false;
  119. }
  120. /**
  121. * Create and open a new contiguous file of a specified size.
  122. *
  123. * \note This function only supports short DOS 8.3 names.
  124. * See open() for more information.
  125. *
  126. * \param[in] dirFile The directory where the file will be created.
  127. * \param[in] path A path with a valid DOS 8.3 file name.
  128. * \param[in] size The desired file size.
  129. *
  130. * \return true for success, false for failure.
  131. * Reasons for failure include \a path contains
  132. * an invalid DOS 8.3 file name, the FAT volume has not been initialized,
  133. * a file is already open, the file already exists, the root
  134. * directory is full or an I/O error.
  135. */
  136. bool SdBaseFile::createContiguous(SdBaseFile *dirFile, const char *path, uint32_t size) {
  137. if (ENABLED(SDCARD_READONLY)) return false;
  138. uint32_t count;
  139. // don't allow zero length file
  140. if (size == 0) return false;
  141. if (!open(dirFile, path, O_CREAT | O_EXCL | O_RDWR)) return false;
  142. // calculate number of clusters needed
  143. count = ((size - 1) >> (vol_->clusterSizeShift_ + 9)) + 1;
  144. // allocate clusters
  145. if (!vol_->allocContiguous(count, &firstCluster_)) {
  146. remove();
  147. return false;
  148. }
  149. fileSize_ = size;
  150. // insure sync() will update dir entry
  151. flags_ |= F_FILE_DIR_DIRTY;
  152. return sync();
  153. }
  154. /**
  155. * Return a file's directory entry.
  156. *
  157. * \param[out] dir Location for return of the file's directory entry.
  158. *
  159. * \return true for success, false for failure.
  160. */
  161. bool SdBaseFile::dirEntry(dir_t *dir) {
  162. // make sure fields on SD are correct
  163. if (!sync()) return false;
  164. // read entry
  165. dir_t *p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
  166. if (!p) return false;
  167. // copy to caller's struct
  168. memcpy(dir, p, sizeof(dir_t));
  169. return true;
  170. }
  171. /**
  172. * Format the name field of \a dir into the 13 byte array
  173. * \a name in standard 8.3 short name format.
  174. *
  175. * \param[in] dir The directory structure containing the name.
  176. * \param[out] name A 13 byte char array for the formatted name.
  177. */
  178. void SdBaseFile::dirName(const dir_t &dir, char *name) {
  179. uint8_t j = 0;
  180. LOOP_L_N(i, 11) {
  181. if (dir.name[i] == ' ')continue;
  182. if (i == 8) name[j++] = '.';
  183. name[j++] = dir.name[i];
  184. }
  185. name[j] = 0;
  186. }
  187. /**
  188. * Test for the existence of a file in a directory
  189. *
  190. * \param[in] name Name of the file to be tested for.
  191. *
  192. * The calling instance must be an open directory file.
  193. *
  194. * dirFile.exists("TOFIND.TXT") searches for "TOFIND.TXT" in the directory
  195. * dirFile.
  196. *
  197. * \return true if the file exists else false.
  198. */
  199. bool SdBaseFile::exists(const char *name) {
  200. SdBaseFile file;
  201. return file.open(this, name, O_READ);
  202. }
  203. /**
  204. * Get a string from a file.
  205. *
  206. * fgets() reads bytes from a file into the array pointed to by \a str, until
  207. * \a num - 1 bytes are read, or a delimiter is read and transferred to \a str,
  208. * or end-of-file is encountered. The string is then terminated
  209. * with a null byte.
  210. *
  211. * fgets() deletes CR, '\\r', from the string. This insures only a '\\n'
  212. * terminates the string for Windows text files which use CRLF for newline.
  213. *
  214. * \param[out] str Pointer to the array where the string is stored.
  215. * \param[in] num Maximum number of characters to be read
  216. * (including the final null byte). Usually the length
  217. * of the array \a str is used.
  218. * \param[in] delim Optional set of delimiters. The default is "\n".
  219. *
  220. * \return For success fgets() returns the length of the string in \a str.
  221. * If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
  222. **/
  223. int16_t SdBaseFile::fgets(char *str, int16_t num, char *delim) {
  224. char ch;
  225. int16_t n = 0;
  226. int16_t r = -1;
  227. while ((n + 1) < num && (r = read(&ch, 1)) == 1) {
  228. // delete CR
  229. if (ch == '\r') continue;
  230. str[n++] = ch;
  231. if (!delim) {
  232. if (ch == '\n') break;
  233. }
  234. else {
  235. if (strchr(delim, ch)) break;
  236. }
  237. }
  238. if (r < 0) {
  239. // read error
  240. return -1;
  241. }
  242. str[n] = '\0';
  243. return n;
  244. }
  245. /**
  246. * Get a file's name
  247. *
  248. * \param[out] name An array of 13 characters for the file's name.
  249. *
  250. * \return true for success, false for failure.
  251. */
  252. bool SdBaseFile::getDosName(char * const name) {
  253. if (!isOpen()) return false;
  254. if (isRoot()) {
  255. name[0] = '/';
  256. name[1] = '\0';
  257. return true;
  258. }
  259. // cache entry
  260. dir_t *p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
  261. if (!p) return false;
  262. // format name
  263. dirName(*p, name);
  264. return true;
  265. }
  266. void SdBaseFile::getpos(filepos_t *pos) {
  267. pos->position = curPosition_;
  268. pos->cluster = curCluster_;
  269. }
  270. /**
  271. * List directory contents.
  272. *
  273. * \param[in] pr Print stream for list.
  274. *
  275. * \param[in] flags The inclusive OR of
  276. *
  277. * LS_DATE - %Print file modification date
  278. *
  279. * LS_SIZE - %Print file size.
  280. *
  281. * LS_R - Recursive list of subdirectories.
  282. *
  283. * \param[in] indent Amount of space before file name. Used for recursive
  284. * list to indicate subdirectory level.
  285. */
  286. void SdBaseFile::ls(uint8_t flags, uint8_t indent) {
  287. rewind();
  288. int8_t status;
  289. while ((status = lsPrintNext(flags, indent))) {
  290. if (status > 1 && (flags & LS_R)) {
  291. uint16_t index = curPosition() / 32 - 1;
  292. SdBaseFile s;
  293. if (s.open(this, index, O_READ)) s.ls(flags, indent + 2);
  294. seekSet(32 * (index + 1));
  295. }
  296. }
  297. }
  298. // saves 32 bytes on stack for ls recursion
  299. // return 0 - EOF, 1 - normal file, or 2 - directory
  300. int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) {
  301. dir_t dir;
  302. uint8_t w = 0;
  303. while (1) {
  304. if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0;
  305. if (dir.name[0] == DIR_NAME_FREE) return 0;
  306. // skip deleted entry and entries for . and ..
  307. if (dir.name[0] != DIR_NAME_DELETED && dir.name[0] != '.'
  308. && DIR_IS_FILE_OR_SUBDIR(&dir)) break;
  309. }
  310. // indent for dir level
  311. LOOP_L_N(i, indent) SERIAL_CHAR(' ');
  312. // print name
  313. LOOP_L_N(i, 11) {
  314. if (dir.name[i] == ' ')continue;
  315. if (i == 8) {
  316. SERIAL_CHAR('.');
  317. w++;
  318. }
  319. SERIAL_CHAR(dir.name[i]);
  320. w++;
  321. }
  322. if (DIR_IS_SUBDIR(&dir)) {
  323. SERIAL_CHAR('/');
  324. w++;
  325. }
  326. if (flags & (LS_DATE | LS_SIZE)) {
  327. while (w++ < 14) SERIAL_CHAR(' ');
  328. }
  329. // print modify date/time if requested
  330. if (flags & LS_DATE) {
  331. SERIAL_CHAR(' ');
  332. printFatDate(dir.lastWriteDate);
  333. SERIAL_CHAR(' ');
  334. printFatTime(dir.lastWriteTime);
  335. }
  336. // print size if requested
  337. if (!DIR_IS_SUBDIR(&dir) && (flags & LS_SIZE)) {
  338. SERIAL_CHAR(' ');
  339. SERIAL_ECHO(dir.fileSize);
  340. }
  341. SERIAL_EOL();
  342. return DIR_IS_FILE(&dir) ? 1 : 2;
  343. }
  344. /**
  345. * Calculate a checksum for an 8.3 filename
  346. *
  347. * \param name The 8.3 file name to calculate
  348. *
  349. * \return The checksum byte
  350. */
  351. uint8_t lfn_checksum(const uint8_t *name) {
  352. uint8_t sum = 0;
  353. for (uint8_t i = 11; i; i--)
  354. sum = ((sum & 1) << 7) + (sum >> 1) + *name++;
  355. return sum;
  356. }
  357. // Format directory name field from a 8.3 name string
  358. bool SdBaseFile::make83Name(const char *str, uint8_t *name, const char **ptr) {
  359. uint8_t n = 7, // Max index until a dot is found
  360. i = 11;
  361. while (i) name[--i] = ' '; // Set whole FILENAME.EXT to spaces
  362. while (*str && *str != '/') { // For each character, until nul or '/'
  363. uint8_t c = *str++; // Get char and advance
  364. if (c == '.') { // For a dot...
  365. if (n == 10) return false; // Already moved the max index? fail!
  366. n = 10; // Move the max index for full 8.3 name
  367. i = 8; // Move up to the extension place
  368. }
  369. else {
  370. // Fail for illegal characters
  371. PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
  372. while (uint8_t b = pgm_read_byte(p++)) if (b == c) return false;
  373. if (i > n || c < 0x21 || c == 0x7F) return false; // Check size, non-printable characters
  374. name[i++] = c + (WITHIN(c, 'a', 'z') ? 'A' - 'a' : 0); // Uppercase required for 8.3 name
  375. }
  376. }
  377. *ptr = str; // Set passed pointer to the end
  378. return name[0] != ' '; // Return true if any name was set
  379. }
  380. /**
  381. * Make a new directory.
  382. *
  383. * \param[in] parent An open SdFat instance for the directory that will contain
  384. * the new directory.
  385. *
  386. * \param[in] path A path with a valid 8.3 DOS name for the new directory.
  387. *
  388. * \param[in] pFlag Create missing parent directories if true.
  389. *
  390. * \return true for success, false for failure.
  391. * Reasons for failure include this file is already open, \a parent is not a
  392. * directory, \a path is invalid or already exists in \a parent.
  393. */
  394. bool SdBaseFile::mkdir(SdBaseFile *parent, const char *path, bool pFlag) {
  395. if (ENABLED(SDCARD_READONLY)) return false;
  396. uint8_t dname[11];
  397. SdBaseFile dir1, dir2;
  398. SdBaseFile *sub = &dir1;
  399. SdBaseFile *start = parent;
  400. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  401. uint8_t dlname[LONG_FILENAME_LENGTH];
  402. #endif
  403. if (!parent || isOpen()) return false;
  404. if (*path == '/') {
  405. while (*path == '/') path++;
  406. if (!parent->isRoot()) {
  407. if (!dir2.openRoot(parent->vol_)) return false;
  408. parent = &dir2;
  409. }
  410. }
  411. for (;;) {
  412. if (!TERN(LONG_FILENAME_WRITE_SUPPORT, parsePath(path, dname, dlname, &path), make83Name(path, dname, &path))) return false;
  413. while (*path == '/') path++;
  414. if (!*path) break;
  415. if (!sub->open(parent, dname OPTARG(LONG_FILENAME_WRITE_SUPPORT, dlname), O_READ)) {
  416. if (!pFlag || !sub->mkdir(parent, dname OPTARG(LONG_FILENAME_WRITE_SUPPORT, dlname)))
  417. return false;
  418. }
  419. if (parent != start) parent->close();
  420. parent = sub;
  421. sub = parent != &dir1 ? &dir1 : &dir2;
  422. }
  423. return mkdir(parent, dname OPTARG(LONG_FILENAME_WRITE_SUPPORT, dlname));
  424. }
  425. bool SdBaseFile::mkdir(SdBaseFile *parent, const uint8_t dname[11]
  426. OPTARG(LONG_FILENAME_WRITE_SUPPORT, const uint8_t dlname[LONG_FILENAME_LENGTH])
  427. ) {
  428. if (ENABLED(SDCARD_READONLY)) return false;
  429. if (!parent->isDir()) return false;
  430. // create a normal file
  431. if (!open(parent, dname OPTARG(LONG_FILENAME_WRITE_SUPPORT, dlname), O_CREAT | O_EXCL | O_RDWR)) return false;
  432. // convert file to directory
  433. flags_ = O_READ;
  434. type_ = FAT_FILE_TYPE_SUBDIR;
  435. // allocate and zero first cluster
  436. if (!addDirCluster()) return false;
  437. // force entry to SD
  438. if (!sync()) return false;
  439. // cache entry - should already be in cache due to sync() call
  440. dir_t *p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  441. if (!p) return false;
  442. // change directory entry attribute
  443. p->attributes = DIR_ATT_DIRECTORY;
  444. // make entry for '.'
  445. dir_t d;
  446. memcpy(&d, p, sizeof(d));
  447. d.name[0] = '.';
  448. LOOP_S_L_N(i, 1, 11) d.name[i] = ' ';
  449. // cache block for '.' and '..'
  450. uint32_t block = vol_->clusterStartBlock(firstCluster_);
  451. if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false;
  452. // copy '.' to block
  453. memcpy(&vol_->cache()->dir[0], &d, sizeof(d));
  454. // make entry for '..'
  455. d.name[1] = '.';
  456. if (parent->isRoot()) {
  457. d.firstClusterLow = 0;
  458. d.firstClusterHigh = 0;
  459. }
  460. else {
  461. d.firstClusterLow = parent->firstCluster_ & 0xFFFF;
  462. d.firstClusterHigh = parent->firstCluster_ >> 16;
  463. }
  464. // copy '..' to block
  465. memcpy(&vol_->cache()->dir[1], &d, sizeof(d));
  466. // write first block
  467. return vol_->cacheFlush();
  468. }
  469. /**
  470. * Open a file in the current working directory.
  471. *
  472. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  473. *
  474. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  475. * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t).
  476. *
  477. * \return true for success, false for failure.
  478. */
  479. bool SdBaseFile::open(const char *path, uint8_t oflag) {
  480. return open(cwd_, path, oflag);
  481. }
  482. /**
  483. * Open a file or directory by name.
  484. *
  485. * \param[in] dirFile An open SdFat instance for the directory containing the
  486. * file to be opened.
  487. *
  488. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  489. *
  490. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  491. * OR of flags from the following list
  492. *
  493. * O_READ - Open for reading.
  494. *
  495. * O_RDONLY - Same as O_READ.
  496. *
  497. * O_WRITE - Open for writing.
  498. *
  499. * O_WRONLY - Same as O_WRITE.
  500. *
  501. * O_RDWR - Open for reading and writing.
  502. *
  503. * O_APPEND - If set, the file offset shall be set to the end of the
  504. * file prior to each write.
  505. *
  506. * O_AT_END - Set the initial position at the end of the file.
  507. *
  508. * O_CREAT - If the file exists, this flag has no effect except as noted
  509. * under O_EXCL below. Otherwise, the file shall be created
  510. *
  511. * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
  512. *
  513. * O_SYNC - Call sync() after each write. This flag should not be used with
  514. * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class.
  515. * These functions do character at a time writes so sync() will be called
  516. * after each byte.
  517. *
  518. * O_TRUNC - If the file exists and is a regular file, and the file is
  519. * successfully opened and is not read only, its length shall be truncated to 0.
  520. *
  521. * WARNING: A given file must not be opened by more than one SdBaseFile object
  522. * of file corruption may occur.
  523. *
  524. * \note Directory files must be opened read only. Write and truncation is
  525. * not allowed for directory files.
  526. *
  527. * \return true for success, false for failure.
  528. * Reasons for failure include this file is already open, \a dirFile is not
  529. * a directory, \a path is invalid, the file does not exist
  530. * or can't be opened in the access mode specified by oflag.
  531. */
  532. bool SdBaseFile::open(SdBaseFile *dirFile, const char *path, uint8_t oflag) {
  533. uint8_t dname[11];
  534. SdBaseFile dir1, dir2;
  535. SdBaseFile *parent = dirFile, *sub = &dir1;
  536. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  537. uint8_t dlname[LONG_FILENAME_LENGTH];
  538. #endif
  539. if (!dirFile || isOpen()) return false;
  540. if (*path == '/') { // Path starts with '/'
  541. if (!dirFile->isRoot()) { // Is the passed dirFile the root?
  542. if (!dir2.openRoot(dirFile->vol_)) return false; // Get the root in dir2, if possible
  543. parent = &dir2; // Change 'parent' to point at the root dir
  544. }
  545. while (*path == '/') path++; // Skip all leading slashes
  546. }
  547. for (;;) {
  548. if (!TERN(LONG_FILENAME_WRITE_SUPPORT, parsePath(path, dname, dlname, &path), make83Name(path, dname, &path))) return false;
  549. while (*path == '/') path++;
  550. if (!*path) break;
  551. if (TERN0(LONG_FILENAME_WRITE_SUPPORT, !sub->open(parent, dname, dlname, O_READ))) return false;
  552. if (parent != dirFile) parent->close();
  553. parent = sub;
  554. sub = parent != &dir1 ? &dir1 : &dir2;
  555. }
  556. return open(parent, dname OPTARG(LONG_FILENAME_WRITE_SUPPORT, dlname), oflag);
  557. }
  558. // open with filename in dname and long filename in dlname
  559. bool SdBaseFile::open(SdBaseFile *dirFile, const uint8_t dname[11]
  560. OPTARG(LONG_FILENAME_WRITE_SUPPORT, const uint8_t dlname[LONG_FILENAME_LENGTH])
  561. , uint8_t oflag
  562. ) {
  563. bool emptyFound = false, fileFound = false;
  564. uint8_t index = 0;
  565. dir_t *p;
  566. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  567. // LFN - Long File Name support
  568. const bool useLFN = dlname[0] != 0;
  569. bool lfnFileFound = false;
  570. vfat_t *pvFat;
  571. uint8_t emptyCount = 0,
  572. emptyIndex = 0,
  573. reqEntriesNum = useLFN ? getLFNEntriesNum((char*)dlname) + 1 : 1,
  574. lfnNameLength = useLFN ? strlen((char*)dlname) : 0,
  575. lfnName[LONG_FILENAME_LENGTH],
  576. lfnSequenceNumber = 0,
  577. lfnChecksum = 0;
  578. #endif
  579. // Rewind this dir
  580. vol_ = dirFile->vol_;
  581. dirFile->rewind();
  582. // search for file
  583. while (dirFile->curPosition_ < dirFile->fileSize_) {
  584. // Get absolute index position
  585. index = (dirFile->curPosition_ >> 5) IF_DISABLED(LONG_FILENAME_WRITE_SUPPORT, & 0x0F);
  586. // Get next entry
  587. if (!(p = dirFile->readDirCache())) return false;
  588. // Check empty status: Is entry empty?
  589. if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) {
  590. // Count the contiguous available entries in which (eventually) fit the new dir entry, if it's a write operation
  591. if (!emptyFound) {
  592. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  593. if (emptyCount == 0) emptyIndex = index;
  594. // Incr empty entries counter
  595. // If found the required empty entries, mark it
  596. if (++emptyCount == reqEntriesNum) {
  597. dirBlock_ = dirFile->vol_->cacheBlockNumber();
  598. dirIndex_ = index & 0xF;
  599. emptyFound = true;
  600. }
  601. #else
  602. dirBlock_ = dirFile->vol_->cacheBlockNumber();
  603. dirIndex_ = index;
  604. emptyFound = true;
  605. #endif
  606. }
  607. // Done if no entries follow
  608. if (p->name[0] == DIR_NAME_FREE) break;
  609. }
  610. else { // Entry not empty
  611. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  612. // Reset empty counter
  613. if (!emptyFound) emptyCount = 0;
  614. // Search for SFN or LFN?
  615. if (!useLFN) {
  616. // Check using SFN: file found?
  617. if (!memcmp(dname, p->name, 11)) {
  618. fileFound = true;
  619. break;
  620. }
  621. }
  622. else {
  623. // Check using LFN: LFN not found? continue search for LFN
  624. if (!lfnFileFound) {
  625. // Is this dir a LFN?
  626. if (isDirLFN(p)) {
  627. // Get VFat dir entry
  628. pvFat = (vfat_t *) p;
  629. // Get checksum from the last entry of the sequence
  630. if (pvFat->sequenceNumber & 0x40) lfnChecksum = pvFat->checksum;
  631. // Get LFN sequence number
  632. lfnSequenceNumber = pvFat->sequenceNumber & 0x1F;
  633. if WITHIN(lfnSequenceNumber, 1, reqEntriesNum) {
  634. // Check checksum for all other entries with the starting checksum fetched before
  635. if (lfnChecksum == pvFat->checksum) {
  636. // Set chunk of LFN from VFAT entry into lfnName
  637. getLFNName(pvFat, (char *)lfnName, lfnSequenceNumber);
  638. // LFN found?
  639. if (!strncasecmp((char*)dlname, (char*)lfnName, lfnNameLength)) lfnFileFound = true;
  640. }
  641. }
  642. }
  643. }
  644. else { // Complete LFN found, check for related SFN
  645. // Check if only the SFN checksum match because the filename may be different due to different truncation methods
  646. if (!isDirLFN(p) && (lfnChecksum == lfn_checksum(p->name))) {
  647. fileFound = true;
  648. break;
  649. }
  650. else lfnFileFound = false; // SFN not valid for the LFN found, reset LFN FileFound
  651. }
  652. }
  653. #else
  654. if (!memcmp(dname, p->name, 11)) {
  655. fileFound = true;
  656. break;
  657. }
  658. #endif // LONG_FILENAME_WRITE_SUPPORT
  659. }
  660. }
  661. if (fileFound) {
  662. // don't open existing file if O_EXCL
  663. if (oflag & O_EXCL) return false;
  664. TERN_(LONG_FILENAME_WRITE_SUPPORT, index &= 0xF);
  665. }
  666. else {
  667. // don't create unless O_CREAT and O_WRITE
  668. if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
  669. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  670. // Use bookmark index if found empty entries
  671. if (emptyFound) index = emptyIndex;
  672. // Make room for needed entries
  673. while (emptyCount < reqEntriesNum) {
  674. p = dirFile->readDirCache();
  675. if (!p) break;
  676. emptyCount++;
  677. }
  678. while (emptyCount < reqEntriesNum) {
  679. if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) return false;
  680. // add and zero cluster for dirFile - first cluster is in cache for write
  681. if (!dirFile->addDirCluster()) return false;
  682. emptyCount += dirFile->vol_->blocksPerCluster() * 16;
  683. }
  684. // Move to 1st entry to write
  685. if (!dirFile->seekSet(32 * index)) return false;
  686. // Dir entries write loop: [LFN] + SFN(1)
  687. LOOP_L_N(dirWriteIdx, reqEntriesNum) {
  688. index = (dirFile->curPosition_ / 32) & 0xF;
  689. p = dirFile->readDirCache();
  690. // LFN or SFN Entry?
  691. if (dirWriteIdx < reqEntriesNum - 1) {
  692. // Write LFN Entries
  693. pvFat = (vfat_t *) p;
  694. // initialize as empty file
  695. memset(pvFat, 0, sizeof(*pvFat));
  696. lfnSequenceNumber = (reqEntriesNum - dirWriteIdx - 1) & 0x1F;
  697. pvFat->attributes = DIR_ATT_LONG_NAME;
  698. pvFat->checksum = lfn_checksum(dname);
  699. // Set sequence number and mark as last LFN entry if it's the 1st loop
  700. pvFat->sequenceNumber = lfnSequenceNumber | (dirWriteIdx == 0 ? 0x40 : 0);
  701. // Set LFN name block
  702. setLFNName(pvFat, (char*)dlname, lfnSequenceNumber);
  703. }
  704. else {
  705. // Write SFN Entry
  706. // initialize as empty file
  707. memset(p, 0, sizeof(*p));
  708. memcpy(p->name, dname, 11);
  709. // set timestamps
  710. if (dateTime_) {
  711. // call user date/time function
  712. dateTime_(&p->creationDate, &p->creationTime);
  713. }
  714. else {
  715. // use default date/time
  716. p->creationDate = FAT_DEFAULT_DATE;
  717. p->creationTime = FAT_DEFAULT_TIME;
  718. }
  719. p->lastAccessDate = p->creationDate;
  720. p->lastWriteDate = p->creationDate;
  721. p->lastWriteTime = p->creationTime;
  722. }
  723. // write entry to SD
  724. dirFile->vol_->cacheSetDirty();
  725. if (!dirFile->vol_->cacheFlush()) return false;
  726. }
  727. #else // !LONG_FILENAME_WRITE_SUPPORT
  728. if (emptyFound) {
  729. index = dirIndex_;
  730. p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  731. if (!p) return false;
  732. }
  733. else {
  734. if (dirFile->type_ == FAT_FILE_TYPE_ROOT_FIXED) return false;
  735. // add and zero cluster for dirFile - first cluster is in cache for write
  736. if (!dirFile->addDirCluster()) return false;
  737. // use first entry in cluster
  738. p = dirFile->vol_->cache()->dir;
  739. index = 0;
  740. }
  741. // initialize as empty file
  742. memset(p, 0, sizeof(*p));
  743. memcpy(p->name, dname, 11);
  744. // set timestamps
  745. if (dateTime_) {
  746. // call user date/time function
  747. dateTime_(&p->creationDate, &p->creationTime);
  748. }
  749. else {
  750. // use default date/time
  751. p->creationDate = FAT_DEFAULT_DATE;
  752. p->creationTime = FAT_DEFAULT_TIME;
  753. }
  754. p->lastAccessDate = p->creationDate;
  755. p->lastWriteDate = p->creationDate;
  756. p->lastWriteTime = p->creationTime;
  757. // write entry to SD
  758. if (!dirFile->vol_->cacheFlush()) return false;
  759. #endif // !LONG_FILENAME_WRITE_SUPPORT
  760. }
  761. // open entry in cache
  762. return openCachedEntry(index, oflag);
  763. }
  764. /**
  765. * Open a file by index.
  766. *
  767. * \param[in] dirFile An open SdFat instance for the directory.
  768. *
  769. * \param[in] index The \a index of the directory entry for the file to be
  770. * opened. The value for \a index is (directory file position)/32.
  771. *
  772. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  773. * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
  774. *
  775. * See open() by path for definition of flags.
  776. * \return true for success or false for failure.
  777. */
  778. bool SdBaseFile::open(SdBaseFile *dirFile, uint16_t index, uint8_t oflag) {
  779. vol_ = dirFile->vol_;
  780. // error if already open
  781. if (isOpen() || !dirFile) return false;
  782. // don't open existing file if O_EXCL - user call error
  783. if (oflag & O_EXCL) return false;
  784. // seek to location of entry
  785. if (!dirFile->seekSet(32 * index)) return false;
  786. // read entry into cache
  787. dir_t *p = dirFile->readDirCache();
  788. if (!p) return false;
  789. // error if empty slot or '.' or '..'
  790. if (p->name[0] == DIR_NAME_FREE ||
  791. p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
  792. return false;
  793. }
  794. // open cached entry
  795. return openCachedEntry(index & 0xF, oflag);
  796. }
  797. // open a cached directory entry. Assumes vol_ is initialized
  798. bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
  799. dir_t *p;
  800. #if ENABLED(SDCARD_READONLY)
  801. if (oflag & (O_WRITE | O_CREAT | O_TRUNC)) goto FAIL;
  802. #endif
  803. // location of entry in cache
  804. p = &vol_->cache()->dir[dirIndex];
  805. // write or truncate is an error for a directory or read-only file
  806. if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
  807. if (oflag & (O_WRITE | O_TRUNC)) goto FAIL;
  808. }
  809. // remember location of directory entry on SD
  810. dirBlock_ = vol_->cacheBlockNumber();
  811. dirIndex_ = dirIndex;
  812. // copy first cluster number for directory fields
  813. firstCluster_ = (uint32_t)p->firstClusterHigh << 16;
  814. firstCluster_ |= p->firstClusterLow;
  815. // make sure it is a normal file or subdirectory
  816. if (DIR_IS_FILE(p)) {
  817. fileSize_ = p->fileSize;
  818. type_ = FAT_FILE_TYPE_NORMAL;
  819. }
  820. else if (DIR_IS_SUBDIR(p)) {
  821. if (!vol_->chainSize(firstCluster_, &fileSize_)) goto FAIL;
  822. type_ = FAT_FILE_TYPE_SUBDIR;
  823. }
  824. else
  825. goto FAIL;
  826. // save open flags for read/write
  827. flags_ = oflag & F_OFLAG;
  828. // set to start of file
  829. curCluster_ = 0;
  830. curPosition_ = 0;
  831. if ((oflag & O_TRUNC) && !truncate(0)) return false;
  832. return oflag & O_AT_END ? seekEnd(0) : true;
  833. FAIL:
  834. type_ = FAT_FILE_TYPE_CLOSED;
  835. return false;
  836. }
  837. /**
  838. * Open the next file or subdirectory in a directory.
  839. *
  840. * \param[in] dirFile An open SdFat instance for the directory containing the
  841. * file to be opened.
  842. *
  843. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  844. * OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
  845. *
  846. * See open() by path for definition of flags.
  847. * \return true for success or false for failure.
  848. */
  849. bool SdBaseFile::openNext(SdBaseFile *dirFile, uint8_t oflag) {
  850. if (!dirFile) return false;
  851. // error if already open
  852. if (isOpen()) return false;
  853. vol_ = dirFile->vol_;
  854. while (1) {
  855. uint8_t index = 0xF & (dirFile->curPosition_ >> 5);
  856. // read entry into cache
  857. dir_t *p = dirFile->readDirCache();
  858. if (!p) return false;
  859. // done if last entry
  860. if (p->name[0] == DIR_NAME_FREE) return false;
  861. // skip empty slot or '.' or '..'
  862. if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') {
  863. continue;
  864. }
  865. // must be file or dir
  866. if (DIR_IS_FILE_OR_SUBDIR(p)) {
  867. return openCachedEntry(index, oflag);
  868. }
  869. }
  870. return false;
  871. }
  872. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  873. /**
  874. * Check if dir is a long file name entry (LFN)
  875. *
  876. * \param[in] dir Parent of this directory will be opened. Must not be root.
  877. * \return true if the dir is a long file name entry (LFN)
  878. */
  879. bool SdBaseFile::isDirLFN(const dir_t* dir) {
  880. if (DIR_IS_LONG_NAME(dir)) {
  881. vfat_t *VFAT = (vfat_t*)dir;
  882. // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
  883. if ((VFAT->firstClusterLow == 0) && WITHIN((VFAT->sequenceNumber & 0x1F), 1, MAX_VFAT_ENTRIES)) return true;
  884. }
  885. return false;
  886. }
  887. /**
  888. * Check if dirname string is a long file name (LFN)
  889. *
  890. * \param[in] dirname The string to check
  891. * \return true if the dirname is a long file name (LFN)
  892. * \return false if the dirname is a short file name 8.3 (SFN)
  893. */
  894. bool SdBaseFile::isDirNameLFN(const char *dirname) {
  895. uint8_t length = strlen(dirname);
  896. uint8_t idx = length;
  897. bool dotFound = false;
  898. if (idx > 12) return true; // LFN due to filename length > 12 ("filename.ext")
  899. // Check dot(s) position
  900. while (idx) {
  901. if (dirname[--idx] == '.') {
  902. if (!dotFound) {
  903. // Last dot (extension) is allowed only
  904. // in position [1..8] from start or [0..3] from end for SFN else it's a LFN
  905. // A filename starting with "." is a LFN (eg. ".file" ->in SFN-> "file~1 ")
  906. // A filename ending with "." is a SFN (if length <= 9) (eg. "file." ->in SFN-> "file ")
  907. if (idx > 8 || idx == 0 || (length - idx - 1) > 3) return true; // LFN due to dot extension position
  908. dotFound = true;
  909. }
  910. else {
  911. // Found another dot, is a LFN
  912. return true;
  913. }
  914. }
  915. }
  916. // If no dots found, the filename must be of max 8 characters
  917. if ((!dotFound) && length > 8) return true; // LFN due to max filename (without extension) length
  918. return false;
  919. }
  920. /**
  921. * Parse path and return 8.3 format and LFN filenames (if the parsed path is a LFN)
  922. * The SFN is without dot ("FILENAMEEXT")
  923. * The LFN is complete ("Filename.ext")
  924. */
  925. bool SdBaseFile::parsePath(const char *path, uint8_t *name, uint8_t *lname, const char **ptrNextPath) {
  926. // Init randomizer for SFN generation
  927. randomSeed(millis());
  928. // Parse the LFN
  929. uint8_t ilfn = 0;
  930. bool lastDotFound = false;
  931. const char *pLastDot = 0;
  932. const char *lfnpath = path;
  933. uint8_t c;
  934. while (*lfnpath && *lfnpath != '/') {
  935. if (ilfn == LONG_FILENAME_LENGTH - 1) return false; // Name too long
  936. c = *lfnpath++; // Get char and advance
  937. // Fail for illegal characters
  938. PGM_P p = PSTR("|<>^+=?/[];:,*\"\\");
  939. while (uint8_t b = pgm_read_byte(p++)) if (b == c) return false; // Check reserved characters
  940. if (c < 0x20 || c == 0x7F) return false; // Check non-printable characters
  941. if (c == '.' && (lfnpath - 1) > path) { // Skip dot '.' check in 1st position
  942. // Save last dot pointer (skip if starts with '.')
  943. pLastDot = lfnpath - 1;
  944. lastDotFound = true;
  945. }
  946. lname[ilfn++] = c; // Set LFN character
  947. }
  948. // Terminate LFN
  949. lname[ilfn] = 0;
  950. // Parse/generate 8.3 SFN. Will take
  951. // until 8 characters for the filename part
  952. // until 3 characters for the extension part (if exists)
  953. // Add 4 more characters if name part < 3
  954. // Add '~cnt' characters if it's a LFN
  955. const bool isLFN = isDirNameLFN((char*)lname);
  956. uint8_t n = isLFN ? 5 : 7, // Max index for each component of the file:
  957. // starting with 7 or 5 (if LFN)
  958. // switch to 10 for extension if the last dot is found
  959. i = 11;
  960. while (i) name[--i] = ' '; // Set whole FILENAMEEXT to spaces
  961. while (*path && *path != '/') {
  962. c = *path++; // Get char and advance
  963. // Skip spaces and dots (if it's not the last dot)
  964. if (c == ' ') continue;
  965. if (c == '.' && (!lastDotFound || (lastDotFound && path < pLastDot))) continue;
  966. // Fail for illegal characters
  967. PGM_P p = PSTR("|<>^+=?/[];:,*\"\\");
  968. while (uint8_t b = pgm_read_byte(p++)) if (b == c) return false; // Check reserved characters
  969. if (c < 0x21 || c == 0x7F) return false; // Check non-printable characters
  970. // Is last dot?
  971. if (c == '.') {
  972. // Switch to extension part
  973. n = 10;
  974. i = 8;
  975. }
  976. // If in valid range add the character
  977. else if (i <= n) // Check size for 8.3 format
  978. name[i++] = c + (WITHIN(c, 'a', 'z') ? 'A' - 'a' : 0); // Uppercase required for 8.3 name
  979. }
  980. // If it's a LFN then the SFN always need:
  981. // - A minimal of 3 characters (otherwise 4 chars are added)
  982. // - The '~cnt' at the end
  983. if (isLFN) {
  984. // Get the 1st free character
  985. uint8_t iFree = 0;
  986. while (1) if (name[iFree++] == ' ' || iFree == 11) break;
  987. iFree--;
  988. // Check minimal length
  989. if (iFree < 3) {
  990. // Append 4 extra characters
  991. name[iFree++] = random(0,24) + 'A'; name[iFree++] = random(0,24) + 'A';
  992. name[iFree++] = random(0,24) + 'A'; name[iFree++] = random(0,24) + 'A';
  993. }
  994. // Append '~cnt' characters
  995. if (iFree > 5) iFree = 5; // Force the append in the last 3 characters of name part
  996. name[iFree++] = '~';
  997. name[iFree++] = random(1,9) + '0';
  998. name[iFree++] = random(1,9) + '0';
  999. }
  1000. // Check if LFN is needed
  1001. if (!isLFN) lname[0] = 0; // Zero LFN
  1002. *ptrNextPath = path; // Set passed pointer to the end
  1003. return name[0] != ' '; // Return true if any name was set
  1004. }
  1005. /**
  1006. * Get the LFN filename block from a dir. Get the block in lname at startOffset
  1007. */
  1008. void SdBaseFile::getLFNName(vfat_t *pFatDir, char *lname, uint8_t sequenceNumber) {
  1009. uint8_t startOffset = (sequenceNumber - 1) * FILENAME_LENGTH;
  1010. LOOP_L_N(i, FILENAME_LENGTH) {
  1011. const uint16_t utf16_ch = (i >= 11) ? pFatDir->name3[i - 11] : (i >= 5) ? pFatDir->name2[i - 5] : pFatDir->name1[i];
  1012. #if ENABLED(UTF_FILENAME_SUPPORT)
  1013. // We can't reconvert to UTF-8 here as UTF-8 is variable-size encoding, but joining LFN blocks
  1014. // needs static bytes addressing. So here just store full UTF-16LE words to re-convert later.
  1015. uint16_t idx = (startOffset + i) * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding
  1016. lname[idx] = utf16_ch & 0xFF;
  1017. lname[idx + 1] = (utf16_ch >> 8) & 0xFF;
  1018. #else
  1019. // Replace all multibyte characters to '_'
  1020. lname[startOffset + i] = (utf16_ch > 0xFF) ? '_' : (utf16_ch & 0xFF);
  1021. #endif
  1022. }
  1023. }
  1024. /**
  1025. * Set the LFN filename block lname to a dir. Put the block based on sequence number
  1026. */
  1027. void SdBaseFile::setLFNName(vfat_t *pFatDir, char *lname, uint8_t sequenceNumber) {
  1028. uint8_t startOffset = (sequenceNumber - 1) * FILENAME_LENGTH;
  1029. uint8_t nameLength = strlen(lname);
  1030. LOOP_L_N(i, FILENAME_LENGTH) {
  1031. uint16_t ch = 0;
  1032. if ((startOffset + i) < nameLength)
  1033. ch = lname[startOffset + i];
  1034. else if ((startOffset + i) > nameLength)
  1035. ch = 0xFFFF;
  1036. // Set char
  1037. if (i < 5)
  1038. pFatDir->name1[i] = ch;
  1039. else if (i < 11)
  1040. pFatDir->name2[i - 5] = ch;
  1041. else
  1042. pFatDir->name3[i - 11] = ch;
  1043. }
  1044. }
  1045. #endif // LONG_FILENAME_WRITE_SUPPORT
  1046. #if 0
  1047. /**
  1048. * Open a directory's parent directory.
  1049. *
  1050. * \param[in] dir Parent of this directory will be opened. Must not be root.
  1051. *
  1052. * \return true for success, false for failure.
  1053. */
  1054. bool SdBaseFile::openParent(SdBaseFile *dir) {
  1055. dir_t entry;
  1056. SdBaseFile file;
  1057. uint32_t c;
  1058. uint32_t cluster;
  1059. uint32_t lbn;
  1060. // error if already open or dir is root or dir is not a directory
  1061. if (isOpen() || !dir || dir->isRoot() || !dir->isDir()) return false;
  1062. vol_ = dir->vol_;
  1063. // position to '..'
  1064. if (!dir->seekSet(32)) return false;
  1065. // read '..' entry
  1066. if (dir->read(&entry, sizeof(entry)) != 32) return false;
  1067. // verify it is '..'
  1068. if (entry.name[0] != '.' || entry.name[1] != '.') return false;
  1069. // start cluster for '..'
  1070. cluster = entry.firstClusterLow;
  1071. cluster |= (uint32_t)entry.firstClusterHigh << 16;
  1072. if (cluster == 0) return openRoot(vol_);
  1073. // start block for '..'
  1074. lbn = vol_->clusterStartBlock(cluster);
  1075. // first block of parent dir
  1076. if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) return false;
  1077. dir_t *p = &vol_->cacheBuffer_.dir[1];
  1078. // verify name for '../..'
  1079. if (p->name[0] != '.' || p->name[1] != '.') return false;
  1080. // '..' is pointer to first cluster of parent. open '../..' to find parent
  1081. if (p->firstClusterHigh == 0 && p->firstClusterLow == 0) {
  1082. if (!file.openRoot(dir->volume())) return false;
  1083. }
  1084. else if (!file.openCachedEntry(1, O_READ))
  1085. return false;
  1086. // search for parent in '../..'
  1087. do {
  1088. if (file.readDir(&entry, nullptr) != 32) return false;
  1089. c = entry.firstClusterLow;
  1090. c |= (uint32_t)entry.firstClusterHigh << 16;
  1091. } while (c != cluster);
  1092. // open parent
  1093. return open(&file, file.curPosition() / 32 - 1, O_READ);
  1094. }
  1095. #endif
  1096. /**
  1097. * Open a volume's root directory.
  1098. *
  1099. * \param[in] vol The FAT volume containing the root directory to be opened.
  1100. *
  1101. * \return true for success, false for failure.
  1102. * Reasons for failure include the file is already open, the FAT volume has
  1103. * not been initialized or it a FAT12 volume.
  1104. */
  1105. bool SdBaseFile::openRoot(SdVolume *vol) {
  1106. // error if file is already open
  1107. if (isOpen()) return false;
  1108. if (vol->fatType() == 16 || (FAT12_SUPPORT && vol->fatType() == 12)) {
  1109. type_ = FAT_FILE_TYPE_ROOT_FIXED;
  1110. firstCluster_ = 0;
  1111. fileSize_ = 32 * vol->rootDirEntryCount();
  1112. }
  1113. else if (vol->fatType() == 32) {
  1114. type_ = FAT_FILE_TYPE_ROOT32;
  1115. firstCluster_ = vol->rootDirStart();
  1116. if (!vol->chainSize(firstCluster_, &fileSize_)) return false;
  1117. }
  1118. else // volume is not initialized, invalid, or FAT12 without support
  1119. return false;
  1120. vol_ = vol;
  1121. // read only
  1122. flags_ = O_READ;
  1123. // set to start of file
  1124. curCluster_ = curPosition_ = 0;
  1125. // root has no directory entry
  1126. dirBlock_ = dirIndex_ = 0;
  1127. return true;
  1128. }
  1129. /**
  1130. * Return the next available byte without consuming it.
  1131. *
  1132. * \return The byte if no error and not at eof else -1;
  1133. */
  1134. int SdBaseFile::peek() {
  1135. filepos_t pos;
  1136. getpos(&pos);
  1137. int c = read();
  1138. if (c >= 0) setpos(&pos);
  1139. return c;
  1140. }
  1141. // print uint8_t with width 2
  1142. static void print2u(const uint8_t v) {
  1143. if (v < 10) SERIAL_CHAR('0');
  1144. SERIAL_ECHO(v);
  1145. }
  1146. /**
  1147. * %Print a directory date field to Serial.
  1148. *
  1149. * Format is yyyy-mm-dd.
  1150. *
  1151. * \param[in] fatDate The date field from a directory entry.
  1152. */
  1153. /**
  1154. * %Print a directory date field.
  1155. *
  1156. * Format is yyyy-mm-dd.
  1157. *
  1158. * \param[in] pr Print stream for output.
  1159. * \param[in] fatDate The date field from a directory entry.
  1160. */
  1161. void SdBaseFile::printFatDate(uint16_t fatDate) {
  1162. SERIAL_ECHO(FAT_YEAR(fatDate));
  1163. SERIAL_CHAR('-');
  1164. print2u(FAT_MONTH(fatDate));
  1165. SERIAL_CHAR('-');
  1166. print2u(FAT_DAY(fatDate));
  1167. }
  1168. /**
  1169. * %Print a directory time field.
  1170. *
  1171. * Format is hh:mm:ss.
  1172. *
  1173. * \param[in] pr Print stream for output.
  1174. * \param[in] fatTime The time field from a directory entry.
  1175. */
  1176. void SdBaseFile::printFatTime(uint16_t fatTime) {
  1177. print2u(FAT_HOUR(fatTime));
  1178. SERIAL_CHAR(':');
  1179. print2u(FAT_MINUTE(fatTime));
  1180. SERIAL_CHAR(':');
  1181. print2u(FAT_SECOND(fatTime));
  1182. }
  1183. /**
  1184. * Print a file's name to Serial
  1185. *
  1186. * \return true for success, false for failure.
  1187. */
  1188. bool SdBaseFile::printName() {
  1189. char name[FILENAME_LENGTH];
  1190. if (!getDosName(name)) return false;
  1191. SERIAL_ECHO(name);
  1192. return true;
  1193. }
  1194. /**
  1195. * Read the next byte from a file.
  1196. *
  1197. * \return For success read returns the next byte in the file as an int.
  1198. * If an error occurs or end of file is reached -1 is returned.
  1199. */
  1200. int16_t SdBaseFile::read() {
  1201. uint8_t b;
  1202. return read(&b, 1) == 1 ? b : -1;
  1203. }
  1204. /**
  1205. * Read data from a file starting at the current position.
  1206. *
  1207. * \param[out] buf Pointer to the location that will receive the data.
  1208. *
  1209. * \param[in] nbyte Maximum number of bytes to read.
  1210. *
  1211. * \return For success read() returns the number of bytes read.
  1212. * A value less than \a nbyte, including zero, will be returned
  1213. * if end of file is reached.
  1214. * If an error occurs, read() returns -1. Possible errors include
  1215. * read() called before a file has been opened, corrupt file system
  1216. * or an I/O error occurred.
  1217. */
  1218. int16_t SdBaseFile::read(void *buf, uint16_t nbyte) {
  1219. uint8_t *dst = reinterpret_cast<uint8_t*>(buf);
  1220. uint16_t offset, toRead;
  1221. uint32_t block; // raw device block number
  1222. // error if not open or write only
  1223. if (!isOpen() || !(flags_ & O_READ)) return -1;
  1224. // max bytes left in file
  1225. NOMORE(nbyte, fileSize_ - curPosition_);
  1226. // amount left to read
  1227. toRead = nbyte;
  1228. while (toRead > 0) {
  1229. offset = curPosition_ & 0x1FF; // offset in block
  1230. if (type_ == FAT_FILE_TYPE_ROOT_FIXED) {
  1231. block = vol_->rootDirStart() + (curPosition_ >> 9);
  1232. }
  1233. else {
  1234. uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
  1235. if (offset == 0 && blockOfCluster == 0) {
  1236. // start of new cluster
  1237. if (curPosition_ == 0)
  1238. curCluster_ = firstCluster_; // use first cluster in file
  1239. else if (!vol_->fatGet(curCluster_, &curCluster_)) // get next cluster from FAT
  1240. return -1;
  1241. }
  1242. block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
  1243. }
  1244. uint16_t n = toRead;
  1245. // amount to be read from current block
  1246. NOMORE(n, 512 - offset);
  1247. // no buffering needed if n == 512
  1248. if (n == 512 && block != vol_->cacheBlockNumber()) {
  1249. if (!vol_->readBlock(block, dst)) return -1;
  1250. }
  1251. else {
  1252. // read block to cache and copy data to caller
  1253. if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1;
  1254. uint8_t *src = vol_->cache()->data + offset;
  1255. memcpy(dst, src, n);
  1256. }
  1257. dst += n;
  1258. curPosition_ += n;
  1259. toRead -= n;
  1260. }
  1261. return nbyte;
  1262. }
  1263. /**
  1264. * Read the next entry in a directory.
  1265. *
  1266. * \param[out] dir The dir_t struct that will receive the data.
  1267. *
  1268. * \return For success readDir() returns the number of bytes read.
  1269. * A value of zero will be returned if end of file is reached.
  1270. * If an error occurs, readDir() returns -1. Possible errors include
  1271. * readDir() called before a directory has been opened, this is not
  1272. * a directory file or an I/O error occurred.
  1273. */
  1274. int8_t SdBaseFile::readDir(dir_t *dir, char *longFilename) {
  1275. int16_t n;
  1276. // if not a directory file or miss-positioned return an error
  1277. if (!isDir() || (0x1F & curPosition_)) return -1;
  1278. #define INVALIDATE_LONGNAME() (longFilename[0] = longFilename[1] = '\0')
  1279. // If we have a longFilename buffer, mark it as invalid.
  1280. // If a long filename is found it will be filled automatically.
  1281. if (longFilename) INVALIDATE_LONGNAME();
  1282. uint8_t checksum_error = 0xFF, checksum = 0;
  1283. while (1) {
  1284. n = read(dir, sizeof(dir_t));
  1285. if (n != sizeof(dir_t)) return n ? -1 : 0;
  1286. // Last entry if DIR_NAME_FREE
  1287. if (dir->name[0] == DIR_NAME_FREE) return 0;
  1288. // Skip deleted entry and entry for . and ..
  1289. if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') {
  1290. if (longFilename) INVALIDATE_LONGNAME(); // Invalidate erased file long name, if any
  1291. continue;
  1292. }
  1293. if (longFilename) {
  1294. // Fill the long filename if we have a long filename entry.
  1295. // Long filename entries are stored before the short filename.
  1296. if (DIR_IS_LONG_NAME(dir)) {
  1297. vfat_t *VFAT = (vfat_t*)dir;
  1298. // Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
  1299. if (VFAT->firstClusterLow == 0) {
  1300. const uint8_t seq = VFAT->sequenceNumber & 0x1F;
  1301. if (WITHIN(seq, 1, MAX_VFAT_ENTRIES)) {
  1302. if (seq == 1) {
  1303. checksum = VFAT->checksum;
  1304. checksum_error = 0;
  1305. }
  1306. else if (checksum != VFAT->checksum) // orphan detected
  1307. checksum_error = 1;
  1308. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  1309. getLFNName(VFAT, longFilename, seq); // Get chunk of LFN from VFAT entry
  1310. #else // !LONG_FILENAME_WRITE_SUPPORT
  1311. n = (seq - 1) * (FILENAME_LENGTH);
  1312. LOOP_L_N(i, FILENAME_LENGTH) {
  1313. const uint16_t utf16_ch = (i >= 11) ? VFAT->name3[i - 11] : (i >= 5) ? VFAT->name2[i - 5] : VFAT->name1[i];
  1314. #if ENABLED(UTF_FILENAME_SUPPORT)
  1315. // We can't reconvert to UTF-8 here as UTF-8 is variable-size encoding, but joining LFN blocks
  1316. // needs static bytes addressing. So here just store full UTF-16LE words to re-convert later.
  1317. uint16_t idx = (n + i) * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding
  1318. longFilename[idx] = utf16_ch & 0xFF;
  1319. longFilename[idx + 1] = (utf16_ch >> 8) & 0xFF;
  1320. #else
  1321. // Replace all multibyte characters to '_'
  1322. longFilename[n + i] = (utf16_ch > 0xFF) ? '_' : (utf16_ch & 0xFF);
  1323. #endif
  1324. }
  1325. #endif // !LONG_FILENAME_WRITE_SUPPORT
  1326. // If this VFAT entry is the last one, add a NUL terminator at the end of the string
  1327. if (VFAT->sequenceNumber & 0x40)
  1328. longFilename[LONG_FILENAME_CHARSIZE * TERN(LONG_FILENAME_WRITE_SUPPORT, seq * FILENAME_LENGTH, (n + FILENAME_LENGTH))] = '\0';
  1329. }
  1330. }
  1331. }
  1332. else {
  1333. if (!checksum_error && lfn_checksum(dir->name) != checksum) checksum_error = 1; // orphan detected
  1334. if (checksum_error) INVALIDATE_LONGNAME();
  1335. }
  1336. }
  1337. // Post-process normal file or subdirectory longname, if any
  1338. if (DIR_IS_FILE_OR_SUBDIR(dir)) {
  1339. #if ENABLED(UTF_FILENAME_SUPPORT)
  1340. #if LONG_FILENAME_CHARSIZE > 2
  1341. // Add warning for developers for currently not supported 3-byte cases (Conversion series of 2-byte
  1342. // codepoints to 3-byte in-place will break the rest of filename)
  1343. #error "Currently filename re-encoding is done in-place. It may break the remaining chars to use 3-byte codepoints."
  1344. #endif
  1345. // Is there a long filename to decode?
  1346. if (longFilename) {
  1347. // Reset n to the start of the long name
  1348. n = 0;
  1349. for (uint16_t idx = 0; idx < (LONG_FILENAME_LENGTH) / 2; idx += 2) { // idx is fixed since FAT LFN always contains UTF-16LE encoding
  1350. const uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8);
  1351. if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
  1352. longFilename[n++] = '_';
  1353. else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte UTF-8 char
  1354. longFilename[n++] = utf16_ch & 0x007F;
  1355. else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte UTF-8 char
  1356. longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
  1357. longFilename[n++] = 0x80 | ( utf16_ch & 0x3F);
  1358. }
  1359. else {
  1360. #if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte UTF-8 char
  1361. longFilename[n++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
  1362. longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
  1363. longFilename[n++] = 0xC0 | ( utf16_ch & 0x3F);
  1364. #else // Encode as '_'
  1365. longFilename[n++] = '_';
  1366. #endif
  1367. }
  1368. if (0 == utf16_ch) break; // End of filename
  1369. } // idx
  1370. } // longFilename
  1371. #endif
  1372. return n;
  1373. } // DIR_IS_FILE_OR_SUBDIR
  1374. }
  1375. }
  1376. // Read next directory entry into the cache
  1377. // Assumes file is correctly positioned
  1378. dir_t* SdBaseFile::readDirCache() {
  1379. uint8_t i;
  1380. // error if not directory
  1381. if (!isDir()) return 0;
  1382. // index of entry in cache
  1383. i = (curPosition_ >> 5) & 0xF;
  1384. // use read to locate and cache block
  1385. if (read() < 0) return 0;
  1386. // advance to next entry
  1387. curPosition_ += 31;
  1388. // return pointer to entry
  1389. return vol_->cache()->dir + i;
  1390. }
  1391. /**
  1392. * Remove a file.
  1393. *
  1394. * The directory entry and all data for the file are deleted.
  1395. *
  1396. * \note This function should not be used to delete the 8.3 version of a
  1397. * file that has a long name. For example if a file has the long name
  1398. * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
  1399. *
  1400. * \return true for success, false for failure.
  1401. * Reasons for failure include the file read-only, is a directory,
  1402. * or an I/O error occurred.
  1403. */
  1404. bool SdBaseFile::remove() {
  1405. if (ENABLED(SDCARD_READONLY)) return false;
  1406. // free any clusters - will fail if read-only or directory
  1407. if (!truncate(0)) return false;
  1408. // cache directory entry
  1409. dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1410. if (!d) return false;
  1411. #if ENABLED(LONG_FILENAME_WRITE_SUPPORT)
  1412. // get SFN checksum before name rewrite (needed for LFN deletion)
  1413. const uint8_t sfn_checksum = lfn_checksum(d->name);
  1414. #endif
  1415. // mark entry deleted
  1416. d->name[0] = DIR_NAME_DELETED;
  1417. // set this file closed
  1418. type_ = FAT_FILE_TYPE_CLOSED;
  1419. // write entry to SD
  1420. #if DISABLED(LONG_FILENAME_WRITE_SUPPORT)
  1421. return vol_->cacheFlush();
  1422. #else // LONG_FILENAME_WRITE_SUPPORT
  1423. flags_ = 0;
  1424. if (!vol_->cacheFlush()) return false;
  1425. // Check if the entry has a LFN
  1426. bool lastEntry = false;
  1427. // loop back to search for any LFN entries related to this file
  1428. LOOP_S_LE_N(sequenceNumber, 1, MAX_VFAT_ENTRIES) {
  1429. dirIndex_ = (dirIndex_ - 1) & 0xF;
  1430. if (dirBlock_ == 0) break;
  1431. if (dirIndex_ == 0xF) dirBlock_--;
  1432. dir_t *dir = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1433. if (!dir) return false;
  1434. // check for valid LFN: not deleted, not top dirs (".", ".."), must be a LFN
  1435. if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.' || !isDirLFN(dir)) break;
  1436. // check coherent LFN: checksum and sequenceNumber must match
  1437. vfat_t* dirlfn = (vfat_t*) dir;
  1438. if (dirlfn->checksum != sfn_checksum || (dirlfn->sequenceNumber & 0x1F) != sequenceNumber) break; // orphan entry
  1439. // is last entry of LFN ?
  1440. lastEntry = (dirlfn->sequenceNumber & 0x40);
  1441. // mark as deleted
  1442. dirlfn->sequenceNumber = DIR_NAME_DELETED;
  1443. // Flush to SD
  1444. if (!vol_->cacheFlush()) return false;
  1445. // exit on last entry of LFN deleted
  1446. if (lastEntry) break;
  1447. }
  1448. // Restore current index
  1449. //if (!seekSet(32UL * dirIndex_)) return false;
  1450. //dirIndex_ += prevDirIndex;
  1451. return true;
  1452. #endif // LONG_FILENAME_WRITE_SUPPORT
  1453. }
  1454. /**
  1455. * Remove a file.
  1456. *
  1457. * The directory entry and all data for the file are deleted.
  1458. *
  1459. * \param[in] dirFile The directory that contains the file.
  1460. * \param[in] path Path for the file to be removed.
  1461. *
  1462. * \note This function should not be used to delete the 8.3 version of a
  1463. * file that has a long name. For example if a file has the long name
  1464. * "New Text Document.txt" you should not delete the 8.3 name "NEWTEX~1.TXT".
  1465. *
  1466. * \return true for success, false for failure.
  1467. * Reasons for failure include the file is a directory, is read only,
  1468. * \a dirFile is not a directory, \a path is not found
  1469. * or an I/O error occurred.
  1470. */
  1471. bool SdBaseFile::remove(SdBaseFile *dirFile, const char *path) {
  1472. if (ENABLED(SDCARD_READONLY)) return false;
  1473. SdBaseFile file;
  1474. return file.open(dirFile, path, O_WRITE) ? file.remove() : false;
  1475. }
  1476. /**
  1477. * Rename a file or subdirectory.
  1478. *
  1479. * \param[in] dirFile Directory for the new path.
  1480. * \param[in] newPath New path name for the file/directory.
  1481. *
  1482. * \return true for success, false for failure.
  1483. * Reasons for failure include \a dirFile is not open or is not a directory
  1484. * file, newPath is invalid or already exists, or an I/O error occurs.
  1485. */
  1486. bool SdBaseFile::rename(SdBaseFile *dirFile, const char *newPath) {
  1487. if (ENABLED(SDCARD_READONLY)) return false;
  1488. uint32_t dirCluster = 0;
  1489. // must be an open file or subdirectory
  1490. if (!(isFile() || isSubDir())) return false;
  1491. // can't move file
  1492. if (vol_ != dirFile->vol_) return false;
  1493. // sync() and cache directory entry
  1494. sync();
  1495. dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1496. if (!d) return false;
  1497. // save directory entry
  1498. dir_t entry;
  1499. memcpy(&entry, d, sizeof(entry));
  1500. // mark entry deleted
  1501. d->name[0] = DIR_NAME_DELETED;
  1502. // make directory entry for new path
  1503. SdBaseFile file;
  1504. if (isFile()) {
  1505. if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) {
  1506. goto restore;
  1507. }
  1508. }
  1509. else {
  1510. // don't create missing path prefix components
  1511. if (!file.mkdir(dirFile, newPath, false)) {
  1512. goto restore;
  1513. }
  1514. // save cluster containing new dot dot
  1515. dirCluster = file.firstCluster_;
  1516. }
  1517. // change to new directory entry
  1518. dirBlock_ = file.dirBlock_;
  1519. dirIndex_ = file.dirIndex_;
  1520. // mark closed to avoid possible destructor close call
  1521. file.type_ = FAT_FILE_TYPE_CLOSED;
  1522. // cache new directory entry
  1523. d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1524. if (!d) return false;
  1525. // copy all but name field to new directory entry
  1526. memcpy(&d->attributes, &entry.attributes, sizeof(entry) - sizeof(d->name));
  1527. // update dot dot if directory
  1528. if (dirCluster) {
  1529. // get new dot dot
  1530. uint32_t block = vol_->clusterStartBlock(dirCluster);
  1531. if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return false;
  1532. memcpy(&entry, &vol_->cache()->dir[1], sizeof(entry));
  1533. // free unused cluster
  1534. if (!vol_->freeChain(dirCluster)) return false;
  1535. // store new dot dot
  1536. block = vol_->clusterStartBlock(firstCluster_);
  1537. if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false;
  1538. memcpy(&vol_->cache()->dir[1], &entry, sizeof(entry));
  1539. }
  1540. return vol_->cacheFlush();
  1541. restore:
  1542. if ((d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE))) {
  1543. // restore entry
  1544. d->name[0] = entry.name[0];
  1545. vol_->cacheFlush();
  1546. }
  1547. return false;
  1548. }
  1549. /**
  1550. * Remove a directory file.
  1551. *
  1552. * The directory file will be removed only if it is empty and is not the
  1553. * root directory. rmdir() follows DOS and Windows and ignores the
  1554. * read-only attribute for the directory.
  1555. *
  1556. * \note This function should not be used to delete the 8.3 version of a
  1557. * directory that has a long name. For example if a directory has the
  1558. * long name "New folder" you should not delete the 8.3 name "NEWFOL~1".
  1559. *
  1560. * \return true for success, false for failure.
  1561. * Reasons for failure include the file is not a directory, is the root
  1562. * directory, is not empty, or an I/O error occurred.
  1563. */
  1564. bool SdBaseFile::rmdir() {
  1565. if (ENABLED(SDCARD_READONLY)) return false;
  1566. // must be open subdirectory
  1567. if (!isSubDir()) return false;
  1568. rewind();
  1569. // make sure directory is empty
  1570. while (curPosition_ < fileSize_) {
  1571. dir_t *p = readDirCache();
  1572. if (!p) return false;
  1573. // done if past last used entry
  1574. if (p->name[0] == DIR_NAME_FREE) break;
  1575. // skip empty slot, '.' or '..'
  1576. if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
  1577. // error not empty
  1578. if (DIR_IS_FILE_OR_SUBDIR(p)) return false;
  1579. }
  1580. // convert empty directory to normal file for remove
  1581. type_ = FAT_FILE_TYPE_NORMAL;
  1582. flags_ |= O_WRITE;
  1583. return remove();
  1584. }
  1585. /**
  1586. * Recursively delete a directory and all contained files.
  1587. *
  1588. * This is like the Unix/Linux 'rm -rf *' if called with the root directory
  1589. * hence the name.
  1590. *
  1591. * Warning - This will remove all contents of the directory including
  1592. * subdirectories. The directory will then be removed if it is not root.
  1593. * The read-only attribute for files will be ignored.
  1594. *
  1595. * \note This function should not be used to delete the 8.3 version of
  1596. * a directory that has a long name. See remove() and rmdir().
  1597. *
  1598. * \return true for success, false for failure.
  1599. */
  1600. bool SdBaseFile::rmRfStar() {
  1601. if (ENABLED(SDCARD_READONLY)) return false;
  1602. uint32_t index;
  1603. SdBaseFile f;
  1604. rewind();
  1605. while (curPosition_ < fileSize_) {
  1606. // remember position
  1607. index = curPosition_ / 32;
  1608. dir_t *p = readDirCache();
  1609. if (!p) return false;
  1610. // done if past last entry
  1611. if (p->name[0] == DIR_NAME_FREE) break;
  1612. // skip empty slot or '.' or '..'
  1613. if (p->name[0] == DIR_NAME_DELETED || p->name[0] == '.') continue;
  1614. // skip if part of long file name or volume label in root
  1615. if (!DIR_IS_FILE_OR_SUBDIR(p)) continue;
  1616. if (!f.open(this, index, O_READ)) return false;
  1617. if (f.isSubDir()) {
  1618. // recursively delete
  1619. if (!f.rmRfStar()) return false;
  1620. }
  1621. else {
  1622. // ignore read-only
  1623. f.flags_ |= O_WRITE;
  1624. if (!f.remove()) return false;
  1625. }
  1626. // position to next entry if required
  1627. if (curPosition_ != (32 * (index + 1))) {
  1628. if (!seekSet(32 * (index + 1))) return false;
  1629. }
  1630. }
  1631. // don't try to delete root
  1632. if (!isRoot()) {
  1633. if (!rmdir()) return false;
  1634. }
  1635. return true;
  1636. }
  1637. /**
  1638. * Create a file object and open it in the current working directory.
  1639. *
  1640. * \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
  1641. *
  1642. * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
  1643. * OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t).
  1644. */
  1645. SdBaseFile::SdBaseFile(const char *path, uint8_t oflag) {
  1646. type_ = FAT_FILE_TYPE_CLOSED;
  1647. writeError = false;
  1648. open(path, oflag);
  1649. }
  1650. /**
  1651. * Sets a file's position.
  1652. *
  1653. * \param[in] pos The new position in bytes from the beginning of the file.
  1654. *
  1655. * \return true for success, false for failure.
  1656. */
  1657. bool SdBaseFile::seekSet(const uint32_t pos) {
  1658. uint32_t nCur, nNew;
  1659. // error if file not open or seek past end of file
  1660. if (!isOpen() || pos > fileSize_) return false;
  1661. if (type_ == FAT_FILE_TYPE_ROOT_FIXED) {
  1662. curPosition_ = pos;
  1663. return true;
  1664. }
  1665. if (pos == 0) {
  1666. curCluster_ = curPosition_ = 0; // set position to start of file
  1667. return true;
  1668. }
  1669. // calculate cluster index for cur and new position
  1670. nCur = (curPosition_ - 1) >> (vol_->clusterSizeShift_ + 9);
  1671. nNew = (pos - 1) >> (vol_->clusterSizeShift_ + 9);
  1672. if (nNew < nCur || curPosition_ == 0)
  1673. curCluster_ = firstCluster_; // must follow chain from first cluster
  1674. else
  1675. nNew -= nCur; // advance from curPosition
  1676. while (nNew--)
  1677. if (!vol_->fatGet(curCluster_, &curCluster_)) return false;
  1678. curPosition_ = pos;
  1679. return true;
  1680. }
  1681. void SdBaseFile::setpos(filepos_t *pos) {
  1682. curPosition_ = pos->position;
  1683. curCluster_ = pos->cluster;
  1684. }
  1685. /**
  1686. * The sync() call causes all modified data and directory fields
  1687. * to be written to the storage device.
  1688. *
  1689. * \return true for success, false for failure.
  1690. * Reasons for failure include a call to sync() before a file has been
  1691. * opened or an I/O error.
  1692. */
  1693. bool SdBaseFile::sync() {
  1694. // only allow open files and directories
  1695. if (ENABLED(SDCARD_READONLY) || !isOpen()) goto FAIL;
  1696. if (flags_ & F_FILE_DIR_DIRTY) {
  1697. dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1698. // check for deleted by another open file object
  1699. if (!d || d->name[0] == DIR_NAME_DELETED) goto FAIL;
  1700. // do not set filesize for dir files
  1701. if (!isDir()) d->fileSize = fileSize_;
  1702. // update first cluster fields
  1703. d->firstClusterLow = firstCluster_ & 0xFFFF;
  1704. d->firstClusterHigh = firstCluster_ >> 16;
  1705. // set modify time if user supplied a callback date/time function
  1706. if (dateTime_) {
  1707. dateTime_(&d->lastWriteDate, &d->lastWriteTime);
  1708. d->lastAccessDate = d->lastWriteDate;
  1709. }
  1710. // clear directory dirty
  1711. flags_ &= ~F_FILE_DIR_DIRTY;
  1712. }
  1713. return vol_->cacheFlush();
  1714. FAIL:
  1715. writeError = true;
  1716. return false;
  1717. }
  1718. /**
  1719. * Copy a file's timestamps
  1720. *
  1721. * \param[in] file File to copy timestamps from.
  1722. *
  1723. * \note
  1724. * Modify and access timestamps may be overwritten if a date time callback
  1725. * function has been set by dateTimeCallback().
  1726. *
  1727. * \return true for success, false for failure.
  1728. */
  1729. bool SdBaseFile::timestamp(SdBaseFile *file) {
  1730. dir_t dir;
  1731. // get timestamps
  1732. if (!file->dirEntry(&dir)) return false;
  1733. // update directory fields
  1734. if (!sync()) return false;
  1735. dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1736. if (!d) return false;
  1737. // copy timestamps
  1738. d->lastAccessDate = dir.lastAccessDate;
  1739. d->creationDate = dir.creationDate;
  1740. d->creationTime = dir.creationTime;
  1741. d->creationTimeTenths = dir.creationTimeTenths;
  1742. d->lastWriteDate = dir.lastWriteDate;
  1743. d->lastWriteTime = dir.lastWriteTime;
  1744. // write back entry
  1745. return vol_->cacheFlush();
  1746. }
  1747. /**
  1748. * Set a file's timestamps in its directory entry.
  1749. *
  1750. * \param[in] flags Values for \a flags are constructed by a bitwise-inclusive
  1751. * OR of flags from the following list
  1752. *
  1753. * T_ACCESS - Set the file's last access date.
  1754. *
  1755. * T_CREATE - Set the file's creation date and time.
  1756. *
  1757. * T_WRITE - Set the file's last write/modification date and time.
  1758. *
  1759. * \param[in] year Valid range 1980 - 2107 inclusive.
  1760. *
  1761. * \param[in] month Valid range 1 - 12 inclusive.
  1762. *
  1763. * \param[in] day Valid range 1 - 31 inclusive.
  1764. *
  1765. * \param[in] hour Valid range 0 - 23 inclusive.
  1766. *
  1767. * \param[in] minute Valid range 0 - 59 inclusive.
  1768. *
  1769. * \param[in] second Valid range 0 - 59 inclusive
  1770. *
  1771. * \note It is possible to set an invalid date since there is no check for
  1772. * the number of days in a month.
  1773. *
  1774. * \note
  1775. * Modify and access timestamps may be overwritten if a date time callback
  1776. * function has been set by dateTimeCallback().
  1777. *
  1778. * \return true for success, false for failure.
  1779. */
  1780. bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
  1781. uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
  1782. if (ENABLED(SDCARD_READONLY)) return false;
  1783. uint16_t dirDate, dirTime;
  1784. if (!isOpen()
  1785. || year < 1980
  1786. || year > 2107
  1787. || month < 1
  1788. || month > 12
  1789. || day < 1
  1790. || day > 31
  1791. || hour > 23
  1792. || minute > 59
  1793. || second > 59) {
  1794. return false;
  1795. }
  1796. // update directory entry
  1797. if (!sync()) return false;
  1798. dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
  1799. if (!d) return false;
  1800. dirDate = FAT_DATE(year, month, day);
  1801. dirTime = FAT_TIME(hour, minute, second);
  1802. if (flags & T_ACCESS) {
  1803. d->lastAccessDate = dirDate;
  1804. }
  1805. if (flags & T_CREATE) {
  1806. d->creationDate = dirDate;
  1807. d->creationTime = dirTime;
  1808. // seems to be units of 1/100 second not 1/10 as Microsoft states
  1809. d->creationTimeTenths = second & 1 ? 100 : 0;
  1810. }
  1811. if (flags & T_WRITE) {
  1812. d->lastWriteDate = dirDate;
  1813. d->lastWriteTime = dirTime;
  1814. }
  1815. return vol_->cacheFlush();
  1816. }
  1817. /**
  1818. * Truncate a file to a specified length. The current file position
  1819. * will be maintained if it is less than or equal to \a length otherwise
  1820. * it will be set to end of file.
  1821. *
  1822. * \param[in] length The desired length for the file.
  1823. *
  1824. * \return true for success, false for failure.
  1825. * Reasons for failure include file is read only, file is a directory,
  1826. * \a length is greater than the current file size or an I/O error occurs.
  1827. */
  1828. bool SdBaseFile::truncate(uint32_t length) {
  1829. if (ENABLED(SDCARD_READONLY)) return false;
  1830. uint32_t newPos;
  1831. // error if not a normal file or read-only
  1832. if (!isFile() || !(flags_ & O_WRITE)) return false;
  1833. // error if length is greater than current size
  1834. if (length > fileSize_) return false;
  1835. // fileSize and length are zero - nothing to do
  1836. if (fileSize_ == 0) return true;
  1837. // remember position for seek after truncation
  1838. newPos = curPosition_ > length ? length : curPosition_;
  1839. // position to last cluster in truncated file
  1840. if (!seekSet(length)) return false;
  1841. if (length == 0) {
  1842. // free all clusters
  1843. if (!vol_->freeChain(firstCluster_)) return false;
  1844. firstCluster_ = 0;
  1845. }
  1846. else {
  1847. uint32_t toFree;
  1848. if (!vol_->fatGet(curCluster_, &toFree)) return false;
  1849. if (!vol_->isEOC(toFree)) {
  1850. // free extra clusters
  1851. if (!vol_->freeChain(toFree)) return false;
  1852. // current cluster is end of chain
  1853. if (!vol_->fatPutEOC(curCluster_)) return false;
  1854. }
  1855. }
  1856. fileSize_ = length;
  1857. // need to update directory entry
  1858. flags_ |= F_FILE_DIR_DIRTY;
  1859. if (!sync()) return false;
  1860. // set file to correct position
  1861. return seekSet(newPos);
  1862. }
  1863. /**
  1864. * Write data to an open file.
  1865. *
  1866. * \note Data is moved to the cache but may not be written to the
  1867. * storage device until sync() is called.
  1868. *
  1869. * \param[in] buf Pointer to the location of the data to be written.
  1870. *
  1871. * \param[in] nbyte Number of bytes to write.
  1872. *
  1873. * \return For success write() returns the number of bytes written, always
  1874. * \a nbyte. If an error occurs, write() returns -1. Possible errors
  1875. * include write() is called before a file has been opened, write is called
  1876. * for a read-only file, device is full, a corrupt file system or an I/O error.
  1877. */
  1878. int16_t SdBaseFile::write(const void *buf, uint16_t nbyte) {
  1879. #if ENABLED(SDCARD_READONLY)
  1880. writeError = true; return -1;
  1881. #endif
  1882. // convert void* to uint8_t* - must be before goto statements
  1883. const uint8_t *src = reinterpret_cast<const uint8_t*>(buf);
  1884. // number of bytes left to write - must be before goto statements
  1885. uint16_t nToWrite = nbyte;
  1886. // error if not a normal file or is read-only
  1887. if (!isFile() || !(flags_ & O_WRITE)) goto FAIL;
  1888. // seek to end of file if append flag
  1889. if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
  1890. if (!seekEnd()) goto FAIL;
  1891. }
  1892. while (nToWrite > 0) {
  1893. uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
  1894. uint16_t blockOffset = curPosition_ & 0x1FF;
  1895. if (blockOfCluster == 0 && blockOffset == 0) {
  1896. // start of new cluster
  1897. if (curCluster_ == 0) {
  1898. if (firstCluster_ == 0) {
  1899. // allocate first cluster of file
  1900. if (!addCluster()) goto FAIL;
  1901. }
  1902. else {
  1903. curCluster_ = firstCluster_;
  1904. }
  1905. }
  1906. else {
  1907. uint32_t next;
  1908. if (!vol_->fatGet(curCluster_, &next)) goto FAIL;
  1909. if (vol_->isEOC(next)) {
  1910. // add cluster if at end of chain
  1911. if (!addCluster()) goto FAIL;
  1912. }
  1913. else {
  1914. curCluster_ = next;
  1915. }
  1916. }
  1917. }
  1918. // max space in block
  1919. uint16_t n = 512 - blockOffset;
  1920. // lesser of space and amount to write
  1921. NOMORE(n, nToWrite);
  1922. // block for data write
  1923. uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
  1924. if (n == 512) {
  1925. // full block - don't need to use cache
  1926. if (vol_->cacheBlockNumber() == block) {
  1927. // invalidate cache if block is in cache
  1928. vol_->cacheSetBlockNumber(0xFFFFFFFF, false);
  1929. }
  1930. if (!vol_->writeBlock(block, src)) goto FAIL;
  1931. }
  1932. else {
  1933. if (blockOffset == 0 && curPosition_ >= fileSize_) {
  1934. // start of new block don't need to read into cache
  1935. if (!vol_->cacheFlush()) goto FAIL;
  1936. // set cache dirty and SD address of block
  1937. vol_->cacheSetBlockNumber(block, true);
  1938. }
  1939. else {
  1940. // rewrite part of block
  1941. if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL;
  1942. }
  1943. uint8_t *dst = vol_->cache()->data + blockOffset;
  1944. memcpy(dst, src, n);
  1945. }
  1946. curPosition_ += n;
  1947. src += n;
  1948. nToWrite -= n;
  1949. }
  1950. if (curPosition_ > fileSize_) {
  1951. // update fileSize and insure sync will update dir entry
  1952. fileSize_ = curPosition_;
  1953. flags_ |= F_FILE_DIR_DIRTY;
  1954. }
  1955. else if (dateTime_ && nbyte) {
  1956. // insure sync will update modified date and time
  1957. flags_ |= F_FILE_DIR_DIRTY;
  1958. }
  1959. if (flags_ & O_SYNC) {
  1960. if (!sync()) goto FAIL;
  1961. }
  1962. return nbyte;
  1963. FAIL:
  1964. // return for write error
  1965. writeError = true;
  1966. return -1;
  1967. }
  1968. #endif // SDSUPPORT