Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: recovery/repair_exe/mspexecutableelevator.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2007-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // This is the implementation of the API for verifying and executing
17 // an executable under high integrity using an Msi Patch.
18 //
19 // This class assumes the following:
20 // 1) its needed Msi has already been installed,
21 // 2) its needed Msp is in the same directory as this module,
22 // 3) the name of the Msp file,
23 // 4) the name of the property passed as CustomActionData to the custom action,
24 // 5) the guid of the patch, and
25 // 6) the guid of the Msi install which will be patched.
26
27 #define _WIN32_MSI 300
28
29 #include "omaha/recovery/repair_exe/mspexecutableelevator.h"
30 #include <atlpath.h>
31 #include <msi.h>
32 #include "omaha/base/debug.h"
33 #include "omaha/base/safe_format.h"
34 #include "omaha/base/string.h"
35
36 namespace omaha {
37
38 namespace msp_executable_elevator {
39
40 // Used to return information back to the process that called
41 // ExecuteGoogleSignedExe.
42 struct SharedMemoryInfo {
43 HANDLE process;
44 HRESULT launch_result;
45 };
46
47 // Used to store the name of the shared memory. The name is retrieved from
48 // the MSP command line when parsing the command line. The code assumes that
49 // only one thread per process will call ParseMSPCommandLine followed by
50 // SetResultOfExecute (which is a safe assumption if this functionality is only
51 // used for the purpose for which it was originally written).
52 // Assumes that the MSP is in the same directory as the current process.
53 static TCHAR parsed_shared_memory_name[200];
54
55 HRESULT ExecuteGoogleSignedExe(const TCHAR* exe,
56 const TCHAR* args,
57 const TCHAR* kProductGuid,
58 const TCHAR* kPatchGuid,
59 const TCHAR* kPatchName,
60 HANDLE* process) {
61 ASSERT1(exe);
62 ASSERT1(args);
63 ASSERT1(process);
64 ASSERT1(kProductGuid);
65 ASSERT1(kPatchGuid);
66 ASSERT1(kPatchName);
67
68 // Create shared memory in which to receive result of attempt to launch
69 // process and a handle to the launched process.
70 HRESULT hr = E_FAIL;
71 GUID random_guid = {0};
72 TCHAR shared_memory_name[200] = {0};
73 if (SUCCEEDED(::CoCreateGuid(&random_guid)) &&
74 0 < ::StringFromGUID2(random_guid,
75 shared_memory_name,
76 ARRAYSIZE(shared_memory_name))) {
77 HANDLE file_mapping = ::CreateFileMapping(INVALID_HANDLE_VALUE,
78 NULL,
79 PAGE_READWRITE,
80 0,
81 sizeof(file_mapping),
82 shared_memory_name);
83 if (file_mapping) {
84 SharedMemoryInfo* shared_info = reinterpret_cast<SharedMemoryInfo*>
85 (::MapViewOfFileEx(file_mapping,
86 FILE_MAP_ALL_ACCESS,
87 0,
88 0,
89 sizeof(*shared_info),
90 0));
91 if (shared_info) {
92 shared_info->launch_result = E_FAIL;
93 shared_info->process = NULL;
94 // Create command line to pass to patch. Parameters are the name of the
95 // shared memory just created, the current process id, the executable
96 // to launch, and the executable's arguments.
97 CString command_line;
98 SafeCStringFormat(&command_line,
99 _T("EXECUTABLECOMMANDLINE=\"%s %u \"\"%s\"\" %s\" ")
100 _T("REINSTALL=ALL"),
101 shared_memory_name,
102 GetCurrentProcessId(),
103 exe,
104 args);
105 // Generate path to patch using path to current module.
106 TCHAR module_name[MAX_PATH] = {0};
107 DWORD len = ::GetModuleFileName(_AtlBaseModule.GetModuleInstance(),
108 module_name,
109 ARRAYSIZE(module_name));
110 module_name[ARRAYSIZE(module_name) - 1] = '\0';
111 if (0 < len && len < ARRAYSIZE(module_name) &&
112 0 < command_line.GetLength()) {
113 CPath path = module_name;
114 if (path.RemoveFileSpec() && path.Append(kPatchName)) {
115 path.Canonicalize();
116 // Set install level to none so that user does not see
117 // an Msi window and so that a restore point is not created.
118 ::MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
119 UINT res = ::MsiApplyPatch(path,
120 NULL,
121 INSTALLTYPE_DEFAULT,
122 command_line);
123 // MsiApplyPatch will not return until the passed executable has
124 // been launched (or not) and the shared memory has been updated.
125 *process = shared_info->process;
126 hr = HRESULT_FROM_WIN32(res);
127 if (SUCCEEDED(hr))
128 hr = shared_info->launch_result;
129 }
130 }
131 ::MsiRemovePatches(kPatchGuid,
132 kProductGuid,
133 INSTALLTYPE_SINGLE_INSTANCE,
134 NULL);
135 VERIFY1(::UnmapViewOfFile(shared_info));
136 }
137 VERIFY1(::CloseHandle(file_mapping));
138 }
139 }
140 return hr;
141 }
142
143 bool ParseMSPCommandLine(TCHAR* command_line,
144 TCHAR** executable_result,
145 TCHAR** arguments_result,
146 DWORD* calling_process_id) {
147 ASSERT1(command_line);
148 ASSERT1(executable_result);
149 ASSERT1(arguments_result);
150 ASSERT1(calling_process_id);
151 // Parse command line. First extract name of shared memory into which
152 // the process handle of launched executable will be written. Then extract
153 // the process id of calling process. This process id will be used to create
154 // for the calling process a handle to the launched executable. Finally,
155 // extract the path to executable so that we can verify the executable.
156 TCHAR* shared_memory_name = NULL;
157 TCHAR* process_id_param = NULL;
158 TCHAR* arguments = NULL;
159 if (SplitCommandLineInPlace(command_line, &shared_memory_name, &arguments) &&
160 shared_memory_name && arguments &&
161 SplitCommandLineInPlace(arguments, &process_id_param, &arguments) &&
162 process_id_param && arguments &&
163 SplitCommandLineInPlace(arguments, executable_result, &arguments) &&
164 *executable_result && arguments) {
165 *calling_process_id = static_cast<DWORD>(_wtoi(process_id_param));
166 *arguments_result = arguments;
167 _tcsncpy(parsed_shared_memory_name,
168 shared_memory_name,
169 ARRAYSIZE(parsed_shared_memory_name));
170 parsed_shared_memory_name[ARRAYSIZE(parsed_shared_memory_name) - 1] =
171 _T('\0');
172 return true;
173 }
174 return false;
175 }
176
177 // Copy process handle and result to shared memory.
178 // Process can be NULL.
179 bool SetResultOfExecute(HANDLE process, HRESULT result) {
180 bool success = false;
181 if (_T('\0') != *parsed_shared_memory_name) {
182 HANDLE file_mapping = ::OpenFileMapping(FILE_MAP_WRITE,
183 FALSE,
184 parsed_shared_memory_name);
185 if (file_mapping) {
186 SharedMemoryInfo* shared_info = reinterpret_cast<SharedMemoryInfo*>
187 (::MapViewOfFileEx(file_mapping,
188 FILE_MAP_WRITE,
189 0,
190 0,
191 sizeof(SharedMemoryInfo),
192 0));
193 if (shared_info) {
194 shared_info->process = process;
195 shared_info->launch_result = result;
196 VERIFY1(::UnmapViewOfFile(shared_info));
197 success = true;
198 } else {
199 ASSERT(false, (_T("::MapViewOfFileEx failed.")));
200 }
201
202 VERIFY1(::CloseHandle(file_mapping));
203 } else {
204 ASSERT(false, (_T("::OpenFileMapping failed.")));
205 }
206 } else {
207 ASSERT(false, (_T("parsed_shared_memory_name is empty.")));
208 }
209 return success;
210 }
211
212 } // namespace msp_executable_elevator
213
214 } // namespace omaha
215
OLDNEW
« no previous file with comments | « recovery/repair_exe/mspexecutableelevator.h ('k') | recovery/repair_exe/mspexecutableelevator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698