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(); }
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); }