Esempio n. 1
0
        public IEnumerable <IWiiDiscSection> EnumerateSections(long imageSize)
        {
            bool generateUpdateFiller = false;
            bool generateOtherFiller  = false;
            bool forceFillerJunk      = false;
            long discOffset           = 0;
            WiiDiscHeaderSection hdr  = (WiiDiscHeaderSection)NStream.DiscHeader;

            //this.Header = (BaseSection)hdr;
            yield return(hdr);

            discOffset += hdr.Size;
            string lastId           = null;
            long   lastDiscOffset   = 0;
            long   updateGapPadding = 0;

            foreach (WiiPartitionInfo part in hdr.Partitions) //already sorted
            {
                WiiPartitionPlaceHolder placeholder = part as WiiPartitionPlaceHolder;

                //do we have a gap
                if (lastId != null || part.DiscOffset - discOffset != 0) //null if last was header
                {
                    if (part.DiscOffset < discOffset)
                    {
                        throw new HandledException("Partition alignment error, this could be a bug when adding missing partitions");
                    }

                    WiiFillerSection gap = new WiiFillerSection(NStream, part.Type == PartitionType.Update, discOffset, part.DiscOffset - discOffset, updateGapPadding, null, generateUpdateFiller, generateOtherFiller, forceFillerJunk);
                    yield return(gap);

                    discOffset += gap.Size;
                    ensurePosition(NStream, discOffset - updateGapPadding);
                }

                WiiPartitionSection partSec;
                if (placeholder != null)
                {
                    if (placeholder.Filename != null)
                    {
                        if (generateOtherFiller && NStream.Position + updateGapPadding > hdr.Partitions.Max(a => a is WiiPartitionPlaceHolder ? 0 : a.DiscOffset))
                        {
                            NStream.Complete(); //Placeholders from now, no stream reading required
                        }
                        partSec = new WiiPartitionSection(NStream, (WiiDiscHeaderSection)NStream.DiscHeader, placeholder.Stream, discOffset);
                        ensurePosition(NStream, discOffset + partSec.Size - updateGapPadding); //used to be a seek - _stream.Seek(partSec.Size, SeekOrigin.Current); //stream will seek forward
                    }
                    else
                    {
                        continue; //force filler
                    }
                }
                else //should not get called when _stream is null
                {
                    partSec = new WiiPartitionSection(NStream, (WiiDiscHeaderSection)NStream.DiscHeader, this.NStream, discOffset);
                }

                yield return(partSec);

                ensurePosition(NStream, discOffset + partSec.Size - updateGapPadding);
                if (generateOtherFiller && NStream.Position + updateGapPadding > hdr.Partitions.Max(a => a is WiiPartitionPlaceHolder ? 0 : a.DiscOffset))
                {
                    NStream.Complete(); //Placeholders from now, no stream reading required
                }
                if (placeholder != null && placeholder.Filename != null)
                {
                    placeholder.Dispose();
                }

                lastId         = partSec.Id;
                lastDiscOffset = partSec.DiscOffset + updateGapPadding;
                discOffset    += partSec.Size;
            }

            if (lastId != null)
            {
                yield return(new WiiFillerSection(NStream, false, discOffset, (imageSize == 0 ? NStream.Length : imageSize) - discOffset, 0, null, generateUpdateFiller, generateOtherFiller, forceFillerJunk));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Forward read of the full iso
        /// </summary>
        /// <param name="generateUpdateFiller">True: blank the update filler, False: copy it to catch the unknown extra data sin some images</param>
        /// <param name="generateOtherFiller">True: skip reading other filler (junk) and generate it, False: read filler sections from the source</param>
        /// <param name="forceFillerJunk">True: Generate the junk even if either of the above is false for comparison purposes</param>
        /// <returns></returns>
        public IEnumerable <IWiiDiscSection> EnumerateSectionsFix(bool generateUpdateFiller, bool generateOtherFiller, bool forceFillerJunk)
        {
            long discOffset          = 0;
            WiiDiscHeaderSection hdr = (WiiDiscHeaderSection)NStream.DiscHeader;

            //this.Header = (BaseSection)hdr;
            yield return(hdr);

            discOffset += hdr.Size;
            string lastId           = null;
            long   lastDiscOffset   = 0;
            long   updateGapPadding = 0;

            foreach (WiiPartitionInfo part in hdr.Partitions) //already sorted
            {
                WiiPartitionPlaceHolder placeholder = part as WiiPartitionPlaceHolder;

                //do we have a gap
                if (lastId != null || part.DiscOffset - discOffset != 0)                                             //null if last was header
                {
                    if (lastDiscOffset <= 0x50000L && part.DiscOffset > part.SrcDiscOffset && updateGapPadding == 0) //only once
                    {
                        updateGapPadding = part.DiscOffset - part.SrcDiscOffset;
                        Log?.LogDetail(string.Format("Moving Data Partition from {0} to {1}", part.SrcDiscOffset.ToString("X8"), part.DiscOffset.ToString("X8")));
                    }

                    if (part.DiscOffset < discOffset)
                    {
                        throw new HandledException("Partition alignment error, this could be a bug when adding missing partitions");
                    }

                    WiiFillerSection gap = new WiiFillerSection(NStream, discOffset < 0xF800000L, discOffset, part.DiscOffset - discOffset, updateGapPadding, null, generateUpdateFiller, generateOtherFiller, forceFillerJunk);
                    yield return(gap);

                    discOffset += gap.Size;
                    ensurePosition(NStream, discOffset - updateGapPadding);
                }

                WiiPartitionSection partSec;
                if (placeholder != null)
                {
                    if (placeholder.Filename != null)
                    {
                        if (generateOtherFiller && NStream.Position + updateGapPadding > hdr.Partitions.Max(a => a is WiiPartitionPlaceHolder ? 0 : a.DiscOffset))
                        {
                            NStream.Complete(); //Placeholders from now, no stream reading required
                        }
                        partSec = new WiiPartitionSection(NStream, (WiiDiscHeaderSection)NStream.DiscHeader, placeholder.Stream, discOffset);
                        ensurePosition(NStream, discOffset + partSec.Size - updateGapPadding); //used to be a seek - _stream.Seek(partSec.Size, SeekOrigin.Current); //stream will seek forward
                    }
                    else
                    {
                        continue; //force filler
                    }
                }
                else //should not get called when _stream is null
                {
                    partSec = new WiiPartitionSection(NStream, (WiiDiscHeaderSection)NStream.DiscHeader, this.NStream, discOffset);
                }

                //correct the stream length - required for 1 dual layer than when shrank is seen as single layer
                if (partSec.DiscOffset + partSec.PartitionLength > NStream.Length)
                {
                    NStream.SetLength(partSec.DiscOffset + partSec.PartitionLength);
                }

                yield return(partSec);

                ensurePosition(NStream, discOffset + partSec.Size - updateGapPadding);
                if (generateOtherFiller && NStream.Position + updateGapPadding > hdr.Partitions.Max(a => a is WiiPartitionPlaceHolder ? 0 : a.DiscOffset))
                {
                    NStream.Complete(); //Placeholders from now, no stream reading required
                }
                if (placeholder != null && placeholder.Filename != null)
                {
                    placeholder.Dispose();
                }

                lastId         = partSec.Id;
                lastDiscOffset = partSec.DiscOffset + updateGapPadding;
                discOffset    += partSec.Size;
            }

            if (lastId != null)
            {
                yield return(new WiiFillerSection(NStream, false, discOffset, NStream.RecoverySize - discOffset, 0, lastDiscOffset == 0xF800000 && lastId == "RELS" ? lastId : null, generateUpdateFiller, generateOtherFiller, forceFillerJunk));
            }
        }