⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsiunit.pas

📁 用于CD/DVD烧录的Delphi源码,包括source和demo
💻 PAS
📖 第 1 页 / 共 5 页
字号:
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 + -