From 89234befb354ebfc454b7187cab6e3c252866a2e Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 14 Dec 2017 19:21:33 +0000 Subject: [PATCH] Added ATAPI report to DiscImageChef.Device.Report. --- DiscImageChef.Device.Report/CMakeLists.txt | 7 +- DiscImageChef.Device.Report/ata.h | 736 +++++ DiscImageChef.Device.Report/atapi_report.c | 195 ++ DiscImageChef.Device.Report/atapi_report.h | 11 + DiscImageChef.Device.Report/identify_decode.c | 2406 +++++++++++++++++ DiscImageChef.Device.Report/identify_decode.h | 27 + DiscImageChef.Device.Report/main.c | 55 +- 7 files changed, 3435 insertions(+), 2 deletions(-) create mode 100644 DiscImageChef.Device.Report/atapi_report.c create mode 100644 DiscImageChef.Device.Report/atapi_report.h create mode 100644 DiscImageChef.Device.Report/identify_decode.c create mode 100644 DiscImageChef.Device.Report/identify_decode.h diff --git a/DiscImageChef.Device.Report/CMakeLists.txt b/DiscImageChef.Device.Report/CMakeLists.txt index 4f1177ab..1290bfe6 100644 --- a/DiscImageChef.Device.Report/CMakeLists.txt +++ b/DiscImageChef.Device.Report/CMakeLists.txt @@ -3,4 +3,9 @@ project(DiscImageChef_Device_Report C) set(CMAKE_C_STANDARD 90) -add_executable(DiscImageChef_Device_Report main.c scsi.c scsi.h main.h ata.h ata.c atapi.c atapi.h) \ No newline at end of file +find_package(LibXml2) + +include_directories(${LIBXML2_INCLUDE_DIR}) + +add_executable(DiscImageChef_Device_Report main.c scsi.c scsi.h main.h ata.h ata.c atapi.c atapi.h atapi_report.c atapi_report.h identify_decode.c identify_decode.h) +target_link_libraries(DiscImageChef_Device_Report ${LIBXML2_LIBRARIES}) \ No newline at end of file diff --git a/DiscImageChef.Device.Report/ata.h b/DiscImageChef.Device.Report/ata.h index 7c6f9b00..c95e2800 100644 --- a/DiscImageChef.Device.Report/ata.h +++ b/DiscImageChef.Device.Report/ata.h @@ -7,6 +7,7 @@ #include +#pragma pack(1) typedef struct { uint8_t feature; @@ -106,6 +107,741 @@ typedef enum ATA_IDENTIFY_DEVICE = 0xEC } AtaCommands; +typedef struct +{ + /* + Word 0 + General device configuration + On ATAPI devices: + Bits 12 to 8 indicate device type as SCSI defined + Bits 6 to 5: + 0 = Device shall set DRQ within 3 ms of receiving PACKET + 1 = Device shall assert INTRQ when DRQ is set to one + 2 = Device shall set DRQ within 50 µs of receiving PACKET + Bits 1 to 0: + 0 = 12 byte command packet + 1 = 16 byte command packet + CompactFlash is 0x848A (non magnetic, removable, not MFM, hardsector, and UltraFAST) + */ + uint16_t GeneralConfiguration; + /* + Word 1 + Cylinders in default translation mode + Obsoleted in ATA/ATAPI-6 + */ + uint16_t Cylinders; + /* + Word 2 + Specific configuration + */ + uint16_t SpecificConfiguration; + /* + Word 3 + Heads in default translation mode + Obsoleted in ATA/ATAPI-6 + */ + uint16_t Heads; + /* + Word 4 + Unformatted bytes per track in default translation mode + Obsoleted in ATA-2 + */ + uint16_t UnformattedBPT; + /* + Word 5 + Unformatted bytes per sector in default translation mode + Obsoleted in ATA-2 + */ + uint16_t UnformattedBPS; + /* + Word 6 + Sectors per track in default translation mode + Obsoleted in ATA/ATAPI-6 + */ + uint16_t SectorsPerTrack; + /* + Words 7 to 8 + CFA: Number of sectors per card + */ + uint32_t SectorsPerCard; + /* + Word 9 + Vendor unique + Obsoleted in ATA/ATAPI-4 + */ + uint16_t VendorWord9; + /* + Words 10 to 19 + Device serial number, right justified, padded with spaces + */ + uint8_t SerialNumber[20]; + /* + Word 20 + Manufacturer defined + Obsoleted in ATA-2 + 0x0001 = single ported single sector buffer + 0x0002 = dual ported multi sector buffer + 0x0003 = dual ported multi sector buffer with reading + */ + uint16_t BufferType; + /* + Word 21 + Size of buffer in 512 byte increments + Obsoleted in ATA-2 + */ + uint16_t BufferSize; + /* + Word 22 + Bytes of ECC available in READ/WRITE LONG commands + Obsoleted in ATA/ATAPI-4 + */ + uint16_t EccBytes; + /* + Words 23 to 26 + Firmware revision, left justified, padded with spaces + */ + uint8_t FirmwareRevision[8]; + /* + Words 27 to 46 + Model number, left justified, padded with spaces + */ + uint8_t Model[40]; + /* + Word 47 bits 7 to 0 + Maximum number of sectors that can be transferred per + interrupt on read and write multiple commands + */ + uint8_t MultipleMaxSectors; + /* + Word 47 bits 15 to 8 + Vendor unique + ATA/ATAPI-4 says it must be 0x80 + */ + uint8_t VendorWord47; + /* + Word 48 + ATA-1: Set to 1 if it can perform doubleword I/O + ATA-2 to ATA/ATAPI-7: Reserved + ATA8-ACS: Trusted Computing feature set + */ + uint16_t TrustedComputing; + /* + Word 49 + Capabilities + */ + uint16_t Capabilities; + /* + Word 50 + Capabilities + */ + uint16_t Capabilities2; + /* + Word 51 bits 7 to 0 + Vendor unique + Obsoleted in ATA/ATAPI-4 + */ + uint8_t VendorWord51; + /* + Word 51 bits 15 to 8 + Transfer timing mode in PIO + Obsoleted in ATA/ATAPI-4 + */ + uint8_t PIOTransferTimingMode; + /* + Word 52 bits 7 to 0 + Vendor unique + Obsoleted in ATA/ATAPI-4 + */ + uint8_t VendorWord52; + /* + Word 52 bits 15 to 8 + Transfer timing mode in DMA + Obsoleted in ATA/ATAPI-4 + */ + uint8_t DMATransferTimingMode; + /* + Word 53 bits 7 to 0 + Reports if words 54 to 58 are valid + */ + uint8_t ExtendedIdentify; + /* + Word 53 bits 15 to 8 + Free-fall Control Sensitivity + */ + uint8_t FreeFallSensitivity; + /* + Word 54 + Cylinders in current translation mode + Obsoleted in ATA/ATAPI-6 + */ + uint16_t CurrentCylinders; + /* + Word 55 + Heads in current translation mode + Obsoleted in ATA/ATAPI-6 + */ + uint16_t CurrentHeads; + /* + Word 56 + Sectors per track in current translation mode + Obsoleted in ATA/ATAPI-6 + */ + uint16_t CurrentSectorsPerTrack; + /* + Words 57 to 58 + Total sectors currently user-addressable + Obsoleted in ATA/ATAPI-6 + */ + uint32_t CurrentSectors; + /* + Word 59 bits 7 to 0 + Number of sectors currently set to transfer on a READ/WRITE MULTIPLE command + */ + uint8_t MultipleSectorNumber; + /* + Word 59 bits 15 to 8 + Indicates if is valid + */ + uint8_t Capabilities3; + /* + Words 60 to 61 + If drive supports LBA, how many sectors are addressable using LBA + */ + uint32_t LBASectors; + /* + Word 62 bits 7 to 0 + Single word DMA modes available + Obsoleted in ATA/ATAPI-4 + In ATAPI it's not obsolete, indicates UDMA mode (UDMA7 is instead MDMA0) + */ + uint8_t DMASupported; + /* + Word 62 bits 15 to 8 + Single word DMA mode currently active + Obsoleted in ATA/ATAPI-4 + In ATAPI it's not obsolete, bits 0 and 1 indicate MDMA mode+1, + bit 10 indicates DMA is supported and bit 15 indicates DMADIR bit + in PACKET is required for DMA transfers + */ + uint8_t DMAActive; + /* + Word 63 bits 7 to 0 + Multiword DMA modes available + */ + uint8_t MDMASupported; + /* + Word 63 bits 15 to 8 + Multiword DMA mode currently active + */ + uint8_t MDMAActive; + + /* + Word 64 bits 7 to 0 + Supported Advanced PIO transfer modes + */ + uint8_t APIOSupported; + /* + Word 64 bits 15 to 8 + Reserved + */ + uint8_t ReservedWord64; + /* + Word 65 + Minimum MDMA transfer cycle time per word in nanoseconds + */ + uint16_t MinMDMACycleTime; + /* + Word 66 + Recommended MDMA transfer cycle time per word in nanoseconds + */ + uint16_t RecMDMACycleTime; + /* + Word 67 + Minimum PIO transfer cycle time without flow control in nanoseconds + */ + uint16_t MinPIOCycleTimeNoFlow; + /* + Word 68 + Minimum PIO transfer cycle time with IORDY flow control in nanoseconds + */ + uint16_t MinPIOCycleTimeFlow; + + /* + Word 69 + Additional supported + */ + uint16_t CommandSet5; + /* + Word 70 + Reserved + */ + uint16_t ReservedWord70; + /* + Word 71 + ATAPI: Typical time in ns from receipt of PACKET to release bus + */ + uint16_t PacketBusRelease; + /* + Word 72 + ATAPI: Typical time in ns from receipt of SERVICE to clear BSY + */ + uint16_t ServiceBusyClear; + /* + Word 73 + Reserved + */ + uint16_t ReservedWord73; + /* + Word 74 + Reserved + */ + uint16_t ReservedWord74; + + /* + Word 75 + Maximum Queue depth + */ + uint16_t MaxQueueDepth; + + /* + Word 76 + Serial ATA Capabilities + */ + uint16_t SATACapabilities; + /* + Word 77 + Serial ATA Additional Capabilities + */ + uint16_t SATACapabilities2; + + /* + Word 78 + Supported Serial ATA features + */ + uint16_t SATAFeatures; + /* + Word 79 + Enabled Serial ATA features + */ + uint16_t EnabledSATAFeatures; + + /* + Word 80 + Major version of ATA/ATAPI standard supported + */ + uint16_t MajorVersion; + /* + Word 81 + Minimum version of ATA/ATAPI standard supported + */ + uint16_t MinorVersion; + + /* + Word 82 + Supported command/feature sets + */ + uint16_t CommandSet; + /* + Word 83 + Supported command/feature sets + */ + uint16_t CommandSet2; + /* + Word 84 + Supported command/feature sets + */ + uint16_t CommandSet3; + + /* + Word 85 + Enabled command/feature sets + */ + uint16_t EnabledCommandSet; + /* + Word 86 + Enabled command/feature sets + */ + uint16_t EnabledCommandSet2; + /* + Word 87 + Enabled command/feature sets + */ + uint16_t EnabledCommandSet3; + + /* + Word 88 bits 7 to 0 + Supported Ultra DMA transfer modes + */ + uint8_t UDMASupported; + /* + Word 88 bits 15 to 8 + Selected Ultra DMA transfer modes + */ + uint8_t UDMAActive; + + /* + Word 89 + Time required for security erase completion + */ + uint16_t SecurityEraseTime; + /* + Word 90 + Time required for enhanced security erase completion + */ + uint16_t EnhancedSecurityEraseTime; + /* + Word 91 + Current advanced power management value + */ + uint16_t CurrentAPM; + + /* + Word 92 + Master password revision code + */ + uint16_t MasterPasswordRevisionCode; + /* + Word 93 + Hardware reset result + */ + uint16_t HardwareResetResult; + + /* + Word 94 bits 7 to 0 + Current AAM value + */ + uint8_t CurrentAAM; + /* + Word 94 bits 15 to 8 + Vendor's recommended AAM value + */ + uint8_t RecommendedAAM; + + /* + Word 95 + Stream minimum request size + */ + uint16_t StreamMinReqSize; + /* + Word 96 + Streaming transfer time in DMA + */ + uint16_t StreamTransferTimeDMA; + /* + Word 97 + Streaming access latency in DMA and PIO + */ + uint16_t StreamAccessLatency; + /* + Words 98 to 99 + Streaming performance granularity + */ + uint32_t StreamPerformanceGranularity; + + /* + Words 100 to 103 + 48-bit LBA addressable sectors + */ + uint64_t LBA48Sectors; + + /* + Word 104 + Streaming transfer time in PIO + */ + uint16_t StreamTransferTimePIO; + + /* + Word 105 + Maximum number of 512-byte block per DATA SET MANAGEMENT command + */ + uint16_t DataSetMgmtSize; + + /* + Word 106 + Bit 15 should be zero + Bit 14 should be one + Bit 13 set indicates device has multiple logical sectors per physical sector + Bit 12 set indicates logical sector has more than 256 words (512 bytes) + Bits 11 to 4 are reserved + Bits 3 to 0 indicate power of two of logical sectors per physical sector + */ + uint16_t PhysLogSectorSize; + + /* + Word 107 + Interseek delay for ISO-7779 acoustic testing, in microseconds + */ + uint16_t InterseekDelay; + + /* + Words 108 to 111 + World Wide Name + */ + uint64_t WWN; + + /* + Words 112 to 115 + Reserved for WWN extension to 128 bit + */ + uint64_t WWNExtension; + + /* + Word 116 + Reserved for technical report + */ + uint16_t ReservedWord116; + + /* + Words 117 to 118 + Words per logical sector + */ + uint32_t LogicalSectorWords; + + /* + Word 119 + Supported command/feature sets + */ + uint16_t CommandSet4; + /* + Word 120 + Supported command/feature sets + */ + uint16_t EnabledCommandSet4; + + /* + Words 121 to 125 + Reserved + */ + uint16_t ReservedWords121[5]; + + /* + Word 126 + ATAPI byte count limit + */ + uint16_t ATAPIByteCount; + + /* + Word 127 + Removable Media Status Notification feature set support + Bits 15 to 2 are reserved + Bits 1 to 0 must be 0 for not supported or 1 for supported. 2 and 3 are reserved. + Obsoleted in ATA8-ACS + */ + uint16_t RemovableStatusSet; + + /* + Word 128 + Security status + */ + uint16_t SecurityStatus; + + /* + Words 129 to 159 + */ + uint16_t ReservedWords129[31]; + + /* + Word 160 + CFA power mode + Bit 15 must be set + Bit 13 indicates mode 1 is required for one or more commands + Bit 12 indicates mode 1 is disabled + Bits 11 to 0 indicates maximum current in mA + */ + uint16_t CFAPowerMode; + + /* + Words 161 to 167 + Reserved for CFA + */ + uint16_t ReservedCFA[7]; + + /* + Word 168 + Bits 15 to 4, reserved + Bits 3 to 0, device nominal form factor + */ + uint16_t DeviceFormFactor; + /* + Word 169 + DATA SET MANAGEMENT support + */ + uint16_t DataSetMgmt; + /* + Words 170 to 173 + Additional product identifier + */ + uint8_t AdditionalPID[8]; + + /* + Word 174 + Reserved + */ + uint16_t ReservedWord174; + /* + Word 175 + Reserved + */ + uint16_t ReservedWord175; + + /* + Words 176 to 195 + Current media serial number + */ + uint8_t MediaSerial[40]; + /* + Words 196 to 205 + Current media manufacturer + */ + uint8_t MediaManufacturer[20]; + + /* + Word 206 + SCT Command Transport features + */ + uint16_t SCTCommandTransport; + + /* + Word 207 + Reserved for CE-ATA + */ + uint16_t ReservedCEATAWord207; + /* + Word 208 + Reserved for CE-ATA + */ + uint16_t ReservedCEATAWord208; + + /* + Word 209 + Alignment of logical block within a larger physical block + Bit 15 shall be cleared to zero + Bit 14 shall be set to one + Bits 13 to 0 indicate logical sector offset within the first physical sector + */ + uint16_t LogicalAlignment; + + /* + Words 210 to 211 + Write/Read/Verify sector count mode 3 only + */ + uint32_t WRVSectorCountMode3; + /* + Words 212 to 213 + Write/Read/Verify sector count mode 2 only + */ + uint32_t WRVSectorCountMode2; + + /* + Word 214 + NV Cache capabilities + Bits 15 to 12 feature set version + Bits 11 to 18 power mode feature set version + Bits 7 to 5 reserved + Bit 4 feature set enabled + Bits 3 to 2 reserved + Bit 1 power mode feature set enabled + Bit 0 power mode feature set supported + */ + uint16_t NVCacheCaps; + /* + Words 215 to 216 + NV Cache Size in Logical BLocks + */ + uint32_t NVCacheSize; + /* + Word 217 + Nominal media rotation rate + In ACS-1 meant NV Cache read speed in MB/s + */ + uint16_t NominalRotationRate; + /* + Word 218 + NV Cache write speed in MB/s + Reserved since ACS-2 + */ + uint16_t NVCacheWriteSpeed; + /* + Word 219 bits 7 to 0 + Estimated device spin up in seconds + */ + uint8_t NVEstimatedSpinUp; + /* + Word 219 bits 15 to 8 + NV Cache reserved + */ + uint8_t NVReserved; + + /* + Word 220 bits 7 to 0 + Write/Read/Verify feature set current mode + */ + uint8_t WRVMode; + /* + Word 220 bits 15 to 8 + Reserved + */ + uint8_t WRVReserved; + + /* + Word 221 + Reserved + */ + uint16_t ReservedWord221; + + /* + Word 222 + Transport major revision number + Bits 15 to 12 indicate transport type. 0 parallel, 1 serial, 0xE PCIe. + Bits 11 to 0 indicate revision + */ + uint16_t TransportMajorVersion; + /* + Word 223 + Transport minor revision number + */ + uint16_t TransportMinorVersion; + + /* + Words 224 to 229 + Reserved for CE-ATA + */ + uint16_t ReservedCEATA224[6]; + + /* + Words 230 to 233 + 48-bit LBA if Word 69 bit 3 is set + */ + uint64_t ExtendedUserSectors; + + /* + Word 234 + Minimum number of 512 byte units per DOWNLOAD MICROCODE mode 3 + */ + uint16_t MinDownloadMicroMode3; + /* + Word 235 + Maximum number of 512 byte units per DOWNLOAD MICROCODE mode 3 + */ + uint16_t MaxDownloadMicroMode3; + + /* + Words 236 to 254 + */ + uint16_t ReservedWords[19]; + + /* + Word 255 bits 7 to 0 + Should be 0xA5 + */ + uint8_t Signature; + /* + Word 255 bits 15 to 8 + Checksum + */ + uint8_t Checksum; +} IdentifyDevice; + unsigned char *AtaToCString(unsigned char* string, int len); int SendAtaCommandChs(int fd, AtaRegistersCHS registers, AtaErrorRegistersCHS **errorRegisters, int protocol, int transferRegister, unsigned char *buffer, unsigned int buffer_len, int transferBlocks); int SendAtaCommandLba28(int fd, AtaRegistersLBA28 registers, AtaErrorRegistersLBA28 **errorRegisters, int protocol, int transferRegister, unsigned char *buffer, unsigned int buffer_len, int transferBlocks); diff --git a/DiscImageChef.Device.Report/atapi_report.c b/DiscImageChef.Device.Report/atapi_report.c new file mode 100644 index 00000000..8c2db8e3 --- /dev/null +++ b/DiscImageChef.Device.Report/atapi_report.c @@ -0,0 +1,195 @@ +// +// Created by claunia on 13/12/17. +// + +#include +#include +#include "atapi_report.h" +#include "ata.h" +#include "atapi.h" +#include "identify_decode.h" + +#define DIC_ATAPI_REPORT_ELEMENT "ATAPI" + +void AtapiReport(int fd, xmlTextWriterPtr xmlWriter) +{ + unsigned char *atapi_ident = NULL; + AtaErrorRegistersCHS *ata_error_chs; + int error; + + error = IdentifyPacket(fd, &atapi_ident, &ata_error_chs); + + if(error) + { + fprintf(stderr, "Error {0} requesting IDENTIFY PACKET DEVICE", error); + return; + } + + IdentifyDevice *identify = malloc(512); + memcpy(identify, atapi_ident, 512); + + xmlTextWriterStartElement(xmlWriter, BAD_CAST DIC_ATAPI_REPORT_ELEMENT); + + if((uint64_t)*identify->AdditionalPID != 0 && (uint64_t)*identify->AdditionalPID != 0x2020202020202020) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "AdditionalPid", AtaToCString(identify->AdditionalPID, 8)); + if(identify->APIOSupported) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "APIOSupported", DecodeTransferMode(le16toh(identify->APIOSupported))); + if(identify->ATAPIByteCount) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "ATAPIByteCount", "%u", le16toh(identify->ATAPIByteCount)); + if(identify->BufferType) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "BufferType", "%u", le16toh(identify->BufferType)); + if(identify->BufferSize) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "BufferSize", "%u", le16toh(identify->BufferSize)); + if(identify->Capabilities) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Capabilities", DecodeCapabilities(le16toh(identify->Capabilities))); + if(identify->Capabilities2) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Capabilities2", DecodeCapabilities2(le16toh(identify->Capabilities2))); + if(identify->Capabilities3) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Capabilities3", DecodeCapabilities3(identify->Capabilities3)); + if(identify->CFAPowerMode) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "CFAPowerMode", "%u", le16toh(identify->CFAPowerMode)); + if(identify->CommandSet) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "CommandSet", DecodeCommandSet(le16toh(identify->CommandSet))); + if(identify->CommandSet2) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "CommandSet2", DecodeCommandSet2(le16toh(identify->CommandSet2))); + if(identify->CommandSet3) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "CommandSet3", DecodeCommandSet3(le16toh(identify->CommandSet3))); + if(identify->CommandSet4) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "CommandSet4", DecodeCommandSet4(le16toh(identify->CommandSet4))); + if(identify->CommandSet5) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "CommandSet5", DecodeCommandSet5(le16toh(identify->CommandSet5))); + if(identify->CurrentAAM) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "CurrentAAM", "%u", identify->CurrentAAM); + if(identify->CurrentAPM) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "CurrentAPM", "%u", le16toh(identify->CurrentAPM)); + if(identify->DataSetMgmt) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "DataSetMgmt", DecodeDataSetMgmt(le16toh(identify->DataSetMgmt))); + if(identify->DataSetMgmtSize) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "DataSetMgmtSize", "%u", le16toh(identify->DataSetMgmtSize)); + if(identify->DeviceFormFactor) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "DeviceFormFactor", DecodeDeviceFormFactor(le16toh(identify->DeviceFormFactor))); + if(identify->DMAActive) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "DMAActive", DecodeTransferMode(le16toh(identify->DMAActive))); + if(identify->DMASupported) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "DMASupported", DecodeTransferMode(le16toh(identify->DMASupported))); + if(identify->DMATransferTimingMode) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "DMATransferTimingMode", "%u", identify->DMATransferTimingMode); + if(identify->EnhancedSecurityEraseTime) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "EnhancedSecurityEraseTime", "%u", le16toh(identify->EnhancedSecurityEraseTime)); + if(identify->EnabledCommandSet) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "EnabledCommandSet", DecodeCommandSet(le16toh(identify->EnabledCommandSet))); + if(identify->EnabledCommandSet2) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "EnabledCommandSet2", DecodeCommandSet2(le16toh(identify->EnabledCommandSet2))); + if(identify->EnabledCommandSet3) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "EnabledCommandSet3", DecodeCommandSet3(le16toh(identify->EnabledCommandSet3))); + if(identify->EnabledCommandSet4) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "EnabledCommandSet4", DecodeCommandSet4(le16toh(identify->EnabledCommandSet4))); + if(identify->EnabledSATAFeatures) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "EnabledSATAFeatures", DecodeSATAFeatures(le16toh(identify->EnabledSATAFeatures))); + if(identify->ExtendedUserSectors) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "ExtendedUserSectors", "%llu", le64toh(identify->ExtendedUserSectors)); + if(identify->FreeFallSensitivity) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "FreeFallSensitivity", "%u", identify->FreeFallSensitivity); + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "FirmwareRevision", AtaToCString(identify->FirmwareRevision, 8)); + if(identify->GeneralConfiguration) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "GeneralConfiguration", DecodeGeneralConfiguration(le16toh(identify->GeneralConfiguration))); + if(identify->HardwareResetResult) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "HardwareResetResult", "%u", le16toh(identify->HardwareResetResult)); + if(identify->InterseekDelay) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "InterseekDelay", "%u", le16toh(identify->InterseekDelay)); + if(identify->MajorVersion) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "MajorVersion", DecodeMajorVersion(le16toh(identify->MajorVersion))); + if(identify->MasterPasswordRevisionCode) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MasterPasswordRevisionCode", "%u", le16toh(identify->MasterPasswordRevisionCode)); + if(identify->MaxDownloadMicroMode3) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MaxDownloadMicroMode3", "%u", le16toh(identify->MaxDownloadMicroMode3)); + if(identify->MaxQueueDepth) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MaxQueueDepth", "%u", le16toh(identify->MaxQueueDepth)); + if(identify->MDMAActive) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "MDMAActive", DecodeTransferMode(le16toh(identify->MDMAActive))); + if(identify->MDMASupported) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "MDMASupported", DecodeTransferMode(le16toh(identify->MDMASupported))); + if(identify->MinDownloadMicroMode3) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MinDownloadMicroMode3", "%u", le16toh(identify->MinDownloadMicroMode3)); + if(identify->MinMDMACycleTime) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MinMDMACycleTime", "%u", le16toh(identify->MinMDMACycleTime)); + if(identify->MinorVersion) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MinorVersion", "%u", le16toh(identify->MinorVersion)); + if(identify->MinPIOCycleTimeNoFlow) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MinPIOCycleTimeNoFlow", "%u", le16toh(identify->MinPIOCycleTimeNoFlow)); + if(identify->MinPIOCycleTimeFlow) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MinPIOCycleTimeFlow", "%u", le16toh(identify->MinPIOCycleTimeFlow)); + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "Model", AtaToCString(identify->Model, 40)); + if(identify->MultipleMaxSectors) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MultipleMaxSectors", "%u", identify->MultipleMaxSectors); + if(identify->MultipleSectorNumber) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MultipleSectorNumber", "%u", identify->MultipleSectorNumber); + if(identify->NVCacheCaps) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "NVCacheCaps", "%u", le16toh(identify->NVCacheCaps)); + if(identify->NVCacheSize) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "NVCacheSize", "%u", le32toh(identify->NVCacheSize)); + if(identify->NVCacheWriteSpeed) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "NVCacheWriteSpeed", "%u", le16toh(identify->NVCacheWriteSpeed)); + if(identify->NVEstimatedSpinUp) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "NVEstimatedSpinUp", "%u", identify->NVEstimatedSpinUp); + if(identify->PacketBusRelease) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "PacketBusRelease", "%u", le16toh(identify->PacketBusRelease)); + if(identify->PIOTransferTimingMode) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "PIOTransferTimingMode", "%u", identify->PIOTransferTimingMode); + if(identify->RecommendedAAM) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "RecommendedAAM", "%u", identify->RecommendedAAM); + if(identify->RecMDMACycleTime) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "RecMDMACycleTime", "%u", le16toh(identify->RecMDMACycleTime)); + if(identify->RemovableStatusSet) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "RemovableStatusSet", "%u", le16toh(identify->RemovableStatusSet)); + if(identify->SATACapabilities) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "SATACapabilities", DecodeSATACapabilities(le16toh(identify->SATACapabilities))); + if(identify->SATACapabilities2) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "SATACapabilities2", DecodeSATACapabilities2(le16toh(identify->SATACapabilities2))); + if(identify->SATAFeatures) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "SATAFeatures", DecodeSATAFeatures(le16toh(identify->SATAFeatures))); + if(identify->SCTCommandTransport) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "SCTCommandTransport", DecodeSCTCommandTransport(le16toh(identify->SCTCommandTransport))); + if(identify->SectorsPerCard) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SectorsPerCard", "%u", le32toh(identify->SectorsPerCard)); + if(identify->SecurityEraseTime) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SecurityEraseTime", "%u", le16toh(identify->SecurityEraseTime)); + if(identify->SecurityStatus) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "SecurityStatus", DecodeSecurityStatus(le16toh(identify->SecurityStatus))); + if(identify->ServiceBusyClear) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "ServiceBusyClear", "%u", le16toh(identify->ServiceBusyClear)); + if(identify->SpecificConfiguration) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "SpecificConfiguration", DecodeSpecificConfiguration(le16toh(identify->SpecificConfiguration))); + if(identify->StreamAccessLatency) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "StreamAccessLatency", "%u", le16toh(identify->StreamAccessLatency)); + if(identify->StreamMinReqSize) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "StreamMinReqSize", "%u", le16toh(identify->StreamMinReqSize)); + if(identify->StreamPerformanceGranularity) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "StreamPerformanceGranularity", "%u", le32toh(identify->StreamPerformanceGranularity)); + if(identify->StreamTransferTimeDMA) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "StreamTransferTimeDMA", "%u", le16toh(identify->StreamTransferTimeDMA)); + if(identify->StreamTransferTimePIO) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "StreamTransferTimePIO", "%u", le16toh(identify->StreamTransferTimePIO)); + if(identify->TransportMajorVersion) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "TransportMajorVersion", "%u", le16toh(identify->TransportMajorVersion)); + if(identify->TransportMinorVersion) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "TransportMinorVersion", "%u", le16toh(identify->TransportMinorVersion)); + if(identify->TrustedComputing) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "TrustedComputing", DecodeTrustedComputing(le16toh(identify->TrustedComputing))); + if(identify->UDMAActive) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "UDMAActive", DecodeTransferMode(le16toh(identify->UDMAActive))); + if(identify->UDMASupported) + xmlTextWriterWriteElement(xmlWriter, BAD_CAST "UDMASupported", DecodeTransferMode(le16toh(identify->UDMASupported))); + if(identify->WRVMode) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "WRVMode", "%u", identify->WRVMode); + if(identify->WRVSectorCountMode3) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "WRVSectorCountMode3", "%u", le32toh(identify->WRVSectorCountMode3)); + if(identify->WRVSectorCountMode2) + xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "WRVSectorCountMode2", "%u", le32toh(identify->WRVSectorCountMode2)); + + xmlTextWriterStartElement(xmlWriter, BAD_CAST "Identify"); + xmlTextWriterWriteBase64(xmlWriter, atapi_ident, 0, 512); + xmlTextWriterEndElement(xmlWriter); + + xmlTextWriterEndElement(xmlWriter); +} \ No newline at end of file diff --git a/DiscImageChef.Device.Report/atapi_report.h b/DiscImageChef.Device.Report/atapi_report.h new file mode 100644 index 00000000..766e9098 --- /dev/null +++ b/DiscImageChef.Device.Report/atapi_report.h @@ -0,0 +1,11 @@ +// +// Created by claunia on 13/12/17. +// + +#ifndef DISCIMAGECHEF_DEVICE_REPORT_ATAPI_REPORT_H +#define DISCIMAGECHEF_DEVICE_REPORT_ATAPI_REPORT_H + +#include + +void AtapiReport(int fd, xmlTextWriterPtr xmlWriter); +#endif //DISCIMAGECHEF_DEVICE_REPORT_ATAPI_REPORT_H diff --git a/DiscImageChef.Device.Report/identify_decode.c b/DiscImageChef.Device.Report/identify_decode.c new file mode 100644 index 00000000..3a5ae8c0 --- /dev/null +++ b/DiscImageChef.Device.Report/identify_decode.c @@ -0,0 +1,2406 @@ +// +// Created by claunia on 14/12/17. +// + +#include +#include +#include +#include "identify_decode.h" + +#define MAX_STRING_SIZE 512 + +char *DecodeGeneralConfiguration(uint16_t configuration) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(configuration & 0x8000) + { + strcat(decoded, "NonMagnetic"); + set = 1; + } + + if(configuration & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FormatGapReq"); + set = 1; + } + + if(configuration & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "TrackOffset"); + set = 1; + } + + if(configuration & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DataStrobeOffset"); + set = 1; + } + + if(configuration & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "RotationalSpeedTolerance"); + set = 1; + } + + if(configuration & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "UltraFastIDE"); + set = 1; + } + + if(configuration & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FastIDE"); + set = 1; + } + + if(configuration & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SlowIDE"); + set = 1; + } + + if(configuration & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Removable"); + set = 1; + } + + if(configuration & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Fixed"); + set = 1; + } + + if(configuration & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SpindleControl"); + set = 1; + } + + if(configuration & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "HighHeadSwitch"); + set = 1; + } + + if(configuration & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NotMFM"); + set = 1; + } + + if(configuration & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "IncompleteResponse"); + set = 1; + } + + if(configuration & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "HardSector"); + set = 1; + } + + if(configuration & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeTransferMode(uint16_t transferMode) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(transferMode & 0x80) + { + strcat(decoded, "Mode7"); + set = 1; + } + + if(transferMode & 0x40) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode6"); + set = 1; + } + + if(transferMode & 0x20) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode5"); + set = 1; + } + + if(transferMode & 0x10) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode4"); + set = 1; + } + + if(transferMode & 0x08) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode3"); + set = 1; + } + + if(transferMode & 0x04) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode2"); + set = 1; + } + + if(transferMode & 0x02) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode1"); + set = 1; + } + + if(transferMode & 0x01) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Mode0"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCapabilities(uint16_t capabilities) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(capabilities & 0x8000) + { + strcat(decoded, "InterleavedDMA"); + set = 1; + } + + if(capabilities & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CommandQueue"); + set = 1; + } + + if(capabilities & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "StandardStanbyTimer"); + set = 1; + } + + if(capabilities & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "RequiresATASoftReset"); + set = 1; + } + + if(capabilities & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "IORDY"); + set = 1; + } + + if(capabilities & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CanDisableIORDY"); + set = 1; + } + + if(capabilities & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "LBASupport"); + set = 1; + } + + if(capabilities & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DMASupport"); + set = 1; + } + + if(capabilities & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "VendorBit7"); + set = 1; + } + + if(capabilities & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "VendorBit6"); + set = 1; + } + + if(capabilities & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "VendorBit5"); + set = 1; + } + + if(capabilities & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "VendorBit4"); + set = 1; + } + + if(capabilities & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "VendorBit3"); + set = 1; + } + + if(capabilities & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "VendorBit2"); + set = 1; + } + + if(capabilities & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "PhysicalAlignment1"); + set = 1; + } + + if(capabilities & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "PhysicalAlignment0"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCapabilities2(uint16_t capabilities) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(capabilities & 0x8000) + { + strcat(decoded, "MustBeClear"); + set = 1; + } + + if(capabilities & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MustBeSet"); + set = 1; + } + + if(capabilities & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(capabilities & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(capabilities & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(capabilities & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(capabilities & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(capabilities & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved08"); + set = 1; + } + + if(capabilities & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(capabilities & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved06"); + set = 1; + } + + if(capabilities & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved05"); + set = 1; + } + + if(capabilities & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved04"); + set = 1; + } + + if(capabilities & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved03"); + set = 1; + } + + if(capabilities & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved02"); + set = 1; + } + + if(capabilities & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved01"); + set = 1; + } + + if(capabilities & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SpecificStandbyTimer"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCapabilities3(uint8_t capabilities) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(capabilities & 0x80) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "BlockErase"); + set = 1; + } + + if(capabilities & 0x40) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Overwrite"); + set = 1; + } + + if(capabilities & 0x20) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CryptoScramble"); + set = 1; + } + + if(capabilities & 0x10) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Sanitize"); + set = 1; + } + + if(capabilities & 0x08) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SanitizeCommands"); + set = 1; + } + + if(capabilities & 0x04) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SanitizeAntifreeze"); + set = 1; + } + + if(capabilities & 0x02) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved01"); + set = 1; + } + + if(capabilities & 0x01) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MultipleValid"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCommandSet(uint16_t commandset) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(commandset & 0x8000) + { + strcat(decoded, "Obsolete15"); + set = 1; + } + + if(commandset & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Nop"); + set = 1; + } + + if(commandset & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ReadBuffer"); + set = 1; + } + + if(commandset & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WriteBuffer"); + set = 1; + } + + if(commandset & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Obsolete11"); + set = 1; + } + + if(commandset & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "HPA"); + set = 1; + } + + if(commandset & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DeviceReset"); + set = 1; + } + + if(commandset & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Service"); + set = 1; + } + + if(commandset & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Release"); + set = 1; + } + + if(commandset & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "LookAhead"); + set = 1; + } + + if(commandset & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WriteCache"); + set = 1; + } + + if(commandset & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Packet"); + set = 1; + } + + if(commandset & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "PowerManagement"); + set = 1; + } + + if(commandset & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "RemovableMedia"); + set = 1; + } + + if(commandset & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SecurityMode"); + set = 1; + } + + if(commandset & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SMART"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCommandSet2(uint16_t commandset) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(commandset & 0x8000) + { + strcat(decoded, "MustBeClear"); + set = 1; + } + + if(commandset & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MustBeSet"); + set = 1; + } + + if(commandset & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FlushCacheExt"); + set = 1; + } + + if(commandset & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FlushCache"); + set = 1; + } + + if(commandset & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DCO"); + set = 1; + } + + if(commandset & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "LBA48"); + set = 1; + } + + if(commandset & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AAM"); + set = 1; + } + + if(commandset & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SetMax"); + set = 1; + } + + if(commandset & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AddressOffsetReservedAreaBoot"); + set = 1; + } + + if(commandset & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SetFeaturesRequired"); + set = 1; + } + + if(commandset & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "PowerUpInStandby"); + set = 1; + } + + if(commandset & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "RemovableNotification"); + set = 1; + } + + if(commandset & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "APM"); + set = 1; + } + + if(commandset & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CompactFlash"); + set = 1; + } + + if(commandset & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DownloadMicrocode"); + set = 1; + } + + if(commandset & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SMART"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCommandSet3(uint16_t commandset) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(commandset & 0x8000) + { + strcat(decoded, "MustBeClear"); + set = 1; + } + + if(commandset & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MustBeSet"); + set = 1; + } + + if(commandset & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "IdleImmediate"); + set = 1; + } + + if(commandset & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(commandset & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(commandset & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WriteURG"); + set = 1; + } + + if(commandset & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ReadURG"); + set = 1; + } + + if(commandset & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WWN"); + set = 1; + } + + if(commandset & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FUAWriteQ"); + set = 1; + } + + if(commandset & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FUAWrite"); + set = 1; + } + + if(commandset & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "GPL"); + set = 1; + } + + if(commandset & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Streaming"); + set = 1; + } + + if(commandset & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MCPT"); + set = 1; + } + + if(commandset & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MediaSerial"); + set = 1; + } + + if(commandset & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SMARTSelfTest"); + set = 1; + } + + if(commandset & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SMARTLog"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCommandSet4(uint16_t commandset) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(commandset & 0x8000) + { + strcat(decoded, "MustBeClear"); + set = 1; + } + + if(commandset & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "MustBeSet"); + set = 1; + } + + if(commandset & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(commandset & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(commandset & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(commandset & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(commandset & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DSN"); + set = 1; + } + + if(commandset & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AMAC"); + set = 1; + } + + if(commandset & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ExtPowerCond"); + set = 1; + } + + if(commandset & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ExtStatusReport"); + set = 1; + } + + if(commandset & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FreeFallControl"); + set = 1; + } + + if(commandset & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SegmentedDownloadMicrocode"); + set = 1; + } + + if(commandset & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "RWDMAExtGpl"); + set = 1; + } + + if(commandset & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WriteUnc"); + set = 1; + } + + if(commandset & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WRV"); + set = 1; + } + + if(commandset & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DT1825"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeCommandSet5(uint16_t commandset) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(commandset & 0x8000) + { + strcat(decoded, "CFast"); + set = 1; + } + + if(commandset & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DeterministicTrim"); + set = 1; + } + + if(commandset & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "LongPhysSectorAligError"); + set = 1; + } + + if(commandset & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DeviceConfDMA"); + set = 1; + } + + if(commandset & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ReadBufferDMA"); + set = 1; + } + + if(commandset & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WriteBufferDMA"); + set = 1; + } + + if(commandset & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SetMaxDMA"); + set = 1; + } + + if(commandset & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DownloadMicroCodeDMA"); + set = 1; + } + + if(commandset & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "IEEE1667"); + set = 1; + } + + if(commandset & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Ata28"); + set = 1; + } + + if(commandset & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ReadZeroTrim"); + set = 1; + } + + if(commandset & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Encrypted"); + set = 1; + } + + if(commandset & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ExtSectors"); + set = 1; + } + + if(commandset & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AllCacheNV"); + set = 1; + } + + if(commandset & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ZonedBit1"); + set = 1; + } + + if(commandset & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ZonedBit0"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeDataSetMgmt(uint16_t datasetmgmt) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(datasetmgmt & 0x8000) + { + strcat(decoded, "Reserved15"); + set = 1; + } + + if(datasetmgmt & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved14"); + set = 1; + } + + if(datasetmgmt & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(datasetmgmt & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(datasetmgmt & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(datasetmgmt & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(datasetmgmt & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(datasetmgmt & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved08"); + set = 1; + } + + if(datasetmgmt & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(datasetmgmt & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved06"); + set = 1; + } + + if(datasetmgmt & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved05"); + set = 1; + } + + if(datasetmgmt & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved04"); + set = 1; + } + + if(datasetmgmt & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved03"); + set = 1; + } + + if(datasetmgmt & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved02"); + set = 1; + } + + if(datasetmgmt & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved01"); + set = 1; + } + + if(datasetmgmt & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Trim"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeDeviceFormFactor(uint16_t formfactor) +{ + switch(formfactor) + { + case 0: + return "NotReported"; + case 1: + return "FiveAndQuarter"; + case 2: + return "ThreeAndHalf"; + case 3: + return "TwoAndHalf"; + case 4: + return "OnePointEight"; + case 5: + return "LessThanOnePointEight"; + default: + return NULL; + } +} + +char *DecodeSATAFeatures(uint16_t features) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(features & 0x8000) + { + strcat(decoded, "Reserved15"); + set = 1; + } + + if(features & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved14"); + set = 1; + } + + if(features & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(features & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(features & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(features & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(features & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(features & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved08"); + set = 1; + } + + if(features & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NCQAutoSense"); + set = 1; + } + + if(features & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "SettingsPreserve"); + set = 1; + } + + if(features & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "HardwareFeatureControl"); + set = 1; + } + + if(features & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "InOrderData"); + set = 1; + } + + if(features & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "InitPowerMgmt"); + set = 1; + } + + if(features & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DMASetup"); + set = 1; + } + + if(features & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NonZeroBufferOffset"); + set = 1; + } + + if(features & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Clear"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeMajorVersion(uint16_t version) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(version & 0x8000) + { + strcat(decoded, "Reserved15"); + set = 1; + } + + if(version & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved14"); + set = 1; + } + + if(version & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(version & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(version & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ACS4"); + set = 1; + } + + if(version & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ACS3"); + set = 1; + } + + if(version & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ACS2"); + set = 1; + } + + if(version & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Ata8ACS"); + set = 1; + } + + if(version & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AtaAtapi7"); + set = 1; + } + + if(version & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AtaAtapi6"); + set = 1; + } + + if(version & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AtaAtapi5"); + set = 1; + } + + if(version & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "AtaAtapi4"); + set = 1; + } + + if(version & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Ata3"); + set = 1; + } + + if(version & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Ata2"); + set = 1; + } + + if(version & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Ata1"); + set = 1; + } + + if(version & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved00"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeSATACapabilities(uint16_t capabilities) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(capabilities & 0x8000) + { + strcat(decoded, "ReadLogDMAExt"); + set = 1; + } + + if(capabilities & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DevSlumbTrans"); + set = 1; + } + + if(capabilities & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "HostSlumbTrans"); + set = 1; + } + + if(capabilities & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NCQPriority"); + set = 1; + } + + if(capabilities & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "UnloadNCQ"); + set = 1; + } + + if(capabilities & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "PHYEventCounter"); + set = 1; + } + + if(capabilities & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "PowerReceipt"); + set = 1; + } + + if(capabilities & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NCQ"); + set = 1; + } + + if(capabilities & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(capabilities & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved06"); + set = 1; + } + + if(capabilities & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved05"); + set = 1; + } + + if(capabilities & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved04"); + set = 1; + } + + if(capabilities & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Gen3Speed"); + set = 1; + } + + if(capabilities & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Gen2Speed"); + set = 1; + } + + if(capabilities & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Gen1Speed"); + set = 1; + } + + if(capabilities & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Clear"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeSATACapabilities2(uint16_t capabilities) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(capabilities & 0x8000) + { + strcat(decoded, "Reserved15"); + set = 1; + } + + if(capabilities & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved14"); + set = 1; + } + + if(capabilities & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(capabilities & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(capabilities & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(capabilities & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(capabilities & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(capabilities & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved08"); + set = 1; + } + + if(capabilities & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(capabilities & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FPDMAQ"); + set = 1; + } + + if(capabilities & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NCQMgmt"); + set = 1; + } + + if(capabilities & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "NCQStream"); + set = 1; + } + + if(capabilities & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CurrentSpeedBit2"); + set = 1; + } + + if(capabilities & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CurrentSpeedBit1"); + set = 1; + } + + if(capabilities & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "CurrentSpeedBit0"); + set = 1; + } + + if(capabilities & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Clear"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeSCTCommandTransport(uint16_t transport) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(transport & 0x8000) + { + strcat(decoded, "Vendor15"); + set = 1; + } + + if(transport & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Vendor14"); + set = 1; + } + + if(transport & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Vendor13"); + set = 1; + } + + if(transport & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Vendor12"); + set = 1; + } + + if(transport & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(transport & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(transport & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(transport & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved08"); + set = 1; + } + + if(transport & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(transport & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved06"); + set = 1; + } + + if(transport & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "DataTables"); + set = 1; + } + + if(transport & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "FeaturesControl"); + set = 1; + } + + if(transport & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "ErrorRecoveryControl"); + set = 1; + } + + if(transport & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "WriteSame"); + set = 1; + } + + if(transport & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "LongSectorAccess"); + set = 1; + } + + if(transport & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Supported"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeSecurityStatus(uint16_t status) +{ + char *decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(status & 0x8000) + { + strcat(decoded, "Reserved15"); + set = 1; + } + + if(status & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved14"); + set = 1; + } + + if(status & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(status & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(status & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(status & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(status & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(status & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Maximum"); + set = 1; + } + + if(status & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(status & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved06"); + set = 1; + } + + if(status & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Enhanced"); + set = 1; + } + + if(status & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Expired"); + set = 1; + } + + if(status & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Frozen"); + set = 1; + } + + if(status & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Locked"); + set = 1; + } + + if(status & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Enabled"); + set = 1; + } + + if(status & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Supported"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} + +char *DecodeSpecificConfiguration(uint16_t configuration) +{ + switch(configuration) + { + case 0x37C8: + return "RequiresSetIncompleteResponse"; + case 0x738C: + return "RequiresSetCompleteResponse"; + case 0x8C73: + return "NotRequiresSetIncompleteResponse"; + case 0xC837: + return "NotRequiresSetCompleteResponse"; + default: + return NULL; + } +} + +char *DecodeTrustedComputing(uint16_t trutedcomputing) +{ + char* decoded = malloc(MAX_STRING_SIZE); + memset(decoded, 0, MAX_STRING_SIZE); + int set = 0; + + if(trutedcomputing & 0x8000) + { + strcat(decoded, "Clear"); + set = 1; + } + + if(trutedcomputing & 0x4000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Set"); + set = 1; + } + + if(trutedcomputing & 0x2000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved13"); + set = 1; + } + + if(trutedcomputing & 0x1000) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved12"); + set = 1; + } + + if(trutedcomputing & 0x0800) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved11"); + set = 1; + } + + if(trutedcomputing & 0x0400) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved10"); + set = 1; + } + + if(trutedcomputing & 0x0200) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved09"); + set = 1; + } + + if(trutedcomputing & 0x0100) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved08"); + set = 1; + } + + if(trutedcomputing & 0x0080) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved07"); + set = 1; + } + + if(trutedcomputing & 0x0040) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved06"); + set = 1; + } + + if(trutedcomputing & 0x0020) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved05"); + set = 1; + } + + if(trutedcomputing & 0x0010) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved04"); + set = 1; + } + + if(trutedcomputing & 0x0008) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved03"); + set = 1; + } + + if(trutedcomputing & 0x0004) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved02"); + set = 1; + } + + if(trutedcomputing & 0x0002) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "Reserved01"); + set = 1; + } + + if(trutedcomputing & 0x0001) + { + if(set) + strcat(decoded, " "); + strcat(decoded, "TrustedComputing"); + set = 1; + } + + if(set) + return decoded; + + return NULL; +} \ No newline at end of file diff --git a/DiscImageChef.Device.Report/identify_decode.h b/DiscImageChef.Device.Report/identify_decode.h new file mode 100644 index 00000000..fb58c350 --- /dev/null +++ b/DiscImageChef.Device.Report/identify_decode.h @@ -0,0 +1,27 @@ +// +// Created by claunia on 14/12/17. +// + +#ifndef DISCIMAGECHEF_DEVICE_REPORT_IDENTIFY_DECODE_H +#define DISCIMAGECHEF_DEVICE_REPORT_IDENTIFY_DECODE_H +char *DecodeGeneralConfiguration(uint16_t configuration); +char *DecodeTransferMode(uint16_t transferMode); +char *DecodeCapabilities(uint16_t capabilities); +char *DecodeCapabilities2(uint16_t capabilities); +char *DecodeCapabilities3(uint8_t capabilities); +char *DecodeCommandSet(uint16_t commandset); +char *DecodeCommandSet2(uint16_t commandset); +char *DecodeCommandSet3(uint16_t commandset); +char *DecodeCommandSet4(uint16_t commandset); +char *DecodeCommandSet5(uint16_t commandset); +char *DecodeDataSetMgmt(uint16_t datasetmgmt); +char *DecodeDeviceFormFactor(uint16_t formfactor); +char *DecodeSATAFeatures(uint16_t features); +char *DecodeMajorVersion(uint16_t capabilities); +char *DecodeSATACapabilities(uint16_t capabilities); +char *DecodeSATACapabilities2(uint16_t transport); +char *DecodeSCTCommandTransport(uint16_t transport); +char *DecodeSecurityStatus(uint16_t status); +char *DecodeSpecificConfiguration(uint16_t configuration); +char *DecodeTrustedComputing(uint16_t trutedcomputing); +#endif //DISCIMAGECHEF_DEVICE_REPORT_IDENTIFY_DECODE_H diff --git a/DiscImageChef.Device.Report/main.c b/DiscImageChef.Device.Report/main.c index fd975caa..d0feab92 100644 --- a/DiscImageChef.Device.Report/main.c +++ b/DiscImageChef.Device.Report/main.c @@ -8,13 +8,17 @@ #include "ata.h" #include "main.h" #include "atapi.h" +#include "atapi_report.h" +#include #define DIC_VERSION "3.99.6.0" #define DIC_COPYRIGHT "Copyright © 2011-2017 Natalia Portillo" +#define XML_ENCODING "UTF-8" +#define DIC_REPORT_ROOT "DicDeviceReport" int main(int argc, void *argv[]) { - int fd; + int fd, rc; unsigned char *scsi_sense = NULL; unsigned char *scsi_inq_data = NULL; unsigned char *ata_ident = NULL; @@ -25,6 +29,8 @@ int main(int argc, void *argv[]) unsigned char* product; unsigned char* revision; int deviceType = DEVICE_TYPE_UNKNOWN; + char* xmlFilename = malloc(NAME_MAX + 1); + xmlTextWriterPtr xmlWriter; printf("The Disc Image Chef Device Reporter for Linux %s\n", DIC_VERSION); printf("%s\n", DIC_COPYRIGHT); @@ -89,6 +95,53 @@ int main(int argc, void *argv[]) printf("Product: %s\n", product); printf("Revision: %s\n", revision); + if(deviceType != DEVICE_TYPE_ATA && deviceType!=DEVICE_TYPE_ATAPI && deviceType != DEVICE_TYPE_SCSI) + { + printf("Unsupported device type %s.", DeviceType[deviceType]); + return 3; + } + + sprintf(xmlFilename, "%s_%s_%s.xml", manufacturer, product, revision); + + xmlWriter = xmlNewTextWriterFilename(xmlFilename, 0); + if(xmlWriter == NULL) + { + printf("Could not create XML report file.\n"); + return 4; + } + + rc = xmlTextWriterStartDocument(xmlWriter, NULL, XML_ENCODING, NULL); + if(rc < 0) + { + printf("Could not create XML report file.\n"); + return 4; + } + + rc = xmlTextWriterStartElement(xmlWriter, BAD_CAST DIC_REPORT_ROOT); + if(rc < 0) + { + printf("Could not create XML report file.\n"); + return 4; + } + + char* xmlComment = malloc(255); + sprintf(xmlComment, "Report created with DiscImageChef.Device.Report v%s", DIC_VERSION); + rc = xmlTextWriterWriteComment(xmlWriter, xmlComment); + if(rc < 0) + { + printf("Could not create XML report file.\n"); + return 4; + } + + if(deviceType == DEVICE_TYPE_ATAPI) + AtapiReport(fd, xmlWriter); + + rc = xmlTextWriterEndDocument(xmlWriter); + if (rc < 0) { + printf("Could not close XML report file.\n"); + return 4; + } + close(fd); return 0;