Пример #1
0
        public override void Write(BinaryWriter bw)
        {
            base.Write(bw);
            if (Tree == null)
            {
                bw.Write(false);
            }
            else
            {
                bw.Write(true);
                Tree.Write(bw);
            }

            if (Game == null)
            {
                bw.Write(false);
            }
            else
            {
                bw.Write(true);
                Game.Write(bw);
            }

            int count = _dirDats.Count;

            bw.Write(count);
            for (int i = 0; i < count; i++)
            {
                _dirDats[i].Write(bw);
            }

            count = _children.Count;
            bw.Write(count);
            for (int i = 0; i < count; i++)
            {
                FileType type = _children[i].FileType;
                bw.Write((byte)type);
                _children[i].Write(bw);
            }

            if (DBTypeGet.isCompressedDir(FileType))
            {
                bw.Write((byte)ZipStatus);
            }
        }
Пример #2
0
        public static RvFile FromAZipFile(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker thWrk)
        {
            RvFile    fileDir           = new RvFile(dbDir.FileType);
            DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat;

            string    filename = dbDir.FullNameCase;
            ICompress checkZ   = dbDir.FileType == FileType.Zip ? new Zip() : (ICompress) new SevenZ();
            ZipReturn zr       = checkZ.ZipFileOpen(filename, dbDir.FileModTimeStamp);

            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 (_fs == null)
                {
                    _fs = new FileScan();
                }
                List <FileScan.FileResults> fr = _fs.Scan(checkZ, false, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3);

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

                    if (fr[i].FileStatus != ZipReturn.ZipGood)
                    {
                        thWrk.Report(new bgwShowCorrupt(fr[i].FileStatus, filename + " : " + lf.Filename));
                        tFile.GotStatus = GotStatus.Corrupt;
                    }
                    else
                    {
                        tFile.HeaderFileType = fr[i].HeaderFileType;
                        tFile.SHA1           = fr[i].SHA1;
                        tFile.MD5            = fr[i].MD5;
                        tFile.AltSize        = fr[i].AltSize;
                        tFile.AltCRC         = fr[i].AltCRC;
                        tFile.AltSHA1        = fr[i].AltSHA1;
                        tFile.AltMD5         = fr[i].AltMD5;

                        if (fr[i].CRC != null)
                        {
                            tFile.FileStatusSet(FileStatus.CRCFromHeader);
                            if (eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3)
                            {
                                tFile.FileStatusSet(FileStatus.CRCVerified);
                            }
                        }

                        tFile.FileStatusSet(
                            FileStatus.SizeVerified |
                            (fr[i].HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) |
                            (fr[i].SHA1 != null ? FileStatus.SHA1Verified : 0) |
                            (fr[i].MD5 != null ? FileStatus.MD5Verified : 0) |
                            (fr[i].AltSize != null ? FileStatus.AltSizeVerified : 0) |
                            (fr[i].AltCRC != null ? FileStatus.AltCRCVerified : 0) |
                            (fr[i].AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) |
                            (fr[i].AltMD5 != null ? FileStatus.AltMD5Verified : 0)
                            );
                    }

                    fileDir.ChildAdd(tFile);
                }
            }
            else if (zr == ZipReturn.ZipFileLocked)
            {
                thWrk.Report(new bgwShowError(filename, "Zip File Locked"));
                dbDir.FileModTimeStamp = 0;
                dbDir.GotStatus        = GotStatus.FileLocked;
            }
            else
            {
                thWrk.Report(new bgwShowCorrupt(zr, filename));
                dbDir.GotStatus = GotStatus.Corrupt;
            }
            checkZ.ZipFileClose();

            return(fileDir);
        }
Пример #3
0
        public static RvFile FromADir(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort)
        {
            string    fullDir   = dbDir.FullName;
            DatStatus datStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat;

            RvFile fileDir = new RvFile(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)
            {
                RvFile tDir = new RvFile(FileType.Dir)
                {
                    Name             = dir.Name,
                    FileModTimeStamp = dir.LastWriteTime
                };
                tDir.SetStatus(datStatus, GotStatus.Got);
                fileDir.ChildAdd(tDir);
            }

            // add all the files into scanDir
            foreach (FileInfo oFile in oFiles)
            {
                string fName = oFile.Name;
                if (fName == "__RomVault.tmp")
                {
                    File.Delete(oFile.FullName);
                    continue;
                }
                string fExt = Path.GetExtension(oFile.Name);

                FileType ft = DBTypeGet.fromExtention(fExt);

                if (Settings.rvSettings.FilesOnly)
                {
                    ft = FileType.File;
                }

                RvFile tFile = new RvFile(ft)
                {
                    Name             = oFile.Name,
                    Size             = (ulong)oFile.Length,
                    FileModTimeStamp = oFile.LastWriteTime
                };
                tFile.FileStatusSet(FileStatus.SizeVerified);
                tFile.SetStatus(datStatus, GotStatus.Got);

                if (eScanLevel == EScanLevel.Level3 && tFile.FileType == FileType.File)
                {
                    FromAFile(tFile, fullDir, eScanLevel, bgw, ref fileErrorAbort);
                }

                fileDir.ChildAdd(tFile);
            }
            return(fileDir);
        }
Пример #4
0
        private static void Compare(RvFile dbDir, RvFile 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 fileDir we mark that file in dbDir as missing.
            // if we find extra files in fileDir 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)
            {
                RvFile dbChild   = null;
                RvFile fileChild = null;
                int    res       = 0;

                if (dbIndex < dbDir.ChildCount && fileIndex < fileDir.ChildCount)
                {
                    dbChild   = dbDir.Child(dbIndex);
                    fileChild = fileDir.Child(fileIndex);
                    //Debug.WriteLine($@"{dbChild.Name} , {fileChild.Name}");
                    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;
                            _thWrk.Report(new bgwValue2(fileIndex + 1));
                            _thWrk.Report(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("Error in File Scanning Code.");
                        break;
                    }

                    //Complete MultiName Compare
                    List <RvFile> dbs        = new List <RvFile>();
                    List <RvFile> files      = new List <RvFile>();
                    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;
                    }

                    bool caseTest = files.Count > 1;
                    // if we only have one file, we don't need to test twice.
                    // so we need to do a case sensitive match first and then a case insensitive match
                    // indexCase=0 means do full case filename test
                    // indexCase=1 means do case insensitive test
                    for (int indexCase = (caseTest ? 0 : 1); indexCase < 2; indexCase += 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 = Scanner.Compare.Phase1Test(dbs[indexdb], files[indexfile], EScanLevel, indexCase, out bool matchedAlt);
                                if (!matched)
                                {
                                    continue;
                                }

                                MatchFound(dbs[indexdb], files[indexfile], matchedAlt);
                                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 = Scanner.Compare.Phase2Test(dbs[indexdb], files[indexfile], EScanLevel, indexCase, fullDir, _thWrk, ref _fileErrorAbort, out bool matchedAlt);
                                if (!matched)
                                {
                                    continue;
                                }

                                MatchFound(dbs[indexdb], files[indexfile], matchedAlt);
                                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;
                        }
                        if (NewFileFound(files[indexfile], dbDir, dbIndex))
                        {
                            dbIndex++;
                        }
                    }

                    fileIndex += filesCount;
                    break;

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

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

                if (_fileErrorAbort)
                {
                    return;
                }
                if (enableCancel && !DBTypeGet.isCompressedDir(ft) && _thWrk.CancellationPending)
                {
                    return;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Called from 5 places:
        /// 1: ScanFiles: main top level loop.
        /// 2: MatchFound: called after a ZIP/SevenZip is matched to an item in the DB, where the zip has either changed or never been scanned or level 3 scanning
        /// 3: MatchFound: called when an directory is matched to an item in the DB that is not from a DAT. (This is a directory not found in the main tree, as main tree dir's are processes in top level loop
        /// 4: NewFileFound: called after a new unmatched ZIP/SevenZip is found.
        /// 5: NewFileFound: called after a new unmatched DIR is found.
        /// </summary>
        /// <param name="dbDir"></param>
        /// <param name="report"></param>
        private static void CheckADir(RvFile dbDir, bool report)
        {
            if (_cacheSaveTimer.Elapsed.TotalMinutes > Settings.rvSettings.CacheSaveTimePeriod)
            {
                _thWrk.Report("Saving Cache");
                DB.Write();
                _thWrk.Report("Saving Cache Complete");
                _cacheSaveTimer.Reset();
                _cacheSaveTimer.Start();
            }

            string fullDir = dbDir.FullName;

            if (report)
            {
                _thWrk.Report(new bgwText2(fullDir));
            }

            // 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.
            RvFile 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:
            case FileType.SevenZip:
                fileDir = Populate.FromAZipFile(dbDir, EScanLevel, _thWrk);
                break;

            case FileType.Dir:
                fileDir = Populate.FromADir(dbDir, EScanLevel, _thWrk, ref _fileErrorAbort);
                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)
            {
                _thWrk.Report(new bgwSetRange2(fileDir.ChildCount));

                _thWrk.Report(new bgwRange2Visible(true));
            }

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

            Compare(dbDir, fileDir, report, true);
        }
Пример #6
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;
                }
            }
        }
Пример #7
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);
        }
Пример #8
0
        private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode, FileType thisFileType)
        {
            if (gameNode.Attributes == null)
            {
                return;
            }

            RvDir parent = tDat;

            RvDir tDir = new RvDir(DBTypeGet.DirFromFile(thisFileType))
            {
                Name      = VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("name")),
                Game      = new RvGame(),
                Dat       = tDat.Dat,
                DatStatus = DatStatus.InDatCollect
            };


            tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));

            tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
            tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
            tDir.Game.AddData(RvGame.GameData.Year, VarFix.CleanFileName(gameNode.SelectSingleNode("year")));
            tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.CleanFileName(gameNode.SelectSingleNode("publisher")));



            RvDir tDirCHD = new RvDir(FileType.Dir)
            {
                Name      = VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("name")),
                Game      = new RvGame(),
                Dat       = tDat.Dat,
                DatStatus = DatStatus.InDatCollect
            };

            tDirCHD.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));

            tDirCHD.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
            tDirCHD.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
            tDirCHD.Game.AddData(RvGame.GameData.Year, VarFix.CleanFileName(gameNode.SelectSingleNode("year")));
            tDirCHD.Game.AddData(RvGame.GameData.Manufacturer, VarFix.CleanFileName(gameNode.SelectSingleNode("publisher")));



            int    index1;
            string testName  = tDir.Name;
            int    nameCount = 0;

            while (parent.ChildNameSearch(tDir, out index1) == 0)
            {
                tDir.Name = testName + "_" + nameCount;
                nameCount++;
            }
            tDirCHD.Name = tDir.Name;


            XmlNodeList partNodeList = gameNode.SelectNodes("part");

            if (partNodeList == null)
            {
                return;
            }

            for (int iP = 0; iP < partNodeList.Count; iP++)
            {
                _indexContinue = -1;
                XmlNodeList dataAreaNodeList = partNodeList[iP].SelectNodes("dataarea");
                if (dataAreaNodeList != null)
                {
                    for (int iD = 0; iD < dataAreaNodeList.Count; iD++)
                    {
                        XmlNodeList romNodeList = dataAreaNodeList[iD].SelectNodes("rom");
                        if (romNodeList != null)
                        {
                            for (int iR = 0; iR < romNodeList.Count; iR++)
                            {
                                LoadRomFromDat(ref tDir, romNodeList[iR], thisFileType);
                            }
                        }
                    }
                }
            }
            for (int iP = 0; iP < partNodeList.Count; iP++)
            {
                XmlNodeList diskAreaNodeList = partNodeList[iP].SelectNodes("diskarea");
                if (diskAreaNodeList != null)
                {
                    for (int iD = 0; iD < diskAreaNodeList.Count; iD++)
                    {
                        XmlNodeList romNodeList = diskAreaNodeList[iD].SelectNodes("disk");
                        if (romNodeList != null)
                        {
                            for (int iR = 0; iR < romNodeList.Count; iR++)
                            {
                                LoadDiskFromDat(ref tDirCHD, romNodeList[iR]);
                            }
                        }
                    }
                }
            }

            if (tDir.ChildCount > 0)
            {
                parent.ChildAdd(tDir, index1);
            }
            if (tDirCHD.ChildCount > 0)
            {
                parent.ChildAdd(tDirCHD, index1);
            }
        }
Пример #9
0
        public override void Read(BinaryReader br, List <RvDat> parentDirDats)
        {
            base.Read(br, parentDirDats);
            bool foundTree = br.ReadBoolean();

            if (foundTree)
            {
                Tree = new RvTreeRow();
                Tree.Read(br);
            }
            else
            {
                Tree = null;
            }

            bool foundGame = br.ReadBoolean();

            if (foundGame)
            {
                Game = new RvGame();
                Game.Read(br);
            }
            else
            {
                Game = null;
            }

            int count = br.ReadInt32();

            _dirDats.Clear();
            for (int i = 0; i < count; i++)
            {
                RvDat dat = new RvDat {
                    DatIndex = i
                };
                dat.Read(br);
                _dirDats.Add(dat);

                string datname = TreeFullName + @"\" + dat.GetData(RvDat.DatData.DatName);
                if ((datname.Length >= 9) && (datname.Substring(0, 9) == @"RomVault\"))
                {
                    datname = datname.Substring(9);
                }

                DB.Bgw.ReportProgress(0, new bgwText("Loading: " + datname));
                DB.Bgw.ReportProgress((int)br.BaseStream.Position);
            }
            if (_dirDats.Count > 0)
            {
                parentDirDats = _dirDats;
            }

            count = br.ReadInt32();
            _children.Clear();
            for (int i = 0; i < count; i++)
            {
                RvBase tChild = DBTypeGet.GetRvType((FileType)br.ReadByte());

                tChild.Parent = this;
                tChild.Read(br, parentDirDats);
                _children.Add(tChild);
            }

            if (DBTypeGet.isCompressedDir(FileType))
            {
                ZipStatus = (ZipStatus)br.ReadByte();
            }
        }
Пример #10
0
        public static RvFile FromADir(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort)
        {
            string    fullDir   = dbDir.FullName;
            DatStatus datStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat;

            RvFile fileDir = new RvFile(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)
            {
                RvFile tDir = new RvFile(FileType.Dir)
                {
                    Name             = dir.Name,
                    FileModTimeStamp = dir.LastWriteTime
                };
                tDir.SetStatus(datStatus, GotStatus.Got);
                fileDir.ChildAdd(tDir);
            }

            // add all the files into scanDir
            foreach (FileInfo oFile in oFiles)
            {
                string fName = oFile.Name;
                if (fName == "__RomVault.tmp")
                {
                    File.Delete(oFile.FullName);
                    continue;
                }
                string fExt = Path.GetExtension(oFile.Name);

                FileType ft = DBTypeGet.fromExtention(fExt);

                if (Settings.rvSettings.FilesOnly)
                {
                    ft = FileType.File;
                }

                RvFile tFile = new RvFile(ft)
                {
                    Name             = oFile.Name,
                    Size             = (ulong)oFile.Length,
                    FileModTimeStamp = oFile.LastWriteTime
                };
                tFile.FileStatusSet(FileStatus.SizeVerified);
                tFile.SetStatus(datStatus, GotStatus.Got);

                if (eScanLevel == EScanLevel.Level3 && tFile.FileType == FileType.File)
                {
                    FromAFile(tFile, fullDir, eScanLevel, bgw, ref fileErrorAbort);
                }

                fileDir.ChildAdd(tFile);

                /*
                 * // if we find a zip file add it as zip files.
                 * // else
                 * if (ft == FileType.File)
                 * {
                 * // 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
                 *
                 * errorCode = CHD.CheckFile(oFile, out tFile.AltSHA1, out tFile.AltMD5, out tFile.CHDVersion);
                 *
                 * if (errorCode == 0)
                 * {
                 *  if (tFile.AltSHA1 != null)
                 *  {
                 *      tFile.FileStatusSet(FileStatus.AltSHA1FromHeader);
                 *  }
                 *  if (tFile.AltMD5 != null)
                 *  {
                 *      tFile.FileStatusSet(FileStatus.AltMD5FromHeader);
                 *  }
                 *
                 *  // if we are scanning at Level3 then we get all the info here
                 *  if (EScanLevel == EScanLevel.Level3)
                 *  {
                 *      FileResults(fullDir, tFile);
                 *      ChdManCheck(fullDir, tFile);
                 *  }
                 * }
                 * else if (errorCode == 32)
                 * {
                 *  tFile.GotStatus = GotStatus.FileLocked;
                 *  _bgw.Report(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;
                 * }
                 * }
                 */
            }
            return(fileDir);
        }
Пример #11
0
        private static void LoadGameFromDat(ref RvDir tDat, XmlNode gameNode, FileType thisFileType)
        {
            if (gameNode.Attributes == null)
            {
                return;
            }

            RvDir parent = tDat;
            RvDir tDir;
            int   index1 = 0;

            string fullname = VarFix.CleanFullFileName(gameNode.Attributes.GetNamedItem("name"));

            if (_cleanFileNames)
            {
                fullname = fullname.Replace("/", "-");
            }
            else
            {
                while (fullname.Contains("/"))
                {
                    int    firstSlash = fullname.IndexOf("/", StringComparison.Ordinal);
                    string dir        = fullname.Substring(0, firstSlash);
                    dir = VarFix.CleanFileName(dir);

                    fullname = fullname.Substring(firstSlash + 1);
                    int index;
                    if (parent.ChildNameSearch(new RvDir(FileType.Dir)
                    {
                        Name = dir
                    }, out index) == 0)
                    {
                        parent = (RvDir)parent.Child(index);
                    }
                    else
                    {
                        RvDir tpDir = new RvDir(FileType.Dir)
                        {
                            Name      = dir,
                            DatStatus = DatStatus.InDatCollect,
                            Dat       = tDat.Dat,
                            Tree      = new RvTreeRow()
                        };
                        parent.ChildAdd(tpDir, index);
                        parent = tpDir;
                    }
                }
            }

            tDir = new RvDir(DBTypeGet.DirFromFile(thisFileType))
            {
                Name      = fullname,
                DatStatus = DatStatus.InDatCollect,
                Dat       = tDat.Dat
            };

            string testName  = tDir.Name;
            int    nameCount = 0;

            while (parent.ChildNameSearch(tDir, out index1) == 0)
            {
                tDir.Name = testName + "_" + nameCount;
                nameCount++;
            }

            tDir.Game = new RvGame();
            tDir.Game.AddData(RvGame.GameData.RomOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("romof")));
            tDir.Game.AddData(RvGame.GameData.Description, VarFix.String(gameNode.SelectSingleNode("description")));

            tDir.Game.AddData(RvGame.GameData.Sourcefile, VarFix.String(gameNode.Attributes.GetNamedItem("sourcefile")));
            tDir.Game.AddData(RvGame.GameData.IsBios, VarFix.String(gameNode.Attributes.GetNamedItem("isbios")));
            tDir.Game.AddData(RvGame.GameData.CloneOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("cloneof")));
            tDir.Game.AddData(RvGame.GameData.SampleOf, VarFix.CleanFileName(gameNode.Attributes.GetNamedItem("sampleof")));
            tDir.Game.AddData(RvGame.GameData.Board, VarFix.String(gameNode.Attributes.GetNamedItem("board")));
            tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(gameNode.SelectSingleNode("year")));
            tDir.Game.AddData(RvGame.GameData.Manufacturer, VarFix.String(gameNode.SelectSingleNode("manufacturer")));

            XmlNode trurip = gameNode.SelectSingleNode("trurip");

            if (trurip != null)
            {
                tDir.Game.AddData(RvGame.GameData.Trurip, "yes");
                tDir.Game.AddData(RvGame.GameData.Year, VarFix.String(trurip.SelectSingleNode("year")));
                tDir.Game.AddData(RvGame.GameData.Publisher, VarFix.String(trurip.SelectSingleNode("publisher")));
                tDir.Game.AddData(RvGame.GameData.Developer, VarFix.String(trurip.SelectSingleNode("developer")));
                tDir.Game.AddData(RvGame.GameData.Edition, VarFix.String(trurip.SelectSingleNode("edition")));
                tDir.Game.AddData(RvGame.GameData.Version, VarFix.String(trurip.SelectSingleNode("version")));
                tDir.Game.AddData(RvGame.GameData.Type, VarFix.String(trurip.SelectSingleNode("type")));
                tDir.Game.AddData(RvGame.GameData.Media, VarFix.String(trurip.SelectSingleNode("media")));
                tDir.Game.AddData(RvGame.GameData.Language, VarFix.String(trurip.SelectSingleNode("language")));
                tDir.Game.AddData(RvGame.GameData.Players, VarFix.String(trurip.SelectSingleNode("players")));
                tDir.Game.AddData(RvGame.GameData.Ratings, VarFix.String(trurip.SelectSingleNode("ratings")));
                tDir.Game.AddData(RvGame.GameData.Peripheral, VarFix.String(trurip.SelectSingleNode("peripheral")));
                tDir.Game.AddData(RvGame.GameData.Genre, VarFix.String(trurip.SelectSingleNode("genre")));
                tDir.Game.AddData(RvGame.GameData.MediaCatalogNumber, VarFix.String(trurip.SelectSingleNode("mediacatalognumber")));
                tDir.Game.AddData(RvGame.GameData.BarCode, VarFix.String(trurip.SelectSingleNode("barcode")));
            }

            RvDir tDirCHD = new RvDir(FileType.Dir)
            {
                Name      = tDir.Name,
                DatStatus = tDir.DatStatus,
                Dat       = tDir.Dat,
                Game      = tDir.Game
            };

            XmlNodeList romNodeList = gameNode.SelectNodes("rom");

            if (romNodeList != null)
            {
                for (int i = 0; i < romNodeList.Count; i++)
                {
                    LoadRomFromDat(ref tDir, romNodeList[i], thisFileType);
                }
            }

            XmlNodeList diskNodeList = gameNode.SelectNodes("disk");

            if (diskNodeList != null)
            {
                for (int i = 0; i < diskNodeList.Count; i++)
                {
                    LoadDiskFromDat(ref tDirCHD, diskNodeList[i]);
                }
            }

            if (tDir.ChildCount > 0)
            {
                parent.ChildAdd(tDir, index1);
            }
            if (tDirCHD.ChildCount > 0)
            {
                parent.ChildAdd(tDirCHD);
            }
        }
Пример #12
0
        private static ReturnCode OpenInputStream(RvFile fileIn, bool rawCopy, out ICompress zipFileIn, out bool sourceTrrntzip, out Stream readStream, out ulong streamSize, out ushort compressionMethod, out string error)
        {
            zipFileIn         = null;
            sourceTrrntzip    = false;
            readStream        = null;
            streamSize        = 0;
            compressionMethod = 0;

            if (fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) // Input is a ZipFile
            {
                RvFile zZipFileIn = fileIn.Parent;
                if (zZipFileIn.FileType != DBTypeGet.DirFromFile(fileIn.FileType))
                {
                    error = "File Open but Source File is not correct type, Logic Error.";
                    return(ReturnCode.LogicError);
                }

                string    fileNameIn = zZipFileIn.FullNameCase;
                ZipReturn zr1;


                if (zZipFileIn.FileType == FileType.SevenZip)
                {
                    sourceTrrntzip = false;
                    zipFileIn      = new SevenZ();
                    zr1            = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.FileModTimeStamp);
                }
                else
                {
                    sourceTrrntzip = (zZipFileIn.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip;
                    zipFileIn      = new Zip();
                    zr1            = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.FileModTimeStamp, fileIn.ZipFileHeaderPosition == null);
                }

                switch (zr1)
                {
                case ZipReturn.ZipGood:
                    break;

                case ZipReturn.ZipErrorFileNotFound:
                    error = "File not found, Rescan required before fixing " + fileIn.Name;
                    return(ReturnCode.RescanNeeded);

                case ZipReturn.ZipErrorTimeStamp:
                    error = "File has changed, Rescan required before fixing " + fileIn.Name;
                    return(ReturnCode.RescanNeeded);

                default:
                    error = "Error Open Zip" + zr1 + ", with File " + fileIn.DatTreeFullName;
                    return(ReturnCode.FileSystemError);
                }

                if (fileIn.FileType == FileType.SevenZipFile)
                {
                    ((SevenZ)zipFileIn).ZipFileOpenReadStream(fileIn.ZipFileIndex, out readStream, out streamSize);
                }
                else
                {
                    if (fileIn.ZipFileHeaderPosition != null)
                    {
                        ((Zip)zipFileIn).ZipFileOpenReadStreamQuick((ulong)fileIn.ZipFileHeaderPosition, rawCopy, out readStream, out streamSize, out compressionMethod);
                    }
                    else
                    {
                        ((Zip)zipFileIn).ZipFileOpenReadStream(fileIn.ZipFileIndex, rawCopy, out readStream, out streamSize, out compressionMethod);
                    }
                }
            }
            else // Input is a regular file
            {
                string fileNameIn = fileIn.FullName;
                if (!File.Exists(fileNameIn))
                {
                    error = "Rescan needed, File Not Found :" + fileNameIn;
                    return(ReturnCode.RescanNeeded);
                }
                FileInfo fileInInfo = new FileInfo(fileNameIn);
                if (fileInInfo.LastWriteTime != fileIn.FileModTimeStamp)
                {
                    error = "Rescan needed, File Changed :" + fileNameIn;
                    return(ReturnCode.RescanNeeded);
                }
                int errorCode = FileStream.OpenFileRead(fileNameIn, out readStream);
                if (errorCode != 0)
                {
                    error = new Win32Exception(errorCode).Message + ". " + fileNameIn;
                    return(ReturnCode.FileSystemError);
                }
                if (fileIn.Size == null)
                {
                    error = "Null File Size found in Fixing File :" + fileNameIn;
                    return(ReturnCode.LogicError);
                }
                streamSize = (ulong)fileIn.Size;
                if ((ulong)readStream.Length != streamSize)
                {
                    error = "Rescan needed, File Length Changed :" + fileNameIn;
                    return(ReturnCode.RescanNeeded);
                }
            }

            error = "";
            return(ReturnCode.Good);
        }
Пример #13
0
        public static ReturnCode FixZip(RvFile fixZip, List <RvFile> fileProcessQueue, ref int totalFixed, out string errorMessage)
        {
            errorMessage = "";

            //Check for error status
            if (fixZip.DirStatus.HasUnknown())
            {
                return(ReturnCode.FindFixes); // Error
            }
            bool needsTrrntzipped = fixZip.ZipStatus != ZipStatus.TrrntZip && fixZip.GotStatus == GotStatus.Got && fixZip.DatStatus == DatStatus.InDatCollect && (Settings.rvSettings.FixLevel == EFixLevel.TrrntZipLevel1 || Settings.rvSettings.FixLevel == EFixLevel.TrrntZipLevel2 || Settings.rvSettings.FixLevel == EFixLevel.TrrntZipLevel3);

            // file corrupt and not in tosort
            //      if file cannot be fully fixed copy to corrupt
            //      process zipfile

            if (fixZip.GotStatus == GotStatus.Corrupt && fixZip.DatStatus != DatStatus.InToSort && !fixZip.DirStatus.HasFixable())
            {
                ReturnCode moveReturnCode = FixAZipFunctions.MoveZipToCorrupt(fixZip, out errorMessage);
                if (moveReturnCode != ReturnCode.Good)
                {
                    return(moveReturnCode);
                }
            }

            // has fixable
            //      process zipfile

            else if (fixZip.DirStatus.HasFixable())
            {
                // do nothing here but continue on to process zip.
            }

            // need trrntzipped
            //      process zipfile

            else if (needsTrrntzipped)
            {
                // rv7Zip format is not finalized yet so do not use
                if (!Settings.rvSettings.ConvertToRV7Z && (fixZip.FileType == FileType.SevenZip))
                //if (fixZip.FileType == FileType.SevenZip)
                {
                    needsTrrntzipped = false;
                }
                // do nothing here but continue on to process zip.
            }


            // got empty zip that should be deleted
            //      process zipfile
            else if (fixZip.GotStatus == GotStatus.Got && fixZip.GotStatus != GotStatus.Corrupt && !fixZip.DirStatus.HasAnyFiles())
            {
                // do nothing here but continue on to process zip.
            }

            // else
            //      skip this zipfile
            else
            {
                // nothing can be done to return
                return(ReturnCode.Good);
            }

            if (!fixZip.DirStatus.HasFixable() && !needsTrrntzipped)
            {
                return(ReturnCode.Good);
            }

            string fixZipFullName = fixZip.TreeFullName;

            if (!fixZip.DirStatus.HasFixable() && needsTrrntzipped)
            {
                Report.ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), "", 0, "TrrntZipping", "", "", ""));
            }


            FixFileUtils.CheckCreateDirectories(fixZip.Parent);

            string filename = fixZip.FullName;

            if (fixZip.GotStatus == GotStatus.NotGot)
            {
                if (File.Exists(filename))
                {
                    errorMessage = "Unexpected file found in directory. Rescan needed.\n" + filename;
                    return(ReturnCode.RescanNeeded);
                }
            }

            ReportError.LogOut("");
            ReportError.LogOut(fixZipFullName + " : " + fixZip.RepStatus);
            ReportError.LogOut("------------------------------------------------------------");
            Debug.WriteLine(fixZipFullName + " : " + fixZip.RepStatus);
            ReportError.LogOut("Zip File Status Before Fix:");
            for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++)
            {
                ReportError.LogOut(fixZip.Child(intLoop));
            }
            ReportError.LogOut("");

            ReturnCode returnCode    = ReturnCode.Good;
            RepStatus  fileRepStatus = RepStatus.UnSet;

            ICompress tempFixZip       = null;
            ICompress toSortCorruptOut = null;
            ICompress toSortZipOut     = null;

            try
            {
                RvFile toSortGame        = null;
                RvFile toSortCorruptGame = null;

                List <RvFile> fixZipTemp = new List <RvFile>();

                FileType fixFileType = fixZip.FileType;

                for (int iRom = 0; iRom < fixZip.ChildCount; iRom++)
                {
                    RvFile fixZippedFile = new RvFile(DBTypeGet.FileFromDir(fixFileType));
                    fixZip.Child(iRom).CopyTo(fixZippedFile);

                    fixZipTemp.Add(fixZippedFile);

                    ReportError.LogOut(fixZippedFile.RepStatus + " : " + fixZip.Child(iRom).FullName);

                    fileRepStatus = fixZippedFile.RepStatus;
                    switch (fixZippedFile.RepStatus)
                    {
                        #region Nothing to copy

                    // any file we do not have or do not want in the destination zip
                    case RepStatus.Missing:
                    case RepStatus.NotCollected:
                    case RepStatus.Rename:
                    case RepStatus.Delete:
                        if (!
                            (
                                // got the file in the original zip but will be deleting it
                                fixZippedFile.DatStatus == DatStatus.NotInDat && fixZippedFile.GotStatus == GotStatus.Got ||
                                fixZippedFile.DatStatus == DatStatus.NotInDat && fixZippedFile.GotStatus == GotStatus.Corrupt ||
                                fixZippedFile.DatStatus == DatStatus.InDatMerged && fixZippedFile.GotStatus == GotStatus.Got ||
                                fixZippedFile.DatStatus == DatStatus.InToSort && fixZippedFile.GotStatus == GotStatus.Got ||
                                fixZippedFile.DatStatus == DatStatus.InToSort && fixZippedFile.GotStatus == GotStatus.Corrupt ||

                                // do not have this file and cannot fix it here
                                fixZippedFile.DatStatus == DatStatus.InDatCollect && fixZippedFile.GotStatus == GotStatus.NotGot ||
                                fixZippedFile.DatStatus == DatStatus.InDatBad && fixZippedFile.GotStatus == GotStatus.NotGot ||
                                fixZippedFile.DatStatus == DatStatus.InDatMerged && fixZippedFile.GotStatus == GotStatus.NotGot
                            )
                            )
                        {
                            ReportError.SendAndShow("Error in Fix Rom Status " + fixZippedFile.RepStatus + " : " +
                                                    fixZippedFile.DatStatus + " : " + fixZippedFile.GotStatus);
                        }

                        if (fixZippedFile.RepStatus == RepStatus.Delete)
                        {
                            if (Settings.rvSettings.DetailedFixReporting)
                            {
                                Report.ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), fixZippedFile.Name, fixZippedFile.Size, "Delete", "", "", ""));
                            }

                            returnCode = FixFileUtils.DoubleCheckDelete(fixZippedFile, out errorMessage);
                            if (returnCode != ReturnCode.Good)
                            {
                                CloseZipFile(ref tempFixZip);
                                CloseToSortGame(toSortGame, ref toSortZipOut);
                                CloseToSortCorruptGame(toSortGame, ref toSortZipOut);
                                return(returnCode);
                            }
                        }

                        fixZippedFile.GotStatus = GotStatus.NotGot;
                        break;

                        #endregion


                    // any files we are just moving from the original zip to the destination zip
                    case RepStatus.Correct:
                    case RepStatus.InToSort:
                    case RepStatus.NeededForFix:
                    case RepStatus.Corrupt:
                    {
                        returnCode = FixAZipFunctions.CorrectZipFile(fixZip, fixZippedFile, ref tempFixZip, iRom, fileProcessQueue, out errorMessage);
                        if (returnCode != ReturnCode.Good)
                        {
                            CloseZipFile(ref tempFixZip);
                            CloseToSortGame(toSortGame, ref toSortZipOut);
                            CloseToSortCorruptGame(toSortGame, ref toSortZipOut);
                            return(returnCode);
                        }
                        break;
                    }

                    case RepStatus.CanBeFixed:
                    case RepStatus.CorruptCanBeFixed:
                    {
                        returnCode = FixAZipFunctions.CanBeFixed(fixZip, fixZippedFile, ref tempFixZip, fileProcessQueue, ref totalFixed, out errorMessage);
                        if (returnCode != ReturnCode.Good)
                        {
                            CloseZipFile(ref tempFixZip);
                            CloseToSortGame(toSortGame, ref toSortZipOut);
                            CloseToSortCorruptGame(toSortGame, ref toSortZipOut);
                            return(returnCode);
                        }
                        break;
                    }

                    case RepStatus.MoveToSort:
                    {
                        returnCode = FixAZipFunctions.MovetoSort(fixZip, fixZippedFile, ref toSortGame, ref toSortZipOut, iRom);
                        if (returnCode != ReturnCode.Good)
                        {
                            CloseZipFile(ref tempFixZip);
                            CloseToSortGame(toSortGame, ref toSortZipOut);
                            CloseToSortCorruptGame(toSortGame, ref toSortZipOut);
                            return(returnCode);
                        }
                        break;
                    }

                    case RepStatus.MoveToCorrupt:
                        FixAZipFunctions.MoveToCorrupt(fixZip, fixZippedFile, ref toSortCorruptGame, ref toSortCorruptOut, iRom);
                        break;

                    default:
                        ReportError.UnhandledExceptionHandler(
                            "Unknown file status found " + fixZippedFile.RepStatus + " while fixing file " +
                            fixZip.Name + " Dat Status = " + fixZippedFile.DatStatus + " GotStatus " +
                            fixZippedFile.GotStatus);
                        break;
                    }
                }

                //if ToSort Zip Made then close the zip and add this new zip to the Database
                CloseToSortGame(toSortGame, ref toSortZipOut);

                //if Corrupt Zip Made then close the zip and add this new zip to the Database
                CloseToSortCorruptGame(toSortCorruptGame, ref toSortCorruptOut);

                #region Process original Zip

                if (File.Exists(filename))
                {
                    if (!File.SetAttributes(filename, FileAttributes.Normal))
                    {
                        int error = Error.GetLastError();
                        Report.ReportProgress(new bgwShowError(filename,
                                                               "Error Setting File Attributes to Normal. Deleting Original Fix File. Code " + error));
                    }

                    try
                    {
                        File.Delete(filename);
                    }
                    catch (Exception e)
                    {
                        errorMessage = "Error While trying to delete file " + filename + ". " + e.Message;

                        if (tempFixZip != null && tempFixZip.ZipOpen != ZipOpenType.Closed)
                        {
                            tempFixZip.ZipFileClose();
                            tempFixZip = null;
                        }

                        return(ReturnCode.RescanNeeded);
                    }
                }

                #endregion

                bool checkDelete = false;

                #region process the temp Zip rename it to the original Zip

                if (tempFixZip != null && tempFixZip.ZipOpen != ZipOpenType.Closed)
                {
                    string tempFilename = tempFixZip.ZipFilename;
                    tempFixZip.ZipFileClose();

                    if (tempFixZip.LocalFilesCount() > 0)
                    {
                        // now rename the temp fix file to the correct filename
                        File.Move(tempFilename, filename);
                        FileInfo nFile  = new FileInfo(filename);
                        RvFile   tmpZip = new RvFile(FileType.Zip)
                        {
                            Name             = Path.GetFileName(filename),
                            FileModTimeStamp = nFile.LastWriteTime
                        };
                        tmpZip.SetStatus(fixZip.DatStatus, GotStatus.Got);

                        fixZip.FileAdd(tmpZip, false);
                        fixZip.ZipStatus = tempFixZip.ZipStatus;
                    }
                    else
                    {
                        File.Delete(tempFilename);
                        checkDelete = true;
                    }

                    tempFixZip = null;
                }
                else
                {
                    checkDelete = true;
                }

                #endregion

                #region Now put the New Game Status information into the Database.

                int intLoopFix = 0;
                foreach (RvFile tmpZip in fixZipTemp)
                {
                    tmpZip.CopyTo(fixZip.Child(intLoopFix));

                    if (fixZip.Child(intLoopFix).RepStatus == RepStatus.Deleted)
                    {
                        if (fixZip.Child(intLoopFix).FileRemove() == EFile.Delete)
                        {
                            fixZip.ChildRemove(intLoopFix);
                            continue;
                        }
                    }

                    intLoopFix++;
                }

                #endregion

                if (checkDelete)
                {
                    FixFileUtils.CheckDeleteFile(fixZip);
                }

                ReportError.LogOut("");
                ReportError.LogOut("Zip File Status After Fix:");
                for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++)
                {
                    ReportError.LogOut(fixZip.Child(intLoop));
                }

                ReportError.LogOut("");

                return(ReturnCode.Good);
            }
            catch (ZipFileException ex)
            {
                tempFixZip?.ZipFileCloseFailed();
                toSortZipOut?.ZipFileCloseFailed();
                toSortCorruptOut?.ZipFileCloseFailed();
                tempFixZip       = null;
                toSortZipOut     = null;
                toSortCorruptOut = null;

                errorMessage = ex.Message;
                return(ex.returnCode);
            }
            catch (Exception ex)
            {
                tempFixZip?.ZipFileCloseFailed();
                toSortZipOut?.ZipFileCloseFailed();
                toSortCorruptOut?.ZipFileCloseFailed();
                tempFixZip       = null;
                toSortZipOut     = null;
                toSortCorruptOut = null;

                errorMessage = ex.Message;
                return(ReturnCode.LogicError);
            }
            finally
            {
                if (tempFixZip != null)
                {
                    ReportError.UnhandledExceptionHandler($"{tempFixZip.ZipFilename} tempZipOut was left open, ZipFile= {fixZipFullName} , fileRepStatus= {fileRepStatus} , returnCode= {returnCode}");
                }
                if (toSortZipOut != null)
                {
                    ReportError.UnhandledExceptionHandler($"{toSortZipOut.ZipFilename} toSortZipOut was left open");
                }
                if (toSortCorruptOut != null)
                {
                    ReportError.UnhandledExceptionHandler($"{toSortCorruptOut.ZipFilename} toSortCorruptOut was left open");
                }
            }
        }