My aim is to detect Solid State Drives in systems with raid configuration. Using smartmontools' following command I observe bit 434 (217) shows value 1 for SSD: smartctl -i -r ataioctl,2 /dev/csmi0,0
Attempting to read the same 512 bytes of data I am trying to send IDENTIFY DEVICE commands in following 2 ways:
Method 1 fails with DeviceIoControl() set GetLastError() as 87 (ERROR_INVALID_PARAMETER), Can you help me in understanding what could be wrong and am I on the right track?
Method 2 has info->IoctlHeader.ReturnCode = 3 which means CSMI_SAS_STATUS_INVALID_PARAMETER.(CSMI buffer provided is too small)
///////// Method 1 /////////
handle = CreateFile(L"\\\\.\\PhysicalDrive0",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL,
NULL);
if (handle == INVALID_HANDLE_VALUE)
{
printf("Unable to open handle to device , Error %u\n", GetLastError());
return 1;
}
//Allocate memory for ATA_PASS_THROUGH_EX and clear the contents
pATAData = (PATA_PASS_THROUGH_EX) VirtualAlloc(NULL, dataSize, MEM_COMMIT, PAGE_READWRITE);
ZeroMemory(pATAData,dataSize);
//Fill in the IDENTIFY DEVICE query data
pATAData->Length = sizeof(ATA_PASS_THROUGH_EX);
pATAData->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);
pATAData->DataTransferLength = 512;
pATAData->AtaFlags = ATA_FLAGS_DATA_IN;
pATAData->TimeOutValue = 10; //Seconds
pATAData->CurrentTaskFile[6] = 0xEC; /* send the command*/
status = DeviceIoControl( handle,
IOCTL_ATA_PASS_THROUGH,
pATAData,
dataSize, /* input buffer and size */
pATAData,
dataSize, /* output buffer and size */
&bytescopied, /* bytes copied to output buffer*/
NULL ); /* no overlapping */
//////// Method 2 //////////
BYTE portNumber = 0;
_stprintf_s(DeviceName, (sizeof(char)*128),_T("\\\\.\\Scsi%u:"),portNumber);
// get a handle to the miniport driver
handle = CreateFile(DeviceName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL,
NULL);
if (handle == INVALID_HANDLE_VALUE)
{
printf("Unable to open handle to device , Error %u\n", GetLastError());
return;
}
CSMI_SAS_STP_PASSTHRU_BUFFER* info = (CSMI_SAS_STP_PASSTHRU_BUFFER *) calloc(1, sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER));
info->IoctlHeader.HeaderLength = sizeof(IOCTL_HEADER);
info->IoctlHeader.Timeout = CSMI_SAS_TIMEOUT;
info->IoctlHeader.ControlCode = CC_CSMI_SAS_STP_PASSTHRU;
info->IoctlHeader.Length = sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER) - sizeof(IOCTL_HEADER);
info->IoctlHeader.ReturnCode = 0;
memcpy(&info->IoctlHeader.Signature, CSMI_SAS_SIGNATURE, sizeof(CSMI_SAS_SIGNATURE));
bSuccess = DeviceIoControl(handle, IOCTL_SCSI_MINIPORT, info, sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER),
info, sizeof(CSMI_SAS_STP_PASSTHRU_BUFFER),
&bytesReturned, NULL);