Nói chung, chúng ta có thể dùng hàm API Windows có tên là DeviceIoControl() để truy xuất các thông tin vật lý của ổ đĩa (cứng, USB...) như Model number, Serial number, Firmware revision... Các hằng và kiểu dữ liệu phục vụ cho việc truy xuất thông tin vật lý của ổ đĩa được định nghĩa trong bộ DDK (Device development Kit).
1. Chạy Visual Studio .Net, chọn menu File.New project. Khi cửa sổ "New Project" hiển thị, bạn duyệt tìm mục "Visual Basic" trong cửa sổ "Project types", chọn mục "Windows" con của mục "Visual Basic", chọn icon "Windows Application" rồi chọn button Ok để tạo Project mới theo qui định.
2. Khi cửa sổ hiển thị Form thiết kế trống ban đầu, bạn hãy thiết kế Form gồm 4 đối tượng: 1 label, 1 textbox, 1 button và 1 ListBox như hình dưới đây. Hãy thiết lập thuộc tính (Name) cho textbox là txtDrive, cho button là btnStart, cho ListBox là lstInfo.
3. Nhấn đúp chuột vào button "Xem thong tin" để tạo thủ tục xử lý sự kiện click chuột trên nó. Khi cửa sổ code của Form hiển thị, bạn hiệu chỉnh nội dung đơn giản ban đầu thành đoạn code VB .Net dưới đây:
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Public Class Form1
'code cho Form1
'định nghĩa các hằng cần dùng cho hàm CreateFile
Private Const FILE_SHARE_READ As Short = &H1S
Private Const FILE_SHARE_WRITE As Short = &H2S
Private Const GENERIC_READ As Integer = &H80000000
Private Const GENERIC_WRITE As Integer = &H40000000
Private Const OPEN_EXISTING As Short = 3
Private Const CREATE_NEW As Short = 1
'định nghĩa các hằng, các kiểu cần dùng cho hàm DeviceIOControl
'các thông tin này được lấy từ bộ DDK
Private Const DFP_RECEIVE_DRIVE_DATA As Integer = &H7C088
Private Enum HDINFO
HD_MODEL_NUMBER
HD_SERIAL_NUMBER
HD_FIRMWARE_REVISION
End Enum
Private Structure IDEREGS
Dim bFeaturesReg As Byte
Dim bSectorCountReg As Byte
Dim bSectorNumberReg As Byte
Dim bCylLowReg As Byte
Dim bCylHighReg As Byte
Dim bDriveHeadReg As Byte
Dim bCommandReg As Byte
Dim bReserved As Byte
End Structure
Private Structure SENDCMDINPARAMS
Dim cBufferSize As Int32
Dim irDriveRegs As IDEREGS
Dim bDriveNumber As Byte
Dim bReserved1 As Byte
Dim bReserved2 As Byte
Dim bReserved3 As Byte
Dim dwReserved1 As Int32
Dim dwReserved2 As Int32
Dim dwReserved3 As Int32
Dim dwReserved4 As Int32
End Structure
Private Structure DRIVERSTATUS
Dim bDriveError As Byte
Dim bIDEStatus As Byte
Dim bReserved1 As Byte
Dim bReserved2 As Byte
Dim dwReserved1 As Int32
Dim dwReserved2 As Int32
End Structure
'không cần dùng kiểu SENDCMDOUTPARAMS như version VB 6.0
'khai báo các hàm API cần dùng
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As Integer, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Integer) As Integer
Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Integer, ByVal dwIoControlCode As Integer, ByVal lpInBuffer As IntPtr, ByVal nInBufferSize As Integer, <Out()> ByVal lpOutBuffer As IntPtr, ByVal nOutBufferSize As Integer, ByRef lpBytesReturned As Integer, ByVal lpOverlapped As Integer) As Integer
'định nghĩa các biến cần dùng
Dim bin As New SENDCMDINPARAMS
'định nghĩa hàm GetHDInfo để đọc thöng tin vật lý của disk
Private Function GetHDInfo(ByRef Drive As Byte, ByRef hdi As HDINFO) As String
'định nghĩa các biến cần dùng
Dim hdh As Integer
Dim br As Integer
Dim ix As Integer
Dim hddfr As Integer
Dim hddln As Integer
Dim s As String
Select Case hdi 'kiểm tra mã chức năng
Case HDINFO.HD_MODEL_NUMBER
hddfr = 55 'vị trí đầu của chuỗi ModelNumber
hddln = 40 'độ dài chuỗi ModelNumber
Case HDINFO.HD_SERIAL_NUMBER
hddfr = 21 'vị trí đầu của chuỗi SerialNumber
hddln = 20 'độ dài chuỗi SerialNumber
Case HDINFO.HD_FIRMWARE_REVISION
hddfr = 47 'vị trí đầu của chuỗi FirmwareRevision
hddln = 8 'độ dài chuỗi FirmwareRevision
Case Else
Err.Raise(10001, "Mã chức năng không đúng")
End Select
'tạo file nhận dạng ổ đĩa cần đọc thông tin
hdh = CreateFile("\\.\PhysicalDrive" & Drive, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0)
'kiểm tra việc tạo file
If hdh = 0 Then
Err.Raise(10003, , "Gặp lỗi khi gọi CreateFile")
End If
'thiết lập các thông số input
With bin
.bDriveNumber = Drive
.cBufferSize = 512
With .irDriveRegs
If (Drive And 1) <> 0 Then
.bDriveHeadReg = &HB0S
Else
.bDriveHeadReg = &HA0S
End If
.bCommandReg = &HECS
.bSectorCountReg = 1
.bSectorNumberReg = 1
End With
End With
'gọi hàm DeviceIoControl để đọc thông tin đĩa
Dim pbout As IntPtr = Marshal.AllocHGlobal(528)
Dim pbin As IntPtr = Marshal.AllocHGlobal(Len(bin))
Marshal.StructureToPtr(bin, pbin, False)
DeviceIoControl(hdh, DFP_RECEIVE_DRIVE_DATA, pbin, Len(bin), pbout, 528, br, 0)
'copy kết quả từ bộ nhớ "unmanaged" về bộ nhớ managed
Dim bBuffer(0 To 512) As Byte
For ix = 1 To 512
bBuffer(ix) = Marshal.ReadByte(pbout, ix + 15)
Next
'rút trích thông tin cần truy xuất
s = ""
For ix = hddfr To hddfr + hddln - 1 Step 2
If bBuffer(ix + 1) = 0 Then Exit For
s = s & Chr(bBuffer(ix + 1))
If bBuffer(ix) = 0 Then Exit For
s = s & Chr(bBuffer(ix))
Next ix
GetHDInfo = Trim(s)
'đóng handle disk
CloseHandle(hdh)
End Function
'thủ tục xử lý sự kiện click chuột trên button
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Dim Drive As Byte
Drive = CByte(txtDrive.Text)
lstInfo.Items.Clear()
lstInfo.Items.Add("Current drive: " & Drive)
lstInfo.Items.Add("")
'đọc và hiển thị các thông tin của đĩa
lstInfo.Items.Add("Model number: " & GetHDInfo(Drive, HDINFO.HD_MODEL_NUMBER))
lstInfo.Items.Add("Serial number: " & GetHDInfo(Drive, HDINFO.HD_SERIAL_NUMBER))
lstInfo.Items.Add("Firmware Revision: " & GetHDInfo(Drive, HDINFO.HD_FIRMWARE_REVISION))
End Sub
End Class
4. Chọn menu Debug.Start Debuging để dịch và chạy chương trình, nếu bạn nhập đúng đoạn code trên thì chương trình sẽ chạy đúng. Bạn thử nhập chỉ số 0 (nhận dạng ổ đĩa cứng đầu tiên) rồi nhấn button "Xem thong tin", thông tin về đĩa đầu tiên sẽ được hiển thị. Nếu bạn có đĩa cứng khác và/hoặc đĩa USB, bạn hãy nhập chỉ số 1, 2... rồi nhấn button "Xem thong tin" để xem thông tin về ổ đĩa tương ứng.
Nguyễn Văn Hiệp
(theo PC World VN)