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