const
SPT_SENSE_LENGTH = 32;
SPTWB_DATA_LENGTH = 512;
CDB6GENERIC_LENGTH = 6;
SCSI_IOCTL_DATA_IN = 1;
SCSIOP_INQUIRY = $12;
SCSIOP_MODE_SENSE = $1A;
MODE_PAGE_CAPABILITIES = $2A;
IOCTL_SCSI_PASS_THROUGH = $04D004;
type
ULONG_PTR = ULONG;
SCSI_PASS_THROUGH = record
Length: Word;
ScsiStatus: UCHAR;
PathId: UCHAR;
TargetId: UCHAR;
Lun: UCHAR;
CdbLength: UCHAR;
SenseInfoLength: UCHAR;
DataIn: UCHAR;
DataTransferLength: ULONG;
TimeOutValue: ULONG;
DataBufferOffset: ULONG_PTR;
SenseInfoOffset: ULONG;
Cdb: array[0..15] of UCHAR;
end;
PSCSI_PASS_THROUGH = ^SCSI_PASS_THROUGH;
SCSI_PASS_THROUGH_WITH_BUFFERS = record
spt: SCSI_PASS_THROUGH;
Filler: ULONG;
ucSenseBuf: array[0..SPT_SENSE_LENGTH-1] of UCHAR;
ucDataBuf: array[0..SPTWB_DATA_LENGTH-1]of UCHAR;
end;
PSCSI_PASS_THROUGH_WITH_BUFFERS = ^SCSI_PASS_THROUGH_WITH_BUFFERS;
TDeviceProperty = record
CDRReader: Boolean;
CDRWReader: Boolean;
CDRWriter: Boolean;
CDRWWriter: Boolean;
DVDROMReader: Boolean;
DVDRReader: Boolean;
DVDRAMReader: Boolean;
DVDRWriter: Boolean;
DVDRAMWriter: Boolean;
end;
function OffsetOf(a,b: Pointer): integer;
begin
Result:= Integer(b) - Integer(a);
end;
function GetDeviceProperty(Letra: Char; var DeviceProperty: TDeviceProperty): String;
var
Disk: THandle;
Sptwb: SCSI_PASS_THROUGH_WITH_BUFFERS;
l: ULONG;
Returned: Cardinal;
begin
Result:= EmptyStr;
FillChar(DeviceProperty,SizeOf(DeviceProperty),0);
Disk:= CreateFile(PChar('\\.\' + Letra + ':'),GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0);
if Disk <> INVALID_HANDLE_VALUE then
begin
FillChar(Sptwb,Sizeof(Sptwb),0);
Sptwb.Spt.Length:= sizeof(SCSI_PASS_THROUGH);
Sptwb.Spt.PathId:= 0;
Sptwb.Spt.TargetId:= 1;
Sptwb.Spt.Lun:= 0;
Sptwb.Spt.CdbLength:= CDB6GENERIC_LENGTH;
Sptwb.Spt.SenseInfoLength:= 24;
Sptwb.Spt.DataIn:= SCSI_IOCTL_DATA_IN;
Sptwb.Spt.DataTransferLength:= 192;
Sptwb.Spt.TimeOutValue:= 2;
Sptwb.Spt.DataBufferOffset:=
OffsetOf(@Sptwb,@Sptwb.ucDataBuf);
Sptwb.Spt.SenseInfoOffset:=
OffsetOf(@Sptwb,@Sptwb.ucSenseBuf);
Sptwb.Spt.Cdb[0]:= SCSIOP_MODE_SENSE;
Sptwb.Spt.Cdb[1]:= $08;
Sptwb.Spt.Cdb[2]:= MODE_PAGE_CAPABILITIES;
Sptwb.Spt.Cdb[4]:= 192;
l:= OffsetOf(@Sptwb,@Sptwb.ucDataBuf) +
sptwb.Spt.DataTransferLength;
if DeviceIoControl(Disk,IOCTL_SCSI_PASS_THROUGH,@Sptwb,
Sizeof(SCSI_PASS_THROUGH),@sptwb,l,Returned,nil) then
begin
if ((Sptwb.ucDataBuf[6] and $01) or (Sptwb.ucDataBuf[6] and $02) > 0) then
begin
DeviceProperty.CDRReader:= (Sptwb.ucDataBuf[6] and $01) > 0;
DeviceProperty.CDRWReader:= (Sptwb.ucDataBuf[6] and $02) > 0;
if (Sptwb.ucDataBuf[7] and $01) or (Sptwb.ucDataBuf[7] and $02) > 0 then
begin
DeviceProperty.CDRWriter:= (Sptwb.ucDataBuf[7] and $01) > 0;
DeviceProperty.CDRWWriter:= (Sptwb.ucDataBuf[7] and $02) > 0;
end;
end;
if (Sptwb.ucDataBuf[6] and $08) or (Sptwb.ucDataBuf[6] and $10) or
(Sptwb.ucDataBuf[6] and $20) > 0 then
begin
DeviceProperty.DVDROMReader:= (Sptwb.ucDataBuf[6] and $08) > 0;
DeviceProperty.DVDRReader:= (Sptwb.ucDataBuf[6] and $10) > 0;
DeviceProperty.DVDRAMReader:= (Sptwb.ucDataBuf[6] and $20) > 0;
if ((Sptwb.ucDataBuf[7] and $10) or (Sptwb.ucDataBuf[7] and $20) > 0) then
begin
DeviceProperty.DVDRWriter:= (Sptwb.ucDataBuf[7] and $10) > 0;
DeviceProperty.DVDRAMWriter:= (Sptwb.ucDataBuf[7] and $20) > 0;
end;
end;
end else Result:= SysErrormessage(GetLastError);
CloseHandle(Disk);
end else Result:= SysErrormessage(GetLastError);
end;