diff options
Diffstat (limited to 'src/burn/engine/elevation.cpp')
-rw-r--r-- | src/burn/engine/elevation.cpp | 3239 |
1 files changed, 3239 insertions, 0 deletions
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp new file mode 100644 index 00000000..9d1b8fc7 --- /dev/null +++ b/src/burn/engine/elevation.cpp | |||
@@ -0,0 +1,3239 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | |||
6 | const DWORD BURN_TIMEOUT = 5 * 60 * 1000; // TODO: is 5 minutes good? | ||
7 | |||
8 | typedef enum _BURN_ELEVATION_MESSAGE_TYPE | ||
9 | { | ||
10 | BURN_ELEVATION_MESSAGE_TYPE_UNKNOWN, | ||
11 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE, | ||
12 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE, | ||
13 | BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN, | ||
14 | BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME, | ||
15 | BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, | ||
16 | BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE, | ||
17 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, | ||
18 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, | ||
19 | BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP, | ||
20 | BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION, | ||
21 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, | ||
22 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE, | ||
23 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE, | ||
24 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE, | ||
25 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER, | ||
26 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY, | ||
27 | BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_EMBEDDED_CHILD, | ||
28 | BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE, | ||
29 | BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE, | ||
30 | BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, | ||
31 | BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, | ||
32 | BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, | ||
33 | |||
34 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, | ||
35 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, | ||
36 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN, | ||
37 | BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE, | ||
38 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN, | ||
39 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE, | ||
40 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, | ||
41 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, | ||
42 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR, | ||
43 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE, | ||
44 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE, | ||
45 | BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID, | ||
46 | BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE, | ||
47 | } BURN_ELEVATION_MESSAGE_TYPE; | ||
48 | |||
49 | |||
50 | // struct | ||
51 | |||
52 | typedef struct _BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT | ||
53 | { | ||
54 | BURN_USER_EXPERIENCE* pBA; | ||
55 | BOOL fPauseCompleteNeeded; | ||
56 | BOOL fSrpCompleteNeeded; | ||
57 | } BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT; | ||
58 | |||
59 | typedef struct _BURN_ELEVATION_CACHE_MESSAGE_CONTEXT | ||
60 | { | ||
61 | PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler; | ||
62 | LPPROGRESS_ROUTINE pfnProgress; | ||
63 | LPVOID pvContext; | ||
64 | } BURN_ELEVATION_CACHE_MESSAGE_CONTEXT; | ||
65 | |||
66 | typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT | ||
67 | { | ||
68 | PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler; | ||
69 | LPVOID pvContext; | ||
70 | } BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT; | ||
71 | |||
72 | typedef struct _BURN_ELEVATION_MSI_MESSAGE_CONTEXT | ||
73 | { | ||
74 | PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler; | ||
75 | LPVOID pvContext; | ||
76 | } BURN_ELEVATION_MSI_MESSAGE_CONTEXT; | ||
77 | |||
78 | typedef struct _BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT | ||
79 | { | ||
80 | DWORD dwProcessId; | ||
81 | } BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT; | ||
82 | |||
83 | typedef struct _BURN_ELEVATION_CHILD_MESSAGE_CONTEXT | ||
84 | { | ||
85 | DWORD dwLoggingTlsId; | ||
86 | HANDLE hPipe; | ||
87 | HANDLE* phLock; | ||
88 | BOOL* pfDisabledAutomaticUpdates; | ||
89 | BURN_APPROVED_EXES* pApprovedExes; | ||
90 | BURN_CONTAINERS* pContainers; | ||
91 | BURN_PACKAGES* pPackages; | ||
92 | BURN_PAYLOADS* pPayloads; | ||
93 | BURN_VARIABLES* pVariables; | ||
94 | BURN_REGISTRATION* pRegistration; | ||
95 | BURN_USER_EXPERIENCE* pUserExperience; | ||
96 | } BURN_ELEVATION_CHILD_MESSAGE_CONTEXT; | ||
97 | |||
98 | |||
99 | // internal function declarations | ||
100 | |||
101 | static DWORD WINAPI ElevatedChildCacheThreadProc( | ||
102 | __in LPVOID lpThreadParameter | ||
103 | ); | ||
104 | static HRESULT WaitForElevatedChildCacheThread( | ||
105 | __in HANDLE hCacheThread, | ||
106 | __in DWORD dwExpectedExitCode | ||
107 | ); | ||
108 | static HRESULT ProcessApplyInitializeMessages( | ||
109 | __in BURN_PIPE_MESSAGE* pMsg, | ||
110 | __in_opt LPVOID pvContext, | ||
111 | __out DWORD* pdwResult | ||
112 | ); | ||
113 | static HRESULT ProcessBurnCacheMessages( | ||
114 | __in BURN_PIPE_MESSAGE* pMsg, | ||
115 | __in LPVOID pvContext, | ||
116 | __out DWORD* pdwResult | ||
117 | ); | ||
118 | static HRESULT ProcessGenericExecuteMessages( | ||
119 | __in BURN_PIPE_MESSAGE* pMsg, | ||
120 | __in LPVOID pvContext, | ||
121 | __out DWORD* pdwResult | ||
122 | ); | ||
123 | static HRESULT ProcessMsiPackageMessages( | ||
124 | __in BURN_PIPE_MESSAGE* pMsg, | ||
125 | __in_opt LPVOID pvContext, | ||
126 | __out DWORD* pdwResult | ||
127 | ); | ||
128 | static HRESULT ProcessLaunchApprovedExeMessages( | ||
129 | __in BURN_PIPE_MESSAGE* pMsg, | ||
130 | __in_opt LPVOID pvContext, | ||
131 | __out DWORD* pdwResult | ||
132 | ); | ||
133 | static HRESULT ProcessProgressRoutineMessage( | ||
134 | __in BURN_PIPE_MESSAGE* pMsg, | ||
135 | __in LPPROGRESS_ROUTINE pfnProgress, | ||
136 | __in LPVOID pvContext, | ||
137 | __out DWORD* pdwResult | ||
138 | ); | ||
139 | static HRESULT ProcessElevatedChildMessage( | ||
140 | __in BURN_PIPE_MESSAGE* pMsg, | ||
141 | __in_opt LPVOID pvContext, | ||
142 | __out DWORD* pdwResult | ||
143 | ); | ||
144 | static HRESULT ProcessElevatedChildCacheMessage( | ||
145 | __in BURN_PIPE_MESSAGE* pMsg, | ||
146 | __in_opt LPVOID pvContext, | ||
147 | __out DWORD* pdwResult | ||
148 | ); | ||
149 | static HRESULT ProcessResult( | ||
150 | __in DWORD dwResult, | ||
151 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
152 | ); | ||
153 | static HRESULT OnApplyInitialize( | ||
154 | __in HANDLE hPipe, | ||
155 | __in BURN_VARIABLES* pVariables, | ||
156 | __in BURN_REGISTRATION* pRegistration, | ||
157 | __in HANDLE* phLock, | ||
158 | __in BOOL* pfDisabledWindowsUpdate, | ||
159 | __in BYTE* pbData, | ||
160 | __in SIZE_T cbData | ||
161 | ); | ||
162 | static HRESULT OnApplyUninitialize( | ||
163 | __in HANDLE* phLock | ||
164 | ); | ||
165 | static HRESULT OnSessionBegin( | ||
166 | __in BURN_REGISTRATION* pRegistration, | ||
167 | __in BURN_VARIABLES* pVariables, | ||
168 | __in BYTE* pbData, | ||
169 | __in SIZE_T cbData | ||
170 | ); | ||
171 | static HRESULT OnSessionResume( | ||
172 | __in BURN_REGISTRATION* pRegistration, | ||
173 | __in BURN_VARIABLES* pVariables, | ||
174 | __in BYTE* pbData, | ||
175 | __in SIZE_T cbData | ||
176 | ); | ||
177 | static HRESULT OnSessionEnd( | ||
178 | __in BURN_PACKAGES* pPackages, | ||
179 | __in BURN_REGISTRATION* pRegistration, | ||
180 | __in BURN_VARIABLES* pVariables, | ||
181 | __in BYTE* pbData, | ||
182 | __in SIZE_T cbData | ||
183 | ); | ||
184 | static HRESULT OnSaveState( | ||
185 | __in BURN_REGISTRATION* pRegistration, | ||
186 | __in BYTE* pbData, | ||
187 | __in SIZE_T cbData | ||
188 | ); | ||
189 | static HRESULT OnCacheCompletePayload( | ||
190 | __in HANDLE hPipe, | ||
191 | __in BURN_PACKAGES* pPackages, | ||
192 | __in BURN_PAYLOADS* pPayloads, | ||
193 | __in BYTE* pbData, | ||
194 | __in SIZE_T cbData | ||
195 | ); | ||
196 | static HRESULT OnCacheVerifyPayload( | ||
197 | __in HANDLE hPipe, | ||
198 | __in BURN_PACKAGES* pPackages, | ||
199 | __in BURN_PAYLOADS* pPayloads, | ||
200 | __in BYTE* pbData, | ||
201 | __in SIZE_T cbData | ||
202 | ); | ||
203 | static void OnCacheCleanup( | ||
204 | __in_z LPCWSTR wzBundleId | ||
205 | ); | ||
206 | static HRESULT OnProcessDependentRegistration( | ||
207 | __in const BURN_REGISTRATION* pRegistration, | ||
208 | __in BYTE* pbData, | ||
209 | __in SIZE_T cbData | ||
210 | ); | ||
211 | static HRESULT OnExecuteExePackage( | ||
212 | __in HANDLE hPipe, | ||
213 | __in BURN_PACKAGES* pPackages, | ||
214 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
215 | __in BURN_VARIABLES* pVariables, | ||
216 | __in BYTE* pbData, | ||
217 | __in SIZE_T cbData | ||
218 | ); | ||
219 | static HRESULT OnExecuteMsiPackage( | ||
220 | __in HANDLE hPipe, | ||
221 | __in BURN_PACKAGES* pPackages, | ||
222 | __in BURN_VARIABLES* pVariables, | ||
223 | __in BYTE* pbData, | ||
224 | __in SIZE_T cbData | ||
225 | ); | ||
226 | static HRESULT OnExecuteMspPackage( | ||
227 | __in HANDLE hPipe, | ||
228 | __in BURN_PACKAGES* pPackages, | ||
229 | __in BURN_VARIABLES* pVariables, | ||
230 | __in BYTE* pbData, | ||
231 | __in SIZE_T cbData | ||
232 | ); | ||
233 | static HRESULT OnExecuteMsuPackage( | ||
234 | __in HANDLE hPipe, | ||
235 | __in BURN_PACKAGES* pPackages, | ||
236 | __in BURN_VARIABLES* pVariables, | ||
237 | __in BYTE* pbData, | ||
238 | __in SIZE_T cbData | ||
239 | ); | ||
240 | static HRESULT OnExecutePackageProviderAction( | ||
241 | __in BURN_PACKAGES* pPackages, | ||
242 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
243 | __in BYTE* pbData, | ||
244 | __in SIZE_T cbData | ||
245 | ); | ||
246 | static HRESULT OnExecutePackageDependencyAction( | ||
247 | __in BURN_PACKAGES* pPackages, | ||
248 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
249 | __in BYTE* pbData, | ||
250 | __in SIZE_T cbData | ||
251 | ); | ||
252 | static HRESULT CALLBACK BurnCacheMessageHandler( | ||
253 | __in BURN_CACHE_MESSAGE* pMessage, | ||
254 | __in LPVOID pvContext | ||
255 | ); | ||
256 | static DWORD CALLBACK ElevatedProgressRoutine( | ||
257 | __in LARGE_INTEGER TotalFileSize, | ||
258 | __in LARGE_INTEGER TotalBytesTransferred, | ||
259 | __in LARGE_INTEGER StreamSize, | ||
260 | __in LARGE_INTEGER StreamBytesTransferred, | ||
261 | __in DWORD dwStreamNumber, | ||
262 | __in DWORD dwCallbackReason, | ||
263 | __in HANDLE hSourceFile, | ||
264 | __in HANDLE hDestinationFile, | ||
265 | __in_opt LPVOID lpData | ||
266 | ); | ||
267 | static int GenericExecuteMessageHandler( | ||
268 | __in GENERIC_EXECUTE_MESSAGE* pMessage, | ||
269 | __in LPVOID pvContext | ||
270 | ); | ||
271 | static int MsiExecuteMessageHandler( | ||
272 | __in WIU_MSI_EXECUTE_MESSAGE* pMessage, | ||
273 | __in_opt LPVOID pvContext | ||
274 | ); | ||
275 | static HRESULT OnCleanPackage( | ||
276 | __in BURN_PACKAGES* pPackages, | ||
277 | __in BYTE* pbData, | ||
278 | __in SIZE_T cbData | ||
279 | ); | ||
280 | static HRESULT OnLaunchApprovedExe( | ||
281 | __in HANDLE hPipe, | ||
282 | __in BURN_APPROVED_EXES* pApprovedExes, | ||
283 | __in BURN_VARIABLES* pVariables, | ||
284 | __in BYTE* pbData, | ||
285 | __in SIZE_T cbData | ||
286 | ); | ||
287 | static HRESULT OnMsiBeginTransaction( | ||
288 | __in BURN_PACKAGES* pPackages, | ||
289 | __in BYTE* pbData, | ||
290 | __in SIZE_T cbData | ||
291 | ); | ||
292 | static HRESULT OnMsiCommitTransaction( | ||
293 | __in BURN_PACKAGES* pPackages, | ||
294 | __in BYTE* pbData, | ||
295 | __in SIZE_T cbData | ||
296 | ); | ||
297 | static HRESULT OnMsiRollbackTransaction( | ||
298 | __in BURN_PACKAGES* pPackages, | ||
299 | __in BYTE* pbData, | ||
300 | __in SIZE_T cbData | ||
301 | ); | ||
302 | static HRESULT ElevatedOnPauseAUBegin( | ||
303 | __in HANDLE hPipe | ||
304 | ); | ||
305 | static HRESULT ElevatedOnPauseAUComplete( | ||
306 | __in HANDLE hPipe, | ||
307 | __in HRESULT hrStatus | ||
308 | ); | ||
309 | static HRESULT ElevatedOnSystemRestorePointBegin( | ||
310 | __in HANDLE hPipe | ||
311 | ); | ||
312 | static HRESULT ElevatedOnSystemRestorePointComplete( | ||
313 | __in HANDLE hPipe, | ||
314 | __in HRESULT hrStatus | ||
315 | ); | ||
316 | |||
317 | |||
318 | // function definitions | ||
319 | |||
320 | extern "C" HRESULT ElevationElevate( | ||
321 | __in BURN_ENGINE_STATE* pEngineState, | ||
322 | __in_opt HWND hwndParent | ||
323 | ) | ||
324 | { | ||
325 | Assert(BURN_MODE_ELEVATED != pEngineState->mode); | ||
326 | Assert(!pEngineState->companionConnection.sczName); | ||
327 | Assert(!pEngineState->companionConnection.sczSecret); | ||
328 | Assert(!pEngineState->companionConnection.hProcess); | ||
329 | Assert(!pEngineState->companionConnection.dwProcessId); | ||
330 | Assert(INVALID_HANDLE_VALUE == pEngineState->companionConnection.hPipe); | ||
331 | Assert(INVALID_HANDLE_VALUE == pEngineState->companionConnection.hCachePipe); | ||
332 | |||
333 | HRESULT hr = S_OK; | ||
334 | int nResult = IDOK; | ||
335 | HANDLE hPipesCreatedEvent = INVALID_HANDLE_VALUE; | ||
336 | |||
337 | hr = UserExperienceOnElevateBegin(&pEngineState->userExperience); | ||
338 | ExitOnRootFailure(hr, "BA aborted elevation requirement."); | ||
339 | |||
340 | hr = PipeCreateNameAndSecret(&pEngineState->companionConnection.sczName, &pEngineState->companionConnection.sczSecret); | ||
341 | ExitOnFailure(hr, "Failed to create pipe name and client token."); | ||
342 | |||
343 | hr = PipeCreatePipes(&pEngineState->companionConnection, TRUE, &hPipesCreatedEvent); | ||
344 | ExitOnFailure(hr, "Failed to create pipe and cache pipe."); | ||
345 | |||
346 | LogId(REPORT_STANDARD, MSG_LAUNCH_ELEVATED_ENGINE_STARTING); | ||
347 | |||
348 | do | ||
349 | { | ||
350 | nResult = IDOK; | ||
351 | |||
352 | // Create the elevated process and if successful, wait for it to connect. | ||
353 | hr = PipeLaunchChildProcess(pEngineState->sczBundleEngineWorkingPath, &pEngineState->companionConnection, TRUE, hwndParent); | ||
354 | if (SUCCEEDED(hr)) | ||
355 | { | ||
356 | LogId(REPORT_STANDARD, MSG_LAUNCH_ELEVATED_ENGINE_SUCCESS); | ||
357 | |||
358 | hr = PipeWaitForChildConnect(&pEngineState->companionConnection); | ||
359 | if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr) | ||
360 | { | ||
361 | hr = E_SUSPECTED_AV_INTERFERENCE; | ||
362 | } | ||
363 | ExitOnFailure(hr, "Failed to connect to elevated child process."); | ||
364 | |||
365 | LogId(REPORT_STANDARD, MSG_CONNECT_TO_ELEVATED_ENGINE_SUCCESS); | ||
366 | } | ||
367 | else if (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr) | ||
368 | { | ||
369 | // The user clicked "Cancel" on the elevation prompt or the elevation prompt timed out, provide the notification with the option to retry. | ||
370 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
371 | nResult = UserExperienceSendError(&pEngineState->userExperience, BOOTSTRAPPER_ERROR_TYPE_ELEVATE, NULL, hr, NULL, MB_ICONERROR | MB_RETRYCANCEL, IDNOACTION); | ||
372 | } | ||
373 | } while (IDRETRY == nResult); | ||
374 | ExitOnFailure(hr, "Failed to elevate."); | ||
375 | |||
376 | LExit: | ||
377 | ReleaseHandle(hPipesCreatedEvent); | ||
378 | |||
379 | if (FAILED(hr)) | ||
380 | { | ||
381 | PipeConnectionUninitialize(&pEngineState->companionConnection); | ||
382 | } | ||
383 | |||
384 | UserExperienceOnElevateComplete(&pEngineState->userExperience, hr); | ||
385 | |||
386 | return hr; | ||
387 | } | ||
388 | |||
389 | extern "C" HRESULT ElevationApplyInitialize( | ||
390 | __in HANDLE hPipe, | ||
391 | __in BURN_USER_EXPERIENCE* pBA, | ||
392 | __in BURN_VARIABLES* pVariables, | ||
393 | __in BOOTSTRAPPER_ACTION action, | ||
394 | __in BURN_AU_PAUSE_ACTION auAction, | ||
395 | __in BOOL fTakeSystemRestorePoint | ||
396 | ) | ||
397 | { | ||
398 | HRESULT hr = S_OK; | ||
399 | BYTE* pbData = NULL; | ||
400 | SIZE_T cbData = 0; | ||
401 | DWORD dwResult = 0; | ||
402 | BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT context = { }; | ||
403 | |||
404 | context.pBA = pBA; | ||
405 | |||
406 | // serialize message data | ||
407 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)action); | ||
408 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
409 | |||
410 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)auAction); | ||
411 | ExitOnFailure(hr, "Failed to write update action to message buffer."); | ||
412 | |||
413 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fTakeSystemRestorePoint); | ||
414 | ExitOnFailure(hr, "Failed to write system restore point action to message buffer."); | ||
415 | |||
416 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
417 | ExitOnFailure(hr, "Failed to write variables."); | ||
418 | |||
419 | // send message | ||
420 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE, pbData, cbData, ProcessApplyInitializeMessages, &context, &dwResult); | ||
421 | ExitOnFailure(hr, "Failed to send message to per-machine process."); | ||
422 | |||
423 | hr = (HRESULT)dwResult; | ||
424 | |||
425 | // Best effort to keep the sequence of BA events sane. | ||
426 | if (context.fPauseCompleteNeeded) | ||
427 | { | ||
428 | UserExperienceOnPauseAUComplete(pBA, hr); | ||
429 | } | ||
430 | if (context.fSrpCompleteNeeded) | ||
431 | { | ||
432 | UserExperienceOnSystemRestorePointComplete(pBA, hr); | ||
433 | } | ||
434 | |||
435 | LExit: | ||
436 | ReleaseBuffer(pbData); | ||
437 | |||
438 | return hr; | ||
439 | } | ||
440 | |||
441 | extern "C" HRESULT ElevationApplyUninitialize( | ||
442 | __in HANDLE hPipe | ||
443 | ) | ||
444 | { | ||
445 | HRESULT hr = S_OK; | ||
446 | BYTE* pbData = NULL; | ||
447 | SIZE_T cbData = 0; | ||
448 | DWORD dwResult = 0; | ||
449 | |||
450 | // send message | ||
451 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE, pbData, cbData, NULL, NULL, &dwResult); | ||
452 | ExitOnFailure(hr, "Failed to send message to per-machine process."); | ||
453 | |||
454 | hr = (HRESULT)dwResult; | ||
455 | |||
456 | LExit: | ||
457 | ReleaseBuffer(pbData); | ||
458 | |||
459 | return hr; | ||
460 | } | ||
461 | |||
462 | /******************************************************************* | ||
463 | ElevationSessionBegin - | ||
464 | |||
465 | *******************************************************************/ | ||
466 | extern "C" HRESULT ElevationSessionBegin( | ||
467 | __in HANDLE hPipe, | ||
468 | __in_z LPCWSTR wzEngineWorkingPath, | ||
469 | __in_z LPCWSTR wzResumeCommandLine, | ||
470 | __in BOOL fDisableResume, | ||
471 | __in BURN_VARIABLES* pVariables, | ||
472 | __in DWORD dwRegistrationOperations, | ||
473 | __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction, | ||
474 | __in DWORD64 qwEstimatedSize | ||
475 | ) | ||
476 | { | ||
477 | HRESULT hr = S_OK; | ||
478 | BYTE* pbData = NULL; | ||
479 | SIZE_T cbData = 0; | ||
480 | DWORD dwResult = 0; | ||
481 | |||
482 | // serialize message data | ||
483 | hr = BuffWriteString(&pbData, &cbData, wzEngineWorkingPath); | ||
484 | ExitOnFailure(hr, "Failed to write engine working path to message buffer."); | ||
485 | |||
486 | hr = BuffWriteString(&pbData, &cbData, wzResumeCommandLine); | ||
487 | ExitOnFailure(hr, "Failed to write resume command line to message buffer."); | ||
488 | |||
489 | hr = BuffWriteNumber(&pbData, &cbData, fDisableResume); | ||
490 | ExitOnFailure(hr, "Failed to write resume flag."); | ||
491 | |||
492 | hr = BuffWriteNumber(&pbData, &cbData, dwRegistrationOperations); | ||
493 | ExitOnFailure(hr, "Failed to write registration operations to message buffer."); | ||
494 | |||
495 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction); | ||
496 | ExitOnFailure(hr, "Failed to write dependency registration action to message buffer."); | ||
497 | |||
498 | hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize); | ||
499 | ExitOnFailure(hr, "Failed to write estimated size to message buffer."); | ||
500 | |||
501 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
502 | ExitOnFailure(hr, "Failed to write variables."); | ||
503 | |||
504 | // send message | ||
505 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN, pbData, cbData, NULL, NULL, &dwResult); | ||
506 | ExitOnFailure(hr, "Failed to send message to per-machine process."); | ||
507 | |||
508 | hr = (HRESULT)dwResult; | ||
509 | |||
510 | LExit: | ||
511 | ReleaseBuffer(pbData); | ||
512 | |||
513 | return hr; | ||
514 | } | ||
515 | |||
516 | /******************************************************************* | ||
517 | ElevationSessionResume - | ||
518 | |||
519 | *******************************************************************/ | ||
520 | extern "C" HRESULT ElevationSessionResume( | ||
521 | __in HANDLE hPipe, | ||
522 | __in_z LPCWSTR wzResumeCommandLine, | ||
523 | __in BOOL fDisableResume, | ||
524 | __in BURN_VARIABLES* pVariables | ||
525 | ) | ||
526 | { | ||
527 | HRESULT hr = S_OK; | ||
528 | BYTE* pbData = NULL; | ||
529 | SIZE_T cbData = 0; | ||
530 | DWORD dwResult = 0; | ||
531 | |||
532 | // serialize message data | ||
533 | hr = BuffWriteString(&pbData, &cbData, wzResumeCommandLine); | ||
534 | ExitOnFailure(hr, "Failed to write resume command line to message buffer."); | ||
535 | |||
536 | hr = BuffWriteNumber(&pbData, &cbData, fDisableResume); | ||
537 | ExitOnFailure(hr, "Failed to write resume flag."); | ||
538 | |||
539 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
540 | ExitOnFailure(hr, "Failed to write variables."); | ||
541 | |||
542 | // send message | ||
543 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME, pbData, cbData, NULL, NULL, &dwResult); | ||
544 | ExitOnFailure(hr, "Failed to send message to per-machine process."); | ||
545 | |||
546 | hr = (HRESULT)dwResult; | ||
547 | |||
548 | LExit: | ||
549 | ReleaseBuffer(pbData); | ||
550 | |||
551 | return hr; | ||
552 | } | ||
553 | |||
554 | /******************************************************************* | ||
555 | ElevationSessionEnd - | ||
556 | |||
557 | *******************************************************************/ | ||
558 | extern "C" HRESULT ElevationSessionEnd( | ||
559 | __in HANDLE hPipe, | ||
560 | __in BURN_RESUME_MODE resumeMode, | ||
561 | __in BOOTSTRAPPER_APPLY_RESTART restart, | ||
562 | __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction | ||
563 | ) | ||
564 | { | ||
565 | HRESULT hr = S_OK; | ||
566 | BYTE* pbData = NULL; | ||
567 | SIZE_T cbData = 0; | ||
568 | DWORD dwResult = 0; | ||
569 | |||
570 | // serialize message data | ||
571 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)resumeMode); | ||
572 | ExitOnFailure(hr, "Failed to write resume mode to message buffer."); | ||
573 | |||
574 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)restart); | ||
575 | ExitOnFailure(hr, "Failed to write restart enum to message buffer."); | ||
576 | |||
577 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction); | ||
578 | ExitOnFailure(hr, "Failed to write dependency registration action to message buffer."); | ||
579 | |||
580 | // send message | ||
581 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, pbData, cbData, NULL, NULL, &dwResult); | ||
582 | ExitOnFailure(hr, "Failed to send message to per-machine process."); | ||
583 | |||
584 | hr = (HRESULT)dwResult; | ||
585 | |||
586 | LExit: | ||
587 | ReleaseBuffer(pbData); | ||
588 | |||
589 | return hr; | ||
590 | } | ||
591 | |||
592 | /******************************************************************* | ||
593 | ElevationSaveState - | ||
594 | |||
595 | *******************************************************************/ | ||
596 | HRESULT ElevationSaveState( | ||
597 | __in HANDLE hPipe, | ||
598 | __in_bcount(cbBuffer) BYTE* pbBuffer, | ||
599 | __in SIZE_T cbBuffer | ||
600 | ) | ||
601 | { | ||
602 | HRESULT hr = S_OK; | ||
603 | DWORD dwResult = 0; | ||
604 | |||
605 | // send message | ||
606 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE, pbBuffer, cbBuffer, NULL, NULL, &dwResult); | ||
607 | ExitOnFailure(hr, "Failed to send message to per-machine process."); | ||
608 | |||
609 | hr = (HRESULT)dwResult; | ||
610 | |||
611 | LExit: | ||
612 | return hr; | ||
613 | } | ||
614 | |||
615 | /******************************************************************* | ||
616 | ElevationCacheCompletePayload - | ||
617 | |||
618 | *******************************************************************/ | ||
619 | extern "C" HRESULT ElevationCacheCompletePayload( | ||
620 | __in HANDLE hPipe, | ||
621 | __in BURN_PACKAGE* pPackage, | ||
622 | __in BURN_PAYLOAD* pPayload, | ||
623 | __in_z LPCWSTR wzUnverifiedPath, | ||
624 | __in BOOL fMove, | ||
625 | __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, | ||
626 | __in LPPROGRESS_ROUTINE pfnProgress, | ||
627 | __in LPVOID pContext | ||
628 | ) | ||
629 | { | ||
630 | HRESULT hr = S_OK; | ||
631 | BYTE* pbData = NULL; | ||
632 | SIZE_T cbData = 0; | ||
633 | DWORD dwResult = 0; | ||
634 | BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { }; | ||
635 | |||
636 | context.pfnCacheMessageHandler = pfnCacheMessageHandler; | ||
637 | context.pfnProgress = pfnProgress; | ||
638 | context.pvContext = pContext; | ||
639 | |||
640 | // serialize message data | ||
641 | hr = BuffWriteString(&pbData, &cbData, pPackage->sczId); | ||
642 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
643 | |||
644 | hr = BuffWriteString(&pbData, &cbData, pPayload->sczKey); | ||
645 | ExitOnFailure(hr, "Failed to write payload id to message buffer."); | ||
646 | |||
647 | hr = BuffWriteString(&pbData, &cbData, wzUnverifiedPath); | ||
648 | ExitOnFailure(hr, "Failed to write unverified path to message buffer."); | ||
649 | |||
650 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fMove); | ||
651 | ExitOnFailure(hr, "Failed to write move flag to message buffer."); | ||
652 | |||
653 | // send message | ||
654 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult); | ||
655 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD message to per-machine process."); | ||
656 | |||
657 | hr = (HRESULT)dwResult; | ||
658 | |||
659 | LExit: | ||
660 | ReleaseBuffer(pbData); | ||
661 | |||
662 | return hr; | ||
663 | } | ||
664 | |||
665 | extern "C" HRESULT ElevationCacheVerifyPayload( | ||
666 | __in HANDLE hPipe, | ||
667 | __in BURN_PACKAGE* pPackage, | ||
668 | __in BURN_PAYLOAD* pPayload, | ||
669 | __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, | ||
670 | __in LPPROGRESS_ROUTINE pfnProgress, | ||
671 | __in LPVOID pContext | ||
672 | ) | ||
673 | { | ||
674 | HRESULT hr = S_OK; | ||
675 | BYTE* pbData = NULL; | ||
676 | SIZE_T cbData = 0; | ||
677 | DWORD dwResult = 0; | ||
678 | BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { }; | ||
679 | |||
680 | context.pfnCacheMessageHandler = pfnCacheMessageHandler; | ||
681 | context.pfnProgress = pfnProgress; | ||
682 | context.pvContext = pContext; | ||
683 | |||
684 | // serialize message data | ||
685 | hr = BuffWriteString(&pbData, &cbData, pPackage->sczId); | ||
686 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
687 | |||
688 | hr = BuffWriteString(&pbData, &cbData, pPayload->sczKey); | ||
689 | ExitOnFailure(hr, "Failed to write payload id to message buffer."); | ||
690 | |||
691 | // send message | ||
692 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult); | ||
693 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD message to per-machine process."); | ||
694 | |||
695 | hr = (HRESULT)dwResult; | ||
696 | |||
697 | LExit: | ||
698 | ReleaseBuffer(pbData); | ||
699 | |||
700 | return hr; | ||
701 | } | ||
702 | |||
703 | /******************************************************************* | ||
704 | ElevationCacheCleanup - | ||
705 | |||
706 | *******************************************************************/ | ||
707 | extern "C" HRESULT ElevationCacheCleanup( | ||
708 | __in HANDLE hPipe | ||
709 | ) | ||
710 | { | ||
711 | HRESULT hr = S_OK; | ||
712 | DWORD dwResult = 0; | ||
713 | |||
714 | // send message | ||
715 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP, NULL, 0, NULL, NULL, &dwResult); | ||
716 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP message to per-machine process."); | ||
717 | |||
718 | hr = (HRESULT)dwResult; | ||
719 | |||
720 | LExit: | ||
721 | return hr; | ||
722 | } | ||
723 | |||
724 | extern "C" HRESULT ElevationProcessDependentRegistration( | ||
725 | __in HANDLE hPipe, | ||
726 | __in const BURN_DEPENDENT_REGISTRATION_ACTION* pAction | ||
727 | ) | ||
728 | { | ||
729 | HRESULT hr = S_OK; | ||
730 | BYTE* pbData = NULL; | ||
731 | SIZE_T cbData = 0; | ||
732 | DWORD dwResult = 0; | ||
733 | |||
734 | // serialize message data | ||
735 | hr = BuffWriteNumber(&pbData, &cbData, pAction->type); | ||
736 | ExitOnFailure(hr, "Failed to write action type to message buffer."); | ||
737 | |||
738 | hr = BuffWriteString(&pbData, &cbData, pAction->sczBundleId); | ||
739 | ExitOnFailure(hr, "Failed to write bundle id to message buffer."); | ||
740 | |||
741 | hr = BuffWriteString(&pbData, &cbData, pAction->sczDependentProviderKey); | ||
742 | ExitOnFailure(hr, "Failed to write dependent provider key to message buffer."); | ||
743 | |||
744 | // send message | ||
745 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION, pbData, cbData, NULL, NULL, &dwResult); | ||
746 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION message to per-machine process."); | ||
747 | |||
748 | hr = (HRESULT)dwResult; | ||
749 | |||
750 | LExit: | ||
751 | ReleaseBuffer(pbData); | ||
752 | |||
753 | return hr; | ||
754 | } | ||
755 | |||
756 | /******************************************************************* | ||
757 | ElevationExecuteExePackage - | ||
758 | |||
759 | *******************************************************************/ | ||
760 | extern "C" HRESULT ElevationExecuteExePackage( | ||
761 | __in HANDLE hPipe, | ||
762 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
763 | __in BURN_VARIABLES* pVariables, | ||
764 | __in BOOL fRollback, | ||
765 | __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, | ||
766 | __in LPVOID pvContext, | ||
767 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
768 | ) | ||
769 | { | ||
770 | HRESULT hr = S_OK; | ||
771 | BYTE* pbData = NULL; | ||
772 | SIZE_T cbData = 0; | ||
773 | BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { }; | ||
774 | DWORD dwResult = 0; | ||
775 | |||
776 | // serialize message data | ||
777 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.pPackage->sczId); | ||
778 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
779 | |||
780 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->exePackage.action); | ||
781 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
782 | |||
783 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); | ||
784 | ExitOnFailure(hr, "Failed to write rollback."); | ||
785 | |||
786 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczIgnoreDependencies); | ||
787 | ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer."); | ||
788 | |||
789 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczAncestors); | ||
790 | ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer."); | ||
791 | |||
792 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
793 | ExitOnFailure(hr, "Failed to write variables."); | ||
794 | |||
795 | // send message | ||
796 | context.pfnGenericMessageHandler = pfnGenericMessageHandler; | ||
797 | context.pvContext = pvContext; | ||
798 | |||
799 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult); | ||
800 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE message to per-machine process."); | ||
801 | |||
802 | hr = ProcessResult(dwResult, pRestart); | ||
803 | |||
804 | LExit: | ||
805 | ReleaseBuffer(pbData); | ||
806 | |||
807 | return hr; | ||
808 | } | ||
809 | |||
810 | extern "C" HRESULT ElevationMsiBeginTransaction( | ||
811 | __in HANDLE hPipe, | ||
812 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary | ||
813 | ) | ||
814 | { | ||
815 | HRESULT hr = S_OK; | ||
816 | BYTE* pbData = NULL; | ||
817 | SIZE_T cbData = 0; | ||
818 | DWORD dwResult = ERROR_SUCCESS; | ||
819 | |||
820 | // serialize message data | ||
821 | hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczId); | ||
822 | ExitOnFailure(hr, "Failed to write transaction name to message buffer."); | ||
823 | |||
824 | hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczLogPath); | ||
825 | ExitOnFailure(hr, "Failed to write transaction log path to message buffer."); | ||
826 | |||
827 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, pbData, cbData, NULL, NULL, &dwResult); | ||
828 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION message to per-machine process."); | ||
829 | |||
830 | hr = static_cast<HRESULT>(dwResult); | ||
831 | |||
832 | LExit: | ||
833 | ReleaseBuffer(pbData); | ||
834 | |||
835 | return hr; | ||
836 | } | ||
837 | |||
838 | extern "C" HRESULT ElevationMsiCommitTransaction( | ||
839 | __in HANDLE hPipe, | ||
840 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary | ||
841 | ) | ||
842 | { | ||
843 | HRESULT hr = S_OK; | ||
844 | BYTE* pbData = NULL; | ||
845 | SIZE_T cbData = 0; | ||
846 | DWORD dwResult = ERROR_SUCCESS; | ||
847 | |||
848 | // serialize message data | ||
849 | hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczId); | ||
850 | ExitOnFailure(hr, "Failed to write transaction name to message buffer."); | ||
851 | |||
852 | hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczLogPath); | ||
853 | ExitOnFailure(hr, "Failed to write transaction log path to message buffer."); | ||
854 | |||
855 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, pbData, cbData, NULL, NULL, &dwResult); | ||
856 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION message to per-machine process."); | ||
857 | |||
858 | hr = static_cast<HRESULT>(dwResult); | ||
859 | |||
860 | LExit: | ||
861 | ReleaseBuffer(pbData); | ||
862 | |||
863 | return hr; | ||
864 | } | ||
865 | |||
866 | extern "C" HRESULT ElevationMsiRollbackTransaction( | ||
867 | __in HANDLE hPipe, | ||
868 | __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary | ||
869 | ) | ||
870 | { | ||
871 | HRESULT hr = S_OK; | ||
872 | BYTE* pbData = NULL; | ||
873 | SIZE_T cbData = 0; | ||
874 | DWORD dwResult = ERROR_SUCCESS; | ||
875 | |||
876 | // serialize message data | ||
877 | hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczId); | ||
878 | ExitOnFailure(hr, "Failed to write transaction name to message buffer."); | ||
879 | |||
880 | hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczLogPath); | ||
881 | ExitOnFailure(hr, "Failed to write transaction log path to message buffer."); | ||
882 | |||
883 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, pbData, cbData, NULL, NULL, &dwResult); | ||
884 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION message to per-machine process."); | ||
885 | |||
886 | hr = static_cast<HRESULT>(dwResult); | ||
887 | |||
888 | LExit: | ||
889 | ReleaseBuffer(pbData); | ||
890 | |||
891 | return hr; | ||
892 | } | ||
893 | |||
894 | |||
895 | |||
896 | /******************************************************************* | ||
897 | ElevationExecuteMsiPackage - | ||
898 | |||
899 | *******************************************************************/ | ||
900 | extern "C" HRESULT ElevationExecuteMsiPackage( | ||
901 | __in HANDLE hPipe, | ||
902 | __in_opt HWND hwndParent, | ||
903 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
904 | __in BURN_VARIABLES* pVariables, | ||
905 | __in BOOL fRollback, | ||
906 | __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, | ||
907 | __in LPVOID pvContext, | ||
908 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
909 | ) | ||
910 | { | ||
911 | HRESULT hr = S_OK; | ||
912 | BYTE* pbData = NULL; | ||
913 | SIZE_T cbData = 0; | ||
914 | BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { }; | ||
915 | DWORD dwResult = 0; | ||
916 | |||
917 | // serialize message data | ||
918 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback); | ||
919 | ExitOnFailure(hr, "Failed to write rollback flag to message buffer."); | ||
920 | |||
921 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msiPackage.pPackage->sczId); | ||
922 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
923 | |||
924 | hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent); | ||
925 | ExitOnFailure(hr, "Failed to write parent hwnd to message buffer."); | ||
926 | |||
927 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msiPackage.sczLogPath); | ||
928 | ExitOnFailure(hr, "Failed to write package log to message buffer."); | ||
929 | |||
930 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.actionMsiProperty); | ||
931 | ExitOnFailure(hr, "Failed to write actionMsiProperty to message buffer."); | ||
932 | |||
933 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.uiLevel); | ||
934 | ExitOnFailure(hr, "Failed to write UI level to message buffer."); | ||
935 | |||
936 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.fDisableExternalUiHandler); | ||
937 | ExitOnFailure(hr, "Failed to write fDisableExternalUiHandler to message buffer."); | ||
938 | |||
939 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.action); | ||
940 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
941 | |||
942 | // Feature actions. | ||
943 | for (DWORD i = 0; i < pExecuteAction->msiPackage.pPackage->Msi.cFeatures; ++i) | ||
944 | { | ||
945 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.rgFeatures[i]); | ||
946 | ExitOnFailure(hr, "Failed to write feature action to message buffer."); | ||
947 | } | ||
948 | |||
949 | // Slipstream patches actions. | ||
950 | for (DWORD i = 0; i < pExecuteAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++i) | ||
951 | { | ||
952 | BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pExecuteAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + i; | ||
953 | BOOTSTRAPPER_ACTION_STATE* pAction = fRollback ? &pSlipstreamMsp->rollback : &pSlipstreamMsp->execute; | ||
954 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction); | ||
955 | ExitOnFailure(hr, "Failed to write slipstream patch action to message buffer."); | ||
956 | } | ||
957 | |||
958 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
959 | ExitOnFailure(hr, "Failed to write variables."); | ||
960 | |||
961 | |||
962 | // send message | ||
963 | context.pfnMessageHandler = pfnMessageHandler; | ||
964 | context.pvContext = pvContext; | ||
965 | |||
966 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult); | ||
967 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE message to per-machine process."); | ||
968 | |||
969 | hr = ProcessResult(dwResult, pRestart); | ||
970 | |||
971 | LExit: | ||
972 | ReleaseBuffer(pbData); | ||
973 | |||
974 | return hr; | ||
975 | } | ||
976 | |||
977 | /******************************************************************* | ||
978 | ElevationExecuteMspPackage - | ||
979 | |||
980 | *******************************************************************/ | ||
981 | extern "C" HRESULT ElevationExecuteMspPackage( | ||
982 | __in HANDLE hPipe, | ||
983 | __in_opt HWND hwndParent, | ||
984 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
985 | __in BURN_VARIABLES* pVariables, | ||
986 | __in BOOL fRollback, | ||
987 | __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler, | ||
988 | __in LPVOID pvContext, | ||
989 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
990 | ) | ||
991 | { | ||
992 | HRESULT hr = S_OK; | ||
993 | BYTE* pbData = NULL; | ||
994 | SIZE_T cbData = 0; | ||
995 | BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { }; | ||
996 | DWORD dwResult = 0; | ||
997 | |||
998 | // serialize message data | ||
999 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.pPackage->sczId); | ||
1000 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
1001 | |||
1002 | hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent); | ||
1003 | ExitOnFailure(hr, "Failed to write parent hwnd to message buffer."); | ||
1004 | |||
1005 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.sczTargetProductCode); | ||
1006 | ExitOnFailure(hr, "Failed to write target product code to message buffer."); | ||
1007 | |||
1008 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.sczLogPath); | ||
1009 | ExitOnFailure(hr, "Failed to write package log to message buffer."); | ||
1010 | |||
1011 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.actionMsiProperty); | ||
1012 | ExitOnFailure(hr, "Failed to write actionMsiProperty to message buffer."); | ||
1013 | |||
1014 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.uiLevel); | ||
1015 | ExitOnFailure(hr, "Failed to write UI level to message buffer."); | ||
1016 | |||
1017 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.fDisableExternalUiHandler); | ||
1018 | ExitOnFailure(hr, "Failed to write fDisableExternalUiHandler to message buffer."); | ||
1019 | |||
1020 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.action); | ||
1021 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
1022 | |||
1023 | hr = BuffWriteNumber(&pbData, &cbData, pExecuteAction->mspTarget.cOrderedPatches); | ||
1024 | ExitOnFailure(hr, "Failed to write count of ordered patches to message buffer."); | ||
1025 | |||
1026 | for (DWORD i = 0; i < pExecuteAction->mspTarget.cOrderedPatches; ++i) | ||
1027 | { | ||
1028 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage->sczId); | ||
1029 | ExitOnFailure(hr, "Failed to write ordered patch id to message buffer."); | ||
1030 | } | ||
1031 | |||
1032 | hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData); | ||
1033 | ExitOnFailure(hr, "Failed to write variables."); | ||
1034 | |||
1035 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback); | ||
1036 | ExitOnFailure(hr, "Failed to write rollback flag to message buffer."); | ||
1037 | |||
1038 | // send message | ||
1039 | context.pfnMessageHandler = pfnMessageHandler; | ||
1040 | context.pvContext = pvContext; | ||
1041 | |||
1042 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult); | ||
1043 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE message to per-machine process."); | ||
1044 | |||
1045 | hr = ProcessResult(dwResult, pRestart); | ||
1046 | |||
1047 | LExit: | ||
1048 | ReleaseBuffer(pbData); | ||
1049 | |||
1050 | return hr; | ||
1051 | } | ||
1052 | |||
1053 | /******************************************************************* | ||
1054 | ElevationExecuteMsuPackage - | ||
1055 | |||
1056 | *******************************************************************/ | ||
1057 | extern "C" HRESULT ElevationExecuteMsuPackage( | ||
1058 | __in HANDLE hPipe, | ||
1059 | __in BURN_EXECUTE_ACTION* pExecuteAction, | ||
1060 | __in BOOL fRollback, | ||
1061 | __in BOOL fStopWusaService, | ||
1062 | __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler, | ||
1063 | __in LPVOID pvContext, | ||
1064 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
1065 | ) | ||
1066 | { | ||
1067 | HRESULT hr = S_OK; | ||
1068 | BYTE* pbData = NULL; | ||
1069 | SIZE_T cbData = 0; | ||
1070 | BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { }; | ||
1071 | DWORD dwResult = 0; | ||
1072 | |||
1073 | // serialize message data | ||
1074 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msuPackage.pPackage->sczId); | ||
1075 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
1076 | |||
1077 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msuPackage.sczLogPath); | ||
1078 | ExitOnFailure(hr, "Failed to write package log to message buffer."); | ||
1079 | |||
1080 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msuPackage.action); | ||
1081 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
1082 | |||
1083 | hr = BuffWriteNumber(&pbData, &cbData, fRollback); | ||
1084 | ExitOnFailure(hr, "Failed to write rollback."); | ||
1085 | |||
1086 | hr = BuffWriteNumber(&pbData, &cbData, fStopWusaService); | ||
1087 | ExitOnFailure(hr, "Failed to write StopWusaService."); | ||
1088 | |||
1089 | // send message | ||
1090 | context.pfnGenericMessageHandler = pfnGenericMessageHandler; | ||
1091 | context.pvContext = pvContext; | ||
1092 | |||
1093 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult); | ||
1094 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE message to per-machine process."); | ||
1095 | |||
1096 | hr = ProcessResult(dwResult, pRestart); | ||
1097 | |||
1098 | LExit: | ||
1099 | ReleaseBuffer(pbData); | ||
1100 | |||
1101 | return hr; | ||
1102 | } | ||
1103 | |||
1104 | extern "C" HRESULT ElevationExecutePackageProviderAction( | ||
1105 | __in HANDLE hPipe, | ||
1106 | __in BURN_EXECUTE_ACTION* pExecuteAction | ||
1107 | ) | ||
1108 | { | ||
1109 | HRESULT hr = S_OK; | ||
1110 | BYTE* pbData = NULL; | ||
1111 | SIZE_T cbData = 0; | ||
1112 | DWORD dwResult = 0; | ||
1113 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
1114 | |||
1115 | // Serialize the message data. | ||
1116 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageProvider.pPackage->sczId); | ||
1117 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
1118 | |||
1119 | hr = BuffWriteNumber(&pbData, &cbData, pExecuteAction->packageProvider.action); | ||
1120 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
1121 | |||
1122 | // Send the message. | ||
1123 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER, pbData, cbData, NULL, NULL, &dwResult); | ||
1124 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER message to per-machine process."); | ||
1125 | |||
1126 | // Ignore the restart since this action only results in registry writes. | ||
1127 | hr = ProcessResult(dwResult, &restart); | ||
1128 | |||
1129 | LExit: | ||
1130 | ReleaseBuffer(pbData); | ||
1131 | |||
1132 | return hr; | ||
1133 | } | ||
1134 | |||
1135 | extern "C" HRESULT ElevationExecutePackageDependencyAction( | ||
1136 | __in HANDLE hPipe, | ||
1137 | __in BURN_EXECUTE_ACTION* pExecuteAction | ||
1138 | ) | ||
1139 | { | ||
1140 | HRESULT hr = S_OK; | ||
1141 | BYTE* pbData = NULL; | ||
1142 | SIZE_T cbData = 0; | ||
1143 | DWORD dwResult = 0; | ||
1144 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
1145 | |||
1146 | // Serialize the message data. | ||
1147 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageDependency.pPackage->sczId); | ||
1148 | ExitOnFailure(hr, "Failed to write package id to message buffer."); | ||
1149 | |||
1150 | hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageDependency.sczBundleProviderKey); | ||
1151 | ExitOnFailure(hr, "Failed to write bundle dependency key to message buffer."); | ||
1152 | |||
1153 | hr = BuffWriteNumber(&pbData, &cbData, pExecuteAction->packageDependency.action); | ||
1154 | ExitOnFailure(hr, "Failed to write action to message buffer."); | ||
1155 | |||
1156 | // Send the message. | ||
1157 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY, pbData, cbData, NULL, NULL, &dwResult); | ||
1158 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY message to per-machine process."); | ||
1159 | |||
1160 | // Ignore the restart since this action only results in registry writes. | ||
1161 | hr = ProcessResult(dwResult, &restart); | ||
1162 | |||
1163 | LExit: | ||
1164 | ReleaseBuffer(pbData); | ||
1165 | |||
1166 | return hr; | ||
1167 | } | ||
1168 | |||
1169 | /******************************************************************* | ||
1170 | ElevationCleanPackage - | ||
1171 | |||
1172 | *******************************************************************/ | ||
1173 | extern "C" HRESULT ElevationCleanPackage( | ||
1174 | __in HANDLE hPipe, | ||
1175 | __in BURN_PACKAGE* pPackage | ||
1176 | ) | ||
1177 | { | ||
1178 | HRESULT hr = S_OK; | ||
1179 | BYTE* pbData = NULL; | ||
1180 | SIZE_T cbData = 0; | ||
1181 | DWORD dwResult = 0; | ||
1182 | |||
1183 | // serialize message data | ||
1184 | hr = BuffWriteString(&pbData, &cbData, pPackage->sczId); | ||
1185 | ExitOnFailure(hr, "Failed to write clean package id to message buffer."); | ||
1186 | |||
1187 | // send message | ||
1188 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE, pbData, cbData, NULL, NULL, &dwResult); | ||
1189 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE message to per-machine process."); | ||
1190 | |||
1191 | hr = (HRESULT)dwResult; | ||
1192 | |||
1193 | LExit: | ||
1194 | ReleaseBuffer(pbData); | ||
1195 | |||
1196 | return hr; | ||
1197 | } | ||
1198 | |||
1199 | extern "C" HRESULT ElevationLaunchApprovedExe( | ||
1200 | __in HANDLE hPipe, | ||
1201 | __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe, | ||
1202 | __out DWORD* pdwProcessId | ||
1203 | ) | ||
1204 | { | ||
1205 | HRESULT hr = S_OK; | ||
1206 | BYTE* pbData = NULL; | ||
1207 | SIZE_T cbData = 0; | ||
1208 | DWORD dwResult = 0; | ||
1209 | BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT context = { }; | ||
1210 | |||
1211 | // Serialize message data. | ||
1212 | hr = BuffWriteString(&pbData, &cbData, pLaunchApprovedExe->sczId); | ||
1213 | ExitOnFailure(hr, "Failed to write approved exe id to message buffer."); | ||
1214 | |||
1215 | hr = BuffWriteString(&pbData, &cbData, pLaunchApprovedExe->sczArguments); | ||
1216 | ExitOnFailure(hr, "Failed to write approved exe arguments to message buffer."); | ||
1217 | |||
1218 | hr = BuffWriteNumber(&pbData, &cbData, pLaunchApprovedExe->dwWaitForInputIdleTimeout); | ||
1219 | ExitOnFailure(hr, "Failed to write approved exe WaitForInputIdle timeout to message buffer."); | ||
1220 | |||
1221 | // Send the message. | ||
1222 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE, pbData, cbData, ProcessLaunchApprovedExeMessages, &context, &dwResult); | ||
1223 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE message to per-machine process."); | ||
1224 | |||
1225 | hr = (HRESULT)dwResult; | ||
1226 | *pdwProcessId = context.dwProcessId; | ||
1227 | |||
1228 | LExit: | ||
1229 | ReleaseBuffer(pbData); | ||
1230 | |||
1231 | return hr; | ||
1232 | } | ||
1233 | |||
1234 | /******************************************************************* | ||
1235 | ElevationChildPumpMessages - | ||
1236 | |||
1237 | *******************************************************************/ | ||
1238 | extern "C" HRESULT ElevationChildPumpMessages( | ||
1239 | __in DWORD dwLoggingTlsId, | ||
1240 | __in HANDLE hPipe, | ||
1241 | __in HANDLE hCachePipe, | ||
1242 | __in BURN_APPROVED_EXES* pApprovedExes, | ||
1243 | __in BURN_CONTAINERS* pContainers, | ||
1244 | __in BURN_PACKAGES* pPackages, | ||
1245 | __in BURN_PAYLOADS* pPayloads, | ||
1246 | __in BURN_VARIABLES* pVariables, | ||
1247 | __in BURN_REGISTRATION* pRegistration, | ||
1248 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1249 | __out HANDLE* phLock, | ||
1250 | __out BOOL* pfDisabledAutomaticUpdates, | ||
1251 | __out DWORD* pdwChildExitCode, | ||
1252 | __out BOOL* pfRestart | ||
1253 | ) | ||
1254 | { | ||
1255 | HRESULT hr = S_OK; | ||
1256 | BURN_ELEVATION_CHILD_MESSAGE_CONTEXT cacheContext = { }; | ||
1257 | BURN_ELEVATION_CHILD_MESSAGE_CONTEXT context = { }; | ||
1258 | HANDLE hCacheThread = NULL; | ||
1259 | BURN_PIPE_RESULT result = { }; | ||
1260 | |||
1261 | cacheContext.dwLoggingTlsId = dwLoggingTlsId; | ||
1262 | cacheContext.hPipe = hCachePipe; | ||
1263 | cacheContext.pContainers = pContainers; | ||
1264 | cacheContext.pPackages = pPackages; | ||
1265 | cacheContext.pPayloads = pPayloads; | ||
1266 | cacheContext.pVariables = pVariables; | ||
1267 | cacheContext.pRegistration = pRegistration; | ||
1268 | cacheContext.pUserExperience = pUserExperience; | ||
1269 | |||
1270 | context.dwLoggingTlsId = dwLoggingTlsId; | ||
1271 | context.hPipe = hPipe; | ||
1272 | context.phLock = phLock; | ||
1273 | context.pfDisabledAutomaticUpdates = pfDisabledAutomaticUpdates; | ||
1274 | context.pApprovedExes = pApprovedExes; | ||
1275 | context.pContainers = pContainers; | ||
1276 | context.pPackages = pPackages; | ||
1277 | context.pPayloads = pPayloads; | ||
1278 | context.pVariables = pVariables; | ||
1279 | context.pRegistration = pRegistration; | ||
1280 | context.pUserExperience = pUserExperience; | ||
1281 | |||
1282 | hCacheThread = ::CreateThread(NULL, 0, ElevatedChildCacheThreadProc, &cacheContext, 0, NULL); | ||
1283 | ExitOnNullWithLastError(hCacheThread, hr, "Failed to create elevated cache thread."); | ||
1284 | |||
1285 | hr = PipePumpMessages(hPipe, ProcessElevatedChildMessage, &context, &result); | ||
1286 | ExitOnFailure(hr, "Failed to pump messages in child process."); | ||
1287 | |||
1288 | // Wait for the cache thread and verify it gets the right result but don't fail if things | ||
1289 | // don't work out. | ||
1290 | WaitForElevatedChildCacheThread(hCacheThread, result.dwResult); | ||
1291 | |||
1292 | *pdwChildExitCode = result.dwResult; | ||
1293 | *pfRestart = result.fRestart; | ||
1294 | |||
1295 | LExit: | ||
1296 | ReleaseHandle(hCacheThread); | ||
1297 | |||
1298 | return hr; | ||
1299 | } | ||
1300 | |||
1301 | extern "C" HRESULT ElevationChildResumeAutomaticUpdates() | ||
1302 | { | ||
1303 | HRESULT hr = S_OK; | ||
1304 | |||
1305 | LogId(REPORT_STANDARD, MSG_RESUME_AU_STARTING); | ||
1306 | |||
1307 | hr = WuaResumeAutomaticUpdates(); | ||
1308 | ExitOnFailure(hr, "Failed to resume automatic updates after pausing them, continuing..."); | ||
1309 | |||
1310 | LogId(REPORT_STANDARD, MSG_RESUME_AU_SUCCEEDED); | ||
1311 | |||
1312 | LExit: | ||
1313 | return hr; | ||
1314 | } | ||
1315 | |||
1316 | // internal function definitions | ||
1317 | |||
1318 | static DWORD WINAPI ElevatedChildCacheThreadProc( | ||
1319 | __in LPVOID lpThreadParameter | ||
1320 | ) | ||
1321 | { | ||
1322 | HRESULT hr = S_OK; | ||
1323 | BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = reinterpret_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(lpThreadParameter); | ||
1324 | BOOL fComInitialized = FALSE; | ||
1325 | BURN_PIPE_RESULT result = { }; | ||
1326 | |||
1327 | if (!::TlsSetValue(pContext->dwLoggingTlsId, pContext->hPipe)) | ||
1328 | { | ||
1329 | ExitWithLastError(hr, "Failed to set elevated cache pipe into thread local storage for logging."); | ||
1330 | } | ||
1331 | |||
1332 | // initialize COM | ||
1333 | hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); | ||
1334 | ExitOnFailure(hr, "Failed to initialize COM."); | ||
1335 | fComInitialized = TRUE; | ||
1336 | |||
1337 | hr = PipePumpMessages(pContext->hPipe, ProcessElevatedChildCacheMessage, pContext, &result); | ||
1338 | ExitOnFailure(hr, "Failed to pump messages in child process."); | ||
1339 | |||
1340 | hr = (HRESULT)result.dwResult; | ||
1341 | |||
1342 | LExit: | ||
1343 | if (fComInitialized) | ||
1344 | { | ||
1345 | ::CoUninitialize(); | ||
1346 | } | ||
1347 | |||
1348 | return (DWORD)hr; | ||
1349 | } | ||
1350 | |||
1351 | static HRESULT WaitForElevatedChildCacheThread( | ||
1352 | __in HANDLE hCacheThread, | ||
1353 | __in DWORD dwExpectedExitCode | ||
1354 | ) | ||
1355 | { | ||
1356 | UNREFERENCED_PARAMETER(dwExpectedExitCode); | ||
1357 | |||
1358 | HRESULT hr = S_OK; | ||
1359 | DWORD dwExitCode = ERROR_SUCCESS; | ||
1360 | |||
1361 | if (WAIT_OBJECT_0 != ::WaitForSingleObject(hCacheThread, BURN_TIMEOUT)) | ||
1362 | { | ||
1363 | ExitWithLastError(hr, "Failed to wait for cache thread to terminate."); | ||
1364 | } | ||
1365 | |||
1366 | if (!::GetExitCodeThread(hCacheThread, &dwExitCode)) | ||
1367 | { | ||
1368 | ExitWithLastError(hr, "Failed to get cache thread exit code."); | ||
1369 | } | ||
1370 | |||
1371 | AssertSz(dwExitCode == dwExpectedExitCode, "Cache thread should have exited with the expected exit code."); | ||
1372 | |||
1373 | LExit: | ||
1374 | return hr; | ||
1375 | } | ||
1376 | |||
1377 | static HRESULT ProcessApplyInitializeMessages( | ||
1378 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1379 | __in_opt LPVOID pvContext, | ||
1380 | __out DWORD* pdwResult | ||
1381 | ) | ||
1382 | { | ||
1383 | HRESULT hr = S_OK; | ||
1384 | BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT*>(pvContext); | ||
1385 | BYTE* pbData = (BYTE*)pMsg->pvData; | ||
1386 | SIZE_T iData = 0; | ||
1387 | HRESULT hrStatus = S_OK; | ||
1388 | HRESULT hrBA = S_OK; | ||
1389 | |||
1390 | // Process the message. | ||
1391 | switch (pMsg->dwMessage) | ||
1392 | { | ||
1393 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN: | ||
1394 | pContext->fPauseCompleteNeeded = TRUE; | ||
1395 | hrBA = UserExperienceOnPauseAUBegin(pContext->pBA); | ||
1396 | break; | ||
1397 | |||
1398 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE: | ||
1399 | // read hrStatus | ||
1400 | hr = BuffReadNumber(pbData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&hrStatus)); | ||
1401 | ExitOnFailure(hr, "Failed to read pause AU hrStatus."); | ||
1402 | |||
1403 | pContext->fPauseCompleteNeeded = FALSE; | ||
1404 | hrBA = UserExperienceOnPauseAUComplete(pContext->pBA, hrStatus); | ||
1405 | break; | ||
1406 | |||
1407 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN: | ||
1408 | if (pContext->fPauseCompleteNeeded) | ||
1409 | { | ||
1410 | pContext->fPauseCompleteNeeded = FALSE; | ||
1411 | hrBA = UserExperienceOnPauseAUComplete(pContext->pBA, E_INVALIDSTATE); | ||
1412 | } | ||
1413 | |||
1414 | pContext->fSrpCompleteNeeded = TRUE; | ||
1415 | hrBA = UserExperienceOnSystemRestorePointBegin(pContext->pBA); | ||
1416 | break; | ||
1417 | |||
1418 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE: | ||
1419 | // read hrStatus | ||
1420 | hr = BuffReadNumber(pbData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&hrStatus)); | ||
1421 | ExitOnFailure(hr, "Failed to read system restore point hrStatus."); | ||
1422 | |||
1423 | pContext->fSrpCompleteNeeded = FALSE; | ||
1424 | hrBA = UserExperienceOnSystemRestorePointComplete(pContext->pBA, hrStatus); | ||
1425 | break; | ||
1426 | |||
1427 | default: | ||
1428 | hr = E_INVALIDARG; | ||
1429 | ExitOnRootFailure(hr, "Invalid apply initialize message."); | ||
1430 | break; | ||
1431 | } | ||
1432 | |||
1433 | *pdwResult = static_cast<DWORD>(hrBA); | ||
1434 | |||
1435 | LExit: | ||
1436 | return hr; | ||
1437 | } | ||
1438 | |||
1439 | static HRESULT ProcessBurnCacheMessages( | ||
1440 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1441 | __in LPVOID pvContext, | ||
1442 | __out DWORD* pdwResult | ||
1443 | ) | ||
1444 | { | ||
1445 | HRESULT hr = S_OK; | ||
1446 | SIZE_T iData = 0; | ||
1447 | BURN_ELEVATION_CACHE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CACHE_MESSAGE_CONTEXT*>(pvContext); | ||
1448 | BURN_CACHE_MESSAGE message = { }; | ||
1449 | BOOL fProgressRoutine = FALSE; | ||
1450 | |||
1451 | // Process the message. | ||
1452 | switch (pMsg->dwMessage) | ||
1453 | { | ||
1454 | case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN: | ||
1455 | // read message parameters | ||
1456 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.begin.cacheStep)); | ||
1457 | ExitOnFailure(hr, "Failed to read begin cache step."); | ||
1458 | |||
1459 | message.type = BURN_CACHE_MESSAGE_BEGIN; | ||
1460 | break; | ||
1461 | |||
1462 | case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE: | ||
1463 | // read message parameters | ||
1464 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.complete.hrStatus)); | ||
1465 | ExitOnFailure(hr, "Failed to read complete hresult."); | ||
1466 | |||
1467 | message.type = BURN_CACHE_MESSAGE_COMPLETE; | ||
1468 | break; | ||
1469 | |||
1470 | case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS: | ||
1471 | // read message parameters | ||
1472 | hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize); | ||
1473 | ExitOnFailure(hr, "Failed to read begin cache step."); | ||
1474 | |||
1475 | message.type = BURN_CACHE_MESSAGE_SUCCESS; | ||
1476 | break; | ||
1477 | |||
1478 | case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE: | ||
1479 | fProgressRoutine = TRUE; | ||
1480 | break; | ||
1481 | |||
1482 | default: | ||
1483 | hr = E_INVALIDARG; | ||
1484 | ExitOnRootFailure(hr, "Invalid burn cache message."); | ||
1485 | break; | ||
1486 | } | ||
1487 | |||
1488 | if (fProgressRoutine) | ||
1489 | { | ||
1490 | hr = ProcessProgressRoutineMessage(pMsg, pContext->pfnProgress, pContext->pvContext, pdwResult); | ||
1491 | } | ||
1492 | else | ||
1493 | { | ||
1494 | hr = pContext->pfnCacheMessageHandler(&message, pContext->pvContext); | ||
1495 | *pdwResult = static_cast<DWORD>(hr); | ||
1496 | } | ||
1497 | |||
1498 | LExit: | ||
1499 | return hr; | ||
1500 | } | ||
1501 | |||
1502 | static HRESULT ProcessGenericExecuteMessages( | ||
1503 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1504 | __in LPVOID pvContext, | ||
1505 | __out DWORD* pdwResult | ||
1506 | ) | ||
1507 | { | ||
1508 | HRESULT hr = S_OK; | ||
1509 | SIZE_T iData = 0; | ||
1510 | BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT*>(pvContext); | ||
1511 | LPWSTR sczMessage = NULL; | ||
1512 | DWORD cFiles = 0; | ||
1513 | LPWSTR* rgwzFiles = NULL; | ||
1514 | GENERIC_EXECUTE_MESSAGE message = { }; | ||
1515 | |||
1516 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwAllowedResults); | ||
1517 | ExitOnFailure(hr, "Failed to allowed results."); | ||
1518 | |||
1519 | // Process the message. | ||
1520 | switch (pMsg->dwMessage) | ||
1521 | { | ||
1522 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS: | ||
1523 | message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS; | ||
1524 | |||
1525 | // read message parameters | ||
1526 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.progress.dwPercentage); | ||
1527 | ExitOnFailure(hr, "Failed to progress."); | ||
1528 | break; | ||
1529 | |||
1530 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR: | ||
1531 | message.type = GENERIC_EXECUTE_MESSAGE_ERROR; | ||
1532 | |||
1533 | // read message parameters | ||
1534 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.error.dwErrorCode); | ||
1535 | ExitOnFailure(hr, "Failed to read error code."); | ||
1536 | |||
1537 | hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage); | ||
1538 | ExitOnFailure(hr, "Failed to read message."); | ||
1539 | |||
1540 | message.error.wzMessage = sczMessage; | ||
1541 | break; | ||
1542 | |||
1543 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE: | ||
1544 | message.type = GENERIC_EXECUTE_MESSAGE_FILES_IN_USE; | ||
1545 | |||
1546 | // read message parameters | ||
1547 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cFiles); | ||
1548 | ExitOnFailure(hr, "Failed to read file count."); | ||
1549 | |||
1550 | rgwzFiles = (LPWSTR*)MemAlloc(sizeof(LPWSTR*) * cFiles, TRUE); | ||
1551 | ExitOnNull(rgwzFiles, hr, E_OUTOFMEMORY, "Failed to allocate buffer for files in use."); | ||
1552 | |||
1553 | for (DWORD i = 0; i < cFiles; ++i) | ||
1554 | { | ||
1555 | hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &rgwzFiles[i]); | ||
1556 | ExitOnFailure(hr, "Failed to read file name: %u", i); | ||
1557 | } | ||
1558 | |||
1559 | message.filesInUse.cFiles = cFiles; | ||
1560 | message.filesInUse.rgwzFiles = (LPCWSTR*)rgwzFiles; | ||
1561 | break; | ||
1562 | |||
1563 | default: | ||
1564 | hr = E_INVALIDARG; | ||
1565 | ExitOnRootFailure(hr, "Invalid package message."); | ||
1566 | break; | ||
1567 | } | ||
1568 | |||
1569 | // send message | ||
1570 | *pdwResult = (DWORD)pContext->pfnGenericMessageHandler(&message, pContext->pvContext); | ||
1571 | |||
1572 | LExit: | ||
1573 | ReleaseStr(sczMessage); | ||
1574 | |||
1575 | if (rgwzFiles) | ||
1576 | { | ||
1577 | for (DWORD i = 0; i < cFiles; ++i) | ||
1578 | { | ||
1579 | ReleaseStr(rgwzFiles[i]); | ||
1580 | } | ||
1581 | MemFree(rgwzFiles); | ||
1582 | } | ||
1583 | return hr; | ||
1584 | } | ||
1585 | |||
1586 | static HRESULT ProcessMsiPackageMessages( | ||
1587 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1588 | __in_opt LPVOID pvContext, | ||
1589 | __out DWORD* pdwResult | ||
1590 | ) | ||
1591 | { | ||
1592 | HRESULT hr = S_OK; | ||
1593 | SIZE_T iData = 0; | ||
1594 | WIU_MSI_EXECUTE_MESSAGE message = { }; | ||
1595 | DWORD cMsiData = 0; | ||
1596 | LPWSTR* rgwzMsiData = NULL; | ||
1597 | BURN_ELEVATION_MSI_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_MSI_MESSAGE_CONTEXT*>(pvContext); | ||
1598 | LPWSTR sczMessage = NULL; | ||
1599 | |||
1600 | // Read MSI extended message data. | ||
1601 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cMsiData); | ||
1602 | ExitOnFailure(hr, "Failed to read MSI data count."); | ||
1603 | |||
1604 | if (cMsiData) | ||
1605 | { | ||
1606 | rgwzMsiData = (LPWSTR*)MemAlloc(sizeof(LPWSTR*) * cMsiData, TRUE); | ||
1607 | ExitOnNull(rgwzMsiData, hr, E_OUTOFMEMORY, "Failed to allocate buffer to read MSI data."); | ||
1608 | |||
1609 | for (DWORD i = 0; i < cMsiData; ++i) | ||
1610 | { | ||
1611 | hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &rgwzMsiData[i]); | ||
1612 | ExitOnFailure(hr, "Failed to read MSI data: %u", i); | ||
1613 | } | ||
1614 | |||
1615 | message.cData = cMsiData; | ||
1616 | message.rgwzData = (LPCWSTR*)rgwzMsiData; | ||
1617 | } | ||
1618 | |||
1619 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwAllowedResults); | ||
1620 | ExitOnFailure(hr, "Failed to read UI flags."); | ||
1621 | |||
1622 | // Process the rest of the message. | ||
1623 | switch (pMsg->dwMessage) | ||
1624 | { | ||
1625 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS: | ||
1626 | // read message parameters | ||
1627 | message.type = WIU_MSI_EXECUTE_MESSAGE_PROGRESS; | ||
1628 | |||
1629 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.progress.dwPercentage); | ||
1630 | ExitOnFailure(hr, "Failed to read progress."); | ||
1631 | break; | ||
1632 | |||
1633 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR: | ||
1634 | // read message parameters | ||
1635 | message.type = WIU_MSI_EXECUTE_MESSAGE_ERROR; | ||
1636 | |||
1637 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.error.dwErrorCode); | ||
1638 | ExitOnFailure(hr, "Failed to read error code."); | ||
1639 | |||
1640 | hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage); | ||
1641 | ExitOnFailure(hr, "Failed to read message."); | ||
1642 | message.error.wzMessage = sczMessage; | ||
1643 | break; | ||
1644 | |||
1645 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE: | ||
1646 | // read message parameters | ||
1647 | message.type = WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE; | ||
1648 | |||
1649 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, (DWORD*)&message.msiMessage.mt); | ||
1650 | ExitOnFailure(hr, "Failed to read message type."); | ||
1651 | |||
1652 | hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage); | ||
1653 | ExitOnFailure(hr, "Failed to read message."); | ||
1654 | message.msiMessage.wzMessage = sczMessage; | ||
1655 | break; | ||
1656 | |||
1657 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE: | ||
1658 | message.type = WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE; | ||
1659 | message.msiFilesInUse.cFiles = cMsiData; | ||
1660 | message.msiFilesInUse.rgwzFiles = (LPCWSTR*)rgwzMsiData; | ||
1661 | break; | ||
1662 | |||
1663 | default: | ||
1664 | hr = E_INVALIDARG; | ||
1665 | ExitOnRootFailure(hr, "Invalid package message."); | ||
1666 | break; | ||
1667 | } | ||
1668 | |||
1669 | // send message | ||
1670 | *pdwResult = (DWORD)pContext->pfnMessageHandler(&message, pContext->pvContext); | ||
1671 | |||
1672 | LExit: | ||
1673 | ReleaseStr(sczMessage); | ||
1674 | |||
1675 | if (rgwzMsiData) | ||
1676 | { | ||
1677 | for (DWORD i = 0; i < cMsiData; ++i) | ||
1678 | { | ||
1679 | ReleaseStr(rgwzMsiData[i]); | ||
1680 | } | ||
1681 | |||
1682 | MemFree(rgwzMsiData); | ||
1683 | } | ||
1684 | |||
1685 | return hr; | ||
1686 | } | ||
1687 | |||
1688 | static HRESULT ProcessLaunchApprovedExeMessages( | ||
1689 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1690 | __in_opt LPVOID pvContext, | ||
1691 | __out DWORD* pdwResult | ||
1692 | ) | ||
1693 | { | ||
1694 | HRESULT hr = S_OK; | ||
1695 | SIZE_T iData = 0; | ||
1696 | BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT*>(pvContext); | ||
1697 | DWORD dwProcessId = 0; | ||
1698 | |||
1699 | // Process the message. | ||
1700 | switch (pMsg->dwMessage) | ||
1701 | { | ||
1702 | case BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID: | ||
1703 | // read message parameters | ||
1704 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &dwProcessId); | ||
1705 | ExitOnFailure(hr, "Failed to read approved exe process id."); | ||
1706 | pContext->dwProcessId = dwProcessId; | ||
1707 | break; | ||
1708 | |||
1709 | default: | ||
1710 | hr = E_INVALIDARG; | ||
1711 | ExitOnRootFailure(hr, "Invalid launch approved exe message."); | ||
1712 | break; | ||
1713 | } | ||
1714 | |||
1715 | *pdwResult = static_cast<DWORD>(hr); | ||
1716 | |||
1717 | LExit: | ||
1718 | return hr; | ||
1719 | } | ||
1720 | |||
1721 | static HRESULT ProcessProgressRoutineMessage( | ||
1722 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1723 | __in LPPROGRESS_ROUTINE pfnProgress, | ||
1724 | __in LPVOID pvContext, | ||
1725 | __out DWORD* pdwResult | ||
1726 | ) | ||
1727 | { | ||
1728 | HRESULT hr = S_OK; | ||
1729 | SIZE_T iData = 0; | ||
1730 | LARGE_INTEGER liTotalFileSize = { }; | ||
1731 | LARGE_INTEGER liTotalBytesTransferred = { }; | ||
1732 | LARGE_INTEGER liStreamSize = { }; | ||
1733 | LARGE_INTEGER liStreamBytesTransferred = { }; | ||
1734 | DWORD dwStreamNumber = 0; | ||
1735 | DWORD dwCallbackReason = CALLBACK_CHUNK_FINISHED; | ||
1736 | HANDLE hSourceFile = INVALID_HANDLE_VALUE; | ||
1737 | HANDLE hDestinationFile = INVALID_HANDLE_VALUE; | ||
1738 | |||
1739 | hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD64*>(&liTotalFileSize.QuadPart)); | ||
1740 | ExitOnFailure(hr, "Failed to read total file size for progress."); | ||
1741 | |||
1742 | hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD64*>(&liTotalBytesTransferred.QuadPart)); | ||
1743 | ExitOnFailure(hr, "Failed to read total bytes transferred for progress."); | ||
1744 | |||
1745 | *pdwResult = pfnProgress(liTotalFileSize, liTotalBytesTransferred, liStreamSize, liStreamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, pvContext); | ||
1746 | |||
1747 | LExit: | ||
1748 | return hr; | ||
1749 | } | ||
1750 | |||
1751 | static HRESULT ProcessElevatedChildMessage( | ||
1752 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1753 | __in_opt LPVOID pvContext, | ||
1754 | __out DWORD* pdwResult | ||
1755 | ) | ||
1756 | { | ||
1757 | HRESULT hr = S_OK; | ||
1758 | BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(pvContext); | ||
1759 | HRESULT hrResult = S_OK; | ||
1760 | DWORD dwPid = 0; | ||
1761 | |||
1762 | switch (pMsg->dwMessage) | ||
1763 | { | ||
1764 | case BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION: | ||
1765 | hrResult = OnMsiBeginTransaction(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1766 | break; | ||
1767 | |||
1768 | case BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION: | ||
1769 | hrResult = OnMsiCommitTransaction(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1770 | break; | ||
1771 | |||
1772 | case BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION: | ||
1773 | hrResult = OnMsiRollbackTransaction(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1774 | break; | ||
1775 | |||
1776 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE: | ||
1777 | hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1778 | break; | ||
1779 | |||
1780 | case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE: | ||
1781 | hrResult = OnApplyUninitialize(pContext->phLock); | ||
1782 | break; | ||
1783 | |||
1784 | case BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN: | ||
1785 | hrResult = OnSessionBegin(pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1786 | break; | ||
1787 | |||
1788 | case BURN_ELEVATION_MESSAGE_TYPE_SESSION_RESUME: | ||
1789 | hrResult = OnSessionResume(pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1790 | break; | ||
1791 | |||
1792 | case BURN_ELEVATION_MESSAGE_TYPE_SESSION_END: | ||
1793 | hrResult = OnSessionEnd(pContext->pPackages, pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1794 | break; | ||
1795 | |||
1796 | case BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE: | ||
1797 | hrResult = OnSaveState(pContext->pRegistration, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1798 | break; | ||
1799 | |||
1800 | case BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION: | ||
1801 | hrResult = OnProcessDependentRegistration(pContext->pRegistration, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1802 | break; | ||
1803 | |||
1804 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE: | ||
1805 | hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pPackages, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1806 | break; | ||
1807 | |||
1808 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE: | ||
1809 | hrResult = OnExecuteMsiPackage(pContext->hPipe, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1810 | break; | ||
1811 | |||
1812 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE: | ||
1813 | hrResult = OnExecuteMspPackage(pContext->hPipe, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1814 | break; | ||
1815 | |||
1816 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE: | ||
1817 | hrResult = OnExecuteMsuPackage(pContext->hPipe, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1818 | break; | ||
1819 | |||
1820 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER: | ||
1821 | hrResult = OnExecutePackageProviderAction(pContext->pPackages, &pContext->pRegistration->relatedBundles, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1822 | break; | ||
1823 | |||
1824 | case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY: | ||
1825 | hrResult = OnExecutePackageDependencyAction(pContext->pPackages, &pContext->pRegistration->relatedBundles, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1826 | break; | ||
1827 | |||
1828 | case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE: | ||
1829 | hrResult = OnCleanPackage(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1830 | break; | ||
1831 | |||
1832 | case BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE: | ||
1833 | hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1834 | break; | ||
1835 | |||
1836 | default: | ||
1837 | hr = E_INVALIDARG; | ||
1838 | ExitOnRootFailure(hr, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessage); | ||
1839 | } | ||
1840 | |||
1841 | *pdwResult = dwPid ? dwPid : (DWORD)hrResult; | ||
1842 | |||
1843 | LExit: | ||
1844 | return hr; | ||
1845 | } | ||
1846 | |||
1847 | static HRESULT ProcessElevatedChildCacheMessage( | ||
1848 | __in BURN_PIPE_MESSAGE* pMsg, | ||
1849 | __in_opt LPVOID pvContext, | ||
1850 | __out DWORD* pdwResult | ||
1851 | ) | ||
1852 | { | ||
1853 | HRESULT hr = S_OK; | ||
1854 | BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(pvContext); | ||
1855 | HRESULT hrResult = S_OK; | ||
1856 | |||
1857 | switch (pMsg->dwMessage) | ||
1858 | { | ||
1859 | case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD: | ||
1860 | hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1861 | break; | ||
1862 | |||
1863 | case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD: | ||
1864 | hrResult = OnCacheVerifyPayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1865 | break; | ||
1866 | |||
1867 | case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP: | ||
1868 | OnCacheCleanup(pContext->pRegistration->sczId); | ||
1869 | hrResult = S_OK; | ||
1870 | break; | ||
1871 | |||
1872 | case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE: | ||
1873 | hrResult = OnCleanPackage(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData); | ||
1874 | break; | ||
1875 | |||
1876 | default: | ||
1877 | hr = E_INVALIDARG; | ||
1878 | ExitOnRootFailure(hr, "Unexpected elevated cache message sent to child process, msg: %u", pMsg->dwMessage); | ||
1879 | } | ||
1880 | |||
1881 | *pdwResult = (DWORD)hrResult; | ||
1882 | |||
1883 | LExit: | ||
1884 | return hr; | ||
1885 | } | ||
1886 | |||
1887 | static HRESULT ProcessResult( | ||
1888 | __in DWORD dwResult, | ||
1889 | __out BOOTSTRAPPER_APPLY_RESTART* pRestart | ||
1890 | ) | ||
1891 | { | ||
1892 | HRESULT hr = static_cast<HRESULT>(dwResult); | ||
1893 | if (HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED) == hr) | ||
1894 | { | ||
1895 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_REQUIRED; | ||
1896 | hr = S_OK; | ||
1897 | } | ||
1898 | else if (HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED) == hr) | ||
1899 | { | ||
1900 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; | ||
1901 | hr = S_OK; | ||
1902 | } | ||
1903 | |||
1904 | return hr; | ||
1905 | } | ||
1906 | |||
1907 | static HRESULT OnApplyInitialize( | ||
1908 | __in HANDLE hPipe, | ||
1909 | __in BURN_VARIABLES* pVariables, | ||
1910 | __in BURN_REGISTRATION* pRegistration, | ||
1911 | __in HANDLE* phLock, | ||
1912 | __in BOOL* pfDisabledWindowsUpdate, | ||
1913 | __in BYTE* pbData, | ||
1914 | __in SIZE_T cbData | ||
1915 | ) | ||
1916 | { | ||
1917 | HRESULT hr = S_OK; | ||
1918 | SIZE_T iData = 0; | ||
1919 | DWORD dwAction = 0; | ||
1920 | DWORD dwAUAction = 0; | ||
1921 | DWORD dwTakeSystemRestorePoint = 0; | ||
1922 | LPWSTR sczBundleName = NULL; | ||
1923 | HRESULT hrStatus = S_OK; | ||
1924 | |||
1925 | // Deserialize message data. | ||
1926 | hr = BuffReadNumber(pbData, cbData, &iData, &dwAction); | ||
1927 | ExitOnFailure(hr, "Failed to read action."); | ||
1928 | |||
1929 | hr = BuffReadNumber(pbData, cbData, &iData, &dwAUAction); | ||
1930 | ExitOnFailure(hr, "Failed to read update action."); | ||
1931 | |||
1932 | hr = BuffReadNumber(pbData, cbData, &iData, &dwTakeSystemRestorePoint); | ||
1933 | ExitOnFailure(hr, "Failed to read system restore point action."); | ||
1934 | |||
1935 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
1936 | ExitOnFailure(hr, "Failed to read variables."); | ||
1937 | |||
1938 | // Initialize. | ||
1939 | hr = ApplyLock(TRUE, phLock); | ||
1940 | ExitOnFailure(hr, "Failed to acquire lock due to setup in other session."); | ||
1941 | |||
1942 | // Reset and reload the related bundles. | ||
1943 | RelatedBundlesUninitialize(&pRegistration->relatedBundles); | ||
1944 | |||
1945 | hr = RelatedBundlesInitializeForScope(TRUE, pRegistration, &pRegistration->relatedBundles); | ||
1946 | ExitOnFailure(hr, "Failed to initialize per-machine related bundles."); | ||
1947 | |||
1948 | // Attempt to pause AU with best effort. | ||
1949 | if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction) | ||
1950 | { | ||
1951 | hr = ElevatedOnPauseAUBegin(hPipe); | ||
1952 | ExitOnFailure(hr, "ElevatedOnPauseAUBegin failed."); | ||
1953 | |||
1954 | LogId(REPORT_STANDARD, MSG_PAUSE_AU_STARTING); | ||
1955 | |||
1956 | hrStatus = hr = WuaPauseAutomaticUpdates(); | ||
1957 | if (FAILED(hr)) | ||
1958 | { | ||
1959 | LogId(REPORT_STANDARD, MSG_FAILED_PAUSE_AU, hr); | ||
1960 | hr = S_OK; | ||
1961 | } | ||
1962 | else | ||
1963 | { | ||
1964 | LogId(REPORT_STANDARD, MSG_PAUSE_AU_SUCCEEDED); | ||
1965 | if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction) | ||
1966 | { | ||
1967 | *pfDisabledWindowsUpdate = TRUE; | ||
1968 | } | ||
1969 | } | ||
1970 | |||
1971 | hr = ElevatedOnPauseAUComplete(hPipe, hrStatus); | ||
1972 | ExitOnFailure(hr, "ElevatedOnPauseAUComplete failed."); | ||
1973 | } | ||
1974 | |||
1975 | if (dwTakeSystemRestorePoint) | ||
1976 | { | ||
1977 | hr = VariableGetString(pVariables, BURN_BUNDLE_NAME, &sczBundleName); | ||
1978 | if (FAILED(hr)) | ||
1979 | { | ||
1980 | hr = S_OK; | ||
1981 | ExitFunction(); | ||
1982 | } | ||
1983 | |||
1984 | hr = ElevatedOnSystemRestorePointBegin(hPipe); | ||
1985 | ExitOnFailure(hr, "ElevatedOnSystemRestorePointBegin failed."); | ||
1986 | |||
1987 | LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_STARTING); | ||
1988 | |||
1989 | BOOTSTRAPPER_ACTION action = static_cast<BOOTSTRAPPER_ACTION>(dwAction); | ||
1990 | SRP_ACTION restoreAction = (BOOTSTRAPPER_ACTION_INSTALL == action) ? SRP_ACTION_INSTALL : (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? SRP_ACTION_UNINSTALL : SRP_ACTION_MODIFY; | ||
1991 | hrStatus = hr = SrpCreateRestorePoint(sczBundleName, restoreAction); | ||
1992 | if (SUCCEEDED(hr)) | ||
1993 | { | ||
1994 | LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_SUCCEEDED); | ||
1995 | } | ||
1996 | else if (E_NOTIMPL == hr) | ||
1997 | { | ||
1998 | LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_DISABLED); | ||
1999 | hr = S_OK; | ||
2000 | } | ||
2001 | else | ||
2002 | { | ||
2003 | LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_FAILED, hr); | ||
2004 | hr = S_OK; | ||
2005 | } | ||
2006 | |||
2007 | hr = ElevatedOnSystemRestorePointComplete(hPipe, hrStatus); | ||
2008 | ExitOnFailure(hr, "ElevatedOnSystemRestorePointComplete failed."); | ||
2009 | } | ||
2010 | |||
2011 | LExit: | ||
2012 | ReleaseStr(sczBundleName); | ||
2013 | return hr; | ||
2014 | } | ||
2015 | |||
2016 | static HRESULT OnApplyUninitialize( | ||
2017 | __in HANDLE* phLock | ||
2018 | ) | ||
2019 | { | ||
2020 | Assert(phLock); | ||
2021 | |||
2022 | // TODO: end system restore point. | ||
2023 | |||
2024 | if (*phLock) | ||
2025 | { | ||
2026 | ::ReleaseMutex(*phLock); | ||
2027 | ::CloseHandle(*phLock); | ||
2028 | *phLock = NULL; | ||
2029 | } | ||
2030 | |||
2031 | return S_OK; | ||
2032 | } | ||
2033 | |||
2034 | static HRESULT OnSessionBegin( | ||
2035 | __in BURN_REGISTRATION* pRegistration, | ||
2036 | __in BURN_VARIABLES* pVariables, | ||
2037 | __in BYTE* pbData, | ||
2038 | __in SIZE_T cbData | ||
2039 | ) | ||
2040 | { | ||
2041 | HRESULT hr = S_OK; | ||
2042 | SIZE_T iData = 0; | ||
2043 | LPWSTR sczEngineWorkingPath = NULL; | ||
2044 | DWORD dwRegistrationOperations = 0; | ||
2045 | DWORD dwDependencyRegistrationAction = 0; | ||
2046 | DWORD64 qwEstimatedSize = 0; | ||
2047 | |||
2048 | // Deserialize message data. | ||
2049 | hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingPath); | ||
2050 | ExitOnFailure(hr, "Failed to read engine working path."); | ||
2051 | |||
2052 | hr = BuffReadString(pbData, cbData, &iData, &pRegistration->sczResumeCommandLine); | ||
2053 | ExitOnFailure(hr, "Failed to read resume command line."); | ||
2054 | |||
2055 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDisableResume); | ||
2056 | ExitOnFailure(hr, "Failed to read resume flag."); | ||
2057 | |||
2058 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationOperations); | ||
2059 | ExitOnFailure(hr, "Failed to read registration operations."); | ||
2060 | |||
2061 | hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction); | ||
2062 | ExitOnFailure(hr, "Failed to read dependency registration action."); | ||
2063 | |||
2064 | hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize); | ||
2065 | ExitOnFailure(hr, "Failed to read estimated size."); | ||
2066 | |||
2067 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
2068 | ExitOnFailure(hr, "Failed to read variables."); | ||
2069 | |||
2070 | // Begin session in per-machine process. | ||
2071 | hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize); | ||
2072 | ExitOnFailure(hr, "Failed to begin registration session."); | ||
2073 | |||
2074 | LExit: | ||
2075 | ReleaseStr(sczEngineWorkingPath); | ||
2076 | |||
2077 | return hr; | ||
2078 | } | ||
2079 | |||
2080 | static HRESULT OnSessionResume( | ||
2081 | __in BURN_REGISTRATION* pRegistration, | ||
2082 | __in BURN_VARIABLES* pVariables, | ||
2083 | __in BYTE* pbData, | ||
2084 | __in SIZE_T cbData | ||
2085 | ) | ||
2086 | { | ||
2087 | HRESULT hr = S_OK; | ||
2088 | SIZE_T iData = 0; | ||
2089 | |||
2090 | // Deserialize message data. | ||
2091 | hr = BuffReadString(pbData, cbData, &iData, &pRegistration->sczResumeCommandLine); | ||
2092 | ExitOnFailure(hr, "Failed to read resume command line."); | ||
2093 | |||
2094 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDisableResume); | ||
2095 | ExitOnFailure(hr, "Failed to read resume flag."); | ||
2096 | |||
2097 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
2098 | ExitOnFailure(hr, "Failed to read variables."); | ||
2099 | |||
2100 | // resume session in per-machine process | ||
2101 | hr = RegistrationSessionResume(pRegistration, pVariables); | ||
2102 | ExitOnFailure(hr, "Failed to resume registration session."); | ||
2103 | |||
2104 | LExit: | ||
2105 | return hr; | ||
2106 | } | ||
2107 | |||
2108 | static HRESULT OnSessionEnd( | ||
2109 | __in BURN_PACKAGES* pPackages, | ||
2110 | __in BURN_REGISTRATION* pRegistration, | ||
2111 | __in BURN_VARIABLES* pVariables, | ||
2112 | __in BYTE* pbData, | ||
2113 | __in SIZE_T cbData | ||
2114 | ) | ||
2115 | { | ||
2116 | HRESULT hr = S_OK; | ||
2117 | SIZE_T iData = 0; | ||
2118 | DWORD dwResumeMode = 0; | ||
2119 | DWORD dwRestart = 0; | ||
2120 | DWORD dwDependencyRegistrationAction = 0; | ||
2121 | |||
2122 | // Deserialize message data. | ||
2123 | hr = BuffReadNumber(pbData, cbData, &iData, &dwResumeMode); | ||
2124 | ExitOnFailure(hr, "Failed to read resume mode enum."); | ||
2125 | |||
2126 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRestart); | ||
2127 | ExitOnFailure(hr, "Failed to read restart enum."); | ||
2128 | |||
2129 | hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction); | ||
2130 | ExitOnFailure(hr, "Failed to read dependency registration action."); | ||
2131 | |||
2132 | // suspend session in per-machine process | ||
2133 | hr = RegistrationSessionEnd(pRegistration, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction); | ||
2134 | ExitOnFailure(hr, "Failed to suspend registration session."); | ||
2135 | |||
2136 | LExit: | ||
2137 | return hr; | ||
2138 | } | ||
2139 | |||
2140 | static HRESULT OnSaveState( | ||
2141 | __in BURN_REGISTRATION* pRegistration, | ||
2142 | __in BYTE* pbData, | ||
2143 | __in SIZE_T cbData | ||
2144 | ) | ||
2145 | { | ||
2146 | HRESULT hr = S_OK; | ||
2147 | |||
2148 | // save state in per-machine process | ||
2149 | hr = RegistrationSaveState(pRegistration, pbData, cbData); | ||
2150 | ExitOnFailure(hr, "Failed to save state."); | ||
2151 | |||
2152 | LExit: | ||
2153 | return hr; | ||
2154 | } | ||
2155 | |||
2156 | static HRESULT OnCacheCompletePayload( | ||
2157 | __in HANDLE hPipe, | ||
2158 | __in BURN_PACKAGES* pPackages, | ||
2159 | __in BURN_PAYLOADS* pPayloads, | ||
2160 | __in BYTE* pbData, | ||
2161 | __in SIZE_T cbData | ||
2162 | ) | ||
2163 | { | ||
2164 | HRESULT hr = S_OK; | ||
2165 | SIZE_T iData = 0; | ||
2166 | LPWSTR scz = NULL; | ||
2167 | BURN_PACKAGE* pPackage = NULL; | ||
2168 | BURN_PAYLOAD* pPayload = NULL; | ||
2169 | LPWSTR sczUnverifiedPath = NULL; | ||
2170 | BOOL fMove = FALSE; | ||
2171 | |||
2172 | // Deserialize message data. | ||
2173 | hr = BuffReadString(pbData, cbData, &iData, &scz); | ||
2174 | ExitOnFailure(hr, "Failed to read package id."); | ||
2175 | |||
2176 | if (scz && *scz) | ||
2177 | { | ||
2178 | hr = PackageFindById(pPackages, scz, &pPackage); | ||
2179 | ExitOnFailure(hr, "Failed to find package: %ls", scz); | ||
2180 | } | ||
2181 | |||
2182 | hr = BuffReadString(pbData, cbData, &iData, &scz); | ||
2183 | ExitOnFailure(hr, "Failed to read payload id."); | ||
2184 | |||
2185 | if (scz && *scz) | ||
2186 | { | ||
2187 | hr = PayloadFindById(pPayloads, scz, &pPayload); | ||
2188 | ExitOnFailure(hr, "Failed to find payload: %ls", scz); | ||
2189 | } | ||
2190 | |||
2191 | hr = BuffReadString(pbData, cbData, &iData, &sczUnverifiedPath); | ||
2192 | ExitOnFailure(hr, "Failed to read unverified path."); | ||
2193 | |||
2194 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fMove); | ||
2195 | ExitOnFailure(hr, "Failed to read move flag."); | ||
2196 | |||
2197 | if (pPackage && pPayload) // complete payload. | ||
2198 | { | ||
2199 | hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); | ||
2200 | ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey); | ||
2201 | } | ||
2202 | else | ||
2203 | { | ||
2204 | hr = E_INVALIDARG; | ||
2205 | ExitOnRootFailure(hr, "Invalid data passed to cache complete payload."); | ||
2206 | } | ||
2207 | |||
2208 | LExit: | ||
2209 | ReleaseStr(sczUnverifiedPath); | ||
2210 | ReleaseStr(scz); | ||
2211 | |||
2212 | return hr; | ||
2213 | } | ||
2214 | |||
2215 | static HRESULT OnCacheVerifyPayload( | ||
2216 | __in HANDLE hPipe, | ||
2217 | __in BURN_PACKAGES* pPackages, | ||
2218 | __in BURN_PAYLOADS* pPayloads, | ||
2219 | __in BYTE* pbData, | ||
2220 | __in SIZE_T cbData | ||
2221 | ) | ||
2222 | { | ||
2223 | HRESULT hr = S_OK; | ||
2224 | SIZE_T iData = 0; | ||
2225 | LPWSTR scz = NULL; | ||
2226 | BURN_PACKAGE* pPackage = NULL; | ||
2227 | BURN_PAYLOAD* pPayload = NULL; | ||
2228 | LPWSTR sczCacheDirectory = NULL; | ||
2229 | |||
2230 | // Deserialize message data. | ||
2231 | hr = BuffReadString(pbData, cbData, &iData, &scz); | ||
2232 | ExitOnFailure(hr, "Failed to read package id."); | ||
2233 | |||
2234 | if (scz && *scz) | ||
2235 | { | ||
2236 | hr = PackageFindById(pPackages, scz, &pPackage); | ||
2237 | ExitOnFailure(hr, "Failed to find package: %ls", scz); | ||
2238 | } | ||
2239 | |||
2240 | hr = BuffReadString(pbData, cbData, &iData, &scz); | ||
2241 | ExitOnFailure(hr, "Failed to read payload id."); | ||
2242 | |||
2243 | if (scz && *scz) | ||
2244 | { | ||
2245 | hr = PayloadFindById(pPayloads, scz, &pPayload); | ||
2246 | ExitOnFailure(hr, "Failed to find payload: %ls", scz); | ||
2247 | } | ||
2248 | |||
2249 | if (pPackage && pPayload) | ||
2250 | { | ||
2251 | hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCacheDirectory); | ||
2252 | ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId); | ||
2253 | |||
2254 | hr = CacheVerifyPayload(pPayload, sczCacheDirectory, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); | ||
2255 | } | ||
2256 | else | ||
2257 | { | ||
2258 | hr = E_INVALIDARG; | ||
2259 | ExitOnRootFailure(hr, "Invalid data passed to cache verify payload."); | ||
2260 | } | ||
2261 | // Nothing should be logged on failure. | ||
2262 | |||
2263 | LExit: | ||
2264 | ReleaseStr(sczCacheDirectory); | ||
2265 | ReleaseStr(scz); | ||
2266 | |||
2267 | return hr; | ||
2268 | } | ||
2269 | |||
2270 | static void OnCacheCleanup( | ||
2271 | __in_z LPCWSTR wzBundleId | ||
2272 | ) | ||
2273 | { | ||
2274 | CacheCleanup(TRUE, wzBundleId); | ||
2275 | } | ||
2276 | |||
2277 | static HRESULT OnProcessDependentRegistration( | ||
2278 | __in const BURN_REGISTRATION* pRegistration, | ||
2279 | __in BYTE* pbData, | ||
2280 | __in SIZE_T cbData | ||
2281 | ) | ||
2282 | { | ||
2283 | HRESULT hr = S_OK; | ||
2284 | SIZE_T iData = 0; | ||
2285 | BURN_DEPENDENT_REGISTRATION_ACTION action = { }; | ||
2286 | |||
2287 | // Deserialize message data. | ||
2288 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&action.type); | ||
2289 | ExitOnFailure(hr, "Failed to read action type."); | ||
2290 | |||
2291 | hr = BuffReadString(pbData, cbData, &iData, &action.sczBundleId); | ||
2292 | ExitOnFailure(hr, "Failed to read bundle id."); | ||
2293 | |||
2294 | hr = BuffReadString(pbData, cbData, &iData, &action.sczDependentProviderKey); | ||
2295 | ExitOnFailure(hr, "Failed to read dependent provider key."); | ||
2296 | |||
2297 | // Execute the registration action. | ||
2298 | hr = DependencyProcessDependentRegistration(pRegistration, &action); | ||
2299 | ExitOnFailure(hr, "Failed to execute dependent registration action for provider key: %ls", action.sczDependentProviderKey); | ||
2300 | |||
2301 | LExit: | ||
2302 | // TODO: do the right thing here. | ||
2303 | //DependencyUninitializeRegistrationAction(&action); | ||
2304 | ReleaseStr(action.sczDependentProviderKey); | ||
2305 | ReleaseStr(action.sczBundleId) | ||
2306 | |||
2307 | return hr; | ||
2308 | } | ||
2309 | |||
2310 | static HRESULT OnExecuteExePackage( | ||
2311 | __in HANDLE hPipe, | ||
2312 | __in BURN_PACKAGES* pPackages, | ||
2313 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
2314 | __in BURN_VARIABLES* pVariables, | ||
2315 | __in BYTE* pbData, | ||
2316 | __in SIZE_T cbData | ||
2317 | ) | ||
2318 | { | ||
2319 | HRESULT hr = S_OK; | ||
2320 | SIZE_T iData = 0; | ||
2321 | LPWSTR sczPackage = NULL; | ||
2322 | DWORD dwRollback = 0; | ||
2323 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2324 | LPWSTR sczIgnoreDependencies = NULL; | ||
2325 | LPWSTR sczAncestors = NULL; | ||
2326 | BOOTSTRAPPER_APPLY_RESTART exeRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
2327 | |||
2328 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE; | ||
2329 | |||
2330 | // Deserialize message data. | ||
2331 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2332 | ExitOnFailure(hr, "Failed to read EXE package id."); | ||
2333 | |||
2334 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.exePackage.action); | ||
2335 | ExitOnFailure(hr, "Failed to read action."); | ||
2336 | |||
2337 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); | ||
2338 | ExitOnFailure(hr, "Failed to read rollback."); | ||
2339 | |||
2340 | hr = BuffReadString(pbData, cbData, &iData, &sczIgnoreDependencies); | ||
2341 | ExitOnFailure(hr, "Failed to read the list of dependencies to ignore."); | ||
2342 | |||
2343 | hr = BuffReadString(pbData, cbData, &iData, &sczAncestors); | ||
2344 | ExitOnFailure(hr, "Failed to read the list of ancestors."); | ||
2345 | |||
2346 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
2347 | ExitOnFailure(hr, "Failed to read variables."); | ||
2348 | |||
2349 | hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage); | ||
2350 | if (E_NOTFOUND == hr) | ||
2351 | { | ||
2352 | hr = PackageFindRelatedById(pRelatedBundles, sczPackage, &executeAction.exePackage.pPackage); | ||
2353 | } | ||
2354 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2355 | |||
2356 | // Pass the list of dependencies to ignore, if any, to the related bundle. | ||
2357 | if (sczIgnoreDependencies && *sczIgnoreDependencies) | ||
2358 | { | ||
2359 | hr = StrAllocString(&executeAction.exePackage.sczIgnoreDependencies, sczIgnoreDependencies, 0); | ||
2360 | ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore."); | ||
2361 | } | ||
2362 | |||
2363 | // Pass the list of ancestors, if any, to the related bundle. | ||
2364 | if (sczAncestors && *sczAncestors) | ||
2365 | { | ||
2366 | hr = StrAllocString(&executeAction.exePackage.sczAncestors, sczAncestors, 0); | ||
2367 | ExitOnFailure(hr, "Failed to allocate the list of ancestors."); | ||
2368 | } | ||
2369 | |||
2370 | // Execute EXE package. | ||
2371 | hr = ExeEngineExecutePackage(&executeAction, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, &exeRestart); | ||
2372 | ExitOnFailure(hr, "Failed to execute EXE package."); | ||
2373 | |||
2374 | LExit: | ||
2375 | ReleaseStr(sczAncestors); | ||
2376 | ReleaseStr(sczIgnoreDependencies); | ||
2377 | ReleaseStr(sczPackage); | ||
2378 | PlanUninitializeExecuteAction(&executeAction); | ||
2379 | |||
2380 | if (SUCCEEDED(hr)) | ||
2381 | { | ||
2382 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == exeRestart) | ||
2383 | { | ||
2384 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | ||
2385 | } | ||
2386 | else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == exeRestart) | ||
2387 | { | ||
2388 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED); | ||
2389 | } | ||
2390 | } | ||
2391 | |||
2392 | return hr; | ||
2393 | } | ||
2394 | |||
2395 | static HRESULT OnExecuteMsiPackage( | ||
2396 | __in HANDLE hPipe, | ||
2397 | __in BURN_PACKAGES* pPackages, | ||
2398 | __in BURN_VARIABLES* pVariables, | ||
2399 | __in BYTE* pbData, | ||
2400 | __in SIZE_T cbData | ||
2401 | ) | ||
2402 | { | ||
2403 | HRESULT hr = S_OK; | ||
2404 | SIZE_T iData = 0; | ||
2405 | LPWSTR sczPackage = NULL; | ||
2406 | HWND hwndParent = NULL; | ||
2407 | BOOL fRollback = 0; | ||
2408 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2409 | BOOTSTRAPPER_APPLY_RESTART msiRestart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
2410 | |||
2411 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE; | ||
2412 | |||
2413 | // Deserialize message data. | ||
2414 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); | ||
2415 | ExitOnFailure(hr, "Failed to read rollback flag."); | ||
2416 | |||
2417 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2418 | ExitOnFailure(hr, "Failed to read MSI package id."); | ||
2419 | |||
2420 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msiPackage.pPackage); | ||
2421 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2422 | |||
2423 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); | ||
2424 | ExitOnFailure(hr, "Failed to read parent hwnd."); | ||
2425 | |||
2426 | hr = BuffReadString(pbData, cbData, &iData, &executeAction.msiPackage.sczLogPath); | ||
2427 | ExitOnFailure(hr, "Failed to read package log."); | ||
2428 | |||
2429 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.actionMsiProperty); | ||
2430 | ExitOnFailure(hr, "Failed to read actionMsiProperty."); | ||
2431 | |||
2432 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.uiLevel); | ||
2433 | ExitOnFailure(hr, "Failed to read UI level."); | ||
2434 | |||
2435 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.fDisableExternalUiHandler); | ||
2436 | ExitOnFailure(hr, "Failed to read fDisableExternalUiHandler."); | ||
2437 | |||
2438 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.action); | ||
2439 | ExitOnFailure(hr, "Failed to read action."); | ||
2440 | |||
2441 | // Read feature actions. | ||
2442 | if (executeAction.msiPackage.pPackage->Msi.cFeatures) | ||
2443 | { | ||
2444 | executeAction.msiPackage.rgFeatures = (BOOTSTRAPPER_FEATURE_ACTION*)MemAlloc(executeAction.msiPackage.pPackage->Msi.cFeatures * sizeof(BOOTSTRAPPER_FEATURE_ACTION), TRUE); | ||
2445 | ExitOnNull(executeAction.msiPackage.rgFeatures, hr, E_OUTOFMEMORY, "Failed to allocate memory for feature actions."); | ||
2446 | |||
2447 | for (DWORD i = 0; i < executeAction.msiPackage.pPackage->Msi.cFeatures; ++i) | ||
2448 | { | ||
2449 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.rgFeatures[i]); | ||
2450 | ExitOnFailure(hr, "Failed to read feature action."); | ||
2451 | } | ||
2452 | } | ||
2453 | |||
2454 | // Read slipstream patches actions. | ||
2455 | if (executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages) | ||
2456 | { | ||
2457 | for (DWORD i = 0; i < executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++i) | ||
2458 | { | ||
2459 | BURN_SLIPSTREAM_MSP* pSlipstreamMsp = executeAction.msiPackage.pPackage->Msi.rgSlipstreamMsps + i; | ||
2460 | BOOTSTRAPPER_ACTION_STATE* pAction = fRollback ? &pSlipstreamMsp->rollback : &pSlipstreamMsp->execute; | ||
2461 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction); | ||
2462 | ExitOnFailure(hr, "Failed to read slipstream action."); | ||
2463 | } | ||
2464 | } | ||
2465 | |||
2466 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
2467 | ExitOnFailure(hr, "Failed to read variables."); | ||
2468 | |||
2469 | // Execute MSI package. | ||
2470 | hr = MsiEngineExecutePackage(hwndParent, &executeAction, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart); | ||
2471 | ExitOnFailure(hr, "Failed to execute MSI package."); | ||
2472 | |||
2473 | LExit: | ||
2474 | ReleaseStr(sczPackage); | ||
2475 | PlanUninitializeExecuteAction(&executeAction); | ||
2476 | |||
2477 | if (SUCCEEDED(hr)) | ||
2478 | { | ||
2479 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == msiRestart) | ||
2480 | { | ||
2481 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | ||
2482 | } | ||
2483 | else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == msiRestart) | ||
2484 | { | ||
2485 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED); | ||
2486 | } | ||
2487 | } | ||
2488 | |||
2489 | return hr; | ||
2490 | } | ||
2491 | |||
2492 | static HRESULT OnExecuteMspPackage( | ||
2493 | __in HANDLE hPipe, | ||
2494 | __in BURN_PACKAGES* pPackages, | ||
2495 | __in BURN_VARIABLES* pVariables, | ||
2496 | __in BYTE* pbData, | ||
2497 | __in SIZE_T cbData | ||
2498 | ) | ||
2499 | { | ||
2500 | HRESULT hr = S_OK; | ||
2501 | SIZE_T iData = 0; | ||
2502 | LPWSTR sczPackage = NULL; | ||
2503 | HWND hwndParent = NULL; | ||
2504 | BOOL fRollback = 0; | ||
2505 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2506 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
2507 | |||
2508 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSP_TARGET; | ||
2509 | |||
2510 | // Deserialize message data. | ||
2511 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2512 | ExitOnFailure(hr, "Failed to read MSP package id."); | ||
2513 | |||
2514 | hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.pPackage); | ||
2515 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2516 | |||
2517 | hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent); | ||
2518 | ExitOnFailure(hr, "Failed to read parent hwnd."); | ||
2519 | |||
2520 | executeAction.mspTarget.fPerMachineTarget = TRUE; // we're in the elevated process, clearly we're targeting a per-machine product. | ||
2521 | |||
2522 | hr = BuffReadString(pbData, cbData, &iData, &executeAction.mspTarget.sczTargetProductCode); | ||
2523 | ExitOnFailure(hr, "Failed to read target product code."); | ||
2524 | |||
2525 | hr = BuffReadString(pbData, cbData, &iData, &executeAction.mspTarget.sczLogPath); | ||
2526 | ExitOnFailure(hr, "Failed to read package log."); | ||
2527 | |||
2528 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.actionMsiProperty); | ||
2529 | ExitOnFailure(hr, "Failed to read actionMsiProperty."); | ||
2530 | |||
2531 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.uiLevel); | ||
2532 | ExitOnFailure(hr, "Failed to read UI level."); | ||
2533 | |||
2534 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.fDisableExternalUiHandler); | ||
2535 | ExitOnFailure(hr, "Failed to read fDisableExternalUiHandler."); | ||
2536 | |||
2537 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.action); | ||
2538 | ExitOnFailure(hr, "Failed to read action."); | ||
2539 | |||
2540 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.cOrderedPatches); | ||
2541 | ExitOnFailure(hr, "Failed to read count of ordered patches."); | ||
2542 | |||
2543 | if (executeAction.mspTarget.cOrderedPatches) | ||
2544 | { | ||
2545 | executeAction.mspTarget.rgOrderedPatches = (BURN_ORDERED_PATCHES*)MemAlloc(executeAction.mspTarget.cOrderedPatches * sizeof(BURN_ORDERED_PATCHES), TRUE); | ||
2546 | ExitOnNull(executeAction.mspTarget.rgOrderedPatches, hr, E_OUTOFMEMORY, "Failed to allocate memory for ordered patches."); | ||
2547 | |||
2548 | for (DWORD i = 0; i < executeAction.mspTarget.cOrderedPatches; ++i) | ||
2549 | { | ||
2550 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2551 | ExitOnFailure(hr, "Failed to read ordered patch package id."); | ||
2552 | |||
2553 | hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.rgOrderedPatches[i].pPackage); | ||
2554 | ExitOnFailure(hr, "Failed to find ordered patch package: %ls", sczPackage); | ||
2555 | } | ||
2556 | } | ||
2557 | |||
2558 | hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData); | ||
2559 | ExitOnFailure(hr, "Failed to read variables."); | ||
2560 | |||
2561 | hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback); | ||
2562 | ExitOnFailure(hr, "Failed to read rollback flag."); | ||
2563 | |||
2564 | // Execute MSP package. | ||
2565 | hr = MspEngineExecutePackage(hwndParent, &executeAction, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &restart); | ||
2566 | ExitOnFailure(hr, "Failed to execute MSP package."); | ||
2567 | |||
2568 | LExit: | ||
2569 | ReleaseStr(sczPackage); | ||
2570 | PlanUninitializeExecuteAction(&executeAction); | ||
2571 | |||
2572 | if (SUCCEEDED(hr)) | ||
2573 | { | ||
2574 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart) | ||
2575 | { | ||
2576 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | ||
2577 | } | ||
2578 | else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart) | ||
2579 | { | ||
2580 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED); | ||
2581 | } | ||
2582 | } | ||
2583 | |||
2584 | return hr; | ||
2585 | } | ||
2586 | |||
2587 | static HRESULT OnExecuteMsuPackage( | ||
2588 | __in HANDLE hPipe, | ||
2589 | __in BURN_PACKAGES* pPackages, | ||
2590 | __in BURN_VARIABLES* pVariables, | ||
2591 | __in BYTE* pbData, | ||
2592 | __in SIZE_T cbData | ||
2593 | ) | ||
2594 | { | ||
2595 | HRESULT hr = S_OK; | ||
2596 | SIZE_T iData = 0; | ||
2597 | LPWSTR sczPackage = NULL; | ||
2598 | DWORD dwRollback = 0; | ||
2599 | DWORD dwStopWusaService = 0; | ||
2600 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2601 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | ||
2602 | |||
2603 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE; | ||
2604 | |||
2605 | // Deserialize message data. | ||
2606 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2607 | ExitOnFailure(hr, "Failed to read MSU package id."); | ||
2608 | |||
2609 | hr = BuffReadString(pbData, cbData, &iData, &executeAction.msuPackage.sczLogPath); | ||
2610 | ExitOnFailure(hr, "Failed to read package log."); | ||
2611 | |||
2612 | hr = BuffReadNumber(pbData, cbData, &iData, reinterpret_cast<DWORD*>(&executeAction.msuPackage.action)); | ||
2613 | ExitOnFailure(hr, "Failed to read action."); | ||
2614 | |||
2615 | hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback); | ||
2616 | ExitOnFailure(hr, "Failed to read rollback."); | ||
2617 | |||
2618 | hr = BuffReadNumber(pbData, cbData, &iData, &dwStopWusaService); | ||
2619 | ExitOnFailure(hr, "Failed to read StopWusaService."); | ||
2620 | |||
2621 | hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage); | ||
2622 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2623 | |||
2624 | // execute MSU package | ||
2625 | hr = MsuEngineExecutePackage(&executeAction, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, &restart); | ||
2626 | ExitOnFailure(hr, "Failed to execute MSU package."); | ||
2627 | |||
2628 | LExit: | ||
2629 | ReleaseStr(sczPackage); | ||
2630 | PlanUninitializeExecuteAction(&executeAction); | ||
2631 | |||
2632 | if (SUCCEEDED(hr)) | ||
2633 | { | ||
2634 | if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart) | ||
2635 | { | ||
2636 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED); | ||
2637 | } | ||
2638 | else if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart) | ||
2639 | { | ||
2640 | hr = HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_INITIATED); | ||
2641 | } | ||
2642 | } | ||
2643 | |||
2644 | return hr; | ||
2645 | } | ||
2646 | |||
2647 | static HRESULT OnExecutePackageProviderAction( | ||
2648 | __in BURN_PACKAGES* pPackages, | ||
2649 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
2650 | __in BYTE* pbData, | ||
2651 | __in SIZE_T cbData | ||
2652 | ) | ||
2653 | { | ||
2654 | HRESULT hr = S_OK; | ||
2655 | SIZE_T iData = 0; | ||
2656 | LPWSTR sczPackage = NULL; | ||
2657 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2658 | |||
2659 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER; | ||
2660 | |||
2661 | // Deserialize the message data. | ||
2662 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2663 | ExitOnFailure(hr, "Failed to read package id from message buffer."); | ||
2664 | |||
2665 | hr = BuffReadNumber(pbData, cbData, &iData, reinterpret_cast<DWORD*>(&executeAction.packageProvider.action)); | ||
2666 | ExitOnFailure(hr, "Failed to read action."); | ||
2667 | |||
2668 | // Find the package again. | ||
2669 | hr = PackageFindById(pPackages, sczPackage, &executeAction.packageProvider.pPackage); | ||
2670 | if (E_NOTFOUND == hr) | ||
2671 | { | ||
2672 | hr = PackageFindRelatedById(pRelatedBundles, sczPackage, &executeAction.packageProvider.pPackage); | ||
2673 | } | ||
2674 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2675 | |||
2676 | // Execute the package provider action. | ||
2677 | hr = DependencyExecutePackageProviderAction(&executeAction); | ||
2678 | ExitOnFailure(hr, "Failed to execute package provider action."); | ||
2679 | |||
2680 | LExit: | ||
2681 | ReleaseStr(sczPackage); | ||
2682 | PlanUninitializeExecuteAction(&executeAction); | ||
2683 | |||
2684 | return hr; | ||
2685 | } | ||
2686 | |||
2687 | static HRESULT OnExecutePackageDependencyAction( | ||
2688 | __in BURN_PACKAGES* pPackages, | ||
2689 | __in BURN_RELATED_BUNDLES* pRelatedBundles, | ||
2690 | __in BYTE* pbData, | ||
2691 | __in SIZE_T cbData | ||
2692 | ) | ||
2693 | { | ||
2694 | HRESULT hr = S_OK; | ||
2695 | SIZE_T iData = 0; | ||
2696 | LPWSTR sczPackage = NULL; | ||
2697 | BURN_EXECUTE_ACTION executeAction = { }; | ||
2698 | |||
2699 | executeAction.type = BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY; | ||
2700 | |||
2701 | // Deserialize the message data. | ||
2702 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2703 | ExitOnFailure(hr, "Failed to read package id from message buffer."); | ||
2704 | |||
2705 | hr = BuffReadString(pbData, cbData, &iData, &executeAction.packageDependency.sczBundleProviderKey); | ||
2706 | ExitOnFailure(hr, "Failed to read bundle dependency key from message buffer."); | ||
2707 | |||
2708 | hr = BuffReadNumber(pbData, cbData, &iData, reinterpret_cast<DWORD*>(&executeAction.packageDependency.action)); | ||
2709 | ExitOnFailure(hr, "Failed to read action."); | ||
2710 | |||
2711 | // Find the package again. | ||
2712 | hr = PackageFindById(pPackages, sczPackage, &executeAction.packageDependency.pPackage); | ||
2713 | if (E_NOTFOUND == hr) | ||
2714 | { | ||
2715 | hr = PackageFindRelatedById(pRelatedBundles, sczPackage, &executeAction.packageDependency.pPackage); | ||
2716 | } | ||
2717 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2718 | |||
2719 | // Execute the package dependency action. | ||
2720 | hr = DependencyExecutePackageDependencyAction(TRUE, &executeAction); | ||
2721 | ExitOnFailure(hr, "Failed to execute package dependency action."); | ||
2722 | |||
2723 | LExit: | ||
2724 | ReleaseStr(sczPackage); | ||
2725 | PlanUninitializeExecuteAction(&executeAction); | ||
2726 | |||
2727 | return hr; | ||
2728 | } | ||
2729 | |||
2730 | static HRESULT CALLBACK BurnCacheMessageHandler( | ||
2731 | __in BURN_CACHE_MESSAGE* pMessage, | ||
2732 | __in LPVOID pvContext | ||
2733 | ) | ||
2734 | { | ||
2735 | HRESULT hr = S_OK; | ||
2736 | DWORD dwResult = 0; | ||
2737 | HANDLE hPipe = (HANDLE)pvContext; | ||
2738 | BYTE* pbData = NULL; | ||
2739 | SIZE_T cbData = 0; | ||
2740 | DWORD dwMessage = 0; | ||
2741 | |||
2742 | switch (pMessage->type) | ||
2743 | { | ||
2744 | case BURN_CACHE_MESSAGE_BEGIN: | ||
2745 | // serialize message data | ||
2746 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep); | ||
2747 | ExitOnFailure(hr, "Failed to write progress percentage to message buffer."); | ||
2748 | |||
2749 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN; | ||
2750 | break; | ||
2751 | |||
2752 | case BURN_CACHE_MESSAGE_COMPLETE: | ||
2753 | // serialize message data | ||
2754 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->complete.hrStatus); | ||
2755 | ExitOnFailure(hr, "Failed to write error code to message buffer."); | ||
2756 | |||
2757 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE; | ||
2758 | break; | ||
2759 | |||
2760 | case BURN_CACHE_MESSAGE_SUCCESS: | ||
2761 | hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize); | ||
2762 | ExitOnFailure(hr, "Failed to count of files in use to message buffer."); | ||
2763 | |||
2764 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS; | ||
2765 | break; | ||
2766 | } | ||
2767 | |||
2768 | // send message | ||
2769 | hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult); | ||
2770 | ExitOnFailure(hr, "Failed to send burn cache message to per-user process."); | ||
2771 | |||
2772 | hr = dwResult; | ||
2773 | |||
2774 | LExit: | ||
2775 | ReleaseBuffer(pbData); | ||
2776 | |||
2777 | return hr; | ||
2778 | } | ||
2779 | |||
2780 | static DWORD CALLBACK ElevatedProgressRoutine( | ||
2781 | __in LARGE_INTEGER TotalFileSize, | ||
2782 | __in LARGE_INTEGER TotalBytesTransferred, | ||
2783 | __in LARGE_INTEGER /*StreamSize*/, | ||
2784 | __in LARGE_INTEGER /*StreamBytesTransferred*/, | ||
2785 | __in DWORD /*dwStreamNumber*/, | ||
2786 | __in DWORD /*dwCallbackReason*/, | ||
2787 | __in HANDLE /*hSourceFile*/, | ||
2788 | __in HANDLE /*hDestinationFile*/, | ||
2789 | __in_opt LPVOID lpData | ||
2790 | ) | ||
2791 | { | ||
2792 | HRESULT hr = S_OK; | ||
2793 | DWORD dwResult = 0; | ||
2794 | HANDLE hPipe = (HANDLE)lpData; | ||
2795 | BYTE* pbData = NULL; | ||
2796 | SIZE_T cbData = 0; | ||
2797 | DWORD dwMessage = BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE; | ||
2798 | |||
2799 | hr = BuffWriteNumber64(&pbData, &cbData, TotalFileSize.QuadPart); | ||
2800 | ExitOnFailure(hr, "Failed to write total file size progress to message buffer."); | ||
2801 | |||
2802 | hr = BuffWriteNumber64(&pbData, &cbData, TotalBytesTransferred.QuadPart); | ||
2803 | ExitOnFailure(hr, "Failed to write total bytes transferred progress to message buffer."); | ||
2804 | |||
2805 | // send message | ||
2806 | hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult); | ||
2807 | ExitOnFailure(hr, "Failed to send progress routine message to per-user process."); | ||
2808 | |||
2809 | LExit: | ||
2810 | ReleaseBuffer(pbData); | ||
2811 | |||
2812 | return dwResult; | ||
2813 | } | ||
2814 | |||
2815 | static int GenericExecuteMessageHandler( | ||
2816 | __in GENERIC_EXECUTE_MESSAGE* pMessage, | ||
2817 | __in LPVOID pvContext | ||
2818 | ) | ||
2819 | { | ||
2820 | HRESULT hr = S_OK; | ||
2821 | int nResult = IDOK; | ||
2822 | HANDLE hPipe = (HANDLE)pvContext; | ||
2823 | BYTE* pbData = NULL; | ||
2824 | SIZE_T cbData = 0; | ||
2825 | DWORD dwMessage = 0; | ||
2826 | |||
2827 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwAllowedResults); | ||
2828 | ExitOnFailure(hr, "Failed to write UI flags."); | ||
2829 | |||
2830 | switch(pMessage->type) | ||
2831 | { | ||
2832 | case GENERIC_EXECUTE_MESSAGE_PROGRESS: | ||
2833 | // serialize message data | ||
2834 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->progress.dwPercentage); | ||
2835 | ExitOnFailure(hr, "Failed to write progress percentage to message buffer."); | ||
2836 | |||
2837 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS; | ||
2838 | break; | ||
2839 | |||
2840 | case GENERIC_EXECUTE_MESSAGE_ERROR: | ||
2841 | // serialize message data | ||
2842 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->error.dwErrorCode); | ||
2843 | ExitOnFailure(hr, "Failed to write error code to message buffer."); | ||
2844 | |||
2845 | hr = BuffWriteString(&pbData, &cbData, pMessage->error.wzMessage); | ||
2846 | ExitOnFailure(hr, "Failed to write message to message buffer."); | ||
2847 | |||
2848 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR; | ||
2849 | break; | ||
2850 | |||
2851 | case GENERIC_EXECUTE_MESSAGE_FILES_IN_USE: | ||
2852 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->filesInUse.cFiles); | ||
2853 | ExitOnFailure(hr, "Failed to count of files in use to message buffer."); | ||
2854 | |||
2855 | for (DWORD i = 0; i < pMessage->filesInUse.cFiles; ++i) | ||
2856 | { | ||
2857 | hr = BuffWriteString(&pbData, &cbData, pMessage->filesInUse.rgwzFiles[i]); | ||
2858 | ExitOnFailure(hr, "Failed to write file in use to message buffer."); | ||
2859 | } | ||
2860 | |||
2861 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE; | ||
2862 | break; | ||
2863 | } | ||
2864 | |||
2865 | // send message | ||
2866 | hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, reinterpret_cast<DWORD*>(&nResult)); | ||
2867 | ExitOnFailure(hr, "Failed to send message to per-user process."); | ||
2868 | |||
2869 | LExit: | ||
2870 | ReleaseBuffer(pbData); | ||
2871 | |||
2872 | return nResult; | ||
2873 | } | ||
2874 | |||
2875 | static int MsiExecuteMessageHandler( | ||
2876 | __in WIU_MSI_EXECUTE_MESSAGE* pMessage, | ||
2877 | __in_opt LPVOID pvContext | ||
2878 | ) | ||
2879 | { | ||
2880 | HRESULT hr = S_OK; | ||
2881 | int nResult = IDOK; | ||
2882 | HANDLE hPipe = (HANDLE)pvContext; | ||
2883 | BYTE* pbData = NULL; | ||
2884 | SIZE_T cbData = 0; | ||
2885 | DWORD dwMessage = 0; | ||
2886 | |||
2887 | // Always send any extra data via the struct first. | ||
2888 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->cData); | ||
2889 | ExitOnFailure(hr, "Failed to write MSI data count to message buffer."); | ||
2890 | |||
2891 | for (DWORD i = 0; i < pMessage->cData; ++i) | ||
2892 | { | ||
2893 | hr = BuffWriteString(&pbData, &cbData, pMessage->rgwzData[i]); | ||
2894 | ExitOnFailure(hr, "Failed to write MSI data to message buffer."); | ||
2895 | } | ||
2896 | |||
2897 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwAllowedResults); | ||
2898 | ExitOnFailure(hr, "Failed to write UI flags."); | ||
2899 | |||
2900 | switch (pMessage->type) | ||
2901 | { | ||
2902 | case WIU_MSI_EXECUTE_MESSAGE_PROGRESS: | ||
2903 | // serialize message data | ||
2904 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->progress.dwPercentage); | ||
2905 | ExitOnFailure(hr, "Failed to write progress percentage to message buffer."); | ||
2906 | |||
2907 | // set message id | ||
2908 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS; | ||
2909 | break; | ||
2910 | |||
2911 | case WIU_MSI_EXECUTE_MESSAGE_ERROR: | ||
2912 | // serialize message data | ||
2913 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->error.dwErrorCode); | ||
2914 | ExitOnFailure(hr, "Failed to write error code to message buffer."); | ||
2915 | |||
2916 | hr = BuffWriteString(&pbData, &cbData, pMessage->error.wzMessage); | ||
2917 | ExitOnFailure(hr, "Failed to write message to message buffer."); | ||
2918 | |||
2919 | // set message id | ||
2920 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR; | ||
2921 | break; | ||
2922 | |||
2923 | case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE: | ||
2924 | // serialize message data | ||
2925 | hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pMessage->msiMessage.mt); | ||
2926 | ExitOnFailure(hr, "Failed to write MSI message type to message buffer."); | ||
2927 | |||
2928 | hr = BuffWriteString(&pbData, &cbData, pMessage->msiMessage.wzMessage); | ||
2929 | ExitOnFailure(hr, "Failed to write message to message buffer."); | ||
2930 | |||
2931 | // set message id | ||
2932 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE; | ||
2933 | break; | ||
2934 | |||
2935 | case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE: | ||
2936 | // NOTE: we do not serialize other message data here because all the "files in use" are in the data above. | ||
2937 | |||
2938 | // set message id | ||
2939 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE; | ||
2940 | break; | ||
2941 | |||
2942 | default: | ||
2943 | hr = E_UNEXPECTED; | ||
2944 | ExitOnFailure(hr, "Invalid message type: %d", pMessage->type); | ||
2945 | } | ||
2946 | |||
2947 | // send message | ||
2948 | hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, (DWORD*)&nResult); | ||
2949 | ExitOnFailure(hr, "Failed to send msi message to per-user process."); | ||
2950 | |||
2951 | LExit: | ||
2952 | ReleaseBuffer(pbData); | ||
2953 | |||
2954 | return nResult; | ||
2955 | } | ||
2956 | |||
2957 | static HRESULT OnCleanPackage( | ||
2958 | __in BURN_PACKAGES* pPackages, | ||
2959 | __in BYTE* pbData, | ||
2960 | __in SIZE_T cbData | ||
2961 | ) | ||
2962 | { | ||
2963 | HRESULT hr = S_OK; | ||
2964 | SIZE_T iData = 0; | ||
2965 | LPWSTR sczPackage = NULL; | ||
2966 | BURN_PACKAGE* pPackage = NULL; | ||
2967 | |||
2968 | // Deserialize message data. | ||
2969 | hr = BuffReadString(pbData, cbData, &iData, &sczPackage); | ||
2970 | ExitOnFailure(hr, "Failed to read package id."); | ||
2971 | |||
2972 | hr = PackageFindById(pPackages, sczPackage, &pPackage); | ||
2973 | ExitOnFailure(hr, "Failed to find package: %ls", sczPackage); | ||
2974 | |||
2975 | // Remove the package from the cache. | ||
2976 | hr = CacheRemovePackage(TRUE, pPackage->sczId, pPackage->sczCacheId); | ||
2977 | ExitOnFailure(hr, "Failed to remove from cache package: %ls", pPackage->sczId); | ||
2978 | |||
2979 | LExit: | ||
2980 | ReleaseStr(sczPackage); | ||
2981 | return hr; | ||
2982 | } | ||
2983 | |||
2984 | static HRESULT OnLaunchApprovedExe( | ||
2985 | __in HANDLE hPipe, | ||
2986 | __in BURN_APPROVED_EXES* pApprovedExes, | ||
2987 | __in BURN_VARIABLES* pVariables, | ||
2988 | __in BYTE* pbData, | ||
2989 | __in SIZE_T cbData | ||
2990 | ) | ||
2991 | { | ||
2992 | HRESULT hr = S_OK; | ||
2993 | SIZE_T iData = 0; | ||
2994 | BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = NULL; | ||
2995 | BURN_APPROVED_EXE* pApprovedExe = NULL; | ||
2996 | REGSAM samDesired = KEY_QUERY_VALUE; | ||
2997 | HKEY hKey = NULL; | ||
2998 | DWORD dwProcessId = 0; | ||
2999 | BYTE* pbSendData = NULL; | ||
3000 | SIZE_T cbSendData = 0; | ||
3001 | DWORD dwResult = 0; | ||
3002 | |||
3003 | pLaunchApprovedExe = (BURN_LAUNCH_APPROVED_EXE*)MemAlloc(sizeof(BURN_LAUNCH_APPROVED_EXE), TRUE); | ||
3004 | |||
3005 | // Deserialize message data. | ||
3006 | hr = BuffReadString(pbData, cbData, &iData, &pLaunchApprovedExe->sczId); | ||
3007 | ExitOnFailure(hr, "Failed to read approved exe id."); | ||
3008 | |||
3009 | hr = BuffReadString(pbData, cbData, &iData, &pLaunchApprovedExe->sczArguments); | ||
3010 | ExitOnFailure(hr, "Failed to read approved exe arguments."); | ||
3011 | |||
3012 | hr = BuffReadNumber(pbData, cbData, &iData, &pLaunchApprovedExe->dwWaitForInputIdleTimeout); | ||
3013 | ExitOnFailure(hr, "Failed to read approved exe WaitForInputIdle timeout."); | ||
3014 | |||
3015 | hr = ApprovedExesFindById(pApprovedExes, pLaunchApprovedExe->sczId, &pApprovedExe); | ||
3016 | ExitOnFailure(hr, "The per-user process requested unknown approved exe with id: %ls", pLaunchApprovedExe->sczId); | ||
3017 | |||
3018 | LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_SEARCH, pApprovedExe->sczKey, pApprovedExe->sczValueName ? pApprovedExe->sczValueName : L"", pApprovedExe->fWin64 ? L"yes" : L"no"); | ||
3019 | |||
3020 | if (pApprovedExe->fWin64) | ||
3021 | { | ||
3022 | samDesired |= KEY_WOW64_64KEY; | ||
3023 | } | ||
3024 | |||
3025 | hr = RegOpen(HKEY_LOCAL_MACHINE, pApprovedExe->sczKey, samDesired, &hKey); | ||
3026 | ExitOnFailure(hr, "Failed to open the registry key for the approved exe path."); | ||
3027 | |||
3028 | hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath); | ||
3029 | ExitOnFailure(hr, "Failed to read the value for the approved exe path."); | ||
3030 | |||
3031 | hr = ApprovedExesVerifySecureLocation(pVariables, pLaunchApprovedExe); | ||
3032 | ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath); | ||
3033 | if (S_FALSE == hr) | ||
3034 | { | ||
3035 | LogStringLine(REPORT_STANDARD, "The executable path is not in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath); | ||
3036 | ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)); | ||
3037 | } | ||
3038 | |||
3039 | hr = ApprovedExesLaunch(pVariables, pLaunchApprovedExe, &dwProcessId); | ||
3040 | ExitOnFailure(hr, "Failed to launch approved exe: %ls", pLaunchApprovedExe->sczExecutablePath); | ||
3041 | |||
3042 | //send process id over pipe | ||
3043 | hr = BuffWriteNumber(&pbSendData, &cbSendData, dwProcessId); | ||
3044 | ExitOnFailure(hr, "Failed to write the approved exe process id to message buffer."); | ||
3045 | |||
3046 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID, pbSendData, cbSendData, NULL, NULL, &dwResult); | ||
3047 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID message to per-user process."); | ||
3048 | |||
3049 | LExit: | ||
3050 | ReleaseBuffer(pbSendData); | ||
3051 | ApprovedExesUninitializeLaunch(pLaunchApprovedExe); | ||
3052 | return hr; | ||
3053 | } | ||
3054 | |||
3055 | static HRESULT OnMsiBeginTransaction( | ||
3056 | __in BURN_PACKAGES* pPackages, | ||
3057 | __in BYTE* pbData, | ||
3058 | __in SIZE_T cbData | ||
3059 | ) | ||
3060 | { | ||
3061 | HRESULT hr = S_OK; | ||
3062 | SIZE_T iData = 0; | ||
3063 | LPWSTR sczId = NULL; | ||
3064 | LPWSTR sczLogPath = NULL; | ||
3065 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; | ||
3066 | |||
3067 | // Deserialize message data. | ||
3068 | hr = BuffReadString(pbData, cbData, &iData, &sczId); | ||
3069 | ExitOnFailure(hr, "Failed to read rollback boundary id."); | ||
3070 | |||
3071 | hr = BuffReadString(pbData, cbData, &iData, &sczLogPath); | ||
3072 | ExitOnFailure(hr, "Failed to read transaction log path."); | ||
3073 | |||
3074 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); | ||
3075 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); | ||
3076 | |||
3077 | pRollbackBoundary->sczLogPath = sczLogPath; | ||
3078 | |||
3079 | hr = MsiEngineBeginTransaction(pRollbackBoundary); | ||
3080 | |||
3081 | LExit: | ||
3082 | ReleaseStr(sczId); | ||
3083 | ReleaseStr(sczLogPath); | ||
3084 | |||
3085 | if (pRollbackBoundary) | ||
3086 | { | ||
3087 | pRollbackBoundary->sczLogPath = NULL; | ||
3088 | } | ||
3089 | |||
3090 | return hr; | ||
3091 | } | ||
3092 | |||
3093 | static HRESULT OnMsiCommitTransaction( | ||
3094 | __in BURN_PACKAGES* pPackages, | ||
3095 | __in BYTE* pbData, | ||
3096 | __in SIZE_T cbData | ||
3097 | ) | ||
3098 | { | ||
3099 | HRESULT hr = S_OK; | ||
3100 | SIZE_T iData = 0; | ||
3101 | LPWSTR sczId = NULL; | ||
3102 | LPWSTR sczLogPath = NULL; | ||
3103 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; | ||
3104 | |||
3105 | // Deserialize message data. | ||
3106 | hr = BuffReadString(pbData, cbData, &iData, &sczId); | ||
3107 | ExitOnFailure(hr, "Failed to read rollback boundary id."); | ||
3108 | |||
3109 | hr = BuffReadString(pbData, cbData, &iData, &sczLogPath); | ||
3110 | ExitOnFailure(hr, "Failed to read transaction log path."); | ||
3111 | |||
3112 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); | ||
3113 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); | ||
3114 | |||
3115 | pRollbackBoundary->sczLogPath = sczLogPath; | ||
3116 | |||
3117 | hr = MsiEngineCommitTransaction(pRollbackBoundary); | ||
3118 | |||
3119 | LExit: | ||
3120 | ReleaseStr(sczId); | ||
3121 | ReleaseStr(sczLogPath); | ||
3122 | |||
3123 | if (pRollbackBoundary) | ||
3124 | { | ||
3125 | pRollbackBoundary->sczLogPath = NULL; | ||
3126 | } | ||
3127 | |||
3128 | return hr; | ||
3129 | } | ||
3130 | |||
3131 | static HRESULT OnMsiRollbackTransaction( | ||
3132 | __in BURN_PACKAGES* pPackages, | ||
3133 | __in BYTE* pbData, | ||
3134 | __in SIZE_T cbData | ||
3135 | ) | ||
3136 | { | ||
3137 | HRESULT hr = S_OK; | ||
3138 | SIZE_T iData = 0; | ||
3139 | LPWSTR sczId = NULL; | ||
3140 | LPWSTR sczLogPath = NULL; | ||
3141 | BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; | ||
3142 | |||
3143 | // Deserialize message data. | ||
3144 | hr = BuffReadString(pbData, cbData, &iData, &sczId); | ||
3145 | ExitOnFailure(hr, "Failed to read rollback boundary id."); | ||
3146 | |||
3147 | hr = BuffReadString(pbData, cbData, &iData, &sczLogPath); | ||
3148 | ExitOnFailure(hr, "Failed to read transaction log path."); | ||
3149 | |||
3150 | hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary); | ||
3151 | ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId); | ||
3152 | |||
3153 | pRollbackBoundary->sczLogPath = sczLogPath; | ||
3154 | |||
3155 | hr = MsiEngineRollbackTransaction(pRollbackBoundary); | ||
3156 | |||
3157 | LExit: | ||
3158 | ReleaseStr(sczId); | ||
3159 | ReleaseStr(sczLogPath); | ||
3160 | |||
3161 | if (pRollbackBoundary) | ||
3162 | { | ||
3163 | pRollbackBoundary->sczLogPath = NULL; | ||
3164 | } | ||
3165 | |||
3166 | return hr; | ||
3167 | } | ||
3168 | |||
3169 | static HRESULT ElevatedOnPauseAUBegin( | ||
3170 | __in HANDLE hPipe | ||
3171 | ) | ||
3172 | { | ||
3173 | HRESULT hr = S_OK; | ||
3174 | DWORD dwResult = 0; | ||
3175 | |||
3176 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, NULL, 0, NULL, NULL, &dwResult); | ||
3177 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN message to per-user process."); | ||
3178 | |||
3179 | LExit: | ||
3180 | return hr; | ||
3181 | } | ||
3182 | |||
3183 | static HRESULT ElevatedOnPauseAUComplete( | ||
3184 | __in HANDLE hPipe, | ||
3185 | __in HRESULT hrStatus | ||
3186 | ) | ||
3187 | { | ||
3188 | HRESULT hr = S_OK; | ||
3189 | BYTE* pbSendData = NULL; | ||
3190 | SIZE_T cbSendData = 0; | ||
3191 | DWORD dwResult = 0; | ||
3192 | |||
3193 | hr = BuffWriteNumber(&pbSendData, &cbSendData, hrStatus); | ||
3194 | ExitOnFailure(hr, "Failed to write the pause au status to message buffer."); | ||
3195 | |||
3196 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult); | ||
3197 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE message to per-user process."); | ||
3198 | |||
3199 | LExit: | ||
3200 | ReleaseBuffer(pbSendData); | ||
3201 | |||
3202 | return hr; | ||
3203 | } | ||
3204 | |||
3205 | static HRESULT ElevatedOnSystemRestorePointBegin( | ||
3206 | __in HANDLE hPipe | ||
3207 | ) | ||
3208 | { | ||
3209 | HRESULT hr = S_OK; | ||
3210 | DWORD dwResult = 0; | ||
3211 | |||
3212 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN, NULL, 0, NULL, NULL, &dwResult); | ||
3213 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN message to per-user process."); | ||
3214 | |||
3215 | LExit: | ||
3216 | return hr; | ||
3217 | } | ||
3218 | |||
3219 | static HRESULT ElevatedOnSystemRestorePointComplete( | ||
3220 | __in HANDLE hPipe, | ||
3221 | __in HRESULT hrStatus | ||
3222 | ) | ||
3223 | { | ||
3224 | HRESULT hr = S_OK; | ||
3225 | BYTE* pbSendData = NULL; | ||
3226 | SIZE_T cbSendData = 0; | ||
3227 | DWORD dwResult = 0; | ||
3228 | |||
3229 | hr = BuffWriteNumber(&pbSendData, &cbSendData, hrStatus); | ||
3230 | ExitOnFailure(hr, "Failed to write the system restore point status to message buffer."); | ||
3231 | |||
3232 | hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult); | ||
3233 | ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE message to per-user process."); | ||
3234 | |||
3235 | LExit: | ||
3236 | ReleaseBuffer(pbSendData); | ||
3237 | |||
3238 | return hr; | ||
3239 | } | ||