mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Added report for removable media to DiscImageChef.Device.Report.
This commit is contained in:
@@ -528,3 +528,14 @@ int Seek10(int fd, unsigned char **senseBuffer, uint32_t lba)
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TestUnitReady(int fd, unsigned char **senseBuffer)
|
||||||
|
{
|
||||||
|
unsigned char cmd_len = 6;
|
||||||
|
char cdb[] = {SCSI_TEST_UNIT_READY, 0, 0, 0, 0, 0};
|
||||||
|
unsigned char *buffer = malloc(0);
|
||||||
|
|
||||||
|
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ int ReadLong10(int fd, unsigned char **buffer, unsigned char **senseBuffer, int
|
|||||||
int ReadLong16(int fd, unsigned char **buffer, unsigned char **senseBuffer, int correct, uint64_t lba, uint32_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 Seek6(int fd, unsigned char **senseBuffer, uint32_t lba);
|
||||||
int Seek10(int fd, unsigned char **senseBuffer, uint32_t lba);
|
int Seek10(int fd, unsigned char **senseBuffer, uint32_t lba);
|
||||||
|
int TestUnitReady(int fd, unsigned char **senseBuffer);
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libxml/xmlwriter.h>
|
#include <libxml/xmlwriter.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "scsi_report.h"
|
#include "scsi_report.h"
|
||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include "inquiry_decode.h"
|
#include "inquiry_decode.h"
|
||||||
@@ -254,7 +255,279 @@ void ScsiReport(int fd, xmlTextWriterPtr xmlWriter)
|
|||||||
{
|
{
|
||||||
if(removable)
|
if(removable)
|
||||||
{
|
{
|
||||||
// TODO: Removable
|
user_response = ' ';
|
||||||
|
int anyMedia = FALSE;
|
||||||
|
|
||||||
|
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 "RemovableMedias"); // <RemovableMedias>
|
||||||
|
|
||||||
|
xmlTextWriterStartElement(xmlWriter, BAD_CAST "testedMediaType"); // <testedMediaType>
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
uint64_t blocks = 0;
|
||||||
|
uint32_t blockSize = 0;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(decMode != NULL)
|
||||||
|
decMode->decoded = 0;
|
||||||
|
|
||||||
|
printf("Querying SCSI MODE SENSE (10)...\n");
|
||||||
|
error = ModeSense10(fd, &mode10Response, &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, mode10Response, 0, (*(mode10Response + 0) << 8) + *(mode10Response + 1) + 2);
|
||||||
|
xmlTextWriterEndElement(xmlWriter);
|
||||||
|
decMode = DecodeMode10(mode10Response, inquiry->PeripheralDeviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Querying SCSI MODE SENSE (6)...\n");
|
||||||
|
error = ModeSense6(fd, &mode6Response, &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, mode6Response, 0, *(mode6Response + 0) + 1);
|
||||||
|
xmlTextWriterEndElement(xmlWriter);
|
||||||
|
if(!decMode->decoded)
|
||||||
|
decMode = DecodeMode6(mode6Response, inquiry->PeripheralDeviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
user_response = ' ';
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
user_response = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(supportsReadLong10 && blockSize != longBlockSize)
|
||||||
|
xmlTextWriterWriteFormatElement(xmlWriter, BAD_CAST "LongBlockSize", "%d", longBlockSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlTextWriterEndElement(xmlWriter); // </testedMediaType>
|
||||||
|
|
||||||
|
if(!anyMedia)
|
||||||
|
{
|
||||||
|
xmlTextWriterEndElement(xmlWriter); // </RemovableMedias>
|
||||||
|
anyMedia = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user