internal override List<BuilderExtent> FixExtents(out long totalLength) { List<BuilderExtent> fixedRegions = new List<BuilderExtent>(); DateTime buildTime = DateTime.UtcNow; Encoding suppEncoding = _buildParams.UseJoliet ? Encoding.BigEndianUnicode : Encoding.ASCII; Dictionary<BuildDirectoryMember, uint> primaryLocationTable = new Dictionary<BuildDirectoryMember, uint>(); Dictionary<BuildDirectoryMember, uint> supplementaryLocationTable = new Dictionary<BuildDirectoryMember, uint>(); long focus = DiskStart + (3 * IsoUtilities.SectorSize); // Primary, Supplementary, End (fixed at end...) if (_bootEntry != null) { focus += IsoUtilities.SectorSize; } // #################################################################### // # 0. Fix boot image location // #################################################################### long bootCatalogPos = 0; if (_bootEntry != null) { long bootImagePos = focus; Stream realBootImage = PatchBootImage(_bootImage, (uint)(DiskStart / IsoUtilities.SectorSize), (uint)(bootImagePos / IsoUtilities.SectorSize)); BuilderStreamExtent bootImageExtent = new BuilderStreamExtent(focus, realBootImage); fixedRegions.Add(bootImageExtent); focus += Utilities.RoundUp(bootImageExtent.Length, IsoUtilities.SectorSize); bootCatalogPos = focus; byte[] bootCatalog = new byte[IsoUtilities.SectorSize]; BootValidationEntry bve = new BootValidationEntry(); bve.WriteTo(bootCatalog, 0x00); _bootEntry.ImageStart = (uint)Utilities.Ceil(bootImagePos, IsoUtilities.SectorSize); _bootEntry.SectorCount = (ushort)Utilities.Ceil(_bootImage.Length, Sizes.Sector); _bootEntry.WriteTo(bootCatalog, 0x20); fixedRegions.Add(new BuilderBufferExtent(bootCatalogPos, bootCatalog)); focus += IsoUtilities.SectorSize; } // #################################################################### // # 1. Fix file locations // #################################################################### // Find end of the file data, fixing the files in place as we go foreach (BuildFileInfo fi in _files) { primaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); supplementaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); FileExtent extent = new FileExtent(fi, focus); // Only remember files of non-zero length (otherwise we'll stomp on a valid file) if (extent.Length != 0) { fixedRegions.Add(extent); } focus += Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // #################################################################### // # 2. Fix directory locations // #################################################################### // There are two directory tables // 1. Primary (std ISO9660) // 2. Supplementary (Joliet) // Find start of the second set of directory data, fixing ASCII directories in place. long startOfFirstDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { primaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus); fixedRegions.Add(extent); focus += Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // Find end of the second directory table, fixing supplementary directories in place. long startOfSecondDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { supplementaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus); fixedRegions.Add(extent); focus += Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // #################################################################### // # 3. Fix path tables // #################################################################### // There are four path tables: // 1. LE, ASCII // 2. BE, ASCII // 3. LE, Supp Encoding (Joliet) // 4. BE, Supp Encoding (Joliet) // Find end of the path table long startOfFirstPathTable = focus; PathTable pathTable = new PathTable(false, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Add(pathTable); focus += Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); long primaryPathTableLength = pathTable.Length; long startOfSecondPathTable = focus; pathTable = new PathTable(true, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Add(pathTable); focus += Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); long startOfThirdPathTable = focus; pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Add(pathTable); focus += Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); long supplementaryPathTableLength = pathTable.Length; long startOfFourthPathTable = focus; pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Add(pathTable); focus += Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); // Find the end of the disk totalLength = focus; // #################################################################### // # 4. Prepare volume descriptors now other structures are fixed // #################################################################### int regionIdx = 0; focus = DiskStart; PrimaryVolumeDescriptor pvDesc = new PrimaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)primaryPathTableLength, // PathTableSize (uint)(startOfFirstPathTable / IsoUtilities.SectorSize), // TypeLPathTableLocation (uint)(startOfSecondPathTable / IsoUtilities.SectorSize), // TypeMPathTableLocation (uint)(startOfFirstDirData / IsoUtilities.SectorSize), // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(Encoding.ASCII), // RootDirectory.DataLength buildTime); pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus); fixedRegions.Insert(regionIdx++, pvdr); focus += IsoUtilities.SectorSize; if (_bootEntry != null) { BootVolumeDescriptor bvDesc = new BootVolumeDescriptor( (uint)(bootCatalogPos / IsoUtilities.SectorSize)); BootVolumeDescriptorRegion bvdr = new BootVolumeDescriptorRegion(bvDesc, focus); fixedRegions.Insert(regionIdx++, bvdr); focus += IsoUtilities.SectorSize; } SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)supplementaryPathTableLength, // PathTableSize (uint)(startOfThirdPathTable / IsoUtilities.SectorSize), // TypeLPathTableLocation (uint)(startOfFourthPathTable / IsoUtilities.SectorSize), // TypeMPathTableLocation (uint)(startOfSecondDirData / IsoUtilities.SectorSize), // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(suppEncoding), // RootDirectory.DataLength buildTime, suppEncoding); svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus); fixedRegions.Insert(regionIdx++, svdr); focus += IsoUtilities.SectorSize; VolumeDescriptorSetTerminator evDesc = new VolumeDescriptorSetTerminator(); VolumeDescriptorSetTerminatorRegion evdr = new VolumeDescriptorSetTerminatorRegion(evDesc, focus); fixedRegions.Insert(regionIdx++, evdr); return fixedRegions; }
internal override List <BuilderExtent> FixExtents(out long totalLength) { List <BuilderExtent> fixedRegions = new List <BuilderExtent>(); DateTime buildTime = DateTime.UtcNow; Encoding suppEncoding = _buildParams.UseJoliet ? Encoding.BigEndianUnicode : Encoding.ASCII; Dictionary <BuildDirectoryMember, uint> primaryLocationTable = new Dictionary <BuildDirectoryMember, uint>(); Dictionary <BuildDirectoryMember, uint> supplementaryLocationTable = new Dictionary <BuildDirectoryMember, uint>(); // #################################################################### // # 1. Fix file locations // #################################################################### long focus = FirstDataExtent; long highestFileLocation = 0; // Find end of the file data, fixing the files in place as we go foreach (BuildFileInfo fi in _files) { primaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); supplementaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); FileExtent extent = new FileExtent(fi, focus); // Only remember files of non-zero length (otherwise we'll stomp on a valid file) if (extent.Length != 0) { fixedRegions.Add(extent); } highestFileLocation = focus; focus += Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // #################################################################### // # 2. Fix directory locations // #################################################################### // There are two directory tables // 1. Primary (std ISO9660) // 2. Supplementary (Joliet) long pushFilesBackAmt = 0; int regionIdx = 0; long pushAmt = 0; //I actually want the path and directory tables before the files, //so lets find out how big it is then move all of the files long unfocused = focus; focus = FirstDataExtent; // Find start of the second set of directory data, fixing ASCII directories in place. long startOfFirstDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { primaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus); fixedRegions.Insert(regionIdx++, extent); pushAmt = Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); pushFilesBackAmt += pushAmt; focus += pushAmt; } // Find end of the second directory table, fixing supplementary directories in place. long startOfSecondDirData = 0; if (_buildParams.UseJoliet) { startOfSecondDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { supplementaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus); fixedRegions.Insert(regionIdx++, extent); pushAmt = Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); pushFilesBackAmt += pushAmt; focus += pushAmt; } } //Push these back now because I'm going to throw the path tables in before them PushDataBack(primaryLocationTable, supplementaryLocationTable, fixedRegions, pushFilesBackAmt, regionIdx, false); unfocused += pushFilesBackAmt; highestFileLocation += pushFilesBackAmt; focus = FirstDataExtent; pushFilesBackAmt = 0; int numDirExtents = regionIdx; regionIdx = 0; // #################################################################### // # 3. Fix path tables // #################################################################### // There are four path tables: // 1. LE, ASCII // 2. BE, ASCII // 3. LE, Supp Encoding (Joliet) // 4. BE, Supp Encoding (Joliet) // Find end of the path table long startOfFirstPathTable = focus; PathTable pathTable = new PathTable(false, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; long primaryPathTableLength = pathTable.Length; long startOfSecondPathTable = focus; pathTable = new PathTable(true, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; long startOfThirdPathTable = 0; long startOfFourthPathTable = 0; long supplementaryPathTableLength = 0; if (_buildParams.UseJoliet) { startOfThirdPathTable = focus; pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; supplementaryPathTableLength = pathTable.Length; startOfFourthPathTable = 0; pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; startOfSecondDirData += pushFilesBackAmt; } startOfFirstDirData += pushFilesBackAmt; highestFileLocation += pushFilesBackAmt; PushDataBack(primaryLocationTable, supplementaryLocationTable, fixedRegions, pushFilesBackAmt, regionIdx, true); unfocused += pushFilesBackAmt; pushFilesBackAmt = 0; //Done pushing, unless we want to expand the disc next // #################################################################### // # 3a. Correct the file locations // #################################################################### if (_buildParams.LastFileStartSector > 0) { long highFileSector = highestFileLocation / IsoUtilities.SectorSize; if (_buildParams.LastFileStartSector < highFileSector + _buildParams.LBAoffset) { throw new Exception("Disc image is too big for GD-ROM, can't build"); } else { pushFilesBackAmt = ((_buildParams.LastFileStartSector - highFileSector - _buildParams.LBAoffset) * IsoUtilities.SectorSize); } PushDataBack(primaryLocationTable, supplementaryLocationTable, fixedRegions, pushFilesBackAmt, regionIdx + numDirExtents, false); } // Find the end of the disk totalLength = unfocused; if (_buildParams.EndSector.HasValue) { long desiredLength = (_buildParams.EndSector.Value - _buildParams.LBAoffset) * IsoUtilities.SectorSize; if (totalLength < desiredLength) { totalLength = desiredLength; } else { throw new Exception("Disc is too big, exceeds the desired end sector."); } } // #################################################################### // # 4. Prepare volume descriptors now other structures are fixed // #################################################################### regionIdx = 0; focus = DiskStart; PrimaryVolumeDescriptor pvDesc = new PrimaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)primaryPathTableLength, // PathTableSize (uint)(startOfFirstPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeLPathTableLocation (uint)(startOfSecondPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeMPathTableLocation (uint)(startOfFirstDirData / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(Encoding.ASCII), // RootDirectory.DataLength buildTime); pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; pvDesc.SystemIdentifier = _buildParams.SystemIdentifier; pvDesc.VolumeSetIdentifier = _buildParams.VolumeSetIdentifier; pvDesc.PublisherIdentifier = _buildParams.PublisherIdentifier; pvDesc.DataPreparerIdentifier = _buildParams.DataPreparerIdentifier; pvDesc.ApplicationIdentifier = _buildParams.ApplicationIdentifier; PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus); fixedRegions.Insert(regionIdx++, pvdr); focus += IsoUtilities.SectorSize; if (_buildParams.UseJoliet) { //If you're not using Joilet, this is a copy of the regular descriptor and a waste of space to include. SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)supplementaryPathTableLength, // PathTableSize (uint)(startOfThirdPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeLPathTableLocation (uint)(startOfFourthPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeMPathTableLocation (uint)(startOfSecondDirData / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(suppEncoding), // RootDirectory.DataLength buildTime, suppEncoding); svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus); fixedRegions.Insert(regionIdx++, svdr); focus += IsoUtilities.SectorSize; } VolumeDescriptorSetTerminator evDesc = new VolumeDescriptorSetTerminator(); VolumeDescriptorSetTerminatorRegion evdr = new VolumeDescriptorSetTerminatorRegion(evDesc, focus); fixedRegions.Insert(regionIdx++, evdr); return(fixedRegions); }
internal override List<BuilderExtent> FixExtents(out long totalLength) { List<BuilderExtent> fixedRegions = new List<BuilderExtent>(); DateTime buildTime = DateTime.UtcNow; Encoding suppEncoding = _buildParams.UseJoliet ? Encoding.BigEndianUnicode : Encoding.ASCII; Dictionary<BuildDirectoryMember, uint> primaryLocationTable = new Dictionary<BuildDirectoryMember, uint>(); Dictionary<BuildDirectoryMember, uint> supplementaryLocationTable = new Dictionary<BuildDirectoryMember, uint>(); // #################################################################### // # 1. Fix file locations // #################################################################### long focus = FirstDataExtent; long highestFileLocation = 0; // Find end of the file data, fixing the files in place as we go foreach (BuildFileInfo fi in _files) { primaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); supplementaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); FileExtent extent = new FileExtent(fi, focus); // Only remember files of non-zero length (otherwise we'll stomp on a valid file) if (extent.Length != 0) { fixedRegions.Add(extent); } highestFileLocation = focus; focus += Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // #################################################################### // # 2. Fix directory locations // #################################################################### // There are two directory tables // 1. Primary (std ISO9660) // 2. Supplementary (Joliet) long pushFilesBackAmt = 0; int regionIdx = 0; long pushAmt = 0; //I actually want the path and directory tables before the files, //so lets find out how big it is then move all of the files long unfocused = focus; focus = FirstDataExtent; // Find start of the second set of directory data, fixing ASCII directories in place. long startOfFirstDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { primaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus); fixedRegions.Insert(regionIdx++, extent); pushAmt = Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); pushFilesBackAmt += pushAmt; focus += pushAmt; } // Find end of the second directory table, fixing supplementary directories in place. long startOfSecondDirData = 0; if (_buildParams.UseJoliet) { startOfSecondDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { supplementaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus); fixedRegions.Insert(regionIdx++, extent); pushAmt = Utilities.RoundUp(extent.Length, IsoUtilities.SectorSize); pushFilesBackAmt += pushAmt; focus += pushAmt; } } //Push these back now because I'm going to throw the path tables in before them PushDataBack(primaryLocationTable, supplementaryLocationTable, fixedRegions, pushFilesBackAmt, regionIdx, false); unfocused += pushFilesBackAmt; highestFileLocation += pushFilesBackAmt; focus = FirstDataExtent; pushFilesBackAmt = 0; int numDirExtents = regionIdx; regionIdx = 0; // #################################################################### // # 3. Fix path tables // #################################################################### // There are four path tables: // 1. LE, ASCII // 2. BE, ASCII // 3. LE, Supp Encoding (Joliet) // 4. BE, Supp Encoding (Joliet) // Find end of the path table long startOfFirstPathTable = focus; PathTable pathTable = new PathTable(false, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; long primaryPathTableLength = pathTable.Length; long startOfSecondPathTable = focus; pathTable = new PathTable(true, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; long startOfThirdPathTable = 0; long startOfFourthPathTable = 0; long supplementaryPathTableLength = 0; if (_buildParams.UseJoliet) { startOfThirdPathTable = focus; pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; supplementaryPathTableLength = pathTable.Length; startOfFourthPathTable = 0; pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Insert(regionIdx++, pathTable); pushAmt = Utilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); focus += pushAmt; pushFilesBackAmt += pushAmt; startOfSecondDirData += pushFilesBackAmt; } startOfFirstDirData += pushFilesBackAmt; highestFileLocation += pushFilesBackAmt; PushDataBack(primaryLocationTable, supplementaryLocationTable, fixedRegions, pushFilesBackAmt, regionIdx, true); unfocused += pushFilesBackAmt; pushFilesBackAmt = 0; //Done pushing, unless we want to expand the disc next // #################################################################### // # 3a. Correct the file locations // #################################################################### if(_buildParams.LastFileStartSector > 0) { long highFileSector = highestFileLocation / IsoUtilities.SectorSize; if (_buildParams.LastFileStartSector < highFileSector + _buildParams.LBAoffset) { throw new Exception("Disc image is too big for GD-ROM, can't build"); } else { pushFilesBackAmt = ((_buildParams.LastFileStartSector - highFileSector - _buildParams.LBAoffset) * IsoUtilities.SectorSize); } PushDataBack(primaryLocationTable, supplementaryLocationTable, fixedRegions, pushFilesBackAmt, regionIdx + numDirExtents, false); } // Find the end of the disk totalLength = unfocused; if (_buildParams.EndSector.HasValue) { long desiredLength = (_buildParams.EndSector.Value - _buildParams.LBAoffset) * IsoUtilities.SectorSize; if (totalLength < desiredLength) { totalLength = desiredLength; } else { throw new Exception("Disc is too big, exceeds the desired end sector."); } } // #################################################################### // # 4. Prepare volume descriptors now other structures are fixed // #################################################################### regionIdx = 0; focus = DiskStart; PrimaryVolumeDescriptor pvDesc = new PrimaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)primaryPathTableLength, // PathTableSize (uint)(startOfFirstPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeLPathTableLocation (uint)(startOfSecondPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeMPathTableLocation (uint)(startOfFirstDirData / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(Encoding.ASCII), // RootDirectory.DataLength buildTime); pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; pvDesc.SystemIdentifier = _buildParams.SystemIdentifier; pvDesc.VolumeSetIdentifier = _buildParams.VolumeSetIdentifier; pvDesc.PublisherIdentifier = _buildParams.PublisherIdentifier; pvDesc.DataPreparerIdentifier = _buildParams.DataPreparerIdentifier; pvDesc.ApplicationIdentifier = _buildParams.ApplicationIdentifier; PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus); fixedRegions.Insert(regionIdx++, pvdr); focus += IsoUtilities.SectorSize; if (_buildParams.UseJoliet) { //If you're not using Joilet, this is a copy of the regular descriptor and a waste of space to include. SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)supplementaryPathTableLength, // PathTableSize (uint)(startOfThirdPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeLPathTableLocation (uint)(startOfFourthPathTable / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // TypeMPathTableLocation (uint)(startOfSecondDirData / IsoUtilities.SectorSize) + _buildParams.LBAoffset, // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(suppEncoding), // RootDirectory.DataLength buildTime, suppEncoding); svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus); fixedRegions.Insert(regionIdx++, svdr); focus += IsoUtilities.SectorSize; } VolumeDescriptorSetTerminator evDesc = new VolumeDescriptorSetTerminator(); VolumeDescriptorSetTerminatorRegion evdr = new VolumeDescriptorSetTerminatorRegion(evDesc, focus); fixedRegions.Insert(regionIdx++, evdr); return fixedRegions; }
protected override List <BuilderExtent> FixExtents(out long totalLength) { List <BuilderExtent> fixedRegions = new List <BuilderExtent>(); DateTime buildTime = DateTime.UtcNow; Encoding suppEncoding = _buildParams.UseJoliet ? Encoding.BigEndianUnicode : Encoding.ASCII; Dictionary <BuildDirectoryMember, uint> primaryLocationTable = new Dictionary <BuildDirectoryMember, uint>(); Dictionary <BuildDirectoryMember, uint> supplementaryLocationTable = new Dictionary <BuildDirectoryMember, uint>(); long focus = DiskStart + 3 * IsoUtilities.SectorSize; // Primary, Supplementary, End (fixed at end...) if (_bootEntry != null) { focus += IsoUtilities.SectorSize; } // #################################################################### // # 0. Fix boot image location // #################################################################### long bootCatalogPos = 0; if (_bootEntry != null) { long bootImagePos = focus; Stream realBootImage = PatchBootImage(_bootImage, (uint)(DiskStart / IsoUtilities.SectorSize), (uint)(bootImagePos / IsoUtilities.SectorSize)); BuilderStreamExtent bootImageExtent = new BuilderStreamExtent(focus, realBootImage); fixedRegions.Add(bootImageExtent); focus += MathUtilities.RoundUp(bootImageExtent.Length, IsoUtilities.SectorSize); bootCatalogPos = focus; byte[] bootCatalog = new byte[IsoUtilities.SectorSize]; BootValidationEntry bve = new BootValidationEntry(); bve.WriteTo(bootCatalog, 0x00); _bootEntry.ImageStart = (uint)MathUtilities.Ceil(bootImagePos, IsoUtilities.SectorSize); _bootEntry.SectorCount = (ushort)MathUtilities.Ceil(_bootImage.Length, Sizes.Sector); _bootEntry.WriteTo(bootCatalog, 0x20); fixedRegions.Add(new BuilderBufferExtent(bootCatalogPos, bootCatalog)); focus += IsoUtilities.SectorSize; } // #################################################################### // # 1. Fix file locations // #################################################################### // Find end of the file data, fixing the files in place as we go foreach (BuildFileInfo fi in _files) { primaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); supplementaryLocationTable.Add(fi, (uint)(focus / IsoUtilities.SectorSize)); FileExtent extent = new FileExtent(fi, focus); // Only remember files of non-zero length (otherwise we'll stomp on a valid file) if (extent.Length != 0) { fixedRegions.Add(extent); } focus += MathUtilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // #################################################################### // # 2. Fix directory locations // #################################################################### // There are two directory tables // 1. Primary (std ISO9660) // 2. Supplementary (Joliet) // Find start of the second set of directory data, fixing ASCII directories in place. long startOfFirstDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { primaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus); fixedRegions.Add(extent); focus += MathUtilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // Find end of the second directory table, fixing supplementary directories in place. long startOfSecondDirData = focus; foreach (BuildDirectoryInfo di in _dirs) { supplementaryLocationTable.Add(di, (uint)(focus / IsoUtilities.SectorSize)); DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus); fixedRegions.Add(extent); focus += MathUtilities.RoundUp(extent.Length, IsoUtilities.SectorSize); } // #################################################################### // # 3. Fix path tables // #################################################################### // There are four path tables: // 1. LE, ASCII // 2. BE, ASCII // 3. LE, Supp Encoding (Joliet) // 4. BE, Supp Encoding (Joliet) // Find end of the path table long startOfFirstPathTable = focus; PathTable pathTable = new PathTable(false, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Add(pathTable); focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); long primaryPathTableLength = pathTable.Length; long startOfSecondPathTable = focus; pathTable = new PathTable(true, Encoding.ASCII, _dirs, primaryLocationTable, focus); fixedRegions.Add(pathTable); focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); long startOfThirdPathTable = focus; pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Add(pathTable); focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); long supplementaryPathTableLength = pathTable.Length; long startOfFourthPathTable = focus; pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus); fixedRegions.Add(pathTable); focus += MathUtilities.RoundUp(pathTable.Length, IsoUtilities.SectorSize); // Find the end of the disk totalLength = focus; // #################################################################### // # 4. Prepare volume descriptors now other structures are fixed // #################################################################### int regionIdx = 0; focus = DiskStart; PrimaryVolumeDescriptor pvDesc = new PrimaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)primaryPathTableLength, // PathTableSize (uint)(startOfFirstPathTable / IsoUtilities.SectorSize), // TypeLPathTableLocation (uint)(startOfSecondPathTable / IsoUtilities.SectorSize), // TypeMPathTableLocation (uint)(startOfFirstDirData / IsoUtilities.SectorSize), // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(Encoding.ASCII), // RootDirectory.DataLength buildTime); pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus); fixedRegions.Insert(regionIdx++, pvdr); focus += IsoUtilities.SectorSize; if (_bootEntry != null) { BootVolumeDescriptor bvDesc = new BootVolumeDescriptor( (uint)(bootCatalogPos / IsoUtilities.SectorSize)); BootVolumeDescriptorRegion bvdr = new BootVolumeDescriptorRegion(bvDesc, focus); fixedRegions.Insert(regionIdx++, bvdr); focus += IsoUtilities.SectorSize; } SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor( (uint)(totalLength / IsoUtilities.SectorSize), // VolumeSpaceSize (uint)supplementaryPathTableLength, // PathTableSize (uint)(startOfThirdPathTable / IsoUtilities.SectorSize), // TypeLPathTableLocation (uint)(startOfFourthPathTable / IsoUtilities.SectorSize), // TypeMPathTableLocation (uint)(startOfSecondDirData / IsoUtilities.SectorSize), // RootDirectory.LocationOfExtent (uint)_rootDirectory.GetDataSize(suppEncoding), // RootDirectory.DataLength buildTime, suppEncoding); svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier; SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus); fixedRegions.Insert(regionIdx++, svdr); focus += IsoUtilities.SectorSize; VolumeDescriptorSetTerminator evDesc = new VolumeDescriptorSetTerminator(); VolumeDescriptorSetTerminatorRegion evdr = new VolumeDescriptorSetTerminatorRegion(evDesc, focus); fixedRegions.Insert(regionIdx++, evdr); return(fixedRegions); }