xref: /reactos/drivers/input/i8042prt/hwhacks.c (revision cce399e7)
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
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
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
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