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
20 const GUID MSSmBios_RawSMBiosTables_GUID
= SMBIOS_DATA_GUID
;
21 PVOID i8042SMBiosTables
;
43 typedef struct _MATCHENTRY
49 #define MAX_MATCH_ENTRIES 3
50 typedef struct _HARDWARE_TABLE
52 MATCHENTRY MatchEntries
[MAX_MATCH_ENTRIES
];
56 const HARDWARE_TABLE i8042HardwareTable
[] =
58 // { {{BOARD_VENDOR, "RIOWORKS"}, {BOARD_NAME, "HDAMB"}, {BOARD_VERSION, "Rev E"}}, FL_NOLOOP },
59 // { {{BOARD_VENDOR, "ASUSTeK Computer Inc."}, {BOARD_NAME, "G1S"}, {BOARD_VERSION, "1.0"}}, FL_NOLOOP },
61 { {{SYS_VENDOR
, "Microsoft Corporation"}, {SYS_PRODUCT
, "Virtual Machine"}}, FL_INITHACK
},
62 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Inspiron 6000 "}}, FL_INITHACK
},
63 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D430 "}}, FL_INITHACK
},
64 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D530 "}}, FL_INITHACK
},
65 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D531 "}}, FL_INITHACK
},
66 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D600 "}}, FL_INITHACK
},
67 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D610 "}}, FL_INITHACK
},
68 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D620 "}}, FL_INITHACK
},
69 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D630 "}}, FL_INITHACK
},
70 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude D810 "}}, FL_INITHACK
},
71 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude E4300 "}}, FL_INITHACK
},
72 { {{SYS_VENDOR
, "Dell Inc."}, {SYS_PRODUCT
, "Latitude E4310 "}}, FL_INITHACK
},
81 _In_ PDMI_HEADER Header
,
82 _In_ ULONG FieldOffset
)
87 StringIndex
= ((PUCHAR
)Header
)[FieldOffset
];
93 String
= (PCHAR
)Header
+ Header
->Length
;
95 while (--StringIndex
!= 0)
109 i8042ParseSMBiosTables(
110 _In_reads_bytes_(TableSize
) PVOID SMBiosTables
,
111 _In_ ULONG TableSize
)
113 PMSSmBios_RawSMBiosTables BiosTablesHeader
= SMBiosTables
;
115 ULONG Remaining
, i
, j
;
117 PCHAR Strings
[ID_STRINGS_MAX
] = { 0 };
119 Header
= (PDMI_HEADER
)(&BiosTablesHeader
->SMBiosData
);
120 Remaining
= BiosTablesHeader
->Size
;
122 while (Remaining
>= sizeof(*Header
))
125 if (Header
->Type
== DMI_ENTRY_END_OF_TABLE
)
128 switch (Header
->Type
)
131 if (Remaining
< DMI_BIOS_SIZE
)
133 Strings
[BIOS_VENDOR
] = GetDmiString(Header
, DMI_BIOS_VENDOR
);
134 Strings
[BIOS_VERSION
] = GetDmiString(Header
, DMI_BIOS_VERSION
);
135 Strings
[BIOS_DATE
] = GetDmiString(Header
, DMI_BIOS_DATE
);
138 case DMI_ENTRY_SYSTEM
:
139 if (Remaining
< DMI_SYS_SIZE
)
141 Strings
[SYS_VENDOR
] = GetDmiString(Header
, DMI_SYS_VENDOR
);
142 Strings
[SYS_PRODUCT
] = GetDmiString(Header
, DMI_SYS_PRODUCT
);
143 Strings
[SYS_VERSION
] = GetDmiString(Header
, DMI_SYS_VERSION
);
144 Strings
[SYS_SERIAL
] = GetDmiString(Header
, DMI_SYS_SERIAL
);
147 case DMI_ENTRY_BASEBOARD
:
148 if (Remaining
< DMI_BOARD_SIZE
)
150 Strings
[BOARD_VENDOR
] = GetDmiString(Header
, DMI_BOARD_VENDOR
);
151 Strings
[BOARD_NAME
] = GetDmiString(Header
, DMI_BOARD_NAME
);
152 Strings
[BOARD_VERSION
] = GetDmiString(Header
, DMI_BOARD_VERSION
);
153 Strings
[BOARD_SERIAL
] = GetDmiString(Header
, DMI_BOARD_SERIAL
);
154 Strings
[BOARD_ASSET_TAG
] = GetDmiString(Header
, DMI_BOARD_ASSET_TAG
);
157 case DMI_ENTRY_CHASSIS
:
158 case DMI_ENTRY_ONBOARD_DEVICE
:
159 case DMI_ENTRY_OEMSTRINGS
:
160 // DMI_ENTRY_IPMI_DEV?
161 // DMI_ENTRY_ONBOARD_DEV_EXT?
165 Remaining
-= Header
->Length
;
166 Data
= (PCHAR
)Header
+ Header
->Length
;
168 /* Now loop until we find 2 zeroes */
169 while ((Remaining
>= 2) && ((Data
[0] != 0) || (Data
[1] != 0)))
178 /* Go to the next header */
180 Header
= (PDMI_HEADER
)((PUCHAR
)Data
+ 2);
184 DbgPrint("i8042prt: Dumping DMI data:\n");
185 DbgPrint("BIOS_VENDOR: %s\n", Strings
[BIOS_VENDOR
]);
186 DbgPrint("BIOS_VERSION: %s\n", Strings
[BIOS_VERSION
]);
187 DbgPrint("BIOS_DATE: %s\n", Strings
[BIOS_DATE
]);
188 DbgPrint("SYS_VENDOR: %s\n", Strings
[SYS_VENDOR
]);
189 DbgPrint("SYS_PRODUCT: %s\n", Strings
[SYS_PRODUCT
]);
190 DbgPrint("SYS_VERSION: %s\n", Strings
[SYS_VERSION
]);
191 DbgPrint("SYS_SERIAL: %s\n", Strings
[SYS_SERIAL
]);
192 DbgPrint("BOARD_VENDOR: %s\n", Strings
[BOARD_VENDOR
]);
193 DbgPrint("BOARD_NAME: %s\n", Strings
[BOARD_NAME
]);
194 DbgPrint("BOARD_VERSION: %s\n", Strings
[BOARD_VERSION
]);
195 DbgPrint("BOARD_SERIAL: %s\n", Strings
[BOARD_SERIAL
]);
196 DbgPrint("BOARD_ASSET_TAG: %s\n", Strings
[BOARD_ASSET_TAG
]);
199 /* Now loop the hardware table to find a match */
200 for (i
= 0; i
< ARRAYSIZE(i8042HardwareTable
); i
++)
202 for (j
= 0; j
< MAX_MATCH_ENTRIES
; j
++)
204 ULONG Type
= i8042HardwareTable
[i
].MatchEntries
[j
].Type
;
208 /* Check for a match */
209 if ((Strings
[Type
] == NULL
) ||
210 strcmp(i8042HardwareTable
[i
].MatchEntries
[j
].String
,
211 Strings
[i8042HardwareTable
[i
].MatchEntries
[j
].Type
]))
213 /* Does not match, try next entry */
219 if (j
== MAX_MATCH_ENTRIES
)
221 /* All items matched! */
222 i8042HwFlags
= i8042HardwareTable
[i
].Flags
;
223 DPRINT("Found match for hw table index %u\n", i
);
231 i8042StoreSMBiosTables(
232 _In_reads_bytes_(TableSize
) PVOID SMBiosTables
,
233 _In_ ULONG TableSize
)
235 static UNICODE_STRING mssmbiosKeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\mssmbios");
236 static UNICODE_STRING DataName
= RTL_CONSTANT_STRING(L
"Data");
237 static UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(L
"SMBiosData");
238 OBJECT_ATTRIBUTES ObjectAttributes
;
239 HANDLE KeyHandle
= NULL
, SubKeyHandle
= NULL
;
242 /* Create registry key */
243 InitializeObjectAttributes(&ObjectAttributes
,
245 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
248 Status
= ZwCreateKey(&KeyHandle
,
256 if (!NT_SUCCESS(Status
))
262 InitializeObjectAttributes(&ObjectAttributes
,
264 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
267 Status
= ZwCreateKey(&SubKeyHandle
,
275 if (!NT_SUCCESS(Status
))
282 ZwSetValueKey(SubKeyHandle
,
289 ZwClose(SubKeyHandle
);
295 i8042InitializeHwHacks(
299 PVOID DataBlockObject
;
300 PWNODE_ALL_DATA AllData
;
303 /* Open the data block object for the SMBIOS table */
304 Status
= IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID
,
307 if (!NT_SUCCESS(Status
))
309 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status
);
313 /* Query the required buffer size */
315 Status
= IoWMIQueryAllData(DataBlockObject
, &BufferSize
, NULL
);
316 if (!NT_SUCCESS(Status
))
318 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status
);
322 AllData
= ExAllocatePoolWithTag(PagedPool
, BufferSize
, 'BTMS');
325 DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n", BufferSize
);
329 /* Query the buffer data */
330 Status
= IoWMIQueryAllData(DataBlockObject
, &BufferSize
, AllData
);
331 if (!NT_SUCCESS(Status
))
333 DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status
);
334 ExFreePoolWithTag(AllData
, 'BTMS');
338 /* FIXME: This function should be removed once the mssmbios driver is implemented */
339 /* Store SMBios data in registry */
340 i8042StoreSMBiosTables(AllData
+ 1,
341 AllData
->FixedInstanceSize
);
342 DPRINT1("SMBiosTables HACK, see CORE-14867\n");
344 /* Parse the table */
345 i8042ParseSMBiosTables(AllData
+ 1,
346 AllData
->WnodeHeader
.BufferSize
);
348 /* Free the buffer */
349 ExFreePoolWithTag(AllData
, 'BTMS');