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("entropy"); 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("Entropy command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Entropy command", "--duplicated-sectors={0}", duplicatedSectors); DicConsole.DebugWriteLine("Entropy command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Entropy command", "--separated-tracks={0}", separatedTracks); DicConsole.DebugWriteLine("Entropy command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Entropy command", "--whole-disc={0}", wholeDisc); 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 checksumming"); return((int)ErrorNumber.UnrecognizedFormat); } inputFormat.Open(inputFilter); Statistics.AddMediaFormat(inputFormat.Format); Statistics.AddMedia(inputFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); Entropy entropyCalculator = new Entropy(MainClass.Debug, MainClass.Verbose, inputFormat); entropyCalculator.InitProgressEvent += Progress.InitProgress; entropyCalculator.InitProgress2Event += Progress.InitProgress2; entropyCalculator.UpdateProgressEvent += Progress.UpdateProgress; entropyCalculator.UpdateProgress2Event += Progress.UpdateProgress2; entropyCalculator.EndProgressEvent += Progress.EndProgress; entropyCalculator.EndProgress2Event += Progress.EndProgress2; if (separatedTracks) { EntropyResults[] tracksEntropy = entropyCalculator.CalculateTracksEntropy(duplicatedSectors); foreach (EntropyResults trackEntropy in tracksEntropy) { DicConsole.WriteLine("Entropy for track {0} is {1:F4}.", trackEntropy.Track, trackEntropy.Entropy); if (trackEntropy.UniqueSectors != null) { DicConsole.WriteLine("Track {0} has {1} unique sectors ({2:P3})", trackEntropy.Track, trackEntropy.UniqueSectors, (double)trackEntropy.UniqueSectors / (double)trackEntropy.Sectors); } } } if (!wholeDisc) { return((int)ErrorNumber.NoError); } EntropyResults entropy = entropyCalculator.CalculateMediaEntropy(duplicatedSectors); DicConsole.WriteLine("Entropy for disk is {0:F4}.", entropy.Entropy); if (entropy.UniqueSectors != null) { DicConsole.WriteLine("Disk has {0} unique sectors ({1:P3})", entropy.UniqueSectors, (double)entropy.UniqueSectors / (double)entropy.Sectors); } return((int)ErrorNumber.NoError); }
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("analyze"); 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("Analyze command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Analyze command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Analyze command", "--filesystems={0}", searchForFilesystems); DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Analyze command", "--partitions={0}", searchForPartitions); DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } Encoding encoding = null; if (encodingName != null) { try { encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); } } catch (ArgumentException) { DicConsole.ErrorWriteLine("Specified encoding is not supported."); return((int)ErrorNumber.EncodingUnknown); } } PluginBase plugins = GetPluginBase.Instance; bool checkraw = false; try { IMediaImage imageFormat = ImageFormat.Detect(inputFilter); if (imageFormat == null) { DicConsole.WriteLine("Image format not identified, not proceeding with analysis."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); } else { DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); } DicConsole.WriteLine(); try { if (!imageFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } if (MainClass.Verbose) { ImageInfo.PrintImageInfo(imageFormat); DicConsole.WriteLine(); } Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMedia(imageFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); DicConsole.DebugWriteLine("Analyze command", "Stack trace: {0}", ex.StackTrace); return((int)ErrorNumber.CannotOpenFormat); } List <string> idPlugins; IFilesystem plugin; string information; if (searchForPartitions) { List <Partition> partitions = Core.Partitions.GetAll(imageFormat); Core.Partitions.AddSchemesToStats(partitions); if (partitions.Count == 0) { DicConsole.DebugWriteLine("Analyze command", "No partitions found"); if (!searchForFilesystems) { DicConsole.WriteLine("No partitions founds, not searching for filesystems"); return((int)ErrorNumber.NothingFound); } checkraw = true; } else { DicConsole.WriteLine("{0} partitions found.", partitions.Count); for (int i = 0; i < partitions.Count; i++) { DicConsole.WriteLine(); DicConsole.WriteLine("Partition {0}:", partitions[i].Sequence); DicConsole.WriteLine("Partition name: {0}", partitions[i].Name); DicConsole.WriteLine("Partition type: {0}", partitions[i].Type); DicConsole.WriteLine("Partition start: sector {0}, byte {1}", partitions[i].Start, partitions[i].Offset); DicConsole.WriteLine("Partition length: {0} sectors, {1} bytes", partitions[i].Length, partitions[i].Size); DicConsole.WriteLine("Partition scheme: {0}", partitions[i].Scheme); DicConsole.WriteLine("Partition description:"); DicConsole.WriteLine(partitions[i].Description); if (!searchForFilesystems) { continue; } DicConsole.WriteLine("Identifying filesystem on partition"); Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.PluginsList.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); plugin.GetInformation(imageFormat, partitions[i], out information, encoding); DicConsole.Write(information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } else { plugins.PluginsList.TryGetValue(idPlugins[0], out plugin); if (plugin == null) { continue; } DicConsole.WriteLine($"Identified by {plugin.Name}."); plugin.GetInformation(imageFormat, partitions[i], out information, encoding); DicConsole.Write("{0}", information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } } if (checkraw) { Partition wholePart = new Partition { Name = "Whole device", Length = imageFormat.Info.Sectors, Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize }; Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.PluginsList.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); plugin.GetInformation(imageFormat, wholePart, out information, encoding); DicConsole.Write(information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } else { plugins.PluginsList.TryGetValue(idPlugins[0], out plugin); if (plugin != null) { DicConsole.WriteLine($"Identified by {plugin.Name}."); plugin.GetInformation(imageFormat, wholePart, out information, encoding); DicConsole.Write(information); Statistics.AddFilesystem(plugin.XmlFsType.Type); } } } } catch (Exception ex) { DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); DicConsole.DebugWriteLine("Analyze command", ex.StackTrace); return((int)ErrorNumber.UnexpectedException); } return((int)ErrorNumber.NoError); }
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); }
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("extract-files"); 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("Extract-Files command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Extract-Files command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Extract-Files command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Extract-Files command", "--options={0}", pluginOptions); DicConsole.DebugWriteLine("Extract-Files command", "--output={0}", outputDir); DicConsole.DebugWriteLine("Extract-Files command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Extract-Files command", "--xattrs={0}", extractXattrs); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); Dictionary <string, string> parsedOptions = Core.Options.Parse(pluginOptions); DicConsole.DebugWriteLine("Extract-Files command", "Parsed options:"); foreach (KeyValuePair <string, string> parsedOption in parsedOptions) { DicConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value); } parsedOptions.Add("debug", MainClass.Debug.ToString()); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } Encoding encoding = null; if (encodingName != null) { try { encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); } } catch (ArgumentException) { DicConsole.ErrorWriteLine("Specified encoding is not supported."); return((int)ErrorNumber.EncodingUnknown); } } PluginBase plugins = GetPluginBase.Instance; try { IMediaImage imageFormat = ImageFormat.Detect(inputFilter); if (imageFormat == null) { DicConsole.WriteLine("Image format not identified, not proceeding with analysis."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); } else { DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); } if (outputDir == null) { DicConsole.WriteLine("Output directory missing."); return((int)ErrorNumber.MissingArgument); } if (Directory.Exists(outputDir) || File.Exists(outputDir)) { DicConsole.ErrorWriteLine("Destination exists, aborting."); return((int)ErrorNumber.DestinationExists); } Directory.CreateDirectory(outputDir); try { if (!imageFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } DicConsole.DebugWriteLine("Extract-Files command", "Correctly opened image file."); DicConsole.DebugWriteLine("Extract-Files command", "Image without headers is {0} bytes.", imageFormat.Info.ImageSize); DicConsole.DebugWriteLine("Extract-Files command", "Image has {0} sectors.", imageFormat.Info.Sectors); DicConsole.DebugWriteLine("Extract-Files command", "Image identifies disk type as {0}.", imageFormat.Info.MediaType); Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMedia(imageFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); return((int)ErrorNumber.CannotOpenFormat); } List <Partition> partitions = Core.Partitions.GetAll(imageFormat); Core.Partitions.AddSchemesToStats(partitions); List <string> idPlugins; IReadOnlyFilesystem plugin; Errno error; if (partitions.Count == 0) { DicConsole.DebugWriteLine("Extract-Files command", "No partitions found"); } else { DicConsole.WriteLine("{0} partitions found.", partitions.Count); for (int i = 0; i < partitions.Count; i++) { DicConsole.WriteLine(); DicConsole.WriteLine("Partition {0}:", partitions[i].Sequence); DicConsole.WriteLine("Identifying filesystem on partition"); Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin .GetType() .GetConstructor(Type.EmptyTypes) ?.Invoke(new object[] { }); error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } } else { plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin); DicConsole.WriteLine($"Identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin .GetType().GetConstructor(Type.EmptyTypes) ?.Invoke(new object[] { }); error = fs.Mount(imageFormat, partitions[i], encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } } Partition wholePart = new Partition { Name = "Whole device", Length = imageFormat.Info.Sectors, Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize }; Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart); if (idPlugins.Count == 0) { DicConsole.WriteLine("Filesystem not identified"); } else if (idPlugins.Count > 1) { DicConsole.WriteLine($"Identified by {idPlugins.Count} plugins"); foreach (string pluginName in idPlugins) { if (plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin)) { DicConsole.WriteLine($"As identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin .GetType().GetConstructor(Type.EmptyTypes) ?.Invoke(new object[] { }); error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } } else { plugins.ReadOnlyFilesystems.TryGetValue(idPlugins[0], out plugin); DicConsole.WriteLine($"Identified by {plugin.Name}."); IReadOnlyFilesystem fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.Invoke(new object[] { }); error = fs.Mount(imageFormat, wholePart, encoding, parsedOptions, @namespace); if (error == Errno.NoError) { string volumeName = string.IsNullOrEmpty(fs.XmlFsType.VolumeName) ? "NO NAME" : fs.XmlFsType.VolumeName; ExtractFilesInDir("/", fs, volumeName); Statistics.AddFilesystem(fs.XmlFsType.Type); } else { DicConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); } } } catch (Exception ex) { DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); DicConsole.DebugWriteLine("Extract-Files command", ex.StackTrace); return((int)ErrorNumber.UnexpectedException); } return((int)ErrorNumber.NoError); }
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("convert-image"); if (extra.Count > 2) { DicConsole.ErrorWriteLine("Too many arguments."); return((int)ErrorNumber.UnexpectedArgumentCount); } if (extra.Count <= 1) { DicConsole.ErrorWriteLine("Missing input image."); return((int)ErrorNumber.MissingArgument); } inputFile = extra[0]; outputFile = extra[1]; DicConsole.DebugWriteLine("Analyze command", "--cicm-xml={0}", cicmXml); DicConsole.DebugWriteLine("Analyze command", "--comments={0}", comments); DicConsole.DebugWriteLine("Analyze command", "--count={0}", count); DicConsole.DebugWriteLine("Analyze command", "--creator={0}", creator); DicConsole.DebugWriteLine("Analyze command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Analyze command", "--drive-manufacturer={0}", driveManufacturer); DicConsole.DebugWriteLine("Analyze command", "--drive-model={0}", driveModel); DicConsole.DebugWriteLine("Analyze command", "--drive-revision={0}", driveFirmwareRevision); DicConsole.DebugWriteLine("Analyze command", "--drive-serial={0}", driveSerialNumber); DicConsole.DebugWriteLine("Analyze command", "--force={0}", force); DicConsole.DebugWriteLine("Analyze command", "--format={0}", wantedOutputFormat); DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Analyze command", "--media-barcode={0}", mediaBarcode); DicConsole.DebugWriteLine("Analyze command", "--media-lastsequence={0}", lastMediaSequence); DicConsole.DebugWriteLine("Analyze command", "--media-manufacturer={0}", mediaManufacturer); DicConsole.DebugWriteLine("Analyze command", "--media-model={0}", mediaModel); DicConsole.DebugWriteLine("Analyze command", "--media-partnumber={0}", mediaPartNumber); DicConsole.DebugWriteLine("Analyze command", "--media-sequence={0}", mediaSequence); DicConsole.DebugWriteLine("Analyze command", "--media-serial={0}", mediaSerialNumber); DicConsole.DebugWriteLine("Analyze command", "--media-title={0}", mediaTitle); DicConsole.DebugWriteLine("Analyze command", "--options={0}", outputOptions); DicConsole.DebugWriteLine("Analyze command", "--output={0}", outputFile); DicConsole.DebugWriteLine("Analyze command", "--resume-file={0}", resumeFile); DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose); Dictionary <string, string> parsedOptions = Core.Options.Parse(outputOptions); DicConsole.DebugWriteLine("Analyze command", "Parsed options:"); foreach (KeyValuePair <string, string> parsedOption in parsedOptions) { DicConsole.DebugWriteLine("Analyze command", "{0} = {1}", parsedOption.Key, parsedOption.Value); } if (count == 0) { DicConsole.ErrorWriteLine("Need to specify more than 0 sectors to copy at once"); return((int)ErrorNumber.InvalidArgument); } Resume resume = null; CICMMetadataType sidecar = null; XmlSerializer xs = new XmlSerializer(typeof(CICMMetadataType)); if (cicmXml != null) { if (File.Exists(cicmXml)) { try { StreamReader sr = new StreamReader(cicmXml); sidecar = (CICMMetadataType)xs.Deserialize(sr); sr.Close(); } catch { DicConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing..."); return((int)ErrorNumber.InvalidSidecar); } } else { DicConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing..."); return((int)ErrorNumber.FileNotFound); } } xs = new XmlSerializer(typeof(Resume)); if (resumeFile != null) { if (File.Exists(resumeFile)) { try { StreamReader sr = new StreamReader(resumeFile); resume = (Resume)xs.Deserialize(sr); sr.Close(); } catch { DicConsole.ErrorWriteLine("Incorrect resume file, not continuing..."); return((int)ErrorNumber.InvalidResume); } } else { DicConsole.ErrorWriteLine("Could not find resume file, not continuing..."); return((int)ErrorNumber.FileNotFound); } } FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } if (File.Exists(outputFile)) { DicConsole.ErrorWriteLine("Output file already exists, not continuing."); return((int)ErrorNumber.DestinationExists); } PluginBase plugins = GetPluginBase.Instance; IMediaImage inputFormat = ImageFormat.Detect(inputFilter); if (inputFormat == null) { DicConsole.WriteLine("Input image format not identified, not proceeding with conversion."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Input image format identified by {0} ({1}).", inputFormat.Name, inputFormat.Id); } else { DicConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name); } try { if (!inputFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } DicConsole.DebugWriteLine("Convert-image command", "Correctly opened image file."); DicConsole.DebugWriteLine("Convert-image command", "Image without headers is {0} bytes.", inputFormat.Info.ImageSize); DicConsole.DebugWriteLine("Convert-image command", "Image has {0} sectors.", inputFormat.Info.Sectors); DicConsole.DebugWriteLine("Convert-image command", "Image identifies media type as {0}.", inputFormat.Info.MediaType); Statistics.AddMediaFormat(inputFormat.Format); Statistics.AddMedia(inputFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); DicConsole.DebugWriteLine("Convert-image command", "Stack trace: {0}", ex.StackTrace); return((int)ErrorNumber.CannotOpenFormat); } List <IWritableImage> candidates = new List <IWritableImage>(); // Try extension if (string.IsNullOrEmpty(wantedOutputFormat)) { candidates.AddRange(plugins.WritableImages.Values.Where(t => t.KnownExtensions .Contains(Path.GetExtension(outputFile)))); } // Try Id else if (Guid.TryParse(wantedOutputFormat, out Guid outId)) { candidates.AddRange(plugins.WritableImages.Values.Where(t => t.Id.Equals(outId))); } // Try name else { candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, wantedOutputFormat, StringComparison .InvariantCultureIgnoreCase))); } if (candidates.Count == 0) { DicConsole.WriteLine("No plugin supports requested extension."); return((int)ErrorNumber.FormatNotFound); } if (candidates.Count > 1) { DicConsole.WriteLine("More than one plugin supports requested extension."); return((int)ErrorNumber.TooManyFormats); } IWritableImage outputFormat = candidates[0]; if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); } else { DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name); } if (!outputFormat.SupportedMediaTypes.Contains(inputFormat.Info.MediaType)) { DicConsole.ErrorWriteLine("Output format does not support media type, cannot continue..."); return((int)ErrorNumber.UnsupportedMedia); } foreach (MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags) { if (outputFormat.SupportedMediaTags.Contains(mediaTag) || force) { continue; } DicConsole.ErrorWriteLine("Converting image will lose media tag {0}, not continuing...", mediaTag); DicConsole.ErrorWriteLine("If you don't care, use force option."); return((int)ErrorNumber.DataWillBeLost); } bool useLong = inputFormat.Info.ReadableSectorTags.Count != 0; foreach (SectorTagType sectorTag in inputFormat.Info.ReadableSectorTags) { if (outputFormat.SupportedSectorTags.Contains(sectorTag)) { continue; } if (force) { if (sectorTag != SectorTagType.CdTrackFlags && sectorTag != SectorTagType.CdTrackIsrc && sectorTag != SectorTagType.CdSectorSubchannel) { useLong = false; } continue; } DicConsole.ErrorWriteLine("Converting image will lose sector tag {0}, not continuing...", sectorTag); DicConsole .ErrorWriteLine("If you don't care, use force option. This will skip all sector tags converting only user data."); return((int)ErrorNumber.DataWillBeLost); } if (!outputFormat.Create(outputFile, inputFormat.Info.MediaType, parsedOptions, inputFormat.Info.Sectors, inputFormat.Info.SectorSize)) { DicConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage); return((int)ErrorNumber.CannotCreateFormat); } ImageInfo metadata = new ImageInfo { Application = "DiscImageChef", ApplicationVersion = Version.GetVersion(), Comments = comments ?? inputFormat.Info.Comments, Creator = creator ?? inputFormat.Info.Creator, DriveFirmwareRevision = driveFirmwareRevision ?? inputFormat.Info.DriveFirmwareRevision, DriveManufacturer = driveManufacturer ?? inputFormat.Info.DriveManufacturer, DriveModel = driveModel ?? inputFormat.Info.DriveModel, DriveSerialNumber = driveSerialNumber ?? inputFormat.Info.DriveSerialNumber, LastMediaSequence = lastMediaSequence != 0 ? lastMediaSequence : inputFormat.Info.LastMediaSequence, MediaBarcode = mediaBarcode ?? inputFormat.Info.MediaBarcode, MediaManufacturer = mediaManufacturer ?? inputFormat.Info.MediaManufacturer, MediaModel = mediaModel ?? inputFormat.Info.MediaModel, MediaPartNumber = mediaPartNumber ?? inputFormat.Info.MediaPartNumber, MediaSequence = mediaSequence != 0 ? mediaSequence : inputFormat.Info.MediaSequence, MediaSerialNumber = mediaSerialNumber ?? inputFormat.Info.MediaSerialNumber, MediaTitle = mediaTitle ?? inputFormat.Info.MediaTitle }; if (!outputFormat.SetMetadata(metadata)) { DicConsole.ErrorWrite("Error {0} setting metadata, ", outputFormat.ErrorMessage); if (!force) { DicConsole.ErrorWriteLine("not continuing..."); return((int)ErrorNumber.WriteError); } DicConsole.ErrorWriteLine("continuing..."); } CICMMetadataType cicmMetadata = inputFormat.CicmMetadata; List <DumpHardwareType> dumpHardware = inputFormat.DumpHardware; foreach (MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags) { if (force && !outputFormat.SupportedMediaTags.Contains(mediaTag)) { continue; } DicConsole.WriteLine("Converting media tag {0}", mediaTag); byte[] tag = inputFormat.ReadDiskTag(mediaTag); if (outputFormat.WriteMediaTag(tag, mediaTag)) { continue; } if (force) { DicConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", outputFormat.ErrorMessage); } else { DicConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...", outputFormat.ErrorMessage); return((int)ErrorNumber.WriteError); } } DicConsole.WriteLine("{0} sectors to convert", inputFormat.Info.Sectors); ulong doneSectors = 0; if (inputFormat is IOpticalMediaImage inputOptical && outputFormat is IWritableOpticalImage outputOptical && inputOptical.Tracks != null) { if (!outputOptical.SetTracks(inputOptical.Tracks)) { DicConsole.ErrorWriteLine("Error {0} sending tracks list to output image.", outputFormat.ErrorMessage); return((int)ErrorNumber.WriteError); } foreach (Track track in inputOptical.Tracks) { doneSectors = 0; ulong trackSectors = track.TrackEndSector - track.TrackStartSector + 1; while (doneSectors < trackSectors) { byte[] sector; uint sectorsToDo; if (trackSectors - doneSectors >= (ulong)count) { sectorsToDo = (uint)count; } else { sectorsToDo = (uint)(trackSectors - doneSectors); } DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)", doneSectors + track.TrackStartSector, doneSectors + sectorsToDo + track.TrackStartSector, (doneSectors + track.TrackStartSector) / (double)inputFormat.Info.Sectors, track.TrackSequence); bool result; if (useLong) { if (sectorsToDo == 1) { sector = inputFormat.ReadSectorLong(doneSectors + track.TrackStartSector); result = outputFormat.WriteSectorLong(sector, doneSectors + track.TrackStartSector); } else { sector = inputFormat.ReadSectorsLong(doneSectors + track.TrackStartSector, sectorsToDo); result = outputFormat.WriteSectorsLong(sector, doneSectors + track.TrackStartSector, sectorsToDo); } } else { if (sectorsToDo == 1) { sector = inputFormat.ReadSector(doneSectors + track.TrackStartSector); result = outputFormat.WriteSector(sector, doneSectors + track.TrackStartSector); } else { sector = inputFormat.ReadSectors(doneSectors + track.TrackStartSector, sectorsToDo); result = outputFormat.WriteSectors(sector, doneSectors + track.TrackStartSector, sectorsToDo); } } if (!result) { if (force) { DicConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", outputFormat.ErrorMessage, doneSectors); } else { DicConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...", outputFormat.ErrorMessage, doneSectors); return((int)ErrorNumber.WriteError); } } doneSectors += sectorsToDo; } } DicConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)", inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0, inputOptical.Tracks.Count); DicConsole.WriteLine(); foreach (SectorTagType tag in inputFormat.Info.ReadableSectorTags.OrderBy(t => t)) { if (!useLong) { break; } switch (tag) { case SectorTagType.AppleSectorTag: case SectorTagType.CdSectorSync: case SectorTagType.CdSectorHeader: case SectorTagType.CdSectorSubHeader: case SectorTagType.CdSectorEdc: case SectorTagType.CdSectorEccP: case SectorTagType.CdSectorEccQ: case SectorTagType.CdSectorEcc: // This tags are inline in long sector continue; } if (force && !outputFormat.SupportedSectorTags.Contains(tag)) { continue; } foreach (Track track in inputOptical.Tracks) { doneSectors = 0; ulong trackSectors = track.TrackEndSector - track.TrackStartSector + 1; byte[] sector; bool result; switch (tag) { case SectorTagType.CdTrackFlags: case SectorTagType.CdTrackIsrc: DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag, track.TrackSequence, track.TrackSequence / (double)inputOptical.Tracks.Count); sector = inputFormat.ReadSectorTag(track.TrackStartSector, tag); result = outputFormat.WriteSectorTag(sector, track.TrackStartSector, tag); if (!result) { if (force) { DicConsole.ErrorWriteLine("Error {0} writing tag, continuing...", outputFormat.ErrorMessage); } else { DicConsole.ErrorWriteLine("Error {0} writing tag, not continuing...", outputFormat.ErrorMessage); return((int)ErrorNumber.WriteError); } } continue; } while (doneSectors < trackSectors) { uint sectorsToDo; if (trackSectors - doneSectors >= (ulong)count) { sectorsToDo = (uint)count; } else { sectorsToDo = (uint)(trackSectors - doneSectors); } DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)", doneSectors + track.TrackStartSector, doneSectors + sectorsToDo + track.TrackStartSector, (doneSectors + track.TrackStartSector) / (double)inputFormat.Info.Sectors, track.TrackSequence, tag); if (sectorsToDo == 1) { sector = inputFormat.ReadSectorTag(doneSectors + track.TrackStartSector, tag); result = outputFormat.WriteSectorTag(sector, doneSectors + track.TrackStartSector, tag); } else { sector = inputFormat.ReadSectorsTag(doneSectors + track.TrackStartSector, sectorsToDo, tag); result = outputFormat.WriteSectorsTag(sector, doneSectors + track.TrackStartSector, sectorsToDo, tag); } if (!result) { if (force) { DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, continuing...", outputFormat.ErrorMessage, doneSectors); } else { DicConsole.ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...", outputFormat.ErrorMessage, doneSectors); return((int)ErrorNumber.WriteError); } } doneSectors += sectorsToDo; } } switch (tag) { case SectorTagType.CdTrackFlags: case SectorTagType.CdTrackIsrc: DicConsole.Write("\rConverting tag {0} in track {1} ({2:P2} done).", tag, inputOptical.Tracks.Count, 1.0); break; default: DicConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)", inputFormat.Info.Sectors, inputFormat.Info.Sectors, 1.0, inputOptical.Tracks.Count, tag); break; } DicConsole.WriteLine(); } }
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("decode"); 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("Decode command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Decode command", "--disk-tags={0}", diskTags); DicConsole.DebugWriteLine("Decode command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Decode command", "--length={0}", length); DicConsole.DebugWriteLine("Decode command", "--sector-tags={0}", sectorTags); DicConsole.DebugWriteLine("Decode command", "--start={0}", startSector); DicConsole.DebugWriteLine("Decode command", "--verbose={0}", MainClass.Verbose); 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 decoding"); return((int)ErrorNumber.UnrecognizedFormat); } inputFormat.Open(inputFilter); Statistics.AddMediaFormat(inputFormat.Format); Statistics.AddMedia(inputFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); if (diskTags) { if (inputFormat.Info.ReadableMediaTags.Count == 0) { DicConsole.WriteLine("There are no disk tags in chosen disc image."); } else { foreach (MediaTagType tag in inputFormat.Info.ReadableMediaTags) { switch (tag) { case MediaTagType.SCSI_INQUIRY: { byte[] inquiry = inputFormat.ReadDiskTag(MediaTagType.SCSI_INQUIRY); if (inquiry == null) { DicConsole.WriteLine("Error reading SCSI INQUIRY response from disc image"); } else { DicConsole.WriteLine("SCSI INQUIRY command response:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(Inquiry.Prettify(inquiry)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.ATA_IDENTIFY: { byte[] identify = inputFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY); if (identify == null) { DicConsole.WriteLine("Error reading ATA IDENTIFY DEVICE response from disc image"); } else { DicConsole.WriteLine("ATA IDENTIFY DEVICE command response:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(Identify.Prettify(identify)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.ATAPI_IDENTIFY: { byte[] identify = inputFormat.ReadDiskTag(MediaTagType.ATAPI_IDENTIFY); if (identify == null) { DicConsole .WriteLine("Error reading ATA IDENTIFY PACKET DEVICE response from disc image"); } else { DicConsole.WriteLine("ATA IDENTIFY PACKET DEVICE command response:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(Identify.Prettify(identify)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.CD_ATIP: { byte[] atip = inputFormat.ReadDiskTag(MediaTagType.CD_ATIP); if (atip == null) { DicConsole.WriteLine("Error reading CD ATIP from disc image"); } else { DicConsole.WriteLine("CD ATIP:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(ATIP.Prettify(atip)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.CD_FullTOC: { byte[] fulltoc = inputFormat.ReadDiskTag(MediaTagType.CD_FullTOC); if (fulltoc == null) { DicConsole.WriteLine("Error reading CD full TOC from disc image"); } else { DicConsole.WriteLine("CD full TOC:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(FullTOC.Prettify(fulltoc)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.CD_PMA: { byte[] pma = inputFormat.ReadDiskTag(MediaTagType.CD_PMA); if (pma == null) { DicConsole.WriteLine("Error reading CD PMA from disc image"); } else { DicConsole.WriteLine("CD PMA:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(PMA.Prettify(pma)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.CD_SessionInfo: { byte[] sessioninfo = inputFormat.ReadDiskTag(MediaTagType.CD_SessionInfo); if (sessioninfo == null) { DicConsole.WriteLine("Error reading CD session information from disc image"); } else { DicConsole.WriteLine("CD session information:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(Session.Prettify(sessioninfo)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.CD_TEXT: { byte[] cdtext = inputFormat.ReadDiskTag(MediaTagType.CD_TEXT); if (cdtext == null) { DicConsole.WriteLine("Error reading CD-TEXT from disc image"); } else { DicConsole.WriteLine("CD-TEXT:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(CDTextOnLeadIn.Prettify(cdtext)); DicConsole .WriteLine("================================================================================"); } break; } case MediaTagType.CD_TOC: { byte[] toc = inputFormat.ReadDiskTag(MediaTagType.CD_TOC); if (toc == null) { DicConsole.WriteLine("Error reading CD TOC from disc image"); } else { DicConsole.WriteLine("CD TOC:"); DicConsole .WriteLine("================================================================================"); DicConsole.WriteLine(TOC.Prettify(toc)); DicConsole .WriteLine("================================================================================"); } break; } default: DicConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag); break; } } } } if (sectorTags) { if (length.ToLowerInvariant() == "all") { } else { if (!ulong.TryParse(length, out ulong _)) { DicConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length); DicConsole.WriteLine("Not decoding sectors tags"); return(3); } } if (inputFormat.Info.ReadableSectorTags.Count == 0) { DicConsole.WriteLine("There are no sector tags in chosen disc image."); } else { foreach (SectorTagType tag in inputFormat.Info.ReadableSectorTags) { switch (tag) { default: DicConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag); break; } } } // TODO: Not implemented } return((int)ErrorNumber.NoError); }
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("image-info"); 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("Analyze command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Analyze command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Analyze command", "--verbose={0}", MainClass.Verbose); FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } try { IMediaImage imageFormat = ImageFormat.Detect(inputFilter); if (imageFormat == null) { DicConsole.WriteLine("Image format not identified."); return((int)ErrorNumber.UnrecognizedFormat); } DicConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); DicConsole.WriteLine(); try { if (!imageFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } ImageInfo.PrintImageInfo(imageFormat); Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMedia(imageFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); DicConsole.DebugWriteLine("Image-info command", "Stack trace: {0}", ex.StackTrace); return((int)ErrorNumber.CannotOpenFormat); } } catch (Exception ex) { DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); DicConsole.DebugWriteLine("Image-info command", ex.StackTrace); return((int)ErrorNumber.UnexpectedException); } return((int)ErrorNumber.NoError); }
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("create-sidecar"); 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("Create sidecar command", "--block-size={0}", blockSize); DicConsole.DebugWriteLine("Create sidecar command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Create sidecar command", "--encoding={0}", encodingName); DicConsole.DebugWriteLine("Create sidecar command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Create sidecar command", "--tape={0}", tape); DicConsole.DebugWriteLine("Create sidecar command", "--verbose={0}", MainClass.Verbose); Encoding encoding = null; if (encodingName != null) { try { encoding = Claunia.Encoding.Encoding.GetEncoding(encodingName); if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Using encoding for {0}.", encoding.EncodingName); } } catch (ArgumentException) { DicConsole.ErrorWriteLine("Specified encoding is not supported."); return((int)ErrorNumber.EncodingUnknown); } } if (File.Exists(inputFile)) { if (tape) { DicConsole.ErrorWriteLine("You cannot use --tape option when input is a file."); return((int)ErrorNumber.ExpectedDirectory); } FiltersList filtersList = new FiltersList(); IFilter inputFilter = filtersList.GetFilter(inputFile); if (inputFilter == null) { DicConsole.ErrorWriteLine("Cannot open specified file."); return((int)ErrorNumber.CannotOpenFile); } try { IMediaImage imageFormat = ImageFormat.Detect(inputFilter); if (imageFormat == null) { DicConsole.WriteLine("Image format not identified, not proceeding with analysis."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); } else { DicConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); } try { if (!imageFormat.Open(inputFilter)) { DicConsole.WriteLine("Unable to open image format"); DicConsole.WriteLine("No error given"); return((int)ErrorNumber.CannotOpenFormat); } DicConsole.DebugWriteLine("Analyze command", "Correctly opened image file."); } catch (Exception ex) { DicConsole.ErrorWriteLine("Unable to open image format"); DicConsole.ErrorWriteLine("Error: {0}", ex.Message); return((int)ErrorNumber.CannotOpenFormat); } Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddFilter(inputFilter.Name); Sidecar sidecarClass = new Sidecar(imageFormat, inputFile, inputFilter.Id, encoding); sidecarClass.InitProgressEvent += Progress.InitProgress; sidecarClass.UpdateProgressEvent += Progress.UpdateProgress; sidecarClass.EndProgressEvent += Progress.EndProgress; sidecarClass.InitProgressEvent2 += Progress.InitProgress2; sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2; sidecarClass.EndProgressEvent2 += Progress.EndProgress2; sidecarClass.UpdateStatusEvent += Progress.UpdateStatus; System.Console.CancelKeyPress += (sender, e) => { e.Cancel = true; sidecarClass.Abort(); }; CICMMetadataType sidecar = sidecarClass.Create(); DicConsole.WriteLine("Writing metadata sidecar"); FileStream xmlFs = new FileStream(Path.Combine(Path.GetDirectoryName(inputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(inputFile) + ".cicm.xml"), FileMode.CreateNew); XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); xmlSer.Serialize(xmlFs, sidecar); xmlFs.Close(); } catch (Exception ex) { DicConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); DicConsole.DebugWriteLine("Analyze command", ex.StackTrace); return((int)ErrorNumber.UnexpectedException); } } else if (Directory.Exists(inputFile)) { if (!tape) { DicConsole.ErrorWriteLine("Cannot create a sidecar from a directory."); return((int)ErrorNumber.ExpectedFile); } string[] contents = Directory.GetFiles(inputFile, "*", SearchOption.TopDirectoryOnly); List <string> files = contents.Where(file => new FileInfo(file).Length % blockSize == 0).ToList(); files.Sort(StringComparer.CurrentCultureIgnoreCase); Sidecar sidecarClass = new Sidecar(); sidecarClass.InitProgressEvent += Progress.InitProgress; sidecarClass.UpdateProgressEvent += Progress.UpdateProgress; sidecarClass.EndProgressEvent += Progress.EndProgress; sidecarClass.InitProgressEvent2 += Progress.InitProgress2; sidecarClass.UpdateProgressEvent2 += Progress.UpdateProgress2; sidecarClass.EndProgressEvent2 += Progress.EndProgress2; sidecarClass.UpdateStatusEvent += Progress.UpdateStatus; CICMMetadataType sidecar = sidecarClass.BlockTape(Path.GetFileName(inputFile), files, blockSize); DicConsole.WriteLine("Writing metadata sidecar"); FileStream xmlFs = new FileStream(Path.Combine(Path.GetDirectoryName(inputFile) ?? throw new InvalidOperationException(), Path.GetFileNameWithoutExtension(inputFile) + ".cicm.xml"), FileMode.CreateNew); XmlSerializer xmlSer = new XmlSerializer(typeof(CICMMetadataType)); xmlSer.Serialize(xmlFs, sidecar); xmlFs.Close(); } else { DicConsole.ErrorWriteLine("The specified input file cannot be found."); } return((int)ErrorNumber.NoError); }
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("checksum"); 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("Checksum command", "--adler32={0}", doAdler32); DicConsole.DebugWriteLine("Checksum command", "--crc16={0}", doCrc16); DicConsole.DebugWriteLine("Checksum command", "--crc32={0}", doCrc32); DicConsole.DebugWriteLine("Checksum command", "--crc64={0}", doCrc64); DicConsole.DebugWriteLine("Checksum command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Checksum command", "--fletcher16={0}", doFletcher16); DicConsole.DebugWriteLine("Checksum command", "--fletcher32={0}", doFletcher32); DicConsole.DebugWriteLine("Checksum command", "--input={0}", inputFile); DicConsole.DebugWriteLine("Checksum command", "--md5={0}", doMd5); DicConsole.DebugWriteLine("Checksum command", "--separated-tracks={0}", separatedTracks); DicConsole.DebugWriteLine("Checksum command", "--sha1={0}", doSha1); DicConsole.DebugWriteLine("Checksum command", "--sha256={0}", doSha256); DicConsole.DebugWriteLine("Checksum command", "--sha384={0}", doSha384); DicConsole.DebugWriteLine("Checksum command", "--sha512={0}", doSha512); DicConsole.DebugWriteLine("Checksum command", "--spamsum={0}", doSpamSum); DicConsole.DebugWriteLine("Checksum command", "--verbose={0}", MainClass.Verbose); DicConsole.DebugWriteLine("Checksum command", "--whole-disc={0}", wholeDisc); 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 checksumming"); return((int)ErrorNumber.UnrecognizedFormat); } inputFormat.Open(inputFilter); Statistics.AddMediaFormat(inputFormat.Format); Statistics.AddMedia(inputFormat.Info.MediaType, false); Statistics.AddFilter(inputFilter.Name); EnableChecksum enabledChecksums = new EnableChecksum(); if (doAdler32) { enabledChecksums |= EnableChecksum.Adler32; } if (doCrc16) { enabledChecksums |= EnableChecksum.Crc16; } if (doCrc32) { enabledChecksums |= EnableChecksum.Crc32; } if (doCrc64) { enabledChecksums |= EnableChecksum.Crc64; } if (doMd5) { enabledChecksums |= EnableChecksum.Md5; } if (doSha1) { enabledChecksums |= EnableChecksum.Sha1; } if (doSha256) { enabledChecksums |= EnableChecksum.Sha256; } if (doSha384) { enabledChecksums |= EnableChecksum.Sha384; } if (doSha512) { enabledChecksums |= EnableChecksum.Sha512; } if (doSpamSum) { enabledChecksums |= EnableChecksum.SpamSum; } if (doFletcher16) { enabledChecksums |= EnableChecksum.Fletcher16; } if (doFletcher32) { enabledChecksums |= EnableChecksum.Fletcher32; } Checksum mediaChecksum = null; switch (inputFormat) { case IOpticalMediaImage opticalInput when opticalInput.Tracks != null: try { Checksum trackChecksum = null; if (wholeDisc) { mediaChecksum = new Checksum(enabledChecksums); } ulong previousTrackEnd = 0; List <Track> inputTracks = opticalInput.Tracks; foreach (Track currentTrack in inputTracks) { if (currentTrack.TrackStartSector - previousTrackEnd != 0 && wholeDisc) { for (ulong i = previousTrackEnd + 1; i < currentTrack.TrackStartSector; i++) { DicConsole.Write("\rHashing track-less sector {0}", i); byte[] hiddenSector = inputFormat.ReadSector(i); mediaChecksum?.Update(hiddenSector); } } DicConsole.DebugWriteLine("Checksum command", "Track {0} starts at sector {1} and ends at sector {2}", currentTrack.TrackSequence, currentTrack.TrackStartSector, currentTrack.TrackEndSector); if (separatedTracks) { trackChecksum = new Checksum(enabledChecksums); } ulong sectors = currentTrack.TrackEndSector - currentTrack.TrackStartSector + 1; ulong doneSectors = 0; DicConsole.WriteLine("Track {0} has {1} sectors", currentTrack.TrackSequence, sectors); while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= SECTORS_TO_READ) { sector = opticalInput.ReadSectors(doneSectors, SECTORS_TO_READ, currentTrack.TrackSequence); DicConsole.Write("\rHashings sectors {0} to {2} of track {1}", doneSectors, currentTrack.TrackSequence, doneSectors + SECTORS_TO_READ); doneSectors += SECTORS_TO_READ; } else { sector = opticalInput.ReadSectors(doneSectors, (uint)(sectors - doneSectors), currentTrack.TrackSequence); DicConsole.Write("\rHashings sectors {0} to {2} of track {1}", doneSectors, currentTrack.TrackSequence, doneSectors + (sectors - doneSectors)); doneSectors += sectors - doneSectors; } if (wholeDisc) { mediaChecksum?.Update(sector); } if (separatedTracks) { trackChecksum?.Update(sector); } } DicConsole.WriteLine(); if (separatedTracks) { if (trackChecksum != null) { foreach (ChecksumType chk in trackChecksum.End()) { DicConsole.WriteLine("Track {0}'s {1}: {2}", currentTrack.TrackSequence, chk.type, chk.Value); } } } previousTrackEnd = currentTrack.TrackEndSector; } if (opticalInput.Info.Sectors - previousTrackEnd != 0 && wholeDisc) { for (ulong i = previousTrackEnd + 1; i < opticalInput.Info.Sectors; i++) { DicConsole.Write("\rHashing track-less sector {0}", i); byte[] hiddenSector = inputFormat.ReadSector(i); mediaChecksum?.Update(hiddenSector); } } if (wholeDisc) { if (mediaChecksum != null) { foreach (ChecksumType chk in mediaChecksum.End()) { DicConsole.WriteLine("Disk's {0}: {1}", chk.type, chk.Value); } } } } catch (Exception ex) { if (MainClass.Debug) { DicConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message); } else { DicConsole.WriteLine("Unable to get separate tracks, not checksumming them"); } } break; case ITapeImage tapeImage when tapeImage.IsTape && tapeImage.Files?.Count > 0: { Checksum trackChecksum = null; if (wholeDisc) { mediaChecksum = new Checksum(enabledChecksums); } ulong previousTrackEnd = 0; foreach (TapeFile currentFile in tapeImage.Files) { if (currentFile.FirstBlock - previousTrackEnd != 0 && wholeDisc) { for (ulong i = previousTrackEnd + 1; i < currentFile.FirstBlock; i++) { DicConsole.Write("\rHashing file-less block {0}", i); byte[] hiddenSector = inputFormat.ReadSector(i); mediaChecksum?.Update(hiddenSector); } } DicConsole.DebugWriteLine("Checksum command", "Track {0} starts at sector {1} and ends at block {2}", currentFile.File, currentFile.FirstBlock, currentFile.LastBlock); if (separatedTracks) { trackChecksum = new Checksum(enabledChecksums); } ulong sectors = currentFile.LastBlock - currentFile.FirstBlock + 1; ulong doneSectors = 0; DicConsole.WriteLine("File {0} has {1} sectors", currentFile.File, sectors); while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= SECTORS_TO_READ) { sector = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock, SECTORS_TO_READ); DicConsole.Write("\rHashings blocks {0} to {2} of file {1}", doneSectors, currentFile.File, doneSectors + SECTORS_TO_READ); doneSectors += SECTORS_TO_READ; } else { sector = tapeImage.ReadSectors(doneSectors + currentFile.FirstBlock, (uint)(sectors - doneSectors)); DicConsole.Write("\rHashings blocks {0} to {2} of file {1}", doneSectors, currentFile.File, doneSectors + (sectors - doneSectors)); doneSectors += sectors - doneSectors; } if (wholeDisc) { mediaChecksum?.Update(sector); } if (separatedTracks) { trackChecksum?.Update(sector); } } DicConsole.WriteLine(); if (separatedTracks) { if (trackChecksum != null) { foreach (ChecksumType chk in trackChecksum.End()) { DicConsole.WriteLine("File {0}'s {1}: {2}", currentFile.File, chk.type, chk.Value); } } } previousTrackEnd = currentFile.LastBlock; } if (tapeImage.Info.Sectors - previousTrackEnd != 0 && wholeDisc) { for (ulong i = previousTrackEnd + 1; i < tapeImage.Info.Sectors; i++) { DicConsole.Write("\rHashing file-less sector {0}", i); byte[] hiddenSector = inputFormat.ReadSector(i); mediaChecksum?.Update(hiddenSector); } } if (wholeDisc) { if (mediaChecksum != null) { foreach (ChecksumType chk in mediaChecksum.End()) { DicConsole.WriteLine("Tape's {0}: {1}", chk.type, chk.Value); } } } break; } default: { mediaChecksum = new Checksum(enabledChecksums); ulong sectors = inputFormat.Info.Sectors; DicConsole.WriteLine("Sectors {0}", sectors); ulong doneSectors = 0; while (doneSectors < sectors) { byte[] sector; if (sectors - doneSectors >= SECTORS_TO_READ) { sector = inputFormat.ReadSectors(doneSectors, SECTORS_TO_READ); DicConsole.Write("\rHashings sectors {0} to {1}", doneSectors, doneSectors + SECTORS_TO_READ); doneSectors += SECTORS_TO_READ; } else { sector = inputFormat.ReadSectors(doneSectors, (uint)(sectors - doneSectors)); DicConsole.Write("\rHashings sectors {0} to {1}", doneSectors, doneSectors + (sectors - doneSectors)); doneSectors += sectors - doneSectors; } mediaChecksum.Update(sector); } DicConsole.WriteLine(); foreach (ChecksumType chk in mediaChecksum.End()) { DicConsole.WriteLine("Disk's {0}: {1}", chk.type, chk.Value); } break; } } return((int)ErrorNumber.NoError); }
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("compare"); if (extra.Count > 2) { DicConsole.ErrorWriteLine("Too many arguments."); return((int)ErrorNumber.UnexpectedArgumentCount); } if (extra.Count <= 1) { DicConsole.ErrorWriteLine("Missing input image."); return((int)ErrorNumber.MissingArgument); } inputFile1 = extra[0]; inputFile2 = extra[1]; DicConsole.DebugWriteLine("Compare command", "--debug={0}", MainClass.Debug); DicConsole.DebugWriteLine("Compare command", "--input1={0}", inputFile1); DicConsole.DebugWriteLine("Compare command", "--input2={0}", inputFile2); DicConsole.DebugWriteLine("Compare command", "--verbose={0}", MainClass.Verbose); FiltersList filtersList = new FiltersList(); IFilter inputFilter1 = filtersList.GetFilter(inputFile1); filtersList = new FiltersList(); IFilter inputFilter2 = filtersList.GetFilter(inputFile2); if (inputFilter1 == null) { DicConsole.ErrorWriteLine("Cannot open input file 1"); return((int)ErrorNumber.CannotOpenFile); } if (inputFilter2 == null) { DicConsole.ErrorWriteLine("Cannot open input file 2"); return((int)ErrorNumber.CannotOpenFile); } IMediaImage input1Format = ImageFormat.Detect(inputFilter1); IMediaImage input2Format = ImageFormat.Detect(inputFilter2); if (input1Format == null) { DicConsole.ErrorWriteLine("Input file 1 format not identified, not proceeding with comparison."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Input file 1 format identified by {0} ({1}).", input1Format.Name, input1Format.Id); } else { DicConsole.WriteLine("Input file 1 format identified by {0}.", input1Format.Name); } if (input2Format == null) { DicConsole.ErrorWriteLine("Input file 2 format not identified, not proceeding with comparison."); return((int)ErrorNumber.UnrecognizedFormat); } if (MainClass.Verbose) { DicConsole.VerboseWriteLine("Input file 2 format identified by {0} ({1}).", input2Format.Name, input2Format.Id); } else { DicConsole.WriteLine("Input file 2 format identified by {0}.", input2Format.Name); } input1Format.Open(inputFilter1); input2Format.Open(inputFilter2); Statistics.AddMediaFormat(input1Format.Format); Statistics.AddMediaFormat(input2Format.Format); Statistics.AddMedia(input1Format.Info.MediaType, false); Statistics.AddMedia(input2Format.Info.MediaType, false); Statistics.AddFilter(inputFilter1.Name); Statistics.AddFilter(inputFilter2.Name); StringBuilder sb = new StringBuilder(); if (MainClass.Verbose) { sb.AppendLine("\tDisc image 1\tDisc image 2"); sb.AppendLine("================================"); sb.AppendFormat("File\t{0}\t{1}", inputFile1, inputFile2).AppendLine(); sb.AppendFormat("Disc image format\t{0}\t{1}", input1Format.Name, input2Format.Name).AppendLine(); } else { sb.AppendFormat("Disc image 1: {0}", inputFile1).AppendLine(); sb.AppendFormat("Disc image 2: {0}", inputFile2).AppendLine(); } bool imagesDiffer = false; ImageInfo image1Info = input1Format.Info; ImageInfo image2Info = input2Format.Info; List <Session> image1Sessions = new List <Session>(); List <Session> image2Sessions = new List <Session>(); Dictionary <MediaTagType, byte[]> image1DiskTags = new Dictionary <MediaTagType, byte[]>(); Dictionary <MediaTagType, byte[]> image2DiskTags = new Dictionary <MediaTagType, byte[]>(); foreach (MediaTagType disktag in Enum.GetValues(typeof(MediaTagType))) { try { byte[] temparray = input1Format.ReadDiskTag(disktag); image1DiskTags.Add(disktag, temparray); } #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch { // ignored } #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body } foreach (MediaTagType disktag in Enum.GetValues(typeof(MediaTagType))) { try { byte[] temparray = input2Format.ReadDiskTag(disktag); image2DiskTags.Add(disktag, temparray); } #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch { // ignored } #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body } if (MainClass.Verbose) { sb.AppendFormat("Has partitions?\t{0}\t{1}", image1Info.HasPartitions, image2Info.HasPartitions) .AppendLine(); sb.AppendFormat("Has sessions?\t{0}\t{1}", image1Info.HasSessions, image2Info.HasSessions).AppendLine(); sb.AppendFormat("Image size\t{0}\t{1}", image1Info.ImageSize, image2Info.ImageSize).AppendLine(); sb.AppendFormat("Sectors\t{0}\t{1}", image1Info.Sectors, image2Info.Sectors).AppendLine(); sb.AppendFormat("Sector size\t{0}\t{1}", image1Info.SectorSize, image2Info.SectorSize).AppendLine(); sb.AppendFormat("Creation time\t{0}\t{1}", image1Info.CreationTime, image2Info.CreationTime) .AppendLine(); sb.AppendFormat("Last modification time\t{0}\t{1}", image1Info.LastModificationTime, image2Info.LastModificationTime).AppendLine(); sb.AppendFormat("Disk type\t{0}\t{1}", image1Info.MediaType, image2Info.MediaType).AppendLine(); sb.AppendFormat("Image version\t{0}\t{1}", image1Info.Version, image2Info.Version).AppendLine(); sb.AppendFormat("Image application\t{0}\t{1}", image1Info.Application, image2Info.Application) .AppendLine(); sb.AppendFormat("Image application version\t{0}\t{1}", image1Info.ApplicationVersion, image2Info.ApplicationVersion).AppendLine(); sb.AppendFormat("Image creator\t{0}\t{1}", image1Info.Creator, image2Info.Creator).AppendLine(); sb.AppendFormat("Image name\t{0}\t{1}", image1Info.MediaTitle, image2Info.MediaTitle).AppendLine(); sb.AppendFormat("Image comments\t{0}\t{1}", image1Info.Comments, image2Info.Comments).AppendLine(); sb.AppendFormat("Disk manufacturer\t{0}\t{1}", image1Info.MediaManufacturer, image2Info.MediaManufacturer).AppendLine(); sb.AppendFormat("Disk model\t{0}\t{1}", image1Info.MediaModel, image2Info.MediaModel).AppendLine(); sb.AppendFormat("Disk serial number\t{0}\t{1}", image1Info.MediaSerialNumber, image2Info.MediaSerialNumber).AppendLine(); sb.AppendFormat("Disk barcode\t{0}\t{1}", image1Info.MediaBarcode, image2Info.MediaBarcode) .AppendLine(); sb.AppendFormat("Disk part no.\t{0}\t{1}", image1Info.MediaPartNumber, image2Info.MediaPartNumber) .AppendLine(); sb.AppendFormat("Disk sequence\t{0}\t{1}", image1Info.MediaSequence, image2Info.MediaSequence) .AppendLine(); sb.AppendFormat("Last disk on sequence\t{0}\t{1}", image1Info.LastMediaSequence, image2Info.LastMediaSequence).AppendLine(); sb.AppendFormat("Drive manufacturer\t{0}\t{1}", image1Info.DriveManufacturer, image2Info.DriveManufacturer).AppendLine(); sb.AppendFormat("Drive firmware revision\t{0}\t{1}", image1Info.DriveFirmwareRevision, image2Info.DriveFirmwareRevision).AppendLine(); sb.AppendFormat("Drive model\t{0}\t{1}", image1Info.DriveModel, image2Info.DriveModel).AppendLine(); sb.AppendFormat("Drive serial number\t{0}\t{1}", image1Info.DriveSerialNumber, image2Info.DriveSerialNumber).AppendLine(); foreach (MediaTagType disktag in Enum.GetValues(typeof(MediaTagType))) { sb.AppendFormat("Has {0}?\t{1}\t{2}", disktag, image1DiskTags.ContainsKey(disktag), image2DiskTags.ContainsKey(disktag)).AppendLine(); } } DicConsole.WriteLine("Comparing disk image characteristics"); if (image1Info.HasPartitions != image2Info.HasPartitions) { imagesDiffer = true; if (!MainClass.Verbose) { sb.AppendLine("Image partitioned status differ"); } } if (image1Info.HasSessions != image2Info.HasSessions) { imagesDiffer = true; if (!MainClass.Verbose) { sb.AppendLine("Image session status differ"); } } if (image1Info.Sectors != image2Info.Sectors) { imagesDiffer = true; if (!MainClass.Verbose) { sb.AppendLine("Image sectors differ"); } } if (image1Info.SectorSize != image2Info.SectorSize) { imagesDiffer = true; if (!MainClass.Verbose) { sb.AppendLine("Image sector size differ"); } } if (image1Info.MediaType != image2Info.MediaType) { imagesDiffer = true; if (!MainClass.Verbose) { sb.AppendLine("Disk type differ"); } } ulong leastSectors; if (image1Info.Sectors < image2Info.Sectors) { imagesDiffer = true; leastSectors = image1Info.Sectors; if (!MainClass.Verbose) { sb.AppendLine("Image 2 has more sectors"); } } else if (image1Info.Sectors > image2Info.Sectors) { imagesDiffer = true; leastSectors = image2Info.Sectors; if (!MainClass.Verbose) { sb.AppendLine("Image 1 has more sectors"); } } else { leastSectors = image1Info.Sectors; } DicConsole.WriteLine("Comparing sectors..."); for (ulong sector = 0; sector < leastSectors; sector++) { DicConsole.Write("\rComparing sector {0} of {1}...", sector + 1, leastSectors); try { byte[] image1Sector = input1Format.ReadSector(sector); byte[] image2Sector = input2Format.ReadSector(sector); ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector, image2Sector); if (different) { imagesDiffer = true; sb.AppendFormat("Sector {0} is different", sector).AppendLine(); } else if (!sameSize) { imagesDiffer = true; sb .AppendFormat("Sector {0} has different sizes ({1} bytes in image 1, {2} in image 2) but are otherwise identical", sector, image1Sector.LongLength, image2Sector.LongLength).AppendLine(); } } #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body catch { // ignored } #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body } DicConsole.WriteLine(); sb.AppendLine(imagesDiffer ? "Images differ" : "Images do not differ"); DicConsole.WriteLine(sb.ToString()); return((int)ErrorNumber.NoError); }