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

📄 taspidev.pas

📁 使用ASPI读SCSI/IDE/ATAPI的CDROM数据或音乐磁道数据的程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit TASPIDEV;
// -----------------------------------------------------------------------------
// Project:         CD-ROM and CD-audio Interface Components
// Component Names: TASPIdevice
// Module:          TAspiDev
// Description:     Implements basic-level interface to wnaspi32.dll
//                  and some of fundamental functions for SCSI interface,
//                  that are device-type independent.
// Version:         0.2 early beta
// Date:            25-MAY-1999
// Target:          Win32, Delphi3
// Authors:         Sergey "KSER" Kabikov,   iamkser@hotmail.com
// Copyright        (c) 1999 Sergey Kabikov
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Acknowledgements:
// 1. Thanks to Jay A. Key (scsiprog@geocities.com) for his "akrip" program,
//    which sources (http://www.geocities.com/SiliconValley/Byte/7125/)
//    helps to solve many problems.
// -----------------------------------------------------------------------------

interface
uses Windows;
  const      {=======  Possible values of Direction parameter ========}
   SRB_NODIR   = $00;    // Direction determined by SCSI command
   SRB_DIR_IN  = $08;    // Transfer from SCSI target to host
   SRB_DIR_OUT = $10;    // Transfer from host to SCSI target
type
   TScsiDeviceType = (TSDDisk, TSDTape,  TSDPrinter, TSDProcessor,
                      TSDWORM, TSDCDROM, TSDScanner, TSDOptical,
                      TSDChanger, TSDCommunication, TSDInvalid, TSDAny);
var
   TScsiDeviceTypeName : array[TScsiDeviceType] of string = ('Disk Drive',
      'Tape Drive', 'Printer', 'Processor', 'WORM Drive', 'CD-ROM Drive',
      'Scanner', 'Optical Drive', 'Changer', 'Communication Device',
      'Invalid', 'Any Type Device');
type
   TScsiError =     {======== Errors from SRB_Status field ========}
    (Err_None,               Err_Aborted,            Err_InvalidRequest,
     Err_HAerror,            Err_InvalidHostAdapter, Err_NoDevice,
     Err_InvalidSrb,         Err_BufferAlign,        Err_AspiIsBusy,
     Err_BufferTooBig,       Err_Unknown,
                    {======== Errors from SRB_HaStat field ========}
     Err_CommandTimeout,  { transaction time ran out }
     Err_SrbTimeout,      { while waiting to process }
     Err_MessageReject,
     Err_BusReset,
     Err_ParityError,
     Err_RequestSenseFailed,
     Err_SelectionTimeout,
     Err_DataOverrun,         {... or underrun }
     Err_UnexpectedBusFree,
     Err_BusPhaseSequence,    {... failure }
                    {======== Errors from SRB_TargStat field ========}
     Err_CheckCondition,
     Err_TargetBusy,
     Err_TargetReservationConflict,
     Err_TargetQueueFull,
                    {======== Errors of SendScsiCommand ========}
     Err_InvalidDevice, { Trying to exec SCSI command for non-exist device }
     Err_NoEvent,       { Unable to get event handle for notification      }
     Err_NotifyTimeout, { WaitForSingleObject result was unacceptable      }
                    {======== Errors from SRB_Sense area ========}
     Err_SenseUnknown,     // Unknown SRB_Sense.ErrorCode value
     Err_SenseFileMark,
     Err_SenseEndOfMedia,
     Err_SenseIllegalLength,
     Err_SenseIncorrectLength,
     Err_SenseNoSense,        // There is no sense key info to be reported
     Err_SenseRecoveredError, // Last command completed successfully with
                     // some recovery action performed by the target.
     Err_SenseNotReady,       // Unit addressed cannot be accessed.
                              //  Operator intervention may be required.
     Err_SenseMediumError,    // Command terminated with a non-recovered
                     // error condition that was probably caused by a flaw
                     // in the medium or an error in the recorded data.
     Err_SenseHardwareError,  // Non-recoverable hardware failure detected
     Err_SenseIllegalRequest, // Illegal parameter detected in the command
                    // descriptor block or in the additional parameters.
     Err_SenseUnitAttention,  // Removable medium may have been changed or
                              // the target has been reset.
     Err_SenseDataProtect,    // Read/Write Command was applied to the
                    // block that is protected from this operation.
     Err_SenseBlankCheck,     // Write-once device or a sequential-access
                    // device encountered blank medium or end-of-data
                    // indication while reading or a write-once device
                    // encountered a non-blank medium while writing.
     Err_SenseVendorSpecific,
     Err_SenseCopyAborted,    // COPY, COMPARE, or COPY AND VERIFY command
                    // was aborted due to an error condition on the source
                    // device, the destination device, or both.
     Err_SenseAbortedCommand, // Target aborted the command. Host may be
                    // able to recover by trying the command again.
     Err_SenseEqual,     // SEARCH DATA has satisfied an equal comparison.
     Err_SenseVolumeOverflow, // Buffered peripheral device has reached
                    // the end-of-partition and data may remain in the
                    // buffer that has not been written to the medium.
                    // RECOVER BUFFERED DATA command may be issued to read
                    // the unwritten data from the buffer.
     Err_SenseMiscompare,     // Source data did not match the data read
                              // from the medium.
     Err_SenseReserved
     );
var
   ScsiErrorName : array[TScsiError] of string = ('Err_None',
      'Err_Aborted', 'Err_InvalidRequest', 'Err_HAerror',
      'Err_InvalidHostAdapter', 'Err_NoDevice', 'Err_InvalidSrb',
      'Err_BufferAlign', 'Err_AspiIsBusy', 'Err_BufferTooBig',
      'Err_Unknown', 'Err_CommandTimeout', 'Err_SrbTimeout',
      'Err_MessageReject', 'Err_BusReset', 'Err_ParityError',
      'Err_RequestSenseFailed', 'Err_SelectionTimeout',
      'Err_DataOverrun', 'Err_UnexpectedBusFree',
      'Err_BusPhaseSequence', 'Err_CheckCondition', 'Err_TargetBusy',
      'Err_TargetReservationConflict', 'Err_TargetQueueFull',
      'Err_InvalidDevice', 'Err_NoEvent', 'Err_NotifyTimeout',
      'Err_SenseUnknown', 'Err_SenseFileMark', 'Err_SenseEndOfMedia',
      'Err_SenseIllegalLength', 'Err_SenseIncorrectLength',
      'Err_SenseNoSense', 'Err_SenseRecoveredError',
      'Err_SenseNotReady', 'Err_SenseMediumError', 'Err_SenseHardwareError',
      'Err_SenseIllegalRequest', 'Err_SenseUnitAttention',
      'Err_SenseDataProtect', 'Err_SenseBlankCheck',
      'Err_SenseVendorSpecific', 'Err_SenseCopyAborted',
      'Err_SenseAbortedCommand', 'Err_SenseEqual',
      'Err_SenseVolumeOverflow', 'Err_SenseMiscompare', 'Err_SenseReserved');
type
   TdeviceID  = record  Adapter, Target, Lun : byte;   end;
   TscsiSenseInfo = array[0..127] of BYTE;
   TCallBackProc = procedure;
   TScsiDeviceInfo = packed record
        PeripheralQualifier  : BYTE;
          { 000b = Peripheral device type is currently connected to this
                   logical unit. Especially for hot-swap devices. All fixed
                   devices shall also use this peripheral qualifier.
            001b = The target is capable of supporting the peripheral device;
                   however, the physical device is not currently connected.
            010b = Reserved.
            011b = The target is not capable of supporting a physical device
                   on this logical unit. It's illegal LUN for all commands.
            1XXb = Vendor-specific codes.  }
        DeviceType           : BYTE;
          {  00h = Direct-access device (e.g. magnetic disk)
             01h = Sequential-access device (e.g. magnetic tape)
             02h = Printer device
             03h = Processor device
             04h = Write-once device (e.g. some optical disks)
             05h = CD-ROM device
             06h = Scanner device
             07h = Optical memory device (e.g. some optical disks)
             08h = Medium changer device (e.g. jukeboxes)
             09h = Communications device
             0Ah, 0Bh = Defined by ASC IT8 (Graphic arts pre-press devices)
             0Ch..1Eh = Reserved
             1Fh = Unknown or no device type  }
        DeviceTypeModifier   : BYTE;     { Vendor-specific, in SCSI-I only }
        RemovableMedium      : BOOLEAN;  { defines if medium is removable  }
        ISOversion           : BYTE;     {compliance level to the ISO
              version of SCSI (ISO 9316), 0 means no compliance acclaimed }
        ECMAversion          : BYTE;     {compliance level to the ECMA
              version of SCSI (ECMA-111), 0 means no compliance acclaimed }
        ANSIversion          : BYTE;     {compliance level to the ANSI SCSI:
             0 = The device might or might not comply to an ANSI standard,
             1 = The device complies to ANSI SCSI-1,
             2 = The device complies to ANSI SCSI-2, etc. }
        AsyncEventCapability : BOOLEAN;  {indicates that the device supports
             the asynchronous event notification capability. For Processor
             device-type definition ONLY. Reserved for all other types. }
        TerminateIOcapability: BOOLEAN;  {indicates that the device supports
             the TERMINATE I/O PROCESS message }
        ResponseDataFormat   : BYTE; { indicates the INQUIRY data format is:
             0 = as specified in SCSI-1,
             1 = products that were designed prior to the SCSI-2 (i.e. CCS),
             2 = as specified in SCSI-2,
             3..0Fh = reserved.  }
        AdditionalDataLength : BYTE; { specifies the length in bytes of the
             parameters, i.e. (full_record_length - 4). If the record length
             specified here is too small to transfer all of the parameters,
             this value shall not be adjusted to reflect the truncation. }
        WideBus32capability  : BOOLEAN;  {indicates that the device supports
             32-bit wide data transfers  }
        WideBus16capability  : BOOLEAN;  {indicates that the device supports
             16-bit wide data transfers.  If the values of both the WideBus
             flags are false,the device only supports 8-bit data transfers.}
        RelativeAddressingCapability  : BOOLEAN; { If this flag is set, the
             linked (and ONLY linked) commands may use relative addressing }
        SynchronousTransferCapability : BOOLEAN;  {indicates that the device
             supports synchronous data transfers  }
        LinkedCommandsCapability      : BOOLEAN;  {indicates that the device
             supports execution of linked commands for this logical unit.  }
        CommandQueuingCapability      : BOOLEAN;  {indicates that the device
             supports tagged command queuing for this logical unit.        }
        SoftResetCapability  : BOOLEAN;    { FALSE indicates that the device
             responds to the RESET condition with hard RESET alternative,
             TRUE - that it responds with the soft RESET alternative       }
        VendorID             : string[8];
        ProductID            : string[16];
        ProductRevision      : string[4];
        VendorSpecific       : string[20];
           { All this strings are left-aligned ASCII data fields that shall
             contain only graphic codes (i.e. code values 20h through 7Eh),
             and the unused bytes shall be filled with space characters.   }
   end;
   TScsiHAinfo = packed record
        ScsiId            : BYTE;
        MaxTargetCount    : BYTE;
        ResidualSupport   : BOOLEAN;
        MaxTransferLength : DWORD;
        BufferAlignMask   : WORD;
        ScsiManagerId,
        HostAdapterId     : String[16];
   end;
   TASPIDevice = class      { Common ASPI device class }
      private
        fHAcount      : DWORD;
        fLastError    : TScsiError;
        fSense        : TscsiSenseInfo;
        fShortTimeout   : DWORD;
        fMediumTimeout  : DWORD;
        fLongTimeout    : DWORD;
        fAudioTimeout   : DWORD;
        fDeviceID     : TdeviceID;
        fDeviceType   : TScsiDeviceType;
        fDeviceInfo   : TScsiDeviceInfo;
        fHAinfo       : TScsiHAinfo;
      protected
        function  GetAspiError(Status, HaStat, TargStat : BYTE) : BOOLEAN;
        procedure ChangeDevice(Value : TdeviceID); virtual;
        procedure SetDeviceID(Value : TdeviceID);
      public
        constructor Create(AOwner : TObject);
        destructor  Destroy; override;
          {===================== Raw ASPI functions ===================}
        function    ASPIhaInquiry(HaId : BYTE;
               var sh : TScsiHAinfo) : BOOLEAN;        //True if OK
        function  ASPIgetDeviceType(DeviceAddress : TDeviceID;
               var SDeviceType : TScsiDeviceType)               : BOOLEAN;
        function  ASPIsendScsiCommand(Pcdb : pointer; CdbLen : DWORD;
               Pbuf : pointer; BufLen : DWORD;       // Always works with
               Direction, Timeout: DWORD) : BOOLEAN; //  'current' device
        procedure ASPIabortCommand(HaId : BYTE; Psrb : pointer);
        function  ASPIresetDevice : BOOLEAN;   // Resets 'current' device
        function  ASPIgetDriveInt13info(DeviceAddress : TDeviceID;
               var Support, DosSupport : BOOLEAN;
               var DriveNumber, Heads, Sectors : BYTE) : BOOLEAN;
               // NOTE: This command is NOT VALID under WinNT.
               // Support=false -> no int 13 support anyway
               // else if DosSupport=false -> supported on non-DOS basis
               //  else -> supported under DOS control
          {================== Mid-level ASPI functions ================}
        function ASPIsend6(OpCode : BYTE; Lba : DWORD; Byte4 : BYTE;
               Pbuf : pointer; BufLen, Direction,Timeout: DWORD) : BOOLEAN;
        function ASPIsend10(OpCode : BYTE; Byte1 : BYTE;
               Lba : DWORD; Byte6 : BYTE; Word7 : WORD;
               Pbuf : pointer; BufLen, Direction,Timeout: DWORD) : BOOLEAN;
        function ASPIsend12(OpCode : BYTE; Byte1 : BYTE;
               Lba, TLength : DWORD; Byte10 : BYTE;
               Pbuf : pointer; BufLen, Direction,Timeout: DWORD) : BOOLEAN;
        function  GetDeviceInfo(DId : TdeviceID;
                                var DInfo : TScsiDeviceInfo) : BOOLEAN;
        function  EnumDevices(DType: TScsiDeviceType; CBack: TCallBackProc)
               : integer;   // Returns number of found devices.
                            // Calls CBack() every time when finds one.
        property HAcount      : DWORD      read fHAcount;
        property Sense        : TscsiSenseInfo read fSense;
        property LastError    : TScsiError read fLastError default Err_None;
        property DeviceID     : TdeviceID read fDeviceID  write SetDeviceID;
        property DeviceType   : TScsiDeviceType read fDeviceType;
        property DeviceInfo   : TScsiDeviceInfo read fDeviceInfo;
        property HAinfo       : TScsiHAinfo     read fHAinfo;
      published

⌨️ 快捷键说明

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