📄 scsiunit.pas
字号:
end;
function SCSIreadCdFlagsToByte9(Flags: TScsiReadCdFormatFlags): BYTE;
begin
Result := 0;
if cffSync in Flags then
Result := Result or $80;
if cffSubheader in Flags then
Result := Result or $40;
if cffHeader in Flags then
Result := Result or $20;
if cffUserData in Flags then
Result := Result or $10;
if cffEDCandECC in Flags then
Result := Result or 8;
if cffC2errorBits in Flags then
begin
if cffBlockErrByte in Flags then
Result := Result or 4
else
Result := Result or 2;
end;
end;
function SCSIreadCdFlagsToSize(SectorType: TScsiReadCdSectorType;
Flags: TScsiReadCdFormatFlags): integer;
const
SectorSize: array[0..31, 0..3] of integer =
((-1, -1, -1, -1), (-1, -1, -1, -1), (2048, 2336, 2048, 2328), (2336, 2336,
2328, 2328),
(4, 4, 4, 4), (-1, -1, -1, -1), (2052, 2340, -1, -1), (2340, 2340, -1, -1),
(0, 0, 8, 8), (-1, -1, -1, -1), (2048, 2336, 2056, 2336), (2336, 2336, 2336,
2336),
(4, 4, 12, 12), (-1, -1, -1, -1), (2052, 2340, 2060, 2340), (2340, 2340,
2340, 2340),
(-1, -1, -1, -1), (-1, -1, -1, -1), (-1, -1, -1, -1), (-1, -1, -1, -1),
(16, 16, 16, 16), (-1, -1, -1, -1), (2064, 2352, -1, -1), (2352, 2352, -1,
-1),
(-1, -1, -1, -1), (-1, -1, -1, -1), (-1, -1, -1, -1), (-1, -1, -1, -1),
(16, 16, 24, 24), (-1, -1, -1, -1), (2064, 2352, 2072, 2352), (2352, 2352,
2352, 2352));
begin
if SectorType in [csfAnyType, csfAudio] then
Result := 2352
else
Result :=
SectorSize[SCSIreadCdFlagsToByte9(Flags) shr 3, ORD(SectorType) - 2];
if Result = -1 then
exit;
if cffC2errorBits in Flags then
begin
Inc(Result, 294);
if cffBlockErrByte in Flags then
Inc(Result, 2);
end;
if cffSubchannelQ in Flags then
begin
if (cffSubchannelRaw in Flags) or (cffSubchannelPW in Flags) then
Result := -1
else
Inc(Result, 16);
end
else
begin
if cffSubchannelRaw in Flags then
begin
if cffSubchannelPW in Flags then
Result := -1
else
Inc(Result, 96);
end
else if cffSubchannelPW in Flags then
Inc(Result, 96);
end;
end;
{$WARNINGS OFF}
function SCSIWriteCdEX(DeviceID: TCDBurnerInfo;
GLBA, SectorCount: DWORD;
SectorType: TScsiReadCdSectorType;
Flags: TScsiReadCdFormatFlags;
Buf: pointer; BufLen: DWORD;
var Sdf: TScsiDefaults): TScsiError;
var
CDB: TCDB12;
dummy: byte;
i: integer;
SdfTemp: DWORD;
begin
FillChar(cdb, 12, 0);
cdb[9] := SCSIreadCdFlagsToByte9(Flags);
i := SCSIreadCdFlagsToSize(SectorType, Flags);
if (i <= 0) or (SectorCount <= 0)
or (BufLen < (SectorCount * i))
or not Assigned(Buf) then
begin
Result := Err_InvalidArgument;
exit;
end;
FillChar(Buf^, BufLen, 0);
cdb[0] := $BE;
cdb[1] := ORD(SectorType) shl 2;
ScatterDWORD(GLBA, cdb[2], cdb[3], cdb[4], cdb[5]);
ScatterDWORD(SectorCount, dummy, cdb[6], cdb[7], cdb[8]);
if cffSubchannelRaw in Flags then
cdb[10] := 1
else if cffSubchannelQ in Flags then
cdb[10] := 2
else if cffSubchannelPW in Flags then
cdb[10] := 4
else
cdb[10] := 0;
cdb[11] := 0;
SdfTemp := Sdf.Timeout;
Sdf.Timeout := Sdf.ReadTimeout;
Result := ASPIsend12CDB(DeviceID, CDB, @Buf, SizeOf(Buf), SRB_DIR_OUT, Sdf);
Sdf.Timeout := SdfTemp;
end;
{$WARNINGS ON}
{$WARNINGS OFF}
function SCSIreadCdEX(DeviceID: TCDBurnerInfo;
GLBA, SectorCount: DWORD;
SectorType: TScsiReadCdSectorType;
Flags: TScsiReadCdFormatFlags;
Buf: pointer; BufLen: DWORD;
var Sdf: TScsiDefaults): TScsiError;
var
CDB: TCDB12;
dummy: byte;
i: integer;
SdfTemp: DWORD;
begin
FillChar(cdb, 12, 0);
cdb[9] := SCSIreadCdFlagsToByte9(Flags);
i := SCSIreadCdFlagsToSize(SectorType, Flags);
if (i <= 0) or (SectorCount <= 0)
or (BufLen < (SectorCount * i))
or not Assigned(Buf) then
begin
Result := Err_InvalidArgument;
exit;
end;
FillChar(Buf^, BufLen, 0);
cdb[0] := $BE;
cdb[1] := ORD(SectorType) shl 2;
ScatterDWORD(GLBA, cdb[2], cdb[3], cdb[4], cdb[5]);
ScatterDWORD(SectorCount, dummy, cdb[6], cdb[7], cdb[8]);
if cffSubchannelRaw in Flags then
cdb[10] := 1
else if cffSubchannelQ in Flags then
cdb[10] := 2
else if cffSubchannelPW in Flags then
cdb[10] := 4
else
cdb[10] := 0;
cdb[11] := 0;
SdfTemp := Sdf.Timeout;
Sdf.Timeout := Sdf.ReadTimeout;
Result := ASPIsend12CDB(DeviceID, CDB, Buf, BufLen, SRB_DIR_IN, Sdf);
Sdf.Timeout := SdfTemp;
end;
{$WARNINGS ON}
//+++++++++++++++++++++++++ writing functions +++++++++++++++++++++++++
{Function SCSISetWriteParameters(DevID :TCDBurnerInfo;Size: Integer;
Write_Type,Data_Block_type,Track_Mode,Session_Format : integer;
Packet_Size,Audio_Pause_Length : integer; Test_Write, Burn_Proof : Boolean;
var Sdf : TScsiDefaults) : TScsiError;
var
Buf : TScsiWriteModePage;
bufsize : DWord;
BufPos : Cardinal;
BurnProofTestWrite : Byte;
begin
BufSize := 60;
BurnProofTestWrite := 0;
//CDB: 55 10 00 00 00 00 00 00 3C 00
//Sending 60 (0x3C) bytes of data.
//Write Data: 00 00 20 00 00 00 00 00 05 32 01 04 08 00 00 00 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
FillChar(Buf,Sizeof(Buf),0);
// Result := SCSImodeSensePage(DevID,$05,@Buf,BufSize,0,Sdf);
Result := SCSImodeSense(DevID,$05,@Buf,BufSize,sdf);
BufPos := 0;
if Result <> Err_None then exit;
FillChar(Buf.ResvBytes,Sizeof(Buf.ResvBytes),0);
Buf.ResvBytes[3] := $20;
Buf.PSPageCode := $05;
Buf.PageLength := $32; //lsb
BufSize := 60;
// if (Test_Write = True) then BurnProofTestWrite := 16;
// if (Burn_Proof = True) then BurnProofTestWrite := BurnProofTestWrite + 64;
Buf.TestFlagWriteType := Write_Type + BurnProofTestWrite;
Buf.MSFPCopyTrackMode := Track_Mode;
Buf.DataBlockType := Data_Block_type;
Buf.HostApplicationCode := 0;
Buf.SessionFormat := Session_Format;
Buf.PacketSize := Packet_Size;
Buf.AudioPauseLength := Audio_Pause_Length;
FillChar(Buf.MediaCatalogNumber,Sizeof(Buf.MediaCatalogNumber),0);
FillChar(Buf.InternationalStandardRecordingCode,
SizeOf(Buf.InternationalStandardRecordingCode),0);
FillChar(Buf.SubHeader,Sizeof(Buf.SubHeader),0);
sdf.ModePageType := MPTchangeable;
Result := SCSImodeSelect(DevID,@Buf,BufSize,sdf);
//Result := SCSImodeSelectPage(DevID,$05,@Buf,BufSize,0,sdf);
end; }
function SCSISetWriteParameters(DevID: TCDBurnerInfo; Size: Integer;
Write_Type, Data_Block_type, Track_Mode, Session_Format: integer;
Packet_Size, Audio_Pause_Length: integer; Test_Write, Burn_Proof: Boolean;
var Sdf: TScsiDefaults): TScsiError;
var
Buf: TScsiWriteModePage;
bufsize: DWord;
begin
BufSize := sizeof(Buf);
{get current params}
Result := SCSImodeSensePage(DevID, $05, @Buf, BufSize, 0, Sdf);
{reset params to new settings}
Sdf.ModePageType := MPTchangeable;
if Result <> Err_None then
exit;
Buf.PSPageCode := $05;
Buf.PageLength := $32; //$32;
Buf.TestFlagWriteType := Write_Type; //Write_Type;
if Test_Write = True then
Buf.TestFlagWriteType := BitOn(Buf.TestFlagWriteType, 4)
else if IsBitSet(Buf.TestFlagWriteType, 4) then
BitOFF(Buf.TestFlagWriteType, 4);
if Burn_Proof = True then
Buf.TestFlagWriteType := BitOn(Buf.TestFlagWriteType, 6)
else if IsBitSet(Buf.TestFlagWriteType, 6) then
BitOFF(Buf.TestFlagWriteType, 6);
Buf.MSFPCopyTrackMode := Track_Mode;
Buf.DataBlockType := Data_Block_type;
Buf.HostApplicationCode := 0;
Buf.SessionFormat := Session_Format;
Buf.PacketSize := Packet_Size;
Buf.AudioPauseLength := SwapWord(Audio_Pause_Length);
FillChar(Buf.MediaCatalogNumber, Sizeof(Buf.MediaCatalogNumber), 0);
FillChar(Buf.InternationalStandardRecordingCode,
SizeOf(Buf.InternationalStandardRecordingCode), 0);
FillChar(Buf.SubHeader, Sizeof(Buf.SubHeader), 0);
{Reset to new parameters }
Result := SCSImodeSelectPage(DevID, $05, @Buf, BufSize, 0, sdf);
end;
function SCSIWrite10EX(DeviceID: TCDBurnerInfo;
DisablePageOut, ForceUnitAccess: boolean;
GLBA, SectorCount: WORD; Buf: pointer; BufLen: DWORD;
var Sdf: TScsiDefaults): TScsiError;
var
Arg1: byte;
SdfTemp: DWORD;
CDB: TCDB10;
begin
//cdr CDB: 2A 00 00 00 00 00 00 00 1F 00
FillChar(cdb, 10, 0);
Arg1 := 0;
if DisablePageOut then
Arg1 := $10;
if ForceUnitAccess then
Arg1 := Arg1 or 8;
SdfTemp := Sdf.Timeout;
Sdf.Timeout := Sdf.ReadTimeout;
cdb[0] := SCSI_WRITE10;
cdb[1] := AttachLUN(Arg1, DeviceID.DriveID);
FillDWORD(GLBA, cdb[2]);
cdb[7] := HiByte(SectorCount);
cdb[8] := LoByte(SectorCount);
Result := ASPIsend10CDB(DeviceID, CDB, Buf, BufLen, SRB_DIR_OUT, Sdf);
Sdf.Timeout := SdfTemp;
end;
function SCSIWrite10(DeviceID: TCDBurnerInfo;
GLBA, SectorCount: WORD; Buf: pointer; BufLen: DWORD;
var Sdf: TScsiDefaults): TScsiError;
begin
Result := SCSIWrite10EX(DeviceID, False, False,
GLBA, SectorCount, Buf, BufLen, Sdf);
end;
function SCSIWriteCDDA(DeviceID: TCDBurnerInfo;
GLBA, SectorCount: DWORD;
SectorType: TScsiReadCdSectorType;
Flags: TScsiReadCdFormatFlags;
Buf: pointer; BufLen: DWORD;
var Sdf: TScsiDefaults): TScsiError;
var
SdfTemp: DWORD;
begin
SdfTemp := Sdf.Timeout;
Sdf.Timeout := Sdf.ReadTimeout;
Result := SCSIWrite10EX(DeviceID, False, False,
GLBA, SectorCount, Buf, BufLen, Sdf);
Sdf.Timeout := SdfTemp;
end;
function SCSIBlankCD(DeviceID: TCDBurnerInfo; BlankType: byte; LBA: longint;
var Sdf: TScsiDefaults): TScsiError;
var
cdb: TCDB6;
m_lba: longint;
begin
m_lba := LBA;
FillChar(cdb, 6, 0);
cdb[0] := AC_BLANK; {command, Blank}
cdb[1] := BlankType; {blanktype}
cdb[2] := (m_lba shr 24) and $FF;
cdb[3] := (m_lba shr 16) and $FF;
cdb[4] := (m_lba shr 8) and $FF;
cdb[5] := m_lba and $FF;
Result := ASPIsend6CDB(DeviceID, CDB, nil, 0, SRB_DIR_IN, Sdf);
end;
function SCSIReadBuffer(DeviceID: TCDBurnerInfo;
Buf: pointer; var Sdf: TScsiDefaults): TScsiError;
var
CDB: TCDB10;
begin
FillChar(cdb, 10, 0);
cdb[0] := SCSI_READ_BUFF;
cdb[1] := $00;
cdb[2] := $00;
Result := ASPIsend10CDB(DeviceID, CDB, Buf, SizeOf(Buf), SRB_DIR_IN, Sdf);
end;
function SCSIReadBufferCapacity(DeviceID: TCDBurnerInfo;
Buf: pointer; var Sdf: TScsiDefaults): TScsiError;
var
CDB: TCDB10;
begin
FillChar(cdb, 10, 0);
cdb[0] := SCSI_READ_BUFFER_CAP;
cdb[8] := SizeOf(TScsiCDBufferInfo);
Result := ASPIsend10CDB(DeviceID, CDB, Buf, SizeOf(TScsiCDBufferInfo),
SRB_DIR_IN, Sdf);
end;
function SCSIgetMaxBufferSize(DeviceID: TCDBurnerInfo;
var Value: WORD; var Sdf: TScsiDefaults): TScsiError;
begin
Result := SCSIReadBufferCapacity(DeviceID, @Value, Sdf);
end;
function SCSIgetBufferCapacity(DeviceID: TCDBurnerInfo;
var Value: TScsiCDBufferInfo; var Sdf: TScsiDefaults): TScsiError;
begin
Result := SCSIReadBufferCapacity(DeviceID, @Value, sdf);
end;
function SCSIgetBufferSize(DeviceID: TCDBurnerInfo;
var Value: WORD; var Sdf: TScsiDefaults): TScsiError;
begin
Result := SCSIReadBuffer(DeviceID, @Value, Sdf);
end;
function SCSICloseSession(DeviceID: TCDBurnerInfo; var Sdf: TScsiDefaults):
TScsiError;
var
cdb: TCDB6;
begin
FillChar(cdb, 6, 0);
cdb[0] := AC_CLOSETRACKSESSION; {command}
cdb[1] := $01;
cdb[2] := CLOSE_SESSION;
Result := ASPIsend6CDB(DeviceID, CDB, nil, 0, SRB_DIR_IN, Sdf);
end;
function SCSICloseTrack(DeviceID: TCDBurnerInfo; Track: byte;
var Sdf: TScsiDefaults): TScsiError;
var
cdb: TCDB6;
begin
FillChar(cdb, 6, 0);
cdb[0] := AC_CLOSETRACKSESSION; {command}
cdb[1] := $01;
cdb[2] := CLOSE_TRACK;
cdb[5] := Track;
Result := ASPIsend6CDB(DeviceID, CDB, nil, 0, SRB_DIR_IN, Sdf);
end;
function SCSISYNCCACHE(DeviceID: TCDBurnerInfo; var Sdf: TScsiDefaults):
TScsiError;
var
cdb: TCDB10;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -