Retrieving the real harddisk serial number and in any condition for any hard drive
Posted on 2010-08-19
I am using VB.NET in VS2005 and trying to get the manufacturer assigned (unchangeable) serial number of the harddisk. I will use this id for distribution protection of my software.
The number should not be the HardDisk VolumeSerialNumber of the partition that can be re-assigned by software methods.
I am working on this problem for a period and searched some solutions the first one is "using WMI" by the value "Win32_physicalmedia". But this method returns the serial number as blank for some harddrives or for some PC configuration (I could not find the actual reason for it is doing so but I am lucky to find it happening on my development PC). There are many different examples of WMI, for example the following;
Dim TheSearcher As ManagementObjectSearcher = New ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia")
For Each wmi_HD As ManagementObject In TheSearcher.Get()
It returns an empty string in my PC, but returns the actual manufacturer assigned serial when run at my colleagues PC's.
And the second method I found; Using CreateFile from "kernel32.dll" API. It is something like this (not the full code given here because the original example is long, just for giving an idea about the example);
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
handle = CreateFile("\\.\PhysicalDrive" & "0", HDDID_GENERIC_READ + HDDID_GENERIC_WRITE, HDDID_FILE_SHARE_READ + HDDID_FILE_SHARE_WRITE, 0, HDDID_OPEN_EXISTING, 0, 0)
serialNumber = HDDID_SwapChars(sco.IDS.SerialNumber)
model = HDDID_SwapChars(sco.IDS.ModelNumber)
It works for all disks that I have, but the "CreateFile" function does not work when logged in with limited administrative privileges (i.e. logged in as limited user account in Windows).
Is there any third method that works in all conditions? Or a trick to make above examples working.