Click here to Skip to main content
16,016,527 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
The following program failed with GetLastError() returning code 50. What could be wrong? Please note the hard disk in question definitely has a serial number.


C++
BOOL GetDiskSerialNumber(std::wstring& wstSerialNumber, const TCHAR * wszPath)
{
    HANDLE hDevice = INVALID_HANDLE_VALUE;  // handle to the drive to be examined 
    BOOL bResult = FALSE;                 // results flag
    DWORD junk = 0;                     // discard results

    hDevice = CreateFileW(wszPath,          // drive to open
        0,                // no access to the drive
        FILE_SHARE_READ | // share mode
        FILE_SHARE_WRITE,
        NULL,             // default security attributes
        OPEN_EXISTING,    // disposition
        0,                // file attributes
        NULL);            // do not copy file attributes

    if (hDevice == INVALID_HANDLE_VALUE)    // cannot open the drive
    {
        return (FALSE);
    }

    STORAGE_PROPERTY_QUERY Query;
    Query.PropertyId = StorageAdapterSerialNumberProperty;
    Query.QueryType = PropertyStandardQuery;


    STORAGE_ADAPTER_SERIAL_NUMBER SNumber;
    //SNumber.Size = sizeof(STORAGE_ADAPTER_SERIAL_NUMBER);
    //SNumber.Version = sizeof(STORAGE_ADAPTER_SERIAL_NUMBER);

    bResult = DeviceIoControl(hDevice,                       // device to be queried
        IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform
        &Query, sizeof(Query),                       // no input buffer
        &SNumber, sizeof(SNumber),            // output buffer
        &junk,                         // # bytes returned
        (LPOVERLAPPED)NULL);          // synchronous I/O

    CloseHandle(hDevice);
    DWORD dwLastError;
    if (!bResult)
    {
        dwLastError = GetLastError();
    }
    wstSerialNumber = SNumber.SerialNumber;

    return (bResult);
}


What I have tried:

I came up with this code after perusing documentation because I could not get anything useful from using google search.
Posted

1 solution

DeviceIoControl returns error code 50 when the requested operation is not supported by the device: System Error Codes (0-499) (WinError.h) - Win32 apps | Microsoft Learn[^]

IIRC not all hard drives support serial numbers, so that may be your problem.

And BTW if you are planning on using this to identify your system as part of an anti-piracy policy, I'd suggest it's a pretty poor idea: not all "drives" in a system are physical (mapped to network shares, logical drives within a physical drive, etc.) and it is very, very simple update a system by fitting a larger drive and cloning the old one. Use the processor and / or motherboard instead.
 
Share this answer
 
Comments
Gbenbam 29-Apr-24 7:41am    
Do all motherboards and processors always have serial numbers?

Well in this particular case, the hard disk did have a serial number which I retrieved using WMI. The problem is that WMI some times have issues. One have to couinnitialize the main thread one and uninitialize it one at the end of the program. For that and other reasons I decided to use deviceiocontrol.
Dave Kreskowiak 29-Apr-24 9:35am    
No. Serial numbers are not required to be present by any standard.
Gbenbam 29-Apr-24 8:16am    
I remember that I tried to use this hard disk serial number anti-piracy scheme in the past and found out from multiple testing that while all branded computer system hard disk and all laptop hard disk have serial number, cloned or computers (or personally assembled computers) hard disk do not have serial numbers at all. So, I decided to use either processor or motherboard hard disk. Years back , I asked here on code project how to retrieve the motherboard serial number. I was told how to do so but was informed,also, that not all motherboards have serial number. I was advised to use Mac address because it is always there, but unfortunately it is hackable. The fellow in question went on to share with me a code on how to get mac address. That code is still here on code project. Although, I went on to use that MAC address-based anti-piracy scheme, I wanted to avoid the possibility of people by-passing my anti-piracy scheme by hacking the MAC address. This your response has made me to remember why I eventually decided against using a hard disk based anti-piracy scheme.

I may have to go back to that MAC address scheme and focus more on encryption.
Dave Kreskowiak 29-Apr-24 9:48am    
Let's clarify a bit. NO hardware is required to have serial numbers on it.

MAC addresses are NOT globally unique. The first three bytes of the MAC are the vendor identifier, which are used to id the vendor that made the adapter and maybe a product line. The last 3 bytes are the "serial number", but since that's only 3 bytes (a range of 16.7 million values,) it is entirely possible to have multiple adapters with the same MAC. You just can't have more than one copy of a MAC address on a network segment.

Oh, and nobody needs to "hack" a MAC address. There are network cards out there, or more specifically, their drivers, that will let you change the MAC address to whatever you need to avoid collisions with other cards.
Gbenbam 29-Apr-24 11:30am    
This sounds like bad news to me. So, what do you suggest?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900