Flirting & love
Now available for free: Free Report Online Profits

ASPI programming in Win32

Feb 10th, 2003: ASPIshim.zip and ASPItesting.zip *updated* ! Jon added some functionalities to the test programs, and added some fixes in the DLL. To download the updated files follow the two links below ("here" and "example"). Thanks Jon !

This section is VisualBasic specific. For general information about ASPI programming please read the ASPI general information first.

Visual Basic programming

by Jon F. Zahornacky

Recommended SCSI hw & books from Amazon

To support ASPI from the Visual Basic environment, it is necessary to use a Wrapper DLL to interface to the WNASPI32.DLL layer.

Even if you declare GetASPI32SupportInfo and SendASPI32Command correctly in the VB IDE, you will get a Bad DLL calling convention when you return from the ASPI call. Reference:

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q153586

The best solution is a Wrapper DLL to conform the VB call to the WNASPI32.DLL. The DLL properly formats the call stack for the VB environment, and makes sure the arguments are correctly passed in to the ASPI layer.

The DLL can go into the VB project directory or the system path. The Visual C Wrapper DLL source code is available here, for you to modify as you see fit. This code is released under LGPL.

To use the wrapper DLL, declare the functions in VB this way:

'*******************************************************************
'** ASPI DLL Declarations - using the ASPIshim.DLL
'*******************************************************************

Private Declare Function GetASPI32SupportInfoEx Lib "ASPIshim" () As Long

Private Declare Function SendASPI32ExecIOEx Lib "ASPIshim" _
            Alias "SendASPI32CommandEx" (hSRB As SRB_ExecuteIO) As Long

You will notice that GetASPI32SupportInfo and SendASPI32Command are alias's to GetASPI32SupportInfoEx and SendASPI32CommandEx in the DLL. This is for clarity mostly, as the name could be the same as the ASPIshim DLL is referenced explicitly.

The following is an example of how to send a command to the ASPI layer:

'*******************************************************************
'** SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2)
'*******************************************************************
Private Type SRB_ExecuteIO
  SRB_Cmd As Byte '00h/00 ASPI command code
  SRB_Status As Byte '01h/01 ASPI command status byte
  SRB_HaID As Byte '02h/02 ASPI host adapter number
  SRB_Flags As Byte '03h/03 ASPI request flags
  SRB_Hdr_Rsvd As Long '04h/04 Reserved, must = 0
  SRB_Target As Byte '08h/08 Target's SCSI ID
  SRB_Lun As Byte 09h/09 Target's LUN number
  SRB_Rsvd1 As Integer '0ah/10 Reserved for alignment
  SRB_BufLen As Long  '0ch/12 Data Allocation Length
  SRB_BufPointer As Long '10h/16 Data Buffer Pointer
  SRB_SenseLen As Byte  '14h/20 Sense Allocation Length
  SRB_CDBLen As Byte '15h/21 CDB Length
  SRB_HaStat As Byte '16h/22 Host Adapter Status
  SRB_TargStat As Byte '17h/23 Target Status
  SRB_PostProc As Long '18h/24 Post routine
  SRB_Rsvd2(19) As Byte '1ch/28 Reserved, must = 0
  SRB_CDBByte(15) As Byte '30h/48 SCSI CDB
  SRB_SenseData(15) As Byte '40h/64 Request Sense buffer
End Type
 
Type TOC_TRACK
  Rsvd1 As Byte
  ADR As Byte
  Track As Byte
  Rsvd2 As Byte
  Addr(3) As Byte
End Type
 
Type TOC
  TocLen(1) As Byte
  FirstTrack As Byte
  LastTrack As Byte
  TocTrack(99) As TOC_TRACK
End Type
 
Const SS_PENDING = &H0 'SRB being processed
Const SS_COMP = &H1 'SRB completed without error
Const SC_EXEC_CMD = &H2 'Execute SCSI command
Const SRB_DIR_IN = &H8  'Transfer from SCSI target to host

'*******************************************************************
'** Send a Read TOC command to CDROM at HA=0, ID=0, LU=0
'*******************************************************************
Private Sub Command1_Click()
 Dim ExecIO As SRB_ExecuteIO
 Dim DataBuffer As TOC

 ExecIO.SRB_Cmd = SC_EXEC_CMD
 ExecIO.SRB_HaID = 0
 ExecIO.SRB_Flags = SRB_DIR_IN
 ExecIO.SRB_Hdr_Rsvd = 0
 ExecIO.SRB_Target = 0
 ExecIO.SRB_Lun = 0
 ExecIO.SRB_SenseLen = 14
 ExecIO.SRB_BufLen = &H324
 ExecIO.SRB_BufPointer = VarPtr(TocBuffer)
 ExecIO.SRB_CDBLen = &HA
 ExecIO.SRB_CDBByte(0) = &H43     'read TOC command
 ExecIO.SRB_CDBByte(1) = &H2       'MSF mode
 ExecIO.SRB_CDBByte(7) = &H3       'high-order byte of buffer len
 ExecIO.SRB_CDBByte(8) = &H24     'low-order byte of buffer len

 nRet = SendASPI32ExecIOEx(ExecIO)
 While ExecIO.SRB_Status = SS_PENDING
   DoEvents
 Wend

 If (ExecIO.SRB_Status <> SS_COMP) Then Debug.Print "Error"
End Sub

Note: More command "Type" defines are included in the sample source code.

Contact Info: Jon F Zahornacky -- jonzeke@yahoo.com

 

Working with SCSI ? This is the book to buy: