function READ_RAW_SECTOR_FROM_CD( hCD : THandle;
HTL :
String;
var Data :
Array of Byte;
StartSector : DWord;
AnzahlSector : DWord;
flags : Byte)
: Boolean;
const
RAW_READ_CMD = $BE;
// ATAPI RAW READ
PACKET_LEN = 2352;
// Sektorlänge
SCSI_IOCTL_DATA_IN = 1;
IOCTL_SCSI_PASS_THROUGH = $04D004;
var
srb : SCSI_PASS_THROUGH_DIRECT;
nb : Cardinal;
Begin
Result := False;
ZeroMemory(@srb, SizeOf(srb));
ZeroMemory(@Data, SizeOf(Data));
if hCD <> INVALID_HANDLE_VALUE
then begin
srb.Length := sizeof(SCSI_PASS_THROUGH);
srb.PathId := StrToInt(HTL[1]);
// SCSI controller ID
srb.TargetId := StrToInt(HTL[3]);
// target device ID
srb.Lun := StrToInt(HTL[5]);
// logical unit device ID
srb.CdbLength := 12;
srb.SenseInfoLength := 0;
// SenseInfo
srb.DataIn := SCSI_IOCTL_DATA_IN;
srb.DataTransferLength := PACKET_LEN * AnzahlSector;
srb.TimeOutValue := 200;
// TimeOut
srb.DataBuffer := @Data;
srb.SenseInfoOffset := 0;
// SenseInfo
// CDB
srb.Cdb[0] := RAW_READ_CMD;
srb.Cdb[1] := $0;
// Format Disk
srb.Cdb[2] := HIBYTE(HIWORD(StartSector));
srb.Cdb[3] := LOBYTE(HIWORD(StartSector));
srb.Cdb[4] := HIBYTE(LOWORD(StartSector));
srb.Cdb[5] := LOBYTE(LOWORD(StartSector));
srb.Cdb[6] := LOBYTE(HIWORD(AnzahlSector));
srb.Cdb[7] := LOBYTE(LOWORD(AnzahlSector));
srb.Cdb[8] := HIBYTE(LOWORD(AnzahlSector));
srb.Cdb[9] := flags;
srb.Cdb[10] := 0;
// Sub-Channel Data Bits
srb.Cdb[11] := 0;
// reserved
Result := DeviceIoControl(hCD,
IOCTL_SCSI_PASS_THROUGH,
@srb,
sizeof(srb),
@srb,
0,
nb,
Nil);
end;
end;