Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        // 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);
        }