11 Lập trình: Dùng VB.Net đọc “serial number” đĩa cứng

(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).

??? Tìm hiểu thêm:

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</out()>

‘đị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
FPT Aptech – Hệ Thống Đào Tạo Lập Trình Viên Quốc Tế

FPT Aptech trực thuộc Tổ chức Giáo dục FPT có hơn 25 năm kinh nghiệm đào tạo lập trình viên quốc tế tại Việt Nam, và luôn là sự lựa chọn ưu tiên của các sinh viên và nhà tuyển dụng.
0981578920
icons8-exercise-96