- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / app / metro_driver_win.cc
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 "metro_driver_win.h"
6
7 #include <string.h>
8
9 #include "chrome/app/client_util.h"
10 #include "chrome/common/chrome_constants.h"
11
12 namespace {
13 // This environment variable controls the loading of the metro driver DLL.
14 const char* kMetroModeEnvVar = "CHROME_METRO_DLL";
15
16 typedef int (*InitMetro)(LPTHREAD_START_ROUTINE thread_proc, void* context);
17
18 struct Context {
19   MetroDriver::MainFn fn;
20   HINSTANCE instance;
21 };
22
23 DWORD WINAPI MainThread(void* param) {
24   Context* context = reinterpret_cast<Context*>(param);
25   int rv = context->fn(context->instance);
26   delete context;
27   return rv;
28 }
29
30 }  // namespace
31
32 MetroDriver::MetroDriver() : init_metro_fn_(NULL) {
33   if (0 != ::GetEnvironmentVariableA(kMetroModeEnvVar, NULL, 0))
34     return;
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");
39     return;
40   }
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);
45   if (!metro_dll) {
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
48     // directory.
49     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());
54     }
55   }
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");
59   if (!metro_dll)
60     return;
61   init_metro_fn_ = ::GetProcAddress(metro_dll, "InitMetro");
62 }
63
64 int MetroDriver::RunInMetro(HINSTANCE instance, MainFn main_fn) {
65   Context* context = new Context;
66   context->fn = main_fn;
67   context->instance = instance;
68
69   return reinterpret_cast<InitMetro>(init_metro_fn_)(&MainThread, context);
70 }