Beispiel #1
0
        /// <summary>
        ///     Sends a MMC/SD command
        /// </summary>
        /// <returns>The result of the command.</returns>
        /// <param name="ptId">Platform ID for executing the command</param>
        /// <param name="fd">File handle</param>
        /// <param name="command">MMC/SD opcode</param>
        /// <param name="buffer">Buffer for MMC/SD command response</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense"><c>True</c> if MMC/SD returned non-OK status</param>
        /// <param name="write"><c>True</c> if data is sent from host to card</param>
        /// <param name="isApplication"><c>True</c> if command should be preceded with CMD55</param>
        /// <param name="flags">Flags indicating kind and place of response</param>
        /// <param name="blocks">How many blocks to transfer</param>
        /// <param name="argument">Command argument</param>
        /// <param name="response">Response registers</param>
        /// <param name="blockSize">Size of block in bytes</param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendMmcCommand(PlatformID ptId, object fd, MmcCommands command,
                                           bool write,
                                           bool isApplication, MmcFlags flags, uint argument,
                                           uint blockSize,
                                           uint blocks, ref byte[] buffer, out uint[] response,
                                           out double duration,
                                           out bool sense, uint timeout = 0)
        {
            switch (ptId)
            {
            case PlatformID.Win32NT:
            {
                return(Windows.Command.SendMmcCommand((SafeFileHandle)fd, command, write, isApplication, flags,
                                                      argument, blockSize, blocks, ref buffer, out response,
                                                      out duration, out sense, timeout));
            }

            case PlatformID.Linux:
            {
                return(Linux.Command.SendMmcCommand((int)fd, command, write, isApplication, flags, argument,
                                                    blockSize, blocks, ref buffer, out response, out duration,
                                                    out sense, timeout));
            }

            default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
            }
        }
Beispiel #2
0
        /// <summary>
        ///     Sends an ATA command in 48-bit format
        /// </summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="ptId">Platform ID for executing the command</param>
        /// <param name="fd">File handle</param>
        /// <param name="buffer">Buffer for SCSI command response</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
        /// <param name="registers">Registers to send to the device</param>
        /// <param name="errorRegisters">Registers returned by the device</param>
        /// <param name="protocol">ATA protocol to use</param>
        /// <param name="transferRegister">What register contains the transfer length</param>
        /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendAtaCommand(PlatformID ptId, object fd,
                                           AtaRegistersLba48 registers,
                                           out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
                                           AtaTransferRegister transferRegister, ref byte[] buffer,
                                           uint timeout,
                                           bool transferBlocks, out double duration,
                                           out bool sense)
        {
            switch (ptId)
            {
            case PlatformID.Win32NT:
            {
                // No check for Windows version. A 48-bit ATA disk simply does not work on earlier systems
                return(Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol,
                                                      ref buffer, timeout, out duration, out sense));
            }

            case PlatformID.Linux:
            {
                return(Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol,
                                                    transferRegister, ref buffer, timeout, transferBlocks,
                                                    out duration, out sense));
            }

            case PlatformID.FreeBSD:
            {
                return(FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
                                                      ref buffer, timeout, out duration, out sense));
            }

            default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
            }
        }
        /// <summary>
        ///     Sends a SCSI command
        /// </summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="fd">File handle</param>
        /// <param name="cdb">SCSI CDB</param>
        /// <param name="buffer">Buffer for SCSI command response</param>
        /// <param name="senseBuffer">Buffer with the SCSI sense</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="direction">SCSI command transfer direction</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense">
        ///     <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
        ///     sense
        /// </param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendScsiCommand(object fd, byte[] cdb, ref byte[] buffer,
                                            out byte[] senseBuffer,
                                            uint timeout, ScsiDirection direction, out double duration,
                                            out bool sense)
        {
            PlatformID ptId = DetectOS.GetRealPlatformID();

            return(SendScsiCommand(ptId, fd, cdb, ref buffer, out senseBuffer, timeout, direction, out duration,
                                   out sense));
        }
        /// <summary>
        ///     Sends an ATA command in 48-bit LBA format
        /// </summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="fd">File handle</param>
        /// <param name="buffer">Buffer for SCSI command response</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
        /// <param name="registers">Registers to send to the device</param>
        /// <param name="errorRegisters">Registers returned by the device</param>
        /// <param name="protocol">ATA protocol to use</param>
        /// <param name="transferRegister">What register contains the transfer length</param>
        /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendAtaCommand(object fd, AtaRegistersLba48 registers,
                                           out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
                                           AtaTransferRegister transferRegister, ref byte[]        buffer,
                                           uint timeout,
                                           bool transferBlocks, out double duration,
                                           out bool sense)
        {
            PlatformID ptId = DetectOS.GetRealPlatformID();

            return(SendAtaCommand(ptId, fd, registers, out errorRegisters, protocol, transferRegister,
                                  ref buffer,
                                  timeout, transferBlocks, out duration, out sense));
        }
        /// <summary>
        ///     Sends a MMC/SD command
        /// </summary>
        /// <returns>The result of the command.</returns>
        /// <param name="fd">File handle</param>
        /// <param name="command">MMC/SD opcode</param>
        /// <param name="buffer">Buffer for MMC/SD command response</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense"><c>True</c> if MMC/SD returned non-OK status</param>
        /// <param name="write"><c>True</c> if data is sent from host to card</param>
        /// <param name="isApplication"><c>True</c> if command should be preceded with CMD55</param>
        /// <param name="flags">Flags indicating kind and place of response</param>
        /// <param name="blocks">How many blocks to transfer</param>
        /// <param name="argument">Command argument</param>
        /// <param name="response">Response registers</param>
        /// <param name="blockSize">Size of block in bytes</param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendMmcCommand(object fd, MmcCommands command, bool write,
                                           bool isApplication,
                                           MmcFlags flags, uint argument, uint blockSize,
                                           uint blocks,
                                           ref byte[] buffer, out uint[] response, out double duration,
                                           out bool sense,
                                           uint timeout = 0)
        {
            PlatformID ptId = DetectOS.GetRealPlatformID();

            return(SendMmcCommand(ptId, (int)fd, command, write, isApplication, flags, argument,
                                  blockSize, blocks,
                                  ref buffer, out response, out duration, out sense, timeout));
        }
Beispiel #6
0
        /// <summary>
        ///     Sends an ATA command in 28-bit LBA format
        /// </summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="ptId">Platform ID for executing the command</param>
        /// <param name="fd">File handle</param>
        /// <param name="buffer">Buffer for SCSI command response</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense"><c>True</c> if ATA returned non-OK status</param>
        /// <param name="registers">Registers to send to the device</param>
        /// <param name="errorRegisters">Registers returned by the device</param>
        /// <param name="protocol">ATA protocol to use</param>
        /// <param name="transferRegister">What register contains the transfer length</param>
        /// <param name="transferBlocks">Set to <c>true</c> if the transfer length is in block, otherwise it is in bytes</param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendAtaCommand(PlatformID ptId, object fd,
                                           AtaRegistersLba28 registers,
                                           out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
                                           AtaTransferRegister transferRegister, ref byte[] buffer,
                                           uint timeout,
                                           bool transferBlocks, out double duration,
                                           out bool sense)
        {
            switch (ptId)
            {
            case PlatformID.Win32NT:
            {
                if (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 1 &&
                    (Environment.OSVersion.ServicePack == "Service Pack 1" ||
                     Environment.OSVersion.ServicePack == "") ||
                    Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor == 0)
                {
                    throw new InvalidOperationException("Windows XP or earlier is not supported.");
                }

                // Windows NT 4 or earlier, requires special ATA pass thru SCSI. But DiscImageChef cannot run there (or can it?)
                if (Environment.OSVersion.Version.Major <= 4)
                {
                    throw new InvalidOperationException("Windows NT 4.0 or earlier is not supported.");
                }

                return(Windows.Command.SendAtaCommand((SafeFileHandle)fd, registers, out errorRegisters, protocol,
                                                      ref buffer, timeout, out duration, out sense));
            }

            case PlatformID.Linux:
            {
                return(Linux.Command.SendAtaCommand((int)fd, registers, out errorRegisters, protocol,
                                                    transferRegister, ref buffer, timeout, transferBlocks,
                                                    out duration, out sense));
            }

            case PlatformID.FreeBSD:
            {
                return(FreeBSD.Command.SendAtaCommand((IntPtr)fd, registers, out errorRegisters, protocol,
                                                      ref buffer, timeout, out duration, out sense));
            }

            default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
            }
        }
Beispiel #7
0
        /// <summary>Initializes the dump log</summary>
        /// <param name="outputFile">Output log file</param>
        /// <param name="dev">Device</param>
        public DumpLog(string outputFile, Device dev)
        {
            if (string.IsNullOrEmpty(outputFile))
            {
                return;
            }

            logSw = new StreamWriter(outputFile, true);

            logSw.WriteLine("Start logging at {0}", DateTime.Now);

            PlatformID platId  = DetectOS.GetRealPlatformID();
            string     platVer = DetectOS.GetVersion();

            var assemblyVersion =
                Attribute.GetCustomAttribute(typeof(DumpLog).Assembly, typeof(AssemblyInformationalVersionAttribute)) as
                AssemblyInformationalVersionAttribute;

            logSw.WriteLine("################# System information #################");

            logSw.WriteLine("{0} {1} ({2}-bit)", DetectOS.GetPlatformName(platId, platVer), platVer,
                            Environment.Is64BitOperatingSystem ? 64 : 32);

            if (DetectOS.IsMono)
            {
                logSw.WriteLine("Mono {0}", Version.GetMonoVersion());
            }
            else if (DetectOS.IsNetCore)
            {
                logSw.WriteLine(".NET Core {0}", Version.GetNetCoreVersion());
            }
            else
            {
                logSw.WriteLine(RuntimeInformation.FrameworkDescription);
            }

            logSw.WriteLine();

            logSw.WriteLine("################# Program information ################");
            logSw.WriteLine("DiscImageChef {0}", assemblyVersion?.InformationalVersion);
            logSw.WriteLine("Running in {0}-bit", Environment.Is64BitProcess ? 64 : 32);
        #if DEBUG
            logSw.WriteLine("DEBUG version");
        #endif
            logSw.WriteLine("Command line: {0}", Environment.CommandLine);
            logSw.WriteLine();

            if (dev.IsRemote)
            {
                logSw.WriteLine("################# Remote information #################");
                logSw.WriteLine("Server: {0}", dev.RemoteApplication);
                logSw.WriteLine("Version: {0}", dev.RemoteVersion);

                logSw.WriteLine("Operating system: {0} {1}", dev.RemoteOperatingSystem,
                                dev.RemoteOperatingSystemVersion);

                logSw.WriteLine("Architecture: {0}", dev.RemoteArchitecture);
                logSw.WriteLine("Protocol version: {0}", dev.RemoteProtocolVersion);
                logSw.WriteLine("######################################################");
            }

            logSw.WriteLine("################# Device information #################");
            logSw.WriteLine("Manufacturer: {0}", dev.Manufacturer);
            logSw.WriteLine("Model: {0}", dev.Model);
            logSw.WriteLine("Firmware revision: {0}", dev.FirmwareRevision);
            logSw.WriteLine("Serial number: {0}", dev.Serial);
            logSw.WriteLine("Removable device: {0}", dev.IsRemovable);
            logSw.WriteLine("Device type: {0}", dev.Type);
            logSw.WriteLine("CompactFlash device: {0}", dev.IsCompactFlash);
            logSw.WriteLine("PCMCIA device: {0}", dev.IsPcmcia);
            logSw.WriteLine("USB device: {0}", dev.IsUsb);

            if (dev.IsUsb)
            {
                logSw.WriteLine("USB manufacturer: {0}", dev.UsbManufacturerString);
                logSw.WriteLine("USB product: {0}", dev.UsbProductString);
                logSw.WriteLine("USB serial: {0}", dev.UsbSerialString);
                logSw.WriteLine("USB vendor ID: {0:X4}h", dev.UsbVendorId);
                logSw.WriteLine("USB product ID: {0:X4}h", dev.UsbProductId);
            }

            logSw.WriteLine("FireWire device: {0}", dev.IsFireWire);

            if (dev.IsFireWire)
            {
                logSw.WriteLine("FireWire vendor: {0}", dev.FireWireVendorName);
                logSw.WriteLine("FireWire model: {0}", dev.FireWireModelName);
                logSw.WriteLine("FireWire GUID: 0x{0:X16}", dev.FireWireGuid);
                logSw.WriteLine("FireWire vendor ID: 0x{0:X8}", dev.FireWireVendor);
                logSw.WriteLine("FireWire product ID: 0x{0:X8}", dev.FireWireModel);
            }

            logSw.WriteLine("######################################################");

            logSw.WriteLine();
            logSw.WriteLine("################ Dumping progress log ################");
            logSw.Flush();
        }
Beispiel #8
0
        public static void SaveSettings()
        {
            try
            {
                PlatformID ptId = DetectOS.GetRealPlatformID();

                switch (ptId)
                {
                // In case of macOS or iOS settings will be saved in ~/Library/Preferences/com.claunia.discimagechef.plist
                case PlatformID.MacOSX:
                case PlatformID.iOS:
                {
                    NSDictionary root = new NSDictionary
                    {
                        { "SaveReportsGlobally", Current.SaveReportsGlobally },
                        { "ShareReports", Current.ShareReports },
                        { "GdprCompliance", Current.GdprCompliance }
                    };
                    if (Current.Stats != null)
                    {
                        NSDictionary stats = new NSDictionary
                        {
                            { "ShareStats", Current.Stats.ShareStats },
                            { "BenchmarkStats", Current.Stats.BenchmarkStats },
                            { "CommandStats", Current.Stats.CommandStats },
                            { "DeviceStats", Current.Stats.DeviceStats },
                            { "FilesystemStats", Current.Stats.FilesystemStats },
                            { "FilterStats", Current.Stats.FilterStats },
                            { "MediaImageStats", Current.Stats.MediaImageStats },
                            { "MediaScanStats", Current.Stats.MediaScanStats },
                            { "PartitionStats", Current.Stats.PartitionStats },
                            { "MediaStats", Current.Stats.MediaStats },
                            { "VerifyStats", Current.Stats.VerifyStats }
                        };
                        root.Add("Stats", stats);
                    }

                    string preferencesPath =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library",
                                     "Preferences");
                    string preferencesFilePath = Path.Combine(preferencesPath, "com.claunia.discimagechef.plist");

                    FileStream fs = new FileStream(preferencesFilePath, FileMode.Create);
                    BinaryPropertyListWriter.Write(fs, root);
                    fs.Close();
                }
                break;

#if !NETSTANDARD2_0
                // In case of Windows settings will be saved in the registry: HKLM/SOFTWARE/Claunia.com/DiscImageChef
                case PlatformID.Win32NT:
                case PlatformID.Win32S:
                case PlatformID.Win32Windows:
                case PlatformID.WinCE:
                case PlatformID.WindowsPhone:
                {
                    RegistryKey parentKey =
                        Registry.CurrentUser.OpenSubKey("SOFTWARE", true)?.CreateSubKey("Claunia.com");
                    RegistryKey key = parentKey?.CreateSubKey("DiscImageChef");

                    if (key != null)
                    {
                        key.SetValue("SaveReportsGlobally", Current.SaveReportsGlobally);
                        key.SetValue("ShareReports", Current.ShareReports);
                        key.SetValue("GdprCompliance", Current.GdprCompliance);

                        if (Current.Stats != null)
                        {
                            key.SetValue("Statistics", true);
                            key.SetValue("ShareStats", Current.Stats.ShareStats);
                            key.SetValue("BenchmarkStats", Current.Stats.BenchmarkStats);
                            key.SetValue("CommandStats", Current.Stats.CommandStats);
                            key.SetValue("DeviceStats", Current.Stats.DeviceStats);
                            key.SetValue("FilesystemStats", Current.Stats.FilesystemStats);
                            key.SetValue("FilterStats", Current.Stats.FilterStats);
                            key.SetValue("MediaImageStats", Current.Stats.MediaImageStats);
                            key.SetValue("MediaScanStats", Current.Stats.MediaScanStats);
                            key.SetValue("PartitionStats", Current.Stats.PartitionStats);
                            key.SetValue("MediaStats", Current.Stats.MediaStats);
                            key.SetValue("VerifyStats", Current.Stats.VerifyStats);
                        }
                        else
                        {
                            key.SetValue("Statistics", true);
                            key.DeleteValue("ShareStats", false);
                            key.DeleteValue("BenchmarkStats", false);
                            key.DeleteValue("CommandStats", false);
                            key.DeleteValue("DeviceStats", false);
                            key.DeleteValue("FilesystemStats", false);
                            key.DeleteValue("MediaImageStats", false);
                            key.DeleteValue("MediaScanStats", false);
                            key.DeleteValue("PartitionStats", false);
                            key.DeleteValue("MediaStats", false);
                            key.DeleteValue("VerifyStats", false);
                        }
                    }
                }
                break;
#endif
                // Otherwise, settings will be saved in ~/.config/DiscImageChef.xml
                default:
                {
                    string homePath      = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                    string xdgConfigPath =
                        Path.Combine(homePath,
                                     Environment.GetEnvironmentVariable(XDG_CONFIG_HOME) ??
                                     XDG_CONFIG_HOME_RESOLVED);
                    string settingsPath = Path.Combine(xdgConfigPath, "DiscImageChef.xml");

                    if (!Directory.Exists(xdgConfigPath))
                    {
                        Directory.CreateDirectory(xdgConfigPath);
                    }

                    FileStream    fs = new FileStream(settingsPath, FileMode.Create);
                    XmlSerializer xs = new XmlSerializer(Current.GetType());
                    xs.Serialize(fs, Current);
                    fs.Close();
                }
                break;
                }
            }
            #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
        }
Beispiel #9
0
        /// <summary>
        ///     Loads settings
        /// </summary>
        public static void LoadSettings()
        {
            Current = new DicSettings();
            PlatformID ptId     = DetectOS.GetRealPlatformID();
            string     homePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

            try
            {
                switch (ptId)
                {
                // In case of macOS or iOS statistics and reports will be saved in ~/Library/Application Support/Claunia.com/DiscImageChef
                case PlatformID.MacOSX:
                case PlatformID.iOS:
                {
                    string appSupportPath =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library",
                                     "Application Support", "Claunia.com");
                    if (!Directory.Exists(appSupportPath))
                    {
                        Directory.CreateDirectory(appSupportPath);
                    }

                    string dicPath = Path.Combine(appSupportPath, "DiscImageChef");
                    if (!Directory.Exists(dicPath))
                    {
                        Directory.CreateDirectory(dicPath);
                    }

                    ReportsPath = Path.Combine(dicPath, "Reports");
                    if (!Directory.Exists(ReportsPath))
                    {
                        Directory.CreateDirectory(ReportsPath);
                    }

                    StatsPath = Path.Combine(dicPath, "Statistics");
                    if (!Directory.Exists(StatsPath))
                    {
                        Directory.CreateDirectory(StatsPath);
                    }
                }
                break;

                // In case of Windows statistics and reports will be saved in %APPDATA%\Claunia.com\DiscImageChef
                case PlatformID.Win32NT:
                case PlatformID.Win32S:
                case PlatformID.Win32Windows:
                case PlatformID.WinCE:
                case PlatformID.WindowsPhone:
                {
                    string appSupportPath =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                                     "Claunia.com");
                    if (!Directory.Exists(appSupportPath))
                    {
                        Directory.CreateDirectory(appSupportPath);
                    }

                    string dicPath = Path.Combine(appSupportPath, "DiscImageChef");
                    if (!Directory.Exists(dicPath))
                    {
                        Directory.CreateDirectory(dicPath);
                    }

                    ReportsPath = Path.Combine(dicPath, "Reports");
                    if (!Directory.Exists(ReportsPath))
                    {
                        Directory.CreateDirectory(ReportsPath);
                    }

                    StatsPath = Path.Combine(dicPath, "Statistics");
                    if (!Directory.Exists(StatsPath))
                    {
                        Directory.CreateDirectory(StatsPath);
                    }
                }
                break;

                // Otherwise, statistics and reports will be saved in ~/.claunia.com/DiscImageChef
                default:
                {
                    string xdgDataPath =
                        Path.Combine(homePath,
                                     Environment.GetEnvironmentVariable(XDG_DATA_HOME) ?? XDG_DATA_HOME_RESOLVED);

                    string oldDicPath = Path.Combine(homePath, ".claunia.com", "DiscImageChef");
                    string dicPath    = Path.Combine(xdgDataPath, "DiscImageChef");

                    if (Directory.Exists(oldDicPath) && !Directory.Exists(dicPath))
                    {
                        Directory.Move(oldDicPath, dicPath);
                        Directory.Delete(Path.Combine(homePath, ".claunia.com"));
                    }

                    if (!Directory.Exists(dicPath))
                    {
                        Directory.CreateDirectory(dicPath);
                    }

                    ReportsPath = Path.Combine(dicPath, "Reports");
                    if (!Directory.Exists(ReportsPath))
                    {
                        Directory.CreateDirectory(ReportsPath);
                    }

                    StatsPath = Path.Combine(dicPath, "Statistics");
                    if (!Directory.Exists(StatsPath))
                    {
                        Directory.CreateDirectory(StatsPath);
                    }
                }
                break;
                }
            }
            catch { ReportsPath = null; }

            FileStream   prefsFs = null;
            StreamReader prefsSr = null;

            try
            {
                switch (ptId)
                {
                // In case of macOS or iOS settings will be saved in ~/Library/Preferences/com.claunia.discimagechef.plist
                case PlatformID.MacOSX:
                case PlatformID.iOS:
                {
                    string preferencesPath =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Library",
                                     "Preferences");
                    string preferencesFilePath = Path.Combine(preferencesPath, "com.claunia.discimagechef.plist");

                    if (!File.Exists(preferencesFilePath))
                    {
                        SetDefaultSettings();
                        SaveSettings();
                    }

                    prefsFs = new FileStream(preferencesFilePath, FileMode.Open, FileAccess.Read);

                    NSDictionary parsedPreferences = (NSDictionary)BinaryPropertyListParser.Parse(prefsFs);
                    if (parsedPreferences != null)
                    {
                        Current.SaveReportsGlobally =
                            parsedPreferences.TryGetValue("SaveReportsGlobally", out NSObject obj) &&
                            ((NSNumber)obj).ToBool();

                        Current.ShareReports = parsedPreferences.TryGetValue("ShareReports", out obj) &&
                                               ((NSNumber)obj).ToBool();

                        if (parsedPreferences.TryGetValue("Stats", out obj))
                        {
                            NSDictionary stats = (NSDictionary)obj;

                            if (stats != null)
                            {
                                Current.Stats = new StatsSettings
                                {
                                    ShareStats =
                                        stats.TryGetValue("ShareStats", out NSObject obj2) &&
                                        ((NSNumber)obj2).ToBool(),
                                    BenchmarkStats =
                                        stats.TryGetValue("BenchmarkStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    CommandStats =
                                        stats.TryGetValue("CommandStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    DeviceStats =
                                        stats.TryGetValue("DeviceStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    FilesystemStats =
                                        stats.TryGetValue("FilesystemStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    FilterStats =
                                        stats.TryGetValue("FilterStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    MediaImageStats =
                                        stats.TryGetValue("MediaImageStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    MediaScanStats =
                                        stats.TryGetValue("MediaScanStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    PartitionStats =
                                        stats.TryGetValue("PartitionStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    MediaStats =
                                        stats.TryGetValue("MediaStats", out obj2) && ((NSNumber)obj2).ToBool(),
                                    VerifyStats =
                                        stats.TryGetValue("VerifyStats", out obj2) && ((NSNumber)obj2).ToBool()
                                }
                            }
                            ;
                        }
                        else
                        {
                            Current.Stats = null;
                        }

                        Current.GdprCompliance = parsedPreferences.TryGetValue("GdprCompliance", out obj)
                                                         ? (ulong)((NSNumber)obj).ToLong()
                                                         : 0;

                        prefsFs.Close();
                    }
                    else
                    {
                        prefsFs.Close();

                        SetDefaultSettings();
                        SaveSettings();
                    }
                }
                break;

#if !NETSTANDARD2_0
                // In case of Windows settings will be saved in the registry: HKLM/SOFTWARE/Claunia.com/DiscImageChef
                case PlatformID.Win32NT:
                case PlatformID.Win32S:
                case PlatformID.Win32Windows:
                case PlatformID.WinCE:
                case PlatformID.WindowsPhone:
                {
                    RegistryKey parentKey = Registry.CurrentUser.OpenSubKey("SOFTWARE")?.OpenSubKey("Claunia.com");
                    if (parentKey == null)
                    {
                        SetDefaultSettings();
                        SaveSettings();
                        return;
                    }

                    RegistryKey key = parentKey.OpenSubKey("DiscImageChef");
                    if (key == null)
                    {
                        SetDefaultSettings();
                        SaveSettings();
                        return;
                    }

                    Current.SaveReportsGlobally = Convert.ToBoolean(key.GetValue("SaveReportsGlobally"));
                    Current.ShareReports        = Convert.ToBoolean(key.GetValue("ShareReports"));
                    Current.GdprCompliance      = Convert.ToUInt64(key.GetValue("GdprCompliance"));

                    bool stats = Convert.ToBoolean(key.GetValue("Statistics"));
                    if (stats)
                    {
                        Current.Stats = new StatsSettings
                        {
                            ShareStats      = Convert.ToBoolean(key.GetValue("ShareStats")),
                            BenchmarkStats  = Convert.ToBoolean(key.GetValue("BenchmarkStats")),
                            CommandStats    = Convert.ToBoolean(key.GetValue("CommandStats")),
                            DeviceStats     = Convert.ToBoolean(key.GetValue("DeviceStats")),
                            FilesystemStats = Convert.ToBoolean(key.GetValue("FilesystemStats")),
                            FilterStats     = Convert.ToBoolean(key.GetValue("FilterStats")),
                            MediaImageStats = Convert.ToBoolean(key.GetValue("MediaImageStats")),
                            MediaScanStats  = Convert.ToBoolean(key.GetValue("MediaScanStats")),
                            PartitionStats  = Convert.ToBoolean(key.GetValue("PartitionStats")),
                            MediaStats      = Convert.ToBoolean(key.GetValue("MediaStats")),
                            VerifyStats     = Convert.ToBoolean(key.GetValue("VerifyStats"))
                        }
                    }
                    ;
                }

                break;
#endif
                // Otherwise, settings will be saved in ~/.config/DiscImageChef.xml
                default:
                {
                    string oldConfigPath =
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".config");
                    string oldSettingsPath = Path.Combine(oldConfigPath, "DiscImageChef.xml");

                    string xdgConfigPath =
                        Path.Combine(homePath,
                                     Environment.GetEnvironmentVariable(XDG_CONFIG_HOME) ??
                                     XDG_CONFIG_HOME_RESOLVED);
                    string settingsPath = Path.Combine(xdgConfigPath, "DiscImageChef.xml");

                    if (File.Exists(oldSettingsPath) && !File.Exists(settingsPath))
                    {
                        if (!Directory.Exists(xdgConfigPath))
                        {
                            Directory.CreateDirectory(xdgConfigPath);
                        }
                        File.Move(oldSettingsPath, settingsPath);
                    }

                    if (!File.Exists(settingsPath))
                    {
                        SetDefaultSettings();
                        SaveSettings();
                        return;
                    }

                    XmlSerializer xs = new XmlSerializer(Current.GetType());
                    prefsSr = new StreamReader(settingsPath);
                    Current = (DicSettings)xs.Deserialize(prefsSr);
                }

                break;
                }
            }
            catch
            {
                prefsFs?.Close();
                prefsSr?.Close();
                SetDefaultSettings();
                SaveSettings();
            }
        }
Beispiel #10
0
        /// <summary>
        ///     Sends a SCSI command
        /// </summary>
        /// <returns>0 if no error occurred, otherwise, errno</returns>
        /// <param name="ptId">Platform ID for executing the command</param>
        /// <param name="fd">File handle</param>
        /// <param name="cdb">SCSI CDB</param>
        /// <param name="buffer">Buffer for SCSI command response</param>
        /// <param name="senseBuffer">Buffer with the SCSI sense</param>
        /// <param name="timeout">Timeout in seconds</param>
        /// <param name="direction">SCSI command transfer direction</param>
        /// <param name="duration">Time it took to execute the command in milliseconds</param>
        /// <param name="sense">
        ///     <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
        ///     sense
        /// </param>
        /// <exception cref="InvalidOperationException">If the specified platform is not supported</exception>
        internal static int SendScsiCommand(PlatformID ptId, object fd, byte[] cdb,
                                            ref byte[] buffer,
                                            out byte[] senseBuffer, uint timeout, ScsiDirection direction,
                                            out double duration, out bool sense)
        {
            switch (ptId)
            {
            case PlatformID.Win32NT:
            {
                ScsiIoctlDirection dir;

                switch (direction)
                {
                case ScsiDirection.In:
                    dir = ScsiIoctlDirection.In;
                    break;

                case ScsiDirection.Out:
                    dir = ScsiIoctlDirection.Out;
                    break;

                default:
                    dir = ScsiIoctlDirection.Unspecified;
                    break;
                }

                return(Windows.Command.SendScsiCommand((SafeFileHandle)fd, cdb, ref buffer, out senseBuffer,
                                                       timeout, dir, out duration, out sense));
            }

            case PlatformID.Linux:
            {
                Linux.ScsiIoctlDirection dir;

                switch (direction)
                {
                case ScsiDirection.In:
                    dir = Linux.ScsiIoctlDirection.In;
                    break;

                case ScsiDirection.Out:
                    dir = Linux.ScsiIoctlDirection.Out;
                    break;

                case ScsiDirection.Bidirectional:
                    dir = Linux.ScsiIoctlDirection.Unspecified;
                    break;

                case ScsiDirection.None:
                    dir = Linux.ScsiIoctlDirection.None;
                    break;

                default:
                    dir = Linux.ScsiIoctlDirection.Unknown;
                    break;
                }

                return(Linux.Command.SendScsiCommand((int)fd, cdb, ref buffer, out senseBuffer, timeout, dir,
                                                     out duration, out sense));
            }

            case PlatformID.FreeBSD:
            {
                CcbFlags flags = 0;

                switch (direction)
                {
                case ScsiDirection.In:
                    flags = CcbFlags.CamDirIn;
                    break;

                case ScsiDirection.Out:
                    flags = CcbFlags.CamDirOut;
                    break;

                case ScsiDirection.Bidirectional:
                    flags = CcbFlags.CamDirBoth;
                    break;

                case ScsiDirection.None:
                    flags = CcbFlags.CamDirNone;
                    break;
                }

                return(IntPtr.Size == 8
                        ? FreeBSD.Command.SendScsiCommand64((IntPtr)fd, cdb, ref buffer, out senseBuffer,
                                                            timeout, flags, out duration, out sense)
                        : FreeBSD.Command.SendScsiCommand((IntPtr)fd, cdb, ref buffer, out senseBuffer, timeout,
                                                          flags, out duration, out sense));
            }

            default: throw new InvalidOperationException($"Platform {ptId} not yet supported.");
            }
        }
        protected void OnBtnSaveClicked(object sender, EventArgs e)
        {
            SaveFileDialog dlgSave = new SaveFileDialog {
                CheckFileExists = true
            };

            dlgSave.Filters.Add(new FileFilter {
                Extensions = new[] { "log" }, Name = "Log files"
            });
            DialogResult result = dlgSave.ShowDialog(this);

            if (result != DialogResult.Ok)
            {
                return;
            }

            try
            {
                FileStream   logFs = new FileStream(dlgSave.FileName, FileMode.Create, FileAccess.ReadWrite);
                StreamWriter logSw = new StreamWriter(logFs);

                logSw.WriteLine("Log saved at {0}", DateTime.Now);

                PlatformID platId  = DetectOS.GetRealPlatformID();
                string     platVer = DetectOS.GetVersion();
                AssemblyInformationalVersionAttribute assemblyVersion =
                    Attribute.GetCustomAttribute(typeof(DicConsole).Assembly,
                                                 typeof(AssemblyInformationalVersionAttribute)) as
                    AssemblyInformationalVersionAttribute;

                logSw.WriteLine("################# System information #################");
                logSw.WriteLine("{0} {1} ({2}-bit)", DetectOS.GetPlatformName(platId, platVer), platVer,
                                Environment.Is64BitOperatingSystem ? 64 : 32);
                if (DetectOS.IsMono)
                {
                    logSw.WriteLine("Mono {0}", Version.GetMonoVersion());
                }
                else if (DetectOS.IsNetCore)
                {
                    logSw.WriteLine(".NET Core {0}", Version.GetNetCoreVersion());
                }
                else
                {
                    logSw.WriteLine(RuntimeInformation.FrameworkDescription);
                }

                logSw.WriteLine();

                logSw.WriteLine("################# Program information ################");
                logSw.WriteLine("DiscImageChef {0}", assemblyVersion?.InformationalVersion);
                logSw.WriteLine("Running in {0}-bit", Environment.Is64BitProcess ? 64 : 32);
                logSw.WriteLine("Running GUI mode using {0}", Application.Instance.Platform.ID);
                #if DEBUG
                logSw.WriteLine("DEBUG version");
                #endif
                logSw.WriteLine("Command line: {0}", Environment.CommandLine);
                logSw.WriteLine();

                logSw.WriteLine("################# Console ################");
                foreach (LogEntry entry in ConsoleHandler.Entries)
                {
                    if (entry.Type != "Info")
                    {
                        logSw.WriteLine("{0}: ({1}) {2}", entry.Timestamp, entry.Type.ToLower(), entry.Message);
                    }
                    else
                    {
                        logSw.WriteLine("{0}: {1}", entry.Timestamp, entry.Message);
                    }
                }

                logSw.Close();
                logFs.Close();
            }
            catch (Exception exception)
            {
                MessageBox.Show("Exception {0} trying to save logfile, details has been sent to console.",
                                exception.Message);
                DicConsole.ErrorWriteLine("Console", exception.Message);
                DicConsole.ErrorWriteLine("Console", exception.StackTrace);
            }
        }
Beispiel #12
0
        public static int Main(string[] args)
        {
            object[] attributes = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
            AssemblyTitle   = ((AssemblyTitleAttribute)attributes[0]).Title;
            attributes      = typeof(MainClass).Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
            AssemblyVersion =
                Attribute.GetCustomAttribute(typeof(MainClass).Assembly, typeof(AssemblyInformationalVersionAttribute))
                as AssemblyInformationalVersionAttribute;
            AssemblyCopyright = ((AssemblyCopyrightAttribute)attributes[0]).Copyright;

            DicConsole.WriteLineEvent      += System.Console.WriteLine;
            DicConsole.WriteEvent          += System.Console.Write;
            DicConsole.ErrorWriteLineEvent += System.Console.Error.WriteLine;

            Settings.Settings.LoadSettings();

            DicContext ctx = DicContext.Create(Settings.Settings.LocalDbPath);

            ctx.Database.Migrate();
            ctx.SaveChanges();

            bool masterDbUpdate = false;

            if (!File.Exists(Settings.Settings.MasterDbPath))
            {
                masterDbUpdate = true;
                UpdateCommand.DoUpdate(true);
            }

            DicContext mctx = DicContext.Create(Settings.Settings.MasterDbPath);

            mctx.Database.Migrate();
            mctx.SaveChanges();

            if ((args.Length < 1 || args[0].ToLowerInvariant() != "gui") &&
                Settings.Settings.Current.GdprCompliance < DicSettings.GdprLevel)
            {
                new ConfigureCommand(true, true).Invoke(args);
            }
            Statistics.LoadStats();
            if (Settings.Settings.Current.Stats != null && Settings.Settings.Current.Stats.ShareStats)
            {
                Task.Run(() => { Statistics.SubmitStats(); });
            }

            PlatformID currentPlatform = DetectOS.GetRealPlatformID();

            CommandSet commands = new CommandSet("DiscImageChef")
            {
                $"{AssemblyTitle} {AssemblyVersion?.InformationalVersion}",
                $"{AssemblyCopyright}",
                "",
                "usage: DiscImageChef COMMAND [OPTIONS]",
                "",
                "Global options:",
                { "verbose|v", "Shows verbose output.", b => Verbose = b != null },
                { "debug|d", "Shows debug output from plugins.", b => Debug = b != null },
                "",
                "Available commands:",
                new AnalyzeCommand(),
                new BenchmarkCommand(),
                new ChecksumCommand(),
                new CompareCommand(),
                new ConfigureCommand(false, false),
                new ConvertImageCommand(),
                new CreateSidecarCommand(),
                new DecodeCommand()
            };

            if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux ||
                currentPlatform == PlatformID.Win32NT)
            {
                commands.Add(new DeviceInfoCommand());
                commands.Add(new DeviceReportCommand());
                commands.Add(new DumpMediaCommand());
            }

            commands.Add(new EntropyCommand());
            commands.Add(new ExtractFilesCommand());
            commands.Add(new FormatsCommand());
            commands.Add(new GuiCommand());
            commands.Add(new ImageInfoCommand());

            if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux ||
                currentPlatform == PlatformID.Win32NT)
            {
                commands.Add(new ListDevicesCommand());
            }

            commands.Add(new ListEncodingsCommand());
            commands.Add(new ListNamespacesCommand());
            commands.Add(new ListOptionsCommand());
            commands.Add(new LsCommand());

            if (currentPlatform == PlatformID.FreeBSD || currentPlatform == PlatformID.Linux ||
                currentPlatform == PlatformID.Win32NT)
            {
                commands.Add(new MediaInfoCommand());
                commands.Add(new MediaScanCommand());
            }

            commands.Add(new PrintHexCommand());
            commands.Add(new StatisticsCommand());
            commands.Add(new UpdateCommand(masterDbUpdate));
            commands.Add(new VerifyCommand());

            int ret = commands.Run(args);

            Statistics.SaveStats();

            return(ret);
        }