13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 53f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/win/win_util.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <aclapi.h> 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <shobjidl.h> // Must be before propkey. 9731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include <propkey.h> 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <propvarutil.h> 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <sddl.h> 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <shlobj.h> 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/registry.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h" 193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/win/scoped_handle.h" 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/win/windows_version.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace base { 243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsennamespace win { 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(struct_name, member) \ 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott offsetof(struct_name, member) + \ 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (sizeof static_cast<struct_name*>(NULL)->member) 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define NONCLIENTMETRICS_SIZE_PRE_VISTA \ 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid GetNonClientMetrics(NONCLIENTMETRICS* metrics) { 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(metrics); 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static const UINT SIZEOF_NONCLIENTMETRICS = 36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick (base::win::GetVersion() >= base::win::VERSION_VISTA) ? 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sizeof(NONCLIENTMETRICS) : NONCLIENTMETRICS_SIZE_PRE_VISTA; 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott metrics->cbSize = SIZEOF_NONCLIENTMETRICS; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const bool success = !!SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SIZEOF_NONCLIENTMETRICS, metrics, 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 0); 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(success); 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool GetUserSidString(std::wstring* user_sid) { 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the current token. 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE token = NULL; 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::win::ScopedHandle token_scoped(token); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<BYTE> user_bytes(new BYTE[size]); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TOKEN_USER* user = reinterpret_cast<TOKEN_USER*>(user_bytes.get()); 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!::GetTokenInformation(token, TokenUser, user, size, &size)) 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!user->User.Sid) 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Convert the data to a string. 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wchar_t* sid_string; 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!::ConvertSidToStringSid(user->User.Sid, &sid_string)) 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *user_sid = sid_string; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ::LocalFree(sid_string); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool IsShiftPressed() { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (::GetKeyState(VK_SHIFT) & 0x8000) == 0x8000; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool IsCtrlPressed() { 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (::GetKeyState(VK_CONTROL) & 0x8000) == 0x8000; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool IsAltPressed() { 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (::GetKeyState(VK_MENU) & 0x8000) == 0x8000; 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool UserAccountControlIsEnabled() { 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // This can be slow if Windows ends up going to disk. Should watch this key 88513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // for changes and only read it once, preferably on the file thread. 89513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // http://code.google.com/p/chromium/issues/detail?id=61644 90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::ThreadRestrictions::ScopedAllowIO allow_io; 91513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::win::RegKey key(HKEY_LOCAL_MACHINE, 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick KEY_READ); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD uac_enabled; 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (key.ReadValueDW(L"EnableLUA", &uac_enabled) != ERROR_SUCCESS) 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Users can set the EnableLUA value to something arbitrary, like 2, which 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Vista will treat as UAC enabled, so we make sure it is not set to 0. 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return (uac_enabled != 0); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SetAppIdForPropertyStore(IPropertyStore* property_store, 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const wchar_t* app_id) { 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(property_store); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // App id should be less than 128 chars and contain no space. And recommended 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // format is CompanyName.ProductName[.SubProduct.ProductNumber]. 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // See http://msdn.microsoft.com/en-us/library/dd378459%28VS.85%29.aspx 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(lstrlen(app_id) < 128 && wcschr(app_id, L' ') == NULL); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PROPVARIANT property_value; 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (FAILED(InitPropVariantFromString(app_id, &property_value))) 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HRESULT result = property_store->SetValue(PKEY_AppUserModel_ID, 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott property_value); 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (S_OK == result) 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result = property_store->Commit(); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PropVariantClear(&property_value); 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return SUCCEEDED(result); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char16 kAutoRunKeyPath[] = 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"; 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool AddCommandToAutoRun(HKEY root_key, const string16& name, 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& command) { 130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return (autorun_key.WriteValue(name.c_str(), command.c_str()) == 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ERROR_SUCCESS); 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool RemoveCommandFromAutoRun(HKEY root_key, const string16& name) { 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); 13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return (autorun_key.DeleteValue(name.c_str()) == ERROR_SUCCESS); 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ReadCommandFromAutoRun(HKEY root_key, 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const string16& name, 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen string16* command) { 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE); 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return (autorun_key.ReadValue(name.c_str(), command) == ERROR_SUCCESS); 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} // namespace win 1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} // namespace base 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef _MSC_VER 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// If the ASSERT below fails, please install Visual Studio 2005 Service Pack 1. 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottextern char VisualStudio2005ServicePack1Detection[10]; 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCOMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == sizeof(void*), 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VS2005SP1Detect); 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Chrome requires at least Service Pack 1 for Visual Studio 2005. 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // _MSC_VER 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef COPY_FILE_COPY_SYMLINK 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#error You must install the Windows 2008 or Vista Software Development Kit and \ 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottset it as your default include path to build this library. You can grab it by \ 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottsearching for "download windows sdk 2008" in your favorite web search engine. \ 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottAlso make sure you register the SDK with Visual Studio, by selecting \ 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott"Integrate Windows SDK with Visual Studio 2005" from the Windows SDK \ 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottmenu (see Start - All Programs - Microsoft Windows SDK - \ 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottVisual Studio Registration). 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 171