Example #1
0
        public static void FromAFile(RvFile file, string directory, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort)
        {
            _bgw = bgw;
            string    filename   = Path.Combine(directory, string.IsNullOrWhiteSpace(file.FileName) ? file.Name : file.FileName);
            ICompress fileToScan = new Compress.File.File();
            ZipReturn zr         = fileToScan.ZipFileOpen(filename, file.FileModTimeStamp);

            if (zr == ZipReturn.ZipFileLocked)
            {
                file.GotStatus = GotStatus.FileLocked;
                return;
            }

            if (zr != ZipReturn.ZipGood)
            {
                ReportError.Show("File: " + filename + " Error: " + zr + ". Scan Aborted.");
                file.GotStatus = GotStatus.FileLocked;
                fileErrorAbort = true;
                return;
            }

            if (_fs == null)
            {
                _fs = new FileScan();
            }
            List <FileScan.FileResults> fr = _fs.Scan(fileToScan, true, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3);

            file.HeaderFileType = fr[0].HeaderFileType;
            file.Size           = fr[0].Size;
            file.CRC            = fr[0].CRC;
            file.SHA1           = fr[0].SHA1;
            file.MD5            = fr[0].MD5;
            file.AltSize        = fr[0].AltSize;
            file.AltCRC         = fr[0].AltCRC;
            file.AltSHA1        = fr[0].AltSHA1;
            file.AltMD5         = fr[0].AltMD5;


            file.FileStatusSet(
                FileStatus.SizeVerified |
                (file.HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) |
                (file.CRC != null ? FileStatus.CRCVerified : 0) |
                (file.SHA1 != null ? FileStatus.SHA1Verified : 0) |
                (file.MD5 != null ? FileStatus.MD5Verified : 0) |
                (file.AltSize != null ? FileStatus.AltSizeVerified : 0) |
                (file.AltCRC != null ? FileStatus.AltCRCVerified : 0) |
                (file.AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) |
                (file.AltMD5 != null ? FileStatus.AltMD5Verified : 0)
                );

            if (fr[0].HeaderFileType == HeaderFileType.CHD)
            {
                bool deepCheck = (eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3);
                CHD.fileProcess     = FileProcess;
                CHD.fileProgress    = FileProgress;
                CHD.fileSystemError = FileSystemError;
                CHD.fileError       = FileError;
                CHD.generalError    = GeneralError;
                hdErr result = CHD.CheckFile(file.Name, directory, Settings.isLinux, ref deepCheck, out uint?chdVersion, out byte[] chdSHA1, out byte[] chdMD5, ref fileErrorAbort);
                switch (result)
                {
                case hdErr.HDERR_NONE:
                    file.CHDVersion = chdVersion;
                    if (chdSHA1 != null)
                    {
                        file.AltSHA1 = chdSHA1;
                        file.FileStatusSet(FileStatus.AltSHA1FromHeader);
                        if (deepCheck)
                        {
                            file.FileStatusSet(FileStatus.AltSHA1Verified);
                        }
                    }

                    if (chdMD5 != null)
                    {
                        file.AltMD5 = chdMD5;
                        file.FileStatusSet(FileStatus.AltMD5FromHeader);
                        if (deepCheck)
                        {
                            file.FileStatusSet(FileStatus.AltMD5Verified);
                        }
                    }
                    break;

                case hdErr.HDERR_OUT_OF_MEMORY:
                case hdErr.HDERR_INVALID_FILE:
                case hdErr.HDERR_INVALID_DATA:
                case hdErr.HDERR_READ_ERROR:
                case hdErr.HDERR_DECOMPRESSION_ERROR:
                case hdErr.HDERR_CANT_VERIFY:
                    file.GotStatus = GotStatus.Corrupt;
                    break;

                default:
                    ReportError.UnhandledExceptionHandler(result.ToString());
                    break;
                }
            }
            fileToScan.ZipFileClose();
        }
Example #2
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);
        }