Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HDD serial number flipped every 2 bytes in Windows XP, Vista and 7 but not in Windows 8

I need to get HDD serial number to use it as a key for licensing a software. I used diskid32 code in this url: http://www.winsim.com/diskid32/diskid32.html It used the DeviceIoControl Win32 API with the IO control code of IOCTL_STORAGE_QUERY_PROPERTY.

It worked. However, when I double check with the actual serial number printed on the HDD itself, I found that every 2 bytes of the number was flipped.

A simple solution could be to simply flip the bytes back. It worked in Windows XP, Vista and 7 but in windows 8 not need to be flipped!

I wish to know the exact reason why the bytes were flipped in Windows XP, Vista and 7, and why not flipped in Windows 8. What about next Windows?

Part of code with minor changes:

  int drive = 0;
  HANDLE hPhysicalDriveIOCTL = 0;
  char driveName [256];
  sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
  //  Windows NT, Windows 2000, Windows XP - admin rights not required
  hPhysicalDriveIOCTL = CreateFile (driveName, 0,
                           FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                           OPEN_EXISTING, 0, NULL);
  if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
  {
     _STORAGE_PROPERTY_QUERY query;
     DWORD cbBytesReturned = 0;
     char buffer [10000];

     memset ((void *) & query, 0, sizeof (query));
     query.PropertyId = StorageDeviceProperty;
     query.QueryType = PropertyStandardQuery;

     memset (buffer, 0, sizeof (buffer));

     if ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
               & query,
               sizeof (query),
               & buffer,
               sizeof (buffer),
               & cbBytesReturned, NULL) )
     {
         _STORAGE_DEVICE_DESCRIPTOR * descrip = (_STORAGE_DEVICE_DESCRIPTOR *) & buffer;
         char serialNumber [1000];
         char modelNumber [1000];
         char vendorId [1000];
         char productRevision [1000];

         flipAndCodeBytes (buffer,
                           descrip -> SerialNumberOffset,
                           1, serialNumber );

        ...
     }
like image 926
A.Danesh Avatar asked Jan 31 '13 10:01

A.Danesh


People also ask

How do I find my hard drive serial number Windows XP?

For XP, navigate: start>control panel>system, select the 'hardware' tab>device manager, expand 'disk drives' then right click on the hdd in question. select properties then click the 'details' tab. from the drop down box select 'hardware ids' and bingo.....

Where is my ssd serial number?

Serial Number is on a separate label and is on the bottom of the SSD. Main label can be on the top or bottom of the SSD.


2 Answers

I use the same approach (and same code) in my software licensing. Yes, Windows 8 for some reason is returning flipped values for this method, I can't say why (so I can't answer your question).

My solution is the one that you pointed out: Flip the values again. So, after calling the "flipAndCodeBytes", you could test if is a Windows 8 OS, and flip the values.

In my case, it's working now (I got the same values for Windows XP/Vista/7 and Windows 8).

Good luck!

like image 71
cunhaw Avatar answered Sep 20 '22 22:09

cunhaw


Just turn off the flip using the "flip" flag of the flibAndCodeBytes function when windows 8 or greater.

bool shoulFlipBytes = true;
if(IsWin8OrLater()) shouldFlipBytes = false;

flipAndCodeBytes(buffer,
                 descrip->SerialNumberOffset,
                 shouldFlipBytes,
                 serialNumber);

You can use this to check for windows version:

#include <windows.h>

bool IsWin8OrLater() {
    DWORD version = GetVersion();
    DWORD major = (DWORD) (LOBYTE(LOWORD(version)));
    DWORD minor = (DWORD) (HIBYTE(LOWORD(version)));

    return (major > 6) || ((major == 6) && (minor >= 2));
}

According to http://msdn.microsoft.com/en-us/library/ms724832%28VS.85%29.aspx (Thanks to ChrisV Determine if O/S is Windows 7)

like image 27
zajac.m2 Avatar answered Sep 18 '22 22:09

zajac.m2