Tip Getting the real hard disk serial number as normal user and as admin.

fmellaerts

Member
Joined
Jan 10, 2011
Messages
9
Programming Experience
Beginner
Hi,

For my software protection, I use the real harddisk serial number. How to get it ?
You can use a third party dll or program, but it's also possible from within your VB.NET application.
Using the next code, you can get the serial number as a normal user, as administrator, but NOT as guest !
I've been testing it on WIN XP, WIN 7 and WIN 8, and works without any problems !

I hope someone can use it...

Freddy Mellaerts



Imports System.Text
Imports System.Management

Public Class HDInfo

''' <summary>Gets the real harddisk serialnumber of the first harddisk (disk0).</summary>
''' <remarks>
''' This function will only work if the OS version >= 5.1 (FROM WIN XP UP TO WIN 8).
''' Administrator priveleges are only required, if the user is a GUEST.
''' </remarks>
''' <returns>If succeeded, the harddisk serialnumber as String, an empty String if failed.</returns> _
Public Function HDSN() As String

Dim mc As New ManagementClass("Win32_PhysicalMedia") 'Use "Win32_PhysicalMedia", because "Win32_DiskDrive" will NOT WORK on WIN XP !
Dim prop As String = "SerialNumber" 'The property to search for.
Dim moc As ManagementObjectCollection = Nothing 'The Management Object Collection.
Dim moce As ManagementObjectCollection.ManagementObjectEnumerator = Nothing 'The Management Object Enumerator.

Try

'Get instances.
moc = mc.GetInstances

'Set the enumerator.
moce = moc.GetEnumerator

'If the collection has minimum 1 item, get the serialnumber for the first harddisk (disk0).
If moc.Count > 0 Then

'Resets the enumerator to the beginning of the collection.
moce.Reset()

'Move the enumerator to the next (first) item of the collection.
moce.MoveNext()

'Get the raw serial number.
Dim result As String = moce.Current.GetPropertyValue(prop).ToString

'Remove all space characters ("20").
'Example : 20202020205635424544434553 will be 5635424544434553.
Dim serialNumber1 As String = result.Replace("20", "")

'IF THE USER IS ADMINISTRATOR, THE SERIALNUMBER1 STRING WILL ALREADY CONTAIN THE SERIAL NUMBER IN ASCII, AND NO CONVERSION IS REQUIRED (Microsoft bug ?),
'BUT IF THE SERIALNUMBER1 STRING IS A HEX STRING, CONVERT IT TO ASCII :
If System.Text.RegularExpressions.Regex.IsMatch(serialNumber1, "^[a-fA-F0-9]+$") Then

'Convert to ASCII. Example : 5635424544434553 will be converted to V5BEDCES.
serialNumber1 = HexDecode(serialNumber1)

'Swap pairs of characters.
'Example : V5BEDCES will be converted to 5VEBCDSE.
Dim serialNumber2 As String = ""
For i As Integer = 0 To serialNumber1.Length - 1 Step 2
serialNumber2 &= serialNumber1(i + 1)
serialNumber2 &= serialNumber1(i)
Next

'Return the serialnumber as ASCII string.
Return serialNumber2

Else 'If serialNumber1 is ASCII, remove spaces and return the serialnumber string.
Return serialNumber1.Trim
End If

Else 'If the collection is empty, return an empty serialnumber string.
Return ""
End If

Catch ex As ManagementException
MsgBox(ex.Message, MsgBoxStyle.Critical, "HDSERIAL")
Return ""
Finally
If mc IsNot Nothing Then mc.Dispose()
If moc IsNot Nothing Then moc.Dispose()
If moce IsNot Nothing Then moce.Dispose()
End Try

End Function

''' <summary>Decodes a HEX-string to an ASCII string.</summary>
''' <param name="strHEX">The HEX-string to decode.</param>
''' <returns>If succeeded, the decoded String, an empty String if failed.</returns>
Private Function HexDecode(ByVal strHEX As String) As String
Try
Dim sb As StringBuilder = New StringBuilder
For i As Integer = 0 To strHEX.Length - 1 Step 2
sb.Append(Convert.ToChar(Convert.ToUInt32(strHEX.Substring(i, 2), 16)).ToString)
Next
Return sb.ToString
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "HDSERIAL")
Return ""
End Try
End Function

End Class
 
Back
Top