mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Added SSC report to DiscImageChef.Device.Report.
This commit is contained in:
@@ -7,5 +7,5 @@ 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 scsi_report.c scsi_report.h inquiry_decode.c inquiry_decode.h scsi_mode.h scsi_mode.c mmc_report.c mmc_report.h cdrom_mode.h)
|
||||
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 scsi_report.c scsi_report.h inquiry_decode.c inquiry_decode.h scsi_mode.h scsi_mode.c mmc_report.c mmc_report.h cdrom_mode.h ssc_report.c ssc_report.h)
|
||||
target_link_libraries(DiscImageChef_Device_Report ${LIBXML2_LIBRARIES})
|
||||
@@ -847,3 +847,83 @@ int HlDtStReadRawDvd(int fd, unsigned char **buffer, unsigned char **senseBuffer
|
||||
return error;
|
||||
}
|
||||
|
||||
int ReadBlockLimits(int fd, unsigned char **buffer, unsigned char **senseBuffer)
|
||||
{
|
||||
unsigned char cmd_len = 6;
|
||||
unsigned int buffer_len = 6;
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
|
||||
unsigned char cdb[] = {SCSI_READ_BLOCK_LIMITS, 0, 0, 0, 0, 0};
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int ReportDensitySupport(int fd, unsigned char **buffer, unsigned char **senseBuffer, int mediumType, int currentMedia)
|
||||
{
|
||||
unsigned char cmd_len = 10;
|
||||
unsigned int buffer_len = 256;
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
|
||||
unsigned char cdb[] = {SCSI_REPORT_DENSITY_SUPPORT, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
if(currentMedia)
|
||||
cdb[1] |= 0x01;
|
||||
if(mediumType)
|
||||
cdb[1] |= 0x02;
|
||||
cdb[7] = (uint8_t)((buffer_len & 0xFF00) >> 8);
|
||||
cdb[8] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
buffer_len = (unsigned int)(*(*buffer + 0) << 8) + *(*buffer + 1) + 2;
|
||||
|
||||
free(*buffer);
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
cdb[7] = (uint8_t)((buffer_len & 0xFF00) >> 8);
|
||||
cdb[8] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int ReadMediaSerialNumber(int fd, unsigned char **buffer, unsigned char **senseBuffer)
|
||||
{
|
||||
unsigned char cmd_len = 12;
|
||||
unsigned int buffer_len = 256;
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
|
||||
unsigned char cdb[] = {SCSI_READ_MEDIA_SERIAL, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
cdb[6] = (uint8_t)((buffer_len & 0xFF000000) >> 24);
|
||||
cdb[7] = (uint8_t)((buffer_len & 0xFF0000) >> 16);
|
||||
cdb[8] = (uint8_t)((buffer_len & 0xFF00) >> 8);
|
||||
cdb[9] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
buffer_len = (unsigned int)((*(*buffer + 0) << 24) + (*(*buffer + 1) << 16)) + (*(*buffer + 2) << 8) + *(*buffer + 3) + 4;
|
||||
|
||||
free(*buffer);
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
cdb[6] = (uint8_t)((buffer_len & 0xFF000000) >> 24);
|
||||
cdb[7] = (uint8_t)((buffer_len & 0xFF0000) >> 16);
|
||||
cdb[8] = (uint8_t)((buffer_len & 0xFF00) >> 8);
|
||||
cdb[9] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -47,10 +47,14 @@ int PioneerReadCdDa(int fd, unsigned char **buffer, unsigned char **senseBuffer,
|
||||
int PioneerReadCdDaMsf(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint32_t startMsf, uint32_t endMsf, uint32_t blockSize, uint8_t subchannel);
|
||||
int NecReadCdDa(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint32_t lba, uint32_t transferLength);
|
||||
int HlDtStReadRawDvd(int fd, unsigned char **buffer, unsigned char **senseBuffer, uint32_t lba, uint32_t transferLength);
|
||||
int ReadBlockLimits(int fd, unsigned char **buffer, unsigned char **senseBuffer);
|
||||
int ReportDensitySupport(int fd, unsigned char **buffer, unsigned char **senseBuffer, int mediumType, int currentMedia);
|
||||
int ReadMediaSerialNumber(int fd, unsigned char **buffer, unsigned char **senseBuffer);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SCSI_TEST_UNIT_READY = 0x00,
|
||||
SCSI_READ_BLOCK_LIMITS = 0x05,
|
||||
SCSI_READ = 0x08,
|
||||
SCSI_SEEK = 0x0B,
|
||||
SCSI_INQUIRY = 0x12,
|
||||
@@ -64,12 +68,14 @@ typedef enum
|
||||
SCSI_SEEK_10 = 0x2B,
|
||||
SCSI_READ_BUFFER = 0x3C,
|
||||
MMC_READ_TOC_PMA_ATIP = 0x43,
|
||||
SCSI_REPORT_DENSITY_SUPPORT = 0x44,
|
||||
MMC_GET_CONFIGURATION = 0x46,
|
||||
SCSI_MODE_SENSE_10 = 0x5A,
|
||||
SCSI_ATA_PASSTHROUGH_16 = 0x85,
|
||||
SCSI_READ_16 = 0x88,
|
||||
SCSI_SERVICE_ACTION_IN = 0x9E,
|
||||
SCSI_READ_12 = 0xA8,
|
||||
SCSI_READ_MEDIA_SERIAL = 0xAB,
|
||||
MMC_READ_DISC_STRUCTURE = 0xAD,
|
||||
MMC_READ_CD_MSF = 0xB9,
|
||||
MMC_READ_CD = 0xBE,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "inquiry_decode.h"
|
||||
#include "scsi_mode.h"
|
||||
#include "mmc_report.h"
|
||||
#include "ssc_report.h"
|
||||
|
||||
void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
|
||||
{
|
||||
@@ -251,7 +252,7 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
|
||||
}
|
||||
else if(inquiry->PeripheralDeviceType == 0x01) // SequentialAccess
|
||||
{
|
||||
// TODO: Report SSC
|
||||
SscReport(fd, xmlWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
307
DiscImageChef.Device.Report/ssc_report.c
Normal file
307
DiscImageChef.Device.Report/ssc_report.c
Normal file
@@ -0,0 +1,307 @@
|
||||
//
|
||||
// Created by claunia on 18/12/17.
|
||||
//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libxml/xmlwriter.h>
|
||||
#include "ssc_report.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_mode.h"
|
||||
|
||||
DensitySupport *DecodeDensity(unsigned char *response);
|
||||
MediaTypeSupport *DecodeMediumTypes(unsigned char *response);
|
||||
|
||||
void SscReport(int fd, xmlTextWriterPtr xmlWriter)
|
||||
{
|
||||
unsigned char *sense = NULL;
|
||||
unsigned char *buffer = NULL;
|
||||
int i, error, len;
|
||||
char user_response = ' ';
|
||||
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SequentialDevice"); // <SequentialDevice>
|
||||
|
||||
printf("Querying SCSI READ BLOCK LIMITS...\n");
|
||||
error = ReadBlockLimits(fd, &buffer, &sense);
|
||||
if(!error)
|
||||
{
|
||||
uint8_t granularity = (uint8_t)(buffer[0] & 0x1F);
|
||||
uint32_t maxBlockLen = (uint32_t)((buffer[1] << 16) + (buffer[2] << 8) + buffer[3]);
|
||||
uint16_t minBlockLen = (uint16_t)((buffer[4] << 8) + buffer[5]);
|
||||
|
||||
if(granularity > 0)
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "BlockSizeGranularity", "%d", granularity);
|
||||
if(maxBlockLen > 0)
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MaxBlockLength", "%d", maxBlockLen);
|
||||
if(minBlockLen > 0)
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MinBlockLength", "%d", minBlockLen);
|
||||
}
|
||||
|
||||
printf("Querying SCSI REPORT DENSITY SUPPORT...\n");
|
||||
error = ReportDensitySupport(fd, &buffer, &sense, FALSE, FALSE);
|
||||
if(!error)
|
||||
{
|
||||
DensitySupport *dsh = DecodeDensity(buffer);
|
||||
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedDensities"); // <SupportedDensities>
|
||||
|
||||
for(i = 0; i < dsh->count; i++)
|
||||
{
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedDensity"); // <SupportedDensity>
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "BitsPerMm", "%d", (dsh->descriptors[i]->bitsPerMm[0] << 16) + (dsh->descriptors[i]->bitsPerMm[1] << 8) + dsh->descriptors[i]->bitsPerMm[2]);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Capacity", "%d", be32toh(dsh->descriptors[i]->capacity));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "DefaultDensity", "%s", dsh->descriptors[i]->deflt ? "true" : "false");
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Description", "%20s", dsh->descriptors[i]->description);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Duplicate", "%s", dsh->descriptors[i]->dup ? "true" : "false");
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Name", "%8s", dsh->descriptors[i]->densityName);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Organization", "%8s", dsh->descriptors[i]->organization);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "PrimaryCode", "%d", dsh->descriptors[i]->primaryCode);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SecondaryCode", "%d", dsh->descriptors[i]->secondaryCode);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Tracks", "%d", be16toh(dsh->descriptors[i]->tracks));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Width", "%d", be16toh(dsh->descriptors[i]->mediaWidth));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Writable", "%s", dsh->descriptors[i]->wrtok ? "true" : "false");
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedDensity>
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedDensities>
|
||||
}
|
||||
|
||||
printf("Querying SCSI REPORT DENSITY SUPPORT for medium types...\n");
|
||||
error = ReportDensitySupport(fd, &buffer, &sense, TRUE, FALSE);
|
||||
if(!error)
|
||||
{
|
||||
MediaTypeSupport *mtsh = DecodeMediumTypes(buffer);
|
||||
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedMediaTypes"); // <SupportedMediaTypes>
|
||||
|
||||
for(i = 0; i < mtsh->count; i++)
|
||||
{
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedMedia"); // <SupportedMedia>
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Description", "%20s", mtsh->descriptors[i]->description);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Length", "%d", be16toh(mtsh->descriptors[i]->length));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MediumType", "%d", mtsh->descriptors[i]->mediumType);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Name", "%8s", mtsh->descriptors[i]->densityName);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Organization", "%8s", mtsh->descriptors[i]->organization);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Width", "%d", be16toh(mtsh->descriptors[i]->mediaWidth));
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedDensity"); // <SupportedDensity>
|
||||
// TODO: Density codes
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedMedia>
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedMediaTypes>
|
||||
}
|
||||
|
||||
user_response = ' ';
|
||||
int anyMedia = FALSE;
|
||||
DecodedMode *decMode;
|
||||
|
||||
while(user_response != 'N' && user_response != 'n')
|
||||
{
|
||||
do
|
||||
{
|
||||
printf("Do you have media that you can insert in the drive? (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')
|
||||
{
|
||||
printf("Please insert it in the drive and press any key when it is ready.\n");
|
||||
scanf("%c");
|
||||
|
||||
char mediaManufacturer[256], mediaName[256], mediaModel[256];
|
||||
printf("Please write a description of the media type and press enter: ");
|
||||
gets(mediaName);
|
||||
printf("Please write the media manufacturer and press enter: ");
|
||||
gets(mediaManufacturer);
|
||||
printf("Please write the media model and press enter: ");
|
||||
gets(mediaModel);
|
||||
|
||||
error = TestUnitReady(fd, &sense);
|
||||
int mediaRecognized = TRUE;
|
||||
int leftRetries = 20;
|
||||
|
||||
if(error)
|
||||
{
|
||||
if((sense[0] == 0x70 || sense[0] == 0x71) && (sense[2] & 0x0F) != 0x00)
|
||||
{
|
||||
if(sense[12] == 0x3A || (sense[12] == 0x04 && sense[13] == 0x01))
|
||||
{
|
||||
while(leftRetries > 0)
|
||||
{
|
||||
printf("\rWating for drive to become ready");
|
||||
sleep(2);
|
||||
error = TestUnitReady(fd, &sense);
|
||||
if(!error)
|
||||
break;
|
||||
|
||||
leftRetries--;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
mediaRecognized = !error;
|
||||
}
|
||||
else
|
||||
mediaRecognized = FALSE;
|
||||
}
|
||||
else
|
||||
mediaRecognized = FALSE;
|
||||
}
|
||||
|
||||
if(!anyMedia)
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "TestedMedia"); // <TestedMedia>
|
||||
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SequentialMedia"); // <SequentialMedia>
|
||||
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MediaIsRecognized", "%s", mediaRecognized ? "true" : "false");
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Manufacturer", "%s", mediaManufacturer);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MediumTypeName", "%s",mediaName);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Model", "%s", mediaModel);
|
||||
|
||||
if(mediaRecognized)
|
||||
{
|
||||
printf("Querying SCSI MODE SENSE (10)...\n");
|
||||
error = ModeSense10(fd, &buffer, &sense, FALSE, TRUE, MODE_PAGE_DEFAULT, 0x3F, 0x00);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsModeSense10", "%s", !error ? "true" : "false");
|
||||
if(!error)
|
||||
{
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "ModeSense10Data");
|
||||
xmlTextWriterWriteBase64(xmlWriter, buffer, 0, (*(buffer + 0) << 8) + *(buffer + 1) + 2);
|
||||
xmlTextWriterEndElement(xmlWriter);
|
||||
decMode = DecodeMode10(buffer, 0x01);
|
||||
}
|
||||
|
||||
printf("Querying SCSI MODE SENSE (6)...\n");
|
||||
error = ModeSense6(fd, &buffer, &sense, FALSE, MODE_PAGE_DEFAULT, 0x00, 0x00);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsModeSense6", "%s", !error ? "true" : "false");
|
||||
if(!error)
|
||||
{
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "ModeSense6Data");
|
||||
xmlTextWriterWriteBase64(xmlWriter, buffer, 0, *(buffer + 0) + 1);
|
||||
xmlTextWriterEndElement(xmlWriter);
|
||||
if(!decMode->decoded)
|
||||
decMode = DecodeMode6(buffer, 0x01);
|
||||
}
|
||||
|
||||
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("Querying SCSI REPORT DENSITY SUPPORT for current media...\n");
|
||||
error = ReportDensitySupport(fd, &buffer, &sense, FALSE, TRUE);
|
||||
if(!error)
|
||||
{
|
||||
DensitySupport *dsh = DecodeDensity(buffer);
|
||||
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedDensities"); // <SupportedDensities>
|
||||
|
||||
for(i = 0; i < dsh->count; i++)
|
||||
{
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedDensity"); // <SupportedDensity>
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "BitsPerMm", "%d", (dsh->descriptors[i]->bitsPerMm[0] << 16) + (dsh->descriptors[i]->bitsPerMm[1] << 8) + dsh->descriptors[i]->bitsPerMm[2]);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Capacity", "%d", be32toh(dsh->descriptors[i]->capacity));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "DefaultDensity", "%s", dsh->descriptors[i]->deflt ? "true" : "false");
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Description", "%20s", dsh->descriptors[i]->description);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Duplicate", "%s", dsh->descriptors[i]->dup ? "true" : "false");
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Name", "%8s", dsh->descriptors[i]->densityName);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Organization", "%8s", dsh->descriptors[i]->organization);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "PrimaryCode", "%d", dsh->descriptors[i]->primaryCode);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SecondaryCode", "%d", dsh->descriptors[i]->secondaryCode);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Tracks", "%d", be16toh(dsh->descriptors[i]->tracks));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Width", "%d", be16toh(dsh->descriptors[i]->mediaWidth));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Writable", "%s", dsh->descriptors[i]->wrtok ? "true" : "false");
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedDensity>
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedDensities>
|
||||
}
|
||||
|
||||
|
||||
printf("Querying SCSI REPORT DENSITY SUPPORT for medium types for current media...\n");
|
||||
error = ReportDensitySupport(fd, &buffer, &sense, TRUE, TRUE);
|
||||
if(!error)
|
||||
{
|
||||
MediaTypeSupport *mtsh = DecodeMediumTypes(buffer);
|
||||
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedMediaTypes"); // <SupportedMediaTypes>
|
||||
|
||||
for(i = 0; i < mtsh->count; i++)
|
||||
{
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedMedia"); // <SupportedMedia>
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Description", "%20s", mtsh->descriptors[i]->description);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Length", "%d", be16toh(mtsh->descriptors[i]->length));
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "MediumType", "%d", mtsh->descriptors[i]->mediumType);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Name", "%8s", mtsh->descriptors[i]->densityName);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Organization", "%8s", mtsh->descriptors[i]->organization);
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "Width", "%d", be16toh(mtsh->descriptors[i]->mediaWidth));
|
||||
xmlTextWriterStartElement(xmlWriter, BAD_CAST "SupportedDensity"); // <SupportedDensity>
|
||||
// TODO: Density codes
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedMedia>
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(xmlWriter); // </SupportedMediaTypes>
|
||||
}
|
||||
|
||||
printf("Trying SCSI READ MEDIA SERIAL NUMBER...\n");
|
||||
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "SupportsRead", "%s", !ReadMediaSerialNumber(fd, &buffer, &sense) ? "true" : "false");
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(xmlWriter); // </SequentialMedia>
|
||||
|
||||
if(!anyMedia)
|
||||
{
|
||||
xmlTextWriterEndElement(xmlWriter); // </TestedMedia>
|
||||
anyMedia = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xmlTextWriterEndElement(xmlWriter); // </SequentialDevice>
|
||||
}
|
||||
|
||||
DensitySupport *DecodeDensity(unsigned char *response)
|
||||
{
|
||||
DensitySupport *decoded = malloc(sizeof(DensitySupport));
|
||||
memset(decoded, 0, sizeof(DensitySupport));
|
||||
uint16_t responseLen = (uint16_t)((response[0] << 8) + response[1] + 2);
|
||||
int offset = 4;
|
||||
|
||||
while(offset + 3 < responseLen)
|
||||
{
|
||||
int lenValid = response[offset + 2] & 0x20;
|
||||
uint16_t descLen = (uint16_t)((response[offset + 3] << 8) + response[offset + 4] + 5);
|
||||
|
||||
decoded->descriptors[decoded->count] = malloc(sizeof(DensityDescriptor));
|
||||
memset(decoded->descriptors[decoded->count], 0, sizeof(DensityDescriptor));
|
||||
memcpy(decoded->descriptors[decoded->count], response + offset, sizeof(DensityDescriptor));
|
||||
|
||||
if(lenValid)
|
||||
offset += descLen;
|
||||
else
|
||||
offset += 52;
|
||||
|
||||
decoded->count++;
|
||||
}
|
||||
}
|
||||
|
||||
MediaTypeSupport *DecodeMediumTypes(unsigned char *response)
|
||||
{
|
||||
MediaTypeSupport *decoded = malloc(sizeof(MediaTypeSupport));
|
||||
memset(decoded, 0, sizeof(MediaTypeSupport));
|
||||
uint16_t responseLen = (uint16_t)((response[0] << 8) + response[1] + 2);
|
||||
int offset = 4;
|
||||
|
||||
while(offset + 3 < responseLen)
|
||||
{
|
||||
decoded->descriptors[decoded->count] = malloc(sizeof(MediumDescriptor));
|
||||
memset(decoded->descriptors[decoded->count], 0, sizeof(MediumDescriptor));
|
||||
memcpy(decoded->descriptors[decoded->count], response + offset, sizeof(MediumDescriptor));
|
||||
|
||||
offset += 56;
|
||||
decoded->count++;
|
||||
}
|
||||
}
|
||||
58
DiscImageChef.Device.Report/ssc_report.h
Normal file
58
DiscImageChef.Device.Report/ssc_report.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Created by claunia on 18/12/17.
|
||||
//
|
||||
|
||||
#ifndef DISCIMAGECHEF_DEVICE_REPORT_SSC_REPORT_H
|
||||
#define DISCIMAGECHEF_DEVICE_REPORT_SSC_REPORT_H
|
||||
void SscReport(int fd, xmlTextWriterPtr xmlWriter);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t primaryCode;
|
||||
uint8_t secondaryCode;
|
||||
uint8_t dlv : 1;
|
||||
uint8_t reserved : 4;
|
||||
uint8_t deflt : 1;
|
||||
uint8_t dup : 1;
|
||||
uint8_t wrtok : 1;
|
||||
uint16_t length;
|
||||
uint8_t bitsPerMm[3];
|
||||
uint16_t mediaWidth;
|
||||
uint16_t tracks;
|
||||
uint32_t capacity;
|
||||
unsigned char organization[8];
|
||||
unsigned char densityName[8];
|
||||
unsigned char description[20];
|
||||
} DensityDescriptor;
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mediumType;
|
||||
uint8_t reserved;
|
||||
uint16_t length;
|
||||
uint8_t codes_len;
|
||||
uint8_t codes[9];
|
||||
uint16_t mediaWidth;
|
||||
uint16_t mediumLength;
|
||||
uint16_t reserved2;
|
||||
unsigned char organization[8];
|
||||
unsigned char densityName[8];
|
||||
unsigned char description[20];
|
||||
} MediumDescriptor;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count;
|
||||
DensityDescriptor *descriptors[1260];
|
||||
} DensitySupport;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t count;
|
||||
MediumDescriptor *descriptors[1170];
|
||||
} MediaTypeSupport;
|
||||
#endif //DISCIMAGECHEF_DEVICE_REPORT_SSC_REPORT_H
|
||||
Reference in New Issue
Block a user