Ejemplo n.º 1
0
 /// <summary>
 /// Initializes a new FAT file.
 /// </summary>
 /// <param name="aFileSystem">The FAT file system to which the file belongs.</param>
 /// <param name="parent">The parent directory of the file.</param>
 /// <param name="aName">The name of the file.</param>
 /// <param name="aSize">The size of the file.</param>
 /// <param name="aFirstCluster">The first cluster number of the file.</param>
 /// <remarks>
 /// Size is UInt32 because FAT doesn't support bigger. Don't change to UInt64.
 /// </remarks>
 public FATFile(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aSize, UInt32 aFirstCluster)
     : base(aFileSystem, parent, aName, aSize)
 {
     TheFATFileSystem = aFileSystem;
     FirstClusterNum = aFirstCluster;
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Formats the specified partition as FAT32.
        /// </summary>
        /// <param name="thePartition">The partition to format.</param>
        public static void FormatPartitionAsFAT32(Partition thePartition)
        {
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"Creating block array... Block size: ") + thePartition.BlockSize);
#endif

            byte[] newBPBData = thePartition.TheDiskDevice.NewBlockArray(1);

#if FATFS_TRACE
            BasicConsole.WriteLine("Block array created.");
#endif

            //FAT signature
            newBPBData[510] = 0x55;
            newBPBData[511] = 0xAA;

            //Bytes per sector - 512
            UInt16 bytesPerSector = 512;
            newBPBData[11] = (byte)(bytesPerSector);
            newBPBData[12] = (byte)(bytesPerSector >> 8);
            ulong partitionSize = thePartition.BlockCount * thePartition.BlockSize;

#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"partitionSize: ") + partitionSize);
#endif
            
            byte sectorsPerCluster = 0x1;
            //See http://www.win.tue.nl/~aeb/linux/fs/fat/fat-1.html
            if (partitionSize < 0x10400000UL /*(260MiB)*/)
            {
                sectorsPerCluster = 0x1; //1
            }
            else if (partitionSize < 0x200000000 /*(8GiB)*/)
            {
                sectorsPerCluster = 0x8; //8
            }
            else if (partitionSize < 0x400000000UL /*(16GiB)*/)
            {
                sectorsPerCluster = 0x10; //16
            }
            else if (partitionSize < 0x800000000UL /*(32GiB)*/)
            {
                sectorsPerCluster = 0x20; //32
            }
            else if (partitionSize < 0x20000000000UL /*(2TiB)*/)
            {
                sectorsPerCluster = 0x40; //64
            }
            //Max. 2TB - if greater, then error!
            else
            {
                ExceptionMethods.Throw(new Exceptions.NotSupportedException("Drive too big! Max. size 2TB for FAT32."));
            }
            //Sectors per cluster - 32 KiB clusters = 64 sectors per cluster
            newBPBData[13] = sectorsPerCluster;
            //Reserved sector count - 32 for FAT32 (by convention... and FAT32 does not imply 32 sectors)
            UInt16 reservedSectors = 32;
            newBPBData[14] = (byte)(reservedSectors);
            newBPBData[15] = (byte)(reservedSectors >> 8);
            //Number of FATs - always 2
            newBPBData[16] = 0x02;
            //Root entry count - always 0 for FAT32
            // - Do nothing
            
            //Total sector count
            // - At newBPBData[19] - N/A for FAT32
            //      - Do nothing
            // - At newBPBData[32] - Total number of sectors in the file system
            uint totalSectors = (uint)thePartition.BlockCount;
            newBPBData[32] = (byte)(totalSectors);
            newBPBData[33] = (byte)(totalSectors >> 8);
            newBPBData[34] = (byte)(totalSectors >> 16);
            newBPBData[35] = (byte)(totalSectors >> 24);


            //FAT sector count
            // - At newBPBData[22] - always 0 for FAT32
            // - At newBPBData[36] - See calculation below

            //FAT sector count = 2 * RoundUp(Number of bytes for 1 FAT / Bytes per sector)
            
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"totalSectors: ") + totalSectors +
                                                       ", reservedSectors: " + reservedSectors +
                                                       ", sectorsPerCluster: " + sectorsPerCluster +
                                                       ", bytesPerSector: " + bytesPerSector);
#endif

            // Number of bytes for 2 FAT  = 4 * Number of data clusters
            //                            = 4 * (RndDown((totalSectors - ReservedSectors) / sectorsPerCluster) - RndUp(Clusters for 2 FATs))
            //               bytesPer2FAT = 4 * (X - RndUp((bytesPerFAT * 2) / bytesPerCluster))
            //               bytesPer2FAT = (4 * X * bytesPerCluster) / (bytesPerCluster + 8)
            uint dataClusters = (totalSectors - reservedSectors) / sectorsPerCluster;
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"dataClusters: ") + dataClusters);
#endif
            uint bytesPerCluster = (uint)sectorsPerCluster * bytesPerSector;
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"bytesPerCluster: ") + bytesPerCluster);
            BasicConsole.WriteLine(((FOS_System.String)"4 * dataClusters: ") + (4 * dataClusters));
            BasicConsole.WriteLine(((FOS_System.String)"4 * dataClusters * bytesPerCluster: ") + (4 * dataClusters * bytesPerCluster));
            BasicConsole.WriteLine(((FOS_System.String)"bytesPerCluster + 8: ") + (bytesPerCluster + 8));
#endif
            
            uint bytesPer2FAT = (uint)Math.Divide((4 * (ulong)dataClusters * bytesPerCluster), (bytesPerCluster + 8)); //Calculation rounds down
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"bytesPer2FAT: ") + bytesPer2FAT);
#endif
            uint FATSectorCount = bytesPer2FAT / bytesPerSector;
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"FATSectorCount: ") + FATSectorCount);
#endif
            newBPBData[36] = (byte)(FATSectorCount);
            newBPBData[37] = (byte)(FATSectorCount >> 8);
            newBPBData[38] = (byte)(FATSectorCount >> 16);
            newBPBData[39] = (byte)(FATSectorCount >> 24);
            
#if FATFS_TRACE
            BasicConsole.WriteLine(((FOS_System.String)"totalSectors: ") + totalSectors +
                                                       ", reservedSectors: " + reservedSectors +
                                                       ", sectorsPerCluster: " + sectorsPerCluster +
                                                       ", bytesPerSector: " + bytesPerSector +
                                                       ", bytesPerCluster: " + bytesPerCluster +
                                                       ", dataClusters: " + dataClusters +
                                                       ", bytesPer2FAT: " + bytesPer2FAT +
                                                       ", FATSectorCount: " + FATSectorCount);
            BasicConsole.DelayOutput(10);
#endif

            //Root cluster (number/index - min value is 2)
            newBPBData[44] = 0x02;
            
#if FATFS_TRACE
            BasicConsole.WriteLine("Writing new BPB...");
            BasicConsole.DelayOutput(1);
#endif

            thePartition.WriteBlock(0UL, 1U, newBPBData);
            
#if FATFS_TRACE
            BasicConsole.WriteLine("Written new BPB. Attempting to load new file system...");
#endif

            thePartition.CleanCaches();

            FATFileSystem fs = new FATFileSystem(thePartition);
            if (!fs.IsValid)
            {
#if FATFS_TRACE
                BasicConsole.WriteLine("Failed to format properly. Scrubbing new BPB...");
#endif
                thePartition.WriteBlock(0UL, 1U, null);
#if FATFS_TRACE
                BasicConsole.WriteLine("Scrub done.");
#endif

                ExceptionMethods.Throw(new FOS_System.Exception("Failed to format properly! FATFileSystem did not recognise system as valid."));
            }
            else if (fs.FATType != FATTypeEnum.FAT32)
            {
#if FATFS_TRACE
                BasicConsole.WriteLine("Failed to format properly. Scrubbing new BPB...");
#endif
                byte[] scrubBPB = thePartition.TheDiskDevice.NewBlockArray(1);
                thePartition.WriteBlock(0UL, 1U, scrubBPB);
#if FATFS_TRACE
                BasicConsole.WriteLine("Scrub done.");
#endif

                ExceptionMethods.Throw(new FOS_System.Exception(((FOS_System.String)"Failed to format properly! FATFileSystem recognised incorrect FAT type. Type recognised: ") + (uint)fs.FATType));
            }
            
#if FATFS_TRACE
            BasicConsole.WriteLine("FAT recognised. Setting up empty FAT table...");
            try
            {
#endif
                //Mark all clusters as empty
                fs.ThePartition.WriteBlock(fs.ReservedSectorCount, FATSectorCount, null);
#if FATFS_TRACE
            }
            catch
            {
                BasicConsole.WriteLine("Failed to clear potentially pre-existing FAT table! File system may not function as expected.");
                FOS_System.GC.Cleanup();
                FOS_System.GC.Cleanup();
            }

            BasicConsole.WriteLine("Marking root directory cluster as used...");
#endif
            //Mark root cluster as being 1 cluster in size.
            fs.SetFATEntryAndSave(2, GetFATEntryEOFValue(FATTypeEnum.FAT32));
            
#if FATFS_TRACE
            BasicConsole.WriteLine("Done. Clearing the root directory...");
#endif
            //Empty the root directory (in case of junk data)
            fs.WriteCluster(2, null);
            
#if FATFS_TRACE
            BasicConsole.WriteLine("Format complete.");
#endif
            fs.thePartition.CleanCaches();
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Initializes a new FAT directory.
 /// </summary>
 /// <param name="aFileSystem">The FAT file system to which the directory belongs.</param>
 /// <param name="parent">The FAT directory which is the parent of the directory. Null for the root directory.</param>
 /// <param name="aName">The name of the directory.</param>
 /// <param name="aFirstCluster">The first cluster number of the directory.</param>
 public FATDirectory(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aFirstCluster)
     : base(aFileSystem, parent, aName)
 {
     _theFile = new FATFile(aFileSystem, parent, Name, 0, aFirstCluster) { IsDirectoryFile = true };
 }