[I8042PRT] Move DMI/SMBIOS parsing functions into library
[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 break;
77
78 case DMI_ENTRY_BASEBOARD:
79 if (Remaining < DMI_BOARD_SIZE)
80 return;
81 Strings[BOARD_VENDOR] = GetDmiString(Header, DMI_BOARD_VENDOR);
82 Strings[BOARD_NAME] = GetDmiString(Header, DMI_BOARD_NAME);
83 Strings[BOARD_VERSION] = GetDmiString(Header, DMI_BOARD_VERSION);
84 Strings[BOARD_SERIAL] = GetDmiString(Header, DMI_BOARD_SERIAL);
85 Strings[BOARD_ASSET_TAG] = GetDmiString(Header, DMI_BOARD_ASSET_TAG);
86 break;
87
88 case DMI_ENTRY_CHASSIS:
89 case DMI_ENTRY_ONBOARD_DEVICE:
90 case DMI_ENTRY_OEMSTRINGS:
91 // DMI_ENTRY_IPMI_DEV?
92 // DMI_ENTRY_ONBOARD_DEV_EXT?
93 break;
94 }
95
96 Remaining -= Header->Length;
97 Data = (PCHAR)Header + Header->Length;
98
99 /* Now loop until we find 2 zeroes */
100 while ((Remaining >= 2) && ((Data[0] != 0) || (Data[1] != 0)))
101 {
102 Data++;
103 Remaining--;
104 }
105
106 if (Remaining < 2)
107 break;
108
109 /* Go to the next header */
110 Remaining -= 2;
111 Header = (PDMI_HEADER)((PUCHAR)Data + 2);
112 }
113 }