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.
5 #include "chrome_frame/update_launcher.h"
10 #include "base/win/scoped_com_initializer.h"
11 #include "google_update/google_update_idl.h"
15 const wchar_t kChromeFrameGuid
[] = L
"{8BA986DA-5100-405E-AA35-86F34A02ACBF}";
17 const DWORD kLaunchFailureExitCode
= 0xFF;
19 const wchar_t kUpdateCommandFlag
[] = L
"--update-cmd";
21 // Waits indefinitely for the provided process to exit. Returns the process's
22 // exit code, or kLaunchFailureExitCode if an error occurs in the waiting.
23 DWORD
WaitForProcessExitCode(HANDLE handle
) {
25 return ((::WaitForSingleObject(handle
, INFINITE
) == WAIT_OBJECT_0
) &&
26 ::GetExitCodeProcess(handle
, &exit_code
)) ?
27 exit_code
: kLaunchFailureExitCode
;
32 namespace update_launcher
{
34 std::wstring
GetUpdateCommandFromArguments(const wchar_t* command_line
) {
37 if (command_line
!= NULL
) {
39 wchar_t** args
= NULL
;
40 args
= ::CommandLineToArgvW(command_line
, &num_args
);
43 if (num_args
== 3 && _wcsicmp(args
[1], kUpdateCommandFlag
) == 0)
52 // Because we do not have 'base' and all of its pretty RAII helpers, please
53 // ensure that this function only ever contains a single 'return', in order
54 // to reduce the chance of introducing a leak.
55 DWORD
LaunchUpdateCommand(const std::wstring
& command
) {
56 DWORD exit_code
= kLaunchFailureExitCode
;
58 base::win::ScopedCOMInitializer com_initializer
;
59 if (com_initializer
.succeeded()) {
60 IProcessLauncher
* ipl
= NULL
;
61 HANDLE process
= NULL
;
63 HRESULT hr
= ::CoCreateInstance(__uuidof(ProcessLauncherClass
), NULL
,
64 CLSCTX_ALL
, __uuidof(IProcessLauncher
),
65 reinterpret_cast<void**>(&ipl
));
68 ULONG_PTR phandle
= NULL
;
69 DWORD id
= ::GetCurrentProcessId();
71 hr
= ipl
->LaunchCmdElevated(kChromeFrameGuid
,
72 command
.c_str(), id
, &phandle
);
74 process
= reinterpret_cast<HANDLE
>(phandle
);
75 exit_code
= WaitForProcessExitCode(process
);
80 ::CloseHandle(process
);
88 } // namespace process_launcher