Leaked source code of windows server 2003
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.

371 lines
14 KiB

  1. /*
  2. * $Log: V:/Flite/archives/TrueFFS5/Src/DOSFORMT.C_V $
  3. *
  4. * Rev 1.7 Feb 19 2002 20:59:12 oris
  5. * Replaced dosformt.h with blockdev.h
  6. *
  7. * Rev 1.6 Jan 29 2002 20:07:56 oris
  8. * Removed prototype of flBuildGeometry (already found in blockdev.h).
  9. *
  10. * Rev 1.5 Jan 28 2002 21:24:58 oris
  11. * Removed the use of back-slashes in macro definitions.
  12. *
  13. * Rev 1.4 Apr 16 2001 13:33:44 oris
  14. * Removed warrnings.
  15. *
  16. * Rev 1.3 Apr 09 2001 15:06:42 oris
  17. * End with an empty line.
  18. *
  19. * Rev 1.2 Apr 01 2001 07:44:48 oris
  20. * Updated copywrite notice
  21. *
  22. * Rev 1.1 Feb 14 2001 02:00:26 oris
  23. * Added oldFormat.
  24. *
  25. * Rev 1.0 Feb 02 2001 13:48:44 oris
  26. * Initial revision.
  27. *
  28. */
  29. /***********************************************************************************/
  30. /* M-Systems Confidential */
  31. /* Copyright (C) M-Systems Flash Disk Pioneers Ltd. 1995-2001 */
  32. /* All Rights Reserved */
  33. /***********************************************************************************/
  34. /* NOTICE OF M-SYSTEMS OEM */
  35. /* SOFTWARE LICENSE AGREEMENT */
  36. /* */
  37. /* THE USE OF THIS SOFTWARE IS GOVERNED BY A SEPARATE LICENSE */
  38. /* AGREEMENT BETWEEN THE OEM AND M-SYSTEMS. REFER TO THAT AGREEMENT */
  39. /* FOR THE SPECIFIC TERMS AND CONDITIONS OF USE, */
  40. /* OR CONTACT M-SYSTEMS FOR LICENSE ASSISTANCE: */
  41. /* E-MAIL = [email protected] */
  42. /***********************************************************************************/
  43. #include "fltl.h"
  44. #ifdef FORMAT_VOLUME
  45. #include "blockdev.h"
  46. #define FAT12bit (LE4(bpb->totalSectorsInVolume) < 4086LU * bpb->sectorsPerCluster)
  47. /*----------------------------------------------------------------------*/
  48. /* g e t D r i v e G e o m e t r y */
  49. /* */
  50. /* Calculates the geometry parameters for BIOS/DOS media */
  51. /* */
  52. /* Parameters: */
  53. /* vol : Pointer identifying drive */
  54. /* oldFormat : Format media with coluster size of 1 sector */
  55. /* */
  56. /* Returns: */
  57. /* bpb : volume BIOS parameter block */
  58. /* cylinders : Number of "cylinders" in volume */
  59. /* noOfFATs : Number of FAT copies */
  60. /*----------------------------------------------------------------------*/
  61. static void getDriveGeometry(TL vol,
  62. BPB FAR2 *bpb,
  63. dword FAR2 *cylinders,
  64. unsigned noOfFATs,
  65. FLBoolean oldFormat)
  66. {
  67. dword heads, sectors;
  68. long int sizeInSectors, noOfClusters;
  69. int directorySectors, sectorsPerFAT;
  70. int minClusterSize;
  71. SectorNo sectorAlignment;
  72. SectorNo capacity = vol.sectorsInVolume(vol.rec); /* Volume size in sectors */
  73. minClusterSize = ((oldFormat == TRUE) ? 1: MIN_CLUSTER_SIZE);
  74. flBuildGeometry( (dword)capacity, (dword FAR2 *)cylinders,
  75. (dword FAR2 *)&heads, (dword FAR2 *)&sectors,oldFormat);
  76. if (vol.recommendedClusterInfo)
  77. vol.recommendedClusterInfo(vol.rec,&minClusterSize,&sectorAlignment);
  78. toLE2(bpb->sectorsPerTrack,(word) sectors);
  79. toLE2(bpb->noOfHeads,(word) heads);
  80. toUNAL2(bpb->bytesPerSector,SECTOR_SIZE);
  81. bpb->noOfFATS = (byte)noOfFATs;
  82. bpb->mediaDescriptor = 0xf8; /* hard disk */
  83. toLE4(bpb->noOfHiddenSectors,sectors);
  84. sizeInSectors = (long) (*cylinders) * heads * sectors - sectors;
  85. toLE4(bpb->totalSectorsInVolume,sizeInSectors);
  86. toUNAL2(bpb->totalSectorsInVolumeDOS3,
  87. (word)(sizeInSectors > 65535l ? 0 : sizeInSectors));
  88. noOfClusters = sizeInSectors / minClusterSize;
  89. for (bpb->sectorsPerCluster = (byte)minClusterSize;
  90. noOfClusters > (!oldFormat && bpb->sectorsPerCluster < 8 ? 32766l : 65534l);
  91. bpb->sectorsPerCluster <<= 1, noOfClusters >>= 1);
  92. if (FAT12bit)
  93. sectorsPerFAT =
  94. (word) ((((noOfClusters + 2L) * 3 + 1) / 2 - 1) / SECTOR_SIZE + 1);
  95. else
  96. sectorsPerFAT =
  97. (word) (((noOfClusters + 2L) * 2 - 1) / SECTOR_SIZE + 1);
  98. toLE2(bpb->sectorsPerFAT,(word)sectorsPerFAT);
  99. directorySectors = (int)(capacity / 200);
  100. if (directorySectors < 1) directorySectors = 1;
  101. if (directorySectors > 15) directorySectors = 15;
  102. toUNAL2(bpb->rootDirectoryEntries,
  103. (word)(directorySectors * (SECTOR_SIZE / sizeof(DirectoryEntry))));
  104. if (vol.recommendedClusterInfo) {
  105. int sectorPadding = (int)((sectorAlignment - (sectors + 1 + noOfFATs * sectorsPerFAT + directorySectors)) % bpb->sectorsPerCluster);
  106. if (sectorPadding < 0)
  107. sectorPadding += bpb->sectorsPerCluster;
  108. toLE2(bpb->reservedSectors,sectorPadding + 1);
  109. }
  110. else
  111. toLE2(bpb->reservedSectors,1);
  112. }
  113. /*----------------------------------------------------------------------*/
  114. /* c r e a t e M a s t e r B o o t R e c o r d */
  115. /* */
  116. /* Creates the Master Boot Record (Sector 0) */
  117. /* */
  118. /* Parameters: */
  119. /* vol : Pointer identifying drive */
  120. /* bpb : volume BIOS parameter block */
  121. /* */
  122. /* Returns: */
  123. /* FLStatus : 0 on success, failed otherwise */
  124. /* cylinders : Number of "cylinders" in volume */
  125. /*----------------------------------------------------------------------*/
  126. static FLStatus createMasterBootRecord(TL vol,
  127. BPB *bpb,
  128. dword cylinders)
  129. {
  130. static byte bootCode[] = {
  131. 0xFA, 0x33, 0xC0, 0x8E, 0xD0, 0xBC, 0x00, 0x7C,
  132. 0x8B, 0xF4, 0x50, 0x07, 0x50, 0x1F, 0xFB, 0xFC,
  133. 0xBF, 0x00, 0x06, 0xB9, 0x00, 0x01, 0xF2, 0xA5,
  134. 0xEA, 0x1D, 0x06, 0x00, 0x00, 0xBE, 0xBE, 0x07,
  135. 0xB3, 0x04, 0x80, 0x3C, 0x80, 0x74, 0x0E, 0x80,
  136. 0x3C, 0x00, 0x75, 0x1C, 0x83, 0xC6, 0x10, 0xFE,
  137. 0xCB, 0x75, 0xEF, 0xCD, 0x18, 0x8B, 0x14, 0x8B,
  138. 0x4C, 0x02, 0x8B, 0xEE, 0x83, 0xC6, 0x10, 0xFE,
  139. 0xCB, 0x74, 0x1A, 0x80, 0x3C, 0x00, 0x74, 0xF4,
  140. 0xBE, 0x8B, 0x06, 0xAC, 0x3C, 0x00, 0x74, 0x0B,
  141. 0x56, 0xBB, 0x07, 0x00, 0xB4, 0x0E, 0xCD, 0x10,
  142. 0x5E, 0xEB, 0xF0, 0xEB, 0xFE, 0xBF, 0x05, 0x00,
  143. 0xBB, 0x00, 0x7C, 0xB8, 0x01, 0x02, 0x57, 0xCD,
  144. 0x13, 0x5F, 0x73, 0x0C, 0x33, 0xC0, 0xCD, 0x13,
  145. 0x4F, 0x75, 0xED, 0xBE, 0xA3, 0x06, 0xEB, 0xD3,
  146. 0xBE, 0xC2, 0x06, 0xBF, 0xFE, 0x7D, 0x81, 0x3D,
  147. 0x55, 0xAA, 0x75, 0xC7, 0x8B, 0xF5, 0xEA, 0x00,
  148. 0x7C, 0x00, 0x00, 0x49, 0x6E, 0x76, 0x61, 0x6C,
  149. 0x69, 0x64, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
  150. 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x74, 0x61, 0x62,
  151. 0x6C, 0x65, 0x00, 0x45, 0x72, 0x72, 0x6F, 0x72,
  152. 0x20, 0x6C, 0x6F, 0x61, 0x64, 0x69, 0x6E, 0x67,
  153. 0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
  154. 0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
  155. 0x6D, 0x00, 0x4D, 0x69, 0x73, 0x73, 0x69, 0x6E,
  156. 0x67, 0x20, 0x6F, 0x70, 0x65, 0x72, 0x61, 0x74,
  157. 0x69, 0x6E, 0x67, 0x20, 0x73, 0x79, 0x73, 0x74,
  158. 0x65, 0x6D};
  159. /* create partition table */
  160. PartitionTable partitionTable;
  161. Partition* ptEntry;
  162. tffsset(&partitionTable,0,sizeof partitionTable);
  163. tffscpy(&partitionTable,bootCode,sizeof bootCode);
  164. ptEntry = partitionTable.ptEntry;
  165. ptEntry->activeFlag = 0x80; /* bootable */
  166. if (LE2(bpb->noOfHeads) > 1) {
  167. ptEntry->startingHead = 1;
  168. toLE2(ptEntry->startingCylinderSector,CYLINDER_SECTOR(0,1));
  169. }
  170. else {
  171. ptEntry->startingHead = 0;
  172. toLE2(ptEntry->startingCylinderSector,CYLINDER_SECTOR(1,1));
  173. }
  174. ptEntry->type = FAT12bit ? 1 : 4;
  175. ptEntry->endingHead = LE2(bpb->noOfHeads) - 1;
  176. toLE2(ptEntry->endingCylinderSector,
  177. (word)CYLINDER_SECTOR((cylinders - 1),LE2(bpb->sectorsPerTrack)));
  178. toUNAL4(ptEntry->startingSectorOfPartition,LE2(bpb->sectorsPerTrack));
  179. toUNAL4(ptEntry->sectorsInPartition,LE4(bpb->totalSectorsInVolume));
  180. toLE2(partitionTable.signature,PARTITION_SIGNATURE);
  181. return vol.writeSector(vol.rec,0,&partitionTable);
  182. }
  183. /*----------------------------------------------------------------------*/
  184. /* c r e a t e D O S B o o t S e c t o r */
  185. /* */
  186. /* Creates the DOS boot sector */
  187. /* */
  188. /* Parameters: */
  189. /* vol : Pointer identifying drive */
  190. /* bpb : volume BIOS parameter block */
  191. /* volumeId : 32-bit volume id */
  192. /* volumeLabel : volume label */
  193. /* */
  194. /* Returns: */
  195. /* FLStatus : 0 on success, failed otherwise */
  196. /*----------------------------------------------------------------------*/
  197. static FLStatus createDOSbootSector(TL vol,
  198. BPB *bpb,
  199. const byte FAR1 *volumeId,
  200. const byte FAR1 *volumeLabel)
  201. {
  202. DOSBootSector bootSector;
  203. tffsset(&bootSector,0,sizeof bootSector);
  204. bootSector.physicalDriveNo = 0x80;
  205. bootSector.extendedBootSignature = 0x29;
  206. tffscpy(bootSector.volumeId,volumeId,sizeof bootSector.volumeId);
  207. tffsset(bootSector.volumeLabel,' ',sizeof bootSector.volumeLabel);
  208. if (volumeLabel)
  209. tffscpy(bootSector.volumeLabel,volumeLabel,sizeof bootSector.volumeLabel);
  210. tffscpy(bootSector.systemId,
  211. FAT12bit ? "FAT12 " : "FAT16 ",
  212. sizeof bootSector.systemId);
  213. bootSector.bpb = *bpb;
  214. bootSector.bpb.jumpInstruction[0] = 0xe9;
  215. tffscpy(bootSector.bpb.OEMname,"MSystems",sizeof bootSector.bpb.OEMname);
  216. toLE2(bootSector.signature,PARTITION_SIGNATURE);
  217. return vol.writeSector(vol.rec,(SectorNo) LE4(bpb->noOfHiddenSectors),&bootSector);
  218. }
  219. /*----------------------------------------------------------------------*/
  220. /* c r e a t e F A T s */
  221. /* */
  222. /* Creates the FAT's */
  223. /* */
  224. /* Parameters: */
  225. /* vol : Pointer identifying drive */
  226. /* bpb : volume BIOS parameter block */
  227. /* */
  228. /* Returns: */
  229. /* FLStatus : 0 on success, failed otherwise */
  230. /*----------------------------------------------------------------------*/
  231. static FLStatus createFATs(TL vol, BPB *bpb)
  232. {
  233. int iFAT;
  234. SectorNo sectorNo = (SectorNo) (LE4(bpb->noOfHiddenSectors) +
  235. LE2(bpb->reservedSectors));
  236. /* create the FATs */
  237. for (iFAT = 0; iFAT < bpb->noOfFATS; iFAT++) {
  238. int iSector;
  239. byte FATEntry[SECTOR_SIZE];
  240. for (iSector = 0; iSector < LE2(bpb->sectorsPerFAT); iSector++) {
  241. tffsset(FATEntry,0,SECTOR_SIZE);
  242. if (iSector == 0) { /* write the reserved FAT entries */
  243. FATEntry[0] = bpb->mediaDescriptor;
  244. FATEntry[1] = 0xff;
  245. FATEntry[2] = 0xff;
  246. if (!FAT12bit)
  247. FATEntry[3] = 0xff;
  248. }
  249. checkStatus(vol.writeSector(vol.rec,sectorNo++,FATEntry));
  250. }
  251. }
  252. return flOK;
  253. }
  254. /*----------------------------------------------------------------------*/
  255. /* c r e a t e R o o t D i r e c t o r y */
  256. /* */
  257. /* Creates the root directory */
  258. /* */
  259. /* Parameters: */
  260. /* vol : Pointer identifying drive */
  261. /* bpb : volume BIOS parameter block */
  262. /* volumeLabel : volume label */
  263. /* */
  264. /* Returns: */
  265. /* FLStatus : 0 on success, failed otherwise */
  266. /*----------------------------------------------------------------------*/
  267. static FLStatus createRootDirectory(TL vol,
  268. BPB *bpb,
  269. const byte FAR1 *volumeLabel)
  270. {
  271. int iEntry;
  272. SectorNo sectorNo = (SectorNo) (LE4(bpb->noOfHiddenSectors) +
  273. LE2(bpb->reservedSectors) +
  274. bpb->noOfFATS * LE2(bpb->sectorsPerFAT));
  275. /* create the root directory */
  276. for (iEntry = 0; iEntry < UNAL2(bpb->rootDirectoryEntries);
  277. iEntry += (SECTOR_SIZE / sizeof(DirectoryEntry))) {
  278. DirectoryEntry rootDirectorySector[SECTOR_SIZE / sizeof(DirectoryEntry)];
  279. tffsset(rootDirectorySector,0,SECTOR_SIZE);
  280. if (iEntry == 0 && volumeLabel) {
  281. tffsset(rootDirectorySector[0].name,' ',sizeof rootDirectorySector[0].name);
  282. tffscpy(rootDirectorySector[0].name,volumeLabel,sizeof rootDirectorySector[0].name);
  283. rootDirectorySector[0].attributes = 0x28; /* VOL + ARC */
  284. toLE2(rootDirectorySector[0].updateTime,0);
  285. toLE2(rootDirectorySector[0].updateDate,0x21); /* 1/1/80 */
  286. }
  287. checkStatus(vol.writeSector(vol.rec,sectorNo++,rootDirectorySector));
  288. }
  289. return flOK;
  290. }
  291. /*----------------------------------------------------------------------*/
  292. /* f l D o s F o r m a t */
  293. /* */
  294. /* Writes a DOS-FAT file system on the Flash volume */
  295. /* */
  296. /* Parameters: */
  297. /* vol : Pointer identifying drive */
  298. /* formatParams : Address of FormatParams structure to use */
  299. /* */
  300. /* Returns: */
  301. /* FLStatus : 0 on success, failed otherwise */
  302. /*----------------------------------------------------------------------*/
  303. FLStatus flDosFormat(TL vol, BDTLPartitionFormatParams FAR1 *formatParams)
  304. {
  305. dword cylinders;
  306. BPB bpb;
  307. getDriveGeometry(&vol,&bpb,&cylinders,formatParams->noOfFATcopies,
  308. (formatParams->flags & TL_OLD_FORMAT) ? TRUE : FALSE);
  309. checkStatus(createMasterBootRecord(&vol,&bpb,cylinders));
  310. checkStatus(createDOSbootSector(&vol,&bpb,formatParams->volumeId,formatParams->volumeLabel));
  311. checkStatus(createFATs(&vol,&bpb));
  312. checkStatus(createRootDirectory(&vol,&bpb,formatParams->volumeLabel));
  313. return flOK;
  314. }
  315. #endif