// 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) { if (missingFile.FileStatusIs(FileStatus.SHA1FromDAT) && gotFile.FileStatusIs(FileStatus.SHA1Verified) && !ArrByte.bCompare(missingFile.SHA1, gotFile.SHA1)) return false; if (missingFile.FileStatusIs(FileStatus.MD5FromDAT) && gotFile.FileStatusIs(FileStatus.MD5Verified) && !ArrByte.bCompare(missingFile.MD5, gotFile.MD5)) return false; return true; }
public static void LogOut(RvFile f) { if (!Settings.DebugLogsEnabled) return; StreamWriter sw = new StreamWriter(_logfilename, true); ReportFile(sw, f); sw.Flush(); sw.Close(); }
private static void LoadDiskFromDat(ref RvDir tGame, XmlNode romNode) { if (romNode.Attributes == null) return; XmlNode name = romNode.Attributes.GetNamedItem("name"); RvFile tRom = new RvFile(FileType.File) { Name = VarFix.CleanFullFileName(name) + ".chd", SHA1CHD = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")), Dat = tGame.Dat }; if (tRom.SHA1CHD != null) tRom.FileStatusSet(FileStatus.SHA1CHDFromDAT); tGame.ChildAdd(tRom); }
// find all of the files that we think we have that match the needed CRC and Size. public static void RomSearchFindFixes(RvFile tRom, List<RvFile> lstFiles, out List<RvFile> lstFilesOut) { lstFilesOut = new List<RvFile>(); if (tRom.CRC == null || tRom.Size == null) return; int intIndex; int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex); while (intRes == 0) { if (lstFiles[intIndex].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(tRom, lstFiles[intIndex])) lstFilesOut.Add(lstFiles[intIndex]); intIndex++; intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1; } }
// 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 ZipFile 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; ZipFile zipFileIn = null; System.IO.Stream readStream = null; bool isZeroLengthFile = DBHelper.IsZeroLengthFile(fileOut); if (!isZeroLengthFile) { #region check that the in and out file match 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.MD5CHDFromDAT) && 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; } } #endregion #region Find and Check/Open Input Files if (fileIn.FileType == FileType.ZipFile) // Input is a ZipFile { RvDir zZipFileIn = fileIn.Parent; if (zZipFileIn.FileType != FileType.Zip) { error = "Zip File Open but Source File is not a zip, Logic Error."; return ReturnCode.LogicError; } string fileNameIn = zZipFileIn.FullName; sourceTrrntzip = (zZipFileIn.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip; //if (zZipFileIn.ZipFileType == RvZip.ZipType.Zip) //{ zipFileIn = new ZipFile(); ZipReturn zr1; if (fileIn.ZipFileHeaderPosition != null) zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, false); else zr1 = zipFileIn.ZipFileOpen(fileNameIn, zZipFileIn.TimeStamp, true); switch (zr1) { case ZipReturn.ZipGood: break; case ZipReturn.ZipErrorFileNotFound: error = "File not found, Rescan required before fixing " + fileIn.Name; return ReturnCode.FileSystemError; case ZipReturn.ZipErrorTimeStamp: error = "File has changed, Rescan required before fixing " + fileIn.Name; return ReturnCode.FileSystemError; default: error = "Error Open Zip" + zr1 + ", with File " + fileIn.DatFullName; return ReturnCode.FileSystemError; } if (fileIn.ZipFileHeaderPosition != null) zipFileIn.ZipFileOpenReadStreamQuick((ulong)fileIn.ZipFileHeaderPosition, rawCopy, out readStream, out streamSize, out compressionMethod); else zipFileIn.ZipFileOpenReadStream(fileIn.ZipFileIndex, rawCopy, out readStream, out streamSize, out compressionMethod); } else // Input is a regular file { string fileNameIn = fileIn.FullName; if (!IO.File.Exists(fileNameIn)) { error = "Rescan needed, File Changed :" + fileNameIn; return ReturnCode.RescanNeeded; } IO.FileInfo fileInInfo = new IO.FileInfo(fileNameIn); if (fileInInfo.LastWriteTime != fileIn.TimeStamp) { error = "Rescan needed, File Changed :" + fileNameIn; return ReturnCode.RescanNeeded; } int errorCode = IO.FileStream.OpenFileRead(fileNameIn, out readStream); if (errorCode != 0) { error = new Win32Exception(errorCode).Message + ". " + fileNameIn; return ReturnCode.FileSystemError; } if (fileIn.Size == null) { error = "Null File Size found in Fixing File :" + fileNameIn; return ReturnCode.LogicError; } streamSize = (ulong)fileIn.Size; if ((ulong)readStream.Length != streamSize) { error = "Rescan needed, File Length Changed :" + fileNameIn; return ReturnCode.RescanNeeded; } } #endregion } else { sourceTrrntzip = true; } if (!rawCopy && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3)) compressionMethod = 8; #region Find and Check/Open Output Files System.IO.Stream writeStream; if (fileOut.FileType == FileType.ZipFile) { // if ZipFileOut == null then we have not open the output zip yet so open it from writing. if (zipFileOut == null) { if (IO.Path.GetFileName(zipFilenameOut) == "__ROMVault.tmp") { if (IO.File.Exists(zipFilenameOut)) IO.File.Delete(zipFilenameOut); } else if (IO.File.Exists(zipFilenameOut)) { error = "Rescan needed, File Changed :" + zipFilenameOut; return ReturnCode.RescanNeeded; } zipFileOut = new ZipFile(); 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 IO.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 (IO.File.Exists(zipFilenameOut) && fileOut.GotStatus != GotStatus.Corrupt) { error = "Rescan needed, File Changed :" + zipFilenameOut; return ReturnCode.RescanNeeded; } int errorCode = IO.FileStream.OpenFileWrite(zipFilenameOut, out writeStream); if (errorCode != 0) { error = new Win32Exception(errorCode).Message + ". " + zipFilenameOut; return ReturnCode.FileSystemError; } } #endregion byte[] bCRC; byte[] bMD5 = null; byte[] bSHA1 = null; if (!isZeroLengthFile) { #region Do Data Tranfer CRC32Hash crc32 = null; MD5 md5 = null; SHA1 sha1 = null; if (!rawCopy) { crc32 = new CRC32Hash(); md5 = MD5.Create(); sha1 = SHA1.Create(); } 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(); IO.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) { crc32.TransformBlock(_buffer, 0, sizenow, null, 0); md5.TransformBlock(_buffer, 0, sizenow, null, 0); sha1.TransformBlock(_buffer, 0, sizenow, null, 0); } 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) { crc32.TransformFinalBlock(_buffer, 0, 0); md5.TransformFinalBlock(_buffer, 0, 0); sha1.TransformFinalBlock(_buffer, 0, 0); bCRC = crc32.Hash; bMD5 = md5.Hash; bSHA1 = sha1.Hash; } // 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 && 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 (IO.File.Exists(tmpFilename)) // IO.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) { 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(); IO.FileInfo fi = new IO.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 IO.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) { 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 IO.File.Delete(zipFilenameOut); return ReturnCode.SourceCheckSumError; } } } if (fileOut.FileType == FileType.ZipFile) { 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 IO.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 IO.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 IO.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; }
private static ReturnCode FixFileCanBeFixed(RvFile fixFile) { string fixFileFullName = fixFile.FullName; CheckCreateParent(fixFile.Parent); // check to see if there is already a file with the name of the fixFile, and move it out the way. ReturnCode rc = FixFilePreCheckFixFile(fixFile); if (rc != ReturnCode.Good) return rc; // now we can fix the file. ZipFile tempZipOut = null; RvFile foundFile; ReturnCode returnCode; if (DBHelper.IsZeroLengthFile(fixFile)) { RvFile fileIn = new RvFile(FileType.File); returnCode = FixFileCopy.CopyFile(fileIn, ref tempZipOut, fixFile.FullName, fixFile, false, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; default: _error = fixFile.FullName + " " + fixFile.RepStatus + " " + returnCode + " : " + _error; ReCheckFile(fixFile); return ReturnCode.StartOver; } _fixed++; return ReturnCode.Good; } #if NEWFINDFIX List<RvFile> lstFixRomTable = new List<RvFile>(); List<RvFile> family = fixFile.MyFamily.Family; for (int iFind = 0; iFind < family.Count; iFind++) { if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(fixFile, family[iFind])) lstFixRomTable.Add(family[iFind]); } RvFile fixingFile = lstFixRomTable[0]; #else // search for the database for the file to be used to repair this file: List<RvFile> lstFixRomTableCRC; DBHelper.RomSearchFindFixes(fixFile, _lstRomTableSortedCRCSize, out lstFixRomTableCRC); List<RvFile> lstFixRomTableSHA1CHD; DBHelper.RomSearchFindFixesSHA1CHD(fixFile, _lstRomTableSortedSHA1CHD, out lstFixRomTableSHA1CHD); if (lstFixRomTableCRC.Count == 0 && lstFixRomTableSHA1CHD.Count == 0) { // thought we could fix the file, turns out we cannot fixFile.GotStatus = GotStatus.NotGot; return ReturnCode.Good; } RvFile fixingFile = lstFixRomTableCRC.Count > 0 ? lstFixRomTableCRC[0] : lstFixRomTableSHA1CHD[0]; #endif string fts = fixingFile.FullName; ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixFileFullName), "", Path.GetFileName(fixFileFullName), fixFile.Size, "<--", Path.GetDirectoryName(fts), Path.GetFileName(fts), fixingFile.Name)); returnCode = FixFileCopy.CopyFile(fixingFile, ref tempZipOut, fixFile.FullName, fixFile, false, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; case ReturnCode.SourceCRCCheckSumError: { ReportProgress(new bgwShowFixError("CRC Error")); // the file we used for fix turns out to be corrupt // mark the source file as Corrupt fixingFile.GotStatus = GotStatus.Corrupt; // recheck for the fix ReCheckFile(fixFile); CheckReprocess(fixingFile); // and go back one and try again. return ReturnCode.StartOver; } case ReturnCode.SourceCheckSumError: { // the file we used for fix turns out not not match its own DAT's correct MD5/SHA1 // (Problem with logic here is that it could still match the file being fixed, but this case is not correctly handled) ReportProgress(new bgwShowFixError("Failed")); // remove the file we thought we correctly had (The file that we where trying to use for the fix) if (fixingFile.FileRemove() == EFile.Delete) { _error = "Should not mark for delete as it is in a DAT"; return ReturnCode.LogicError; } // possibly use a check here to see if the index of the found file is futher down the zip and so we can just contine // instead of restarting. // add in the actual file we found fixingFile.Parent.ChildAdd(foundFile); AddFoundFile(foundFile); // recheck for the fix ReCheckFile(fixFile); CheckReprocess(fixingFile); // and go back one and try again. return ReturnCode.StartOver; } case ReturnCode.DestinationCheckSumError: { ReportProgress(new bgwShowFixError("Failed")); // recheck for the fix ReCheckFile(fixFile); return ReturnCode.StartOver; } default: return returnCode; } CheckReprocessClearList(); // Check the files that we found that where used to fix this file, and if they not listed as correct files, they can be set to be deleted. #if NEWFINDFIX foreach (RvFile file in lstFixRomTable) { if (file.RepStatus != RepStatus.NeededForFix && file.RepStatus != RepStatus.Rename) continue; file.RepStatus = RepStatus.Delete; CheckReprocess(file, true); } #else foreach (RvFile file in lstFixRomTableCRC) { if (file.RepStatus != RepStatus.NeededForFix && file.RepStatus != RepStatus.Rename) continue; file.RepStatus = RepStatus.Delete; CheckReprocess(file, true); } foreach (RvFile file in lstFixRomTableSHA1CHD) { if (file.RepStatus != RepStatus.NeededForFix && file.RepStatus != RepStatus.Rename) continue; file.RepStatus = RepStatus.Delete; CheckReprocess(file, true); } #endif CheckReprocessFinalCheck(); _fixed++; return ReturnCode.Good; }
private static bool IsDeepScanned(RvFile tFile) { return ( tFile.FileStatusIs(FileStatus.SizeVerified) && tFile.FileStatusIs(FileStatus.CRCVerified) && tFile.FileStatusIs(FileStatus.SHA1Verified) && tFile.FileStatusIs(FileStatus.MD5Verified) ); }
private static void DeepScanFile(string directory, RvFile tFile) { string filename = Path.Combine(directory, tFile.Name); int errorCode = UnCompFiles.CheckSumRead(filename, true, out tFile.CRC, out tFile.MD5, out tFile.SHA1); if (errorCode == 32) { tFile.GotStatus = GotStatus.FileLocked; return; } if (errorCode != 0) { ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted."); _fileErrorAbort = true; return; } tFile.FileStatusSet(FileStatus.SizeVerified | FileStatus.CRCVerified | FileStatus.SHA1Verified | FileStatus.MD5Verified); }
private static void ReportFile(TextWriter sw, RvFile f) { sw.WriteLine(f.ReportIndex.ToString("D8") + " " + ArrByte.ToString(f.CRC) + " " + f.GotStatus.ToString().PadRight(10) + " " + f.RepStatus.ToString().PadRight(15) + " " + f.TreeFullName); }
private void AddRom(RvFile tRomTable, string pathAdd) { if (tRomTable.DatStatus != DatStatus.InDatMerged || tRomTable.RepStatus != RepStatus.NotCollected || chkBoxShowMerged.Checked) { RomGrid.Rows.Add(); int row = RomGrid.Rows.Count - 1; RomGrid.Rows[row].Tag = tRomTable; for (int i = 0; i < RomGrid.Rows[row].Cells.Count; i++) { DataGridViewCellStyle cs = RomGrid.Rows[row].Cells[i].Style; cs.BackColor = _displayColor[(int)tRomTable.RepStatus]; cs.ForeColor = _fontColor[(int)tRomTable.RepStatus]; } string fname = pathAdd + tRomTable.Name; if (!string.IsNullOrEmpty(tRomTable.FileName)) fname += " (Found: " + tRomTable.FileName + ")"; if (tRomTable.CHDVersion != null) fname += " (V" + tRomTable.CHDVersion + ")"; RomGrid.Rows[row].Cells["CRom"].Value = fname; RomGrid.Rows[row].Cells["CMerge"].Value = tRomTable.Merge; RomGrid.Rows[row].Cells["CStatus"].Value = tRomTable.Status; string strSize = tRomTable.Size.ToString(); string flags = ""; if (tRomTable.FileStatusIs(FileStatus.SizeFromDAT)) flags += "D"; if (tRomTable.FileStatusIs(FileStatus.SizeFromHeader)) flags += "H"; if (tRomTable.FileStatusIs(FileStatus.SizeVerified)) flags += "V"; if (!String.IsNullOrEmpty(flags)) strSize += " (" + flags + ")"; RomGrid.Rows[row].Cells["CSize"].Value = strSize; string strCRC = ArrByte.ToString(tRomTable.CRC); flags = ""; if (tRomTable.FileStatusIs(FileStatus.CRCFromDAT)) flags += "D"; if (tRomTable.FileStatusIs(FileStatus.CRCFromHeader)) flags += "H"; if (tRomTable.FileStatusIs(FileStatus.CRCVerified)) flags += "V"; if (!String.IsNullOrEmpty(flags)) strCRC += " (" + flags + ")"; RomGrid.Rows[row].Cells["CCRC32"].Value = strCRC; if (tRomTable.SHA1CHD == null) { string strSHA1 = ArrByte.ToString(tRomTable.SHA1); flags = ""; if (tRomTable.FileStatusIs(FileStatus.SHA1FromDAT)) flags += "D"; if (tRomTable.FileStatusIs(FileStatus.SHA1FromHeader)) flags += "H"; if (tRomTable.FileStatusIs(FileStatus.SHA1Verified)) flags += "V"; if (!String.IsNullOrEmpty(flags)) strSHA1 += " (" + flags + ")"; RomGrid.Rows[row].Cells["CSHA1"].Value = strSHA1; } else { string strSHA1CHD = "CHD: " + ArrByte.ToString(tRomTable.SHA1CHD); flags = ""; if (tRomTable.FileStatusIs(FileStatus.SHA1CHDFromDAT)) flags += "D"; if (tRomTable.FileStatusIs(FileStatus.SHA1CHDFromHeader)) flags += "H"; if (tRomTable.FileStatusIs(FileStatus.SHA1CHDVerified)) flags += "V"; if (!String.IsNullOrEmpty(flags)) strSHA1CHD += " (" + flags + ")"; RomGrid.Rows[row].Cells["CSHA1"].Value = strSHA1CHD; } if (tRomTable.MD5CHD == null) { string strMD5 = ArrByte.ToString(tRomTable.MD5); flags = ""; if (tRomTable.FileStatusIs(FileStatus.MD5FromDAT)) flags += "D"; if (tRomTable.FileStatusIs(FileStatus.MD5FromHeader)) flags += "H"; if (tRomTable.FileStatusIs(FileStatus.MD5Verified)) flags += "V"; if (!String.IsNullOrEmpty(flags)) strMD5 += " (" + flags + ")"; RomGrid.Rows[row].Cells["CMD5"].Value = strMD5; } else { string strMD5CHD = "CHD: " + ArrByte.ToString(tRomTable.MD5CHD); flags = ""; if (tRomTable.FileStatusIs(FileStatus.MD5CHDFromDAT)) flags += "D"; if (tRomTable.FileStatusIs(FileStatus.MD5CHDFromHeader)) flags += "H"; if (tRomTable.FileStatusIs(FileStatus.MD5CHDVerified)) flags += "V"; if (!String.IsNullOrEmpty(flags)) strMD5CHD += " (" + flags + ")"; RomGrid.Rows[row].Cells["CMD5"].Value = strMD5CHD; } if (tRomTable.FileType == FileType.ZipFile) { RomGrid.Rows[row].Cells["ZipIndex"].Value = tRomTable.ZipFileIndex == -1 ? "" : tRomTable.ZipFileIndex.ToString(CultureInfo.InvariantCulture); RomGrid.Rows[row].Cells["ZipHeader"].Value = tRomTable.ZipFileHeaderPosition == null ? "" : tRomTable.ZipFileHeaderPosition.ToString(); } } }
/* * In the mame Dat: * status="nodump" has a size but no CRC * status="baddump" has a size and crc */ private static void RomCheckCollect(RvFile tRom, bool merge) { if (merge) { if (string.IsNullOrEmpty(tRom.Merge)) tRom.Merge = "(Auto Merged)"; tRom.DatStatus = DatStatus.InDatMerged; return; } if (!string.IsNullOrEmpty(tRom.Merge)) tRom.Merge = "(No-Merge) " + tRom.Merge; if (tRom.Status == "nodump") { tRom.CRC = null; tRom.DatStatus = DatStatus.InDatBad; return; } if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && tRom.Size == 0) { tRom.DatStatus = DatStatus.InDatCollect; return; } /* if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) || (tRom.CRC.Length != 8)) { tRom.CRC = null; tRom.DatStatus = DatStatus.InDatBad; return; } */ tRom.DatStatus = DatStatus.InDatCollect; }
private static ReturnCode FixZip(RvDir fixZip) { //Check for error status if (fixZip.DirStatus.HasUnknown()) return ReturnCode.FindFixes; // Error bool needsTrrntzipped = fixZip.ZipStatus != ZipStatus.TrrntZip && fixZip.GotStatus == GotStatus.Got && fixZip.DatStatus == DatStatus.InDatCollect && (Settings.FixLevel == eFixLevel.TrrntZipLevel1 || Settings.FixLevel == eFixLevel.TrrntZipLevel2 || Settings.FixLevel == eFixLevel.TrrntZipLevel3); // file corrupt and not in tosort // if file cannot be fully fixed copy to corrupt // process zipfile if (fixZip.GotStatus == GotStatus.Corrupt && fixZip.DatStatus != DatStatus.InToSort) { ReturnCode movReturnCode = MoveZiptoCorrupt(fixZip); if (movReturnCode != ReturnCode.Good) return movReturnCode; } // has fixable // process zipfile else if (fixZip.DirStatus.HasFixable()) { // do nothing here but continue on to process zip. } // need trrntzipped // process zipfile else if (needsTrrntzipped) { // do nothing here but continue on to process zip. } // got empty zip that should be deleted // process zipfile else if (fixZip.GotStatus == GotStatus.Got && fixZip.GotStatus != GotStatus.Corrupt && !fixZip.DirStatus.HasAnyFiles()) { // do nothing here but continue on to process zip. } // else // skip this zipfile else { // nothing can be done to return return ReturnCode.Good; } string fixZipFullName = fixZip.TreeFullName; if (!fixZip.DirStatus.HasFixable() && needsTrrntzipped) ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), "", 0, "TrrntZipping", "", "", "")); CheckCreateParent(fixZip.Parent); ReportError.LogOut(""); ReportError.LogOut(fixZipFullName + " : " + fixZip.RepStatus); ReportError.LogOut("------------------------------------------------------------"); Debug.WriteLine(fixZipFullName + " : " + fixZip.RepStatus); ReportError.LogOut("Zip File Status Before Fix:"); for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++) ReportError.LogOut((RvFile)fixZip.Child(intLoop)); ReportError.LogOut(""); ZipFile tempZipOut = null; ZipFile toSortCorruptOut = null; ZipFile toSortZipOut = null; RvDir toSortGame = null; RvDir toSortCorruptGame = null; ReturnCode returnCode; List<RvFile> fixZipTemp = new List<RvFile>(); for (int iRom = 0; iRom < fixZip.ChildCount; iRom++) { RvFile zipFileFixing = new RvFile(FileType.ZipFile); fixZip.Child(iRom).CopyTo(zipFileFixing); if (iRom == fixZipTemp.Count) fixZipTemp.Add(zipFileFixing); else fixZipTemp[iRom] = zipFileFixing; ReportError.LogOut(zipFileFixing.RepStatus + " : " + fixZip.Child(iRom).FullName); switch (zipFileFixing.RepStatus) { #region Nothing to copy // any file we do not have or do not want in the destination zip case RepStatus.Missing: case RepStatus.NotCollected: case RepStatus.Rename: case RepStatus.Delete: if (! ( // got the file in the original zip but will be deleting it (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Corrupt) || (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) || // do not have this file and cannot fix it here (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.NotGot) || (zipFileFixing.DatStatus == DatStatus.InDatBad && zipFileFixing.GotStatus == GotStatus.NotGot) || (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.NotGot) ) ) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); if (zipFileFixing.RepStatus == RepStatus.Delete) { returnCode = DoubleCheckDelete(zipFileFixing); if (returnCode != ReturnCode.Good) goto ZipOpenFailed; } zipFileFixing.GotStatus = GotStatus.NotGot; break; #endregion #region Copy from Original to Destination // any files we are just moving from the original zip to the destination zip case RepStatus.Correct: case RepStatus.InToSort: case RepStatus.NeededForFix: case RepStatus.Corrupt: { if (! ( (zipFileFixing.DatStatus == DatStatus.InDatCollect && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InDatMerged && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Got) || (zipFileFixing.DatStatus == DatStatus.InToSort && zipFileFixing.GotStatus == GotStatus.Corrupt) ) ) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); RvFile foundFile; bool rawcopy = (zipFileFixing.RepStatus == RepStatus.InToSort) || (zipFileFixing.RepStatus == RepStatus.Corrupt); // Correct rawcopy=false // NeededForFix rawcopy=false // InToSort rawcopy=true // Corrupt rawcopy=true RepStatus originalStatus = zipFileFixing.RepStatus; returnCode = FixFileCopy.CopyFile( (RvFile)fixZip.Child(iRom), ref tempZipOut, Path.Combine(fixZip.Parent.FullName, "__RomVault.tmp"), zipFileFixing, rawcopy, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; if (originalStatus == RepStatus.NeededForFix) zipFileFixing.RepStatus = RepStatus.NeededForFix; break; case ReturnCode.SourceCRCCheckSumError: { RvFile tFile = (RvFile)fixZip.Child(iRom); tFile.GotStatus = GotStatus.Corrupt; ReCheckFile(tFile); //decrease index so this file gets reprocessed iRom--; continue; } case ReturnCode.SourceCheckSumError: { // Set the file in the zip that we thought we correctly had as missing RvFile tFile = (RvFile)fixZip.Child(iRom); if (tFile.FileRemove() == EFile.Delete) { _error = "Should not mark for delete as it is in a DAT"; return ReturnCode.LogicError; } // Add in at the current location the incorrect file. (This file will be reprocessed and then at some point deleted.) fixZip.ChildAdd(foundFile, iRom); AddFoundFile(foundFile); ReCheckFile(tFile); //decrease index so this file gets reprocessed iRom--; continue; } // not needed as source and destination are the same // case ReturnCode.DestinationCheckSumError: default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } } break; #endregion #region Case.CanBeFixed case RepStatus.CanBeFixed: case RepStatus.CorruptCanBeFixed: { if (!(zipFileFixing.DatStatus == DatStatus.InDatCollect && (zipFileFixing.GotStatus == GotStatus.NotGot || zipFileFixing.GotStatus == GotStatus.Corrupt))) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); ReportError.LogOut("Fixing File:"); ReportError.LogOut(zipFileFixing); string strPath = fixZip.Parent.FullName; string tempZipFilename = Path.Combine(strPath, "__RomVault.tmp"); if (DBHelper.IsZeroLengthFile(zipFileFixing)) { RvFile fileIn = new RvFile(FileType.ZipFile) { Size = 0 }; RvFile foundFile; returnCode = FixFileCopy.CopyFile(fileIn, ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } break; } #if NEWFINDFIX List<RvFile> lstFixRomTable = new List<RvFile>(); List<RvFile> family = zipFileFixing.MyFamily.Family; for (int iFind = 0; iFind < family.Count; iFind++) { if (family[iFind].GotStatus == GotStatus.Got && FindFixes.CheckIfMissingFileCanBeFixedByGotFile(zipFileFixing, family[iFind])) lstFixRomTable.Add(family[iFind]); } #else List<RvFile> lstFixRomTable; DBHelper.RomSearchFindFixes(zipFileFixing, _lstRomTableSortedCRCSize, out lstFixRomTable); #endif ReportError.LogOut("Found Files To use for Fixes:"); foreach (RvFile t in lstFixRomTable) ReportError.LogOut(t); if (lstFixRomTable.Count > 0) { string ts = lstFixRomTable[0].Parent.FullName; string sourceDir; string sourceFile; if (lstFixRomTable[0].FileType == FileType.ZipFile) { sourceDir = Path.GetDirectoryName(ts); sourceFile = Path.GetFileName(ts); } else { sourceDir = ts; sourceFile = ""; } ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "<--", sourceDir, sourceFile, lstFixRomTable[0].Name)); RvFile foundFile; returnCode = FixFileCopy.CopyFile(lstFixRomTable[0], ref tempZipOut, tempZipFilename, zipFileFixing, false, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply so continue; break; case ReturnCode.SourceCRCCheckSumError: { ReportProgress(new bgwShowFixError("CRC Error")); // the file we used for fix turns out to be corrupt RvFile tFile = (RvFile)fixZip.Child(iRom); // mark the source file as Corrupt lstFixRomTable[0].GotStatus = GotStatus.Corrupt; // recheck for the fix ReCheckFile(tFile); // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to // start over on this zip. if (lstFixRomTable[0].Parent == fixZip) { returnCode = ReturnCode.StartOver; goto ZipOpenFailed; } // add the fixing source zip into the processList so that it is also reprocessed and we just changed it. if (!_processList.Contains(lstFixRomTable[0].Parent)) _processList.Add(lstFixRomTable[0].Parent); // and go back one and try again. iRom--; continue; } case ReturnCode.SourceCheckSumError: { ReportProgress(new bgwShowFixError("Failed")); // the file we used for fix turns out not not match its own DAT's correct MD5/SHA1 // (Problem with logic here is that it could still match the file being fixed, but this case is not correctly handled) RvFile tFile = (RvFile)fixZip.Child(iRom); // remove the file we thought we correctly had (The file that we where trying to use for the fix) if (lstFixRomTable[0].FileRemove() == EFile.Delete) { _error = "Should not mark for delete as it is in a DAT"; return ReturnCode.LogicError; } // possibly use a check here to see if the index of the found file is futher down the zip and so we can just contine // instead of restarting. // add in the actual file we found lstFixRomTable[0].Parent.ChildAdd(foundFile); AddFoundFile(foundFile); // recheck for the fix ReCheckFile(tFile); // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to // start over on this zip. if (lstFixRomTable[0].Parent == fixZip) { returnCode = ReturnCode.StartOver; goto ZipOpenFailed; } // add the fixing source zip into the processList so that it is also reprocessed and we just changed it. if (!_processList.Contains(lstFixRomTable[0].Parent)) _processList.Add(lstFixRomTable[0].Parent); // and go back one and try again. iRom--; continue; } case ReturnCode.DestinationCheckSumError: { ReportProgress(new bgwShowFixError("Failed")); // the file we used for fix turns out not to have the correct MD5/SHA1 RvFile tFile = (RvFile)fixZip.Child(iRom); // recheck for the fix ReCheckFile(tFile); // if the file being used from the fix is actually from this file then we have a big mess, and we are just going to // start over on this zip. // The need for this is that the file being pulled in from inside this zip will be marked as Rename // and so would then automatically be deleted, in the case this exception happens, this source file instead // should be set to move to tosort. if (lstFixRomTable[0].Parent == fixZip) { returnCode = ReturnCode.StartOver; goto ZipOpenFailed; } // and go back one and try again. iRom--; continue; } default: //_error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + Environment.NewLine + _error; goto ZipOpenFailed; } //Check to see if the files used for fix, can now be set to delete CheckReprocessClearList(); foreach (RvFile tFixRom in lstFixRomTable) { if (tFixRom.RepStatus == RepStatus.NeededForFix) { tFixRom.RepStatus = RepStatus.Delete; ReportError.LogOut("Setting File Status to Delete:"); ReportError.LogOut(tFixRom); CheckReprocess(tFixRom, true); } } CheckReprocessFinalCheck(); _fixed++; } else // thought we could fix it, turns out we cannot zipFileFixing.GotStatus = GotStatus.NotGot; } break; #endregion #region Case.MoveToSort case RepStatus.MoveToSort: { if (!(zipFileFixing.DatStatus == DatStatus.NotInDat && zipFileFixing.GotStatus == GotStatus.Got)) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); ReportError.LogOut("Moving File out to ToSort:"); ReportError.LogOut(zipFileFixing); // move the rom out to the To Sort Directory if (toSortGame == null) { string toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + ".zip"); string toSortFileName = fixZip.Name; int fileC = 0; while (File.Exists(toSortFullName)) { fileC++; toSortFullName = Path.Combine(Settings.ToSort(), fixZip.Name + fileC + ".zip"); toSortFileName = fixZip.Name + fileC; } toSortGame = new RvDir(FileType.Zip) { Name = toSortFileName, DatStatus = DatStatus.InToSort, GotStatus = GotStatus.Got }; } RvFile toSortRom = new RvFile(FileType.ZipFile) { Name = zipFileFixing.Name, Size = zipFileFixing.Size, CRC = zipFileFixing.CRC, SHA1 = zipFileFixing.SHA1, MD5 = zipFileFixing.MD5 }; toSortRom.SetStatus(DatStatus.InToSort, GotStatus.Got); toSortRom.FileStatusSet( FileStatus.SizeFromHeader | FileStatus.SizeVerified | FileStatus.CRCFromHeader | FileStatus.CRCVerified | FileStatus.SHA1FromHeader | FileStatus.SHA1Verified | FileStatus.MD5FromHeader | FileStatus.MD5Verified , zipFileFixing); toSortGame.ChildAdd(toSortRom); string destination = Path.Combine(Settings.ToSort(), toSortGame.Name + ".zip"); ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "ToSort", Path.GetFileName(destination), toSortRom.Name)); RvFile foundFile; returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortZipOut, destination, toSortRom, true, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; //raw copying so Checksums are not checked //case ReturnCode.SourceCRCCheckSumError: //case ReturnCode.SourceCheckSumError: //case ReturnCode.DestinationCheckSumError: default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } zipFileFixing.GotStatus = GotStatus.NotGot; // Changes RepStatus to Deleted } break; #endregion #region Case.MoveToCorrupt case RepStatus.MoveToCorrupt: { if (!((zipFileFixing.DatStatus == DatStatus.InDatCollect || zipFileFixing.DatStatus == DatStatus.NotInDat) && zipFileFixing.GotStatus == GotStatus.Corrupt)) ReportError.SendAndShow(Resources.FixFiles_FixZip_Error_in_Fix_Rom_Status + zipFileFixing.RepStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.DatStatus + Resources.FixFiles_FixZip_Colon + zipFileFixing.GotStatus); ReportError.LogOut("Moving File to Corrupt"); ReportError.LogOut(zipFileFixing); string toSortFullName; if (toSortCorruptGame == null) { string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); if (!Directory.Exists(corruptDir)) { Directory.CreateDirectory(corruptDir); } toSortFullName = Path.Combine(corruptDir, fixZip.Name + ".zip"); string toSortFileName = fixZip.Name; int fileC = 0; while (File.Exists(toSortFullName)) { fileC++; toSortFullName = Path.Combine(corruptDir, fixZip.Name + fileC + ".zip"); toSortFileName = fixZip.Name + fileC; } toSortCorruptGame = new RvDir(FileType.Zip) { Name = toSortFileName, DatStatus = DatStatus.InToSort, GotStatus = GotStatus.Got }; } else { string corruptDir = Path.Combine(Settings.ToSort(), "Corrupt"); toSortFullName = Path.Combine(corruptDir, toSortCorruptGame.Name + ".zip"); } RvFile toSortCorruptRom = new RvFile(FileType.ZipFile) { Name = zipFileFixing.Name, Size = zipFileFixing.Size, CRC = zipFileFixing.CRC }; toSortCorruptRom.SetStatus(DatStatus.InToSort, GotStatus.Corrupt); toSortCorruptGame.ChildAdd(toSortCorruptRom); ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), zipFileFixing.Name, zipFileFixing.Size, "-->", "Corrupt", Path.GetFileName(toSortFullName), zipFileFixing.Name)); RvFile foundFile; returnCode = FixFileCopy.CopyFile((RvFile)fixZip.Child(iRom), ref toSortCorruptOut, toSortFullName, toSortCorruptRom, true, out _error, out foundFile); switch (returnCode) { case ReturnCode.Good: // correct reply to continue; break; // doing a raw copy so not needed // case ReturnCode.SourceCRCCheckSumError: // case ReturnCode.SourceCheckSumError: // case ReturnCode.DestinationCheckSumError: default: _error = zipFileFixing.FullName + " " + zipFileFixing.RepStatus + " " + returnCode + " : " + _error; goto ZipOpenFailed; } zipFileFixing.GotStatus = GotStatus.NotGot; } break; #endregion default: ReportError.UnhandledExceptionHandler("Unknown file status found " + zipFileFixing.RepStatus + " while fixing file " + fixZip.Name + " Dat Status = " + zipFileFixing.DatStatus + " GotStatus " + zipFileFixing.GotStatus); break; } } #region if ToSort Zip Made then close the zip and add this new zip to the Database if (toSortGame != null) { toSortZipOut.ZipFileClose(); toSortGame.TimeStamp = toSortZipOut.TimeStamp; toSortGame.DatStatus = DatStatus.InToSort; toSortGame.GotStatus = GotStatus.Got; toSortGame.ZipStatus = toSortZipOut.ZipStatus; RvDir toSort = (RvDir)DB.DirTree.Child(1); toSort.ChildAdd(toSortGame); } #endregion #region if Corrupt Zip Made then close the zip and add this new zip to the Database if (toSortCorruptGame != null) { toSortCorruptOut.ZipFileClose(); toSortCorruptGame.TimeStamp = toSortCorruptOut.TimeStamp; toSortCorruptGame.DatStatus = DatStatus.InToSort; toSortCorruptGame.GotStatus = GotStatus.Got; RvDir toSort = (RvDir)DB.DirTree.Child(1); int indexcorrupt; RvDir corruptDir = new RvDir(FileType.Dir) { Name = "Corrupt", DatStatus = DatStatus.InToSort }; int found = toSort.ChildNameSearch(corruptDir, out indexcorrupt); if (found != 0) { corruptDir.GotStatus = GotStatus.Got; indexcorrupt = toSort.ChildAdd(corruptDir); } ((RvDir)toSort.Child(indexcorrupt)).ChildAdd(toSortCorruptGame); } #endregion #region Process original Zip string filename = fixZip.FullName; if (File.Exists(filename)) { if (!File.SetAttributes(filename, FileAttributes.Normal)) { int error = Error.GetLastError(); ReportProgress(new bgwShowError(filename, "Error Setting File Attributes to Normal. Deleting Original Fix File. Code " + error)); } try { File.Delete(filename); } catch (Exception) { int error = Error.GetLastError(); _error = "Error While trying to delete file " + filename + ". Code " + error; if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed) tempZipOut.ZipFileClose(); return ReturnCode.RescanNeeded; } } #endregion bool checkDelete = false; #region process the temp Zip rename it to the original Zip if (tempZipOut != null && tempZipOut.ZipOpen != ZipOpenType.Closed) { string tempFilename = tempZipOut.ZipFilename; tempZipOut.ZipFileClose(); if (tempZipOut.LocalFilesCount() > 0) { // now rename the temp fix file to the correct filename File.Move(tempFilename, filename); FileInfo nFile = new FileInfo(filename); RvDir tmpZip = new RvDir(FileType.Zip) { Name = Path.GetFileNameWithoutExtension(filename), TimeStamp = nFile.LastWriteTime }; tmpZip.SetStatus(fixZip.DatStatus, GotStatus.Got); fixZip.FileAdd(tmpZip); fixZip.ZipStatus = tempZipOut.ZipStatus; } else { File.Delete(tempFilename); checkDelete = true; } } else checkDelete = true; #endregion #region Now put the New Game Status information into the Database. int intLoopFix = 0; foreach (RvFile tmpZip in fixZipTemp) { tmpZip.CopyTo(fixZip.Child(intLoopFix)); if (fixZip.Child(intLoopFix).RepStatus == RepStatus.Deleted) if (fixZip.Child(intLoopFix).FileRemove() == EFile.Delete) { fixZip.ChildRemove(intLoopFix); continue; } intLoopFix++; } #endregion if (checkDelete) CheckDeleteObject(fixZip); ReportError.LogOut(""); ReportError.LogOut("Zip File Status After Fix:"); for (int intLoop = 0; intLoop < fixZip.ChildCount; intLoop++) ReportError.LogOut((RvFile)fixZip.Child(intLoop)); ReportError.LogOut(""); return ReturnCode.Good; ZipOpenFailed: if (tempZipOut != null) tempZipOut.ZipFileCloseFailed(); if (toSortZipOut != null) toSortZipOut.ZipFileCloseFailed(); if (toSortCorruptOut != null) toSortCorruptOut.ZipFileCloseFailed(); return returnCode; }
public static bool RomFromSameGame(RvFile a, RvFile b) { if (a.Parent == null) return false; if (b.Parent == null) return false; return a.Parent == b.Parent; }
public static bool IsZeroLengthFile(RvFile tFile) { if (tFile.MD5 != null) { if (!ArrByte.bCompare(tFile.MD5, ZeroByteMD5)) return false; } if (tFile.SHA1 != null) { if (!ArrByte.bCompare(tFile.SHA1, ZeroByteSHA1)) return false; } if (tFile.CRC != null) if (!ArrByte.bCompare(tFile.CRC, ZeroByteCRC)) return false; return tFile.Size == 0; }
public void FileStatusSet(FileStatus flag, RvFile copyFrom) { _fileStatus |= flag & copyFrom._fileStatus; }
public void FileStatusSet(FileStatus flag, RvFile copyFrom) { _fileStatus |= (flag & copyFrom._fileStatus); }
private static bool LoadRomFromDat(ref RvDir tGame, FileType thisFileType) { if (DatFileLoader.Next != "(") { DatUpdate.SendAndShowDat(Resources.DatCmpReader_LoadRomFromDat_not_found_after_rom, DatFileLoader.Filename); return false; } string line=DatFileLoader.GnRest(); string linelc = line.ToLower(); int posName = linelc.IndexOf("name ", StringComparison.Ordinal); int posSize = linelc.IndexOf(" size ", posName+5,StringComparison.Ordinal); int posDate = linelc.IndexOf(" date ", posSize+6,StringComparison.Ordinal); int posCrc = linelc.IndexOf(" crc ", posDate+6,StringComparison.Ordinal); int posEnd = linelc.IndexOf(" )", posCrc+5,StringComparison.Ordinal); if (posName < 0 || posSize < 0 || posDate < 0 || posCrc < 0 || posEnd < 0) { DatFileLoader.Gn(); return false; } string name = line.Substring(posName + 5, posSize - (posName + 5)); string size = line.Substring(posSize + 6, posDate - (posSize + 6)); //string date = line.Substring(posDate + 6, posCrc - (posDate + 6)); string crc = line.Substring(posCrc + 5, posEnd - (posCrc + 5)); RvFile tRom = new RvFile(thisFileType) { Dat = tGame.Dat, Name = VarFix.CleanFullFileName(name.Trim()), Size = VarFix.ULong(size.Trim()), CRC = VarFix.CleanMD5SHA1(crc.Trim(), 8) }; if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); tGame.ChildAdd(tRom); return true; }
private 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 all of the files that we have that match the needed SHA1 CHD. public static void RomSearchFindFixesSHA1CHD(RvFile tRom, List<RvFile> lstFiles, out List<RvFile> lstFilesOut) { lstFilesOut = new List<RvFile>(); if (tRom.SHA1CHD == null) return; int intIndex; int intRes = RomSearchSHA1CHD(tRom, lstFiles, out intIndex); while (intRes == 0) { if (lstFiles[intIndex].GotStatus == GotStatus.Got) lstFilesOut.Add(lstFiles[intIndex]); intIndex++; intRes = intIndex < lstFiles.Count ? RomSortSHA1CHDFunc(lstFiles[intIndex], tRom) : 1; } }
private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode, FileType thisFileType) { if (romNode.Attributes == null) return; RvFile tRom = new RvFile(thisFileType) { Dat = tGame.Dat, Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")), Name = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("name")), CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8), SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), MD5 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("md5"), 32), Merge = VarFix.CleanFullFileName(romNode.Attributes.GetNamedItem("merge")), Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")) }; if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); if (tRom.MD5 != null) tRom.FileStatusSet(FileStatus.MD5FromDAT); tGame.ChildAdd(tRom); }
// find all of the files that we think we have that match the needed CRC and Size. public static void RomSearchFindMatchingFiles(RvFile tRom, List<RvFile> lstFiles, out int startIndex, out int length) { int intIndex; int intRes = RomSearchCRCSize(tRom, lstFiles, out intIndex); startIndex = intIndex; while (intRes == 0) { intIndex++; intRes = intIndex < lstFiles.Count ? RomSortCRCSizeFunc(lstFiles[intIndex], tRom) : 1; } length = intIndex - startIndex; }
private static int RomSearchSHA1CHD(RvFile tRom, List<RvFile> lstFiles, out int index) { if (lstFiles.Count == 0) { index = 0; return -1; } // this one below method will always return the first item in a list if there is more than one matching result. int intBottom = -1; int intTop = lstFiles.Count - 1; while (intBottom + 1 < intTop) { int intMid = (intBottom + intTop + 1) / 2; int intRes = RomSortSHA1CHDFunc(lstFiles[intMid], tRom); if (intRes >= 0) intTop = intMid; else intBottom = intMid; } intBottom++; index = intBottom; return RomSortSHA1CHDFunc(lstFiles[intBottom], tRom); }
private static int RomSortCRCSizeFunc(RvFile a, RvFile b) { int retv = ArrByte.iCompare(a.CRC, b.CRC); if (retv == 0) retv = ULong.iCompare(a.Size, b.Size); return retv; }
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); }
private static void RomSortSHA1CHD(int intBase, int intTop, List<RvFile> lstFiles) { if ((intTop - intBase) <= 1) return; int intMiddle = (intTop + intBase) / 2; if ((intMiddle - intBase) > 1) RomSortSHA1CHD(intBase, intMiddle, lstFiles); if ((intTop - intMiddle) > 1) RomSortSHA1CHD(intMiddle, intTop, lstFiles); int intBottomSize = intMiddle - intBase; int intTopSize = intTop - intMiddle; RvFile[] lstBottom = new RvFile[intBottomSize]; RvFile[] lstTop = new RvFile[intTopSize]; for (int intloop = 0; intloop < intBottomSize; intloop++) lstBottom[intloop] = lstFiles[intBase + intloop]; for (int intloop = 0; intloop < intTopSize; intloop++) lstTop[intloop] = lstFiles[intMiddle + intloop]; int intBottomCount = 0; int intTopCount = 0; int intCount = intBase; while (intBottomCount < intBottomSize && intTopCount < intTopSize) { if (RomSortSHA1CHDFunc(lstBottom[intBottomCount], lstTop[intTopCount]) < 1) { lstFiles[intCount] = lstBottom[intBottomCount]; intCount++; intBottomCount++; } else { lstFiles[intCount] = lstTop[intTopCount]; intCount++; intTopCount++; } } while (intBottomCount < intBottomSize) { lstFiles[intCount] = lstBottom[intBottomCount]; intCount++; intBottomCount++; } while (intTopCount < intTopSize) { lstFiles[intCount] = lstTop[intTopCount]; intCount++; intTopCount++; } }
private static bool IschdmanScanned(RvFile tFile) { //if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader)) // return true; if (tFile.GotStatus == GotStatus.Corrupt) return true; return tFile.FileStatusIs(FileStatus.SHA1CHDVerified); }
private static int RomSortSHA1CHDFunc(RvFile a, RvFile b) { int retv = ArrByte.iCompare(a.SHA1CHD, b.SHA1CHD); return retv; }
private static void ChdManCheck(string directory, RvFile tFile) { string filename = Path.Combine(directory, tFile.Name); if (!tFile.FileStatusIs(FileStatus.SHA1CHDFromHeader)) return; _bgw.ReportProgress(0, new bgwText2(filename)); string error; CHD.CHDManCheck res = CHD.ChdmanCheck(filename, _bgw, out error); switch (res) { case CHD.CHDManCheck.Good: tFile.FileStatusSet(FileStatus.SHA1CHDVerified); return; case CHD.CHDManCheck.Corrupt: _bgw.ReportProgress(0, new bgwShowError(filename, error)); tFile.GotStatus = GotStatus.Corrupt; return; case CHD.CHDManCheck.CHDReturnError: case CHD.CHDManCheck.CHDUnknownError: _bgw.ReportProgress(0, new bgwShowError(filename, error)); return; case CHD.CHDManCheck.ChdmanNotFound: return; case CHD.CHDManCheck.CHDNotFound: ReportError.Show("File: " + filename + " Error: Not Found scan Aborted."); _fileErrorAbort = true; return; default: ReportError.UnhandledExceptionHandler(error); return; } }
private static void LoadRomFromDat(ref RvDir tGame, XmlNode romNode) { if (romNode.Attributes == null) return; XmlNode name = romNode.Attributes.GetNamedItem("name"); string loadflag = VarFix.String(romNode.Attributes.GetNamedItem("loadflag")); if (name != null) { RvFile tRom = new RvFile(FileType.ZipFile) { Name = VarFix.CleanFullFileName(name), Size = VarFix.ULong(romNode.Attributes.GetNamedItem("size")), CRC = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("crc"), 8), SHA1 = VarFix.CleanMD5SHA1(romNode.Attributes.GetNamedItem("sha1"), 40), Status = VarFix.ToLower(romNode.Attributes.GetNamedItem("status")), Dat = tGame.Dat }; if (tRom.Size != null) tRom.FileStatusSet(FileStatus.SizeFromDAT); if (tRom.CRC != null) tRom.FileStatusSet(FileStatus.CRCFromDAT); if (tRom.SHA1 != null) tRom.FileStatusSet(FileStatus.SHA1FromDAT); _indexContinue = tGame.ChildAdd(tRom); } else if (loadflag.ToLower() == "continue") { RvFile tZippedFile = (RvFile)tGame.Child(_indexContinue); tZippedFile.Size += VarFix.ULong(romNode.Attributes.GetNamedItem("size")); } }
//Raw Copy // Returns True is a raw copy can be used // Returns False is a full recompression is required private static bool RawCopy(RvFile fileIn, RvFile fileOut, bool forceRaw) { if (fileIn == null || fileOut == null) return false; if ((fileIn.FileType != FileType.ZipFile) || (fileOut.FileType != FileType.ZipFile)) return false; if (fileIn.Parent == null) return false; if (forceRaw) return true; bool trrntzipped = (fileIn.Parent.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip; bool deepchecked = fileIn.FileStatusIs(FileStatus.SHA1Verified) && fileIn.FileStatusIs(FileStatus.MD5Verified); switch (Settings.FixLevel) { case eFixLevel.TrrntZipLevel1: return trrntzipped; case eFixLevel.TrrntZipLevel2: return trrntzipped && deepchecked; case eFixLevel.TrrntZipLevel3: return false; case eFixLevel.Level1: return true; case eFixLevel.Level2: return deepchecked; case eFixLevel.Level3: return false; } return false; }
private static ReturnCode FixFilePreCheckFixFile(RvFile fixFile) { string fileName = fixFile.FullName; // find all files in the DB with this name // there could be another file if: // there is a wrong file with the same name that can just be deleted // there is a wrong file with the same name that needs moved to ToSort // there is a wrong file with the same name that is needed to fix another file List<RvBase> testList = new List<RvBase>(); RvDir parent = fixFile.Parent; int index; // start by finding the first file in the DB. (This should always work, as it will at least find the current file that CanBeFixed if (parent.ChildNameSearch(fixFile, out index) != 0) { ReportError.Show("Logic error trying to find the file we are fixing " + fileName); return ReturnCode.LogicError; } testList.Add(parent.Child(index++)); // now loop to see if there are any more files with the same name. (This is a case insensative compare) while (index < parent.ChildCount && DBHelper.CompareName(fixFile, parent.Child(index)) == 0) { testList.Add(parent.Child(index)); index++; } // if we found more that one file in the DB then we need to process the incorrect file first. if (testList.Count > 1) { foreach (RvBase testChild in testList) { if (testChild == fixFile) continue; if (testChild.DatStatus != DatStatus.NotInDat) { ReportError.Show(Resources.FixFiles_FixFile_Trying_to_fix_a_file_that_already_exists + fileName); return ReturnCode.LogicError; } RvFile testFile = testChild as RvFile; if (testFile == null) { ReportError.Show("Did not find a file logic error while fixing duplicate named file. in FixFile"); return ReturnCode.LogicError; } switch (testFile.RepStatus) { case RepStatus.Delete: { ReturnCode ret = FixFileDelete(testFile); if (ret != ReturnCode.Good) return ret; break; } case RepStatus.MoveToSort: { ReturnCode ret = FixFileMoveToSort(testFile); if (ret != ReturnCode.Good) return ret; break; } case RepStatus.MoveToCorrupt: { ReturnCode ret = FixFileMoveToCorrupt(testFile); if (ret != ReturnCode.Good) return ret; break; } case RepStatus.NeededForFix: case RepStatus.Rename: { // so now we have found the file with the same case insensative name and can rename it to something else to get it out of the way for now. // need to check that the .tmp filename does not already exists. File.SetAttributes(testChild.FullName, FileAttributes.Normal); File.Move(testChild.FullName, testChild.FullName + ".tmp"); if (!parent.FindChild(testChild, out index)) { ReportError.Show("Unknown file status in Matching File found of " + testFile.RepStatus); return ReturnCode.LogicError; } parent.ChildRemove(index); testChild.Name = testChild.Name + ".tmp"; parent.ChildAdd(testChild); break; } default: { ReportError.Show("Unknown file status in Matching File found of " + testFile.RepStatus); return ReturnCode.LogicError; } } } } else { // if there is only one file in the DB then it must be the current file that CanBeFixed if (testList[0] != fixFile) { ReportError.Show("Logic error trying to find the file we are fixing " + fileName + " DB found file does not match"); return ReturnCode.LogicError; } } return ReturnCode.Good; }