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