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

📄 mbdrvlib.pas

📁 刻录机源码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  OR ((DW SHR  8) AND $0000FF00)
  OR ((DW SHR 24) AND $000000FF);
end;
//------------------------------------------------------------------------------

procedure CvtEndians(const Src; var Dest; Count : integer);
var
  pSrc,
  pDst: PChar;
  i : integer;
begin
  pSrc := @Src;
  pDst := PChar(@Dest) + Count;
  for i := 0 to Count-1 do begin
    Dec(pDst);
    pDst^ := pSrc^;
    Inc(pSrc);
  end;
end;

{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.InitializeASPI(InternalFirst: Boolean = False; AspiPath: String = ''): Boolean;
begin
  try
    result := _InitializeASPI(InternalFirst, AspiPath);
  except
    result := False;
  end;
  if result then
  begin
    GetHostAdapterInfo(0);
    ScanDevices;
  end;
end;
{******************************************************************************}
{                              Set Write Parametes                             }
{******************************************************************************}
var
  ModeSenseBuf1, ModeSenseBuf2: array[0..$200-1] of byte;

{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.CheckWriteMethod(wm: TWriteMethod): Boolean;
var
  s, i: Integer;
begin
  Result := False;
  fillchar(ModeSenseBuf1, sizeof(ModeSenseBuf1), 0);
  fillchar(ModeSenseBuf2, sizeof(ModeSenseBuf2), 0);
  if ModeSense10($05, ModeSenseBuf1, SizeOf(ModeSenseBuf1)) then
  begin
    if ModeSenseBuf1[16] = $05 then s := 16
    else if ModeSenseBuf1[8] = $05 then s := 8
    else s := 8;
    for i :=0 to SizeOf(ModeSenseBuf1)-s-1 do ModeSenseBuf2[i] := ModeSenseBuf1[i+s];
    move(ModeSenseBuf2, ModePage05, sizeof(ModePage05));
    ModePage05.DBType := $00;
    if wm = wmTAO then
      ModePage05.WriteType := $01
    else if wm = wmSAO then
      ModePage05.WriteType := $02
    else
    begin
      ModePage05.DBType := 1;
      ModePage05.WriteType := $03;
    end;
    ModePage05.TrackMode := $10;
    ModePage05.SessionFormat := $0;
    ModePage05.Res9 := $0;
    ModePage05.PauseLen := $9600; // Pause
    ModePage05.TrackMode := $0;
    move(ModePage05, ModeSenseBuf2, ModePage05.PageLen+s+1);
    fillchar(ModeSenseBuf1, SizeOf(ModeSenseBuf1), 0);
    for i :=0 to $3c-s do ModeSenseBuf1[i+8] := ModeSenseBuf2[i];
    if ModeSelect10(@ModeSenseBuf1[0], ModePage05.PageLen+10) then
      Result := True;
  end;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.GetWriteMethods: Boolean;
begin
  fWriteMethods := [];
  if CheckWriteMethod(wmDAO) then Include(fWriteMethods, wmDAO);
  if CheckWriteMethod(wmSAO) then Include(fWriteMethods, wmSAO);
  if CheckWriteMethod(wmTAO) then Include(fWriteMethods, wmTAO);
  result := True;

end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.GetDriveLetter: Char;
var
  fh: THandle;
  buf: array[0..63] of char;
  tmp: String;
  pscsiAddr: PSCSI_ADDRESS;
  returned: Cardinal;
  DriveLetter: Byte;
begin
  result := #0;
  if ASPILayerName = 'BMASPI32' then
  begin
    result := GetDriveLetterBMASPI(fHAID, fTarget, fLUN);
    exit;
  end;
  for DriveLetter := 2 to 26 do
  begin
    tmp := '\\.\'+Chr(DriveLetter+64)+':'+#0;
    fh := CreateFile (@tmp[1], GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
    if ( fh = INVALID_HANDLE_VALUE ) then
      fh := CreateFile(@tmp[1], GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
    if ( fh <> INVALID_HANDLE_VALUE ) then
    begin
      FillChar(buf, Sizeof(buf), 0);
      pscsiAddr := @buf;
      pscsiAddr.Length := sizeof(SCSI_ADDRESS);
      if ( DeviceIoControl( fh, 266264, nil, 0, pscsiAddr, sizeof(SCSI_ADDRESS), returned, nil ) ) then
      begin
        if (pscsiAddr.PortNumber = fHAID) and (pscsiAddr.TargetId = fTarget) then
        begin
          result := Chr(DriveLetter+64);
          CloseHandle(fh);
          exit;
        end;
      end;
      CloseHandle(fh);
    end;
  end;
  DriveLetter := GetDiskLetter(fHAID, fTarget, fLUN);
  if DriveLetter <> 128 then
    Result := Chr(DriveLetter+65);
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.Notification(aComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(aComponent, Operation);
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.SetDriveLetter(Value: Char);
begin
  SetDeviceByDriveLetter(Value);
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
var
  xdi: TSRB_GetDiskInfo;

function TSCSIDevice.SetDeviceByDriveLetter(DriveLetter: Char): Boolean;
var
  fh: THandle;
  buf: array[0..63] of char;
  tmp: String;
  pscsiAddr: PSCSI_ADDRESS;
  returned: Cardinal;
  i, t, l, ha: Integer;
begin
  result := False;
  tmp := '\\.\'+DriveLetter+':'+#0;
  fh := CreateFile (@tmp[1], GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
  if ( fh = INVALID_HANDLE_VALUE ) then
    fh := CreateFile(@tmp[1], GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0 );
  if ( fh = INVALID_HANDLE_VALUE ) then
  begin
    i := Byte(DriveLetter)-64;
    if fDriveLetters[i] <> '' then
    begin
      Device := fDriveLetters[i];
      CloseHandle(fh);
      Result := True;
    end;    
    for ha := 0 to fAdapters-1 do
    begin
      for t:= 0 to 7 do
      for l := 0 to 7 do
      begin
        fillchar(xdi, sizeof(xdi), 0);
        xdi.Command := SC_GET_DISK_INFO;
        xdi.HaID := ha;
        xdi.Target := t;
        xdi.Lun := l;
        SendASPI32Command (@xdi);
        if xdi.Status = 1 then
        begin
          if xdi.Int13HDriveInfo = Ord(DriveLetter) - 65 then
          begin
            tmp := IntToStr(ha)+':'+IntToStr(t)+':'+IntToStr(l)+' '+DriveLetter+':';
            Device := tmp;
            result := True;
            exit;
          end;
        end;
      end;
    end;
  end
  else
  begin
    result := True;
    exit;
  end;
  FillChar(buf, Sizeof(buf), 0);
  pscsiAddr := @buf;
  pscsiAddr.Length := sizeof(SCSI_ADDRESS);
  if ( DeviceIoControl( fh, 266264, nil, 0, pscsiAddr, sizeof(SCSI_ADDRESS), returned, nil ) ) then
  begin
    tmp := IntToStr(pscsiAddr.PortNumber)+':'+IntToStr(pscsiAddr.TargetId)+':'+IntToStr(pscsiAddr.Lun)+' '+DriveLetter+':';
    Device := tmp;
    result := True;
  end;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.SelectDevice(sDevice: String): Boolean;
begin
  Device := sDevice;
  Result := True;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.GetDiskLetter(H, T, L: Byte): Byte;
begin
  fillchar(xdi, sizeof(xdi), 0);
  xdi.Command := SC_GET_DISK_INFO;
  xdi.HaID := H;
  xdi.Target := T;
  xdi.Lun := L;
  SendASPI32Command (@xdi);
  if xdi.Status = 1 then
    result := xdi.Int13HDriveInfo
  else
    result := 128;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.GetASPIInitialized: Boolean;
begin
  result := ASPIDLLLoaded;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.MaxWriteSpeed: Word;
begin
  if GetDeviceCapabilities then
    result := ModePage2A.MaxWriteSpeed
  else
   result := 0;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.SetWriteSpeed;
begin
  SetCDSpeed(fReadSpeed, Value);
  FWriteSpeed := Value;
end;

{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.MaxReadSpeed: Word;
begin
  if GetDeviceCapabilities then
  begin
    result := ModePage2A.MaxReadSpeed;
  end
  else
   result := 0;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.CurrentReadSpeed;
begin
  if GetDeviceCapabilities then
    result := ModePage2A.CurReadSpeed
  else
    result := 0;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
function TSCSIDevice.CurrentWriteSpeed: Word;
begin
  if GetDeviceCapabilities then
    result := ModePage2A.CurWriteSpeed
  else
   result := 0;
end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.ScanDevices;
var
  ha, t, l: Integer;
  llun, lha, lt: Integer;
  str: String;
  sDrvLtr: String;
begin
  fDevices.Clear;
  lha := fHaID;
  lt := fTarget;
  llun := fLun;
  fLun := 0;
  if DoDebug then DebugMsg('>>> '+ASPILayerName, mtMESSAGE);
  for ha := 0 to fAdapters-1 do
  begin
    GetHostAdapterInfo(ha);
    str := fHAInquiry.HA_Identifier;
    str := trim(str);
    if DoDebug then DebugMsg('>>> '+fHAInquiry.HA_ManagerId+' ('+str+')', mtMESSAGE);
    for t:= 0 to 7 do
    for l := 0 to 7 do
    begin
      fHaID := ha;
      fTarget := t;
      fLUN := l;
      FillChar(fInquiryData, SizeOf(fInquiryData), 0);
      if Inquiry then
      begin
        //Str := IntToStr(ha)+':'+IntToStr(t)+':'+IntToStr(l)+' - '+fInquiryData.VendorID+' '+fInquiryData.ProductID+' '+fInquiryData.ProductRev;        //Writeln(str);
        if (fInquiryData.PeripheralData = 5) or (fInquiryData.PeripheralData = 4) then
        begin
          sDrvLtr := GetDriveLetter;
          if sDrvLtr = #0 then
            sDrvLtr := '?:'
          else
            sDrvLtr := sDrvLtr+':';
          Str := IntToStr(ha)+':'+IntToStr(t)+':'+IntToStr(l)+','+sDrvLtr+' '+fInquiryData.VendorID+''+fInquiryData.ProductID+''+fInquiryData.ProductRev;
          if fInquiryData.PeripheralData = 4 then
            Str := Str + ' (not supported)';
          fDevices.Add(str);
        end;
      end;
    end;
  end;
  fHaID := lha;
  fTarget := lt;
  fLUN := llun;
  {  if fDevices.Count > 0 then  SetDeviceID(fDevices[0]);} // auto select first device if any
  fErrorString := '';
  ErrorString := '';

end;
{******************************************************************************}
{                                                                              }
{******************************************************************************}
procedure TSCSIDevice.DebugMsg;
begin
  if Assigned(fOnDebugMsg) then
    fOnDebugMsg(Self, Msg, mType);
end;
{******************************************************************************}
{                            Get Disk Information                              }
{******************************************************************************}
function TSCSIDevice.GetDiskInformation: Boolean;
var
  lsrb: TSRB_GetDiskInfo;

⌨️ 快捷键说明

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