📄 clsaspi.cls
字号:
Dim haid As t_HAID
Dim i As Long
'go through all 26 possible drives
For i = 1 To 26
'CD-ROM?
If GetDriveType(Chr(i + 64) & ":") = 5 Then
'compare to the parameters
If NTGetHAID(Chr$(i + 64), haid) Then
If haid.HA = HA And _
haid.ID = ID And _
haid.LUN = LUN Then
'found it!
DriveCharWinNT = Chr$(i + 64)
End If
End If
End If
Next
End Function
Private Function NTGetHAID(ByVal strDrv As String, ByRef haid As t_HAID) As Boolean
Dim returned As Long, Status As Long
Dim fh As Long, i As Long
Dim pscsiAddr As t_SCSI_ADDRESS
'get drive handle
If GetDriveHandle(Left$(strDrv, 1), fh) Then
'get SCSI address
pscsiAddr.Length = Len(pscsiAddr)
Status = DeviceIoControl(fh, IOCTL_SCSI_GET_ADDRESS, _
pscsiAddr, Len(pscsiAddr), _
pscsiAddr, Len(pscsiAddr), _
returned, ByVal 0&)
CloseHandle fh
'success?
If Status = 1 Then
With pscsiAddr
haid.HA = .PortNumber
haid.ID = .TargetID
haid.LUN = .LUN
NTGetHAID = True
Exit Function
End With
End If
End If
End Function
Private Sub FindDrives()
Dim HACnt As Integer
Dim IDCnt As Integer
Dim LUNCnt As Integer
Dim HAInq As SRB_HAInquiry
Dim DevTyp As SRB_GetDevType
' Host Adapters
HACnt = LoByte(LoWord(ASPILib.CallFunc(FNC_INFO)))
For HACnt = 0 To HACnt
For IDCnt = 0 To 7
For LUNCnt = 0 To 7
ZeroMemory DevTyp, LenB(DevTyp)
DevTyp.SRB_Hdr.SRB_Cmd = SC_GET_DEV_TYPE
DevTyp.SRB_Hdr.SRB_HAID = HACnt
DevTyp.SRB_Target = IDCnt
DevTyp.SRB_LUN = LUNCnt
SRBGetDev DevTyp
If DevTyp.SRB_Hdr.SRB_Status = SS_COMP Then
Debug.Print "ASPI: found device (" & DevTyp.DEV_DeviceType & ")", _
" HA: " & HACnt & " " & _
" ID: " & IDCnt & " " & _
" LUN: " & LUNCnt
If DevTyp.DEV_DeviceType = DTYPE_CDROM Then
colDrives.Add Chr$(HACnt) & Chr$(IDCnt) & Chr$(LUNCnt)
End If
End If
Next
Next
Next
End Sub
Private Property Get Iscsi_DriveChar(handle As String) As Variant
Dim btHA As Byte
Dim btID As Byte
Dim btLUN As Byte
btHA = Asc(Mid$(handle, 1, 1))
btID = Asc(Mid$(handle, 2, 1))
btLUN = Asc(Mid$(handle, 3, 1))
If IsNT Then
Iscsi_DriveChar = DriveCharWinNT(btHA, btID, btLUN)
Else
Iscsi_DriveChar = DriveCharWin9x(btHA, btID, btLUN)
End If
End Property
Private Property Get ISCSI_DriveCount() As Integer
ISCSI_DriveCount = colDrives.Count
End Property
Private Property Get ISCSI_DriveHandle(index As Integer) As String
ISCSI_DriveHandle = colDrives.Item(index)
End Property
Private Function ISCSI_ExecCMD(ByVal drive As String, _
cdb() As Byte, _
CDBLen As Byte, _
direction As DataDirection, _
ByVal buffer As Long, _
ByVal bufferlen As Long, _
Optional timeout As Integer = 5) As Status
Dim SRB_Exec As SRB_ExecuteIO
Dim SRB_Timeout As SRB_GetSetTimeouts
Dim blnTimeout As Boolean
Dim hEvent As Long
Dim lngRet As Long
Dim btHA As Byte
Dim btID As Byte
Dim btLUN As Byte
' Bus Address
btHA = Asc(Mid$(drive, 1, 1))
btID = Asc(Mid$(drive, 2, 1))
btLUN = Asc(Mid$(drive, 3, 1))
' Event for scsi status
hEvent = CreateEvent(0, 1, 0, 0)
ResetEvent hEvent
With SRB_Exec
.SRB_Hdr.SRB_Cmd = SC_EXEC_SCSI_CMD
.SRB_PostProc = hEvent
.SRB_Hdr.SRB_HAID = btHA
.SRB_Target = btID
.SRB_LUN = btLUN
.SRB_BufPointer = buffer
.SRB_BufLen = bufferlen
.SRB_SenseLen = SENSE_LEN
If direction = DIR_IN Then
.SRB_Hdr.SRB_Flags = SRB_DIR_IN
Else
.SRB_Hdr.SRB_Flags = SRB_DIR_OUT
End If
.SRB_CDBLen = CDBLen
CopyMemory .SRB_CDBByte(0), cdb(0), CDBLen
End With
SRBExec SRB_Exec
If Not blnTimeout Then
' wait for ever?
If timeout = 0 Then
Do While SRB_Exec.SRB_Hdr.SRB_Status = SS_PENDING
DoEvents
Loop
Else
' wait for a specific amount of time for completion
Sleep 30
If SRB_Exec.SRB_Hdr.SRB_Status = SS_PENDING Then
lngRet = WaitForSingleObject(hEvent, timeout * 1000)
End If
End If
Else
Do While SRB_Exec.SRB_Hdr.SRB_Status = SS_PENDING
DoEvents
Loop
End If
If blnTimeout Then
If SRB_Exec.SRB_Hdr.SRB_Status = SS_ABORTED Then
ISCSI_ExecCMD = STATUS_TIMEOUT
Else
ISCSI_ExecCMD = SRB_Exec.SRB_TargStat
End If
Else
If lngRet = WAIT_TIMEOUT And SRB_Exec.SRB_Hdr.SRB_Status <> SS_COMP Then
ISCSI_ExecCMD = STATUS_TIMEOUT
Else
ISCSI_ExecCMD = SRB_Exec.SRB_TargStat
End If
End If
btLastSK = SRB_Exec.SRB_SenseData(2) And &HF
btLastASC = SRB_Exec.SRB_SenseData(12)
btLastASCQ = SRB_Exec.SRB_SenseData(13)
CloseHandle hEvent
End Function
Private Function SRBInq(udt As SRB_HAInquiry) As Long
SRBInq = ASPILib.CallFunc(FNC_CMD, VarPtr(udt))
End Function
Private Function SRBGetDev(udt As SRB_GetDevType) As Long
SRBGetDev = ASPILib.CallFunc(FNC_CMD, VarPtr(udt))
End Function
Private Function SRBDiskInfo(udt As SRB_GetDiskInfo) As Long
SRBDiskInfo = ASPILib.CallFunc(FNC_CMD, VarPtr(udt))
End Function
Private Function SRBExec(udt As SRB_ExecuteIO) As Long
SRBExec = ASPILib.CallFunc(FNC_CMD, VarPtr(udt))
End Function
Private Function SRBSetTimeout(udt As SRB_GetSetTimeouts) As Long
SRBSetTimeout = ASPILib.CallFunc(FNC_CMD, VarPtr(udt))
End Function
Private Property Get ISCSI_HostAdapter(handle As String) As Byte
ISCSI_HostAdapter = Asc(Mid$(handle, 1, 1))
End Property
Private Property Get ISCSI_Initialized() As Boolean
ISCSI_Initialized = HiByte(LoWord(ASPILib.CallFunc(FNC_INFO))) = SS_COMP
End Property
Private Property Get ISCSI_Installed() As Boolean
ISCSI_Installed = blnASPIInst
End Property
Private Sub Class_Initialize()
Set ASPILib = New clsCDECL
Set colDrives = New Collection
blnASPIInst = ASPILib.DllLoad("WNASPI32.DLL")
FindDrives
End Sub
Private Sub Class_Terminate()
ASPILib.DllUnload
End Sub
Private Function IsW2K() As Boolean
Dim sys As OSVERSIONINFOEX
sys.dwOSVersionInfoSize = Len(sys)
GetVersionEx sys
If sys.dwPlatformId = VER_PLATFORM_WIN32_NT Then
IsW2K = sys.dwMajorVersion >= 5
End If
End Function
Private Function IsNT() As Boolean
Dim sys As OSVERSIONINFOEX
sys.dwOSVersionInfoSize = Len(sys)
GetVersionEx sys
IsNT = sys.dwPlatformId = VER_PLATFORM_WIN32_NT
End Function
Private Function LoWord(ByVal DWord As Long) As Long
LoWord = DWord And &HFFFF&
End Function
Private Function HiWord(ByVal DWord As Long) As Long
HiWord = (DWord And &HFFFF0000) \ &H10000
End Function
Private Function LoByte(ByRef Word As Integer) As Byte
LoByte = Word And &HFF
End Function
Private Function HiByte(ByRef Word As Integer) As Byte
HiByte = (Word And &HFF00&) \ &H100
End Function
Private Property Get ISCSI_Interface() As String
ISCSI_Interface = "ASPI"
End Property
Private Property Get ISCSI_LastASC() As Byte
ISCSI_LastASC = btLastASC
End Property
Private Property Get ISCSI_LastASCQ() As Byte
ISCSI_LastASCQ = btLastASCQ
End Property
Private Property Get ISCSI_LastSK() As Byte
ISCSI_LastSK = btLastSK
End Property
Private Property Get ISCSI_LUN(handle As String) As Byte
ISCSI_LUN = Asc(Mid$(handle, 3, 1))
End Property
Private Property Get ISCSI_TargetID(handle As String) As Byte
ISCSI_TargetID = Asc(Mid$(handle, 2, 1))
End Property
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -