SMBIOS Demystified

Contents

Introduction

SMBIOS stands for System Management BIOS. It is a way for system vendors to present data about their system without having to resort to querying hardware and so forth. To make the experience of getting this information easy for users, there is a commonly agreed-upon specification. This SMBIOS specification can be found here.

SMBIOS Data Format

The SMBIOS data format is straightforward. However, it can be slightly tricky to understand it and, unfortunately, I could find no info on the Internet, except for the specification, on how to interpret it. This article is intended to demystify it.

Now, to the details.

  • SMBIOS data is a simple table of entries. Each entry is called a structure.
  • There is no fixed number of structures. In other words, the number of structures in the table can vary.
  • All structures are placed one after another and are packed closely; there is no padding data between two consecutive structures.
  • Each structure size is a multiple of byte length. The SMBIOS table is not bit packed; this makes it simple to navigate.
  • Each structure has a mandatory part called a structure header that has a fixed length.
  • Each structure is identified by a type.
  • Some structures are mandatory.
  • Some structure types will and should occur only once.
  • Some structure types can occur more than once.
  • Each structure has a formatted section containing, at a minimum, the header.
  • A structure could have an unformatted section. The unformatted section could contain proprietary information, OEM specific data, or it could contain string data.

The following figure shows a graphic representation of the SMBIOS table.

More about the structure

The structure, as you can see, has a mandatory header occupying the following four bytes.

Type: The first byte identifies the type of the stucture. For example, type 0 indicates a BIOS information structure; type 1 indicates a System Information structure, and so on. These details can be obtained from the specification (see the References section).

Length of formatted section: The second bytes contain the length of a section of data called the formatted section. The formatted section contains any data that is fixed length for the type of structure. For predefined types, the details on the formatted section can be found in the specifications.

Handle: A 2-byte–length field.

Unformatted section: An unformatted section can follow the formatted section. This section can contain variable length data like strings or OEM-specific data. The interesting part here is the string data. The strings are ANSI strings and they are arranged as a table of NULL-terminated strings. Any fields in the formatted section that refer to strings shall indicate so by specifying the index of the string in this table.

For example, if the structure were so defined:

DDh ; example fictitous type
05h ; length of formatted section
12h ;
34h ; 2 bytes of handle
01h ; index of fictitous string data in string table
41h ; 'A'
42h ; 'B'
43h ; 'C'
44h ; 'D'
00h ; '\0'
00h ; END OF STRUCTURE

For this structure, if one were to try to get the string corresponding to the fictitous string data, one would navigate to the byte at a distance of 05h (length of the formatted section) from the start of the structure, and then look for 01th (01 being the index for the fictitous string data field) string until one hits the end of the structure.

The following picture explains it better.

SMBIOS Data Retrieval Using WMI

SMBIOS data can be retrieved for the system in two ways:

SMBIOS Parser Sample

The attached sample is a simple SMBIOS parser. When executed, the parser simply queries for SMBIOS data using WMI, parses it, and then fills a combo box with a list of structures encountered while parsing. When one selects a structure from the combo box, the corresponding location of the structure is highlighted on the right hand side and for a few types. The individual structure’s parsed data is shown in the window below.

The parser provides a few methods to parse info for selected few types, such as SMBIOS table types 0,1,2,3,4,11

A snapshot of the parser is shown below:

For ease, the whole parsing has been wrapped under a class called SMBiosData whose public interface is below:

class SMBiosData
{
public:
   //used to query the system for BIOS data. This is usually the
   //first method used.
   BOOL FetchSMBiosData();
   //used to enumerate the fetched data to get the number of structures
   void EnumTables(DWORD dwParam, ENUMPROC pfnEnumProc);

   //used to query for specific structures
   BOOL GetData(SMBios_TYPE0&  stSMBiosType0);
   BOOL GetData(SMBios_TYPE1&  stSMBiosType1);
   BOOL GetData(SMBios_TYPE2&  stSMBiosType2);
   BOOL GetData(SMBios_TYPE3&  stSMBiosType3);
   BOOL GetData(SMBios_TYPE4&  stSMBiosType4);
   BOOL GetData(SMBios_TYPE11& stSMBiosType11);

   //in case of some structures, it is easier to query by index,
   //because there could be multiple structures with the same type.
   //The method below can be used in such cases
   BYTE*   GetTableByIndex(BYTE byIndex,DWORD& dwTotalTableSize);

};

The sample code in the parser could serve as a good starting point to extend it to parse any other table types. I leave it as an exercise for interested readers.

References

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read