public void Create_A_Subdirectory_Entry_With_Files() { var xRootDirectory = mFS.GetRootDirectory(); mFS.CreateDirectory(xRootDirectory, "First"); var root = mFS.GetDirectoryListing(xRootDirectory); mFS.CreateDirectory(root[0], "Sub"); Assert.AreEqual(mFS.GetDirectoryListing(root[0]).Count, 1); var dir = root[0]; Assert.AreEqual("First", dir.mName); mFS.CreateFile(dir, "test.txt"); Assert.AreEqual(mFS.GetDirectoryListing(dir).Count, 2); mFS.CreateFile(dir, "test2.txt"); Assert.AreEqual(mFS.GetDirectoryListing(dir).Count, 3); Assert.AreEqual("test.txt", mFS.GetDirectoryListing(dir)[1].mName); Assert.AreEqual(@"0:\First\test.txt", mFS.GetDirectoryListing(dir)[1].mFullPath); }
/// <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(); }
private static void Main(string[] args) { // Create synthetic ram disk device var ramDiskDevice = new RamDiskDevice(1024 * 1024 * 10 / 512); var ramDevice = new Device() { DeviceDriver = ramDiskDevice }; // Setup device -- required as part of framework in operating system ramDiskDevice.Setup(ramDevice); ramDiskDevice.Initialize(); ramDiskDevice.Start(); // Create master boot block record var mbr = new MasterBootBlock(ramDiskDevice) { 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 driver var partitionDevice = new PartitionDeviceDriver(); // Setup partition configuration var configuraiton = new DiskPartitionConfiguration() { StartLBA = mbr.Partitions[0].StartLBA, TotalBlocks = mbr.Partitions[0].TotalBlocks, Index = 0, ReadOnly = false, }; // Setup device -- required as part of framework in operating system var device = new Device() { Configuration = configuraiton, DeviceDriver = partitionDevice, }; // Setup and initialize partitionDevice.Setup(device); partitionDevice.Initialize(); partitionDevice.Start(); // 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)).ToUpperInvariant(); 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; }
/// <summary> /// Creates the specified options. /// </summary> /// <param name="options">The options.</param> static public 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(); }
/// <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); }