private static ReturnCode CheckInputAndOutputFile(RvFile fileIn, RvFile fileOut, out string error) { // need to check for matching headers types here also. if (fileOut.FileStatusIs(FileStatus.SizeFromDAT) && fileOut.Size != null && fileIn.Size != fileOut.Size) { error = "Source and destination Size does not match. Logic Error."; return(ReturnCode.LogicError); } if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.BCompare(fileIn.CRC, fileOut.CRC)) { error = "Source and destination CRC does not match. Logic Error."; return(ReturnCode.LogicError); } if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileIn.FileStatusIs(FileStatus.SHA1Verified)) { if (fileIn.SHA1 != null && fileOut.SHA1 != null && !ArrByte.BCompare(fileIn.SHA1, fileOut.SHA1)) { error = "Source and destination SHA1 does not match. Logic Error."; return(ReturnCode.LogicError); } } if (fileOut.FileStatusIs(FileStatus.MD5FromDAT) && fileIn.FileStatusIs(FileStatus.MD5Verified)) { if (fileIn.MD5 != null && fileOut.MD5 != null && !ArrByte.BCompare(fileIn.MD5, fileOut.MD5)) { error = "Source and destination SHA1 does not match. Logic Error."; return(ReturnCode.LogicError); } } error = ""; return(ReturnCode.Good); }
public static ReturnCode DecompressSource7ZipFile(RvFile db7zFile, bool includeGood, out string error) { // this just checks for one file, should be changed to chek for one got file. if (db7zFile.ChildCount == 1) { error = "Single File"; return(ReturnCode.Good); } byte[] buffer = new byte[BufferSize]; RvFile cacheDir = DB.RvFileCache(); SevenZ sevenZipFileCaching = new SevenZ(); ZipReturn zr1 = sevenZipFileCaching.ZipFileOpen(db7zFile.FullNameCase, db7zFile.FileModTimeStamp, true); if (zr1 != ZipReturn.ZipGood) { error = "Error opening 7zip file for caching"; return(ReturnCode.RescanNeeded); } RvFile outDir = new RvFile(FileType.Dir) { Name = db7zFile.Name + ".cache", Parent = cacheDir, DatStatus = DatStatus.InToSort, GotStatus = GotStatus.Got }; int nameDirIndex = 0; while (cacheDir.ChildNameSearch(outDir, out int index) == 0) { nameDirIndex++; outDir.Name = db7zFile.Name + ".cache (" + nameDirIndex + ")"; } cacheDir.ChildAdd(outDir); Directory.CreateDirectory(outDir.FullName); for (int i = 0; i < sevenZipFileCaching.LocalFilesCount(); i++) { if (sevenZipFileCaching.GetLocalFile(i).IsDirectory) { continue; } RvFile thisFile = null; for (int j = 0; j < db7zFile.ChildCount; j++) { if (db7zFile.Child(j).ZipFileIndex != i) { continue; } thisFile = db7zFile.Child(j); break; } if (thisFile == null) { error = "Error opening 7zip file for caching"; return(ReturnCode.RescanNeeded); } bool extract = true; // first check to see if we have a file version of this compressed file somewhere else. foreach (RvFile f in thisFile.FileGroup.Files) { if (f.FileType == FileType.File && f.GotStatus == GotStatus.Got) { extract = false; } } if (!extract) { continue; } extract = false; if (includeGood) { // if this is the file we are fixing then pull out the correct files. if (thisFile.RepStatus == RepStatus.Correct || thisFile.RepStatus == RepStatus.InToSort || thisFile.RepStatus == RepStatus.MoveToSort) { extract = true; } } // next check to see if we need this extracted to fix another file foreach (RvFile f in thisFile.FileGroup.Files) { if (f.RepStatus == RepStatus.CanBeFixed) { extract = true; break; } } if (!extract) { continue; } string cleanedName = thisFile.Name; cleanedName = cleanedName.Replace("/", "-"); cleanedName = cleanedName.Replace("\\", "-"); if (cleanedName.Length >= 248) { string mainName = Path.GetFileNameWithoutExtension(cleanedName); string extName = Path.GetExtension(cleanedName); mainName = mainName.Substring(0, 248 - extName.Length); cleanedName = mainName + extName; } RvFile outFile = new RvFile(FileType.File) { Name = cleanedName, Size = thisFile.Size, CRC = thisFile.CRC, SHA1 = thisFile.SHA1, MD5 = thisFile.MD5, GotStatus = GotStatus.Got, HeaderFileType = thisFile.HeaderFileType, AltSize = thisFile.AltSize, AltCRC = thisFile.AltCRC, AltSHA1 = thisFile.AltSHA1, AltMD5 = thisFile.AltMD5, FileGroup = thisFile.FileGroup }; int tryname = 0; while (outDir.ChildNameSearch(outFile, out int index) == 0) { tryname += 1; string mainName = Path.GetFileNameWithoutExtension(cleanedName); string extName = Path.GetExtension(cleanedName); cleanedName = mainName + $"_{tryname}" + extName; outFile.Name = cleanedName; } outFile.SetStatus(DatStatus.InToSort, GotStatus.Got); outFile.FileStatusSet( FileStatus.HeaderFileTypeFromHeader | FileStatus.SizeFromHeader | FileStatus.SizeVerified | FileStatus.CRCFromHeader | FileStatus.CRCVerified | FileStatus.SHA1FromHeader | FileStatus.SHA1Verified | FileStatus.MD5FromHeader | FileStatus.MD5Verified | FileStatus.AltSizeFromHeader | FileStatus.AltSizeVerified | FileStatus.AltCRCFromHeader | FileStatus.AltCRCVerified | FileStatus.AltSHA1FromHeader | FileStatus.AltSHA1Verified | FileStatus.AltMD5FromHeader | FileStatus.AltMD5Verified , thisFile); outFile.RepStatus = RepStatus.NeededForFix; sevenZipFileCaching.ZipFileOpenReadStream(i, out Stream readStream, out ulong unCompressedSize); string filenameOut = Path.Combine(outDir.FullName, outFile.Name); if (Settings.rvSettings.DetailedFixReporting) { string fixZipFullName = db7zFile.TreeFullName; Report.ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), thisFile.Name, thisFile.Size, "-->", outDir.FullName, "", outFile.Name)); } ThreadMD5 tmd5 = null; ThreadSHA1 tsha1 = null; ThreadCRC tcrc32 = new ThreadCRC(); if (Settings.rvSettings.FixLevel != EFixLevel.Level1) { tmd5 = new ThreadMD5(); tsha1 = new ThreadSHA1(); } int errorCode = FileStream.OpenFileWrite(filenameOut, out Stream writeStream); ulong sizetogo = unCompressedSize; while (sizetogo > 0) { int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo; try { readStream.Read(buffer, 0, sizenow); } catch (Exception ex) { if (ex is ZlibException || ex is DataErrorException) { ZipReturn zr = sevenZipFileCaching.ZipFileCloseReadStream(); if (zr != ZipReturn.ZipGood) { error = "Error Closing " + zr + " Stream :" + sevenZipFileCaching.ZipFilename; return(ReturnCode.FileSystemError); } sevenZipFileCaching.ZipFileClose(); writeStream.Flush(); writeStream.Close(); if (filenameOut != null) { File.Delete(filenameOut); } thisFile.GotStatus = GotStatus.Corrupt; error = "Unexpected corrupt archive file found:\n" + db7zFile.FullName + "\nRun Find Fixes, and Fix to continue fixing correctly."; return(ReturnCode.SourceDataStreamCorrupt); } error = "Error reading Source File " + ex.Message; return(ReturnCode.FileSystemError); } tcrc32.Trigger(buffer, sizenow); tmd5?.Trigger(buffer, sizenow); tsha1?.Trigger(buffer, sizenow); try { writeStream.Write(buffer, 0, sizenow); } catch (Exception e) { error = "Error writing out file. " + Environment.NewLine + e.Message; return(ReturnCode.FileSystemError); } tcrc32.Wait(); tmd5?.Wait(); tsha1?.Wait(); sizetogo = sizetogo - (ulong)sizenow; } writeStream.Flush(); writeStream.Close(); writeStream.Dispose(); tcrc32.Finish(); tmd5?.Finish(); tsha1?.Finish(); byte[] bCRC = tcrc32.Hash; byte[] bMD5 = tmd5?.Hash; byte[] bSHA1 = tsha1?.Hash; tcrc32.Dispose(); tmd5?.Dispose(); tsha1?.Dispose(); FileInfo fi = new FileInfo(filenameOut); outFile.FileModTimeStamp = fi.LastWriteTime; if (bCRC != null && thisFile.CRC != null && !ArrByte.BCompare(bCRC, thisFile.CRC)) { // error in file. error = "Error found in cache extract CRC"; return(ReturnCode.SourceCheckSumMismatch); } if (bMD5 != null && thisFile.MD5 != null && !ArrByte.BCompare(bMD5, thisFile.MD5)) { // error in file. error = "Error found in cache extract MD5"; return(ReturnCode.SourceCheckSumMismatch); } if (bSHA1 != null && thisFile.SHA1 != null && !ArrByte.BCompare(bSHA1, thisFile.SHA1)) { // error in file. error = "Error found in cache extract SHA1"; return(ReturnCode.SourceCheckSumMismatch); } thisFile.FileGroup.Files.Add(outFile); outDir.ChildAdd(outFile); } sevenZipFileCaching.ZipFileClose(); error = ""; return(ReturnCode.Good); }
private static ReturnCode ValidateFileOut(RvFile fileIn, RvFile fileOut, bool rawCopy, byte[] bCRC, byte[] bSHA1, byte[] bMD5, out string error) { if (fileOut.FileType == FileType.ZipFile || fileOut.FileType == FileType.SevenZipFile) { fileOut.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader); } if (fileOut.FileStatusIs(FileStatus.CRCFromDAT) && fileOut.CRC != null && !ArrByte.BCompare(fileOut.CRC, bCRC)) { error = "CRC checksum error. Level 2 scan your files"; return(ReturnCode.DestinationCheckSumMismatch); } fileOut.CRC = bCRC; if (!rawCopy || fileIn.FileStatusIs(FileStatus.CRCVerified)) { fileOut.FileStatusSet(FileStatus.CRCVerified); } if (bSHA1 != null) { if (fileOut.FileStatusIs(FileStatus.SHA1FromDAT) && fileOut.SHA1 != null && !ArrByte.BCompare(fileOut.SHA1, bSHA1)) { error = "SHA1 checksum error. Level 2 scan your files"; return(ReturnCode.DestinationCheckSumMismatch); } fileOut.SHA1 = bSHA1; fileOut.FileStatusSet(FileStatus.SHA1Verified); } if (bMD5 != null) { if (fileOut.FileStatusIs(FileStatus.MD5FromDAT) && fileOut.MD5 != null && !ArrByte.BCompare(fileOut.MD5, bMD5)) { error = "MD5 checksum error. Level 2 scan your files"; return(ReturnCode.DestinationCheckSumMismatch); } fileOut.MD5 = bMD5; fileOut.FileStatusSet(FileStatus.MD5Verified); } if (fileIn.Size != null) { fileOut.Size = fileIn.Size; fileOut.FileStatusSet(FileStatus.SizeVerified); } fileOut.GotStatus = fileIn.GotStatus == GotStatus.Corrupt ? GotStatus.Corrupt : GotStatus.Got; fileOut.FileStatusSet(FileStatus.SizeVerified); if (fileOut.AltSHA1 == null && fileIn.AltSHA1 != null) { fileOut.AltSHA1 = fileIn.AltSHA1; } if (fileOut.AltMD5 == null && fileIn.AltMD5 != null) { fileOut.AltMD5 = fileIn.AltMD5; } fileOut.CHDVersion = fileIn.CHDVersion; fileOut.FileStatusSet(FileStatus.AltSHA1FromHeader | FileStatus.AltMD5FromHeader | FileStatus.AltSHA1Verified | FileStatus.AltMD5Verified, fileIn); error = ""; return(ReturnCode.Good); }
private static ReturnCode ValidateFileIn(RvFile fileIn, byte[] bCRC, byte[] bSHA1, byte[] bMD5, out string error) { if (!ArrByte.BCompare(bCRC, fileIn.CRC)) { fileIn.GotStatus = GotStatus.Corrupt; error = "Source CRC does not match Source Data stream, corrupt Zip"; return(ReturnCode.SourceDataStreamCorrupt); } fileIn.FileStatusSet(FileStatus.CRCVerified | FileStatus.SizeVerified); if (bMD5 != null) { // check to see if we have a MD5 from the DAT file if (fileIn.FileStatusIs(FileStatus.MD5FromDAT)) { if (fileIn.MD5 == null) { error = "Should have an filein MD5 from Dat but not found. Logic Error."; return(ReturnCode.LogicError); } if (!ArrByte.BCompare(fileIn.MD5, bMD5)) { error = "Source file did not match MD5"; return(ReturnCode.SourceCheckSumMismatch); } fileIn.FileStatusSet(FileStatus.MD5Verified); } // check to see if we have an MD5 (not from the DAT) so must be from previously scanning this file. else if (fileIn.MD5 != null) { if (!ArrByte.BCompare(fileIn.MD5, bMD5)) { // if we had an MD5 from a preview scan and it now does not match, something has gone really bad. error = "The MD5 found does not match a previously scanned MD5, this should not happen, unless something got corrupt."; return(ReturnCode.LogicError); } } else { fileIn.MD5 = bMD5; fileIn.FileStatusSet(FileStatus.MD5Verified); } } if (bSHA1 != null) { // check to see if we have a SHA1 from the DAT file if (fileIn.FileStatusIs(FileStatus.SHA1FromDAT)) { if (fileIn.SHA1 == null) { error = "Should have an filein SHA1 from Dat but not found. Logic Error."; return(ReturnCode.LogicError); } if (!ArrByte.BCompare(fileIn.SHA1, bSHA1)) { error = "Source file did not match SHA1"; return(ReturnCode.SourceCheckSumMismatch); } fileIn.FileStatusSet(FileStatus.SHA1Verified); } // check to see if we have an SHA1 (not from the DAT) so must be from previously scanning this file. else if (fileIn.SHA1 != null) { if (!ArrByte.BCompare(fileIn.SHA1, bSHA1)) { // if we had an SHA1 from a preview scan and it now does not match, something has gone really bad. error = "The SHA1 found does not match a previously scanned SHA1, this should not happen, unless something got corrupt."; return(ReturnCode.LogicError); } } else { fileIn.SHA1 = bSHA1; fileIn.FileStatusSet(FileStatus.SHA1Verified); } } error = ""; return(ReturnCode.Good); }
public static bool CheckIfGotfileAndMatchingFileAreFullMatches(RvFile gotFile, RvFile matchingFile) { if (gotFile.FileStatusIs(FileStatus.SHA1Verified) && matchingFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.BCompare(gotFile.SHA1, matchingFile.SHA1)) { return(false); } if (gotFile.FileStatusIs(FileStatus.MD5Verified) && matchingFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.BCompare(gotFile.MD5, matchingFile.MD5)) { return(false); } return(true); }
// find fix files, if the gotFile has been fully scanned check the SHA1/MD5, if not then just return true as the CRC/Size is all we have to go on. // this means that if the gotfile has not been fully scanned this will return true even with the source and destination SHA1/MD5 possibly different. public static bool CheckIfMissingFileCanBeFixedByGotFile(RvFile missingFile, RvFile gotFile) { // should probably be checking that the header type also match if (missingFile.FileStatusIs(FileStatus.SHA1FromDAT) && gotFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.BCompare(missingFile.SHA1, gotFile.SHA1)) { if (missingFile.FileStatusIs(FileStatus.SHA1FromDAT) && gotFile.FileStatusIs(FileStatus.AltSHA1Verified) && !ArrByte.BCompare(missingFile.SHA1, gotFile.AltSHA1)) { return(false); } } if (missingFile.FileStatusIs(FileStatus.MD5FromDAT) && gotFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.BCompare(missingFile.MD5, gotFile.MD5)) { if (missingFile.FileStatusIs(FileStatus.MD5FromDAT) && gotFile.FileStatusIs(FileStatus.AltMD5Verified) && !ArrByte.BCompare(missingFile.MD5, gotFile.AltMD5)) { return(false); } } return(true); }