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