Private Function GetDriveInfo(drvNumber As IDE_DRIVE_NUMBER) As DRIVE_INFO
Dim hDrive As Long
Dim di As DRIVE_INFO
hDrive = SmartOpen(drvNumber)
If hDrive <> INVALID_HANDLE_VALUE Then
If SmartGetVersion(hDrive) = True Then
With di
.bDriveType = 0
.NumAttributes = 0
ReDim .Attributes(0)
.bDriveType = 1
End With
If SmartCheckEnabled(hDrive, drvNumber) Then
If IdentifyDrive(hDrive, IDE_ID_FUNCTION, drvNumber, di) = True Then
GetDriveInfo = di
End If 'IdentifyDrive
End If 'SmartCheckEnabled
End If 'SmartGetVersion
End If 'hDrive <> INVALID_HANDLE_VALUE
CloseHandle hDrive
End Function
Private Function IdentifyDrive(ByVal hDrive As Long, _
ByVal IDCmd As Byte, _
ByVal drvNumber As IDE_DRIVE_NUMBER, _
di As DRIVE_INFO) As Boolean
'Function: Send an IDENTIFY command to the drive
'drvNumber = 0-3
'IDCmd = IDE_ID_FUNCTION or IDE_ATAPI_ID
Dim SCIP As SENDCMDINPARAMS
Dim IDSEC As IDSECTOR
Dim bArrOut(OUTPUT_DATA_SIZE - 1) As Byte
Dim cbBytesReturned As Long
With SCIP
.cBufferSize = IDENTIFY_BUFFER_SIZE
.bDriveNumber = CByte(drvNumber)
With .irDriveRegs
.bFeaturesReg = 0
.bSectorCountReg = 1
.bSectorNumberReg = 1
.bCylLowReg = 0
.bCylHighReg = 0
.bDriveHeadReg = &HA0 'compute the drive number
If Not IsWinNT4Plus Then
.bDriveHeadReg = .bDriveHeadReg Or ((drvNumber And 1) * 16)
End If
'the command can either be IDE
'identify or ATAPI identify.
.bCommandReg = CByte(IDCmd)
End With
End With
If DeviceIoControl(hDrive, _
DFP_RECEIVE_DRIVE_DATA, _
SCIP, _
Len(SCIP) - 4, _
bArrOut(0), _
OUTPUT_DATA_SIZE, _
cbBytesReturned, _
ByVal 0&) Then
CopyMemory IDSEC, bArrOut(16), Len(IDSEC)
di.Model = StrConv(SwapBytes(IDSEC.sModelNumber), vbUnicode)
di.SerialNumber = StrConv(SwapBytes(IDSEC.sSerialNumber), vbUnicode)
IdentifyDrive = True
End If
End Function
Private Function IsWinNT4Plus() As Boolean
'returns True if running Windows NT4 or later
Dim osv As OSVERSIONINFO
osv.OSVSize = Len(osv)
If GetVersionEx(osv) = 1 Then
IsWinNT4Plus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _
(osv.dwVerMajor >= 4)
End If
End Function
Private Function SmartCheckEnabled(ByVal hDrive As Long, _
drvNumber As IDE_DRIVE_NUMBER) As Boolean
'SmartCheckEnabled - Check if SMART enable
'FUNCTION: Send a SMART_ENABLE_SMART_OPERATIONS command to the drive
'bDriveNum = 0-3
Dim SCIP As SENDCMDINPARAMS
Dim SCOP As SENDCMDOUTPARAMS
Dim cbBytesReturned As Long
With SCIP
.cBufferSize = 0
With .irDriveRegs
.bFeaturesReg = SMART_ENABLE_SMART_OPERATIONS
.bSectorCountReg = 1
.bSectorNumberReg = 1
.bCylLowReg = SMART_CYL_LOW
.bCylHighReg = SMART_CYL_HI
.bDriveHeadReg = &HA0
If Not IsWinNT4Plus Then
.bDriveHeadReg = .bDriveHeadReg Or ((drvNumber And 1) * 16)
End If
.bCommandReg = IDE_EXECUTE_SMART_FUNCTION
End With
.bDriveNumber = drvNumber
End With
SmartCheckEnabled = DeviceIoControl(hDrive, _
DFP_SEND_DRIVE_COMMAND, _
SCIP, _
Len(SCIP) - 4, _
SCOP, _
Len(SCOP) - 4, _
cbBytesReturned, _
ByVal 0&)
End Function
Private Function SmartGetVersion(ByVal hDrive As Long) As Boolean
Dim cbBytesReturned As Long
Dim GVOP As GETVERSIONOUTPARAMS
SmartGetVersion = DeviceIoControl(hDrive, _
DFP_GET_VERSION, _
ByVal 0&, 0, _
GVOP, _
Len(GVOP), _
cbBytesReturned, _
ByVal 0&)
End Function
Private Function SmartOpen(drvNumber As IDE_DRIVE_NUMBER) As Long
'Open SMART to allow DeviceIoControl
'communications and return SMART handle
If IsWinNT4Plus() Then
SmartOpen = CreateFile("\\.\PhysicalDrive" & CStr(drvNumber), _
GENERIC_READ Or GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
ByVal 0&, _
OPEN_EXISTING, _
0&, _
0&)
Else
SmartOpen = CreateFile("\\.\SMARTVSD", _
0&, 0&, _
ByVal 0&, _
CREATE_NEW, _
0&, _
0&)
End If
End Function
Private Function SwapBytes(b() As Byte) As Byte()
Dim bTemp As Byte
Dim cnt As Long
For cnt = LBound(b) To UBound(b) Step 2
bTemp = b(cnt)
b(cnt) = b(cnt + 1)
b(cnt + 1) = bTemp
Next cnt
SwapBytes = b()
End Function
|