15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <aclapi.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <shellapi.h> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <shlobj.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shobjidl.h> // Must be before propkey. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <initguid.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <propkey.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <propvarutil.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sddl.h> 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <signal.h> 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdlib.h> 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/registry.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_co_mem.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_handle.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/scoped_propvariant.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets the value of |property_key| to |property_value| in |property_store|. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetPropVariantValueForPropertyStore( 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPropertyStore* property_store, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PROPERTYKEY& property_key, 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::win::ScopedPropVariant& property_value) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(property_store); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HRESULT result = property_store->SetValue(property_key, property_value.get()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == S_OK) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = property_store->Commit(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SUCCEEDED(result); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void __cdecl ForceCrashOnSigAbort(int) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *((int*)0) = 0x1337; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const wchar_t kWindows8OSKRegPath[] = 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"\\LocalServer32"; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool g_crash_on_process_detach = false; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NONCLIENTMETRICS_SIZE_PRE_VISTA \ 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetNonClientMetrics(NONCLIENTMETRICS* metrics) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(metrics); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const UINT SIZEOF_NONCLIENTMETRICS = 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (base::win::GetVersion() >= base::win::VERSION_VISTA) ? 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metrics->cbSize = SIZEOF_NONCLIENTMETRICS; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SIZEOF_NONCLIENTMETRICS, metrics, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(success); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetUserSidString(std::wstring* user_sid) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the current token. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE token = NULL; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedHandle token_scoped(token); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<BYTE[]> user_bytes(new BYTE[size]); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TOKEN_USER* user = reinterpret_cast<TOKEN_USER*>(user_bytes.get()); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::GetTokenInformation(token, TokenUser, user, size, &size)) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!user->User.Sid) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert the data to a string. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t* sid_string; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!::ConvertSidToStringSid(user->User.Sid, &sid_string)) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *user_sid = sid_string; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::LocalFree(sid_string); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsShiftPressed() { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsCtrlPressed() { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (::GetKeyState(VK_CONTROL) & 0x8000) == 0x8000; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsAltPressed() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (::GetKeyState(VK_MENU) & 0x8000) == 0x8000; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UserAccountControlIsEnabled() { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be slow if Windows ends up going to disk. Should watch this key 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for changes and only read it once, preferably on the file thread. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://code.google.com/p/chromium/issues/detail?id=61644 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey key(HKEY_LOCAL_MACHINE, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) KEY_READ); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD uac_enabled; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key.ReadValueDW(L"EnableLUA", &uac_enabled) != ERROR_SUCCESS) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Users can set the EnableLUA value to something arbitrary, like 2, which 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Vista will treat as UAC enabled, so we make sure it is not set to 0. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (uac_enabled != 0); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetBooleanValueForPropertyStore(IPropertyStore* property_store, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PROPERTYKEY& property_key, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool property_bool_value) { 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedPropVariant property_value; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FAILED(InitPropVariantFromBoolean(property_bool_value, 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_value.Receive()))) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetPropVariantValueForPropertyStore(property_store, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_key, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_value); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetStringValueForPropertyStore(IPropertyStore* property_store, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PROPERTYKEY& property_key, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* property_string_value) { 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedPropVariant property_value; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FAILED(InitPropVariantFromString(property_string_value, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_value.Receive()))) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetPropVariantValueForPropertyStore(property_store, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) property_key, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_value); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetAppIdForPropertyStore(IPropertyStore* property_store, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* app_id) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // App id should be less than 64 chars and contain no space. And recommended 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // format is CompanyName.ProductName[.SubProduct.ProductNumber]. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://msdn.microsoft.com/en-us/library/dd378459%28VS.85%29.aspx 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(lstrlen(app_id) < 64 && wcschr(app_id, L' ') == NULL); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SetStringValueForPropertyStore(property_store, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PKEY_AppUserModel_ID, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_id); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char16 kAutoRunKeyPath[] = 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AddCommandToAutoRun(HKEY root_key, const string16& name, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& command) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (autorun_key.WriteValue(name.c_str(), command.c_str()) == 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERROR_SUCCESS); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (autorun_key.DeleteValue(name.c_str()) == ERROR_SUCCESS); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReadCommandFromAutoRun(HKEY root_key, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& name, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16* command) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (autorun_key.ReadValue(name.c_str(), command) == ERROR_SUCCESS); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetShouldCrashOnProcessDetach(bool crash) { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_crash_on_process_detach = crash; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ShouldCrashOnProcessDetach() { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_crash_on_process_detach; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetAbortBehaviorForCrashReporting() { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Prevent CRT's abort code from prompting a dialog or trying to "report" it. 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Disabling the _CALL_REPORTFAULT behavior is important since otherwise it 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // has the sideffect of clearing our exception filter, which means we 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // don't get any crash. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set a SIGABRT handler for good measure. We will crash even if the default 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is left in place, however this allows us to crash earlier. And it also 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // lets us crash in response to code which might directly call raise(SIGABRT) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) signal(SIGABRT, ForceCrashOnSigAbort); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool IsTouchEnabledDevice() { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_WIN7) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMultiTouch = NID_INTEGRATED_TOUCH | NID_MULTI_INPUT | NID_READY; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sm = GetSystemMetrics(SM_DIGITIZER); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sm & kMultiTouch) == kMultiTouch) { 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayVirtualKeyboard() { 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_WIN8) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static base::LazyInstance<string16>::Leaky osk_path = 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (osk_path.Get().empty()) { 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We need to launch TabTip.exe from the location specified under the 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // LocalServer32 key for the {{054AAE20-4BEA-4347-8A35-64A533254A9D}} 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // CLSID. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TabTip.exe is typically found at 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // c:\program files\common files\microsoft shared\ink on English Windows. 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We don't want to launch TabTip.exe from 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // c:\program files (x86)\common files\microsoft shared\ink. This path is 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // normally found on 64 bit Windows. 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::RegKey key(HKEY_LOCAL_MACHINE, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kWindows8OSKRegPath, 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) KEY_READ | KEY_WOW64_64KEY); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DWORD osk_path_length = 1024; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (key.ReadValue(NULL, 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WriteInto(&osk_path.Get(), osk_path_length), 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &osk_path_length, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL) != ERROR_SUCCESS) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(WARNING) << "Failed to read on screen keyboard path from registry"; 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t common_program_files_offset = 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) osk_path.Get().find(L"%CommonProgramFiles%"); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Typically the path to TabTip.exe read from the registry will start with 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // %CommonProgramFiles% which needs to be replaced with the corrsponding 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // expanded string. 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the path does not begin with %CommonProgramFiles% we use it as is. 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (common_program_files_offset != string16::npos) { 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Preserve the beginning quote in the path. 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) osk_path.Get().erase(common_program_files_offset, 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wcslen(L"%CommonProgramFiles%")); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The path read from the registry contains the %CommonProgramFiles% 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // environment variable prefix. On 64 bit Windows the SHGetKnownFolderPath 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // function returns the common program files path with the X86 suffix for 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the FOLDERID_ProgramFilesCommon value. 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // To get the correct path to TabTip.exe we first read the environment 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // variable CommonProgramW6432 which points to the desired common 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // files path. Failing that we fallback to the SHGetKnownFolderPath API. 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We then replace the %CommonProgramFiles% value with the actual common 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // files path found in the process. 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string16 common_program_files_path; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<wchar_t[]> common_program_files_wow6432; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DWORD buffer_size = 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetEnvironmentVariable(L"CommonProgramW6432", NULL, 0); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (buffer_size) { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_program_files_wow6432.reset(new wchar_t[buffer_size]); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetEnvironmentVariable(L"CommonProgramW6432", 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_program_files_wow6432.get(), 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) buffer_size); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_program_files_path = common_program_files_wow6432.get(); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!common_program_files_path.empty()); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::win::ScopedCoMem<wchar_t> common_program_files; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, NULL, 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &common_program_files))) { 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) common_program_files_path = common_program_files; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) osk_path.Get().insert(1, common_program_files_path); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HINSTANCE ret = ::ShellExecuteW(NULL, 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"", 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) osk_path.Get().c_str(), 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NULL, 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SW_SHOW); 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return reinterpret_cast<int>(ret) > 32; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DismissVirtualKeyboard() { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_WIN8) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We dismiss the virtual keyboard by generating the ESC keystroke 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // programmatically. 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wchar_t kOSKClassName[] = L"IPTip_Main_Window"; 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HWND osk = ::FindWindow(kOSKClassName, NULL); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (::IsWindow(osk) && ::IsWindowEnabled(osk)) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0); 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace win 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// There are optimizer bugs in x86 VS2012 pre-Update 1. 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if _MSC_VER == 1700 && defined _M_IX86 && _MSC_FULL_VER < 170051106 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#pragma message("Relevant defines:") 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define __STR2__(x) #x 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define __STR1__(x) __STR2__(x) 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define __PPOUT__(x) "#define " #x " " __STR1__(x) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(_M_IX86) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) #pragma message(__PPOUT__(_M_IX86)) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(_M_X64) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) #pragma message(__PPOUT__(_M_X64)) 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(_MSC_FULL_VER) 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) #pragma message(__PPOUT__(_MSC_FULL_VER)) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#pragma message("Visual Studio 2012 x86 must be updated to at least Update 1") 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#error Must install Update 1 to Visual Studio 2012. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // _MSC_VER 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 351