1 /* 2 * PROJECT: ReactOS DMI/SMBIOS Library 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dmilib.c 5 * PURPOSE: SMBIOS table parsing functions 6 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) 7 * REFERENCES: http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf 8 */ 9 10 #include "precomp.h" 11 12 static 13 PCHAR 14 GetDmiString( 15 _In_ PDMI_HEADER Header, 16 _In_ ULONG FieldOffset) 17 { 18 ULONG StringIndex; 19 PCHAR String; 20 21 StringIndex = ((PUCHAR)Header)[FieldOffset]; 22 if (StringIndex == 0) 23 { 24 return NULL; 25 } 26 27 String = (PCHAR)Header + Header->Length; 28 29 while (--StringIndex != 0) 30 { 31 while (*String != 0) 32 String++; 33 34 String++; 35 } 36 37 return String; 38 } 39 40 VOID 41 ParseSMBiosTables( 42 _In_reads_bytes_(TableSize) PVOID SMBiosTables, 43 _In_ ULONG TableSize, 44 _Inout_updates_(ID_STRINGS_MAX) PCHAR * Strings) 45 { 46 PMSSmBios_RawSMBiosTables BiosTablesHeader = SMBiosTables; 47 PDMI_HEADER Header; 48 ULONG Remaining; 49 PCHAR Data; 50 51 Header = (PDMI_HEADER)(&BiosTablesHeader->SMBiosData); 52 Remaining = BiosTablesHeader->Size; 53 54 while (Remaining >= sizeof(*Header)) 55 { 56 if (Header->Type == DMI_ENTRY_END_OF_TABLE) 57 break; 58 59 switch (Header->Type) 60 { 61 case DMI_ENTRY_BIOS: 62 if (Remaining < DMI_BIOS_SIZE) 63 return; 64 Strings[BIOS_VENDOR] = GetDmiString(Header, DMI_BIOS_VENDOR); 65 Strings[BIOS_VERSION] = GetDmiString(Header, DMI_BIOS_VERSION); 66 Strings[BIOS_DATE] = GetDmiString(Header, DMI_BIOS_DATE); 67 break; 68 69 case DMI_ENTRY_SYSTEM: 70 if (Remaining < DMI_SYS_SIZE) 71 return; 72 Strings[SYS_VENDOR] = GetDmiString(Header, DMI_SYS_VENDOR); 73 Strings[SYS_PRODUCT] = GetDmiString(Header, DMI_SYS_PRODUCT); 74 Strings[SYS_VERSION] = GetDmiString(Header, DMI_SYS_VERSION); 75 Strings[SYS_SERIAL] = GetDmiString(Header, DMI_SYS_SERIAL); 76 Strings[SYS_SKU] = GetDmiString(Header, DMI_SYS_SKU); 77 Strings[SYS_FAMILY] = GetDmiString(Header, DMI_SYS_FAMILY); 78 break; 79 80 case DMI_ENTRY_BASEBOARD: 81 if (Remaining < DMI_BOARD_SIZE) 82 return; 83 Strings[BOARD_VENDOR] = GetDmiString(Header, DMI_BOARD_VENDOR); 84 Strings[BOARD_NAME] = GetDmiString(Header, DMI_BOARD_NAME); 85 Strings[BOARD_VERSION] = GetDmiString(Header, DMI_BOARD_VERSION); 86 Strings[BOARD_SERIAL] = GetDmiString(Header, DMI_BOARD_SERIAL); 87 Strings[BOARD_ASSET_TAG] = GetDmiString(Header, DMI_BOARD_ASSET_TAG); 88 break; 89 90 case DMI_ENTRY_CHASSIS: 91 case DMI_ENTRY_ONBOARD_DEVICE: 92 case DMI_ENTRY_OEMSTRINGS: 93 // DMI_ENTRY_IPMI_DEV? 94 // DMI_ENTRY_ONBOARD_DEV_EXT? 95 break; 96 } 97 98 Remaining -= Header->Length; 99 Data = (PCHAR)Header + Header->Length; 100 101 /* Now loop until we find 2 zeroes */ 102 while ((Remaining >= 2) && ((Data[0] != 0) || (Data[1] != 0))) 103 { 104 Data++; 105 Remaining--; 106 } 107 108 if (Remaining < 2) 109 break; 110 111 /* Go to the next header */ 112 Remaining -= 2; 113 Header = (PDMI_HEADER)((PUCHAR)Data + 2); 114 } 115 } 116