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 "google_update/google_update_idl.h"
14 const wchar_t kChromeFrameGuid
[] = L
"{8BA986DA-5100-405E-AA35-86F34A02ACBF}";
16 const DWORD kLaunchFailureExitCode
= 0xFF;
18 const wchar_t kUpdateCommandFlag
[] = L
"--update-cmd";
20 // Waits indefinitely for the provided process to exit. Returns the process's
21 // exit code, or kLaunchFailureExitCode if an error occurs in the waiting.
22 DWORD
WaitForProcessExitCode(HANDLE handle
) {
25 DWORD wait_result
= ::WaitForSingleObject(handle
, INFINITE
);
27 if (wait_result
== WAIT_OBJECT_0
&& ::GetExitCodeProcess(handle
, &exit_code
))
30 return kLaunchFailureExitCode
;
35 namespace update_launcher
{
37 std::wstring
GetUpdateCommandFromArguments(const wchar_t* command_line
) {
40 if (command_line
!= NULL
) {
42 wchar_t** args
= NULL
;
43 args
= ::CommandLineToArgvW(command_line
, &num_args
);
46 if (num_args
== 3 && _wcsicmp(args
[1], kUpdateCommandFlag
) == 0)
55 // Because we do not have 'base' and all of its pretty RAII helpers, please
56 // ensure that this function only ever contains a single 'return', in order
57 // to reduce the chance of introducing a leak.
58 DWORD
LaunchUpdateCommand(const std::wstring
& command
) {
59 DWORD exit_code
= kLaunchFailureExitCode
;
61 HRESULT hr
= ::CoInitialize(NULL
);
64 IProcessLauncher
* ipl
= NULL
;
65 HANDLE process
= NULL
;
67 hr
= ::CoCreateInstance(__uuidof(ProcessLauncherClass
), NULL
,
68 CLSCTX_ALL
, __uuidof(IProcessLauncher
),
69 reinterpret_cast<void**>(&ipl
));
72 ULONG_PTR phandle
= NULL
;
73 DWORD id
= ::GetCurrentProcessId();
75 hr
= ipl
->LaunchCmdElevated(kChromeFrameGuid
,
76 command
.c_str(), id
, &phandle
);
78 process
= reinterpret_cast<HANDLE
>(phandle
);
79 exit_code
= WaitForProcessExitCode(process
);
84 ::CloseHandle(process
);
94 } // namespace process_launcher