[DMILIB] Process SKU and Family strings
[reactos.git] / sdk / lib / dmilib / dmilib.c
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 }