• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
WaitForProcessExitCode(HANDLE handle)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 
GetUpdateCommandFromArguments(const wchar_t * command_line)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 
LaunchUpdateCommand(const std::wstring & command)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