Beispiel #1
0
        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;
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        /// <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();
        }
Beispiel #4
0
        /// <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();
        }