Write() public method

When overridden in a derived class, writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
/// The sum of and is greater than the buffer length. /// /// is null. /// /// or is negative. /// /// An I/O error occurs. /// /// The stream does not support writing. /// /// Methods were called after the stream was closed. ///
public Write ( byte buffer, int offset, int count ) : void
buffer byte An array of bytes. This method copies bytes from to the current stream.
offset int The zero-based byte offset in at which to begin copying bytes to the current stream.
count int The number of bytes to be written to the current stream.
return void
Esempio n. 1
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();
        }
Esempio n. 2
0
        /// <summary>
        /// Main
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns></returns>
        static int Main(string[] args)
        {
            Console.WriteLine();
            Console.WriteLine("MakeImageBoot v1.0 [www.mosa-project.org]");
            Console.WriteLine("Copyright 2010. New BSD License.");
            Console.WriteLine("Written by Philipp Garcia ([email protected])");
            Console.WriteLine();

            string mbrFilename = string.Empty;
            string fatcodeFilename = string.Empty;
            string volumeLabel = string.Empty;
            ImageFormat imageFormat = ImageFormat.VHD;
            bool mbrOption = true;
            bool patchSyslinuxOption = false;
            bool floppyMedia = false;
            uint blockCount = 1024 * 1024 / 512;
            FileSystem fileSystem = FileSystem.FAT12;
            List<IncludeFile> includeFiles = new List<IncludeFile>();

            bool valid = (args.Length < 2);

            if (valid)
                valid = System.IO.File.Exists(args[0]);

            if (valid)
            {
                Console.WriteLine("Usage: CreateBootImage <boot.config file> <image name>");
                Console.Error.WriteLine("ERROR: Missing arguments");
                return -1;
            }

            Console.WriteLine("Building image...");

            try
            {

                StreamReader reader = File.OpenText(args[0]);

                while (true)
                {
                    string line = reader.ReadLine();
                    if (line == null) break;

                    if (string.IsNullOrEmpty(line))
                        continue;

                    string[] parts = line.Split('\t');

                    switch (parts[0].Trim())
                    {
                        case "-mbr": mbrOption = true; mbrFilename = (parts.Length > 1) ? parts[1] : null; break;
                        case "-boot": fatcodeFilename = (parts.Length > 1) ? parts[1] : null; break;
                        case "-vhd": imageFormat = ImageFormat.VHD; break;
                        case "-img": imageFormat = ImageFormat.IMG; break;
                        case "-vdi": imageFormat = ImageFormat.VDI; break;
                        case "-syslinux": patchSyslinuxOption = true; break;
                        case "-fat12": fileSystem = FileSystem.FAT12; break;
                        case "-fat16": fileSystem = FileSystem.FAT16; break;
                        case "-fat32": fileSystem = FileSystem.FAT32; break;
                        case "-file": if (parts.Length > 2) includeFiles.Add(new IncludeFile(parts[1], parts[2]));
                            else includeFiles.Add(new IncludeFile(parts[1])); break;
                        case "-blocks": blockCount = Convert.ToUInt32(parts[1]); break;
                        case "-volume": volumeLabel = parts[1]; break;
                        case "-floppy": floppyMedia = true; break;
                        default: break;
                    }
                }

                reader.Close();

                if (System.IO.File.Exists(args[1]))
                    System.IO.File.Delete(args[1]);

                DiskGeometry diskGeometry = new Mosa.DeviceSystem.DiskGeometry();
                diskGeometry.GuessGeometry(blockCount);

                Console.WriteLine("Disk Geometry CHS = " + diskGeometry.Cylinders + "/" + diskGeometry.Heads + "/" + diskGeometry.SectorsPerTrack);

                // Create disk image file
                Mosa.EmulatedDevices.Synthetic.DiskDevice diskDevice = new Mosa.EmulatedDevices.Synthetic.DiskDevice(args[1]);

                if (imageFormat == ImageFormat.VDI)
                {
                    // Create header
                    byte[] header = Mosa.DeviceSystem.VDI.CreateHeader(
                        blockCount,
                        Guid.NewGuid().ToByteArray(),
                        Guid.NewGuid().ToByteArray(),
                        diskGeometry
                    );

                    diskDevice.WriteBlock(0, 1, header);

                    byte[] map = Mosa.DeviceSystem.VDI.CreateImageMap(blockCount);

                    diskDevice.WriteBlock(1, (uint)(map.Length / 512), map);

                    diskDevice.BlockOffset = 1 + (uint)(map.Length / 512);
                }

                // Expand disk image
                diskDevice.WriteBlock(blockCount - 1, 1, new byte[512]);

                // Create partition device
                PartitionDevice partitionDevice;

                if (mbrOption)
                {
                    // Create master boot block record
                    MasterBootBlock 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 (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;
                    }

                    if (!string.IsNullOrEmpty(mbrFilename))
                        mbr.Code = ReadFile(mbrFilename);

                    mbr.Write();

                    partitionDevice = new PartitionDevice(diskDevice, mbr.Partitions[0], false);
                }
                else
                {
                    partitionDevice = new PartitionDevice(diskDevice, false);
                }

                // Set FAT settings
                FatSettings fatSettings = new FatSettings();

                switch (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 = floppyMedia;
                fatSettings.VolumeLabel = volumeLabel;
                fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };
                fatSettings.SectorsPerTrack = diskGeometry.SectorsPerTrack;
                fatSettings.NumberOfHeads = diskGeometry.Heads;
                fatSettings.HiddenSectors = diskGeometry.SectorsPerTrack;
                if (!string.IsNullOrEmpty(fatcodeFilename))
                    fatSettings.OSBootCode = ReadFile(fatcodeFilename);

                // Create FAT file system
                FatFileSystem fat = new FatFileSystem(partitionDevice);
                fat.Format(fatSettings);

                fat.SetVolumeName(volumeLabel);

                foreach (IncludeFile includeFile in includeFiles)
                {
                    string filename = includeFile.Filename;

                    Mosa.FileSystem.FAT.FatFileAttributes fileAttributes = new Mosa.FileSystem.FAT.FatFileAttributes();
                    if (includeFile.Archive) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Archive;
                    if (includeFile.ReadOnly) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.ReadOnly;
                    if (includeFile.Hidden) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Hidden;
                    if (includeFile.System) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.System;

                    byte[] file = ReadFile(filename);
                    string newname = (Path.GetFileNameWithoutExtension(includeFile.Newname).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Newname).PadRight(3).Substring(1, 3)).ToUpper();
                    FatFileLocation location = fat.CreateFile(newname, fileAttributes, 0);

                    if (!location.Valid)
                        throw new Exception("Unable to write file");

                    FatFileStream fatFileStream = new FatFileStream(fat, location);
                    fatFileStream.Write(file, 0, file.Length);
                    fatFileStream.Flush();
                }

                if (patchSyslinuxOption)
                {
                    // Locate ldlinux.sys file for patching
                    string filename = "ldlinux.sys";
                    string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(3).Substring(0, 4)).ToUpper();

                    FatFileLocation location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

                    if (location.Valid)
                    {
                        // Read boot sector
                        Mosa.ClassLib.BinaryFormat bootSector = new Mosa.ClassLib.BinaryFormat(partitionDevice.ReadBlock(0, 1));

                        // Set the first sector location of the file
                        bootSector.SetUInt(0x1F8, fat.GetSectorByCluster(location.FirstCluster));

                        // Change jump address
                        bootSector.SetUInt(0x01, 0x58);

                        // Write back patched boot sector
                        partitionDevice.WriteBlock(0, 1, bootSector.Data);

                        // Get the file size & number of sectors used
                        uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);
                        uint sectorCount = (fileSize + 511) >> 9;

                        uint[] sectors = new uint[65];
                        uint nsec = 0;

                        // Create list of the first 65 sectors of the file
                        for (uint cluster = location.FirstCluster; ((cluster != 0) & (nsec <= 64)); cluster = fat.GetNextCluster(cluster))
                        {
                            uint sec = fat.GetSectorByCluster(cluster);
                            for (uint s = 0; s < fat.SectorsPerCluster; s++)
                                sectors[nsec++] = sec + s;
                        }

                        // Read the first cluster of the file
                        Mosa.ClassLib.BinaryFormat firstCluster = new Mosa.ClassLib.BinaryFormat(fat.ReadCluster(location.FirstCluster));

                        uint patchArea = 0;

                        // Search for 0x3EB202FE (magic)
                        for (patchArea = 0; (firstCluster.GetUInt(patchArea) != 0x3EB202FE) && (patchArea < fat.ClusterSizeInBytes); patchArea += 4) ;

                        patchArea = patchArea + 8;

                        if (patchArea < fat.ClusterSizeInBytes)
                        {
                            // Set up the totals
                            firstCluster.SetUShort(patchArea, (ushort)(fileSize >> 2));
                            firstCluster.SetUShort(patchArea + 2, (ushort)(sectorCount - 1));

                            // Clear sector entries
                            firstCluster.Fill(patchArea + 8, 0, 64 * 4);

                            // Set sector entries
                            for (nsec = 0; nsec < 64; nsec++)
                                firstCluster.SetUInt(patchArea + 8 + (nsec * 4), sectors[nsec + 1]);

                            // Clear out checksum
                            firstCluster.SetUInt(patchArea + 4, 0);

                            // Write back the updated cluster
                            fat.WriteCluster(location.FirstCluster, firstCluster.Data);

                            // Re-Calculate checksum by openning the file
                            FatFileStream file = new FatFileStream(fat, location);

                            uint csum = 0x3EB202FE;
                            for (uint index = 0; index < (file.Length >> 2); index++)
                            {
                                uint value = (uint)file.ReadByte() | ((uint)file.ReadByte() << 8) | ((uint)file.ReadByte() << 16) | ((uint)file.ReadByte() << 24);
                                csum -= value;
                            }

                            // Set the checksum
                            firstCluster.SetUInt(patchArea + 4, csum);

                            // Write patched cluster back to disk
                            fat.WriteCluster(location.FirstCluster, firstCluster.Data);
                        }

                    }
                }

                if (imageFormat == ImageFormat.VHD)
                {
                    // Create footer
                    byte[] footer = Mosa.DeviceSystem.VHD.CreateFooter(
                        blockCount,
                        (uint)(DateTime.Now - (new DateTime(2000, 1, 1, 0, 0, 0))).Seconds,
                        Guid.NewGuid().ToByteArray(),
                        diskGeometry
                    );

                    diskDevice.WriteBlock(blockCount, 1, footer);
                }

                Console.WriteLine("Completed!");
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error: " + e.ToString());
                return -1;
            }

            return 0;
        }
Esempio n. 3
0
        /// <summary>
        /// Creates the specified options.
        /// </summary>
        /// <param name="options">The options.</param>
        public static void Create(Options 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 / 512) + 1;
                }
            }

            var diskGeometry = new Mosa.DeviceSystem.DiskGeometry();
            diskGeometry.GuessGeometry(blockCount);

            // Create disk image file
            BlockFileStream diskDevice = new BlockFileStream(options.DiskImageFileName);

            if (options.ImageFormat == ImageFormatType.VDI)
            {
                // Create header
                byte[] header = Mosa.DeviceSystem.VDI.CreateHeader(
                    blockCount,
                    options.MediaGuid.ToByteArray(),
                    options.MediaLastSnapGuid.ToByteArray(),
                    diskGeometry
                );

                diskDevice.WriteBlock(0, 1, header);

                byte[] map = Mosa.DeviceSystem.VDI.CreateImageMap(blockCount);

                diskDevice.WriteBlock(1, (uint)(map.Length / 512), map);

                diskDevice.BlockOffset = 1 + (uint)(map.Length / 512);
            }

            // Expand disk image
            diskDevice.WriteBlock(blockCount - 1, 1, new byte[512]);

            // Create partition device
            PartitionDevice partitionDevice;

            if (options.MBROption)
            {
                // Create master boot block record
                MasterBootBlock 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 FileSystemType.FAT12: mbr.Partitions[0].PartitionType = PartitionType.FAT12; break;
                    case FileSystemType.FAT16: mbr.Partitions[0].PartitionType = PartitionType.FAT16; break;
                    case FileSystemType.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
            FatSettings fatSettings = new FatSettings();

            switch (options.FileSystem)
            {
                case FileSystemType.FAT12: fatSettings.FATType = FatType.FAT12; break;
                case FileSystemType.FAT16: fatSettings.FATType = FatType.FAT16; break;
                case FileSystemType.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
            FatFileSystem 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)
            {
                Mosa.FileSystem.FAT.FatFileAttributes fileAttributes = new Mosa.FileSystem.FAT.FatFileAttributes();
                if (includeFile.Archive) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Archive;
                if (includeFile.ReadOnly) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.ReadOnly;
                if (includeFile.Hidden) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Hidden;
                if (includeFile.System) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.System;

                //byte[] file = File.ReadAllBytes(includeFile.Filename);
                string newname = (Path.GetFileNameWithoutExtension(includeFile.Filename).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Filename).PadRight(4).Substring(1, 3)).ToUpper();
                FatFileLocation location = fat.CreateFile(newname, fileAttributes, 0);

                if (!location.Valid)
                    throw new Exception("Unable to write file");

                FatFileStream fatFileStream = new FatFileStream(fat, location);
                fatFileStream.Write(includeFile.Content, 0, includeFile.Content.Length);
                fatFileStream.Flush();
            }

            if (options.PatchSyslinuxOption)
            {
                // Locate ldlinux.sys file for patching
                string filename = "ldlinux.sys";
                string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

                FatFileLocation location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

                if (location.Valid)
                {
                    // Read boot sector
                    Mosa.ClassLib.BinaryFormat bootSector = new Mosa.ClassLib.BinaryFormat(partitionDevice.ReadBlock(0, 1));

                    // Set the first sector location of the file
                    bootSector.SetUInt(0x1F8, fat.GetSectorByCluster(location.FirstCluster));

                    // Change jump address
                    bootSector.SetUInt(0x01, 0x58);

                    // Write back patched boot sector
                    partitionDevice.WriteBlock(0, 1, bootSector.Data);

                    // Get the file size & number of sectors used
                    uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);
                    uint sectorCount = (fileSize + 511) >> 9;

                    uint[] sectors = new uint[65];
                    uint nsec = 0;

                    // Create list of the first 65 sectors of the file
                    for (uint cluster = location.FirstCluster; ((cluster != 0) & (nsec <= 64)); cluster = fat.GetNextCluster(cluster))
                    {
                        uint sec = fat.GetSectorByCluster(cluster);
                        for (uint s = 0; s < fat.SectorsPerCluster; s++)
                            sectors[nsec++] = sec + s;
                    }

                    // Read the first cluster of the file
                    Mosa.ClassLib.BinaryFormat firstCluster = new Mosa.ClassLib.BinaryFormat(fat.ReadCluster(location.FirstCluster));

                    uint patchArea = 0;

                    // Search for 0x3EB202FE (magic)
                    for (patchArea = 0; (firstCluster.GetUInt(patchArea) != 0x3EB202FE) && (patchArea < fat.ClusterSizeInBytes); patchArea += 4) ;

                    patchArea = patchArea + 8;

                    if (patchArea < fat.ClusterSizeInBytes)
                    {
                        // Set up the totals
                        firstCluster.SetUShort(patchArea, (ushort)(fileSize >> 2));
                        firstCluster.SetUShort(patchArea + 2, (ushort)(sectorCount - 1));

                        // Clear sector entries
                        firstCluster.Fill(patchArea + 8, 0, 64 * 4);

                        // Set sector entries
                        for (nsec = 0; nsec < 64; nsec++)
                            firstCluster.SetUInt(patchArea + 8 + (nsec * 4), sectors[nsec + 1]);

                        // Clear out checksum
                        firstCluster.SetUInt(patchArea + 4, 0);

                        // Write back the updated cluster
                        fat.WriteCluster(location.FirstCluster, firstCluster.Data);

                        // Re-Calculate checksum by opening the file
                        FatFileStream file = new FatFileStream(fat, location);

                        uint csum = 0x3EB202FE;
                        for (uint index = 0; index < (file.Length >> 2); index++)
                        {
                            uint value = (uint)file.ReadByte() | ((uint)file.ReadByte() << 8) | ((uint)file.ReadByte() << 16) | ((uint)file.ReadByte() << 24);
                            csum -= value;
                        }

                        // Set the checksum
                        firstCluster.SetUInt(patchArea + 4, csum);

                        // Write patched cluster back to disk
                        fat.WriteCluster(location.FirstCluster, firstCluster.Data);
                    }
                }
            }

            if (options.ImageFormat == ImageFormatType.VHD)
            {
                // Create footer
                byte[] footer = Mosa.DeviceSystem.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();
        }
Esempio n. 4
0
        private static void Main(string[] args)
        {
            // Create synthetic ram disk device
            var ramDiskDevice = new RamDiskDevice(1024 * 1024 * 10 / 512);

            // Create master boot block record
            var mbr = new MasterBootBlock(ramDiskDevice);
            mbr.DiskSignature = 0x12345678;
            mbr.Partitions[0].Bootable = true;
            mbr.Partitions[0].StartLBA = 17;
            mbr.Partitions[0].TotalBlocks = ramDiskDevice.TotalBlocks - 17;
            mbr.Partitions[0].PartitionType = PartitionType.FAT12;
            mbr.Write();

            // Create partition device
            var partitionDevice = new PartitionDevice(ramDiskDevice, mbr.Partitions[0], false);

            // Set FAT settings
            var fatSettings = new FatSettings();

            fatSettings.FATType = FatType.FAT12;
            fatSettings.FloppyMedia = false;
            fatSettings.VolumeLabel = "MOSADISK";
            fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };

            // Create FAT file system
            var fat = new FatFileSystem(partitionDevice);
            fat.Format(fatSettings);

            if (fat.IsValid)
            {
                switch (fat.FATType)
                {
                    case FatType.FAT12: Console.WriteLine("FAT12"); break;
                    case FatType.FAT16: Console.WriteLine("FAT16"); break;
                    case FatType.FAT32: Console.WriteLine("FAT32"); break;
                    default: Console.WriteLine("Unknown"); break;
                }
                Console.WriteLine("  Volume Name: " + fat.VolumeLabel);
            }
            else
            {
                Console.WriteLine("Unknown File System");
            }

            var files = new List<IncludeFile>();

            files.Add(new IncludeFile("CREDITS.TXT", GetResource("CREDITS.txt")));
            files.Add(new IncludeFile("LICENSE.TXT", GetResource("LICENSE.txt")));

            foreach (var includeFile in files)
            {
                Console.WriteLine("Writing File: " + includeFile.Filename);

                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();

                Console.WriteLine("  Source Length: " + includeFile.Content.Length.ToString());
                Console.WriteLine("  Stream Length: " + fatFileStream.Length.ToString());
            }

            foreach (var includeFile in files)
            {
                Console.WriteLine("Searching File: " + includeFile.Filename);

                var location = fat.FindEntry(includeFile.Filename);

                if (location.IsValid)
                {
                    Console.WriteLine("  Found: " + includeFile.Filename);

                    var fatFileStream = new FatFileStream(fat, location);
                    Console.WriteLine("  Length: " + fatFileStream.Length.ToString());

                    for (;;)
                    {
                        int i = fatFileStream.ReadByte();

                        if (i < 0)
                            break;

                        Console.Write((char)i);
                    }
                    Console.WriteLine();
                    fatFileStream.Position = 0;

                    var buffer = new byte[fatFileStream.Length];
                    fatFileStream.Read(buffer, 0, (int)fatFileStream.Length);

                    Console.WriteLine(System.Text.Encoding.UTF8.GetString(buffer));
                }
                else
                {
                    Console.WriteLine("  Not Found: " + includeFile.Filename);
                }
            }

            return;
        }