public RemoveDuplicatesForm(ChecksumSet set) { InitializeComponent(); _set = set; InitializeFormVariables(); SetLanguage(); }
public ChecksumFile(ChecksumSet set) { State = ChecksumFileState.NotProcessed; Guid = System.Guid.NewGuid().ToString(); Set = set; }
public bool LoadAndVerifyFile(string fileName, bool doVerify, bool getFileInfo) { if (Directory.Exists(fileName)) { List<string> verifyFiles = new List<string>(); Dictionary<string, List<string>> dict = GetFilesAllDirectories(fileName); foreach (List<string> dirFiles in dict.Values) { foreach (string dirFile in dirFiles) { string dirFileExt = Path.GetExtension(dirFile).ToLower(); if (dirFileExt == ".md5" || dirFileExt == ".sfv" || dirFileExt == ".sha1") verifyFiles.Add(dirFile); } } ListViewBeginUpdate(); try { foreach (string verifyFile in verifyFiles) LoadAndVerifyFile(verifyFile, doVerify, getFileInfo); } finally { ListViewEndUpdate(); } return true; } if (!File.Exists(fileName)) { MessageBox.Show(string.Format(Language.MainForm.FileNotFound_Message, fileName), Language.MainForm.FileNotFound_Title, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; } string baseDirectory = Path.GetDirectoryName(fileName); string ext = Path.GetExtension(fileName).ToLower(); ChecksumType setType; if (ext == ".md5") setType = ChecksumType.MD5; else if (ext == ".sfv") setType = ChecksumType.SFV; else if (ext == ".sha1") setType = ChecksumType.SHA1; else return false; ChecksumSet set = new ChecksumSet(fileName, baseDirectory, setType); SetStatusText(string.Format(Language.MainForm.Status_LoadingFile, set.VerificationFileName)); Application.DoEvents(); Program.Settings.AddRecentFile(fileName); ListViewBeginUpdate(); try { if (!_workingOnList) { lvwFiles.Items.Clear(); lvwFiles.Groups.Clear(); Application.DoEvents(); } string[] lines = File.ReadAllLines(fileName, Encoding.GetEncoding(CODE_PAGE)); ListViewGroup group = new ListViewGroup(lvwFiles.Groups.Count.ToString(), Path.GetFileName(fileName)); lvwFiles.Groups.Add(group); StringBuilder comment = new StringBuilder(); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (line == null) continue; line = line.Trim(); if (string.IsNullOrEmpty(line)) continue; if (line.StartsWith(";") || (line.StartsWith("#") && (set.Type == ChecksumType.MD5 || set.Type == ChecksumType.SHA1))) { comment.AppendLine(line.Substring(1, line.Length - 1)); } else { ChecksumFile file = new ChecksumFile(set); if (set.Type == ChecksumType.MD5) { string chkMD5; string chkFileName; if (line.StartsWith("MD5 (")) { int idx = line.LastIndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); chkFileName = line.Substring(5, idx - 5 - 3); chkMD5 = line.Substring(idx + 1, line.Length - idx - 1); if (chkMD5.Length != 32) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); } else { int idx = line.IndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); if (idx == 32) { chkMD5 = line.Substring(0, idx); chkFileName = line.Substring(idx + 1, line.Length - idx - 1); } else { idx = line.LastIndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); chkFileName = line.Substring(0, idx); chkMD5 = line.Substring(idx + 1, line.Length - idx - 1); if (chkMD5.Length != 32) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); } } if (chkFileName.StartsWith("*")) // md5sum chkFileName = chkFileName.Substring(1); file.FileName = chkFileName; file.OriginalChecksum = chkMD5; } else if (set.Type == ChecksumType.SHA1) { string chkSHA1; string chkFileName; if (line.StartsWith("SHA1 (")) { int idx = line.LastIndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); chkFileName = line.Substring(6, idx - 6 - 3); chkSHA1 = line.Substring(idx + 1, line.Length - idx - 1); if (chkSHA1.Length != 40) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); } else { int idx = line.IndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); if (idx == 40) { chkSHA1 = line.Substring(0, idx); chkFileName = line.Substring(idx + 1, line.Length - idx - 1); } else { idx = line.LastIndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); chkFileName = line.Substring(0, idx); chkSHA1 = line.Substring(idx + 1, line.Length - idx - 1); if (chkSHA1.Length != 40) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); } } if (chkFileName.StartsWith("*")) // md5sum chkFileName = chkFileName.Substring(1); file.FileName = chkFileName; file.OriginalChecksum = chkSHA1; } else if (set.Type == ChecksumType.SFV) { int idx = line.LastIndexOf(' '); if (idx == -1) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); string chkSFV = line.Substring(idx + 1, line.Length - idx - 1); string chkFileName = line.Substring(0, idx); if (chkSFV.StartsWith("$")) // remove leading $ chkSFV = chkSFV.Substring(1); if (chkSFV.StartsWith("0x") || chkSFV.StartsWith("0X")) // remove leading 0x chkSFV = chkSFV.Substring(2); if (chkSFV.Length != 8) throw new InvalidChecksumFileException(fileName, set.Type, lines, i, CODE_PAGE); file.FileName = chkFileName; file.OriginalChecksum = chkSFV; } else { throw new Exception(string.Format("{0} not implemented", set.Type)); } file.FileName = file.FileName.Replace('/', '\\'); // NOTE: Looks like hkSFV ignores this setting for checking //if (!Program.Settings.General.Recursive && file.FileName.Contains('\\')) // continue; set.Files.Add(file); ListViewItem item = new ListViewItem(new[] { file.FileName, file.Guid }); item.Tag = file; item.StateImageIndex = 0; item.Group = group; lvwFiles.Items.Add(item); } } set.Comments = comment.ToString(); if (lvwFiles.Items.Count != 0) lvwFiles.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.ColumnContent); } finally { ListViewEndUpdate(); } if (!_workingOnList) { _totalSizeOfSets = 0; _files_parts = 0; _sets.Clear(); } if (getFileInfo) { int lastPercent = 0; set.TotalSize = 0; for (int i = 0; i < set.Files.Count; i++) { int percent = (i * 100 / set.Files.Count); if (percent / 5 > lastPercent / 5) { SetStatusText(string.Format(Language.MainForm.Status_LoadingFilePercentage, set.VerificationFileName, (percent / 5) * 5)); Application.DoEvents(); lastPercent = percent; } ChecksumFile file = set.Files[i]; string fullFileName = Path.Combine(set.Directory, file.FileName); if (File.Exists(fullFileName)) { FileInfo fileInfo = TryGetNewFileInfo(fullFileName); file.FileInfo = fileInfo; set.TotalSize += fileInfo.Length; } } } _totalSizeOfSets += set.TotalSize; _files_parts += set.Files.Count; _sets.Add(set); if (!_workingOnList && doVerify) Verify(); return true; }
private void GetWorkset(string fileName, string directoryName, ChecksumType setType, List<string> filesAndFolders, out int overwriteCount) { SetStatusText(Language.MainForm.Status_GettingFileList); Application.DoEvents(); IDictionary<string, List<string>> files; if (filesAndFolders == null) { if (Program.Settings.General.Recursive) { files = GetFilesAllDirectories(directoryName); } else { files = new Dictionary<string, List<string>>(); files.Add(directoryName, Directory.GetFiles(directoryName, "*.*", SearchOption.TopDirectoryOnly).ToList()); } } else { files = new Dictionary<string, List<string>>(); foreach (string item in filesAndFolders) { if (Directory.Exists(item)) { if (Program.Settings.General.Recursive) { foreach (var kvp in GetFilesAllDirectories(item)) { files.Add(kvp.Key, kvp.Value); } } else { files.Add(item, Directory.GetFiles(item, "*.*", SearchOption.TopDirectoryOnly).ToList()); } } else { List<string> topFiles; if (!files.TryGetValue(directoryName, out topFiles)) { topFiles = new List<string>(); files.Add(directoryName, topFiles); } topFiles.Add(item); } } } if (Program.Settings.Create.SortFiles) { SetStatusText(Language.MainForm.Status_PreSorting); Application.DoEvents(); files = new SortedDictionary<string, List<string>>(files, StringComparer.InvariantCultureIgnoreCase); foreach (KeyValuePair<string, List<string>> kvp in new Dictionary<string, List<string>>(files)) { files[kvp.Key] = kvp.Value.OrderBy(p => p).ToList(); } } SetStatusText(Language.MainForm.Status_GettingFileInfo); Application.DoEvents(); List<string> excludeExt = new List<string>(); if (!string.IsNullOrEmpty(Program.Settings.Create.ExcludeFilesOfType)) { string[] exts = Program.Settings.Create.ExcludeFilesOfType.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string ext in exts) { string extMod = ext.ToLower(); if (extMod.StartsWith("*")) extMod = extMod.Substring(1, extMod.Length - 1); if (extMod.StartsWith(".")) { if (!excludeExt.Contains(extMod)) excludeExt.Add(extMod); } } } _sets.Clear(); ChecksumSet set = new ChecksumSet(fileName, directoryName, setType); string checksumExt = Path.GetExtension(fileName); if (!Program.Settings.Create.CreateForEachSubDir) _sets.Add(set); int trimLength = directoryName.Length; if (!directoryName.EndsWith("\\")) trimLength++; int filesProcessed = 0; int lastPercent = 0; int totalFiles = 0; foreach (KeyValuePair<string, List<string>> kvp in files) { totalFiles += kvp.Value.Count; } foreach (KeyValuePair<string, List<string>> kvp in files) { if (Program.Settings.Create.CreateForEachSubDir) { string tmpFileName; if (Program.Settings.Create.PromptForFileName) { tmpFileName = Path.Combine(kvp.Key, Path.GetFileName(fileName)); } else { tmpFileName = Path.GetFileName(kvp.Key) + checksumExt; tmpFileName = Path.Combine(kvp.Key, tmpFileName); } set = new ChecksumSet(tmpFileName, kvp.Key, setType); _sets.Add(set); trimLength = kvp.Key.Length; if (!kvp.Key.EndsWith("\\")) trimLength++; } long directoryTotalSize = 0; foreach (string file in kvp.Value) { filesProcessed++; int percent = (filesProcessed * 100 / totalFiles); if (percent / 5 > lastPercent / 5) { SetStatusText(string.Format(Language.MainForm.Status_GettingFileInfoPercentage, (percent / 5) * 5)); Application.DoEvents(); lastPercent = percent; } bool ok = true; foreach (string ext in excludeExt) { if (string.Compare(Path.GetExtension(file), ext, true) == 0) { ok = false; break; } } if (ok) { FileInfo fileInfo = TryGetNewFileInfo(file); if ((fileInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) continue; ChecksumFile checksumFile = new ChecksumFile(set); checksumFile.FileInfo = fileInfo; checksumFile.State = ChecksumFileState.NotProcessed; checksumFile.FileName = file.Substring(trimLength, file.Length - trimLength); set.Files.Add(checksumFile); directoryTotalSize += fileInfo.Length; } } set.TotalSize += directoryTotalSize; } overwriteCount = 0; foreach (ChecksumSet setx in _sets) { if (File.Exists(setx.VerificationFileName)) overwriteCount++; } }
private void FindRenamedFiles(ChecksumSet set, out int newOK) { Guard.ArgumentNotNull(set, "set"); SetStatusText(string.Format(Language.MainForm.Status_FindingRenamesInFile, set.VerificationFileName)); Application.DoEvents(); newOK = 0; Dictionary<string, string> outOfSetFiles = new Dictionary<string, string>(); const long bytesProcessed = 0; DateTime start = DateTime.Now; long speed = 0; foreach (ChecksumFile file in set.Files) { if (file.State == ChecksumFileState.Missing) { string fullFileName = Path.Combine(set.Directory, file.FileName); string directory = Path.GetDirectoryName(fullFileName); string lookForExt = Path.GetExtension(fullFileName); //string searchPattern = "*" + Path.GetExtension(fullFileName); if (!Directory.Exists(directory)) continue; string[] files = Directory.GetFiles(directory, "*.*", SearchOption.TopDirectoryOnly); foreach (string foundFile in files) { string foundFileExt = Path.GetExtension(foundFile); if (string.Compare(lookForExt, foundFileExt, true) != 0) // extensions don't match { if (!string.IsNullOrEmpty(foundFileExt) && foundFileExt != ".") // and foundFile is not "no extension" continue; } // if the physical file was in our set, don't check it again bool alreadyChecked = false; foreach (ChecksumFile checkedFile in set.Files) { string checkedFullFileName = Path.Combine(set.Directory, checkedFile.FileName); if (string.Compare(checkedFullFileName, foundFile, true) == 0) { alreadyChecked = true; break; } } if (!alreadyChecked) { // check outOfSetFiles string tmpChecksum; if (!outOfSetFiles.TryGetValue(foundFile, out tmpChecksum)) { FileInfo fileInfo = TryGetNewFileInfo(foundFile); if (set.Type == ChecksumType.MD5) { DateTime speedStart = DateTime.Now; file.CurrentChecksum = GetChecksumWithProgress(MD5WithProgress, fileInfo, speed, bytesProcessed, start); if (string.IsNullOrEmpty(file.CurrentChecksum)) continue; TimeSpan speedSpan = DateTime.Now - speedStart; if (fileInfo.Length > 1024 * 1024 && (long)speedSpan.TotalSeconds > 0) speed = fileInfo.Length / (long)speedSpan.TotalSeconds; } else if (set.Type == ChecksumType.SFV) { DateTime speedStart = DateTime.Now; file.CurrentChecksum = GetChecksumWithProgress(CRC32WithProgress, fileInfo, speed, bytesProcessed, start); if (string.IsNullOrEmpty(file.CurrentChecksum)) continue; TimeSpan speedSpan = DateTime.Now - speedStart; if (fileInfo.Length > 1024 * 1024 && (long)speedSpan.TotalSeconds > 0) speed = fileInfo.Length / (long)speedSpan.TotalSeconds; } else if (set.Type == ChecksumType.SHA1) { DateTime speedStart = DateTime.Now; file.CurrentChecksum = GetChecksumWithProgress(SHA1WithProgress, fileInfo, speed, bytesProcessed, start); if (string.IsNullOrEmpty(file.CurrentChecksum)) continue; TimeSpan speedSpan = DateTime.Now - speedStart; if (fileInfo.Length > 1024 * 1024 && (long)speedSpan.TotalSeconds > 0) speed = fileInfo.Length / (long)speedSpan.TotalSeconds; } else { throw new Exception(string.Format("{0} not implemented", set.Type)); } outOfSetFiles.Add(foundFile, file.CurrentChecksum); } else { file.CurrentChecksum = tmpChecksum; } if (string.Compare(file.CurrentChecksum, file.OriginalChecksum, true) == 0) { if (Program.Settings.Check.Renaming == CheckRenaming.Lowercase) fullFileName = fullFileName.ToLower(); try { File.Move(foundFile, fullFileName); } catch (Exception ex) { Trace.WriteLine(ex); // TODO, write exception to results tab or prompt user } file.State = ChecksumFileState.OK; _files_ok++; _files_missing--; newOK++; UpdateStatusBar(); break; } } } } } if (newOK != 0) { ApplyHideGood(); } }