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)HMODULE GetMetroModule() { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HMODULE kUninitialized = reinterpret_cast<HMODULE>(1); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HMODULE metro_module = kUninitialized; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (metro_module == kUninitialized) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the cache, note that the initialization is idempotent 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // under the assumption that metro_driver is never unloaded, so the 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // race to this assignment is safe. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metro_module = GetModuleHandleA("metro_driver.dll"); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (metro_module != NULL) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This must be a metro process if the metro_driver is loaded. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(IsMetroProcess()); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(metro_module != kUninitialized); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metro_module; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsMetroProcess() { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ImmersiveState { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImmersiveUnknown, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImmersiveTrue, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kImmersiveFalse 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The immersive state of a process can never change. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look it up once and cache it here. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static ImmersiveState state = kImmersiveUnknown; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state == kImmersiveUnknown) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsProcessImmersive(::GetCurrentProcess())) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = kImmersiveTrue; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state = kImmersiveFalse; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(kImmersiveUnknown, state); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state == kImmersiveTrue; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsProcessImmersive(HANDLE process) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE user32 = ::GetModuleHandleA("user32.dll"); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(user32 != NULL); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsImmersiveProcessFunc is_immersive_process = 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<IsImmersiveProcessFunc>( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(user32, "IsImmersiveProcess")); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_immersive_process) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return is_immersive_process(process) ? true: false; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wchar_t* LocalAllocAndCopyString(const string16& src) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t dest_size = (src.length() + 1) * sizeof(wchar_t); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t* dest = reinterpret_cast<wchar_t*>(LocalAlloc(LPTR, dest_size)); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::wcslcpy(dest, src.c_str(), dest_size); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dest; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsParentalControlActivityLoggingOn() { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Query this info on Windows Vista and above. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool parental_control_logging_required = false; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool parental_control_status_determined = false; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parental_control_status_determined) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parental_control_logging_required; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parental_control_status_determined = true; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedComPtr<IWindowsParentalControlsCore> parent_controls; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = parent_controls.CreateInstance( 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __uuidof(WindowsParentalControls)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedComPtr<IWPCSettings> settings; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = parent_controls->GetUserSettings(NULL, settings.Receive()); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long restrictions = 0; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings->GetRestrictions(&restrictions); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parental_control_logging_required = 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (restrictions & WPCFLAG_LOGGING_REQUIRED) == WPCFLAG_LOGGING_REQUIRED; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parental_control_logging_required; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Metro driver exports for getting the launch type, initial url, initial 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// search term, etc. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef const wchar_t* (*GetInitialUrl)(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef const wchar_t* (*GetInitialSearchString)(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef base::win::MetroLaunchType (*GetLaunchType)( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::MetroPreviousExecutionState* previous_state); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MetroLaunchType GetMetroLaunchParams(string16* params) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE metro = base::win::GetMetroModule(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!metro) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::win::METRO_LAUNCH_ERROR; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLaunchType get_launch_type = reinterpret_cast<GetLaunchType>( 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(metro, "GetLaunchType")); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(get_launch_type); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::MetroLaunchType launch_type = get_launch_type(NULL); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((launch_type == base::win::METRO_PROTOCOL) || 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (launch_type == base::win::METRO_LAUNCH)) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInitialUrl initial_metro_url = reinterpret_cast<GetInitialUrl>( 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(metro, "GetInitialUrl")); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initial_metro_url); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *params = initial_metro_url(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (launch_type == base::win::METRO_SEARCH) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInitialSearchString initial_search_string = 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<GetInitialSearchString>( 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(metro, "GetInitialSearchString")); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(initial_search_string); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *params = initial_search_string(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return launch_type; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace win 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 146