public static void CreateDiskImage(System.IO.Stream s, FATFormatInfo fi) { if (s.GetType() == typeof(System.IO.FileStream)) { CreateDiskImage((System.IO.FileStream)s, fi); return; } s.SetLength(0); FileCompression.WriteZeros(s, 0, (long)fi.TotalSectors * 512); FormatDiskImage(s, fi, false); }
static void CreateDiskImage(System.IO.FileStream fs, FATFormatInfo fi) { if (fs.Length != 0) { fs.SetLength(0); } FileCompression.CompressStream(fs); FileCompression.SetSparse(fs); FileCompression.WriteZeros(fs, 0, fi.TotalSectors * 512); FormatDiskImage(fs, fi, false); }
public static void CreateDiskImage(string filename, FATType type, int size_mbytes, string volumeLabel, int spt, int heads) { FATFormatInfo fi = new FATFormatInfo(type, size_mbytes, volumeLabel, spt, heads); CreateDiskImage(filename, fi); }
public static void CreateDiskImage(string filename, FATFormatInfo fi) { System.IO.FileStream fs = System.IO.File.Create(filename); CreateDiskImage(fs, fi); fs.Close(); }
static void FormatDiskImage(System.IO.Stream s, bool must_init) { FATFormatInfo fi = new FATFormatInfo(FATType.None, (int)(s.Length / 0x100000), null, 63, 16); FormatDiskImage(s, fi, must_init); }
static void FormatDiskImage(System.IO.Stream s, FATFormatInfo fi, bool MustInitialize) { var assembly = typeof(FATFormatter).GetTypeInfo().Assembly; byte[] bootsect; using (var stream = assembly.GetManifestResourceStream(fi.Type == FATType.FAT32 ? "OSDevelopment.Resources.bootsect32" : "OSDevelopment.Resources.bootsect16")) { bootsect = new byte[stream.Length]; stream.Read(bootsect, 0, (int)stream.Length); } if (!s.CanWrite || !s.CanSeek) { throw new System.IO.IOException(); } if (fi.Type == FATType.None) { fi.Type = DefaultFatType(fi.TotalSectors); } if (fi.Type != FATType.FAT16 && fi.Type != FATType.FAT32) { throw new NotSupportedException(); } if (!ValidFatType(fi.Type, fi.TotalSectors)) { throw new FATException("Invalid type of FAT, given sector count."); } if (fi.BootSector == null) { fi.BootSector = bootsect; } s.Seek(0, System.IO.SeekOrigin.Begin); System.IO.BinaryWriter bw = new System.IO.BinaryWriter(s); // Get sectors per cluster uint spc = 0; { uint[][] t = fi.Type == FATType.FAT16 ? FAT16Table : FAT32Table; foreach (uint[] i in t) { if (i[0] >= fi.TotalSectors) { spc = i[1]; break; } } } #if DEBUG System.Diagnostics.Debug.Assert(spc != 0); // Should have been prevented by ValidFatType(). #endif // Get FAT sectors uint fatsz; { uint rootsec = fi.Type == FATType.FAT32 ? 0u : 32u; uint resvd = fi.Type == FATType.FAT32 ? 32u : 1u; uint t1 = fi.TotalSectors - (resvd + rootsec); uint t2 = (256 * spc) + 2; if (fi.Type == FATType.FAT32) { t2 /= 2; } fatsz = (t1 + (t2 - 1)) / t2; } if (MustInitialize) { // FAT32: 2 fats + 32 reserved + root cluster; FAT16: 2 fats + 1 reserved + 32 root directory FileCompression.WriteZeros(s, 0, (long)(fatsz * 2 + (fi.Type == FATType.FAT32 ? 32 + spc : 33)) * 512); s.Seek(0, System.IO.SeekOrigin.Begin); } switch (fi.Type) { case FATType.FAT16: { s.Write(fi.BootSector, 0, 512); s.Seek(11, System.IO.SeekOrigin.Begin); bw.Write((ushort)512); // Bytes per sector bw.Write((byte)spc); // sectors per cluster bw.Write((ushort)1); // Reserved sector count bw.Write((byte)2); // Number of FATs bw.Write((ushort)512); // Number of root entries if (fi.TotalSectors < 65536) { bw.Write((ushort)fi.TotalSectors); // Total sectors 16 } else { bw.Write((ushort)0); } bw.Write(fi.MediaType); // Media type bw.Write((ushort)fatsz); // FAT sectors bw.Write(fi.SectorsPerTrack); // Sectors per track bw.Write(fi.Heads); // Number of heads bw.Write((uint)0); // Hidden sectors if (fi.TotalSectors >= 65536) { bw.Write(fi.TotalSectors); // Total sectors 32 } else { bw.Write((uint)0); } bw.Write(fi.DriveNumber); // drv num bw.Write((byte)0); // resvd bw.Write((byte)0x29); // ext boot sig bw.Write((uint)System.DateTime.Now.ToFileTime()); if (!string.IsNullOrEmpty(fi.VolumeLabel)) { string lab = fi.VolumeLabel.ToUpper(); if (lab.Length > 11) { lab = lab.Remove(11); } while (lab.Length < 11) { lab += "\x20"; } bw.Write(lab.ToCharArray()); } else { bw.Write("NO NAME ".ToCharArray()); } bw.Write("FAT16 ".ToCharArray()); for (uint pos = 1; pos <= fatsz + 1; pos += fatsz) { s.Seek((long)pos * 512, System.IO.SeekOrigin.Begin); bw.Write((uint)(0xFFFFFF00 | fi.MediaType)); } break; } case FATType.FAT32: { for (long pos = 0; pos <= 3072; pos += 3072) { s.Seek(pos, System.IO.SeekOrigin.Begin); s.Write(fi.BootSector, 0, 512); s.Seek(pos + 11, System.IO.SeekOrigin.Begin); bw.Write((ushort)512); // Bytes per sector bw.Write((byte)spc); // sectors per cluster bw.Write((ushort)32); // Reserved sector count bw.Write((byte)2); // Number of FATs bw.Write((ushort)0); // Number of root entries bw.Write((ushort)0); // Total sectors 16 bw.Write(fi.MediaType); // Media type bw.Write((ushort)0); // FAT sectors 16 bw.Write(fi.SectorsPerTrack); // Sectors per track bw.Write(fi.Heads); // Number of heads bw.Write((uint)0); // Hidden sectors bw.Write(fi.TotalSectors); // Total sectors 32 bw.Write(fatsz); // FAT sectors 32 bw.Write((ushort)0); // Flags bw.Write((ushort)0); // Version bw.Write((uint)2); // Root cluster bw.Write((ushort)1); // FSInfo sector bw.Write((ushort)6); // Backup boot sector s.Seek(12, System.IO.SeekOrigin.Current); // Reserved bytes bw.Write((byte)fi.DriveNumber); // Drive number bw.Write((byte)0); // Reserved bw.Write((byte)0x29); // ext boot sig bw.Write((uint)System.DateTime.Now.ToFileTime()); if (!string.IsNullOrEmpty(fi.VolumeLabel)) { string lab = fi.VolumeLabel.ToUpper(); if (lab.Length > 11) { lab = lab.Remove(11); } while (lab.Length < 11) { lab += "\x20"; } bw.Write(lab.ToCharArray()); } else { bw.Write("NO NAME ".ToCharArray()); } bw.Write("FAT32 ".ToCharArray()); s.Seek(pos + 512, System.IO.SeekOrigin.Begin); byte[] fsinfo; using (var stream = assembly.GetManifestResourceStream("OSDevelopment.Resources.fsinfo")) { fsinfo = new byte[stream.Length]; stream.Read(fsinfo, 0, (int)stream.Length); } s.Write(fsinfo, 0, 512); s.Seek(510, System.IO.SeekOrigin.Current); bw.Write((ushort)0xAA55); // so that all three sectors have 0xAA55 } for (long pos = 32; pos <= fatsz + 32; pos += fatsz) { s.Seek(pos * 512, System.IO.SeekOrigin.Begin); bw.Write((uint)(0x0FFFFF00 | fi.MediaType)); // First entry with media type bw.Write((uint)(0x0FFFFFFF)); // Cluster 1 with eoc mark bw.Write((uint)(0x0FFFFFFF)); // Cluster 2 used for root dorectory, mark next as eoc } break; } } }