diff --git a/CICMMetadata b/CICMMetadata index 3df79256..97781ddc 160000 --- a/CICMMetadata +++ b/CICMMetadata @@ -1 +1 @@ -Subproject commit 3df79256d41193469126aedf9723021b7477a057 +Subproject commit 97781ddc50086a641ab2ae0816e0dd0298ab2ca5 diff --git a/DiscImageChef.Decoders/ChangeLog b/DiscImageChef.Decoders/ChangeLog index 5b8fc052..92476c16 100644 --- a/DiscImageChef.Decoders/ChangeLog +++ b/DiscImageChef.Decoders/ChangeLog @@ -1,3 +1,11 @@ +2016-10-17 Natalia Portillo + + * CIS.cs: + * Enums.cs: + * Types.cs: + * VendorCode.cs: + * DiscImageChef.Decoders.csproj: Added PCMCIA support. + 2016-10-16 Natalia Portillo * EVPD.cs: Corrected typo. Cleaned code. diff --git a/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj b/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj index 50a23ebd..1d4c624f 100644 --- a/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj +++ b/DiscImageChef.Decoders/DiscImageChef.Decoders.csproj @@ -93,6 +93,10 @@ + + + + @@ -115,6 +119,7 @@ + diff --git a/DiscImageChef.Decoders/PCMCIA/CIS.cs b/DiscImageChef.Decoders/PCMCIA/CIS.cs index 84608052..49753b26 100644 --- a/DiscImageChef.Decoders/PCMCIA/CIS.cs +++ b/DiscImageChef.Decoders/PCMCIA/CIS.cs @@ -29,13 +29,298 @@ // ---------------------------------------------------------------------------- // Copyright © 2011-2016 Natalia Portillo // ****************************************************************************/ + using System; +using System.Collections.Generic; +using System.Text; + namespace DiscImageChef.Decoders.PCMCIA { - public class CIS + public static class CIS { - public CIS() + // TODO: Handle links? Or are they removed in lower layers of the operating system drivers? + public static Tuple[] GetTuples(byte[] data) { + List tuples = new List(); + int position = 0; + + while(position < data.Length) + { + Tuple tuple = new Tuple(); + + tuple.Code = (TupleCodes)data[position]; + + if(tuple.Code == TupleCodes.CISTPL_NULL) + continue; + if(tuple.Code == TupleCodes.CISTPL_END) + break; + + tuple.Link = data[position + 1]; + + if(position + 2 + tuple.Link > data.Length) + break; + + tuple.Data = new byte[tuple.Link + 2]; + Array.Copy(data, position, tuple.Data, 0, tuple.Link + 2); + + tuples.Add(tuple); + position += tuple.Link + 2; + } + + return tuples.ToArray(); + } + + public static DeviceGeometryTuple DecodeDeviceGeometryTuple(Tuple tuple) + { + if(tuple == null) + return null; + + if(tuple.Code != TupleCodes.CISTPL_DEVICEGEO && tuple.Code != TupleCodes.CISTPL_DEVICEGEO_A) + return null; + + if(tuple.Data == null) + return null; + + return DecodeDeviceGeometryTuple(tuple.Data); + } + + public static DeviceGeometryTuple DecodeDeviceGeometryTuple(byte[] data) + { + if(data == null) + return null; + if((data.Length - 2) % 6 != 0) + return null; + + DeviceGeometryTuple tuple = new DeviceGeometryTuple(); + List geometries = new List(); + + for(int position = 2; position < data.Length; position += 6) + { + DeviceGeometry geometry = new DeviceGeometry(); + geometry.CardInterface = data[position]; + geometry.EraseBlockSize = data[position + 1]; + geometry.ReadBlockSize = data[position + 2]; + geometry.WriteBlockSize = data[position + 3]; + geometry.Partitions = data[position + 4]; + geometry.Interleaving = data[position + 5]; + geometries.Add(geometry); + } + + tuple.Code = (TupleCodes)data[0]; + tuple.Link = data[1]; + tuple.Geometries = geometries.ToArray(); + + return tuple; + } + + public static string PrettifyDeviceGeometryTuple(DeviceGeometryTuple tuple) + { + if(tuple == null) + return null; + + if(tuple.Code != TupleCodes.CISTPL_DEVICEGEO && tuple.Code != TupleCodes.CISTPL_DEVICEGEO_A) + return null; + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("PCMCIA Device Geometry Tuples:"); + foreach(DeviceGeometry geometry in tuple.Geometries) + { + sb.AppendLine("\tGeometry:"); + sb.AppendFormat("\t\tDevice width: {0} bits", (1 << (geometry.CardInterface - 1)) * 8).AppendLine(); + sb.AppendFormat("\t\tErase block = {0} bytes", (1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1))).AppendLine(); + sb.AppendFormat("\t\tRead block = {0} bytes", (1 << (geometry.ReadBlockSize - 1)) * (1 << (geometry.Interleaving - 1))).AppendLine(); + sb.AppendFormat("\t\tWrite block = {0} bytes", (1 << (geometry.WriteBlockSize - 1)) * (1 << (geometry.Interleaving - 1))).AppendLine(); + sb.AppendFormat("\t\tPartition alignment = {0} bytes", (1 << (geometry.EraseBlockSize - 1)) * (1 << (geometry.Interleaving - 1)) * (1 << (geometry.Partitions - 1))).AppendLine(); + } + + return sb.ToString(); + } + + public static string PrettifyDeviceGeometryTuple(Tuple tuple) + { + return PrettifyDeviceGeometryTuple(DecodeDeviceGeometryTuple(tuple)); + } + + public static string PrettifyDeviceGeometryTuple(byte[] data) + { + return PrettifyDeviceGeometryTuple(DecodeDeviceGeometryTuple(data)); + } + + public static ManufacturerIdentificationTuple DecodeManufacturerIdentificationTuple(Tuple tuple) + { + if(tuple == null) + return null; + + if(tuple.Code != TupleCodes.CISTPL_MANFID) + return null; + + if(tuple.Data == null) + return null; + + return DecodeManufacturerIdentificationTuple(tuple.Data); + } + + public static ManufacturerIdentificationTuple DecodeManufacturerIdentificationTuple(byte[] data) + { + if(data == null) + return null; + + if(data.Length < 6) + return null; + + ManufacturerIdentificationTuple tuple = new ManufacturerIdentificationTuple(); + tuple.Code = (TupleCodes)data[0]; + tuple.Link = data[1]; + tuple.ManufacturerID = BitConverter.ToUInt16(data, 2); + tuple.CardID = BitConverter.ToUInt16(data, 4); + + return tuple; + } + + public static string PrettifyManufacturerIdentificationTuple(ManufacturerIdentificationTuple tuple) + { + if(tuple == null) + return null; + + if(tuple.Code != TupleCodes.CISTPL_MANFID) + return null; + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("PCMCIA Manufacturer Identification Tuple:"); + sb.AppendFormat("\tManufacturer ID: {0}", VendorCode.Prettify(tuple.ManufacturerID)).AppendLine(); + sb.AppendFormat("\tCard ID:D 0x{0:X4}", tuple.CardID).AppendLine(); + + return sb.ToString(); + } + + public static string PrettifyManufacturerIdentificationTuple(Tuple tuple) + { + return PrettifyManufacturerIdentificationTuple(DecodeManufacturerIdentificationTuple(tuple)); + } + + public static string PrettifyManufacturerIdentificationTuple(byte[] data) + { + return PrettifyManufacturerIdentificationTuple(DecodeManufacturerIdentificationTuple(data)); + } + + public static Level1VersionTuple DecodeLevel1VersionTuple(Tuple tuple) + { + if(tuple == null) + return null; + + if(tuple.Code != TupleCodes.CISTPL_VERS_1) + return null; + + if(tuple.Data == null) + return null; + + return DecodeLevel1VersionTuple(tuple.Data); + } + + public static Level1VersionTuple DecodeLevel1VersionTuple(byte[] data) + { + if(data == null) + return null; + + if(data.Length < 4) + return null; + + List buffer = new List(); + List strings = null; + bool firstString = false; + bool secondString = false; + + Level1VersionTuple tuple = new Level1VersionTuple(); + tuple.Code = (TupleCodes)data[0]; + tuple.Link = data[1]; + tuple.MajorVersion = data[2]; + tuple.MinorVersion = data[3]; + + for(int position = 4; position < data.Length; position++) + { + if(data[position] == 0xFF) + break; + + buffer.Add(data[position]); + + if(data[position] == 0x00) + { + if(!firstString) + { + tuple.Manufacturer = StringHandlers.CToString(buffer.ToArray()); + buffer = new List(); + firstString = true; + continue; + } + + if(!secondString) + { + tuple.Product = StringHandlers.CToString(buffer.ToArray()); + buffer = new List(); + firstString = true; + continue; + } + + if(strings == null) + strings = new List(); + + strings.Add(StringHandlers.CToString(buffer.ToArray())); + buffer = new List(); + } + } + + if(strings != null) + tuple.AdditionalInformation = strings.ToArray(); + + return tuple; + } + + public static string PrettifyLevel1VersionTuple(Level1VersionTuple tuple) + { + if(tuple == null) + return null; + + if(tuple.Code != TupleCodes.CISTPL_VERS_1) + return null; + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("PCMCIA Level 1 Version / Product Information Tuple:"); + + sb.AppendFormat("\tCard indicates compliance with PC Card Standard Release {0}.{1}", tuple.MajorVersion, tuple.MinorVersion).AppendLine(); + + if(string.IsNullOrEmpty(tuple.Manufacturer)) + sb.AppendLine("\tNo manufacturer information string."); + else + sb.AppendFormat("\tManufacturer: {0}", tuple.Manufacturer).AppendLine(); + + if(string.IsNullOrEmpty(tuple.Product)) + sb.AppendLine("\tNo product name string."); + else + sb.AppendFormat("\tProduct name: {0}", tuple.Product).AppendLine(); + + if(tuple.AdditionalInformation == null || tuple.AdditionalInformation.Length == 0) + sb.AppendLine("\tNo additional information."); + else + { + sb.AppendLine("\tAdditional information:"); + foreach(string info in tuple.AdditionalInformation) + { + if(!string.IsNullOrEmpty(info)) + sb.AppendFormat("\t\t{0}", info).AppendLine(); + } + } + + return sb.ToString(); + } + + public static string PrettifyLevel1VersionTuple(Tuple tuple) + { + return PrettifyLevel1VersionTuple(DecodeLevel1VersionTuple(tuple)); + } + + public static string PrettifyLevel1VersionTuple(byte[] data) + { + return PrettifyLevel1VersionTuple(DecodeLevel1VersionTuple(data)); } - } +} } diff --git a/DiscImageChef.Decoders/PCMCIA/Enums.cs b/DiscImageChef.Decoders/PCMCIA/Enums.cs index 30502cd1..87298423 100644 --- a/DiscImageChef.Decoders/PCMCIA/Enums.cs +++ b/DiscImageChef.Decoders/PCMCIA/Enums.cs @@ -29,10 +29,262 @@ // ---------------------------------------------------------------------------- // Copyright © 2011-2016 Natalia Portillo // ****************************************************************************/ -using System; + namespace DiscImageChef.Decoders.PCMCIA { - public enum Enums + /// + /// Tuple codes. + /// + public enum TupleCodes : byte { + /// + /// Checksum control + /// + CISTPL_CHECKSUM = 0x10, + /// + /// End-of-chain + /// + CISTPL_END = 0xFF, + /// + /// Indirect access PC Card memory + /// + CISTPL_INDIRECT = 0x03, + /// + /// Link-target-control + /// + CISTPL_LINKTARGET = 0x13, + /// + /// Longlink to attribute memory + /// + CISTPL_LONGLINK_A = 0x11, + /// + /// Longlink to common memory + /// + CISTPL_LONGLINK_C = 0x12, + /// + /// Longlink to next chain on a Cardbus PC Card + /// + CISTPL_LONGLINK_CB = 0x02, + /// + /// Longlink to function specific chains + /// + CISTPL_LONGLINK_MFC = 0x06, + /// + /// No-link to common memory + /// + CISTPL_NO_LINK = 0x14, + /// + /// Null tuple + /// + CISTPL_NULL = 0x00, + /// + /// Alternate language string + /// + CISTPL_ALTSTR = 0x16, + /// + /// Common memory device information + /// + CISTPL_DEVICE = 0x01, + /// + /// Attribute memory device information + /// + CISTPL_DEVICE_A = 0x17, + /// + /// Other operating conditions information for attribute memory + /// + CISTPL_DEVICE_OA = 0x1D, + /// + /// Other operating conditions information for common memory + /// + CISTPL_DEVICE_OC = 0x1C, + /// + /// Device geometry information for common memory + /// + CISTPL_DEVICEGEO = 0x1E, + /// + /// Device geometry information for attribute memory + /// + CISTPL_DEVICEGEO_A = 0x1F, + /// + /// Extended common memory device information + /// + CISTPL_EXTDEVIC = 0x09, + /// + /// Function extensions + /// + CISTPL_FUNCE = 0x22, + /// + /// Function class identification + /// + CISTPL_FUNCID = 0x21, + /// + /// JEDEC programming information for attribute memory + /// + CISTPL_JEDEC_A = 0x19, + /// + /// JEDEC programming information for common memory + /// + CISTPL_JEDEC_C = 0x18, + /// + /// Manufacturer identification string + /// + CISTPL_MANFID = 0x20, + /// + /// Level 1 version/product information + /// + CISTPL_VERS_1 = 0x15, + /// + /// BAR for a CardBus PC Card + /// + CISTPL_BAR = 0x07, + /// + /// Configuration-table-entry + /// + CISTPL_CFTABLE_ENTRY = 0x1B, + /// + /// Configuration-table-entry for a CardBus PC Card + /// + CISTPL_CFTABLE_ENTRY_CB = 0x05, + /// + /// Configuration tuple for a 16-bit PC Card + /// + CISTPL_CONFIG = 0x1A, + /// + /// Configuration tuple for a CardBus PC Card + /// + CISTPL_CONFIG_CB = 0x04, + /// + /// Function state save/restore definition + /// + CISTPL_PWR_MGMNT = 0x08, + /// + /// Battery replacement date + /// + CISTPL_BATTERY = 0x45, + /// + /// Card initialization date + /// + CISTPL_DATE = 0x44, + /// + /// Level 2 version/product information + /// + CISTPL_VERS_2 = 0x40, + /// + /// Byte ordering for disk-like partitions + /// + CISTPL_BYTEORDER = 0x43, + /// + /// Data recording format for common memory + /// + CISTPL_FORMAT = 0x41, + /// + /// Data recording format for attribute memory + /// + CISTPL_FORMAT_A = 0x47, + /// + /// Partition geometry + /// + CISTPL_GEOMETRY = 0x42, + /// + /// Software interleaving + /// + CISTPL_SWIL = 0x23, + /// + /// Partition organization + /// + CISTPL_ORG = 0x46, + /// + /// Special purpose + /// + CISTPL_SPCL = 0x90 + } + + public enum DeviceTypeCodes : byte + { + /// + /// No device, used to designate a hole + /// + DTYPE_NULL = 0, + /// + /// Masked ROM + /// + DTYPE_ROM = 1, + /// + /// One-type-programmable ROM + /// + DTYPE_OTPROM = 2, + /// + /// UV-Erasable Programmable ROM + /// + DTYPE_EPROM = 3, + /// + /// Electronically-Erasable Programmable ROM + /// + DTYPE_EEPROM = 4, + /// + /// Flash memory + /// + DTYPE_FLASH = 5, + /// + /// Static RAM + /// + DTYPE_SRAM = 6, + /// + /// Dynamic RAM + /// + DTYPE_DRAM = 7, + /// + /// Function-specific memory address range + /// + DTYPE_FUNCSPEC = 13, + /// + /// Extended type follows + /// + DTYPE_EXTEND = 14 + } + + public enum DeviceSpeedCodes : byte + { + /// + /// No device + /// + DSPEED_NULL = 0, + /// + /// 250 ns + /// + DSPEED_250NS = 1, + /// + /// 200 ns + /// + DSPEED_200NS = 2, + /// + /// 150 ns + /// + DSPEED_150NS = 3, + /// + /// 100 ns + /// + DSPEED_100NS = 4, + /// + /// Extended speed follows + /// + DSPEED_EXT = 7 + } + + public enum FunctionCodes : byte + { + MultiFunction = 0x00, + Memory = 0x01, + Serial = 0x02, + Parallel = 0x03, + FixedDisk = 0x04, + Video = 0x05, + Network = 0x06, + AIMS = 0x07, + SCSI = 0x08, + Security = 0x09, + Instrument = 0x0A, + HighSpeedSerial = 0x0B, + VendorSpecific = 0xFE } } diff --git a/DiscImageChef.Decoders/PCMCIA/Types.cs b/DiscImageChef.Decoders/PCMCIA/Types.cs index 1b76184f..16803fde 100644 --- a/DiscImageChef.Decoders/PCMCIA/Types.cs +++ b/DiscImageChef.Decoders/PCMCIA/Types.cs @@ -29,10 +29,451 @@ // ---------------------------------------------------------------------------- // Copyright © 2011-2016 Natalia Portillo // ****************************************************************************/ -using System; + namespace DiscImageChef.Decoders.PCMCIA { - public struct Types + /// + /// Basic classure of a PCMCIA tuple + /// + public class Tuple { + public TupleCodes Code; + public byte Link; + public byte[] Data; + } + + /// + /// Checksum tuple + /// + public class ChecksumTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Offset to region to be checksummed + /// + public short Offset; + /// + /// Length of region to be checksummed + /// + public ushort Length; + /// + /// Modulo-256 sum of region + /// + public byte Checksum; + } + + /// + /// Indirect Access PC Card Memory + /// + public class IndirectTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + } + + /// + /// Link target tuple + /// + public class LinkTargetTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// 'C''I''S' in ASCII + /// + public byte[] Tag; + } + + /// + /// 16-bit PC Card Long Link Tuple + /// + public class LongLinkTuple + { + /// + /// or or + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Target address + /// + public uint Address; + } + + public class ConfigurationAddress + { + /// + /// Target address space, 0 = attribute, 1 = common + /// + public byte TargetAddressSpace; + /// + /// Target address + /// + public uint Address; + } + + /// + /// Multiple function link tuple + /// + public class MultipleFunctionLinkTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// How many functions follow + /// + public byte NumberFunctions; + /// + /// Link to more configuration registers + /// + public ConfigurationAddress[] Addresses; + } + + public class NoLinkTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + } + + public class AlternateStringTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Array of strings. On memory they're preceded by an ISO Escape Code indicating codepage. Here they're stored as Unicode, so no need for it. + /// + public string[] Strings; + } + + public class ExtendedDeviceSpeed + { + /// + /// Another extended follows + /// + public bool Extended; + /// + /// Speed mantisa + /// + public byte Mantissa; + /// + /// Speed exponent + /// + public byte Exponent; + } + + public struct DeviceInfo + { + /// + /// Device type code + /// + public DeviceTypeCodes Type; + /// + /// Write protected + /// + public bool WPS; + /// + /// Speed code + /// + public DeviceSpeedCodes Speed; + /// + /// Extended speeds + /// + public ExtendedDeviceSpeed[] ExtendedSpeeds; + /// + /// Extended types + /// + public byte[] ExtendedTypes; + /// + /// Size in units - 1 + /// + public byte Units; + /// + /// Code to define units unit + /// + public byte SizeCode; + } + + public class DeviceTuple + { + /// + /// or + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Array of device information bytes + /// + public DeviceInfo[] Infos; + } + + public struct OtherConditionInfo + { + /// + /// True if another other condition info follows + /// + public bool Extended; + /// + /// Vcc used + /// + public byte VccUsed; + /// + /// Supports WAIT# signal + /// + public bool MWAIT; + } + + public class OtherConditionTuple + { + /// + /// or + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Array of other condition information bytes + /// + public OtherConditionInfo[] OtherConditionInfos; + /// + /// Array of device information bytes + /// + public DeviceInfo[] Infos; + } + + public struct DeviceGeometry + { + /// + /// 1 << n-1 bytes, 2 = 16-bit PC Card, 3 = CardBus PC Card + /// + public byte CardInterface; + /// + /// Erase block size in 1 << n-1 increments of wide accesses. + /// If n == 4, and == 16, erase block size = 32 * 4 = 128 bytes + /// + public byte EraseBlockSize; + /// + /// Read block size in 1 << n-1 increments of wide accesses. + /// If n == 4, and == 16, read block size = 32 * 4 = 128 bytes + /// + public byte ReadBlockSize; + /// + /// Write block size in 1 << n-1 increments of wide accesses. + /// If n == 4, and == 16, write block size = 32 * 4 = 128 bytes + /// + public byte WriteBlockSize; + /// + /// Device partitioning in granularity of 1 << n-1 erase blocks + /// If n == 4, and erase block is 128 bytes, partitions must be aligned to 32 erase block, or 4096 bytes + /// + public byte Partitions; + /// + /// Card employs a multiple of 1 << n-1 times interleaving the entire memory arrays + /// + public byte Interleaving; + } + + public class DeviceGeometryTuple + { + /// + /// or + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Array of device geometries + /// + public DeviceGeometry[] Geometries; + } + + public class FunctionIdentificationTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Function code + /// + public FunctionCodes Function; + /// + /// Device contains boot ROM + /// + public bool ROM; + /// + /// Device wants to be part of power-on-self-test + /// + public bool POST; + } + + public class ManufacturerIdentificationTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Manufacturer ID + /// + public ushort ManufacturerID; + /// + /// Card ID + /// + public ushort CardID; + } + + public class Level1VersionTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Major version of standard compliance + /// + public byte MajorVersion; + /// + /// Minor version of standard compliance + /// + public byte MinorVersion; + /// + /// Manufacturer string + /// + public string Manufacturer; + /// + /// Product string + /// + public string Product; + /// + /// Additional information strings + /// + public string[] AdditionalInformation; + } + + public class Level2VersionTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Version of this classure + /// + public byte StructureVersion; + /// + /// Level of compliance + /// + public byte Compliance; + /// + /// Address of first data byte + /// + public ushort Address; + /// + /// Vendor-specific byte + /// + public byte VendorSpecific1; + /// + /// Vendor-specific byte + /// + public byte VendorSpecific2; + /// + /// Number of copies of CIS present + /// + public byte CISCopies; + /// + /// Vendor of software that formatted the card + /// + public string OEM; + /// + /// Informational message about the card + /// + public string Information; + } + + public class GeometryTuple + { + /// + /// + /// + public TupleCodes Code; + /// + /// Link to next tuple + /// + public byte Link; + /// + /// Sectors per track + /// + public byte SectorsPerTrack; + /// + /// Tracks per cylinder + /// + public byte TracksPerCylinder; + /// + /// Cylinders + /// + public ushort Cylinders; } } diff --git a/DiscImageChef.Decoders/PCMCIA/VendorCode.cs b/DiscImageChef.Decoders/PCMCIA/VendorCode.cs index 5ef49c5d..9608b74f 100644 --- a/DiscImageChef.Decoders/PCMCIA/VendorCode.cs +++ b/DiscImageChef.Decoders/PCMCIA/VendorCode.cs @@ -29,13 +29,645 @@ // ---------------------------------------------------------------------------- // Copyright © 2011-2016 Natalia Portillo // ****************************************************************************/ -using System; + namespace DiscImageChef.Decoders.PCMCIA { - public class VendorCode + public static class VendorCode { - public VendorCode() + public static string Prettify(ushort id) { + switch(id) + { + #region JEDEC + case 0x01: + return "AMD"; + case 0x02: + return "AMI"; + case 0x83: + return "Fairchild"; + case 0x04: + return "Fujitsu"; + case 0x85: + return "GTE"; + case 0x86: + return "Harris"; + case 0x07: + return "Hitachi"; + case 0x08: + return "Inmos"; + case 0x89: + return "Intel"; + case 0x8A: + return "I.T.T."; + case 0x0B: + return "Intersil"; + case 0x8C: + return "Monolithic Memories"; + case 0x0D: + return "Mostek"; + case 0x0E: + return "Freescale"; + case 0x8F: + return "National"; + case 0x10: + return "NEC"; + case 0x91: + return "RCA"; + case 0x92: + return "Raytheon"; + case 0x13: + return "Conexant"; + case 0x94: + return "Seeq"; + case 0x15: + return "NXP"; + case 0x16: + return "Synertek"; + case 0x97: + return "Texas Instruments"; + case 0x98: + return "Toshiba"; + case 0x19: + return "Xicor"; + case 0x1A: + return "Zilog"; + case 0x9B: + return "Eurotechnique"; + case 0x1C: + return "Mitsubishi2"; + case 0x9D: + return "Lucent"; + case 0x9E: + return "Exel"; + case 0x1F: + return "Atmel"; + case 0x20: + return "SGS/Thomson"; + case 0xA1: + return "Lattice Semiconductor"; + case 0xA2: + return "NCR"; + case 0x23: + return "Wafer Scale Integration"; + case 0xA4: + return "International Business Machines"; + case 0x25: + return "Tristar"; + case 0x26: + return "Visic"; + case 0xA7: + return "International CMOS Technology"; + case 0xA8: + return "SSSI"; + case 0x29: + return "Microchip Technology"; + case 0x2A: + return "Ricoh"; + case 0xAB: + return "VLSI"; + case 0x2C: + return "Micron Technology"; + case 0xAD: + return "Hynix Semiconductor"; + case 0xAE: + return "OKI Semiconductor"; + case 0x2F: + return "ACTEL"; + case 0xB0: + return "Sharp"; + case 0x31: + return "Catalyst"; + case 0x32: + return "Panasonic"; + case 0xB3: + return "IDT"; + case 0x34: + return "Cypress"; + case 0xB5: + return "Digital Equipment Corporation"; + case 0xB6: + return "LSI Logic"; + case 0x37: + return "Zarlink"; + case 0x38: + return "UTMC"; + case 0xB9: + return "Thinking Machine"; + case 0xBA: + return "Thomson CSF"; + case 0x3B: + return "Integrated CMOS"; + case 0xBC: + return "Honeywell"; + case 0x3D: + return "Tektronix"; + case 0x3E: + return "Oracle Corporation"; + case 0xBF: + return "Silicon Storage Technology"; + case 0x40: + return "ProMos"; + case 0xC1: + return "Infineon"; + case 0xC2: + return "Macronix"; + case 0x43: + return "Xerox"; + case 0xC4: + return "Plus Logic"; + case 0x45: + return "SanDisk Corporation"; + case 0x46: + return "Elan Circuit Technology"; + case 0xC7: + return "European Silicon"; + case 0xC8: + return "Apple"; + case 0x49: + return "Xilinx"; + case 0x4A: + return "Compaq"; + case 0xCB: + return "Protocol Engines"; + case 0x4C: + return "SCI"; + case 0xCD: + return "Seiko Instruments"; + case 0xCE: + return "Samsung"; + case 0x4F: + return "I3 Design System"; + case 0xD0: + return "Klic"; + case 0x51: + return "Crosspoint Solutions"; + case 0x52: + return "Alliance Semiconductor"; + case 0xD3: + return "Tandem"; + case 0x54: + return "Hewlett-Packard"; + case 0xD5: + return "Integrated Silicon Solutions"; + case 0xD6: + return "Brooktree"; + case 0x57: + return "New Media"; + case 0x58: + return "MHS Electronic"; + case 0xD9: + return "Performance Semiconductors"; + case 0xDA: + return "Winbond Electronic"; + case 0x5B: + return "Kawasaki Steel"; + case 0x5D: + return "TECMAR"; + case 0x5E: + return "Exar"; + case 0xDF: + return "PCMCIA"; + case 0xE0: + return "LG Semiconductor"; + case 0x61: + return "Northern Telecom"; + case 0x62: + return "Sanyo2"; + case 0xE3: + return "Array Microsystems"; + case 0x64: + return "Crystal Semiconductor"; + case 0xE5: + return "Analog Devices"; + case 0xE6: + return "PMC-Sierra"; + case 0x67: + return "Asparix"; + case 0x68: + return "Convex Computer"; + case 0xE9: + return "Nimbus Technology"; + case 0x6B: + return "Transwitch"; + case 0xEC: + return "Micronas"; + case 0x6D: + return "Canon"; + case 0x6E: + return "Altera"; + case 0xEF: + return "NEXCOM"; + case 0x70: + return "Qualcomm"; + case 0xF1: + return "Sony"; + case 0xF2: + return "Cray Research"; + case 0x73: + return "AMS"; + case 0xF4: + return "Vitesse"; + case 0x75: + return "Aster Electronics"; + case 0x76: + return "Bay Networks"; + case 0xF7: + return "Zentrum"; + case 0xF8: + return "TRW"; + case 0x79: + return "Thesys"; + case 0x7A: + return "Solbourne Computer"; + case 0xFB: + return "Allied-Signal"; + case 0x7C: + return "Dialog Semiconductor"; + case 0xFD: + return "Media Vision"; + case 0xFE: + return "Numonyx Corporation"; + case 0x7F01: + return "Cirrus Logic"; + case 0x7F02: + return "National Instruments"; + case 0x7F04: + return "Alcatel Mietec"; + case 0x7F07: + return "JTAG Technologies"; + case 0x7F08: + return "Loral"; + case 0x7F0B: + return "Bestlink Systems"; + case 0x7F0D: + return "GENNUM"; + case 0x7F0E: + return "VideoLogic"; + case 0x7F10: + return "Chip Express"; + case 0x7F13: + return "TCSI"; + case 0x7F15: + return "Hughes Aircraft"; + case 0x7F16: + return "Lanstar Semiconductor"; + case 0x7F19: + return "Music Semi"; + case 0x7F1A: + return "Ericsson Components"; + case 0x7F1C: + return "Eon Silicon Devices"; + case 0x7F1F: + return "Integ.Memories Tech."; + case 0x7F20: + return "Corollary Inc."; + case 0x7F23: + return "EIV(Switzerland)"; + case 0x7F25: + return "Zarlink(formerly Mitel)"; + case 0x7F26: + return "Clearpoint"; + case 0x7F29: + return "Vanguard"; + case 0x7F2A: + return "Hagiwara Sys-Com"; + case 0x7F2C: + return "Celestica"; + case 0x7F2F: + return "Rohm Company Ltd."; + case 0x7F31: + return "Libit Signal Processing"; + case 0x7F32: + return "Enhanced Memories Inc."; + case 0x7F34: + return "Adaptec Inc."; + case 0x7F37: + return "AMIC Technology"; + case 0x7F38: + return "Adobe Systems"; + case 0x7F3B: + return "Newport Digital"; + case 0x7F3D: + return "T Square"; + case 0x7F3E: + return "Seiko Epson"; + case 0x7F40: + return "Viking Components"; + case 0x7F43: + return "Suwa Electronics"; + case 0x7F45: + return "Micron CMS"; + case 0x7F46: + return "American Computer &Digital Components Inc"; + case 0x7F49: + return "CPU Design"; + case 0x7F4A: + return "Price Point"; + case 0x7F4C: + return "Tellabs"; + case 0x7F4F: + return "Transcend Information"; + case 0x7F51: + return "CKD Corporation Ltd."; + case 0x7F52: + return "Capital Instruments, Inc."; + case 0x7F54: + return "Linvex Technology"; + case 0x7F57: + return "Dynamem, Inc."; + case 0x7F58: + return "NERA ASA"; + case 0x7F5B: + return "Acorn Computers"; + case 0x7F5D: + return "Oak Technology, Inc."; + case 0x7F5E: + return "Itec Memory"; + case 0x7F61: + return "Wintec Industries"; + case 0x7F62: + return "Super PC Memory"; + case 0x7F64: + return "Galvantech"; + case 0x7F67: + return "GateField"; + case 0x7F68: + return "Integrated Memory System"; + case 0x7F6B: + return "Goldenram"; + case 0x7F6D: + return "Cimaron Communications"; + case 0x7F6E: + return "Nippon Steel Semi.Corp."; + case 0x7F70: + return "AMCC"; + case 0x7F73: + return "Digital Microwave"; + case 0x7F75: + return "MIMOS Semiconductor"; + case 0x7F76: + return "Advanced Fibre"; + case 0x7F79: + return "Acbel Polytech Inc."; + case 0x7F7A: + return "Apacer Technology"; + case 0x7F7C: + return "FOXCONN"; + case 0x7F83: + return "ILC Data Device"; + case 0x7F85: + return "Micro Linear"; + case 0x7F86: + return "Univ.Of NC"; + case 0x7F89: + return "Nchip"; + case 0x7F8A: + return "Galileo Tech"; + case 0x7F8C: + return "Graychip"; + case 0x7F8F: + return "Robert Bosch"; + case 0x7F91: + return "DATARAM"; + case 0x7F92: + return "United Microelec Corp."; + case 0x7F94: + return "Smart Modular"; + case 0x7F97: + return "Qlogic"; + case 0x7F98: + return "Kingston"; + case 0x7F9B: + return "SpaSE"; + case 0x7F9D: + return "Programmable Micro Corp"; + case 0x7F9E: + return "DoD"; + case 0x7FA1: + return "Dallas Semiconductor"; + case 0x7FA2: + return "Omnivision"; + case 0x7FA4: + return "Novatel Wireless"; + case 0x7FA7: + return "Cabletron"; + case 0x7FA8: + return "Silicon Technology"; + case 0x7FAB: + return "Vantis"; + case 0x7FAD: + return "Century"; + case 0x7FAE: + return "Hal Computers"; + case 0x7FB0: + return "Juniper Networks"; + case 0x7FB3: + return "Tundra Semiconductor"; + case 0x7FB5: + return "LightSpeed Semi."; + case 0x7FB6: + return "ZSP Corp."; + case 0x7FB9: + return "Dynachip"; + case 0x7FBA: + return "PNY Electronics"; + case 0x7FBC: + return "MMC Networks"; + case 0x7FBF: + return "Broadcom"; + case 0x7FC1: + return "V3 Semiconductor"; + case 0x7FC2: + return "Flextronics(formerly Orbit)"; + case 0x7FC4: + return "Transmeta"; + case 0x7FC7: + return "Enhance 3000 Inc"; + case 0x7FC8: + return "Tower Semiconductor"; + case 0x7FCB: + return "Maxim Integrated Product"; + case 0x7FCD: + return "Centaur Technology"; + case 0x7FCE: + return "Unigen Corporation"; + case 0x7FD0: + return "Memory Card Technology"; + case 0x7FD3: + return "Aica Kogyo, Ltd."; + case 0x7FD5: + return "MSC Vertriebs GmbH"; + case 0x7FD6: + return "AKM Company, Ltd."; + case 0x7FD9: + return "GSI Technology"; + case 0x7FDA: + return "Dane-Elec (C Memory)"; + case 0x7FDC: + return "Lara Technology"; + case 0x7FDF: + return "Tanisys Technology"; + case 0x7FE0: + return "Truevision"; + case 0x7FE3: + return "MGV Memory"; + case 0x7FE5: + return "Gadzoox Networks"; + case 0x7FE6: + return "Multi Dimensional Cons."; + case 0x7FE9: + return "Triscend"; + case 0x7FEA: + return "XaQti"; + case 0x7FEC: + return "Clear Logic"; + case 0x7FEF: + return "Advantage Memory"; + case 0x7FF1: + return "LeCroy"; + case 0x7FF2: + return "Yamaha Corporation"; + case 0x7FF4: + return "NetLogic Microsystems"; + case 0x7FF7: + return "BF Goodrich Data."; + case 0x7FF8: + return "Epigram"; + case 0x7FFB: + return "Admor Memory"; + case 0x7FFD: + return "Quadratics Superconductor"; + case 0x7FFE: + return "3COM"; + #endregion JEDEC + + case 0x0100: + return "Digital Equipment Corporation"; + case 0x0101: + return "3Com Corporation"; + case 0x0102: + return "Megahertz Corporation"; + case 0x0104: + return "Socket Communications"; + case 0x0105: + return "TDK Corporation"; + case 0x0108: + return "Standard Microsystems Corporation"; + case 0x0109: + return "Motorola Corporation"; + case 0x010b: + return "National Instruments"; + case 0x0115: + return "US Robotics Corporation"; + case 0x0121: + return "Olicom"; + case 0x0126: + return "Proxim"; + case 0x0128: + return "Megahertz Corporation"; + case 0x012F: + return "Adaptec Corporation"; + case 0x0137: + return "Quatech"; + case 0x0138: + return "Compaq"; + case 0x0140: + return "Ositech"; + case 0x0143: + return "D-Link"; + case 0x0149: + return "Netgear"; + case 0x014D: + return "Simple Technology"; + case 0x0156: + return "Lucent Technologies"; + case 0x015F: + return "Aironet Wireless Communications"; + case 0x016B: + return "Ericsson"; + case 0x016C: + return "Psion"; + case 0x0183: + return "Compaq"; + case 0x0186: + return "Kingston"; + case 0x0192: + return "Sierra Wireless"; + case 0x0194: + return "Dayna Corporation"; + case 0x01a6: + return "Raytheon"; + case 0x01BF: + return "Belkin"; + case 0x01EB: + return "Bay Networks"; + case 0x0200: + return "Farallon Communications"; + case 0x021B: + return "Telecom Device"; + case 0x023D: + return "Nokia Communications"; + case 0x0250: + return "Samsung"; + case 0x0264: + return "Anycom"; + case 0x0268: + return "Alvarion Ltd."; + case 0x026C: + return "Symbol"; + case 0x026F: + return "BUFFALO"; + case 0x0274: + return "The Linksys Group"; + case 0x0288: + return "NEC Infrontia"; + case 0x028A: + return "I-O DATA"; + case 0x02AA: + return "Asustek Computer"; + case 0x02AC: + return "Siemens"; + case 0x02D2: + return "Microsoft Corporation"; + case 0x02DF: + return "AmbiCom Inc"; + case 0x0a02: + return "BreezeCOM"; + case 0x10CD: + return "NewMedia"; + case 0x1668: + return "ACTIONTEC"; + case 0x3401: + return "Lasat Communications A/S"; + case 0x4E01: + return "Lexar Media"; + case 0x5241: + return "Archos"; + case 0x890F: + return "Dual"; + case 0x8A01: + return "Compex Corporation"; + case 0xC001: + return "Contec"; + case 0xC00B: + return "MACNICA"; + case 0xC00C: + return "Roland"; + case 0xC00F: + return "Corega K.K."; + case 0xC012: + return "Hagiwara SYS-COM"; + case 0xC015: + return "RATOC System Inc."; + case 0xC020: + return "NextCom K.K."; + case 0xC250: + return "EMTAC Technology Corporation"; + case 0xD601: + return "Elsa"; + default: + return string.Format("Unknown vendor id 0x{0:X4}", id); + } } } } diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index c48cfdde..8e8bf0a6 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,8 @@ +2016-10-17 Natalia Portillo + + * Variables.cs: + * Constructor.cs: Added PCMCIA support. + 2016-10-12 Natalia Portillo * SPC.cs: Added REQUEST SENSE command. diff --git a/DiscImageChef.Devices/Device/Constructor.cs b/DiscImageChef.Devices/Device/Constructor.cs index e2b1ecbe..b1d3a77b 100644 --- a/DiscImageChef.Devices/Device/Constructor.cs +++ b/DiscImageChef.Devices/Device/Constructor.cs @@ -239,6 +239,56 @@ namespace DiscImageChef.Devices firewire = false; #endregion FireWire + #region PCMCIA + if(platformID == Interop.PlatformID.Linux) + { + if(devicePath.StartsWith("/dev/sd", StringComparison.Ordinal) || devicePath.StartsWith("/dev/sr", StringComparison.Ordinal) || devicePath.StartsWith("/dev/st", StringComparison.Ordinal)) + { + string devPath = devicePath.Substring(5); + if(System.IO.Directory.Exists("/sys/block/" + devPath)) + { + string resolvedLink = Linux.Command.ReadLink("/sys/block/" + devPath); + resolvedLink = "/sys" + resolvedLink.Substring(2); + if(!string.IsNullOrEmpty(resolvedLink)) + { + while(resolvedLink.Contains("/sys/devices")) + { + resolvedLink = System.IO.Path.GetDirectoryName(resolvedLink); + if(System.IO.Directory.Exists(resolvedLink + "/pcmcia_socket")) + { + string[] subdirs = System.IO.Directory.GetDirectories(resolvedLink + "/pcmcia_socket", "pcmcia_socket*", System.IO.SearchOption.TopDirectoryOnly); + + if(subdirs.Length > 0) + { + string possibleDir = System.IO.Path.Combine(resolvedLink, "pcmcia_socket", subdirs[0]); + if(System.IO.File.Exists(possibleDir + "/card_type") && + System.IO.File.Exists(possibleDir + "/cis")) + { + System.IO.FileStream cisFs; + + cisFs = new System.IO.FileStream(possibleDir + "/cis", System.IO.FileMode.Open, System.IO.FileAccess.Read); + byte[] cisBuf = new byte[65536]; + int cisCount = cisFs.Read(cisBuf, 0, 65536); + cis = new byte[cisCount]; + Array.Copy(cisBuf, 0, cis, 0, cisCount); + cisFs.Close(); + + pcmcia = true; + break; + } + } + } + } + } + } + } + } + // TODO: Implement for other operating systems + else + pcmcia = false; + #endregion PCMCIA + + if(!scsiSense) { Decoders.SCSI.Inquiry.SCSIInquiry? Inquiry = Decoders.SCSI.Inquiry.Decode(inqBuf); @@ -305,6 +355,8 @@ namespace DiscImageChef.Devices { removable |= (ATAID.Value.GeneralConfiguration & Identify.GeneralConfigurationBit.Removable) == Identify.GeneralConfigurationBit.Removable; } + else + compactFlash = true; } } } diff --git a/DiscImageChef.Devices/Device/Variables.cs b/DiscImageChef.Devices/Device/Variables.cs index 3cf6ffc6..434e3584 100644 --- a/DiscImageChef.Devices/Device/Variables.cs +++ b/DiscImageChef.Devices/Device/Variables.cs @@ -58,6 +58,9 @@ namespace DiscImageChef.Devices readonly string firewireModelName; readonly uint firewireVendor; readonly string firewireVendorName; + readonly bool compactFlash; + readonly bool pcmcia; + readonly byte[] cis; /// /// Gets the Platform ID for this device @@ -320,6 +323,41 @@ namespace DiscImageChef.Devices /// /// The FireWire vendor name. public string FireWireVendorName { get { return firewireVendorName; } } + + /// + /// Gets a value indicating whether this device is a CompactFlash device. + /// + /// true if this device is a CompactFlash device; otherwise, false. + public bool IsCompactFlash + { + get + { + return compactFlash; + } + } + + /// + /// Gets a value indicating whether this device is a PCMCIA device. + /// + /// true if this device is a PCMCIA device; otherwise, false. + public bool IsPCMCIA + { + get + { + return pcmcia; + } + } + + /// + /// Contains the PCMCIA CIS if applicable + /// + public byte[] CIS + { + get + { + return cis; + } + } } } diff --git a/DiscImageChef.DiscImages/CHD.cs b/DiscImageChef.DiscImages/CHD.cs index 0ae97ecd..e774af32 100644 --- a/DiscImageChef.DiscImages/CHD.cs +++ b/DiscImageChef.DiscImages/CHD.cs @@ -33,18 +33,15 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Runtime.InteropServices; +using System.Text; using System.Text.RegularExpressions; -using Claunia.RsrcFork; using DiscImageChef.CommonTypes; using DiscImageChef.Console; using DiscImageChef.Filters; -using System.Linq; -using System.Text; -using SharpCompress.Compressors.Deflate; using SharpCompress.Compressors; -using System.Reflection; -using System.Reflection.Emit; +using SharpCompress.Compressors.Deflate; namespace DiscImageChef.ImagePlugins { @@ -594,6 +591,7 @@ namespace DiscImageChef.ImagePlugins Dictionary offsetmap; byte[] identify; + byte[] cis; #endregion @@ -961,7 +959,7 @@ namespace DiscImageChef.ImagePlugins case hardDiskMetadata: if(isCdrom || isGdrom) throw new ImageNotSupportedException("Image cannot be a hard disk and a C/GD-ROM at the same time, aborting."); - + string gddd = StringHandlers.CToString(meta); Regex gdddRegEx = new Regex(hardDiskMetadataRegEx); Match gdddMatch = gdddRegEx.Match(gddd); @@ -1424,6 +1422,11 @@ namespace DiscImageChef.ImagePlugins if(!ImageInfo.readableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) ImageInfo.readableMediaTags.Add(MediaTagType.ATA_IDENTIFY); break; + case pcmciaCisMetadata: + cis = meta; + if(!ImageInfo.readableMediaTags.Contains(MediaTagType.PCMCIA_CIS)) + ImageInfo.readableMediaTags.Add(MediaTagType.PCMCIA_CIS); + break; } nextMetaOff = header.next; @@ -1548,6 +1551,11 @@ namespace DiscImageChef.ImagePlugins sectorCache = new Dictionary(); hunkCache = new Dictionary(); + // TODO: Detect CompactFlash + // TODO: Get manufacturer and drive name from CIS if applicable + if(cis != null) + ImageInfo.mediaType = MediaType.PCCardTypeI; + return true; } @@ -1639,7 +1647,7 @@ namespace DiscImageChef.ImagePlugins } break; case CHDV3EntryFlags.Uncompressed: - uncompressedV3: + uncompressedV3: hunk = new byte[bytesPerHunk]; imageStream.Seek((long)entry.offset, SeekOrigin.Begin); imageStream.Read(hunk, 0, hunk.Length); @@ -1697,7 +1705,7 @@ namespace DiscImageChef.ImagePlugins { if(isHdd) throw new FeaturedNotSupportedByDiscImageException("Cannot access optical tracks on a hard disk image"); - + return VerifySector(GetAbsoluteSector(sectorAddress, track)); } @@ -2311,6 +2319,9 @@ namespace DiscImageChef.ImagePlugins if(ImageInfo.readableMediaTags.Contains(MediaTagType.ATA_IDENTIFY)) return identify; + if(ImageInfo.readableMediaTags.Contains(MediaTagType.PCMCIA_CIS)) + return cis; + throw new FeatureUnsupportedImageException("Feature not supported by image format"); } diff --git a/DiscImageChef.DiscImages/ChangeLog b/DiscImageChef.DiscImages/ChangeLog index 74e010e8..a79d59cd 100644 --- a/DiscImageChef.DiscImages/ChangeLog +++ b/DiscImageChef.DiscImages/ChangeLog @@ -1,3 +1,7 @@ +2016-10-17 Natalia Portillo + + * CHD.cs: Added PCMCIA support. + 2016-10-10 Natalia Portillo * DiscJuggler.cs: diff --git a/DiscImageChef.Metadata/ChangeLog b/DiscImageChef.Metadata/ChangeLog index ef4f3800..749ca119 100644 --- a/DiscImageChef.Metadata/ChangeLog +++ b/DiscImageChef.Metadata/ChangeLog @@ -1,3 +1,7 @@ +2016-10-17 Natalia Portillo + + * DeviceReport.cs: Added PCMCIA support. + 2016-10-12 Natalia Portillo * MediaType.cs: Added support for DDS, DDS-2, DDS-3, DDS-4. diff --git a/DiscImageChef.Metadata/DeviceReport.cs b/DiscImageChef.Metadata/DeviceReport.cs index aa2c595d..ed730ca0 100644 --- a/DiscImageChef.Metadata/DeviceReport.cs +++ b/DiscImageChef.Metadata/DeviceReport.cs @@ -47,6 +47,7 @@ namespace DiscImageChef.Metadata public ataType ATAPI; public scsiType SCSI; public bool CompactFlash; + public pcmciaType PCMCIA; [XmlIgnore] public bool CompactFlashSpecified; @@ -1001,5 +1002,21 @@ namespace DiscImageChef.Metadata [XmlIgnore] public bool MediumTypeSpecified; } + + public class pcmciaType + { + public byte[] CIS; + public string Compliance; + public ushort ManufacturerCode; + public ushort CardCode; + public string Manufacturer; + public string ProductName; + public string[] AdditionalInformation; + + [XmlIgnore] + public bool ManufacturerCodeSpecified; + [XmlIgnore] + public bool CardCodeSpecified; + } } diff --git a/DiscImageChef/ChangeLog b/DiscImageChef/ChangeLog index 15ff1dd4..38e672ac 100644 --- a/DiscImageChef/ChangeLog +++ b/DiscImageChef/ChangeLog @@ -1,3 +1,11 @@ +2016-10-17 Natalia Portillo + + * Commands/DumpMedia.cs: + * Commands/DeviceInfo.cs: + * Commands/DeviceReport.cs: + * Commands/CreateSidecar.cs: + Added PCMCIA support. + 2016-10-14 Natalia Portillo * Commands/DeviceInfo.cs: diff --git a/DiscImageChef/Commands/CreateSidecar.cs b/DiscImageChef/Commands/CreateSidecar.cs index b2a46df8..512f157e 100644 --- a/DiscImageChef/Commands/CreateSidecar.cs +++ b/DiscImageChef/Commands/CreateSidecar.cs @@ -40,6 +40,7 @@ using System.IO; using DiscImageChef.CommonTypes; using DiscImageChef.PartPlugins; using DiscImageChef.Filters; +using DiscImageChef.Decoders.PCMCIA; namespace DiscImageChef.Commands { @@ -687,10 +688,42 @@ namespace DiscImageChef.Commands sidecar.BlockMedia[0].ATA.Identify.Size = _imageFormat.ReadDiskTag(MediaTagType.ATA_IDENTIFY).Length; break; case MediaTagType.PCMCIA_CIS: + byte[] cis = _imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS); sidecar.BlockMedia[0].PCMCIA = new PCMCIAType(); sidecar.BlockMedia[0].PCMCIA.CIS = new DumpType(); - sidecar.BlockMedia[0].PCMCIA.CIS.Checksums = Core.Checksum.GetChecksums(_imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS)).ToArray(); - sidecar.BlockMedia[0].PCMCIA.CIS.Size = _imageFormat.ReadDiskTag(MediaTagType.PCMCIA_CIS).Length; + sidecar.BlockMedia[0].PCMCIA.CIS.Checksums = Core.Checksum.GetChecksums(cis).ToArray(); + sidecar.BlockMedia[0].PCMCIA.CIS.Size = cis.Length; + Decoders.PCMCIA.Tuple[] tuples = CIS.GetTuples(cis); + if(tuples != null) + { + foreach(Decoders.PCMCIA.Tuple tuple in tuples) + { + if(tuple.Code == TupleCodes.CISTPL_MANFID) + { + ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple); + + if(manfid != null) + { + sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID; + sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID; + sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true; + sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified = true; + } + } + else if(tuple.Code == TupleCodes.CISTPL_VERS_1) + { + Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); + + if(vers != null) + { + sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer; + sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; + sidecar.BlockMedia[0].PCMCIA.Compliance = string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion); + sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation; + } + } + } + } break; case MediaTagType.SCSI_INQUIRY: sidecar.BlockMedia[0].SCSI = new SCSIType(); diff --git a/DiscImageChef/Commands/DeviceInfo.cs b/DiscImageChef/Commands/DeviceInfo.cs index 93104c3e..5e3826a5 100644 --- a/DiscImageChef/Commands/DeviceInfo.cs +++ b/DiscImageChef/Commands/DeviceInfo.cs @@ -94,6 +94,76 @@ namespace DiscImageChef.Commands DicConsole.WriteLine(); } + if(dev.IsPCMCIA) + { + DicConsole.WriteLine("PCMCIA device"); + DicConsole.WriteLine("PCMCIA CIS is {0} bytes", dev.CIS.Length); + Decoders.PCMCIA.Tuple[] tuples = Decoders.PCMCIA.CIS.GetTuples(dev.CIS); + if(tuples != null) + { + foreach(Decoders.PCMCIA.Tuple tuple in tuples) + { + switch(tuple.Code) + { + case Decoders.PCMCIA.TupleCodes.CISTPL_NULL: + case Decoders.PCMCIA.TupleCodes.CISTPL_END: + break; + case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICEGEO: + case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICEGEO_A: + DicConsole.WriteLine("{0}", Decoders.PCMCIA.CIS.PrettifyDeviceGeometryTuple(tuple)); + break; + case Decoders.PCMCIA.TupleCodes.CISTPL_MANFID: + DicConsole.WriteLine("{0}", Decoders.PCMCIA.CIS.PrettifyManufacturerIdentificationTuple(tuple)); + break; + case Decoders.PCMCIA.TupleCodes.CISTPL_VERS_1: + DicConsole.WriteLine("{0}", Decoders.PCMCIA.CIS.PrettifyLevel1VersionTuple(tuple)); + break; + case Decoders.PCMCIA.TupleCodes.CISTPL_ALTSTR: + case Decoders.PCMCIA.TupleCodes.CISTPL_BAR: + case Decoders.PCMCIA.TupleCodes.CISTPL_BATTERY: + case Decoders.PCMCIA.TupleCodes.CISTPL_BYTEORDER: + case Decoders.PCMCIA.TupleCodes.CISTPL_CFTABLE_ENTRY: + case Decoders.PCMCIA.TupleCodes.CISTPL_CFTABLE_ENTRY_CB: + case Decoders.PCMCIA.TupleCodes.CISTPL_CHECKSUM: + case Decoders.PCMCIA.TupleCodes.CISTPL_CONFIG: + case Decoders.PCMCIA.TupleCodes.CISTPL_CONFIG_CB: + case Decoders.PCMCIA.TupleCodes.CISTPL_DATE: + case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE: + case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE_A: + case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE_OA: + case Decoders.PCMCIA.TupleCodes.CISTPL_DEVICE_OC: + case Decoders.PCMCIA.TupleCodes.CISTPL_EXTDEVIC: + case Decoders.PCMCIA.TupleCodes.CISTPL_FORMAT: + case Decoders.PCMCIA.TupleCodes.CISTPL_FORMAT_A: + case Decoders.PCMCIA.TupleCodes.CISTPL_FUNCE: + case Decoders.PCMCIA.TupleCodes.CISTPL_FUNCID: + case Decoders.PCMCIA.TupleCodes.CISTPL_GEOMETRY: + case Decoders.PCMCIA.TupleCodes.CISTPL_INDIRECT: + case Decoders.PCMCIA.TupleCodes.CISTPL_JEDEC_A: + case Decoders.PCMCIA.TupleCodes.CISTPL_JEDEC_C: + case Decoders.PCMCIA.TupleCodes.CISTPL_LINKTARGET: + case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_A: + case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_C: + case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_CB: + case Decoders.PCMCIA.TupleCodes.CISTPL_LONGLINK_MFC: + case Decoders.PCMCIA.TupleCodes.CISTPL_NO_LINK: + case Decoders.PCMCIA.TupleCodes.CISTPL_ORG: + case Decoders.PCMCIA.TupleCodes.CISTPL_PWR_MGMNT: + case Decoders.PCMCIA.TupleCodes.CISTPL_SPCL: + case Decoders.PCMCIA.TupleCodes.CISTPL_SWIL: + case Decoders.PCMCIA.TupleCodes.CISTPL_VERS_2: + DicConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}", tuple.Code); + break; + default: + DicConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}", (byte)tuple.Code); + break; + } + } + } + else + DicConsole.DebugWriteLine("Device-Info command", "Could not get tuples"); + } + switch(dev.Type) { case DeviceType.ATA: diff --git a/DiscImageChef/Commands/DeviceReport.cs b/DiscImageChef/Commands/DeviceReport.cs index 7d83924b..f47b7f19 100644 --- a/DiscImageChef/Commands/DeviceReport.cs +++ b/DiscImageChef/Commands/DeviceReport.cs @@ -36,6 +36,7 @@ using DiscImageChef.Devices; using DiscImageChef.Metadata; using System.IO; using System.Collections.Generic; +using DiscImageChef.Decoders.PCMCIA; namespace DiscImageChef.Commands { @@ -174,6 +175,44 @@ namespace DiscImageChef.Commands } } + if(dev.IsPCMCIA) + { + report.PCMCIA = new pcmciaType(); + report.PCMCIA.CIS = dev.CIS; + Decoders.PCMCIA.Tuple[] tuples = CIS.GetTuples(dev.CIS); + if(tuples != null) + { + foreach(Decoders.PCMCIA.Tuple tuple in tuples) + { + if(tuple.Code == TupleCodes.CISTPL_MANFID) + { + ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple); + + if(manfid != null) + { + report.PCMCIA.ManufacturerCode = manfid.ManufacturerID; + report.PCMCIA.CardCode = manfid.CardID; + report.PCMCIA.ManufacturerCodeSpecified = true; + report.PCMCIA.CardCodeSpecified = true; + } + } + else if(tuple.Code == TupleCodes.CISTPL_VERS_1) + { + Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); + + if(vers != null) + { + report.PCMCIA.Manufacturer = vers.Manufacturer; + report.PCMCIA.ProductName = vers.Product; + report.PCMCIA.Compliance = string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion); + report.PCMCIA.AdditionalInformation = vers.AdditionalInformation; + } + } + } + } + + } + DicConsole.WriteLine("Querying ATA IDENTIFY..."); dev.AtaIdentify(out buffer, out errorRegs, timeout, out duration); diff --git a/DiscImageChef/Commands/DumpMedia.cs b/DiscImageChef/Commands/DumpMedia.cs index 8fa390db..373642de 100644 --- a/DiscImageChef/Commands/DumpMedia.cs +++ b/DiscImageChef/Commands/DumpMedia.cs @@ -35,6 +35,7 @@ using System.Collections.Generic; using System.IO; using DiscImageChef.CommonTypes; using DiscImageChef.Console; +using DiscImageChef.Decoders.PCMCIA; using DiscImageChef.Devices; using DiscImageChef.Filesystems; using DiscImageChef.Filters; @@ -162,6 +163,47 @@ namespace DiscImageChef.Commands writeToFile(sidecar.BlockMedia[0].USB.Descriptors.Image, dev.USBDescriptors); } + if(dev.IsPCMCIA) + { + sidecar.BlockMedia[0].PCMCIA = new PCMCIAType(); + sidecar.BlockMedia[0].PCMCIA.CIS = new DumpType(); + sidecar.BlockMedia[0].PCMCIA.CIS.Image = options.OutputPrefix + ".cis.bin"; + sidecar.BlockMedia[0].PCMCIA.CIS.Size = dev.CIS.Length; + sidecar.BlockMedia[0].PCMCIA.CIS.Checksums = Core.Checksum.GetChecksums(dev.CIS).ToArray(); + writeToFile(sidecar.BlockMedia[0].PCMCIA.CIS.Image, dev.CIS); + Decoders.PCMCIA.Tuple[] tuples = CIS.GetTuples(dev.CIS); + if(tuples != null) + { + foreach(Decoders.PCMCIA.Tuple tuple in tuples) + { + if(tuple.Code == TupleCodes.CISTPL_MANFID) + { + ManufacturerIdentificationTuple manfid = CIS.DecodeManufacturerIdentificationTuple(tuple); + + if(manfid != null) + { + sidecar.BlockMedia[0].PCMCIA.ManufacturerCode = manfid.ManufacturerID; + sidecar.BlockMedia[0].PCMCIA.CardCode = manfid.CardID; + sidecar.BlockMedia[0].PCMCIA.ManufacturerCodeSpecified = true; + sidecar.BlockMedia[0].PCMCIA.CardCodeSpecified = true; + } + } + else if(tuple.Code == TupleCodes.CISTPL_VERS_1) + { + Level1VersionTuple vers = CIS.DecodeLevel1VersionTuple(tuple); + + if(vers != null) + { + sidecar.BlockMedia[0].PCMCIA.Manufacturer = vers.Manufacturer; + sidecar.BlockMedia[0].PCMCIA.ProductName = vers.Product; + sidecar.BlockMedia[0].PCMCIA.Compliance = string.Format("{0}.{1}", vers.MajorVersion, vers.MinorVersion); + sidecar.BlockMedia[0].PCMCIA.AdditionalInformation = vers.AdditionalInformation; + } + } + } + } + } + sidecar.BlockMedia[0].ATA = new ATAType(); sidecar.BlockMedia[0].ATA.Identify = new DumpType(); sidecar.BlockMedia[0].ATA.Identify.Image = options.OutputPrefix + ".identify.bin"; @@ -863,7 +905,12 @@ namespace DiscImageChef.Commands sidecar.BlockMedia[0].Checksums = dataChk.End().ToArray(); string xmlDskTyp, xmlDskSubTyp; - Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp); + if(dev.IsCompactFlash) + Metadata.MediaType.MediaTypeToString(MediaType.CompactFlash, out xmlDskTyp, out xmlDskSubTyp); + else if(dev.IsPCMCIA) + Metadata.MediaType.MediaTypeToString(MediaType.PCCardTypeI, out xmlDskTyp, out xmlDskSubTyp); + else + Metadata.MediaType.MediaTypeToString(MediaType.GENERIC_HDD, out xmlDskTyp, out xmlDskSubTyp); sidecar.BlockMedia[0].DiskType = xmlDskTyp; sidecar.BlockMedia[0].DiskSubType = xmlDskSubTyp; // TODO: Implement device firmware revision