Banyak pertanyaan di forum-forum programming tentang bagaimana mendapatkan serial number hardisk yang bawaan dari pabriknya. Tapi bukan yang serial number volume yah, karena serial volume akan berubah2 saat proses format. Kebanyakan code yang Rani temukan menggunakan WMI, tapi serial number yang dihasilkan tak sesuai harapan. Rani pengennya serial number yang sama yang biasanya dihasilkan oleh code HDSN seperti yang di link Planet Source Code , dan code ini sebelumnya Rani pakai di aplikasi-aplikasi yang menggunakan Visual Basic 6 (VB6). Dan sekarang saat migrasi aplikasi ke VB.NET Rani butuh code yang sama, sayangnya klo menggunakan WMI hasilnya ga sama. Berarti harus cari cara selain menggunakan WMI, ada ga ya? Akhirnya dapet solusi terbaik dengan menggunakan DeviceIOControl yang diperoleh dari blog jo0ls' .Net stuff . Kemudian Rani adaptasi sesuai kebutuhan. Caranya setelah membuat project/solution windows form bernama HDDSerial Number, tambahkan sebuah module bernama SerialNumber.vb Kemudian tambahkan code sebagai berikut: Imports System.Runtime.InteropServices Imports Microsoft.Win32.SafeHandles Imports System.Security Imports System.ComponentModel Imports System.Text Module SerialNumber _ Private Class NativeMethods "kernel32" , SetLastError:= True )> _ Public Shared Function CreateFile( _ ByVal FileName As String , _ ByVal DesiredAccess As Integer , _ ByVal ShareMode As Integer , _ ByVal SecurityAttributes As IntPtr , _ ByVal CreationDisposition As Integer , _ ByVal FlagsAndAttributes As Integer , _ ByVal hTemplateFile As IntPtr) As SafeFileHandle End Function "kernel32.dll" , SetLastError:= True )> _ Friend Shared Function DeviceIoControl( _ ByVal deviceHandle As SafeFileHandle, _ ByVal controlCode As Integer , _ ByRef inBuffer As ATA_PASS_THROUGH_EX_WITH_BUFFERS, _ ByVal inBufferSize As Integer , _ ByRef outBuffer As ATA_PASS_THROUGH_EX_WITH_BUFFERS, _ ByVal outBufferSize As Integer , _ ByRef bytesReturned As Integer , _ ByVal overlapped1 As IntPtr) As Boolean End Function End Class _ Private Structure ATA_PASS_THROUGH_EX Public Length As Short Public AtaFlags As Short Public PathId As Byte Public TargetId As Byte Public Lun As Byte Public ReservedAsUchar As Byte Public DataTransferLength As Integer Public TimeOutValue As Integer Public ReservedAsUlong As Integer Public DataBufferOffset As IntPtr _ Public PreviousTaskFile() As Byte _ Public CurrentTaskFile() As Byte End Structure _ Private Structure ATA_PASS_THROUGH_EX_WITH_BUFFERS Public Apt As ATA_PASS_THROUGH_EX _ Public Data() As Byte End Structure Public Enum HDINFO HD_MODEL_NUMBER = 0 HD_SERIAL_NUMBER = 1 HD_FIRMWARE_REVISION = 2 End Enum Public Function HDDInfo( ByVal InfoType As HDINFO) As String Dim letter As Char = "c" Const GenericRead As Integer = &H80000000 Const GenericWrite As Integer = &H40000000 Const FileShareRead As Integer = 1 Const FileShareWrite As Integer = 2 Const OpenExisting As Integer = 3 Dim drivePath As String = String .Concat( "\\.\" & letter & ":" ) Using driveHandle As SafeFileHandle = NativeMethods.CreateFile( _ drivePath, _ GenericRead Or GenericWrite, _ FileShareRead Or FileShareWrite, _ IntPtr.Zero, _ OpenExisting, _ 0, _ IntPtr.Zero) If driveHandle.IsInvalid Then Return "CreateFile ERROR: " & ( New Win32Exception).Message End If Dim apex As New ATA_PASS_THROUGH_EX apex.Length = Marshal.SizeOf(apex) ' ATA_FLAGS_DATA_IN apex.AtaFlags = 2 ' The command returns a 512 byte package of gosip. apex.DataTransferLength = 512 apex.TimeOutValue = 10 ' 10 second timeout. apex.DataBufferOffset = Marshal.OffsetOf( _ GetType (ATA_PASS_THROUGH_EX_WITH_BUFFERS), "Data" ) ' This contains the command we are requesting. apex.CurrentTaskFile = New Byte(7) 'the command "IDENTIFY DEVICE" apex.CurrentTaskFile(6) = &HEC Dim apexb As New ATA_PASS_THROUGH_EX_WITH_BUFFERS apexb.Apt = apex Dim inBufferSize As Integer = Marshal.SizeOf( _ GetType (ATA_PASS_THROUGH_EX_WITH_BUFFERS)) Dim bytesReturned As Integer Const IOCTL_ATA_PASS_THROUGH As Integer = &H4D02C Dim result As Boolean = NativeMethods.DeviceIoControl( _ driveHandle, IOCTL_ATA_PASS_THROUGH, _ apexb, inBufferSize, apexb, inBufferSize, _ bytesReturned, IntPtr.Zero) If result = False Then Return "DeviceIOControl ERROR: " & ( New Win32Exception).Message End If Select Case InfoType Case HDINFO.HD_SERIAL_NUMBER Return GetString(apexb.Data, 20, 20) Case HDINFO.HD_FIRMWARE_REVISION Return GetString(apexb.Data, 46, 8) Case HDINFO.HD_MODEL_NUMBER Return GetString(apexb.Data, 54, 40) Case Else Return Nothing End Select End Using End Function Private Function GetString( ByVal bytes() As Byte , _ ByVal offset As Integer , _ ByVal length As Integer ) As String ' The strings are slightly weird - endianness? ' If you use ASCII.GetBytes Then Each character ' pair is reversed. Dim sb As New StringBuilder() For i As Integer = offset To offset + length - 1 Step 2 sb.Append(Chr(bytes(i + 1))) sb.Append(Chr(bytes(i))) Next Return RTrim(LTrim(sb.ToString)) End Function End Module Atur UI pada Form1 supaya property text menjadi "Hardisk Serial Number", tambahkan 3 label dan 3 TextBox. Berinama textbox-textbox tersebut dengan txtSerialNumber, txtModel, dan txtFirmware. Kemudian ketikan isyarat berikut: Imports System.Management Public Class Form1 Private Sub Form1_Load( ByVal sender As Object, _ ByVal e As EventArgs) Handles MyBase .Load Try txtSerialNumber.Text = HDDInfo(HDINFO.HD_SERIAL_NUMBER) txtModel.Text = HDDInfo(HDINFO.HD_MODEL_NUMBER) txtFirmware.Text = HDDInfo(HDINFO.HD_FIRMWARE_REVISION) Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Class Jalankan, dan ini penampakan hasil di PC Rani: Catatan: Jangan lupa untuk Run as Administrator supaya aplikasi dapat berjalan baik pada Vista, Windows 7, dan Windows 8. Referensi: http://stackoverflow.com/questions/782053/get-hdd-and-not-volume-serial-number-on-vista-ultimate-64-bit http://jo0ls-dotnet-stuff.blogspot.co.id/2011/02/getting-hard-disk-drive-gosip-with.html Click here if you like this article. Sumber http://rani-irsan.blogspot.com