|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "Compatibility.h" |
|
8 |
|
9 #include "nsWinUtils.h" |
|
10 #include "Statistics.h" |
|
11 |
|
12 #include "mozilla/Preferences.h" |
|
13 |
|
14 using namespace mozilla; |
|
15 using namespace mozilla::a11y; |
|
16 |
|
17 /** |
|
18 * Return true if module version is lesser than the given version. |
|
19 */ |
|
20 bool |
|
21 IsModuleVersionLessThan(HMODULE aModuleHandle, DWORD aMajor, DWORD aMinor) |
|
22 { |
|
23 wchar_t fileName[MAX_PATH]; |
|
24 ::GetModuleFileNameW(aModuleHandle, fileName, MAX_PATH); |
|
25 |
|
26 DWORD dummy = 0; |
|
27 DWORD length = ::GetFileVersionInfoSizeW(fileName, &dummy); |
|
28 |
|
29 LPBYTE versionInfo = new BYTE[length]; |
|
30 ::GetFileVersionInfoW(fileName, 0, length, versionInfo); |
|
31 |
|
32 UINT uLen; |
|
33 VS_FIXEDFILEINFO* fixedFileInfo = nullptr; |
|
34 ::VerQueryValueW(versionInfo, L"\\", (LPVOID*)&fixedFileInfo, &uLen); |
|
35 DWORD dwFileVersionMS = fixedFileInfo->dwFileVersionMS; |
|
36 DWORD dwFileVersionLS = fixedFileInfo->dwFileVersionLS; |
|
37 delete [] versionInfo; |
|
38 |
|
39 DWORD dwLeftMost = HIWORD(dwFileVersionMS); |
|
40 DWORD dwSecondRight = HIWORD(dwFileVersionLS); |
|
41 return (dwLeftMost < aMajor || |
|
42 (dwLeftMost == aMajor && dwSecondRight < aMinor)); |
|
43 } |
|
44 |
|
45 |
|
46 //////////////////////////////////////////////////////////////////////////////// |
|
47 // Compatibility |
|
48 //////////////////////////////////////////////////////////////////////////////// |
|
49 |
|
50 uint32_t Compatibility::sConsumers = Compatibility::UNKNOWN; |
|
51 |
|
52 void |
|
53 Compatibility::Init() |
|
54 { |
|
55 // Note we collect some AT statistics/telemetry here for convenience. |
|
56 |
|
57 HMODULE jawsHandle = ::GetModuleHandleW(L"jhook"); |
|
58 if (jawsHandle) |
|
59 sConsumers |= (IsModuleVersionLessThan(jawsHandle, 8, 2173)) ? |
|
60 OLDJAWS : JAWS; |
|
61 |
|
62 if (::GetModuleHandleW(L"gwm32inc")) |
|
63 sConsumers |= WE; |
|
64 |
|
65 if (::GetModuleHandleW(L"dolwinhk")) |
|
66 sConsumers |= DOLPHIN; |
|
67 |
|
68 if (::GetModuleHandleW(L"STSA32")) |
|
69 sConsumers |= SEROTEK; |
|
70 |
|
71 if (::GetModuleHandleW(L"nvdaHelperRemote")) |
|
72 sConsumers |= NVDA; |
|
73 |
|
74 if (::GetModuleHandleW(L"OsmHooks")) |
|
75 sConsumers |= COBRA; |
|
76 |
|
77 if (::GetModuleHandleW(L"WebFinderRemote")) |
|
78 sConsumers |= ZOOMTEXT; |
|
79 |
|
80 if (::GetModuleHandleW(L"Kazahook")) |
|
81 sConsumers |= KAZAGURU; |
|
82 |
|
83 if (::GetModuleHandleW(L"TextExtractorImpl32") || |
|
84 ::GetModuleHandleW(L"TextExtractorImpl64")) |
|
85 sConsumers |= YOUDAO; |
|
86 |
|
87 if (::GetModuleHandleW(L"uiautomation") || |
|
88 ::GetModuleHandleW(L"uiautomationcore")) |
|
89 sConsumers |= UIAUTOMATION; |
|
90 |
|
91 // If we have a known consumer remove the unknown bit. |
|
92 if (sConsumers != Compatibility::UNKNOWN) |
|
93 sConsumers ^= Compatibility::UNKNOWN; |
|
94 |
|
95 // Gather telemetry |
|
96 uint32_t temp = sConsumers; |
|
97 for (int i = 0; temp; i++) { |
|
98 if (temp & 0x1) |
|
99 statistics::A11yConsumers(i); |
|
100 |
|
101 temp >>= 1; |
|
102 } |
|
103 |
|
104 // Turn off new tab switching for Jaws and WE. |
|
105 if (sConsumers & (JAWS | OLDJAWS | WE)) { |
|
106 // Check to see if the pref for disallowing CtrlTab is already set. If so, |
|
107 // bail out (respect the user settings). If not, set it. |
|
108 if (!Preferences::HasUserValue("browser.ctrlTab.disallowForScreenReaders")) |
|
109 Preferences::SetBool("browser.ctrlTab.disallowForScreenReaders", true); |
|
110 } |
|
111 } |
|
112 |