[I8042PRT] Move DMI/SMBIOS parsing functions into library
[reactos.git] / drivers / input / i8042prt / hwhacks.c
1 /*
2 * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/i8042prt/hwhacks.c
5 * PURPOSE: Mouse specific 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
11 #include "i8042prt.h"
12 #include <wmiguid.h>
13 #include <wmidata.h>
14 #include <wmistr.h>
15 #include <dmilib.h>
16
17 #define NDEBUG
18 #include <debug.h>
19
20 const GUID MSSmBios_RawSMBiosTables_GUID = SMBIOS_DATA_GUID;
21 PVOID i8042SMBiosTables;
22 ULONG i8042HwFlags;
23
24 typedef struct _MATCHENTRY
25 {
26 ULONG Type;
27 PCHAR String;
28 } MATCHENTRY;
29
30 #define MAX_MATCH_ENTRIES 3
31 typedef struct _HARDWARE_TABLE
32 {
33 MATCHENTRY MatchEntries[MAX_MATCH_ENTRIES];
34 ULONG Flags;
35 } HARDWARE_TABLE;
36
37 const HARDWARE_TABLE i8042HardwareTable[] =
38 {
39 // { {{BOARD_VENDOR, "RIOWORKS"}, {BOARD_NAME, "HDAMB"}, {BOARD_VERSION, "Rev E"}}, FL_NOLOOP },
40 // { {{BOARD_VENDOR, "ASUSTeK Computer Inc."}, {BOARD_NAME, "G1S"}, {BOARD_VERSION, "1.0"}}, FL_NOLOOP },
41
42 { {{SYS_VENDOR, "Microsoft Corporation"}, {SYS_PRODUCT, "Virtual Machine"}}, FL_INITHACK },
43 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Inspiron 6000 "}}, FL_INITHACK },
44 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D430 "}}, FL_INITHACK },
45 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D530 "}}, FL_INITHACK },
46 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D531 "}}, FL_INITHACK },
47 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D600 "}}, FL_INITHACK },
48 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D610 "}}, FL_INITHACK },
49 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D620 "}}, FL_INITHACK },
50 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D630 "}}, FL_INITHACK },
51 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D810 "}}, FL_INITHACK },
52 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude E4300 "}}, FL_INITHACK },
53 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude E4310 "}}, FL_INITHACK },
54
55 };
56
57
58
59 static
60 VOID
61 i8042ParseSMBiosTables(
62 _In_reads_bytes_(TableSize) PVOID SMBiosTables,
63 _In_ ULONG TableSize)
64 {
65 ULONG i, j;
66 PCHAR Strings[ID_STRINGS_MAX] = { 0 };
67
68 ParseSMBiosTables(SMBiosTables, TableSize, Strings);
69
70 #if 0 // DBG
71 DbgPrint("i8042prt: Dumping DMI data:\n");
72 DbgPrint("BIOS_VENDOR: %s\n", Strings[BIOS_VENDOR]);
73 DbgPrint("BIOS_VERSION: %s\n", Strings[BIOS_VERSION]);
74 DbgPrint("BIOS_DATE: %s\n", Strings[BIOS_DATE]);
75 DbgPrint("SYS_VENDOR: %s\n", Strings[SYS_VENDOR]);
76 DbgPrint("SYS_PRODUCT: %s\n", Strings[SYS_PRODUCT]);
77 DbgPrint("SYS_VERSION: %s\n", Strings[SYS_VERSION]);
78 DbgPrint("SYS_SERIAL: %s\n", Strings[SYS_SERIAL]);
79 DbgPrint("BOARD_VENDOR: %s\n", Strings[BOARD_VENDOR]);
80 DbgPrint("BOARD_NAME: %s\n", Strings[BOARD_NAME]);
81 DbgPrint("BOARD_VERSION: %s\n", Strings[BOARD_VERSION]);
82 DbgPrint("BOARD_SERIAL: %s\n", Strings[BOARD_SERIAL]);
83 DbgPrint("BOARD_ASSET_TAG: %s\n", Strings[BOARD_ASSET_TAG]);
84 #endif
85
86 /* Now loop the hardware table to find a match */
87 for (i = 0; i < ARRAYSIZE(i8042HardwareTable); i++)
88 {
89 for (j = 0; j < MAX_MATCH_ENTRIES; j++)
90 {
91 ULONG Type = i8042HardwareTable[i].MatchEntries[j].Type;
92
93 if (Type != ID_NONE)
94 {
95 /* Check for a match */
96 if ((Strings[Type] == NULL) ||
97 strcmp(i8042HardwareTable[i].MatchEntries[j].String,
98 Strings[i8042HardwareTable[i].MatchEntries[j].Type]))
99 {
100 /* Does not match, try next entry */
101 break;
102 }
103 }
104 }
105
106 if (j == MAX_MATCH_ENTRIES)
107 {
108 /* All items matched! */
109 i8042HwFlags = i8042HardwareTable[i].Flags;
110 DPRINT("Found match for hw table index %u\n", i);
111 break;
112 }
113 }
114 }
115
116 static
117 VOID
118 i8042StoreSMBiosTables(
119 _In_reads_bytes_(TableSize) PVOID SMBiosTables,
120 _In_ ULONG TableSize)
121 {
122 static UNICODE_STRING mssmbiosKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\mssmbios");
123 static UNICODE_STRING DataName = RTL_CONSTANT_STRING(L"Data");
124 static UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SMBiosData");
125 OBJECT_ATTRIBUTES ObjectAttributes;
126 HANDLE KeyHandle = NULL, SubKeyHandle = NULL;
127 NTSTATUS Status;
128
129 /* Create registry key */
130 InitializeObjectAttributes(&ObjectAttributes,
131 &mssmbiosKeyName,
132 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
133 NULL,
134 NULL);
135 Status = ZwCreateKey(&KeyHandle,
136 KEY_WRITE,
137 &ObjectAttributes,
138 0,
139 NULL,
140 REG_OPTION_VOLATILE,
141 NULL);
142
143 if (!NT_SUCCESS(Status))
144 {
145 return;
146 }
147
148 /* Create sub key */
149 InitializeObjectAttributes(&ObjectAttributes,
150 &DataName,
151 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
152 KeyHandle,
153 NULL);
154 Status = ZwCreateKey(&SubKeyHandle,
155 KEY_WRITE,
156 &ObjectAttributes,
157 0,
158 NULL,
159 REG_OPTION_VOLATILE,
160 NULL);
161
162 if (!NT_SUCCESS(Status))
163 {
164 ZwClose(KeyHandle);
165 return;
166 }
167
168 /* Write value */
169 ZwSetValueKey(SubKeyHandle,
170 &ValueName,
171 0,
172 REG_BINARY,
173 SMBiosTables,
174 TableSize);
175
176 ZwClose(SubKeyHandle);
177 ZwClose(KeyHandle);
178 }
179
180 VOID
181 NTAPI
182 i8042InitializeHwHacks(
183 VOID)
184 {
185 NTSTATUS Status;
186 PVOID DataBlockObject;
187 PWNODE_ALL_DATA AllData;
188 ULONG BufferSize;
189
190 /* Open the data block object for the SMBIOS table */
191 Status = IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID,
192 WMIGUID_QUERY,
193 &DataBlockObject);
194 if (!NT_SUCCESS(Status))
195 {
196 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
197 return;
198 }
199
200 /* Query the required buffer size */
201 BufferSize = 0;
202 Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, NULL);
203 if (!NT_SUCCESS(Status))
204 {
205 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
206 return;
207 }
208
209 AllData = ExAllocatePoolWithTag(PagedPool, BufferSize, 'BTMS');
210 if (AllData == NULL)
211 {
212 DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n", BufferSize);
213 return;
214 }
215
216 /* Query the buffer data */
217 Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, AllData);
218 if (!NT_SUCCESS(Status))
219 {
220 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
221 ExFreePoolWithTag(AllData, 'BTMS');
222 return;
223 }
224
225 /* FIXME: This function should be removed once the mssmbios driver is implemented */
226 /* Store SMBios data in registry */
227 i8042StoreSMBiosTables(AllData + 1,
228 AllData->FixedInstanceSize);
229 DPRINT1("SMBiosTables HACK, see CORE-14867\n");
230
231 /* Parse the table */
232 i8042ParseSMBiosTables(AllData + 1,
233 AllData->WnodeHeader.BufferSize);
234
235 /* Free the buffer */
236 ExFreePoolWithTag(AllData, 'BTMS');
237 }
238