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