public static void Write() { if (File.Exists(Program.rvSettings.CacheFile)) { string bname = Program.rvSettings.CacheFile + "Backup"; if (File.Exists(bname)) { File.Delete(bname); } File.Move(Program.rvSettings.CacheFile, bname); } FileStream fs = new FileStream(Program.rvSettings.CacheFile, FileMode.CreateNew, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fs); DBVersion.VersionNow = DBVersion.Version; bw.Write(DBVersion.Version); DirTree.Write(bw); bw.Write(EndCacheMarker); bw.Flush(); bw.Close(); fs.Close(); fs.Dispose(); }
public static void Write() { string tname = Settings.rvSettings.CacheFile + "_tmp"; if (File.Exists(tname)) { File.Delete(tname); while (File.Exists(tname)) { Thread.Sleep(50); } } try { using (FileStream fs = new FileStream(tname, FileMode.CreateNew, FileAccess.Write)) { using (BinaryWriter bw = new BinaryWriter(fs, Encoding.UTF8, true)) { DBVersion.VersionNow = DBVersion.Version; bw.Write(DBVersion.Version); DirRoot.Write(bw); bw.Write(EndCacheMarker); bw.Flush(); bw.Close(); } fs.Close(); } } catch (Exception e) { ReportError.UnhandledExceptionHandler($"Error Writing Cache File, your cache is now out of date, fix this error and rescan: {e.Message}"); return; } if (File.Exists(Settings.rvSettings.CacheFile)) { string bname = Settings.rvSettings.CacheFile + "Backup"; if (File.Exists(bname)) { File.Delete(bname); while (File.Exists(bname)) { Thread.Sleep(50); } } File.Move(Settings.rvSettings.CacheFile, bname); while (File.Exists(Settings.rvSettings.CacheFile)) { Thread.Sleep(50); } } File.Move(tname, Settings.rvSettings.CacheFile); }
public static void WriteConfig(Settings settings) { if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault3cfg.xml"))) { File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault3cfg.xml")); } using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault3cfg.xml"))) { XmlSerializer x = new XmlSerializer(typeof(Settings)); x.Serialize(sw, settings); sw.Flush(); } }
public void WriteConfig() { //if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg"))) // File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2.cfg")); if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2cfg.xml"))) { File.Delete(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2cfg.xml")); } using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RomVault2cfg.xml"))) { XmlSerializer x = new XmlSerializer(Program.rvSettings.GetType()); x.Serialize(sw, Program.rvSettings); sw.Flush(); } }
public static void WriteConfig(Settings settings) { string configPath = Path.Combine(Environment.CurrentDirectory, "RomVault3cfg.xml"); if (File.Exists(configPath)) { File.Delete(configPath); } using (StreamWriter sw = new StreamWriter(configPath)) { XmlSerializer x = new XmlSerializer(typeof(Settings)); x.Serialize(sw, settings); sw.Flush(); } }
public static void Write() { if (File.Exists(Settings.rvSettings.CacheFile)) { string bname = Settings.rvSettings.CacheFile + "Backup"; if (File.Exists(bname)) { File.Delete(bname); while (File.Exists(bname)) { Thread.Sleep(50); } } File.Move(Settings.rvSettings.CacheFile, bname); while (File.Exists(Settings.rvSettings.CacheFile)) { Thread.Sleep(50); } } FileStream fs = new FileStream(Settings.rvSettings.CacheFile, FileMode.CreateNew, FileAccess.Write); using (BinaryWriter bw = new BinaryWriter(fs, Encoding.UTF8, true)) { DBVersion.VersionNow = DBVersion.Version; bw.Write(DBVersion.Version); DirTree.Write(bw); bw.Write(EndCacheMarker); bw.Flush(); bw.Close(); } fs.Close(); fs.Dispose(); }
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); }
public static TrrntZipStatus ReZipFiles(List <ZippedFile> zippedFiles, ICompress originalZipFile, byte[] buffer, StatusCallback statusCallBack, LogCallback logCallback, int threadId) { zipType inputType; switch (originalZipFile) { case Zip _: inputType = zipType.zip; break; case SevenZ _: inputType = zipType.sevenzip; break; case Compress.File.File _: inputType = zipType.iso; break; default: return(TrrntZipStatus.Unknown); } zipType outputType = Program.OutZip == zipType.both ? inputType : Program.OutZip; if (outputType == zipType.iso) { outputType = zipType.zip; } int bufferSize = buffer.Length; string filename = originalZipFile.ZipFilename; string tmpFilename = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename) + ".tmp"); string outExt = outputType == zipType.zip ? ".zip" : ".7z"; string outfilename = Path.Combine(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename) + outExt); if (inputType != outputType) { if (File.Exists(outfilename)) { logCallback?.Invoke(threadId, "Error output " + outExt + " file already exists"); return(TrrntZipStatus.RepeatFilesFound); } } if (File.Exists(tmpFilename)) { File.Delete(tmpFilename); } ICompress zipFileOut = outputType == zipType.zip ? new Zip() : (ICompress) new SevenZ(); try { zipFileOut.ZipFileCreate(tmpFilename); ulong fileSizeTotal = 0; ulong fileSizeProgress = 0; int filePercentReported = 20; foreach (ZippedFile f in zippedFiles) { fileSizeTotal += f.Size; } // by now the zippedFiles have been sorted so just loop over them foreach (ZippedFile t in zippedFiles) { if (Program.VerboseLogging) { logCallback?.Invoke(threadId, $"{t.Size,15} {t.StringCRC} {t.Name}"); } Stream readStream = null; ulong streamSize = 0; ZipReturn zrInput = ZipReturn.ZipUntested; switch (originalZipFile) { case Zip z: zrInput = z.ZipFileOpenReadStream(t.Index, false, out readStream, out streamSize, out ushort _); break; case SevenZ z7: zrInput = z7.ZipFileOpenReadStream(t.Index, out readStream, out streamSize); break; case Compress.File.File zf: zrInput = zf.ZipFileOpenReadStream(t.Index, out readStream, out streamSize); break; } ZipReturn zrOutput = zipFileOut.ZipFileOpenWriteStream(false, true, t.Name, streamSize, 8, out Stream writeStream); if ((zrInput != ZipReturn.ZipGood) || (zrOutput != ZipReturn.ZipGood)) { //Error writing local File. zipFileOut.ZipFileClose(); originalZipFile.ZipFileClose(); File.Delete(tmpFilename); return(TrrntZipStatus.CorruptZip); } Stream crcCs = new CrcCalculatorStream(readStream, true); ulong sizetogo = streamSize; while (sizetogo > 0) { int sizenow = sizetogo > (ulong)bufferSize ? bufferSize : (int)sizetogo; fileSizeProgress += (ulong)sizenow; int filePercent = (int)((double)fileSizeProgress / fileSizeTotal * 20); if (filePercent != filePercentReported) { statusCallBack?.Invoke(threadId, filePercent * 5); filePercentReported = filePercent; } crcCs.Read(buffer, 0, sizenow); writeStream.Write(buffer, 0, sizenow); sizetogo = sizetogo - (ulong)sizenow; } writeStream.Flush(); crcCs.Close(); if (inputType != zipType.sevenzip) { originalZipFile.ZipFileCloseReadStream(); } uint crc = (uint)((CrcCalculatorStream)crcCs).Crc; if (t.CRC == null) { t.CRC = crc; } if (crc != t.CRC) { return(TrrntZipStatus.CorruptZip); } zipFileOut.ZipFileCloseWriteStream(t.ByteCRC); } statusCallBack?.Invoke(threadId, 100); zipFileOut.ZipFileClose(); originalZipFile.ZipFileClose(); File.Delete(filename); File.Move(tmpFilename, outfilename); return(TrrntZipStatus.ValidTrrntzip); } catch (Exception) { zipFileOut?.ZipFileCloseFailed(); originalZipFile?.ZipFileClose(); return(TrrntZipStatus.CorruptZip); } }
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); }
// This Function returns: // Good : Everything Worked Correctly // RescanNeeded : Something unexpectedly changed in the files, so Stop fixing and prompt user to rescan. // LogicError : This Should never happen and is a logic problem in the code. // FileSystemError : Something is wrong with the files, like it was locked and could not be opened. // SourceDataStreamCorrupt : This happens when either zlib returns ZlibException, or the CRC does not match the extracted zip. // SourceCheckSumMismatch : If the extracted files does not match its expected SHA1 or MD5 // DestinationCheckSumMismatch : If the extracted files does not match the file to be fixed expected CRC,SHA1 or MD5. /// <summary> /// Performs the RomVault File Copy, with the source and destination being files or zipped files /// </summary> /// <param name="fileIn">This is the file being copied, it may be a zipped file or a regular file system file</param> /// <param name="zipFileOut">This is the zip file that is being written to.</param> /// <param name="filenameOut">This is the name of the file to be written to if we are just making a file</param> /// <param name="fileOut">This is the actual output filename</param> /// <param name="forceRaw">if true then we will do a raw copy, this is so that we can copy corrupt zips</param> /// <param name="error">This is the returned error message if this copy fails</param> /// <returns>ReturnCode.Good is the valid return code otherwise we have an error</returns> public static ReturnCode CopyFile(RvFile fileIn, ICompress zipFileOut, string filenameOut, RvFile fileOut, bool forceRaw, out string error) { if (zipFileOut == null && filenameOut == null) { throw new Exception("Error in CopyFile: Both Outputs are null"); } if (zipFileOut != null && filenameOut != null) { throw new Exception("Error in CopyFile: Both Outputs are set"); } ICompress zipFileIn = null; Stream readStream = null; ThreadCRC tcrc32 = null; ThreadMD5 tmd5 = null; ThreadSHA1 tsha1 = null; ReturnCode retC; error = ""; if (_buffer == null) { _buffer = new byte[BufferSize]; } bool rawCopy = TestRawCopy(fileIn, fileOut, forceRaw); ulong streamSize = 0; ushort compressionMethod = 8; bool sourceTrrntzip; bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut); if (!isZeroLengthFile) { //check that the in and out file match retC = CheckInputAndOutputFile(fileIn, fileOut, out error); if (retC != ReturnCode.Good) { return(retC); } //Find and Check/Open Input Files retC = OpenInputStream(fileIn, rawCopy, out zipFileIn, out sourceTrrntzip, out readStream, out streamSize, out compressionMethod, out error); if (retC != ReturnCode.Good) { return(retC); } } else { sourceTrrntzip = true; } if (!rawCopy) { compressionMethod = 8; } //Find and Check/Open Output Files retC = OpenOutputStream(fileOut, fileIn, zipFileOut, filenameOut, compressionMethod, rawCopy, sourceTrrntzip, null, out Stream writeStream, out error); if (retC != ReturnCode.Good) { return(retC); } byte[] bCRC; byte[] bMD5 = null; byte[] bSHA1 = null; if (!isZeroLengthFile) { #region Do Data Tranfer if (!rawCopy) { tcrc32 = new ThreadCRC(); if (Settings.rvSettings.FixLevel != EFixLevel.Level1) { tmd5 = new ThreadMD5(); tsha1 = new ThreadSHA1(); } } ulong sizetogo = streamSize; 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) { if ((fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) && zipFileIn != null) { ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); if (zr != ZipReturn.ZipGood) { error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename; return(ReturnCode.FileSystemError); } zipFileIn.ZipFileClose(); } else { readStream.Close(); } writeStream.Flush(); writeStream.Close(); if (filenameOut != null) { File.Delete(filenameOut); } error = "Unexpected corrupt archive file found:\n" + fileIn.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; if (Report.CancellationPending()) { tcrc32?.Dispose(); tmd5?.Dispose(); tsha1?.Dispose(); if ((fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) && zipFileIn != null) { ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); if (zr != ZipReturn.ZipGood) { error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename; return(ReturnCode.FileSystemError); } zipFileIn.ZipFileClose(); } else { readStream.Close(); } if (fileOut.FileType == FileType.ZipFile || fileOut.FileType == FileType.SevenZipFile) { zipFileOut.ZipFileCloseFailed(); } else { writeStream.Flush(); writeStream.Close(); } return(ReturnCode.Cancel); } } writeStream.Flush(); #endregion #region Collect Checksums // if we did a full copy then we just calculated all the checksums while doing the copy if (!rawCopy) { tcrc32.Finish(); tmd5?.Finish(); tsha1?.Finish(); bCRC = tcrc32.Hash; bMD5 = tmd5?.Hash; bSHA1 = tsha1?.Hash; tcrc32.Dispose(); tmd5?.Dispose(); tsha1?.Dispose(); } // if we raw copied and the source file has been FileChecked then we can trust the checksums in the source file else { bCRC = fileIn.CRC.Copy(); if (fileIn.FileStatusIs(FileStatus.MD5Verified)) { bMD5 = fileIn.MD5.Copy(); } if (fileIn.FileStatusIs(FileStatus.SHA1Verified)) { bSHA1 = fileIn.SHA1.Copy(); } } #endregion #region close the ReadStream if ((fileIn.FileType == FileType.ZipFile || fileIn.FileType == FileType.SevenZipFile) && zipFileIn != null) { ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); if (zr != ZipReturn.ZipGood) { error = "Error Closing " + zr + " Stream :" + zipFileIn.ZipFilename; return(ReturnCode.FileSystemError); } zipFileIn.ZipFileClose(); } else { readStream.Close(); } #endregion } else { CopyZeroLengthFile(fileOut, zipFileOut, out bCRC, out bMD5, out bSHA1); } #region close the WriteStream if (fileOut.FileType == FileType.ZipFile || fileOut.FileType == FileType.SevenZipFile) { ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(bCRC); if (zr != ZipReturn.ZipGood) { error = "Error Closing Stream " + zr; return(ReturnCode.FileSystemError); } fileOut.ZipFileIndex = zipFileOut.LocalFilesCount() - 1; fileOut.ZipFileHeaderPosition = zipFileOut.GetLocalFile(fileOut.ZipFileIndex).LocalHead; fileOut.FileModTimeStamp = 629870671200000000; } else { writeStream.Flush(); writeStream.Close(); FileInfo fi = new FileInfo(filenameOut); fileOut.FileModTimeStamp = fi.LastWriteTime; } #endregion if (!isZeroLengthFile) { if (!rawCopy) { retC = ValidateFileIn(fileIn, bCRC, bSHA1, bMD5, out error); if (retC != ReturnCode.Good) { return(retC); } } } retC = ValidateFileOut(fileIn, fileOut, rawCopy, bCRC, bSHA1, bMD5, out error); if (retC != ReturnCode.Good) { return(retC); } return(ReturnCode.Good); }
private static ReturnCode OpenOutputStream(RvFile fileOut, RvFile fileIn, ref ICompress zipFileOut, string zipFilenameOut, ushort compressionMethod, bool rawCopy, bool sourceTrrntzip, out Stream writeStream, out string error) { writeStream = null; if ((fileOut.FileType == FileType.ZipFile) || (fileOut.FileType == FileType.SevenZipFile)) { // if ZipFileOut == null then we have not open the output zip yet so open it from writing. if (zipFileOut == null) { if (Path.GetFileName(zipFilenameOut) == "__RomVault.tmp") { if (File.Exists(zipFilenameOut)) { File.Delete(zipFilenameOut); } } else if (File.Exists(zipFilenameOut)) { error = "Rescan needed, File Changed :" + zipFilenameOut; return(ReturnCode.RescanNeeded); } if (fileOut.FileType == FileType.ZipFile) { zipFileOut = new ZipFile(); } else { zipFileOut = new SevenZ(); } ZipReturn zrf = zipFileOut.ZipFileCreate(zipFilenameOut); if (zrf != ZipReturn.ZipGood) { error = "Error Opening Write Stream " + zrf; return(ReturnCode.FileSystemError); } } else { if (zipFileOut.ZipOpen != ZipOpenType.OpenWrite) { error = "Output Zip File is not set to OpenWrite, Logic Error."; return(ReturnCode.LogicError); } if (zipFileOut.ZipFilename != new FileInfo(zipFilenameOut).FullName) { error = "Output Zip file has changed name from " + zipFileOut.ZipFilename + " to " + zipFilenameOut + ". Logic Error"; return(ReturnCode.LogicError); } } if (fileIn.Size == null) { error = "Null File Size found in Fixing File :" + fileIn.FullName; return(ReturnCode.LogicError); } ZipReturn zr = zipFileOut.ZipFileOpenWriteStream(rawCopy, sourceTrrntzip, fileOut.Name, (ulong)fileIn.Size, compressionMethod, out writeStream); if (zr != ZipReturn.ZipGood) { error = "Error Opening Write Stream " + zr; return(ReturnCode.FileSystemError); } } else { if (File.Exists(zipFilenameOut) && (fileOut.GotStatus != GotStatus.Corrupt)) { error = "Rescan needed, File Changed :" + zipFilenameOut; return(ReturnCode.RescanNeeded); } int errorCode = FileStream.OpenFileWrite(zipFilenameOut, out writeStream); if (errorCode != 0) { error = new Win32Exception(errorCode).Message + ". " + zipFilenameOut; return(ReturnCode.FileSystemError); } } error = ""; return(ReturnCode.Good); }
// This Function returns: // Good : Everything Worked Correctly // RescanNeeded : Something unexpectidly changed in the files, so Stop prompt user to rescan. // LogicError : This Should never happen and is a logic problem in the code // FileSystemError : Something is wrong with the files /// <summary> /// Performs the RomVault File Copy, with the source and destination being files or zipped files /// </summary> /// <param name="fileIn">This is the file being copied, it may be a zipped file or a regular file system file</param> /// <param name="zipFileOut"> /// This is the zip file that is being writen to, if it is null a new zip file will be made if we /// are coping to a zip /// </param> /// <param name="zipFilenameOut">This is the name of the .zip file to be made that will be created in zipFileOut</param> /// <param name="fileOut">This is the actual output filename</param> /// <param name="forceRaw">if true then we will do a raw copy, this is so that we can copy corrupt zips</param> /// <param name="error">This is the returned error message if this copy fails</param> /// <param name="foundFile"> /// If we are SHA1/MD5 checking the source file for the first time, and it is different from what /// we expected the correct values for this file are returned in foundFile /// </param> /// <returns>ReturnCode.Good is the valid return code otherwire we have an error</returns> public static ReturnCode CopyFile(RvFile fileIn, ref ICompress zipFileOut, string zipFilenameOut, RvFile fileOut, bool forceRaw, out string error, out RvFile foundFile) { foundFile = null; error = ""; if (_buffer == null) { _buffer = new byte[BufferSize]; } bool rawCopy = RawCopy(fileIn, fileOut, forceRaw); ulong streamSize = 0; ushort compressionMethod = 8; bool sourceTrrntzip = false; ICompress zipFileIn = null; Stream readStream = null; ReturnCode retC; bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut); if (!isZeroLengthFile) { //check that the in and out file match retC = CheckInputAndOutputFile(fileIn, fileOut, out error); if (retC != ReturnCode.Good) { return(retC); } //Find and Check/Open Input Files retC = OpenInputStream(fileIn, rawCopy, out zipFileIn, out sourceTrrntzip, out readStream, out streamSize, out compressionMethod, out error); if (retC != ReturnCode.Good) { return(retC); } } else { sourceTrrntzip = true; } if (!rawCopy && ((Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel1) || (Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel2) || (Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel3))) { compressionMethod = 8; } //Find and Check/Open Output Files Stream writeStream; retC = OpenOutputStream(fileOut, fileIn, ref zipFileOut, zipFilenameOut, compressionMethod, rawCopy, sourceTrrntzip, out writeStream, out error); if (retC != ReturnCode.Good) { return(retC); } byte[] bCRC; byte[] bMD5 = null; byte[] bSHA1 = null; if (!isZeroLengthFile) { #region Do Data Tranfer ThreadCRC tcrc32 = null; ThreadMD5 tmd5 = null; ThreadSHA1 tsha1 = null; if (!rawCopy) { tcrc32 = new ThreadCRC(); tmd5 = new ThreadMD5(); tsha1 = new ThreadSHA1(); } ulong sizetogo = streamSize; while (sizetogo > 0) { int sizenow = sizetogo > BufferSize ? BufferSize : (int)sizetogo; try { readStream.Read(_buffer, 0, sizenow); } catch (ZlibException) { if ((fileIn.FileType == FileType.ZipFile) && (zipFileIn != null)) { ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); if (zr != ZipReturn.ZipGood) { error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex); return(ReturnCode.FileSystemError); } zipFileIn.ZipFileClose(); } else { readStream.Close(); } if (fileOut.FileType == FileType.ZipFile) { ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(new byte[] { 0, 0, 0, 0 }); if (zr != ZipReturn.ZipGood) { error = "Error Closing Stream " + zr; return(ReturnCode.FileSystemError); } zipFileOut.ZipFileRollBack(); } else { writeStream.Flush(); writeStream.Close(); File.Delete(zipFilenameOut); } error = "Error in Data Stream"; return(ReturnCode.SourceCRCCheckSumError); } catch (Exception e) { error = "Error reading Source File " + e.Message; return(ReturnCode.FileSystemError); } if (!rawCopy) { tcrc32.Trigger(_buffer, sizenow); tmd5.Trigger(_buffer, sizenow); tsha1.Trigger(_buffer, sizenow); tcrc32.Wait(); tmd5.Wait(); tsha1.Wait(); } try { writeStream.Write(_buffer, 0, sizenow); } catch (Exception e) { Debug.WriteLine(e.Message); error = "Error writing out file. " + Environment.NewLine + e.Message; return(ReturnCode.FileSystemError); } sizetogo = sizetogo - (ulong)sizenow; } writeStream.Flush(); #endregion #region Collect Checksums // if we did a full copy then we just calculated all the checksums while doing the copy if (!rawCopy) { tcrc32.Finish(); tmd5.Finish(); tsha1.Finish(); bCRC = tcrc32.Hash; bMD5 = tmd5.Hash; bSHA1 = tsha1.Hash; tcrc32.Dispose(); tmd5.Dispose(); tsha1.Dispose(); } // if we raw copied and the source file has been FileChecked then we can trust the checksums in the source file else { bCRC = ArrByte.Copy(fileIn.CRC); if (fileIn.FileStatusIs(FileStatus.MD5Verified)) { bMD5 = ArrByte.Copy(fileIn.MD5); } if (fileIn.FileStatusIs(FileStatus.SHA1Verified)) { bSHA1 = ArrByte.Copy(fileIn.SHA1); } } #endregion #region close the ReadStream if (((fileIn.FileType == FileType.ZipFile) || (fileIn.FileType == FileType.SevenZipFile)) && (zipFileIn != null)) { ZipReturn zr = zipFileIn.ZipFileCloseReadStream(); if (zr != ZipReturn.ZipGood) { error = "Error Closing " + zr + " Stream :" + zipFileIn.Filename(fileIn.ReportIndex); return(ReturnCode.FileSystemError); } zipFileIn.ZipFileClose(); } else { readStream.Close(); //if (RVIO.File.Exists(tmpFilename)) // RVIO.File.Delete(tmpFilename); } #endregion } else { // Zero Length File (Directory in a Zip) if (fileOut.FileType == FileType.ZipFile) { zipFileOut.ZipFileAddDirectory(); } bCRC = VarFix.CleanMD5SHA1("00000000", 8); bMD5 = VarFix.CleanMD5SHA1("d41d8cd98f00b204e9800998ecf8427e", 32); bSHA1 = VarFix.CleanMD5SHA1("da39a3ee5e6b4b0d3255bfef95601890afd80709", 40); } #region close the WriteStream if ((fileOut.FileType == FileType.ZipFile) || (fileOut.FileType == FileType.SevenZipFile)) { ZipReturn zr = zipFileOut.ZipFileCloseWriteStream(bCRC); if (zr != ZipReturn.ZipGood) { error = "Error Closing Stream " + zr; return(ReturnCode.FileSystemError); } fileOut.ZipFileIndex = zipFileOut.LocalFilesCount() - 1; fileOut.ZipFileHeaderPosition = zipFileOut.LocalHeader(fileOut.ZipFileIndex); } else { writeStream.Flush(); writeStream.Close(); FileInfo fi = new FileInfo(zipFilenameOut); fileOut.TimeStamp = fi.LastWriteTime; } #endregion if (!isZeroLengthFile) { if (!rawCopy) { if (!ArrByte.bCompare(bCRC, fileIn.CRC)) { fileIn.GotStatus = GotStatus.Corrupt; error = "Source CRC does not match Source Data stream, corrupt Zip"; if (fileOut.FileType == FileType.ZipFile) { zipFileOut.ZipFileRollBack(); } else { File.Delete(zipFilenameOut); } return(ReturnCode.SourceCRCCheckSumError); } fileIn.FileStatusSet(FileStatus.CRCVerified | FileStatus.SizeVerified); bool sourceFailed = false; // 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)) { sourceFailed = true; } else { 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 == null) { fileIn.MD5 = bMD5; fileIn.FileStatusSet(FileStatus.MD5Verified); } // 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)) { sourceFailed = true; } else { 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 == null) { fileIn.SHA1 = bSHA1; fileIn.FileStatusSet(FileStatus.SHA1Verified); } if (sourceFailed) { if ((fileIn.FileType == FileType.ZipFile) || (fileIn.FileType == FileType.SevenZipFile)) { RvFile tZFile = new RvFile(FileType.ZipFile); foundFile = tZFile; tZFile.ZipFileIndex = fileIn.ZipFileIndex; tZFile.ZipFileHeaderPosition = fileIn.ZipFileHeaderPosition; } else { foundFile = new RvFile(fileIn.FileType); } foundFile.Name = fileIn.Name; foundFile.Size = fileIn.Size; foundFile.CRC = bCRC; foundFile.MD5 = bMD5; foundFile.SHA1 = bSHA1; foundFile.TimeStamp = fileIn.TimeStamp; foundFile.SetStatus(DatStatus.NotInDat, GotStatus.Got); foundFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.MD5Verified | FileStatus.SHA1Verified); if (fileOut.FileType == FileType.ZipFile) { zipFileOut.ZipFileRollBack(); } else { File.Delete(zipFilenameOut); } return(ReturnCode.SourceCheckSumError); } } } 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)) { //Rollback the file if (fileOut.FileType == FileType.ZipFile) { zipFileOut.ZipFileRollBack(); } else { File.Delete(zipFilenameOut); } return(ReturnCode.DestinationCheckSumError); } 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)) { //Rollback the file if (fileOut.FileType == FileType.ZipFile) { zipFileOut.ZipFileRollBack(); } else { File.Delete(zipFilenameOut); } return(ReturnCode.DestinationCheckSumError); } fileOut.SHA1 = bSHA1; fileOut.FileStatusSet(FileStatus.SHA1Verified); } if (bMD5 != null) { if (fileOut.FileStatusIs(FileStatus.MD5FromDAT) && (fileOut.MD5 != null) && !ArrByte.bCompare(fileOut.MD5, bMD5)) { //Rollback the file if (fileOut.FileType == FileType.ZipFile) { zipFileOut.ZipFileRollBack(); } else { File.Delete(zipFilenameOut); } return(ReturnCode.DestinationCheckSumError); } fileOut.MD5 = bMD5; fileOut.FileStatusSet(FileStatus.MD5Verified); } if (fileIn.Size != null) { fileOut.Size = fileIn.Size; fileOut.FileStatusSet(FileStatus.SizeVerified); } if (fileIn.GotStatus == GotStatus.Corrupt) { fileOut.GotStatus = GotStatus.Corrupt; } else { fileOut.GotStatus = GotStatus.Got; // Changes RepStatus to Correct } fileOut.FileStatusSet(FileStatus.SizeVerified); if ((fileOut.SHA1CHD == null) && (fileIn.SHA1CHD != null)) { fileOut.SHA1CHD = fileIn.SHA1CHD; } if ((fileOut.MD5CHD == null) && (fileIn.MD5CHD != null)) { fileOut.MD5CHD = fileIn.MD5CHD; } fileOut.CHDVersion = fileIn.CHDVersion; fileOut.FileStatusSet(FileStatus.SHA1CHDFromHeader | FileStatus.MD5CHDFromHeader | FileStatus.SHA1CHDVerified | FileStatus.MD5CHDVerified, fileIn); return(ReturnCode.Good); }