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