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/metro.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_comptr.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_should_tsf_aware_required = false; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HMODULE GetMetroModule() { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HMODULE kUninitialized = reinterpret_cast<HMODULE>(1); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HMODULE metro_module = kUninitialized; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (metro_module == kUninitialized) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the cache, note that the initialization is idempotent 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // under the assumption that metro_driver is never unloaded, so the 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // race to this assignment is safe. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metro_module = GetModuleHandleA("metro_driver.dll"); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (metro_module != NULL) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must be a metro process if the metro_driver is loaded. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsMetroProcess()); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(metro_module != kUninitialized); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metro_module; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsMetroProcess() { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ImmersiveState { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImmersiveUnknown, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImmersiveTrue, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImmersiveFalse 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The immersive state of a process can never change. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look it up once and cache it here. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ImmersiveState state = kImmersiveUnknown; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == kImmersiveUnknown) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsProcessImmersive(::GetCurrentProcess())) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = kImmersiveTrue; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = kImmersiveFalse; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(kImmersiveUnknown, state); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state == kImmersiveTrue; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsProcessImmersive(HANDLE process) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE user32 = ::GetModuleHandleA("user32.dll"); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(user32 != NULL); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsImmersiveProcessFunc is_immersive_process = 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<IsImmersiveProcessFunc>( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(user32, "IsImmersiveProcess")); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_immersive_process) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_immersive_process(process) ? true: false; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsTSFAwareRequired() { 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_AURA) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::win::GetVersion() >= base::win::VERSION_WIN8) 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Although this function is equal to IsMetroProcess at this moment, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chrome for Win7 and Vista may support TSF in the future. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_should_tsf_aware_required || IsMetroProcess(); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetForceToUseTSF() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_should_tsf_aware_required = true; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since Windows 8 Metro mode disables CUAS (Cicero Unaware Application 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Support) via ImmDisableLegacyIME API, Chrome must be fully TSF-aware on 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Metro mode. For debugging purposes, explicitly call ImmDisableLegacyIME so 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that one can test TSF functionality even on Windows 8 desktop mode. Note 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that CUAS cannot be disabled on Windows Vista/7 where ImmDisableLegacyIME 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is not available. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef BOOL (* ImmDisableLegacyIMEFunc)(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE imm32 = ::GetModuleHandleA("imm32.dll"); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (imm32 == NULL) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImmDisableLegacyIMEFunc imm_disable_legacy_ime = 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<ImmDisableLegacyIMEFunc>( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(imm32, "ImmDisableLegacyIME")); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (imm_disable_legacy_ime == NULL) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unsupported API, just do nothing. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!imm_disable_legacy_ime()) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Failed to disable legacy IME."; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wchar_t* LocalAllocAndCopyString(const string16& src) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t dest_size = (src.length() + 1) * sizeof(wchar_t); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t* dest = reinterpret_cast<wchar_t*>(LocalAlloc(LPTR, dest_size)); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::wcslcpy(dest, src.c_str(), dest_size); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dest; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsParentalControlActivityLoggingOn() { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Query this info on Windows Vista and above. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool parental_control_logging_required = false; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool parental_control_status_determined = false; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parental_control_status_determined) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parental_control_logging_required; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parental_control_status_determined = true; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedComPtr<IWindowsParentalControlsCore> parent_controls; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = parent_controls.CreateInstance( 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __uuidof(WindowsParentalControls)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedComPtr<IWPCSettings> settings; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = parent_controls->GetUserSettings(NULL, settings.Receive()); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long restrictions = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings->GetRestrictions(&restrictions); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parental_control_logging_required = 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (restrictions & WPCFLAG_LOGGING_REQUIRED) == WPCFLAG_LOGGING_REQUIRED; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parental_control_logging_required; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Metro driver exports for getting the launch type, initial url, initial 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// search term, etc. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef const wchar_t* (*GetInitialUrl)(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef const wchar_t* (*GetInitialSearchString)(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef base::win::MetroLaunchType (*GetLaunchType)( 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::MetroPreviousExecutionState* previous_state); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MetroLaunchType GetMetroLaunchParams(string16* params) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE metro = base::win::GetMetroModule(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!metro) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::win::METRO_LAUNCH_ERROR; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLaunchType get_launch_type = reinterpret_cast<GetLaunchType>( 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(metro, "GetLaunchType")); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(get_launch_type); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::MetroLaunchType launch_type = get_launch_type(NULL); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((launch_type == base::win::METRO_PROTOCOL) || 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (launch_type == base::win::METRO_LAUNCH)) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInitialUrl initial_metro_url = reinterpret_cast<GetInitialUrl>( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(metro, "GetInitialUrl")); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initial_metro_url); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *params = initial_metro_url(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (launch_type == base::win::METRO_SEARCH) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInitialSearchString initial_search_string = 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<GetInitialSearchString>( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(metro, "GetInitialSearchString")); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initial_search_string); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *params = initial_search_string(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launch_type; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace win 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 188