Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FatSettings"/> class.
 /// </summary>
 public FatSettings()
 {
     this.FATType = FatType.FAT16;	// default
     this.SerialID = new byte[0];
     this.FloppyMedia = false;
     this.OSBootCode = null;
 }
Example #2
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(Entry.DOSName + offset);

            if (first == FileNameAttribute.LastEntry)
            {
                return(false);
            }

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
            {
                return(false);
            }

            if (first == FileNameAttribute.Escape)
            {
                return(false);
            }

            FatFileAttributes attribute = (FatFileAttributes)entry.GetByte(Entry.FileAttributes + offset);

            if ((attribute & FatFileAttributes.VolumeLabel) == FatFileAttributes.VolumeLabel)
            {
                return(true);
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
            {
                return(false);
            }

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
            {
                return(false);
            }

            if (first == FileNameAttribute.Escape)
            {
                return(false);
            }

            string entryname = FatFileSystem.ExtractFileName(data, offset);

            if (entryname == name)
            {
                return(true);
            }

            return(false);
        }
Example #4
0
 internal DirectoryEntry(FatFileSystemOptions options, FileName name, FatAttributes attrs, FatType fatVariant)
 {
     _options = options;
     _fatVariant = fatVariant;
     _name = name;
     _attr = (byte)attrs;
 }
 internal DirectoryEntry(FatFileSystemOptions options, Stream stream, FatType fatVariant)
 {
     _options    = options;
     _fatVariant = fatVariant;
     byte[] buffer = StreamUtilities.ReadExact(stream, 32);
     Load(buffer, 0);
 }
Example #6
0
 internal DirectoryEntry(FatFileSystemOptions options, FileName name, FatAttributes attrs, FatType fatVariant)
 {
     _options    = options;
     _fatVariant = fatVariant;
     _name       = name;
     _attr       = (byte)attrs;
 }
Example #7
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            var entry = new DataBlock(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
            {
                return(false);
            }

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
            {
                return(false);
            }

            if (first == FileNameAttribute.Escape)
            {
                return(false);
            }

            uint startcluster = FatFileSystem.GetClusterEntry(data, offset, type);

            if (startcluster == cluster)
            {
                return(true);
            }

            return(false);
        }
Example #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FatSettings"/> class.
 /// </summary>
 public FatSettings()
 {
     this.FATType     = FatType.FAT16;           // default
     this.SerialID    = new byte[0];
     this.FloppyMedia = false;
     this.OSBootCode  = null;
 }
Example #9
0
 internal DirectoryEntry(FatFileSystemOptions options, Stream stream, FatType fatVariant)
 {
     _options = options;
     _fatVariant = fatVariant;
     byte[] buffer = Utilities.ReadFully(stream, 32);
     Load(buffer, 0);
 }
Example #10
0
        public FileAllocationTable(FatType type, Stream stream, ushort firstFatSector, uint fatSize, byte numFats, byte activeFat)
        {
            _stream         = stream;
            _firstFatSector = firstFatSector;
            _numFats        = numFats;

            _stream.Position = (firstFatSector + (fatSize * activeFat)) * Utilities.SectorSize;
            _buffer          = new FatBuffer(type, Utilities.ReadFully(_stream, (int)(fatSize * Utilities.SectorSize)));
        }
Example #11
0
        public FileAllocationTable(FatType type, Stream stream, ushort firstFatSector, uint fatSize, byte numFats, byte activeFat)
        {
            _stream = stream;
            _firstFatSector = firstFatSector;
            _numFats = numFats;

            _stream.Position = (firstFatSector + (fatSize * activeFat)) * Utilities.SectorSize;
            _buffer = new FatBuffer(type, Utilities.ReadFully(_stream, (int)(fatSize * Utilities.SectorSize)));
        }
Example #12
0
        internal override bool Compare(byte[] data, int offset, FatType type)
        {
            if ((FileNameAttribute)data[offset + (uint)Entry.DOSName] == FileNameAttribute.LastEntry)
            {
                return(true);
            }

            return(false);
        }
Example #13
0
        internal override bool Compare(byte[] data, int offset, FatType type)
        {
            switch ((FileNameAttribute)data[offset + (uint)Entry.DOSName])
            {
            case FileNameAttribute.LastEntry:
            case FileNameAttribute.Deleted:
            case FileNameAttribute.Escape:
            case FileNameAttribute.Dot:
                return(false);

            default:
                return(true);
            }
        }
Example #14
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
                return true;

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
                return true;

            return false;
        }
Example #15
0
 internal DirectoryEntry(DirectoryEntry toCopy)
 {
     _options = toCopy._options;
     _fatVariant = toCopy._fatVariant;
     _name = toCopy._name;
     _attr = toCopy._attr;
     _creationTimeTenth = toCopy._creationTimeTenth;
     _creationTime = toCopy._creationTime;
     _creationDate = toCopy._creationDate;
     _lastAccessDate = toCopy._lastAccessDate;
     _firstClusterHi = toCopy._firstClusterHi;
     _lastWriteTime = toCopy._lastWriteTime;
     _firstClusterLo = toCopy._firstClusterLo;
     _fileSize = toCopy._fileSize;
 }
Example #16
0
 internal DirectoryEntry(DirectoryEntry toCopy)
 {
     _options           = toCopy._options;
     _fatVariant        = toCopy._fatVariant;
     _name              = toCopy._name;
     _attr              = toCopy._attr;
     _creationTimeTenth = toCopy._creationTimeTenth;
     _creationTime      = toCopy._creationTime;
     _creationDate      = toCopy._creationDate;
     _lastAccessDate    = toCopy._lastAccessDate;
     _firstClusterHi    = toCopy._firstClusterHi;
     _lastWriteTime     = toCopy._lastWriteTime;
     _firstClusterLo    = toCopy._firstClusterLo;
     _fileSize          = toCopy._fileSize;
 }
Example #17
0
        public override bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
            {
                return(true);
            }

            //if ((first == FileSystem.FAT.FatFileSystem.FileNameAttribute.Deleted) | (first == FileSystem.FAT.FatFileSystem.FileNameAttribute.Dot))
            //    return true;

            return(false);
        }
Example #18
0
        internal static uint GetClusterEntry(byte[] data, uint index, FatType type)
        {
            uint cluster = BitConverter.ToUInt16(data, (int)((uint)Entry.FirstCluster + (index * (uint)Entry.EntrySize)));

            if (type == FatType.FAT32)
            {
                cluster |= (uint)BitConverter.ToUInt16(data, (int)((uint)Entry.EAIndex + (index * (uint)Entry.EntrySize))) << 16;
            }

            if (cluster == 0)
            {
                cluster = 2;
            }

            return(cluster);
        }
Example #19
0
 internal DirectoryEntry(DirectoryEntry toCopy)
 {
     _options           = toCopy._options;
     _fatVariant        = toCopy._fatVariant;
     Name               = toCopy.Name;
     _attr              = toCopy._attr;
     _creationTimeTenth = toCopy._creationTimeTenth;
     _creationTime      = toCopy._creationTime;
     _creationDate      = toCopy._creationDate;
     _lastAccessDate    = toCopy._lastAccessDate;
     _firstClusterHi    = toCopy._firstClusterHi;
     _lastWriteTime     = toCopy._lastWriteTime;
     _firstClusterLo    = toCopy._firstClusterLo;
     _fileSize          = toCopy._fileSize;
     _longFileName      = new LongFileName();
     toCopy._longFileName.CopyTo(_longFileName);
 }
Example #20
0
        static public uint GetClusterEntry(byte[] data, uint index, FatType type)
        {
            BinaryFormat entry   = new BinaryFormat(data);
            uint         cluster = entry.GetUShort(Entry.FirstCluster + (index * Entry.EntrySize));

            if (type == FatType.FAT32)
            {
                cluster |= ((uint)entry.GetUShort(Entry.EAIndex + (index * Entry.EntrySize))) << 16;
            }

            if (cluster == 0)
            {
                cluster = 2;
            }

            return(cluster);
        }
Example #21
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
            {
                return(true);
            }

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
            {
                return(true);
            }

            return(false);
        }
Example #22
0
        internal override bool Compare(byte[] data, int offset, FatType type)
        {
            switch ((FileNameAttribute)data[offset + (uint)Entry.DOSName])
            {
                case FileNameAttribute.LastEntry:
                case FileNameAttribute.Deleted:
                case FileNameAttribute.Escape:
                case FileNameAttribute.Dot:
                    return false;
                default:
                    break;
            }

            uint startcluster = FatFileSystem.GetClusterEntry(data, (uint)offset, type);
            if (startcluster == Cluster)
                return true;

            return false;
        }
Example #23
0
        public override bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
            {
                return(false);
            }

            if ((first == FileNameAttribute.Deleted)) //| (first == FileSystem.FAT.FatFileSystem.FileNameAttribute.Dot)
            {
                return(false);
            }

            if (first == FileNameAttribute.Escape)
            {
                return(false);
            }

            string entryname = ASCII.GetString(data, (int)offset, 8).Trim();
            string entryExt  = ASCII.GetString(data, (int)(offset + 8), 3).Trim();

            string[] xStr = name.Split('.');
            if (xStr.Length > 1)
            {
                if (entryname.ToLower() == xStr[0].Trim('\0').ToLower() && entryExt.ToLower() == xStr[1].Trim('\0').ToLower())
                {
                    return(true);
                }
            }

            if (entryname.ToLower() == this.name.Trim().ToLower())
            {
                return(true);
            }

            return(false);
        }
Example #24
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            var entry = new BinaryFormat(data);

            byte first = entry.GetByte(offset + Entry.DOSName);

            if (first == FileNameAttribute.LastEntry)
                return false;

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
                return false;

            if (first == FileNameAttribute.Escape)
                return false;

            string entryname = FatFileSystem.ExtractFileName(data, offset);

            if (entryname == name)
                return true;

            return false;
        }
Example #25
0
        /// <summary>
        /// Compares the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public bool Compare(byte[] data, uint offset, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            byte first = entry.GetByte(Entry.DOSName + offset);

            if (first == FileNameAttribute.LastEntry)
                return false;

            if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
                return false;

            if (first == FileNameAttribute.Escape)
                return false;

            FatFileAttributes attribute = (FatFileAttributes)entry.GetByte(Entry.FileAttributes + offset);

            if ((attribute & FatFileAttributes.VolumeLabel) == FatFileAttributes.VolumeLabel)
                return true;

            return false;
        }
Example #26
0
		/// <summary>
		/// Compares the specified data.
		/// </summary>
		/// <param name="data">The data.</param>
		/// <param name="offset">The offset.</param>
		/// <param name="type">The type.</param>
		/// <returns></returns>
		public bool Compare(byte[] data, uint offset, FatType type)
		{
			BinaryFormat entry = new BinaryFormat(data);

			byte first = entry.GetByte(offset + Entry.DOSName);

			if (first == FileNameAttribute.LastEntry)
				return false;

			if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
				return false;

			if (first == FileNameAttribute.Escape)
				return false;

			uint startcluster = FatFileSystem.GetClusterEntry(data, offset, type);

			if (startcluster == cluster)
				return true;

			return false;
		}
Example #27
0
				return false;

			if ((first == FileNameAttribute.Deleted) | (first == FileNameAttribute.Dot))
				return false;

			if (first == FileNameAttribute.Escape)
				return false;

			uint startcluster = FatFileSystem.GetClusterEntry(data, offset, type);

			if (startcluster == cluster)
				return true;

			return false;
		}
	}
}
Example #28
0
        private static void WriteBS(byte[] bootSector, int offset, bool isFloppy, uint volId, string label, FatType fatType)
        {
            if (string.IsNullOrEmpty(label))
            {
                label = "NO NAME    ";
            }

            string fsType = "FAT32   ";
            if (fatType == FatType.Fat12)
            {
                fsType = "FAT12   ";
            }
            else if (fatType == FatType.Fat16)
            {
                fsType = "FAT16   ";
            }

            // Drive Number (for BIOS)
            bootSector[offset + 0] = (byte)(isFloppy ? 0x00 : 0x80);

            // Reserved
            bootSector[offset + 1] = 0;

            // Boot Signature (indicates next 3 fields present)
            bootSector[offset + 2] = 0x29;

            // Volume Id
            Utilities.WriteBytesLittleEndian(volId, bootSector, offset + 3);

            // Volume Label
            Utilities.StringToBytes(label + "           ", bootSector, offset + 7, 11);

            // File System Type
            Utilities.StringToBytes(fsType, bootSector, offset + 18, 8);
        }
Example #29
0
 private static uint CalcFatSize(uint sectors, FatType fatType, byte sectorsPerCluster)
 {
     uint numClusters = (uint)(sectors / sectorsPerCluster);
     uint fatBytes = (numClusters * (ushort)fatType) / 8;
     return (fatBytes + Utilities.SectorSize - 1) / Utilities.SectorSize;
 }
Example #30
0
        /// <summary>
        /// Writes a FAT12/FAT16 BPB.
        /// </summary>
        /// <param name="bootSector">The buffer to fill</param>
        /// <param name="sectors">The total capacity of the disk (in sectors)</param>
        /// <param name="fatType">The number of bits in each FAT entry</param>
        /// <param name="maxRootEntries">The maximum number of root directory entries</param>
        /// <param name="hiddenSectors">The number of hidden sectors before this file system (i.e. partition offset)</param>
        /// <param name="reservedSectors">The number of reserved sectors before the FAT</param>
        /// <param name="sectorsPerCluster">The number of sectors per cluster</param>
        /// <param name="diskGeometry">The geometry of the disk containing the Fat file system</param>
        /// <param name="isFloppy">Indicates if the disk is a removable media (a floppy disk)</param>
        /// <param name="volId">The disk's volume Id</param>
        /// <param name="label">The disk's label (or null)</param>
        private static void WriteBPB(
            byte[] bootSector,
            uint sectors,
            FatType fatType,
            ushort maxRootEntries,
            uint hiddenSectors,
            ushort reservedSectors,
            byte sectorsPerCluster,
            Geometry diskGeometry,
            bool isFloppy,
            uint volId,
            string label)
        {
            uint fatSectors = CalcFatSize(sectors, fatType, sectorsPerCluster);

            bootSector[0] = 0xEB;
            bootSector[1] = 0x3C;
            bootSector[2] = 0x90;

            // OEM Name
            Utilities.StringToBytes("DISCUTIL", bootSector, 3, 8);

            // Bytes Per Sector (512)
            bootSector[11] = 0;
            bootSector[12] = 2;

            // Sectors Per Cluster
            bootSector[13] = sectorsPerCluster;

            // Reserved Sector Count
            Utilities.WriteBytesLittleEndian(reservedSectors, bootSector, 14);

            // Number of FATs
            bootSector[16] = 2;

            // Number of Entries in the root directory
            Utilities.WriteBytesLittleEndian((ushort)maxRootEntries, bootSector, 17);

            // Total number of sectors (small)
            Utilities.WriteBytesLittleEndian((ushort)(sectors < 0x10000 ? sectors : 0), bootSector, 19);

            // Media
            bootSector[21] = (byte)(isFloppy ? 0xF0 : 0xF8);

            // FAT size (FAT12/FAT16)
            Utilities.WriteBytesLittleEndian((ushort)(fatType < FatType.Fat32 ? fatSectors : 0), bootSector, 22);

            // Sectors Per Track
            Utilities.WriteBytesLittleEndian((ushort)diskGeometry.SectorsPerTrack, bootSector, 24);

            // Heads Per Cylinder
            Utilities.WriteBytesLittleEndian((ushort)diskGeometry.HeadsPerCylinder, bootSector, 26);

            // Hidden Sectors
            Utilities.WriteBytesLittleEndian((uint)hiddenSectors, bootSector, 28);

            // Total number of sectors (large)
            Utilities.WriteBytesLittleEndian((uint)(sectors >= 0x10000 ? sectors : 0), bootSector, 32);

            if (fatType < FatType.Fat32)
            {
                WriteBS(bootSector, 36, isFloppy, volId, label, fatType);
            }
            else
            {
                // FAT size (FAT32)
                Utilities.WriteBytesLittleEndian((uint)fatSectors, bootSector, 36);

                // Ext flags: 0x80 = FAT 1 (i.e. Zero) active, mirroring
                bootSector[40] = 0x00;
                bootSector[41] = 0x00;

                // Filesystem version (0.0)
                bootSector[42] = 0;
                bootSector[43] = 0;

                // First cluster of the root directory, always 2 since we don't do bad sectors...
                Utilities.WriteBytesLittleEndian((uint)2, bootSector, 44);

                // Sector number of FSINFO
                Utilities.WriteBytesLittleEndian((uint)1, bootSector, 48);

                // Sector number of the Backup Boot Sector
                Utilities.WriteBytesLittleEndian((uint)6, bootSector, 50);

                // Reserved area - must be set to 0
                Array.Clear(bootSector, 52, 12);

                WriteBS(bootSector, 64, isFloppy, volId, label, fatType);
            }

            bootSector[510] = 0x55;
            bootSector[511] = 0xAA;
        }
Example #31
0
 public FatBuffer(FatType type, byte[] buffer)
 {
     _type         = type;
     _buffer       = buffer;
     _dirtySectors = new Dictionary <uint, uint>();
 }
Example #32
0
 public FatBuffer(FatType type, DelayedByteArray buffer)
 {
     _type         = type;
     _buffer       = buffer;
     _dirtySectors = new Dictionary <uint, uint>();
 }
Example #33
0
        /// <summary>
        /// Formats the partition with specified fat settings.
        /// </summary>
        /// <param name="fatSettings">The fat settings.</param>
        /// <returns></returns>
        public bool Format(FatSettings fatSettings)
        {
            if (!partition.CanWrite)
                return false;

            this.fatType = fatSettings.FATType;
            bytesPerSector = 512;
            nbrFats = 2;

            totalSectors = partition.BlockCount;
            sectorsPerCluster = GetSectorsPerClusterByTotalSectors(fatType, totalSectors);

            if (sectorsPerCluster == 0)
                return false;

            if (fatType == FatType.FAT32)
            {
                reservedSectors = 32;
                rootEntries = 0;
            }
            else
            {
                reservedSectors = 1;
                rootEntries = 512;
            }

            rootDirSectors = (((rootEntries * 32) + (bytesPerSector - 1)) / bytesPerSector);

            uint val1 = totalSectors - (reservedSectors + rootDirSectors);
            uint val2 = (uint)((sectorsPerCluster * 256) + nbrFats);

            if (fatType == FatType.FAT32)
                val2 = val2 / 2;

            uint sectorsPerFat = (val1 + (val2 - 1)) / val2;

            firstRootDirectorySector = reservedSectors + sectorsPerFat;

            BinaryFormat bootSector = new BinaryFormat(512);

            bootSector.SetUInt(BootSector.JumpInstruction, 0);
            bootSector.SetString(BootSector.EOMName, "MOSA    ");
            bootSector.SetUShort(BootSector.BytesPerSector, (ushort)bytesPerSector);
            bootSector.SetByte(BootSector.SectorsPerCluster, (byte)sectorsPerCluster);
            bootSector.SetUShort(BootSector.ReservedSectors, (ushort)reservedSectors);
            bootSector.SetByte(BootSector.FatAllocationTables, nbrFats);
            bootSector.SetUShort(BootSector.MaxRootDirEntries, (ushort)rootEntries);
            bootSector.SetUShort(BootSector.BootSectorSignature, 0xAA55);

            if (totalSectors > 0xFFFF)
            {
                bootSector.SetUShort(BootSector.TotalSectors16, 0);
                bootSector.SetUInt(BootSector.TotalSectors32, totalSectors);
            }
            else
            {
                bootSector.SetUShort(BootSector.TotalSectors16, (ushort)totalSectors);
                bootSector.SetUInt(BootSector.TotalSectors32, 0);
            }

            if (fatSettings.FloppyMedia)
            {
                // Default is 1.44
                bootSector.SetByte(BootSector.MediaDescriptor, 0xF0); // 0xF0 = 3.5" Double Sided, 80 tracks per side, 18 sectors per track (1.44MB).
            }
            else
                bootSector.SetByte(BootSector.MediaDescriptor, 0xF8); // 0xF8 = Hard disk

            bootSector.SetUShort(BootSector.SectorsPerTrack, fatSettings.SectorsPerTrack);
            bootSector.SetUShort(BootSector.NumberOfHeads, fatSettings.NumberOfHeads);
            bootSector.SetUInt(BootSector.HiddenSectors, fatSettings.HiddenSectors);

            if (fatType != FatType.FAT32)
            {
                bootSector.SetUShort(BootSector.SectorsPerFAT, (ushort)sectorsPerFat);
                if (fatSettings.FloppyMedia)
                    bootSector.SetByte(BootSector.PhysicalDriveNbr, 0x00);
                else
                    bootSector.SetByte(BootSector.PhysicalDriveNbr, 0x80);

                bootSector.SetByte(BootSector.ReservedCurrentHead, 0);
                bootSector.SetByte(BootSector.ExtendedBootSignature, 0x29);
                bootSector.SetBytes(BootSector.IDSerialNumber, fatSettings.SerialID, 0, (uint)Math.Min(4, fatSettings.SerialID.Length));

                if (string.IsNullOrEmpty(fatSettings.VolumeLabel))
                    bootSector.SetString(BootSector.VolumeLabel, "NO NAME    ");
                else
                {
                    bootSector.SetString(BootSector.VolumeLabel, "           ");  // 11 blank spaces
                    bootSector.SetString(BootSector.VolumeLabel, fatSettings.VolumeLabel, (uint)Math.Min(11, fatSettings.VolumeLabel.Length));
                }

                if (fatSettings.OSBootCode != null)
                {
                    if (fatSettings.OSBootCode.Length == 512)
                    {
                        bootSector.SetBytes(BootSector.JumpInstruction, fatSettings.OSBootCode, BootSector.JumpInstruction, 3);
                        bootSector.SetBytes(BootSector.OSBootCode, fatSettings.OSBootCode, BootSector.OSBootCode, 448);
                    }
                    else
                    {
                        bootSector.SetByte(BootSector.JumpInstruction, 0xEB); // 0xEB = JMP Instruction
                        bootSector.SetByte(BootSector.JumpInstruction + 1, 0x3C);
                        bootSector.SetByte(BootSector.JumpInstruction + 2, 0x90);
                        bootSector.SetBytes(BootSector.OSBootCode, fatSettings.OSBootCode, 0, (uint)Math.Min(448, fatSettings.OSBootCode.Length));
                    }
                }

                if (fatType == FatType.FAT12)
                    bootSector.SetString(BootSector.FATType, "FAT12   ");
                else
                    bootSector.SetString(BootSector.FATType, "FAT16   ");
            }

            if (fatType == FatType.FAT32)
            {
                bootSector.SetUShort(BootSector.SectorsPerFAT, 0);
                bootSector.SetUInt(BootSector.FAT32_SectorPerFAT, sectorsPerFat);
                bootSector.SetByte(BootSector.FAT32_Flags, 0);
                bootSector.SetUShort(BootSector.FAT32_Version, 0);
                bootSector.SetUInt(BootSector.FAT32_ClusterNumberOfRoot, 2);
                bootSector.SetUShort(BootSector.FAT32_SectorFSInformation, 1);
                bootSector.SetUShort(BootSector.FAT32_SecondBootSector, 6);
                bootSector.SetByte(BootSector.FAT32_PhysicalDriveNbr, 0x80);
                bootSector.SetByte(BootSector.FAT32_Reserved2, 0);
                bootSector.SetByte(BootSector.FAT32_ExtendedBootSignature, 0x29);
                bootSector.SetBytes(BootSector.FAT32_IDSerialNumber, fatSettings.SerialID, 0, (uint)Math.Min(4, fatSettings.SerialID.Length));
                bootSector.SetString(BootSector.FAT32_VolumeLabel, "           ");  // 11 blank spaces
                bootSector.SetString(BootSector.FAT32_VolumeLabel, fatSettings.VolumeLabel, (uint)(fatSettings.VolumeLabel.Length <= 11 ? fatSettings.VolumeLabel.Length : 11));
                bootSector.SetString(BootSector.FAT32_FATType, "FAT32   ");

                if (fatSettings.OSBootCode.Length == 512)
                {
                    bootSector.SetBytes(BootSector.JumpInstruction, fatSettings.OSBootCode, BootSector.JumpInstruction, 3);
                    bootSector.SetBytes(BootSector.FAT32_OSBootCode, fatSettings.OSBootCode, BootSector.FAT32_OSBootCode, 420);
                }
                else
                {
                    bootSector.SetByte(BootSector.JumpInstruction, 0xEB);  // 0xEB = JMP Instruction
                    bootSector.SetByte(BootSector.JumpInstruction + 1, 0x58);
                    bootSector.SetByte(BootSector.JumpInstruction + 2, 0x90);
                    bootSector.SetBytes(BootSector.FAT32_OSBootCode, fatSettings.OSBootCode, 0, (uint)Math.Min(420, fatSettings.OSBootCode.Length));
                }
            }

            // Write Boot Sector
            partition.WriteBlock(0, 1, bootSector.Data);

            if (fatType == FatType.FAT32)
            {
                // Write backup Boot Sector
                if (fatType == FatType.FAT32)
                    partition.WriteBlock(6, 1, bootSector.Data);

                // Create FSInfo Structure
                BinaryFormat infoSector = new BinaryFormat(512);

                infoSector.SetUInt(FSInfo.FSI_LeadSignature, 0x41615252);

                //FSInfo.FSI_Reserved1
                infoSector.SetUInt(FSInfo.FSI_StructureSigature, 0x61417272);
                infoSector.SetUInt(FSInfo.FSI_FreeCount, 0xFFFFFFFF);
                infoSector.SetUInt(FSInfo.FSI_NextFree, 0xFFFFFFFF);

                //FSInfo.FSI_Reserved2
                bootSector.SetUInt(FSInfo.FSI_TrailSignature, 0xAA550000);

                // Write FSInfo Structure
                partition.WriteBlock(1, 1, infoSector.Data);
                partition.WriteBlock(7, 1, infoSector.Data);

                // Create 2nd sector
                BinaryFormat secondSector = new BinaryFormat(512);

                secondSector.SetUShort(FSInfo.FSI_TrailSignature2, 0xAA55);

                partition.WriteBlock(2, 1, secondSector.Data);
                partition.WriteBlock(8, 1, secondSector.Data);
            }

            // Create FAT table(s)

            // Clear primary & secondary FATs
            BinaryFormat emptyFat = new BinaryFormat(512);

            for (uint i = 1; i < sectorsPerFat; i++)
                partition.WriteBlock(reservedSectors + i, 1, emptyFat.Data);

            if (nbrFats == 2)
                for (uint i = 1; i < sectorsPerFat; i++)
                    partition.WriteBlock(reservedSectors + sectorsPerFat + i, 1, emptyFat.Data);

            // First FAT block is special
            BinaryFormat firstFat = new BinaryFormat(512);

            if (fatType == FatType.FAT12)
            {
                firstFat.SetByte(1, 0xFF);
                firstFat.SetByte(2, 0xFF); // 0xF8
            }
            else if (fatType == FatType.FAT16)
            {
                firstFat.SetUShort(0, 0xFFFF);
                firstFat.SetUShort(2, 0xFFFF); // 0xFFF8
            }
            else // if (type == FatType.FAT32)
            {
                firstFat.SetUInt(0, 0x0FFFFFFF);
                firstFat.SetUInt(4, 0x0FFFFFFF); // 0x0FFFFFF8
                firstFat.SetUInt(8, 0x0FFFFFFF); // Also reserve the 2nd cluster for root directory
            }

            if (fatSettings.FloppyMedia)
                firstFat.SetByte(0, 0xF0);
            else
                firstFat.SetByte(0, 0xF8);

            partition.WriteBlock(reservedSectors, 1, firstFat.Data);

            if (nbrFats == 2)
                partition.WriteBlock(reservedSectors + sectorsPerFat, 1, firstFat.Data);

            // Create Empty Root Directory
            if (fatType == FatType.FAT32)
            {
            }
            else
            {
                for (uint i = 0; i < rootDirSectors; i++)
                    partition.WriteBlock(firstRootDirectorySector + i, 1, emptyFat.Data);
            }

            return ReadBootSector();
        }
Example #34
0
        /// <summary>
        /// Gets the cluster entry.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="index">The index.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static uint GetClusterEntry(byte[] data, uint index, FatType type)
        {
            BinaryFormat entry = new BinaryFormat(data);

            uint cluster = entry.GetUShort(Entry.FirstCluster + (index * Entry.EntrySize));

            if (type == FatType.FAT32)
                cluster |= ((uint)entry.GetUShort(Entry.EAIndex + (index * Entry.EntrySize))) << 16;

            return cluster;
        }
Example #35
0
 private DirectoryEntry(FatFileSystemOptions options, byte[] buffer, int offset, FatType fatVariant, string longFilename)
 {
     _options    = options;
     _fatVariant = fatVariant;
     Load(buffer, offset, longFilename);
 }
Example #36
0
        internal static DirectoryEntry CreateFrom(FatFileSystemOptions options, ArraySegment <byte> entry, string longFilename, FatType fatVariant)
        {
            var directoryEntry = new DirectoryEntry(options, entry.Array, entry.Offset, fatVariant, longFilename);

            return(directoryEntry);
        }
Example #37
0
 public abstract bool Compare(byte[] data, uint offset, FatType type);
        public bool IsFAT()
        {
            byte[] BootSector = this.PartitionX.NewBlockArray(1);

            this.PartitionX.ReadBlock(0UL, 1U, BootSector);

            var xSig = BitConverter.ToUInt16(BootSector, 510);

            if (xSig != 0xAA55)
            {
                return(false);
            }
            //BPB (BIOS Parameter Block)
            BytePerSector     = BitConverter.ToUInt16(BootSector, 11);
            SectorsPerCluster = BootSector[13];
            ReservedSector    = BitConverter.ToUInt16(BootSector, 14);
            TotalFAT          = BootSector[16];
            DirectoryEntry    = BitConverter.ToUInt16(BootSector, 17);

            if (BitConverter.ToUInt16(BootSector, 19) == 0)
            {
                //Large amount of sector on media. This field is set if there are more than 65535 sectors in the volume.
                TotalSectors = BitConverter.ToUInt32(BootSector, 32);
            }
            else
            {
                TotalSectors = BitConverter.ToUInt16(BootSector, 19);
            }

            //FAT 12 and FAT 16 ONLY
            SectorsPerFAT = BitConverter.ToUInt16(BootSector, 22);

            if (SectorsPerFAT == 0)
            {
                //FAT 32 ONLY
                SectorsPerFAT = BitConverter.ToUInt32(BootSector, 36);
            }

            //Not Necessary, To Avoid Crashes during corrupted BPB Info
            if (TotalFAT == 0 || TotalFAT > 2 || BytePerSector == 0 || TotalSectors == 0)
            {
                return(false);
            }

            //Some Calculations
            try
            {
                DataSectorCount = TotalSectors - (ReservedSector + (TotalFAT * SectorsPerFAT) + ReservedSector);
                ClusterCount    = DataSectorCount / SectorsPerCluster;
            }
            catch
            {
                return(false);
            }

            if (ClusterCount < 4085)
            {
                FatType = FatType.FAT12;
            }
            else if (ClusterCount < 65525)
            {
                FatType = FatType.FAT16;
            }
            else
            {
                FatType = FatType.FAT32;
            }

            if (FatType == FAT.FatType.FAT32)
            {
                SerialNo = BitConverter.ToUInt32(BootSector, 39);
                byte[] Vlabel = new byte[11];
                for (int i = 71; i < 82; i++)
                {
                    Vlabel[i - 71] = BootSector[i];
                }
                VolumeLabel     = Encoding.ASCII.GetString(Vlabel);
                VolumeLabel     = VolumeLabel.TrimEnd('\0');
                RootCluster     = BitConverter.ToUInt32(BootSector, 44);
                RootSector      = 0;
                RootSectorCount = 0;
            }
            else
            {
                SerialNo = BitConverter.ToUInt32(BootSector, 67);
                byte[] Vlabel = new byte[11];
                for (int i = 43; i < 54; i++)
                {
                    Vlabel[i - 43] = BootSector[i];
                }
                VolumeLabel     = Encoding.ASCII.GetString(Vlabel);
                VolumeLabel     = VolumeLabel.TrimEnd('\0');
                RootSector      = ReservedSector + (TotalFAT * SectorsPerFAT);
                RootSectorCount = (UInt32)((DirectoryEntry * 32 + (BytePerSector - 1)) / BytePerSector);
            }
            DataSector = ReservedSector + (TotalFAT * SectorsPerFAT) + RootSectorCount;

            return(true);
        }
Example #39
0
File: misc.cs Project: vdt/AtomOS
 internal abstract bool Compare(byte[] data, int offset, FatType type);
Example #40
0
        private void Initialize(Stream data)
        {
            _data = data;
            _data.Position = 0;
            _bootSector = Utilities.ReadSector(_data);

            _type = DetectFATType(_bootSector);

            ReadBPB();

            LoadFAT();

            LoadClusterReader();

            LoadRootDirectory();
        }
Example #41
0
        public DirectoryEntry GetDirectoryEntry(FatFileSystemOptions options, Stream stream, FatType fileSystemFatVariant)
        {
            byte[] bytes = DirectoryEntryReader.Read(stream);

            ArraySegment <byte>[] directoryEntries = CreateEmptyEntries(bytes);

            string longFilename = string.Empty;

            if (1 < directoryEntries.Length)
            {
                longFilename = ReadLongFilename(directoryEntries);
            }

            int            lastIndex      = directoryEntries.Length - 1;
            DirectoryEntry directoryEntry = DirectoryEntry.CreateFrom(options, directoryEntries[lastIndex], longFilename, fileSystemFatVariant);

            return(directoryEntry);
        }
Example #42
0
        /// <summary>
        /// Reads the boot sector.
        /// </summary>
        /// <returns></returns>
        protected bool ReadBootSector()
        {
            valid = false;

            if (blockSize != 512)   // only going to work with 512 sector sizes (for now)
                return false;

            BinaryFormat bootSector = new BinaryFormat(partition.ReadBlock(0, 1));

            if (bootSector.GetUShort(BootSector.BootSectorSignature) != 0xAA55)
                return false;

            byte extendedBootSignature = bootSector.GetByte(BootSector.ExtendedBootSignature);
            byte extendedBootSignature32 = bootSector.GetByte(BootSector.FAT32_ExtendedBootSignature);

            if ((extendedBootSignature != 0x29) && (extendedBootSignature != 0x28) && (extendedBootSignature32 != 0x29))
                return false;

            volumeLabel = bootSector.GetString(BootSector.VolumeLabel, 8).ToString().TrimEnd();
            bytesPerSector = bootSector.GetUShort(BootSector.BytesPerSector);
            sectorsPerCluster = bootSector.GetByte(BootSector.SectorsPerCluster);
            reservedSectors = bootSector.GetByte(BootSector.ReservedSectors);
            nbrFats = bootSector.GetByte(BootSector.FatAllocationTables);
            rootEntries = bootSector.GetUShort(BootSector.MaxRootDirEntries);
            rootCluster32 = bootSector.GetUInt(BootSector.FAT32_ClusterNumberOfRoot);

            uint sectorsPerFat16 = bootSector.GetUShort(BootSector.SectorsPerFAT);
            uint sectorsPerFat32 = bootSector.GetUInt(BootSector.FAT32_SectorPerFAT);
            uint totalSectors16 = bootSector.GetUShort(BootSector.TotalSectors16);
            uint totalSectors32 = bootSector.GetUInt(BootSector.TotalSectors32);
            uint sectorsPerFat = (sectorsPerFat16 != 0) ? sectorsPerFat16 : sectorsPerFat32;
            uint fatSectors = 0;

            try
            {
                fatSectors = nbrFats * sectorsPerFat;
                clusterSizeInBytes = sectorsPerCluster * blockSize;
                rootDirSectors = (((rootEntries * 32) + (bytesPerSector - 1)) / bytesPerSector);
                firstDataSector = reservedSectors + (nbrFats * sectorsPerFat) + rootDirSectors;
                totalSectors = (totalSectors16 != 0) ? totalSectors16 : totalSectors32;
                dataSectors = totalSectors - (reservedSectors + (nbrFats * sectorsPerFat) + rootDirSectors);
                totalClusters = dataSectors / sectorsPerCluster;
                entriesPerSector = (bytesPerSector / 32);
                firstRootDirectorySector = reservedSectors + fatSectors;
                dataAreaStart = firstRootDirectorySector + rootDirSectors;
            }
            catch
            {
                return false;
            }

            // Some basic checks
            if ((nbrFats == 0) || (nbrFats > 2) || (totalSectors == 0) || (sectorsPerFat == 0))
                return false;

            if (totalClusters < 4085)
                fatType = FatType.FAT12;
            else if (totalClusters < 65525)
                fatType = FatType.FAT16;
            else
                fatType = FatType.FAT32;

            if (fatType == FatType.FAT12)
            {
                reservedClusterMark = 0xFF0;
                endOfClusterMark = 0x0FF8;
                badClusterMark = 0x0FF7;
                fatMask = 0xFFFFFFFF;
                fatEntries = sectorsPerFat * 3 * blockSize / 2;
            }
            else if (fatType == FatType.FAT16)
            {
                reservedClusterMark = 0xFFF0;
                endOfClusterMark = 0xFFF8;
                badClusterMark = 0xFFF7;
                fatMask = 0xFFFFFFFF;
                fatEntries = sectorsPerFat * blockSize / 2;
            }
            else
            { //  if (type == FatType.FAT32) {
                reservedClusterMark = 0xFFF0;
                endOfClusterMark = 0x0FFFFFF8;
                badClusterMark = 0x0FFFFFF7;
                fatMask = 0x0FFFFFFF;
                fatEntries = sectorsPerFat * blockSize / 4;
            }

            // More basic checks
            if ((fatType == FatType.FAT32) && (rootCluster32 == 0))
                return false;

            valid = true;

            serialNbr = bootSector.GetBytes(fatType != FatType.FAT32 ? BootSector.IDSerialNumber : BootSector.FAT32_IDSerialNumber, 4);

            return true;
        }
Example #43
0
        internal override bool Compare(byte[] data, int offset, FatType type)
        {
            switch ((FileNameAttribute)data[offset + (int)Entry.DOSName])
            {
            case FileNameAttribute.LastEntry:
            case FileNameAttribute.Deleted:
            case FileNameAttribute.Escape:
                return(false);

            default:
                break;
            }

            int index;

            for (index = 7; index >= 0 && data[offset + index] == ' '; index--)
            {
                ;
            }
            index++;

            int dot = Name.IndexOf('.');

            if (dot == -1)
            {
                dot = Name.Length;
            }

            if (dot != index)
            {
                return(false);
            }

            for (index = 0; index < dot; index++)
            {
                if ((data[offset + index] & 0xDF) != (Name[index] & 0xDF))
                {
                    return(false);
                }
            }

            for (index = 10; index >= 8 && data[offset + index] == ' '; index--)
            {
                ;
            }
            index -= 7;

            int index2 = Name.Length - dot - 1;

            if (index2 < 0)
            {
                index2 = 0;
            }

            if (index2 != index)
            {
                return(false);
            }

            dot++;
            for (index = 0; index < index2; index++)
            {
                if ((data[offset + index + 8] & 0xDF) != (Name[dot + index] & 0xDF))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #44
0
 /// <summary>
 /// Gets the sectors per cluster by total sectors.
 /// </summary>
 /// <param name="type">The type.</param>
 /// <param name="sectors">The sectors.</param>
 /// <returns></returns>
 public static byte GetSectorsPerClusterByTotalSectors(FatType type, uint sectors)
 {
     switch (type)
     {
         case FatType.FAT12:
             {
                 if (sectors < 512) return 1;
                 else if (sectors == 720) return 2;
                 else if (sectors == 1440) return 2;
                 else if (sectors <= 2880) return 1;
                 else if (sectors <= 5760) return 2;
                 else if (sectors <= 16384) return 4;
                 else if (sectors <= 32768) return 8;
                 else return 0;
             }
         case FatType.FAT16:
             {
                 if (sectors < 8400) return 0;
                 else if (sectors < 32680) return 2;
                 else if (sectors < 262144) return 4;
                 else if (sectors < 524288) return 8;
                 else if (sectors < 1048576) return 16;
                 else if (sectors < 2097152) return 32;
                 else if (sectors < 4194304) return 64;
                 else return 0;
             }
         case FatType.FAT32:
             {
                 if (sectors < 66600) return 0;
                 else if (sectors < 532480) return 1;
                 else if (sectors < 16777216) return 8;
                 else if (sectors < 33554432) return 16;
                 else if (sectors < 67108864) return 32;
                 else return 64;
             }
         default: return 0;
     }
 }
Example #45
0
        private unsafe bool IsFAT()
        {
            var BootSector = new byte[512];

            if (!IDevice.Read(0U, 1U, BootSector))
            {
                Heap.Free(BootSector);
                return(false);
            }

            var xSig = BitConverter.ToUInt16(BootSector, 510);

            if (xSig != 0xAA55)
            {
                Heap.Free(BootSector);
                return(false);
            }

            /* BPB (BIOS Parameter Block) */
            BytePerSector     = BitConverter.ToUInt16(BootSector, 11);
            SectorsPerCluster = BootSector[13];
            ReservedSector    = BitConverter.ToUInt16(BootSector, 14);
            TotalFAT          = BootSector[16];
            DirectoryEntry    = BitConverter.ToUInt16(BootSector, 17);

            if (BitConverter.ToUInt16(BootSector, 19) == 0)
            {
                /* Large amount of sector on media. This field is set if there are more than 65535 sectors in the volume. */
                TotalSectors = BitConverter.ToUInt32(BootSector, 32);
            }
            else
            {
                TotalSectors = BitConverter.ToUInt16(BootSector, 19);
            }

            /* FAT 12 and FAT 16 ONLY */
            SectorsPerFAT = BitConverter.ToUInt16(BootSector, 22);

            if (SectorsPerFAT == 0)
            {
                /* FAT 32 ONLY */
                SectorsPerFAT = BitConverter.ToUInt32(BootSector, 36);
            }

            /* Not Necessary, To Avoid Crashes during corrupted BPB Info */
            // Just to prevent ourself from hacking
            if (TotalFAT == 0 || TotalFAT > 2 || BytePerSector == 0 || TotalSectors == 0 || SectorsPerCluster == 0)
            {
                Heap.Free(BootSector);
                return(false);
            }

            /* Some basic calculations to check basic error :P */
            uint RootDirSectors = 0;

            DataSectorCount = TotalSectors - (ReservedSector + (TotalFAT * SectorsPerFAT) + RootDirSectors);
            ClusterCount    = DataSectorCount / SectorsPerCluster;

            /* Finally we got key xD */
            if (ClusterCount < 4085)
            {
                FatType = FatType.FAT12;
            }
            else if (ClusterCount < 65525)
            {
                FatType = FatType.FAT16;
            }
            else
            {
                FatType = FatType.FAT32;
            }

            /* Now we open door of gold coins xDD */
            if (FatType == FatType.FAT32)
            {
                SerialNo        = BitConverter.ToUInt32(BootSector, 39);
                VolumeLabel     = new string((sbyte *)BootSector.GetDataOffset(), 71, 11); // for checking
                RootCluster     = BitConverter.ToUInt32(BootSector, 44);
                RootSector      = 0;
                RootSectorCount = 0;
            }
            /* The key is of another door */
            else
            {
                SerialNo        = BitConverter.ToUInt32(BootSector, 67);
                VolumeLabel     = new string((sbyte *)BootSector.GetDataOffset(), 43, 11);
                RootSector      = ReservedSector + (TotalFAT * SectorsPerFAT);
                RootSectorCount = (UInt32)((DirectoryEntry * 32 + (BytePerSector - 1)) / BytePerSector);
                fatEntries      = SectorsPerFAT * 512 / 4;
            }
            /* Now it shows our forward path ;) */
            EntriesPerSector = (UInt32)(BytePerSector / 32);
            DataSector       = ReservedSector + (TotalFAT * SectorsPerFAT) + RootSectorCount;

            mFSType = FileSystemType.FAT;

            Heap.Free(BootSector);
            return(true);
        }
Example #46
0
 public FatBuffer(FatType type, DelayedByteArray buffer)
 {
     _type = type;
     _buffer = buffer;
     _dirtySectors = new Dictionary<uint, uint>();
 }
Example #47
0
 public FatBuffer(FatType type, byte[] buffer)
 {
     _type = type;
     _buffer = buffer;
     _dirtySectors = new Dictionary<uint, uint>();
 }