WinAPI: How to Get Hard Disk Serial Number?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1

Thread: WinAPI: How to Get Hard Disk Serial Number?

Hybrid View

  1. #1
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,051

    WinAPI: How to Get Hard Disk Serial Number?

    Q: How to programmatically get the serial number assigned to a hard disk (or another type of physical drive) by the manufacturer?

    A: One solution is to call DeviceIoControl function with IOCTL_STORAGE_QUERY_PROPERTY control code.

    Example
    Code:
    #include <Windows.h>
    #include <atlstr.h>
    
    DWORD GetPhysicalDriveSerialNumber(UINT nDriveNumber, CString& strSerialNumber)
    {
        DWORD dwResult = NO_ERROR;
        strSerialNumber.Empty();
    
        // Format physical drive path (may be '\\.\PhysicalDrive0', '\\.\PhysicalDrive1' and so on).
        CString strDrivePath;
        strDrivePath.Format(_T("\\\\.\\PhysicalDrive%u"), nDriveNumber);
    
        // call CreateFile to get a handle to physical drive
        HANDLE hDevice = ::CreateFile(strDrivePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL, OPEN_EXISTING, 0, NULL);
    
        if(INVALID_HANDLE_VALUE == hDevice)
            return ::GetLastError();
    
        // set the input STORAGE_PROPERTY_QUERY data structure
        STORAGE_PROPERTY_QUERY storagePropertyQuery;
        ZeroMemory(&storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY));
        storagePropertyQuery.PropertyId = StorageDeviceProperty;
        storagePropertyQuery.QueryType = PropertyStandardQuery;
    
        // get the necessary output buffer size
        STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = { 0 };
        DWORD dwBytesReturned = 0;
        if(!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
            &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
            &storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER),
            &dwBytesReturned, NULL))
        {
            dwResult = ::GetLastError();
            ::CloseHandle(hDevice);
            return dwResult;
        }
    
        // allocate the necessary memory for the output buffer
        const DWORD dwOutBufferSize = storageDescriptorHeader.Size;
        BYTE* pOutBuffer = new BYTE[dwOutBufferSize];
        ZeroMemory(pOutBuffer, dwOutBufferSize);
    
        // get the storage device descriptor
        if (!::DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY,
            &storagePropertyQuery, sizeof(STORAGE_PROPERTY_QUERY),
            pOutBuffer, dwOutBufferSize,
            &dwBytesReturned, NULL))
        {
            dwResult = ::GetLastError();
            delete[]pOutBuffer;
            ::CloseHandle(hDevice);
            return dwResult;
        }
    
        // Now, the output buffer points to a STORAGE_DEVICE_DESCRIPTOR structure
        // followed by additional info like vendor ID, product ID, serial number, and so on.
        STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pOutBuffer;
        const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset;
        if (dwSerialNumberOffset != 0)
        {
            // finally, get the serial number
            strSerialNumber = CString(pOutBuffer + dwSerialNumberOffset);
        }
    
        // perform cleanup and return
        delete[]pOutBuffer;
        ::CloseHandle(hDevice);
        return dwResult;
    }
    Code:
        // ...
        UINT nDriveNumber = 0;
        CString strSerialNumber;
        DWORD dwResult = GetPhysicalDriveSerialNumber(nDriveNumber, strSerialNumber);
        CString strReport;
        if (NO_ERROR == dwResult)
        {
            strReport.Format(_T("Drive #%u serial number: '%s'"), nDriveNumber, strSerialNumber);
        }
        else
        {
            strReport.Format(_T("GetPhysicalDriveSerialNumber failed. Error: %u"), dwResult);
        }
        ::MessageBox(NULL, strReport, _T("Test"), MB_OK);
    Resources and related articles
    Last edited by ovidiucucu; June 14th, 2014 at 09:21 AM.
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center