reactos/drivers/input/i8042prt/hwhacks.c
Scott Maday 99a6d03786
[I8042PRT] Add Latitude D820 to the hack list (#4185)
Fixes the Dell Latitude D820 TouchPad not working.
2021-12-25 03:07:33 +01:00

241 lines
7.9 KiB
C

/*
* PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/input/i8042prt/hwhacks.c
* PURPOSE: Mouse specific functions
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
* REFERENCES: - http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
* -
*/
#include "i8042prt.h"
#include <wmiguid.h>
#include <wmidata.h>
#include <wmistr.h>
#include <dmilib.h>
#define NDEBUG
#include <debug.h>
const GUID MSSmBios_RawSMBiosTables_GUID = SMBIOS_DATA_GUID;
PVOID i8042SMBiosTables;
ULONG i8042HwFlags;
typedef struct _MATCHENTRY
{
ULONG Type;
PCHAR String;
} MATCHENTRY;
#define MAX_MATCH_ENTRIES 3
typedef struct _HARDWARE_TABLE
{
MATCHENTRY MatchEntries[MAX_MATCH_ENTRIES];
ULONG Flags;
} HARDWARE_TABLE;
const HARDWARE_TABLE i8042HardwareTable[] =
{
// { {{BOARD_VENDOR, "RIOWORKS"}, {BOARD_NAME, "HDAMB"}, {BOARD_VERSION, "Rev E"}}, FL_NOLOOP },
// { {{BOARD_VENDOR, "ASUSTeK Computer Inc."}, {BOARD_NAME, "G1S"}, {BOARD_VERSION, "1.0"}}, FL_NOLOOP },
{ {{SYS_VENDOR, "Microsoft Corporation"}, {SYS_PRODUCT, "Virtual Machine"}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Inspiron 6000 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D430 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D530 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D531 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D600 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D610 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D620 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D630 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D810 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude D820 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude E4300 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude E4310 "}}, FL_INITHACK },
{ {{SYS_VENDOR, "Dell Inc."}, {SYS_PRODUCT, "Latitude E6400 "}}, FL_INITHACK },
};
static
VOID
i8042ParseSMBiosTables(
_In_reads_bytes_(TableSize) PVOID SMBiosTables,
_In_ ULONG TableSize)
{
ULONG i, j;
PCHAR Strings[ID_STRINGS_MAX] = { 0 };
ParseSMBiosTables(SMBiosTables, TableSize, Strings);
#if 0 // DBG
DbgPrint("i8042prt: Dumping DMI data:\n");
DbgPrint("BIOS_VENDOR: %s\n", Strings[BIOS_VENDOR]);
DbgPrint("BIOS_VERSION: %s\n", Strings[BIOS_VERSION]);
DbgPrint("BIOS_DATE: %s\n", Strings[BIOS_DATE]);
DbgPrint("SYS_VENDOR: %s\n", Strings[SYS_VENDOR]);
DbgPrint("SYS_PRODUCT: %s\n", Strings[SYS_PRODUCT]);
DbgPrint("SYS_VERSION: %s\n", Strings[SYS_VERSION]);
DbgPrint("SYS_SERIAL: %s\n", Strings[SYS_SERIAL]);
DbgPrint("BOARD_VENDOR: %s\n", Strings[BOARD_VENDOR]);
DbgPrint("BOARD_NAME: %s\n", Strings[BOARD_NAME]);
DbgPrint("BOARD_VERSION: %s\n", Strings[BOARD_VERSION]);
DbgPrint("BOARD_SERIAL: %s\n", Strings[BOARD_SERIAL]);
DbgPrint("BOARD_ASSET_TAG: %s\n", Strings[BOARD_ASSET_TAG]);
#endif
/* Now loop the hardware table to find a match */
for (i = 0; i < ARRAYSIZE(i8042HardwareTable); i++)
{
for (j = 0; j < MAX_MATCH_ENTRIES; j++)
{
ULONG Type = i8042HardwareTable[i].MatchEntries[j].Type;
if (Type != ID_NONE)
{
/* Check for a match */
if ((Strings[Type] == NULL) ||
strcmp(i8042HardwareTable[i].MatchEntries[j].String,
Strings[i8042HardwareTable[i].MatchEntries[j].Type]))
{
/* Does not match, try next entry */
break;
}
}
}
if (j == MAX_MATCH_ENTRIES)
{
/* All items matched! */
i8042HwFlags = i8042HardwareTable[i].Flags;
DPRINT("Found match for hw table index %u\n", i);
break;
}
}
}
static
VOID
i8042StoreSMBiosTables(
_In_reads_bytes_(TableSize) PVOID SMBiosTables,
_In_ ULONG TableSize)
{
static UNICODE_STRING mssmbiosKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\mssmbios");
static UNICODE_STRING DataName = RTL_CONSTANT_STRING(L"Data");
static UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SMBiosData");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE KeyHandle = NULL, SubKeyHandle = NULL;
NTSTATUS Status;
/* Create registry key */
InitializeObjectAttributes(&ObjectAttributes,
&mssmbiosKeyName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwCreateKey(&KeyHandle,
KEY_WRITE,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
NULL);
if (!NT_SUCCESS(Status))
{
return;
}
/* Create sub key */
InitializeObjectAttributes(&ObjectAttributes,
&DataName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
KeyHandle,
NULL);
Status = ZwCreateKey(&SubKeyHandle,
KEY_WRITE,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
NULL);
if (!NT_SUCCESS(Status))
{
ZwClose(KeyHandle);
return;
}
/* Write value */
ZwSetValueKey(SubKeyHandle,
&ValueName,
0,
REG_BINARY,
SMBiosTables,
TableSize);
ZwClose(SubKeyHandle);
ZwClose(KeyHandle);
}
VOID
NTAPI
i8042InitializeHwHacks(
VOID)
{
NTSTATUS Status;
PVOID DataBlockObject;
PWNODE_ALL_DATA AllData;
ULONG BufferSize;
/* Open the data block object for the SMBIOS table */
Status = IoWMIOpenBlock(&MSSmBios_RawSMBiosTables_GUID,
WMIGUID_QUERY,
&DataBlockObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
return;
}
/* Query the required buffer size */
BufferSize = 0;
Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
return;
}
AllData = ExAllocatePoolWithTag(PagedPool, BufferSize, 'BTMS');
if (AllData == NULL)
{
DPRINT1("Failed to allocate %lu bytes for SMBIOS tables\n", BufferSize);
return;
}
/* Query the buffer data */
Status = IoWMIQueryAllData(DataBlockObject, &BufferSize, AllData);
if (!NT_SUCCESS(Status))
{
DPRINT1("IoWMIOpenBlock failed: 0x%08lx\n", Status);
ExFreePoolWithTag(AllData, 'BTMS');
return;
}
/* FIXME: This function should be removed once the mssmbios driver is implemented */
/* Store SMBios data in registry */
i8042StoreSMBiosTables(AllData + 1,
AllData->FixedInstanceSize);
DPRINT1("SMBiosTables HACK, see CORE-14867\n");
/* Parse the table */
i8042ParseSMBiosTables(AllData + 1,
AllData->WnodeHeader.BufferSize);
/* Free the buffer */
ExFreePoolWithTag(AllData, 'BTMS');
}