Click here to Skip to main content
15,312,406 members
Articles / Programming Languages / C++
Posted 27 Mar 2020

Tagged as


22 bookmarked

How to Get the BIOS UUID

Rate me:
Please Sign up or sign in to vote.
4.99/5 (15 votes)
29 Mar 2020MIT2 min read
Get a unique identifier for a computer
The BIOS UUID is a unique number tied to the motherboard and if you changed your motherboard, you can safely say you changed your computer. From my point of view, it is a better method of identifying your hardware and, as I'll show you in this tip, it is very easy to implement.


In another article on this site, Michael Haephrati shows how to retrieve the hard drive serial number to be used as a unique hardware ID.

It can be up for debate how you define the "same hardware". Most people will agree that if you just change the case, it is still the same computer, while people who had to replace a hard drive because of a crash might be arguing that they are still using the same computer.

The BIOS UUID is a unique number tied to the motherboard and I feel that if you changed your motherboard, you can safely say you changed your computer. From my point of view, it is a better method of identifying your hardware and, as I'll show you, it is very easy to implement.


What most of us call "the BIOS" is technically called SMBIOS (System Management BIOS) and its specification is managed by an entity called DMTF. If you ask, those initials don't mean anything; they used to stand for Distributed Management Task Force but not any more: they are just four random letters.

The latest version of the standard can be found here and it makes for a very long and tedious reading.

The TLDR; is that the SMBIOS has a loooong collection of structures and the UUID is in the System Information table.

Getting access to the SMBIOS tables is just a call to Windows API GetSystemFirmwareTable function.

That's all there is: call GetSystemFirmwareTable function to get the start of SMBIOS tables, iterate through those tables until you find the system information table, and read the 16 bytes of UUID. The only remaining quirk is that BIOS UUID has a strange byte ordering and some bytes have to be swapped.

The Code

Everything is one single function bool biosuuid (unsigned char *uuid). If successful, it returns a 16 byte array with the BIOS UUID.

First, it calls the GetSystemFirmwareTable to retrieve the raw SMBIOS data:

DWORD size = 0;

// Get size of BIOS table
size = GetSystemFirmwareTable ('RSMB', 0, smb, size);
smb = (RawSMBIOSData*)malloc (size);

// Get BIOS table
GetSystemFirmwareTable ('RSMB', 0, smb, size);

Each BIOS block has two parts, a formatted (known length) part and an un-formatted part. The formatted part starts with a type and a length. The function goes through successive blocks until it finds the System Information block with type 0x01:

//Go through BIOS structures
data = smb->SMBIOSTableData;
while (data < smb->SMBIOSTableData + smb->Length)
  BYTE *next;
  dmi_header *h = (dmi_header*)data;

  if (h->length < 4)

  //Search for System Information structure with type 0x01 (see para 7.2)
  if (h->type == 0x01 && h->length >= 0x19)
    data += 0x08; //UUID is at offset 0x08

A valid UUID should not consist of only zeroes or only ones:

// check if there is a valid UUID (not all 0x00 or all 0xff)
bool all_zero = true, all_one = true;
for (int i = 0; i < 16 && (all_zero || all_one); i++)
  if (data[i] != 0x00) all_zero = false;
  if (data[i] != 0xFF) all_one = false;

Now we just have to copy the UUID taking care of the byte ordering issue:

  if (!all_zero && !all_one)
    /* As off version 2.6 of the SMBIOS specification, the first 3 fields
    of the UUID are supposed to be encoded on little-endian. (para 7.2.1) */
    *uuid++ = data[3];
    *uuid++ = data[2];
    *uuid++ = data[1];
    *uuid++ = data[0];
    *uuid++ = data[5];
    *uuid++ = data[4];
    *uuid++ = data[7];
    *uuid++ = data[6];
    for (int i = 8; i < 16; i++)
      *uuid++ = data[i];

    result = true;

If we haven't located the block, we have to advance to the next one skipping over the un-formatted (variable length) part of the block. The end of the un-formatted part is marked by two 0x00 bytes:

//skip over formatted area
next = data + h->length;

//skip over unformatted area of the structure (marker is 0000h)
while (next < smb->SMBIOSTableData + smb->Length && (next[0] != 0 || next[1] != 0))
next += 2;

data = next;

That's all! In 100 lines of code, you've got a unique identifier for the motherboard.


  • 27th March, 2020 Initial version


This article, along with any associated source code and files, is licensed under The MIT License


About the Author

Mircea Neacsu
Canada Canada
Mircea is an OOP (old, opinionated programmer) with more years of experience than he likes to admit. Always opened to new things, he is however too bruised to follow any passing fad.

Lately he hangs around here hoping that some of the things he learned can be useful to others.

Comments and Discussions

QuestionHow to do this on linux Pin
Member 150110463-Dec-20 5:51
MemberMember 150110463-Dec-20 5:51 
AnswerMy vote of 5 Pin
Michael Haephrati11-May-20 2:20
mvaMichael Haephrati11-May-20 2:20 
GeneralRe: My vote of 5 Pin
Mircea Neacsu12-May-20 7:38
mvaMircea Neacsu12-May-20 7:38 
GeneralMy vote of 5 Pin
Jan Heckman30-Mar-20 0:12
professionalJan Heckman30-Mar-20 0:12 
QuestionStructure definition Pin
Rene Koenig28-Mar-20 22:18
MemberRene Koenig28-Mar-20 22:18 

interesting article, thanks for sharing! A small correction, though: Your dmi_header structure definition is not quite correct. The handle at offset 2 is not a pointer, it's just a 16 bit WORD. OK, you're using the previous structure members only, so it does not really matter in this particular case, but... Wink | ;)

AnswerRe: Structure definition Pin
Mircea Neacsu29-Mar-20 3:29
mvaMircea Neacsu29-Mar-20 3:29 
GeneralMy vote of 5 Pin
Shao Voon Wong27-Mar-20 12:58
mvaShao Voon Wong27-Mar-20 12:58 
QuestionPlatform toolset? Pin
RedDk27-Mar-20 10:07
MemberRedDk27-Mar-20 10:07 
AnswerRe: Platform toolset? Pin
Mircea Neacsu27-Mar-20 10:25
mvaMircea Neacsu27-Mar-20 10:25 
PraiseMy vote of 5 Pin
Michael Haephrati27-Mar-20 7:34
mvaMichael Haephrati27-Mar-20 7:34 
GeneralRe: My vote of 5 Pin
Mircea Neacsu27-Mar-20 10:07
mvaMircea Neacsu27-Mar-20 10:07 
SuggestionAlternate Pin
dandy7227-Mar-20 5:06
Memberdandy7227-Mar-20 5:06 
PraiseRe: Alternate Pin
Peter_in_278027-Mar-20 20:35
professionalPeter_in_278027-Mar-20 20:35 
GeneralRe: Alternate Pin
dandy7228-Mar-20 3:05
Memberdandy7228-Mar-20 3:05 
GeneralRe: Alternate Pin
FiresChild30-Mar-20 4:53
MemberFiresChild30-Mar-20 4:53 
GeneralRe: Alternate Pin
dandy7230-Mar-20 5:46
Memberdandy7230-Mar-20 5:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.