Click here to Skip to main content
15,900,461 members
Articles / Programming Languages / C#

Get Physical HDD Serial Number without WMI

Rate me:
Please Sign up or sign in to vote.
4.79/5 (63 votes)
6 May 2008CPOL2 min read 963.6K   62.8K   178   196
Retrieve the physical Hard drive ID and other info using low level APIs like DeviceIOControl

Sample Image - DriveInfo.png

Introduction

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.

Background

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:

C#
m_list = new DriveListEx();
m_list.Load();
//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.

C++
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;
       break;
    }
  }
   if(bAdd)
   {
      WORD* diskdata = new WORD[256];
      ::memcpy(diskdata,pIdSector,256*sizeof(WORD));
      m_list.push_back(diskdata);
   }
  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 release.zip archive, since they are 32 bit for Windows XP.

History

  • 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.

License

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


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

Comments and Discussions

 
Generalyou are right but... Pin
dmihailescu1-Jan-07 15:46
dmihailescu1-Jan-07 15:46 
GeneralRe: you are right but... Pin
mvendert3-Jan-07 5:14
mvendert3-Jan-07 5:14 
GeneralRe: you are right but... Pin
rlivelyppk8-Jan-07 5:45
rlivelyppk8-Jan-07 5:45 
GeneralRe: you are right but... Pin
amach18-May-07 13:20
amach18-May-07 13:20 
NewsRe: you are right but... Pin
amach25-May-07 7:58
amach25-May-07 7:58 
GeneralRe: you are right but... Pin
Hamed Musavi11-Aug-07 22:28
Hamed Musavi11-Aug-07 22:28 
GeneralRe: a better solution Pin
dmihailescu30-Oct-07 5:16
dmihailescu30-Oct-07 5:16 
GeneralRe: a better solution Pin
Douglas R. Keesler30-Oct-07 11:46
Douglas R. Keesler30-Oct-07 11:46 

I understand, I think you made that same point in your comment dated Dec. 2006!

Let me use my own situation as an example. In 7yrs I have change OS one time... went from 2000 to XP. However, I have changed hard drives at least 6 times... in fact, I just installed a new primary drive last weekend.

The hard drive is the most frequently changed piece of hardware in the system... so are you trying to say, "I want my software to only run on one specific hard drive." That seems absurd.

If you are trying to prevent/limit unauthorized license sharing... here's what I do... I have a two stage system - licensing and validation. I tie the licensing to user specific data: name, order #, original email, etc... and then the validation process looks at multiple pieces of hardware data: Computer name, HDID, Mac Addr, Bios SN, Processor, OS, etc.... This gives me a "snapshot" of the system it was licensed on, and then I use a percentage basis to validate. If the validation request results in a 90% match, I will validate and update the database with the new snapshot, however if it's only a 30% match I can invalidate the license and return a message that he needs to contact the vendor and request a new license key.

So it doesn't matter whether the HDID is "immutable" or not... it doesn't even matter whether the HDID has changed or not, or for what reason it changed.. the more important question is how many pieces of hardware info have changed. If they still have the same Mac address, same Bios, same processor ID, same OS version and serial number, same amount of Ram installed, etc.. it's likely they just got a new hard drive and are still on the same system. My point is tying a license to ANY one piece of hardware or hardware data is a bad idea.. it will cost you more money in dissatisfied customers than you would lose through license abuse. Tie your licenses to your customer data only, and then use a relaxed hardware based validation system to validate the license -- but that system should rely on many pieces of information, not just the hard drive.




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




AnswerRe: SCSI Arrays Pin
Divesh4u18-Jan-07 4:16
Divesh4u18-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.