/// <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; }
/// <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); }
/// <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); }
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); }
/// <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); }
internal DirectoryEntry(FatFileSystemOptions options, Stream stream, FatType fatVariant) { _options = options; _fatVariant = fatVariant; byte[] buffer = Utilities.ReadFully(stream, 32); Load(buffer, 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))); }
internal override bool Compare(byte[] data, int offset, FatType type) { if ((FileNameAttribute)data[offset + (uint)Entry.DOSName] == FileNameAttribute.LastEntry) { return(true); } return(false); }
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); } }
/// <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; }
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; }
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); }
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); }
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); }
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); }
/// <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); }
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; }
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); }
/// <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; }
/// <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; }
/// <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; }
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; } } }
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); }
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; }
/// <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; }
public FatBuffer(FatType type, byte[] buffer) { _type = type; _buffer = buffer; _dirtySectors = new Dictionary <uint, uint>(); }
public FatBuffer(FatType type, DelayedByteArray buffer) { _type = type; _buffer = buffer; _dirtySectors = new Dictionary <uint, uint>(); }
/// <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(); }
/// <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; }
private DirectoryEntry(FatFileSystemOptions options, byte[] buffer, int offset, FatType fatVariant, string longFilename) { _options = options; _fatVariant = fatVariant; Load(buffer, offset, longFilename); }
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); }
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); }
internal abstract bool Compare(byte[] data, int offset, FatType type);
private void Initialize(Stream data) { _data = data; _data.Position = 0; _bootSector = Utilities.ReadSector(_data); _type = DetectFATType(_bootSector); ReadBPB(); LoadFAT(); LoadClusterReader(); LoadRootDirectory(); }
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); }
/// <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; }
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); }
/// <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; } }
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); }
public FatBuffer(FatType type, DelayedByteArray buffer) { _type = type; _buffer = buffer; _dirtySectors = new Dictionary<uint, uint>(); }
public FatBuffer(FatType type, byte[] buffer) { _type = type; _buffer = buffer; _dirtySectors = new Dictionary<uint, uint>(); }