Chromium Code Reviews| Index: chrome/app/chrome_exe_main_win.cc |
| =================================================================== |
| --- chrome/app/chrome_exe_main_win.cc (revision 125893) |
| +++ chrome/app/chrome_exe_main_win.cc (working copy) |
| @@ -13,7 +13,12 @@ |
| #include "content/public/common/result_codes.h" |
| #include "sandbox/src/sandbox_factory.h" |
| -int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) { |
| +namespace { |
|
darin (slow to review)
2012/03/16 21:12:57
nit: new line after namespace open
|
| +typedef int (*InitMetro)(LPTHREAD_START_ROUTINE thread_proc); |
| +// this environment variable controls the loading of the metro driver DLL. |
|
darin (slow to review)
2012/03/16 21:12:57
brett-nit: "this" -> "This"
|
| +const char* kMetroModeEnvVar = "CHROME_METRO_DLL"; |
| + |
| +int RunChrome(HINSTANCE instance) { |
| bool exit_now = true; |
| // We restarted because of a previous crash. Ask user if we should relaunch. |
| if (ShowRestartDialogIfCrashed(&exit_now)) { |
| @@ -36,6 +41,58 @@ |
| int rc = loader->Launch(instance, &sandbox_info); |
| loader->RelaunchChromeBrowserWithNewCommandLineIfNeeded(); |
| delete loader; |
| - |
| return rc; |
| } |
| + |
| +// Helper class to manage the metro driver dll. When present in the system, |
| +// the main process thread needs to call InitMetro() on the dll. |
| +class MetroDriver { |
|
darin (slow to review)
2012/03/16 21:12:57
feels like this should be in a file of its own
|
| + public: |
| + MetroDriver() : metro_dll_(0), init_metro_fn_(NULL) { |
| + if (0 != ::GetEnvironmentVariableA(kMetroModeEnvVar, NULL, 0)) |
| + return; |
| + // We haven't tried to load the metro driver, this probably means we are the |
| + // browser. Find it or not we set the environment variable because we don't |
| + // want to keep trying in the child processes. |
| + metro_dll_ = ::LoadLibraryA("metro_driver.dll"); |
| + ::SetEnvironmentVariableA(kMetroModeEnvVar, metro_dll_ ? "1" : "0"); |
| + if (!metro_dll_) |
| + return; |
| + init_metro_fn_ = reinterpret_cast<InitMetro>( |
| + ::GetProcAddress(metro_dll_, "InitMetro")); |
| + } |
| + |
| + // returns true if chrome is being launched in metro. If so we should |
| + // call RunInMetro(). If not then we should just run chrome as usual. |
| + bool in_metro_mode() const { |
| + return (init_metro_fn_ != NULL); |
| + } |
| + |
| + // Enter the metro main function, which will only return when chrome metro |
| + // is closed. Once metro has initialized, the dll creates a new thread |
| + // which will run|SurrogateMainThread|. |
| + int RunInMetro(HINSTANCE instance) { |
| + module_instance_ = instance; |
| + return init_metro_fn_(&SurrogateMainThread); |
| + } |
| + |
| + private: |
| + static HINSTANCE module_instance_; |
| + |
| + static DWORD WINAPI SurrogateMainThread(void*) { |
| + return RunChrome(module_instance_); |
| + } |
| + |
| + HMODULE metro_dll_; |
| + InitMetro init_metro_fn_; |
| +}; |
| + |
| +HINSTANCE MetroDriver::module_instance_; |
| +} // namespace |
|
darin (slow to review)
2012/03/16 21:12:57
nit: new line before namespace close
|
| + |
| +int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) { |
| + MetroDriver metro_driver; |
| + if (metro_driver.in_metro_mode()) |
| + return metro_driver.RunInMetro(instance); |
| + return RunChrome(instance); |
| +} |