By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,824 Members | 1,255 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,824 IT Pros & Developers. It's quick & easy.

Get the Serial number of the hard disk

Airslash
100+
P: 221
Hello,

I've written a class that resembles a hard drive. I'm already able using the Windows API to get information such as the remaining free bytes, the sectors and clusters,a nd it all works fine.

The last step that I need is to obtain the serial number of the harddrive in question. From what I can understand in the MSDN library you need to take into account that a Volume can span multiple disks etc, but I don't wanne waste time on that right now, I'd just be happy if I can read the serial number of a single disk.

That kept in mind, i've written a function that retrieves all the data I need, i'm just a bit scared about the part for retrieving the serial. I've read somewhere that I need a VOLUME_DISK_EXTENTS structure and use a 20bytes offset and 20 bytes length to read the serial number.

I've come up with this code so far:
Expand|Select|Wrap|Line Numbers
  1. bool BigBrother::IO::Drive::LoadDriveData() const
  2. {
  3.     // Create the return values
  4.     bool ResultOne, ResultTwo, ResultThree;
  5.  
  6.     // Create the UNC compatible root of the drive.
  7.     AnsiString root = AnsiString(mDriveLetter) + ":\\";
  8.  
  9.     // Set all the datamembers to 0 first, so that we have clean
  10.     // values to work with.
  11.     mSectorsPerCluster = 0;
  12.     mBytesPerSector = 0;
  13.     mFreeClusters = 0;
  14.     mTotalClusters = 0;
  15.     mTotalBytes = 0;
  16.     mFreeBytes = 0;
  17.  
  18.     // Use the Windows API to fill the datamembers. Store the result
  19.     // of the API call in a boolean.
  20.     ResultOne = ::GetDiskFreeSpace(root.c_str(), &mSectorsPerCluster, &mBytesPerSector, &mFreeClusters, &mTotalClusters);
  21.     ResultTwo = ::GetDiskFreeSpaceEx(root.c_str(), 0, (_ULARGE_INTEGER *)&mTotalBytes, (_ULARGE_INTEGER *)&mFreeBytes);
  22.  
  23.     // Calculate the AllocationUnitSiwe of the disk.
  24.     mAllocationUnitSize = (mBytesPerSector * mSectorsPerCluster);
  25.  
  26.     // Create the string to point to our device.
  27.     AnsiString DeviceString = "\\\\.\\" + AnsiString(mDriveLetter) + ":";
  28.  
  29.     // Create a handle to our drive, so we can pass this further down in the
  30.     // Windows API to retrieve the windows Serial.
  31.     HANDLE DriveHandle = ::CreateFileA(DeviceString.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ |FILE_SHARE_WRITE, OPEN_EXISTING, 0, 0);
  32.  
  33.     // Check if the handle is valid before continuing down this path.
  34.     if(DriveHandle != INVALID_HANDLE_VALUE)
  35.     {
  36.         // Create a COLUME_DISK_EXTENTS structure and read the info about the drive.
  37.         VOLUME_DISK_EXTENTS VolumeInfo;
  38.         long BytesRead;
  39.         ResultThree = ::DeviceIoControl(DriveHandle, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, &VolumeInfo, sizeof(VolumeInfo), &BytesReturned, 0);
  40.  
  41.         // Copy the serial number to our datamember.
  42.         // We need to offset the extend with 20 and read a length of 20 bytes to get the entire serial.
  43.         memcpy(&mSerial, VolumeInfo->StartingOffset + 0x20, 0x20);
  44.     }
  45.     // Return the logical result of the Windows API calls.
  46.     return (ResultOne && ResultTwo);
  47. }
  48.  
Can someone who has done this before, explain to me if i'm using the VOLUME_DISK_EXTENTS struct properly, or if I'm missing the ball completly?
Mar 10 '10 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.