예제 #1
0
        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("media-scan");

            if (extra.Count > 1)
            {
                DicConsole.ErrorWriteLine("Too many arguments.");
                return((int)ErrorNumber.UnexpectedArgumentCount);
            }

            if (extra.Count == 0)
            {
                DicConsole.ErrorWriteLine("Missing device path.");
                return((int)ErrorNumber.MissingArgument);
            }

            devicePath = extra[0];

            DicConsole.DebugWriteLine("Media-Scan command", "--debug={0}", MainClass.Debug);
            DicConsole.DebugWriteLine("Media-Scan command", "--device={0}", devicePath);
            DicConsole.DebugWriteLine("Media-Scan command", "--ibg-log={0}", ibgLogPath);
            DicConsole.DebugWriteLine("Media-Scan command", "--mhdd-log={0}", mhddLogPath);
            DicConsole.DebugWriteLine("Media-Scan command", "--verbose={0}", MainClass.Verbose);

            if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
            {
                devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
            }

            Device dev = new Device(devicePath);

            if (dev.Error)
            {
                DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
                return((int)ErrorNumber.CannotOpenDevice);
            }

            Statistics.AddDevice(dev);

            MediaScan scanner = new MediaScan(mhddLogPath, ibgLogPath, devicePath, dev);

            scanner.UpdateStatus          += Progress.UpdateStatus;
            scanner.StoppingErrorMessage  += Progress.ErrorMessage;
            scanner.UpdateProgress        += Progress.UpdateProgress;
            scanner.PulseProgress         += Progress.PulseProgress;
            scanner.InitProgress          += Progress.InitProgress;
            scanner.EndProgress           += Progress.EndProgress;
            System.Console.CancelKeyPress += (sender, e) =>
            {
                e.Cancel = true;
                scanner.Abort();
            };
            ScanResults results = scanner.Scan();

            DicConsole.WriteLine("Took a total of {0} seconds ({1} processing commands).", results.TotalTime,
                                 results.ProcessingTime);
            DicConsole.WriteLine("Average speed: {0:F3} MiB/sec.", results.AvgSpeed);
            DicConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", results.MaxSpeed);
            DicConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", results.MinSpeed);
            DicConsole.WriteLine("Summary:");
            DicConsole.WriteLine("{0} sectors took less than 3 ms.", results.A);
            DicConsole.WriteLine("{0} sectors took less than 10 ms but more than 3 ms.", results.B);
            DicConsole.WriteLine("{0} sectors took less than 50 ms but more than 10 ms.", results.C);
            DicConsole.WriteLine("{0} sectors took less than 150 ms but more than 50 ms.", results.D);
            DicConsole.WriteLine("{0} sectors took less than 500 ms but more than 150 ms.", results.E);
            DicConsole.WriteLine("{0} sectors took more than 500 ms.", results.F);
            DicConsole.WriteLine("{0} sectors could not be read.",
                                 results.UnreadableSectors.Count);
            if (results.UnreadableSectors.Count > 0)
            {
                foreach (ulong bad in results.UnreadableSectors)
                {
                    DicConsole.WriteLine("Sector {0} could not be read", bad);
                }
            }

            DicConsole.WriteLine();

            #pragma warning disable RECS0018     // Comparison of floating point numbers with equality operator
            if (results.SeekTotal != 0 || results.SeekMin != double.MaxValue || results.SeekMax != double.MinValue)
                #pragma warning restore RECS0018 // Comparison of floating point numbers with equality operator
            {
                DicConsole.WriteLine("Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)",
                                     results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
            }

            dev.Close();
            return((int)ErrorNumber.NoError);
        }
예제 #2
0
        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("dump-media");

            if (extra.Count > 2)
            {
                DicConsole.ErrorWriteLine("Too many arguments.");

                return((int)ErrorNumber.UnexpectedArgumentCount);
            }

            if (extra.Count <= 1)
            {
                DicConsole.ErrorWriteLine("Missing paths.");

                return((int)ErrorNumber.MissingArgument);
            }

            devicePath = extra[0];
            outputFile = extra[1];

            DicConsole.DebugWriteLine("Dump-Media command", "--cicm-xml={0}", cicmXml);
            DicConsole.DebugWriteLine("Dump-Media command", "--debug={0}", MainClass.Debug);
            DicConsole.DebugWriteLine("Dump-Media command", "--device={0}", devicePath);
            DicConsole.DebugWriteLine("Dump-Media command", "--encoding={0}", encodingName);
            DicConsole.DebugWriteLine("Dump-Media command", "--first-pregap={0}", firstTrackPregap);
            DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force);
            DicConsole.DebugWriteLine("Dump-Media command", "--force={0}", force);
            DicConsole.DebugWriteLine("Dump-Media command", "--format={0}", wantedOutputFormat);
            DicConsole.DebugWriteLine("Dump-Media command", "--no-metadata={0}", noMetadata);
            DicConsole.DebugWriteLine("Dump-Media command", "--options={0}", Options);
            DicConsole.DebugWriteLine("Dump-Media command", "--output={0}", outputFile);
            DicConsole.DebugWriteLine("Dump-Media command", "--persistent={0}", persistent);

            // TODO: Disabled temporarily
            //DicConsole.DebugWriteLine("Dump-Media command", "--raw={0}",           raw);
            DicConsole.DebugWriteLine("Dump-Media command", "--resume={0}", doResume);
            DicConsole.DebugWriteLine("Dump-Media command", "--retry-passes={0}", retryPasses);
            DicConsole.DebugWriteLine("Dump-Media command", "--skip={0}", skip);
            DicConsole.DebugWriteLine("Dump-Media command", "--stop-on-error={0}", stopOnError);
            DicConsole.DebugWriteLine("Dump-Media command", "--verbose={0}", MainClass.Verbose);

            Dictionary <string, string> parsedOptions = Core.Options.Parse(outputOptions);

            DicConsole.DebugWriteLine("Dump-Media command", "Parsed options:");

            foreach (KeyValuePair <string, string> parsedOption in parsedOptions)
            {
                DicConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
            }

            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 (devicePath.Length == 2 &&
                devicePath[1] == ':' &&
                devicePath[0] != '/' &&
                char.IsLetter(devicePath[0]))
            {
                devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
            }

            Device dev;

            try
            {
                dev = new Device(devicePath);

                if (dev.IsRemote)
                {
                    Statistics.AddRemote(dev.RemoteApplication, dev.RemoteVersion, dev.RemoteOperatingSystem,
                                         dev.RemoteOperatingSystemVersion, dev.RemoteArchitecture);
                }

                if (dev.Error)
                {
                    DicConsole.ErrorWriteLine(Error.Print(dev.LastError));

                    return((int)ErrorNumber.CannotOpenDevice);
                }
            }
            catch (DeviceException e)
            {
                DicConsole.ErrorWriteLine(e.Message ?? Error.Print(e.LastError));

                return((int)ErrorNumber.CannotOpenDevice);
            }

            Statistics.AddDevice(dev);

            string outputPrefix = Path.Combine(Path.GetDirectoryName(outputFile),
                                               Path.GetFileNameWithoutExtension(outputFile));

            Resume resume = null;
            var    xs     = new XmlSerializer(typeof(Resume));

            if (File.Exists(outputPrefix + ".resume.xml") && doResume)
            {
                try
                {
                    var sr = new StreamReader(outputPrefix + ".resume.xml");
                    resume = (Resume)xs.Deserialize(sr);
                    sr.Close();
                }
                catch
                {
                    DicConsole.ErrorWriteLine("Incorrect resume file, not continuing...");

                    return((int)ErrorNumber.InvalidResume);
                }
            }

            if (resume != null &&
                resume.NextBlock > resume.LastBlock &&
                resume.BadBlocks.Count == 0 &&
                !resume.Tape)
            {
                DicConsole.WriteLine("Media already dumped correctly, not continuing...");

                return((int)ErrorNumber.AlreadyDumped);
            }

            CICMMetadataType sidecar = null;
            var sidecarXs            = new XmlSerializer(typeof(CICMMetadataType));

            if (cicmXml != null)
            {
                if (File.Exists(cicmXml))
                {
                    try
                    {
                        var sr = new StreamReader(cicmXml);
                        sidecar = (CICMMetadataType)sidecarXs.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);
                }
            }

            PluginBase            plugins    = GetPluginBase.Instance;
            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];

            var dumpLog = new DumpLog(outputPrefix + ".log", dev);

            if (MainClass.Verbose)
            {
                dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
                DicConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id);
            }
            else
            {
                dumpLog.WriteLine("Output image format: {0}.", outputFormat.Name);
                DicConsole.WriteLine("Output image format: {0}.", outputFormat.Name);
            }

            var dumper = new Dump(doResume, dev, devicePath, outputFormat, retryPasses, force, false, persistent,
                                  stopOnError, resume, dumpLog, encoding, outputPrefix, outputFile, parsedOptions,
                                  sidecar, (uint)skip, noMetadata, noTrim, firstTrackPregap);

            dumper.UpdateStatus         += Progress.UpdateStatus;
            dumper.ErrorMessage         += Progress.ErrorMessage;
            dumper.StoppingErrorMessage += Progress.ErrorMessage;
            dumper.UpdateProgress       += Progress.UpdateProgress;
            dumper.PulseProgress        += Progress.PulseProgress;
            dumper.InitProgress         += Progress.InitProgress;
            dumper.EndProgress          += Progress.EndProgress;
            dumper.InitProgress2        += Progress.InitProgress2;
            dumper.EndProgress2         += Progress.EndProgress2;
            dumper.UpdateProgress2      += Progress.UpdateProgress2;

            System.Console.CancelKeyPress += (sender, e) =>
            {
                e.Cancel = true;
                dumper.Abort();
            };

            dumper.Start();

            dev.Close();

            return((int)ErrorNumber.NoError);
        }
예제 #3
0
        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("media-info");

            if (extra.Count > 1)
            {
                DicConsole.ErrorWriteLine("Too many arguments.");
                return((int)ErrorNumber.UnexpectedArgumentCount);
            }

            if (extra.Count == 0)
            {
                DicConsole.ErrorWriteLine("Missing device path.");
                return((int)ErrorNumber.MissingArgument);
            }

            devicePath = extra[0];

            DicConsole.DebugWriteLine("Media-Info command", "--debug={0}", MainClass.Debug);
            DicConsole.DebugWriteLine("Media-Info command", "--device={0}", devicePath);
            DicConsole.DebugWriteLine("Media-Info command", "--output-prefix={0}", outputPrefix);
            DicConsole.DebugWriteLine("Media-Info command", "--verbose={0}", MainClass.Verbose);

            if (devicePath.Length == 2 && devicePath[1] == ':' && devicePath[0] != '/' && char.IsLetter(devicePath[0]))
            {
                devicePath = "\\\\.\\" + char.ToUpper(devicePath[0]) + ':';
            }

            Device dev = new Device(devicePath);

            if (dev.Error)
            {
                DicConsole.ErrorWriteLine("Error {0} opening device.", dev.LastError);
                return((int)ErrorNumber.CannotOpenDevice);
            }

            Statistics.AddDevice(dev);

            switch (dev.Type)
            {
            case DeviceType.ATA:
                DoAtaMediaInfo();
                break;

            case DeviceType.MMC:
            case DeviceType.SecureDigital:
                DoSdMediaInfo();
                break;

            case DeviceType.NVMe:
                DoNvmeMediaInfo(outputPrefix, dev);
                break;

            case DeviceType.ATAPI:
            case DeviceType.SCSI:
                DoScsiMediaInfo(outputPrefix, dev);
                break;

            default: throw new NotSupportedException("Unknown device type.");
            }

            return((int)ErrorNumber.NoError);
        }