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 "metro_driver_win.h"
9 #include "chrome/app/client_util.h"
10 #include "chrome/common/chrome_constants.h"
13 // This environment variable controls the loading of the metro driver DLL.
14 const char* kMetroModeEnvVar
= "CHROME_METRO_DLL";
16 typedef int (*InitMetro
)(LPTHREAD_START_ROUTINE thread_proc
, void* context
);
19 MetroDriver::MainFn fn
;
23 DWORD WINAPI
MainThread(void* param
) {
24 Context
* context
= reinterpret_cast<Context
*>(param
);
25 int rv
= context
->fn(context
->instance
);
32 MetroDriver::MetroDriver() : init_metro_fn_(NULL
) {
33 if (0 != ::GetEnvironmentVariableA(kMetroModeEnvVar
, NULL
, 0))
35 // The metro activation always has the |ServerName| parameter. If we dont
36 // see it, we are being launched in desktop mode.
37 if (!wcsstr(::GetCommandLineW(), L
" -ServerName:DefaultBrowserServer")) {
38 ::SetEnvironmentVariableA(kMetroModeEnvVar
, "0");
41 // We haven't tried to load the metro driver, this probably means we are the
42 // browser. Find it or not we set the environment variable because we don't
43 // want to keep trying in the child processes.
44 HMODULE metro_dll
= ::LoadLibraryW(chrome::kMetroDriverDll
);
46 // It is not next to the build output, so this must be an actual deployment
47 // and in that case we need the mainloader to find the current version
49 base::string16
version(GetCurrentModuleVersion());
50 if (!version
.empty()) {
51 std::wstring
exe_path(GetExecutablePath());
52 exe_path
.append(version
).append(L
"\\").append(chrome::kMetroDriverDll
);
53 metro_dll
= ::LoadLibraryW(exe_path
.c_str());
56 // We set the environment variable always, so we don't keep trying in
57 // the child processes.
58 ::SetEnvironmentVariableA(kMetroModeEnvVar
, metro_dll
? "1" : "0");
61 init_metro_fn_
= ::GetProcAddress(metro_dll
, "InitMetro");
64 int MetroDriver::RunInMetro(HINSTANCE instance
, MainFn main_fn
) {
65 Context
* context
= new Context
;
66 context
->fn
= main_fn
;
67 context
->instance
= instance
;
69 return reinterpret_cast<InitMetro
>(init_metro_fn_
)(&MainThread
, context
);