public static BootImageOptions Parse(string filename) { var options = new BootImageOptions(); var reader = File.OpenText(filename); while (true) { string line = reader.ReadLine(); if (line == null) break; if (string.IsNullOrEmpty(line)) continue; string[] parts = line.Split(new char[] { '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries); switch (parts[0].Trim()) { case "-mbr": options.MBROption = true; options.MBRCode = (parts.Length > 1) ? File.ReadAllBytes(parts[1]) : null; break; case "-boot": options.FatBootCode = (parts.Length > 1) ? File.ReadAllBytes(parts[1]) : null; break; case "-vhd": options.ImageFormat = ImageFormat.VHD; break; case "-img": options.ImageFormat = ImageFormat.IMG; break; case "-vdi": options.ImageFormat = ImageFormat.VDI; break; case "-syslinux": options.PatchSyslinuxOption = true; break; case "-guid": if (parts.Length > 1) options.MediaGuid = new Guid(parts[1]); break; case "-snapguid": if (parts.Length > 1) options.MediaLastSnapGuid = new Guid(parts[1]); break; case "-fat12": options.FileSystem = FileSystem.FAT12; break; case "-fat16": options.FileSystem = FileSystem.FAT16; break; case "-fat32": options.FileSystem = FileSystem.FAT32; break; case "-file": if (parts.Length > 2) options.IncludeFiles.Add(new IncludeFile(parts[1], parts[2])); else options.IncludeFiles.Add(new IncludeFile(parts[1])); break; case "-blocks": options.BlockCount = Convert.ToUInt32(parts[1]); break; case "-volume": options.VolumeLabel = parts[1]; break; default: break; } } reader.Close(); return options; }
private void CreateDiskImage(string compiledFile) { var bootImageOptions = new BootImageOptions(); if (Options.BootLoader == BootLoader.Syslinux_6_03) { bootImageOptions.MBRCode = GetResource(@"syslinux\6.03", "mbr.bin"); bootImageOptions.FatBootCode = GetResource(@"syslinux\6.03", "ldlinux.bin"); bootImageOptions.IncludeFiles.Add(new IncludeFile("ldlinux.sys", GetResource(@"syslinux\6.03", "ldlinux.sys"))); bootImageOptions.IncludeFiles.Add(new IncludeFile("mboot.c32", GetResource(@"syslinux\6.03", "mboot.c32"))); } else if (Options.BootLoader == BootLoader.Syslinux_3_72) { bootImageOptions.MBRCode = GetResource(@"syslinux\3.72", "mbr.bin"); bootImageOptions.FatBootCode = GetResource(@"syslinux\3.72", "ldlinux.bin"); bootImageOptions.IncludeFiles.Add(new IncludeFile("ldlinux.sys", GetResource(@"syslinux\3.72", "ldlinux.sys"))); bootImageOptions.IncludeFiles.Add(new IncludeFile("mboot.c32", GetResource(@"syslinux\3.72", "mboot.c32"))); } bootImageOptions.IncludeFiles.Add(new IncludeFile("syslinux.cfg", GetResource(@"syslinux", "syslinux.cfg"))); bootImageOptions.IncludeFiles.Add(new IncludeFile(compiledFile, "main.exe")); bootImageOptions.IncludeFiles.Add(new IncludeFile("TEST.TXT", Encoding.ASCII.GetBytes("This is a test file."))); bootImageOptions.VolumeLabel = "MOSABOOT"; var vmext = ".img"; switch (Options.ImageFormat) { case ImageFormat.VHD: vmext = ".vhd"; break; case ImageFormat.VDI: vmext = ".vdi"; break; default: break; } ImageFile = Path.Combine(Options.DestinationDirectory, Path.GetFileNameWithoutExtension(Options.SourceFile) + vmext); bootImageOptions.DiskImageFileName = ImageFile; bootImageOptions.PatchSyslinuxOption = true; bootImageOptions.FileSystem = Options.FileSystem; bootImageOptions.ImageFormat = Options.ImageFormat; bootImageOptions.BootLoader = Options.BootLoader; Generator.Create(bootImageOptions); }
/// <summary> /// Creates the specified options. /// </summary> /// <param name="options">The options.</param> public static void Create(BootImageOptions options) { if (File.Exists(options.DiskImageFileName)) { File.Delete(options.DiskImageFileName); } uint blockCount = options.BlockCount; if (blockCount == 0) { blockCount = 8400 + 1; foreach (var file in options.IncludeFiles) { blockCount += ((uint)file.Content.Length / SectorSize) + 1; } } var diskGeometry = new DiskGeometry(); diskGeometry.GuessGeometry(blockCount); // Create disk image file var diskDevice = new BlockFileStream(options.DiskImageFileName); if (options.ImageFormat == ImageFormat.VDI) { // Create header var header = VDI.CreateHeader( blockCount, options.MediaGuid.ToByteArray(), options.MediaLastSnapGuid.ToByteArray(), diskGeometry ); diskDevice.WriteBlock(0, 1, header); var map = VDI.CreateImageMap(blockCount); diskDevice.WriteBlock(1, (uint)(map.Length / SectorSize), map); diskDevice.BlockOffset = 1 + (uint)(map.Length / 512); } // Expand disk image diskDevice.WriteBlock(blockCount - 1, 1, new byte[SectorSize]); // Create partition device PartitionDevice partitionDevice; if (options.MBROption) { // Create master boot block record var mbr = new MasterBootBlock(diskDevice); // Setup partition entry mbr.DiskSignature = 0x12345678; mbr.Partitions[0].Bootable = true; mbr.Partitions[0].StartLBA = diskGeometry.SectorsPerTrack; mbr.Partitions[0].TotalBlocks = blockCount - mbr.Partitions[0].StartLBA; switch (options.FileSystem) { case FileSystem.FAT12: mbr.Partitions[0].PartitionType = PartitionType.FAT12; break; case FileSystem.FAT16: mbr.Partitions[0].PartitionType = PartitionType.FAT16; break; case FileSystem.FAT32: mbr.Partitions[0].PartitionType = PartitionType.FAT32; break; default: break; } mbr.Code = options.MBRCode; mbr.Write(); partitionDevice = new PartitionDevice(diskDevice, mbr.Partitions[0], false); } else { partitionDevice = new PartitionDevice(diskDevice, false); } // Set FAT settings var fatSettings = new FatSettings(); switch (options.FileSystem) { case FileSystem.FAT12: fatSettings.FATType = FatType.FAT12; break; case FileSystem.FAT16: fatSettings.FATType = FatType.FAT16; break; case FileSystem.FAT32: fatSettings.FATType = FatType.FAT32; break; default: break; } fatSettings.FloppyMedia = false; fatSettings.VolumeLabel = options.VolumeLabel; fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 }; fatSettings.SectorsPerTrack = diskGeometry.SectorsPerTrack; fatSettings.NumberOfHeads = diskGeometry.Heads; fatSettings.HiddenSectors = diskGeometry.SectorsPerTrack; fatSettings.OSBootCode = options.FatBootCode; // Create FAT file system var fat = new FatFileSystem(partitionDevice); if (!fat.Format(fatSettings)) { throw new Exception("ERROR: Invalid FAT settings"); } fat.SetVolumeName(options.VolumeLabel); foreach (var includeFile in options.IncludeFiles) { var fileAttributes = new FatFileAttributes(); if (includeFile.Archive) fileAttributes |= FatFileAttributes.Archive; if (includeFile.ReadOnly) fileAttributes |= FatFileAttributes.ReadOnly; if (includeFile.Hidden) fileAttributes |= FatFileAttributes.Hidden; if (includeFile.System) fileAttributes |= FatFileAttributes.System; string newname = (Path.GetFileNameWithoutExtension(includeFile.Filename).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Filename).PadRight(4).Substring(1, 3)).ToUpper(); var location = fat.CreateFile(newname, fileAttributes); if (!location.IsValid) throw new Exception("Unable to write file"); var fatFileStream = new FatFileStream(fat, location); fatFileStream.Write(includeFile.Content, 0, includeFile.Content.Length); fatFileStream.Flush(); } if (options.PatchSyslinuxOption) { if (options.BootLoader == BootLoader.Syslinux_6_03) { Syslinux.PatchSyslinux_6_03(partitionDevice, fat); } else if (options.BootLoader == BootLoader.Syslinux_3_72) { Syslinux.PatchSyslinux_3_72(partitionDevice, fat); } } if (options.ImageFormat == ImageFormat.VHD) { // Create footer var footer = VHD.CreateFooter( blockCount, (uint)(DateTime.Now - (new DateTime(2000, 1, 1, 0, 0, 0))).Seconds, options.MediaGuid.ToByteArray(), diskGeometry ); diskDevice.WriteBlock(blockCount, 1, footer); } diskDevice.Dispose(); }
/// <summary> /// Creates the specified options. /// </summary> /// <param name="options">The options.</param> static public void Create(BootImageOptions options) { if (File.Exists(options.DiskImageFileName)) { File.Delete(options.DiskImageFileName); } uint blockCount = options.BlockCount; if (blockCount == 0) { blockCount = 8400 + 1; foreach (var file in options.IncludeFiles) { blockCount += ((uint)file.Content.Length / SectorSize) + 1; } } var diskGeometry = new DiskGeometry(); diskGeometry.GuessGeometry(blockCount); // Create disk image file var diskDeviceDriver = new BlockFileStreamDriver(options.DiskImageFileName); var diskDevice = new Device() { DeviceDriver = diskDeviceDriver }; // Setup device -- required as part of framework in operating system diskDeviceDriver.Setup(diskDevice); diskDeviceDriver.Initialize(); diskDeviceDriver.Start(); if (options.ImageFormat == ImageFormat.VDI) { // Create header var header = VDI.CreateHeader( blockCount, options.MediaGuid.ToByteArray(), options.MediaLastSnapGuid.ToByteArray(), diskGeometry ); diskDeviceDriver.WriteBlock(0, 1, header); var map = VDI.CreateImageMap(blockCount); diskDeviceDriver.WriteBlock(1, (uint)(map.Length / SectorSize), map); diskDeviceDriver.BlockOffset = 1 + (uint)(map.Length / 512); } // Expand disk image diskDeviceDriver.WriteBlock(blockCount - 1, 1, new byte[SectorSize]); // Create partition device driver var partitionDevice = new PartitionDeviceDriver(); // Setup partition configuration var configuraiton = new DiskPartitionConfiguration() { Index = 0, ReadOnly = false, }; if (options.MBROption) { // Create master boot block record var mbr = new MasterBootBlock(diskDeviceDriver) { // Setup partition entry DiskSignature = 0x12345678 }; mbr.Partitions[0].Bootable = true; mbr.Partitions[0].StartLBA = diskGeometry.SectorsPerTrack; mbr.Partitions[0].TotalBlocks = blockCount - mbr.Partitions[0].StartLBA; switch (options.FileSystem) { case FileSystem.FAT12: mbr.Partitions[0].PartitionType = PartitionType.FAT12; break; case FileSystem.FAT16: mbr.Partitions[0].PartitionType = PartitionType.FAT16; break; case FileSystem.FAT32: mbr.Partitions[0].PartitionType = PartitionType.FAT32; break; default: break; } mbr.Code = options.MBRCode; mbr.Write(); configuraiton.StartLBA = mbr.Partitions[0].StartLBA; configuraiton.TotalBlocks = mbr.Partitions[0].TotalBlocks; } else { configuraiton.StartLBA = 0; configuraiton.TotalBlocks = diskDeviceDriver.TotalBlocks; } // Setup device -- required as part of framework in operating system var device = new Device() { Configuration = configuraiton, DeviceDriver = partitionDevice, Parent = diskDevice, }; // Setup and initialize partitionDevice.Setup(device); partitionDevice.Initialize(); partitionDevice.Start(); // Set FAT settings var fatSettings = new FatSettings(); switch (options.FileSystem) { case FileSystem.FAT12: fatSettings.FATType = FatType.FAT12; break; case FileSystem.FAT16: fatSettings.FATType = FatType.FAT16; break; case FileSystem.FAT32: fatSettings.FATType = FatType.FAT32; break; default: break; } fatSettings.FloppyMedia = false; fatSettings.VolumeLabel = options.VolumeLabel; fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 }; fatSettings.SectorsPerTrack = diskGeometry.SectorsPerTrack; fatSettings.NumberOfHeads = diskGeometry.Heads; fatSettings.HiddenSectors = diskGeometry.SectorsPerTrack; fatSettings.OSBootCode = options.FatBootCode; // Create FAT file system var fat = new FatFileSystem(partitionDevice); if (!fat.Format(fatSettings)) { throw new Exception("ERROR: Invalid FAT settings"); } fat.SetVolumeName(options.VolumeLabel); foreach (var includeFile in options.IncludeFiles) { var fileAttributes = new FatFileAttributes(); if (includeFile.Archive) { fileAttributes |= FatFileAttributes.Archive; } if (includeFile.ReadOnly) { fileAttributes |= FatFileAttributes.ReadOnly; } if (includeFile.Hidden) { fileAttributes |= FatFileAttributes.Hidden; } if (includeFile.System) { fileAttributes |= FatFileAttributes.System; } string newname = (Path.GetFileNameWithoutExtension(includeFile.Filename).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Filename).PadRight(4).Substring(1, 3)).ToUpper(); var location = fat.CreateFile(newname, fileAttributes); if (!location.IsValid) { throw new Exception("Unable to write file"); } var fatFileStream = new FatFileStream(fat, location); fatFileStream.Write(includeFile.Content, 0, includeFile.Content.Length); fatFileStream.Flush(); } if (options.PatchSyslinuxOption) { if (options.BootLoader == BootLoader.Syslinux_6_03) { Syslinux.PatchSyslinux_6_03(partitionDevice, fat); } else if (options.BootLoader == BootLoader.Syslinux_3_72) { Syslinux.PatchSyslinux_3_72(partitionDevice, fat); } } if (options.ImageFormat == ImageFormat.VHD) { // Create footer var footer = VHD.CreateFooter( blockCount, (uint)(DateTime.Now - (new DateTime(2000, 1, 1, 0, 0, 0))).Seconds, options.MediaGuid.ToByteArray(), diskGeometry ); diskDeviceDriver.WriteBlock(blockCount, 1, footer); } diskDeviceDriver.Dispose(); }