Home | History | Annotate | Download | only in win
      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 
     12 namespace base {
     13 namespace win {
     14 
     15 HMODULE 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 
     34 bool 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 
     55 bool 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 
     69 wchar_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 
     76 bool 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.
    110 extern "C" {
    111 typedef const wchar_t* (*GetInitialUrl)();
    112 typedef const wchar_t* (*GetInitialSearchString)();
    113 typedef base::win::MetroLaunchType (*GetLaunchType)(
    114     base::win::MetroPreviousExecutionState* previous_state);
    115 }
    116 
    117 MetroLaunchType 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