public static bool Execute(RvFile tFile) { if (tFile.Size == 0) { CommandZero.Parameters["crc"].Value = VarFix.ToDBString(tFile.CRC); CommandZero.Parameters["sha1"].Value = VarFix.ToDBString(tFile.SHA1); CommandZero.Parameters["md5"].Value = VarFix.ToDBString(tFile.MD5); object resZero = CommandZero.ExecuteScalar(); if (resZero == null || resZero == DBNull.Value) return false; int countZero = Convert.ToInt32(resZero); return countZero > 0; } Command.Parameters["size"].Value = tFile.Size; Command.Parameters["crc"].Value = VarFix.ToDBString(tFile.CRC); Command.Parameters["sha1"].Value = VarFix.ToDBString(tFile.SHA1); Command.Parameters["md5"].Value = VarFix.ToDBString(tFile.MD5); object res = Command.ExecuteScalar(); if (res == null || res == DBNull.Value) return false; int count = Convert.ToInt32(res); return count > 0; }
// CHDs as disk private static void ProcessDir(RvFile dir, int depth = 1) { string indent = new string('\t', depth); // recursive indent List <string> disks = new List <string> { string.Empty }; for (int i = 0; i < dir.ChildCount; i++) { RvFile item = dir.Child(i); if (item.IsDir && item.FileType == FileType.Dir) { if (disks.Count > 2 && item.Name != disks[0]) // flush the last one if there were only CHDs in it { justCHDs(indent, disks); disks.Clear(); } // tabulate next disk list, if any disks = new List <string> { item.Name, item.Game == null ? item.Name : item.Game.GetData(RvGame.GameData.Description) }; for (int j = 0; j < item.ChildCount; j++) { RvFile chd = item.Child(j); if (chd.IsFile && chd.FileType == FileType.File && chd.Name.EndsWith(".chd")) { if (!string.IsNullOrEmpty(chd.AltSHA1.ToHexString())) { disks.Add(indent + "\t<disk name=\"" + clean(chd.Name).Replace(".chd", "") + "\" sha1=\"" + chd.AltSHA1.ToHexString() + "\"/>"); } else { disks.Add(indent + "\t<disk name=\"" + clean(chd.Name).Replace(".chd", "") + "\" status=\"nodump\"/>"); } } } } if (item.FileType == FileType.Zip || item.FileType == FileType.SevenZip) { WriteLine(indent + "<game name=\"" + Path.GetFileNameWithoutExtension(clean(item.Name)) + "\">"); string desc = item.Game == null ? item.Name : item.Game.GetData(RvGame.GameData.Description); WriteLine(indent + "\t<description>" + clean(desc) + "</description>"); for (int j = 0; j < item.ChildCount; j++) { RvFile file = item.Child(j); if (file.IsFile) { WriteLine(indent + "\t<rom name=\"" + clean(file.Name) + "\" size=\"" + file.Size + "\" crc=\"" + file.CRC.ToHexString() + "\" md5=\"" + file.MD5.ToHexString() + "\" sha1=\"" + file.SHA1.ToHexString() + "\"/>"); } } if (disks.Count > 2) // take care of previous list of CHDs now { for (int j = 2; j < disks.Count; j++) { WriteLine(disks[j]); } disks.Clear(); } WriteLine(indent + "</game>"); } if (item.FileType == FileType.Dir) { if (numDisks(item) == 0) // only recurse when children are not CHDs { WriteLine(indent + "<dir name=\"" + clean(item.Name) + "\">"); ProcessDir(item, depth + 1); WriteLine(indent + "</dir>"); } } } // check for one last CHDs-only game if (disks.Count > 2) { justCHDs(indent, disks); } }
private static void SetChecked(RvFile pTree, RvTreeRow.TreeSelect nSelection) { RvTreeRow.OpenStream(); SetCheckedRecurse(pTree, nSelection); RvTreeRow.CloseStream(); }
public void Setup(ref RvFile dirTree) { Selected = null; _lTree = dirTree; SetupInt(); }
public static RvFile FromAZipFile(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker thWrk) { RvFile fileDir = new RvFile(dbDir.FileType); DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; string filename = dbDir.FullName; ICompress checkZ = dbDir.FileType == FileType.Zip ? new Zip() : (ICompress) new SevenZ(); ZipReturn zr = checkZ.ZipFileOpen(filename, dbDir.FileModTimeStamp); 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 (_fs == null) { _fs = new FileScan(); } List <FileScan.FileResults> fr = _fs.Scan(checkZ, false, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3); // 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(dbDir.FileType)) { Name = checkZ.Filename(i), ZipFileIndex = i, ZipFileHeaderPosition = checkZ.LocalHeader(i), Size = checkZ.UncompressedSize(i), CRC = checkZ.CRC32(i), FileModTimeStamp = checkZ.LastModified(i) }; // all levels read the CRC from the ZIP header tFile.SetStatus(chechingDatStatus, GotStatus.Got); tFile.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader); if (fr[i].FileStatus != ZipReturn.ZipGood) { thWrk.Report(new bgwShowCorrupt(fr[i].FileStatus, filename + " : " + checkZ.Filename(i))); tFile.GotStatus = GotStatus.Corrupt; } else { tFile.HeaderFileType = fr[i].HeaderFileType; tFile.SHA1 = fr[i].SHA1; tFile.MD5 = fr[i].MD5; tFile.AltSize = fr[i].AltSize; tFile.AltCRC = fr[i].AltCRC; tFile.AltSHA1 = fr[i].AltSHA1; tFile.AltMD5 = fr[i].AltMD5; tFile.FileStatusSet( FileStatus.SizeVerified | (fr[i].HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) | (fr[i].CRC != null ? FileStatus.CRCVerified : 0) | (fr[i].SHA1 != null ? FileStatus.SHA1Verified : 0) | (fr[i].MD5 != null ? FileStatus.MD5Verified : 0) | (fr[i].AltSize != null ? FileStatus.AltSizeVerified : 0) | (fr[i].AltCRC != null ? FileStatus.AltCRCVerified : 0) | (fr[i].AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) | (fr[i].AltMD5 != null ? FileStatus.AltMD5Verified : 0) ); } fileDir.ChildAdd(tFile); } } else if (zr == ZipReturn.ZipFileLocked) { thWrk.Report(new bgwShowError(filename, "Zip File Locked")); dbDir.FileModTimeStamp = 0; dbDir.GotStatus = GotStatus.FileLocked; } else { thWrk.Report(new bgwShowCorrupt(zr, filename)); dbDir.GotStatus = GotStatus.Corrupt; } checkZ.ZipFileClose(); return(fileDir); }
public static RvFile ReadInDatFile(RvDat datFile, ThreadWorker thWrk) { try { _thWrk = thWrk; string datRootFullName = datFile.GetData(RvDat.DatData.DatRootFullName); string fullPath = RvFile.GetDatPhysicalPath(datRootFullName); Debug.WriteLine("Reading Dat " + fullPath); DatRead dr = new DatRead { ErrorReport = ReadError }; dr.ReadDat(fullPath, out DatHeader dh); if (dh == null) { return(null); } // if we are auto adding extra directories then create a new directory. string extraDirName = ""; if (string.IsNullOrEmpty(extraDirName) && datFile.UseDescriptionAsDirName && !string.IsNullOrWhiteSpace(dh.Description)) { extraDirName = dh.Description; } if (string.IsNullOrEmpty(extraDirName)) { extraDirName = !string.IsNullOrEmpty(dh.RootDir) ? dh.RootDir : dh.Name; } string dirNameRule = Path.GetDirectoryName(datRootFullName) + Path.DirectorySeparatorChar + VarFix.CleanFileName(extraDirName) + Path.DirectorySeparatorChar; DatRule datRule = FindDatRule(dirNameRule); DatClean.CleanFilenames(dh.BaseDir); switch (datRule.Filter) { case FilterType.CHDsOnly: DatClean.RemoveNonCHD(dh.BaseDir); break; case FilterType.RomsOnly: DatClean.RemoveCHD(dh.BaseDir); break; } DatClean.RemoveNoDumps(dh.BaseDir); SetMergeType(datRule, dh); if (datFile.SingleArchive) { DatClean.MakeDatSingleLevel(dh, datFile.UseDescriptionAsDirName); } DatClean.RemoveUnNeededDirectories(dh.BaseDir); SetCompressionMethod(datRule, dh); // This sorts the files into the required dir order for the set compression type. DatClean.DirectoryExpand(dh.BaseDir); // this works because we only expand files, so the order inside the zip / 7z does not matter. DatClean.RemoveEmptyDirectories(dh.BaseDir); DatClean.CleanFilenamesFixDupes(dh.BaseDir); // you may get repeat filenames inside Zip's / 7Z's and they may not be sorted to find them by now. RvFile newDir = ExternalDatConverter.ConvertFromExternalDat(dh, datFile); return(newDir); } catch (Exception e) { string datRootFullName = datFile?.GetData(RvDat.DatData.DatRootFullName); Console.WriteLine(e); throw new Exception("Error is DAT " + datRootFullName + " " + e.Message); } }
public static List <RvFile> GetFixFileList(RvFile fixFile) { return(fixFile.FileGroup.Files.FindAll(file => file.GotStatus == GotStatus.Got && DBHelper.CheckIfMissingFileCanBeFixedByGotFile(fixFile, file))); }
private static bool RecursiveDatTree(RvFile tDir, out int datCount) { datCount = 0; string strPath = RvFile.GetDatPhysicalPath(tDir.DatTreeFullName); if (!Directory.Exists(strPath)) { ReportError.Show("Path: " + strPath + " Not Found."); return(false); } DirectoryInfo oDir = new DirectoryInfo(strPath); List <FileInfo> lFilesIn = new List <FileInfo>(); FileInfo[] oFilesIn = oDir.GetFiles("*.dat", false); lFilesIn.AddRange(oFilesIn); oFilesIn = oDir.GetFiles("*.xml", false); lFilesIn.AddRange(oFilesIn); datCount += lFilesIn.Count; foreach (FileInfo file in lFilesIn) { RvDat tDat = new RvDat(); tDat.AddData(RvDat.DatData.DatRootFullName, Path.Combine(tDir.DatTreeFullName, file.Name)); tDat.TimeStamp = file.LastWriteTime; string datRootFullName = tDat.GetData(RvDat.DatData.DatRootFullName); DatRule datRule = DatReader.FindDatRule(datRootFullName); tDat.MultiDatOverride = datRule.MultiDATDirOverride; tDat.UseDescriptionAsDirName = datRule.UseDescriptionAsDirName; tDat.SingleArchive = datRule.SingleArchive; tDat.RemoveSubDir = datRule.RemoveSubDir; tDir.DirDatAdd(tDat); } if (tDir.DirDatCount > 1) { for (int i = 0; i < tDir.DirDatCount; i++) { tDir.DirDat(i).MultiDatsInDirectory = true; } } DirectoryInfo[] oSubDir = oDir.GetDirectories(false); foreach (DirectoryInfo t in oSubDir) { RvFile cDir = new RvFile(FileType.Dir) { Name = t.Name, DatStatus = DatStatus.InDatCollect }; int index = tDir.ChildAdd(cDir); RecursiveDatTree(cDir, out int retDatCount); datCount += retDatCount; if (retDatCount == 0) { tDir.ChildRemove(index); } } 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); }
public static void ListCheck(List <RvFile> lstRomTableSortedCRC, int start, int length) { if (lstRomTableSortedCRC.Count == 0) { return; } List <RvFile> missingFiles = new List <RvFile>(); // files we dont have that we need List <RvFile> correctFiles = new List <RvFile>(); // files we have that are in the correct place List <RvFile> unNeededFiles = new List <RvFile>(); // files we have that are not in the correct place List <RvFile> inToSortFiles = new List <RvFile>(); // files we have that are in tosort List <RvFile> allGotFiles = new List <RvFile>(); // all files we have List <RvFile> corruptFiles = new List <RvFile>(); // corrupt files that we do not need, a corrupt file is missing if it is needed // set the found status of this file for (int iLoop = 0; iLoop < length; iLoop++) { RvFile tFile = lstRomTableSortedCRC[start + iLoop]; switch (tFile.RepStatus) { case RepStatus.UnScanned: break; case RepStatus.Missing: missingFiles.Add(tFile); // these are checked in step 1 to fixes from the allGotFiles List. break; case RepStatus.Correct: correctFiles.Add(tFile); break; case RepStatus.Corrupt: if (tFile.DatStatus == DatStatus.InDatCollect) { missingFiles.Add(tFile); // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found. } else { corruptFiles.Add(tFile); // all other corrupt files should be deleted or moved to tosort/corrupt } break; case RepStatus.UnNeeded: case RepStatus.Unknown: unNeededFiles.Add(tFile); break; case RepStatus.NotCollected: break; case RepStatus.InToSort: inToSortFiles.Add(tFile); break; case RepStatus.Ignore: break; // Ignore File default: ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus); break; } } allGotFiles.AddRange(correctFiles); allGotFiles.AddRange(unNeededFiles); allGotFiles.AddRange(inToSortFiles); #region Step 1 Check the Missing files from the allGotFiles List. // check to see if we can find any of the missing files in the gotFiles list. // if we find them mark them as CanBeFixed, // or if they are missing corrupt files set then as corruptCanBefixed foreach (RvFile missingFile in missingFiles) { if (DBHelper.IsZeroLengthFile(missingFile)) { missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed; continue; } foreach (RvFile gotFile in allGotFiles) { if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, gotFile)) { continue; } missingFile.RepStatus = missingFile.RepStatus == RepStatus.Corrupt ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed; break; } if (missingFile.RepStatus == RepStatus.Corrupt) { missingFile.RepStatus = RepStatus.MoveToCorrupt; } } #endregion #region Step 2 Check all corrupt files. // if we have a correct version of the corrupt file then the corrput file can just be deleted, // otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort. // we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with foreach (RvFile corruptFile in corruptFiles) { if (allGotFiles.Count > 0) { corruptFile.RepStatus = RepStatus.Delete; } if ((corruptFile.RepStatus == RepStatus.Corrupt) && (corruptFile.DatStatus != DatStatus.InToSort)) { corruptFile.RepStatus = RepStatus.MoveToCorrupt; } } #endregion #region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort foreach (RvFile unNeededFile in unNeededFiles) { /* * // check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted. * foreach (RvFile correctFile in correctFiles) * { * if (!FindSHA1MD5MatchingFiles(unNeededFile, correctFile)) continue; * unNeededFile.RepStatus = RepStatus.Delete; * break; * } * if (unNeededFile.RepStatus == RepStatus.Delete) continue; */ if (DBHelper.IsZeroLengthFile(unNeededFile)) { unNeededFile.RepStatus = RepStatus.Delete; continue; } // check if the unNeededFile is needed to fix a missing file foreach (RvFile missingFile in missingFiles) { if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, unNeededFile)) { continue; } unNeededFile.RepStatus = RepStatus.NeededForFix; break; } if (unNeededFile.RepStatus == RepStatus.NeededForFix) { continue; } // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted. foreach (RvFile correctFile in correctFiles) { if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, correctFile)) { continue; } unNeededFile.RepStatus = RepStatus.Delete; break; } if (unNeededFile.RepStatus == RepStatus.Delete) { continue; } // and finally see if the file is already in ToSort, and if it is deleted. foreach (RvFile inToSortFile in inToSortFiles) { if (!CheckIfGotfileAndMatchingFileAreFullMatches(unNeededFile, inToSortFile)) { continue; } unNeededFile.RepStatus = RepStatus.Delete; break; } if (unNeededFile.RepStatus == RepStatus.Delete) { continue; } // otherwise move the file out to ToSort unNeededFile.RepStatus = RepStatus.MoveToSort; } #endregion #region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort foreach (RvFile inToSortFile in inToSortFiles) { /* * // check if we have a confirmed SHA1 / MD5 match of this file, and if we do we just mark this file to be deleted. * foreach (RvFile correctFile in correctFiles) * { * if (!FindSHA1MD5MatchingFiles(inToSortFile, correctFile)) continue; * inToSortFile.RepStatus = RepStatus.Delete; * break; * } * if (inToSortFile.RepStatus == RepStatus.Delete) continue; */ // check if the ToSortFile is needed to fix a missing file foreach (RvFile missingFile in missingFiles) { if (!CheckIfMissingFileCanBeFixedByGotFile(missingFile, inToSortFile)) { continue; } inToSortFile.RepStatus = RepStatus.NeededForFix; break; } if (inToSortFile.RepStatus == RepStatus.NeededForFix) { continue; } // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted. foreach (RvFile correctFile in correctFiles) { if (!CheckIfGotfileAndMatchingFileAreFullMatches(inToSortFile, correctFile)) { continue; } inToSortFile.RepStatus = RepStatus.Delete; break; } // otherwise leave the file in ToSort } #endregion //need to check here for roms that just need renamed inside the one ZIP //this prevents Zips from self deadlocking for (int iLoop0 = 0; iLoop0 < length; iLoop0++) { if (lstRomTableSortedCRC[start + iLoop0].RepStatus != RepStatus.NeededForFix) { continue; } for (int iLoop1 = 0; iLoop1 < length; iLoop1++) { if (lstRomTableSortedCRC[start + iLoop1].RepStatus != RepStatus.CanBeFixed) { continue; } if (!CheckIfMissingFileCanBeFixedByGotFile(lstRomTableSortedCRC[start + iLoop1], lstRomTableSortedCRC[start + iLoop0])) { continue; } if (DBHelper.RomFromSameGame(lstRomTableSortedCRC[start + iLoop0], lstRomTableSortedCRC[start + iLoop1])) { lstRomTableSortedCRC[start + iLoop0].RepStatus = RepStatus.Rename; } } } }
public static void CreateToSortDirs(RvFile inFile, out RvFile outDir, out string filename) { List <RvFile> dirTree = new List <RvFile>(); RvFile rFile = inFile; while (rFile.Parent != null) { rFile = rFile.Parent; dirTree.Insert(0, rFile); } dirTree.RemoveAt(0); RvFile toSort = DB.RvFileToSort(); dirTree[0] = toSort; int dirTreeCount = dirTree.Count; for (int i = 1; i < dirTreeCount; i++) { RvFile baseDir = dirTree[i - 1]; RvFile thisDir = dirTree[i]; RvFile tDir = new RvFile(FileType.Dir) { Name = thisDir.Name, DatStatus = DatStatus.InToSort }; int found = baseDir.ChildNameSearch(tDir, out int index); if (found == 0) { tDir = baseDir.Child(index); } else { baseDir.ChildAdd(tDir, index); } string fullpath = tDir.FullName; if (!Directory.Exists(fullpath)) { Directory.CreateDirectory(fullpath); DirectoryInfo di = new DirectoryInfo(fullpath); tDir.SetStatus(DatStatus.InToSort, GotStatus.Got); tDir.TimeStamp = di.LastWriteTime; } dirTree[i] = tDir; } outDir = dirTree[dirTreeCount - 1]; filename = inFile.Name; string toSortFullName = Path.Combine(outDir.FullName, filename); int fileC = 0; string name = null, ext = null; while (File.Exists(toSortFullName)) { if (name == null) { int pIndex = inFile.Name.LastIndexOf('.'); if (pIndex >= 0) { name = inFile.Name.Substring(0, pIndex); ext = inFile.Name.Substring(pIndex + 1); } else { name = inFile.Name; ext = ""; } } filename = name + "_" + fileC + "." + ext; toSortFullName = Path.Combine(outDir.FullName, filename); } }
private void RomGridMouseUp(object sender, MouseEventArgs e) { if (e == null || e.Button == MouseButtons.Left) { var hitTest = RomGrid.HitTest(e.X, e.Y); if (hitTest.ColumnIndex != (int)eRomGrid.DupeCount) { return; } if (hitTest.RowIndex < 0) { return; } RvFile tFile = romGrid[hitTest.RowIndex]; FrmRomInfo fri = new FrmRomInfo(); fri.SetRom(tFile); fri.ShowDialog(); return; } if (e == null || e.Button != MouseButtons.Right) { return; } int currentMouseOverRow = RomGrid.HitTest(e.X, e.Y).RowIndex; if (currentMouseOverRow < 0) { return; } string name = (RomGrid.Rows[currentMouseOverRow].Cells[1].Value ?? "").ToString(); string size = (RomGrid.Rows[currentMouseOverRow].Cells[3].Value ?? "").ToString(); if (size.Contains(" ")) { size = size.Substring(0, size.IndexOf(" ")); } string crc = (RomGrid.Rows[currentMouseOverRow].Cells[4].Value ?? "").ToString(); if (crc.Length > 8) { crc = crc.Substring(0, 8); } string sha1 = (RomGrid.Rows[currentMouseOverRow].Cells[5].Value ?? "").ToString(); if (sha1.Length > 40) { sha1 = sha1.Substring(0, 40); } string md5 = (RomGrid.Rows[currentMouseOverRow].Cells[6].Value ?? "").ToString(); if (md5.Length > 32) { md5 = md5.Substring(0, 32); } string clipText = "Name : " + name + Environment.NewLine; clipText += "Size : " + size + Environment.NewLine; clipText += "CRC32: " + crc + Environment.NewLine; if (sha1.Length > 0) { clipText += "SHA1 : " + sha1 + Environment.NewLine; } if (md5.Length > 0) { clipText += "MD5 : " + md5 + Environment.NewLine; } try { Clipboard.Clear(); Clipboard.SetText(clipText); } catch { } }
private void RomGridCellValueNeeded(object sender, DataGridViewCellValueEventArgs e) { RvFile tFile = romGrid[e.RowIndex]; switch ((eRomGrid)e.ColumnIndex) { case eRomGrid.Got: Bitmap bmp = new Bitmap(54, 18); Graphics g = Graphics.FromImage(bmp); string bitmapName = "R_" + tFile.DatStatus + "_" + tFile.RepStatus; Bitmap romIcon = rvImages.GetBitmap(bitmapName); if (romIcon != null) { g.DrawImage(romIcon, 0, 0, 54, 18); e.Value = bmp; } else { Debug.WriteLine($"Missing image for {bitmapName}"); } g.Dispose(); break; case eRomGrid.Rom: string fname = tFile.UiDisplayName; if (!string.IsNullOrEmpty(tFile.FileName)) { fname += " (Found: " + tFile.FileName + ")"; } if (tFile.CHDVersion != null) { fname += " (V" + tFile.CHDVersion + ")"; } if (tFile.HeaderFileType != HeaderFileType.Nothing) { fname += " (" + tFile.HeaderFileType + ")"; } e.Value = fname; break; case eRomGrid.Merge: e.Value = tFile.Merge; break; case eRomGrid.Size: e.Value = SetCell(tFile.Size.ToString(), tFile, FileStatus.SizeFromDAT, FileStatus.SizeFromHeader, FileStatus.SizeVerified); break; case eRomGrid.CRC32: e.Value = SetCell(tFile.CRC.ToHexString(), tFile, FileStatus.CRCFromDAT, FileStatus.CRCFromHeader, FileStatus.CRCVerified); break; case eRomGrid.SHA1: e.Value = SetCell(tFile.SHA1.ToHexString(), tFile, FileStatus.SHA1FromDAT, FileStatus.SHA1FromHeader, FileStatus.SHA1Verified); break; case eRomGrid.MD5: e.Value = SetCell(tFile.MD5.ToHexString(), tFile, FileStatus.MD5FromDAT, FileStatus.MD5FromHeader, FileStatus.MD5Verified); break; case eRomGrid.AltSize: e.Value = SetCell(tFile.AltSize.ToString(), tFile, FileStatus.AltSizeFromDAT, FileStatus.AltSizeFromHeader, FileStatus.AltSizeVerified); break; case eRomGrid.AltCRC32: e.Value = SetCell(tFile.AltCRC.ToHexString(), tFile, FileStatus.AltCRCFromDAT, FileStatus.AltCRCFromHeader, FileStatus.AltCRCVerified); break; case eRomGrid.AltSHA1: e.Value = SetCell(tFile.AltSHA1.ToHexString(), tFile, FileStatus.AltSHA1FromDAT, FileStatus.AltSHA1FromHeader, FileStatus.AltSHA1Verified); break; case eRomGrid.AltMD5: e.Value = SetCell(tFile.AltMD5.ToHexString(), tFile, FileStatus.AltMD5FromDAT, FileStatus.AltMD5FromHeader, FileStatus.AltMD5Verified); break; case eRomGrid.Status: e.Value = tFile.Status; break; case eRomGrid.DateModFile: { if (tFile.FileModTimeStamp == 0) { break; } DateTime tmp = new DateTime(tFile.FileModTimeStamp); e.Value = tmp.ToString("yyyy/MM/dd HH:mm:ss"); break; } #if dt case eRomGrid.DateModDat: { if (tFile.DatModTimeStamp == null) { break; } DateTime tmp = new DateTime((long)tFile.DatModTimeStamp); e.Value = tmp.ToString("yyyy/MM/dd HH:mm:ss"); break; } #endif case eRomGrid.ZipIndex: if (tFile.FileType == FileType.ZipFile) { e.Value = tFile.ZipFileIndex == -1 ? "" : tFile.ZipFileIndex.ToString(); } break; case eRomGrid.DupeCount: if (tFile.FileGroup != null) { e.Value = tFile.FileGroup.Files.Count.ToString(); } break; } }
public static bool Phase1Test(RvFile dbFile, RvFile testFile, EScanLevel eScanLevel, int indexCase, out bool MatchedAlt) { MatchedAlt = false; //Debug.WriteLine("Comparing Dat File " + dbFile.TreeFullName); //Debug.WriteLine("Comparing File " + testFile.TreeFullName); int retv = indexCase == 0 ? dbFile.Name.CompareTo(testFile.Name): DBHelper.CompareName(dbFile, testFile); if (retv != 0) { return(false); } FileType dbfileType = dbFile.FileType; FileType dbtestFile = testFile.FileType; #if ZipFile if (dbfileType == FileType.File && dbtestFile == FileType.Zip) { dbtestFile = FileType.File; } #endif retv = Math.Sign(dbfileType.CompareTo(dbtestFile)); if (retv != 0) { return(false); } // filetypes are now know to be the same // Dir's and Zip's are not deep scanned so matching here is done if (dbfileType == FileType.Dir || dbfileType == FileType.Zip || dbfileType == FileType.SevenZip) { return(true); } // we can now fully test anything that had a CRC in the testFile // this is anything that came from an archive, or a file that was level 3 scanned if (testFile.CRC != null) { return(CompareWithAlt(dbFile, testFile, out MatchedAlt)); } // we are now just dealing with Files that were not scanned at all already. // Phase 1 we will try and just do a timestamp / file size match for this. // but if we are scanning at a deeper level than the DB file then we cannot timestamp match. // // this could happen where we started with a level 1 scan of a file, and are now re-scanning at level 2 if (eScanLevel != EScanLevel.Level1 && !Utils.IsDeepScanned(dbFile)) { return(false); } if (dbFile.FileModTimeStamp != testFile.FileModTimeStamp) { return(false); } if (dbFile.Size == testFile.Size) { return(true); } if ((dbFile.Size ?? 0) + (ulong)FileHeaderReader.FileHeaderReader.GetFileHeaderLength(dbFile.HeaderFileType) != testFile.Size) { return(false); } MatchedAlt = true; return(true); }
public static ReturnCode MoveFile(RvFile fileIn, RvFile fileOut, string outFilename, out bool fileMoved, out string error) { error = ""; fileMoved = false; bool fileMove = TestFileMove(fileIn, fileOut); if (!fileMove) { return(ReturnCode.Good); } byte[] bCRC; byte[] bMD5 = null; byte[] bSHA1 = null; string fileNameIn = fileIn.FullName; if (!File.Exists(fileNameIn)) { error = "Rescan needed, File Not Found :" + fileNameIn; return(ReturnCode.RescanNeeded); } FileInfo fileInInfo = new FileInfo(fileNameIn); if (fileInInfo.LastWriteTime != fileIn.FileModTimeStamp) { error = "Rescan needed, File Changed :" + fileNameIn; return(ReturnCode.RescanNeeded); } string fileNameOut = outFilename ?? fileOut.FullName; File.Move(fileNameIn, fileNameOut); bCRC = fileIn.CRC.Copy(); if (fileIn.FileStatusIs(FileStatus.MD5Verified)) { bMD5 = fileIn.MD5.Copy(); } if (fileIn.FileStatusIs(FileStatus.SHA1Verified)) { bSHA1 = fileIn.SHA1.Copy(); } FileInfo fi = new FileInfo(fileNameOut); fileOut.FileModTimeStamp = fi.LastWriteTime; ReturnCode retC = ValidateFileOut(fileIn, fileOut, true, bCRC, bSHA1, bMD5, out error); if (retC != ReturnCode.Good) { return(retC); } CheckDeleteFile(fileIn); fileMoved = true; return(ReturnCode.Good); }
public static void CheckAllDats(RvFile dbFile, string romVaultPath) { CheckAllDatsInternal(dbFile, "DatRoot" + romVaultPath.Substring(8)); }
private static void ListCheckSHA1CHD(List <RvFile> lstRomTableSortedSHA1CHD, int start, int length) { if (lstRomTableSortedSHA1CHD.Count == 0) { return; } List <RvFile> missingFiles = new List <RvFile>(); // files we done have have that we need List <RvFile> correctFiles = new List <RvFile>(); // files we have that are in the correct place List <RvFile> unNeededFiles = new List <RvFile>(); // files we have that are not in the correct place List <RvFile> inToSortFiles = new List <RvFile>(); // files we have that are in tosort List <RvFile> allGotFiles = new List <RvFile>(); // all files we have List <RvFile> corruptFiles = new List <RvFile>(); // corrupt files that we do not need, a corrupt file is missing if it is needed // set the found status of this file for (int iLoop = 0; iLoop < length; iLoop++) { RvFile tFile = lstRomTableSortedSHA1CHD[start + iLoop]; switch (tFile.RepStatus) { case RepStatus.Missing: missingFiles.Add(tFile); // these are checked in step 1 to fixes from the allGotFiles List. break; case RepStatus.Correct: correctFiles.Add(tFile); break; case RepStatus.Corrupt: case RepStatus.MoveToCorrupt: if (tFile.DatStatus == DatStatus.InDatCollect) { missingFiles.Add(tFile); // corrupt files that are also InDatcollect are treated as missing files, and a fix should be found. } else { corruptFiles.Add(tFile); // all other corrupt files should be deleted or moved to tosort/corrupt } break; case RepStatus.UnNeeded: case RepStatus.Unknown: case RepStatus.MoveToSort: case RepStatus.InToSort: case RepStatus.Delete: case RepStatus.NeededForFix: case RepStatus.Rename: if (tFile.IsInToSort) { inToSortFiles.Add(tFile); } else { unNeededFiles.Add(tFile); } break; case RepStatus.NotCollected: break; case RepStatus.Ignore: break; // Ignore File default: ReportError.SendAndShow(Resources.FindFixes_ListCheck_Unknown_test_status + tFile.DatFullName + Resources.Comma + tFile.DatStatus + Resources.Comma + tFile.RepStatus); break; } } allGotFiles.AddRange(correctFiles); allGotFiles.AddRange(unNeededFiles); allGotFiles.AddRange(inToSortFiles); #region Step 1 Check the Missing files from the allGotFiles List. // check to see if we can find any of the missing files in the gotFiles list. // if we find them mark them as CanBeFixed, foreach (RvFile missingFile in missingFiles) { if (allGotFiles.Count > 0) { missingFile.RepStatus = (missingFile.RepStatus == RepStatus.Corrupt) || (missingFile.RepStatus == RepStatus.MoveToCorrupt) ? RepStatus.CorruptCanBeFixed : RepStatus.CanBeFixed; } } #endregion #region Step 2 Check all corrupt files. // if we have a correct version of the corrupt file then the corrput file can just be deleted, // otherwise if the corrupt file is not already in ToSort it should be moved out to ToSort. // we can only check corrupt files using the CRC from the ZIP header, as it is corrupt so we cannot get a correct SHA1 / MD5 to check with foreach (RvFile corruptFile in corruptFiles) { if (allGotFiles.Count > 0) { corruptFile.RepStatus = RepStatus.Delete; } if ((corruptFile.RepStatus == RepStatus.Corrupt) && (corruptFile.DatStatus != DatStatus.InToSort)) { corruptFile.RepStatus = RepStatus.MoveToCorrupt; } } #endregion #region Step 3 Check if unNeeded files are needed for a fix, otherwise delete them or move them to tosort foreach (RvFile unNeededFile in unNeededFiles) { // check if the unNeededFile is needed to fix a missing file if (missingFiles.Count > 0) { unNeededFile.RepStatus = RepStatus.NeededForFix; continue; } // now that we know this file is not needed for a fix if we have a correct version of it, it can be deleted. if (correctFiles.Count > 0) { // this probably should check its old state if (unNeededFile.RepStatus != RepStatus.NeededForFix) { unNeededFile.RepStatus = RepStatus.Delete; } continue; } if (inToSortFiles.Count > 0) { if (unNeededFile.RepStatus != RepStatus.NeededForFix) { unNeededFile.RepStatus = RepStatus.Delete; } continue; } // otherwise move the file out to ToSort if (unNeededFile.RepStatus != RepStatus.NeededForFix) { unNeededFile.RepStatus = RepStatus.MoveToSort; } } #endregion #region Step 4 Check if ToSort files are needed for a fix, otherwise delete them or leave them in tosort foreach (RvFile inToSortFile in inToSortFiles) { // check if the ToSortFile is needed to fix a missing file if (missingFiles.Count > 0) { inToSortFile.RepStatus = RepStatus.NeededForFix; continue; } // now that we know this file is not needed for a fix do a CRC only find against correct files to see if this file can be deleted. if (correctFiles.Count <= 0) { continue; } if (inToSortFile.RepStatus != RepStatus.NeededForFix) { inToSortFile.RepStatus = RepStatus.Delete; } // otherwise leave the file in ToSort } #endregion }
public static RvFile FindSourceToUseForFix(RvFile fixFile, List <RvFile> lstFixRomTable) { switch (fixFile.FileType) { // first option is // if we are fixing a 7Z file first try and find an uncompressed file to use // else try and find a zip file to use, else use a 7Z file case FileType.SevenZipFile: { RvFile retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.File); if (retFile != null) { return(retFile); } retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.ZipFile); if (retFile != null) { return(retFile); } break; } case FileType.ZipFile: { RvFile retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.ZipFile && (tFile.Parent.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip && tFile.FileStatusIs(FileStatus.SHA1Verified) && tFile.FileStatusIs(FileStatus.MD5Verified)); if (retFile != null) { return(retFile); } retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.ZipFile && (tFile.Parent.ZipStatus & ZipStatus.TrrntZip) == ZipStatus.TrrntZip ); if (retFile != null) { return(retFile); } retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.File); if (retFile != null) { return(retFile); } retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.ZipFile); if (retFile != null) { return(retFile); } break; } case FileType.File: { RvFile retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.File); if (retFile != null) { return(retFile); } retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.ZipFile && tFile.FileStatusIs(FileStatus.SHA1Verified) && tFile.FileStatusIs(FileStatus.MD5Verified) ); if (retFile != null) { return(retFile); } retFile = lstFixRomTable.FirstOrDefault(tFile => tFile.FileType == FileType.ZipFile); if (retFile != null) { return(retFile); } break; } } return(lstFixRomTable[0]); }
private static void RemoveOldDats(RvFile dbDir, RvFile tmpDir) { // now compare the old and new dats removing any old dats // in the current directory RvFile lDir = dbDir; if (!lDir.IsDir) { return; } int dbIndex = 0; int scanIndex = 0; while (dbIndex < lDir.DirDatCount || scanIndex < tmpDir.DirDatCount) { RvDat dbDat = null; int res = 0; if (dbIndex < lDir.DirDatCount && scanIndex < tmpDir.DirDatCount) { dbDat = lDir.DirDat(dbIndex); RvDat fileDat = tmpDir.DirDat(scanIndex); res = DBHelper.DatCompare(dbDat, fileDat); } else if (scanIndex < tmpDir.DirDatCount) { //this is a new dat that we have now found at the end of the list //fileDat = tmpDir.DirDat(scanIndex); res = 1; } else if (dbIndex < lDir.DirDatCount) { dbDat = lDir.DirDat(dbIndex); res = -1; } switch (res) { case 0: if (dbDat != null) { dbDat.Status = DatUpdateStatus.Correct; } dbIndex++; scanIndex++; break; case 1: // this is a new dat that we will add next time around scanIndex++; break; case -1: if (dbDat != null) { dbDat.Status = DatUpdateStatus.Delete; } lDir.DirDatRemove(dbIndex); break; } } // now scan the child directory structure of this directory dbIndex = 0; scanIndex = 0; while (dbIndex < lDir.ChildCount || scanIndex < tmpDir.ChildCount) { RvFile dbChild = null; RvFile fileChild = null; int res = 0; if (dbIndex < lDir.ChildCount && scanIndex < tmpDir.ChildCount) { dbChild = lDir.Child(dbIndex); fileChild = tmpDir.Child(scanIndex); res = DBHelper.CompareName(dbChild, fileChild); } else if (scanIndex < tmpDir.ChildCount) { //found a new directory on the end of the list //fileChild = tmpDir.Child(scanIndex); res = 1; } else if (dbIndex < lDir.ChildCount) { dbChild = lDir.Child(dbIndex); res = -1; } switch (res) { case 0: // found a matching directory in DatRoot So recurse back into it RemoveOldDats(dbChild, fileChild); dbIndex++; scanIndex++; break; case 1: // found a new directory will be added later scanIndex++; break; case -1: if (dbChild?.FileType == FileType.Dir && dbChild.Dat == null) { RemoveOldDats(dbChild, new RvFile(FileType.Dir)); } dbIndex++; break; } } }
public static bool FindAltExactMatch(FileGroup fGroup, RvFile file) { return(fGroup.FindAltExactMatch(file)); }
public static void UpdateDat(ThreadWorker thWrk) { try { _thWrk = thWrk; if (_thWrk == null) { return; } _thWrk.Report(new bgwText("Clearing DB Status")); RepairStatus.ReportStatusReset(DB.DirTree); _datCount = 0; _thWrk.Report(new bgwText("Finding Dats")); RvFile datRoot = new RvFile(FileType.Dir) { Name = "RomVault", DatStatus = DatStatus.InDatCollect }; // build a datRoot tree of the DAT's in DatRoot, and count how many dats are found if (!RecursiveDatTree(datRoot, out _datCount)) { _thWrk.Report(new bgwText("Dat Update Complete")); _thWrk.Finished = true; _thWrk = null; return; } _thWrk.Report(new bgwText("Scanning Dats")); _datsProcessed = 0; // now compare the database DAT's with datRoot removing any old DAT's RemoveOldDats(DB.DirTree.Child(0), datRoot); // next clean up the File status removing any old DAT's RemoveOldDatsCleanUpFiles(DB.DirTree.Child(0)); _thWrk.Report(new bgwSetRange(_datCount - 1)); // next add in new DAT and update the files UpdateDatList(DB.DirTree.Child(0), datRoot); // finally remove any unneeded directories from the TreeView RemoveOldTree(DB.DirTree.Child(0)); _thWrk.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk.Report(new bgwText("Dat Update Complete")); _thWrk.Finished = true; _thWrk = null; } catch (Exception exc) { ReportError.UnhandledExceptionHandler(exc); _thWrk?.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk?.Report(new bgwText("Complete")); if (_thWrk != null) { _thWrk.Finished = true; } _thWrk = null; } }
public static RvFile FromADir(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort) { string fullDir = dbDir.FullName; DatStatus datStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; RvFile fileDir = new RvFile(FileType.Dir); DirectoryInfo oDir = new DirectoryInfo(fullDir); DirectoryInfo[] oDirs = oDir.GetDirectories(); FileInfo[] oFiles = oDir.GetFiles(); // add all the subdirectories into scanDir foreach (DirectoryInfo dir in oDirs) { RvFile tDir = new RvFile(FileType.Dir) { Name = dir.Name, FileModTimeStamp = dir.LastWriteTime }; tDir.SetStatus(datStatus, GotStatus.Got); fileDir.ChildAdd(tDir); } // add all the files into scanDir foreach (FileInfo oFile in oFiles) { string fName = oFile.Name; if (fName == "__RomVault.tmp") { File.Delete(oFile.FullName); continue; } string fExt = Path.GetExtension(oFile.Name); FileType ft = DBTypeGet.fromExtention(fExt); if (Settings.rvSettings.FilesOnly) { ft = FileType.File; } RvFile tFile = new RvFile(ft) { Name = oFile.Name, Size = (ulong)oFile.Length, FileModTimeStamp = oFile.LastWriteTime }; tFile.FileStatusSet(FileStatus.SizeVerified); tFile.SetStatus(datStatus, GotStatus.Got); if (eScanLevel == EScanLevel.Level3 && tFile.FileType == FileType.File) { FromAFile(tFile, fullDir, eScanLevel, bgw, ref fileErrorAbort); } fileDir.ChildAdd(tFile); /* * // if we find a zip file add it as zip files. * // else * if (ft == FileType.File) * { * // Scanning a file * // * // Level1 & 2 : (are the same for files) Fully checksum changed only files * // Here we are just getting the TimeStamp of the File, and later * // if the TimeStamp was not matched we will have to read the files CRC, MD5 & SHA1 * // * // Level3: Fully checksum everything * // Get everything about the file right here so * // read CRC, MD5 & SHA1 * * errorCode = CHD.CheckFile(oFile, out tFile.AltSHA1, out tFile.AltMD5, out tFile.CHDVersion); * * if (errorCode == 0) * { * if (tFile.AltSHA1 != null) * { * tFile.FileStatusSet(FileStatus.AltSHA1FromHeader); * } * if (tFile.AltMD5 != null) * { * tFile.FileStatusSet(FileStatus.AltMD5FromHeader); * } * * // if we are scanning at Level3 then we get all the info here * if (EScanLevel == EScanLevel.Level3) * { * FileResults(fullDir, tFile); * ChdManCheck(fullDir, tFile); * } * } * else if (errorCode == 32) * { * tFile.GotStatus = GotStatus.FileLocked; * _bgw.Report(new bgwShowError(fullDir, "File Locked")); * } * else * { * string filename = Path.Combine(fullDir, tFile.Name); * ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted."); * _fileErrorAbort = true; * return fileDir; * } * } */ } return(fileDir); }
private static void UpdateDatList(RvFile dbDir, RvFile tmpDir) { AddNewDats(dbDir, tmpDir); UpdateDirs(dbDir, tmpDir); }
private void PaintTree(RvFile pTree, Graphics g, Rectangle t) { UiTree uTree = (UiTree)pTree.Tree.UiObject; int y = uTree.RTree.Top - _vScroll; if (uTree.RTree.IntersectsWith(t)) { Pen p = new Pen(Brushes.Gray, 1) { DashStyle = DashStyle.Dot }; string lTree = uTree.TreeBranches; for (int j = 0; j < lTree.Length; j++) { int x = j * 18 - _hScroll; string cTree = lTree.Substring(j, 1); switch (cTree) { case "│": g.DrawLine(p, x + 9, y, x + 9, y + uTree.RTree.Height); break; case "├": g.DrawLine(p, x + 9, y, x + 9, y + uTree.RTree.Height); g.DrawLine(p, x + 9, y + 8, x + 27, y + 8); break; case "└": g.DrawLine(p, x + 9, y, x + 9, y + 8); g.DrawLine(p, x + 9, y + 8, x + 27, y + 8); break; case "┐": g.DrawLine(p, x + 9, y + 8, x + 9, y + uTree.RTree.Height); break; } } } if (!uTree.RExpand.IsEmpty) { if (uTree.RExpand.IntersectsWith(t)) { g.DrawImage(pTree.Tree.TreeExpanded ? rvImages.ExpandBoxMinus : rvImages.ExpandBoxPlus, RSub(uTree.RExpand, _hScroll, _vScroll)); } } if (uTree.RChecked.IntersectsWith(t)) { switch (pTree.Tree.Checked) { case RvTreeRow.TreeSelect.Locked: g.DrawImage(rvImages.TickBoxLocked, RSub(uTree.RChecked, _hScroll, _vScroll)); break; case RvTreeRow.TreeSelect.UnSelected: g.DrawImage(rvImages.TickBoxUnTicked, RSub(uTree.RChecked, _hScroll, _vScroll)); break; case RvTreeRow.TreeSelect.Selected: g.DrawImage(rvImages.TickBoxTicked, RSub(uTree.RChecked, _hScroll, _vScroll)); break; } } if (uTree.RIcon.IntersectsWith(t)) { int icon = 2; //yellow if (pTree.DirStatus.HasInToSort()) { icon = 4; //blue } else if (!pTree.DirStatus.HasCorrect() && pTree.DirStatus.HasMissing()) { icon = 1; //red } else if (!pTree.DirStatus.HasMissing()) { icon = 3; //green } Bitmap bm; if (pTree.Dat == null && pTree.DirDatCount == 0) // Directory above DAT's in Tree { bm = rvImages.GetBitmap("DirectoryTree" + icon); } else if (pTree.Dat == null && pTree.DirDatCount >= 1) // Directory that contains DAT's { bm = rvImages.GetBitmap("Tree" + icon); } else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT { bm = rvImages.GetBitmap("Tree" + icon); } else { ReportError.SendAndShow("Unknown Tree settings in DisplayTree."); bm = null; } if (bm != null) { g.DrawImage(bm, RSub(uTree.RIcon, _hScroll, _vScroll)); } } Rectangle recBackGround = new Rectangle(uTree.RText.X, uTree.RText.Y, Width - uTree.RText.X + _hScroll, uTree.RText.Height); if (recBackGround.IntersectsWith(t)) { string thistxt; List <string> datList = null; string subtxt = "( Have:" + pTree.DirStatus.CountCorrect() + " \\ Missing: " + pTree.DirStatus.CountMissing() + " )"; if (pTree.Dat == null && pTree.DirDatCount == 0) // Directory above DAT's in Tree { thistxt = pTree.Name; } else if (pTree.Dat == null && pTree.DirDatCount == 1) // Directory that contains DAT's { thistxt = pTree.Name + ": " + pTree.DirDat(0).GetData(RvDat.DatData.Description); } else if (pTree.Dat == null && pTree.DirDatCount > 1) // Directory above DAT's in Tree { thistxt = pTree.Name; if (pTree.Tree.TreeExpanded) { datList = new List <string>(); for (int i = 0; i < pTree.DirDatCount; i++) { if (!pTree.DirDat(i).AutoAddedDirectory) { string title = pTree.DirDat(i).GetData(RvDat.DatData.Description); if (string.IsNullOrWhiteSpace(title)) { title = pTree.DirDat(i).GetData(RvDat.DatData.DatName); } datList.Add(title); } } } } // pTree.Parent.DirDatCount>1: This should probably be a test like parent contains Dat else if (pTree.Dat != null && pTree.Dat.AutoAddedDirectory && pTree.Parent.DirDatCount > 1) { thistxt = pTree.Name + ": "; } else if (pTree.Dat != null && pTree.DirDatCount == 0) // Directories made by a DAT { thistxt = pTree.Name; } else { ReportError.SendAndShow("Unknown Tree settings in DisplayTree."); thistxt = ""; } if (pTree.IsInToSort) { subtxt = ""; } if (pTree.FileStatusIs(FileStatus.PrimaryToSort | FileStatus.CacheToSort)) { thistxt += " (Primary)"; } else if (pTree.FileStatusIs(FileStatus.PrimaryToSort)) { thistxt += " (Primary)"; } else if (pTree.FileStatusIs(FileStatus.CacheToSort)) { thistxt += " (Cache)"; } Brush textBrush; if (Selected != null && pTree.TreeFullName == Selected.TreeFullName) { g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), RSub(recBackGround, _hScroll, _vScroll)); textBrush = Brushes.Wheat; } else { textBrush = Brushes.Black; } thistxt += " " + subtxt; g.DrawString(thistxt, tFont, textBrush, uTree.RText.Left - _hScroll, uTree.RText.Top + 1 - _vScroll); if (datList != null) { for (int i = 0; i < datList.Count; i++) { g.DrawString(datList[i], tFont1, textBrush, ((UiTree)pTree.Tree.UiObject).RText.Left + 20 - _hScroll, ((UiTree)pTree.Tree.UiObject).RText.Top + 14 + i * 12 - _vScroll); } } } if (!pTree.Tree.TreeExpanded) { return; } for (int i = 0; i < pTree.ChildCount; i++) { RvFile tDir = pTree.Child(i); if (tDir.IsDir && tDir.Tree?.UiObject != null) { PaintTree(tDir, g, t); } } }
/// <summary> /// Add the new DAT's into the DAT list /// And merge in the new DAT data into the database /// </summary> /// <param name="dbDir">The Current database dir</param> /// <param name="tmpDir">A temp directory containing the DAT found in this directory in DatRoot</param> private static void AddNewDats(RvFile dbDir, RvFile tmpDir) { int dbIndex = 0; int scanIndex = 0; Debug.WriteLine(""); Debug.WriteLine("Scanning for Adding new DATS"); while (dbIndex < dbDir.DirDatCount || scanIndex < tmpDir.DirDatCount) { RvDat dbDat = null; RvDat fileDat = null; int res = 0; if (dbIndex < dbDir.DirDatCount && scanIndex < tmpDir.DirDatCount) { dbDat = dbDir.DirDat(dbIndex); fileDat = tmpDir.DirDat(scanIndex); res = DBHelper.DatCompare(dbDat, fileDat); Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatRootFullName) + " : and " + fileDat.GetData(RvDat.DatData.DatRootFullName) + " : " + res); } else if (scanIndex < tmpDir.DirDatCount) { fileDat = tmpDir.DirDat(scanIndex); res = 1; Debug.WriteLine("Checking : and " + fileDat.GetData(RvDat.DatData.DatRootFullName) + " : " + res); } else if (dbIndex < dbDir.DirDatCount) { dbDat = dbDir.DirDat(dbIndex); res = -1; Debug.WriteLine("Checking " + dbDat.GetData(RvDat.DatData.DatRootFullName) + " : and : " + res); } switch (res) { case 0: _datsProcessed++; _thWrk.Report(_datsProcessed); _thWrk.Report(new bgwText("Dat : " + Path.GetFileNameWithoutExtension(fileDat?.GetData(RvDat.DatData.DatRootFullName)))); Debug.WriteLine("Correct"); // Should already be set as correct above if (dbDat != null) { dbDat.Status = DatUpdateStatus.Correct; } dbIndex++; scanIndex++; break; case 1: _datsProcessed++; _thWrk.Report(_datsProcessed); _thWrk.Report(new bgwText("Scanning New Dat : " + Path.GetFileNameWithoutExtension(fileDat?.GetData(RvDat.DatData.DatRootFullName)))); Debug.WriteLine("Adding new DAT"); if (LoadNewDat(fileDat, dbDir)) { dbIndex++; } scanIndex++; break; case -1: // This should not happen as deleted dat have been removed above //dbIndex++; ReportError.SendAndShow("ERROR Deleting a DAT that should already be deleted."); break; } } }
private bool CheckMouseUp(RvFile pTree, int x, int y, MouseEventArgs mevent) { if (((UiTree)pTree.Tree.UiObject).RChecked.Contains(x, y)) { RvChecked?.Invoke(pTree, mevent); if (mevent.Button == MouseButtons.Right) { _mousehit = true; if (pTree.FileStatusIs(FileStatus.PrimaryToSort) || pTree.FileStatusIs(FileStatus.CacheToSort)) { return(true); } SetChecked(pTree, RvTreeRow.TreeSelect.Locked); return(true); } _mousehit = true; SetChecked(pTree, pTree.Tree.Checked == RvTreeRow.TreeSelect.Selected ? RvTreeRow.TreeSelect.UnSelected : RvTreeRow.TreeSelect.Selected); return(true); } if (((UiTree)pTree.Tree.UiObject).RExpand.Contains(x, y)) { _mousehit = true; SetExpanded(pTree, mevent.Button == MouseButtons.Right); return(true); } if (((UiTree)pTree.Tree.UiObject).RText.Contains(x, y)) { _mousehit = true; RvSelected?.Invoke(pTree, mevent); Selected = pTree; return(true); } if (!pTree.Tree.TreeExpanded) { return(false); } for (int i = 0; i < pTree.ChildCount; i++) { RvFile rDir = pTree.Child(i); if (!rDir.IsDir || rDir.Tree == null) { continue; } if (CheckMouseUp(rDir, x, y, mevent)) { return(true); } } return(false); }
private static bool LoadNewDat(RvDat fileDat, RvFile thisDirectory) { // Read the new Dat File into newDatFile RvFile newDatFile = DatReader.ReadInDatFile(fileDat, _thWrk); // If we got a valid Dat File back if (newDatFile?.Dat == null) { ReportError.Show("Error reading Dat " + fileDat.GetData(RvDat.DatData.DatRootFullName)); return(false); } if (newDatFile.ChildCount == 0) { return(false); } if ( !fileDat.MultiDatOverride && newDatFile.Dat.GetData(RvDat.DatData.DirSetup) != "noautodir" && ( fileDat.MultiDatsInDirectory || !string.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir)) ) ) { // if we are auto adding extra directories then create a new directory. string dirName = ""; if (string.IsNullOrEmpty(dirName) && fileDat.UseDescriptionAsDirName && !string.IsNullOrWhiteSpace(newDatFile.Dat.GetData(RvDat.DatData.Description))) { dirName = newDatFile.Dat.GetData(RvDat.DatData.Description); } if (string.IsNullOrEmpty(dirName) && !string.IsNullOrEmpty(newDatFile.Dat.GetData(RvDat.DatData.RootDir))) { dirName = newDatFile.Dat.GetData(RvDat.DatData.RootDir); } if (string.IsNullOrEmpty(dirName)) { dirName = newDatFile.Dat.GetData(RvDat.DatData.DatName); } if (string.IsNullOrEmpty(dirName)) { dirName = Path.GetFileNameWithoutExtension(newDatFile.Dat.GetData(RvDat.DatData.DatRootFullName)); } newDatFile.Name = VarFix.CleanFileName(dirName); newDatFile.DatStatus = DatStatus.InDatCollect; newDatFile.Tree = new RvTreeRow(); RvFile newDirectory = new RvFile(FileType.Dir) { Dat = newDatFile.Dat }; // add the DAT into this directory newDirectory.ChildAdd(newDatFile); newDatFile = newDirectory; newDatFile.Dat.AutoAddedDirectory = true; } else { newDatFile.Dat.AutoAddedDirectory = false; } if (thisDirectory.Tree == null) { thisDirectory.Tree = new RvTreeRow(); } if (MergeInDat(thisDirectory, newDatFile, out RvDat conflictDat, true)) { ReportError.Show("Dat Merge conflict occured Cache contains " + conflictDat.GetData(RvDat.DatData.DatRootFullName) + " new dat " + newDatFile.Dat.GetData(RvDat.DatData.DatRootFullName) + " is trying to use the same directory and so will be ignored."); return(false); } //SetInDat(thisDirectory); // Add the new Dat thisDirectory.DirDatAdd(newDatFile.Dat); // Merge the files/directories in the Dat MergeInDat(thisDirectory, newDatFile, out conflictDat, false); return(true); }
private void SetupTree(RvFile pTree, string pTreeBranches) { int nodeDepth = pTreeBranches.Length - 1; int nodeHeight = 16; if (pTree.Tree.TreeExpanded && pTree.DirDatCount > 1) { for (int i = 0; i < pTree.DirDatCount; i++) { if (!pTree.DirDat(i).AutoAddedDirectory) { nodeHeight += 12; } } } UiTree uTree = new UiTree(); pTree.Tree.UiObject = uTree; uTree.TreeBranches = pTreeBranches; uTree.RTree = new Rectangle(0, _yPos, 1 + nodeDepth * 18, nodeHeight); uTree.RExpand = new Rectangle(5 + nodeDepth * 18, _yPos + 4, 9, 9); uTree.RChecked = new Rectangle(20 + nodeDepth * 18, _yPos + 2, 13, 13); uTree.RIcon = new Rectangle(35 + nodeDepth * 18, _yPos, 16, 16); uTree.RText = new Rectangle(51 + nodeDepth * 18, _yPos, 500, nodeHeight); pTreeBranches = pTreeBranches.Replace("├", "│"); pTreeBranches = pTreeBranches.Replace("└", " "); _yPos = _yPos + nodeHeight; bool found = false; int last = 0; for (int i = 0; i < pTree.ChildCount; i++) { RvFile dir = pTree.Child(i); if (!dir.IsDir) { continue; } if (dir.Tree == null) { continue; } found = true; if (pTree.Tree.TreeExpanded) { last = i; } } if (!found && pTree.DirDatCount <= 1) { uTree.RExpand = new Rectangle(0, 0, 0, 0); } if (pTree.Tree.TreeExpanded && found) { uTree.TreeBranches += "┐"; } for (int i = 0; i < pTree.ChildCount; i++) { RvFile dir = pTree.Child(i); if (!dir.IsDir) { continue; } if (dir.Tree == null) { continue; } if (!pTree.Tree.TreeExpanded) { continue; } if (i != last) { SetupTree(pTree.Child(i), pTreeBranches + "├"); } else { SetupTree(pTree.Child(i), pTreeBranches + "└"); } } }
private static bool MergeInDat(RvFile dbDat, RvFile newDat, out RvDat conflict, bool checkOnly) { conflict = null; int dbIndex = 0; int newIndex = 0; while (dbIndex < dbDat.ChildCount || newIndex < newDat.ChildCount) { RvFile dbChild = null; RvFile newDatChild = null; int res = 0; if (dbIndex < dbDat.ChildCount && newIndex < newDat.ChildCount) { dbChild = dbDat.Child(dbIndex); // are files newDatChild = newDat.Child(newIndex); // is from a dat item res = DBHelper.CompareName(dbChild, newDatChild); } else if (newIndex < newDat.ChildCount) { newDatChild = newDat.Child(newIndex); res = 1; } else if (dbIndex < dbDat.ChildCount) { dbChild = dbDat.Child(dbIndex); res = -1; } if (res == 0) { if (dbChild == null || newDatChild == null) { ShowDat("Error in Logic", dbDat.FullName); break; } List <RvFile> dbDats = new List <RvFile>(); List <RvFile> newDats = new List <RvFile>(); int dbDatsCount = 1; int newDatsCount = 1; dbDats.Add(dbChild); newDats.Add(newDatChild); while (dbIndex + dbDatsCount < dbDat.ChildCount && DBHelper.CompareName(dbChild, dbDat.Child(dbIndex + dbDatsCount)) == 0) { dbDats.Add(dbDat.Child(dbIndex + dbDatsCount)); dbDatsCount += 1; } while (newIndex + newDatsCount < newDat.ChildCount && DBHelper.CompareName(newDatChild, newDat.Child(newIndex + newDatsCount)) == 0) { newDats.Add(newDat.Child(newIndex + newDatsCount)); newDatsCount += 1; } if (dbDatsCount > 1 || newDatsCount > 1) { ReportError.SendAndShow("Double Name Found"); } for (int indexdb = 0; indexdb < dbDatsCount; indexdb++) { if (dbDats[indexdb].DatStatus == DatStatus.NotInDat) { continue; } if (checkOnly) { conflict = dbChild.Dat; return(true); } ShowDat("Unknown Update Dat Status " + dbChild.DatStatus, dbDat.FullName); break; } if (!checkOnly) { for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++) { if (newDats[indexNewDats].SearchFound) { continue; } for (int indexDbDats = 0; indexDbDats < dbDatsCount; indexDbDats++) { if (dbDats[indexDbDats].SearchFound) { continue; } bool matched = Compare.DatMergeCompare(dbDats[indexDbDats], newDats[indexNewDats], out bool altMatch); if (!matched) { continue; } dbDats[indexDbDats].DatAdd(newDats[indexNewDats], altMatch); FileType ft = dbChild.FileType; if (ft == FileType.Zip || ft == FileType.SevenZip || ft == FileType.Dir) { RvFile dChild = dbChild; RvFile dNewChild = newDatChild; MergeInDat(dChild, dNewChild, out conflict, false); } dbDats[indexDbDats].SearchFound = true; newDats[indexNewDats].SearchFound = true; } } for (int indexNewDats = 0; indexNewDats < newDatsCount; indexNewDats++) { if (newDats[indexNewDats].SearchFound) { continue; } dbDat.ChildAdd(newDats[indexNewDats], dbIndex); dbChild = dbDat.Child(dbIndex); SetMissingStatus(dbChild); dbIndex++; } } dbIndex += dbDatsCount; newIndex += newDatsCount; } if (res == 1) { if (!checkOnly) { dbDat.ChildAdd(newDatChild, dbIndex); dbChild = dbDat.Child(dbIndex); SetMissingStatus(dbChild); dbIndex++; } newIndex++; } if (res == -1) { dbIndex++; } } return(false); }
/// <summary> /// Fixed a missing file inside a .ZIP file. /// </summary> /// <param name="fixZip">The RvFile of the actual .ZIP file that is being fixed.</param> /// <param name="fixZippedFile">A temp copy of the RvFile record of the actual compressed file inside the fixZip .zip that is about to be fixed.</param> /// <param name="tempFixZip">Is the new output archive file that is being created to fix this zip, that will become the new zip once done</param> /// <param name="filesUserForFix"></param> /// <param name="totalFixed"></param> /// <param name="errorMessage"></param> /// <returns></returns> public static ReturnCode CanBeFixed(RvFile fixZip, RvFile fixZippedFile, ref ICompress tempFixZip, Dictionary <string, RvFile> filesUserForFix, ref int totalFixed, out string errorMessage) { if (!( fixZippedFile.DatStatus == DatStatus.InDatCollect && (fixZippedFile.GotStatus == GotStatus.NotGot || fixZippedFile.GotStatus == GotStatus.Corrupt))) { ReportError.SendAndShow("Error in Fix Rom Status " + fixZippedFile.RepStatus + " : " + fixZippedFile.DatStatus + " : " + fixZippedFile.GotStatus); } ReportError.LogOut("CanBeFixed:"); ReportError.LogOut(fixZippedFile); if (tempFixZip == null) { ReturnCode ret1 = FixAZipFunctions.OpenTempFizZip(fixZip, out tempFixZip, out errorMessage); if (ret1 != ReturnCode.Good) { return(ret1); } } List <RvFile> lstFixRomTable = FindSourceFile.GetFixFileList(fixZippedFile); ReportError.LogOut("CanBeFixed: picking from"); ReportError.ReportList(lstFixRomTable); if (DBHelper.IsZeroLengthFile(fixZippedFile)) { RvFile fileInZ = new RvFile(FileType.ZipFile) { Size = 0 }; ReturnCode returnCode1 = FixFileUtils.CopyFile(fileInZ, tempFixZip, null, fixZippedFile, false, out errorMessage); switch (returnCode1) { case ReturnCode.Good: // correct reply to continue; break; case ReturnCode.Cancel: return(returnCode1); default: throw new FixAZip.ZipFileException(returnCode1, fixZippedFile.FullName + " " + fixZippedFile.RepStatus + " " + returnCode1 + " : " + errorMessage); } } else { if (lstFixRomTable.Count == 0) { // thought we could fix it, turns out we cannot fixZippedFile.GotStatus = GotStatus.NotGot; errorMessage = ""; return(ReturnCode.Good); } RvFile fileIn = FindSourceFile.FindSourceToUseForFix(fixZippedFile, lstFixRomTable); if (fileIn.FileType == FileType.SevenZipFile) { ReturnCode returnCode1 = Decompress7ZipFile.DecompressSource7ZipFile(fileIn.Parent, false, out errorMessage); if (returnCode1 != ReturnCode.Good) { ReportError.LogOut($"DecompressSource7Zip: OutputOutput {fixZip.FileName} return {returnCode1}"); return(returnCode1); } lstFixRomTable = FindSourceFile.GetFixFileList(fixZippedFile); fileIn = FindSourceFile.FindSourceToUseForFix(fixZippedFile, lstFixRomTable); } ReportError.LogOut("CanBeFixed: Copying from"); ReportError.LogOut(fileIn); FixAZipFunctions.GetSourceDir(fileIn, out string sourceDir, out string sourceFile); string fixZipFullName = fixZip.TreeFullName; bool rawCopy = FixFileUtils.TestRawCopy(fileIn, fixZippedFile, false); Report.ReportProgress(new bgwShowFix(Path.GetDirectoryName(fixZipFullName), Path.GetFileName(fixZipFullName), fixZippedFile.Name, fixZippedFile.Size, rawCopy ? "<--Raw" : "<--Compress", sourceDir, sourceFile, fileIn.Name)); fixZippedFile.FileTestFix(fileIn); ReturnCode returnCode = FixFileUtils.CopyFile(fileIn, tempFixZip, null, fixZippedFile, false, out errorMessage); switch (returnCode) { case ReturnCode.Good: // correct reply so continue; break; case ReturnCode.RescanNeeded: ReportError.LogOut($"CanBeFixed: RescanNeeded"); return(returnCode); case ReturnCode.SourceDataStreamCorrupt: { ReportError.LogOut($"CanBeFixed: Source Data Stream Corrupt / CRC Error"); Report.ReportProgress(new bgwShowFixError("CRC Error")); fileIn.GotStatus = GotStatus.Corrupt; return(returnCode); } case ReturnCode.SourceCheckSumMismatch: { ReportError.LogOut($"CanBeFixed: Source Checksum Mismatch / Fix file CRC was not as expected"); Report.ReportProgress(new bgwShowFixError("Fix file CRC was not as expected")); return(returnCode); } case ReturnCode.DestinationCheckSumMismatch: { ReportError.LogOut($"CanBeFixed: Destination Checksum Mismatch / Destination file CRC was not as expected"); Report.ReportProgress(new bgwShowFixError("Destination file CRC was not as expected")); return(returnCode); } case ReturnCode.FileSystemError: { ReportError.LogOut($"CanBeFixed: Source File Error {errorMessage}"); Report.ReportProgress(new bgwShowFixError($"CanBeFixed: Source File Error {errorMessage}")); return(returnCode); } case ReturnCode.Cancel: return(returnCode); default: throw new FixAZip.ZipFileException(returnCode, fixZippedFile.FullName + " " + fixZippedFile.RepStatus + " " + returnCode + Environment.NewLine + errorMessage); } } //Check to see if the files used for fix, can now be set to delete foreach (RvFile f in lstFixRomTable) { string fn = f.TreeFullName; if (!filesUserForFix.ContainsKey(fn)) { filesUserForFix.Add(fn, f); } } totalFixed++; errorMessage = ""; return(ReturnCode.Good); }
private static void UpdateDirs(RvFile dbDir, RvFile fileDir) { int dbIndex = 0; int scanIndex = 0; dbDir.DatStatus = DatStatus.InDatCollect; if (dbDir.Tree == null) { Debug.WriteLine("Adding Tree View to " + dbDir.Name); dbDir.Tree = new RvTreeRow(); } Debug.WriteLine(""); Debug.WriteLine("Now scanning dirs"); while (dbIndex < dbDir.ChildCount || scanIndex < fileDir.ChildCount) { RvFile dbChild = null; RvFile fileChild = null; int res = 0; if (dbIndex < dbDir.ChildCount && scanIndex < fileDir.ChildCount) { dbChild = dbDir.Child(dbIndex); fileChild = fileDir.Child(scanIndex); res = DBHelper.CompareName(dbChild, fileChild); Debug.WriteLine("Checking " + dbChild.Name + " : and " + fileChild.Name + " : " + res); } else if (scanIndex < fileDir.ChildCount) { fileChild = fileDir.Child(scanIndex); res = 1; Debug.WriteLine("Checking : and " + fileChild.Name + " : " + res); } else if (dbIndex < dbDir.ChildCount) { dbChild = dbDir.Child(dbIndex); res = -1; } switch (res) { case 0: // found a matching directory in DatRoot So recurse back into it if (dbChild.GotStatus == GotStatus.Got) { if (dbChild.Name != fileChild.Name) // check if the case of the Item in the DB is different from the Dat Root Actual filename { if (!string.IsNullOrEmpty(dbChild.FileName)) // if we do not already have a different case name stored { dbChild.FileName = dbChild.Name; // copy the DB filename to the FileName } else // We already have a different case filename found in RomRoot { if (dbChild.FileName == fileChild.Name) // check if the DatRoot name does now match the name in the DB Filename { dbChild.FileName = null; // if it does undo the BadCase Flag } } dbChild.Name = fileChild.Name; // Set the db Name to match the DatRoot Name. } } else { dbChild.Name = fileChild.Name; } UpdateDatList(dbChild, fileChild); dbIndex++; scanIndex++; break; case 1: // found a new directory in Dat RvFile tDir = new RvFile(FileType.Dir) { Name = fileChild.Name, Tree = new RvTreeRow(), DatStatus = DatStatus.InDatCollect }; dbDir.ChildAdd(tDir, dbIndex); Debug.WriteLine("Adding new Dir and Calling back in to check this DIR " + tDir.Name); UpdateDatList(tDir, fileChild); dbIndex++; scanIndex++; break; case -1: // all files dbIndex++; break; } } }