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 3// found in the LICENSE file. 4 5#include "base/win/metro.h" 6 7#include "base/message_loop/message_loop.h" 8#include "base/strings/string_util.h" 9#include "base/win/scoped_comptr.h" 10#include "base/win/windows_version.h" 11 12namespace base { 13namespace win { 14 15HMODULE GetMetroModule() { 16 const HMODULE kUninitialized = reinterpret_cast<HMODULE>(1); 17 static HMODULE metro_module = kUninitialized; 18 19 if (metro_module == kUninitialized) { 20 // Initialize the cache, note that the initialization is idempotent 21 // under the assumption that metro_driver is never unloaded, so the 22 // race to this assignment is safe. 23 metro_module = GetModuleHandleA("metro_driver.dll"); 24 if (metro_module != NULL) { 25 // This must be a metro process if the metro_driver is loaded. 26 DCHECK(IsMetroProcess()); 27 } 28 } 29 30 DCHECK(metro_module != kUninitialized); 31 return metro_module; 32} 33 34bool IsMetroProcess() { 35 enum ImmersiveState { 36 kImmersiveUnknown, 37 kImmersiveTrue, 38 kImmersiveFalse 39 }; 40 // The immersive state of a process can never change. 41 // Look it up once and cache it here. 42 static ImmersiveState state = kImmersiveUnknown; 43 44 if (state == kImmersiveUnknown) { 45 if (IsProcessImmersive(::GetCurrentProcess())) { 46 state = kImmersiveTrue; 47 } else { 48 state = kImmersiveFalse; 49 } 50 } 51 DCHECK_NE(kImmersiveUnknown, state); 52 return state == kImmersiveTrue; 53} 54 55bool IsProcessImmersive(HANDLE process) { 56 typedef BOOL (WINAPI* IsImmersiveProcessFunc)(HANDLE process); 57 HMODULE user32 = ::GetModuleHandleA("user32.dll"); 58 DCHECK(user32 != NULL); 59 60 IsImmersiveProcessFunc is_immersive_process = 61 reinterpret_cast<IsImmersiveProcessFunc>( 62 ::GetProcAddress(user32, "IsImmersiveProcess")); 63 64 if (is_immersive_process) 65 return is_immersive_process(process) ? true: false; 66 return false; 67} 68 69wchar_t* LocalAllocAndCopyString(const string16& src) { 70 size_t dest_size = (src.length() + 1) * sizeof(wchar_t); 71 wchar_t* dest = reinterpret_cast<wchar_t*>(LocalAlloc(LPTR, dest_size)); 72 base::wcslcpy(dest, src.c_str(), dest_size); 73 return dest; 74} 75 76bool IsParentalControlActivityLoggingOn() { 77 // Query this info on Windows Vista and above. 78 if (base::win::GetVersion() < base::win::VERSION_VISTA) 79 return false; 80 81 static bool parental_control_logging_required = false; 82 static bool parental_control_status_determined = false; 83 84 if (parental_control_status_determined) 85 return parental_control_logging_required; 86 87 parental_control_status_determined = true; 88 89 ScopedComPtr<IWindowsParentalControlsCore> parent_controls; 90 HRESULT hr = parent_controls.CreateInstance( 91 __uuidof(WindowsParentalControls)); 92 if (FAILED(hr)) 93 return false; 94 95 ScopedComPtr<IWPCSettings> settings; 96 hr = parent_controls->GetUserSettings(NULL, settings.Receive()); 97 if (FAILED(hr)) 98 return false; 99 100 unsigned long restrictions = 0; 101 settings->GetRestrictions(&restrictions); 102 103 parental_control_logging_required = 104 (restrictions & WPCFLAG_LOGGING_REQUIRED) == WPCFLAG_LOGGING_REQUIRED; 105 return parental_control_logging_required; 106} 107 108// Metro driver exports for getting the launch type, initial url, initial 109// search term, etc. 110extern "C" { 111typedef const wchar_t* (*GetInitialUrl)(); 112typedef const wchar_t* (*GetInitialSearchString)(); 113typedef base::win::MetroLaunchType (*GetLaunchType)( 114 base::win::MetroPreviousExecutionState* previous_state); 115} 116 117MetroLaunchType GetMetroLaunchParams(string16* params) { 118 HMODULE metro = base::win::GetMetroModule(); 119 if (!metro) 120 return base::win::METRO_LAUNCH_ERROR; 121 122 GetLaunchType get_launch_type = reinterpret_cast<GetLaunchType>( 123 ::GetProcAddress(metro, "GetLaunchType")); 124 DCHECK(get_launch_type); 125 126 base::win::MetroLaunchType launch_type = get_launch_type(NULL); 127 128 if ((launch_type == base::win::METRO_PROTOCOL) || 129 (launch_type == base::win::METRO_LAUNCH)) { 130 GetInitialUrl initial_metro_url = reinterpret_cast<GetInitialUrl>( 131 ::GetProcAddress(metro, "GetInitialUrl")); 132 DCHECK(initial_metro_url); 133 *params = initial_metro_url(); 134 } else if (launch_type == base::win::METRO_SEARCH) { 135 GetInitialSearchString initial_search_string = 136 reinterpret_cast<GetInitialSearchString>( 137 ::GetProcAddress(metro, "GetInitialSearchString")); 138 DCHECK(initial_search_string); 139 *params = initial_search_string(); 140 } 141 return launch_type; 142} 143 144} // namespace win 145} // namespace base 146