|
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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 "google_update_idl.h" // NOLINT | |
11 | |
12 namespace { | |
13 | |
14 const wchar_t kChromeFrameGuid[] = L"{8BA986DA-5100-405E-AA35-86F34A02ACBF}"; | |
15 | |
16 const DWORD kLaunchFailureExitCode = 0xFF; | |
17 | |
18 const wchar_t kUpdateCommandFlag[] = L"--update-cmd"; | |
19 | |
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) { | |
23 DWORD exit_code = 0; | |
24 | |
25 DWORD wait_result = WaitForSingleObject(handle, INFINITE); | |
26 | |
27 if (wait_result == WAIT_OBJECT_0 && ::GetExitCodeProcess(handle, &exit_code)) | |
28 return exit_code; | |
29 | |
30 return kLaunchFailureExitCode; | |
31 } | |
32 | |
33 } // namespace | |
34 | |
35 namespace update_launcher { | |
36 | |
37 std::wstring GetUpdateCommandFromArguments(const wchar_t* command_line) { | |
38 if (command_line == NULL) | |
39 return L""; | |
40 | |
41 int num_args = 0; | |
42 wchar_t** args = NULL; | |
43 args = ::CommandLineToArgvW(command_line, &num_args); | |
robertshield
2011/01/24 15:08:42
The caller is supposed to free args when done (the
erikwright (departed)
2011/01/24 17:17:14
Done.
| |
44 | |
45 if (num_args != 3) | |
46 return L""; | |
47 | |
48 if (_wcsicmp(args[1], kUpdateCommandFlag) != 0) | |
robertshield
2011/01/24 15:08:42
You should also check that args isn't NULL, to be
erikwright (departed)
2011/01/24 17:17:14
Done.
| |
49 return L""; | |
50 | |
51 return args[2]; | |
52 } | |
53 | |
54 // Because we do not have 'base' and all of its pretty RAII helpers, please | |
55 // ensure that this function only ever contains a single 'return', in order | |
56 // to reduce the chance of introducing a leak. | |
57 DWORD LaunchUpdateCommand(const std::wstring& command) { | |
58 DWORD exit_code = kLaunchFailureExitCode; | |
59 | |
60 HRESULT hr = ::CoInitialize(NULL); | |
61 | |
62 if (SUCCEEDED(hr)) { | |
63 IProcessLauncher* ipl = NULL; | |
64 HANDLE process = NULL; | |
65 | |
66 hr = ::CoCreateInstance(__uuidof(ProcessLauncherClass), NULL, | |
67 CLSCTX_ALL, __uuidof(IProcessLauncher), | |
68 reinterpret_cast<void**>(&ipl)); | |
69 | |
70 if (SUCCEEDED(hr)) { | |
71 ULONG_PTR phandle = NULL; | |
72 DWORD id = ::GetCurrentProcessId(); | |
73 | |
74 hr = ipl->LaunchCmdElevated(kChromeFrameGuid, | |
75 command.c_str(), id, &phandle); | |
76 if (SUCCEEDED(hr)) { | |
77 process = reinterpret_cast<HANDLE>(phandle); | |
78 exit_code = WaitForProcessExitCode(process); | |
robertshield
2011/01/24 15:08:42
nit: one too many spaces.
erikwright (departed)
2011/01/24 17:17:14
Done.
| |
79 } | |
80 } | |
81 | |
82 if (process) | |
83 ::CloseHandle(process); | |
84 if (ipl) | |
85 ipl->Release(); | |
86 | |
87 ::CoUninitialize(); | |
88 } | |
89 | |
90 return exit_code; | |
91 } | |
92 | |
93 } // namespace process_launcher | |
OLD | NEW |