[VB6] อ่านค่า Physical Serial Number ของฮาร์ดดิสต์ที่บู๊ตระบบวินโดวส์ด้วย API
http://www.g2gnet.com/webboard/images/vb6/getbootdiskapi.pngจากตอนที่แล้วได้นำเสนอ การค้นหา Harddisk ที่ติดตั้ง Windows พร้อมกับอ่านค่า Physical Serial Number ด้วย WMI (Windows Management Instrumentation) มาตอนนี้จะใช้ Win32 API หรือ Application Programming Interface ซึ่งค่อนข้างจะทำความเข้าใจในตัวโค้ดได้ยากมากกว่า WMI แต่ทว่ากลับได้ผลลัพธ์ที่ค่อนข้างจะเที่ยงตรงและแม่นยำ ในกรณีที่ฮาร์ดดิสต์ของคุณมีอยู่หลายลูก และติดตั้งระบบปฏิบัติการวินโดวส์เอาไว้หลายเวอร์ชั่น เรื่องแบบนี้ต้องลองทดสอบกันดูเอาเองครับ ... อนึ่ง!!! สำหรับในตอนนี้แอดมินเลือกใช้ API สำหรับการค้นหาว่าระบบปฏิบัติการมันถูกบู๊ตระบบจากไดร์ฟอะไร (เช่น C) และคืนค่ากลับให้เป็นหมายเลขของ Physical Harddisk แต่เวลาหา Serial Number แอดมินใช้ WMI เข้าช่วย เพื่อให้ง่ายต่อการศึกษา มากกว่าการใช้ API ทั้งหมดครับผม ...
มาดูโค้ดกันเถอะ ... (ส่วนของ Sub Main)
' / -----------------------------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand only)
' / Facebook: https://www.facebook.com/commonindy (Worldwide)
' / MORE: http://www.g2gnet.com/webboard
' /
' / Purpose: Get boot disk and read Physical Serial Number.
' / Microsoft Visual Basic 6.0 Service Pack 6
' /
' / This is open source code under @Copyleft by Thongkorn Tubtimkrob.
' / You can modify and/or distribute without to inform the developer.
' / -----------------------------------------------------------------------------------------------
Option Explicit
Sub Main()
MsgBox "Boot Disk is Serial Number: " & GetBootDiskSerialNumber, , "VB6 Get Boot Hard Disk"
End Sub
Public Function GetBootDiskSerialNumber() As String
On Error Resume Next
Dim Objs As Object
Dim Obj As Object
Dim WMI As Object
Dim BootDisk As String
Dim strComputer As String
Set WMI = GetObject("WinMgmts:")
For Each Obj In WMI.InstancesOf("Win32_PhysicalMedia")
If Obj.Tag = "\\.\PHYSICALDRIVE" + CStr(GetBootPhysicalDrive) Then _
GetBootDiskSerialNumber = Replace(Trim(Obj.SerialNumber), Chr(0), "")
Next Obj
End Function
มาดูโค้ดในส่วนของโมดูล ... (API - Application Programming Interface)
' / -----------------------------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand only)
' / Facebook: https://www.facebook.com/commonindy (Worldwide)
' / MORE: http://www.g2gnet.com/webboard
' /
' / Purpose: Get boot disk and read Physical Serial Number.
' / Microsoft Visual Basic 6.0 Service Pack 6
' /
' / This is open source code under @Copyleft by Thongkorn Tubtimkrob.
' / You can modify and/or distribute without to inform the developer.
' / -----------------------------------------------------------------------------------------------
Option Explicit
Public Const FILE_SHARE_READ = &H1
Public Const FILE_SHARE_WRITE = &H2
Public Const GENERIC_READ = &H80000000
Public Const GENERIC_WRITE = &H40000000
Public Const OPEN_EXISTING = 3
Public Const IOCTL_VOLUME_BASE As Long = 86 ' Asc("V")
Public Const METHOD_BUFFERED As Long = 0
Public Const FILE_READ_ACCESS As Long = 1
Public Const FILE_ANY_ACCESS As Long = 0
'// DEFINE IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS CTL_CODE(IOCTL_VOLUME_BASE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS)
Public Const IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = _
(((IOCTL_VOLUME_BASE) * (2& ^ 16&)) Or _
((FILE_ANY_ACCESS) * (2& ^ 14&)) Or _
((0&) * (2& ^ 2&)) Or _
(METHOD_BUFFERED))
Public Type DISK_EXTENT
DiskNumber As Long
StartingOffset As Currency
ExtentLength As Currency
End Type
Public Type VOLUME_DISK_EXTENTS
NumberOfDiskExtents As Currency
Extents(1 To 4) As DISK_EXTENT
End Type
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long _
) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function GetWindowsDirectory Lib "Kernel32.dll" Alias "GetWindowsDirectoryW" ( _
ByVal lpBuffer As Long, _
ByVal uSize As Long _
) As Long
Public Declare Function DeviceIoControlNoInput Lib "kernel32" Alias "DeviceIoControl" ( _
ByVal hDevice As Long, _
ByVal dwIoControlCode As Long, _
ByVal lpInBuffer As Long, _
ByVal nInBufferSize As Long, _
ByRef lpOutBuffer As Any, _
ByVal nOutBufferSize As Long, _
ByRef lpBytesReturned As Long, _
ByVal lpOverlapped As Long _
) As Long
'/ Return the index of the physical drive from which we've booted into Windows.
Public Function GetBootPhysicalDrive() As Long
Dim sWindowsPath As String
Dim nRet As Long
Dim sDevicePath As String
Dim hLogicalBootDrive As Long
Dim sVolumeDevice As String
Dim uVolumeDiskExtentsAs VOLUME_DISK_EXTENTS
Dim nBytesReturned As Long
'/ Allocate space and retrieve the windows directory.
sWindowsPath = Space$(64)
nRet = GetWindowsDirectory(StrPtr(sWindowsPath), 64)
'/ This gives us the volume that Windows is on. Open it.
sVolumeDevice = "\\.\" & Left$(sWindowsPath, 2)
hLogicalBootDrive = CreateFile(sVolumeDevice, GENERIC_READ + GENERIC_WRITE, FILE_SHARE_READ + FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&)
'/ Find out information about this volume.
nRet = DeviceIoControlNoInput(hLogicalBootDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, 0&, 0&, uVolumeDiskExtents, LenB(uVolumeDiskExtents), nBytesReturned, 0&)
If nRet = 0 Then
'/ Something went wrong. Return error value.
GetBootPhysicalDrive = -1
Else
'/ This is the physical disk number.
GetBootPhysicalDrive = uVolumeDiskExtents.Extents(1).DiskNumber
End If
'/ Close volume.
CloseHandle hLogicalBootDrive
End Function
ดาวน์โหลดโค้ดต้นฉบับ VB6 ได้ที่นี่ ...
หน้า:
[1]