fat.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154
  1. /****************************************************************************
  2. * This file is part of the AVRIDE device driver.
  3. *
  4. * Copyright (c) 2002-2004 by Michael Fischer. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the author nor the names of its contributors may
  16. * be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  23. * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. ****************************************************************************
  33. * History:
  34. *
  35. * 14.12.02 mifi First Version
  36. * 23.12.02 mifi Add FileOpen, FileClose, FileError, FileSize,
  37. * FileSeek and FileRead. But the FileSeek function.
  38. * does not work in the moment, later...
  39. * 28.12.02 mifi Now support FAT16 AND FAT32.
  40. * 01.01.03 mifi Support long directory entries, but without to
  41. * check the checksum of the short entry.
  42. * Change FAT32FileSize return value from int to long.
  43. * The max size of a long filename segment is
  44. * (FAT_LONG_NAME_LEN-1). But the complete filename can
  45. * be longer.
  46. *
  47. * segment1/segment2/segment3/index.html
  48. *
  49. * segmentX max length = (FAT_LONG_NAME_LEN-1)
  50. *
  51. * 04.01.03 mifi Take a look at the return values...
  52. * 18.01.03 mifi Change Licence from GPL to BSD.
  53. * 25.01.03 mifi Implement a new FindFile function.
  54. * I have some trouble with short file names under
  55. * Win98. Win98 store a short name like "enlogo.gif"
  56. * as a long name, nasty OS.
  57. * Remove FAT32_MAX_FILES and the array aFileHandle,
  58. * a file handle will now be allocated by NutHeapAlloc,
  59. * therefore we have no restrictions about the count of
  60. * the open file handle. (Only by available memory)
  61. * 27.01.03 mifi Rename all FAT32xxx function to FATxxx.
  62. *
  63. * 28.01.03 mifi Start porting to Nut/OS 3.X.X
  64. * 19.06.03 mifi Change the call of IDEInit, now we use the BaseAddress
  65. * of 0. Because the fat module does not need to know the
  66. * address. It will be handled in ide.c.
  67. * 29.06.03 mifi First ATAPI-Version
  68. * Now we can read files from a CD-ROM. But there exist
  69. * some open points:
  70. * - only first session from a multisession CD is supported
  71. * - only iso9660, no Joliet support now, later
  72. * 24.07.04 mifi Some changes to support more than one drive (datanut)
  73. * 25.07.04 mifi Add support for the PCMCIA_11 hardware.
  74. * 27.07.04 mifi Start to add functionality for write function.
  75. * 03.08.04 mifi Add format function.
  76. ****************************************************************************/
  77. #define __FAT_C__
  78. #define LOG_MODULE LOG_FAT_MODULE
  79. #include <string.h>
  80. #include <stddef.h>
  81. #include <ctype.h>
  82. #include <time.h>
  83. #include <sys/heap.h>
  84. #include <sys/event.h>
  85. #include <sys/thread.h>
  86. #include <sys/device.h>
  87. #include "typedefs.h"
  88. #include "fat.h"
  89. #include "fatdrv.h"
  90. #include "portio.h"
  91. #include "log.h"
  92. /*==========================================================*/
  93. /* DEFINE: All Structures and Common Constants */
  94. /*==========================================================*/
  95. //
  96. // FAT return codes
  97. //
  98. #define FAT_OK 0
  99. #define FAT_ERROR -1
  100. #define FAT_ERROR_EOF -2
  101. #define FAT_ERROR_IDE -3
  102. //
  103. // Define for correct return values Nut/OS
  104. //
  105. #define NUTDEV_OK 0
  106. #define NUTDEV_ERROR -1
  107. #define NUTDEV_WRONG_HW -2
  108. #define FAT_MAX_DRIVE 3
  109. //
  110. // Some defines for the FAT structures
  111. //
  112. #define ZIP_DRIVE_BR_SECTOR 32
  113. #define BPB_RsvdSecCnt 32
  114. #define BPB_NumFATs 2
  115. #define BPB_HiddSec 63
  116. #define FAT32_MEDIA 0xf8
  117. #define FAT32_SECTOR_SIZE HW_SECTOR_SIZE
  118. #define FAT32_OFFSET_FSINFO 1
  119. #define FAT32_OFFSET_BACKUP_BOOT 6
  120. #define FAT16_CLUSTER_EOF 0x0000FFFF
  121. #define FAT16_CLUSTER_ERROR 0x0000FFF7
  122. #define FAT16_CLUSTER_MASK 0x0000FFFF
  123. #define FAT32_CLUSTER_EOF 0x0FFFFFFF
  124. #define FAT32_CLUSTER_ERROR 0x0FFFFFF7
  125. #define FAT32_CLUSTER_MASK 0x0FFFFFFF
  126. #define FAT_SIGNATURE 0xAA55
  127. #define MBR_SIGNATURE FAT_SIGNATURE
  128. #define MBR_FAT32 0x0B
  129. #define FSINFO_FIRSTSIGNATURE 0x41615252
  130. #define FSINFO_FSINFOSIGNATURE 0x61417272
  131. #define FSINFO_SIGNATURE FAT_SIGNATURE
  132. #define DIRECTORY_ATTRIBUTE_READ_ONLY 0x01
  133. #define DIRECTORY_ATTRIBUTE_HIDDEN 0x02
  134. #define DIRECTORY_ATTRIBUTE_SYSTEM_FILE 0x04
  135. #define DIRECTORY_ATTRIBUTE_VOLUME_ID 0x08
  136. #define DIRECTORY_ATTRIBUTE_DIRECTORY 0x10
  137. #define DIRECTORY_ATTRIBUTE_ARCHIVE 0x20
  138. //
  139. // DIRECTORY_ATTRIBUTE_READ_ONLY |
  140. // DIRECTORY_ATTRIBUTE_HIDDEN |
  141. // DIRECTORY_ATTRIBUTE_SYSTEM_FILE |
  142. // DIRECTORY_ATTRIBUTE_VOLUME_ID
  143. //
  144. #define DIRECTORY_ATTRIBUTE_LONG_NAME 0x0F
  145. //
  146. // DIRECTORY_ATTRIBUTE_READ_ONLY |
  147. // DIRECTORY_ATTRIBUTE_HIDDEN |
  148. // DIRECTORY_ATTRIBUTE_SYSTEM_FILE |
  149. // DIRECTORY_ATTRIBUTE_VOLUME_ID |
  150. // DIRECTORY_ATTRIBUTE_DIRECTORY |
  151. // DIRECTORY_ATTRIBUTE_ARCHIVE
  152. //
  153. #define DIRECTORY_ATTRIBUTE_LONG_NAME_MASK 0x3F
  154. #define FAT_NAME_LEN 8
  155. #define FAT_EXT_LEN 3
  156. //
  157. // FAT_SHORT_NAME_LEN name len =
  158. // name + ext + 1 for the point
  159. //
  160. #define FAT_SHORT_NAME_LEN (FAT_NAME_LEN+FAT_EXT_LEN+1)
  161. #define FAT_LONG_NAME_LEN 64
  162. //
  163. // Some stuff for HD and CD, DRIVE_INFO Flags
  164. //
  165. //
  166. #define FLAG_FAT_IS_CDROM 0x0001
  167. #define FLAG_FAT_IS_ZIP 0x0002
  168. //
  169. // DiskSize to SectorPerCluster table
  170. //
  171. typedef struct
  172. {
  173. DWORD DiskSize;
  174. BYTE SecPerClusVal;
  175. } DSKSZTOSECPERCLUS;
  176. typedef struct _FAT32FileDataTime
  177. {
  178. unsigned Seconds:5;
  179. unsigned Minute:6;
  180. unsigned Hour:5;
  181. unsigned Day:5;
  182. unsigned Month:4;
  183. unsigned Year:7;
  184. } FAT32_FILEDATETIME, *PFAT32_FILEDATETIME;
  185. typedef struct _FAT32DirectoryEntry
  186. {
  187. BYTE Name[FAT_NAME_LEN];
  188. BYTE Extension[FAT_EXT_LEN];
  189. BYTE Attribute;
  190. BYTE Reserved[8];
  191. WORD HighCluster;
  192. FAT32_FILEDATETIME Date;
  193. WORD LowCluster;
  194. DWORD FileSize;
  195. } FAT32_DIRECTORY_ENTRY;
  196. typedef struct _FAT32DirectoryEntryLong
  197. {
  198. BYTE Order;
  199. WORD Name1[5];
  200. BYTE Attribute;
  201. BYTE Type;
  202. BYTE Chksum;
  203. WORD Name2[6];
  204. WORD LowCluster;
  205. WORD Name3[2];
  206. } FAT32_DIRECTORY_ENTRY_LONG;
  207. typedef struct _FAT32FileSystemInformation
  208. {
  209. DWORD FirstSignature;
  210. BYTE Reserved1[480];
  211. DWORD FSInfoSignature;
  212. DWORD NumberOfFreeClusters;
  213. DWORD MostRecentlyAllocatedCluster;
  214. BYTE Reserved2[12];
  215. BYTE Reserved3[2];
  216. WORD Signature;
  217. } FAT32_FSINFO;
  218. typedef struct _FAT32PartitionEntry
  219. {
  220. BYTE BootInd;
  221. BYTE FirstHead;
  222. BYTE FirstSector;
  223. BYTE FirstTrack;
  224. BYTE FileSystem;
  225. BYTE LastHead;
  226. BYTE LastSector;
  227. BYTE LastTrack;
  228. DWORD StartSectors;
  229. DWORD NumSectors;
  230. } FAT32_PARTITION_ENTRY;
  231. typedef struct _FAT32PartionTable
  232. {
  233. BYTE LoadInstruction[446];
  234. FAT32_PARTITION_ENTRY Partition[4];
  235. WORD Signature; /* AA55 */
  236. } FAT32_PARTITION_TABLE;
  237. typedef struct _bpbfat16
  238. {
  239. BYTE DrvNum;
  240. BYTE Reserved1;
  241. BYTE BootSig;
  242. DWORD VollID;
  243. BYTE VolLab[11];
  244. BYTE FilSysType[8];
  245. BYTE Reserved2[28];
  246. } BPBFAT16;
  247. typedef struct _bpbfat32
  248. {
  249. DWORD FATSz32; // xxx
  250. WORD ExtFlags; // 0
  251. WORD FSVer; // must 0
  252. DWORD RootClus; //
  253. WORD FSInfo; // typically 1
  254. WORD BkBootSec; // typically 6
  255. BYTE Reserved[12]; // set all to zero
  256. BYTE DrvNum; // must 0x80
  257. BYTE Reserved1; // set all to zero
  258. BYTE BootSig; // must 0x29
  259. DWORD VollID; // xxx
  260. BYTE VolLab[11]; // "abcdefghijk"
  261. BYTE FilSysType[8]; // "FAT32 "
  262. } BPBFAT32;
  263. typedef union _bpboffset36
  264. {
  265. BPBFAT16 FAT16;
  266. BPBFAT32 FAT32;
  267. } BPBOFFSET36;
  268. typedef struct _FAT32BootRecord
  269. {
  270. BYTE JumpBoot[3]; // 0xeb, 0x58, 0x90
  271. BYTE OEMName[8]; // "MSWIN4.1"
  272. WORD BytsPerSec; // must 512
  273. BYTE SecPerClus; // 8 for 4K cluster
  274. WORD RsvdSecCnt; // typically 32 for FAT32
  275. BYTE NumFATs; // always 2
  276. WORD RootEntCnt; // must 0 for FAT32
  277. WORD TotSec16; // must 0 for FAT32
  278. BYTE Media; // must 0xf8
  279. WORD FATSz16; // 0 for FAT32
  280. WORD SecPerTrk; // 63 for FAT32
  281. WORD NumHeads; // 255 for FAT32
  282. DWORD HiddSec; // 63 for FAT32
  283. DWORD TotSec32; // xxx
  284. BPBOFFSET36 Off36;
  285. BYTE Reserved[420];
  286. WORD Signature; // must 0xAA55
  287. } FAT32_BOOT_RECORD, *PFAT32_BOOT_RECORD;
  288. typedef struct _fat_entry_table16
  289. {
  290. WORD aEntry[256];
  291. } FAT_ENTRY_TABLE16;
  292. typedef struct _fat_entry_table32
  293. {
  294. DWORD aEntry[128];
  295. } FAT_ENTRY_TABLE32;
  296. typedef union _fat_dir_table
  297. {
  298. FAT32_DIRECTORY_ENTRY aShort[16];
  299. FAT32_DIRECTORY_ENTRY_LONG aLong[16];
  300. } FAT_DIR_TABLE;
  301. typedef struct _drive_info
  302. {
  303. BYTE bIsFAT32;
  304. BYTE bDevice;
  305. BYTE bSectorsPerCluster;
  306. BYTE bFlags;
  307. WORD wSectorSize;
  308. DWORD dwRootDirSectors;
  309. DWORD dwFirstRootDirSector;
  310. DWORD dwRootCluster;
  311. DWORD dwFAT1StartSector;
  312. DWORD dwFAT2StartSector;
  313. DWORD dwCluster2StartSector;
  314. DWORD dwClusterSize;
  315. } DRIVE_INFO;
  316. typedef struct _fhandle
  317. {
  318. DWORD dwFileSize;
  319. DWORD dwStartCluster;
  320. DWORD dwReadCluster;
  321. DWORD dwFilePointer; /* total file pointer */
  322. DWORD dwClusterPointer; /* cluster read pointer */
  323. int nLastError;
  324. int nEOF;
  325. DRIVE_INFO *pDrive;
  326. } FHANDLE;
  327. static int QuickFormat(NUTDEVICE *dev, DRIVE_INFO *pDrive);
  328. /*==========================================================*/
  329. /* DEFINE: Definition of all local Data */
  330. /*==========================================================*/
  331. static int nIsInit = FALSE;
  332. static BYTE *pSectorBuffer = NULL;
  333. static char *pLongName1 = NULL;
  334. static char *pLongName2 = NULL;
  335. static DRIVE_INFO sDriveInfo[FAT_MAX_DRIVE];
  336. static HANDLE hFATSemaphore;
  337. static DSKSZTOSECPERCLUS DskTableFAT32[] = {
  338. { 66600, 0}, /* disks up to 32.5MB, the 0 value for SecPerClusVal trips an error */
  339. { 532480, 1}, /* disks up to 260 MB, 0.5k cluster */
  340. { 16777216, 8}, /* disks up to 8 GB, 4k cluster */
  341. { 33554432, 16}, /* disks up to 16 GB, 8k cluster */
  342. { 67108864, 32}, /* disks up to 32 GB, 16k cluster */
  343. { 0xFFFFFFFF, 64} /* disks greather than 32GB, 32k cluster */
  344. };
  345. #define DSK_TABLE_FAT32_ENTRY_COUNT (sizeof(DskTableFAT32) / sizeof(DSKSZTOSECPERCLUS))
  346. /*==========================================================*/
  347. /* DEFINE: Definition of all local Procedures */
  348. /*==========================================================*/
  349. void FATRelease()
  350. {
  351. nIsInit=FALSE;
  352. }
  353. /************************************************************/
  354. /* FATLock */
  355. /************************************************************/
  356. void FATLock(void)
  357. {
  358. NutEventWait(&hFATSemaphore, 0);
  359. }
  360. /************************************************************/
  361. /* FATFree */
  362. /************************************************************/
  363. void FATFree(void)
  364. {
  365. NutEventPost(&hFATSemaphore);
  366. }
  367. /************************************************************/
  368. /* FATSemaInit */
  369. /************************************************************/
  370. void FATSemaInit(void)
  371. {
  372. NutEventPost(&hFATSemaphore);
  373. }
  374. /************************************************************/
  375. /* GetFirstSectorOfCluster */
  376. /************************************************************/
  377. static DWORD GetFirstSectorOfCluster(DRIVE_INFO *pDrive, DWORD dwCluster)
  378. {
  379. DWORD dwSector;
  380. if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
  381. {
  382. dwSector = dwCluster;
  383. }
  384. else
  385. {
  386. dwSector = (dwCluster - 2) * pDrive->bSectorsPerCluster;
  387. dwSector += pDrive->dwCluster2StartSector;
  388. }
  389. return(dwSector);
  390. }
  391. /************************************************************/
  392. /* GetNextCluster */
  393. /************************************************************/
  394. static DWORD GetNextCluster(DRIVE_INFO *pDrive, DWORD dwCluster)
  395. {
  396. DWORD dwNextCluster;
  397. DWORD dwSector;
  398. DWORD dwIndex;
  399. FAT_ENTRY_TABLE16 *pFatTable16;
  400. FAT_ENTRY_TABLE32 *pFatTable32;
  401. if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
  402. {
  403. dwNextCluster = dwCluster + 1;
  404. }
  405. else
  406. {
  407. if (pDrive->bIsFAT32 == TRUE)
  408. {
  409. //
  410. // (HW_SECTOR_SIZE / sizeof(long)) == 128
  411. //
  412. dwSector = (dwCluster / 128) + pDrive->dwFAT1StartSector;
  413. dwIndex = dwCluster % 128;
  414. HWReadSectors(pDrive->bDevice, pSectorBuffer, dwSector, 1);
  415. pFatTable32 = (FAT_ENTRY_TABLE32 *) pSectorBuffer;
  416. dwNextCluster = (pFatTable32->aEntry[dwIndex] & FAT32_CLUSTER_MASK);
  417. if ((dwNextCluster == FAT32_CLUSTER_EOF) || (dwNextCluster == FAT32_CLUSTER_ERROR))
  418. {
  419. dwNextCluster = 0;
  420. }
  421. }
  422. else
  423. { /* FAT16 */
  424. //
  425. // (HW_SECTOR_SIZE / sizeof(word)) == 256
  426. //
  427. dwSector = (dwCluster / 256) + pDrive->dwFAT1StartSector;
  428. dwIndex = dwCluster % 256;
  429. HWReadSectors(pDrive->bDevice, pSectorBuffer, dwSector, 1);
  430. pFatTable16 = (FAT_ENTRY_TABLE16 *) pSectorBuffer;
  431. dwNextCluster = (pFatTable16->aEntry[dwIndex] & FAT16_CLUSTER_MASK);
  432. if ((dwNextCluster == FAT16_CLUSTER_EOF) || (dwNextCluster == FAT16_CLUSTER_ERROR))
  433. {
  434. dwNextCluster = 0;
  435. }
  436. } /* endif pDrive->bIsFAT32 */
  437. }
  438. return(dwNextCluster);
  439. }
  440. /************************************************************/
  441. /* GetLongChar */
  442. /************************************************************/
  443. static char GetLongChar(WORD wValue)
  444. {
  445. BYTE Value;
  446. Value = (BYTE)(wValue & 0x00FF);
  447. if (Value == 0xFF)
  448. {
  449. Value = 0;
  450. }
  451. if (Value != 0)
  452. {
  453. Value = toupper(Value);
  454. }
  455. return((char)Value);
  456. }
  457. /************************************************************/
  458. /* FindFile */
  459. /* */
  460. /* Find a file by a given name pLongName. */
  461. /* */
  462. /* It is possible that a SHORT name like "enlogo.gif" */
  463. /* is stored as a LONG name. I have seen this */
  464. /* nasty behaviour by Win98. Therefore I will check */
  465. /* the long name too, even if nIsLongName is FALSE. */
  466. /************************************************************/
  467. static DWORD FindFile(DRIVE_INFO *pDrive,
  468. FAT32_DIRECTORY_ENTRY *pSearchEntry,
  469. char *pLongName,
  470. DWORD dwDirCluster,
  471. DWORD *pFileSize,
  472. int nIsLongName)
  473. {
  474. int i, x;
  475. BYTE bError;
  476. int nNameLen;
  477. int nMaxLen;
  478. BYTE bFound;
  479. BYTE bEndLoop;
  480. BYTE bOrder;
  481. BYTE bMaxOrder;
  482. int nDirMaxSector;
  483. DWORD dwSector;
  484. DWORD dwNewCluster;
  485. FAT32_DIRECTORY_ENTRY *pDirEntryShort;
  486. FAT32_DIRECTORY_ENTRY_LONG *pDirEntryLong;
  487. char *pDirName = 0;
  488. FAT_DIR_TABLE *pDirTable;
  489. bError = FALSE;
  490. *pFileSize = 0;
  491. dwNewCluster = 0;
  492. nNameLen = strlen(pLongName);
  493. bMaxOrder = (BYTE) ((nNameLen + 12) / 13);
  494. nMaxLen = (int) (bMaxOrder * 13);
  495. if (nMaxLen >= (FAT_LONG_NAME_LEN - 1))
  496. {
  497. bError = TRUE;
  498. }
  499. bOrder = (BYTE) (0x40 | bMaxOrder);
  500. if (bOrder == 0xE5)
  501. {
  502. //
  503. // I do not know what should I do if the bOrder is 0xe5.
  504. // This is a sign for a "empty" entry.
  505. //
  506. bError = TRUE;
  507. }
  508. if (bError == FALSE)
  509. {
  510. bFound = FALSE;
  511. bEndLoop = FALSE;
  512. while ((bEndLoop == FALSE) && (dwDirCluster != 0))
  513. {
  514. dwSector = GetFirstSectorOfCluster(pDrive, dwDirCluster);
  515. nDirMaxSector = (int) pDrive->bSectorsPerCluster;
  516. //
  517. // Test for special case dwDirCluster and FAT16.
  518. //
  519. if ((dwDirCluster == 1) && (pDrive->bIsFAT32 == FALSE))
  520. {
  521. dwSector = pDrive->dwFirstRootDirSector;
  522. nDirMaxSector = (int) pDrive->dwRootDirSectors;
  523. }
  524. //
  525. // One cluster has SecPerCluster sectors.
  526. //
  527. for (i = 0; i < nDirMaxSector; i++)
  528. {
  529. HWReadSectors(pDrive->bDevice, pSectorBuffer, dwSector + i, 1);
  530. pDirTable = (FAT_DIR_TABLE *) pSectorBuffer;
  531. //
  532. // And one sector has 16 entries.
  533. //
  534. // HW_SECTOR_SIZE / sizeof(FAT32_DIRECTORY_ENTRY) = 16
  535. //
  536. for (x = 0; x < 16; x++)
  537. {
  538. if (bFound == TRUE)
  539. {
  540. pDirEntryShort = (FAT32_DIRECTORY_ENTRY *) & pDirTable->aShort[x];
  541. dwNewCluster = pDirEntryShort->HighCluster;
  542. dwNewCluster = (dwNewCluster << 16) | (DWORD) pDirEntryShort->LowCluster;
  543. *pFileSize = pDirEntryShort->FileSize;
  544. bEndLoop = TRUE;
  545. break;
  546. }
  547. //
  548. // Check for valid entry.
  549. //
  550. pDirEntryShort = (FAT32_DIRECTORY_ENTRY *) & pDirTable->aShort[x];
  551. pDirEntryLong = (FAT32_DIRECTORY_ENTRY_LONG *) & pDirTable->aLong[x];
  552. if (nIsLongName == FALSE)
  553. {
  554. //
  555. // Check if it could be a short name. If Win2000 tell us it
  556. // is a short name, it is true. But with Win98 we must
  557. // test both, short and long...
  558. //
  559. if ((pDirEntryShort->Name[0] != 0xE5) && (pDirEntryShort->Name[0] != 0x00))
  560. {
  561. if (memcmp(pDirEntryShort, pSearchEntry, 11) == 0)
  562. {
  563. //
  564. // Check for the correct attribute, this is done with
  565. // the '&' and not with the memcmp.
  566. // With the '&' it is possible to find a hidden archive too :-)
  567. //
  568. if ((pDirEntryShort->Attribute & pSearchEntry->Attribute) ==
  569. pSearchEntry->Attribute)
  570. {
  571. dwNewCluster = pDirEntryShort->HighCluster;
  572. dwNewCluster = (dwNewCluster << 16) | (DWORD) pDirEntryShort->LowCluster;
  573. *pFileSize = pDirEntryShort->FileSize;
  574. bEndLoop = TRUE;
  575. break;
  576. } /* endif Attribute */
  577. } /* endif test Name+Ext */
  578. } /* endif Name[0] != 0xe5, 0x00 */
  579. }
  580. /*
  581. * endif nIsLongName == FALSE
  582. */
  583. if ((pDirEntryLong->Attribute == DIRECTORY_ATTRIBUTE_LONG_NAME)
  584. && (pDirEntryLong->Order == bOrder))
  585. {
  586. //
  587. // Next bOrder is bOrder--
  588. //
  589. if (bOrder & 0x40)
  590. {
  591. bOrder &= ~0x40;
  592. //
  593. // Get the space for the name.
  594. //
  595. pDirName = pLongName2;
  596. //
  597. // Set the end of string.
  598. //
  599. pDirName[nMaxLen--] = 0;
  600. }
  601. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name3[1]);
  602. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name3[0]);
  603. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[5]);
  604. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[4]);
  605. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[3]);
  606. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[2]);
  607. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[1]);
  608. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name2[0]);
  609. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[4]);
  610. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[3]);
  611. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[2]);
  612. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[1]);
  613. pDirName[nMaxLen--] = GetLongChar(pDirEntryLong->Name1[0]);
  614. bOrder--;
  615. if (bOrder == 0)
  616. {
  617. //
  618. // Now compare the name.
  619. //
  620. bOrder = (BYTE) (0x40 | bMaxOrder);
  621. nMaxLen = (int) (bMaxOrder * 13);
  622. if (memcmp(pLongName, pDirName, strlen(pLongName)) == 0)
  623. {
  624. //
  625. // The next entry will be the correct entry.
  626. //
  627. bFound = TRUE;
  628. }
  629. }
  630. }
  631. /*
  632. * pDirEntryLong->Order == bOrder
  633. */
  634. } /* endfor x<16 */
  635. if (bEndLoop == TRUE)
  636. {
  637. break;
  638. }
  639. }
  640. if (bEndLoop == FALSE)
  641. {
  642. //
  643. // No file found in this cluster, get the next one.
  644. //
  645. dwDirCluster = GetNextCluster(pDrive, dwDirCluster);
  646. }
  647. } /* endwhile */
  648. }
  649. /*
  650. * endif bError == FALSE
  651. */
  652. return(dwNewCluster);
  653. }
  654. /************************************************************/
  655. /* MountHW */
  656. /************************************************************/
  657. static int MountHW(int nDrive)
  658. {
  659. int nError;
  660. int i;
  661. DWORD dwSector;
  662. DWORD dwFATSz;
  663. DWORD dwRootDirSectors;
  664. FAT32_PARTITION_TABLE *pPartitionTable;
  665. FAT32_BOOT_RECORD *pBootRecord;
  666. DRIVE_INFO *pDrive;
  667. nError = HW_OK;
  668. i = nDrive;
  669. pDrive = &sDriveInfo[nDrive];
  670. dwSector = 0;
  671. if (pDrive->bFlags & FLAG_FAT_IS_ZIP)
  672. {
  673. dwSector = ZIP_DRIVE_BR_SECTOR;
  674. }
  675. else
  676. {
  677. //
  678. // Try to find a PartitionTable.
  679. //
  680. nError = HWReadSectors(nDrive, pSectorBuffer, 0, 1);
  681. if (nError == HW_OK)
  682. {
  683. pPartitionTable = (FAT32_PARTITION_TABLE *) pSectorBuffer;
  684. if (pPartitionTable->Signature == FAT_SIGNATURE)
  685. {
  686. if (pPartitionTable->Partition[0].NumSectors)
  687. {
  688. //
  689. // We found a PartitionTable, read BootRecord.
  690. //
  691. dwSector = pPartitionTable->Partition[0].StartSectors;
  692. }
  693. }
  694. }
  695. }
  696. if (dwSector != 0)
  697. {
  698. HWReadSectors(i, pSectorBuffer, dwSector, 1);
  699. pBootRecord = (FAT32_BOOT_RECORD *) pSectorBuffer;
  700. //
  701. // Test valid BootRecord.
  702. //
  703. if (pBootRecord->Signature == FAT_SIGNATURE)
  704. {
  705. pDrive->bSectorsPerCluster = pBootRecord->SecPerClus;
  706. if (pBootRecord->FATSz16 != 0)
  707. {
  708. dwFATSz = pBootRecord->FATSz16;
  709. pDrive->bIsFAT32 = FALSE;
  710. pDrive->dwRootCluster = 1; /* special value, see */
  711. /* FindFile */
  712. }
  713. else
  714. {
  715. dwFATSz = pBootRecord->Off36.FAT32.FATSz32;
  716. pDrive->bIsFAT32 = TRUE;
  717. pDrive->dwRootCluster = pBootRecord->Off36.FAT32.RootClus;
  718. }
  719. dwRootDirSectors =
  720. ((pBootRecord->RootEntCnt * 32) +
  721. (pBootRecord->BytsPerSec - 1)) / pBootRecord->BytsPerSec;
  722. pDrive->dwFAT1StartSector = pBootRecord->HiddSec + pBootRecord->RsvdSecCnt;
  723. pDrive->dwFAT2StartSector = pDrive->dwFAT1StartSector + dwFATSz;
  724. pDrive->dwCluster2StartSector =
  725. pBootRecord->HiddSec + pBootRecord->RsvdSecCnt +
  726. (pBootRecord->NumFATs * dwFATSz) + dwRootDirSectors;
  727. pDrive->dwClusterSize = pBootRecord->SecPerClus * pDrive->wSectorSize;
  728. pDrive->dwRootDirSectors = dwRootDirSectors;
  729. pDrive->dwFirstRootDirSector = pDrive->dwFAT2StartSector + dwFATSz;
  730. } /* endif pBootRecord->Signature */
  731. }
  732. /*
  733. * endif dwSector != 0
  734. */
  735. return(nError);
  736. }
  737. /************************************************************/
  738. /* MountAllDrives */
  739. /************************************************************/
  740. static int MountDrive(BYTE bDrive)
  741. {
  742. int nError;
  743. nError = HW_OK;
  744. FATLock();
  745. if (pLongName1 == NULL)
  746. {
  747. pLongName1 = (char *)NutHeapAlloc(FAT_LONG_NAME_LEN);
  748. }
  749. if (pLongName2 == NULL)
  750. {
  751. pLongName2 = (char *)NutHeapAlloc(FAT_LONG_NAME_LEN);
  752. }
  753. if (pSectorBuffer == NULL)
  754. {
  755. pSectorBuffer = (BYTE *)NutHeapAlloc(MAX_SECTOR_SIZE);
  756. }
  757. if ((pSectorBuffer != NULL) && (pLongName1 != NULL) && (pLongName2 != NULL))
  758. {
  759. memset((BYTE *) & sDriveInfo[bDrive], 0x00, sizeof(DRIVE_INFO));
  760. sDriveInfo[bDrive].bDevice = bDrive;
  761. sDriveInfo[bDrive].wSectorSize = HWGetSectorSize(bDrive);
  762. if (HWIsCDROMDevice(bDrive) == TRUE)
  763. {
  764. sDriveInfo[bDrive].bFlags |= FLAG_FAT_IS_CDROM;
  765. }
  766. if (HWIsZIPDevice(bDrive) == TRUE)
  767. {
  768. sDriveInfo[bDrive].bFlags |= FLAG_FAT_IS_ZIP;
  769. }
  770. switch (sDriveInfo[bDrive].wSectorSize)
  771. {
  772. case HW_SECTOR_SIZE:{
  773. nError = MountHW(bDrive);
  774. break;
  775. }
  776. default:{
  777. nError = HW_ERROR;
  778. break;
  779. }
  780. }
  781. }
  782. /*
  783. * endif pSectorBuffer != NULL
  784. */
  785. FATFree();
  786. return(nError);
  787. }
  788. /************************************************************/
  789. /* MountAllDrives */
  790. /************************************************************/
  791. static int MountAllDrives(void)
  792. {
  793. BYTE i;
  794. int nError = HW_OK;
  795. for (i = 0; i < FAT_MAX_DRIVE; i++)
  796. {
  797. MountDrive(i);
  798. }
  799. return(nError);
  800. }
  801. /*==========================================================*/
  802. /* DEFINE: All code exported by the NUTDEVICE */
  803. /*==========================================================*/
  804. /************************************************************/
  805. /* FATUnMountDrive */
  806. /************************************************************/
  807. static int FATUnMountDrive(int nDrive)
  808. {
  809. int nError;
  810. DRIVE_INFO *pDrive;
  811. FATLock();
  812. nError = FAT_OK;
  813. if ((nDrive >= HW_DRIVE_C) && (nDrive <= HW_DRIVE_D))
  814. {
  815. pDrive = &sDriveInfo[nDrive];
  816. pDrive->bSectorsPerCluster = 0;
  817. }
  818. else
  819. {
  820. nError = FAT_ERROR;
  821. }
  822. FATFree();
  823. return(nError);
  824. }
  825. /************************************************************/
  826. /* CFMount */
  827. /************************************************************/
  828. static void CFMount(int nDrive)
  829. {
  830. BYTE *pSectorBuffer;
  831. pSectorBuffer = (BYTE *) NutHeapAlloc(MAX_SECTOR_SIZE);
  832. if (pSectorBuffer != NULL)
  833. {
  834. MountDrive(nDrive);
  835. NutHeapFree(pSectorBuffer);
  836. }
  837. }
  838. /************************************************************/
  839. /* CFUnMount */
  840. /************************************************************/
  841. static void CFUnMount(int nDrive)
  842. {
  843. FATUnMountDrive(nDrive);
  844. }
  845. /************************************************************/
  846. /* FATInit */
  847. /************************************************************/
  848. static int FATInit(NUTDEVICE * pDevice)
  849. {
  850. int nError;
  851. int nHWMode;
  852. BYTE *pSectorBuffer;
  853. nError = NUTDEV_ERROR;
  854. nHWMode = 0;
  855. pSectorBuffer = NULL;
  856. if ((nIsInit == FALSE) &&
  857. (pDevice->dev_name[0] == 'F') &&
  858. (pDevice->dev_name[1] == 'A') &&
  859. (pDevice->dev_name[2] == 'T'))
  860. {
  861. nError = NUTDEV_OK;
  862. //
  863. // Get the mode.
  864. //
  865. switch (pDevice->dev_base)
  866. {
  867. #if (FAT_USE_MMC_INTERFACE >= 1)
  868. case FAT_MODE_MMC:
  869. nHWMode = 0;
  870. break;
  871. #endif
  872. default:
  873. nError = NUTDEV_ERROR;
  874. break;
  875. }
  876. if (nError == NUTDEV_OK)
  877. {
  878. //
  879. // Init my semaphore.
  880. //
  881. FATSemaInit();
  882. pSectorBuffer = (BYTE *) NutHeapAlloc(MAX_SECTOR_SIZE);
  883. if (pSectorBuffer != NULL)
  884. {
  885. /*
  886. * HW init
  887. */
  888. nError = HWInit(nHWMode, CFMount, CFUnMount);
  889. if (nError == HW_OK)
  890. {
  891. HWMountAllDevices(nHWMode, pSectorBuffer);
  892. /*
  893. * FAT init
  894. */
  895. MountAllDrives();
  896. nError = NUTDEV_OK;
  897. nIsInit = TRUE;
  898. }
  899. else
  900. {
  901. nError = NUTDEV_WRONG_HW;
  902. }
  903. NutHeapFree(pSectorBuffer);
  904. } /* endif pSectorBuffer != NULL */
  905. } /* endif nError == NUTDEV_OK */
  906. }
  907. else
  908. {
  909. if (nIsInit == TRUE)
  910. {
  911. #if (FAT_USE_MMC_INTERFACE >= 1)
  912. if ((pDevice->dev_name[0] == 'F') &&
  913. (pDevice->dev_name[1] == 'M') &&
  914. (pDevice->dev_name[2] == '0'))
  915. {
  916. /*
  917. * Always OK, because the MMC card
  918. * can be inserted later.
  919. */
  920. nError = NUTDEV_OK;
  921. }
  922. #endif /* (FAT_USE_MMC_INTERFACE >= 0) */
  923. } /* endif (nIsInit == TRUE) */
  924. } /* endif nIsInit == FALSE */
  925. return(nError);
  926. }
  927. /************************************************************/
  928. /* GetDriveByDevice */
  929. /************************************************************/
  930. static DRIVE_INFO* GetDriveByDevice (NUTDEVICE *pDevice)
  931. {
  932. DRIVE_INFO* pDrive = NULL;
  933. if (pDevice != NULL)
  934. {
  935. switch (pDevice->dev_name[2])
  936. {
  937. case 'F':{
  938. pDrive = &sDriveInfo[HW_DRIVE_C];
  939. break;
  940. }
  941. case '0':{
  942. pDrive = &sDriveInfo[HW_DRIVE_D];
  943. break;
  944. }
  945. case '1':{
  946. pDrive = &sDriveInfo[HW_DRIVE_E];
  947. break;
  948. }
  949. }
  950. }
  951. return(pDrive);
  952. }
  953. /************************************************************/
  954. /* FATFileOpen */
  955. /* */
  956. /* Opens an existing file for reading. */
  957. /* */
  958. /* Parameters: pName points to a string that specifies the */
  959. /* name of the file to open. The name must */
  960. /* exactly match the full pathname of the file.*/
  961. /* */
  962. /* Returns: A pointer to a FILE structure that can be */
  963. /* used to read the file and retrieve */
  964. /* information about the file. */
  965. /* */
  966. /* A return value of -1 indicates an error. */
  967. /************************************************************/
  968. static NUTFILE *FATFileOpen(NUTDEVICE *pDevice, CONST char *pName, int nMode,
  969. int nAccess)
  970. {
  971. int i, x;
  972. int nError;
  973. int nEndWhile;
  974. DWORD dwFileSize;
  975. DWORD dwCluster;
  976. FHANDLE *hFile;
  977. DRIVE_INFO *pDrive;
  978. FAT32_DIRECTORY_ENTRY sDirEntry;
  979. NUTFILE *hNUTFile;
  980. int nLongName;
  981. char *pLongName;
  982. char *pShortName;
  983. char *pExtension;
  984. //
  985. // If the user has forgotten to call NUTDeviceOpen,
  986. // we must call FATInit.
  987. //
  988. if (nIsInit == FALSE)
  989. {
  990. FATInit(pDevice);
  991. }
  992. FATLock();
  993. pDrive = NULL;
  994. nError = TRUE;
  995. nLongName = FALSE;
  996. pLongName = (char *)pLongName1;
  997. //
  998. // hFile is our FAT-Handle.
  999. //
  1000. hFile = NULL;
  1001. //
  1002. // hNUTFile is the.... correct, NUT handle.
  1003. //
  1004. hNUTFile = (NUTFILE *) NUTDEV_ERROR;
  1005. pDrive = GetDriveByDevice(pDevice);
  1006. if ((pDrive != NULL) && (pDrive->bSectorsPerCluster != 0) && (pName[0] != 0))
  1007. {
  1008. //
  1009. // Create a new file handle.
  1010. //
  1011. hFile = (FHANDLE *) NutHeapAlloc(sizeof(FHANDLE));
  1012. if ((pDrive->dwFAT1StartSector) && (hFile != NULL) && (*pName != '.'))
  1013. {
  1014. memset(hFile, 0x00, sizeof(FHANDLE));
  1015. //
  1016. // Start by the ROOT dir...
  1017. //
  1018. dwCluster = pDrive->dwRootCluster;
  1019. //
  1020. // If the first char a "/", jump over, e.g. "/index.html"
  1021. //
  1022. //
  1023. if (*pName == '/')
  1024. {
  1025. pName++;
  1026. }
  1027. nEndWhile = FALSE;
  1028. while (nEndWhile == FALSE)
  1029. { /* master loop */
  1030. nLongName = FALSE;
  1031. //
  1032. // Get Name
  1033. //
  1034. i = 0;
  1035. while ((*pName != '/') && (*pName != '\\') && (*pName != 0))
  1036. {
  1037. if (i >= (FAT_LONG_NAME_LEN - 1))
  1038. {
  1039. nEndWhile = TRUE;
  1040. break;
  1041. }
  1042. pLongName[i] = toupper(*pName);
  1043. i++;
  1044. pName++;
  1045. } /* endwhile Name */
  1046. if (nEndWhile == FALSE)
  1047. {
  1048. pLongName[i] = 0;
  1049. //
  1050. // Check if it is a Long Directory Entry.
  1051. // Yes, I know that 'i' is the length of the string.
  1052. // But the code is easier to read with the next strlen.
  1053. //
  1054. if (strlen(pLongName) <= FAT_SHORT_NAME_LEN)
  1055. {
  1056. //
  1057. // It could be a ShortName, but "abc.defg" is possible
  1058. // and this is a long name too. Therfore we need some tests.
  1059. //
  1060. pExtension = strchr(pLongName, '.');
  1061. if (pExtension == NULL)
  1062. {
  1063. if (strlen(pLongName) > FAT_NAME_LEN)
  1064. {
  1065. nLongName = TRUE;
  1066. }
  1067. else
  1068. {
  1069. nLongName = FALSE;
  1070. }
  1071. }
  1072. else
  1073. {
  1074. //
  1075. // Check the length of the extensions.
  1076. //
  1077. pExtension++; /* jump over the '.' */
  1078. if (strlen(pExtension) > 3)
  1079. {
  1080. nLongName = TRUE;
  1081. }
  1082. }
  1083. }
  1084. else
  1085. { /* Len > FAT_SHORT_NAME_LEN */
  1086. //
  1087. // Now we have a LongName, sure.
  1088. // See the "nasty Win98" in FindFile :-)
  1089. //
  1090. nLongName = TRUE;
  1091. }
  1092. //
  1093. // Here we knows, if we have a LongName or ShortName.
  1094. //
  1095. if (nLongName == FALSE)
  1096. {
  1097. //
  1098. // ShortName
  1099. //
  1100. pShortName = pLongName;
  1101. memset(&sDirEntry, 0x00, sizeof(FAT32_DIRECTORY_ENTRY));
  1102. memset(sDirEntry.Name, 0x20, FAT_NAME_LEN);
  1103. memset(sDirEntry.Extension, 0x20, FAT_EXT_LEN);
  1104. //
  1105. // Get the name
  1106. //
  1107. i = 0;
  1108. while ((pShortName[i] != '.') && (pShortName[i] != 0))
  1109. {
  1110. sDirEntry.Name[i] = pShortName[i];
  1111. i++;
  1112. }
  1113. //
  1114. // And the extension
  1115. //
  1116. if (pShortName[i] == '.')
  1117. {
  1118. i++; /* jump over the '.' */
  1119. x = 0;
  1120. while (pShortName[i] != 0)
  1121. {
  1122. sDirEntry.Extension[x] = pShortName[i];
  1123. i++;
  1124. x++;
  1125. }
  1126. }
  1127. }
  1128. //
  1129. // The file could be a long or short one.
  1130. // I have seen that Win98 store the short filename
  1131. // in a long one :-(
  1132. //
  1133. switch (*pName)
  1134. {
  1135. //
  1136. // The file is an ARCHIVE
  1137. //
  1138. case 0:{
  1139. nEndWhile = TRUE;
  1140. sDirEntry.Attribute = DIRECTORY_ATTRIBUTE_ARCHIVE;
  1141. if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
  1142. {
  1143. dwCluster = 0;
  1144. }
  1145. else
  1146. {
  1147. dwCluster =
  1148. FindFile(pDrive, &sDirEntry, pLongName, dwCluster, &dwFileSize,
  1149. nLongName);
  1150. }
  1151. if (dwCluster != 0)
  1152. {
  1153. hFile->dwFileSize = dwFileSize;
  1154. hFile->dwStartCluster = dwCluster;
  1155. hFile->dwReadCluster = dwCluster;
  1156. hFile->dwFilePointer = 0;
  1157. hFile->dwClusterPointer = 0;
  1158. hFile->pDrive = pDrive;
  1159. hFile->nLastError = FAT_OK;
  1160. hFile->nEOF = FALSE;
  1161. nError = FALSE;
  1162. }
  1163. break;
  1164. } /* endcase 0 */
  1165. //
  1166. // The file is a DIRECTORY
  1167. //
  1168. case '/':
  1169. case '\\':{
  1170. pName++; /* jump over the char */
  1171. sDirEntry.Attribute = DIRECTORY_ATTRIBUTE_DIRECTORY;
  1172. if (pDrive->bFlags & FLAG_FAT_IS_CDROM)
  1173. {
  1174. dwCluster = 0;
  1175. }
  1176. else
  1177. {
  1178. dwCluster =
  1179. FindFile(pDrive, &sDirEntry, pLongName, dwCluster, &dwFileSize,
  1180. nLongName);
  1181. }
  1182. if (dwCluster != 0)
  1183. {
  1184. //
  1185. // The new Cluster is the Cluster of the directory
  1186. //
  1187. }
  1188. else
  1189. {
  1190. nEndWhile = TRUE;
  1191. }
  1192. break;
  1193. } /* endcase / \ */
  1194. default:{
  1195. nEndWhile = TRUE;
  1196. break;
  1197. }
  1198. } /* end switch */
  1199. }
  1200. /*
  1201. * endif nEndWhile == FALSE
  1202. */
  1203. } /* end while */
  1204. }
  1205. /*
  1206. * endif pDrive->dwFAT1StartSector
  1207. */
  1208. if (nError == TRUE)
  1209. {
  1210. //
  1211. // We found no file, therefore we can delete our FAT-Handle
  1212. //
  1213. if (hFile != NULL)
  1214. {
  1215. NutHeapFree(hFile);
  1216. }
  1217. }
  1218. else
  1219. {
  1220. //
  1221. // We have found a FILE and can create a NUT-Handle.
  1222. //
  1223. hNUTFile = NutHeapAlloc(sizeof(NUTFILE));
  1224. if (hNUTFile != NULL)
  1225. {
  1226. hNUTFile->nf_next = 0;
  1227. hNUTFile->nf_dev = pDevice;
  1228. hNUTFile->nf_fcb = hFile;
  1229. }
  1230. else
  1231. {
  1232. //
  1233. // Error, no mem for the NUT-Handle, therefore we
  1234. // can delete our FAT-Handle too.
  1235. //
  1236. NutHeapFree(hFile);
  1237. }
  1238. }
  1239. }
  1240. /*
  1241. * endif pName[0] != 0
  1242. */
  1243. FATFree();
  1244. return(hNUTFile);
  1245. }
  1246. /************************************************************/
  1247. /* FATFileClose */
  1248. /* */
  1249. /* Close a previously opened file. */
  1250. /* */
  1251. /* Parameters: hNUTFile Identifies the file to close. */
  1252. /* This pointer must have been created by */
  1253. /* calling FAT32FileOpen(). */
  1254. /* */
  1255. /* Returns: 0 if the function is successfully closed, */
  1256. /* -1 otherwise. */
  1257. /************************************************************/
  1258. static int FATFileClose(NUTFILE * hNUTFile)
  1259. {
  1260. int nError;
  1261. FHANDLE *hFile;
  1262. nError = NUTDEV_ERROR;
  1263. FATLock();
  1264. if (hNUTFile != NULL)
  1265. {
  1266. hFile = (FHANDLE *) hNUTFile->nf_fcb;
  1267. if (hFile != NULL)
  1268. {
  1269. //
  1270. // Clear our FAT-Handle
  1271. //
  1272. NutHeapFree(hFile);
  1273. }
  1274. //
  1275. // Clear the NUT-Handle
  1276. //
  1277. NutHeapFree(hNUTFile);
  1278. nError = NUTDEV_OK;
  1279. }
  1280. FATFree();
  1281. return(nError);
  1282. }
  1283. /************************************************************/
  1284. /* FATFileSize */
  1285. /* */
  1286. /* Retrieve the size of a file. */
  1287. /* */
  1288. /* Parameters: pFile Identifies the file to query. */
  1289. /* This pointer must have been created by */
  1290. /* calling FAT32FileOpen(). */
  1291. /* */
  1292. /* Returns: The number of bytes in this file or */
  1293. /* -1 if an error occured */
  1294. /************************************************************/
  1295. long FATFileSize(NUTFILE * hNUTFile)
  1296. {
  1297. long lSize;
  1298. FHANDLE *hFile;
  1299. FATLock();
  1300. lSize = NUTDEV_ERROR;
  1301. if (hNUTFile != NULL)
  1302. {
  1303. hFile = (FHANDLE *) hNUTFile->nf_fcb;
  1304. if (hFile != NULL)
  1305. {
  1306. lSize = hFile->dwFileSize;
  1307. }
  1308. }
  1309. FATFree();
  1310. return(lSize);
  1311. }
  1312. #if 0
  1313. /************************************************************/
  1314. /* FATFileSeek */
  1315. /* */
  1316. /* Move the file pointer to a new position. */
  1317. /* It points to the next byte to be read from a file. */
  1318. /* The file pointer is automatically incremented for */
  1319. /* each byte read. When the file is opened, it is at */
  1320. /* position 0, the beginning of the file. */
  1321. /* */
  1322. /* Parameters: pFile Identifies the file to seek. */
  1323. /* This pointer must have been created by */
  1324. /* calling FAT32FileOpen(). */
  1325. /* */
  1326. /* lPos Specifies the new absolute position */
  1327. /* of the file pointer. */
  1328. /* */
  1329. /* Returns: 0 if the function is successful, */
  1330. /* -1 otherwise. */
  1331. /************************************************************/
  1332. int FATFileSeek(FILE * pFile, long lPos)
  1333. {
  1334. int nError = NUTDEV_ERROR;
  1335. FHANDLE *hFile;
  1336. FATLock();
  1337. hFile = (FHANDLE *) pFile;
  1338. //
  1339. // We must do some work here...
  1340. //
  1341. nError = FAT32_ERROR;
  1342. FATFree();
  1343. return(nError);
  1344. }
  1345. #endif
  1346. /************************************************************/
  1347. /* FATFileRead */
  1348. /* */
  1349. /* Read data from a file. */
  1350. /* */
  1351. /* Parameters: pFile Identifies the file to read from. */
  1352. /* This pointer must have been created by */
  1353. /* calling FAT32FileOpen(). */
  1354. /* */
  1355. /* pData Points to the buffer that receives */
  1356. /* the data. */
  1357. /* */
  1358. /* nSize Specifies the number of bytes to */
  1359. /* read from the file. */
  1360. /* */
  1361. /* Returns: The number of bytes read from the file or */
  1362. /* -1 if an error occured. */
  1363. /************************************************************/
  1364. int FATFileRead(NUTFILE * hNUTFile, void *pData, int nSize)
  1365. {
  1366. int nError;
  1367. int nBytesRead;
  1368. int nBytesToRead;
  1369. FHANDLE *hFile;
  1370. DRIVE_INFO *pDrive;
  1371. BYTE *pByte;
  1372. DWORD dwReadSector;
  1373. DWORD dwSector;
  1374. int nSectorCount;
  1375. int nSectorOffset;
  1376. WORD wSectorSize;
  1377. nBytesRead = 0;
  1378. FATLock();
  1379. hFile = NULL;
  1380. nError = NUTDEV_ERROR;
  1381. if (hNUTFile != NULL)
  1382. {
  1383. hFile = (FHANDLE *) hNUTFile->nf_fcb;
  1384. }
  1385. if ((hFile != NULL) && (nSize != 0))
  1386. {
  1387. if (hFile->dwFilePointer < hFile->dwFileSize)
  1388. {
  1389. if ((hFile->dwFilePointer + nSize) > hFile->dwFileSize)
  1390. {
  1391. nSize = (int) (hFile->dwFileSize - hFile->dwFilePointer);
  1392. }
  1393. pDrive = (DRIVE_INFO *) hFile->pDrive;
  1394. pByte = (BYTE *) pData;
  1395. nBytesRead = nSize;
  1396. wSectorSize = pDrive->wSectorSize;
  1397. while (nSize)
  1398. {
  1399. dwSector = GetFirstSectorOfCluster(pDrive, hFile->dwReadCluster);
  1400. nSectorCount = hFile->dwClusterPointer / wSectorSize;
  1401. nSectorOffset = hFile->dwClusterPointer % wSectorSize;
  1402. //
  1403. // (Sector + SectorCount) is the sector to read
  1404. // SectorOffset is the start position in the sector itself
  1405. //
  1406. dwReadSector = dwSector + nSectorCount;
  1407. nError = HWReadSectors(pDrive->bDevice, pSectorBuffer, dwReadSector, 1);
  1408. if (nError == HW_OK)
  1409. {
  1410. //
  1411. // Find the size we can read from ONE sector
  1412. //
  1413. if (nSize > (int) wSectorSize)
  1414. {
  1415. nBytesToRead = wSectorSize;
  1416. }
  1417. else
  1418. {
  1419. nBytesToRead = nSize;
  1420. }
  1421. //
  1422. // Test inside a sector
  1423. //
  1424. if ((nSectorOffset + nBytesToRead) > (int) wSectorSize)
  1425. {
  1426. nBytesToRead = wSectorSize - nSectorOffset;
  1427. }
  1428. memcpy(pByte, &pSectorBuffer[nSectorOffset], nBytesToRead);
  1429. pByte += nBytesToRead;
  1430. hFile->dwFilePointer += nBytesToRead;
  1431. hFile->dwClusterPointer += nBytesToRead;
  1432. //
  1433. // Check for EOF
  1434. if (hFile->dwFilePointer >= hFile->dwFileSize)
  1435. {
  1436. hFile->nEOF = TRUE;
  1437. }
  1438. if (hFile->dwClusterPointer >= pDrive->dwClusterSize)
  1439. {
  1440. //
  1441. // We must switch to the next cluster
  1442. //
  1443. hFile->dwReadCluster = GetNextCluster(pDrive, hFile->dwReadCluster);
  1444. hFile->dwClusterPointer = 0;
  1445. }
  1446. nSize -= nBytesToRead;
  1447. }
  1448. else
  1449. { /* HWReadSectors Error */
  1450. nBytesRead = 0;
  1451. hFile->nLastError = FAT_ERROR_IDE;
  1452. break;
  1453. } /* endif nError == HW_OK */
  1454. } /* endwhile */
  1455. }
  1456. else
  1457. { /* reached the EOF */
  1458. hFile->nLastError = FAT_ERROR_EOF;
  1459. } /* endif hFile->dwFilePointer < hFile->dwFileSize */
  1460. }
  1461. /*
  1462. * endif (hFile != NULL) && (nSize != 0)
  1463. */
  1464. FATFree();
  1465. return(nBytesRead);
  1466. }
  1467. /************************************************************/
  1468. /* FATFileWrite */
  1469. /* */
  1470. /* Write data to a file. */
  1471. /* */
  1472. /* Parameters: pFile Identifies the file to write to. */
  1473. /* This pointer must have been created by */
  1474. /* calling FAT32FileOpen(). */
  1475. /* */
  1476. /* pData Points to the buffer that holds */
  1477. /* the data. */
  1478. /* */
  1479. /* nSize Specifies the number of bytes to */
  1480. /* write to the file. */
  1481. /* */
  1482. /* Returns: The number of bytes written to the file or */
  1483. /* -1 if an error occured. */
  1484. /************************************************************/
  1485. static int FATFileWrite(NUTFILE * hNUTFile, CONST void *pData, int nSize)
  1486. {
  1487. int nError;
  1488. nError = NUTDEV_ERROR;
  1489. return(nError);
  1490. }
  1491. #ifdef __HARVARD_ARCH__
  1492. static int FATFileWriteP(NUTFILE * hNUTFile, PGM_P pData, int nSize)
  1493. {
  1494. int nError;
  1495. nError = NUTDEV_ERROR;
  1496. return(nError);
  1497. }
  1498. #endif
  1499. /************************************************************/
  1500. /* FATIOCtl */
  1501. /* */
  1502. /* Perform IOCTL control functions. */
  1503. /* */
  1504. /* reg May be set to one of the following constants: */
  1505. /* */
  1506. /* Parameters: dev Identifies the device to use. */
  1507. /* reg Requested control function. */
  1508. /* conf Points to a buffer that contains any */
  1509. /* data required for the given control */
  1510. /* function or receives data from that */
  1511. /* function. */
  1512. /* Returns: 0 on success, or -1 if an error occured. */
  1513. /************************************************************/
  1514. int FATIOCtl(NUTDEVICE *dev, int req, void *conf)
  1515. {
  1516. int nError = NUTDEV_ERROR;
  1517. DRIVE_INFO *pDrive = GetDriveByDevice(dev);
  1518. if (pDrive != NULL)
  1519. {
  1520. switch (req)
  1521. {
  1522. #if (FAT_SUPPORT_FORMAT >= 1)
  1523. case FAT_IOCTL_QUICK_FORMAT: {
  1524. nError = QuickFormat(dev, pDrive);
  1525. break;
  1526. }
  1527. #endif
  1528. default: {
  1529. nError = NUTDEV_ERROR;
  1530. break;
  1531. }
  1532. }
  1533. }
  1534. return(nError);
  1535. }
  1536. //
  1537. // FAT Device information structure.
  1538. // Is mapped to the FAT-Device.
  1539. // The user MUST first register the FAT hardware.
  1540. //
  1541. NUTDEVICE devFAT = {
  1542. 0, /* Pointer to next device. */
  1543. /*
  1544. * Unique device name.
  1545. */
  1546. {'F', 'A', 'T', 0, 0, 0, 0, 0, 0},
  1547. IFTYP_STREAM, /* Type of device. */
  1548. 2, /* Base address. */
  1549. 0, /* First interrupt number. */
  1550. 0, /* Interface control block. */
  1551. 0, /* Driver control block. */
  1552. FATInit, /* Driver initialization routine. */
  1553. 0, /* Driver specific control function. */
  1554. 0, /* Driver specific read function. */
  1555. 0, /* Driver specific write function. */
  1556. #ifdef __HARVARD_ARCH__
  1557. 0, /* Driver specific write_p function. */
  1558. #endif
  1559. 0, /* Driver specific open function. */
  1560. 0, /* Driver specific close function. */
  1561. 0
  1562. };
  1563. #if (FAT_USE_MMC_INTERFACE >= 1)
  1564. //
  1565. // FATUSB Device information structure.
  1566. // Is mapped to the first USB drive
  1567. //
  1568. NUTDEVICE devFATMMC0 = {
  1569. 0, /* Pointer to next device. */
  1570. /*
  1571. * Unique device name.
  1572. */
  1573. {'F', 'M', '0', 0, 0, 0, 0, 0, 0},
  1574. IFTYP_STREAM, /* Type of device. */
  1575. 2, /* Base address. */
  1576. 0, /* First interrupt number. */
  1577. 0, /* Interface control block. */
  1578. 0, /* Driver control block. */
  1579. FATInit, /* Driver initialization routine. */
  1580. FATIOCtl, /* Driver specific control function. */
  1581. FATFileRead, /* Driver specific read function. */
  1582. FATFileWrite, /* Driver specific write function. */
  1583. #ifdef __HARVARD_ARCH__
  1584. FATFileWriteP, /* Driver specific write_p function. */
  1585. #endif
  1586. FATFileOpen, /* Driver specific open function. */
  1587. FATFileClose, /* Driver specific close function. */
  1588. FATFileSize
  1589. };
  1590. #endif /* (FAT_USE_MMC_INTERFACE >= 1) */
  1591. #if (FAT_SUPPORT_FORMAT >= 1)
  1592. /************************************************************/
  1593. /* GetClusterSize */
  1594. /************************************************************/
  1595. static BYTE GetClusterSize (DWORD dTotalSectors)
  1596. {
  1597. BYTE bIndex;
  1598. BYTE bSecPerClus = 0;
  1599. for (bIndex=0; bIndex<DSK_TABLE_FAT32_ENTRY_COUNT; bIndex++)
  1600. {
  1601. if (dTotalSectors <= DskTableFAT32[bIndex].DiskSize)
  1602. {
  1603. bSecPerClus = DskTableFAT32[bIndex].SecPerClusVal;
  1604. break;
  1605. }
  1606. }
  1607. return(bSecPerClus);
  1608. }
  1609. /************************************************************/
  1610. /* QuickFormat */
  1611. /************************************************************/
  1612. static int QuickFormat(NUTDEVICE *dev, DRIVE_INFO *pDrive)
  1613. {
  1614. DWORD i;
  1615. int nError = NUTDEV_ERROR;
  1616. BYTE *pBuffer;
  1617. BYTE bDevice;
  1618. BYTE bSecPerClus;
  1619. DWORD dSector;
  1620. DWORD dFirstDataSector;
  1621. DWORD dLastDataSector;
  1622. DWORD dMaxClusterCount;
  1623. DWORD dFAT1StartSector=0;
  1624. DWORD dFAT2StartSector=0;
  1625. DWORD dCluster2StartSector;
  1626. DWORD dClearCount;
  1627. DWORD dTotalSectors;
  1628. DWORD dPossibleClusterCount;
  1629. DWORD dFATSz32;
  1630. FAT32_PARTITION_TABLE *pPartitionTable;
  1631. FAT32_BOOT_RECORD *pBootRecord;
  1632. FAT32_FSINFO *pFSInfo;
  1633. FAT32_DIRECTORY_ENTRY *pDirEntry;
  1634. LONG *pLong;
  1635. DWORD dVollID;
  1636. FATLock();
  1637. /*
  1638. * Get the sector buffer
  1639. */
  1640. pBuffer = (u_char *)NutHeapAlloc(pDrive->wSectorSize);
  1641. if (pBuffer != NULL)
  1642. {
  1643. bDevice = pDrive->bDevice;
  1644. dTotalSectors = HWGetTotalSectors(bDevice);
  1645. dTotalSectors -= BPB_RsvdSecCnt;
  1646. bSecPerClus = GetClusterSize(dTotalSectors);
  1647. if (bSecPerClus == 0)
  1648. {
  1649. /*
  1650. * Sorry, to small for FAT32,
  1651. * the lib will support FAT16 later....
  1652. */
  1653. NutHeapFree(pBuffer);
  1654. return(NUTDEV_ERROR);
  1655. }
  1656. dPossibleClusterCount = (dTotalSectors / (LONG)bSecPerClus);
  1657. dFATSz32 = (dPossibleClusterCount * sizeof(long) +
  1658. (FAT32_SECTOR_SIZE -1) ) / FAT32_SECTOR_SIZE;
  1659. /*
  1660. * First we will clear the sectors which we will use
  1661. * for the MBR, BPB and the FA's.
  1662. */
  1663. dClearCount = BPB_HiddSec + BPB_RsvdSecCnt;
  1664. dClearCount += (BPB_NumFATs * dFATSz32) + bSecPerClus;
  1665. memset(pBuffer, 0x00, pDrive->wSectorSize);
  1666. for (i=0; i<dClearCount; i++)
  1667. {
  1668. nError = HWWriteSectors(bDevice, pBuffer, i, 1);
  1669. if (nError != HW_OK)
  1670. {
  1671. break;
  1672. }
  1673. }
  1674. /*
  1675. * Create the Volume serial number,
  1676. * we have no random value, therefore
  1677. * use the dTotalSectors and time.
  1678. */
  1679. dVollID = (DWORD)time(NULL) * dTotalSectors;
  1680. /*
  1681. * Create MBR (MasterBootRecord)
  1682. */
  1683. memset(pBuffer, 0x00, pDrive->wSectorSize);
  1684. pPartitionTable = (FAT32_PARTITION_TABLE *)pBuffer;
  1685. pPartitionTable->Partition[0].BootInd = 0x00;
  1686. pPartitionTable->Partition[0].FirstHead = 1;
  1687. pPartitionTable->Partition[0].FirstSector = 1;
  1688. pPartitionTable->Partition[0].FirstTrack = 0;
  1689. pPartitionTable->Partition[0].FileSystem = MBR_FAT32;
  1690. pPartitionTable->Partition[0].LastHead = 0;
  1691. pPartitionTable->Partition[0].LastSector = 0;
  1692. pPartitionTable->Partition[0].StartSectors = BPB_HiddSec;
  1693. pPartitionTable->Partition[0].NumSectors = dTotalSectors;
  1694. pPartitionTable->Signature = MBR_SIGNATURE;
  1695. /*
  1696. * Write the MBR to the drive
  1697. */
  1698. nError = HWWriteSectors(bDevice, pBuffer, 0, 1);
  1699. if (nError == HW_OK)
  1700. {
  1701. /*
  1702. * Create the BPB
  1703. */
  1704. memset(pBuffer, 0x00, pDrive->wSectorSize);
  1705. pBootRecord = (FAT32_BOOT_RECORD *)pBuffer;
  1706. pBootRecord->JumpBoot[0] = 0xEB;
  1707. pBootRecord->JumpBoot[1] = 0x58;
  1708. pBootRecord->JumpBoot[2] = 0x90;
  1709. pBootRecord->OEMName[0] = 'M';
  1710. pBootRecord->OEMName[1] = 'S';
  1711. pBootRecord->OEMName[2] = 'D';
  1712. pBootRecord->OEMName[3] = 'O';
  1713. pBootRecord->OEMName[4] = 'S';
  1714. pBootRecord->OEMName[5] = '5';
  1715. pBootRecord->OEMName[6] = '.';
  1716. pBootRecord->OEMName[7] = '0';
  1717. pBootRecord->BytsPerSec = FAT32_SECTOR_SIZE;
  1718. pBootRecord->SecPerClus = bSecPerClus;
  1719. pBootRecord->RsvdSecCnt = BPB_RsvdSecCnt;
  1720. pBootRecord->NumFATs = BPB_NumFATs;
  1721. pBootRecord->RootEntCnt = 0;
  1722. pBootRecord->TotSec16 = 0;
  1723. pBootRecord->Media = FAT32_MEDIA;
  1724. pBootRecord->FATSz16 = 0;
  1725. pBootRecord->SecPerTrk = 63;
  1726. pBootRecord->NumHeads = 255;
  1727. pBootRecord->HiddSec = BPB_HiddSec;
  1728. pBootRecord->TotSec32 = dTotalSectors;
  1729. pBootRecord->Off36.FAT32.FATSz32 = dFATSz32;
  1730. pBootRecord->Off36.FAT32.ExtFlags = 0;
  1731. pBootRecord->Off36.FAT32.FSVer = 0;
  1732. pBootRecord->Off36.FAT32.RootClus = 2;
  1733. pBootRecord->Off36.FAT32.FSInfo = FAT32_OFFSET_FSINFO;
  1734. pBootRecord->Off36.FAT32.BkBootSec = FAT32_OFFSET_BACKUP_BOOT;
  1735. pBootRecord->Off36.FAT32.DrvNum = 0x00;
  1736. pBootRecord->Off36.FAT32.BootSig = 0x29;
  1737. pBootRecord->Off36.FAT32.VollID = dVollID;
  1738. pBootRecord->Off36.FAT32.VolLab[0] = 'N';
  1739. pBootRecord->Off36.FAT32.VolLab[1] = 'O';
  1740. pBootRecord->Off36.FAT32.VolLab[2] = ' ';
  1741. pBootRecord->Off36.FAT32.VolLab[3] = 'N';
  1742. pBootRecord->Off36.FAT32.VolLab[4] = 'A';
  1743. pBootRecord->Off36.FAT32.VolLab[5] = 'M';
  1744. pBootRecord->Off36.FAT32.VolLab[6] = 'E';
  1745. pBootRecord->Off36.FAT32.VolLab[7] = ' ';
  1746. pBootRecord->Off36.FAT32.VolLab[8] = ' ';
  1747. pBootRecord->Off36.FAT32.VolLab[9] = ' ';
  1748. pBootRecord->Off36.FAT32.VolLab[10] = ' ';
  1749. pBootRecord->Off36.FAT32.FilSysType[0] = 'F';
  1750. pBootRecord->Off36.FAT32.FilSysType[1] = 'A';
  1751. pBootRecord->Off36.FAT32.FilSysType[2] = 'T';
  1752. pBootRecord->Off36.FAT32.FilSysType[3] = '3';
  1753. pBootRecord->Off36.FAT32.FilSysType[4] = '2';
  1754. pBootRecord->Off36.FAT32.FilSysType[5] = ' ';
  1755. pBootRecord->Off36.FAT32.FilSysType[6] = ' ';
  1756. pBootRecord->Off36.FAT32.FilSysType[7] = ' ';
  1757. pBootRecord->Signature = FAT_SIGNATURE;
  1758. /*
  1759. * Write the BPB to the drive
  1760. */
  1761. dSector = BPB_HiddSec;
  1762. nError = HWWriteSectors(bDevice, pBuffer, dSector, 1);
  1763. if (nError == HW_OK)
  1764. {
  1765. dSector += FAT32_OFFSET_BACKUP_BOOT;
  1766. nError = HWWriteSectors(bDevice, pBuffer, dSector, 1);
  1767. }
  1768. }
  1769. /*
  1770. * Create the FSINFO
  1771. */
  1772. if (nError == HW_OK)
  1773. {
  1774. memset(pBuffer, 0x00, pDrive->wSectorSize);
  1775. pFSInfo = (FAT32_FSINFO *)pBuffer;
  1776. dFirstDataSector = BPB_HiddSec + BPB_RsvdSecCnt;
  1777. dLastDataSector = dTotalSectors;
  1778. dMaxClusterCount = dLastDataSector - dFirstDataSector;
  1779. dMaxClusterCount = dMaxClusterCount / (LONG)bSecPerClus;
  1780. pFSInfo->FirstSignature = FSINFO_FIRSTSIGNATURE;
  1781. pFSInfo->FSInfoSignature = FSINFO_FSINFOSIGNATURE;
  1782. pFSInfo->NumberOfFreeClusters = dMaxClusterCount;
  1783. pFSInfo->MostRecentlyAllocatedCluster = 2;
  1784. pFSInfo->Signature = FSINFO_SIGNATURE;
  1785. /*
  1786. * Write the FSINFO to the drive
  1787. */
  1788. dSector = BPB_HiddSec + FAT32_OFFSET_FSINFO;
  1789. nError = HWWriteSectors(bDevice, pBuffer, dSector, 1);
  1790. }
  1791. /*
  1792. * Write first FAT entry after format.
  1793. */
  1794. if (nError == HW_OK)
  1795. {
  1796. dFAT1StartSector = BPB_HiddSec + BPB_RsvdSecCnt;
  1797. dFAT2StartSector = dFAT1StartSector + dFATSz32;
  1798. memset(pBuffer, 0x00, pDrive->wSectorSize);
  1799. pLong = (LONG *)pBuffer;
  1800. /*
  1801. * Set the two reserved cluster after the format,
  1802. * take a look in the MS Hardware White Paper
  1803. * Version 1.03, December 6, 2000 for more information.
  1804. */
  1805. *pLong++ = 0x0FFFFFF8;
  1806. *pLong++ = FAT32_CLUSTER_EOF;
  1807. *pLong++ = FAT32_CLUSTER_EOF;
  1808. nError = HWWriteSectors(bDevice, pBuffer, dFAT1StartSector, 1);
  1809. if (nError == HW_OK)
  1810. {
  1811. nError = HWWriteSectors(bDevice, pBuffer, dFAT2StartSector, 1);
  1812. }
  1813. }
  1814. /*
  1815. * Create RootDir
  1816. */
  1817. if (nError == HW_OK)
  1818. {
  1819. memset(pBuffer, 0x00, pDrive->wSectorSize);
  1820. pDirEntry = (FAT32_DIRECTORY_ENTRY *)pBuffer;
  1821. pDirEntry->Name[0] = 'E';
  1822. pDirEntry->Name[1] = 'T';
  1823. pDirEntry->Name[2] = 'H';
  1824. pDirEntry->Name[3] = 'E';
  1825. pDirEntry->Name[4] = 'R';
  1826. pDirEntry->Name[5] = 'N';
  1827. pDirEntry->Name[6] = 'U';
  1828. pDirEntry->Name[7] = 'T';
  1829. pDirEntry->Extension[0] = ' ';
  1830. pDirEntry->Extension[1] = ' ';
  1831. pDirEntry->Extension[2] = ' ';
  1832. pDirEntry->Attribute = DIRECTORY_ATTRIBUTE_VOLUME_ID;
  1833. pDirEntry->HighCluster = 0;
  1834. pDirEntry->LowCluster = 0;
  1835. pDirEntry->FileSize = 0;
  1836. dCluster2StartSector = dFAT2StartSector + dFATSz32;
  1837. nError = HWWriteSectors(bDevice, pBuffer, dCluster2StartSector, 1);
  1838. }
  1839. NutHeapFree(pBuffer);
  1840. FATFree();
  1841. /*
  1842. * Don't forget to mount the drive
  1843. */
  1844. if (nError == HW_OK)
  1845. {
  1846. nError = MountDrive(bDevice);
  1847. }
  1848. if (nError == HW_OK)
  1849. {
  1850. nError = NUTDEV_OK;
  1851. }
  1852. else
  1853. {
  1854. nError = NUTDEV_ERROR;
  1855. }
  1856. }
  1857. return(nError);
  1858. }
  1859. #endif /* (FAT_SUPPORT_FORMAT >= 1) */