Click here to Skip to main content
Licence CPOL
First Posted 29 Dec 2006
Views 372,082
Downloads 17,812
Bookmarked 145 times

Get Physical HDD Serial Number without WMI

By | 6 May 2008 | Article
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:

 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.

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)

About the Author

dmihailescu

Software Developer (Senior)

United States United States

Member

Decebal Mihailescu is a software engineer with interest in .Net, C# and C++.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generalit worked on vista for me. PinmemberWendel Renner4:01 18 Jun '09  
Questionvista problem PinmemberMember 148265321:10 29 May '09  
AnswerRe: vista problem Pinmemberrazvar2:08 15 Oct '09  
Questiongiving the .dll a strong name PinmemberMember 472352214:05 30 Mar '09  
QuestionRe: giving the .dll a strong name PinmemberMember 472352214:07 30 Mar '09  
AnswerRe: giving the .dll a strong name PinmemberMember 472352222:31 30 Mar '09  
GeneralReadPhysicalDriveInNTWithZeroRights is the right way Pinmemberfatass11:16 26 Feb '09  
i was trying to use the code in my applet for logitech G15 but it's hard for a noob Smile | :) and your code can only get data from my nforce sata drives
it's my second app, the first one was to control winamp with commandline
i have never seriously read anything about programming so i hardly understand just the simplest functions
i am worse at programming than to write in English
 
but i have used some code from diskid32 "ReadPhysicalDriveInNTWithZeroRights"
and it works, but not perfectly. i have 8 sata ports (4 nforce and 4 sil 3114)
and i can get data from sata, usb, scsi (the onboard sil 3114 is listed as scsi)
 
i can't get serial number from usb devices but i don't think there are any to get
 
to get the correct serialnumber from scsi i use

char * sserialNumber = (char*)descrip + descrip->SerialNumberOffset;
strcpy_s (serialNumber , sserialNumber);

not flipAndCodeBytes

 
for (drive = 0; drive < MAX_IDE_DRIVES; drive++) drive is the drives real Physical ID

using this with Win32_PerfFormattedData_PerfDisk_PhysicalDisk (string Name)
http://msdn.microsoft.com/en-us/library/aa394262(VS.85).aspx
i can associate all logical drives with the right physical drive
it is not impossible that there is an easier way to do this


it is possible to use this with in admin rights, there is no big difference

without admin rights

hPhysicalDriveIOCTL = CreateFile (driveName, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);

with admin rights

hPhysicalDriveIOCTL = CreateFile (driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE , NULL,
OPEN_EXISTING, 0, NULL);


it's just a drive that I can not get the right information on. the first drive on the sil 3114
i only get Vendor Id "SiImage".
 

but everest get all information right so i think there is a better way to get this information.">uituio[
GeneralError Loading DriveinfoEx.dll PinmemberVikash Yadav16:43 17 Feb '09  
GeneralRe: Error Loading DriveinfoEx.dll Pinmemberdmihailescu12:42 18 Feb '09  
GeneralRe: Error Loading DriveinfoEx.dll PinmemberCannoneer6:42 19 Jun '09  
GeneralRe: Error Loading DriveinfoEx.dll Pinmemberdmihailescu1:43 22 Jun '09  
GeneralRe: Error Loading DriveinfoEx.dll PinmemberPeter Souza3:30 1 Sep '09  
GeneralRe: Error Loading DriveinfoEx.dll PinmemberInvXeesh22:06 11 Nov '10  
QuestionSize of DriveInfoEx.dll... Pinmembersoftwaretry1:34 6 Feb '09  
AnswerRe: Size of DriveInfoEx.dll... Pinmemberdmihailescu13:06 6 Feb '09  
GeneralRe: Size of DriveInfoEx.dll... Pinmembersoftwaretry7:10 16 Feb '09  
GeneralRe: Size of DriveInfoEx.dll... Pinmemberdmihailescu12:44 18 Feb '09  
AnswerRe: Size of DriveInfoEx.dll... PinmemberVikash Yadav21:04 16 Feb '09  
Generalnot able to use the DriveInfoEx.dll in c# PinmemberRavi Tejas1:26 23 Jan '09  
GeneralRe: not able to use the DriveInfoEx.dll in c# Pinmemberdmihailescu12:50 23 Jan '09  
QuestionVisual Studio 2008 shows errors... Pinmembersoftwaretry6:46 19 Jan '09  
AnswerRe: Visual Studio 2008 shows errors... Pinmemberdmihailescu8:43 19 Jan '09  
GeneralRe: Visual Studio 2008 shows errors... PinmemberDasMullet8:22 9 Feb '09  
GeneralRe: Visual Studio 2008 shows errors... PinmemberJacky__E6:35 10 Aug '09  
QuestionProtect DLL Pinmembersoftwaretry6:42 12 Jan '09  

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

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120604.1 | Last Updated 6 May 2008
Article Copyright 2006 by dmihailescu
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid