Click here to Skip to main content
Click here to Skip to main content

Get Physical HDD Serial Number without WMI

By , 6 May 2008
 

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

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
BugNot runing in VS2008memberMenon Santosh13 Mar '13 - 2:28 
Questioni want to get hd Info of other computer through networkmemberehtshamkh15 Jan '13 - 1:20 
QuestionIf there are more than 1 HDD?memberleomifare21 Oct '12 - 21:20 
Questionmac add, ip add, motherboard serial no, processor s.no, local drive s.no....memberPraveen S22 Jul '12 - 20:38 

 
// Mac Address.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include
#include
#define _WIN32_DCOM
#include
#include
#include
#include
 

#pragma comment(lib, "Netapi32.lib")
#pragma comment(lib, "wsock32.lib")
# pragma comment(lib, "wbemuuid.lib")
 

 
using namespace std;
 

void filewrite(string a,int e)
{
ofstream fout;
if(e==1)
fout.open("System Configuration.txt");
else
{
fout.open("System Configuration.txt", ios::app);
fout<<a;
fout<<endl;
}


fout.close();

}
 

void getmac()
{
unsigned char MACData[8];
WKSTA_TRANSPORT_INFO_0 *pwkti;
DWORD dwEntriesRead;
DWORD dwTotalEntries;
BYTE *pbBuffer;
 
NET_API_STATUS dwStatus = NetWkstaTransportEnum(
NULL, // [in] server name
0, // [in] data structure to return
&pbBuffer, // [out] pointer to buffer
MAX_PREFERRED_LENGTH, // [in] maximum length
&dwEntriesRead, // [out] counter of elements actually enumerated
&dwTotalEntries, // [out] total number of elements that could be enumerated
NULL); // [in/out] resume handle
 
assert(dwStatus == NERR_Success);
 
pwkti = (WKSTA_TRANSPORT_INFO_0 *)pbBuffer; // type cast the buffer
 
for(DWORD i=1; i< dwEntriesRead; i++) // first address is 00000000, skip it
{ char dd[33];
// enumerate MACs and print
swscanf((wchar_t *)pwkti[i].wkti0_transport_address, L"%2hx%2hx%2hx%2hx%2hx%2hx",
&MACData[0], &MACData[1], &MACData[2], &MACData[3], &MACData[4], &MACData[5]);
//PrintMACaddress(MACData);
sprintf(dd," %02x-%02x-%02x-%02x-%02x-%02x\n",MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]);
string u="MAC Address :";
u+=dd;
filewrite(u,0);
}



// Release pbBuffer allocated by above function
dwStatus = NetApiBufferFree(pbBuffer);
assert(dwStatus == NERR_Success);
}
 
void getip()
{
WORD wVersionRequested;
WSADATA wsaData;
char name[255];
PHOSTENT hostinfo;
wVersionRequested = MAKEWORD( 1, 1 );
char *ip;
 
if ( WSAStartup( wVersionRequested, &wsaData ) == 0 )
if( gethostname ( name, sizeof(name)) == 0)
{
//printf("Host name: %s\n", name);
string name1="Computer Name: ";
name1+=name;
filewrite(name1,0);
 
if((hostinfo = gethostbyname(name)) != NULL)
{
int nCount = 0;
while(hostinfo->h_addr_list[nCount])
{
ip = inet_ntoa (*(struct in_addr *)hostinfo->h_addr_list[nCount]);
++nCount;
//printf("IP #%d: %s\n", ++nCount, ip);


string s="IP Adress : ";
s+=ip;
filewrite(s,0);
}
}
}
}
 

 

void getsn_no()
{
CoInitializeEx(0, COINIT_MULTITHREADED);
 
CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
 
IWbemLocator *pLoc = NULL;
 
CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *) &pLoc);
 
IWbemServices *pSvc = NULL;
pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL, // User name. NULL = current user
NULL, // User password. NULL = current
0, // Locale. NULL indicates current
NULL, // Security flags.
0, // Authority (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);

 
IEnumWbemClassObject* pEnumerator = NULL;
ULONG uReturn;
int i=1,x=0;
LPCWSTR lp3;
_bstr_t win32;
string data;
 
while(i<=7)
{
 
switch(i)
{
case 1:
filewrite("MOTHER BOARD",0);
win32="SELECT * FROM Win32_BaseBoard";
lp3=L"SerialNumber";
data="SerialNumber :";
break;
case 2:
win32="SELECT * FROM Win32_BaseBoard";
lp3=L"Product";
data="Product ID :";
break;
case 3:
win32="SELECT * FROM Win32_Processor";
lp3=L"ProcessorId";
data="Processor Id :";
x=1;
cout<<"Configuring Software....."<<endl<<endl;
break;
case 4:
filewrite("",0);
filewrite("HARD-DISK & FLAS DRIVE",0);
win32="SELECT * FROM Win32_DiskDrive";
lp3=L"Model";
data="Model NO : ";
break;
case 5:
win32="SELECT * FROM Win32_DiskDrive";
lp3=L"InterfaceType";
data="InterfaceType : ";
break;
case 6:
filewrite("",0);
filewrite("LOCAL DISK's SERIAL No.",0);
win32="SELECT * FROM Win32_LogicalDisk";
lp3=L"Name";
x=3;
break;
case 7:
filewrite("",0);
win32="SELECT * FROM Win32_OperatingSystem";
lp3=L"Name";
filewrite("OS Name |PATH| |PARTITION|",0);
x=0;
break;
}
i++;
 
pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t(win32),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
 
IWbemClassObject *pclsObj;
uReturn = 0;
//filewrite("HD&FLASH DRIVE's ",0);

while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,&pclsObj, &uReturn);
 
if(0 == uReturn)
{
break;
}
 

VARIANT vtProp;
 
// Get the value of the Name property

pclsObj->Get(lp3, 0, &vtProp, 0, 0);
data+=(const char*)_bstr_t(vtProp.bstrVal);
 
if(x==3)
{
lp3=L"VolumeSerialNumber";
string n;
n=data;
n+=" ";
pclsObj->Get(lp3, 0, &vtProp, 0, 0);
n+=(const char*)_bstr_t(vtProp.bstrVal);
data=n;
lp3=L"Name";

}
 
filewrite(data,0);
 

 

VariantClear(&vtProp);
pclsObj->Release();
data.clear();
if(x==1)
{
x=0;
break;
}
}
 
}
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();

 
}
 

 
int _tmain(int argc, _TCHAR* argv[])
 
{
filewrite("",1);
cout<<"Configuring Hardware....."<<endl;
getip();
getmac();
getsn_no();
cout<<endl<<" Configuration Completed";
cout<<endl<<endl<<endl<<"Press any key to continue...";
getch();
return 0;
 
}
 

these stuff works 100% in VC++ , but when i try HDD serial no, by means of win32_PhisicalMedia , get(L"SerialNumber",0.....
it return NULL varient Please help
GeneralMy vote of 5memberNox PasNox11 May '12 - 4:43 
Answeranother methodmembery_sir9 May '12 - 23:06 
GeneralMy vote of 5memberAmir Dashti16 Feb '12 - 4:08 
QuestionHow to get HDD Device Driver without WMI?memberHolt24517 Dec '11 - 15:29 
Question[My vote of 1] Code from WinSim Inc.member_DiZ29 Nov '11 - 6:45 
AnswerRe: [My vote of 1] Code from WinSim Inc.memberdmihailescu29 Nov '11 - 16:14 
GeneralMy vote of 2memberzomorrod.company14 Nov '11 - 1:18 
GeneralRe: My vote of 2memberdmihailescu29 Nov '11 - 16:19 
QuestionDrive lettermemberedy_3dz9 Aug '11 - 10:04 
Generaldriveinfoex.dll requires administrator rights in win 7 - how to solve itmembernileshrajkot22 Apr '11 - 20:38 
GeneralMy vote of 4membernileshrajkot22 Apr '11 - 20:34 
GeneralVery nice............It has get me out of My very hard problem.......memberPritesh Aryan15 Apr '11 - 2:30 
GeneralSorry, i'm a noobmemberblthbllala18 Jan '11 - 11:17 
GeneralMy vote of 2memberMember 164379218 Dec '10 - 5:01 
GeneralRe: My vote of 2memberdmihailescu29 Nov '11 - 16:21 
GeneralSerial ID RAIDmemberbig_buka12 Dec '10 - 21:13 
Generalworks with Win7 x86 not working with xpmemberMember 437972011 Nov '10 - 1:46 
GeneralRe: works with Win7 x86 not working with xpmembernethsu28 Nov '10 - 21:54 
GeneralREAL Hard disk serial numbermemberhingman3 Nov '10 - 20:50 
GeneralRe: REAL Hard disk serial numbermemberDizZ11 Jan '11 - 3:54 
GeneralRe: REAL Hard disk serial numbermemberhingman11 Jan '11 - 16:38 
GeneralMy vote of 5memberArchit937328444829 Oct '10 - 19:33 
GeneralUnable to run on 64 bitmemberilke ALTINPULLUK26 Oct '10 - 4:12 
Questioncan we write this with c sharpmembernethsu24 Oct '10 - 23:47 
AnswerRe: can we write this with c sharpmemberdmihailescu26 Oct '10 - 16:23 
GeneralRe: can we write this with c sharpmembernethsu26 Oct '10 - 17:06 
GeneralNot Work with Framework 4.0memberkalpesh280428 Sep '10 - 22:46 
GeneralSerial No. Almost same as WMI but slightly different.memberjawahar_d24 Aug '10 - 2:32 
QuestionHdd Serial Can Change ?membergsuresh2u27 Jun '10 - 21:05 
AnswerRe: Hdd Serial Can Change ?memberdmihailescu28 Jun '10 - 13:09 
GeneralRe: Hdd Serial Can Change ?memberMember 381005013 Nov '10 - 10:37 
Generalwebservice can't get Physical HDD listmemberjavitgal22 Jun '10 - 6:23 
GeneralRe: webservice can't get Physical HDD listmemberdmihailescu22 Jun '10 - 12:53 
GeneralIOEx and DriveListEx could not be foundmembertmmomdy21 Jun '10 - 17:08 
GeneralRe: IOEx and DriveListEx could not be foundmemberdmihailescu22 Jun '10 - 12:50 
General64 bit dllmemberJosh1991184 May '10 - 22:09 
Questioninformation of external hard drives ?membergeorec11 Apr '10 - 12:17 
AnswerRe: information of external hard drives ?memberdmihailescu11 Apr '10 - 16:42 
GeneralRe: information of external hard drives ?membergeorec12 Apr '10 - 10:04 
GeneralNot Works on Vista or Win7memberHossam™ Ahmed26 Feb '10 - 14:50 
GeneralRe: Not Works on Vista or Win7memberautenje21 Jun '10 - 3:12 
GeneralRe: Not Works on Vista or Win7memberHossam™ Ahmed27 Jun '10 - 22:02 
GeneralRe: Not Works on Vista or Win7memberminregol27 Jul '10 - 2:10 
GeneralVS2008 building errorsmemberjp chow22 Feb '10 - 14:43 
GeneralRe: VS2008 building errorsmembermiliu9 May '10 - 15:28 
GeneralGreat Example!memberSlowpokee52803 Dec '09 - 11:12 

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

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