home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / Data_CD_Wr2028081112006.psc / Burn / clsSPTI.cls < prev    next >
Text File  |  2006-10-26  |  13KB  |  420 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "clsSPTI"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. Private Declare Function DeviceIoControl Lib "kernel32" ( _
  17.     ByVal hDevice As Long, _
  18.     ByVal dwIoControlCode As Long, _
  19.     ByRef lpInBuffer As Any, _
  20.     ByVal nInBufferSize As Long, _
  21.     ByRef lpOutBuffer As Any, _
  22.     ByVal nOutBufferSize As Long, _
  23.     ByRef lpBytesReturned As Long, _
  24.     lpOverlapped As Any _
  25. ) As Long
  26.  
  27. Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _
  28.     ByVal lpFileName As String, _
  29.     ByVal dwDesiredAccess As Long, _
  30.     ByVal dwShareMode As Long, _
  31.     ByVal lpSecurityAttributes As Long, _
  32.     ByVal dwCreationDisposition As Long, _
  33.     ByVal dwFlagsAndAttributes As Long, _
  34.     ByVal hTemplateFile As Long _
  35. ) As Long
  36.  
  37. Private Declare Function CloseHandle Lib "kernel32" ( _
  38.     ByVal hObject As Long _
  39. ) As Long
  40.  
  41. Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" ( _
  42.     ByVal nDrive As String _
  43. ) As Long
  44.  
  45. Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" ( _
  46.     lpVersionInformation As OSVERSIONINFOEX _
  47. ) As Long
  48.  
  49. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
  50.     Destination As Any, _
  51.     source As Any, _
  52.     ByVal Length As Long _
  53. )
  54.  
  55. Private Type SCSI_ADDRESS
  56.     Length                          As Long
  57.     PortNumber                      As Byte
  58.     PathId                          As Byte
  59.     TargetID                        As Byte
  60.     LUN                             As Byte
  61. End Type
  62.  
  63. Private Type OSVERSIONINFOEX
  64.     dwOSVersionInfoSize             As Long
  65.     dwMajorVersion                  As Long
  66.     dwMinorVersion                  As Long
  67.     dwBuildNumber                   As Long
  68.     dwPlatformId                    As Long
  69.     szCSDVersion                    As String * 128
  70. End Type
  71.  
  72. Private Type SPTD
  73.     Length                          As Integer
  74.     ScsiStatus                      As Byte
  75.     PathId                          As Byte
  76.     TargetID                        As Byte
  77.     LUN                             As Byte
  78.     CdbLength                       As Byte
  79.     SenseInfoLength                 As Byte
  80.     DataIn                          As Byte
  81.     DataTransferLength              As Long
  82.     TimeOutValue                    As Long
  83.     DataBuffer                      As Long
  84.     SenseInfoOffset                 As Long
  85.     cdb(15)                         As Byte
  86.     Fill(2)                         As Byte
  87. End Type
  88.  
  89. Private Type SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
  90.     SPT                             As SPTD
  91.     'Fill(3)                         As Byte
  92.     SenseBuffer(35)                 As Byte
  93. End Type
  94.  
  95. Private Enum SPTIDirection
  96.     SCSI_IOCTL_DATA_OUT = 0
  97.     SCSI_IOCTL_DATA_IN = 1
  98.     SCSI_IOCTL_DATA_UNSPECIFIED = 2
  99. End Enum
  100.  
  101. Private Const IOCTL_SCSI_BASE       As Long = &H4
  102.  
  103. Private Const METHOD_BUFFERED       As Long = &H0
  104. Private Const METHOD_IN_DIRECT      As Long = &H1
  105. Private Const METHOD_OUT_DIRECT     As Long = &H2
  106. Private Const METHOD_NEITHER        As Long = &H3
  107.  
  108. Private Const FILE_ANY_ACCESS       As Long = &H0
  109. Private Const FILE_READ_ACCESS      As Long = &H1
  110. Private Const FILE_WRITE_ACCESS     As Long = &H2
  111.  
  112. Private Const INVALID_HANDLE_VALUE  As Long = -1
  113. Private Const OPEN_EXISTING         As Long = &H3
  114. Private Const GENERIC_READ          As Long = &H80000000
  115. Private Const GENERIC_WRITE         As Long = &H40000000
  116. Private Const FILE_SHARE_READ       As Long = &H1
  117. Private Const FILE_SHARE_WRITE      As Long = &H2
  118. Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80
  119.  
  120. Private Const VER_PLATFORM_WIN32_NT As Long = &H2
  121.  
  122. Private IOCTL_SCSI_PASS_THROUGH_DIRECT As Long
  123. Private IOCTL_SCSI_GET_ADDRESS         As Long
  124.  
  125. Private Const DTYPE_CDROM           As Long = 5
  126.  
  127. Private colDrives                   As Collection
  128.  
  129. Private blnW2K                      As Boolean
  130.  
  131. Private lngPower2(31)               As Long
  132. Private lngHandles(25)              As Long
  133.  
  134. Private btLastSK                    As Byte
  135. Private btLastASC                   As Byte
  136. Private btLastASCQ                  As Byte
  137.  
  138. Implements ISCSI
  139.  
  140. Private Sub FindDrives()
  141.     Dim i           As Integer
  142.     Dim strDrive    As String
  143.  
  144.     For i = 1 To 26
  145.         strDrive = Chr$(i + 64)
  146.         If GetDriveType(strDrive & ":") = DTYPE_CDROM Then
  147.             colDrives.Add strDrive
  148.         End If
  149.     Next
  150. End Sub
  151.  
  152. Private Function IsW2K() As Boolean
  153.     Dim sys As OSVERSIONINFOEX
  154.  
  155.     sys.dwOSVersionInfoSize = Len(sys)
  156.     GetVersionEx sys
  157.  
  158.     If sys.dwPlatformId = VER_PLATFORM_WIN32_NT Then
  159.         IsW2K = sys.dwMajorVersion >= 5
  160.     End If
  161. End Function
  162.  
  163. Private Function GetDriveHandle(ByVal drv As String, ByRef fh As Long) As Boolean
  164.     Static Init As Boolean
  165.     Dim flags   As Long
  166.     Dim i       As Integer
  167.  
  168.     ' Already opened all CD/DVD-ROM devices?
  169.     If Not Init Then
  170.  
  171.         ' open all devices for performance
  172.  
  173.         ' on Windows 2000 and higher you need the
  174.         ' GENERIC_WRITE flag as well
  175.         flags = GENERIC_READ
  176.         If IsW2K Then flags = flags Or GENERIC_WRITE
  177.  
  178.         For i = 1 To 26
  179.  
  180.             If GetDriveType(Chr$(i + 64) & ":") = DTYPE_CDROM Then
  181.                     ' \\.\X: for devices
  182.                     fh = CreateFile("\\.\" & Chr$(i + 64) & ":", flags, _
  183.                                     FILE_SHARE_READ Or FILE_SHARE_WRITE, ByVal 0&, _
  184.                                     OPEN_EXISTING, 0, 0)
  185.  
  186.                     lngHandles(i - 1) = fh
  187.  
  188.             Else
  189.                 lngHandles(i - 1) = -1
  190.             End If
  191.  
  192.         Next
  193.         Init = True
  194.     End If
  195.  
  196.     fh = lngHandles(Asc(UCase$(drv)) - 65)
  197.     GetDriveHandle = fh <> -1
  198. End Function
  199.  
  200. Private Function CTL_CODE(ByVal lDevType As Long, _
  201.                           ByVal lFunction As Long, _
  202.                           ByVal lMethod As Long, _
  203.                           ByVal lAccess As Long) As Long
  204.  
  205.     CTL_CODE = LShift(lDevType, 16) Or _
  206.                LShift(lAccess, 14) Or _
  207.                LShift(lFunction, 2) Or _
  208.                lMethod
  209. End Function
  210.  
  211. ' >> Operator
  212. ' from VB-Accelerator
  213. Private Function RShift(ByVal lThis As Long, ByVal lBits As Long) As Long
  214.  
  215.     Static Init As Boolean
  216.  
  217.     If Not Init Then InitShifting: Init = True
  218.  
  219.     If (lBits <= 0) Then
  220.         RShift = lThis
  221.     ElseIf (lBits > 63) Then
  222.         Exit Function
  223.     ElseIf (lBits > 31) Then
  224.         RShift = 0
  225.     Else
  226.         If (lThis And lngPower2(31)) = lngPower2(31) Then
  227.             RShift = (lThis And &H7FFFFFFF) \ lngPower2(lBits) Or lngPower2(31 - lBits)
  228.         Else
  229.             RShift = lThis \ lngPower2(lBits)
  230.         End If
  231.     End If
  232.  
  233. End Function
  234.  
  235. ' << Operator
  236. ' from VB-Accelerator
  237. Private Function LShift(ByVal lThis As Long, ByVal lBits As Long) As Long
  238.  
  239.     Static Init As Boolean
  240.  
  241.     If Not Init Then InitShifting: Init = True
  242.  
  243.     If (lBits <= 0) Then
  244.         LShift = lThis
  245.     ElseIf (lBits > 63) Then
  246.         Exit Function
  247.     ElseIf (lBits > 31) Then
  248.         LShift = 0
  249.     Else
  250.         If (lThis And lngPower2(31 - lBits)) = lngPower2(31 - lBits) Then
  251.             LShift = (lThis And (lngPower2(31 - lBits) - 1)) * lngPower2(lBits) Or lngPower2(31)
  252.         Else
  253.             LShift = (lThis And (lngPower2(31 - lBits) - 1)) * lngPower2(lBits)
  254.         End If
  255.     End If
  256.  
  257. End Function
  258.  
  259. ' powers of 2
  260. Private Sub InitShifting()
  261.     Dim i   As Long
  262.     For i = 0 To 30: lngPower2(i) = 2& ^ i: Next
  263.     lngPower2(31) = &H80000000
  264. End Sub
  265.  
  266. Private Sub Class_Initialize()
  267.     Set colDrives = New Collection
  268.  
  269.     FindDrives
  270.  
  271.     'SPTD Control Code
  272.     IOCTL_SCSI_PASS_THROUGH_DIRECT = CTL_CODE(IOCTL_SCSI_BASE, _
  273.                                               &H405, _
  274.                                               METHOD_BUFFERED, _
  275.                                               FILE_READ_ACCESS Or _
  276.                                               FILE_WRITE_ACCESS)
  277.  
  278.     'SGA Control Code
  279.     IOCTL_SCSI_GET_ADDRESS = CTL_CODE(IOCTL_SCSI_BASE, _
  280.                                       &H406, _
  281.                                       METHOD_BUFFERED, _
  282.                                       FILE_ANY_ACCESS)
  283. End Sub
  284.  
  285. Private Sub Class_Terminate()
  286.     Dim i   As Long
  287.     For i = 0 To 25: CloseHandle lngHandles(i): Next
  288. End Sub
  289.  
  290. Private Property Get Iscsi_DriveChar(handle As String) As Variant
  291.     Iscsi_DriveChar = handle
  292. End Property
  293.  
  294. Private Property Get ISCSI_DriveCount() As Integer
  295.     ISCSI_DriveCount = colDrives.Count
  296. End Property
  297.  
  298. Private Property Get ISCSI_DriveHandle(index As Integer) As String
  299.     ISCSI_DriveHandle = colDrives(index)
  300. End Property
  301.  
  302. 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
  303.     Dim lngHandle   As Long
  304.     Dim BytesRet    As Long
  305.     Dim lngStatus   As Long
  306.     Dim SPT         As SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER
  307.  
  308.     If Not GetDriveHandle(drive, lngHandle) Then
  309.         ISCSI_ExecCMD = STATUS_RESERV_CONF
  310.         Exit Function
  311.     End If
  312.  
  313.     ' Wait For Ever = 1 hour
  314.     If timeout = 0 Then timeout = 3600000
  315.  
  316.     With SPT.SPT
  317.         .Length = Len(SPT.SPT)
  318.         .TimeOutValue = timeout
  319.  
  320.         .SenseInfoLength = UBound(SPT.SenseBuffer) - 4
  321.         .SenseInfoOffset = Len(SPT.SPT) + 4
  322.  
  323.         If direction = DIR_IN Then
  324.             .DataIn = SCSI_IOCTL_DATA_IN
  325.         Else
  326.             .DataIn = SCSI_IOCTL_DATA_OUT
  327.         End If
  328.  
  329.         CopyMemory .cdb(0), cdb(0), CDBLen
  330.         .CdbLength = CDBLen
  331.  
  332.         .DataBuffer = buffer
  333.         .DataTransferLength = bufferlen
  334.     End With
  335.  
  336.     lngStatus = DeviceIoControl(lngHandle, IOCTL_SCSI_PASS_THROUGH_DIRECT, _
  337.                                 SPT, Len(SPT), SPT, Len(SPT), _
  338.                                 BytesRet, ByVal 0&)
  339.  
  340.     If lngStatus <> 1 Then
  341.         ' probably wrong most of the time
  342.         ISCSI_ExecCMD = STATUS_TIMEOUT
  343.     Else
  344.         ISCSI_ExecCMD = SPT.SPT.ScsiStatus
  345.     End If
  346.  
  347.     btLastSK = SPT.SenseBuffer(2)
  348.     btLastASC = SPT.SenseBuffer(12)
  349.     btLastASCQ = SPT.SenseBuffer(13)
  350. End Function
  351.  
  352. Private Property Get ISCSI_HostAdapter(handle As String) As Byte
  353.     Dim lngHandle   As Long
  354.     Dim addr        As SCSI_ADDRESS
  355.     Dim dwRead      As Long
  356.  
  357.     addr.Length = Len(addr)
  358.  
  359.     If GetDriveHandle(handle, lngHandle) Then
  360.         If DeviceIoControl(lngHandle, IOCTL_SCSI_GET_ADDRESS, addr, Len(addr), addr, Len(addr), dwRead, ByVal 0&) = 1 Then
  361.             ISCSI_HostAdapter = addr.PortNumber
  362.         End If
  363.     End If
  364. End Property
  365.  
  366. Private Property Get ISCSI_Initialized() As Boolean
  367.     ISCSI_Initialized = True
  368. End Property
  369.  
  370. Private Property Get ISCSI_Installed() As Boolean
  371.     Dim DrvID   As String
  372.     Dim handle  As Long
  373.     DrvID = ISCSI_DriveHandle(1)
  374.     ISCSI_Installed = GetDriveHandle(DrvID, handle)
  375. End Property
  376.  
  377. Private Property Get ISCSI_Interface() As String
  378.     ISCSI_Interface = "SPTI"
  379. End Property
  380.  
  381. Private Property Get ISCSI_LastASC() As Byte
  382.     ISCSI_LastASC = btLastASC
  383. End Property
  384.  
  385. Private Property Get ISCSI_LastASCQ() As Byte
  386.     ISCSI_LastASCQ = btLastASCQ
  387. End Property
  388.  
  389. Private Property Get ISCSI_LastSK() As Byte
  390.     ISCSI_LastSK = btLastSK
  391. End Property
  392.  
  393. Private Property Get ISCSI_LUN(handle As String) As Byte
  394.     Dim lngHandle   As Long
  395.     Dim addr        As SCSI_ADDRESS
  396.     Dim dwRead      As Long
  397.  
  398.     addr.Length = Len(addr)
  399.  
  400.     If GetDriveHandle(handle, lngHandle) Then
  401.         If DeviceIoControl(lngHandle, IOCTL_SCSI_GET_ADDRESS, addr, Len(addr), addr, Len(addr), dwRead, ByVal 0&) = 1 Then
  402.             ISCSI_LUN = addr.LUN
  403.         End If
  404.     End If
  405. End Property
  406.  
  407. Private Property Get ISCSI_TargetID(handle As String) As Byte
  408.     Dim lngHandle   As Long
  409.     Dim addr        As SCSI_ADDRESS
  410.     Dim dwRead      As Long
  411.  
  412.     addr.Length = Len(addr)
  413.  
  414.     If GetDriveHandle(handle, lngHandle) Then
  415.         If DeviceIoControl(lngHandle, IOCTL_SCSI_GET_ADDRESS, addr, Len(addr), addr, Len(addr), dwRead, ByVal 0&) = 1 Then
  416.             ISCSI_TargetID = addr.TargetID
  417.         End If
  418.     End If
  419. End Property
  420.