Getting the motherboard's serial number

Angry Cub picture Angry Cub · Apr 18, 2017 · Viewed 13.8k times · Source

I want to bind a program to a specific computer, and for that I want to use the serial number of the motherboard as unique identifier.

Although I could find some examples for C# and Java, I couldn't find anything reliable for C++ (I read WMI can fail depending on the hardware), but surely there's a way to do this in C++ too?

Edit : What I want is, in other words, like a simple and rudimentary licensing system. To make it more clear, here's how it would look like :

#define USER_SERIAL 123456789

double GetMotherBoardSerialNumber();
// ...

double currentSerial = GetMotherBoardSerialNumber();

if(currentSerial != USER_SERIAL) {
    exit 1;
}

It is obviously not perfect, but I don't have any server atm to set up an account system so this could be a temporary solution.

Answer

djgandy picture djgandy · Apr 18, 2017

If you want real serial numbers I recommended parsing the SMBIOS table.

The first time I dived into getting reliable real hardware id's I ended up reading the SMBIOS directly from mapped Physical Memory (Windows XP). I had tried other approaches that many recommend before this but some were very unreliable and in deployment it was noted that there were duplicates across clients with some of the other methods. How could 20+ people have identical serials? It made no sense and seemed like OEM's had set fields.

From Windows Vista onwards the correct method to retrieve the table is through GetSystemFirmwareTable. This is because it is no longer possible to map Physical Memory on Windows Vista from user-mode (XP64 & Server 2003 were the same too)

GetSystemFirmwareTable can be used to get the SMBIOS data which you can then parse according to the SMBIOS spec. There's a fair amount of data in the table so generating a unique identifier shouldn't be too difficult. IIRC you generally even get serials for DRAM etc...

I would also recommend testing this thoroughly and having a backup plan if the call fails. There are instances where it just fails and having a good idea of the environment that causes failures will save you a lot of time. If my memory serves me right in the Vista days I had issues with UAC and elevated privileges, however MS may have have changed that since then!