public bool Format(FATSettings fatSettings) { if (!partition.CanWrite) { return(false); } this.fatType = fatSettings.FatType; bytesPerSector = 512; totalSectors = partition.BlockCount; sectorsPerCluster = GetSectorsPerClusterByTotalSectors(fatType, totalSectors); nbrFats = 2; if (fatType == FATType.FAT32) { reservedSectors = 32; rootEntries = 0; } else { reservedSectors = 1; rootEntries = 512; } rootDirSectors = (((rootEntries * 32) + (bytesPerSector - 1)) / bytesPerSector); fatStart = reservedSectors; uint val1 = totalSectors - (reservedSectors + rootDirSectors); uint val2 = (uint)((256 * sectorsPerCluster) + nbrFats); if (fatType == FATType.FAT32) { val2 = val2 / 2; } uint sectorsperfat = (val1 + (val2 - 1)) / val2; BinaryFormat bootSector = new BinaryFormat(512); bootSector.SetUInt(BootSector.JumpInstruction, 0); bootSector.SetString(BootSector.EOMName, "MSWIN4.1"); 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); if (totalSectors > 0xFFFF) { bootSector.SetUShort(BootSector.TotalSectors, 0); bootSector.SetUInt(BootSector.FAT32_TotalSectors, totalClusters); } else { bootSector.SetUShort(BootSector.TotalSectors, (ushort)totalSectors); bootSector.SetUInt(BootSector.FAT32_TotalSectors, 0); } bootSector.SetByte(BootSector.MediaDescriptor, 0xF8); if (fatType == FATType.FAT32) { bootSector.SetUShort(BootSector.SectorsPerFAT, 0); } else { bootSector.SetUShort(BootSector.SectorsPerFAT, (ushort)sectorsperfat); } bootSector.SetUShort(BootSector.SectorsPerTrack, 0); ////FIXME bootSector.SetUInt(BootSector.HiddenSectors, 0); if (fatType != FATType.FAT32) { bootSector.SetByte(BootSector.PhysicalDriveNbr, 0x80); bootSector.SetByte(BootSector.ReservedCurrentHead, 0); bootSector.SetByte(BootSector.ExtendedBootSignature, 0x29); bootSector.SetBytes(BootSector.IDSerialNumber, fatSettings.SerialID, 0, (uint)(fatSettings.SerialID.Length <= 4 ? fatSettings.SerialID.Length : 4)); bootSector.SetString(BootSector.VolumeLabel, " "); // 12 blank spaces bootSector.SetString(BootSector.VolumeLabel, fatSettings.VolumeLabel, (uint)(fatSettings.VolumeLabel.Length <= 12 ? fatSettings.VolumeLabel.Length : 12)); bootSector.SetUShort(BootSector.BootSectorSignature, 0x55AA); //BootSector.OSBootCode // TODO } if (fatType == FATType.FAT12) { bootSector.SetString(BootSector.FATType, "FAT12 "); } else if (fatType == FATType.FAT16) { bootSector.SetString(BootSector.FATType, "FAT16 "); } else // if (type == FatType.FAT32) { bootSector.SetString(BootSector.FATType, "FAT32 "); } if (fatType == FATType.FAT32) { 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); //FAT32_Reserved1 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)(fatSettings.SerialID.Length <= 4 ? fatSettings.SerialID.Length : 4)); bootSector.SetString(BootSector.FAT32_VolumeLabel, " "); // 12 blank spaces bootSector.SetString(BootSector.FAT32_VolumeLabel, fatSettings.VolumeLabel, (uint)(fatSettings.VolumeLabel.Length <= 12 ? fatSettings.VolumeLabel.Length : 12)); bootSector.SetString(BootSector.FAT32_FATType, "FAT32 "); //BootSector.OSBootCode // TODO } // Write Boot Sector partition.WriteBlock(0, 1, bootSector.Data); // Write backup Boot Sector if (fatType == FATType.FAT32) { partition.WriteBlock(0, 1, bootSector.Data); // FIXME: wrong block # } // create FSInfo Structure if (fatType == FATType.FAT32) { 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); partition.WriteBlock(1, 1, infoSector.Data); partition.WriteBlock(7, 1, infoSector.Data); // create 2nd sector BinaryFormat secondSector = new BinaryFormat(512); secondSector.SetUInt((ushort)FSInfo.FSI_TrailSignature2, 0xAA55); partition.WriteBlock(2, 1, secondSector.Data); partition.WriteBlock(8, 1, secondSector.Data); } // create fats /// TODO: incomplete BinaryFormat emptyFat = new BinaryFormat(512); // clear primary & secondary fats entries for (uint i = fatStart; i < fatStart + 1; i++) //FIXME { partition.WriteBlock(i, 1, emptyFat.Data); } // first block is special BinaryFormat firstFat = new BinaryFormat(512); // TODO: incomplete partition.WriteBlock(reservedSectors, 1, emptyFat.Data); return(ReadBootSector()); }