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

📄 mbdrvlib.pas

📁 刻录机源码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
begin
  fillchar(lsrb, sizeof(lsrb), 0);
  lsrb.Command := SC_GET_DISK_INFO;
  lsrb.HaId := fHaID;
  lsrb.Target := fTarget;
  SendASPI32Command (@lsrb);
  result := lsrb.Status = SS_COMP;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
constructor TSCSIDevice.Create;
begin
  inherited Create(AOwner);
  CriticalSection := TCriticalSection.Create;
  fErasing := False;
  fHaid := 254;
  fTarget := 254;
  fLun := 254;
  fDoDebug := False;
  fDevices := TStringList.Create;
  if GetASPIInitialized then
  begin
    GetHostAdapterInfo(0);
    ScanDevices;
  end;
end;
{******************************************************************************}
{                                 FormatUnit                                   }
{******************************************************************************}
function TSCSIDevice.FormatUnit(FormatCode: Byte; Buffer: PChar; Length: Integer): Boolean;
var
  lsrb: TSRB_ExecSCSICmd;
begin
  fillchar(lsrb, sizeof(lsrb), 0);
  lsrb.Flags := $50;
  lsrb.CDBLen := $6;
  lsrb.SenseLen := SENSE_LEN;
  lsrb.BufLen := Length;
  lsrb.BufPointer := @Buffer[0];
  lsrb.CDBCmd := $04;
  lsrb.CDBByte[1] := FormatCode;
  ExecScsiCommand(lsrb, 10000);
  result := lsrb.Status = SS_COMP;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
destructor TSCSIDevice.Destroy;
begin
  fDevices.Free;
  CriticalSection.Destroy;
  Inherited;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.Rewind;
var
  lsrb: TSRB_ExecSCSICmd;
begin
  fillchar(lsrb, sizeof(lsrb), 0);
  lsrb.Flags := SRB_EVENT_NOTIFY;
  lsrb.CDBLen := 06;
  lsrb.CDBCmd := $01;
  lsrb.SenseLen := SENSE_LEN;
  ExecScsiCommand(lsrb, 10000);
end;

function TSCSIDevice.GetHostAdapterInfo;
begin
  fillchar(fHAInquiry, sizeof(fHAInquiry), 0);
  fHAInquiry.Command := SC_HA_INQUIRY;
  fHAInquiry.HaId := ha;
  SendASPI32Command (@fHAInquiry);
  if fHAInquiry.Status =1 then
    result := fHAInquiry.HA_Count
  else
    result := -1;
  fAdapters := result;
  if fAdapters = 0 then fAdapters := 7;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.AbortSCSICommand;
begin
  fillchar(fSCAbort, sizeof(fSCAbort), 0);
  fSCAbort.Command := SC_ABORT_SRB;
  fSCAbort.HaID := fHaID;
  fSCAbort.ToAbort := @srb;
  //SendASPI32Command (@fSCAbort);
  result := fSCAbort.Status = 1;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.SetDeviceID;
var
  P: String;
  v: String;
begin
  if Length(Value) < 5 then
  begin
    if Value <> '' then
      DebugMsg(ERR_INVALIDDEVICE, mtUNKNOWN);
    fHaID := 254;
    fTarget := 254;
    fLun := 254;
    fDevice := '';
    fDeviceName := '';
    fDeviceType := 127;
  end
  else
  begin
    try
      fHaID := StrToInt(Value[1]);
      fTarget := StrToInt(Value[3]);
      fLun := StrToInt(Value[5]);
      fDevice := Value;
      DeviceChanged;
      if (fInquiryData.PeripheralData = 5) or (fInquiryData.PeripheralData = 4) then
      begin
        p := fInquiryData.ProductID;
        p := Trim(p);
        v := fInquiryData.VendorID;
        v := Trim(v);
        if (P = 'CD-W512EB') then
          TEAC512EB := true
        else
          TEAC512EB := False;
        if (P = 'CRX175E') or (P = 'CD-RW  CRX800E') then
          SonyPowerBurn := True
        else
          SonyPowerBurn := False;
        If length(V)<3 then
    	    V:='     ';
        if
        ((P[1] = 'U') and (P[2] = 'J') and (P[3] = 'D') and (P[4] = 'A')) or
        ((V[1] = 'T') and (V[2] = 'D') and (V[3] = 'K')) then
          Wait02 := True
        else
          Wait02 := False;
        if (P = 'CD-RW  CRX100E') then
          SonyCRX100E := True
        else
          SonyCRX100E := False;
        if (P = 'CDRW321040X') then
          fImmedCT := False
        else
          fImmedCT := True;
        if (fInquiryData.ProductID = 'DVD-RW  DVR-103 ') or (fInquiryData.ProductID = 'DVD-RW  DVR-104 ') then
        begin
          PDVR103 := True;
          fImmedCT := True;
        end
        else
          PDVR103 := False;
        if Assigned(fOnDeviceChange) then
          fOnDeviceChange(Self);
        GetWriteMethods;
      end
      else
      begin
        DebugMsg(ERR_INVALIDDEVICE, mtUNKNOWN);
        fDevice := '';
        fDeviceName := '';
        fDeviceType := 127;
        fHaID := 254;
        fTarget := 254;
        fLun := 254;
      end;
      except
        DebugMsg(ERR_INVALIDDEVICE, mtUNKNOWN);
        fDevice := '';
        fDeviceName := '';
        fDeviceType := 127;
        fHaID := 254;
        fTarget := 254;
        fLun := 254;
      end;

  end;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.DeviceChanged;
var
  str: String;
  i: Integer;
begin
  GetDeviceCapabilities;
  if Inquiry then
  begin
    fDeviceType := fInquiryData.PeripheralData;
    with fInquiryData do
    begin
      for i:= 8 to 15 do if VendorID[i] < #32 then VendorID[i] := #32;
      for i:= 16 to 31 do if ProductID[i] < #32 then ProductID[i] := #32;
      for i:= 32 to 35 do if ProductRev[i] < #32 then ProductRev[i] := #32;
      for i:= 36 to 55 do if VendorSpecific[i] < #32 then VendorSpecific[i] := #32;
    end;

    Str := fInquiryData.VendorID+' '+fInquiryData.ProductID+' '+fInquiryData.ProductRev;
    fDeviceName := Str;
  end
  else
    fDeviceName := ErrorString;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.GetAspiError(Status, HaStat, TargStat : BYTE) : String;
begin
  fTargetBusy := False;
  result := ERR_UNKNOWN;
  case Status of
    0,1: result := ERR_NONE;
    2,3: result := ERR_ABORTED;
    $80: result := ERR_INVALIDREQUEST;
    $81: result := ERR_INVALIDHA;
    $82: result := ERR_NODEVICE;
    $E0: result := ERR_INVALIDSRB;
    $E1: result := ERR_BUFFERALIGNMENT;
    $E5: result := ERR_ASPIBUSY;
    $E6: result := ERR_BUFFERTOOBIG;
    4: case HaStat of
      $09: result := ERR_TIMEOUT;
      $0B: result := ERR_SRBTIMEOUT;
      $0D: result := ERR_MESSAGEREJECT;
      $0E: result := ERR_BUSRESET;
      $0F: result := ERR_PARITYERR;
      $10: result := ERR_REQUESTSENSEFAILED;
      $11: result := ERR_SELECTIONTIMEOUT;
      $12: result := ERR_DATAOVERRUN;
      $13: result := ERR_UNEXPECTEDBUSFREE;
      $00: case TargStat of
        0,2: result := ERR_CHECKCONDITION;
        $08: begin result := ERR_TARGETBUSY; fTargetBusy := True; end;
        $18: result := ERR_TARGETCONFLICT;
        $28: result := ERR_QUEFULL;
        end;
      end;
    end;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.AdditionalSenseInformation(scm : TSRB_ExecSCSICmd): String;
var
  s: TSenseArea;
  ErrStr: String;
begin
  s := scm.SenseArea;
  ErrStr := '';
  {$I asc_info.inc}
  fLastSense := s;
  if ErrStr = '' then ErrStr := IntToStr(s.AddSenseCode)+','+IntToStr(s.AddSenQual);
  if s.AddSenLen <> 0 then
    fErrorString := fErrorString + ' ('+ErrStr+')';
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.DecodeSense(scm : TSRB_ExecSCSICmd): String;
var
  s: TSenseArea;
begin
  s := scm.SenseArea;
  Result := GetAspiError(scm.Status, scm.HaStat, scm.TargStat);
  if (Result = ERR_CHECKCONDITION) then
    if s.ErrorCode = 0 then
      Result := ERR_NONE
    else
      if (s.ErrorCode AND $7E) <> $70 then Result := ERR_UNKNOWN
      else
  case (s.SenseKey AND $0F) of
    0:
    begin
      if (s.SenseKey AND $80) <> 0 then Result := ERR_FILEMARK
      else if (s.SenseKey AND $40) <> 0 then Result := ERR_ENDOFMEDIA
      else if (s.SenseKey AND $20) <> 0 then Result := ERR_ILLEGALLENGTH
      else if (s.SenseKey AND $80) <> 0 then Result := ERR_INCORRECTLENGTH
      else  Result := ERR_AS_00_00;
    end;
    1 : Result := ERR_RECOVEREDERROR;
    2 : Result := ERR_NOTREADY;
    3 : Result := ERR_MEDIUMERROR;
    4 : Result := ERR_HARDWAREERROR;
    5 : Result := ERR_ILLEGALREQUEST;
    6 : Result := ERR_UNITATTENTION;
    7 : Result := ERR_DATAPROTECT;
    8 : Result := ERR_ERASECHECK;
    10: Result := ERR_COPYABORTED;
    11: Result := ERR_ABORTEDCOMMAND;
    13: Result := ERR_VOLUMEOVERFLOW;
    14: Result := ERR_MISCOMPARE;
    15: Result := ERR_RESERVED;         
  end;
  fErrorString := Result;
  AdditionalSenseInformation(scm);
end;
{******************************************************************************}
{                             Execute Scsi Command                             }
{******************************************************************************}
function TSCSIDevice.ExecScsiCommand;
var
  Event: THandle;
  EventNotify: Boolean;
 {$IFDEF DEBUG}
 i: Integer;
 s: String;
 {$ENDIF}
begin
  fErrorString := '';
  Event := 0;
  fTargetBusy := False;
  FillChar(fLastSense, sizeof(fLastSense), 0);
  if (not GetASPIInitialized) or (fHaID = 254) then
  begin
    result := $E2;
    exit;
  end;
  EventNotify := sc.Flags and $40 = $40;
  if EventNotify then
  begin
    Event := CreateEvent(nil, true, false, nil); 
    ResetEvent(Event);
    sc.PostProc := Event;
  end
  else
    sc.PostProc := 0;
  sc.Command := SC_EXEC_SCSI_CMD;
  sc.Target := fTarget;
  sc.HaId := fHaID;
  sc.Lun := fLun;
  sc.SenseLen := SENSE_LEN;
  if Timeout <= 10000 then
    Timeout := 10000;

  sc.CDBByte[1] := ((fLun AND 7) SHL 5) OR (sc.CDBByte[1] AND $1F);
  {$DEFINE NOWRITE1}
  {$IFDEF NOWRITE}
  if (sc.CDBCmd <> $2a) and (sc.CDBCmd <> $5b) and (sc.CDBCmd <> $53) then
    SendASPI32Command (@sc)
  else
    sc.Status := 1;
  {$ELSE}
    SendASPI32Command (@sc);
  {$ENDIF}
  if EventNotify then
  begin
    if sc.status = ss_pending then
      WaitForSingleObject(Event, TimeOut);
  end;
  if (sc.Status <> 1) and (sc.Status <> 0) then
    DecodeSense(sc);  
  if GenerateLogs then
  begin
    s := IntToStr(sc.HAID)+':'+IntToHex(sc.Target, 1)+':'+IntToStr(sc.Lun)+' <'+IntToHex(sc.Status, 2)+'>'+' ['+IntToHex(sc.BufLen,5)+']';
    s := '('+IntToHex(sc.CDBCmd, 2)+') {'+IntToHex(sc.Flags, 2)+'|'+IntToHex(sc.CDBLen, 2)+'} - '+s+' ';
    for i:=1 to 15 do s := s + IntTohex(sc.CDBByte[i], 2)+' ';
    s := CommandName[sc.cdbCmd]+' '+s+' ';
    s := s + '|';
    if sc.BufLen <> 0 then
    begin
      for i:=0 to Min($100, sc.BufLen-1) do s := s + IntTohex(Byte(sc.BufPointer[i]), 2)+' ';
    end;
    DebugMsg('<<< '+FormatDateTime('nn:ss:zzz ', now)+s + '= '
    +IntToHex(sc.HaStat, 2)+' '+ IntToHex(sc.TargStat, 2)+' '+IntToHex(sc.SenseArea.ErrorCode,2)+' '+IntToHex(sc.SenseArea.SenseKey, 2)+' '

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -