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); }
private static ReturnCode CheckInputAndOutputFile(RvFile fileIn, RvFile fileOut, out string error) { 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); } } error = ""; return(ReturnCode.Good); }
private static void RomCheckCollect(RvRom tRom, bool merge) { if (merge) { if (string.IsNullOrEmpty(tRom.Merge)) { tRom.Merge = "(Auto Merged)"; } tRom.PutInZip = false; return; } if (!string.IsNullOrEmpty(tRom.Merge)) { tRom.Merge = "(No-Merge) " + tRom.Merge; } if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && (tRom.Size == 0)) { tRom.PutInZip = true; return; } tRom.PutInZip = true; }
/* * In the mame Dat: * status="nodump" has a size but no CRC * status="baddump" has a size and crc */ private static void RomCheckCollect(DatFile tRom, bool merge) { if (merge) { if (string.IsNullOrEmpty(tRom.Merge)) { tRom.Merge = "(Auto Merged)"; } tRom.DatStatus = DatFileStatus.InDatMerged; return; } if (!string.IsNullOrEmpty(tRom.Merge)) { tRom.Merge = "(No-Merge) " + tRom.Merge; } if (tRom.Status == "nodump") { tRom.DatStatus = DatFileStatus.InDatBad; return; } if (ArrByte.bCompare(tRom.CRC, new byte[] { 0, 0, 0, 0 }) && (tRom.Size == 0)) { tRom.DatStatus = DatFileStatus.InDatCollect; return; } tRom.DatStatus = DatFileStatus.InDatCollect; }
public static void DatSetMakeNonMergeSet(DatDir tDat) { // look for merged roms, check if a rom exists in a parent set where the Name,Size and CRC all match. for (int g = 0; g < tDat.ChildCount; g++) { DatDir mGame = (DatDir)tDat.Child(g); if (mGame.DGame == null) { DatSetMakeNonMergeSet(mGame); } else { DatGame dGame = mGame.DGame; if (dGame?.device_ref == null) { continue; } List <DatDir> devices = new List <DatDir> { mGame }; foreach (string device in dGame.device_ref) { AddDevice(device, devices, tDat); } devices.RemoveAt(0); foreach (DatDir device in devices) { for (int i = 0; i < device.ChildCount; i++) { DatFile df0 = (DatFile)device.Child(i); bool crcFound = false; for (int j = 0; j < mGame.ChildCount; j++) { DatFile df1 = (DatFile)mGame.Child(j); if (ArrByte.bCompare(df0.SHA1, df1.SHA1)) { crcFound = true; break; } } if (!crcFound) { mGame.ChildAdd(device.Child(i)); } } } } } }
/* * 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 void DatSetRenameAndRemoveDups(RvDir tDat) { for (int g = 0; g < tDat.ChildCount; g++) { RvDir tDir = (RvDir)tDat.Child(g); if (tDir.Game == null) { DatSetRenameAndRemoveDups(tDir); } else { for (int r = 0; r < tDir.ChildCount - 1; r++) { RvFile f0 = (RvFile)tDir.Child(r); RvFile f1 = (RvFile)tDir.Child(r + 1); if (f0.Name != f1.Name) { continue; } if (f0.Size != f1.Size || !ArrByte.bCompare(f0.CRC, f1.CRC)) { tDir.ChildRemove(r + 1); // remove F1 f1.Name = f1.Name + "_" + ArrByte.ToString(f1.CRC); // rename F1; int pos = tDir.ChildAdd(f1); if (pos < r) { r = pos; } // if this rename moved the File back up the list, start checking again from that file. } else { tDir.ChildRemove(r + 1); } r--; } } } }
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); }
public static void RemoveDupes(DatDir tDat, bool testName = true, bool testWithMergeName = false) { for (int g = 0; g < tDat.ChildCount; g++) { DatDir mGame = (DatDir)tDat.Child(g); if (mGame.DGame == null) { RemoveDupes(mGame, testName); } else { bool found = true; while (found) { found = false; for (int r = 0; r < mGame.ChildCount; r++) { DatFile df0 = (DatFile)mGame.Child(r); for (int t = r + 1; t < mGame.ChildCount; t++) { DatFile df1 = (DatFile)mGame.Child(t); if (testName && df0.Name != df1.Name) { continue; } bool hasCRC = df0.CRC != null && df1.CRC != null; if (hasCRC && !ArrByte.bCompare(df0.CRC, df1.CRC)) { continue; } bool hasSHA1 = df0.SHA1 != null && df1.SHA1 != null; if (hasSHA1 && !ArrByte.bCompare(df0.SHA1, df1.SHA1)) { continue; } bool hasMD5 = df0.MD5 != null && df1.MD5 != null; if (hasMD5 && !ArrByte.bCompare(df0.MD5, df1.MD5)) { continue; } if (!hasCRC && !hasSHA1 && !hasMD5) { continue; } found = true; string name0 = df0.Name; string name1 = df1.Name; bool nS0 = name0.Contains("\\"); bool ns1 = name1.Contains("\\"); if (nS0 && !ns1) { mGame.ChildRemove(df0); } else if (!nS0 && ns1) { mGame.ChildRemove(df1); } else if (nS0 && ns1) { string s0 = name0.Substring(0, name0.IndexOf("\\", StringComparison.Ordinal)); string s1 = name1.Substring(0, name1.IndexOf("\\", StringComparison.Ordinal)); if (s0 != s1) { mGame.ChildRemove(df1); } else { int res = AlphanumComparatorFast.Compare(name0, name1); mGame.ChildRemove(res >= 0 ? df0 : df1); } } else if ((name0 == name1) || (testWithMergeName && (name0 == df1.Merge))) { mGame.ChildRemove(df1); } else { found = false; continue; } r = mGame.ChildCount; t = mGame.ChildCount; } } } } } }
public static void DatSetMakeSplitSet(DatDir tDat) { // look for merged roms, check if a rom exists in a parent set where the Name,Size and CRC all match. for (int g = 0; g < tDat.ChildCount; g++) { DatDir mGame = (DatDir)tDat.Child(g); if (mGame.DGame == null) { DatSetMakeSplitSet(mGame); } else { // find all parents of this game List <DatDir> lstParentGames = new List <DatDir>(); DatFindParentSets.FindParentSet(mGame, tDat, true, ref lstParentGames); // if no parents are found then just set all children as kept if (lstParentGames.Count == 0) { for (int r = 0; r < mGame.ChildCount; r++) { if (mGame.Child(r) is DatFile dfGame) { RomCheckCollect(dfGame, false); } } } else { for (int r = 0; r < mGame.ChildCount; r++) { if (((DatFile)mGame.Child(r)).Status == "nodump") { RomCheckCollect((DatFile)mGame.Child(r), false); continue; } bool found = false; foreach (DatDir romofGame in lstParentGames) { for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { // size/checksum compare, so name does not need to match // if (!string.Equals(mGame.Child(r).Name, romofGame.Child(r1).Name, StringComparison.OrdinalIgnoreCase)) // { // continue; // } ulong?size0 = ((DatFile)mGame.Child(r)).Size; ulong?size1 = ((DatFile)romofGame.Child(r1)).Size; if ((size0 != null) && (size1 != null) && (size0 != size1)) { continue; } byte[] crc0 = ((DatFile)mGame.Child(r)).CRC; byte[] crc1 = ((DatFile)romofGame.Child(r1)).CRC; if ((crc0 != null) && (crc1 != null) && !ArrByte.bCompare(crc0, crc1)) { continue; } byte[] sha0 = ((DatFile)mGame.Child(r)).SHA1; byte[] sha1 = ((DatFile)romofGame.Child(r1)).SHA1; if ((sha0 != null) && (sha1 != null) && !ArrByte.bCompare(sha0, sha1)) { continue; } byte[] md50 = ((DatFile)mGame.Child(r)).MD5; byte[] md51 = ((DatFile)romofGame.Child(r1)).MD5; if ((md50 != null) && (md51 != null) && !ArrByte.bCompare(md50, md51)) { continue; } if (((DatFile)mGame.Child(r)).isDisk != ((DatFile)romofGame.Child(r1)).isDisk) { continue; } // not needed as we are now checking for nodumps at the top of this code // don't merge if only one of the ROM is nodump //if (((DatFile)romofGame.Child(r1)).Status == "nodump" != (((DatFile)mGame.Child(r)).Status == "nodump")) //{ // continue; //} found = true; break; } if (found) { break; } } RomCheckCollect((DatFile)mGame.Child(r), found); } } } } }
private static void DatSetCheckCollect(RvDat tDat) { if (tDat.Games == null) { return; } // now look for merged roms. // check if a rom exists in a parent set where the Name,Size and CRC all match. for (int g = 0; g < tDat.Games.Count; g++) { RvGame mGame = tDat.Games[g]; List <RvGame> lstParentGames = new List <RvGame>(); FindParentSet(mGame, tDat, ref lstParentGames); if ((lstParentGames.Count == 0) || (mGame.IsBios?.ToLower() == "yes")) { for (int r = 0; r < mGame.RomCount; r++) { RomCheckCollect(mGame.Roms[r], false); } } else { for (int r = 0; r < mGame.RomCount; r++) { bool found = false; foreach (RvGame romofGame in lstParentGames) { for (int r1 = 0; r1 < romofGame.RomCount; r1++) { if (mGame.Roms[r].Name.ToLower() != romofGame.Roms[r1].Name.ToLower()) { continue; } ulong?Size0 = mGame.Roms[r].Size; ulong?Size1 = romofGame.Roms[r1].Size; if ((Size0 != null) && (Size1 != null) && (Size0 != Size1)) { continue; } byte[] CRC0 = mGame.Roms[r].CRC; byte[] CRC1 = romofGame.Roms[r1].CRC; if ((CRC0 != null) && (CRC1 != null) && !ArrByte.bCompare(CRC0, CRC1)) { continue; } byte[] SHA0 = mGame.Roms[r].SHA1; byte[] SHA1 = romofGame.Roms[r1].SHA1; if ((SHA0 != null) && (SHA1 != null) && !ArrByte.bCompare(SHA0, SHA1)) { continue; } byte[] MD50 = mGame.Roms[r].MD5; byte[] MD51 = romofGame.Roms[r1].MD5; if ((MD50 != null) && (MD51 != null) && !ArrByte.bCompare(MD50, MD51)) { continue; } // don't merge if only one of the ROM is nodump if (romofGame.Roms[r1].Status == "nodump" != (mGame.Roms[r].Status == "nodump")) { continue; } found = true; break; } if (found) { break; } } RomCheckCollect(mGame.Roms[r], found); } } } }
public static void DatSetMakeMergeSet(DatDir tDat, bool mergeWithGameName = true) { // look for merged roms, check if a rom exists in a parent set where the Name,Size and CRC all match. for (int g = 0; g < tDat.ChildCount; g++) { DatDir mGame = (DatDir)tDat.Child(g); if (mGame.DGame == null) { DatSetMakeMergeSet(mGame, mergeWithGameName); continue; } // find all parents of this game List <DatDir> lstParentGames = new List <DatDir>(); DatFindParentSets.FindParentSet(mGame, tDat, true, ref lstParentGames); // if no parents are found then just set all children as kept if (lstParentGames.Count == 0) { for (int r = 0; r < mGame.ChildCount; r++) { if (mGame.Child(r) is DatFile dfGame) { RomCheckCollect(dfGame, false); } } continue; } List <DatDir> pGames = new List <DatDir>(); List <DatDir> pBios = new List <DatDir>(); foreach (DatDir dd in lstParentGames) { if (dd.DGame.IsBios?.ToLower() == "yes") { pBios.Add(dd); } else { pGames.Add(dd); } } DatBase[] mGameTest = mGame.ToArray(); List <DatBase> mGameKeep = new List <DatBase>(); foreach (DatBase tGame in mGameTest) { if (((DatFile)tGame).Status == "nodump") { mGame.ChildAdd(tGame); continue; } // first remove any file that is in a parent BIOS set bool found = false; foreach (DatDir romofGame in pBios) { for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { // size/checksum compare, so name does not need to match // if (!string.Equals(mGame[r].Name, romofGame.Child(r1).Name, StringComparison.OrdinalIgnoreCase)) // { // continue; // } ulong?size0 = ((DatFile)tGame).Size; ulong?size1 = ((DatFile)romofGame.Child(r1)).Size; if ((size0 != null) && (size1 != null) && (size0 != size1)) { continue; } byte[] crc0 = ((DatFile)tGame).CRC; byte[] crc1 = ((DatFile)romofGame.Child(r1)).CRC; if ((crc0 != null) && (crc1 != null) && !ArrByte.bCompare(crc0, crc1)) { continue; } byte[] sha0 = ((DatFile)tGame).SHA1; byte[] sha1 = ((DatFile)romofGame.Child(r1)).SHA1; if ((sha0 != null) && (sha1 != null) && !ArrByte.bCompare(sha0, sha1)) { continue; } byte[] md50 = ((DatFile)tGame).MD5; byte[] md51 = ((DatFile)romofGame.Child(r1)).MD5; if ((md50 != null) && (md51 != null) && !ArrByte.bCompare(md50, md51)) { continue; } if (((DatFile)tGame).isDisk != ((DatFile)romofGame.Child(r1)).isDisk) { continue; } // not needed as we are now checking for nodumps at the top of this code // don't merge if only one of the ROM is nodump //if (((DatFile)romofGame.Child(r1)).Status == "nodump" != (((DatFile)mGame[r]).Status == "nodump")) //{ // continue; //} found = true; break; } if (found) { break; } } if (!found) { mGameKeep.Add(tGame); } } mGame.ChildrenClear(); if (pGames.Count == 0) { foreach (DatBase tGame in mGameKeep) { mGame.ChildAdd(tGame); } continue; } DatDir romOfTopParent = pGames[pGames.Count - 1]; foreach (DatBase tGame in mGameKeep) { if (mergeWithGameName && !((DatFile)tGame).isDisk) { tGame.Name = mGame.Name + "\\" + tGame.Name; } romOfTopParent.ChildAdd(tGame); } } }
// 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); }
// 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 ScanFiles(object sender, DoWorkEventArgs e) { try { _bgw = sender as BackgroundWorker; if (_bgw == null) { return; } Program.SyncCont = e.Argument as SynchronizationContext; if (Program.SyncCont == null) { _bgw = null; return; } _bgw.ReportProgress(0, new bgwText("Clearing DB Status")); RepairStatus.ReportStatusReset(DB.DirTree); List <RvFile> lstRomTableSortedCRCSize; List <RvFile> lstRomTableSortedSHA1CHD; _bgw.ReportProgress(0, new bgwText("Loading Rom List")); DBHelper.GetSelectedFilesSortCRCSize(out lstRomTableSortedCRCSize); DBHelper.GetSelectedFilesSortSHA1CHD(out lstRomTableSortedSHA1CHD); _bgw.ReportProgress(0, new bgwText("Scanning for Fixes")); _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedCRCSize.Count)); int romIndex0 = 0; int romIndex1 = 1; while (romIndex1 < lstRomTableSortedCRCSize.Count) { if (romIndex1 % 100 == 0) { _bgw.ReportProgress(romIndex1); } if (!ArrByte.bCompare(lstRomTableSortedCRCSize[romIndex0].CRC, lstRomTableSortedCRCSize[romIndex1].CRC) || (lstRomTableSortedCRCSize[romIndex0].Size != lstRomTableSortedCRCSize[romIndex1].Size)) { ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0); romIndex0 = romIndex1; } romIndex1++; } ListCheck(lstRomTableSortedCRCSize, romIndex0, romIndex1 - romIndex0); _bgw.ReportProgress(0, new bgwSetRange(lstRomTableSortedSHA1CHD.Count)); romIndex0 = 0; romIndex1 = 1; while (romIndex1 < lstRomTableSortedSHA1CHD.Count) { if (romIndex1 % 100 == 0) { _bgw.ReportProgress(romIndex1); } if (!ArrByte.bCompare(lstRomTableSortedSHA1CHD[romIndex0].SHA1CHD, lstRomTableSortedSHA1CHD[romIndex1].SHA1CHD)) { ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0); romIndex0 = romIndex1; } romIndex1++; } ListCheckSHA1CHD(lstRomTableSortedSHA1CHD, romIndex0, romIndex1 - romIndex0); _bgw = null; Program.SyncCont = null; } catch (Exception exc) { ReportError.UnhandledExceptionHandler(exc); if (_bgw != null) { _bgw.ReportProgress(0, new bgwText("Updating Cache")); } DB.Write(); if (_bgw != null) { _bgw.ReportProgress(0, new bgwText("Complete")); } _bgw = null; Program.SyncCont = null; } }
private static void DatSetCheckCollect(RvDir tDat) { // now look for merged roms. // check if a rom exists in a parent set where the Name,Size and CRC all match. for (int g = 0; g < tDat.ChildCount; g++) { RvDir mGame = (RvDir)tDat.Child(g); if (mGame.Game == null) { DatSetCheckCollect(mGame); } else { List <RvDir> lstParentGames = new List <RvDir>(); FindParentSet(mGame, tDat, ref lstParentGames); if (lstParentGames.Count == 0) { for (int r = 0; r < mGame.ChildCount; r++) { RomCheckCollect((RvFile)mGame.Child(r), false); } } else { for (int r = 0; r < mGame.ChildCount; r++) { bool found = false; foreach (RvDir romofGame in lstParentGames) { for (int r1 = 0; r1 < romofGame.ChildCount; r1++) { if (mGame.Child(r).Name != romofGame.Child(r1).Name) { continue; } ulong?Size0 = ((RvFile)mGame.Child(r)).Size; ulong?Size1 = ((RvFile)romofGame.Child(r1)).Size; if (Size0 != null && Size1 != null && Size0 != Size1) { continue; } byte[] CRC0 = ((RvFile)mGame.Child(r)).CRC; byte[] CRC1 = ((RvFile)romofGame.Child(r1)).CRC; if (CRC0 != null && CRC1 != null && !ArrByte.bCompare(CRC0, CRC1)) { continue; } byte[] SHA0 = ((RvFile)mGame.Child(r)).SHA1; byte[] SHA1 = ((RvFile)romofGame.Child(r1)).SHA1; if (SHA0 != null && SHA1 != null && !ArrByte.bCompare(SHA0, SHA1)) { continue; } byte[] MD50 = ((RvFile)mGame.Child(r)).MD5; byte[] MD51 = ((RvFile)romofGame.Child(r1)).MD5; if (MD50 != null && MD51 != null && !ArrByte.bCompare(MD50, MD51)) { continue; } byte[] chdSHA0 = ((RvFile)mGame.Child(r)).SHA1CHD; byte[] chdSHA1 = ((RvFile)romofGame.Child(r1)).SHA1CHD; if (chdSHA0 != null && chdSHA1 != null && !ArrByte.bCompare(chdSHA0, chdSHA1)) { continue; } byte[] chdMD50 = ((RvFile)mGame.Child(r)).MD5CHD; byte[] chdMD51 = ((RvFile)romofGame.Child(r1)).MD5CHD; if (chdMD50 != null && chdMD51 != null && !ArrByte.bCompare(chdMD50, chdMD51)) { continue; } found = true; break; } if (found) { break; } } RomCheckCollect((RvFile)mGame.Child(r), found); } } } } }
// 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 && (Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel1 || Program.rvSettings.FixLevel == eFixLevel.TrrntZipLevel2 || Program.rvSettings.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 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(); 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) { 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 && 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); }
public static void RemoveDupes(DatDir tDat) { for (int g = 0; g < tDat.ChildCount; g++) { DatDir mGame = (DatDir)tDat.Child(g); if (mGame.DGame == null) { RemoveDupes(mGame); } else { bool found = true; while (found) { found = false; for (int r = 0; r < mGame.ChildCount; r++) { DatFile df0 = (DatFile)mGame.Child(r); for (int t = r + 1; t < mGame.ChildCount; t++) { DatFile df1 = (DatFile)mGame.Child(t); if (!ArrByte.bCompare(df0.CRC, df1.CRC)) { continue; } found = true; string name0 = df0.Name; string name1 = df1.Name; bool nS0 = name0.Contains("\\"); bool ns1 = name1.Contains("\\"); if (nS0 && !ns1) { mGame.ChildRemove(df0); } else if (!nS0 && ns1) { mGame.ChildRemove(df1); } else if (nS0 && ns1) { string s0 = name0.Substring(0, name0.IndexOf("\\", StringComparison.Ordinal)); string s1 = name1.Substring(0, name1.IndexOf("\\", StringComparison.Ordinal)); if (s0 != s1) { mGame.ChildRemove(df1); } else { int res = AlphanumComparatorFast.Compare(name0, name1); mGame.ChildRemove(res >= 0 ? df0 : df1); } } else if (name0 == name1) { mGame.ChildRemove(df1); } else { found = false; continue; } r = mGame.ChildCount; t = mGame.ChildCount; } } } } } }