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