[I8042PRT] Add Latitude E6400 to the hack list (#1665)
[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 { {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude E6400 "}}, FL_INITHACK },
55
56 };
57
58
59
60 static
61 VOID
62 i8042ParseSMBiosTables(
63 _In_reads_bytes_(TableSize) PVOID SMBiosTables,
64 _In_ ULONG TableSize)
65 {
66 ULONG i, j;
67 PCHAR Strings[ID_STRINGS_MAX] = { 0 };
68
69 ParseSMBiosTables(SMBiosTables, TableSize, Strings);
70
71 #if 0 // DBG
72 DbgPrint("i8042prt: Dumping DMI data:\n");
73 DbgPrint("BIOS_VENDOR: %s\n", Strings[BIOS_VENDOR]);
74 DbgPrint("BIOS_VERSION: %s\n", Strings[BIOS_VERSION]);
75 DbgPrint("BIOS_DATE: %s\n", Strings[BIOS_DATE]);
76 DbgPrint("SYS_VENDOR: %s\n", Strings[SYS_VENDOR]);
77 DbgPrint("SYS_PRODUCT: %s\n", Strings[SYS_PRODUCT]);
78 DbgPrint("SYS_VERSION: %s\n", Strings[SYS_VERSION]);
79 DbgPrint("SYS_SERIAL: %s\n", Strings[SYS_SERIAL]);
80 DbgPrint("BOARD_VENDOR: %s\n", Strings[BOARD_VENDOR]);
81 DbgPrint("BOARD_NAME: %s\n", Strings[BOARD_NAME]);
82 DbgPrint("BOARD_VERSION: %s\n", Strings[BOARD_VERSION]);
83 DbgPrint("BOARD_SERIAL: %s\n", Strings[BOARD_SERIAL]);
84 DbgPrint("BOARD_ASSET_TAG: %s\n", Strings[BOARD_ASSET_TAG]);
85 #endif
86
87 /* Now loop the hardware table to find a match */
88 for (i = 0; i < ARRAYSIZE(i8042HardwareTable); i++)
89 {
90 for (j = 0; j < MAX_MATCH_ENTRIES; j++)
91 {
92 ULONG Type = i8042HardwareTable[i].MatchEntries[j].Type;
93
94 if (Type != ID_NONE)
95 {
96 /* Check for a match */
97 if ((Strings[Type] == NULL) ||
98 strcmp(i8042HardwareTable[i].MatchEntries[j].String,
99 Strings[i8042HardwareTable[i].MatchEntries[j].Type]))
100 {
101 /* Does not match, try next entry */
102 break;
103 }
104 }
105 }
106
107 if (j == MAX_MATCH_ENTRIES)
108 {
109 /* All items matched! */
110 i8042HwFlags = i8042HardwareTable[i].Flags;
111 DPRINT("Found match for hw table index %u\n", i);
112 break;
113 }
114 }
115 }
116
117 static
118 VOID
119 i8042StoreSMBiosTables(
120 _In_reads_bytes_(TableSize) PVOID SMBiosTables,
121 _In_ ULONG TableSize)
122 {
123 static UNICODE_STRING mssmbiosKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\mssmbios");
124 static UNICODE_STRING DataName = RTL_CONSTANT_STRING(L"Data");
125 static UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SMBiosData");
126 OBJECT_ATTRIBUTES ObjectAttributes;
127 HANDLE KeyHandle = NULL, SubKeyHandle = NULL;
128 NTSTATUS Status;
129
130 /* Create registry key */
131 InitializeObjectAttributes(&ObjectAttributes,
132 &mssmbiosKeyName,
133 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
134 NULL,
135 NULL);
136 Status = ZwCreateKey(&KeyHandle,
137 KEY_WRITE,
138 &ObjectAttributes,
139 0,
140 NULL,
141 REG_OPTION_VOLATILE,
142 NULL);
143
144 if (!NT_SUCCESS(Status))
145 {
146 return;
147 }
148
149 /* Create sub key */
150 InitializeObjectAttributes(&ObjectAttributes,
151 &DataName,
152 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
153 KeyHandle,
154 NULL);
155 Status = ZwCreateKey(&SubKeyHandle,
156 KEY_WRITE,
157 &ObjectAttributes,
158 0,
159 NULL,
160 REG_OPTION_VOLATILE,
161 NULL);
162
163 if (!NT_SUCCESS(Status))
164 {
165 ZwClose(KeyHandle);
166 return;
167 }
168
169 /* Write value */
170 ZwSetValueKey(SubKeyHandle,
171 &ValueName,
172 0,
173 REG_BINARY,
174 SMBiosTables,
175 TableSize);
176
177 ZwClose(SubKeyHandle);
178 ZwClose(KeyHandle);
179 }
180
181 VOID
182 NTAPI
183 i8042InitializeHwHacks(
184 VOID)
185 {
186 NTSTATUS Status;
187 PVOID DataBlockObject;
188 PWNODE_ALL_DATA AllData;
189 ULONG BufferSize;
190
191 /* Open the data block object for the SMBIOS table */
192 Status = IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID,
193 WMIGUID_QUERY,
194 &DataBlockObject);
195 if (!NT_SUCCESS(Status))
196 {
197 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
198 return;
199 }
200
201 /* Query the required buffer size */
202 BufferSize = 0;
203 Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, NULL);
204 if (!NT_SUCCESS(Status))
205 {
206 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
207 return;
208 }
209
210 AllData = ExAllocatePoolWithTag(PagedPool, BufferSize, 'BTMS');
211 if (AllData == NULL)
212 {
213 DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n", BufferSize);
214 return;
215 }
216
217 /* Query the buffer data */
218 Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, AllData);
219 if (!NT_SUCCESS(Status))
220 {
221 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
222 ExFreePoolWithTag(AllData, 'BTMS');
223 return;
224 }
225
226 /* FIXME: This function should be removed once the mssmbios driver is implemented */
227 /* Store SMBios data in registry */
228 i8042StoreSMBiosTables(AllData + 1,
229 AllData->FixedInstanceSize);
230 DPRINT1("SMBiosTables HACK, see CORE-14867\n");
231
232 /* Parse the table */
233 i8042ParseSMBiosTables(AllData + 1,
234 AllData->WnodeHeader.BufferSize);
235
236 /* Free the buffer */
237 ExFreePoolWithTag(AllData, 'BTMS');
238 }
239