UNIT1.PAS
上传用户:jzxjwgb
上传日期:2007-01-06
资源大小:64k
文件大小:33k
源码类别:

SCSI/ASPI

开发平台:

Delphi

  1. unit Unit1;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  5.   TASPIdev, TCdBasic, Menus, ExtCtrls, StdCtrls, Spin;
  6. type
  7.   TForm1 = class(TForm)
  8.     MainMenu1: TMainMenu;
  9.     MandatoryCmd: TMenuItem;
  10.     OptionalCmd: TMenuItem;
  11.     ModeCmd: TMenuItem;
  12.     AudioCmd: TMenuItem;
  13.     PlayAudio101: TMenuItem;
  14.     HelpSubmenu: TMenuItem;
  15.     TestReady1: TMenuItem;
  16.     RequestSense1: TMenuItem;
  17.     Inquiry1: TMenuItem;
  18.     Reserve1: TMenuItem;
  19.     Release1: TMenuItem;
  20.     SelfTest1: TMenuItem;
  21.     ReadCapacity1: TMenuItem;
  22.     ReadCapacityPM1: TMenuItem;
  23.     Read101: TMenuItem;
  24.     RezeroUnit1: TMenuItem;
  25.     StartStopUnit1: TMenuItem;
  26.     Seek101: TMenuItem;
  27.     PreFetch1: TMenuItem;
  28.     SynchronizeCache1: TMenuItem;
  29.     LockUnlockCache1: TMenuItem;
  30.     ReadLong1: TMenuItem;
  31.     ReadSubchannel1: TMenuItem;
  32.     ReadToc1: TMenuItem;
  33.     ReadHeaderLBA1: TMenuItem;
  34.     ReadHeaderMSF1: TMenuItem;
  35.     ModeSelectEX1: TMenuItem;
  36.     ModeSenseHeader1: TMenuItem;
  37.     ModeSenseRecover1: TMenuItem;
  38.     ModeSenseRecoverEX1: TMenuItem;
  39.     ModeSenseMediumEX1: TMenuItem;
  40.     ModeSenseDevice1: TMenuItem;
  41.     ModeSenseDeviceEX1: TMenuItem;
  42.     ModeSenseAudio1: TMenuItem;
  43.     ModeSenseAudioEX1: TMenuItem;
  44.     ModeSelect1: TMenuItem;
  45.     ModeSelectEX2: TMenuItem;
  46.     PlayAudio121: TMenuItem;
  47.     PlayAudioMSF1: TMenuItem;
  48.     PlayAudioTI1: TMenuItem;
  49.     PlayAudioR101: TMenuItem;
  50.     PlayAudioR121: TMenuItem;
  51.     PauseAudio1: TMenuItem;
  52.     ResumeAudio1: TMenuItem;
  53.     About1: TMenuItem;
  54.     ASPI1: TMenuItem;
  55.     TASPI1: TMenuItem;
  56.     EnumDevices1: TMenuItem;
  57.     Panel1: TPanel;
  58.     ComboBox1: TComboBox;
  59.     Memo1: TMemo;
  60.     procedure About1Click(Sender: TObject);
  61.     procedure FormCreate(Sender: TObject);
  62.     procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  63.     procedure TestReady1Click(Sender: TObject);
  64.     procedure ComboBox1Change(Sender: TObject);
  65.     procedure Reserve1Click(Sender: TObject);
  66.     procedure Release1Click(Sender: TObject);
  67.     procedure RezeroUnit1Click(Sender: TObject);
  68.     procedure PauseAudio1Click(Sender: TObject);
  69.     procedure ResumeAudio1Click(Sender: TObject);
  70.     procedure ModeSenseAudio1Click(Sender: TObject);
  71.     procedure ModeSenseDevice1Click(Sender: TObject);
  72.     procedure ModeSenseHeader1Click(Sender: TObject);
  73.     procedure SelfTest1Click(Sender: TObject);
  74.     procedure ReadCapacity1Click(Sender: TObject);
  75.     procedure ReadCapacityPM1Click(Sender: TObject);
  76.     procedure StartStopUnit1Click(Sender: TObject);
  77.     procedure Seek101Click(Sender: TObject);
  78.     procedure ReadSubchannel1Click(Sender: TObject);
  79.     procedure ReadToc1Click(Sender: TObject);
  80.     procedure PreFetch1Click(Sender: TObject);
  81.     procedure LockUnlockCache1Click(Sender: TObject);
  82.     procedure PlayAudio101Click(Sender: TObject);
  83.     procedure PlayAudio121Click(Sender: TObject);
  84.     procedure PlayAudioTI1Click(Sender: TObject);
  85.     procedure PlayAudioMSF1Click(Sender: TObject);
  86.     procedure ReadLong1Click(Sender: TObject);
  87.     procedure Read101Click(Sender: TObject);
  88.     procedure ModeSenseRecoverEX1Click(Sender: TObject);
  89.     procedure ModeSenseMediumEX1Click(Sender: TObject);
  90.     procedure ModeSenseDeviceEX1Click(Sender: TObject);
  91.     procedure ModeSenseAudioEX1Click(Sender: TObject);
  92.     procedure TASPI1Click(Sender: TObject);
  93.     procedure EnumDevices1Click(Sender: TObject);
  94.     procedure RequestSense1Click(Sender: TObject);
  95.   private
  96.     { Private declarations }
  97.   public
  98.     CdRom1 : TCdRom;
  99.   end;
  100. var
  101.   Form1: TForm1;
  102.   Log  : Text;    // We can treat 'Log' as text file opened for write
  103. implementation
  104. uses Unit2, Unit3, Unit4, Unit5, Unit6, Unit7, Unit8, Unit9,
  105.      Unit10, Unit11, Unit12, Unit13, Unit14, Unit15, Unit16,
  106.      Unit17, Unit18, Unit19, Unit20, Unit21;
  107. {$R *.DFM}
  108. //=============== LogMemo object functions ================
  109. var
  110.    LogDFile   : TextFile;  // Real disk file for logging
  111.    LogDFileOk : BOOLEAN;   // TRUE if disk file was successfully opened
  112.    LogFileBuf : string;
  113.    LogFileMaxMemoLines : integer;  // Max number of lines that are stored
  114.                                    // in Memo (for editing, remarks etc.)
  115. procedure LogFileAddLine;
  116. begin with Form1.Memo1 do begin
  117.    Lines.BeginUpdate;
  118.    while Lines.Count > LogFileMaxMemoLines do begin
  119.       if LogDFileOk then
  120.        try
  121.          writeln(LogDFile, Lines[0]);
  122.        except
  123.          on EInOutError do begin
  124.             LogDFileOk := FALSE;
  125.             MessageDlg('Error while writing log file. Trying to close it.',
  126.                     mtInformation, [mbOk], 0);
  127.             CloseFile(LogDFile);
  128.       end; end;
  129.       Lines.Delete(0);
  130.    end;
  131.    Lines.EndUpdate;
  132.    Lines.Add(LogFileBuf);
  133.    LogFileBuf := '';
  134. end; end;
  135. function LogFileOut(var P : TTextRec) : integer;
  136. var i : integer;
  137. begin
  138.    with P do begin
  139.       for i := 0 to BufPos-1 do
  140.        if Buffer[i] <> #10 then begin     // Skip all LFs
  141.          if Buffer[i] = #13 then LogFileAddLine
  142.                             else LogFileBuf := LogFileBuf + Buffer[i];
  143.       end;
  144.       BufPos  := 0;
  145.    end;
  146.    result  := 0;
  147. end;
  148. function LogFileFlush(var P : TTextRec) : integer;
  149. begin
  150.    result := 0;
  151. end;
  152. function LogFileClose(var P : TTextRec) : integer;
  153. begin
  154.    P.Mode := fmClosed;
  155.    result := 0;
  156.    if LogDFileOk then begin
  157.       LogFileMaxMemoLines := 0;    // write the rest of log to disk
  158.       LogFileAddLine;
  159.       CloseFile(LogDFile);
  160. end; end;
  161. procedure LogFileAssignRewrite(const FName : string);
  162. begin
  163.    LogDFileOk := TRUE;
  164.    try
  165.       AssignFile(LogDFile, FName);
  166.       Rewrite(LogDFile);
  167.    except
  168.       on EInOutError do begin
  169.          LogDFileOk := FALSE;
  170.          MessageDlg('Cannot open log file '+ FName +
  171.                     '. Logging onto screen only.',
  172.                     mtInformation, [mbOk], 0);
  173.    end; end;
  174.    with TTextRec(Log) do begin
  175.       Handle  := 0;
  176.       Mode    := fmOutput;
  177.       BufSize := sizeof(Buffer);
  178.       BufPos  := 0;
  179.       BufEnd  := 0;
  180.       BufPtr  := @Buffer;
  181.       OpenFunc  := @LogFileFlush;  // do nothing, return Ok
  182.       InOutFunc := @LogFileOut;
  183.       FlushFunc := @LogFileFlush;
  184.       CloseFunc := @LogFileClose;
  185.       Name[0] := #0;
  186.    end;
  187.    LogFileMaxMemoLines := 128;
  188.    LogFileBuf := '======= TCdRom Demo Program Log File =======';
  189.    Form1.Memo1.Lines.Clear;
  190.    LogFileAddLine;
  191. end;
  192. //=============== Some common functions ================
  193. procedure Report(const st : string; Res : BOOLEAN);
  194. var s : string;
  195. begin
  196.    writeln(Log, Copy(st,1,Length(st)-2)+');');
  197.    if Res then write(Log, '     Executed successfully')
  198.           else write(Log, '     Execution failed');
  199.    with Form1.CdRom1 do begin
  200.       write(Log, ', LastErr = ', SCSIerrorName[LastError]);
  201.       if LastError = Err_SenseIllegalRequest then begin
  202.            // detailed error analyse especially for this Demo
  203.          if (Sense[15] AND $80) <> 0 then begin
  204.             writeln(Log);
  205.             write(Log, '     Detailed: Error in ');
  206.             if (Sense[15] AND $80) <> 0
  207.               then write(Log, 'command descriptor block, byte ')
  208.               else write(Log, 'command data block, byte ');
  209.             write(Log, GatherWORD(Sense[16], Sense[17]));
  210.             if (Sense[15] AND 8) <> 0 then
  211.                write(Log, ', bit ', (Sense[15] AND 7));
  212.       end; end;
  213.            // Here is ASC/ASCQ analyse
  214.       if Sense[12] <> 0 then begin    // Additional Sense Code
  215.          writeln(Log);
  216.          write(Log, '     Detailed: ');
  217.          case Sense[12] of
  218.             $1A : s := 'Parameter list length error';
  219.             $1B : s := 'Synchronous data transfer error';
  220.             $20 : s := 'Invalid command operation code';
  221.             $21 : s := 'Logical block address out of range';
  222.             $24 : s := 'Invalid field in command descriptor block';
  223.             $25 : s := 'Logical unit not supported';
  224.             $26 : case Sense[13] of
  225.               0 : s := 'Invalid field in parameter list';
  226.               1 : s := 'Parameter not supported';
  227.               2 : s := 'Parameter value invalid';
  228.               3 : s := 'Threshold parameters not supported';
  229.               end;
  230.             $28 : s := 'Not ready (medium may have changed)';
  231.             $29 : s := 'Power on, reset or bus device reset occured';
  232.             $2A : case Sense[13] of
  233.               0 : s := 'Parameters changed';
  234.               1 : s := 'Mode parameters changed';
  235.               2 : s := 'Log parameters changed';
  236.               end;
  237.             $2B : s := 'Cannot execute copy';
  238.             $2C : s := 'Command sequence error';
  239.             $2F : s := 'Commands cleared by another initiator';
  240.             $30 : case Sense[13] of
  241.               0 : s := 'Incompatible medium installed';
  242.               1 : s := 'Cannot read medium - unknown format';
  243.               2 : s := 'Cannot read medium - incompatible format';
  244.               end;
  245.             $37 : s := 'Rounded parameter';
  246.             $39 : s := 'Saving parameters not supported';
  247.             $3A : s := 'Medium not present';
  248.             $3D : s := 'Invalid bits in identify message';
  249.             $3E : s := 'Logical unit has not self-configured yet';
  250.             $3F : case Sense[13] of
  251.               0 : s := 'Target operation conditions have changed';
  252.               1 : s := 'Microcode has been changed';
  253.               2 : s := 'Changed operating definition';
  254.               3 : s := 'Inquiry data has changed';
  255.               end;
  256.             $40 : s := Format('Diagnostic failure on component %2xh',
  257.                               [Sense[13]]);
  258.             $43 : s := 'Message error';
  259.             $44 : s := 'Internal target failure';
  260.             $45 : s := 'Select or reselect failure';
  261.             $46 : s := 'Unsuccessfull soft reset';
  262.             $47 : s := 'SCSI parity error';
  263.             $48 : s := 'Initiator detected error message received';
  264.             $49 : s := 'Invalid message error';
  265.             $4A : s := 'Command phase error';
  266.             $4B : s := 'Data phase error';
  267.             $4C : s := 'Logical unit failed self-configuration';
  268.             $4E : s := 'Overlapped commands attempted';
  269.             $53 : case Sense[13] of
  270.               0 : s := 'Media load or eject failed';
  271.               2 : s := 'Meduim removal prevented';
  272.               end;
  273.             $57 : s := 'Unable to recover table-of-contents';
  274.             $5A : case Sense[13] of
  275.               0 : s := 'Operator request or state change input';
  276.               1 : s := 'Operator medium removal request';
  277.               end;
  278.             $5B : case Sense[13] of
  279.               0 : s := 'Log exception';
  280.               1 : s := 'Threshold condition met';
  281.               2 : s := 'Log counter at maximum';
  282.               3 : s := 'Log list codes exhausted';
  283.               end;
  284.             $63 : s := 'End of user area encountered on this track';
  285.             $64 : s := 'Illegal mode for this track';
  286.             else s := 'Unknown error code';
  287.          end;
  288.          write(Log, s, ' (ASC=', Sense[12], ', ASCQ=', Sense[13], ')');
  289.       end;
  290.    end;
  291.    writeln(Log);
  292.    flush(Log);
  293. end;
  294. function BVal(Arg : TCheckBox) : string;
  295. begin with Arg do begin
  296.    if Checked then result := Name + '=TRUE, '
  297.               else result := Name + '=FALSE, ';
  298. end; end;
  299. function DVal(Arg : TSpinEdit) : string;
  300. begin with Arg do begin
  301.    result := Name + '=' + IntToStr(Value) + ', ';
  302. end; end;
  303. var IObuf : array[0..9999] of Byte;  // Data buffer for all I/O related ops
  304. procedure LogHex(Buf : pointer; BufLen : DWORD);
  305. var
  306.    i     : integer;
  307.    mb    : array[0..15] of byte;
  308.    s1,s2 : string;
  309.    procedure LogLine(Len : integer);
  310.    var j  : integer;
  311.    begin
  312.       s1 := Format('      %3x0 ', [i]);
  313.       s2 := ' |';
  314.       for j := 0 to 15 do begin
  315.          if (j MOD 4) = 0 then begin
  316.             s1 := s1 + ' ';
  317.            { s2 := s2 + ' '; }
  318.          end { else s1 := s1 + '-' };
  319.          if j >= Len then begin
  320.             s1 := s1 + '   ';
  321.             s2 := s2 + ' ';
  322.          end else begin
  323.             s1 := s1 + Format('%2x', [mb[j]]);
  324.             if mb[j] < $20 then s2 := s2 + ' '
  325.                            else s2 := s2 + CHR(mb[j]);
  326.       end; end;
  327.       writeln(Log, s1, s2, ' |');
  328.    end;
  329. begin
  330.    i := 0;
  331.    while BufLen >= 16 do begin
  332.       Move(Buf^, mb, sizeof(mb));
  333.       LogLine(16);
  334.       Inc(PChar(Buf), sizeof(mb));
  335.       Dec(BufLen, 16);
  336.       Inc(i);
  337.    end;
  338.    if BufLen > 0 then begin
  339.       Move(Buf^, mb, BufLen);
  340.       LogLine(BufLen);
  341.    end;
  342.    flush(Log);
  343. end;
  344. //=========================================================
  345. procedure LogDeviceInfo;
  346. begin
  347.   with Form1.CdRom1.DeviceInfo do begin
  348.    writeln(Log, '   DeviceInfo structure fields:');
  349.    writeln(Log, '     PeripheralQualifier = ', PeripheralQualifier);
  350.    writeln(Log, '     DeviceType          = ', DeviceType);
  351.    writeln(Log, '     DeviceTypeModifier  = ', DeviceTypeModifier);
  352.    writeln(Log, '     RemovableMedium     = ', RemovableMedium);
  353.    writeln(Log, '     ISOversion  = ', ISOversion);
  354.    writeln(Log, '     ECMAversion = ', ECMAversion);
  355.    writeln(Log, '     ANSIversion = ', ANSIversion);
  356.    writeln(Log, '     AsyncEventCapability  = ', AsyncEventCapability);
  357.    writeln(Log, '     TerminateIOcapability = ', TerminateIOcapability);
  358.    writeln(Log, '     ResponseDataFormat    = ', ResponseDataFormat);
  359.    writeln(Log, '     AdditionalDataLength  = ', AdditionalDataLength);
  360.    writeln(Log, '     WideBus32capability   = ', WideBus32capability);
  361.    writeln(Log, '     WideBus16capability   = ', WideBus16capability);
  362.    writeln(Log, '     RelativeAddressingCapability  = ', RelativeAddressingCapability);
  363.    writeln(Log, '     SynchronousTransferCapability = ', SynchronousTransferCapability);
  364.    writeln(Log, '     LinkedCommandsCapability      = ', LinkedCommandsCapability);
  365.    writeln(Log, '     CommandQueuingCapability      = ', CommandQueuingCapability);
  366.    writeln(Log, '     SoftResetCapability           = ', SoftResetCapability);
  367.    writeln(Log, '     VendorID        = "', VendorID, '"');
  368.    writeln(Log, '     ProductID       = "', ProductID, '"');
  369.    writeln(Log, '     ProductRevision = "', ProductRevision, '"');
  370.    writeln(Log, '     VendorSpecific  = "', VendorSpecific, '"');
  371.   with Form1.CdRom1.HAinfo do begin
  372.    writeln(Log, '   HAinfo structure fields:');
  373.    writeln(Log, '     ScsiID            = ', ScsiID);
  374.    writeln(Log, '     MaxTargetCount    = ', MaxTargetCount);
  375.    writeln(Log, '     ResidualSupport   = ', ResidualSupport);
  376.    writeln(Log, '     MaxTransferLength = ', MaxTransferLength);
  377.    writeln(Log, '     BufferAlignMask   = ', BufferAlignMask);
  378.    writeln(Log, '     ScsiManagerID     = "', ScsiManagerID, '"');
  379.    writeln(Log, '     HostAdapterID     = "', HostAdapterID, '"');
  380.   end;
  381. end; end;
  382. var ComboBoxAddItem : boolean;
  383. procedure LogNewDevice;      // CallBack for EnumDevices
  384. var s : string;
  385. begin
  386.    with Form1.CdRom1 do begin
  387.       s := Format('%1x,%1x,%1x : ', [DeviceID.Adapter,
  388.                     DeviceID.Target, DeviceID.Lun]) +
  389.         DeviceInfo.VendorID + ' ' + DeviceInfo.ProductID +
  390.         ' rev.' + DeviceInfo.ProductRevision;
  391.       writeln(Log, TScsiDeviceTypeName[DeviceType], ' found at ', s);
  392.    end;
  393.    LogDeviceInfo;
  394.    flush(Log);
  395.    if ComboBoxAddItem then Form1.ComboBox1.Items.Add(s);
  396. end;
  397. procedure TForm1.ComboBox1Change(Sender: TObject);
  398.    function HexToByte(C : char) : BYTE;
  399.    begin
  400.       result := 0;
  401.       if C in ['0'..'9'] then result := ORD(C) - $30;
  402.       if C in ['A'..'F'] then result := ORD(C) - $37;
  403.       if C in ['a'..'f'] then result := ORD(C) - $57;
  404.    end;
  405. var
  406.    s : string;
  407.    d : TDeviceID;
  408. begin
  409.    s := ComboBox1.Items[ComboBox1.ItemIndex];
  410.    d.Adapter := HexToByte(s[1]);
  411.    d.Target  := HexToByte(s[2]);
  412.    d.Lun     := HexToByte(s[3]);
  413.    CdRom1.DeviceID := d;
  414. end;
  415. procedure TForm1.FormCreate(Sender: TObject);
  416. begin
  417.    CdRom1 := TCdRom.Create(self);
  418.    LogFileAssignRewrite( ExtractFilePath(ParamStr(0)) + 'tcbddemo.log');
  419.    ComboBoxAddItem := TRUE;
  420.    CdRom1.EnumDevices(TSDCdRom, LogNewDevice);
  421.    ComboBoxAddItem := FALSE;               // Next EnumDevices calls will
  422.                                            //  not affects ComboBox
  423.    if ComboBox1.Items.Count > 0 then begin
  424.       ComboBox1.ItemIndex := 0;
  425.       ComboBox1Change(self);
  426. end; end;
  427. procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  428. begin
  429.    CloseFile(Log);
  430.    CdRom1.free;
  431. end;
  432. procedure TForm1.About1Click(Sender: TObject);
  433. begin  AboutBox.ShowModal;  end;
  434. procedure TForm1.TestReady1Click(Sender: TObject);
  435. begin   Report('Trying: SCSItestReady;', CdRom1.SCSItestReady);    end;
  436. procedure TForm1.Reserve1Click(Sender: TObject);
  437. begin   Report('Trying: SCSIreserve;', CdRom1.SCSIreserve);        end;
  438. procedure TForm1.Release1Click(Sender: TObject);
  439. begin   Report('Trying: SCSIrelease;', CdRom1.SCSIrelease);        end;
  440. procedure TForm1.RezeroUnit1Click(Sender: TObject);
  441. begin   Report('Trying: SCSIrezeroUnit;', CdRom1.SCSIrezeroUnit);  end;
  442. procedure TForm1.PauseAudio1Click(Sender: TObject);
  443. begin   Report('Trying: SCSIpauseAudio;', CdRom1.SCSIpauseAudio);  end;
  444. procedure TForm1.ResumeAudio1Click(Sender: TObject);
  445. begin  Report('Trying: SCSIresumeAudio;', CdRom1.SCSIresumeAudio); end;
  446. procedure TForm1.ModeSenseAudio1Click(Sender: TObject);
  447. var APage : TCdRomModePageAudio;
  448. begin
  449.    Report('Trying: SCSImodeSenseAudio(var sh: TCdRomModePageAudio);',
  450.           CdRom1.SCSImodeSenseAudio(APage));
  451.    with APage do begin
  452.       writeln(Log, '     Returned record TCdRomModePageAudio :');
  453.       writeln(Log, '       PSAV = ', PSAV);
  454.       writeln(Log, '       IMM  = ', IMM);
  455.       writeln(Log, '       SOTC = ', SOTC);
  456.       writeln(Log, '       APRV = ', APRV);
  457.       writeln(Log, '       LBAformat = ', LBAformat);
  458.       writeln(Log, '       LBSaudio  = ', LBSaudio);
  459.       writeln(Log, Format('       Volume  = [%2x, %2x, %2x, %2x] hex',
  460.           [Volume[0],  Volume[1],  Volume[2],  Volume[3]]));
  461.       writeln(Log, Format('       Channel = [%2x, %2x, %2x, %2x] hex',
  462.           [Channel[0], Channel[1], Channel[2], Channel[3]]));
  463.       flush(Log);
  464. end; end;
  465. procedure TForm1.ModeSenseDevice1Click(Sender: TObject);
  466. var ITimer : BYTE;
  467. begin
  468.    Report('Trying: SCSImodeSenseDevice(var ITimer: BYTE);',
  469.           CdRom1.SCSImodeSenseDevice(ITimer));
  470.    writeln(Log, '     Returned ITimer = ', ITimer, ' decimal');
  471.    flush(Log);
  472. end;
  473. procedure TForm1.ModeSenseHeader1Click(Sender: TObject);
  474. var
  475.    AHeader : TCdRomModeHeader;
  476.    B       : BYTE;
  477. begin
  478.    Report('Trying: SCSImodeSenseHeader(var sh: TCdRomModeHeader);',
  479.           CdRom1.SCSImodeSenseHeader(AHeader));
  480.    with AHeader do begin
  481.       writeln(Log, '     Returned record TCdRomModeHeader :');
  482.       writeln(Log, '       Meduim = ', TCdRomMediumName[Medium]);
  483.       writeln(Log, '       DPOFUA = ', DPOFUA);
  484.       if BDlength = 0 then
  485.          writeln(Log, '       BDlength = 0')
  486.       else begin
  487.          writeln(Log, '       TCdRomBlockDescriptor Table (',
  488.                    BDlength, ' record total :');
  489.          for B := 0 to BDlength-1 do
  490.           with BD[B] do
  491.            writeln(Log, '       BD[', B:3, ']: Density=', Density,
  492.               ', BlkCount=', BlkCount:6, ', BlkSize=', BlkSize);
  493.       end;
  494.       flush(Log);
  495. end; end;
  496. procedure TForm1.SelfTest1Click(Sender: TObject);
  497. begin with SelfTestDlg do begin
  498.    if ShowModal = mrOk then begin
  499.       Report('Trying: SCSIselfTest('+BVal(DOFF)+BVal(UOFF),
  500.              CdRom1.SCSIselfTest(DOFF.Checked, UOFF.Checked));
  501.    end;
  502. end; end;
  503. procedure TForm1.ReadCapacity1Click(Sender: TObject);
  504. var BCnt, BSize : DWORD;
  505. begin
  506.    Report('Trying: SCSIreadCapacity(var BlkCount, BlkSize : DWORD);',
  507.           CdRom1.SCSIreadCapacity(BCnt,BSize));
  508.    writeln(Log, '     Returned BlkCount = ', BCnt,  ' decimal');
  509.    writeln(Log, '     Returned BlkSize  = ', BSize, ' decimal');
  510.    flush(Log);
  511. end;
  512. procedure TForm1.ReadCapacityPM1Click(Sender: TObject);
  513. var BCnt, BSize : DWORD;
  514. begin with ReadCaPMDlg do begin
  515.    if ShowModal = mrOk then begin
  516.       Report('Trying: SCSIreadCapacityPM(' + DVal(Partition) + DVal(GLBA)+
  517.              'var BlkCount, BlkSize : DWORD);',
  518.              CdRom1.SCSIreadCapacityPM(WORD(Partition.Value),
  519.                                        GLBA.Value, BCnt, BSize));
  520.       writeln(Log, '     Returned BlkCount = ', BCnt,  ' decimal');
  521.       writeln(Log, '     Returned BlkSize  = ', BSize, ' decimal');
  522.       flush(Log);
  523.    end;
  524. end; end;
  525. procedure TForm1.StartStopUnit1Click(Sender: TObject);
  526. begin with StartStopDlg do begin
  527.    if ShowModal = mrOk then begin
  528.       Report('Trying: SCSIstartStopUnit('+BVal(STRT)+BVal(LOEJ)+BVal(IMM),
  529.         CdRom1.SCSIstartStopUnit(STRT.Checked, LOEJ.Checked, IMM.Checked));
  530.    end;
  531. end; end;
  532. procedure TForm1.Seek101Click(Sender: TObject);
  533. begin with Seek10Dlg do begin
  534.    if ShowModal = mrOk then begin
  535.       Report('Trying: SCSIseek10(' + DVal(GLBA),
  536.              CdRom1.SCSIseek10(GLBA.Value));
  537.       flush(Log);
  538.    end;
  539. end; end;
  540. procedure TForm1.ReadSubchannel1Click(Sender: TObject);
  541. var Info : TCdRomSubQinfo;
  542. begin with ReadSubchannelDlg do begin
  543.    if ShowModal = mrOk then begin
  544.       Report('Trying: SCSIreadSubchannel('+BVal(MSFform)+
  545.              'var Info : TCdRomSubQinfo);',
  546.         CdRom1.SCSIreadSubchannel(MSFform.Checked, Info));
  547.       with Info do begin
  548.         writeln(Log, '     Returned record TCdRomSubQinfo :');
  549.         writeln(Log, '       AudioStatus = ',TAudioStatusName[AudioStatus]);
  550.         writeln(Log, '       ADR         = ',TsubchannelADRname[ADR]);
  551.         writeln(Log, '       PreEmphasis = ', PreEmphasis);
  552.         writeln(Log, '       CopyPermit  = ', CopyPermit);
  553.         writeln(Log, '       DataTrack   = ', DataTrack);
  554.         writeln(Log, '       QuadAudio   = ', QuadAudio);
  555.         writeln(Log, '       TrackNumber = ', TrackNumber);
  556.         writeln(Log, '       IndexNumber = ', IndexNumber);
  557.         writeln(Log, '       UPC  = "', UPC,  '"');
  558.         writeln(Log, '       ISRC = "', ISRC, '"');
  559.         if MSFform.Checked then begin
  560.           writeln(Log, '       AbsAddress = ',AbsAddressM:2,' : ',
  561.              AbsAddressS:2,' : ',AbsAddressF:2,'  // in MSF');
  562.           writeln(Log, '       RelAddress = ',RelAddressM:2,' : ',
  563.              RelAddressS:2,' : ',RelAddressF:2,'  //   form');
  564.         end else begin
  565.           writeln(Log, '       AbsAddress = ',AbsAddress,'  // in LBA');
  566.           writeln(Log, '       RelAddress = ',RelAddress,'  //   form');
  567.         end;
  568.         flush(Log);
  569.    end; end;
  570. end; end;
  571. procedure TForm1.ReadToc1Click(Sender: TObject);
  572. var
  573.    Toc : TCdRomToc;
  574.    i   : integer;
  575. begin with ReadTocDlg do begin
  576.    if ShowModal = mrOk then begin
  577.       Report('Trying: SCSIreadToc('+BVal(MSFform)+DVal(Start)+
  578.              'var Toc : TCdRomToc);',
  579.         CdRom1.SCSIreadToc(MSFform.Checked, BYTE(Start.Value), Toc));
  580.       with Toc do begin
  581.         writeln(Log, '     Returned record TCdRomToc :');
  582.         writeln(Log, '       FirstTrack = ', FirstTrack);
  583.         writeln(Log, '       LastTrack  = ', LastTrack);
  584.         writeln(Log, '       TrackCount = ', TrackCount,
  585.            '  // Real tracks + lead-off area (TrackNumber=170)');
  586.         writeln(Log, '       InMSF      = ', InMSF);
  587.       end;
  588.       for i := 0 to Toc.TrackCount-1 do
  589.        with Toc.Track[i] do begin
  590.         writeln(Log, '       TrackNumber = ', TrackNumber);
  591.         writeln(Log, '       ADR         = ',TsubchannelADRname[ADR]);
  592.         writeln(Log, '       PreEmphasis = ', PreEmphasis);
  593.         writeln(Log, '       CopyPermit  = ', CopyPermit);
  594.         writeln(Log, '       DataTrack   = ', DataTrack);
  595.         writeln(Log, '       QuadAudio   = ', QuadAudio);
  596.         if MSFform.Checked then
  597.           writeln(Log, '       Address = ',AddressM:2,' : ',
  598.              AddressS:2,' : ',AddressF:2,'  // in MSF form')
  599.         else
  600.           writeln(Log, '       Address = ',Address,'  // in LBA form');
  601.       end;
  602.       flush(Log);
  603.    end;
  604. end; end;
  605. procedure TForm1.PreFetch1Click(Sender: TObject);
  606. begin with PreFetchDlg do begin
  607.    if ShowModal = mrOk then
  608.       Report('Trying: SCSIpreFetch('
  609.              + BVal(IMM) + DVal(GLBA) + DVal(Sectors),
  610.              CdRom1.SCSIpreFetch(IMM.Checked,
  611.                      GLBA.Value, WORD(Sectors.Value)));
  612. end; end;
  613. procedure TForm1.LockUnlockCache1Click(Sender: TObject);
  614. begin with LockCacheDlg do begin
  615.    if ShowModal = mrOk then
  616.       Report('Trying: SCSIlockUnlockCache('
  617.              + BVal(LOK) + DVal(GLBA) + DVal(Sectors),
  618.              CdRom1.SCSIlockUnlockCache(LOK.Checked,
  619.                          GLBA.Value, WORD(Sectors.Value)));
  620. end; end;
  621. procedure TForm1.PlayAudio101Click(Sender: TObject);
  622. begin with PlayAudio10Dlg do begin
  623.    if ShowModal = mrOk then
  624.       Report('Trying: SCSIplayAydio10(' + DVal(GLBA) + DVal(Sectors),
  625.              CdRom1.SCSIplayAudio10(GLBA.Value, WORD(Sectors.Value)));
  626. end; end;
  627. procedure TForm1.PlayAudio121Click(Sender: TObject);
  628. begin with PlayAudio12Dlg do begin
  629.    if ShowModal = mrOk then
  630.       Report('Trying: SCSIplayAydio12(' + DVal(GLBA) + DVal(Sectors),
  631.              CdRom1.SCSIplayAudio12(GLBA.Value, Sectors.Value));
  632. end; end;
  633. procedure TForm1.PlayAudioTI1Click(Sender: TObject);
  634. begin with PlayAudioTIDlg do begin
  635.    if ShowModal = mrOk then
  636.       Report('Trying: SCSIplayAydioTI('
  637.              + DVal(StartTrack) + DVal(StartIndex)
  638.              + DVal(StopTrack)  + DVal(StopIndex),
  639.              CdRom1.SCSIplayAudioTI(
  640.              BYTE(StartTrack.Value), BYTE(StartIndex.Value),
  641.              BYTE(StopTrack.Value), BYTE(StopIndex.Value)));
  642. end; end;
  643. procedure TForm1.PlayAudioMSF1Click(Sender: TObject);
  644. begin with PlayAudioMSFDlg do begin
  645.    if ShowModal = mrOk then
  646.       Report('Trying: SCSIplayAydioMSF('
  647.              + DVal(StartM) + DVal(StartS) + DVal(StartF)
  648.              + DVal(StopM)  + DVal(StopS)  + DVal(StopF),
  649.              CdRom1.SCSIplayAudioMSF(
  650.                BYTE(StartM.Value), BYTE(StartS.Value), BYTE(StartF.Value),
  651.                BYTE(StopM.Value), BYTE(StopS.Value), BYTE(StopF.Value)));
  652. end; end;
  653. procedure TForm1.ReadLong1Click(Sender: TObject);
  654. var Leng : DWORD;
  655. begin with ReadLongDlg do begin
  656.    if ShowModal = mrOk then begin
  657.       Leng := BufLen.Value;
  658.       Report('Trying: SCSIreadLong(' + BVal(CORR) + DVal(GLBA)
  659.              + 'Buf : Pointer, ' + DVal(BufLen),
  660.              CdRom1.SCSIreadLong(CORR.Checked, GLBA.Value, @IObuf, Leng));
  661.       if (CdRom1.LastError = Err_None) AND (Leng > 0) then begin
  662.          writeln(Log, '     Returned Data Buffer :');
  663.          LogHex(@IObuf, Leng);
  664.       end;
  665.    end;
  666. end; end;
  667. procedure TForm1.Read101Click(Sender: TObject);
  668. var Leng : DWORD;
  669. begin with Read10Dlg do begin
  670.    if ShowModal = mrOk then begin
  671.       Leng := BufLen.Value;
  672.       Report('Trying: SCSIread10(' + BVal(DPO) + BVal(FUA) + DVal(GLBA)
  673.              + DVal(Sectors) + 'Buf : Pointer, ' + DVal(BufLen),
  674.              CdRom1.SCSIread10(DPO.Checked, FUA.Checked, GLBA.Value,
  675.              Sectors.Value, @IObuf, Leng));
  676.       if (CdRom1.LastError = Err_None) AND (Leng > 0) then begin
  677.          writeln(Log, '     Returned Data Buffer :');
  678.          LogHex(@IObuf, Leng);
  679.       end;
  680.    end;
  681. end; end;
  682. procedure TForm1.ModeSenseRecoverEX1Click(Sender: TObject);
  683. var
  684.    PSAV : boolean;
  685.    RLEV, RETR : byte;
  686. begin with ModeSenseRecoverEXDlg do begin
  687.    if ShowModal = mrOk then begin
  688.       Report('Trying: SCSIModeSenseRecoverEX(PCTL='
  689.          + TCdRomModePageTypeName[TCdRomModePageType(PCTL.ItemIndex)]
  690.          + '; var PSAV : boolean; var RLEV, RETR : byte);',
  691.          CdRom1.SCSIModeSenseRecoverEX(
  692.             TCdRomModePageType(PCTL.ItemIndex), PSAV, RLEV, RETR));
  693.       writeln(Log, '     Returned PSAV = ', PSAV);
  694.       writeln(Log, '     Returned RLEV = ', RLEV, ' decimal');
  695.       writeln(Log, '     Returned RETR = ', RETR, ' decimal');
  696.       flush(Log);
  697.    end;
  698. end; end;
  699. procedure TForm1.ModeSenseMediumEX1Click(Sender: TObject);
  700. var
  701.    PSAV : boolean;
  702.    Med1,Med2,Med3,Med4 : TCdRomMediumType;
  703. begin with ModeSenseMediumEXDlg do begin
  704.    if ShowModal = mrOk then begin
  705.       Report('Trying: SCSIModeSenseMediumEX(PCTL='
  706.          + TCdRomModePageTypeName[TCdRomModePageType(PCTL.ItemIndex)]
  707.          + '; var PSAV : boolean; var Med1,Med2,Med3,Med4 : TCdRomMediumType);',
  708.          CdRom1.SCSIModeSenseMediumEX(
  709.             TCdRomModePageType(PCTL.ItemIndex), PSAV, Med1,Med2,Med3,Med4));
  710.       writeln(Log, '     Returned PSAV = ', PSAV);
  711.       writeln(Log, '     Returned Med1 = ', TCdRomMediumName[Med1]);
  712.       writeln(Log, '     Returned Med2 = ', TCdRomMediumName[Med2]);
  713.       writeln(Log, '     Returned Med3 = ', TCdRomMediumName[Med3]);
  714.       writeln(Log, '     Returned Med4 = ', TCdRomMediumName[Med4]);
  715.       flush(Log);
  716.    end;
  717. end; end;
  718. procedure TForm1.ModeSenseDeviceEX1Click(Sender: TObject);
  719. var
  720.    PSAV : boolean;
  721.    ITimer : byte;
  722.    SperMunits, FperSunits : word;
  723. begin with ModeSenseDeviceEXDlg do begin
  724.    if ShowModal = mrOk then begin
  725.       Report('Trying: SCSIModeSenseDeviceEX(PCTL='
  726.          + TCdRomModePageTypeName[TCdRomModePageType(PCTL.ItemIndex)]
  727.          + '; var ITimer : byte; var SperMunits, FperSunits : word);',
  728.          CdRom1.SCSIModeSenseDeviceEX(
  729.             TCdRomModePageType(PCTL.ItemIndex),
  730.             PSAV, ITimer, SperMunits, FperSunits));
  731.       writeln(Log, '     Returned PSAV = ', PSAV);
  732.       writeln(Log, '     Returned ITimer = ', ITimer, ' decimal');
  733.       writeln(Log, '     Returned SperMunits = ', SperMunits, ' decimal');
  734.       writeln(Log, '     Returned FperSunits = ', FperSunits, ' decimal');
  735.       flush(Log);
  736.    end;
  737. end; end;
  738. procedure TForm1.ModeSenseAudioEX1Click(Sender: TObject);
  739. var APage : TCdRomModePageAudio;
  740. begin with ModeSenseAudioEXDlg do begin
  741.    if ShowModal = mrOk then begin
  742.       Report('Trying: SCSImodeSenseAudioEX(PCTL='
  743.          + TCdRomModePageTypeName[TCdRomModePageType(PCTL.ItemIndex)]
  744.          + '; var sh: TCdRomModePageAudio);',
  745.           CdRom1.SCSImodeSenseAudioEX(
  746.               TCdRomModePageType(PCTL.ItemIndex), APage));
  747.       with APage do begin
  748.          writeln(Log, '     Returned record TCdRomModePageAudio :');
  749.          writeln(Log, '       PSAV = ', PSAV);
  750.          writeln(Log, '       IMM  = ', IMM);
  751.          writeln(Log, '       SOTC = ', SOTC);
  752.          writeln(Log, '       APRV = ', APRV);
  753.          writeln(Log, '       LBAformat = ', LBAformat);
  754.          writeln(Log, '       LBSaudio  = ', LBSaudio);
  755.          writeln(Log, Format('       Volume  = [%2x, %2x, %2x, %2x] hex',
  756.              [Volume[0],  Volume[1],  Volume[2],  Volume[3]]));
  757.          writeln(Log, Format('       Channel = [%2x, %2x, %2x, %2x] hex',
  758.              [Channel[0], Channel[1], Channel[2], Channel[3]]));
  759.          flush(Log);
  760.    end; end;
  761. end; end;
  762. procedure TForm1.TASPI1Click(Sender: TObject);
  763. begin
  764.    writeln(Log, 'TASPIdevice fields :');
  765.    with CdRom1 do begin
  766.       writeln(Log, '   HAcount = ', HAcount);
  767.       writeln(Log, '   Sense[0..', sizeof(Sense)-1, '] in table form:');
  768.       LogHex(@Sense, sizeof(Sense));
  769.       writeln(Log, '   LastError = ', SCSIerrorName[LastError]);
  770.       writeln(Log, '   ShortTimeout  = ', ShortTimeout,  ' mSec');
  771.       writeln(Log, '   MediumTimeout = ', MediumTimeout, ' mSec');
  772.       writeln(Log, '   LongTimeout   = ', LongTimeout,   ' mSec');
  773.       writeln(Log, '   AudioTimeout  = ', AudioTimeout,  ' mSec');
  774.       writeln(Log, '   DeviceID   = ',
  775.           DeviceID.Adapter, ',', DeviceID.Target, ',', DeviceID.Lun);
  776.       writeln(Log, '   DeviceType = ', TScsiDeviceTypeName[DeviceType]);
  777.    end;
  778.    LogDeviceInfo;
  779.    flush(Log);
  780. end;
  781. procedure TForm1.EnumDevices1Click(Sender: TObject);
  782. var
  783.    i  : integer;
  784.    DT : TScsiDeviceType;
  785. begin with EnumDevicesDlg do begin
  786.    if ShowModal = mrOk then begin
  787.       DT := TScsiDeviceType(DType.ItemIndex);
  788.       if DT = TSDInvalid then DT := TSDAny;
  789.       Report('Trying: EnumDevices(DType=' + TScsiDeviceTypeName[DT]
  790.          + '; CBack: TCallBackProc);', TRUE);
  791.       i := CdRom1.EnumDevices(DT, LogNewDevice);
  792.       write(Log, '**** ');
  793.       if i < 2 then begin
  794.          if i = 0 then write(Log, 'No') else write(Log, 'Only');
  795.          writeln(Log, ' one device found.');
  796.       end else writeln(Log, '**** Total ', i, ' devices found.');
  797.       flush(Log);
  798.    end;
  799. end; end;
  800. procedure TForm1.RequestSense1Click(Sender: TObject);
  801. var Leng : integer;
  802. begin
  803.    Leng := SizeOf(TscsiSenseInfo);
  804.    Report(Format('Trying: SCSIrequestSense(Buf : Pointer, BufLen=%d);',
  805.           [Leng]),  CdRom1.SCSIrequestSense(@IObuf, Leng));
  806.    if (CdRom1.LastError = Err_None) AND (Leng > 0) then begin
  807.       writeln(Log, '     Returned Data Buffer :');
  808.       LogHex(@IObuf, Leng);
  809. end; end;
  810. end.