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