Index: chrome_frame/update_launcher.cc |
=================================================================== |
--- chrome_frame/update_launcher.cc (revision 0) |
+++ chrome_frame/update_launcher.cc (revision 0) |
@@ -0,0 +1,92 @@ |
+// Copyright (c) 2011 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 "chrome_frame/update_launcher.h" |
+ |
+#include <windows.h> |
+#include <Shellapi.h> |
+ |
+#include "google_update_idl.h" // NOLINT |
+ |
+namespace { |
+ |
+const wchar_t kChromeFrameGuid[] = L"{8BA986DA-5100-405E-AA35-86F34A02ACBF}"; |
+ |
+const DWORD kLaunchFailureExitCode = 0xFF; |
+ |
+const wchar_t kUpdateCommandFlag[] = L"--update-cmd"; |
+ |
+// Waits indefinitely for the provided process to exit. Returns the process's |
+// exit code, or kLaunchFailureExitCode if an error occurs in the waiting. |
+DWORD WaitForProcessExitCode(HANDLE handle) { |
+ DWORD exit_code = 0; |
+ |
+ DWORD wait_result = WaitForSingleObject(handle, INFINITE); |
+ |
+ if (wait_result == WAIT_OBJECT_0 && ::GetExitCodeProcess(handle, &exit_code)) |
+ return exit_code; |
+ |
+ return kLaunchFailureExitCode; |
+} |
+ |
+} // namespace |
+ |
+namespace update_launcher { |
+ |
+std::wstring GetUpdateCommandFromArguments(const wchar_t* command_line) { |
+ if (command_line == NULL) |
+ return L""; |
+ |
+ int num_args = 0; |
+ wchar_t** args = NULL; |
+ args = ::CommandLineToArgvW(command_line, &num_args); |
+ |
+ if (num_args != 3) |
+ return L""; |
+ |
+ if (_wcsicmp(args[1], kUpdateCommandFlag) != 0) |
+ return L""; |
+ |
+ return args[2]; |
+} |
+ |
+// Because we do not have 'base' and all of its pretty RAII helpers, please |
+// ensure that this function only ever contains a single 'return', in order |
+// to reduce the chance of introducing a leak. |
+DWORD LaunchUpdateCommand(const std::wstring& command) { |
+ DWORD exit_code = kLaunchFailureExitCode; |
+ |
+ HANDLE process = NULL; |
+ IProcessLauncher* ipl = NULL; |
+ HRESULT hr = ::CoInitialize(NULL); |
+ |
+ if (SUCCEEDED(hr)) { |
+ hr = ::CoCreateInstance(__uuidof(ProcessLauncherClass), NULL, |
+ CLSCTX_ALL, __uuidof(IProcessLauncher), |
+ reinterpret_cast<void**>(&ipl)); |
+ } |
+ |
+ if (SUCCEEDED(hr)) { |
+ ULONG_PTR phandle = NULL; |
+ DWORD id = ::GetCurrentProcessId(); |
+ |
+ hr = ipl->LaunchCmdElevated(kChromeFrameGuid, |
+ command.c_str(), id, &phandle); |
+ if (SUCCEEDED(hr)) { |
+ process = reinterpret_cast<HANDLE>(phandle); |
+ exit_code = WaitForProcessExitCode(process); |
+ } |
+ } |
+ |
+ if (process) |
+ ::CloseHandle(process); |
+ if (ipl) |
+ ipl->Release(); |
+ |
+ ::CoUninitialize(); |
amit
2011/01/24 05:54:50
We should call CoUninitialize only if CoInitialize
erikwright (departed)
2011/01/24 06:21:00
According to the docs, "successful", including S_F
|
+ |
+ return exit_code; |
+} |
+ |
+} // namespace process_launcher |
Property changes on: chrome_frame\update_launcher.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |