Finally the french wiki does the trick (READ 10 -> http://fr.wikipedia.org/wiki/Commande_SCSI#Read_10)
Here's the code I wrote:
Here's the code I wrote:
Code: Select all
GetSPTIMBR(mbrBuff /*512 bytes sized*/, 512, 0 /*PhysicalDrive0*/)
...
bool GetSPTIMBR(byte* outBuff, int sizeBuff, int phyDrive)
{
DWORD outBytes;
SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
ULONG length = 0;
// Init drive name
wstring fileName = L"\\\\.\\PhysicalDrive";
WCHAR nDrive[3];
_stprintf_s(nDrive, L"%d", phyDrive);
fileName.append(nDrive);
// Open device
HANDLE hDevice = CreateFile(fileName.c_str(), GENERIC_WRITE | GENERIC_READ , FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING, NULL, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
return (FALSE);
}
// Init input / output buffs
ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
ZeroMemory(outBuff,sizeBuff);
// Init struct
sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
//sptdwb.sptd.ScsiStatus = 0; // Must be 0 --> filled by the function
sptdwb.sptd.PathId = 0; // Id of the SCSI bus adapter , often 0
sptdwb.sptd.TargetId = 1; // Scsi Id number of the device
sptdwb.sptd.Lun = 0; // Logical unit number of the device
sptdwb.sptd.CdbLength = CDB10GENERIC_LENGTH; // Size of the CDB struct
sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN; // Size of the data
sptdwb.sptd.SenseInfoLength = SPT_SENSE_LENGTH; // Length of the SenseInfo buff
sptdwb.sptd.DataTransferLength = sizeBuff; // Sector size
sptdwb.sptd.TimeOutValue = 2; // Timeout (secs)
sptdwb.sptd.DataBuffer = outBuff; // Pointer to dataBuff
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf);
// Init CDB --> http://fr.wikipedia.org/wiki/Commande_SCSI
sptdwb.sptd.Cdb[0] = SCSIOP_READ; //SCSIOP_READ_DATA_BUFF;
sptdwb.sptd.Cdb[1] = 0x04; // LUN = 000b, DPO = 0, FUA = 1, RFU1 = 0, RFU1 = 0, RelAdr = 0
sptdwb.sptd.Cdb[2] = 0x00; // Cdb[2-->5] = 0; // First sector Logical block addresss
sptdwb.sptd.Cdb[3] = 0x00;
sptdwb.sptd.Cdb[4] = 0x00;
sptdwb.sptd.Cdb[5] = 0x00;
sptdwb.sptd.Cdb[6] = 0x00; // Cdb[6] = 0; // RFU
byte size[2];
convertIntTo2bytes (sizeBuff, size); // convert int into LSB / MSB
sptdwb.sptd.Cdb[7] = size[1]; //MSB
sptdwb.sptd.Cdb[8] = size[0]; //LSB
length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
bool status = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptdwb, length, &sptdwb, length, &outBytes, FALSE);
CloseHandle(hDevice);
return true;
}