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)); } }
/// <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)); } }