Add chart names to Y values as well in Endure results.
[chromium-blink-merge.git] / win8 / delegate_execute / delegate_execute.cc
blobddb9883daa208bc7e0262131fc28a990deb23fd1
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 "build/intsafe_workaround.h"
7 #include <atlbase.h>
8 #include <atlcom.h>
9 #include <atlctl.h>
10 #include <initguid.h>
11 #include <shellapi.h>
13 #include "base/at_exit.h"
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/process/kill.h"
18 #include "base/strings/string16.h"
19 #include "base/win/scoped_com_initializer.h"
20 #include "base/win/scoped_comptr.h"
21 #include "base/win/scoped_handle.h"
22 #include "breakpad/src/client/windows/handler/exception_handler.h"
23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/installer/util/browser_distribution.h"
25 #include "win8/delegate_execute/command_execute_impl.h"
26 #include "win8/delegate_execute/crash_server_init.h"
27 #include "win8/delegate_execute/delegate_execute_operation.h"
28 #include "win8/delegate_execute/resource.h"
30 using namespace ATL;
32 // Usually classes derived from CAtlExeModuleT, or other types of ATL
33 // COM module classes statically define their CLSID at compile time through
34 // the use of various macros, and ATL internals takes care of creating the
35 // class objects and registering them. However, we need to register the same
36 // object with different CLSIDs depending on a runtime setting, so we handle
37 // that logic here, before the main ATL message loop runs.
38 class DelegateExecuteModule
39 : public ATL::CAtlExeModuleT< DelegateExecuteModule > {
40 public :
41 typedef ATL::CAtlExeModuleT<DelegateExecuteModule> ParentClass;
42 typedef CComObject<CommandExecuteImpl> ImplType;
44 DelegateExecuteModule()
45 : registration_token_(0) {
48 HRESULT PreMessageLoop(int nShowCmd) {
49 HRESULT hr = S_OK;
50 string16 clsid_string;
51 GUID clsid;
52 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
53 if (!dist->GetCommandExecuteImplClsid(&clsid_string))
54 return E_FAIL;
55 hr = ::CLSIDFromString(clsid_string.c_str(), &clsid);
56 if (FAILED(hr))
57 return hr;
59 // We use the same class creation logic as ATL itself. See
60 // _ATL_OBJMAP_ENTRY::RegisterClassObject() in atlbase.h
61 hr = ImplType::_ClassFactoryCreatorClass::CreateInstance(
62 ImplType::_CreatorClass::CreateInstance, IID_IUnknown,
63 instance_.ReceiveVoid());
64 if (FAILED(hr))
65 return hr;
66 hr = ::CoRegisterClassObject(clsid, instance_, CLSCTX_LOCAL_SERVER,
67 REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &registration_token_);
68 if (FAILED(hr))
69 return hr;
71 return ParentClass::PreMessageLoop(nShowCmd);
74 HRESULT PostMessageLoop() {
75 if (registration_token_ != 0) {
76 ::CoRevokeClassObject(registration_token_);
77 registration_token_ = 0;
80 instance_.Release();
82 return ParentClass::PostMessageLoop();
85 private:
86 base::win::ScopedComPtr<IUnknown> instance_;
87 DWORD registration_token_;
90 DelegateExecuteModule _AtlModule;
92 using delegate_execute::DelegateExecuteOperation;
93 using base::win::ScopedHandle;
95 int RelaunchChrome(const DelegateExecuteOperation& operation) {
96 AtlTrace("Relaunching [%ls] with flags [%s]\n",
97 operation.mutex().c_str(), operation.relaunch_flags());
98 ScopedHandle mutex(OpenMutexW(SYNCHRONIZE, FALSE, operation.mutex().c_str()));
99 if (mutex.IsValid()) {
100 const int kWaitSeconds = 5;
101 DWORD result = ::WaitForSingleObject(mutex, kWaitSeconds * 1000);
102 if (result == WAIT_ABANDONED) {
103 // This is the normal case. Chrome exits and windows marks the mutex as
104 // abandoned.
105 } else if (result == WAIT_OBJECT_0) {
106 // This is unexpected. Check if somebody is not closing the mutex on
107 // RelaunchChromehelper, the mutex should not be closed.
108 AtlTrace("Unexpected release of the relaunch mutex!!\n");
109 } else if (result == WAIT_TIMEOUT) {
110 // This could mean that Chrome is hung. Proceed to exterminate.
111 DWORD pid = operation.GetParentPid();
112 AtlTrace("%ds timeout. Killing Chrome %d\n", kWaitSeconds, pid);
113 base::KillProcessById(pid, 0, false);
114 } else {
115 AtlTrace("Failed to wait for relaunch mutex, result is 0x%x\n", result);
117 } else {
118 // It is possible that chrome exits so fast that the mutex is not there.
119 AtlTrace("No relaunch mutex found\n");
122 base::win::ScopedCOMInitializer com_initializer;
124 string16 relaunch_flags(operation.relaunch_flags());
125 SHELLEXECUTEINFO sei = { sizeof(sei) };
126 sei.fMask = SEE_MASK_FLAG_LOG_USAGE;
127 sei.nShow = SW_SHOWNORMAL;
128 sei.lpFile = operation.shortcut().value().c_str();
129 sei.lpParameters = relaunch_flags.c_str();
131 AtlTrace(L"Relaunching Chrome via shortcut [%ls]\n", sei.lpFile);
133 if (!::ShellExecuteExW(&sei)) {
134 int error = HRESULT_FROM_WIN32(::GetLastError());
135 AtlTrace("ShellExecute returned 0x%08X\n", error);
136 return error;
138 return S_OK;
141 extern "C" int WINAPI _tWinMain(HINSTANCE , HINSTANCE, LPTSTR, int nShowCmd) {
142 scoped_ptr<google_breakpad::ExceptionHandler> breakpad =
143 delegate_execute::InitializeCrashReporting();
145 base::AtExitManager exit_manager;
146 AtlTrace("delegate_execute enter\n");
148 CommandLine::Init(0, NULL);
149 HRESULT ret_code = E_UNEXPECTED;
150 DelegateExecuteOperation operation;
151 if (operation.Init(CommandLine::ForCurrentProcess())) {
152 switch (operation.operation_type()) {
153 case DelegateExecuteOperation::DELEGATE_EXECUTE:
154 ret_code = _AtlModule.WinMain(nShowCmd);
155 break;
156 case DelegateExecuteOperation::RELAUNCH_CHROME:
157 ret_code = RelaunchChrome(operation);
158 break;
159 default:
160 NOTREACHED();
163 AtlTrace("delegate_execute exit, code = %d\n", ret_code);
164 return ret_code;