Added SCSI non-removable report to DiscImageChef.Device.Report.

This commit is contained in:
2017-12-16 23:31:17 +00:00
parent 92d0d6c7a1
commit dcdcfafa87
3 changed files with 530 additions and 9 deletions

View File

@@ -39,8 +39,12 @@ int SendScsiCommand(int fd, void *cdb, unsigned char cdb_len, unsigned char *buf
if(error < 0)
error = errno;
else
free(*senseBuffer);
else if(io_hdr.status != 0)
error = io_hdr.status;
else if(io_hdr.host_status != 0)
error = io_hdr.host_status;
else if(io_hdr.info != 0)
error = io_hdr.info & SG_INFO_OK_MASK;
return error;
}
@@ -262,4 +266,265 @@ int ModeSense10(int fd, unsigned char **buffer, unsigned char **senseBuffer, int
error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
}
int ReadCapacity(int fd, unsigned char **buffer, unsigned char **senseBuffer, int RelAddr, uint32_t address, int PMI)
{
unsigned char cmd_len = 10;
unsigned int buffer_len = 8;
*buffer = malloc(buffer_len);
memset(*buffer, 0, buffer_len);
unsigned char cdb[] = {SCSI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if(PMI)
{
cdb[8] = 0x01;
if(RelAddr)
cdb[1] = 0x01;
cdb[2] = (uint8_t)((address & 0xFF000000) >> 24);
cdb[3] = (uint8_t)((address & 0xFF0000) >> 16);
cdb[4] = (uint8_t)((address & 0xFF00) >> 8);
cdb[5] = (uint8_t)(address & 0xFF);
}
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int ReadCapacity16(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint64_t address, int PMI)
{
unsigned char cmd_len = 16;
unsigned int buffer_len = 32;
*buffer = malloc(buffer_len);
memset(*buffer, 0, buffer_len);
unsigned char cdb[] = {SCSI_SERVICE_ACTION_IN, SCSI_READ_CAPACITY_16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if(PMI)
{
cdb[14] = 0x01;
cdb[2] = (uint8_t)((address & 0xFF00000000000000ULL) >> 56);
cdb[3] = (uint8_t)((address & 0xFF000000000000ULL) >> 48);
cdb[4] = (uint8_t)((address & 0xFF0000000000ULL) >> 40);
cdb[5] = (uint8_t)((address & 0xFF00000000ULL) >> 32);
cdb[6] = (uint8_t)((address & 0xFF000000ULL) >> 24);
cdb[7] = (uint8_t)((address & 0xFF0000ULL) >> 16);
cdb[8] = (uint8_t)((address & 0xFF00ULL) >> 8);
cdb[9] = (uint8_t)(address & 0xFFULL);
}
cdb[10] = (uint8_t)((buffer_len & 0xFF000000) >> 24);
cdb[11] = (uint8_t)((buffer_len & 0xFF0000) >> 16);
cdb[12] = (uint8_t)((buffer_len & 0xFF00) >> 8);
cdb[13] = (uint8_t)(buffer_len & 0xFF);
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int Read6(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint32_t lba, uint32_t blockSize, uint8_t transferLength)
{
unsigned char cmd_len = 6;
unsigned int buflen = transferLength == 0 ? 256 * blockSize : transferLength * blockSize;
*buffer = malloc(buflen);
memset(*buffer, 0, buflen);
unsigned char cdb[] = {SCSI_READ, 0, 0, 0, 0, 0};
cdb[1] = (uint8_t)((lba & 0x1F0000) >> 16);
cdb[2] = (uint8_t)((lba & 0xFF00) >> 8);
cdb[3] = (uint8_t)(lba & 0xFF);
cdb[4] = transferLength;
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buflen, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int Read10(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint8_t rdprotect, int dpo, int fua, int fuaNv, int relAddr, uint32_t lba, uint32_t blockSize, uint8_t groupNumber, uint16_t transferLength)
{
unsigned char cmd_len = 10;
unsigned int buflen = transferLength * blockSize;
*buffer = malloc(buflen);
memset(*buffer, 0, buflen);
unsigned char cdb[] = {SCSI_READ_10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
cdb[1] = (uint8_t)((rdprotect & 0x07) << 5);
if(dpo)
cdb[1] += 0x10;
if(fua)
cdb[1] += 0x08;
if(fuaNv)
cdb[1] += 0x02;
if(relAddr)
cdb[1] += 0x01;
cdb[2] = (uint8_t)((lba & 0xFF000000) >> 24);
cdb[3] = (uint8_t)((lba & 0xFF0000) >> 16);
cdb[4] = (uint8_t)((lba & 0xFF00) >> 8);
cdb[5] = (uint8_t)(lba & 0xFF);
cdb[6] = (uint8_t)(groupNumber & 0x1F);
cdb[7] = (uint8_t)((transferLength & 0xFF00) >> 8);
cdb[8] = (uint8_t)(transferLength & 0xFF);
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buflen, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int Read12(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint8_t rdprotect, int dpo, int fua, int fuaNv, int relAddr, uint32_t lba, uint32_t blockSize, uint8_t groupNumber, uint32_t transferLength, int streaming)
{
unsigned char cmd_len = 12;
unsigned int buflen = transferLength * blockSize;
*buffer = malloc(buflen);
memset(*buffer, 0, buflen);
unsigned char cdb[] = {SCSI_READ_12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
cdb[1] = (uint8_t)((rdprotect & 0x07) << 5);
if(dpo)
cdb[1] += 0x10;
if(fua)
cdb[1] += 0x08;
if(fuaNv)
cdb[1] += 0x02;
if(relAddr)
cdb[1] += 0x01;
cdb[2] = (uint8_t)((lba & 0xFF000000) >> 24);
cdb[3] = (uint8_t)((lba & 0xFF0000) >> 16);
cdb[4] = (uint8_t)((lba & 0xFF00) >> 8);
cdb[5] = (uint8_t)(lba & 0xFF);
cdb[6] = (uint8_t)((transferLength & 0xFF000000) >> 24);
cdb[7] = (uint8_t)((transferLength & 0xFF0000) >> 16);
cdb[8] = (uint8_t)((transferLength & 0xFF00) >> 8);
cdb[9] = (uint8_t)(transferLength & 0xFF);
cdb[10] = (uint8_t)(groupNumber & 0x1F);
if(streaming)
cdb[10] += 0x80;
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buflen, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int Read16(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint8_t rdprotect, int dpo, int fua, int fuaNv, uint64_t lba, uint32_t blockSize, uint8_t groupNumber, uint32_t transferLength, int streaming)
{
unsigned char cmd_len = 16;
unsigned int buflen = transferLength * blockSize;
*buffer = malloc(buflen);
memset(*buffer, 0, buflen);
unsigned char cdb[] = {SCSI_READ_16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
cdb[1] = (uint8_t)((rdprotect & 0x07) << 5);
if(dpo)
cdb[1] += 0x10;
if(fua)
cdb[1] += 0x08;
if(fuaNv)
cdb[1] += 0x02;
cdb[2] = (uint8_t)((lba & 0xFF00000000000000ULL) >> 56);
cdb[3] = (uint8_t)((lba & 0xFF000000000000ULL) >> 48);
cdb[4] = (uint8_t)((lba & 0xFF0000000000ULL) >> 40);
cdb[5] = (uint8_t)((lba & 0xFF00000000ULL) >> 32);
cdb[6] = (uint8_t)((lba & 0xFF000000ULL) >> 24);
cdb[7] = (uint8_t)((lba & 0xFF0000ULL) >> 16);
cdb[8] = (uint8_t)((lba & 0xFF00ULL) >> 8);
cdb[9] = (uint8_t)(lba & 0xFFULL);
cdb[10] = (uint8_t)((transferLength & 0xFF000000) >> 24);
cdb[11] = (uint8_t)((transferLength & 0xFF0000) >> 16);
cdb[12] = (uint8_t)((transferLength & 0xFF00) >> 8);
cdb[13] = (uint8_t)(transferLength & 0xFF);
cdb[14] = (uint8_t)(groupNumber & 0x1F);
if(streaming)
cdb[14] += 0x80;
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buflen, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int ReadLong10(int fd, unsigned char **buffer, unsigned char **senseBuffer, int correct, int relAddr, uint32_t lba, uint16_t transferBytes)
{
unsigned char cmd_len = 10;
*buffer = malloc(transferBytes);
memset(*buffer, 0, transferBytes);
unsigned char cdb[] = {SCSI_READ_LONG, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if(correct)
cdb[1] += 0x02;
if(relAddr)
cdb[1] += 0x01;
cdb[2] = (uint8_t)((lba & 0xFF000000) >> 24);
cdb[3] = (uint8_t)((lba & 0xFF0000) >> 16);
cdb[4] = (uint8_t)((lba & 0xFF00) >> 8);
cdb[5] = (uint8_t)(lba & 0xFF);
cdb[7] = (uint8_t)((transferBytes & 0xFF00) >> 8);
cdb[8] = (uint8_t)(transferBytes & 0xFF);
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, transferBytes, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int ReadLong16(int fd, unsigned char **buffer, unsigned char **senseBuffer, int correct, uint64_t lba, uint32_t transferBytes)
{
unsigned char cmd_len = 16;
*buffer = malloc(transferBytes);
memset(*buffer, 0, transferBytes);
unsigned char cdb[] = {SCSI_SERVICE_ACTION_IN, SCSI_READ_LONG_16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
cdb[2] = (uint8_t)((lba & 0xFF00000000000000ULL) >> 56);
cdb[3] = (uint8_t)((lba & 0xFF000000000000ULL) >> 48);
cdb[4] = (uint8_t)((lba & 0xFF0000000000ULL) >> 40);
cdb[5] = (uint8_t)((lba & 0xFF00000000ULL) >> 32);
cdb[6] = (uint8_t)((lba & 0xFF000000ULL) >> 24);
cdb[7] = (uint8_t)((lba & 0xFF0000ULL) >> 16);
cdb[8] = (uint8_t)((lba & 0xFF00ULL) >> 8);
cdb[9] = (uint8_t)(lba & 0xFFULL);
cdb[12] = (uint8_t)((transferBytes & 0xFF00) >> 8);
cdb[13] = (uint8_t)(transferBytes & 0xFF);
if(correct)
cdb[14] += 0x01;
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, transferBytes, senseBuffer, SG_DXFER_FROM_DEV);
return error;
}
int Seek6(int fd, unsigned char **senseBuffer, uint32_t lba)
{
unsigned char cmd_len = 6;
char cdb[] = {SCSI_SEEK, 0, 0, 0, 0, 0};
unsigned char *buffer = malloc(0);
cdb[1] = (uint8_t)((lba & 0x1F0000) >> 16);
cdb[2] = (uint8_t)((lba & 0xFF00) >> 8);
cdb[3] = (uint8_t)(lba & 0xFF);
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
return error;
}
int Seek10(int fd, unsigned char **senseBuffer, uint32_t lba)
{
unsigned char cmd_len = 10;
char cdb[] = {SCSI_SEEK_10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char *buffer = malloc(0);
cdb[2] = (uint8_t)((lba & 0xFF000000) >> 24);
cdb[3] = (uint8_t)((lba & 0xFF0000) >> 16);
cdb[4] = (uint8_t)((lba & 0xFF00) >> 8);
cdb[5] = (uint8_t)(lba & 0xFF);
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
return error;
}

View File

@@ -25,16 +25,36 @@ int Unload(int fd, unsigned char **senseBuffer);
int LoadUnload(int fd, unsigned char **senseBuffer, int immediate, int load, int retense, int endOfTape, int hold);
int ModeSense6(int fd, unsigned char **buffer, unsigned char **senseBuffer, int DBD, uint8_t pageControl, uint8_t pageCode, uint8_t subPageCode);
int ModeSense10(int fd, unsigned char **buffer, unsigned char **senseBuffer, int LLBAA, int DBD, uint8_t pageContorl, uint8_t pageCode, uint8_t subPageCode);
int ReadCapacity(int fd, unsigned char **buffer, unsigned char **senseBuffer, int RelAddr, uint32_t address, int PMI);
int ReadCapacity16(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint64_t address, int PMI);
int Read6(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint32_t lba, uint32_t blockSize, uint8_t transferLength);
int Read10(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint8_t rdprotect, int dpo, int fua, int fuaNv, int relAddr, uint32_t lba, uint32_t blockSize, uint8_t groupNumber, uint16_t transferLength);
int Read12(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint8_t rdprotect, int dpo, int fua, int fuaNv, int relAddr, uint32_t lba, uint32_t blockSize, uint8_t groupNumber, uint32_t transferLength, int streaming);
int Read16(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint8_t rdprotect, int dpo, int fua, int fuaNv, uint64_t lba, uint32_t blockSize, uint8_t groupNumber, uint32_t transferLength, int streaming);
int ReadLong10(int fd, unsigned char **buffer, unsigned char **senseBuffer, int correct, int relAddr, uint32_t lba, uint16_t transferBytes);
int ReadLong16(int fd, unsigned char **buffer, unsigned char **senseBuffer, int correct, uint64_t lba, uint32_t transferBytes);
int Seek6(int fd, unsigned char **senseBuffer, uint32_t lba);
int Seek10(int fd, unsigned char **senseBuffer, uint32_t lba);
typedef enum
{
SCSI_TEST_UNIT_READY = 0x00,
SCSI_READ = 0x08,
SCSI_SEEK = 0x0B,
SCSI_INQUIRY = 0x12,
SCSI_START_STOP_UNIT = 0x1B,
SCSI_LOAD_UNLOAD = SCSI_START_STOP_UNIT,
SCSI_MODE_SENSE = 0x1A,
SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
SCSI_READ_CAPACITY = 0x25,
SCSI_READ_10 = 0x28,
SCSI_READ_LONG = 0x3E,
SCSI_SEEK_10 = 0x2B,
SCSI_MODE_SENSE_10 = 0x5A,
SCSI_ATA_PASSTHROUGH_16 = 0x85
SCSI_ATA_PASSTHROUGH_16 = 0x85,
SCSI_READ_16 = 0x88,
SCSI_SERVICE_ACTION_IN = 0x9E,
SCSI_READ_12 = 0xA8,
} ScsiCommands;
typedef enum
@@ -45,6 +65,12 @@ typedef enum
MODE_PAGE_SAVED = 0xC0
} ScsiModeSensePageControl;
typedef enum
{
SCSI_READ_CAPACITY_16 = 0x10,
SCSI_READ_LONG_16 = 0x11,
} ScsiServiceActionIn;
// SCSI INQUIRY command response
#pragma pack(1)
typedef struct

View File

@@ -17,6 +17,19 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
int removable = FALSE;
char user_response = ' ';
unsigned char* tmpString;
const int testSize512[] = {514,
// Long sector sizes for SuperDisk
536, 558,
// Long sector sizes for 512-byte magneto-opticals
600, 610, 630};
const int testSize1024[] = {
// Long sector sizes for floppies
1026,
// Long sector sizes for 1024-byte magneto-opticals
1200};
const int testSize2048[] = {2380};
const int testSize4096[] = {4760};
const int testSize8192[] = {9424};
printf("Querying SCSI INQUIRY...\n");
@@ -134,7 +147,7 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
if(error)
{
printf("Querying all mode pages using SCSI MODE SENSE (10)...");
printf("Querying all mode pages using SCSI MODE SENSE (10)...\n");
error = ModeSense10(fd, &mode10Response, &sense, FALSE, TRUE, MODE_PAGE_DEFAULT, 0x3F, 0x00);
if(!error)
supportsMode10 = TRUE;
@@ -149,11 +162,11 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
error = ModeSense6(fd, &mode6Response, &sense, FALSE, MODE_PAGE_DEFAULT, 0x3F, 0xFF);
if(error)
{
printf("Querying all mode pages using SCSI MODE SENSE (6)...");
printf("Querying all mode pages using SCSI MODE SENSE (6)...\n");
error = ModeSense6(fd, &mode6Response, &sense, FALSE, MODE_PAGE_DEFAULT, 0x3F, 0x00);
if(error)
{
printf("Querying SCSI MODE SENSE (6)...");
printf("Querying SCSI MODE SENSE (6)...\n");
error = ModeSense6(fd, &mode6Response, &sense, FALSE, MODE_PAGE_DEFAULT, 0x00, 0x00);
if(!error)
supportsMode6 = TRUE;
@@ -186,12 +199,22 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
}
DecodedMode decMode;
DecodedMode decMode6;
DecodedMode decMode10;
memset(&decMode, 0, sizeof(DecodedMode));
memset(&decMode6, 0, sizeof(DecodedMode));
memset(&decMode10, 0, sizeof(DecodedMode));
if(supportsMode10)
decMode = DecodeMode10(mode10Response, inquiry->PeripheralDeviceType);
{
decMode10 = DecodeMode10(mode10Response, inquiry->PeripheralDeviceType);
memcpy(&decMode, &decMode10, sizeof(DecodedMode));
}
else if(supportsMode6)
decMode = DecodeMode6(mode6Response, inquiry->PeripheralDeviceType);
{
decMode6 = DecodeMode6(mode6Response, inquiry->PeripheralDeviceType);
memcpy(&decMode, &decMode6, sizeof(DecodedMode));
}
if(decMode.decoded)
{
@@ -229,6 +252,212 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
xmlTextWriterEndElement(xmlWriter); // </ModeSense>
}
if(inquiry->PeripheralDeviceType == 0x05) // MultiMediaDevice
{
// TODO: Report MMC
}
else if(inquiry->PeripheralDeviceType == 0x01) // SequentialAccess
{
// TODO: Report SSC
}
else
{
if(removable)
{
// TODO: Removable
}
else
{
uint64_t blocks = 0;
uint32_t blockSize = 0;
xmlTextWriterStartElement(xmlWriter, BAD_CAST "ReadCapabilities"); // <ReadCapabilities>
printf("Querying SCSI READ CAPACITY...\n");
error = ReadCapacity(fd, &buffer, &sense, FALSE, 0, FALSE);
if(!error)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsReadCapacity", "%s", "true");
blocks = (uint64_t)(buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3]) + 1;
blockSize = (uint32_t)((buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]));
}
printf("Querying SCSI READ CAPACITY (16)...\n");
error = ReadCapacity16(fd, &buffer, &sense, FALSE, 0);
if(!error)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsReadCapacity16", "%s", "true");
blocks = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + (buffer[3]);
blocks <<= 32;
blocks += (buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7]);
blocks++;
blockSize = (uint32_t)((buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11]));
}
if(blocks != 0)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Blocks", "%llu", blocks);
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "BlockSize", "%lu", blockSize);
}
decMode.decoded = 0;
if(supportsMode10)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsModeSense10", "%s", "true");
xmlTextWriterStartElement(xmlWriter, BAD_CAST "ModeSense10Data");
xmlTextWriterWriteBase64(xmlWriter, mode10Response, 0, (*(mode10Response + 0) << 8) + *(mode10Response + 1) + 2);
xmlTextWriterEndElement(xmlWriter);
}
if(supportsMode6)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsModeSense6", "%s", "true");
xmlTextWriterStartElement(xmlWriter, BAD_CAST "ModeSense6Data");
xmlTextWriterWriteBase64(xmlWriter, mode6Response, 0, *(mode6Response + 0) + 1);
xmlTextWriterEndElement(xmlWriter);
}
if(decMode.decoded)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MediumType", "%d", decMode.Header.MediumType);
if(decMode.Header.descriptorsLength > 0)
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Density", "%d", decMode.Header.BlockDescriptors[0].Density);
}
printf("Trying SCSI READ (6)...\n");
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsRead", "%s", !Read6(fd, &buffer, &sense, 0, blockSize, 1) ? "true" : "false");
printf("Trying SCSI READ (10)...\n");
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsRead10", "%s", !Read10(fd, &buffer, &sense, 0, FALSE, TRUE, FALSE, FALSE, 0, blockSize, 0, 1) ? "true" : "false");
printf("Trying SCSI READ (12)...\n");
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsRead12", "%s", !Read12(fd, &buffer, &sense, 0, FALSE, TRUE, FALSE, FALSE, 0, blockSize, 0, 1, FALSE) ? "true" : "false");
printf("Trying SCSI READ (16)...\n");
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsRead16", "%s", !Read16(fd, &buffer, &sense, 0, FALSE, TRUE, FALSE, 0, blockSize, 0, 1, FALSE) ? "true" : "false");
uint32_t longBlockSize = blockSize;
int supportsReadLong10 = FALSE;
printf("Trying SCSI READ LONG (10)...\n");
ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, 0xFFFF);
if((sense[0] == 0x70 || sense[0] == 0x71) && (sense[2] & 0x0F) == 0x05 && sense[12] == 0x24 && sense[13] == 0x00)
{
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsReadLong", "%s", "true");
supportsReadLong10 = TRUE;
if(sense[0] & 0x80 && sense[2] & 0x20)
{
uint32_t information = (sense[3] << 24) + (sense[4] << 16) + (sense[5] << 8) + sense[6];
longBlockSize = 0xFFFF - (information & 0xFFFF);
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "LongBlockSize", "%d", longBlockSize);
}
}
printf("Trying SCSI READ LONG (10)...\n");
ReadLong16(fd, &buffer, &sense, FALSE, 0, 0xFFFF);
if((sense[0] == 0x70 || sense[0] == 0x71) && (sense[2] & 0x0F) == 0x05 && sense[12] == 0x24 && sense[13] == 0x00)
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsReadLong16", "%s", "true");
int i;
if(supportsReadLong10 && blockSize == longBlockSize)
{
if(blockSize == 512)
{
for(i = 0; i < sizeof(testSize512) / sizeof(int); i++)
{
error = ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, testSize512[i]);
if(!error)
{
longBlockSize = testSize512[i];
break;
}
}
}
else if(blockSize == 1024)
{
for(i = 0; i < sizeof(testSize1024) / sizeof(int); i++)
{
error = ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, testSize1024[i]);
if(!error)
{
longBlockSize = testSize1024[i];
break;
}
}
}
else if(blockSize == 2048)
{
for(i = 0; i < sizeof(testSize2048) / sizeof(int); i++)
{
error = ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, testSize2048[i]);
if(!error)
{
longBlockSize = testSize2048[i];
break;
}
}
}
else if(blockSize == 4096)
{
for(i = 0; i < sizeof(testSize4096) / sizeof(int); i++)
{
error = ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, testSize4096[i]);
if(!error)
{
longBlockSize = testSize4096[i];
break;
}
}
}
else if(blockSize == 8192)
{
for(i = 0; i < sizeof(testSize8192) / sizeof(int); i++)
{
error = ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, testSize8192[i]);
if(!error)
{
longBlockSize = testSize8192[i];
break;
}
}
}
}
if(supportsReadLong10 && blockSize == longBlockSize)
{
do
{
printf("Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours) (Y/N): ");
scanf("%c", &user_response);
printf("\n");
} while(user_response != 'Y' && user_response != 'y' && user_response != 'N' && user_response != 'n');
if(user_response == 'Y' || user_response == 'y')
{
for(i = blockSize; i <= 65536; i++)
{
printf("\rTrying to READ LONG with a size of %d bytes", i);
error = ReadLong10(fd, &buffer, &sense, FALSE, FALSE, 0, i);
if(!error)
{
longBlockSize = i;
break;
}
}
printf("\n");
}
}
if(supportsReadLong10 && blockSize != longBlockSize)
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "LongBlockSize", "%d", longBlockSize);
xmlTextWriterEndElement(xmlWriter); // </ReadCapabilities>
}
}
xmlTextWriterEndElement(xmlWriter); // </SCSI>
}
@@ -442,6 +671,7 @@ DecodedMode DecodeMode10(unsigned char* modeResponse, uint8_t deviceType)
while(offset < length)
{
printf("%doff\n", offset);
int isSubpage = (modeResponse[offset] & 0x40) == 0x40;
uint8_t pageNo = (uint8_t)(modeResponse[offset] & 0x3F);