Example #1
0
        public RedumpInfo GetRedumpEntry(Settings settings, DatData dats, uint crc)
        {
            RedumpEntry redump = dats.RedumpData.FirstOrDefault(a => a.Crc == crc);
            RedumpInfo  output = new RedumpInfo();

            output.MatchType = MatchType.MatchFail;

            if (redump == null)
            {
                if ((redump = dats.CustomData.FirstOrDefault(a => a.Crc == crc)) != null)
                {
                    output.MatchType = MatchType.Custom;
                }
            }
            else
            {
                output.MatchType = MatchType.Redump;
            }

            if (redump != null)
            {
                output.MatchName = SourceFiles.RemoveExtension(redump.Name, true);
                output.Checksums = new ChecksumsResult()
                {
                    Crc = crc, Md5 = redump.Md5, Sha1 = redump.Md5
                };
            }

            return(output);
        }
Example #2
0
        internal static void LogNkitInfo(NkitInfo imageInfo, ILog log, string id, bool isDisc)
        {
            string pfx = string.Format("NKit {0} [{1}]", isDisc ? "Disc" : "Prtn", SourceFiles.CleanseFileName(id).PadRight(4));

            log?.LogDetail(string.Format("{0}: In [{1,2:#.0} MiB] ({2} bytes), Out [{3,2:#.0} MiB] (bytes {4})", pfx, imageInfo.BytesReadSize / (double)(1024 * 1024), imageInfo.BytesReadSize.ToString(), imageInfo.BytesWriteSize / (double)(1024 * 1024), imageInfo.BytesWriteSize.ToString()));
            if (imageInfo.BytesGcz != 0)
            {
                log?.LogDetail(string.Format("{0}: GCZ Out [{1,2:#.0} MiB] ({2} bytes)", pfx, imageInfo.BytesGcz / (double)(1024 * 1024), imageInfo.BytesGcz.ToString()));
            }
            if (imageInfo.BytesJunkFiles != 0)
            {
                log?.LogDetail(string.Format("{0}: Junk Files Removed [{1,2:#.0} MiB] ({2} bytes)", pfx, imageInfo.BytesJunkFiles / (double)(1024 * 1024), imageInfo.BytesJunkFiles.ToString()));
            }
            if (imageInfo.BytesHashesData != 0 || imageInfo.BytesHashesPreservation != 0)
            {
                log?.LogDetail(string.Format("{0}: Hashes In [{1,2:#.0} MiB] ({2} bytes), Preserved [{3,2:#.0} MiB] (bytes {4})", pfx, imageInfo.BytesHashesData / (double)(1024 * 1024), imageInfo.BytesHashesData.ToString(), imageInfo.BytesHashesPreservation / (double)(1024 * 1024), imageInfo.BytesHashesPreservation.ToString()));
            }
            if (imageInfo.BytesPreservationData != 0)
            {
                log?.LogDetail(string.Format("{0}: Preservation Data [{1,2:#.0} MiB] {2} bytes", pfx, imageInfo.BytesPreservationData / (double)(1024 * 1024), imageInfo.BytesPreservationData.ToString()));
            }
            if (imageInfo.BytesPreservationDiscPadding != 0)
            {
                log?.LogDetail(string.Format("{0}: Preservation Padding [{1,2:#.0} MiB] {2} bytes", pfx, imageInfo.BytesPreservationDiscPadding / (double)(1024 * 1024), imageInfo.BytesPreservationDiscPadding.ToString()));
            }
            if (imageInfo.FilesTotal != 0 || imageInfo.FilesAligned != 0)
            {
                log?.LogDetail(string.Format("{0}: {1} Total Files, {2} aligning boundary preserved", pfx, imageInfo.FilesTotal.ToString(), imageInfo.FilesAligned.ToString()));
            }
        }
Example #3
0
        private void btnSettingsProcess_Click(object sender, EventArgs e)
        {
            ListViewItem[] items = itemsToProcess().ToArray();

            if (_state == State.New) //if not resuming
            {
                _processFileIndex  = 0;
                _processFilesCount = items.Length;
            }

            setPaths(txtSettingsOutputPathBase.Text);

            _state = State.Processing;
            setScreenState();

            process(cboSettingsMode.SelectedIndex, items,
                    item => //started item
            {
                Invoke((MethodInvoker) delegate
                {
                    if (lvw.SelectedItems.Count == 0 || lvw.SelectedItems[0] == _processingItem)
                    {
                        item.Selected = true;     //move the logging on
                    }

                    _processingItem = item;
                });
            },
                    item => //completed item
            {
                Invoke((MethodInvoker) delegate
                {
                    setLog(((ProcessFile)item.Tag).Log);
                    _processFileIndex++;
                    OutputResults results = ((ProcessFile)item.Tag).Results;
                    if (results != null)
                    {
                        item.SubItems[1].Text = results.DiscType.ToString();
                        item.SubItems[2].Text = results.ValidateReadResult.ToString();
                        item.SubItems[3].Text = results.VerifyOutputResult.ToString();
                        item.SubItems[4].Text = results.OutputCrc.ToString("X8") ?? "";
                        item.SubItems[5].Text = SourceFiles.CleanseFileName(results.OutputId4 ?? "");
                        item.SubItems[6].Text = (results.RedumpInfo?.MatchType.ToString() ?? "") + (results.IsRecoverable ? "Recoverable" : "");
                        item.SubItems[7].Text = (results.OutputSize / (double)(1024 * 1024)).ToString("#.0") + " MiB";
                        item.SubItems[8].Text = results.RedumpInfo?.MatchName ?? "";
                    }
                    else
                    {
                        item.SubItems[1].Text = "Error";
                    }
                });
                return(_state != State.Stopping); //stop
            }).ContinueWith(
                t =>                              //finished processing
            {
                _state = _processFileIndex == _processFilesCount ? State.Complete : State.Stopped;
                setScreenState();
            });
        }
Example #4
0
        private void lvw_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            foreach (SourceFile sf in SourceFiles.Scan(files, false))
            {
                addItem(sf);
            }
            setScreenState();
        }
Example #5
0
 public string CreateOutputFilename(string newExtension)
 {
     if (!this.IsArchive)
     {
         return(SourceFiles.ChangeExtension(this.FilePath, false, newExtension.TrimStart('.')));
     }
     else
     {
         return(SourceFiles.ChangeExtension(System.IO.Path.Combine(System.IO.Path.GetDirectoryName(this.FilePath), this.Name), false, newExtension.TrimStart('.')));
     }
 }
Example #6
0
        private void saveFile(string path, string imageName, ExtractedFile f, Stream s)
        {
            path = Path.Combine(path, f.DiscType.ToString(), imageName + "_" + f.DiscId8);
            if (f.PartitionId != null)
            {
                path = Path.Combine(path, f.PartitionId);
            }
            path = Path.Combine(path, SourceFiles.PathFix(f.Path.TrimStart('/')));
            Directory.CreateDirectory(path);

            using (Stream b = File.OpenWrite(Path.Combine(path, f.Name)))
                s.Copy(b, f.Length);
        }
Example #7
0
 private bool moveToOther(string src, string dst)
 {
     try
     {
         dst = Path.Combine(dst, Path.GetFileName(src));
         File.Move(src, SourceFiles.GetUniqueName(dst));
         return(true);
     }
     catch
     {
         return(false);
     }
 }
Example #8
0
        public string GetFilename(OutputResults results, string mask)
        {
            try
            {
                string fileName  = SourceFiles.CleanseFileName(SourceFiles.RemoveExtension(results.InputFileName, true));
                string titleName = SourceFiles.CleanseFileName(results.OutputTitle) ?? fileName;
                string tgdbName  = SourceFiles.CleanseFileName(GameTdbData.FirstOrDefault(a => a.Item1 == results.OutputId6)?.Item2) ?? titleName;
                string matchName = results.RedumpInfo?.MatchName != null?SourceFiles.CleanseFileName(results.RedumpInfo.MatchName) : (tgdbName ?? fileName);

                Dictionary <string, string> values = new Dictionary <string, string>
                {
                    { "%src", results.InputFileName ?? Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) },
                    { "%nmo", fileName },
                    { "%nmg", tgdbName },
                    { "%nmd", titleName },
                    { "%nmm", matchName },
                    { "%dno", results.OutputDiscNo == 0 ? "" : string.Format("(Disc {0})", results.OutputDiscNo.ToString()) },
                    { "%ver", results.OutputDiscVersion == 0 ? "" : string.Format("(v1.{0})", results.OutputDiscVersion.ToString("D2")) },
                    { "%rev", results.OutputDiscVersion == 0 ? "" : string.Format("(Rev {0})", results.OutputDiscVersion.ToString("D2")) },
                    { "%crc", results.OutputCrc.ToString("X8") },
                    { "%md5", results.OutputMd5 == null ? "" : BitConverter.ToString(results.OutputMd5).Replace("-", "") },
                    { "%sha", results.OutputSha1 == null ? "" : BitConverter.ToString(results.OutputSha1).Replace("-", "") },
                    { "%id4", SourceFiles.CleanseFileName(results.OutputId4).PadRight(4) },
                    { "%id6", SourceFiles.CleanseFileName(results.OutputId6).PadRight(6) },
                    { "%id8", SourceFiles.CleanseFileName(results.OutputId8).PadRight(8) }
                };

                string[] braces = new[] { "%crc", "%md5", "%sha", "%id4", "%id6", "%id8" };

                string fn = mask;
                foreach (KeyValuePair <string, string> v in values)
                {
                    if (fn.Contains(v.Key))
                    {
                        if (string.IsNullOrEmpty(v.Value) || Regex.IsMatch(fn, Regex.Escape(v.Value), RegexOptions.IgnoreCase))
                        {
                            fn = Regex.Replace(fn, string.Format(@"[ ._-]?{0}", v.Key), "", RegexOptions.IgnoreCase);
                        }
                        else
                        {
                            fn = fn.Replace(v.Key, string.Concat(braces.Contains(v.Key) ? "[" : "", v.Value, braces.Contains(v.Key) ? "]" : ""));
                        }
                    }
                }
                return(SourceFiles.GetUniqueName(fn.Replace("%ext", results.OutputFileExt.Trim('.'))));
            }
            catch (Exception ex)
            {
                throw new HandledException(ex, "DatData.GetFilename - Replace masks");
            }
        }
Example #9
0
        public void AddRedumpEntry(string datFullFilename, string filename, long size, uint crc, byte[] sha1, byte[] md5)
        {
            string ne = Path.GetFileName(filename);
            string n  = SourceFiles.RemoveExtension(filename, true);

            if (!File.Exists(datFullFilename))
            {
                string xml = string.Format(@"<?xml version=""1.0"" encoding=""utf-8""?>
<!DOCTYPE datafile PUBLIC ""-//Logiqx//DTD ROM Management Datafile//EN"" ""http://www.logiqx.com/Dats/datafile.dtd""[]>
<datafile>
  <header>
    <name>Nintendo - Non-Redump Audit Dat</name>
    <description>Created by NKit</description>
    <category>Games</category>
    <version>1</version>
    <date>{0}</date>
    <author>You</author>
    <email>-not specified-</email>
    <homepage>-not specified-</homepage>
    <url>-not specified-</url>
    <comment>-not specified-</comment>
    <clrmamepro />
  </header>
</datafile>
", DateTime.Now.ToString("yyyyMMdd"));
                Directory.CreateDirectory(Path.GetDirectoryName(datFullFilename));
                File.WriteAllText(datFullFilename, xml);
            }

            if (File.Exists(datFullFilename))
            {
                XDocument           matchDoc         = XDocument.Load(datFullFilename);
                XmlNamespaceManager namespaceManager = new XmlNamespaceManager(new NameTable());
                namespaceManager.AddNamespace("empty", "http://demo.com/2011/demo-schema");

                XElement machine = new XElement("machine", new XAttribute("name", n));
                matchDoc.Root.Add(machine);
                XElement desc = new XElement("description", n);
                machine.Add(desc);
                XElement rom = new XElement("rom",
                                            new XAttribute("name", ne),
                                            new XAttribute("size", size.ToString()),
                                            new XAttribute("crc", crc.ToString("x8")),
                                            new XAttribute("md5", md5 == null ? "00000000000000000000000000000000" : BitConverter.ToString(md5).Replace("-", "")),
                                            new XAttribute("sha1", md5 == null ? "0000000000000000000000000000000000000000" : BitConverter.ToString(md5).Replace("-", "")));
                machine.Add(rom);
                matchDoc.Save(datFullFilename);
            }
        }
Example #10
0
        public void Write(Context ctx, Stream inStream, Stream outStream, Coordinator pc)
        {
            try
            {
                WiiDiscHeaderSection      hdr   = null;
                WiiPartitionHeaderSection pHdr  = null;
                string        lastPartitionId   = null;
                PartitionType lastPartitionType = PartitionType.Other;
                NCrc          crc                 = new NCrc();
                Crc           updateCrc           = new Crc();
                bool          updateRemoved       = false;
                string        updateTmpFileName   = null;
                string        updateFileName      = null;
                bool          extractingUpdate    = false;
                CryptoStream  updateCrcStream     = null;
                NStream       updateTarget        = null;
                CryptoStream  target              = null;
                MemorySection removedUpdateFiller = null;
                int           preservedHashCount  = 0;

                NkitInfo nkitDiscInfo     = new NkitInfo();
                long     fstFileAlignment = -1;

                WiiPartitionSection lastPart = null;

                long dstPos = 0;

                long   imageSize = pc.OutputSize;                 //for Wii: pHdr.PartitionDataLength
                string ignoreJunkId;
                pc.WriterCheckPoint1WriteReady(out ignoreJunkId); //wait until read has written the header and set the length

                NDisc disc = new NDisc(_log, inStream);

                foreach (IWiiDiscSection s in disc.EnumerateSections(imageSize)) //no fixing, image should be good //ctx.ImageLength
                {
                    if (s is WiiDiscHeaderSection)
                    {
                        hdr = (WiiDiscHeaderSection)s;
                        hdr.Write8(0x60, 1);
                        hdr.Write8(0x61, 1);

                        fstFileAlignment = ctx?.Settings?.PreserveFstFileAlignment?.FirstOrDefault(a => a.Item1 == hdr.Id8)?.Item2 ?? -1;

                        target = new CryptoStream(outStream, crc, CryptoStreamMode.Write);
                        target.Write(hdr.Data, 0, hdr.Data.Length); //write the header
                        nkitDiscInfo.BytesData += hdr.Size;
                        dstPos += hdr.Size;

                        crc.Snapshot("Disc Header");
                    }
                    else if (s is WiiPartitionSection)
                    {
                        WiiPartitionSection ps     = (WiiPartitionSection)s;
                        WiiHashStore        hashes = new WiiHashStore(ps.PartitionDataLength);
                        ScrubManager        scrub  = ps.Header.ScrubManager;

                        NkitInfo nkitPartInfo = new NkitInfo();

                        if (ps.Header.Type == PartitionType.Update && ctx.Settings.NkitUpdatePartitionRemoval && hdr.Partitions.Count() > 1) //only remove update if there's more partitions
                        {
                            updateRemoved    = true;
                            extractingUpdate = true;

                            pHdr             = ps.Header;
                            extractingUpdate = true;
                            updateCrcStream  = new CryptoStream(ByteStream.Zeros, updateCrc, CryptoStreamMode.Write);
                            crc.Initialize();
                            nkitPartInfo.BytesData += disc.WriteRecoveryPartitionData(updateCrcStream, false, ps, 0, out updateTmpFileName, out updateFileName, out updateTarget);
                            _log?.LogDetail(string.Format("Extracted and Removed {0} Recovery Partition: [{1}]", ps.Header.Type.ToString(), SourceFiles.CleanseFileName(ps.Header.Id).PadRight(4)));
                            removedUpdateFiller = new MemorySection(new byte[0x8000]);
                            removedUpdateFiller.Write(0, hdr.Read(0x40000, 0x100)); //backup the original partition table in case it's non standard in some way
                        }
                        else
                        {
                            target.Write(ps.Header.Data, 0, (int)ps.Header.Size);
                            nkitDiscInfo.BytesData += ps.Header.Size;

                            crc.Snapshot(ps.Id + " Hdr");
                            crc.Crcs.Last().PatchData = ps.Header.Data;
                            dstPos          += ps.Header.Size;
                            ps.NewDiscOffset = dstPos;

                            //long written = 0;
                            using (StreamCircularBuffer decrypted = new StreamCircularBuffer(ps.PartitionDataLength, null, null, output =>
                            {
                                //read decrypted partition
                                foreach (WiiPartitionGroupSection pg in ps.Sections)
                                {
                                    nkitPartInfo.BytesHashesData += (pg.Size / 0x8000 * 0x400); //size of input hashes

                                    if (pg.PreserveHashes())
                                    {
                                        nkitPartInfo.BytesHashesPreservation += hashes.Preserve(pg.Offset, pg.Decrypted, pg.Size);
                                        if (++preservedHashCount >= 1500) //too many will bomb the patch caching when converting back. Something is wrong
                                        {
                                            throw pc.SetWriterException(new HandledException("Over 1500 hashes preserved, aborting as image is corrupt or poorly scrubbed."));
                                        }
                                    }
#if !DECRYPT
                                    for (int i = 0; i < pg.Size / 0x8000; i++)
                                    {
                                        output.Write(pg.Decrypted, (i * 0x8000) + 0x400, 0x7c00);
                                    }
#else
                                    output.Write(pg.Decrypted, 0, (int)pg.Size);
#endif
                                }
                            }))
                            {
                                long len = partitionWrite(decrypted, crc, target, ps, ctx, pc, nkitPartInfo, scrub, hashes, fstFileAlignment);
                                ps.NewPartitionDataLength = len;
                                dstPos  += len;
                                lastPart = ps;
                            }
                        }
                        NkitFormat.LogNkitInfo(nkitPartInfo, _log, ps.Id, false);

                        lastPartitionId   = ps.Id;
                        lastPartitionType = ps.Header.Type;
                    }
                    else if (s is WiiFillerSection)
                    {
                        WiiFillerSection fs    = (WiiFillerSection)s;
                        ScrubManager     scrub = new ScrubManager(null);
                        JunkStream       junk  = new JunkStream(lastPartitionType != PartitionType.Data ? hdr.ReadString(0, 4) : lastPartitionId, hdr.Read8(6), lastPartitionType == PartitionType.Update ? 0 : imageSize);

                        if (lastPartitionType == PartitionType.Update && updateRemoved)
                        {
                            //preserve the original partition table and update filename
                            target.Write(removedUpdateFiller.Data, 0, (int)removedUpdateFiller.Size); //remove update partition by adding a 32k placeholder. Avoid having a non update partition at 0x50000
                            nkitDiscInfo.BytesPreservationDiscPadding += removedUpdateFiller.Size;
                            nkitDiscInfo.BytesGaps += fs.Size;
                            dstPos += removedUpdateFiller.Size;

                            crc.Snapshot(string.Format("{0}Replacement Filler", string.IsNullOrEmpty(lastPartitionId) ? "" : (" " + SourceFiles.CleanseFileName(lastPartitionId).PadRight(4))));
                            if (extractingUpdate)
                            {
                                int storeType;
                                if ((storeType = disc.WriteRecoveryPartitionFiller(updateCrcStream, junk, fs.DiscOffset, true, true, fs, updateTarget, updateTmpFileName, ref updateFileName, updateCrc, true)) != 0)
                                {
                                    _log.LogDetail(string.Format("{0}Update recovery partition stored: {1}", storeType == 2 ? "Other " : "", updateFileName));
                                }
                                extractingUpdate = false;
                            }
                        }
                        else
                        {
                            if (fs.Size != 0)
                            {
                                using (StreamCircularBuffer filler = new StreamCircularBuffer(fs.Size, null, null, output =>
                                {
                                    foreach (WiiFillerSectionItem item in ((WiiFillerSection)s).Sections)
                                    {
                                        output.Write(item.Data, 0, (int)item.Size);
                                    }
                                }))
                                {
                                    Gap  gap    = new Gap(fs.Size, false);
                                    long srcPos = fs.DiscOffset;
                                    long gapLen = gap.Encode(filler, ref srcPos, lastPartitionType == PartitionType.Update ? fs.Size : 0x1cL, fs.Size, junk, scrub, target, _log);
                                    nkitDiscInfo.BytesPreservationData += gapLen;
                                    nkitDiscInfo.BytesGaps             += fs.Size;
                                    dstPos += gapLen;
                                    if (lastPart != null)
                                    {
                                        lastPart.NewPartitionDataLength += gapLen;
                                    }
                                }
                            }
                            //pad partition to 32k
                            int gapLen2 = (int)(dstPos % 0x8000 == 0 ? 0 : 0x8000 - (dstPos % 0x8000));
                            ByteStream.Zeros.Copy(target, gapLen2);
                            nkitDiscInfo.BytesPreservationDiscPadding += gapLen2;
                            dstPos += gapLen2;
                            if (lastPart != null)
                            {
                                lastPart.NewPartitionDataLength += gapLen2;
                            }

                            if (lastPart != null)
                            {
                                lastPart.Header.WriteUInt32B(0x2bc, (uint)(lastPart.NewPartitionDataLength / 4)); //updates the array in the crc data
                                hdr.Partitions.First(a => a.DiscOffset == lastPart.DiscOffset).DiscOffset = (lastPart.NewDiscOffset - 0x20000);
                            }
                            crc.Snapshot(string.Format("{0}{1}Files+Filler", lastPartitionId ?? "", string.IsNullOrEmpty(lastPartitionId) ? "" : " "));
                        }
                    }
                }

                NkitFormat.LogNkitInfo(nkitDiscInfo, _log, hdr.Id, true);

                foreach (CrcItem ci in crc.Crcs.Where(a => a.PatchData != null))
                {
                    ci.PatchCrc = Crc.Compute(ci.PatchData);
                }

                NCrc readerCrcs;
                uint validationCrc;
                pc.WriterCheckPoint2Complete(out readerCrcs, out validationCrc, hdr.Data, dstPos); //wait until reader has completed and get crc patches.

                if (updateRemoved && crc.Crcs.Length > 2)                                          //freeloader wii only has update partition
                {
                    hdr.RemoveUpdatePartition(crc.Crcs[2].Offset);
                }

                hdr.UpdateOffsets();
                hdr.WriteString(0x200, 8, "NKIT v01"); //header and version
                hdr.Write8(0x60, 1);
                hdr.Write8(0x61, 1);
                hdr.WriteUInt32B(0x208, readerCrcs.FullCrc(true)); //original crc
                hdr.WriteUInt32B(0x210, (uint)(imageSize / 4L));   //ctx.ImageLength
                hdr.WriteUInt32B(0x218, updateCrc.Value);          //Update crc - Only if removed
                crc.Crcs[0].PatchCrc  = Crc.Compute(hdr.Data);
                crc.Crcs[0].PatchData = hdr.Data;
                hdr.WriteUInt32B(0x20C, CrcForce.Calculate(crc.FullCrc(true), dstPos, readerCrcs.FullCrc(true), 0x20C, 0)); //magic to force crc
                crc.Crcs[0].PatchCrc = Crc.Compute(hdr.Data);                                                               //update with magic applied

                pc.WriterCheckPoint3ApplyPatches(crc, false, crc.FullCrc(true), crc.FullCrc(true), this.VerifyIsWrite, "NKit Written");
            }
            catch (Exception ex)
            {
                throw pc.SetWriterException(ex, "NkitWriterWii.Write - Convert");
            }
        }
Example #11
0
        public virtual OutputResults Process(Context ctx, NStream input, Stream output)
        {
            OutputResults results = new OutputResults()
            {
                Conversion = ctx.ConversionName, VerifyOutputResult = VerifyResult.Unverified, ValidateReadResult = VerifyResult.Unverified
            };

            try
            {
                StreamCircularBuffer fs = null;

                _timer = new Timer
                {
                    Interval = 250
                };
                _timer.Elapsed += (s, e) =>
                {
                    if (_timerRunning)
                    {
                        return; //keep processing
                    }

                    try
                    {
                        _timerRunning = true;
                        _log.ProcessingProgress(((IProgress)fs)?.Value ?? 0);
                    }
                    catch { }
                    finally
                    {
                        _timerRunning = false;
                    }
                };
                _timer.Enabled = true;

                long size;
                switch (_sizeMode)
                {
                case ProcessorSizeMode.Source:
                    size = input.SourceSize;
                    break;

                case ProcessorSizeMode.Stream:
                    size = input.Length;
                    break;

                case ProcessorSizeMode.Image:
                    size = input.ImageSize;
                    break;

                case ProcessorSizeMode.Recover:
                default:
                    size = input.RecoverySize;
                    break;
                }

                Coordinator pc = new Coordinator(ctx.ValidationCrc, Reader, Writer, size);

                pc.Started += (s, e) =>
                {
                    _timer.Enabled      = true;
                    results.AliasJunkId = e.AliasJunkId;
                };
                pc.Completed += (s, e) =>
                {
                    _timer.Enabled = false;
                    if (Writer is HashWriter)
                    {
                        results.OutputMd5  = e.Md5;
                        results.OutputSha1 = e.Sha1;
                    }
                    else
                    {
                        MemorySection hdr = new MemorySection(e.Header ?? input.DiscHeader.Data);
                        results.OutputTitle       = hdr.ReadStringToNull(0x20, 0x60);
                        results.OutputDiscNo      = hdr.Read8(6);
                        results.OutputDiscVersion = hdr.Read8(7);
                        results.OutputId8         = string.Concat(hdr.ReadString(0, 6), results.OutputDiscNo.ToString("X2"), results.OutputDiscVersion.ToString("X2"));
                        results.ProcessorMessage  = e.ResultMessage;
                        results.OutputCrc         = e.PatchedCrc;
                        results.IsRecoverable     = e.IsRecoverable;
                        if (e.ValidationCrc != 0)
                        {
                            results.ValidationCrc      = e.ValidationCrc;
                            results.ValidateReadResult = e.ValidationCrc == e.PatchedCrc ? VerifyResult.VerifySuccess : VerifyResult.VerifyFailed;
                        }

                        if (!(Writer is VerifyWriter))
                        {
                            results.OutputSize = e.OutputSize; //never store the verify size
                        }
                        else
                        {
                            results.VerifyCrc = e.VerifyCrc;
                            if (e.VerifyIsWrite) //e.ValidationCrc can be set from a previous process run
                            {
                                results.VerifyOutputResult = results.ValidationCrc == results.VerifyCrc ? VerifyResult.VerifySuccess : VerifyResult.VerifyFailed;
                            }
                        }
                    }

                    bool l9 = pc.Patches.Crcs.Any(a => a.Offset > 0xFFFFFFFFL || a.Length > 0xFFFFFFFFL);
                    if (pc.ReaderCrcs != null)
                    {
                        foreach (CrcItem c in pc.ReaderCrcs.Crcs)
                        {
                            _log.LogDebug(string.Format("R-CRC {0}  Before:{1}  After:{2}  L:{3} {4}", c.Offset.ToString(l9 ? "X9" : "X8"), c.Value.ToString("X8"), c.PatchCrc == 0 ? "        " : c.PatchCrc.ToString("X8"), c.Length.ToString(l9 ? "X9" : "X8"), SourceFiles.CleanseFileName(c.Name)));
                        }

                        _log.LogDebug(string.Format("ReadCRC {0}Before:{1} After:{2}", l9 ? " " : "", pc.ReaderCrcs.FullCrc(false).ToString("X8"), pc.ReaderCrcs.FullCrc(true).ToString("X8")));
                    }
                    if (pc.WriterCrcs != null)
                    {
                        foreach (CrcItem c in pc.WriterCrcs.Crcs)
                        {
                            _log.LogDebug(string.Format("W-CRC {0}  Before:{1}  After:{2}  L:{3} {4}", c.Offset.ToString(l9 ? "X9" : "X8"), c.Value.ToString("X8"), c.PatchCrc == 0 ? "        " : c.PatchCrc.ToString("X8"), c.Length.ToString(l9 ? "X9" : "X8"), SourceFiles.CleanseFileName(c.Name)));
                        }

                        _log.LogDebug(string.Format("WriteCRC {0}Before:{1} After:{2}", l9 ? " " : "", pc.WriterCrcs.FullCrc(false).ToString("X8"), pc.WriterCrcs.FullCrc(true).ToString("X8")));
                    }
                    _log.ProcessingComplete(results.OutputSize, results.ProcessorMessage, true);
                };

                try
                {
                    _log.ProcessingStart(input.SourceSize, Title);

                    using (fs = new StreamCircularBuffer(size, input, null, s => Reader.Read(ctx, input, s, pc))) //read in stream and write to circular buffer
                    {
                        Writer.Write(ctx, fs, output, pc);
                    }
                }
                catch
                {
                    if (pc.Exception != null)
                    {
                        throw pc.Exception;
                    }

                    if (fs.WriterException != null)
                    {
                        throw fs.WriterException;
                    }

                    throw; //writer exception
                }

                foreach (CrcItem crc in pc.Patches.Crcs.Where(a => a.PatchData != null || a.PatchFile != null))
                {
                    output.Seek(crc.Offset, SeekOrigin.Begin);
                    if (crc.PatchFile == null)
                    {
                        output.Write(crc.PatchData, 0, (int)Math.Min(crc.Length, crc.PatchData.Length)); //PatchData might be larger
                    }
                    else
                    {
                        using (FileStream pf = File.OpenRead(crc.PatchFile))
                        {
                            pf.Copy(output, pf.Length);
                            ByteStream.Zeros.Copy(output, crc.Length - pf.Length);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (_timer != null)
                {
                    _timer.Enabled = false;
                }

                try
                {
                    _log.ProcessingComplete(results.OutputSize, results.ProcessorMessage, false); // force any log lines to be output - handy for diagnosis
                }
                catch { }
                throw new HandledException(ex, "Failed processing {0} -> {1}", Reader?.GetType()?.Name ?? "<null>", Writer?.GetType()?.Name ?? "<null>");
            }
            finally
            {
                if (_timer != null)
                {
                    _timer.Enabled = false;
                    _timer         = null;
                }
            }

            return(results);
        }
Example #12
0
        private OutputResults process(string conversion, SourceFile sourceFile, bool renameWithMasks, bool toNkit, NkitFormatType nkitFormat, bool isRecovery, bool fullVerify, bool calcHashes, bool testMode, Func <NStream, IEnumerable <Processor> > passes)
        {
            OutputResults results = null;
            NStream       nstream = _nstream;
            string        lastTmp = null;
            string        tmp     = null;

            this.ConvertionName = conversion;

            try
            {
                SourceFile sf         = null;
                long       sourceSize = nstream.SourceSize;

                _context = new Context();
                _context.Initialise(this.ConvertionName, sourceFile, _settings, true, isRecovery, nstream.IsGameCube, nstream.Id8, this);

                List <Processor> processors = passes(nstream).Where(a => a != null).ToList();
                if (nkitFormat == NkitFormatType.Gcz)
                {
                    processors.Add(new Processor(new IsoReader(), new GczWriter(), "To GCZ", this, false, true, ProcessorSizeMode.Stream));
                }
                if (calcHashes)
                {
                    processors.Add(new Processor(new IsoReader(), new HashWriter(), "Calc Hashes", this, false, true, ProcessorSizeMode.Stream));
                }
                if (fullVerify)
                {
                    if (!toNkit)
                    {
                        processors.Add(new Processor(new IsoReader(), new VerifyWriter(), "Full Verify", this, false, true, ProcessorSizeMode.Stream));
                    }
                    else
                    {
                        processors.Add(new Processor(nstream.IsGameCube ? new NkitReaderGc() : (IReader) new NkitReaderWii(), new VerifyWriter(), "NKit Verify", this, true, true, ProcessorSizeMode.Image));
                    }
                    processors.Last().Writer.RequireVerifyCrc = true;
                    processors.Last().Writer.VerifyIsWrite = true; //read verify
                }
                _totalPasses = processors.Count();

                if (processors.Count == 0)
                {
                    return(null);
                }

                DateTime dt = DateTime.Now;
                _completedPasses = 0;

                Log("PROCESSING" + (testMode ? " [TEST MODE]" : ((_context.Settings.DeleteSource ? " [DELETE SOURCE]" : ""))));
                Log("-------------------------------------------------------------------------------");
                if (_forcedWiiFullNkitRebuild)
                {
                    LogBlank();
                    Log(string.Format("Nkit Reencode forced: NkitUpdatePartitionRemoval is {0} and source image has {1} Update Partition", _context.Settings.NkitUpdatePartitionRemoval.ToString(), nstream.IsNkitUpdateRemoved ? "no" : "an"));
                    LogBlank();
                }
                Log(string.Format("{0} [{1}]  {2}  [MiB:{3,2:#.0}]", friendly(nstream.Title), friendly(nstream.Id), nstream.IsGameCube ? "GameCube" : "Wii", (sourceSize / (double)(1024 * 1024))));
                LogBlank();
                string passesText = getPassesLine(nstream, processors);
                Log(passesText);

                int i = 1;
                foreach (Processor pro in processors.Where(pro => pro != null))
                {
                    LogDebug(string.Format("Pass {0}: {1}", (i++).ToString(), pro.ToString()));
                }
                LogBlank();

                foreach (Processor pro in processors)
                {
                    //sort out temp file and open input as nstream each time
                    //raise progress and output messages from processors

                    if (sf != null)
                    {
                        nstream = sf.OpenNStream(!(pro.Writer is HashWriter)); //if hashWriter then read as raw file
                        sf      = null;
                    }

                    tmp = null;
                    FileStream tmpFs = null;

                    try
                    {
                        if (pro.HasWriteStream)
                        {
                            tmp = Path.Combine(_context.Settings.TempPath, Path.GetFileName(Path.GetTempFileName()));
                            if (!Directory.Exists(_context.Settings.TempPath))
                            {
                                Directory.CreateDirectory(_context.Settings.TempPath);
                            }
                            tmpFs = File.Create(tmp, 0x400 * 0x400 * 4, FileOptions.SequentialScan);
                        }

                        _logCache = new List <Tuple <string, LogMessageType> >();
                        OutputResults nr = pro.Process(_context, nstream, tmpFs ?? Stream.Null);
                        _logCache = null;

                        if (results == null)
                        {
                            results                  = nr;
                            results.DiscType         = nstream.IsGameCube ? DiscType.GameCube : DiscType.Wii;
                            results.InputFileName    = sourceFile.AllFiles.Length != 0 ? sourceFile.AllFiles[0] : sourceFile.FilePath;
                            results.InputDiscNo      = nstream.DiscNo;
                            results.InputDiscVersion = nstream.Version;
                            results.InputTitle       = nstream.Title;
                            results.InputId8         = nstream.Id8;
                            results.InputSize        = sourceSize;
                            results.FullSize         = nstream.ImageSize;
                            results.Passes           = passesText;
                            if (pro.IsVerify)
                            {
                                results.OutputSize = results.InputSize;
                            }
                        }
                        else if (pro.Writer is HashWriter) //hash writer gives no meaningful info back other than md5 and sha1 (the crc is forced when nkit, so ignore)
                        {
                            results.OutputMd5  = nr.OutputMd5;
                            results.OutputSha1 = nr.OutputSha1;
                        }
                        else
                        {
                            if (nr.AliasJunkId != null)
                            {
                                results.AliasJunkId = nr.AliasJunkId;
                            }
                            if (nr.OutputTitle != null)
                            {
                                results.OutputDiscNo      = nr.OutputDiscNo;
                                results.OutputDiscVersion = nr.OutputDiscVersion;
                                results.OutputTitle       = nr.OutputTitle;
                            }
                            results.OutputId8         = nr.OutputId8;
                            results.OutputCrc         = nr.OutputCrc;
                            results.OutputPrePatchCrc = nr.OutputPrePatchCrc;
                            results.FullSize          = nstream.ImageSize;
                            if (tmp != null)
                            {
                                results.OutputSize = nr.OutputSize;
                            }

                            if (nr.ValidationCrc != 0 && results.VerifyCrc != 0)
                            {
                                results.VerifyCrc = 0; //blank verify if a new ValidationCrc is set - verification happened when both != 0
                            }
                            if (nr.VerifyCrc != 0)
                            {
                                results.VerifyCrc = nr.VerifyCrc;
                            }
                            if (nr.ValidationCrc != 0)
                            {
                                results.ValidationCrc = nr.ValidationCrc;
                            }
                            if (nr.ValidateReadResult != VerifyResult.Unverified)
                            {
                                results.ValidateReadResult = nr.ValidateReadResult;
                            }
                            if (nr.VerifyOutputResult != VerifyResult.Unverified)
                            {
                                if (results.ValidateReadResult == VerifyResult.Unverified && nstream.IsNkit)
                                {
                                    results.ValidateReadResult = nr.VerifyOutputResult;
                                }
                                results.VerifyOutputResult = nr.VerifyOutputResult;
                            }
                            if (nr.IsRecoverable)
                            {
                                results.IsRecoverable = nr.IsRecoverable;
                            }
                        }
                    }
                    finally
                    {
                        if (tmpFs != null)
                        {
                            tmpFs.Dispose();
                        }

                        nstream.Close();
                    }

                    if (lastTmp != null && tmp != null)
                    {
                        File.Delete(lastTmp);
                    }

                    //handle failures well
                    if (results.ValidateReadResult == VerifyResult.VerifyFailed || results.VerifyOutputResult == VerifyResult.VerifyFailed)
                    {
                        lastTmp = tmp; //keep post loop happy
                        break;
                    }

                    if (_completedPasses != _totalPasses) //last item
                    {
                        sf = SourceFiles.OpenFile(tmp ?? lastTmp);
                    }

                    if (tmp != null)
                    {
                        lastTmp = tmp;
                    }
                }

                TimeSpan ts = DateTime.Now - dt;
                results.ProcessingTime = ts;

                //FAIL
                if (results.ValidateReadResult == VerifyResult.VerifyFailed || results.VerifyOutputResult == VerifyResult.VerifyFailed)
                {
                    LogBlank();
                    Log(string.Format("Verification Failed Crc:{0} - Failed Test Crc:{1}", results.OutputCrc.ToString("X8"), results.ValidationCrc.ToString("X8")));

                    if (lastTmp != null) //only null when verify only
                    {
                        Log("Deleting Output" + (Settings.OutputLevel != 3 ? "" : " (Skipped as OutputLevel is 3:Debug)"));
                        results.OutputFileName = null;
                        if (Settings.OutputLevel != 3)
                        {
                            File.Delete(lastTmp);
                        }

                        LogBlank();
                    }
                }
                else //SUCCESS
                {
                    LogBlank();
                    Log(string.Format("Completed ~ {0}m {1}s  [MiB:{2:#.0}]", ((int)ts.TotalMinutes).ToString(), ts.Seconds.ToString(), (results.OutputSize / (double)(1024 * 1024))));
                    LogBlank();
                    Log("RESULTS");
                    Log("-------------------------------------------------------------------------------");

                    uint   finalCrc = results.ValidationCrc != 0 ? results.ValidationCrc : results.OutputCrc;
                    string mask     = _context.Settings.MatchFailRenameToMask;
                    results.OutputFileExt = "." + SourceFiles.ExtensionString(false, false, toNkit, nkitFormat == NkitFormatType.Gcz).ToLower();
                    results.RedumpInfo    = _context.Dats.GetRedumpEntry(_context.Settings, _context.Dats, finalCrc);
                    if (results.RedumpInfo.MatchType == MatchType.Redump || results.RedumpInfo.MatchType == MatchType.Custom)
                    {
                        Log(string.Format("{0} [{1} Name]", results.RedumpInfo.MatchName, results.RedumpInfo.MatchType.ToString()));
                        if (results.IsRecoverable)
                        {
                            Log(string.Format("Missing Recovery data is required to correctly restore this image!", results.RedumpInfo.MatchName, results.RedumpInfo.MatchType.ToString()));
                        }
                        mask = results.RedumpInfo.MatchType == MatchType.Custom ? _context.Settings.CustomMatchRenameToMask : _context.Settings.RedumpMatchRenameToMask;
                    }
                    else
                    {
                        Log(string.Format("CRC {0} not in Redump or Custom Dat", finalCrc.ToString("X8")));
                    }
                    LogBlank();


                    outputResults(results);


                    if (lastTmp != null) //only null when verify only
                    {
                        if (testMode)
                        {
                            Log("TestMode: Deleting Output");
                            results.OutputFileName = null;
                            if (File.Exists(lastTmp))
                            {
                                File.Delete(lastTmp);
                            }
                        }
                        else if (isRecovery && _context.Settings.RecoveryMatchFailDelete && results.RedumpInfo.MatchType == MatchType.MatchFail)
                        {
                            Log("Failed to Recover to Dat Entry: Deleting Output");
                            results.OutputFileName = null;
                            File.Delete(lastTmp);
                        }
                        else
                        {
                            if (renameWithMasks)
                            {
                                results.OutputFileName = _context.Dats.GetFilename(results, mask);
                                Log("Renaming Output Using Masks");
                            }
                            else
                            {
                                results.OutputFileName = SourceFiles.GetUniqueName(sourceFile.CreateOutputFilename(results.OutputFileExt));
                                Log("Renaming Output Based on Source File" + (sourceFile.AllFiles.Count() > 1 ? "s" : ""));
                            }
                            LogBlank();

                            string path = Path.GetDirectoryName(results.OutputFileName);
                            if (!Directory.Exists(path))
                            {
                                Directory.CreateDirectory(path);
                            }

                            File.Move(lastTmp, results.OutputFileName);

                            Log(string.Format("Output: {0}", Path.GetDirectoryName(results.OutputFileName)));
                            Log(string.Format("    {0}", Path.GetFileName(results.OutputFileName)));

                            //double check test mode just to be sure
                            if (_context.Settings.DeleteSource && !testMode && results.VerifyOutputResult == VerifyResult.VerifySuccess)
                            {
                                LogBlank();
                                Log("Deleting Source:");
                                foreach (string s in sourceFile.AllFiles.Length == 0 ? new string[] { sourceFile.FilePath } : sourceFile.AllFiles)
                                {
                                    Log(string.Format("    {0}", s));
                                    File.Delete(s);
                                }
                            }
                        }
                        LogBlank();
                    }
                }
            }
            catch (Exception ex)
            {
                try
                {
                    if (lastTmp == null)
                    {
                        lastTmp = tmp;
                    }
                    if (lastTmp != null)
                    {
                        LogBlank();
                        Log("Deleting Output" + (Settings.OutputLevel != 3 ? "" : " (Skipped as OutputLevel is 3:Debug)"));
                        if (results != null)
                        {
                            results.OutputFileName = null;
                        }
                        if (Settings.OutputLevel != 3)
                        {
                            File.Delete(lastTmp);
                        }
                    }
                }
                catch { }

                if (_context.Settings.EnableSummaryLog)
                {
                    if (results == null)
                    {
                        results                  = new OutputResults();
                        results.Conversion       = this.ConvertionName;
                        results.DiscType         = (nstream?.IsGameCube ?? true) ? DiscType.GameCube : DiscType.Wii;
                        results.InputFileName    = (sourceFile?.AllFiles?.Length ?? 0) == 0 ? (sourceFile?.FilePath ?? "") : (sourceFile?.AllFiles.FirstOrDefault() ?? "");
                        results.InputDiscNo      = nstream?.DiscNo ?? 0;
                        results.InputDiscVersion = nstream?.Version ?? 0;
                        results.InputTitle       = nstream?.Title ?? "";
                        results.InputId8         = nstream?.Id8 ?? "";
                        results.InputSize        = sourceFile?.Length ?? 0;
                    }
                    results.VerifyOutputResult = VerifyResult.Error;
                    HandledException hex = ex as HandledException;
                    if (hex == null)
                    {
                        hex = new HandledException(ex, "Unhandled Exception");
                    }
                    results.ErrorMessage = hex.FriendlyErrorMessage;
                }
                throw;
            }
            finally
            {
                if (_context.Settings.EnableSummaryLog)
                {
                    summaryLog(_context.Settings, results);
                    Log("Summary Log Written" + (results.VerifyOutputResult != VerifyResult.Error ? "" : " as Errored!"));
                    LogBlank();
                }
            }

            return(results);
        }
Example #13
0
        internal long WriteRecoveryPartitionData(Stream crcStream, bool unscrub, WiiPartitionSection ps, int channelNo, out string tempFileName, out string fileName, out NStream output)
        {
            if (ps.Header.Type == PartitionType.Update)
            {
                fileName = string.Format("{0}_{1}_", BitConverter.ToString(ps.Header.ContentSha1).Replace("-", ""), ps.Header.IsKorean ? "K" : "N");
            }
            else
            {
                fileName = string.Format("{0}_{1}_{2}_{3}_", this.NStream.Id8, channelNo.ToString().PadLeft(2, '0'), SourceFiles.CleanseFileName(ps.Header.Id).PadRight(4), ps.Header.IsKorean ? "K" : "N");
            }
            tempFileName = Path.Combine(Settings.OtherRecoveryFilesPath, fileName + "TEMP");

            Directory.CreateDirectory(Settings.OtherRecoveryFilesPath);
            output = new NStream(File.Create(tempFileName));
            output.Write(ps.Header.Data, 0, (int)ps.Header.Size);
            crcStream.Write(ps.Header.Data, 0, (int)ps.Header.Size);
            long read = ps.Header.Size;

            foreach (WiiPartitionGroupSection pg in ps.Sections)
            {
                if (unscrub)
                {
                    pg.Unscrub(null);
                }
                output.Write(pg.Encrypted, 0, (int)pg.Size);
                crcStream.Write(pg.Encrypted, 0, (int)pg.Size);
                read = ps.Size;
            }
            return(read);
        }
Example #14
0
        /// <summary>
        /// Extracts files from partitions, this is not random access. The iso is read in it's entirety
        /// </summary>
        public ExtractResult ExtractRecoveryFilesWii()
        {
            List <ExtractRecoveryResult> result    = new List <ExtractRecoveryResult>();
            List <WiiPartitionInfo>      toExtract = new List <WiiPartitionInfo>();
            WiiDiscHeaderSection         hdr       = null;
            WiiPartitionHeaderSection    pHdr      = null;
            NStream       target            = null;
            bool          extracting        = false;
            int           channel           = 1;
            string        lastPartitionId   = null;
            PartitionType lastPartitionType = PartitionType.Other;

            string fileName    = null;
            string tmpFileName = null;
            int    extracted   = 0;
            Crc    crc         = new Crc();
            Stream crcStream   = null;
            long   imageSize   = this.NStream.RecoverySize; //for Wii: pHdr.PartitionDataLength


            bool isIso = false; //force to always scrub //Path.GetExtension(_name).ToLower() == ".iso";

            foreach (IWiiDiscSection s in this.EnumerateSectionsFix(false, true, false))
            {
                if (s is WiiDiscHeaderSection)
                {
                    hdr = (WiiDiscHeaderSection)s;

                    Log?.Log(string.Format("Processing: {0}", SourceFileName));

                    toExtract = hdr.Partitions.Where(a => a.Type != PartitionType.Data && a.Type != PartitionType.GameData).ToList();
                    if (toExtract.Count() == 0)
                    {
                        Log?.Log(string.Format("    Skipped: No Recovery Partitions to extract - {0}", SourceFileName));
                        break;
                    }
                }
                else if (s is WiiPartitionSection)
                {
                    WiiPartitionSection ps = (WiiPartitionSection)s;

                    if (!toExtract.Any(a => a.DiscOffset == ps.DiscOffset))
                    {
                        Log?.Log(string.Format("    Skipping {0} Partition: [{1}]...", ps.Header.Type.ToString(), SourceFiles.CleanseFileName(ps.Header.Id).PadRight(4)));
                        continue;
                    }
                    extracting = true;

                    pHdr       = ps.Header;
                    extracting = true;
                    Log?.Log(string.Format("    {0} of {1} - Extracting {2} Recovery Partition: [{3}]", (extracted + 1).ToString(), toExtract.Count().ToString(), ps.Header.Type.ToString(), SourceFiles.CleanseFileName(ps.Header.Id).PadRight(4)));

                    crcStream = new CryptoStream(ByteStream.Zeros, crc, CryptoStreamMode.Write);
                    crc.Initialize();

                    WriteRecoveryPartitionData(crcStream, isIso, ps, channel, out tmpFileName, out fileName, out target);
                    lastPartitionId   = ps.Id;
                    lastPartitionType = ps.Header.Type;
                }
                else if (s is WiiFillerSection)
                {
                    JunkStream       junk = new JunkStream(lastPartitionType != PartitionType.Data ? hdr.ReadString(0, 4) : lastPartitionId, hdr.Read8(6), lastPartitionType == PartitionType.Update ? 0 : imageSize);
                    WiiFillerSection fs   = (WiiFillerSection)s;
                    if (extracting)
                    {
                        int storeType;
                        if ((storeType = WriteRecoveryPartitionFiller(crcStream, junk, fs.DiscOffset, pHdr.Type == PartitionType.Update, false, fs, target, tmpFileName, ref fileName, crc, false)) != 0)
                        {
                            result.Add(new ExtractRecoveryResult()
                            {
                                FileName = fileName, Extracted = true, Type = PartitionType.Other, IsNew = storeType == 2, IsGameCube = false
                            });
                        }

                        if (pHdr.Type != PartitionType.Update)
                        {
                            channel++;
                        }
                        extracted++;
                        extracting = false;
                        bool complete = (extracted == toExtract.Count());
                        if (complete)
                        {
                            break;
                        }
                    }
                }
            }
            return(createExtractResult((Region)hdr.ReadUInt32B(0x4e000), result.ToArray()));
        }
Example #15
0
 private static string pathFix(string path)
 {
     return(SourceFiles.PathFix(path));
 }
Example #16
0
 public string ExtensionString()
 {
     return(SourceFiles.ExtensionString(_isIsoDec, _isWbfs, _isNkit, _isGcz));
 }