(Post 05/11/2010) Chúng tôi đã giới thiệu đến
bạn đọc quy trình xây
dựng ứng dụng và mã lệnh (code) được viết bằng VB 6.0, cho phép truy
xuất thông tin của các ổ đĩa trên máy. Theo yêu cầu của nhiều bạn đọc,
bài viết này giới thiệu cách
viết code bằng VB .Net 2005 để truy xuất thông tin của các ổ đĩa.
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)
Tin liên quan:
|