Example #1
0
        private static void DeepScanFile(string directory, RvFile tFile)
        {
            string filename  = Path.Combine(directory, tFile.Name);
            int    errorCode = UnCompFiles.CheckSumRead(filename, true, out tFile.CRC, out tFile.MD5, out tFile.SHA1);

            if (errorCode == 32)
            {
                tFile.GotStatus = GotStatus.FileLocked;
                return;
            }
            if (errorCode != 0)
            {
                ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted.");
                _fileErrorAbort = true;
                return;
            }
            tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified);
        }
Example #2
0
        private static void ChdManCheck(string directory, RvFile tFile)
        {
            string filename = Path.Combine(directory, tFile.Name);

            if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader))
            {
                return;
            }
            _bgw.ReportProgress(0, new bgwText2(filename));

            string error;

            CHD.CHDManCheck res = CHD.ChdmanCheck(filename, _bgw, out error);
            switch (res)
            {
            case CHD.CHDManCheck.Good:
                tFile.FileStatusSet(FileStatus.SHA1CHDVerified);
                return;

            case CHD.CHDManCheck.Corrupt:
                _bgw.ReportProgress(0, new bgwShowError(filename, error));
                tFile.GotStatus = GotStatus.Corrupt;
                return;

            case CHD.CHDManCheck.CHDReturnError:
            case CHD.CHDManCheck.CHDUnknownError:
                _bgw.ReportProgress(0, new bgwShowError(filename, error));
                return;

            case CHD.CHDManCheck.ChdmanNotFound:
                return;

            case CHD.CHDManCheck.CHDNotFound:
                ReportError.Show("File: " + filename + " Error: Not Found scan Aborted.");
                _fileErrorAbort = true;
                return;

            default:
                ReportError.UnhandledExceptionHandler(error);
                return;
            }
        }
Example #3
0
        private static void SetMissingStatus(RvBase dbChild)
        {
            if (dbChild.FileRemove() == EFile.Delete)
            {
                ReportError.SendAndShow("Error is Set Mssing Status in DatUpdate");
                return;
            }


            FileType ft = dbChild.FileType;

            if (ft == FileType.Zip || ft == FileType.Dir)
            {
                RvDir dbDir = (RvDir)dbChild;
                for (int i = 0; i < dbDir.ChildCount; i++)
                {
                    SetMissingStatus(dbDir.Child(i));
                }
            }
        }
Example #4
0
        public static int CompareName(RvBase var1, RvBase var2)
        {
            int retv = TrrntZipStringCompare(var1.Name, var2.Name);

            if (retv != 0)
            {
                return(retv);
            }

            FileType f1 = var1.FileType;
            FileType f2 = var2.FileType;

            if (f1 == FileType.ZipFile)
            {
                if (f2 != FileType.ZipFile)
                {
                    ReportError.SendAndShow("Incompatible Compare type");
                }

                return(Math.Sign(string.Compare(var1.Name, var2.Name, StringComparison.Ordinal)));
            }
            return(f1.CompareTo(f2));
        }
Example #5
0
        /*
         * private static void SetInDat(RvDir tDir)
         * {
         *  tDir.DatStatus = DatStatus.InDatCollect;
         *  if (tDir.Parent != null)
         *      SetInDat(tDir.Parent);
         * }
         */

        private static Boolean MergeInDat(RvDir dbDat, RvDir newDat, out RvDat conflict, bool checkOnly)
        {
            conflict = null;
            int dbIndex  = 0;
            int newIndex = 0;

            while (dbIndex < dbDat.ChildCount || newIndex < newDat.ChildCount)
            {
                RvBase dbChild     = null;
                RvBase newDatChild = null;
                int    res         = 0;

                if (dbIndex < dbDat.ChildCount && newIndex < newDat.ChildCount)
                {
                    dbChild     = dbDat.Child(dbIndex);   // are files
                    newDatChild = newDat.Child(newIndex); // is from a dat item
                    res         = DBHelper.CompareName(dbChild, newDatChild);
                }
                else if (newIndex < newDat.ChildCount)
                {
                    newDatChild = newDat.Child(newIndex);
                    res         = 1;
                }
                else if (dbIndex < dbDat.ChildCount)
                {
                    dbChild = dbDat.Child(dbIndex);
                    res     = -1;
                }

                if (res == 0)
                {
                    if (dbChild == null || newDatChild == null)
                    {
                        SendAndShowDat(Resources.DatUpdate_MergeInDat_Error_in_Logic, dbDat.FullName);
                        break;
                    }


                    List <RvBase> dbDats       = new List <RvBase>();
                    List <RvBase> newDats      = new List <RvBase>();
                    int           dbDatsCount  = 1;
                    int           newDatsCount = 1;


                    dbDats.Add(dbChild);
                    newDats.Add(newDatChild);

                    while (dbIndex + dbDatsCount < dbDat.ChildCount && DBHelper.CompareName(dbChild, dbDat.Child(dbIndex + dbDatsCount)) == 0)
                    {
                        dbDats.Add(dbDat.Child(dbIndex + dbDatsCount));
                        dbDatsCount += 1;
                    }
                    while (newIndex + newDatsCount < newDat.ChildCount && DBHelper.CompareName(newDatChild, newDat.Child(newIndex + newDatsCount)) == 0)
                    {
                        newDats.Add(newDat.Child(newIndex + newDatsCount));
                        newDatsCount += 1;
                    }

                    if (dbDatsCount > 1 || newDatsCount > 1)
                    {
                        ReportError.SendAndShow("Double Name Found");
                    }

                    for (int indexdb = 0; indexdb < dbDatsCount; indexdb++)
                    {
                        if (dbDats[indexdb].DatStatus == DatStatus.NotInDat)
                        {
                            continue;
                        }

                        if (checkOnly)
                        {
                            conflict = dbChild.Dat;
                            return(true);
                        }

                        SendAndShowDat(Resources.DatUpdate_MergeInDat_Unkown_Update_Dat_Status + dbChild.DatStatus, dbDat.FullName);
                        break;
                    }

                    if (!checkOnly)
                    {
                        for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++)
                        {
                            if (newDats[indexNewDats].SearchFound)
                            {
                                continue;
                            }

                            for (int indexDbDats = 0; indexDbDats < dbDatsCount; indexDbDats++)
                            {
                                if (dbDats[indexDbDats].SearchFound)
                                {
                                    continue;
                                }

                                bool matched = FullCompare(dbDats[indexDbDats], newDats[indexNewDats]);
                                if (!matched)
                                {
                                    continue;
                                }

                                dbDats[indexDbDats].DatAdd(newDats[indexNewDats]);

                                FileType ft = dbChild.FileType;

                                if (ft == FileType.Zip || ft == FileType.Dir)
                                {
                                    RvDir dChild    = (RvDir)dbChild;
                                    RvDir dNewChild = (RvDir)newDatChild;
                                    MergeInDat(dChild, dNewChild, out conflict, checkOnly);
                                }

                                dbDats[indexDbDats].SearchFound   = true;
                                newDats[indexNewDats].SearchFound = true;
                            }
                        }

                        for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++)
                        {
                            if (newDats[indexNewDats].SearchFound)
                            {
                                continue;
                            }

                            dbDat.ChildAdd(newDats[indexNewDats], dbIndex);
                            dbChild = dbDat.Child(dbIndex);
                            SetMissingStatus(dbChild);

                            dbIndex++;
                        }
                    }

                    dbIndex  += dbDatsCount;
                    newIndex += newDatsCount;
                }

                if (res == 1)
                {
                    if (!checkOnly)
                    {
                        dbDat.ChildAdd(newDatChild, dbIndex);
                        dbChild = dbDat.Child(dbIndex);
                        SetMissingStatus(dbChild);

                        dbIndex++;
                    }
                    newIndex++;
                }

                if (res == -1)
                {
                    dbIndex++;
                }
            }
            return(false);
        }
Example #6
0
        public static void UpdateDat(object sender, DoWorkEventArgs e)
        {
            try
            {
                _bgw = sender as BackgroundWorker;
                if (_bgw == null)
                {
                    return;
                }

                Program.SyncCont = e.Argument as SynchronizationContext;
                if (Program.SyncCont == null)
                {
                    _bgw = null;
                    return;
                }


                _bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
                RepairStatus.ReportStatusReset(DB.DirTree);

                _datCount = 0;

                _bgw.ReportProgress(0, new bgwText("Finding Dats"));
                RvDir datRoot = new RvDir(FileType.Dir)
                {
                    Name = "RomVault", DatStatus = DatStatus.InDatCollect
                };

                // build a datRoot tree of the DAT's in DatRoot, and count how many dats are found
                if (!RecursiveDatTree(datRoot, out _datCount))
                {
                    _bgw.ReportProgress(0, new bgwText("Dat Update Complete"));
                    _bgw             = null;
                    Program.SyncCont = null;
                    return;
                }

                _bgw.ReportProgress(0, new bgwText("Scanning Dats"));
                _datsProcessed = 0;

                // now compare the database DAT's with datRoot removing any old DAT's
                RemoveOldDats(DB.DirTree.Child(0), datRoot);

                // next clean up the File status removing any old DAT's
                RemoveOldDatsCleanUpFiles(DB.DirTree.Child(0));

                _bgw.ReportProgress(0, new bgwSetRange(_datCount - 1));

                // next add in new DAT and update the files
                UpdateDatList((RvDir)DB.DirTree.Child(0), datRoot);

                // finally remove any unneeded DIR's from the TreeView
                RemoveOldTree(DB.DirTree.Child(0));

                _bgw.ReportProgress(0, new bgwText("Updating Cache"));
                DB.Write();

                _bgw.ReportProgress(0, new bgwText("Dat Update Complete"));
                _bgw             = null;
                Program.SyncCont = null;
            }
            catch (Exception exc)
            {
                ReportError.UnhandledExceptionHandler(exc);

                if (_bgw != null)
                {
                    _bgw.ReportProgress(0, new bgwText("Updating Cache"));
                }
                DB.Write();
                if (_bgw != null)
                {
                    _bgw.ReportProgress(0, new bgwText("Complete"));
                }

                _bgw             = null;
                Program.SyncCont = null;
            }
        }
Example #7
0
        /// <summary>
        /// Add the new DAT's into the DAT list
        /// And merge in the new DAT data into the database
        /// </summary>
        /// <param name="dbDir">The Current database dir</param>
        /// <param name="tmpDir">A temp directory containing the DAT found in this directory in DatRoot</param>
        private static void AddNewDats(RvDir dbDir, RvDir tmpDir)
        {
            bool autoAddDirectory = (tmpDir.DirDatCount) > 1;

            int dbIndex   = 0;
            int scanIndex = 0;

            Debug.WriteLine("");
            Debug.WriteLine("Scanning for Adding new DATS");
            while (dbIndex < dbDir.DirDatCount || scanIndex < tmpDir.DirDatCount)
            {
                RvDat dbDat   = null;
                RvDat fileDat = null;
                int   res     = 0;

                if (dbIndex < dbDir.DirDatCount && scanIndex < tmpDir.DirDatCount)
                {
                    dbDat   = dbDir.DirDat(dbIndex);
                    fileDat = tmpDir.DirDat(scanIndex);
                    res     = DBHelper.DatCompare(dbDat, fileDat);
                    Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res);
                }
                else if (scanIndex < tmpDir.DirDatCount)
                {
                    fileDat = tmpDir.DirDat(scanIndex);
                    res     = 1;
                    Debug.WriteLine("Checking : and " + fileDat.GetData(RvDat.DatData.DatFullName) + " : " + res);
                }
                else if (dbIndex < dbDir.DirDatCount)
                {
                    dbDat = dbDir.DirDat(dbIndex);
                    res   = -1;
                    Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatFullName) + " : and : " + res);
                }

                switch (res)
                {
                case 0:
                    _datsProcessed++;
                    _bgw.ReportProgress(_datsProcessed);
                    _bgw.ReportProgress(0, new bgwText("Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName))));


                    Debug.WriteLine("Correct");
                    // Should already be set as correct above
                    dbDat.Status = DatUpdateStatus.Correct;
                    dbIndex++;
                    scanIndex++;
                    break;

                case 1:
                    _datsProcessed++;
                    _bgw.ReportProgress(_datsProcessed);
                    _bgw.ReportProgress(0, new bgwText("Scanning New Dat : " + Path.GetFileNameWithoutExtension(fileDat.GetData(RvDat.DatData.DatFullName))));


                    Debug.WriteLine("Adding new DAT");
                    if (UpdateDatFile(fileDat, autoAddDirectory, dbDir))
                    {
                        dbIndex++;
                    }
                    scanIndex++;
                    break;

                case -1:
                    // This should not happen as deleted dat have been removed above
                    //dbIndex++;
                    ReportError.SendAndShow(Resources.DatUpdate_UpdateDatList_ERROR_Deleting_a_DAT_that_should_already_be_deleted);
                    break;
                }
            }
        }
Example #8
0
        private static bool RecursiveDatTree(RvDir tDir, out int datCount)
        {
            datCount = 0;
            string strPath = tDir.DatFullName;

            if (!Directory.Exists(strPath))
            {
                ReportError.Show(Resources.DatUpdate_UpdateDatList_Path + strPath + Resources.DatUpdate_UpdateDatList_Not_Found);
                return(false);
            }

            DirectoryInfo oDir = new DirectoryInfo(strPath);

            FileInfo[] oFilesIn = oDir.GetFiles("*.dat", false);
            datCount += oFilesIn.Length;
            foreach (FileInfo file in oFilesIn)
            {
                RvDat tDat = new RvDat();
                tDat.AddData(RvDat.DatData.DatFullName, file.FullName);
                tDat.TimeStamp = file.LastWriteTime;
                tDir.DirDatAdd(tDat);
            }


            oFilesIn  = oDir.GetFiles("*.xml", false);
            datCount += oFilesIn.Length;
            foreach (FileInfo file in oFilesIn)
            {
                RvDat tDat = new RvDat();
                tDat.AddData(RvDat.DatData.DatFullName, file.FullName);
                tDat.TimeStamp = file.LastWriteTime;
                tDir.DirDatAdd(tDat);
            }

            if (tDir.DirDatCount > 1)
            {
                for (int i = 0; i < tDir.DirDatCount; i++)
                {
                    tDir.DirDat(i).AutoAddDirectory = true;
                }
            }

            DirectoryInfo[] oSubDir = oDir.GetDirectories(false);

            foreach (DirectoryInfo t in oSubDir)
            {
                RvDir cDir = new RvDir(FileType.Dir)
                {
                    Name = t.Name, DatStatus = DatStatus.InDatCollect
                };
                int index = tDir.ChildAdd(cDir);

                int retDatCount;

                RecursiveDatTree(cDir, out retDatCount);
                datCount += retDatCount;

                if (retDatCount == 0)
                {
                    tDir.ChildRemove(index);
                }
            }

            return(true);
        }
Example #9
0
        private void PaintTree(RvDir pTree, Graphics g, Rectangle t)
        {
            int y = pTree.Tree.RTree.Top - _vScroll;

            if (pTree.Tree.RTree.IntersectsWith(t))
            {
                Pen p = new Pen(Brushes.Gray, 1)
                {
                    DashStyle = DashStyle.Dot
                };

                string lTree = pTree.Tree.TreeBranches;
                for (int j = 0; j < lTree.Length; j++)
                {
                    int    x     = j * 18 - _hScroll;
                    string cTree = lTree.Substring(j, 1);
                    switch (cTree)
                    {
                    case "│":
                        g.DrawLine(p, x + 9, y, x + 9, y + 16);
                        break;

                    case "├":
                    case "â””":
                        g.DrawLine(p, x + 9, y, x + 9, y + 16);
                        g.DrawLine(p, x + 9, y + 16, x + 27, y + 16);
                        break;
                    }
                }
            }

            if (!pTree.Tree.RExpand.IsEmpty)
            {
                if (pTree.Tree.RExpand.IntersectsWith(t))
                {
                    g.DrawImage(pTree.Tree.TreeExpanded ? rvImages.ExpandBoxMinus : rvImages.ExpandBoxPlus, RSub(pTree.Tree.RExpand, _hScroll, _vScroll));
                }
            }


            if (pTree.Tree.RChecked.IntersectsWith(t))
            {
                switch (pTree.Tree.Checked)
                {
                case RvTreeRow.TreeSelect.Disabled:
                    g.DrawImage(rvImages.TickBoxDisabled, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
                    break;

                case RvTreeRow.TreeSelect.UnSelected:
                    g.DrawImage(rvImages.TickBoxUnTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
                    break;

                case RvTreeRow.TreeSelect.Selected:
                    g.DrawImage(rvImages.TickBoxTicked, RSub(pTree.Tree.RChecked, _hScroll, _vScroll));
                    break;
                }
            }

            if (pTree.Tree.RIcon.IntersectsWith(t))
            {
                int icon = 2;
                if (pTree.DirStatus.HasInToSort())
                {
                    icon = 4;
                }
                else if (!pTree.DirStatus.HasCorrect())
                {
                    icon = 1;
                }
                else if (!pTree.DirStatus.HasMissing())
                {
                    icon = 3;
                }



                Bitmap bm;
                if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree
                {
                    bm = rvImages.GetBitmap("DirectoryTree" + icon);
                }
                else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's
                {
                    bm = rvImages.GetBitmap("Tree" + icon);
                }
                else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT
                {
                    bm = rvImages.GetBitmap("Tree" + icon);
                }
                else
                {
                    ReportError.SendAndShow("Unknown Tree settings in DisplayTree.");
                    bm = null;
                }

                if (bm != null)
                {
                    g.DrawImage(bm, RSub(pTree.Tree.RIcon, _hScroll, _vScroll));
                }
            }



            Rectangle recBackGround = new Rectangle(pTree.Tree.RText.X, pTree.Tree.RText.Y, Width - pTree.Tree.RText.X + _hScroll, pTree.Tree.RText.Height);

            if (recBackGround.IntersectsWith(t))
            {
                string thistxt;

                if (pTree.Dat == null && pTree.DirDatCount != 1) // Directory above DAT's in Tree
                {
                    thistxt = pTree.Name;
                }
                else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's
                {
                    thistxt = pTree.Name + ": " + pTree.DirDat(0).GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
                }

                // pTree.Parent.DirDatCount>1: This should probably be a test like parent contains Dat
                else if (pTree.Dat != null && pTree.Dat.AutoAddDirectory && pTree.Parent.DirDatCount > 1)
                {
                    thistxt = pTree.Name + ": " + pTree.Dat.GetData(RvDat.DatData.Description) + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
                }
                else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT
                {
                    thistxt = pTree.Name + " ( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )";
                }
                else
                {
                    ReportError.SendAndShow("Unknown Tree settings in DisplayTree.");
                    thistxt = "";
                }


                if (_lSelected != null && pTree.TreeFullName == _lSelected.TreeFullName)
                {
                    g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), RSub(recBackGround, _hScroll, _vScroll));
                    g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.White, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll);
                }
                else
                {
                    g.DrawString(thistxt, new Font("Microsoft Sans Serif", 8), Brushes.Black, pTree.Tree.RText.Left - _hScroll, pTree.Tree.RText.Top + 1 - _vScroll);
                }
            }

            if (pTree.Tree.TreeExpanded)
            {
                for (int i = 0; i < pTree.ChildCount; i++)
                {
                    RvBase tBase = pTree.Child(i);
                    if (tBase is RvDir)
                    {
                        RvDir tDir = (RvDir)tBase;
                        if (tDir.Tree != null)
                        {
                            PaintTree(tDir, g, t);
                        }
                    }
                }
            }
        }
Example #10
0
        public static void Compare(RvDir dbDir, RvDir fileDir, bool report, bool enableCancel)
        {
            string   fullDir = dbDir.FullName;
            FileType ft      = dbDir.FileType;

            // now we scan down the dbDir and the scanDir, comparing them.
            // if we find a match we mark dbDir as found.
            // if we are missing a file in scanDir we mark that file in dbDir as missing.
            // if we find extra files in scanDir we add it to dbDir and mark it as unknown.
            // we also recurse into any sub directories.
            int dbIndex   = 0;
            int fileIndex = 0;


            while (dbIndex < dbDir.ChildCount || fileIndex < fileDir.ChildCount)
            {
                RvBase dbChild   = null;
                RvBase fileChild = null;
                int    res       = 0;

                if (dbIndex < dbDir.ChildCount && fileIndex < fileDir.ChildCount)
                {
                    dbChild   = dbDir.Child(dbIndex);
                    fileChild = fileDir.Child(fileIndex);
                    res       = DBHelper.CompareName(dbChild, fileChild);
                }
                else if (fileIndex < fileDir.ChildCount)
                {
                    //Get any remaining filedir's
                    fileChild = fileDir.Child(fileIndex);
                    res       = 1;
                }
                else if (dbIndex < dbDir.ChildCount)
                {
                    //Get any remaining dbDir's
                    dbChild = dbDir.Child(dbIndex);
                    res     = -1;
                }

                if (report)
                {
                    if (fileChild != null)
                    {
                        long timenow = DateTime.Now.Ticks;
                        if ((timenow - _lastUpdateTime) > (TimeSpan.TicksPerSecond / 10))
                        {
                            _lastUpdateTime = timenow;
                            _bgw.ReportProgress(0, new bgwValue2(fileIndex));
                            _bgw.ReportProgress(0, new bgwText2(Path.Combine(fullDir, fileChild.Name)));
                        }
                    }
                }

                // if this file was found in the DB
                switch (res)
                {
                case 0:

                    if (dbChild == null || fileChild == null)
                    {
                        ReportError.SendAndShow(Resources.FileScanning_CheckADir_Error_in_File_Scanning_Code);
                        break;
                    }

                    //Complete MultiName Compare
                    List <RvBase> dbs        = new List <RvBase>();
                    List <RvBase> files      = new List <RvBase>();
                    int           dbsCount   = 1;
                    int           filesCount = 1;


                    dbs.Add(dbChild);
                    files.Add(fileChild);

                    while (dbIndex + dbsCount < dbDir.ChildCount && DBHelper.CompareName(dbChild, dbDir.Child(dbIndex + dbsCount)) == 0)
                    {
                        dbs.Add(dbDir.Child(dbIndex + dbsCount));
                        dbsCount += 1;
                    }
                    while (fileIndex + filesCount < fileDir.ChildCount && DBHelper.CompareName(fileChild, fileDir.Child(fileIndex + filesCount)) == 0)
                    {
                        files.Add(fileDir.Child(fileIndex + filesCount));
                        filesCount += 1;
                    }

                    for (int indexfile = 0; indexfile < filesCount; indexfile++)
                    {
                        if (files[indexfile].SearchFound)
                        {
                            continue;
                        }

                        for (int indexdb = 0; indexdb < dbsCount; indexdb++)
                        {
                            if (dbs[indexdb].SearchFound)
                            {
                                continue;
                            }

                            bool matched = FullCompare(dbs[indexdb], files[indexfile], false, fullDir, EScanLevel);
                            if (!matched)
                            {
                                continue;
                            }

                            MatchFound(dbs[indexdb], files[indexfile]);
                            dbs[indexdb].SearchFound     = true;
                            files[indexfile].SearchFound = true;
                        }

                        if (files[indexfile].SearchFound)
                        {
                            continue;
                        }

                        for (int indexdb = 0; indexdb < dbsCount; indexdb++)
                        {
                            if (dbs[indexdb].SearchFound)
                            {
                                continue;
                            }

                            bool matched = FullCompare(dbs[indexdb], files[indexfile], true, fullDir, EScanLevel);
                            if (!matched)
                            {
                                continue;
                            }

                            MatchFound(dbs[indexdb], files[indexfile]);
                            dbs[indexdb].SearchFound     = true;
                            files[indexfile].SearchFound = true;
                        }
                    }


                    for (int indexdb = 0; indexdb < dbsCount; indexdb++)
                    {
                        if (dbs[indexdb].SearchFound)
                        {
                            dbIndex++;
                            continue;
                        }
                        DBFileNotFound(dbs[indexdb], dbDir, ref dbIndex);
                    }

                    for (int indexfile = 0; indexfile < filesCount; indexfile++)
                    {
                        if (files[indexfile].SearchFound)
                        {
                            continue;
                        }
                        NewFileFound(files[indexfile], dbDir, dbIndex);
                        dbIndex++;
                    }

                    fileIndex += filesCount;
                    break;

                case 1:
                    NewFileFound(fileChild, dbDir, dbIndex);
                    dbIndex++;
                    fileIndex++;
                    break;

                case -1:
                    DBFileNotFound(dbChild, dbDir, ref dbIndex);
                    break;
                }

                if (_fileErrorAbort)
                {
                    return;
                }
                if (enableCancel && !DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending)
                {
                    return;
                }
            }
        }
Example #11
0
        public static void ScanFiles(object sender, DoWorkEventArgs e)
        {
#if !Debug
            try
            {
#endif
            _fileErrorAbort = false;
            _cacheSaveTimer = new Stopwatch();
            _cacheSaveTimer.Reset();
            if (Settings.CacheSaveTimerEnabled)
            {
                _cacheSaveTimer.Start();
            }

            _bgw = sender as BackgroundWorker;
            if (_bgw == null)
            {
                return;
            }

            Program.SyncCont = e.Argument as SynchronizationContext;
            if (Program.SyncCont == null)
            {
                _bgw = null;
                return;
            }


            _bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
            RepairStatus.ReportStatusReset(DB.DirTree);

            _bgw.ReportProgress(0, new bgwText("Finding Dir's to Scan"));
            //Next get a list of all the directories to be scanned
            List <RvDir> lstDir = new List <RvDir>();
            DBHelper.GetSelectedDirList(ref lstDir);


            _bgw.ReportProgress(0, new bgwText("Scanning Dir's"));
            _bgw.ReportProgress(0, new bgwSetRange(lstDir.Count - 1));
            //Scan the list of directories.
            for (int i = 0; i < lstDir.Count; i++)
            {
                _bgw.ReportProgress(i);
                _bgw.ReportProgress(0, new bgwText("Scanning Dir : " + lstDir[i].FullName));
                string lDir = lstDir[i].FullName;
                Console.WriteLine(lDir);
                if (Directory.Exists(lDir))
                {
                    CheckADir(lstDir[i], true);
                }
                else
                {
                    MarkAsMissing(lstDir[i]);
                }

                if (_bgw.CancellationPending || _fileErrorAbort)
                {
                    break;
                }
            }

            _bgw.ReportProgress(0, new bgwText("Updating Cache"));
            DB.Write();


            _bgw.ReportProgress(0, new bgwText("File Scan Complete"));

            _bgw             = null;
            Program.SyncCont = null;
#if !Debug
        }

        catch (Exception exc)
        {
            ReportError.UnhandledExceptionHandler(exc);

            if (_bgw != null)
            {
                _bgw.ReportProgress(0, new bgwText("Updating Cache"));
            }
            DB.Write();
            if (_bgw != null)
            {
                _bgw.ReportProgress(0, new bgwText("Complete"));
            }

            _bgw             = null;
            Program.SyncCont = null;
        }
#endif
        }
Example #12
0
        private static void CheckADir(RvDir dbDir, bool report)
        {
            if (_cacheSaveTimer.Elapsed.TotalMinutes > Settings.CacheSaveTimePeriod)
            {
                _bgw.ReportProgress(0, "Saving Cache");
                DB.Write();
                _bgw.ReportProgress(0, "Saving Cache Complete");
                _cacheSaveTimer.Reset();
                _cacheSaveTimer.Start();
            }

            string fullDir = dbDir.FullName;

            if (report)
            {
                _bgw.ReportProgress(0, new bgwText2(fullDir));
            }

            DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat;

            // this is a temporary rvDir structure to store the data about the actual directory/files we are scanning
            // we will first populate this variable with the real file data from the directory, and then compare it
            // with the data in dbDir.
            RvDir fileDir = null;


            Debug.WriteLine(fullDir);

            FileType ft = dbDir.FileType;

            #region "Populate fileDir"

            // if we are scanning a ZIP file then populate scanDir from the ZIP file
            switch (ft)
            {
            case FileType.Zip:
            {
                fileDir = new RvDir(ft);

                // open the zip file
                ZipFile checkZ = new ZipFile();

                ZipReturn zr = checkZ.ZipFileOpen(fullDir, dbDir.TimeStamp, true);

                if (zr == ZipReturn.ZipGood)
                {
                    dbDir.ZipStatus = checkZ.ZipStatus;

                    // to be Scanning a ZIP file means it is either new or has changed.
                    // as the code below only calls back here if that is true.
                    //
                    // Level1: Only use header CRC's
                    // Just get the CRC for the ZIP headers.
                    //
                    // Level2: Fully checksum changed only files
                    // We know this file has been changed to do a full checksum scan.
                    //
                    // Level3: Fully checksum everything
                    // So do a full checksum scan.
                    if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3)
                    {
                        checkZ.DeepScan();
                    }

                    // add all of the file information from the zip file into scanDir
                    for (int i = 0; i < checkZ.LocalFilesCount(); i++)
                    {
                        RvFile tFile = new RvFile(DBTypeGet.FileFromDir(ft))
                        {
                            Name                  = checkZ.Filename(i),
                            ZipFileIndex          = i,
                            ZipFileHeaderPosition = checkZ.LocalHeader(i),
                            Size                  = checkZ.UncompressedSize(i),
                            CRC = checkZ.CRC32(i)
                        };
                        // all 3 levels read the CRC from the ZIP header
                        tFile.SetStatus(chechingDatStatus, GotStatus.Got);
                        tFile.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader);

                        // if we are in level 2 or level 3 then do a full CheckSum Scan.
                        if (EScanLevel == eScanLevel.Level2 || EScanLevel == eScanLevel.Level3)
                        {
                            // DeepScan will return ZipReturn.ZipCRCDecodeError if the headers CRC and
                            // the actual CRC do not match.
                            // So we just need to set the MD5 and SHA1 from the ZIP file.
                            zr = checkZ.FileStatus(i);
                            if (zr == ZipReturn.ZipUntested)
                            {
                                _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i)));
                            }
                            else if (zr != ZipReturn.ZipGood)
                            {
                                _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir + " : " + checkZ.Filename(i)));
                                tFile.GotStatus = GotStatus.Corrupt;
                            }
                            else
                            {
                                tFile.MD5  = checkZ.MD5(i);
                                tFile.SHA1 = checkZ.SHA1(i);
                                tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified);
                            }
                        }

                        fileDir.ChildAdd(tFile);
                    }
                }
                else if (zr == ZipReturn.ZipFileLocked)
                {
                    _bgw.ReportProgress(0, new bgwShowError(fullDir, "Zip File Locked"));
                    dbDir.TimeStamp = 0;
                    dbDir.GotStatus = GotStatus.FileLocked;
                }
                else
                {
                    _bgw.ReportProgress(0, new bgwShowCorrupt(zr, fullDir));
                    dbDir.GotStatus = GotStatus.Corrupt;
                }
                checkZ.ZipFileClose();
            }
            break;

            case FileType.Dir:
            {
                fileDir = new RvDir(FileType.Dir);


                DirectoryInfo   oDir   = new DirectoryInfo(fullDir);
                DirectoryInfo[] oDirs  = oDir.GetDirectories();
                FileInfo[]      oFiles = oDir.GetFiles();

                // add all the subdirectories into scanDir
                foreach (DirectoryInfo dir in oDirs)
                {
                    RvBase tDir = new RvDir(FileType.Dir)
                    {
                        Name      = dir.Name,
                        TimeStamp = dir.LastWriteTime,
                    };
                    tDir.SetStatus(chechingDatStatus, GotStatus.Got);
                    fileDir.ChildAdd(tDir);
                }

                // add all the files into scanDir
                foreach (FileInfo oFile in oFiles)
                {
                    // if we find any zip files add them as zip files.
                    string fExt = Path.GetExtension(oFile.Name);
                    switch (fExt.ToLower())
                    {
                    case ".zip":
                    {
                        RvDir tGame = new RvDir(FileType.Zip)
                        {
                            Name      = Path.GetFileNameWithoutExtension(oFile.Name),
                            TimeStamp = oFile.LastWriteTime,
                        };
                        tGame.SetStatus(chechingDatStatus, GotStatus.Got);
                        fileDir.ChildAdd(tGame);
                    }
                    break;

                    default:
                    {
                        string fName = oFile.Name;
                        if (fName == "__RomVault.tmp")
                        {
                            File.Delete(oFile.FullName);
                            continue;
                        }

                        // Scanning a file
                        //
                        // Level1 & 2 : (are the same for files) Fully checksum changed only files
                        // Here we are just getting the TimeStamp of the File, and later
                        // if the TimeStamp was not matched we will have to read the files CRC, MD5 & SHA1
                        //
                        // Level3: Fully checksum everything
                        // Get everything about the file right here so
                        // read CRC, MD5 & SHA1


                        // add all the files in the sub-directory to scanDir
                        RvFile tFile = new RvFile(FileType.File)
                        {
                            Name      = fName,
                            Size      = (ulong)oFile.Length,
                            TimeStamp = oFile.LastWriteTime
                        };

                        tFile.FileStatusSet(FileStatus.SizeVerified);

                        int errorCode = CHD.CheckFile(oFile, out tFile.SHA1CHD, out tFile.MD5CHD, out tFile.CHDVersion);

                        if (errorCode == 0)
                        {
                            if (tFile.SHA1CHD != null)
                            {
                                tFile.FileStatusSet(FileStatus.SHA1CHDFromHeader);
                            }
                            if (tFile.MD5CHD != null)
                            {
                                tFile.FileStatusSet(FileStatus.MD5CHDFromHeader);
                            }

                            tFile.SetStatus(chechingDatStatus, GotStatus.Got);

                            // if we are scanning at Level3 then we get all the info here
                            if (EScanLevel == eScanLevel.Level3)
                            {
                                DeepScanFile(fullDir, tFile);
                                ChdManCheck(fullDir, tFile);
                            }
                        }
                        else if (errorCode == 32)
                        {
                            tFile.GotStatus = GotStatus.FileLocked;
                            _bgw.ReportProgress(0, new bgwShowError(fullDir, "File Locked"));
                        }
                        else
                        {
                            string filename = Path.Combine(fullDir, tFile.Name);
                            ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted.");
                            _fileErrorAbort = true;
                            return;
                        }
                        fileDir.ChildAdd(tFile);
                    }
                    break;
                    }
                }
            }
            break;

            default:
                ReportError.SendAndShow("Un supported file type in CheckADir " + ft);
                break;
            }
            #endregion

            if (fileDir == null)
            {
                ReportError.SendAndShow("Unknown Reading File Type in Dir Scanner");
                return;
            }

            if (report)
            {
                _bgw.ReportProgress(0, new bgwSetRange2(fileDir.ChildCount - 1));

                _bgw.ReportProgress(0, new bgwRange2Visible(true));
            }

            if (!DBTypeGet.isCompressedDir(ft) && _bgw.CancellationPending)
            {
                return;
            }

            Compare(dbDir, fileDir, report, true);
        }
Example #13
0
        private static void ListCheckSHA1CHD(List <RvFile> lstRomTableSortedSHA1CHD, int start, int length)
        {
            if (lstRomTableSortedSHA1CHD.Count == 0)
            {
                return;
            }

            List <RvFile> missingFiles = new List <RvFile>();  // files we done have have that we need

            List <RvFile> correctFiles  = new List <RvFile>(); // files we have that are in the correct place
            List <RvFile> unNeededFiles = new List <RvFile>(); // files we have that are not in the correct place
            List <RvFile> inToSortFiles = new List <RvFile>(); // files we have that are in tosort
            List <RvFile> allGotFiles   = new List <RvFile>(); // all files we have

            List <RvFile> corruptFiles = new List <RvFile>();  // corrupt files that we do not need, a corrupt file is missing if it is needed


            // set the found status of this file
            for (int iLoop = 0; iLoop < length; iLoop++)
            {
                RvFile tFile = lstRomTableSortedSHA1CHD[start + iLoop];

                switch (tFile.RepStatus)
                {
                case RepStatus.Missing:
                    missingFiles.Add(tFile);     // these are checked in step 1 to fixes from the allGotFiles List.
                    break;

                case RepStatus.Correct:
                    correctFiles.Add(tFile);
                    break;

                case RepStatus.Corrupt:
                case RepStatus.MoveToCorrupt:
                    if (tFile.DatStatus == DatStatus.InDatCollect)
                    {
                        missingFiles.Add(tFile);     // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found.
                    }
                    else
                    {
                        corruptFiles.Add(tFile);     // all other corrupt files should be deleted or moved to tosort/corrupt
                    }
                    break;

                case RepStatus.UnNeeded:
                case RepStatus.Unknown:
                case RepStatus.MoveToSort:
                case RepStatus.InToSort:
                case RepStatus.Delete:
                case RepStatus.NeededForFix:
                case RepStatus.Rename:
                    if (tFile.IsInToSort)
                    {
                        inToSortFiles.Add(tFile);
                    }
                    else
                    {
                        unNeededFiles.Add(tFile);
                    }
                    break;

                case RepStatus.NotCollected:
                    break;

                case RepStatus.Ignore:
                    break;     // Ignore File

                default:
                    ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus);
                    break;
                }
            }
            allGotFiles.AddRange(correctFiles);
            allGotFiles.AddRange(unNeededFiles);
            allGotFiles.AddRange(inToSortFiles);

            #region Step 1 Check the Missing files from the allGotFiles List.

            // check to see if we can find any of the missing files in the gotFiles list.
            // if we find them mark them as CanBeFixed,

            foreach (RvFile missingFile in missingFiles)
            {
                if (allGotFiles.Count > 0)
                {
                    missingFile.RepStatus = (missingFile.RepStatus == RepStatus.Corrupt) || (missingFile.RepStatus == RepStatus.MoveToCorrupt) ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed;
                }
            }

            #endregion

            #region Step 2 Check all corrupt files.

            // if we have a correct version of the corrupt file then the corrput file can just be deleted,
            // otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort.

            // we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with

            foreach (RvFile corruptFile in corruptFiles)
            {
                if (allGotFiles.Count > 0)
                {
                    corruptFile.RepStatus = RepStatus.Delete;
                }

                if ((corruptFile.RepStatus == RepStatus.Corrupt) && (corruptFile.DatStatus != DatStatus.InToSort))
                {
                    corruptFile.RepStatus = RepStatus.MoveToCorrupt;
                }
            }

            #endregion

            #region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort

            foreach (RvFile unNeededFile in unNeededFiles)
            {
                // check if the unNeededFile is needed to fix a missing file
                if (missingFiles.Count > 0)
                {
                    unNeededFile.RepStatus = RepStatus.NeededForFix;
                    continue;
                }

                // now that we know this file is not needed for a fix if we have a correct version of it, it can be deleted.
                if (correctFiles.Count > 0)
                {
                    // this probably should check its old state
                    if (unNeededFile.RepStatus != RepStatus.NeededForFix)
                    {
                        unNeededFile.RepStatus = RepStatus.Delete;
                    }
                    continue;
                }

                if (inToSortFiles.Count > 0)
                {
                    if (unNeededFile.RepStatus != RepStatus.NeededForFix)
                    {
                        unNeededFile.RepStatus = RepStatus.Delete;
                    }
                    continue;
                }

                // otherwise move the file out to ToSort
                if (unNeededFile.RepStatus != RepStatus.NeededForFix)
                {
                    unNeededFile.RepStatus = RepStatus.MoveToSort;
                }
            }

            #endregion

            #region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort

            foreach (RvFile inToSortFile in inToSortFiles)
            {
                // check if the ToSortFile is needed to fix a missing file
                if (missingFiles.Count > 0)
                {
                    inToSortFile.RepStatus = RepStatus.NeededForFix;
                    continue;
                }

                // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted.
                if (correctFiles.Count <= 0)
                {
                    continue;
                }

                if (inToSortFile.RepStatus != RepStatus.NeededForFix)
                {
                    inToSortFile.RepStatus = RepStatus.Delete;
                }

                // otherwise leave the file in ToSort
            }

            #endregion
        }
Example #14
0
        public static void ScanFiles(object sender, DoWorkEventArgs e)
        {
            try
            {
                _bgw = sender as BackgroundWorker;
                if (_bgw == null)
                {
                    return;
                }

                Program.SyncCont = e.Argument as SynchronizationContext;
                if (Program.SyncCont == null)
                {
                    _bgw = null;
                    return;
                }

                _bgw.ReportProgress(0, new bgwText("Clearing DB Status"));
                RepairStatus.ReportStatusReset(DB.DirTree);

                List <RvFile> lstRomTableSortedCRCSize;
                List <RvFile> lstRomTableSortedSHA1CHD;

                _bgw.ReportProgress(0, new bgwText("Loading Rom List"));
                DBHelper.GetSelectedFilesSortCRCSize(out lstRomTableSortedCRCSize);
                DBHelper.GetSelectedFilesSortSHA1CHD(out lstRomTableSortedSHA1CHD);

                _bgw.ReportProgress(0, new bgwText("Scanning for Fixes"));
                _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedCRCSize.Count));

                int romIndex0 = 0;
                int romIndex1 = 1;
                while (romIndex1 < lstRomTableSortedCRCSize.Count)
                {
                    if (romIndex1 % 100 == 0)
                    {
                        _bgw.ReportProgress(romIndex1);
                    }

                    if (!ArrByte.bCompare(lstRomTableSortedCRCSize[romIndex0].CRC, lstRomTableSortedCRCSize[romIndex1].CRC) || (lstRomTableSortedCRCSize[romIndex0].Size != lstRomTableSortedCRCSize[romIndex1].Size))
                    {
                        ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0);
                        romIndex0 = romIndex1;
                    }
                    romIndex1++;
                }

                ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0);


                _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedSHA1CHD.Count));

                romIndex0 = 0;
                romIndex1 = 1;
                while (romIndex1 < lstRomTableSortedSHA1CHD.Count)
                {
                    if (romIndex1 % 100 == 0)
                    {
                        _bgw.ReportProgress(romIndex1);
                    }

                    if (!ArrByte.bCompare(lstRomTableSortedSHA1CHD[romIndex0].SHA1CHD, lstRomTableSortedSHA1CHD[romIndex1].SHA1CHD))
                    {
                        ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0);
                        romIndex0 = romIndex1;
                    }
                    romIndex1++;
                }

                ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0);


                _bgw             = null;
                Program.SyncCont = null;
            }
            catch (Exception exc)
            {
                ReportError.UnhandledExceptionHandler(exc);

                if (_bgw != null)
                {
                    _bgw.ReportProgress(0, new bgwText("Updating Cache"));
                }
                DB.Write();
                if (_bgw != null)
                {
                    _bgw.ReportProgress(0, new bgwText("Complete"));
                }

                _bgw             = null;
                Program.SyncCont = null;
            }
        }
Example #15
0
        public static void ListCheck(List <RvFile> lstRomTableSortedCRC, int start, int length)
        {
            if (lstRomTableSortedCRC.Count == 0)
            {
                return;
            }

            List <RvFile> missingFiles = new List <RvFile>();  // files we dont have that we need

            List <RvFile> correctFiles  = new List <RvFile>(); // files we have that are in the correct place
            List <RvFile> unNeededFiles = new List <RvFile>(); // files we have that are not in the correct place
            List <RvFile> inToSortFiles = new List <RvFile>(); // files we have that are in tosort
            List <RvFile> allGotFiles   = new List <RvFile>(); // all files we have

            List <RvFile> corruptFiles = new List <RvFile>();  // corrupt files that we do not need, a corrupt file is missing if it is needed


            // set the found status of this file
            for (int iLoop = 0; iLoop < length; iLoop++)
            {
                RvFile tFile = lstRomTableSortedCRC[start + iLoop];

                switch (tFile.RepStatus)
                {
                case RepStatus.UnScanned:
                    break;

                case RepStatus.Missing:
                    missingFiles.Add(tFile);     // these are checked in step 1 to fixes from the allGotFiles List.
                    break;

                case RepStatus.Correct:
                    correctFiles.Add(tFile);
                    break;

                case RepStatus.Corrupt:
                    if (tFile.DatStatus == DatStatus.InDatCollect)
                    {
                        missingFiles.Add(tFile);     // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found.
                    }
                    else
                    {
                        corruptFiles.Add(tFile);     // all other corrupt files should be deleted or moved to tosort/corrupt
                    }
                    break;

                case RepStatus.UnNeeded:
                case RepStatus.Unknown:
                    unNeededFiles.Add(tFile);
                    break;

                case RepStatus.NotCollected:
                    break;

                case RepStatus.InToSort:
                    inToSortFiles.Add(tFile);
                    break;

                case RepStatus.Ignore:
                    break;     // Ignore File

                default:
                    ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus);
                    break;
                }
            }
            allGotFiles.AddRange(correctFiles);
            allGotFiles.AddRange(unNeededFiles);
            allGotFiles.AddRange(inToSortFiles);

            #region Step 1 Check the Missing files from the allGotFiles List.

            // check to see if we can find any of the missing files in the gotFiles list.
            // if we find them mark them as CanBeFixed,
            // or if they are missing corrupt files set then as corruptCanBefixed

            foreach (RvFile missingFile in missingFiles)
            {
                if (DBHelper.IsZeroLengthFile(missingFile))
                {
                    missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed;
                    continue;
                }

                foreach (RvFile gotFile in allGotFiles)
                {
                    if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, gotFile))
                    {
                        continue;
                    }
                    missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed;
                    break;
                }
                if (missingFile.RepStatus == RepStatus.Corrupt)
                {
                    missingFile.RepStatus = RepStatus.MoveToCorrupt;
                }
            }

            #endregion

            #region Step 2 Check all corrupt files.

            // if we have a correct version of the corrupt file then the corrput file can just be deleted,
            // otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort.

            // we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with

            foreach (RvFile corruptFile in corruptFiles)
            {
                if (allGotFiles.Count > 0)
                {
                    corruptFile.RepStatus = RepStatus.Delete;
                }

                if ((corruptFile.RepStatus == RepStatus.Corrupt) && (corruptFile.DatStatus != DatStatus.InToSort))
                {
                    corruptFile.RepStatus = RepStatus.MoveToCorrupt;
                }
            }

            #endregion

            #region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort

            foreach (RvFile unNeededFile in unNeededFiles)
            {
                /*
                 * // check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted.
                 * foreach (RvFile correctFile in correctFiles)
                 * {
                 *  if (!FindSHA1MD5MatchingFiles(unNeededFile, correctFile)) continue;
                 *  unNeededFile.RepStatus = RepStatus.Delete;
                 *  break;
                 * }
                 * if (unNeededFile.RepStatus == RepStatus.Delete) continue;
                 */

                if (DBHelper.IsZeroLengthFile(unNeededFile))
                {
                    unNeededFile.RepStatus = RepStatus.Delete;
                    continue;
                }

                // check if the unNeededFile is needed to fix a missing file
                foreach (RvFile missingFile in missingFiles)
                {
                    if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, unNeededFile))
                    {
                        continue;
                    }
                    unNeededFile.RepStatus = RepStatus.NeededForFix;
                    break;
                }
                if (unNeededFile.RepStatus == RepStatus.NeededForFix)
                {
                    continue;
                }

                // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted.
                foreach (RvFile correctFile in correctFiles)
                {
                    if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, correctFile))
                    {
                        continue;
                    }
                    unNeededFile.RepStatus = RepStatus.Delete;
                    break;
                }
                if (unNeededFile.RepStatus == RepStatus.Delete)
                {
                    continue;
                }

                // and finally see if the file is already in ToSort, and if it is deleted.
                foreach (RvFile inToSortFile in inToSortFiles)
                {
                    if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, inToSortFile))
                    {
                        continue;
                    }
                    unNeededFile.RepStatus = RepStatus.Delete;
                    break;
                }
                if (unNeededFile.RepStatus == RepStatus.Delete)
                {
                    continue;
                }

                // otherwise move the file out to ToSort
                unNeededFile.RepStatus = RepStatus.MoveToSort;
            }

            #endregion

            #region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort

            foreach (RvFile inToSortFile in inToSortFiles)
            {
                /*
                 * // check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted.
                 * foreach (RvFile correctFile in correctFiles)
                 * {
                 *  if (!FindSHA1MD5MatchingFiles(inToSortFile, correctFile)) continue;
                 *  inToSortFile.RepStatus = RepStatus.Delete;
                 *  break;
                 * }
                 * if (inToSortFile.RepStatus == RepStatus.Delete) continue;
                 */

                // check if the ToSortFile is needed to fix a missing file
                foreach (RvFile missingFile in missingFiles)
                {
                    if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, inToSortFile))
                    {
                        continue;
                    }
                    inToSortFile.RepStatus = RepStatus.NeededForFix;
                    break;
                }
                if (inToSortFile.RepStatus == RepStatus.NeededForFix)
                {
                    continue;
                }

                // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted.
                foreach (RvFile correctFile in correctFiles)
                {
                    if (!CheckIfGotfileAndMatchingFileAreFullMatches(inToSortFile, correctFile))
                    {
                        continue;
                    }
                    inToSortFile.RepStatus = RepStatus.Delete;
                    break;
                }

                // otherwise leave the file in ToSort
            }

            #endregion

            //need to check here for roms that just need renamed inside the one ZIP
            //this prevents Zips from self deadlocking
            for (int iLoop0 = 0; iLoop0 < length; iLoop0++)
            {
                if (lstRomTableSortedCRC[start + iLoop0].RepStatus != RepStatus.NeededForFix)
                {
                    continue;
                }
                for (int iLoop1 = 0; iLoop1 < length; iLoop1++)
                {
                    if (lstRomTableSortedCRC[start + iLoop1].RepStatus != RepStatus.CanBeFixed)
                    {
                        continue;
                    }

                    if (!CheckIfMissingFileCanBeFixedByGotFile(lstRomTableSortedCRC[start + iLoop1], lstRomTableSortedCRC[start + iLoop0]))
                    {
                        continue;
                    }

                    if (DBHelper.RomFromSameGame(lstRomTableSortedCRC[start + iLoop0], lstRomTableSortedCRC[start + iLoop1]))
                    {
                        lstRomTableSortedCRC[start + iLoop0].RepStatus = RepStatus.Rename;
                    }
                }
            }
        }