diff --git a/DICUI.Library/Data/Constants.cs b/DICUI.Library/Data/Constants.cs index 8388ba4a..fa26fa0f 100644 --- a/DICUI.Library/Data/Constants.cs +++ b/DICUI.Library/Data/Constants.cs @@ -1,5 +1,457 @@ namespace DICUI.Data { + /// + /// Top-level commands for DiscImageChef + /// + public static class ChefCommandStrings + { + // Database Family + public const string DatabasePrefixShort = "db"; + public const string DatabasePrefixLong = "database"; + public const string DatabaseStats = "stats"; + public const string DatabaseUpdate = "update"; + + // Device Family + public const string DevicePrefixShort = "dev"; + public const string DevicePrefixLong = "device"; + public const string DeviceInfo = "info"; + public const string DeviceList = "list"; + public const string DeviceReport = "report"; + + // Filesystem Family + public const string FilesystemPrefixShort = "fi"; + public const string FilesystemPrefixShortAlt = "fs"; + public const string FilesystemPrefixLong = "filesystem"; + public const string FilesystemExtract = "extract"; + public const string FilesystemListShort = "ls"; + public const string FilesystemListLong = "list"; + public const string FilesystemOptions = "options"; + + // Image Family + public const string ImagePrefixShort = "i"; + public const string ImagePrefixLong = "image"; + public const string ImageAnalyze = "analyze"; + public const string ImageChecksumShort = "chk"; + public const string ImageChecksumLong = "checksum"; + public const string ImageCompareShort = "cmp"; + public const string ImageCompareLong = "compare"; + public const string ImageConvert = "convert"; + public const string ImageCreateSidecar = "create-sidecar"; + public const string ImageDecode = "decode"; + public const string ImageEntropy = "entropy"; + public const string ImageInfo = "info"; + public const string ImageOptions = "options"; + public const string ImagePrint = "print"; + public const string ImageVerify = "verify"; + + // Media Family + public const string MediaPrefixShort = "m"; + public const string MediaPrefixLong = "media"; + public const string MediaDump = "dump"; + public const string MediaInfo = "info"; + public const string MediaScan = "scan"; + + // Standalone Commands + public const string Configure = "configure"; + public const string Formats = "formats"; + public const string ListEncodings = "list-encodings"; + public const string ListNamespaces = "list-namespaces"; + public const string Remote = "remote"; + } + + /// + /// Supported encodings for DiscImageChef + /// + public static class ChefEncodingStrings + { + public static string ArabicMac = "x-mac-arabic"; + public static string AtariASCII = "atascii"; + public static string CentralEuropeanMac = "x-mac-ce"; + public static string CommodorePETSCII = "petscii"; + public static string CroatianMac = "x-mac-croatian"; + public static string CyrillicMac = "x-mac-cryillic"; + public static string FarsiMac = "x-mac-farsi"; + public static string GreekMac = "x-mac-greek"; + public static string HebrewMac = "x-mac-hebrew"; + public static string RomanianMac = "x-mac-romanian"; + public static string SinclairZXSpectrum = "spectrum"; + public static string SinclairZX80 = "zx80"; + public static string SinclairZX81 = "zx81"; + public static string TurkishMac = "x-mac-turkish"; + public static string UkrainianMac = "x-mac-ukrainian"; + public static string Unicode = "utf-16"; + public static string UnicodeBigEndian = "utf-16BE"; + public static string UnicodeUTF32BigEndian = "utf-32BE"; + public static string UnicodeUTF32 = "utf-32"; + public static string UnicodeUTF7 = "utf-7"; + public static string UnicodeUTF8 = "utf-8"; + public static string USASCII = "us-ascii"; + public static string WesternEuropeanAppleII = "apple2"; + public static string WesternEuropeanAppleIIc = "apple2c"; + public static string WesternEuropeanAppleIIe = "apple2e"; + public static string WesternEuropeanAppleIIgs = "apple2gs"; + public static string WesternEuropeanAppleLisa = "lisa"; + public static string WesternEuropeanAtariST = "atarist"; + public static string WesternEuropeanGEM = "gem"; + public static string WesternEuropeanGEOS = "geos"; + public static string WesternEuropeanISO = "iso-8859-1"; + public static string WesternEuropeanMac = "macintosh"; + public static string WesternEuropeanRadix50 = "radix50"; + } + + /// + /// Dumping flags for DiscImageChef + /// + public static class ChefFlagStrings + { + // Boolean flags + public const string Adler32Short = "-a"; + public const string Adler32Long = "--adler32"; + public const string ClearLong = "--clear"; + public const string ClearAllLong = "--clear-all"; + public const string CRC16Long = "--crc16"; + public const string CRC32Short = "-c"; + public const string CRC32Long = "--crc32"; + public const string CRC64Long = "--crc64"; + public const string DebugShort = "-d"; + public const string DebugLong = "--debug"; + public const string DiskTagsShort = "-f"; + public const string DiskTagsLong = "--disk-tags"; + public const string DuplicatedSectorsShort = "-p"; + public const string DuplicatedSectorsLong = "--duplicated-sectors"; + public const string ExtendedAttributesShort = "-x"; + public const string ExtendedAttributesLong = "--xattrs"; + public const string FilesystemsShort = "-f"; + public const string FilesystemsLong = "--filesystems"; + public const string FirstPregapLong = "--first-pregap"; + public const string FixOffsetLong = "--fix-offset"; + public const string Fletcher16Long = "--fletcher16"; + public const string Fletcher32Long = "--fletcher32"; + public const string ForceShort = "-f"; + public const string ForceLong = "--force"; + public const string LongFormatShort = "-l"; + public const string LongFormatLong = "--long-format"; + public const string LongSectorsShort = "-r"; + public const string LongSectorsLong = "--long-sectors"; + public const string MD5Short = "-m"; + public const string MD5Long = "--md5"; + public const string MetadataLong = "--metadata"; + public const string PartitionsShort = "-p"; + public const string PartitionsLong = "--partitions"; + public const string PersistentLong = "--persistent"; + public const string ResumeShort = "-r"; + public const string ResumeLong = "--resume"; + public const string SectorTagsShort = "-p"; + public const string SectorTagsLong = "--sector-tags"; + public const string SeparatedTracksShort = "-t"; + public const string SeparatedTracksLong = "--separated-tracks"; + public const string SHA1Short = "-s"; + public const string SHA1Long = "--sha1"; + public const string SHA256Long = "--sha256"; + public const string SHA384Long = "--sha384"; + public const string SHA512Long = "--sha512"; + public const string SpamSumShort = "-f"; + public const string SpamSumLong = "--spamsum"; + public const string StopOnErrorShort = "-s"; + public const string StopOnErrorLong = "--stop-on-error"; + public const string TapeShort = "-t"; + public const string TapeLong = "--tape"; + public const string TrimLong = "--trim"; + public const string VerboseShort = "-v"; + public const string VerboseLong = "--verbose"; + public const string VerifyDiscShort = "-w"; + public const string VerifyDiscLong = "--verify-disc"; + public const string VerifySectorsShort = "-s"; + public const string VerifySectorsLong = "--verify-sectors"; + public const string WholeDiscShort = "-w"; + public const string WholeDiscLong = "--whole-disc"; + + // Int8 flags + public const string SpeedLong = "--speed"; + + // Int16 flags + public const string RetryPassesShort = "-p"; + public const string RetryPassesLong = "--retry-passes"; + public const string WidthShort = "-w"; + public const string WidthLong = "--width"; + + // Int32 flags + public const string BlockSizeShort = "-b"; + public const string BlockSizeLong = "--block-size"; + public const string CountShort = "-c"; + public const string CountLong = "--count"; + public const string MediaLastSequenceLong = "--media-lastsequence"; + public const string MediaSequenceLong = "--media-sequence"; + public const string SkipShort = "-k"; + public const string SkipLong = "--skip"; + + // Int64 flags + public const string LengthShort = "-l"; // or "all" + public const string LengthLong = "--length"; // or "all" + public const string StartShort = "-s"; + public const string StartLong = "--start"; + + // String flags + public const string CommentsLong = "--comments"; + public const string CreatorLong = "--creator"; + public const string DriveManufacturerLong = "--drive-manufacturer"; + public const string DriveModelLong = "--drive-model"; + public const string DriveRevisionLong = "--drive-revision"; + public const string DriveSerialLong = "--drive-serial"; + public const string EncodingShort = "-e"; + public const string EncodingLong = "--encoding"; + public const string FormatConvertShort = "-p"; + public const string FormatConvertLong = "--format"; + public const string FormatDumpShort = "-t"; + public const string FormatDumpLong = "--format"; + public const string ImgBurnLogShort = "-b"; + public const string ImgBurnLogLong = "--ibg-log"; + public const string MediaBarcodeLong = "--media-barcode"; + public const string MediaManufacturerLong = "--media-manufacturer"; + public const string MediaModelLong = "--media-model"; + public const string MediaPartNumberLong = "--media-partnumber"; + public const string MediaSerialLong = "--media-serial"; + public const string MediaTitleLong = "--media-title"; + public const string MHDDLogShort = "-m"; + public const string MHDDLogLong = "--mhdd-log"; + public const string NamespaceShort = "-n"; + public const string NamespaceLong = "--namespace"; + public const string OptionsShort = "-O"; + public const string OptionsLong = "--options"; + public const string OutputPrefixShort = "-w"; + public const string OutputPrefixLong = "--output-prefix"; + public const string ResumeFileShort = "-r"; + public const string ResumeFileLong = "--resume-file"; + public const string SubchannelLong = "--subchannel"; + public const string XMLSidecarShort = "-x"; + public const string XMLSidecarLong = "--cicm-xml"; + } + + /// + /// Supported formats for DiscImageChef + /// + public static class ChefFormatStrings + { + // Supported filters + public static string AppleDouble = "AppleDouble"; + public static string AppleSingle = "AppleSingle"; + public static string BZip2 = "BZip2"; + public static string GZip = "GZip"; + public static string LZip = "LZip"; + public static string MacBinary = "MacBinary"; + public static string NoFilter = "No filter"; + public static string PCExchange = "PCExchange"; + public static string XZ = "XZ"; + + // Read-only media image formats + public static string AppleDiskArchivalRetrievalTool = "Apple Disk Archival/Retrieval Tool"; + public static string AppleNewDiskImageFormat = "Apple New Disk Image Format"; + public static string AppleNIB = "Apple NIB"; + public static string BlindWrite4 = "BlindWrite 4"; + public static string BlindWrite5 = "BlindWrite 5"; + public static string CPCEMUDiskFileAndExtendedCPCDiskFile = "CPCEMU Disk-File and Extended CPC Disk-File"; + public static string D2FDiskImage = "d2f disk image"; + public static string D88DiskImage = "D88 Disk Image"; + public static string DIMDiskImage = "DIM Disk Image"; + public static string DiscFerret = "DiscFerret"; + public static string DiscJuggler = "DiscJuggler"; + public static string DreamcastGDIImage = "Dreamcast GDI image"; + public static string DunfieldsIMD = "Dunfield's IMD"; + public static string HDCopyDiskImage = "HD-Copy disk image"; + public static string KryoFluxSTREAM = "KryoFlux STREAM"; + public static string MAMECompressedHunksOfData = "MAME Compressed Hunks of Data"; + public static string MicrosoftVHDX = "Microsoft VHDX"; + public static string NeroBurningROMImage = "Nero Burning ROM image"; + public static string PartCloneDiskImage = "PartClone disk image"; + public static string PartimageDiskImage = "Partimage disk image"; + public static string SpectrumFloppyDiskImage = "Spectrum Floppy Disk Image"; + public static string SuperCardPro = "SuperCardPro"; + public static string SydexCopyQM = "Sydex CopyQM"; + public static string SydexTeleDisk = "Sydex TeleDisk"; + + // Read/write media image formats + public static string ACTApricotDiskImage = "ACT Apricot Disk Image"; + public static string Alcohol120MediaDescriptorStructure = "Alcohol 120% Media Descriptor Structure"; + public static string Anex86DiskImage = "Anex86 Disk Image"; + public static string Apple2InterleavedDiskImage = "Apple ][Interleaved Disk Image"; + public static string Apple2IMG = "Apple 2IMG"; + public static string AppleDiskCopy42 = "Apple DiskCopy 4.2"; + public static string AppleUniversalDiskImageFormat = "Apple Universal Disk Image Format"; + public static string BasicLisaUtility = "Basic Lisa Utility"; + public static string CDRDAOTocfile = "CDRDAO tocfile"; + public static string CDRWinCuesheet = "CDRWin cuesheet"; + public static string CisCopyDiskImageDCFile = "CisCopy Disk Image(DC-File)"; + public static string CloneCD = "CloneCD"; + public static string CopyTape = "CopyTape"; + public static string DigitalResearchDiskCopy = "Digital Research DiskCopy"; + public static string DiscImageChefFormat = "DiscImageChef format"; + public static string IBMSaveDskF = "IBM SaveDskF"; + public static string MAXIDiskImage = "MAXI Disk image"; + public static string ParallelsDiskImage = "Parallels disk image"; + public static string QEMUCopyOnWriteDiskImage = "QEMU Copy-On-Write disk image"; + public static string QEMUCopyOnWriteDiskImageV2 = "QEMU Copy-On-Write disk image v2"; + public static string QEMUEnhancedDiskImage = "QEMU Enhanced Disk image"; + public static string RawDiskImage = "Raw Disk Image"; + public static string RayAracheliansDiskIMage = "Ray Arachelian's Disk IMage"; + public static string RSIDEHardDiskImage = "RS-IDE Hard Disk Image"; + public static string T98HardDiskImage = "T98 Hard Disk Image"; + public static string T98NextNHDr0DiskImage = "T98-Next NHD r0 Disk Image"; + public static string Virtual98DiskImage = "Virtual98 Disk Image"; + public static string VirtualBoxDiskImage = "VirtualBox Disk Image"; + public static string VirtualPC = "VirtualPC"; + public static string VMwareDiskImage = "VMware disk image"; + + // Supported filesystems for identification and information only + public static string AcornAdvancedDiscFilingSystem = "Acorn Advanced Disc Filing System"; + public static string AlexanderOsipovDOSFileSystem = "Alexander Osipov DOS file system"; + public static string AmigaDOSFilesystem = "Amiga DOS filesystem"; + public static string AppleFileSystem = "Apple File System"; + public static string AppleHFSPlusFilesystem = "Apple HFS+ filesystem"; + public static string AppleHierarchicalFileSystem = "Apple Hierarchical File System"; + public static string AppleProDOSFilesystem = "Apple ProDOS filesystem"; + public static string AtheOSFilesystem = "AtheOS Filesystem"; + public static string BeFilesystem = "Be Filesystem"; + public static string BSDFastFileSystem = "BSD Fast File System(aka UNIX File System, UFS)"; + public static string BTreeFileSystem = "B-tree file system"; + public static string CommodoreFileSystem = "Commodore file system"; + public static string CramFilesystem = "Cram filesystem"; + public static string DumpEightPlugin = "dump(8) Plugin"; + public static string ECMA67 = "ECMA-67"; + public static string ExtentFileSystemPlugin = "Extent File System Plugin"; + public static string F2FSPlugin = "F2FS Plugin"; + public static string Files11OnDiskStructure = "Files-11 On-Disk Structure"; + public static string FossilFilesystemPlugin = "Fossil Filesystem Plugin"; + public static string HAMMERFilesystem = "HAMMER Filesystem"; + public static string HighPerformanceOpticalFileSystem = "High Performance Optical File System"; + public static string HPLogicalInterchangeFormatPlugin = "HP Logical Interchange Format Plugin"; + public static string JFSPlugin = "JFS Plugin"; + public static string LinuxExtendedFilesystem = "Linux extended Filesystem"; + public static string LinuxExtendedFilesystem234 = "Linux extended Filesystem 2, 3 and 4"; + public static string LocusFilesystemPlugin = "Locus Filesystem Plugin"; + public static string MicroDOSFileSystem = "MicroDOS file system"; + public static string MicrosoftExtendedFileAllocationTable = "Microsoft Extended File Allocation Table"; + public static string MinixFilesystem = "Minix Filesystem"; + public static string NewTechnologyFileSystem = "New Technology File System(NTFS)"; + public static string NILFS2Plugin = "NILFS2 Plugin"; + public static string NintendoOpticalFilesystems = "Nintendo optical filesystems"; + public static string OS2HighPerformanceFileSystem = "OS/2 High Performance File System"; + public static string OS9RandomBlockFilePlugin = "OS-9 Random Block File Plugin"; + public static string PCEngineCDPlugin = "PC Engine CD Plugin"; + public static string PCFXPlugin = "PC-FX Plugin"; + public static string ProfessionalFileSystem = "Professional File System"; + public static string QNX4Plugin = "QNX4 Plugin"; + public static string QNX6Plugin = "QNX6 Plugin"; + public static string ReiserFilesystemPlugin = "Reiser Filesystem Plugin"; + public static string Reiser4FilesystemPlugin = "Reiser4 Filesystem Plugin"; + public static string ResilientFileSystemPlugin = "Resilient File System plugin"; + public static string RT11FileSystem = "RT-11 file system"; + public static string SmartFileSystem = "SmartFileSystem"; + public static string SolarOSFilesystem = "Solar_OS filesystem"; + public static string SquashFilesystem = "Squash filesystem"; + public static string UNICOSFilesystemPlugin = "UNICOS Filesystem Plugin"; + public static string UniversalDiskFormat = "Universal Disk Format"; + public static string UNIXBootFilesystem = "UNIX Boot filesystem"; + public static string UNIXSystemVFilesystem = "UNIX System V filesystem"; + public static string VeritasFilesystem = "Veritas filesystem"; + public static string VMwareFilesystem = "VMware filesystem"; + public static string XFSFilesystemPlugin = "XFS Filesystem Plugin"; + public static string XiaFilesystem = "Xia filesystem"; + public static string ZFSFilesystemPlugin = "ZFS Filesystem Plugin"; + + // Supported filesystems that can read their contents + public static string AppleDOSFileSystem = "Apple DOS File System"; + public static string AppleLisaFileSystem = "Apple Lisa File System"; + public static string AppleMacintoshFileSystem = "Apple Macintosh File System"; + public static string CPMFileSystem = "CP/M File System"; + public static string FATXFilesystemPlugin = "FATX Filesystem Plugin"; + public static string ISO9660Filesystem = "ISO9660 Filesystem"; + public static string MicrosoftFileAllocationTable = "Microsoft File Allocation Table"; + public static string OperaFilesystemPlugin = "Opera Filesystem Plugin"; + public static string UCSDPascalFilesystem = "U.C.S.D.Pascal filesystem"; + + // Supported partitioning schemes + public static string AcornFileCorePartitions = "Acorn FileCore partitions"; + public static string ACTApricotPartitions = "ACT Apricot partitions"; + public static string AmigaRigidDiskBlock = "Amiga Rigid Disk Block"; + public static string ApplePartitionMap = "Apple Partition Map"; + public static string AtariPartitions = "Atari partitions"; + public static string BSDDisklabel = "BSD disklabel"; + public static string DECDisklabel = "DEC disklabel"; + public static string DragonFlyBSD64bitDisklabel = "DragonFly BSD 64-bit disklabel"; + public static string GUIDPartitionTable = "GUID Partition Table"; + public static string Human68kPartitions = "Human 68k partitions"; + public static string MasterBootRecord = "Master Boot Record"; + public static string NECPC9800PartitionTable = "NEC PC-9800 partition table"; + public static string NeXTDisklabel = "NeXT Disklabel"; + public static string Plan9PartitionTable = "Plan9 partition table"; + public static string RioKarmaPartitioning = "Rio Karma partitioning"; + public static string SGIDiskVolumeHeader = "SGI Disk Volume Header"; + public static string SunDisklabel = "Sun Disklabel"; + public static string UNIXHardwired = "UNIX hardwired"; + public static string UNIXVTOC = "UNIX VTOC"; + public static string XboxPartitioning = "Xbox partitioning"; + public static string XENIX = "XENIX"; + } + + /// + /// Supported namespaces for DiscImageChef + /// + public static class ChefNamespaceStrings + { + // Namespaces for Apple Lisa File System + public static string LisaOfficeSystem = "office"; + public static string LisaPascalWorkshop = "workshop"; + + // Namespaces for ISO9660 Filesystem + public static string JolietVolumeDescriptor = "joliet"; + public static string PrimaryVolumeDescriptor = "normal"; + public static string PrimaryVolumeDescriptorwithEncoding = "romeo"; + public static string RockRidge = "rrip"; + public static string PrimaryVolumeDescriptorVersionSuffix = "vms"; + + // Namespaces for Microsoft File Allocation Table + public static string DOS = "dos"; + public static string LFNWhenAvailable = "ecs"; + public static string LongFileNames = "lfn"; + public static string WindowsNT = "nt"; + public static string OS2Extended = "os2"; + } + + /// + /// Supported options for DiscImageChef + /// + public static class ChefOptionStrings + { + // ACT Apricot Disk Image + public static string ACTApricotDiskImageCompress = "compress"; // boolean, default false + + // Apple DiskCopy 4.2 + public static string AppleDiskCopyMacOSX = "macosx"; // boolean, default false + + // CDRDAO tocfile + public static string CDRDAOTocfileSeparate = "separate"; // boolean, default false + + // CDRWin cuesheet + public static string CDRWinCuesheetSeparate = "separate"; // boolean, default false + + // DiscImageChef format + public static string DiscImageChefDeduplicate = "deduplicate"; // boolean, default true + public static string DiscImageChefDictionary = "dictionary"; // number, default 33554432 + public static string DiscImageChefMaxDDTSize = "max_ddt_size"; // number, default 256 + public static string DiscImageChefMD5 = "md5"; // boolean, default false + public static string DiscImageChefNoCompress = "nocompress"; // boolean, default false + public static string DiscImageChefSectorsPerBlock = "sectors_per_block"; // number, default 4096 + public static string DiscImageChefSHA1 = "sha1"; // boolean, default false + public static string DiscImageChefSHA256 = "sha256"; // boolean, default false + public static string DiscImageChefSpamSum = "spamsum"; // boolean, default false + + // VMware disk image + public static string VMwareDiskImageAdapterType = "adapter_type"; // string, default ide + public static string VMwareDiskImageHWVersion = "hwversion"; // number, default 4 + public static string VMwareDiskImageSparse = "sparse"; // boolean, default false + public static string VMwareDiskImageSplit = "split"; // boolean, default false + } + /// /// Top-level commands for DiscImageCreator /// @@ -44,7 +496,6 @@ public const string D8Opcode = "/d8"; public const string DisableBeep = "/q"; public const string ForceUnitAccess = "/f"; - public const string MCN = "/m"; public const string MultiSession = "/ms"; public const string NoFixSubP = "/np"; public const string NoFixSubQ = "/nq"; diff --git a/DICUI.Library/Data/Enumerations.cs b/DICUI.Library/Data/Enumerations.cs index 6e3f3508..6c6137ff 100644 --- a/DICUI.Library/Data/Enumerations.cs +++ b/DICUI.Library/Data/Enumerations.cs @@ -18,6 +18,143 @@ AddOns = 11, } + /// + /// Supported DiscImageChef commands + /// + public enum ChefCommand + { + NONE = 0, + + // Database Family + DatabaseStats, + DatabaseUpdate, + + // Device Family + DeviceInfo, + DeviceList, + DeviceReport, + + // Filesystem Family + FilesystemExtract, + FilesystemList, + FilesystemOptions, + + // Image Family + ImageAnalyze, + ImageChecksum, + ImageCompare, + ImageConvert, + ImageCreateSidecar, + ImageDecode, + ImageEntropy, + ImageInfo, + ImageOptions, + ImagePrint, + ImageVerify, + + // Media Family + MediaDump, + MediaInfo, + MediaScan, + + // Standalone Commands + Configure, + Formats, + ListEncodings, + ListNamespaces, + Remote, + } + + /// + /// Supported DiscImageChef flags + /// + public enum ChefFlag + { + NONE = 0, + + // Boolean flags + Adler32, + Clear, + ClearAll, + CRC16, + CRC32, + CRC64, + Debug, + DiskTags, + DuplicatedSectors, + ExtendedAttributes, + Filesystems, + FirstPregap, + FixOffset, + Fletcher16, + Fletcher32, + Force, + LongFormat, + LongSectors, + MD5, + Metadata, + Partitions, + Persistent, + Resume, + SectorTags, + SeparatedTracks, + SHA1, + SHA256, + SHA384, + SHA512, + SpamSum, + StopOnError, + Tape, + Trim, + Verbose, + VerifyDisc, + VerifySectors, + WholeDisc, + + // Int8 flags + Speed, + + // Int16 flags + RetryPasses, + Width, + + // Int32 flags + BlockSize, + Count, + MediaLastSequence, + MediaSequence, + Skip, + + // Int64 flags + Length, + Start, + + // String flags + Comments, + Creator, + DriveManufacturer, + DriveModel, + DriveRevision, + DriveSerial, + Encoding, + FormatConvert, + FormatDump, + ImgBurnLog, + MediaBarcode, + MediaManufacturer, + MediaModel, + MediaPartNumber, + MediaSerial, + MediaTitle, + MHDDLog, + Namespace, + Options, + OutputPrefix, + ResumeFile, + Subchannel, + XMLSidecar, + } + /// /// Supported DiscImageCreator commands /// @@ -64,7 +201,6 @@ D8Opcode, DisableBeep, ForceUnitAccess, - MCN, MultiSession, NoFixSubP, NoFixSubQ, diff --git a/DICUI.Library/Utilities/ChefParameters.cs b/DICUI.Library/Utilities/ChefParameters.cs new file mode 100644 index 00000000..be3d3885 --- /dev/null +++ b/DICUI.Library/Utilities/ChefParameters.cs @@ -0,0 +1,1970 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using DICUI.Data; + +namespace DICUI.Utilities +{ + /// + /// Represents a generic set of DiscImageChef parameters + /// + public class ChefParameters + { + /// + /// Base DiscImageChef command to run + /// + public ChefCommand Command { get; set; } + + /// + /// Set of flags to pass to DiscImageCreator + /// + private Dictionary _flags = new Dictionary(); + public bool? this[ChefFlag key] + { + get + { + if (_flags.ContainsKey(key)) + return _flags[key]; + + return null; + } + set + { + _flags[key] = value; + } + } + internal IEnumerable Keys => _flags.Keys; + + #region DiscImageChef Flag Values + + public int? BlockSizeValue { get; set; } + + public string CommentsValue { get; set; } + + public string CreatorValue { get; set; } + + public int? CountValue { get; set; } + + public string DriveManufacturerValue { get; set; } + + public string DriveModelValue { get; set; } + + public string DriveRevisionValue { get; set; } + + public string DriveSerialValue { get; set; } + + public string EncodingValue { get; set; } + + public string FormatConvertValue { get; set; } + + public string FormatDumpValue { get; set; } + + public string ImgBurnLogValue { get; set; } + + public string InputValue { get; set; } + + public string Input1Value { get; set; } + + public string Input2Value { get; set; } + + public long? LengthValue { get; set; } + + public string MediaBarcodeValue { get; set; } + + public int? MediaLastSequenceValue { get; set; } + + public string MediaManufacturerValue { get; set; } + + public string MediaModelValue { get; set; } + + public string MediaPartNumberValue { get; set; } + + public int? MediaSequenceValue { get; set; } + + public string MediaSerialValue { get; set; } + + public string MediaTitleValue { get; set; } + + public string MHDDLogValue { get; set; } + + public string NamespaceValue { get; set; } + + public string OptionsValue { get; set; } + + public string OutputValue { get; set; } + + public string OutputPrefixValue { get; set; } + + public string RemoteHostValue { get; set; } + + public string ResumeFileValue { get; set; } + + public short? RetryPassesValue { get; set; } + + public int? SkipValue { get; set; } + + public sbyte? SpeedValue { get; set; } + + public long? StartValue { get; set; } + + public string SubchannelValue { get; set; } + + public short? WidthValue { get; set; } + + public string XMLSidecarValue { get; set; } + + #endregion + + /// + /// Populate a ChefParameters object from a param string + /// + /// String possibly representing a set of parameters + public ChefParameters(string parameters) + { + // If any parameters are not valid, wipe out everything + if (!ValidateAndSetParameters(parameters)) + { + Command = ChefCommand.NONE; + + _flags = new Dictionary(); + + BlockSizeValue = null; + CommentsValue = null; + CreatorValue = null; + CountValue = null; + DriveManufacturerValue = null; + DriveModelValue = null; + DriveRevisionValue = null; + DriveSerialValue = null; + EncodingValue = null; + FormatConvertValue = null; + FormatDumpValue = null; + ImgBurnLogValue = null; + InputValue = null; + Input1Value = null; + Input2Value = null; + LengthValue = null; + MediaBarcodeValue = null; + MediaLastSequenceValue = null; + MediaManufacturerValue = null; + MediaModelValue = null; + MediaPartNumberValue = null; + MediaSequenceValue = null; + MediaSerialValue = null; + MediaTitleValue = null; + MHDDLogValue = null; + NamespaceValue = null; + OptionsValue = null; + OutputValue = null; + OutputPrefixValue = null; + RemoteHostValue = null; + ResumeFileValue = null; + RetryPassesValue = null; + SkipValue = null; + SpeedValue = null; + StartValue = null; + SubchannelValue = null; + WidthValue = null; + XMLSidecarValue = null; + } + } + + /// + /// Generate parameters based on a set of known inputs + /// + /// KnownSystem value to use + /// MediaType value to use + /// Drive letter to use + /// Filename to use + /// Drive speed to use + /// Enable paranoid mode (safer dumping) + /// User-defined retry passes count + public ChefParameters(KnownSystem? system, MediaType? type, char driveLetter, string filename, int? driveSpeed, bool paranoid, int retryPassesCount) + { + Command = ChefCommand.MediaDump; + + InputValue = $"\\\\?\\{driveLetter.ToString()}:"; + OutputValue = filename; + + this[ChefFlag.Force] = true; + + if (driveSpeed != null) + { + this[ChefFlag.Speed] = true; + SpeedValue = (sbyte?)driveSpeed; + } + + SetDefaultParameters(system, type, paranoid, retryPassesCount); + } + + /// + /// Blindly generate a parameter string based on the inputs + /// + /// Correctly formatted parameter string, null on error + public string GenerateParameters() + { + List parameters = new List(); + + if (Command != ChefCommand.NONE) + parameters.Add(Command.LongName()); + else + return null; + + #region Boolean flags + + // Adler-32 + if (GetSupportedCommands(ChefFlag.Adler32).Contains(Command)) + { + if (this[ChefFlag.Adler32] != null) + parameters.Add($"{ChefFlag.Adler32.LongName()} {this[ChefFlag.Adler32]}"); + } + + // Clear + if (GetSupportedCommands(ChefFlag.Clear).Contains(Command)) + { + if (this[ChefFlag.Clear] != null) + parameters.Add($"{ChefFlag.Clear.LongName()} {this[ChefFlag.Clear]}"); + } + + // Clear All + if (GetSupportedCommands(ChefFlag.ClearAll).Contains(Command)) + { + if (this[ChefFlag.ClearAll] != null) + parameters.Add($"{ChefFlag.ClearAll.LongName()} {this[ChefFlag.ClearAll]}"); + } + + // CRC16 + if (GetSupportedCommands(ChefFlag.CRC16).Contains(Command)) + { + if (this[ChefFlag.CRC16] != null) + parameters.Add($"{ChefFlag.CRC16.LongName()} {this[ChefFlag.CRC16]}"); + } + + // CRC32 + if (GetSupportedCommands(ChefFlag.CRC32).Contains(Command)) + { + if (this[ChefFlag.CRC32] != null) + parameters.Add($"{ChefFlag.CRC32.LongName()} {this[ChefFlag.CRC32]}"); + } + + // CRC64 + if (GetSupportedCommands(ChefFlag.CRC64).Contains(Command)) + { + if (this[ChefFlag.CRC64] != null) + parameters.Add($"{ChefFlag.CRC64.LongName()} {this[ChefFlag.CRC64]}"); + } + + // Debug + if (GetSupportedCommands(ChefFlag.Debug).Contains(Command)) + { + if (this[ChefFlag.Debug] != null) + parameters.Add($"{ChefFlag.Debug.LongName()} {this[ChefFlag.Debug]}"); + } + + // Disk Tags + if (GetSupportedCommands(ChefFlag.DiskTags).Contains(Command)) + { + if (this[ChefFlag.DiskTags] != null) + parameters.Add($"{ChefFlag.DiskTags.LongName()} {this[ChefFlag.DiskTags]}"); + } + + // Duplicated Sectors + if (GetSupportedCommands(ChefFlag.DuplicatedSectors).Contains(Command)) + { + if (this[ChefFlag.DuplicatedSectors] != null) + parameters.Add($"{ChefFlag.DuplicatedSectors.LongName()} {this[ChefFlag.DuplicatedSectors]}"); + } + + // Extended Attributes + if (GetSupportedCommands(ChefFlag.ExtendedAttributes).Contains(Command)) + { + if (this[ChefFlag.ExtendedAttributes] != null) + parameters.Add($"{ChefFlag.ExtendedAttributes.LongName()} {this[ChefFlag.ExtendedAttributes]}"); + } + + // Filesystems + if (GetSupportedCommands(ChefFlag.Filesystems).Contains(Command)) + { + if (this[ChefFlag.Filesystems] != null) + parameters.Add($"{ChefFlag.Filesystems.LongName()} {this[ChefFlag.Filesystems]}"); + } + + // First Pregap + if (GetSupportedCommands(ChefFlag.FirstPregap).Contains(Command)) + { + if (this[ChefFlag.FirstPregap] != null) + parameters.Add($"{ChefFlag.FirstPregap.LongName()} {this[ChefFlag.FirstPregap]}"); + } + + // Fix Offset + if (GetSupportedCommands(ChefFlag.FixOffset).Contains(Command)) + { + if (this[ChefFlag.FixOffset] != null) + parameters.Add($"{ChefFlag.FixOffset.LongName()} {this[ChefFlag.FixOffset]}"); + } + + // Fletcher-16 + if (GetSupportedCommands(ChefFlag.Fletcher16).Contains(Command)) + { + if (this[ChefFlag.Fletcher16] != null) + parameters.Add($"{ChefFlag.Fletcher16.LongName()} {this[ChefFlag.Fletcher16]}"); + } + + // Fletcher-32 + if (GetSupportedCommands(ChefFlag.Fletcher32).Contains(Command)) + { + if (this[ChefFlag.Fletcher32] != null) + parameters.Add($"{ChefFlag.Fletcher32.LongName()} {this[ChefFlag.Fletcher32]}"); + } + + // Force + if (GetSupportedCommands(ChefFlag.Force).Contains(Command)) + { + if (this[ChefFlag.Force] != null) + parameters.Add($"{ChefFlag.Force.LongName()} {this[ChefFlag.Force]}"); + } + + // Long Format + if (GetSupportedCommands(ChefFlag.LongFormat).Contains(Command)) + { + if (this[ChefFlag.LongFormat] != null) + parameters.Add($"{ChefFlag.LongFormat.LongName()} {this[ChefFlag.LongFormat]}"); + } + + // Long Sectors + if (GetSupportedCommands(ChefFlag.LongSectors).Contains(Command)) + { + if (this[ChefFlag.LongSectors] != null) + parameters.Add($"{ChefFlag.LongSectors.LongName()} {this[ChefFlag.LongSectors]}"); + } + + // MD5 + if (GetSupportedCommands(ChefFlag.MD5).Contains(Command)) + { + if (this[ChefFlag.MD5] != null) + parameters.Add($"{ChefFlag.MD5.LongName()} {this[ChefFlag.MD5]}"); + } + + // Metadata + if (GetSupportedCommands(ChefFlag.Metadata).Contains(Command)) + { + if (this[ChefFlag.Metadata] != null) + parameters.Add($"{ChefFlag.Metadata.LongName()} {this[ChefFlag.Metadata]}"); + } + + // Partitions + if (GetSupportedCommands(ChefFlag.Partitions).Contains(Command)) + { + if (this[ChefFlag.Partitions] != null) + parameters.Add($"{ChefFlag.Partitions.LongName()} {this[ChefFlag.Partitions]}"); + } + + // Persistent + if (GetSupportedCommands(ChefFlag.Persistent).Contains(Command)) + { + if (this[ChefFlag.Persistent] != null) + parameters.Add($"{ChefFlag.Persistent.LongName()} {this[ChefFlag.Persistent]}"); + } + + // Resume + if (GetSupportedCommands(ChefFlag.Resume).Contains(Command)) + { + if (this[ChefFlag.Resume] != null) + parameters.Add($"{ChefFlag.Resume.LongName()} {this[ChefFlag.Resume]}"); + } + + // Sector Tags + if (GetSupportedCommands(ChefFlag.SectorTags).Contains(Command)) + { + if (this[ChefFlag.SectorTags] != null) + parameters.Add($"{ChefFlag.SectorTags.LongName()} {this[ChefFlag.SectorTags]}"); + } + + // Separated Tracks + if (GetSupportedCommands(ChefFlag.SeparatedTracks).Contains(Command)) + { + if (this[ChefFlag.SeparatedTracks] != null) + parameters.Add($"{ChefFlag.SeparatedTracks.LongName()} {this[ChefFlag.SeparatedTracks]}"); + } + + // SHA-1 + if (GetSupportedCommands(ChefFlag.SHA1).Contains(Command)) + { + if (this[ChefFlag.SHA1] != null) + parameters.Add($"{ChefFlag.SHA1.LongName()} {this[ChefFlag.SHA1]}"); + } + + // SHA-256 + if (GetSupportedCommands(ChefFlag.SHA256).Contains(Command)) + { + if (this[ChefFlag.SHA256] != null) + parameters.Add($"{ChefFlag.SHA256.LongName()} {this[ChefFlag.SHA256]}"); + } + + // SHA-384 + if (GetSupportedCommands(ChefFlag.SHA384).Contains(Command)) + { + if (this[ChefFlag.SHA384] != null) + parameters.Add($"{ChefFlag.SHA384.LongName()} {this[ChefFlag.SHA384]}"); + } + + // SHA-512 + if (GetSupportedCommands(ChefFlag.SHA512).Contains(Command)) + { + if (this[ChefFlag.SHA512] != null) + parameters.Add($"{ChefFlag.SHA512.LongName()} {this[ChefFlag.SHA512]}"); + } + + // SpamSum + if (GetSupportedCommands(ChefFlag.SpamSum).Contains(Command)) + { + if (this[ChefFlag.SpamSum] != null) + parameters.Add($"{ChefFlag.SpamSum.LongName()} {this[ChefFlag.SpamSum]}"); + } + + // Stop on Error + if (GetSupportedCommands(ChefFlag.StopOnError).Contains(Command)) + { + if (this[ChefFlag.StopOnError] != null) + parameters.Add($"{ChefFlag.StopOnError.LongName()} {this[ChefFlag.StopOnError]}"); + } + + // Tape + if (GetSupportedCommands(ChefFlag.Tape).Contains(Command)) + { + if (this[ChefFlag.Tape] != null) + parameters.Add($"{ChefFlag.Tape.LongName()} {this[ChefFlag.Tape]}"); + } + + // Trim + if (GetSupportedCommands(ChefFlag.Trim).Contains(Command)) + { + if (this[ChefFlag.Trim] != null) + parameters.Add($"{ChefFlag.Trim.LongName()} {this[ChefFlag.Trim]}"); + } + + // Verbose + if (GetSupportedCommands(ChefFlag.Verbose).Contains(Command)) + { + if (this[ChefFlag.Verbose] != null) + parameters.Add($"{ChefFlag.Verbose.LongName()} {this[ChefFlag.Verbose]}"); + } + + // Verify Disc + if (GetSupportedCommands(ChefFlag.VerifyDisc).Contains(Command)) + { + if (this[ChefFlag.VerifyDisc] != null) + parameters.Add($"{ChefFlag.VerifyDisc.LongName()} {this[ChefFlag.VerifyDisc]}"); + } + + // Verify Sectors + if (GetSupportedCommands(ChefFlag.VerifySectors).Contains(Command)) + { + if (this[ChefFlag.VerifySectors] != null) + parameters.Add($"{ChefFlag.VerifySectors.LongName()} {this[ChefFlag.VerifySectors]}"); + } + + // Whole Disc + if (GetSupportedCommands(ChefFlag.WholeDisc).Contains(Command)) + { + if (this[ChefFlag.WholeDisc] != null) + parameters.Add($"{ChefFlag.WholeDisc.LongName()} {this[ChefFlag.WholeDisc]}"); + } + + #endregion + + #region Int8 flags + + // Speed + if (GetSupportedCommands(ChefFlag.Speed).Contains(Command)) + { + if (this[ChefFlag.Speed] == true && SpeedValue != null) + parameters.Add($"{ChefFlag.Speed.LongName()} {SpeedValue}"); + } + + #endregion + + #region Int16 flags + + // Retry Passes + if (GetSupportedCommands(ChefFlag.RetryPasses).Contains(Command)) + { + if (this[ChefFlag.RetryPasses] == true && RetryPassesValue != null) + parameters.Add($"{ChefFlag.RetryPasses.LongName()} {RetryPassesValue}"); + } + + // Width + if (GetSupportedCommands(ChefFlag.Width).Contains(Command)) + { + if (this[ChefFlag.Width] == true && WidthValue != null) + parameters.Add($"{ChefFlag.Width.LongName()} {WidthValue}"); + } + + #endregion + + #region Int32 flags + + // Block Size + if (GetSupportedCommands(ChefFlag.BlockSize).Contains(Command)) + { + if (this[ChefFlag.BlockSize] == true && BlockSizeValue != null) + parameters.Add($"{ChefFlag.BlockSize.LongName()} {BlockSizeValue}"); + } + + // Count + if (GetSupportedCommands(ChefFlag.Count).Contains(Command)) + { + if (this[ChefFlag.Count] == true && CountValue != null) + parameters.Add($"{ChefFlag.Count.LongName()} {CountValue}"); + } + + // Media Last Sequence + if (GetSupportedCommands(ChefFlag.MediaLastSequence).Contains(Command)) + { + if (this[ChefFlag.MediaLastSequence] == true && MediaLastSequenceValue != null) + parameters.Add($"{ChefFlag.MediaLastSequence.LongName()} {MediaLastSequenceValue}"); + } + + // Media Sequence + if (GetSupportedCommands(ChefFlag.MediaSequence).Contains(Command)) + { + if (this[ChefFlag.MediaSequence] == true && MediaSequenceValue != null) + parameters.Add($"{ChefFlag.MediaSequence.LongName()} {MediaSequenceValue}"); + } + + // Skip + if (GetSupportedCommands(ChefFlag.Skip).Contains(Command)) + { + if (this[ChefFlag.Skip] == true && SkipValue != null) + parameters.Add($"{ChefFlag.Skip.LongName()} {SkipValue}"); + } + + #endregion + + #region Int64 flags + + // Length -- TODO: Support "all" case + if (GetSupportedCommands(ChefFlag.Length).Contains(Command)) + { + if (this[ChefFlag.Length] == true && LengthValue != null) + parameters.Add($"{ChefFlag.Length.LongName()} {LengthValue}"); + } + + // Start + if (GetSupportedCommands(ChefFlag.Start).Contains(Command)) + { + if (this[ChefFlag.Start] == true && StartValue != null) + parameters.Add($"{ChefFlag.Start.LongName()} {StartValue}"); + } + + #endregion + + #region String flags + + // Comments + if (GetSupportedCommands(ChefFlag.Comments).Contains(Command)) + { + if (this[ChefFlag.Comments] == true && CommentsValue != null) + parameters.Add($"{ChefFlag.Comments.LongName()} \"{CommentsValue}\""); + } + + // Creator + if (GetSupportedCommands(ChefFlag.Creator).Contains(Command)) + { + if (this[ChefFlag.Creator] == true && CreatorValue != null) + parameters.Add($"{ChefFlag.Creator.LongName()} \"{CreatorValue}\""); + } + + // Drive Manufacturer + if (GetSupportedCommands(ChefFlag.DriveManufacturer).Contains(Command)) + { + if (this[ChefFlag.DriveManufacturer] == true && DriveManufacturerValue != null) + parameters.Add($"{ChefFlag.DriveManufacturer.LongName()} \"{DriveManufacturerValue}\""); + } + + // Drive Model + if (GetSupportedCommands(ChefFlag.DriveModel).Contains(Command)) + { + if (this[ChefFlag.DriveModel] == true && DriveModelValue != null) + parameters.Add($"{ChefFlag.DriveModel.LongName()} \"{DriveModelValue}\""); + } + + // Drive Revision + if (GetSupportedCommands(ChefFlag.DriveRevision).Contains(Command)) + { + if (this[ChefFlag.DriveRevision] == true && DriveRevisionValue != null) + parameters.Add($"{ChefFlag.DriveRevision.LongName()} \"{DriveRevisionValue}\""); + } + + // Drive Serial + if (GetSupportedCommands(ChefFlag.DriveSerial).Contains(Command)) + { + if (this[ChefFlag.DriveSerial] == true && DriveSerialValue != null) + parameters.Add($"{ChefFlag.DriveSerial.LongName()} \"{DriveSerialValue}\""); + } + + // Encoding + if (GetSupportedCommands(ChefFlag.Encoding).Contains(Command)) + { + if (this[ChefFlag.Encoding] == true && EncodingValue != null) + parameters.Add($"{ChefFlag.Encoding.LongName()} \"{EncodingValue}\""); + } + + // Format (Convert) + if (GetSupportedCommands(ChefFlag.FormatConvert).Contains(Command)) + { + if (this[ChefFlag.FormatConvert] == true && FormatConvertValue != null) + parameters.Add($"{ChefFlag.FormatConvert.LongName()} \"{FormatConvertValue}\""); + } + + // Format (Dump) + if (GetSupportedCommands(ChefFlag.FormatDump).Contains(Command)) + { + if (this[ChefFlag.FormatDump] == true && FormatDumpValue != null) + parameters.Add($"{ChefFlag.FormatDump.LongName()} \"{FormatDumpValue}\""); + } + + // ImgBurn Log + if (GetSupportedCommands(ChefFlag.ImgBurnLog).Contains(Command)) + { + if (this[ChefFlag.ImgBurnLog] == true && ImgBurnLogValue != null) + parameters.Add($"{ChefFlag.ImgBurnLog.LongName()} \"{ImgBurnLogValue}\""); + } + + // Media Barcode + if (GetSupportedCommands(ChefFlag.MediaBarcode).Contains(Command)) + { + if (this[ChefFlag.MediaBarcode] == true && MediaBarcodeValue != null) + parameters.Add($"{ChefFlag.MediaBarcode.LongName()} \"{MediaBarcodeValue}\""); + } + + // Media Manufacturer + if (GetSupportedCommands(ChefFlag.MediaManufacturer).Contains(Command)) + { + if (this[ChefFlag.MediaManufacturer] == true && MediaManufacturerValue != null) + parameters.Add($"{ChefFlag.MediaManufacturer.LongName()} \"{MediaManufacturerValue}\""); + } + + // Media Model + if (GetSupportedCommands(ChefFlag.MediaModel).Contains(Command)) + { + if (this[ChefFlag.MediaModel] == true && MediaModelValue != null) + parameters.Add($"{ChefFlag.MediaModel.LongName()} \"{MediaModelValue}\""); + } + + // Media Part Number + if (GetSupportedCommands(ChefFlag.MediaPartNumber).Contains(Command)) + { + if (this[ChefFlag.MediaPartNumber] == true && MediaPartNumberValue != null) + parameters.Add($"{ChefFlag.MediaPartNumber.LongName()} \"{MediaPartNumberValue}\""); + } + + // Media Serial + if (GetSupportedCommands(ChefFlag.MediaSerial).Contains(Command)) + { + if (this[ChefFlag.MediaSerial] == true && MediaSerialValue != null) + parameters.Add($"{ChefFlag.MediaSerial.LongName()} \"{MediaSerialValue}\""); + } + + // Media Title + if (GetSupportedCommands(ChefFlag.MediaTitle).Contains(Command)) + { + if (this[ChefFlag.MediaTitle] == true && MediaTitleValue != null) + parameters.Add($"{ChefFlag.MediaTitle.LongName()} \"{MediaTitleValue}\""); + } + + // MHDD Log + if (GetSupportedCommands(ChefFlag.MHDDLog).Contains(Command)) + { + if (this[ChefFlag.MHDDLog] == true && MHDDLogValue != null) + parameters.Add($"{ChefFlag.MHDDLog.LongName()} \"{MHDDLogValue}\""); + } + + // Namespace + if (GetSupportedCommands(ChefFlag.Namespace).Contains(Command)) + { + if (this[ChefFlag.Namespace] == true && NamespaceValue != null) + parameters.Add($"{ChefFlag.Namespace.LongName()} \"{NamespaceValue}\""); + } + + // Options + if (GetSupportedCommands(ChefFlag.Options).Contains(Command)) + { + if (this[ChefFlag.Options] == true && OptionsValue != null) + parameters.Add($"{ChefFlag.Options.LongName()} \"{OptionsValue}\""); + } + + // Output Prefix + if (GetSupportedCommands(ChefFlag.OutputPrefix).Contains(Command)) + { + if (this[ChefFlag.OutputPrefix] == true && OutputPrefixValue != null) + parameters.Add($"{ChefFlag.OutputPrefix.LongName()} \"{OutputPrefixValue}\""); + } + + // Resume File + if (GetSupportedCommands(ChefFlag.ResumeFile).Contains(Command)) + { + if (this[ChefFlag.ResumeFile] == true && ResumeFileValue != null) + parameters.Add($"{ChefFlag.ResumeFile.LongName()} \"{ResumeFileValue}\""); + } + + // Subchannel + if (GetSupportedCommands(ChefFlag.Subchannel).Contains(Command)) + { + if (this[ChefFlag.Subchannel] == true && SubchannelValue != null) + parameters.Add($"{ChefFlag.Subchannel.LongName()} \"{SubchannelValue}\""); + } + + // XML Sidecar + if (GetSupportedCommands(ChefFlag.XMLSidecar).Contains(Command)) + { + if (this[ChefFlag.XMLSidecar] == true && XMLSidecarValue != null) + parameters.Add($"{ChefFlag.XMLSidecar.LongName()} \"{XMLSidecarValue}\""); + } + + #endregion + + // Handle filenames based on command, if necessary + switch (Command) + { + // Input value only + case ChefCommand.DeviceInfo: + case ChefCommand.DeviceReport: + case ChefCommand.FilesystemList: + case ChefCommand.ImageAnalyze: + case ChefCommand.ImageChecksum: + case ChefCommand.ImageCreateSidecar: + case ChefCommand.ImageDecode: + case ChefCommand.ImageEntropy: + case ChefCommand.ImageInfo: + case ChefCommand.ImagePrint: + case ChefCommand.ImageVerify: + case ChefCommand.MediaInfo: + case ChefCommand.MediaScan: + if (string.IsNullOrWhiteSpace(InputValue)) + return null; + + parameters.Add($"\"{InputValue}\""); + break; + + // Two input values + case ChefCommand.ImageCompare: + if (string.IsNullOrWhiteSpace(Input1Value) || string.IsNullOrWhiteSpace(Input2Value)) + return null; + + parameters.Add($"\"{Input1Value}\""); + parameters.Add($"\"{Input2Value}\""); + break; + + // Input and Output value + case ChefCommand.FilesystemExtract: + case ChefCommand.ImageConvert: + case ChefCommand.MediaDump: + if (string.IsNullOrWhiteSpace(InputValue) || string.IsNullOrWhiteSpace(OutputValue)) + return null; + + parameters.Add($"\"{InputValue}\""); + parameters.Add($"\"{OutputValue}\""); + break; + + // Remote host value only + case ChefCommand.DeviceList: + case ChefCommand.Remote: + if (string.IsNullOrWhiteSpace(RemoteHostValue)) + return null; + + parameters.Add($"\"{RemoteHostValue}\""); + break; + } + + return string.Join(" ", parameters); + } + + /// + /// Returns if the current Parameter object is valid + /// + /// + public bool IsValid() + { + return GenerateParameters() != null; + } + + /// + /// Scan a possible parameter string and populate whatever possible + /// + /// String possibly representing parameters + /// + private bool ValidateAndSetParameters(string parameters) + { + // The string has to be valid by itself first + if (string.IsNullOrWhiteSpace(parameters)) + return false; + + // Now split the string into parts for easier validation + // https://stackoverflow.com/questions/14655023/split-a-string-that-has-white-spaces-unless-they-are-enclosed-within-quotes + parameters = parameters.Trim(); + List parts = Regex.Matches(parameters, @"[\""].+?[\""]|[^ ]+") + .Cast() + .Select(m => m.Value) + .ToList(); + + // Determine what the commandline should look like given the first item + Command = Converters.StringToChefCommand(parts[0], parts.Count > 1 ? parts[1] : null, out bool useSecond); + if (Command == ChefCommand.NONE) + return false; + + // Set the start according to what the full command was + int start = useSecond ? 2 : 1; + + // Loop through all auxilary flags, if necessary + // TODO: Should an invalid flag mean instant failure? There are some flags that share a short form and this could cause issues + int i = 0; + for (i = start; i < parts.Count; i++) + { + // Flag read-out values + sbyte? byteValue = null; + short? shortValue = null; + int? intValue = null; + long? longValue = null; + string stringValue = null; + + // Keep a count of keys to determine if we should break out to filename handling or not + int keyCount = Keys.Count(); + + #region Boolean flags + + // Adler-32 + if (!ProcessBooleanParameter(parts, ChefFlagStrings.Adler32Short, ChefFlagStrings.Adler32Long, ChefFlag.Adler32, ref i)) + return false; + + // Clear + if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.ClearLong, ChefFlag.Clear, ref i)) + return false; + + // Clear All + if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.ClearAllLong, ChefFlag.ClearAll, ref i)) + return false; + + // CRC16 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.CRC16Long, ChefFlag.CRC16, ref i)) + return false; + + // CRC32 + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.CRC32Short, ChefFlagStrings.CRC32Long, ChefFlag.CRC32, ref i)) + return false; + + // CRC64 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.CRC64Long, ChefFlag.CRC64, ref i)) + return false; + + // Debug + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.DebugShort, ChefFlagStrings.DebugLong, ChefFlag.Debug, ref i)) + return false; + + // Disk Tags + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.DiskTagsShort, ChefFlagStrings.DiskTagsLong, ChefFlag.DiskTags, ref i)) + return false; + + // Deduplicated Sectors + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.DuplicatedSectorsShort, ChefFlagStrings.DuplicatedSectorsLong, ChefFlag.DuplicatedSectors, ref i)) + return false; + + // Extended Attributes + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.ExtendedAttributesShort, ChefFlagStrings.ExtendedAttributesLong, ChefFlag.ExtendedAttributes, ref i)) + return false; + + // Filesystems + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.FilesystemsShort, ChefFlagStrings.FilesystemsLong, ChefFlag.Filesystems, ref i)) + return false; + + // First Pregap + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.FirstPregapLong, ChefFlag.FirstPregap, ref i)) + return false; + + // Fix Offset + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.FixOffsetLong, ChefFlag.FixOffset, ref i)) + return false; + + // Fletcher-16 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.Fletcher16Long, ChefFlag.Fletcher16, ref i)) + return false; + + // Fletcher-32 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.Fletcher32Long, ChefFlag.Fletcher32, ref i)) + return false; + + // Force + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.ForceShort, ChefFlagStrings.ForceLong, ChefFlag.Force, ref i)) + return false; + + // Long Format + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.LongFormatShort, ChefFlagStrings.LongFormatLong, ChefFlag.LongFormat, ref i)) + return false; + + // Long Sectors + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.LongSectorsShort, ChefFlagStrings.LongSectorsLong, ChefFlag.LongSectors, ref i)) + return false; + + // MD5 + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.MD5Short, ChefFlagStrings.MD5Long, ChefFlag.MD5, ref i)) + return false; + + // Metadata + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.MetadataLong, ChefFlag.Metadata, ref i)) + return false; + + // Partitions + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.PartitionsShort, ChefFlagStrings.PartitionsLong, ChefFlag.Partitions, ref i)) + return false; + + // Persistent + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.PersistentLong, ChefFlag.Persistent, ref i)) + return false; + + // Resume + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.ResumeShort, ChefFlagStrings.ResumeLong, ChefFlag.Resume, ref i)) + return false; + + // Sector Tags + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.SectorTagsShort, ChefFlagStrings.SectorTagsLong, ChefFlag.SectorTags, ref i)) + return false; + + // Separated Tracks + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.SeparatedTracksShort, ChefFlagStrings.SeparatedTracksLong, ChefFlag.SeparatedTracks, ref i)) + return false; + + // SHA-1 + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.SHA1Short, ChefFlagStrings.SHA1Long, ChefFlag.SHA1, ref i)) + return false; + + // SHA-256 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.SHA256Long, ChefFlag.SHA256, ref i)) + return false; + + // SHA-384 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.SHA384Long, ChefFlag.SHA384, ref i)) + return false; + + // SHA-512 + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.SHA512Long, ChefFlag.SHA512, ref i)) + return false; + + // SpamSum + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.SpamSumShort, ChefFlagStrings.SpamSumLong, ChefFlag.SpamSum, ref i)) + return false; + + // Stop on Error + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.StopOnErrorShort, ChefFlagStrings.StopOnErrorLong, ChefFlag.StopOnError, ref i)) + return false; + + // Tape + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.TapeShort, ChefFlagStrings.TapeLong, ChefFlag.Tape, ref i)) + return false; + + // Trim + else if (!ProcessBooleanParameter(parts, null, ChefFlagStrings.TrimLong, ChefFlag.Trim, ref i)) + return false; + + // Verbose + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.VerboseShort, ChefFlagStrings.VerboseLong, ChefFlag.Verbose, ref i)) + return false; + + // Verify Disc + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.VerifyDiscShort, ChefFlagStrings.VerifyDiscLong, ChefFlag.VerifyDisc, ref i)) + return false; + + // Verify Sectors + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.VerifySectorsShort, ChefFlagStrings.VerifySectorsLong, ChefFlag.VerifySectors, ref i)) + return false; + + // Whole Disc + else if (!ProcessBooleanParameter(parts, ChefFlagStrings.WholeDiscShort, ChefFlagStrings.WholeDiscLong, ChefFlag.VerifySectors, ref i)) + return false; + + #endregion + + #region Int8 flags + + // Speed + byteValue = ProcessInt8Parameter(parts, null, ChefFlagStrings.SpeedLong, ChefFlag.Speed, ref i); + if (byteValue == null) + return false; + else if (byteValue != SByte.MinValue) + SpeedValue = byteValue; + + #endregion + + #region Int16 flags + + // Retry Passes + shortValue = ProcessInt16Parameter(parts, ChefFlagStrings.RetryPassesShort, ChefFlagStrings.RetryPassesLong, ChefFlag.RetryPasses, ref i); + if (shortValue == null) + return false; + else if (shortValue != Int16.MinValue) + RetryPassesValue = shortValue; + + // Width + shortValue = ProcessInt16Parameter(parts, ChefFlagStrings.WidthShort, ChefFlagStrings.WidthLong, ChefFlag.Width, ref i); + if (shortValue == null) + return false; + else if (shortValue != Int16.MinValue) + WidthValue = shortValue; + + #endregion + + #region Int32 flags + + // Block Size + intValue = ProcessInt32Parameter(parts, ChefFlagStrings.BlockSizeShort, ChefFlagStrings.BlockSizeLong, ChefFlag.BlockSize, ref i); + if (intValue == null) + return false; + else if (intValue != Int32.MinValue) + BlockSizeValue = intValue; + + // Count + intValue = ProcessInt32Parameter(parts, ChefFlagStrings.CountShort, ChefFlagStrings.CountLong, ChefFlag.Count, ref i); + if (intValue == null) + return false; + else if (intValue != Int32.MinValue) + CountValue = intValue; + + // Media Last Sequence + intValue = ProcessInt32Parameter(parts, null, ChefFlagStrings.MediaLastSequenceLong, ChefFlag.MediaLastSequence, ref i); + if (intValue == null) + return false; + else if (intValue != Int32.MinValue) + MediaLastSequenceValue = intValue; + + // Media Sequence + intValue = ProcessInt32Parameter(parts, null, ChefFlagStrings.MediaSequenceLong, ChefFlag.MediaSequence, ref i); + if (intValue == null) + return false; + else if (intValue != Int32.MinValue) + MediaSequenceValue = intValue; + + // Skip + intValue = ProcessInt32Parameter(parts, ChefFlagStrings.SkipShort, ChefFlagStrings.SkipLong, ChefFlag.Skip, ref i); + if (intValue == null) + return false; + else if (intValue != Int32.MinValue) + SkipValue = intValue; + + #endregion + + #region Int64 flags + + // Length -- Can also be "all" + longValue = ProcessInt64Parameter(parts, ChefFlagStrings.LengthShort, ChefFlagStrings.LengthLong, ChefFlag.Length, ref i); + if (longValue == null) + return false; + else if (longValue != Int64.MinValue) + LengthValue = longValue; + + // Start + longValue = ProcessInt64Parameter(parts, ChefFlagStrings.StartShort, ChefFlagStrings.StartLong, ChefFlag.Start, ref i); + if (longValue == null) + return false; + else if (longValue != Int64.MinValue) + StartValue = longValue; + + #endregion + + #region String flags + + // Comments + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.CommentsLong, ChefFlag.Comments, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + CommentsValue = stringValue; + + // Creator + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.CreatorLong, ChefFlag.Creator, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + CreatorValue = stringValue; + + // Drive Manufacturer + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.DriveManufacturerLong, ChefFlag.DriveManufacturer, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + DriveManufacturerValue = stringValue; + + // Drive Model + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.DriveModelLong, ChefFlag.DriveModel, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + DriveModelValue = stringValue; + + // Drive Revision + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.DriveRevisionLong, ChefFlag.DriveRevision, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + DriveRevisionValue = stringValue; + + // Drive Serial + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.DriveSerialLong, ChefFlag.DriveSerial, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + DriveSerialValue = stringValue; + + // Encoding -- TODO: List of encodings? + stringValue = ProcessStringParameter(parts, ChefFlagStrings.EncodingShort, ChefFlagStrings.EncodingLong, ChefFlag.Encoding, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + EncodingValue = stringValue; + + // Format (Convert) -- TODO: List of formats? + stringValue = ProcessStringParameter(parts, ChefFlagStrings.FormatConvertShort, ChefFlagStrings.FormatConvertLong, ChefFlag.FormatConvert, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + FormatConvertValue = stringValue; + + // Format (Dump) -- TODO: List of formats? + stringValue = ProcessStringParameter(parts, ChefFlagStrings.FormatDumpShort, ChefFlagStrings.FormatDumpLong, ChefFlag.FormatDump, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + FormatDumpValue = stringValue; + + // ImgBurn Log + stringValue = ProcessStringParameter(parts, ChefFlagStrings.ImgBurnLogShort, ChefFlagStrings.ImgBurnLogLong, ChefFlag.ImgBurnLog, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + ImgBurnLogValue = stringValue; + + // Media Barcode + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.MediaBarcodeLong, ChefFlag.MediaBarcode, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MediaBarcodeValue = stringValue; + + // Media Manufacturer + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.MediaManufacturerLong, ChefFlag.MediaManufacturer, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MediaManufacturerValue = stringValue; + + // Media Model + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.MediaModelLong, ChefFlag.MediaModel, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MediaModelValue = stringValue; + + // Media Part Number + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.MediaPartNumberLong, ChefFlag.MediaPartNumber, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MediaPartNumberValue = stringValue; + + // Media Serial + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.MediaSerialLong, ChefFlag.MediaSerial, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MediaSerialValue = stringValue; + + // Media Title + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.MediaTitleLong, ChefFlag.MediaTitle, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MediaTitleValue = stringValue; + + // MHDD Log + stringValue = ProcessStringParameter(parts, ChefFlagStrings.MHDDLogShort, ChefFlagStrings.MHDDLogLong, ChefFlag.MHDDLog, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + MHDDLogValue = stringValue; + + // Namespace + stringValue = ProcessStringParameter(parts, ChefFlagStrings.NamespaceShort, ChefFlagStrings.NamespaceLong, ChefFlag.Namespace, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + NamespaceValue = stringValue; + + // Options -- TODO: Validate options? + stringValue = ProcessStringParameter(parts, ChefFlagStrings.OptionsShort, ChefFlagStrings.OptionsLong, ChefFlag.Options, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + OptionsValue = stringValue; + + // Output Prefix + stringValue = ProcessStringParameter(parts, ChefFlagStrings.OutputPrefixShort, ChefFlagStrings.OutputPrefixLong, ChefFlag.OutputPrefix, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + OutputPrefixValue = stringValue; + + // Resume File + stringValue = ProcessStringParameter(parts, ChefFlagStrings.ResumeFileShort, ChefFlagStrings.ResumeFileLong, ChefFlag.ResumeFile, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + ResumeFileValue = stringValue; + + // Subchannel + stringValue = ProcessStringParameter(parts, null, ChefFlagStrings.SubchannelLong, ChefFlag.Subchannel, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + SubchannelValue = stringValue; + + // XML Sidecar + stringValue = ProcessStringParameter(parts, ChefFlagStrings.XMLSidecarShort, ChefFlagStrings.XMLSidecarLong, ChefFlag.XMLSidecar, ref i); + if (stringValue == null) + return false; + else if (stringValue != string.Empty) + XMLSidecarValue = stringValue; + + #endregion + + // If we didn't add any new flags, break out since we might be at filename handling + if (keyCount == Keys.Count()) + break; + } + + // Handle filenames based on command, if necessary + switch (Command) + { + // Input value only + case ChefCommand.DeviceInfo: + case ChefCommand.DeviceReport: + case ChefCommand.FilesystemList: + case ChefCommand.ImageAnalyze: + case ChefCommand.ImageChecksum: + case ChefCommand.ImageCreateSidecar: + case ChefCommand.ImageDecode: + case ChefCommand.ImageEntropy: + case ChefCommand.ImageInfo: + case ChefCommand.ImagePrint: + case ChefCommand.ImageVerify: + case ChefCommand.MediaInfo: + case ChefCommand.MediaScan: + if (!DoesExist(parts, i)) + return false; + + InputValue = parts[i].Trim('"'); + i++; + break; + + // Two input values + case ChefCommand.ImageCompare: + if (!DoesExist(parts, i)) + return false; + + Input1Value = parts[i].Trim('"'); + i++; + + if (!DoesExist(parts, i)) + return false; + + Input2Value = parts[i].Trim('"'); + i++; + break; + + // Input and Output value + case ChefCommand.FilesystemExtract: + case ChefCommand.ImageConvert: + case ChefCommand.MediaDump: + if (!DoesExist(parts, i)) + return false; + + InputValue = parts[i].Trim('"'); + i++; + + if (!DoesExist(parts, i)) + return false; + + OutputValue = parts[i].Trim('"'); + i++; + break; + + // Remote host value only + case ChefCommand.DeviceList: + case ChefCommand.Remote: + if (!DoesExist(parts, i)) + return false; + + RemoteHostValue = parts[i].Trim('"'); + i++; + break; + } + + // If we didn't reach the end for some reason, it failed + if (i != parts.Count) + return false; + + return true; + } + + /// + /// Returns whether or not the selected item exists + /// + /// List of parameters to check against + /// Current index + /// True if the next item exists, false otherwise + private bool DoesExist(List parameters, int index) + { + if (index >= parameters.Count) + return false; + + return true; + } + + /// + /// Get the list of commands that use a given flag + /// + /// Flag value to get commands for + /// List of ChefCommands, if possible + private List GetSupportedCommands(ChefFlag flag) + { + var commands = new List(); + switch (flag) + { + case ChefFlag.Adler32: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.BlockSize: + commands.Add(ChefCommand.ImageCreateSidecar); + break; + case ChefFlag.Clear: + commands.Add(ChefCommand.DatabaseUpdate); + break; + case ChefFlag.ClearAll: + commands.Add(ChefCommand.DatabaseUpdate); + break; + case ChefFlag.Comments: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.Count: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.CRC16: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.CRC32: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.CRC64: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.Creator: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.Debug: + commands.Add(ChefCommand.DatabaseStats); + commands.Add(ChefCommand.DatabaseUpdate); + commands.Add(ChefCommand.DeviceInfo); + commands.Add(ChefCommand.DeviceList); + commands.Add(ChefCommand.DeviceReport); + commands.Add(ChefCommand.FilesystemExtract); + commands.Add(ChefCommand.FilesystemList); + commands.Add(ChefCommand.FilesystemOptions); + commands.Add(ChefCommand.ImageAnalyze); + commands.Add(ChefCommand.ImageChecksum); + commands.Add(ChefCommand.ImageCompare); + commands.Add(ChefCommand.ImageConvert); + commands.Add(ChefCommand.ImageCreateSidecar); + commands.Add(ChefCommand.ImageDecode); + commands.Add(ChefCommand.ImageEntropy); + commands.Add(ChefCommand.ImageInfo); + commands.Add(ChefCommand.ImageOptions); + commands.Add(ChefCommand.ImagePrint); + commands.Add(ChefCommand.ImageVerify); + commands.Add(ChefCommand.MediaDump); + commands.Add(ChefCommand.MediaInfo); + commands.Add(ChefCommand.MediaScan); + commands.Add(ChefCommand.Configure); + commands.Add(ChefCommand.Formats); + commands.Add(ChefCommand.ListEncodings); + commands.Add(ChefCommand.ListNamespaces); + commands.Add(ChefCommand.Remote); + break; + case ChefFlag.DiskTags: + commands.Add(ChefCommand.ImageDecode); + break; + case ChefFlag.DriveManufacturer: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.DriveModel: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.DriveRevision: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.DriveSerial: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.DuplicatedSectors: + commands.Add(ChefCommand.ImageEntropy); + break; + case ChefFlag.Encoding: + commands.Add(ChefCommand.FilesystemExtract); + commands.Add(ChefCommand.FilesystemList); + commands.Add(ChefCommand.ImageAnalyze); + commands.Add(ChefCommand.ImageCreateSidecar); + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.ExtendedAttributes: + commands.Add(ChefCommand.FilesystemExtract); + break; + case ChefFlag.Filesystems: + commands.Add(ChefCommand.ImageAnalyze); + break; + case ChefFlag.FirstPregap: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.FixOffset: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.Fletcher16: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.Fletcher32: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.Force: + commands.Add(ChefCommand.ImageConvert); + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.FormatConvert: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.FormatDump: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.ImgBurnLog: + commands.Add(ChefCommand.MediaScan); + break; + case ChefFlag.Length: + commands.Add(ChefCommand.ImageDecode); + commands.Add(ChefCommand.ImagePrint); + break; + case ChefFlag.LongFormat: + commands.Add(ChefCommand.FilesystemList); + break; + case ChefFlag.LongSectors: + commands.Add(ChefCommand.ImagePrint); + break; + case ChefFlag.MD5: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.MediaBarcode: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaLastSequence: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaManufacturer: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaModel: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaPartNumber: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaSequence: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaSerial: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.MediaTitle: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.Metadata: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.MHDDLog: + commands.Add(ChefCommand.MediaScan); + break; + case ChefFlag.Namespace: + commands.Add(ChefCommand.FilesystemExtract); + commands.Add(ChefCommand.FilesystemList); + break; + case ChefFlag.Options: + commands.Add(ChefCommand.FilesystemExtract); + commands.Add(ChefCommand.FilesystemList); + commands.Add(ChefCommand.ImageConvert); + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.OutputPrefix: + commands.Add(ChefCommand.DeviceInfo); + commands.Add(ChefCommand.MediaInfo); + break; + case ChefFlag.Partitions: + commands.Add(ChefCommand.ImageAnalyze); + break; + case ChefFlag.Persistent: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.Resume: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.ResumeFile: + commands.Add(ChefCommand.ImageConvert); + break; + case ChefFlag.RetryPasses: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.SectorTags: + commands.Add(ChefCommand.ImageDecode); + break; + case ChefFlag.SeparatedTracks: + commands.Add(ChefCommand.ImageChecksum); + commands.Add(ChefCommand.ImageEntropy); + break; + case ChefFlag.SHA1: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.SHA256: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.SHA384: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.SHA512: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.Skip: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.SpamSum: + commands.Add(ChefCommand.ImageChecksum); + break; + case ChefFlag.Speed: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.Start: + commands.Add(ChefCommand.ImageDecode); + commands.Add(ChefCommand.ImagePrint); + break; + case ChefFlag.StopOnError: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.Subchannel: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.Tape: + commands.Add(ChefCommand.ImageCreateSidecar); + break; + case ChefFlag.Trim: + commands.Add(ChefCommand.MediaDump); + break; + case ChefFlag.Verbose: + commands.Add(ChefCommand.DatabaseStats); + commands.Add(ChefCommand.DatabaseUpdate); + commands.Add(ChefCommand.DeviceInfo); + commands.Add(ChefCommand.DeviceList); + commands.Add(ChefCommand.DeviceReport); + commands.Add(ChefCommand.FilesystemExtract); + commands.Add(ChefCommand.FilesystemList); + commands.Add(ChefCommand.FilesystemOptions); + commands.Add(ChefCommand.ImageAnalyze); + commands.Add(ChefCommand.ImageChecksum); + commands.Add(ChefCommand.ImageCompare); + commands.Add(ChefCommand.ImageConvert); + commands.Add(ChefCommand.ImageCreateSidecar); + commands.Add(ChefCommand.ImageDecode); + commands.Add(ChefCommand.ImageEntropy); + commands.Add(ChefCommand.ImageInfo); + commands.Add(ChefCommand.ImageOptions); + commands.Add(ChefCommand.ImagePrint); + commands.Add(ChefCommand.ImageVerify); + commands.Add(ChefCommand.MediaDump); + commands.Add(ChefCommand.MediaInfo); + commands.Add(ChefCommand.MediaScan); + commands.Add(ChefCommand.Configure); + commands.Add(ChefCommand.Formats); + commands.Add(ChefCommand.ListEncodings); + commands.Add(ChefCommand.ListNamespaces); + commands.Add(ChefCommand.Remote); + break; + case ChefFlag.VerifyDisc: + commands.Add(ChefCommand.ImageAnalyze); + commands.Add(ChefCommand.ImageVerify); + break; + case ChefFlag.VerifySectors: + commands.Add(ChefCommand.ImageAnalyze); + commands.Add(ChefCommand.ImageVerify); + break; + case ChefFlag.WholeDisc: + commands.Add(ChefCommand.ImageChecksum); + commands.Add(ChefCommand.ImageEntropy); + break; + case ChefFlag.Width: + commands.Add(ChefCommand.ImagePrint); + break; + case ChefFlag.XMLSidecar: + commands.Add(ChefCommand.ImageConvert); + commands.Add(ChefCommand.MediaDump); + break; + + case ChefFlag.NONE: + default: + return commands; + } + + return commands; + } + + /// + /// Returns whether a string is a valid bool + /// + /// String value to check + /// True if it's a valid bool, false otherwise + private bool IsValidBool(string parameter) + { + return bool.TryParse(parameter, out bool temp); + } + + /// + /// Returns whether a string is a valid byte + /// + /// String value to check + /// Lower bound (>=) + /// Upper bound (<=) + /// True if it's a valid byte, false otherwise + private bool IsValidInt8(string parameter, sbyte lowerBound = -1, sbyte upperBound = -1) + { + if (!sbyte.TryParse(parameter, out sbyte temp)) + return false; + else if (lowerBound != -1 && temp < lowerBound) + return false; + else if (upperBound != -1 && temp > upperBound) + return false; + + return true; + } + + /// + /// Returns whether a string is a valid Int16 + /// + /// String value to check + /// Lower bound (>=) + /// Upper bound (<=) + /// True if it's a valid Int16, false otherwise + private bool IsValidInt16(string parameter, short lowerBound = -1, short upperBound = -1) + { + if (!short.TryParse(parameter, out short temp)) + return false; + else if (lowerBound != -1 && temp < lowerBound) + return false; + else if (upperBound != -1 && temp > upperBound) + return false; + + return true; + } + + /// + /// Returns whether a string is a valid Int32 + /// + /// String value to check + /// Lower bound (>=) + /// Upper bound (<=) + /// True if it's a valid Int32, false otherwise + private bool IsValidInt32(string parameter, int lowerBound = -1, int upperBound = -1) + { + if (!int.TryParse(parameter, out int temp)) + return false; + else if (lowerBound != -1 && temp < lowerBound) + return false; + else if (upperBound != -1 && temp > upperBound) + return false; + + return true; + } + + /// + /// Returns whether a string is a valid Int64 + /// + /// String value to check + /// Lower bound (>=) + /// Upper bound (<=) + /// True if it's a valid Int64, false otherwise + private bool IsValidInt64(string parameter, long lowerBound = -1, long upperBound = -1) + { + if (!long.TryParse(parameter, out long temp)) + return false; + else if (lowerBound != -1 && temp < lowerBound) + return false; + else if (upperBound != -1 && temp > upperBound) + return false; + + return true; + } + + /// + /// Process a boolean parameter + /// + /// List of parts to be referenced + /// Short flag string, if available + /// Long flag string, if available + /// ChefFlag value corresponding to the flag + /// Reference to the position in the parts + /// True if the parameter was processed successfully or skipped, false otherwise + private bool ProcessBooleanParameter(List parts, string shortFlagString, string longFlagString, ChefFlag flag, ref int i) + { + if (parts == null) + return false; + + if (parts[i] == shortFlagString || parts[i] == longFlagString) + { + if (!GetSupportedCommands(flag).Contains(Command)) + return false; + else if (!DoesExist(parts, i + 1)) + return false; + else if (!IsValidBool(parts[i + 1])) + return false; + + this[flag] = bool.Parse(parts[i + 1]); + i++; + } + + return true; + } + + /// + /// Process an sbyte parameter + /// + /// List of parts to be referenced + /// Short flag string, if available + /// Long flag string, if available + /// ChefFlag value corresponding to the flag + /// Reference to the position in the parts + /// SByte value if success, Int16.MinValue if skipped, null on error/returns> + private sbyte? ProcessInt8Parameter(List parts, string shortFlagString, string longFlagString, ChefFlag flag, ref int i) + { + if (parts == null) + return null; + + if (parts[i] == shortFlagString || parts[i] == longFlagString) + { + if (!GetSupportedCommands(flag).Contains(Command)) + return null; + else if (!DoesExist(parts, i + 1)) + return null; + else if (!IsValidInt8(parts[i + 1])) + return null; + + this[flag] = true; + i++; + return sbyte.Parse(parts[i]); + } + + return SByte.MinValue; + } + + /// + /// Process an Int16 parameter + /// + /// List of parts to be referenced + /// Short flag string, if available + /// Long flag string, if available + /// ChefFlag value corresponding to the flag + /// Reference to the position in the parts + /// Int16 value if success, Int16.MinValue if skipped, null on error/returns> + private short? ProcessInt16Parameter(List parts, string shortFlagString, string longFlagString, ChefFlag flag, ref int i) + { + if (parts == null) + return null; + + if (parts[i] == shortFlagString || parts[i] == longFlagString) + { + if (!GetSupportedCommands(flag).Contains(Command)) + return null; + else if (!DoesExist(parts, i + 1)) + return null; + else if (!IsValidInt16(parts[i + 1])) + return null; + + this[flag] = true; + i++; + return short.Parse(parts[i]); + } + + return Int16.MinValue; + } + + /// + /// Process an Int32 parameter + /// + /// List of parts to be referenced + /// Short flag string, if available + /// Long flag string, if available + /// ChefFlag value corresponding to the flag + /// Reference to the position in the parts + /// Int32 value if success, Int32.MinValue if skipped, null on error/returns> + private int? ProcessInt32Parameter(List parts, string shortFlagString, string longFlagString, ChefFlag flag, ref int i) + { + if (parts == null) + return null; + + if (parts[i] == shortFlagString || parts[i] == longFlagString) + { + if (!GetSupportedCommands(flag).Contains(Command)) + return null; + else if (!DoesExist(parts, i + 1)) + return null; + else if (!IsValidInt32(parts[i + 1])) + return null; + + this[flag] = true; + i++; + return int.Parse(parts[i]); + } + + return Int32.MinValue; + } + + /// + /// Process an Int64 parameter + /// + /// List of parts to be referenced + /// Short flag string, if available + /// Long flag string, if available + /// ChefFlag value corresponding to the flag + /// Reference to the position in the parts + /// Int64 value if success, Int64.MinValue if skipped, null on error/returns> + private long? ProcessInt64Parameter(List parts, string shortFlagString, string longFlagString, ChefFlag flag, ref int i) + { + if (parts == null) + return null; + + if (parts[i] == shortFlagString || parts[i] == longFlagString) + { + if (!GetSupportedCommands(flag).Contains(Command)) + return null; + else if (!DoesExist(parts, i + 1)) + return null; + else if (!IsValidInt64(parts[i + 1])) + return null; + + this[flag] = true; + i++; + return long.Parse(parts[i]); + } + + return Int64.MinValue; + } + + /// + /// Process a string parameter + /// + /// List of parts to be referenced + /// Short flag string, if available + /// Long flag string, if available + /// ChefFlag value corresponding to the flag + /// Reference to the position in the parts + /// String value if possible, string.Empty on missing, null on error + private string ProcessStringParameter(List parts, string shortFlagString, string longFlagString, ChefFlag flag, ref int i) + { + if (parts == null) + return null; + + if (parts[i] == shortFlagString || parts[i] == longFlagString) + { + if (!GetSupportedCommands(flag).Contains(Command)) + return null; + else if (!DoesExist(parts, i + 1)) + return null; + else if (string.IsNullOrWhiteSpace(parts[i + 1])) + return null; + + this[flag] = true; + i++; + return parts[i].Trim('"'); + } + + return string.Empty; + } + + /// + /// Set default parameters for a given system and media type + /// + /// KnownSystem value to check + /// MediaType value to check + /// Enable paranoid mode (safer dumping) + /// User-defined reread count + private void SetDefaultParameters(KnownSystem? system, MediaType? type, bool paranoid, int retryPassesCount) + { + // First check to see if the combination of system and MediaType is valid + var validTypes = Validators.GetValidMediaTypes(system); + if (!validTypes.Contains(type)) + return; + + // Set retry count + if (retryPassesCount > 0) + { + this[ChefFlag.RetryPasses] = true; + RetryPassesValue = (short)retryPassesCount; + } + + // Paranoia in DiscImageChef means more output + if (paranoid) + { + this[ChefFlag.Debug] = true; + this[ChefFlag.Verbose] = true; + } + + // TODO: Look at dump-media formats and the like and see what options there are there to fill in defaults + // Now sort based on disc type + switch (type) + { + case MediaType.CDROM: + // TODO: Re-add when implemented + //this[ChefFlag.Options] = true; + //OptionsValue = $"{ChefOptionStrings.CDRWinCuesheetSeparate}=true"; + + this[ChefFlag.FirstPregap] = true; + this[ChefFlag.FixOffset] = true; + this[ChefFlag.Subchannel] = true; + SubchannelValue = "any"; + break; + case MediaType.DVD: + // Currently no defaults set + break; + case MediaType.GDROM: + // Currently no defaults set + break; + case MediaType.HDDVD: + // Currently no defaults set + break; + case MediaType.BluRay: + // Currently no defaults set + break; + + // Special Formats + case MediaType.NintendoGameCubeGameDisc: + // Currently no defaults set + break; + case MediaType.NintendoWiiOpticalDisc: + // Currently no defaults set + break; + + // Non-optical + case MediaType.FloppyDisk: + // Currently no defaults set + break; + } + } + } +} diff --git a/DICUI.Library/Utilities/Converters.cs b/DICUI.Library/Utilities/Converters.cs index c89f69ce..8d821b4c 100644 --- a/DICUI.Library/Utilities/Converters.cs +++ b/DICUI.Library/Utilities/Converters.cs @@ -465,9 +465,14 @@ namespace DICUI.Utilities /// Get the default extension for a given disc type /// /// MediaType value to check + /// Whether or not DiscImageChef is being used /// Valid extension (with leading '.'), null on error - public static string Extension(this MediaType? type) + public static string Extension(this MediaType? type, bool useChef) { + // DiscImageChef has a single, unified output format by default + if (useChef) + return ".dicf"; + switch (type) { case MediaType.CDROM: @@ -540,6 +545,254 @@ namespace DICUI.Utilities } } + /// + /// Get the string representation of the ChefCommand enum values + /// + /// ChefCommand value to convert + /// String representing the value, if possible + public static string LongName(this ChefCommand command) + { + switch (command) + { + // Database Family + case ChefCommand.DatabaseStats: + return $"{ChefCommandStrings.DatabasePrefixLong} {ChefCommandStrings.DatabaseStats}"; + case ChefCommand.DatabaseUpdate: + return $"{ChefCommandStrings.DatabasePrefixLong} {ChefCommandStrings.DatabaseUpdate}"; + + // Device Family + case ChefCommand.DeviceInfo: + return $"{ChefCommandStrings.DevicePrefixLong} {ChefCommandStrings.DeviceInfo}"; + case ChefCommand.DeviceList: + return $"{ChefCommandStrings.DevicePrefixLong} {ChefCommandStrings.DeviceList}"; + case ChefCommand.DeviceReport: + return $"{ChefCommandStrings.DevicePrefixLong} {ChefCommandStrings.DeviceReport}"; + + // Filesystem Family + case ChefCommand.FilesystemExtract: + return $"{ChefCommandStrings.FilesystemPrefixLong} {ChefCommandStrings.FilesystemExtract}"; + case ChefCommand.FilesystemList: + return $"{ChefCommandStrings.FilesystemPrefixLong} {ChefCommandStrings.FilesystemListLong}"; + case ChefCommand.FilesystemOptions: + return $"{ChefCommandStrings.FilesystemPrefixLong} {ChefCommandStrings.FilesystemOptions}"; + + // Image Family + case ChefCommand.ImageAnalyze: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageAnalyze}"; + case ChefCommand.ImageChecksum: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageChecksumLong}"; + case ChefCommand.ImageCompare: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageCompareLong}"; + case ChefCommand.ImageConvert: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageConvert}"; + case ChefCommand.ImageCreateSidecar: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageCreateSidecar}"; + case ChefCommand.ImageDecode: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageDecode}"; + case ChefCommand.ImageEntropy: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageEntropy}"; + case ChefCommand.ImageInfo: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageInfo}"; + case ChefCommand.ImageOptions: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageOptions}"; + case ChefCommand.ImagePrint: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImagePrint}"; + case ChefCommand.ImageVerify: + return $"{ChefCommandStrings.ImagePrefixLong} {ChefCommandStrings.ImageVerify}"; + + // Media Family + case ChefCommand.MediaDump: + return $"{ChefCommandStrings.MediaPrefixLong} {ChefCommandStrings.MediaDump}"; + case ChefCommand.MediaInfo: + return $"{ChefCommandStrings.MediaPrefixLong} {ChefCommandStrings.MediaInfo}"; + case ChefCommand.MediaScan: + return $"{ChefCommandStrings.MediaPrefixLong} {ChefCommandStrings.MediaScan}"; + + // Standalone Commands + case ChefCommand.Configure: + return ChefCommandStrings.Configure; + case ChefCommand.Formats: + return ChefCommandStrings.Formats; + case ChefCommand.ListEncodings: + return ChefCommandStrings.ListEncodings; + case ChefCommand.ListNamespaces: + return ChefCommandStrings.ListNamespaces; + case ChefCommand.Remote: + return ChefCommandStrings.Remote; + + case ChefCommand.NONE: + default: + return ""; + } + } + + /// + /// Get the string representation of the ChefFlag enum values + /// + /// ChefFlag value to convert + /// String representing the value, if possible + public static string LongName(this ChefFlag flag) + { + switch (flag) + { + // Boolean flags + case ChefFlag.Adler32: + return ChefFlagStrings.Adler32Long; + case ChefFlag.Clear: + return ChefFlagStrings.ClearLong; + case ChefFlag.ClearAll: + return ChefFlagStrings.ClearAllLong; + case ChefFlag.CRC16: + return ChefFlagStrings.CRC16Long; + case ChefFlag.CRC32: + return ChefFlagStrings.CRC32Long; + case ChefFlag.CRC64: + return ChefFlagStrings.CRC64Long; + case ChefFlag.Debug: + return ChefFlagStrings.DebugLong; + case ChefFlag.DiskTags: + return ChefFlagStrings.DiskTagsLong; + case ChefFlag.DuplicatedSectors: + return ChefFlagStrings.DuplicatedSectorsLong; + case ChefFlag.ExtendedAttributes: + return ChefFlagStrings.ExtendedAttributesLong; + case ChefFlag.Filesystems: + return ChefFlagStrings.FilesystemsLong; + case ChefFlag.FirstPregap: + return ChefFlagStrings.FirstPregapLong; + case ChefFlag.FixOffset: + return ChefFlagStrings.FixOffsetLong; + case ChefFlag.Fletcher16: + return ChefFlagStrings.Fletcher16Long; + case ChefFlag.Fletcher32: + return ChefFlagStrings.Fletcher32Long; + case ChefFlag.Force: + return ChefFlagStrings.ForceLong; + case ChefFlag.LongFormat: + return ChefFlagStrings.LongFormatLong; + case ChefFlag.LongSectors: + return ChefFlagStrings.LongSectorsLong; + case ChefFlag.MD5: + return ChefFlagStrings.MD5Long; + case ChefFlag.Metadata: + return ChefFlagStrings.MetadataLong; + case ChefFlag.Partitions: + return ChefFlagStrings.PartitionsLong; + case ChefFlag.Persistent: + return ChefFlagStrings.PersistentLong; + case ChefFlag.Resume: + return ChefFlagStrings.ResumeLong; + case ChefFlag.SectorTags: + return ChefFlagStrings.SectorTagsLong; + case ChefFlag.SeparatedTracks: + return ChefFlagStrings.SeparatedTracksLong; + case ChefFlag.SHA1: + return ChefFlagStrings.SHA1Long; + case ChefFlag.SHA256: + return ChefFlagStrings.SHA256Long; + case ChefFlag.SHA384: + return ChefFlagStrings.SHA384Long; + case ChefFlag.SHA512: + return ChefFlagStrings.SHA512Long; + case ChefFlag.SpamSum: + return ChefFlagStrings.SpamSumLong; + case ChefFlag.StopOnError: + return ChefFlagStrings.StopOnErrorLong; + case ChefFlag.Tape: + return ChefFlagStrings.TapeLong; + case ChefFlag.Trim: + return ChefFlagStrings.TrimLong; + case ChefFlag.Verbose: + return ChefFlagStrings.VerboseLong; + case ChefFlag.VerifyDisc: + return ChefFlagStrings.VerifyDiscLong; + case ChefFlag.VerifySectors: + return ChefFlagStrings.VerifySectorsLong; + case ChefFlag.WholeDisc: + return ChefFlagStrings.WholeDiscLong; + + // Int8 flags + case ChefFlag.Speed: + return ChefFlagStrings.SpeedLong; + + // Int16 flags + case ChefFlag.RetryPasses: + return ChefFlagStrings.RetryPassesLong; + case ChefFlag.Width: + return ChefFlagStrings.WidthLong; + + // Int32 flags + case ChefFlag.BlockSize: + return ChefFlagStrings.BlockSizeLong; + case ChefFlag.Count: + return ChefFlagStrings.CountLong; + case ChefFlag.MediaLastSequence: + return ChefFlagStrings.MediaLastSequenceLong; + case ChefFlag.MediaSequence: + return ChefFlagStrings.MediaSequenceLong; + case ChefFlag.Skip: + return ChefFlagStrings.SkipLong; + + // Int64 flags + case ChefFlag.Length: + return ChefFlagStrings.LengthLong; + case ChefFlag.Start: + return ChefFlagStrings.StartLong; + + // String flags + case ChefFlag.Comments: + return ChefFlagStrings.CommentsLong; + case ChefFlag.Creator: + return ChefFlagStrings.CreatorLong; + case ChefFlag.DriveManufacturer: + return ChefFlagStrings.DriveManufacturerLong; + case ChefFlag.DriveModel: + return ChefFlagStrings.DriveModelLong; + case ChefFlag.DriveRevision: + return ChefFlagStrings.DriveRevisionLong; + case ChefFlag.DriveSerial: + return ChefFlagStrings.DriveSerialLong; + case ChefFlag.Encoding: + return ChefFlagStrings.EncodingLong; + case ChefFlag.FormatConvert: + return ChefFlagStrings.FormatConvertLong; + case ChefFlag.FormatDump: + return ChefFlagStrings.FormatDumpLong; + case ChefFlag.ImgBurnLog: + return ChefFlagStrings.ImgBurnLogLong; + case ChefFlag.MediaBarcode: + return ChefFlagStrings.MediaBarcodeLong; + case ChefFlag.MediaManufacturer: + return ChefFlagStrings.MediaManufacturerLong; + case ChefFlag.MediaModel: + return ChefFlagStrings.MediaModelLong; + case ChefFlag.MediaPartNumber: + return ChefFlagStrings.MediaPartNumberLong; + case ChefFlag.MediaSerial: + return ChefFlagStrings.MediaSerialLong; + case ChefFlag.MediaTitle: + return ChefFlagStrings.MediaTitleLong; + case ChefFlag.MHDDLog: + return ChefFlagStrings.MHDDLogLong; + case ChefFlag.Namespace: + return ChefFlagStrings.NamespaceLong; + case ChefFlag.Options: + return ChefFlagStrings.OptionsLong; + case ChefFlag.OutputPrefix: + return ChefFlagStrings.OutputPrefixLong; + case ChefFlag.ResumeFile: + return ChefFlagStrings.ResumeFileLong; + case ChefFlag.Subchannel: + return ChefFlagStrings.SubchannelLong; + case ChefFlag.XMLSidecar: + return ChefFlagStrings.XMLSidecarLong; + + case ChefFlag.NONE: + default: + return ""; + } + } + /// /// Get the string representation of the CreatorCommand enum values /// @@ -629,8 +882,6 @@ namespace DICUI.Utilities return CreatorFlagStrings.DisableBeep; case CreatorFlag.ForceUnitAccess: return CreatorFlagStrings.ForceUnitAccess; - case CreatorFlag.MCN: - return CreatorFlagStrings.MCN; case CreatorFlag.MultiSession: return CreatorFlagStrings.MultiSession; case CreatorFlag.NoFixSubP: @@ -2263,6 +2514,132 @@ namespace DICUI.Utilities } } + /// + /// Get the ChefCommand enum value for a given string + /// + /// First part of String value to convert + /// Second part of String value to convert + /// Output bool if the second command was used + /// ChefCommand represented by the string(s), if possible + public static ChefCommand StringToChefCommand(string commandOne, string commandTwo, out bool useSecond) + { + useSecond = false; + switch (commandOne) + { + // Database Family + case ChefCommandStrings.DatabasePrefixShort: + case ChefCommandStrings.DatabasePrefixLong: + useSecond = true; + switch (commandTwo) + { + case ChefCommandStrings.DatabaseStats: + return ChefCommand.DatabaseStats; + case ChefCommandStrings.DatabaseUpdate: + return ChefCommand.DatabaseUpdate; + } + + break; + + // Device Family + case ChefCommandStrings.DevicePrefixShort: + case ChefCommandStrings.DevicePrefixLong: + useSecond = true; + switch (commandTwo) + { + case ChefCommandStrings.DeviceInfo: + return ChefCommand.DeviceInfo; + case ChefCommandStrings.DeviceList: + return ChefCommand.DeviceList; + case ChefCommandStrings.DeviceReport: + return ChefCommand.DeviceReport; + } + + break; + + // Filesystem Family + case ChefCommandStrings.FilesystemPrefixShort: + case ChefCommandStrings.FilesystemPrefixShortAlt: + case ChefCommandStrings.FilesystemPrefixLong: + useSecond = true; + switch (commandTwo) + { + case ChefCommandStrings.FilesystemExtract: + return ChefCommand.FilesystemExtract; + case ChefCommandStrings.FilesystemListShort: + case ChefCommandStrings.FilesystemListLong: + return ChefCommand.FilesystemList; + case ChefCommandStrings.DatabaseStats: + return ChefCommand.FilesystemOptions; + } + + break; + + // Image Family + case ChefCommandStrings.ImagePrefixShort: + case ChefCommandStrings.ImagePrefixLong: + useSecond = true; + switch (commandTwo) + { + case ChefCommandStrings.ImageAnalyze: + return ChefCommand.ImageAnalyze; + case ChefCommandStrings.ImageChecksumShort: + case ChefCommandStrings.ImageChecksumLong: + return ChefCommand.ImageChecksum; + case ChefCommandStrings.ImageCompareShort: + case ChefCommandStrings.ImageCompareLong: + return ChefCommand.ImageCompare; + case ChefCommandStrings.ImageConvert: + return ChefCommand.ImageConvert; + case ChefCommandStrings.ImageCreateSidecar: + return ChefCommand.ImageCreateSidecar; + case ChefCommandStrings.ImageDecode: + return ChefCommand.ImageDecode; + case ChefCommandStrings.ImageEntropy: + return ChefCommand.ImageEntropy; + case ChefCommandStrings.ImageInfo: + return ChefCommand.ImageInfo; + case ChefCommandStrings.ImageOptions: + return ChefCommand.ImageOptions; + case ChefCommandStrings.ImagePrint: + return ChefCommand.ImagePrint; + case ChefCommandStrings.ImageVerify: + return ChefCommand.ImageVerify; + } + + break; + + // Media Family + case ChefCommandStrings.MediaPrefixShort: + case ChefCommandStrings.MediaPrefixLong: + useSecond = true; + switch (commandTwo) + { + case ChefCommandStrings.MediaDump: + return ChefCommand.MediaDump; + case ChefCommandStrings.MediaInfo: + return ChefCommand.MediaInfo; + case ChefCommandStrings.MediaScan: + return ChefCommand.MediaScan; + } + + break; + + // Standalone Commands + case ChefCommandStrings.Configure: + return ChefCommand.Configure; + case ChefCommandStrings.Formats: + return ChefCommand.Formats; + case ChefCommandStrings.ListEncodings: + return ChefCommand.ListEncodings; + case ChefCommandStrings.ListNamespaces: + return ChefCommand.ListNamespaces; + case ChefCommandStrings.Remote: + return ChefCommand.Remote; + } + + return ChefCommand.NONE; + } + /// /// Get the KnownSystem enum value for a given string /// diff --git a/DICUI.Library/Utilities/CreatorParameters.cs b/DICUI.Library/Utilities/CreatorParameters.cs index 09806404..25cb6d0d 100644 --- a/DICUI.Library/Utilities/CreatorParameters.cs +++ b/DICUI.Library/Utilities/CreatorParameters.cs @@ -8,7 +8,7 @@ using DICUI.Data; namespace DICUI.Utilities { /// - /// Represents a generic set of DiscImageCreator parameters + /// Represents a generic set of DiscImageCreator parameters /// public class CreatorParameters { @@ -66,7 +66,7 @@ namespace DICUI.Utilities } internal IEnumerable Keys => _flags.Keys; - #region DIC Flag Values + #region DiscImageCreator Flag Values /// /// Manual offset for Audio CD @@ -122,7 +122,7 @@ namespace DICUI.Utilities #endregion /// - /// Populate a Parameters object from a param string + /// Populate a CreatorParameters object from a param string /// /// String possibly representing a set of parameters public CreatorParameters(string parameters) @@ -342,8 +342,7 @@ namespace DICUI.Utilities } // Add Offset - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc) + if (GetSupportedCommands(CreatorFlag.AddOffset).Contains(Command)) { if (this[CreatorFlag.AddOffset]) { @@ -356,25 +355,21 @@ namespace DICUI.Utilities } // AMSF Dumping - if (Command == CreatorCommand.CompactDisc) + if (GetSupportedCommands(CreatorFlag.AMSF).Contains(Command)) { if (this[CreatorFlag.AMSF]) parameters.Add(CreatorFlag.AMSF.LongName()); } // Atari Jaguar CD - if (Command == CreatorCommand.CompactDisc) + if (GetSupportedCommands(CreatorFlag.AtariJaguar).Contains(Command)) { if (this[CreatorFlag.AtariJaguar]) parameters.Add(CreatorFlag.AtariJaguar.LongName()); } // BE Opcode - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.BEOpcode).Contains(Command)) { if (this[CreatorFlag.BEOpcode] && !this[CreatorFlag.D8Opcode]) { @@ -386,11 +381,7 @@ namespace DICUI.Utilities } // C2 Opcode - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.C2Opcode).Contains(Command)) { if (this[CreatorFlag.C2Opcode]) { @@ -427,45 +418,28 @@ namespace DICUI.Utilities } // Copyright Management Information - if (Command == CreatorCommand.DigitalVideoDisc) + if (GetSupportedCommands(CreatorFlag.CopyrightManagementInformation).Contains(Command)) { if (this[CreatorFlag.CopyrightManagementInformation]) parameters.Add(CreatorFlag.CopyrightManagementInformation.LongName()); } // D8 Opcode - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.D8Opcode).Contains(Command)) { if (this[CreatorFlag.D8Opcode]) parameters.Add(CreatorFlag.D8Opcode.LongName()); } // Disable Beep - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.BluRay - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.DigitalVideoDisc - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap - || Command == CreatorCommand.XBOX) + if (GetSupportedCommands(CreatorFlag.DisableBeep).Contains(Command)) { if (this[CreatorFlag.DisableBeep]) parameters.Add(CreatorFlag.DisableBeep.LongName()); } // Force Unit Access - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.BluRay - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.DigitalVideoDisc - || Command == CreatorCommand.Swap - || Command == CreatorCommand.XBOX) + if (GetSupportedCommands(CreatorFlag.ForceUnitAccess).Contains(Command)) { if (this[CreatorFlag.ForceUnitAccess]) { @@ -475,80 +449,50 @@ namespace DICUI.Utilities } } - // MCN - if (Command == CreatorCommand.CompactDisc) - { - if (this[CreatorFlag.MCN]) - parameters.Add(CreatorFlag.MCN.LongName()); - } - // Multi-Session - if (Command == CreatorCommand.CompactDisc) + if (GetSupportedCommands(CreatorFlag.MultiSession).Contains(Command)) { if (this[CreatorFlag.MultiSession]) parameters.Add(CreatorFlag.MultiSession.LongName()); } // Not fix SubP - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.NoFixSubP).Contains(Command)) { if (this[CreatorFlag.NoFixSubP]) parameters.Add(CreatorFlag.NoFixSubP.LongName()); } // Not fix SubQ - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.NoFixSubQ).Contains(Command)) { if (this[CreatorFlag.NoFixSubQ]) parameters.Add(CreatorFlag.NoFixSubQ.LongName()); } // Not fix SubQ (PlayStation LibCrypt) - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.NoFixSubQLibCrypt).Contains(Command)) { if (this[CreatorFlag.NoFixSubQLibCrypt]) parameters.Add(CreatorFlag.NoFixSubQLibCrypt.LongName()); } // Not fix SubQ (SecuROM) - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.NoFixSubQSecuROM).Contains(Command)) { if (this[CreatorFlag.NoFixSubQSecuROM]) parameters.Add(CreatorFlag.NoFixSubQSecuROM.LongName()); } // Not fix SubRtoW - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.NoFixSubRtoW).Contains(Command)) { if (this[CreatorFlag.NoFixSubRtoW]) parameters.Add(CreatorFlag.NoFixSubRtoW.LongName()); } // Not skip security sectors - if (Command == CreatorCommand.XBOX - || Command == CreatorCommand.XBOXSwap - || Command == CreatorCommand.XGD2Swap - || Command == CreatorCommand.XGD3Swap) + if (GetSupportedCommands(CreatorFlag.NoSkipSS).Contains(Command)) { if (this[CreatorFlag.NoSkipSS]) { @@ -559,35 +503,28 @@ namespace DICUI.Utilities } // Raw read (2064 byte/sector) - if (Command == CreatorCommand.DigitalVideoDisc) + if (GetSupportedCommands(CreatorFlag.Raw).Contains(Command)) { if (this[CreatorFlag.Raw]) parameters.Add(CreatorFlag.Raw.LongName()); } // Reverse read - if (Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.DigitalVideoDisc) + if (GetSupportedCommands(CreatorFlag.Reverse).Contains(Command)) { if (this[CreatorFlag.Reverse]) parameters.Add(CreatorFlag.Reverse.LongName()); } // Scan PlayStation anti-mod strings - if (Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data) + if (GetSupportedCommands(CreatorFlag.ScanAntiMod).Contains(Command)) { if (this[CreatorFlag.ScanAntiMod]) parameters.Add(CreatorFlag.ScanAntiMod.LongName()); } // Scan file to detect protect - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.DigitalVideoDisc - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.ScanFileProtect).Contains(Command)) { if (this[CreatorFlag.ScanFileProtect]) { @@ -603,23 +540,21 @@ namespace DICUI.Utilities } // Scan file to detect protect - if (Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.ScanSectorProtect).Contains(Command)) { if (this[CreatorFlag.ScanSectorProtect]) parameters.Add(CreatorFlag.ScanSectorProtect.LongName()); } // Scan 74:00:00 (Saturn) - if (Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.SeventyFour).Contains(Command)) { if (this[CreatorFlag.SeventyFour]) parameters.Add(CreatorFlag.SeventyFour.LongName()); } // Skip sectors - if (Command == CreatorCommand.Data) + if (GetSupportedCommands(CreatorFlag.SkipSector).Contains(Command)) { if (this[CreatorFlag.SkipSector]) { @@ -640,11 +575,7 @@ namespace DICUI.Utilities } // Set Subchannel read level - if (Command == CreatorCommand.Audio - || Command == CreatorCommand.CompactDisc - || Command == CreatorCommand.Data - || Command == CreatorCommand.GDROM - || Command == CreatorCommand.Swap) + if (GetSupportedCommands(CreatorFlag.SubchannelReadLevel).Contains(Command)) { if (this[CreatorFlag.SubchannelReadLevel]) { @@ -660,7 +591,7 @@ namespace DICUI.Utilities } // VideoNow - if (Command == CreatorCommand.CompactDisc) + if (GetSupportedCommands(CreatorFlag.VideoNow).Contains(Command)) { if (this[CreatorFlag.VideoNow]) { @@ -676,7 +607,7 @@ namespace DICUI.Utilities } // VideoNow Color - if (Command == CreatorCommand.CompactDisc) + if (GetSupportedCommands(CreatorFlag.VideoNowColor).Contains(Command)) { if (this[CreatorFlag.VideoNowColor]) parameters.Add(CreatorFlag.VideoNowColor.LongName()); @@ -1103,8 +1034,7 @@ namespace DICUI.Utilities switch (parts[i]) { case CreatorFlagStrings.AddOffset: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.AddOffset).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) return false; @@ -1117,24 +1047,21 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.AMSF: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.AMSF).Contains(Command)) return false; this[CreatorFlag.AMSF] = true; break; case CreatorFlagStrings.AtariJaguar: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.AtariJaguar).Contains(Command)) return false; this[CreatorFlag.AtariJaguar] = true; break; case CreatorFlagStrings.BEOpcode: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.BEOpcode).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) { @@ -1155,10 +1082,7 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.C2Opcode: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.C2Opcode).Contains(Command)) return false; this[CreatorFlag.C2Opcode] = true; @@ -1180,43 +1104,28 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.CopyrightManagementInformation: - if (parts[0] != CreatorCommandStrings.DigitalVideoDisc) + if (!GetSupportedCommands(CreatorFlag.CopyrightManagementInformation).Contains(Command)) return false; this[CreatorFlag.CopyrightManagementInformation] = true; break; case CreatorFlagStrings.D8Opcode: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.D8Opcode).Contains(Command)) return false; this[CreatorFlag.D8Opcode] = true; break; case CreatorFlagStrings.DisableBeep: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.BluRay - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.DigitalVideoDisc - && parts[0] != CreatorCommandStrings.GDROM - && parts[0] != CreatorCommandStrings.XBOX) + if (!GetSupportedCommands(CreatorFlag.DisableBeep).Contains(Command)) return false; this[CreatorFlag.DisableBeep] = true; break; case CreatorFlagStrings.ForceUnitAccess: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.BluRay - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.DigitalVideoDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM - && parts[0] != CreatorCommandStrings.XBOX) + if (!GetSupportedCommands(CreatorFlag.ForceUnitAccess).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) { @@ -1236,72 +1145,50 @@ namespace DICUI.Utilities i++; break; - case CreatorFlagStrings.MCN: - if (parts[0] != CreatorCommandStrings.CompactDisc) - return false; - - this[CreatorFlag.MCN] = true; - break; - case CreatorFlagStrings.MultiSession: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.MultiSession).Contains(Command)) return false; this[CreatorFlag.MultiSession] = true; break; case CreatorFlagStrings.NoFixSubP: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.NoFixSubP).Contains(Command)) return false; this[CreatorFlag.NoFixSubP] = true; break; case CreatorFlagStrings.NoFixSubQ: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.NoFixSubQ).Contains(Command)) return false; this[CreatorFlag.NoFixSubQ] = true; break; case CreatorFlagStrings.NoFixSubQLibCrypt: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.NoFixSubQLibCrypt).Contains(Command)) return false; this[CreatorFlag.NoFixSubQLibCrypt] = true; break; case CreatorFlagStrings.NoFixSubRtoW: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.NoFixSubRtoW).Contains(Command)) return false; this[CreatorFlag.NoFixSubRtoW] = true; break; case CreatorFlagStrings.NoFixSubQSecuROM: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.NoFixSubQSecuROM).Contains(Command)) return false; this[CreatorFlag.NoFixSubQSecuROM] = true; break; case CreatorFlagStrings.NoSkipSS: - if (parts[0] != CreatorCommandStrings.XBOX - && parts[0] != CreatorCommandStrings.XBOXSwap - && parts[0] != CreatorCommandStrings.XGD2Swap - && parts[0] != CreatorCommandStrings.XGD3Swap) + if (!GetSupportedCommands(CreatorFlag.NoSkipSS).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) { @@ -1322,32 +1209,28 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.Raw: - if (parts[0] != CreatorCommandStrings.DigitalVideoDisc) + if (!GetSupportedCommands(CreatorFlag.Raw).Contains(Command)) return false; this[CreatorFlag.Raw] = true; break; case CreatorFlagStrings.Reverse: - if (parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.DigitalVideoDisc) + if (!GetSupportedCommands(CreatorFlag.Reverse).Contains(Command)) return false; this[CreatorFlag.Reverse] = true; break; case CreatorFlagStrings.ScanAntiMod: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.ScanAntiMod).Contains(Command)) return false; this[CreatorFlag.ScanAntiMod] = true; break; case CreatorFlagStrings.ScanFileProtect: - if (parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.DigitalVideoDisc) + if (!GetSupportedCommands(CreatorFlag.ScanFileProtect).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) { @@ -1368,22 +1251,21 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.ScanSectorProtect: - if (parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data) + if (!GetSupportedCommands(CreatorFlag.ScanSectorProtect).Contains(Command)) return false; this[CreatorFlag.ScanSectorProtect] = true; break; case CreatorFlagStrings.SeventyFour: - if (parts[0] != CreatorCommandStrings.Swap) + if (!GetSupportedCommands(CreatorFlag.SeventyFour).Contains(Command)) return false; this[CreatorFlag.SeventyFour] = true; break; case CreatorFlagStrings.SkipSector: - if (parts[0] != CreatorCommandStrings.Data) + if (!GetSupportedCommands(CreatorFlag.SkipSector).Contains(Command)) return false; else if (!DoesExist(parts, i + 1) || !DoesExist(parts, i + 2)) return false; @@ -1399,10 +1281,7 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.SubchannelReadLevel: - if (parts[0] != CreatorCommandStrings.Audio - && parts[0] != CreatorCommandStrings.CompactDisc - && parts[0] != CreatorCommandStrings.Data - && parts[0] != CreatorCommandStrings.GDROM) + if (!GetSupportedCommands(CreatorFlag.SubchannelReadLevel).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) { @@ -1423,7 +1302,7 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.VideoNow: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.VideoNow).Contains(Command)) return false; else if (!DoesExist(parts, i + 1)) { @@ -1444,7 +1323,7 @@ namespace DICUI.Utilities break; case CreatorFlagStrings.VideoNowColor: - if (parts[0] != CreatorCommandStrings.CompactDisc) + if (!GetSupportedCommands(CreatorFlag.VideoNowColor).Contains(Command)) return false; this[CreatorFlag.VideoNowColor] = true; @@ -1460,18 +1339,174 @@ namespace DICUI.Utilities } /// - /// Returns whether a string is a valid drive letter + /// Returns whether or not the selected item exists /// - /// String value to check - /// True if it's a valid drive letter, false otherwise - private bool IsValidDriveLetter(string parameter) + /// List of parameters to check against + /// Current index + /// True if the next item exists, false otherwise + private bool DoesExist(List parameters, int index) { - if (!Regex.IsMatch(parameter, @"^[A-Z]:?\\?$")) + if (index >= parameters.Count) return false; return true; } + /// + /// Get the list of commands that use a given flag + /// + /// Flag value to get commands for + /// List of ChefCommands, if possible + private List GetSupportedCommands(CreatorFlag flag) + { + var commands = new List(); + switch (flag) + { + case CreatorFlag.AMSF: + commands.Add(CreatorCommand.CompactDisc); + break; + case CreatorFlag.AtariJaguar: + commands.Add(CreatorCommand.CompactDisc); + break; + case CreatorFlag.BEOpcode: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.C2Opcode: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.CopyrightManagementInformation: + commands.Add(CreatorCommand.DigitalVideoDisc); + break; + case CreatorFlag.D8Opcode: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.DisableBeep: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.BluRay); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.DigitalVideoDisc); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + commands.Add(CreatorCommand.XBOX); + break; + case CreatorFlag.ForceUnitAccess: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.BluRay); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.DigitalVideoDisc); + commands.Add(CreatorCommand.Swap); + commands.Add(CreatorCommand.XBOX); + break; + case CreatorFlag.MultiSession: + commands.Add(CreatorCommand.CompactDisc); + break; + case CreatorFlag.NoFixSubP: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.NoFixSubQ: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.NoFixSubQLibCrypt: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.NoFixSubQSecuROM: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.NoFixSubRtoW: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.NoSkipSS: + commands.Add(CreatorCommand.XBOX); + commands.Add(CreatorCommand.XBOXSwap); + commands.Add(CreatorCommand.XGD2Swap); + commands.Add(CreatorCommand.XGD3Swap); + break; + case CreatorFlag.Raw: + commands.Add(CreatorCommand.DigitalVideoDisc); + break; + case CreatorFlag.Reverse: + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.DigitalVideoDisc); + break; + case CreatorFlag.ScanAntiMod: + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + break; + case CreatorFlag.ScanFileProtect: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.DigitalVideoDisc); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.ScanSectorProtect: + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.SeventyFour: + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.SkipSector: + commands.Add(CreatorCommand.Data); + break; + case CreatorFlag.SubchannelReadLevel: + commands.Add(CreatorCommand.Audio); + commands.Add(CreatorCommand.CompactDisc); + commands.Add(CreatorCommand.Data); + commands.Add(CreatorCommand.GDROM); + commands.Add(CreatorCommand.Swap); + break; + case CreatorFlag.VideoNow: + commands.Add(CreatorCommand.CompactDisc); + break; + case CreatorFlag.VideoNowColor: + commands.Add(CreatorCommand.CompactDisc); + break; + + case CreatorFlag.NONE: + default: + return commands; + } + + return commands; + } + /// /// Returns whether a string is a flag (starts with '/') /// @@ -1486,14 +1521,13 @@ namespace DICUI.Utilities } /// - /// Returns whether or not the selected item exists + /// Returns whether a string is a valid drive letter /// - /// List of parameters to check against - /// Current index - /// True if the next item exists, false otherwise - private bool DoesExist(List parameters, int index) + /// String value to check + /// True if it's a valid drive letter, false otherwise + private bool IsValidDriveLetter(string parameter) { - if (index >= parameters.Count) + if (!Regex.IsMatch(parameter, @"^[A-Z]:?\\?$")) return false; return true; @@ -1640,9 +1674,6 @@ namespace DICUI.Utilities this[CreatorFlag.VideoNow] = true; this.VideoNowValue = 20832; break; - case KnownSystem.NECPCEngineTurboGrafxCD: - this[CreatorFlag.MCN] = true; - break; case KnownSystem.SonyPlayStation: this[CreatorFlag.ScanAntiMod] = true; this[CreatorFlag.NoFixSubQLibCrypt] = true; diff --git a/DICUI.Library/Utilities/DumpEnvironment.cs b/DICUI.Library/Utilities/DumpEnvironment.cs index 89db768e..36084995 100644 --- a/DICUI.Library/Utilities/DumpEnvironment.cs +++ b/DICUI.Library/Utilities/DumpEnvironment.cs @@ -20,16 +20,26 @@ namespace DICUI.Utilities { #region Tool paths + /// + /// Path to DiscImageChef executable + /// + public string ChefPath { get; set; } + /// /// Path to DiscImageCreator executable /// - public string DICPath { get; set; } + public string CreatorPath { get; set; } /// /// Path to Subdump executable /// public string SubdumpPath { get; set; } + /// + /// Use DiscImageChef instead of DiscImageCreator + /// + public bool UseChef { get; set; } + #endregion #region Output paths @@ -63,11 +73,21 @@ namespace DICUI.Utilities /// public MediaType? Type { get; set; } + /// + /// Parameters object representing what to send to DiscImageChef + /// + public ChefParameters ChefParameters { get; set; } + /// /// Parameters object representing what to send to DiscImageCreator /// public CreatorParameters CreatorParameters { get; set; } + /// + /// Scan for copy protection, where applicable + /// + public bool ScanForProtection { get; set; } + /// /// Determines if placeholder values should be set for fields /// @@ -80,7 +100,7 @@ namespace DICUI.Utilities #endregion - #region Extra DIC arguments + #region Extra DiscImageCreator arguments /// /// Enable quiet mode (no beeps) @@ -92,11 +112,6 @@ namespace DICUI.Utilities /// public bool ParanoidMode { get; set; } - /// - /// Scan for copy protection, where applicable - /// - public bool ScanForProtection { get; set; } - /// /// Number of C2 error reread attempts /// @@ -155,7 +170,7 @@ namespace DICUI.Utilities public async Task DriveHasLatestFimrware() { // Validate that the required program exists - if (!File.Exists(DICPath)) + if (!File.Exists(CreatorPath)) return false; CreatorParameters parameters = new CreatorParameters(string.Empty) @@ -180,7 +195,7 @@ namespace DICUI.Utilities public async void EjectDisc() { // Validate that the required program exists - if (!File.Exists(DICPath)) + if (!File.Exists(CreatorPath)) return; CancelDumping(); @@ -272,6 +287,18 @@ namespace DICUI.Utilities // Now ensure that all required files exist string combinedBase = Path.Combine(OutputDirectory, outputFilename); + + // If we're using DiscImageChef, the outputs are consistent + if (UseChef) + { + return File.Exists(combinedBase + ".cicm.xml") + && File.Exists(combinedBase + ".dicf") + && File.Exists(combinedBase + ".ibg") + && File.Exists(combinedBase + ".log") + && File.Exists(combinedBase + ".mhddlog.bin") + && File.Exists(combinedBase + ".resume.xml"); + } + switch (Type) { case MediaType.CDROM: @@ -327,7 +354,7 @@ namespace DICUI.Utilities } /// - /// Get the full parameter string for DIC + /// Get the full parameter string for either DiscImageCreator or DiscImageChef /// /// Nullable int representing the drive speed /// String representing the params, null on error @@ -342,12 +369,23 @@ namespace DICUI.Utilities // Set the proper parameters string filename = OutputDirectory + Path.DirectorySeparatorChar + OutputFilename; - CreatorParameters = new CreatorParameters(System, Type, Drive.Letter, filename, driveSpeed, ParanoidMode, RereadAmountC2); - if (QuietMode) - CreatorParameters[CreatorFlag.DisableBeep] = true; - // Generate and return the param string - return CreatorParameters.GenerateParameters(); + if (UseChef) + { + ChefParameters = new ChefParameters(System, Type, Drive.Letter, filename, driveSpeed, ParanoidMode, RereadAmountC2); + + // Generate and return the param string + return ChefParameters.GenerateParameters(); + } + else + { + CreatorParameters = new CreatorParameters(System, Type, Drive.Letter, filename, driveSpeed, ParanoidMode, RereadAmountC2); + if (QuietMode) + CreatorParameters[CreatorFlag.DisableBeep] = true; + + // Generate and return the param string + return CreatorParameters.GenerateParameters(); + } } return null; @@ -359,7 +397,7 @@ namespace DICUI.Utilities public async void ResetDrive() { // Validate that the required program exists - if (!File.Exists(DICPath)) + if (!File.Exists(CreatorPath)) return; // Precautionary check for dumping, just in case @@ -385,7 +423,7 @@ namespace DICUI.Utilities { Result result = IsValidForDump(); - // Execute DIC and external tools, if needed + // Execute dumping program and external tools, if needed if (Validators.GetSupportStatus(System, Type) && !result.Message.Contains("not supported") // Completely unsupported media && !result.Message.Contains("submission info")) // Submission info-only media @@ -394,13 +432,22 @@ namespace DICUI.Utilities if (!result) return result; - progress?.Report(Result.Success("Executing DiscImageCreator... please wait!")); - await Task.Run(() => ExecuteDiskImageCreator()); - progress?.Report(Result.Success("DiscImageCreator has finished!")); + if (UseChef) + { + progress?.Report(Result.Success("Executing DiscImageChef... please wait!")); + await Task.Run(() => ExecuteDiscImageChef()); + progress?.Report(Result.Success("DiscImageChef has finished!")); + } + else + { + progress?.Report(Result.Success("Executing DiscImageCreator... please wait!")); + await Task.Run(() => ExecuteDiscImageCreator()); + progress?.Report(Result.Success("DiscImageCreator has finished!")); + } // Execute additional tools progress?.Report(Result.Success("Running any additional tools... please wait!")); - result = await Task.Run(() => ExecuteAdditionalToolsAfterDIC()); + result = await Task.Run(() => ExecuteAdditionalTools()); progress?.Report(result); } @@ -470,7 +517,13 @@ namespace DICUI.Utilities /// True if the configuration is valid, false otherwise internal bool ParametersValid() { - return CreatorParameters.IsValid() + bool parametersValid = false; + if (UseChef) + parametersValid = ChefParameters.IsValid(); + else + parametersValid = CreatorParameters.IsValid(); + + return parametersValid && !(Drive.InternalDriveType == InternalDriveType.Floppy ^ Type == MediaType.FloppyDisk) && !(Drive.InternalDriveType == InternalDriveType.HardDisk ^ Type == MediaType.HardDisk) && !(Drive.InternalDriveType == InternalDriveType.Removable ^ (Type == MediaType.CompactFlash || Type == MediaType.SDCard || Type == MediaType.FlashDrive)); @@ -484,7 +537,7 @@ namespace DICUI.Utilities /// Run any additional tools given a DumpEnvironment /// /// Result instance with the outcome - private Result ExecuteAdditionalToolsAfterDIC() + private Result ExecuteAdditionalTools() { // Special cases switch (System) @@ -500,16 +553,72 @@ namespace DICUI.Utilities return Result.Success("No external tools needed!"); } + /// + /// Run DiscImageChef + /// + private void ExecuteDiscImageChef() + { + Directory.CreateDirectory(OutputDirectory); + + dicProcess = new Process() + { + StartInfo = new ProcessStartInfo() + { + FileName = ChefPath, + Arguments = ChefParameters.GenerateParameters() ?? "", + }, + }; + dicProcess.Start(); + dicProcess.WaitForExit(); + } + + /// + /// Run DiscImageChef async with an input set of parameters + /// + /// + /// Standard output from commandline window + private async Task ExecuteDiscImageChefWithParameters(ChefParameters parameters) + { + Process childProcess; + string output = await Task.Run(() => + { + childProcess = new Process() + { + StartInfo = new ProcessStartInfo() + { + FileName = ChefPath, + Arguments = parameters.GenerateParameters(), + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardInput = true, + RedirectStandardOutput = true, + }, + }; + childProcess.Start(); + childProcess.WaitForExit(1000); + + // Just in case, we want to push a button 5 times to clear any errors + for (int i = 0; i < 5; i++) + childProcess.StandardInput.WriteLine("Y"); + + string stdout = childProcess.StandardOutput.ReadToEnd(); + childProcess.Dispose(); + return stdout; + }); + + return output; + } + /// /// Run DiscImageCreator /// - private void ExecuteDiskImageCreator() + private void ExecuteDiscImageCreator() { dicProcess = new Process() { StartInfo = new ProcessStartInfo() { - FileName = DICPath, + FileName = CreatorPath, Arguments = CreatorParameters.GenerateParameters() ?? "", }, }; @@ -518,7 +627,7 @@ namespace DICUI.Utilities } /// - /// Run DIC async with an input set of parameters + /// Run DiscImageCreator async with an input set of parameters /// /// /// Standard output from commandline window @@ -531,7 +640,7 @@ namespace DICUI.Utilities { StartInfo = new ProcessStartInfo() { - FileName = DICPath, + FileName = CreatorPath, Arguments = parameters.GenerateParameters(), CreateNoWindow = true, UseShellExecute = false, @@ -588,6 +697,21 @@ namespace DICUI.Utilities // Sanitize the output filename to strip off any potential extension string outputFilename = Path.GetFileNameWithoutExtension(OutputFilename); + // TODO: Notes about DiscImageChef outputs: + // - All hash data is stored in the CICM XML sidecar + // - The path to all track hashes is CICMMetadata.OpticalDisc.Track() + // - Each track has a billion hashes under a Checksums.Checksum() element + // - Checksum type is defined as type="x" - use crc32, md, sha1 + // - Track sizes are under a Size() element + // - Also cotnains a Sequence() element that has TrackNumber() and Session() + // - Currently does not automatically output a CUE, see if this data + // can be used to generate a CUE? + // - When using DICF, Tracks are not named, just numbered. Will need + // to be generated when creating the pseudo-dat + // - `image convert` might be able to help generate CUE, CCD, SUB? + // - CICMMetadata.OpticalDisc.Tracks() and .Sessions() might both be helpful + // - NEED CONFIRMATION OF TRACK SPLITTING ON CD + // Check that all of the relevant files are there if (!FoundAllFiles()) return null; @@ -1338,7 +1462,9 @@ namespace DICUI.Utilities FixOutputPaths(); // Validate that the required program exists - if (!File.Exists(DICPath)) + if (UseChef && !File.Exists(ChefPath)) + return Result.Failure("Error! Could not find DiscImageChef!"); + else if (!UseChef && !File.Exists(CreatorPath)) return Result.Failure("Error! Could not find DiscImageCreator!"); // TODO: Ensure output path not the same as input drive OR DIC/DICUI location diff --git a/DICUI.Library/Utilities/Extensions.cs b/DICUI.Library/Utilities/Extensions.cs index ea249c43..03cd2501 100644 --- a/DICUI.Library/Utilities/Extensions.cs +++ b/DICUI.Library/Utilities/Extensions.cs @@ -188,6 +188,15 @@ namespace DICUI.Utilities RedumpSystem.SonyPlayStation3, }; + /// + /// List of systems that has an LSD pack + /// + public static readonly RedumpSystem[] HasLsd = new RedumpSystem[] + { + RedumpSystem.IBMPCcompatible, + RedumpSystem.SonyPlayStation, + }; + /// /// List of systems that has an SBI pack /// diff --git a/DICUI.Test/Utilities/ConvertersTest.cs b/DICUI.Test/Utilities/ConvertersTest.cs index 09fecb3f..fbf31957 100644 --- a/DICUI.Test/Utilities/ConvertersTest.cs +++ b/DICUI.Test/Utilities/ConvertersTest.cs @@ -65,7 +65,7 @@ namespace DICUI.Test.Utilities [InlineData(MediaType.NONE, null)] public void MediaTypeToExtensionTest(MediaType? mediaType, string expected) { - string actual = Converters.Extension(mediaType); + string actual = Converters.Extension(mediaType, false); Assert.Equal(expected, actual); } diff --git a/DICUI.Test/Utilities/MediaTypeExtensionsTest.cs b/DICUI.Test/Utilities/MediaTypeExtensionsTest.cs index 30eaf099..3c253bba 100644 --- a/DICUI.Test/Utilities/MediaTypeExtensionsTest.cs +++ b/DICUI.Test/Utilities/MediaTypeExtensionsTest.cs @@ -26,7 +26,7 @@ namespace DICUI.Test.Utilities [InlineData(MediaType.NONE, null)] public void ExtensionTest(MediaType? mediaType, string expected) { - string actual = mediaType.Extension(); + string actual = mediaType.Extension(false); Assert.Equal(expected, actual); } diff --git a/DICUI/App.config b/DICUI/App.config index 3bf5566e..34c102b3 100644 --- a/DICUI/App.config +++ b/DICUI/App.config @@ -1,9 +1,11 @@ - - + + + + diff --git a/DICUI/EnumDescriptionConverter.cs b/DICUI/EnumDescriptionConverter.cs index 589ce24f..eb7775b8 100644 --- a/DICUI/EnumDescriptionConverter.cs +++ b/DICUI/EnumDescriptionConverter.cs @@ -13,7 +13,11 @@ namespace DICUI { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - if (value is CreatorCommand) + if (value is ChefCommand) + return ((ChefCommand)value).LongName(); + else if (value is ChefFlag) + return ((ChefFlag)value).LongName(); + else if (value is CreatorCommand) return ((CreatorCommand)value).LongName(); else if (value is CreatorFlag) return ((CreatorFlag)value).LongName(); diff --git a/DICUI/Options.cs b/DICUI/Options.cs index a2fa239c..56b81bc3 100644 --- a/DICUI/Options.cs +++ b/DICUI/Options.cs @@ -9,9 +9,14 @@ namespace DICUI public class Options { public string DefaultOutputPath { get; private set; } - public string DICPath { get; private set; } + public string ChefPath { get; private set; } + public string CreatorPath { get; private set; } public string SubDumpPath { get; private set; } + // TODO: Change to string setting eventually to better support more tools + // TODO: Add to UI either as checkbox next to DiscImageChef or by making it a single select between both paths + public bool UseChef { get; set; } + public int PreferredDumpSpeedCD { get; set; } public int PreferredDumpSpeedDVD { get; set; } public int PreferredDumpSpeedBD { get; set; } @@ -56,9 +61,11 @@ namespace DICUI Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); //TODO: hardcoded, we should find a better way - this.DICPath = GetStringSetting(configFile, "DICPath", "Programs\\DiscImageCreator.exe"); + this.ChefPath = GetStringSetting(configFile, "ChefPath", "Programs\\DiscImageChef.exe"); + this.CreatorPath = GetStringSetting(configFile, "CreatorPath", "Programs\\DiscImageCreator.exe"); this.SubDumpPath = GetStringSetting(configFile, "SubDumpPath", "subdump.exe"); this.DefaultOutputPath = GetStringSetting(configFile, "DefaultOutputPath", "ISO"); + this.UseChef = GetBooleanSetting(configFile, "UseChef", false); this.PreferredDumpSpeedCD = GetInt32Setting(configFile, "PreferredDumpSpeedCD", 72); this.PreferredDumpSpeedDVD = GetInt32Setting(configFile, "PreferredDumpSpeedDVD", 24); diff --git a/DICUI/ViewModels.cs b/DICUI/ViewModels.cs index f96186c5..2d01ec89 100644 --- a/DICUI/ViewModels.cs +++ b/DICUI/ViewModels.cs @@ -13,6 +13,12 @@ namespace DICUI this._options = options; } + public bool UseChef + { + get { return _options.UseChef; } + set { _options.UseChef = value; } + } + public bool QuietMode { get { return _options.QuietMode; } diff --git a/DICUI/Windows/MainWindow.xaml b/DICUI/Windows/MainWindow.xaml index 4f4491fe..9ee90947 100644 --- a/DICUI/Windows/MainWindow.xaml +++ b/DICUI/Windows/MainWindow.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DICUI" mc:Ignorable="d" - Title="Disc Image Creator GUI" Height="450" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize" + Title="DICUI" Height="450" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize" LocationChanged="MainWindowLocationChanged" Activated="MainWindowActivated" Closing="MainWindowClosing"> diff --git a/DICUI/Windows/MainWindow.xaml.cs b/DICUI/Windows/MainWindow.xaml.cs index 1ff01f43..5725f84a 100644 --- a/DICUI/Windows/MainWindow.xaml.cs +++ b/DICUI/Windows/MainWindow.xaml.cs @@ -444,8 +444,10 @@ namespace DICUI.Windows var env = new DumpEnvironment() { // Paths to tools + ChefPath = _options.ChefPath, + CreatorPath = _options.CreatorPath, SubdumpPath = _options.SubDumpPath, - DICPath = _options.DICPath, + UseChef = _options.UseChef, OutputDirectory = OutputDirectoryTextBox.Text, OutputFilename = OutputFilenameTextBox.Text, @@ -453,8 +455,6 @@ namespace DICUI.Windows // Get the currently selected options Drive = DriveLetterComboBox.SelectedItem as Drive, - CreatorParameters = new CreatorParameters(ParametersTextBox.Text), - QuietMode = _options.QuietMode, ParanoidMode = _options.ParanoidMode, ScanForProtection = _options.ScanForProtection, @@ -462,6 +462,9 @@ namespace DICUI.Windows AddPlaceholders = _options.AddPlaceholders, PromptForDiscInformation = _options.PromptForDiscInformation, + ChefParameters = new ChefParameters(ParametersTextBox.Text), + CreatorParameters = new CreatorParameters(ParametersTextBox.Text), + Username = _options.Username, Password = _options.Password, @@ -510,9 +513,9 @@ namespace DICUI.Windows try { - // Check for the firmware first + // Check for the firmware first for DiscImageCreator // TODO: Remove this (and method) once DIC end-to-end logging becomes a thing - if (!await _env.DriveHasLatestFimrware()) + if (!_env.UseChef && !await _env.DriveHasLatestFimrware()) { MessageBox.Show($"DiscImageCreator has reported that drive {_env.Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error); return; @@ -551,28 +554,37 @@ namespace DICUI.Windows if (result) { - // Verify dump output and save it - result = _env.VerifyAndSaveDumpOutput(progress, - EjectWhenDoneCheckBox.IsChecked, - _options.ResetDriveAfterDump, - (si) => - { + // TODO: Remove Chef handling when irrelevant + if (_env.UseChef) + { + ViewModels.LoggerViewModel.VerboseLogLn("DiscImageChef does not support split tracks or DiscImageCreator-compatible outputs"); + ViewModels.LoggerViewModel.VerboseLogLn("No automatic submission information will be gathered for this disc"); + } + else + { + // Verify dump output and save it + result = _env.VerifyAndSaveDumpOutput(progress, + EjectWhenDoneCheckBox.IsChecked, + _options.ResetDriveAfterDump, + (si) => + { // lazy initialization if (_discInformationWindow == null) - { - _discInformationWindow = new DiscInformationWindow(this, si); - _discInformationWindow.Closed += delegate { - _discInformationWindow = null; - }; - } + _discInformationWindow = new DiscInformationWindow(this, si); + _discInformationWindow.Closed += delegate + { + _discInformationWindow = null; + }; + } - _discInformationWindow.Owner = this; - _discInformationWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; - _discInformationWindow.Refresh(); - return _discInformationWindow.ShowDialog(); - } - ); + _discInformationWindow.Owner = this; + _discInformationWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; + _discInformationWindow.Refresh(); + return _discInformationWindow.ShowDialog(); + } + ); + } } StatusLabel.Content = result ? "Dumping complete!" : result.Message; @@ -640,11 +652,11 @@ namespace DICUI.Windows // Set the output filename, if we changed drives or it's not already if (driveChanged || string.IsNullOrEmpty(OutputFilenameTextBox.Text)) - OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? systemType.LongName()) + (mediaType.Extension() ?? ".bin"); + OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? systemType.LongName()) + (mediaType.Extension(_options.UseChef) ?? ".bin"); // If the extension for the file changed, update that automatically - else if (Path.GetExtension(OutputFilenameTextBox.Text) != mediaType.Extension()) - OutputFilenameTextBox.Text = Path.GetFileNameWithoutExtension(OutputFilenameTextBox.Text) + (mediaType.Extension() ?? ".bin"); + else if (Path.GetExtension(OutputFilenameTextBox.Text) != mediaType.Extension(_options.UseChef)) + OutputFilenameTextBox.Text = Path.GetFileNameWithoutExtension(OutputFilenameTextBox.Text) + (mediaType.Extension(_options.UseChef) ?? ".bin"); } /// @@ -763,34 +775,63 @@ namespace DICUI.Windows /// private void ProcessCustomParameters() { - _env.CreatorParameters = new CreatorParameters(ParametersTextBox.Text); + if (_options.UseChef) + { + _env.ChefParameters = new ChefParameters(ParametersTextBox.Text); - int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.CreatorParameters.DriveLetter[0]); - if (driveIndex > -1) - DriveLetterComboBox.SelectedIndex = driveIndex; + if (_env.ChefParameters == null) + return; - int driveSpeed = _env.CreatorParameters.DriveSpeed ?? -1; - if (driveSpeed > 0) - DriveSpeedComboBox.SelectedValue = driveSpeed; + int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.ChefParameters.InputValue[0]); + if (driveIndex > -1) + DriveLetterComboBox.SelectedIndex = driveIndex; + + string trimmedPath = _env.ChefParameters.OutputValue?.Trim('"') ?? string.Empty; + string outputDirectory = Path.GetDirectoryName(trimmedPath); + string outputFilename = Path.GetFileName(trimmedPath); + if (!string.IsNullOrWhiteSpace(outputDirectory)) + OutputDirectoryTextBox.Text = outputDirectory; + else + outputDirectory = OutputDirectoryTextBox.Text; + if (!string.IsNullOrWhiteSpace(outputFilename)) + OutputFilenameTextBox.Text = outputFilename; + else + outputFilename = OutputFilenameTextBox.Text; + } else - _env.CreatorParameters.DriveSpeed = (int?)DriveSpeedComboBox.SelectedValue; + { + _env.CreatorParameters = new CreatorParameters(ParametersTextBox.Text); - string trimmedPath = _env.CreatorParameters.Filename?.Trim('"') ?? string.Empty; - string outputDirectory = Path.GetDirectoryName(trimmedPath); - string outputFilename = Path.GetFileName(trimmedPath); - if (!string.IsNullOrWhiteSpace(outputDirectory)) - OutputDirectoryTextBox.Text = outputDirectory; - else - outputDirectory = OutputDirectoryTextBox.Text; - if (!string.IsNullOrWhiteSpace(outputFilename)) - OutputFilenameTextBox.Text = outputFilename; - else - outputFilename = OutputFilenameTextBox.Text; + if (_env.CreatorParameters == null) + return; - MediaType? mediaType = _env.CreatorParameters.Command.ToMediaType(); - int mediaTypeIndex = _mediaTypes.IndexOf(mediaType); - if (mediaTypeIndex > -1) - MediaTypeComboBox.SelectedIndex = mediaTypeIndex; + int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.CreatorParameters.DriveLetter[0]); + if (driveIndex > -1) + DriveLetterComboBox.SelectedIndex = driveIndex; + + int driveSpeed = _env.CreatorParameters.DriveSpeed ?? -1; + if (driveSpeed > 0) + DriveSpeedComboBox.SelectedValue = driveSpeed; + else + _env.CreatorParameters.DriveSpeed = (int?)DriveSpeedComboBox.SelectedValue; + + string trimmedPath = _env.CreatorParameters.Filename?.Trim('"') ?? string.Empty; + string outputDirectory = Path.GetDirectoryName(trimmedPath); + string outputFilename = Path.GetFileName(trimmedPath); + if (!string.IsNullOrWhiteSpace(outputDirectory)) + OutputDirectoryTextBox.Text = outputDirectory; + else + outputDirectory = OutputDirectoryTextBox.Text; + if (!string.IsNullOrWhiteSpace(outputFilename)) + OutputFilenameTextBox.Text = outputFilename; + else + outputFilename = OutputFilenameTextBox.Text; + + MediaType? mediaType = _env.CreatorParameters.Command.ToMediaType(); + int mediaTypeIndex = _mediaTypes.IndexOf(mediaType); + if (mediaTypeIndex > -1) + MediaTypeComboBox.SelectedIndex = mediaTypeIndex; + } } #endregion diff --git a/DICUI/Windows/OptionsWindow.xaml b/DICUI/Windows/OptionsWindow.xaml index 13a17cf2..1afc8ee9 100644 --- a/DICUI/Windows/OptionsWindow.xaml +++ b/DICUI/Windows/OptionsWindow.xaml @@ -5,11 +5,11 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DICUI" mc:Ignorable="d" - Title="Options" Width="515.132" Height="552"> + Title="Options" Width="515.132" Height="605"> - + @@ -29,19 +29,24 @@ + -