OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/win/win_util.h" | 5 #include "base/win/win_util.h" |
6 | 6 |
7 #include <aclapi.h> | 7 #include <aclapi.h> |
8 #include <cfgmgr32.h> | 8 #include <cfgmgr32.h> |
9 #include <lm.h> | 9 #include <lm.h> |
10 #include <powrprof.h> | 10 #include <powrprof.h> |
11 #include <shellapi.h> | 11 #include <shellapi.h> |
12 #include <shlobj.h> | 12 #include <shlobj.h> |
13 #include <shobjidl.h> // Must be before propkey. | 13 #include <shobjidl.h> // Must be before propkey. |
14 #include <initguid.h> | 14 #include <initguid.h> |
15 #include <propkey.h> | 15 #include <propkey.h> |
16 #include <propvarutil.h> | 16 #include <propvarutil.h> |
17 #include <sddl.h> | 17 #include <sddl.h> |
18 #include <setupapi.h> | 18 #include <setupapi.h> |
19 #include <signal.h> | 19 #include <signal.h> |
20 #include <stdlib.h> | 20 #include <stdlib.h> |
21 | 21 |
| 22 #include "base/base_switches.h" |
| 23 #include "base/command_line.h" |
22 #include "base/lazy_instance.h" | 24 #include "base/lazy_instance.h" |
23 #include "base/logging.h" | 25 #include "base/logging.h" |
24 #include "base/memory/scoped_ptr.h" | 26 #include "base/memory/scoped_ptr.h" |
25 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
26 #include "base/strings/stringprintf.h" | 28 #include "base/strings/stringprintf.h" |
| 29 #include "base/strings/utf_string_conversions.h" |
27 #include "base/threading/thread_restrictions.h" | 30 #include "base/threading/thread_restrictions.h" |
28 #include "base/win/metro.h" | 31 #include "base/win/metro.h" |
29 #include "base/win/registry.h" | 32 #include "base/win/registry.h" |
30 #include "base/win/scoped_co_mem.h" | 33 #include "base/win/scoped_co_mem.h" |
31 #include "base/win/scoped_handle.h" | 34 #include "base/win/scoped_handle.h" |
32 #include "base/win/scoped_propvariant.h" | 35 #include "base/win/scoped_propvariant.h" |
33 #include "base/win/windows_version.h" | 36 #include "base/win/windows_version.h" |
34 | 37 |
| 38 namespace base { |
| 39 namespace win { |
| 40 |
35 namespace { | 41 namespace { |
36 | 42 |
37 // Sets the value of |property_key| to |property_value| in |property_store|. | 43 // Sets the value of |property_key| to |property_value| in |property_store|. |
38 bool SetPropVariantValueForPropertyStore( | 44 bool SetPropVariantValueForPropertyStore( |
39 IPropertyStore* property_store, | 45 IPropertyStore* property_store, |
40 const PROPERTYKEY& property_key, | 46 const PROPERTYKEY& property_key, |
41 const base::win::ScopedPropVariant& property_value) { | 47 const ScopedPropVariant& property_value) { |
42 DCHECK(property_store); | 48 DCHECK(property_store); |
43 | 49 |
44 HRESULT result = property_store->SetValue(property_key, property_value.get()); | 50 HRESULT result = property_store->SetValue(property_key, property_value.get()); |
45 if (result == S_OK) | 51 if (result == S_OK) |
46 result = property_store->Commit(); | 52 result = property_store->Commit(); |
47 return SUCCEEDED(result); | 53 return SUCCEEDED(result); |
48 } | 54 } |
49 | 55 |
50 void __cdecl ForceCrashOnSigAbort(int) { | 56 void __cdecl ForceCrashOnSigAbort(int) { |
51 *((int*)0) = 0x1337; | 57 *((volatile int*)0) = 0x1337; |
52 } | 58 } |
53 | 59 |
54 const wchar_t kWindows8OSKRegPath[] = | 60 const wchar_t kWindows8OSKRegPath[] = |
55 L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" | 61 L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" |
56 L"\\LocalServer32"; | 62 L"\\LocalServer32"; |
57 | 63 |
| 64 } // namespace |
| 65 |
58 // Returns true if a physical keyboard is detected on Windows 8 and up. | 66 // Returns true if a physical keyboard is detected on Windows 8 and up. |
59 // Uses the Setup APIs to enumerate the attached keyboards and returns true | 67 // Uses the Setup APIs to enumerate the attached keyboards and returns true |
60 // if the keyboard count is 1 or more.. While this will work in most cases | 68 // if the keyboard count is 1 or more.. While this will work in most cases |
61 // it won't work if there are devices which expose keyboard interfaces which | 69 // it won't work if there are devices which expose keyboard interfaces which |
62 // are attached to the machine. | 70 // are attached to the machine. |
63 bool IsKeyboardPresentOnSlate() { | 71 bool IsKeyboardPresentOnSlate(std::string* reason) { |
| 72 bool result = false; |
| 73 |
| 74 if (GetVersion() < VERSION_WIN7) { |
| 75 *reason = "Detection not supported"; |
| 76 return false; |
| 77 } |
| 78 |
64 // This function is only supported for Windows 8 and up. | 79 // This function is only supported for Windows 8 and up. |
65 DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN8); | 80 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 81 switches::kDisableUsbKeyboardDetect)) { |
| 82 if (reason) |
| 83 *reason = "Detection disabled"; |
| 84 return false; |
| 85 } |
66 | 86 |
67 // This function should be only invoked for machines with touch screens. | 87 // This function should be only invoked for machines with touch screens. |
68 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) | 88 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) |
69 != NID_INTEGRATED_TOUCH) { | 89 != NID_INTEGRATED_TOUCH) { |
70 return true; | 90 if (reason) { |
| 91 *reason += "NID_INTEGRATED_TOUCH\n"; |
| 92 result = true; |
| 93 } else { |
| 94 return true; |
| 95 } |
71 } | 96 } |
72 | 97 |
73 // If the device is docked, the user is treating the device as a PC. | 98 // If the device is docked, the user is treating the device as a PC. |
74 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) | 99 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) { |
75 return true; | 100 if (reason) { |
| 101 *reason += "SM_SYSTEMDOCKED\n"; |
| 102 result = true; |
| 103 } else { |
| 104 return true; |
| 105 } |
| 106 } |
76 | 107 |
77 // To determine whether a keyboard is present on the device, we do the | 108 // To determine whether a keyboard is present on the device, we do the |
78 // following:- | 109 // following:- |
79 // 1. Check whether the device supports auto rotation. If it does then | 110 // 1. Check whether the device supports auto rotation. If it does then |
80 // it possibly supports flipping from laptop to slate mode. If it | 111 // it possibly supports flipping from laptop to slate mode. If it |
81 // does not support auto rotation, then we assume it is a desktop | 112 // does not support auto rotation, then we assume it is a desktop |
82 // or a normal laptop and assume that there is a keyboard. | 113 // or a normal laptop and assume that there is a keyboard. |
83 | 114 |
84 // 2. If the device supports auto rotation, then we get its platform role | 115 // 2. If the device supports auto rotation, then we get its platform role |
85 // and check the system metric SM_CONVERTIBLESLATEMODE to see if it is | 116 // and check the system metric SM_CONVERTIBLESLATEMODE to see if it is |
(...skipping 10 matching lines...) Expand all Loading... |
96 GetModuleHandle(L"user32.dll"), "GetAutoRotationState")); | 127 GetModuleHandle(L"user32.dll"), "GetAutoRotationState")); |
97 | 128 |
98 if (get_rotation_state) { | 129 if (get_rotation_state) { |
99 AR_STATE auto_rotation_state = AR_ENABLED; | 130 AR_STATE auto_rotation_state = AR_ENABLED; |
100 get_rotation_state(&auto_rotation_state); | 131 get_rotation_state(&auto_rotation_state); |
101 if ((auto_rotation_state & AR_NOSENSOR) || | 132 if ((auto_rotation_state & AR_NOSENSOR) || |
102 (auto_rotation_state & AR_NOT_SUPPORTED)) { | 133 (auto_rotation_state & AR_NOT_SUPPORTED)) { |
103 // If there is no auto rotation sensor or rotation is not supported in | 134 // If there is no auto rotation sensor or rotation is not supported in |
104 // the current configuration, then we can assume that this is a desktop | 135 // the current configuration, then we can assume that this is a desktop |
105 // or a traditional laptop. | 136 // or a traditional laptop. |
106 return true; | 137 if (reason) { |
| 138 *reason += (auto_rotation_state & AR_NOSENSOR) ? "AR_NOSENSOR\n" |
| 139 : "AR_NOT_SUPPORTED\n"; |
| 140 result = true; |
| 141 } else { |
| 142 return true; |
| 143 } |
107 } | 144 } |
108 } | 145 } |
109 | 146 |
110 // Check if the device is being used as a laptop or a tablet. This can be | 147 // Check if the device is being used as a laptop or a tablet. This can be |
111 // checked by first checking the role of the device and then the | 148 // checked by first checking the role of the device and then the |
112 // corresponding system metric (SM_CONVERTIBLESLATEMODE). If it is being used | 149 // corresponding system metric (SM_CONVERTIBLESLATEMODE). If it is being used |
113 // as a tablet then we want the OSK to show up. | 150 // as a tablet then we want the OSK to show up. |
114 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); | 151 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); |
115 | 152 |
116 if (((role == PlatformRoleMobile) || (role == PlatformRoleSlate)) && | 153 if (((role == PlatformRoleMobile) || (role == PlatformRoleSlate)) && |
117 (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) | 154 (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) { |
118 return false; | 155 if (reason) { |
| 156 *reason += (role == PlatformRoleMobile) ? "PlatformRoleMobile\n" |
| 157 : "PlatformRoleSlate\n"; |
| 158 // Don't change result here if it's already true. |
| 159 } else { |
| 160 return false; |
| 161 } |
| 162 } |
119 | 163 |
120 const GUID KEYBOARD_CLASS_GUID = | 164 const GUID KEYBOARD_CLASS_GUID = |
121 { 0x4D36E96B, 0xE325, 0x11CE, | 165 { 0x4D36E96B, 0xE325, 0x11CE, |
122 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; | 166 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; |
123 | 167 |
124 // Query for all the keyboard devices. | 168 // Query for all the keyboard devices. |
125 HDEVINFO device_info = | 169 HDEVINFO device_info = |
126 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); | 170 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); |
127 if (device_info == INVALID_HANDLE_VALUE) | 171 if (device_info == INVALID_HANDLE_VALUE) { |
128 return false; | 172 if (reason) |
| 173 *reason += "No keyboard info\n"; |
| 174 return result; |
| 175 } |
129 | 176 |
130 // Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If | 177 // Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If |
131 // the count is more than 1 we assume that a keyboard is present. This is | 178 // the count is more than 1 we assume that a keyboard is present. This is |
132 // under the assumption that there will always be one keyboard device. | 179 // under the assumption that there will always be one keyboard device. |
133 int keyboard_count = 0; | |
134 for (DWORD i = 0;; ++i) { | 180 for (DWORD i = 0;; ++i) { |
135 SP_DEVINFO_DATA device_info_data = { 0 }; | 181 SP_DEVINFO_DATA device_info_data = { 0 }; |
136 device_info_data.cbSize = sizeof(device_info_data); | 182 device_info_data.cbSize = sizeof(device_info_data); |
137 if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data)) | 183 if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data)) |
138 break; | 184 break; |
139 | 185 |
140 // Get the device ID. | 186 // Get the device ID. |
141 wchar_t device_id[MAX_DEVICE_ID_LEN]; | 187 wchar_t device_id[MAX_DEVICE_ID_LEN]; |
142 CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, | 188 CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, |
143 device_id, | 189 device_id, |
144 MAX_DEVICE_ID_LEN, | 190 MAX_DEVICE_ID_LEN, |
145 0); | 191 0); |
146 if (status == CR_SUCCESS) { | 192 if (status == CR_SUCCESS) { |
147 // To reduce the scope of the hack we only look for ACPI and HID\\VID | 193 // To reduce the scope of the hack we only look for ACPI and HID\\VID |
148 // prefixes in the keyboard device ids. | 194 // prefixes in the keyboard device ids. |
149 if (StartsWith(device_id, L"ACPI", false) || | 195 if (StartsWith(device_id, L"ACPI", CompareCase::INSENSITIVE_ASCII) || |
150 StartsWith(device_id, L"HID\\VID", false)) { | 196 StartsWith(device_id, L"HID\\VID", CompareCase::INSENSITIVE_ASCII)) { |
151 keyboard_count++; | 197 if (reason) { |
| 198 *reason += "device: "; |
| 199 *reason += WideToUTF8(device_id); |
| 200 *reason += '\n'; |
| 201 } |
| 202 // The heuristic we are using is to check the count of keyboards and |
| 203 // return true if the API's report one or more keyboards. Please note |
| 204 // that this will break for non keyboard devices which expose a |
| 205 // keyboard PDO. |
| 206 result = true; |
152 } | 207 } |
153 } | 208 } |
154 } | 209 } |
155 // The heuristic we are using is to check the count of keyboards and return | 210 return result; |
156 // true if the API's report one or more keyboards. Please note that this | |
157 // will break for non keyboard devices which expose a keyboard PDO. | |
158 return keyboard_count >= 1; | |
159 } | 211 } |
160 | 212 |
161 } // namespace | |
162 | |
163 namespace base { | |
164 namespace win { | |
165 | |
166 static bool g_crash_on_process_detach = false; | 213 static bool g_crash_on_process_detach = false; |
167 | 214 |
168 void GetNonClientMetrics(NONCLIENTMETRICS_XP* metrics) { | 215 void GetNonClientMetrics(NONCLIENTMETRICS_XP* metrics) { |
169 DCHECK(metrics); | 216 DCHECK(metrics); |
170 metrics->cbSize = sizeof(*metrics); | 217 metrics->cbSize = sizeof(*metrics); |
171 const bool success = !!SystemParametersInfo( | 218 const bool success = !!SystemParametersInfo( |
172 SPI_GETNONCLIENTMETRICS, | 219 SPI_GETNONCLIENTMETRICS, |
173 metrics->cbSize, | 220 metrics->cbSize, |
174 reinterpret_cast<NONCLIENTMETRICS*>(metrics), | 221 reinterpret_cast<NONCLIENTMETRICS*>(metrics), |
175 0); | 222 0); |
176 DCHECK(success); | 223 DCHECK(success); |
177 } | 224 } |
178 | 225 |
179 bool GetUserSidString(std::wstring* user_sid) { | 226 bool GetUserSidString(std::wstring* user_sid) { |
180 // Get the current token. | 227 // Get the current token. |
181 HANDLE token = NULL; | 228 HANDLE token = NULL; |
182 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) | 229 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) |
183 return false; | 230 return false; |
184 base::win::ScopedHandle token_scoped(token); | 231 ScopedHandle token_scoped(token); |
185 | 232 |
186 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; | 233 DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; |
187 scoped_ptr<BYTE[]> user_bytes(new BYTE[size]); | 234 scoped_ptr<BYTE[]> user_bytes(new BYTE[size]); |
188 TOKEN_USER* user = reinterpret_cast<TOKEN_USER*>(user_bytes.get()); | 235 TOKEN_USER* user = reinterpret_cast<TOKEN_USER*>(user_bytes.get()); |
189 | 236 |
190 if (!::GetTokenInformation(token, TokenUser, user, size, &size)) | 237 if (!::GetTokenInformation(token, TokenUser, user, size, &size)) |
191 return false; | 238 return false; |
192 | 239 |
193 if (!user->User.Sid) | 240 if (!user->User.Sid) |
194 return false; | 241 return false; |
(...skipping 24 matching lines...) Expand all Loading... |
219 | 266 |
220 bool IsAltGrPressed() { | 267 bool IsAltGrPressed() { |
221 return (::GetKeyState(VK_MENU) & 0x8000) == 0x8000 && | 268 return (::GetKeyState(VK_MENU) & 0x8000) == 0x8000 && |
222 (::GetKeyState(VK_CONTROL) & 0x8000) == 0x8000; | 269 (::GetKeyState(VK_CONTROL) & 0x8000) == 0x8000; |
223 } | 270 } |
224 | 271 |
225 bool UserAccountControlIsEnabled() { | 272 bool UserAccountControlIsEnabled() { |
226 // This can be slow if Windows ends up going to disk. Should watch this key | 273 // This can be slow if Windows ends up going to disk. Should watch this key |
227 // for changes and only read it once, preferably on the file thread. | 274 // for changes and only read it once, preferably on the file thread. |
228 // http://code.google.com/p/chromium/issues/detail?id=61644 | 275 // http://code.google.com/p/chromium/issues/detail?id=61644 |
229 base::ThreadRestrictions::ScopedAllowIO allow_io; | 276 ThreadRestrictions::ScopedAllowIO allow_io; |
230 | 277 |
231 base::win::RegKey key(HKEY_LOCAL_MACHINE, | 278 RegKey key(HKEY_LOCAL_MACHINE, |
232 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", | 279 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", |
233 KEY_READ); | 280 KEY_READ); |
234 DWORD uac_enabled; | 281 DWORD uac_enabled; |
235 if (key.ReadValueDW(L"EnableLUA", &uac_enabled) != ERROR_SUCCESS) | 282 if (key.ReadValueDW(L"EnableLUA", &uac_enabled) != ERROR_SUCCESS) |
236 return true; | 283 return true; |
237 // Users can set the EnableLUA value to something arbitrary, like 2, which | 284 // Users can set the EnableLUA value to something arbitrary, like 2, which |
238 // Vista will treat as UAC enabled, so we make sure it is not set to 0. | 285 // Vista will treat as UAC enabled, so we make sure it is not set to 0. |
239 return (uac_enabled != 0); | 286 return (uac_enabled != 0); |
240 } | 287 } |
241 | 288 |
242 bool SetBooleanValueForPropertyStore(IPropertyStore* property_store, | 289 bool SetBooleanValueForPropertyStore(IPropertyStore* property_store, |
243 const PROPERTYKEY& property_key, | 290 const PROPERTYKEY& property_key, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 return SetStringValueForPropertyStore(property_store, | 324 return SetStringValueForPropertyStore(property_store, |
278 PKEY_AppUserModel_ID, | 325 PKEY_AppUserModel_ID, |
279 app_id); | 326 app_id); |
280 } | 327 } |
281 | 328 |
282 static const char16 kAutoRunKeyPath[] = | 329 static const char16 kAutoRunKeyPath[] = |
283 L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; | 330 L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; |
284 | 331 |
285 bool AddCommandToAutoRun(HKEY root_key, const string16& name, | 332 bool AddCommandToAutoRun(HKEY root_key, const string16& name, |
286 const string16& command) { | 333 const string16& command) { |
287 base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); | 334 RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); |
288 return (autorun_key.WriteValue(name.c_str(), command.c_str()) == | 335 return (autorun_key.WriteValue(name.c_str(), command.c_str()) == |
289 ERROR_SUCCESS); | 336 ERROR_SUCCESS); |
290 } | 337 } |
291 | 338 |
292 bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name) { | 339 bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name) { |
293 base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); | 340 RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); |
294 return (autorun_key.DeleteValue(name.c_str()) == ERROR_SUCCESS); | 341 return (autorun_key.DeleteValue(name.c_str()) == ERROR_SUCCESS); |
295 } | 342 } |
296 | 343 |
297 bool ReadCommandFromAutoRun(HKEY root_key, | 344 bool ReadCommandFromAutoRun(HKEY root_key, |
298 const string16& name, | 345 const string16& name, |
299 string16* command) { | 346 string16* command) { |
300 base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE); | 347 RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE); |
301 return (autorun_key.ReadValue(name.c_str(), command) == ERROR_SUCCESS); | 348 return (autorun_key.ReadValue(name.c_str(), command) == ERROR_SUCCESS); |
302 } | 349 } |
303 | 350 |
304 void SetShouldCrashOnProcessDetach(bool crash) { | 351 void SetShouldCrashOnProcessDetach(bool crash) { |
305 g_crash_on_process_detach = crash; | 352 g_crash_on_process_detach = crash; |
306 } | 353 } |
307 | 354 |
308 bool ShouldCrashOnProcessDetach() { | 355 bool ShouldCrashOnProcessDetach() { |
309 return g_crash_on_process_detach; | 356 return g_crash_on_process_detach; |
310 } | 357 } |
311 | 358 |
312 void SetAbortBehaviorForCrashReporting() { | 359 void SetAbortBehaviorForCrashReporting() { |
313 // Prevent CRT's abort code from prompting a dialog or trying to "report" it. | 360 // Prevent CRT's abort code from prompting a dialog or trying to "report" it. |
314 // Disabling the _CALL_REPORTFAULT behavior is important since otherwise it | 361 // Disabling the _CALL_REPORTFAULT behavior is important since otherwise it |
315 // has the sideffect of clearing our exception filter, which means we | 362 // has the sideffect of clearing our exception filter, which means we |
316 // don't get any crash. | 363 // don't get any crash. |
317 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); | 364 _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); |
318 | 365 |
319 // Set a SIGABRT handler for good measure. We will crash even if the default | 366 // Set a SIGABRT handler for good measure. We will crash even if the default |
320 // is left in place, however this allows us to crash earlier. And it also | 367 // is left in place, however this allows us to crash earlier. And it also |
321 // lets us crash in response to code which might directly call raise(SIGABRT) | 368 // lets us crash in response to code which might directly call raise(SIGABRT) |
322 signal(SIGABRT, ForceCrashOnSigAbort); | 369 signal(SIGABRT, ForceCrashOnSigAbort); |
323 } | 370 } |
324 | 371 |
325 bool IsTabletDevice() { | 372 bool IsTabletDevice() { |
326 if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) | 373 if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) |
327 return false; | 374 return false; |
328 | 375 |
329 base::win::Version version = base::win::GetVersion(); | 376 Version version = GetVersion(); |
330 if (version == base::win::VERSION_XP) | 377 if (version == VERSION_XP) |
331 return (GetSystemMetrics(SM_TABLETPC) != 0); | 378 return (GetSystemMetrics(SM_TABLETPC) != 0); |
332 | 379 |
333 // If the device is docked, the user is treating the device as a PC. | 380 // If the device is docked, the user is treating the device as a PC. |
334 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) | 381 if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) |
335 return false; | 382 return false; |
336 | 383 |
337 // PlatformRoleSlate was only added in Windows 8, but prior to Win8 it is | 384 // PlatformRoleSlate was only added in Windows 8, but prior to Win8 it is |
338 // still possible to check for a mobile power profile. | 385 // still possible to check for a mobile power profile. |
339 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); | 386 POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); |
340 bool mobile_power_profile = (role == PlatformRoleMobile); | 387 bool mobile_power_profile = (role == PlatformRoleMobile); |
341 bool slate_power_profile = false; | 388 bool slate_power_profile = false; |
342 if (version >= base::win::VERSION_WIN8) | 389 if (version >= VERSION_WIN8) |
343 slate_power_profile = (role == PlatformRoleSlate); | 390 slate_power_profile = (role == PlatformRoleSlate); |
344 | 391 |
345 if (mobile_power_profile || slate_power_profile) | 392 if (mobile_power_profile || slate_power_profile) |
346 return (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0); | 393 return (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0); |
347 | 394 |
348 return false; | 395 return false; |
349 } | 396 } |
350 | 397 |
351 bool DisplayVirtualKeyboard() { | 398 bool DisplayVirtualKeyboard() { |
352 if (base::win::GetVersion() < base::win::VERSION_WIN8) | 399 if (GetVersion() < VERSION_WIN8) |
353 return false; | 400 return false; |
354 | 401 |
355 if (IsKeyboardPresentOnSlate()) | 402 if (IsKeyboardPresentOnSlate(nullptr)) |
356 return false; | 403 return false; |
357 | 404 |
358 static base::LazyInstance<string16>::Leaky osk_path = | 405 static LazyInstance<string16>::Leaky osk_path = LAZY_INSTANCE_INITIALIZER; |
359 LAZY_INSTANCE_INITIALIZER; | |
360 | 406 |
361 if (osk_path.Get().empty()) { | 407 if (osk_path.Get().empty()) { |
362 // We need to launch TabTip.exe from the location specified under the | 408 // We need to launch TabTip.exe from the location specified under the |
363 // LocalServer32 key for the {{054AAE20-4BEA-4347-8A35-64A533254A9D}} | 409 // LocalServer32 key for the {{054AAE20-4BEA-4347-8A35-64A533254A9D}} |
364 // CLSID. | 410 // CLSID. |
365 // TabTip.exe is typically found at | 411 // TabTip.exe is typically found at |
366 // c:\program files\common files\microsoft shared\ink on English Windows. | 412 // c:\program files\common files\microsoft shared\ink on English Windows. |
367 // We don't want to launch TabTip.exe from | 413 // We don't want to launch TabTip.exe from |
368 // c:\program files (x86)\common files\microsoft shared\ink. This path is | 414 // c:\program files (x86)\common files\microsoft shared\ink. This path is |
369 // normally found on 64 bit Windows. | 415 // normally found on 64 bit Windows. |
370 base::win::RegKey key(HKEY_LOCAL_MACHINE, | 416 RegKey key(HKEY_LOCAL_MACHINE, kWindows8OSKRegPath, |
371 kWindows8OSKRegPath, | 417 KEY_READ | KEY_WOW64_64KEY); |
372 KEY_READ | KEY_WOW64_64KEY); | |
373 DWORD osk_path_length = 1024; | 418 DWORD osk_path_length = 1024; |
374 if (key.ReadValue(NULL, | 419 if (key.ReadValue(NULL, |
375 WriteInto(&osk_path.Get(), osk_path_length), | 420 WriteInto(&osk_path.Get(), osk_path_length), |
376 &osk_path_length, | 421 &osk_path_length, |
377 NULL) != ERROR_SUCCESS) { | 422 NULL) != ERROR_SUCCESS) { |
378 DLOG(WARNING) << "Failed to read on screen keyboard path from registry"; | 423 DLOG(WARNING) << "Failed to read on screen keyboard path from registry"; |
379 return false; | 424 return false; |
380 } | 425 } |
381 size_t common_program_files_offset = | 426 size_t common_program_files_offset = |
382 osk_path.Get().find(L"%CommonProgramFiles%"); | 427 osk_path.Get().find(L"%CommonProgramFiles%"); |
(...skipping 20 matching lines...) Expand all Loading... |
403 DWORD buffer_size = | 448 DWORD buffer_size = |
404 GetEnvironmentVariable(L"CommonProgramW6432", NULL, 0); | 449 GetEnvironmentVariable(L"CommonProgramW6432", NULL, 0); |
405 if (buffer_size) { | 450 if (buffer_size) { |
406 common_program_files_wow6432.reset(new wchar_t[buffer_size]); | 451 common_program_files_wow6432.reset(new wchar_t[buffer_size]); |
407 GetEnvironmentVariable(L"CommonProgramW6432", | 452 GetEnvironmentVariable(L"CommonProgramW6432", |
408 common_program_files_wow6432.get(), | 453 common_program_files_wow6432.get(), |
409 buffer_size); | 454 buffer_size); |
410 common_program_files_path = common_program_files_wow6432.get(); | 455 common_program_files_path = common_program_files_wow6432.get(); |
411 DCHECK(!common_program_files_path.empty()); | 456 DCHECK(!common_program_files_path.empty()); |
412 } else { | 457 } else { |
413 base::win::ScopedCoMem<wchar_t> common_program_files; | 458 ScopedCoMem<wchar_t> common_program_files; |
414 if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, NULL, | 459 if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, NULL, |
415 &common_program_files))) { | 460 &common_program_files))) { |
416 return false; | 461 return false; |
417 } | 462 } |
418 common_program_files_path = common_program_files; | 463 common_program_files_path = common_program_files; |
419 } | 464 } |
420 | 465 |
421 osk_path.Get().insert(1, common_program_files_path); | 466 osk_path.Get().insert(1, common_program_files_path); |
422 } | 467 } |
423 } | 468 } |
424 | 469 |
425 HINSTANCE ret = ::ShellExecuteW(NULL, | 470 HINSTANCE ret = ::ShellExecuteW(NULL, |
426 L"", | 471 L"", |
427 osk_path.Get().c_str(), | 472 osk_path.Get().c_str(), |
428 NULL, | 473 NULL, |
429 NULL, | 474 NULL, |
430 SW_SHOW); | 475 SW_SHOW); |
431 return reinterpret_cast<intptr_t>(ret) > 32; | 476 return reinterpret_cast<intptr_t>(ret) > 32; |
432 } | 477 } |
433 | 478 |
434 bool DismissVirtualKeyboard() { | 479 bool DismissVirtualKeyboard() { |
435 if (base::win::GetVersion() < base::win::VERSION_WIN8) | 480 if (GetVersion() < VERSION_WIN8) |
436 return false; | 481 return false; |
437 | 482 |
438 // We dismiss the virtual keyboard by generating the ESC keystroke | 483 // We dismiss the virtual keyboard by generating the ESC keystroke |
439 // programmatically. | 484 // programmatically. |
440 const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; | 485 const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; |
441 HWND osk = ::FindWindow(kOSKClassName, NULL); | 486 HWND osk = ::FindWindow(kOSKClassName, NULL); |
442 if (::IsWindow(osk) && ::IsWindowEnabled(osk)) { | 487 if (::IsWindow(osk) && ::IsWindowEnabled(osk)) { |
443 PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0); | 488 PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0); |
444 return true; | 489 return true; |
445 } | 490 } |
(...skipping 21 matching lines...) Expand all Loading... |
467 } | 512 } |
468 | 513 |
469 return g_domain_state == ENROLLED; | 514 return g_domain_state == ENROLLED; |
470 } | 515 } |
471 | 516 |
472 void SetDomainStateForTesting(bool state) { | 517 void SetDomainStateForTesting(bool state) { |
473 g_domain_state = state ? ENROLLED : NOT_ENROLLED; | 518 g_domain_state = state ? ENROLLED : NOT_ENROLLED; |
474 } | 519 } |
475 | 520 |
476 bool MaybeHasSHA256Support() { | 521 bool MaybeHasSHA256Support() { |
477 const base::win::OSInfo* os_info = base::win::OSInfo::GetInstance(); | 522 const OSInfo* os_info = OSInfo::GetInstance(); |
478 | 523 |
479 if (os_info->version() == base::win::VERSION_PRE_XP) | 524 if (os_info->version() == VERSION_PRE_XP) |
480 return false; // Too old to have it and this OS is not supported anyway. | 525 return false; // Too old to have it and this OS is not supported anyway. |
481 | 526 |
482 if (os_info->version() == base::win::VERSION_XP) | 527 if (os_info->version() == VERSION_XP) |
483 return os_info->service_pack().major >= 3; // Windows XP SP3 has it. | 528 return os_info->service_pack().major >= 3; // Windows XP SP3 has it. |
484 | 529 |
485 // Assume it is missing in this case, although it may not be. This category | 530 // Assume it is missing in this case, although it may not be. This category |
486 // includes Windows XP x64, and Windows Server, where a hotfix could be | 531 // includes Windows XP x64, and Windows Server, where a hotfix could be |
487 // deployed. | 532 // deployed. |
488 if (os_info->version() == base::win::VERSION_SERVER_2003) | 533 if (os_info->version() == VERSION_SERVER_2003) |
489 return false; | 534 return false; |
490 | 535 |
491 DCHECK(os_info->version() >= base::win::VERSION_VISTA); | 536 DCHECK(os_info->version() >= VERSION_VISTA); |
492 return true; // New enough to have SHA-256 support. | 537 return true; // New enough to have SHA-256 support. |
493 } | 538 } |
494 | 539 |
495 } // namespace win | 540 } // namespace win |
496 } // namespace base | 541 } // namespace base |
OLD | NEW |