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.
5 #include "base/win/metro.h"
7 #include "base/strings/string_util.h"
12 HMODULE
GetMetroModule() {
13 const HMODULE kUninitialized
= reinterpret_cast<HMODULE
>(1);
14 static HMODULE metro_module
= kUninitialized
;
16 if (metro_module
== kUninitialized
) {
17 // Initialize the cache, note that the initialization is idempotent
18 // under the assumption that metro_driver is never unloaded, so the
19 // race to this assignment is safe.
20 metro_module
= GetModuleHandleA("metro_driver.dll");
21 if (metro_module
!= NULL
) {
22 // This must be a metro process if the metro_driver is loaded.
23 DCHECK(IsMetroProcess());
27 DCHECK(metro_module
!= kUninitialized
);
31 bool IsMetroProcess() {
37 // The immersive state of a process can never change.
38 // Look it up once and cache it here.
39 static ImmersiveState state
= kImmersiveUnknown
;
41 if (state
== kImmersiveUnknown
) {
42 if (IsProcessImmersive(::GetCurrentProcess())) {
43 state
= kImmersiveTrue
;
45 state
= kImmersiveFalse
;
48 DCHECK_NE(kImmersiveUnknown
, state
);
49 return state
== kImmersiveTrue
;
52 bool IsProcessImmersive(HANDLE process
) {
53 typedef BOOL (WINAPI
* IsImmersiveProcessFunc
)(HANDLE process
);
54 HMODULE user32
= ::GetModuleHandleA("user32.dll");
55 DCHECK(user32
!= NULL
);
57 IsImmersiveProcessFunc is_immersive_process
=
58 reinterpret_cast<IsImmersiveProcessFunc
>(
59 ::GetProcAddress(user32
, "IsImmersiveProcess"));
61 if (is_immersive_process
)
62 return is_immersive_process(process
) ? true: false;
66 wchar_t* LocalAllocAndCopyString(const string16
& src
) {
67 size_t dest_size
= (src
.length() + 1) * sizeof(wchar_t);
68 wchar_t* dest
= reinterpret_cast<wchar_t*>(LocalAlloc(LPTR
, dest_size
));
69 base::wcslcpy(dest
, src
.c_str(), dest_size
);
73 // Metro driver exports for getting the launch type, initial url, initial
76 typedef const wchar_t* (*GetInitialUrl
)();
77 typedef const wchar_t* (*GetInitialSearchString
)();
78 typedef base::win::MetroLaunchType (*GetLaunchType
)(
79 base::win::MetroPreviousExecutionState
* previous_state
);
82 MetroLaunchType
GetMetroLaunchParams(string16
* params
) {
83 HMODULE metro
= base::win::GetMetroModule();
85 return base::win::METRO_LAUNCH_ERROR
;
87 GetLaunchType get_launch_type
= reinterpret_cast<GetLaunchType
>(
88 ::GetProcAddress(metro
, "GetLaunchType"));
89 DCHECK(get_launch_type
);
91 base::win::MetroLaunchType launch_type
= get_launch_type(NULL
);
93 if ((launch_type
== base::win::METRO_PROTOCOL
) ||
94 (launch_type
== base::win::METRO_LAUNCH
)) {
95 GetInitialUrl initial_metro_url
= reinterpret_cast<GetInitialUrl
>(
96 ::GetProcAddress(metro
, "GetInitialUrl"));
97 DCHECK(initial_metro_url
);
98 *params
= initial_metro_url();
99 } else if (launch_type
== base::win::METRO_SEARCH
) {
100 GetInitialSearchString initial_search_string
=
101 reinterpret_cast<GetInitialSearchString
>(
102 ::GetProcAddress(metro
, "GetInitialSearchString"));
103 DCHECK(initial_search_string
);
104 *params
= initial_search_string();