Chromium Code Reviews| 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 |