Exemplo n.º 1
0
        private BootInitialEntry GetBootInitialEntry()
        {
            byte[] bootCatalog = GetBootCatalog();
            if (bootCatalog == null)
            {
                return(null);
            }

            BootValidationEntry validationEntry = new BootValidationEntry(bootCatalog, 0);

            if (!validationEntry.ChecksumValid)
            {
                return(null);
            }

            return(new BootInitialEntry(bootCatalog, 0x20));
        }
Exemplo n.º 2
0
        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 * _buildParams.SectorSize; // Primary, Supplementary, End (fixed at end...)

            if (_bootEntry != null)
            {
                focus += _buildParams.SectorSize;
            }

            // ####################################################################
            // # 0. Fix boot image location
            // ####################################################################
            long bootCatalogPos = 0;

            if (_bootEntry != null)
            {
                long   bootImagePos  = focus;
                Stream realBootImage = PatchBootImage(_bootImage, (uint)(DiskStart / _buildParams.SectorSize),
                                                      (uint)(bootImagePos / _buildParams.SectorSize));
                BuilderStreamExtent bootImageExtent = new BuilderStreamExtent(focus, realBootImage);
                fixedRegions.Add(bootImageExtent);
                focus += MathUtilities.RoundUp(bootImageExtent.Length, _buildParams.SectorSize);

                bootCatalogPos = focus;
                byte[] bootCatalog      = new byte[_buildParams.SectorSize];
                BootValidationEntry bve = new BootValidationEntry();
                bve.WriteTo(bootCatalog, 0x00);
                _bootEntry.ImageStart  = (uint)MathUtilities.Ceil(bootImagePos, _buildParams.SectorSize);
                _bootEntry.SectorCount = (ushort)MathUtilities.Ceil(_bootImage.Length, Sizes.Sector);
                _bootEntry.WriteTo(bootCatalog, 0x20);
                fixedRegions.Add(new BuilderBufferExtent(bootCatalogPos, bootCatalog));
                focus += _buildParams.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 / _buildParams.SectorSize));
                supplementaryLocationTable.Add(fi, (uint)(focus / _buildParams.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, _buildParams.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 / _buildParams.SectorSize));
                DirectoryExtent extent = new DirectoryExtent(di, primaryLocationTable, Encoding.ASCII, focus);
                fixedRegions.Add(extent);
                focus += MathUtilities.RoundUp(extent.Length, _buildParams.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 / _buildParams.SectorSize));
                DirectoryExtent extent = new DirectoryExtent(di, supplementaryLocationTable, suppEncoding, focus);
                fixedRegions.Add(extent);
                focus += MathUtilities.RoundUp(extent.Length, _buildParams.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, _buildParams.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, _buildParams.SectorSize);

            long startOfThirdPathTable = focus;

            pathTable = new PathTable(false, suppEncoding, _dirs, supplementaryLocationTable, focus);
            fixedRegions.Add(pathTable);
            focus += MathUtilities.RoundUp(pathTable.Length, _buildParams.SectorSize);
            long supplementaryPathTableLength = pathTable.Length;

            long startOfFourthPathTable = focus;

            pathTable = new PathTable(true, suppEncoding, _dirs, supplementaryLocationTable, focus);
            fixedRegions.Add(pathTable);
            focus += MathUtilities.RoundUp(pathTable.Length, _buildParams.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 / _buildParams.SectorSize),            // VolumeSpaceSize
                (uint)primaryPathTableLength,                             // PathTableSize
                (uint)(startOfFirstPathTable / _buildParams.SectorSize),  // TypeLPathTableLocation
                (uint)(startOfSecondPathTable / _buildParams.SectorSize), // TypeMPathTableLocation
                (uint)(startOfFirstDirData / _buildParams.SectorSize),    // RootDirectory.LocationOfExtent
                (uint)_rootDirectory.GetDataSize(Encoding.ASCII),         // RootDirectory.DataLength
                buildTime,
                _sectorSize);

            pvDesc.VolumeIdentifier = _buildParams.VolumeIdentifier;
            PrimaryVolumeDescriptorRegion pvdr = new PrimaryVolumeDescriptorRegion(pvDesc, focus, _sectorSize);

            fixedRegions.Insert(regionIdx++, pvdr);
            focus += _buildParams.SectorSize;

            if (_bootEntry != null)
            {
                BootVolumeDescriptor bvDesc = new BootVolumeDescriptor(
                    (uint)(bootCatalogPos / _buildParams.SectorSize), _buildParams.SectorSize);
                BootVolumeDescriptorRegion bvdr = new BootVolumeDescriptorRegion(bvDesc, focus, _buildParams.SectorSize);
                fixedRegions.Insert(regionIdx++, bvdr);
                focus += _buildParams.SectorSize;
            }

            SupplementaryVolumeDescriptor svDesc = new SupplementaryVolumeDescriptor(
                (uint)(totalLength / _buildParams.SectorSize),            // VolumeSpaceSize
                (uint)supplementaryPathTableLength,                       // PathTableSize
                (uint)(startOfThirdPathTable / _buildParams.SectorSize),  // TypeLPathTableLocation
                (uint)(startOfFourthPathTable / _buildParams.SectorSize), // TypeMPathTableLocation
                (uint)(startOfSecondDirData / _buildParams.SectorSize),   // RootDirectory.LocationOfExtent
                (uint)_rootDirectory.GetDataSize(suppEncoding),           // RootDirectory.DataLength
                buildTime,
                suppEncoding,
                _sectorSize);

            svDesc.VolumeIdentifier = _buildParams.VolumeIdentifier;
            SupplementaryVolumeDescriptorRegion svdr = new SupplementaryVolumeDescriptorRegion(svDesc, focus, _sectorSize);

            fixedRegions.Insert(regionIdx++, svdr);
            focus += _buildParams.SectorSize;

            VolumeDescriptorSetTerminator       evDesc = new VolumeDescriptorSetTerminator(_sectorSize);
            VolumeDescriptorSetTerminatorRegion evdr   = new VolumeDescriptorSetTerminatorRegion(evDesc, focus, _sectorSize);

            fixedRegions.Insert(regionIdx++, evdr);

            return(fixedRegions);
        }