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