public override int Invoke(IEnumerable <string> arguments) { List <string> extra = Options.Parse(arguments); if (showHelp) { Options.WriteOptionDescriptions(CommandSet.Out); return((int)ErrorNumber.HelpRequested); } MainClass.PrintCopyright(); if (MainClass.Debug) { DicConsole.DebugWriteLineEvent += System.Console.Error.WriteLine; } if (MainClass.Verbose) { DicConsole.VerboseWriteLineEvent += System.Console.WriteLine; } Statistics.AddCommand("verify"); if (extra.Count > 1) { DicConsole.ErrorWriteLine("Too many arguments."); return((int)ErrorNumber.UnexpectedArgumentCount); } if (extra.Count == 0) { DicConsole.ErrorWriteLine("Missing input image."); return((int)ErrorNumber.MissingArgument); } inputFile = extra[0]; DicConsole.DebugWriteLine("Verify command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Verify command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Verify command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Verify command", "--verify-disc={0}", verifyDisc); DicConsole.DebugWriteLine("Verify command", "--verify-sectors={0}", verifySectors); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } IMediaImage inputFormat = ImageFormat.Detect(inputFilter); if (inputFormat == null) { DicConsole.ErrorWriteLine("Unable to recognize image format, not verifying"); return((int)ErrorNumber.FormatNotFound); } inputFormat.Open(inputFilter); Statistics.AddMediaFormat(inputFormat.Format); Statistics.AddMedia(inputFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); bool?correctImage = null; long totalSectors = 0; long errorSectors = 0; bool?correctSectors = null; long unknownSectors = 0; IVerifiableImage verifiableImage = inputFormat as IVerifiableImage; IVerifiableSectorsImage verifiableSectorsImage = inputFormat as IVerifiableSectorsImage; if (verifiableImage is null && verifiableSectorsImage is null) { DicConsole.ErrorWriteLine("The specified image does not support any kind of verification"); return((int)ErrorNumber.NotVerificable); } if (verifyDisc && verifiableImage != null) { DateTime startCheck = DateTime.UtcNow; bool? discCheckStatus = verifiableImage.VerifyMediaImage(); DateTime endCheck = DateTime.UtcNow; TimeSpan checkTime = endCheck - startCheck; switch (discCheckStatus) { case true: DicConsole.WriteLine("Disc image checksums are correct"); break; case false: DicConsole.WriteLine("Disc image checksums are incorrect"); break; case null: DicConsole.WriteLine("Disc image does not contain checksums"); break; } correctImage = discCheckStatus; DicConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds); } if (verifySectors) { DateTime startCheck = DateTime.Now; DateTime endCheck = startCheck; List <ulong> failingLbas = new List <ulong>(); List <ulong> unknownLbas = new List <ulong>(); if (verifiableSectorsImage is IOpticalMediaImage opticalMediaImage) { List <Track> inputTracks = opticalMediaImage.Tracks; ulong currentSectorAll = 0; startCheck = DateTime.UtcNow; foreach (Track currentTrack in inputTracks) { ulong remainingSectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector; ulong currentSector = 0; while (remainingSectors > 0) { DicConsole.Write("\rChecking sector {0} of {1}, on track {2}", currentSectorAll, inputFormat.Info.Sectors, currentTrack.TrackSequence); List <ulong> tempfailingLbas; List <ulong> tempunknownLbas; if (remainingSectors < 512) { opticalMediaImage.VerifySectors(currentSector, (uint)remainingSectors, currentTrack.TrackSequence, out tempfailingLbas, out tempunknownLbas); } else { opticalMediaImage.VerifySectors(currentSector, 512, currentTrack.TrackSequence, out tempfailingLbas, out tempunknownLbas); } failingLbas.AddRange(tempfailingLbas); unknownLbas.AddRange(tempunknownLbas); if (remainingSectors < 512) { currentSector += remainingSectors; currentSectorAll += remainingSectors; remainingSectors = 0; } else { currentSector += 512; currentSectorAll += 512; remainingSectors -= 512; } } } endCheck = DateTime.UtcNow; } else if (verifiableSectorsImage != null) { ulong remainingSectors = inputFormat.Info.Sectors; ulong currentSector = 0; startCheck = DateTime.UtcNow; while (remainingSectors > 0) { DicConsole.Write("\rChecking sector {0} of {1}", currentSector, inputFormat.Info.Sectors); List <ulong> tempfailingLbas; List <ulong> tempunknownLbas; if (remainingSectors < 512) { verifiableSectorsImage.VerifySectors(currentSector, (uint)remainingSectors, out tempfailingLbas, out tempunknownLbas); } else { verifiableSectorsImage.VerifySectors(currentSector, 512, out tempfailingLbas, out tempunknownLbas); } failingLbas.AddRange(tempfailingLbas); unknownLbas.AddRange(tempunknownLbas); if (remainingSectors < 512) { currentSector += remainingSectors; remainingSectors = 0; } else { currentSector += 512; remainingSectors -= 512; } } endCheck = DateTime.UtcNow; } TimeSpan checkTime = endCheck - startCheck; DicConsole.Write("\r" + new string(' ', System.Console.WindowWidth - 1) + "\r"); if (unknownSectors > 0) { DicConsole.WriteLine("There is at least one sector that does not contain a checksum"); } if (errorSectors > 0) { DicConsole.WriteLine("There is at least one sector with incorrect checksum or errors"); } if (unknownSectors == 0 && errorSectors == 0) { DicConsole.WriteLine("All sector checksums are correct"); } DicConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds); if (MainClass.Verbose) { DicConsole.VerboseWriteLine("LBAs with error:"); if (failingLbas.Count == (int)inputFormat.Info.Sectors) { DicConsole.VerboseWriteLine("\tall sectors."); } else { foreach (ulong t in failingLbas) { DicConsole.VerboseWriteLine("\t{0}", t); } } DicConsole.WriteLine("LBAs without checksum:"); if (unknownLbas.Count == (int)inputFormat.Info.Sectors) { DicConsole.VerboseWriteLine("\tall sectors."); } else { foreach (ulong t in unknownLbas) { DicConsole.VerboseWriteLine("\t{0}", t); } } } DicConsole.WriteLine("Total sectors........... {0}", inputFormat.Info.Sectors); DicConsole.WriteLine("Total errors............ {0}", failingLbas.Count); DicConsole.WriteLine("Total unknowns.......... {0}", unknownLbas.Count); DicConsole.WriteLine("Total errors+unknowns... {0}", failingLbas.Count + unknownLbas.Count); totalSectors = (long)inputFormat.Info.Sectors; errorSectors = failingLbas.Count; unknownSectors = unknownLbas.Count; if (failingLbas.Count > 0) { correctSectors = false; } else if ((ulong)unknownLbas.Count < inputFormat.Info.Sectors) { correctSectors = true; } } switch (correctImage) { case null when correctSectors is null: return((int)ErrorNumber.NotVerificable); case null when correctSectors == false: return((int)ErrorNumber.BadSectorsImageNotVerified); case null when correctSectors == true: return((int)ErrorNumber.CorrectSectorsImageNotVerified); case false when correctSectors is null: return((int)ErrorNumber.BadImageSectorsNotVerified); case false when correctSectors == false: return((int)ErrorNumber.BadImageBadSectors); case false when correctSectors == true: return((int)ErrorNumber.CorrectSectorsBadImage); case true when correctSectors is null: return((int)ErrorNumber.CorrectImageSectorsNotVerified); case true when correctSectors == false: return((int)ErrorNumber.CorrectImageBadSectors); case true when correctSectors == true: return((int)ErrorNumber.NoError); } return((int)ErrorNumber.NoError); }
void DoWork() { bool?correctDisc = null; long totalSectors = 0; long errorSectors = 0; long correctSectors = 0; long unknownSectors = 0; bool formatHasTracks; IOpticalMediaImage inputOptical = inputFormat as IOpticalMediaImage; IVerifiableSectorsImage verifiableSectorsImage = inputFormat as IVerifiableSectorsImage; try { formatHasTracks = inputOptical?.Tracks?.Count > 0; } catch { formatHasTracks = false; } // Setup progress bars Application.Instance.Invoke(() => { stkProgress.Visible = true; prgProgress.MaxValue = 0; if (chkVerifyImage.Checked == true || chkVerifySectors.Checked == true) { prgProgress.MaxValue = 1; } if (formatHasTracks && inputOptical != null) { prgProgress.MaxValue += inputOptical.Tracks.Count; } else { if (chkVerifySectors.Checked == true) { prgProgress.MaxValue = 2; prgProgress2.Visible = false; lblProgress2.Visible = false; } else { prgProgress2.Visible = true; lblProgress2.Visible = true; } } prgProgress.MaxValue++; }); if (chkVerifyImage.Checked == true) { if (!(inputFormat is IVerifiableImage verifiableImage)) { Application.Instance.Invoke(() => { lblImageResult.Visible = true; lblImageResult.Text = "Disc image does not support verification."; }); } else { Application.Instance.Invoke(() => { lblProgress.Text = "Checking media image..."; if (chkVerifySectors.Checked == true) { prgProgress.Value = 1; } else { prgProgress.Indeterminate = true; } prgProgress2.Indeterminate = true; }); DateTime startCheck = DateTime.UtcNow; bool? discCheckStatus = verifiableImage.VerifyMediaImage(); DateTime endCheck = DateTime.UtcNow; TimeSpan checkTime = endCheck - startCheck; Application.Instance.Invoke(() => { lblImageResult.Visible = true; switch (discCheckStatus) { case true: lblImageResult.Text = "Disc image checksums are correct"; break; case false: lblImageResult.Text = "Disc image checksums are incorrect"; break; case null: lblImageResult.Text = "Disc image does not contain checksums"; break; } }); correctDisc = discCheckStatus; DicConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds); } }