unit wnaspi32; {$mode objfpc} interface uses Windows; type LPSRB = Pointer; const { $packrecords c} SENSE_LEN = 14; // Default sense buffer length SRB_DIR_SCSI = $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 SRB_POSTING = $01; // Enable ASPI posting SRB_EVENT_NOTIFY = $40; // Enable ASPI event notification SRB_ENABLE_RESIDUAL_COUNT = $04; // Enable residual byte count reporting SRB_DATA_SG_LIST = $02; // Data buffer points to scatter-gather list WM_ASPIPOST = $4D42; // ASPI Post message { --------------------------------------------------------------------- ASPI Command Definitions ---------------------------------------------------------------------} SC_HA_INQUIRY = $00; // Host adapter inquiry SC_GET_DEV_TYPE = $01; // Get device type SC_EXEC_SCSI_CMD = $02; // Execute SCSI command SC_ABORT_SRB = $03; // Abort an SRB SC_RESET_DEV = $04; // SCSI bus device reset SC_GET_DISK_INFO = $06; // Get Disk information { --------------------------------------------------------------------- SRB Status ---------------------------------------------------------------------} SS_PENDING = $00; // SRB being processed SS_COMP = $01; // SRB completed without error SS_ABORTED = $02; // SRB aborted SS_ABORT_FAIL = $03; // Unable to abort SRB SS_ERR = $04; // SRB completed with error SS_INVALID_CMD = $80; // Invalid ASPI command SS_INVALID_HA = $81; // Invalid host adapter number SS_NO_DEVICE = $82; // SCSI device not installed SS_INVALID_SRB = $E0; // Invalid parameter set in SRB SS_FAILED_INIT = $E4; // ASPI for windows failed init SS_ASPI_IS_BUSY = $E5; // No resources available to execute cmd SS_BUFFER_TO_BIG = $E6; // Buffer size to big to handle! SS_NO_ADAPTERS = $E8; // No adapters. { --------------------------------------------------------------------- Host Adapter Status ---------------------------------------------------------------------} HASTAT_OK = $00; // Host adapter did not detect an // error HASTAT_SEL_TO = $11; // Selection Timeout HASTAT_DO_DU = $12; // Data overrun data underrun HASTAT_BUS_FREE = $13; // Unexpected bus free HASTAT_PHASE_ERR = $14; // Target bus phase sequence // failure HASTAT_TIMEOUT = $09; // Timed out while SRB was waiting to beprocessed. HASTAT_COMMAND_TIMEOUT = $0B; // While processing the SRB, the adapter timed out. HASTAT_MESSAGE_REJECT = $0D; // While processing SRB, the // adapter received a MESSAGE // REJECT. HASTAT_BUS_RESET = $0E; // A bus reset was detected. HASTAT_PARITY_ERROR = $0F; // A parity error was detected. HASTAT_REQUEST_SENSE_FAILED = $10; // The adapter failed in issuing { --------------------------------------------------------------------- SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY ---------------------------------------------------------------------} type SRB_HAInquiry = record SRB_Cmd : Byte; // ASPI command code = SC_HA_INQUIRY SRB_Status : Byte; // ASPI command status byte SRB_HaId : Byte; // ASPI host adapter number SRB_Flags : Byte; // ASPI request flags SRB_Hdr_Rsvd : DWORD; // Reserved, MUST = 0 HA_Count : Byte; // Number of host adapters present HA_SCSI_ID : Byte; // SCSI ID of host adapter HA_ManagerId : array[0..15] of Byte; // String describing the manager HA_Identifier : array[0..15] of Byte; // String describing the host adapter HA_Unique : array[0..15] of Byte; // Host Adapter Unique parameters HA_Rsvd1 : Word; end; PSRB_HAInquiry = ^SRB_HAInquiry; TSRB_HAInquiry = SRB_HAInquiry; { --------------------------------------------------------------------- SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE ---------------------------------------------------------------------} SRB_GDEVBlock = record SRB_Cmd, // ASPI command code = SC_GET_DEV_TYPE SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags : BYTE; // Reserved SRB_Hdr_Rsvd : DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun, // Target's LUN number SRB_DeviceType, // Target's peripheral device type SRB_Rsvd1 : BYTE; end; TSRB_GDEVBlock = SRB_GDEVBlock; PSRB_GDEVBlock = ^SRB_GDEVBlock; { --------------------------------------------------------------------- SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD ---------------------------------------------------------------------} SRB_ExecSCSICmd = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags : BYTE; // ASPI request flags SRB_Hdr_Rsvd : DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun : BYTE; // Target's LUN number SRB_Rsvd1 : WORD; // Reserved for Alignment SRB_BufLen : DWORD; // Data Allocation Length SRB_BufPointer : Pointer; // Data Buffer Pointer SRB_SenseLen, // Sense Allocation Length SRB_CDBLen, // CDB Length SRB_HaStat, // Host Adapter Status SRB_TargStat : BYTE; // Target Status SRB_PostProc, // Post routine SRB_Rsvd2 : Pointer; // Reserved SRB_Rsvd3, // Reserved for alignment CDBByte : array[0..15] of byte; // SCSI CDB SenseArea : array[0..SENSE_LEN + 1] of byte; // Request Sense buffer end; TSRB_ExecSCSICmd = SRB_ExecSCSICmd; PSRB_ExecSCSICmd = ^SRB_ExecSCSICmd; { --------------------------------------------------------------------- SRB - ABORT AN SRB - SC_ABORT_SRB ---------------------------------------------------------------------} SRB_Abort = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags : BYTE; // Reserved SRB_Hdr_Rsvd : DWORD; // Reserved SRB_ToAbort : Pointer; // Pointer to SRB to abort end; TSRB_Abort = SRB_Abort; PSRB_Abort = ^SRB_Abort; { --------------------------------------------------------------------- SRB - BUS DEVICE RESET - SC_RESET_DEV ---------------------------------------------------------------------} SRB_BusDeviceReset = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags : BYTE; // Reserved SRB_Hdr_Rsvd : DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun : BYTE; // Target's LUN number SRB_Rsvd1 : array[0..11] of byte; // Reserved for Alignment SRB_HaStat, // Host Adapter Status SRB_TargStat : BYTE; // Target Status SRB_PostProc, // Post routine SRB_Rsvd2 : Pointer; // Reserved SRB_Rsvd3, // Reserved CDBByte : array[0..15] of byte; // SCSI CDB end; TSRB_BusDeviceReset = SRB_BusDeviceReset; PSRB_BusDeviceReset = ^SRB_BusDeviceReset; { --------------------------------------------------------------------- SRB - GET DISK INFORMATION - SC_GET_DISK_INFO ---------------------------------------------------------------------} SRB_GetDiskInfo = record SRB_Cmd, // ASPI command code = SC_EXEC_SCSI_CMD SRB_Status, // ASPI command status byte SRB_HaId, // ASPI host adapter number SRB_Flags : BYTE; // Reserved SRB_Hdr_Rsvd : DWORD; // Reserved SRB_Target, // Target's SCSI ID SRB_Lun, // Target's LUN number SRB_DriveFlags, // Driver flags SRB_Int13HDriveInfo, // Host Adapter Status SRB_Heads, // Preferred number of heads translation SRB_Sectors : BYTE; // Preferred number of sectors translation SRB_Rsvd1 : array[0..9] of byte; // Reserved end; TSRB_GetDiskInfo = SRB_GetDiskInfo; PSRB_GetDiskInfo = ^SRB_GetDiskInfo; type TSendASPI32Command = function( LPSRB : Pointer ) : DWORD; cdecl; TGetASPI32SupportInfo = function : DWORD; cdecl; Const SendASPI32Command : TSendASPI32Command = nil; GetASPI32SupportInfo : TGetASPI32SupportInfo = nil; Function ASPILoaded : Boolean; Procedure CheckASPI; procedure UnloadASPI; implementation uses dynlibs; const HWNASPI : TLibHandle = 0; WNASPI = 'wnaspi32.dll'; Function ASPILoaded : Boolean; begin Result:=HWNASPI<>0; end; Procedure CheckASPI; begin HWNASPI:=LoadLibrary(WNASPI); if (HWNASPI<>0) then begin SendASPI32Command:=TSendASPI32Command(GetProcAddress(HWNASPI,'SendASPI32Command')); GetASPI32SupportInfo:=TGetASPI32SupportInfo(GetProcAddress(HWNASPI,'GetASPI32SupportInfo')); end end; procedure UnloadASPI; begin if (HWNASPI<>0) then begin FreeLibrary(HWNASPI); HWNASPI:=TLibHandle(0); SendASPI32Command:=nil; GetASPI32SupportInfo:=nil; end; end; initialization CheckAspi; finalization UnloadASPI; end.