Home | History | Annotate | Download | only in chrome_frame
      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