• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetMetroModule()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 
IsMetroProcess()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 
IsProcessImmersive(HANDLE process)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 
LocalAllocAndCopyString(const string16 & src)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 
IsParentalControlActivityLoggingOn()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 
GetMetroLaunchParams(string16 * params)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