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. 4 5#include "chrome_frame/update_launcher.h" 6 7#include <windows.h> 8#include <Shellapi.h> 9 10#include "base/win/scoped_com_initializer.h" 11#include "base/win/scoped_comptr.h" 12#include "base/win/scoped_handle.h" 13#include "google_update/google_update_idl.h" 14 15namespace { 16 17const wchar_t kChromeFrameGuid[] = L"{8BA986DA-5100-405E-AA35-86F34A02ACBF}"; 18 19const DWORD kLaunchFailureExitCode = 0xFF; 20 21const wchar_t kUpdateCommandFlag[] = L"--update-cmd"; 22 23// Waits indefinitely for the provided process to exit. Returns the process's 24// exit code, or kLaunchFailureExitCode if an error occurs in the waiting. 25DWORD WaitForProcessExitCode(HANDLE handle) { 26 DWORD exit_code = 0; 27 return ((::WaitForSingleObject(handle, INFINITE) == WAIT_OBJECT_0) && 28 ::GetExitCodeProcess(handle, &exit_code)) ? 29 exit_code : kLaunchFailureExitCode; 30} 31 32} // namespace 33 34namespace update_launcher { 35 36std::wstring GetUpdateCommandFromArguments(const wchar_t* command_line) { 37 std::wstring command; 38 39 if (command_line != NULL) { 40 int num_args = 0; 41 wchar_t** args = NULL; 42 args = ::CommandLineToArgvW(command_line, &num_args); 43 44 if (args) { 45 if (num_args == 3 && _wcsicmp(args[1], kUpdateCommandFlag) == 0) 46 command = args[2]; 47 ::LocalFree(args); 48 } 49 } 50 51 return command; 52} 53 54DWORD LaunchUpdateCommand(const std::wstring& command) { 55 base::win::ScopedCOMInitializer com_initializer; 56 if (!com_initializer.succeeded()) 57 return kLaunchFailureExitCode; 58 59 base::win::ScopedComPtr<IProcessLauncher> ipl; 60 if (FAILED(ipl.CreateInstance(__uuidof(ProcessLauncherClass)))) 61 return kLaunchFailureExitCode; 62 63 ULONG_PTR phandle = NULL; 64 if (FAILED(ipl->LaunchCmdElevated(kChromeFrameGuid, command.c_str(), 65 ::GetCurrentProcessId(), &phandle))) 66 return kLaunchFailureExitCode; 67 68 base::win::ScopedHandle process(reinterpret_cast<HANDLE>(phandle)); 69 return WaitForProcessExitCode(process); 70} 71 72} // namespace process_launcher 73