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 15 namespace { 16 17 const wchar_t kChromeFrameGuid[] = L"{8BA986DA-5100-405E-AA35-86F34A02ACBF}"; 18 19 const DWORD kLaunchFailureExitCode = 0xFF; 20 21 const 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. 25 DWORD 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 34 namespace update_launcher { 35 36 std::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 54 DWORD 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