示例#1
0
文件: Coordinator.cs 项目: skudi/NKit
 public HandledException SetReaderException(HandledException ex)
 {
     lock (_stateLock)
     {
         if (_readerException == null)
         {
             _readerException = ex;
         }
         _state = stateEnum.Error;
     }
     return(_readerException);
 }
示例#2
0
 public HandledException SetWriterException(HandledException ex)
 {
     lock (_stateLock)
     {
         if (_writerException == null)
         {
             _writerFirst     = _readerException == null;
             _writerException = ex;
         }
         _state = stateEnum.Error;
     }
     return(_writerException);
 }
示例#3
0
 internal Coordinator(uint validationCrc, IValidation reader, IValidation writer, long processSize)
 {
     _processSize         = processSize;
     _crcs                = null;
     _validationCrc       = validationCrc;
     _state               = stateEnum.Unset;
     _stateLock           = new object();
     _readerVerifyCrc     = reader.RequireVerifyCrc;
     _readerValidationCrc = reader.RequireValidationCrc;
     _writerVerifyCrc     = writer.RequireVerifyCrc;
     _writerValidationCrc = writer.RequireValidationCrc;
     _readerException     = null;
     _writerException     = null;
     _writerFirst         = false;
 }
示例#4
0
        private Task process(int convertMode, ListViewItem[] items, Action <ListViewItem> startItem, Func <ListViewItem, bool> completedItem)
        {
            //get the settings on the main thread to be used on another thread
            var guiSettings = new
            {
                SummaryLog                 = txtSettingsSummaryLog.Text,
                TempPath                   = txtSettingsTempPath.Text,
                CalculateHashes            = chkSettingsCalculateHashes.Checked,
                DeleteSource               = chkSettingsDeleteSource.Checked,
                EnableSummaryLog           = chkSettingsSummaryLog.Checked,
                FullVerify                 = chkSettingsFullVerify.Checked,
                NkitReencode               = chkSettingsReencodeNkit.Checked,
                NkitUpdatePartitionRemoval = chkSettingsRemoveUpdate.Checked,
                TestMode                   = chkSettingsTestMode.Checked,
                MaskRename                 = chkSettingsUseMasks.Checked,
                RecoveryMatchFailDelete    = chkSettingsRecoveryMatchFailDelete.Checked,
                Masks = _masks
            };

            return(Task.Run(() =>
            {
                foreach (ListViewItem item in items)
                {
                    bool exitLoop = false;
                    Converter nkitConvert = null;
                    ProcessFile pf = (ProcessFile)item.Tag;
                    try
                    {
                        SourceFile src = pf.SourceFile;
                        nkitConvert = new Converter(src, false);
                        startItem(item);
                        nkitConvert.Settings.SummaryLog = guiSettings.SummaryLog;
                        nkitConvert.Settings.TempPath = guiSettings.TempPath;
                        nkitConvert.Settings.CalculateHashes = guiSettings.CalculateHashes;
                        nkitConvert.Settings.DeleteSource = guiSettings.DeleteSource;
                        nkitConvert.Settings.EnableSummaryLog = guiSettings.EnableSummaryLog;
                        nkitConvert.Settings.FullVerify = guiSettings.FullVerify;
                        nkitConvert.Settings.NkitReencode = guiSettings.NkitReencode;
                        nkitConvert.Settings.NkitUpdatePartitionRemoval = guiSettings.NkitUpdatePartitionRemoval;
                        nkitConvert.Settings.TestMode = guiSettings.TestMode;
                        nkitConvert.Settings.MaskRename = guiSettings.MaskRename;
                        nkitConvert.Settings.RecoveryMatchFailDelete = guiSettings.RecoveryMatchFailDelete;

                        if (nkitConvert.Settings.DiscType == DiscType.GameCube)
                        {
                            nkitConvert.Settings.RedumpMatchRenameToMask = guiSettings.Masks["GameCube:RedumpMatchRenameToMask"];
                            nkitConvert.Settings.CustomMatchRenameToMask = guiSettings.Masks["GameCube:CustomMatchRenameToMask"];
                            nkitConvert.Settings.MatchFailRenameToMask = guiSettings.Masks["GameCube:MatchFailRenameToMask"];
                        }
                        else
                        {
                            nkitConvert.Settings.RedumpMatchRenameToMask = guiSettings.Masks["Wii:RedumpMatchRenameToMask"];
                            nkitConvert.Settings.CustomMatchRenameToMask = guiSettings.Masks["Wii:CustomMatchRenameToMask"];
                            nkitConvert.Settings.MatchFailRenameToMask = guiSettings.Masks["Wii:MatchFailRenameToMask"];
                        }

                        nkitConvert.LogMessage += NkitConvert_LogMessage;
                        nkitConvert.LogProgress += NkitConvert_LogProgress;
                        pf.Log = "";

                        switch (convertMode)
                        {
                        case 1:     //Recover to ISO
                            pf.Results = nkitConvert.RecoverToIso();
                            break;

                        case 2:     //Recover to Nkit.iso
                            nkitConvert.Settings.NkitFormat = NkitFormatType.Iso;
                            pf.Results = nkitConvert.RecoverToNkit();
                            break;

                        case 3:     //Recover to Nkit.gcz
                            nkitConvert.Settings.NkitFormat = NkitFormatType.Gcz;
                            pf.Results = nkitConvert.RecoverToNkit();
                            break;

                        case 4:     //Convert to .iso
                            pf.Results = nkitConvert.ConvertToIso();
                            break;

                        case 5:     //Convert to Nkit.iso
                            nkitConvert.Settings.NkitFormat = NkitFormatType.Iso;
                            pf.Results = nkitConvert.ConvertToNkit();
                            break;

                        case 6:     //Convert to Nkit.gcz
                            nkitConvert.Settings.NkitFormat = NkitFormatType.Gcz;
                            pf.Results = nkitConvert.ConvertToNkit();
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        try
                        {
                            HandledException hex = ex as HandledException;
                            if (hex == null && ex is AggregateException)
                            {
                                hex = (HandledException)((AggregateException)ex).InnerExceptions.FirstOrDefault(a => a is HandledException);
                            }

                            pf.Log += string.Format("Failed{0}-------{0}{1}", Environment.NewLine, hex != null ? hex.FriendlyErrorMessage : ex.Message);
                        }
                        catch { }
                    }
                    finally
                    {
                        exitLoop = !completedItem(item);
                        if (nkitConvert != null)
                        {
                            nkitConvert.LogMessage -= NkitConvert_LogMessage;
                            nkitConvert.LogProgress -= NkitConvert_LogProgress;
                        }
                    }
                    if (exitLoop)
                    {
                        break;
                    }
                }
            }));
        }
示例#5
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);
        }