예제 #1
0
 public static void WriteSector(bool isRawMode, BuiltStream isoStream, FileStream destStream, byte[] buffer, ref int currentLBA, ref int numRead)
 {
     if (isRawMode)
     {
         byte[] resultSector;
         while (numRead != 0 && numRead < buffer.Length)
         {
             // We need all 2048 bytes for a complete sector!
             int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
             numRead += localRead;
             if (localRead == 0)
             {
                 for (int i = numRead; i < buffer.Length; i++)
                 {
                     buffer[i] = 0;
                 }
                 break; // Prevent infinite loop
             }
         }
         resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
         destStream.Write(resultSector, 0, resultSector.Length);
     }
     else
     {
         destStream.Write(buffer, 0, numRead);
     }
 }
예제 #2
0
        private void BuildSingleDensityArea()
        {
            CDBuilder builder = NewCDBuilderInstance(SINGLE_DENSITY_AREA_LBA_START, SINGLE_DENSITY_AREA_LBA_END);

            byte[] ip0000Data = GDImageUtility.LoadBootstrapInMemory(SingleDensityArea.BootstrapFilePath);
            _singleDensityAreaBootstrapFileName = GDImageUtility.GetBootBinaryFileName(ip0000Data);

            // Handle track02
            List <string> cdda = new List <string>
            {
                _singleDensityAreaAudioTrackPath
            };

            _singleDensityAreaTracks.AddRange(ReadCDDA(cdda));

            // Handle track01
            DirectoryInfo di = new DirectoryInfo(SingleDensityArea.SourceDataDirectory);

            PopulateFromDirectory(builder, di, di.FullName, null, SINGLE_DENSITY_AREA_LBA_END);

            using (BuiltStream isoStream = (BuiltStream)builder.Build())
            {
                _lastProgress = 0;
                WriteDataTrack(true, isoStream, ip0000Data, _singleDensityAreaTracks);
            }
        }
예제 #3
0
        public void BuildStreamLengthIsRespected()
        {
            int length = 1024;
            var extent = new BuilderSparseStreamExtent(0, new ZeroStream(2 * length));

            using (var stream = new BuiltStream(length, new List <BuilderExtent> {
                extent
            }))
            {
                Assert.Equal(0, stream.Position);
                Assert.Equal(length, stream.Length);
                var content = new byte[2 * length];
                var read    = stream.Read(content, 0, content.Length);
                Assert.Equal(length, read);
                Assert.Equal(stream.Length, stream.Position);
            }
        }
예제 #4
0
        private void ExportSingleTrack(BuiltStream isoStream, byte[] ipbinData, List <DiscTrack> tracks)
        {
            long currentBytes = 0;
            long totalBytes   = isoStream.Length;
            int  skip         = 0;

            DiscTrack track3 = new DiscTrack();

            track3.FileName = Path.GetFileName(Track03Path);
            track3.LBA      = GD_START_LBA;
            track3.Type     = 4;
            track3.FileSize = (GD_END_LBA - GD_START_LBA) * DATA_SECTOR_SIZE;
            tracks.Add(track3);
            UpdateIPBIN(ipbinData, tracks);
            using (FileStream destStream = new FileStream(Track03Path, FileMode.Create, FileAccess.Write))
            {
                destStream.Write(ipbinData, 0, ipbinData.Length);
                isoStream.Seek(ipbinData.Length, SeekOrigin.Begin);
                currentBytes += ipbinData.Length;

                byte[] buffer  = new byte[64 * 1024];
                int    numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0)
                {
                    destStream.Write(buffer, 0, numRead);
                    numRead       = isoStream.Read(buffer, 0, buffer.Length);
                    currentBytes += numRead;
                    skip++;
                    if (skip >= 10)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
        }
예제 #5
0
        private void BuildHighDensityArea()
        {
            CDBuilder builder = NewCDBuilderInstance(HIGH_DENSITY_AREA_LBA_START, HIGH_DENSITY_AREA_LBA_END);

            byte[] ipbinData = GDImageUtility.LoadBootstrapInMemory(HighDensityArea.BootstrapFilePath);
            _highDensityAreaBootstrapFileName = GDImageUtility.GetBootBinaryFileName(ipbinData);

            DirectoryInfo di = new DirectoryInfo(HighDensityArea.SourceDataDirectory);

            PopulateFromDirectory(builder, di, di.FullName, _highDensityAreaBootstrapFileName, HIGH_DENSITY_AREA_LBA_END);

            // Handle GDDA
            _highDensityAreaTracks.AddRange(ReadCDDA(_gddaTrackPaths));

            // Handle Data Tracks
            using (BuiltStream isoStream = (BuiltStream)builder.Build())
            {
                _lastProgress = 0;
                WriteDataTrack(false, isoStream, ipbinData, _highDensityAreaTracks);
            }
        }
예제 #6
0
        public static long WriteBootSector(bool isRawMode, BuiltStream isoStream, FileStream destStream, byte[] buffer, ref int currentLBA, ref long currentBytes, byte[] bootstrapData)
        {
            if (isRawMode)
            {
                byte[] resultSector;
                for (int i = 0; i < bootstrapData.Length; i += buffer.Length)
                {
                    Array.Copy(bootstrapData, i, buffer, 0, buffer.Length);
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    currentBytes += buffer.Length;
                }
            }
            else
            {
                destStream.Write(bootstrapData, 0, bootstrapData.Length);
            }

            isoStream.Seek(bootstrapData.Length, SeekOrigin.Begin);
            return((long)bootstrapData.Length); // bytesWritten
        }
예제 #7
0
        private void WriteDataTrack(bool isSingleDensityArea, BuiltStream isoStream, byte[] bootstrapData, List <GDTrack> tracks)
        {
            // When starting this, tracks contains only GDDA tracks (for SDA: only 1 audio track, for HDA: all GDDA if any)

            long currentBytes = 0;
            long totalBytes   = isoStream.Length;
            int  skip         = 0;
            int  currentLBA   = isSingleDensityArea ? SINGLE_DENSITY_AREA_LBA_START : HIGH_DENSITY_AREA_LBA_START;

            bool isHighDensityAreaMultiDataTrack = !isSingleDensityArea && HighDensityDataTrackSplitted;

            string dataTrackFileFirstPath = isSingleDensityArea ? _singleDensityAreaDataTrackPath : _highDensityAreaDataTrackFirstPath; // for SDA/HDA
            string dataTrackFileLastPath  = isSingleDensityArea ? string.Empty : _highDensityAreaDataTrackLastPath;                     // for HDA only

            // Retrive the real space occuped on the data track
            long lastHeaderEnd  = 0;
            long firstFileStart = 0;

            foreach (BuilderExtent extent in isoStream.BuilderExtents)
            {
                if (extent is FileExtent)
                {
                    firstFileStart = extent.Start;
                    break;
                }
                else
                {
                    lastHeaderEnd = extent.Start + GDImageUtility.RoundUp(extent.Length, DATA_SECTOR_SIZE);
                }
            }
            lastHeaderEnd  /= DATA_SECTOR_SIZE;
            firstFileStart /= DATA_SECTOR_SIZE;

            // HDA: Single track is filling all the available space by default, if only one data track in HDA (computed below if HDA has GDDA)
            int trackEnd = HIGH_DENSITY_AREA_LBA_END - HIGH_DENSITY_AREA_LBA_START;

            // SDA: Computing trackEnd for the data track
            if (isSingleDensityArea)
            {
                // SDA: Single data track (track01) is filling the available space... after taken into account the SDA audio track
                long singleDensityAreaAudioTrackFileSize = tracks[0].FileSize; // When SDA, tracks[0] = SDA Audio Track (only 1 track)

                // Computing the space filled by the SDA audio track
                int singleDensityAreaAudioTrackSectorsSize = (int)(GDImageUtility.RoundUp(singleDensityAreaAudioTrackFileSize, RAW_SECTOR_SIZE) / RAW_SECTOR_SIZE);

                // So the SDA data track will fill this space...
                trackEnd = SINGLE_DENSITY_AREA_LBA_END - singleDensityAreaAudioTrackSectorsSize - TRACK_GAP_SECTOR_COUNT; /* FIXME */

                // Updating the SDA audio track in consequence
                tracks[0].LBA = (uint)trackEnd + TRACK_GAP_SECTOR_COUNT;
            }

            if (isHighDensityAreaMultiDataTrack)
            {
                trackEnd = RecomputeAudioTracksLogicalBlockAddresses(tracks, HIGH_DENSITY_AREA_LBA_START, firstFileStart);

                if (trackEnd < lastHeaderEnd)
                {
                    throw new Exception("Not enough room to fit all of the CDDA after we added the data.");
                }

                // trackEnd: HDA when multi tracks: computed with GDDA
            }

            long firstTrackFileSize = trackEnd * DATA_SECTOR_SIZE;

            // Applied for SDA data track and HDA first data track
            if (TruncateData)
            {
                long firstTrackSectorSize = (lastHeaderEnd > TRACK_MINIMUM_SECTOR_COUNT ? lastHeaderEnd : TRACK_MINIMUM_SECTOR_COUNT);
                RecomputeAudioTracksLogicalBlockAddresses(tracks, (uint)currentLBA, firstTrackSectorSize);
                firstTrackFileSize = firstTrackSectorSize * DATA_SECTOR_SIZE;
            }

            // Handle data track (SDA is track01, HDA is track03)
            GDTrack firstTrack = new GDTrack
            {
                FileName = Path.GetFileName(dataTrackFileFirstPath),
                FileSize = firstTrackFileSize,
                LBA      = (uint)currentLBA,
                Type     = GDTrackType.Data
            };

            tracks.Insert(0, firstTrack); // the first data track is at the beginning of the area

            // Handle last data track for HDA (if applicable)
            GDTrack lastTrack = null;

            if (isHighDensityAreaMultiDataTrack)
            {
                lastTrack = new GDTrack
                {
                    FileName = Path.GetFileName(dataTrackFileLastPath),
                    FileSize = (HIGH_DENSITY_AREA_LBA_END - HIGH_DENSITY_AREA_LBA_START - firstFileStart) * DATA_SECTOR_SIZE,
                    LBA      = (uint)(HIGH_DENSITY_AREA_LBA_START + firstFileStart),
                    Type     = GDTrackType.Data
                };
                tracks.Add(lastTrack);
            }

            // Update the TOC in the IP.BIN for the HDA
            if (!isSingleDensityArea)
            {
                GDImageUtility.UpdateBootstrapTableOfContents(bootstrapData, tracks);
            }

            // Initialize stream variables
            byte[] buffer       = new byte[DATA_SECTOR_SIZE];
            int    numRead      = 0;
            long   bytesWritten = 0;

            // Write first (or single) data track
            using (FileStream destStream = new FileStream(dataTrackFileFirstPath, FileMode.Create, FileAccess.Write))
            {
                // Write Bootsector data in the first sector
                bytesWritten = GDImageWriteHelper.WriteBootSector(RawMode, isoStream, destStream, buffer, ref currentLBA, ref currentBytes, bootstrapData);

                numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0 && bytesWritten < firstTrack.FileSize)
                {
                    GDImageWriteHelper.WriteSector(RawMode, isoStream, destStream, buffer, ref currentLBA, ref numRead);

                    numRead       = isoStream.Read(buffer, 0, buffer.Length);
                    bytesWritten += numRead;
                    currentBytes += numRead;

                    skip = NotifyProgress(currentBytes, totalBytes, skip);
                }
            }

            // Write last data track (if any)
            if (isHighDensityAreaMultiDataTrack)
            {
                currentLBA = (int)lastTrack.LBA;

                using (FileStream destStream = new FileStream(dataTrackFileLastPath, FileMode.Create, FileAccess.Write))
                {
                    currentBytes = firstFileStart * DATA_SECTOR_SIZE;
                    isoStream.Seek(currentBytes, SeekOrigin.Begin);

                    numRead = isoStream.Read(buffer, 0, buffer.Length);
                    while (numRead != 0)
                    {
                        GDImageWriteHelper.WriteSector(RawMode, isoStream, destStream, buffer, ref currentLBA, ref numRead);

                        numRead       = isoStream.Read(buffer, 0, buffer.Length);
                        currentBytes += numRead;

                        skip = NotifyProgress(currentBytes, totalBytes, skip);
                    }
                }
            }
        }
예제 #8
0
        public List <DiscTrack> BuildGDROM(string data, string ipbin, List <string> cdda)
        {
            string bootBin;

            byte[]    ipbinData = new byte[0x8000];
            CDBuilder builder   = new CDBuilder();

            builder.VolumeIdentifier       = VolumeIdentifier;
            builder.SystemIdentifier       = SystemIdentifier;
            builder.VolumeSetIdentifier    = VolumeSetIdentifier;
            builder.PublisherIdentifier    = PublisherIdentifier;
            builder.DataPreparerIdentifier = DataPreparerIdentifier;
            builder.ApplicationIdentifier  = ApplicationIdentifier;
            builder.UseJoliet = false; //A stupid default, mkisofs won't do this by default.
            builder.LBAoffset = GD_START_LBA;
            builder.EndSector = GD_END_LBA;

            using (FileStream ipfs = new FileStream(ipbin, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (ipfs.Length != ipbinData.Length)
                {
                    throw new Exception("IP.BIN is the wrong size. Possibly the wrong file? Cannot continue.");
                }
                bootBin = GetBootBin(ipfs);
                ipfs.Seek(0, SeekOrigin.Begin);
                ipfs.Read(ipbinData, 0, ipbinData.Length);
            }
            List <DiscTrack> retval = new List <DiscTrack>();

            if (cdda != null && cdda.Count > 0)
            {
                retval = ReadCDDA(cdda);
            }
            DirectoryInfo di = new DirectoryInfo(data);

            PopulateFromFolder(builder, di, di.FullName, bootBin);

            using (BuiltStream isoStream = (BuiltStream)builder.Build())
            {
                _lastProgress = 0;
                if (retval.Count > 0 || (TruncateData && !string.IsNullOrEmpty(LastTrackPath)))
                {
                    if (RawMode)
                    {
                        ExportMultiTrackRaw(isoStream, ipbinData, retval);
                    }
                    else
                    {
                        ExportMultiTrack(isoStream, ipbinData, retval);
                    }
                }
                else
                {
                    if (RawMode)
                    {
                        ExportSingleTrackRaw(isoStream, ipbinData, retval);
                    }
                    else
                    {
                        ExportSingleTrack(isoStream, ipbinData, retval);
                    }
                }
            }
            return(retval);
        }
예제 #9
0
        private void ExportMultiTrackRaw(BuiltStream isoStream, byte[] ipbinData, List <DiscTrack> tracks)
        {
            //There is a 150 sector gap before and after the CDDA
            long lastHeaderEnd  = 0;
            long firstFileStart = 0;

            foreach (BuilderExtent extent in isoStream.BuilderExtents)
            {
                if (extent is FileExtent)
                {
                    firstFileStart = extent.Start;
                    break;
                }
                else
                {
                    lastHeaderEnd = extent.Start + RoundUp(extent.Length, DATA_SECTOR_SIZE);
                }
            }
            lastHeaderEnd  = lastHeaderEnd / DATA_SECTOR_SIZE;
            firstFileStart = firstFileStart / DATA_SECTOR_SIZE;
            int trackEnd = (int)(firstFileStart - 150);

            for (int i = tracks.Count - 1; i >= 0; i--)
            {
                trackEnd = trackEnd - (int)(RoundUp(tracks[i].FileSize, RAW_SECTOR_SIZE) / RAW_SECTOR_SIZE);
                //Track end is now the beginning of this track and the end of the previous
                tracks[i].LBA = (uint)(trackEnd + GD_START_LBA);
            }
            trackEnd = trackEnd - 150;
            if (trackEnd < lastHeaderEnd)
            {
                throw new Exception("Not enough room to fit all of the CDDA after we added the data.");
            }
            if (TruncateData)
            {
                trackEnd = (int)lastHeaderEnd;
            }
            DiscTrack track3 = new DiscTrack();

            track3.FileName = Path.GetFileName(Track03Path);
            track3.LBA      = GD_START_LBA;
            track3.Type     = 4;
            track3.FileSize = trackEnd * DATA_SECTOR_SIZE;
            tracks.Insert(0, track3);
            DiscTrack lastTrack = new DiscTrack();

            lastTrack.FileName = GetLastTrackName(tracks.Count - 1);
            lastTrack.FileSize = (GD_END_LBA - GD_START_LBA - firstFileStart) * DATA_SECTOR_SIZE;
            lastTrack.LBA      = (uint)(GD_START_LBA + firstFileStart);
            lastTrack.Type     = 4;
            tracks.Add(lastTrack);
            UpdateIPBIN(ipbinData, tracks);

            long currentBytes = 0;
            long totalBytes   = isoStream.Length;
            int  skip         = 0;
            int  currentLBA   = GD_START_LBA;

            using (FileStream destStream = new FileStream(Track03Path, FileMode.Create, FileAccess.Write))
            {
                byte[] buffer = new byte[DATA_SECTOR_SIZE];
                byte[] resultSector;
                for (int i = 0; i < ipbinData.Length; i += buffer.Length)
                {
                    Array.Copy(ipbinData, i, buffer, 0, buffer.Length);
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    currentBytes += 2048;
                }
                isoStream.Seek(ipbinData.Length, SeekOrigin.Begin);
                long bytesWritten = (long)ipbinData.Length;

                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0 && bytesWritten < track3.FileSize)
                {
                    while (numRead != 0 && numRead < buffer.Length)
                    {
                        //We need all 2048 bytes for a complete sector!
                        int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
                        numRead += localRead;
                        if (localRead == 0)
                        {
                            for (int i = numRead; i < buffer.Length; i++)
                            {
                                buffer[i] = 0;
                            }
                            break; //Prevent infinite loop
                        }
                    }
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    numRead       = isoStream.Read(buffer, 0, buffer.Length);
                    bytesWritten += numRead;
                    currentBytes += numRead;
                    skip++;
                    if (skip >= 50)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
            currentLBA = (int)lastTrack.LBA;
            using (FileStream destStream = new FileStream(LastTrackPath, FileMode.Create, FileAccess.Write))
            {
                byte[] buffer = new byte[DATA_SECTOR_SIZE];
                byte[] resultSector;
                currentBytes = firstFileStart * DATA_SECTOR_SIZE;
                isoStream.Seek(currentBytes, SeekOrigin.Begin);
                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0)
                {
                    while (numRead != 0 && numRead < buffer.Length)
                    {
                        //We need all 2048 bytes for a complete sector!
                        int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
                        numRead += localRead;
                        if (localRead == 0)
                        {
                            for (int i = numRead; i < buffer.Length; i++)
                            {
                                buffer[i] = 0;
                            }
                            break; //Prevent infinite loop
                        }
                    }
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    numRead = isoStream.Read(buffer, 0, buffer.Length);

                    currentBytes += numRead;
                    skip++;
                    if (skip >= 10)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Separate raw logic to maintain performance of the 2048 version
        /// </summary>
        private void ExportSingleTrackRaw(BuiltStream isoStream, byte[] ipbinData, List <DiscTrack> tracks)
        {
            long currentBytes = 0;
            long totalBytes   = isoStream.Length;
            int  skip         = 0;

            DiscTrack track3 = new DiscTrack();

            track3.FileName = Path.GetFileName(Track03Path);
            track3.LBA      = GD_START_LBA;
            track3.Type     = 4;
            track3.FileSize = (GD_END_LBA - GD_START_LBA) * DATA_SECTOR_SIZE;
            tracks.Add(track3);
            UpdateIPBIN(ipbinData, tracks);
            using (FileStream destStream = new FileStream(Track03Path, FileMode.Create, FileAccess.Write))
            {
                int    currentLBA = GD_START_LBA;
                byte[] buffer     = new byte[DATA_SECTOR_SIZE];
                byte[] resultSector;
                for (int i = 0; i < ipbinData.Length; i += buffer.Length)
                {
                    Array.Copy(ipbinData, i, buffer, 0, buffer.Length);
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    currentBytes += 2048;
                }
                isoStream.Seek(ipbinData.Length, SeekOrigin.Begin);

                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0)
                {
                    while (numRead != 0 && numRead < buffer.Length)
                    {
                        //We need all 2048 bytes for a complete sector!
                        int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
                        numRead += localRead;
                        if (localRead == 0)
                        {
                            for (int i = numRead; i < buffer.Length; i++)
                            {
                                buffer[i] = 0;
                            }
                            break; //Prevent infinite loop
                        }
                    }
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    numRead       = isoStream.Read(buffer, 0, buffer.Length);
                    currentBytes += numRead;
                    skip++;
                    if (skip >= 10)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
        }
예제 #11
0
        /// <summary>
        /// Separate raw logic to maintain performance of the 2048 version
        /// </summary>
        private void ExportSingleTrackRaw(BuiltStream isoStream, byte[] ipbinData, List<DiscTrack> tracks)
        {
            long currentBytes = 0;
            long totalBytes = isoStream.Length;
            int skip = 0;

            DiscTrack track3 = new DiscTrack();
            track3.FileName = Path.GetFileName(Track03Path);
            track3.LBA = GD_START_LBA;
            track3.Type = 4;
            track3.FileSize = (GD_END_LBA - GD_START_LBA) * DATA_SECTOR_SIZE;
            tracks.Add(track3);
            UpdateIPBIN(ipbinData, tracks);
            using (FileStream destStream = new FileStream(Track03Path, FileMode.Create, FileAccess.Write))
            {
                int currentLBA = GD_START_LBA;
                byte[] buffer = new byte[DATA_SECTOR_SIZE];
                byte[] resultSector;
                for (int i = 0; i < ipbinData.Length; i += buffer.Length)
                {
                    Array.Copy(ipbinData, i, buffer, 0, buffer.Length);
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    currentBytes += 2048;
                }
                isoStream.Seek(ipbinData.Length, SeekOrigin.Begin);

                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0)
                {
                    while (numRead != 0 && numRead < buffer.Length)
                    {
                        //We need all 2048 bytes for a complete sector!
                        int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
                        numRead += localRead;
                        if (localRead == 0)
                        {
                            for (int i = numRead; i < buffer.Length; i++)
                            {
                                buffer[i] = 0;
                            }
                            break; //Prevent infinite loop
                        }
                    }
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    numRead = isoStream.Read(buffer, 0, buffer.Length);
                    currentBytes += numRead;
                    skip++;
                    if (skip >= 10)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
        }
예제 #12
0
        private void ExportSingleTrack(BuiltStream isoStream, byte[] ipbinData, List<DiscTrack> tracks)
        {
            long currentBytes = 0;
            long totalBytes = isoStream.Length;
            int skip = 0;

            DiscTrack track3 = new DiscTrack();
            track3.FileName = Path.GetFileName(Track03Path);
            track3.LBA = GD_START_LBA;
            track3.Type = 4;
            track3.FileSize = (GD_END_LBA - GD_START_LBA) * DATA_SECTOR_SIZE;
            tracks.Add(track3);
            UpdateIPBIN(ipbinData, tracks);
            using (FileStream destStream = new FileStream(Track03Path, FileMode.Create, FileAccess.Write))
            {
                destStream.Write(ipbinData, 0, ipbinData.Length);
                isoStream.Seek(ipbinData.Length, SeekOrigin.Begin);
                currentBytes += ipbinData.Length;

                byte[] buffer = new byte[64 * 1024];
                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0)
                {
                    destStream.Write(buffer, 0, numRead);
                    numRead = isoStream.Read(buffer, 0, buffer.Length);
                    currentBytes += numRead;
                    skip++;
                    if (skip >= 10)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes*100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if(ReportProgress != null){
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
        }
예제 #13
0
        private void ExportMultiTrackRaw(BuiltStream isoStream, byte[] ipbinData, List<DiscTrack> tracks)
        {
            //There is a 150 sector gap before and after the CDDA
            long lastHeaderEnd = 0;
            long firstFileStart = 0;
            foreach (BuilderExtent extent in isoStream.BuilderExtents)
            {
                if (extent is FileExtent)
                {
                    firstFileStart = extent.Start;
                    break;
                }
                else
                {
                    lastHeaderEnd = extent.Start + RoundUp(extent.Length, DATA_SECTOR_SIZE);
                }
            }
            lastHeaderEnd = lastHeaderEnd / DATA_SECTOR_SIZE;
            firstFileStart = firstFileStart / DATA_SECTOR_SIZE;
            int trackEnd = (int)(firstFileStart - 150);
            for (int i = tracks.Count - 1; i >= 0; i--)
            {
                trackEnd = trackEnd - (int)(RoundUp(tracks[i].FileSize, RAW_SECTOR_SIZE) / RAW_SECTOR_SIZE);
                //Track end is now the beginning of this track and the end of the previous
                tracks[i].LBA = (uint)(trackEnd + GD_START_LBA);
            }
            trackEnd = trackEnd - 150;
            if (trackEnd < lastHeaderEnd)
            {
                throw new Exception("Not enough room to fit all of the CDDA after we added the data.");
            }
            if (TruncateData)
            {
                trackEnd = (int)lastHeaderEnd;
            }
            DiscTrack track3 = new DiscTrack();
            track3.FileName = Path.GetFileName(Track03Path);
            track3.LBA = GD_START_LBA;
            track3.Type = 4;
            track3.FileSize = trackEnd * DATA_SECTOR_SIZE;
            tracks.Insert(0, track3);
            DiscTrack lastTrack = new DiscTrack();
            lastTrack.FileName = GetLastTrackName(tracks.Count - 1);
            lastTrack.FileSize = (GD_END_LBA - GD_START_LBA - firstFileStart) * DATA_SECTOR_SIZE;
            lastTrack.LBA = (uint)(GD_START_LBA + firstFileStart);
            lastTrack.Type = 4;
            tracks.Add(lastTrack);
            UpdateIPBIN(ipbinData, tracks);

            long currentBytes = 0;
            long totalBytes = isoStream.Length;
            int skip = 0;
            int currentLBA = GD_START_LBA;

            using (FileStream destStream = new FileStream(Track03Path, FileMode.Create, FileAccess.Write))
            {
                byte[] buffer = new byte[DATA_SECTOR_SIZE];
                byte[] resultSector;
                for (int i = 0; i < ipbinData.Length; i += buffer.Length)
                {
                    Array.Copy(ipbinData, i, buffer, 0, buffer.Length);
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    currentBytes += 2048;
                }
                isoStream.Seek(ipbinData.Length, SeekOrigin.Begin);
                long bytesWritten = (long)ipbinData.Length;

                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0 && bytesWritten < track3.FileSize)
                {
                    while (numRead != 0 && numRead < buffer.Length)
                    {
                        //We need all 2048 bytes for a complete sector!
                        int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
                        numRead += localRead;
                        if (localRead == 0)
                        {
                            for (int i = numRead; i < buffer.Length; i++)
                            {
                                buffer[i] = 0;
                            }
                            break; //Prevent infinite loop
                        }
                    }
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    numRead = isoStream.Read(buffer, 0, buffer.Length);
                    bytesWritten += numRead;
                    currentBytes += numRead;
                    skip++;
                    if (skip >= 50)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
            currentLBA = (int)lastTrack.LBA;
            using (FileStream destStream = new FileStream(LastTrackPath, FileMode.Create, FileAccess.Write))
            {
                byte[] buffer = new byte[DATA_SECTOR_SIZE];
                byte[] resultSector;
                currentBytes = firstFileStart * DATA_SECTOR_SIZE;
                isoStream.Seek(currentBytes, SeekOrigin.Begin);
                int numRead = isoStream.Read(buffer, 0, buffer.Length);
                while (numRead != 0)
                {
                    while (numRead != 0 && numRead < buffer.Length)
                    {
                        //We need all 2048 bytes for a complete sector!
                        int localRead = isoStream.Read(buffer, numRead, buffer.Length - numRead);
                        numRead += localRead;
                        if (localRead == 0)
                        {
                            for (int i = numRead; i < buffer.Length; i++)
                            {
                                buffer[i] = 0;
                            }
                            break; //Prevent infinite loop
                        }
                    }
                    resultSector = SectorConversion.ConvertSectorToRawMode1(buffer, currentLBA++);
                    destStream.Write(resultSector, 0, resultSector.Length);
                    numRead = isoStream.Read(buffer, 0, buffer.Length);

                    currentBytes += numRead;
                    skip++;
                    if (skip >= 10)
                    {
                        skip = 0;
                        int percent = (int)((currentBytes * 100) / totalBytes);
                        if (percent > _lastProgress)
                        {
                            _lastProgress = percent;
                            if (ReportProgress != null)
                            {
                                ReportProgress(_lastProgress);
                            }
                        }
                    }
                }
            }
        }