Click here to Skip to main content
14,580,625 members

How to Get the BIOS UUID

Rate this:
4.98 (12 votes)
Please Sign up or sign in to vote.
4.98 (12 votes)
29 Mar 2020MIT
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.

Introduction

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.

Background

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)
    break;

  //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;
  }
  break;
}

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++;
next += 2;

data = next;

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

History

  • 27th March, 2020 Initial version

License

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

Share

About the Author

Mircea Neacsu
Canada Canada
No Biography provided

Comments and Discussions

 
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
MemberMircea 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 
AnswerRe: Structure definition Pin
Mircea Neacsu29-Mar-20 3:29
MemberMircea 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
MemberMircea 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
MemberMircea 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.

Tip/Trick
Posted 27 Mar 2020

Tagged as

Stats

8.4K views
488 downloads
22 bookmarked