Click here to Skip to main content
14,243,297 members

Get Physical HDD Serial Number without WMI

Rate this:
4.79 (62 votes)
Please Sign up or sign in to vote.
4.79 (62 votes)
6 May 2008CPOL
Retrieve the physical Hard drive ID and other info using low level APIs like DeviceIOControl

Sample Image - DriveInfo.png


Many people looking for a schema to protect their work need to get some information that is hardware specific like the Mac Address or some hard drive serial number.


If you tried other solutions like like this one, it probably did not work for you because it's using the WMI services. I was able to find a solution that worked reasonably well here. It made low level calls to the disk using commands sent by the DeviceIoControl API. The code was not very reusable unless you used native C++. Therefore I brushed it a bit and made it look more Object Oriented. Most importantly, I exposed the drive information through a .NET collection.

Using the Code

Since the collection is written in MC++, I've included some Microsoft DLLs from the redistributable pack in the demo zip. Also it's mandatory to use .NET 2.0 since the collection is generic.

The code is very easy to use from any .NET language, like C# for instance:

m_list = new DriveListEx();
//bind to a a grid view
m_dataGridView.DataSource = m_list;

Points of Interest

The information about the internal drives is gathered in DiskInfo::LoadDiskInfo();

DiskInfo is a native singleton class that wraps the calls to ReadPhysicalDriveInNTWithAdminRights() and ReadIdeDriveAsScsiDriveInNT(). I ignored the ReadPhysicalDriveInNTWithZeroRights() that did not seem to work anyways.

Both functions will call AddIfNew() if they can retrieve the information.

Internally there is a list that holds the raw information about the drives and that is updated when a new drive information was found.

BOOL DiskInfo::AddIfNew(USHORT *pIdSector)
  BOOL bAdd = TRUE;
  for(UINT i =0; i< m_list.size();i++)
    if(memcmp(pIdSector,m_list[i],256 * sizeof(WORD)) == 0)
       bAdd = false;
      WORD* diskdata = new WORD[256];
  return bAdd;

If you are stuck with a non .NET compiler, you could still use the source code from UnmanagedCode.cpp, just uncomment the #define NATIVE_CODE line.
This build is for Windows XP 32 bit systems. If you need it for Vista or 64 bit systems, you should select the right include and lib folders when building and should not use the additional DLLs from the archive, since they are 32 bit for Windows XP.


  • Version 1.1: Added ReadPhysicalDriveInNTUsingSmart for reading the HDD info.
    P.S. I did not get a chance to test it for Windows 95 and alike.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
United States United States
Decebal Mihailescu is a software engineer with interest in .Net, C# and C++.

Comments and Discussions

GeneralRe: VMware with three IDE harddrives Pin
HStrix5-Jan-07 22:48
memberHStrix5-Jan-07 22:48 
GeneralRe: VMware with three IDE harddrives Pin
memphis2330-Oct-08 2:25
membermemphis2330-Oct-08 2:25 
QuestionSCSI Arrays Pin
DBuckner29-Dec-06 18:13
memberDBuckner29-Dec-06 18:13 
Answera better solution Pin
Douglas R. Keesler29-Dec-06 20:10
memberDouglas R. Keesler29-Dec-06 20:10 
GeneralRe: a better solution Pin
poltrone29-Dec-06 21:16
memberpoltrone29-Dec-06 21:16 
GeneralRe: a better solution Pin
Douglas R. Keesler29-Dec-06 21:44
memberDouglas R. Keesler29-Dec-06 21:44 
Generalthat's a different thing Pin
dmihailescu30-Dec-06 7:36
memberdmihailescu30-Dec-06 7:36 
GeneralRe: that's a different thing Pin
Douglas R. Keesler30-Dec-06 13:57
memberDouglas R. Keesler30-Dec-06 13:57 

I understand that.. but it doesn't matter. You stated that this article solved a need for a "schema to protect their work" (presumably software licensing).

The "immutable" diskID doesn't make your software any more difficult to crack. The cracker isn't going to worry about changing the diskID... he's going to modify your code to read the same diskID on all systems. At some point your code returns the unencrypted value. Once the cracker gets that, he modifies your code to always arbitrarily return that value. Now, his valid license will validate correctly on any system in the world. Or worse, he could use your very class to write a keygen program mass producing illegal licenses at will.

If you are just trying to discourage illegal distribution by casual users, the system ID bound with other data is sufficient. If you are protecting against reverse engineering (crackers), both schemes are useless if the actual code that generates/validates the licenses can be deciphered and reproduced.. You need executable encryption in both static and runtime states, further protected by server-side validation (because the hacker cannot trace or disassemble server code).

The moral is that it really doesn't matter what data you use to generate the licenses... it only matters whether this method can be figured out and reproduced. And if your executable code isn't encrypted, and otherwise made inaccessible to analysis, it can be easily cracked. Whether it will be is only determined by how popular your software is.

In business, if two people always agree, one of them is unnecessary.

Generalyou are right but... Pin
dmihailescu1-Jan-07 15:46
memberdmihailescu1-Jan-07 15:46 
GeneralRe: you are right but... Pin
mvendert3-Jan-07 5:14
membermvendert3-Jan-07 5:14 
GeneralRe: you are right but... Pin
rlivelyppk8-Jan-07 5:45
memberrlivelyppk8-Jan-07 5:45 
GeneralRe: you are right but... Pin
amach18-May-07 13:20
memberamach18-May-07 13:20 
NewsRe: you are right but... Pin
amach25-May-07 7:58
memberamach25-May-07 7:58 
GeneralRe: you are right but... Pin
Hamed Mosavi11-Aug-07 22:28
memberHamed Mosavi11-Aug-07 22:28 
GeneralRe: a better solution Pin
dmihailescu30-Oct-07 5:16
memberdmihailescu30-Oct-07 5:16 
GeneralRe: a better solution Pin
Douglas R. Keesler30-Oct-07 11:46
memberDouglas R. Keesler30-Oct-07 11:46 
AnswerRe: SCSI Arrays Pin
Divesh4u18-Jan-07 4:16
memberDivesh4u18-Jan-07 4:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Posted 29 Dec 2006


178 bookmarked