Index: win8/delegate_execute/delegate_execute.cc |
diff --git a/win8/delegate_execute/delegate_execute.cc b/win8/delegate_execute/delegate_execute.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9f3430c7ed63aee871bd1dcfde83167583b89d36 |
--- /dev/null |
+++ b/win8/delegate_execute/delegate_execute.cc |
@@ -0,0 +1,120 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <atlbase.h> |
+#include <atlcom.h> |
+#include <atlctl.h> |
+#include <initguid.h> |
+#include <shellapi.h> |
+ |
+#include "base/at_exit.h" |
+#include "base/command_line.h" |
+#include "base/file_util.h" |
+#include "base/string16.h" |
+#include "base/string_number_conversions.h" |
+#include "base/utf_string_conversions.h" |
+#include "base/win/scoped_com_initializer.h" |
+#include "base/win/scoped_handle.h" |
+#include "chrome/common/chrome_switches.h" |
+#include "command_execute_impl.h" |
+#include "win8/delegate_execute/delegate_execute_operation.h" |
+#include "win8/delegate_execute/resource.h" |
+ |
+using namespace ATL; |
+ |
+class DelegateExecuteModule |
+ : public ATL::CAtlExeModuleT< DelegateExecuteModule > { |
+ public : |
+ typedef ATL::CAtlExeModuleT<DelegateExecuteModule> ParentClass; |
+ |
+ DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DELEGATEEXECUTE, |
+ "{B1935DA1-112F-479A-975B-AB8588ABA636}") |
+ |
+ virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() { |
+ AtlTrace(L"In %hs\n", __FUNCTION__); |
+ HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar); |
+ if (FAILED(hr)) |
+ return hr; |
+ |
+ wchar_t delegate_execute_clsid[MAX_PATH] = {0}; |
+ if (!StringFromGUID2(__uuidof(CommandExecuteImpl), delegate_execute_clsid, |
+ ARRAYSIZE(delegate_execute_clsid))) { |
+ ATLASSERT(false); |
+ return E_FAIL; |
+ } |
+ |
+ hr = registrar->AddReplacement(L"DELEGATE_EXECUTE_CLSID", |
+ delegate_execute_clsid); |
+ ATLASSERT(SUCCEEDED(hr)); |
+ return hr; |
+ } |
+}; |
+ |
+DelegateExecuteModule _AtlModule; |
+ |
+// Relaunch metro Chrome by ShellExecute on |shortcut| with --force-immersive. |
+// |handle_value| is an optional handle on which this function will wait before |
+// performing the relaunch. |
+int RelaunchChrome(const FilePath& shortcut, const string16& handle_value) { |
+ base::win::ScopedHandle handle; |
+ |
+ if (!handle_value.empty()) { |
+ uint32 the_handle = 0; |
+ if (!base::StringToUint(handle_value, &the_handle)) { |
+ // Failed to parse the handle value. Skip the wait but proceed with the |
+ // relaunch. |
+ AtlTrace(L"Failed to parse handle value %ls\n", handle_value.c_str()); |
+ } else { |
+ handle.Set(reinterpret_cast<HANDLE>(the_handle)); |
+ } |
+ } |
+ |
+ if (handle.IsValid()) { |
+ AtlTrace(L"Waiting for chrome.exe to exit.\n"); |
+ DWORD result = ::WaitForSingleObject(handle, 10 * 1000); |
+ AtlTrace(L"And we're back.\n"); |
+ if (result != WAIT_OBJECT_0) { |
+ AtlTrace(L"Failed to wait for parent to exit; result=%u.\n", result); |
+ // This could mean that Chrome has hung. Conservatively proceed with |
+ // the relaunch anyway. |
+ } |
+ handle.Close(); |
+ } |
+ |
+ base::win::ScopedCOMInitializer com_initializer; |
+ |
+ AtlTrace(L"Launching Chrome via %ls.\n", shortcut.value().c_str()); |
+ int ser = reinterpret_cast<int>( |
+ ::ShellExecute(NULL, NULL, shortcut.value().c_str(), |
+ ASCIIToWide(switches::kForceImmersive).c_str(), NULL, |
+ SW_SHOWNORMAL)); |
+ AtlTrace(L"ShellExecute returned %d.\n", ser); |
+ return ser <= 32; |
+} |
+ |
+// |
+extern "C" int WINAPI _tWinMain(HINSTANCE , HINSTANCE, |
+ LPTSTR, int nShowCmd) { |
+ using delegate_execute::DelegateExecuteOperation; |
+ base::AtExitManager exit_manager; |
+ |
+ CommandLine::Init(0, NULL); |
+ CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
+ DelegateExecuteOperation operation; |
+ |
+ operation.Initialize(cmd_line); |
+ switch (operation.operation_type()) { |
+ case DelegateExecuteOperation::EXE_MODULE: |
+ return _AtlModule.WinMain(nShowCmd); |
+ |
+ case DelegateExecuteOperation::RELAUNCH_CHROME: |
+ return RelaunchChrome(operation.relaunch_shortcut(), |
+ cmd_line->GetSwitchValueNative(switches::kWaitForHandle)); |
+ |
+ default: |
+ NOTREACHED(); |
+ } |
+ |
+ return 1; |
+} |