main
cpp 4,120 lines 141 KB
Raw
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_END,
15 BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE,
16 BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE,
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_RELATED_BUNDLE,
22 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE,
23 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE,
24 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE,
25 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE,
26 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE,
27 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER,
28 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY,
29 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_EMBEDDED_CHILD,
30 BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE,
31 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE,
32 BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION,
33 BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION,
34 BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION,
35 BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE,
36 BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE,
37
38 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN,
39 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE,
40 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN,
41 BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE,
42 BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN,
43 BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE,
44 BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS,
45 BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE,
46 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS,
47 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL,
48 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED,
49 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_COMPLETED,
50 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR,
51 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE,
52 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE,
53 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE,
54 BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID,
55 BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE,
56 BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE,
57 } BURN_ELEVATION_MESSAGE_TYPE;
58
59
60 // struct
61
62 typedef struct _BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT
63 {
64 BURN_USER_EXPERIENCE* pBA;
65 BOOL fPauseCompleteNeeded;
66 BOOL fSrpCompleteNeeded;
67 } BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT;
68
69 typedef struct _BURN_ELEVATION_CACHE_MESSAGE_CONTEXT
70 {
71 PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler;
72 LPPROGRESS_ROUTINE pfnProgress;
73 LPVOID pvContext;
74 } BURN_ELEVATION_CACHE_MESSAGE_CONTEXT;
75
76 typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT
77 {
78 PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler;
79 LPVOID pvContext;
80 BOOTSTRAPPER_APPLY_RESTART restart;
81 } BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT;
82
83 typedef struct _BURN_ELEVATION_MSI_MESSAGE_CONTEXT
84 {
85 PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler;
86 LPVOID pvContext;
87 BOOTSTRAPPER_APPLY_RESTART restart;
88 } BURN_ELEVATION_MSI_MESSAGE_CONTEXT;
89
90 typedef struct _BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT
91 {
92 DWORD dwProcessId;
93 } BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT;
94
95 typedef struct _BURN_ELEVATION_CHILD_MESSAGE_CONTEXT
96 {
97 HANDLE hPipe;
98 HANDLE* phLock;
99 BOOL* pfDisabledAutomaticUpdates;
100 BOOL* pfApplying;
101 BURN_APPROVED_EXES* pApprovedExes;
102 BURN_CACHE* pCache;
103 BURN_CONTAINERS* pContainers;
104 BURN_PACKAGES* pPackages;
105 BURN_PAYLOADS* pPayloads;
106 BURN_VARIABLES* pVariables;
107 BURN_REGISTRATION* pRegistration;
108 BURN_USER_EXPERIENCE* pUserExperience;
109 } BURN_ELEVATION_CHILD_MESSAGE_CONTEXT;
110
111
112 // internal function declarations
113
114 /*******************************************************************
115 LaunchElevatedProcess - Called from the per-user process to create
116 the per-machine process and set up the
117 communication pipe.
118
119 *******************************************************************/
120 static HRESULT LaunchElevatedProcess(
121 __in BURN_ENGINE_STATE* pEngineState,
122 __in_opt HWND hwndParent
123 );
124 static DWORD WINAPI ElevatedChildCacheThreadProc(
125 __in LPVOID lpThreadParameter
126 );
127 static HRESULT WaitForElevatedChildCacheThread(
128 __in HANDLE hCacheThread,
129 __in DWORD dwExpectedExitCode
130 );
131 static HRESULT ProcessApplyInitializeMessages(
132 __in PIPE_MESSAGE* pMsg,
133 __in_opt LPVOID pvContext,
134 __out DWORD* pdwResult
135 );
136 static HRESULT ProcessBurnCacheMessages(
137 __in PIPE_MESSAGE* pMsg,
138 __in LPVOID pvContext,
139 __out DWORD* pdwResult
140 );
141 static HRESULT ProcessGenericExecuteMessages(
142 __in PIPE_MESSAGE* pMsg,
143 __in LPVOID pvContext,
144 __out DWORD* pdwResult
145 );
146 static HRESULT ProcessMsiPackageMessages(
147 __in PIPE_MESSAGE* pMsg,
148 __in_opt LPVOID pvContext,
149 __out DWORD* pdwResult
150 );
151 static HRESULT ProcessLaunchApprovedExeMessages(
152 __in PIPE_MESSAGE* pMsg,
153 __in_opt LPVOID pvContext,
154 __out DWORD* pdwResult
155 );
156 static HRESULT ProcessProgressRoutineMessage(
157 __in PIPE_MESSAGE* pMsg,
158 __in LPPROGRESS_ROUTINE pfnProgress,
159 __in LPVOID pvContext,
160 __out DWORD* pdwResult
161 );
162 static HRESULT ProcessElevatedChildMessage(
163 __in PIPE_MESSAGE* pMsg,
164 __in_opt LPVOID pvContext,
165 __out DWORD* pdwResult
166 );
167 static HRESULT ProcessElevatedChildCacheMessage(
168 __in PIPE_MESSAGE* pMsg,
169 __in_opt LPVOID pvContext,
170 __out DWORD* pdwResult
171 );
172 static HRESULT ProcessExecuteActionCompleteMessage(
173 __in BYTE* pbData,
174 __in DWORD cbData,
175 __out BOOTSTRAPPER_APPLY_RESTART* pRestart,
176 __out DWORD* pdwResult
177 );
178 static HRESULT OnApplyInitialize(
179 __in HANDLE hPipe,
180 __in BURN_VARIABLES* pVariables,
181 __in BURN_REGISTRATION* pRegistration,
182 __in BURN_PACKAGES* pPackages,
183 __in HANDLE* phLock,
184 __in BOOL* pfDisabledWindowsUpdate,
185 __in BOOL* pfApplying,
186 __in BYTE* pbData,
187 __in SIZE_T cbData
188 );
189 static HRESULT ElevatedProcessDetect(
190 __in BURN_REGISTRATION* pRegistration,
191 __in BURN_VARIABLES* pVariables,
192 __in BURN_PACKAGES* pPackages
193 );
194 static HRESULT OnApplyUninitialize(
195 __in HANDLE* phLock,
196 __in BOOL* pfApplying,
197 __in BOOL* pfDisabledAutomaticUpdates
198 );
199 static HRESULT OnSessionBegin(
200 __in BURN_CACHE* pCache,
201 __in BURN_REGISTRATION* pRegistration,
202 __in BURN_VARIABLES* pVariables,
203 __in BYTE* pbData,
204 __in SIZE_T cbData
205 );
206 static HRESULT OnSessionEnd(
207 __in BURN_CACHE* pCache,
208 __in BURN_PACKAGES* pPackages,
209 __in BURN_REGISTRATION* pRegistration,
210 __in BURN_VARIABLES* pVariables,
211 __in BYTE* pbData,
212 __in SIZE_T cbData
213 );
214 static HRESULT OnSaveState(
215 __in BURN_REGISTRATION* pRegistration,
216 __in BYTE* pbData,
217 __in SIZE_T cbData
218 );
219 static HRESULT OnCachePreparePackage(
220 __in BURN_CACHE* pCache,
221 __in BURN_PACKAGES* pPackages,
222 __in BYTE* pbData,
223 __in SIZE_T cbData
224 );
225 static HRESULT OnCacheCompletePayload(
226 __in HANDLE hPipe,
227 __in BURN_CACHE* pCache,
228 __in BURN_PACKAGES* pPackages,
229 __in BURN_PAYLOADS* pPayloads,
230 __in BYTE* pbData,
231 __in SIZE_T cbData
232 );
233 static HRESULT OnCacheVerifyPayload(
234 __in HANDLE hPipe,
235 __in BURN_PACKAGES* pPackages,
236 __in BURN_PAYLOADS* pPayloads,
237 __in BYTE* pbData,
238 __in SIZE_T cbData
239 );
240 static void OnCacheCleanup(
241 __in BURN_CACHE* pCache
242 );
243 static HRESULT OnProcessDependentRegistration(
244 __in const BURN_REGISTRATION* pRegistration,
245 __in BYTE* pbData,
246 __in SIZE_T cbData
247 );
248 static HRESULT OnExecuteRelatedBundle(
249 __in HANDLE hPipe,
250 __in BURN_CACHE* pCache,
251 __in BURN_RELATED_BUNDLES* pRelatedBundles,
252 __in BURN_VARIABLES* pVariables,
253 __in BYTE* pbData,
254 __in SIZE_T cbData,
255 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
256 );
257 static HRESULT OnExecuteBundlePackage(
258 __in HANDLE hPipe,
259 __in BURN_CACHE* pCache,
260 __in BURN_PACKAGES* pPackages,
261 __in BURN_VARIABLES* pVariables,
262 __in BYTE* pbData,
263 __in SIZE_T cbData,
264 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
265 );
266 static HRESULT OnExecuteExePackage(
267 __in HANDLE hPipe,
268 __in BURN_CACHE* pCache,
269 __in BURN_PACKAGES* pPackages,
270 __in BURN_VARIABLES* pVariables,
271 __in BYTE* pbData,
272 __in SIZE_T cbData,
273 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
274 );
275 static HRESULT OnExecuteMsiPackage(
276 __in HANDLE hPipe,
277 __in BURN_CACHE* pCache,
278 __in BURN_PACKAGES* pPackages,
279 __in BURN_VARIABLES* pVariables,
280 __in BYTE* pbData,
281 __in SIZE_T cbData,
282 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
283 );
284 static HRESULT OnExecuteMspPackage(
285 __in HANDLE hPipe,
286 __in BURN_CACHE* pCache,
287 __in BURN_PACKAGES* pPackages,
288 __in BURN_VARIABLES* pVariables,
289 __in BYTE* pbData,
290 __in SIZE_T cbData,
291 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
292 );
293 static HRESULT OnExecuteMsuPackage(
294 __in HANDLE hPipe,
295 __in BURN_CACHE* pCache,
296 __in BURN_PACKAGES* pPackages,
297 __in BURN_VARIABLES* pVariables,
298 __in BYTE* pbData,
299 __in SIZE_T cbData,
300 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
301 );
302 static HRESULT OnUninstallMsiCompatiblePackage(
303 __in HANDLE hPipe,
304 __in BURN_CACHE* pCache,
305 __in BURN_PACKAGES* pPackages,
306 __in BURN_VARIABLES* pVariables,
307 __in BYTE* pbData,
308 __in SIZE_T cbData,
309 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
310 );
311 static HRESULT OnExecutePackageProviderAction(
312 __in BURN_PACKAGES* pPackages,
313 __in BURN_RELATED_BUNDLES* pRelatedBundles,
314 __in BYTE* pbData,
315 __in SIZE_T cbData
316 );
317 static HRESULT OnExecutePackageDependencyAction(
318 __in BURN_PACKAGES* pPackages,
319 __in BURN_RELATED_BUNDLES* pRelatedBundles,
320 __in BYTE* pbData,
321 __in SIZE_T cbData
322 );
323 static HRESULT CALLBACK BurnCacheMessageHandler(
324 __in BURN_CACHE_MESSAGE* pMessage,
325 __in LPVOID pvContext
326 );
327 static DWORD CALLBACK ElevatedProgressRoutine(
328 __in LARGE_INTEGER TotalFileSize,
329 __in LARGE_INTEGER TotalBytesTransferred,
330 __in LARGE_INTEGER StreamSize,
331 __in LARGE_INTEGER StreamBytesTransferred,
332 __in DWORD dwStreamNumber,
333 __in DWORD dwCallbackReason,
334 __in HANDLE hSourceFile,
335 __in HANDLE hDestinationFile,
336 __in_opt LPVOID lpData
337 );
338 static int GenericExecuteMessageHandler(
339 __in GENERIC_EXECUTE_MESSAGE* pMessage,
340 __in LPVOID pvContext
341 );
342 static int MsiExecuteMessageHandler(
343 __in WIU_MSI_EXECUTE_MESSAGE* pMessage,
344 __in_opt LPVOID pvContext
345 );
346 static HRESULT OnCleanCompatiblePackage(
347 __in BURN_CACHE* pCache,
348 __in BURN_PACKAGES* pPackages,
349 __in BYTE* pbData,
350 __in SIZE_T cbData
351 );
352 static HRESULT OnCleanPackage(
353 __in BURN_CACHE* pCache,
354 __in BURN_PACKAGES* pPackages,
355 __in BYTE* pbData,
356 __in SIZE_T cbData
357 );
358 static HRESULT OnLaunchApprovedExe(
359 __in HANDLE hPipe,
360 __in BURN_APPROVED_EXES* pApprovedExes,
361 __in BURN_CACHE* pCache,
362 __in BURN_VARIABLES* pVariables,
363 __in BYTE* pbData,
364 __in SIZE_T cbData
365 );
366 static HRESULT OnMsiBeginTransaction(
367 __in BURN_PACKAGES* pPackages,
368 __in BYTE* pbData,
369 __in SIZE_T cbData
370 );
371 static HRESULT OnMsiCommitTransaction(
372 __in BURN_PACKAGES* pPackages,
373 __in BYTE* pbData,
374 __in SIZE_T cbData,
375 __out BOOTSTRAPPER_APPLY_RESTART *pRestart
376 );
377 static HRESULT OnMsiRollbackTransaction(
378 __in BURN_PACKAGES* pPackages,
379 __in BYTE* pbData,
380 __in SIZE_T cbData,
381 __out BOOTSTRAPPER_APPLY_RESTART *pRestart
382 );
383 static HRESULT ElevatedOnPauseAUBegin(
384 __in HANDLE hPipe
385 );
386 static HRESULT ElevatedOnPauseAUComplete(
387 __in HANDLE hPipe,
388 __in HRESULT hrStatus
389 );
390 static HRESULT ElevatedOnSystemRestorePointBegin(
391 __in HANDLE hPipe
392 );
393 static HRESULT ElevatedOnSystemRestorePointComplete(
394 __in HANDLE hPipe,
395 __in HRESULT hrStatus
396 );
397 static HRESULT ElevatedOnExecuteActionComplete(
398 __in HANDLE hPipe,
399 __in BOOTSTRAPPER_APPLY_RESTART restart
400 );
401
402
403 // function definitions
404
405 extern "C" HRESULT ElevationElevate(
406 __in BURN_ENGINE_STATE* pEngineState,
407 __in WM_BURN reason,
408 __in_opt HWND hwndParent
409 )
410 {
411 Assert(BURN_MODE_ELEVATED != pEngineState->internalCommand.mode);
412 Assert(!pEngineState->companionConnection.sczName);
413 Assert(!pEngineState->companionConnection.sczSecret);
414 Assert(!pEngineState->companionConnection.hProcess);
415 Assert(!pEngineState->companionConnection.dwProcessId);
416 Assert(INVALID_HANDLE_VALUE == pEngineState->companionConnection.hPipe);
417 Assert(INVALID_HANDLE_VALUE == pEngineState->companionConnection.hCachePipe);
418 Assert(INVALID_HANDLE_VALUE == pEngineState->companionConnection.hLoggingPipe);
419
420 HRESULT hr = S_OK;
421 int nResult = IDOK;
422
423 hr = BACallbackOnElevateBegin(&pEngineState->userExperience);
424 ExitOnRootFailure(hr, "BA aborted elevation requirement.");
425
426 hr = BurnPipeCreateNameAndSecret(&pEngineState->companionConnection.sczName, &pEngineState->companionConnection.sczSecret);
427 ExitOnFailure(hr, "Failed to create pipe name and client token.");
428
429 hr = BurnPipeCreatePipes(&pEngineState->companionConnection, TRUE);
430 ExitOnFailure(hr, "Failed to create pipe and cache pipe.");
431
432 LogId(REPORT_STANDARD, MSG_LAUNCH_ELEVATED_ENGINE_STARTING);
433
434 do
435 {
436 nResult = IDOK;
437
438 // Create the elevated process and if successful, wait for it to connect.
439 hr = LaunchElevatedProcess(pEngineState, hwndParent);
440 if (SUCCEEDED(hr))
441 {
442 LogId(REPORT_STANDARD, MSG_LAUNCH_ELEVATED_ENGINE_SUCCESS);
443
444 hr = BurnPipeWaitForChildConnect(&pEngineState->companionConnection);
445 if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
446 {
447 hr = E_SUSPECTED_AV_INTERFERENCE;
448 }
449 ExitOnFailure(hr, "Failed to connect to elevated child process.");
450
451 LogId(REPORT_STANDARD, MSG_CONNECT_TO_ELEVATED_ENGINE_SUCCESS);
452 }
453 else if (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr)
454 {
455 // The user clicked "Cancel" on the elevation prompt or the elevation prompt timed out, provide the notification with the option to retry.
456 if (WM_BURN_APPLY == reason)
457 {
458 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
459 }
460
461 nResult = BootstrapperApplicationSendError(&pEngineState->userExperience, BOOTSTRAPPER_ERROR_TYPE_ELEVATE, NULL, hr, NULL, MB_ICONERROR | MB_RETRYCANCEL, IDNOACTION);
462 }
463 } while (IDRETRY == nResult);
464 ExitOnFailure(hr, "Failed to elevate.");
465
466 LExit:
467 if (FAILED(hr))
468 {
469 BurnPipeConnectionUninitialize(&pEngineState->companionConnection);
470 }
471
472 BACallbackOnElevateComplete(&pEngineState->userExperience, hr);
473
474 return hr;
475 }
476
477 extern "C" HRESULT ElevationApplyInitialize(
478 __in HANDLE hPipe,
479 __in BURN_USER_EXPERIENCE* pBA,
480 __in BURN_VARIABLES* pVariables,
481 __in BURN_PLAN* pPlan
482 )
483 {
484 HRESULT hr = S_OK;
485 BYTE* pbData = NULL;
486 SIZE_T cbData = 0;
487 DWORD dwResult = 0;
488 BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT context = { };
489
490 context.pBA = pBA;
491
492 // serialize message data
493 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pPlan->action);
494 ExitOnFailure(hr, "Failed to write action to message buffer.");
495
496 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pPlan->pInternalCommand->automaticUpdates);
497 ExitOnFailure(hr, "Failed to write update action to message buffer.");
498
499 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)!pPlan->pInternalCommand->fDisableSystemRestore);
500 ExitOnFailure(hr, "Failed to write system restore point action to message buffer.");
501
502 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
503 ExitOnFailure(hr, "Failed to write variables.");
504
505 // send message
506 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE, pbData, cbData, ProcessApplyInitializeMessages, &context, &dwResult);
507 ExitOnFailure(hr, "Failed to send message to per-machine process.");
508
509 hr = (HRESULT)dwResult;
510
511 // Best effort to keep the sequence of BA events sane.
512 if (context.fPauseCompleteNeeded)
513 {
514 BACallbackOnPauseAUComplete(pBA, hr);
515 }
516 if (context.fSrpCompleteNeeded)
517 {
518 BACallbackOnSystemRestorePointComplete(pBA, hr);
519 }
520
521 LExit:
522 ReleaseMem(pbData);
523
524 return hr;
525 }
526
527 extern "C" HRESULT ElevationApplyUninitialize(
528 __in HANDLE hPipe
529 )
530 {
531 HRESULT hr = S_OK;
532 BYTE* pbData = NULL;
533 SIZE_T cbData = 0;
534 DWORD dwResult = 0;
535
536 // send message
537 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE, pbData, cbData, NULL, NULL, &dwResult);
538 ExitOnFailure(hr, "Failed to send message to per-machine process.");
539
540 hr = (HRESULT)dwResult;
541
542 LExit:
543 ReleaseMem(pbData);
544
545 return hr;
546 }
547
548 /*******************************************************************
549 ElevationSessionBegin -
550
551 *******************************************************************/
552 extern "C" HRESULT ElevationSessionBegin(
553 __in HANDLE hPipe,
554 __in_z LPCWSTR wzEngineWorkingPath,
555 __in_z LPCWSTR wzResumeCommandLine,
556 __in BOOL fDisableResume,
557 __in BURN_VARIABLES* pVariables,
558 __in DWORD dwRegistrationOperations,
559 __in BOOL fDetectedForeignProviderKeyBundleId,
560 __in DWORD64 qwEstimatedSize,
561 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
562 )
563 {
564 HRESULT hr = S_OK;
565 BYTE* pbData = NULL;
566 SIZE_T cbData = 0;
567 DWORD dwResult = 0;
568
569 // serialize message data
570 hr = BuffWriteString(&pbData, &cbData, wzEngineWorkingPath);
571 ExitOnFailure(hr, "Failed to write engine working path to message buffer.");
572
573 hr = BuffWriteString(&pbData, &cbData, wzResumeCommandLine);
574 ExitOnFailure(hr, "Failed to write resume command line to message buffer.");
575
576 hr = BuffWriteNumber(&pbData, &cbData, fDisableResume);
577 ExitOnFailure(hr, "Failed to write resume flag.");
578
579 hr = BuffWriteNumber(&pbData, &cbData, dwRegistrationOperations);
580 ExitOnFailure(hr, "Failed to write registration operations to message buffer.");
581
582 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fDetectedForeignProviderKeyBundleId);
583 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer.");
584
585 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize);
586 ExitOnFailure(hr, "Failed to write estimated size to message buffer.");
587
588 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
589 ExitOnFailure(hr, "Failed to write registration type to message buffer.");
590
591 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
592 ExitOnFailure(hr, "Failed to write variables.");
593
594 // send message
595 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN, pbData, cbData, NULL, NULL, &dwResult);
596 ExitOnFailure(hr, "Failed to send message to per-machine process.");
597
598 hr = (HRESULT)dwResult;
599
600 LExit:
601 ReleaseMem(pbData);
602
603 return hr;
604 }
605
606 /*******************************************************************
607 ElevationSessionEnd -
608
609 *******************************************************************/
610 extern "C" HRESULT ElevationSessionEnd(
611 __in HANDLE hPipe,
612 __in BURN_RESUME_MODE resumeMode,
613 __in BOOTSTRAPPER_APPLY_RESTART restart,
614 __in BOOL fDetectedForeignProviderKeyBundleId,
615 __in DWORD64 qwEstimatedSize,
616 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
617 )
618 {
619 HRESULT hr = S_OK;
620 BYTE* pbData = NULL;
621 SIZE_T cbData = 0;
622 DWORD dwResult = 0;
623
624 // serialize message data
625 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)resumeMode);
626 ExitOnFailure(hr, "Failed to write resume mode to message buffer.");
627
628 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)restart);
629 ExitOnFailure(hr, "Failed to write restart enum to message buffer.");
630
631 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fDetectedForeignProviderKeyBundleId);
632 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer.");
633
634 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize);
635 ExitOnFailure(hr, "Failed to write estimated size to message buffer.");
636
637 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
638 ExitOnFailure(hr, "Failed to write registration type to message buffer.");
639
640 // send message
641 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, pbData, cbData, NULL, NULL, &dwResult);
642 ExitOnFailure(hr, "Failed to send message to per-machine process.");
643
644 hr = (HRESULT)dwResult;
645
646 LExit:
647 ReleaseMem(pbData);
648
649 return hr;
650 }
651
652 /*******************************************************************
653 ElevationSaveState -
654
655 *******************************************************************/
656 HRESULT ElevationSaveState(
657 __in HANDLE hPipe,
658 __in_bcount(cbBuffer) BYTE* pbBuffer,
659 __in SIZE_T cbBuffer
660 )
661 {
662 HRESULT hr = S_OK;
663 DWORD dwResult = 0;
664
665 // send message
666 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE, pbBuffer, cbBuffer, NULL, NULL, &dwResult);
667 ExitOnFailure(hr, "Failed to send message to per-machine process.");
668
669 hr = (HRESULT)dwResult;
670
671 LExit:
672 return hr;
673 }
674
675 extern "C" HRESULT ElevationCachePreparePackage(
676 __in HANDLE hPipe,
677 __in BURN_PACKAGE* pPackage
678 )
679 {
680 HRESULT hr = S_OK;
681 BYTE* pbData = NULL;
682 SIZE_T cbData = 0;
683 DWORD dwResult = 0;
684
685 // Serialize message data.
686 hr = BuffWriteString(&pbData, &cbData, pPackage ? pPackage->sczId : NULL);
687 ExitOnFailure(hr, "Failed to write package id to message buffer.");
688
689 // Send message.
690 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE, pbData, cbData, NULL, NULL, &dwResult);
691 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE message to per-machine process.");
692
693 hr = (HRESULT)dwResult;
694
695 LExit:
696 ReleaseMem(pbData);
697
698 return hr;
699 }
700
701 /*******************************************************************
702 ElevationCacheCompletePayload -
703
704 *******************************************************************/
705 extern "C" HRESULT ElevationCacheCompletePayload(
706 __in HANDLE hPipe,
707 __in BURN_PACKAGE* pPackage,
708 __in BURN_PAYLOAD* pPayload,
709 __in_z LPCWSTR wzUnverifiedPath,
710 __in BOOL fMove,
711 __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
712 __in LPPROGRESS_ROUTINE pfnProgress,
713 __in LPVOID pContext
714 )
715 {
716 HRESULT hr = S_OK;
717 BYTE* pbData = NULL;
718 SIZE_T cbData = 0;
719 DWORD dwResult = 0;
720 BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { };
721
722 context.pfnCacheMessageHandler = pfnCacheMessageHandler;
723 context.pfnProgress = pfnProgress;
724 context.pvContext = pContext;
725
726 // serialize message data
727 hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
728 ExitOnFailure(hr, "Failed to write package id to message buffer.");
729
730 hr = BuffWriteString(&pbData, &cbData, pPayload->sczKey);
731 ExitOnFailure(hr, "Failed to write payload id to message buffer.");
732
733 hr = BuffWriteString(&pbData, &cbData, wzUnverifiedPath);
734 ExitOnFailure(hr, "Failed to write unverified path to message buffer.");
735
736 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fMove);
737 ExitOnFailure(hr, "Failed to write move flag to message buffer.");
738
739 // send message
740 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult);
741 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD message to per-machine process.");
742
743 hr = (HRESULT)dwResult;
744
745 LExit:
746 ReleaseMem(pbData);
747
748 return hr;
749 }
750
751 extern "C" HRESULT ElevationCacheVerifyPayload(
752 __in HANDLE hPipe,
753 __in BURN_PACKAGE* pPackage,
754 __in BURN_PAYLOAD* pPayload,
755 __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler,
756 __in LPPROGRESS_ROUTINE pfnProgress,
757 __in LPVOID pContext
758 )
759 {
760 HRESULT hr = S_OK;
761 BYTE* pbData = NULL;
762 SIZE_T cbData = 0;
763 DWORD dwResult = 0;
764 BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { };
765
766 context.pfnCacheMessageHandler = pfnCacheMessageHandler;
767 context.pfnProgress = pfnProgress;
768 context.pvContext = pContext;
769
770 // serialize message data
771 hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
772 ExitOnFailure(hr, "Failed to write package id to message buffer.");
773
774 hr = BuffWriteString(&pbData, &cbData, pPayload->sczKey);
775 ExitOnFailure(hr, "Failed to write payload id to message buffer.");
776
777 // send message
778 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult);
779 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD message to per-machine process.");
780
781 hr = (HRESULT)dwResult;
782
783 LExit:
784 ReleaseMem(pbData);
785
786 return hr;
787 }
788
789 /*******************************************************************
790 ElevationCacheCleanup -
791
792 *******************************************************************/
793 extern "C" HRESULT ElevationCacheCleanup(
794 __in HANDLE hPipe
795 )
796 {
797 HRESULT hr = S_OK;
798 DWORD dwResult = 0;
799
800 // send message
801 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP, NULL, 0, NULL, NULL, &dwResult);
802 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP message to per-machine process.");
803
804 hr = (HRESULT)dwResult;
805
806 LExit:
807 return hr;
808 }
809
810 extern "C" HRESULT ElevationProcessDependentRegistration(
811 __in HANDLE hPipe,
812 __in const BURN_DEPENDENT_REGISTRATION_ACTION* pAction
813 )
814 {
815 HRESULT hr = S_OK;
816 BYTE* pbData = NULL;
817 SIZE_T cbData = 0;
818 DWORD dwResult = 0;
819
820 // serialize message data
821 hr = BuffWriteNumber(&pbData, &cbData, pAction->type);
822 ExitOnFailure(hr, "Failed to write action type to message buffer.");
823
824 hr = BuffWriteString(&pbData, &cbData, pAction->sczBundleId);
825 ExitOnFailure(hr, "Failed to write bundle id to message buffer.");
826
827 hr = BuffWriteString(&pbData, &cbData, pAction->sczDependentProviderKey);
828 ExitOnFailure(hr, "Failed to write dependent provider key to message buffer.");
829
830 // send message
831 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION, pbData, cbData, NULL, NULL, &dwResult);
832 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION message to per-machine process.");
833
834 hr = (HRESULT)dwResult;
835
836 LExit:
837 ReleaseMem(pbData);
838
839 return hr;
840 }
841
842 /*******************************************************************
843 ElevationExecuteRelatedBundle -
844
845 *******************************************************************/
846 extern "C" HRESULT ElevationExecuteRelatedBundle(
847 __in HANDLE hPipe,
848 __in BURN_EXECUTE_ACTION* pExecuteAction,
849 __in BURN_VARIABLES* pVariables,
850 __in BOOL fRollback,
851 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
852 __in LPVOID pvContext,
853 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
854 )
855 {
856 HRESULT hr = S_OK;
857 BYTE* pbData = NULL;
858 SIZE_T cbData = 0;
859 BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { };
860 DWORD dwResult = 0;
861
862 // serialize message data
863 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.pRelatedBundle->package.sczId);
864 ExitOnFailure(hr, "Failed to write package id to message buffer.");
865
866 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->relatedBundle.action);
867 ExitOnFailure(hr, "Failed to write action to message buffer.");
868
869 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->relatedBundle.pRelatedBundle->planRelationType);
870 ExitOnFailure(hr, "Failed to write planRelationType to message buffer.");
871
872 hr = BuffWriteNumber(&pbData, &cbData, fRollback);
873 ExitOnFailure(hr, "Failed to write rollback.");
874
875 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.sczIgnoreDependencies);
876 ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer.");
877
878 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.sczAncestors);
879 ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer.");
880
881 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->relatedBundle.sczEngineWorkingDirectory);
882 ExitOnFailure(hr, "Failed to write the custom working directory to the message buffer.");
883
884 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
885 ExitOnFailure(hr, "Failed to write variables.");
886
887 // send message
888 context.pfnGenericMessageHandler = pfnGenericMessageHandler;
889 context.pvContext = pvContext;
890
891 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
892 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE message to per-machine process.");
893
894 hr = static_cast<HRESULT>(dwResult);
895 *pRestart = context.restart;
896
897 LExit:
898 ReleaseMem(pbData);
899
900 return hr;
901 }
902
903 /*******************************************************************
904 ElevationExecuteBundlePackage -
905
906 *******************************************************************/
907 extern "C" HRESULT ElevationExecuteBundlePackage(
908 __in HANDLE hPipe,
909 __in BURN_EXECUTE_ACTION* pExecuteAction,
910 __in BURN_VARIABLES* pVariables,
911 __in BOOL fRollback,
912 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
913 __in LPVOID pvContext,
914 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
915 )
916 {
917 HRESULT hr = S_OK;
918 BYTE* pbData = NULL;
919 SIZE_T cbData = 0;
920 BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { };
921 DWORD dwResult = 0;
922
923 // serialize message data
924 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.pPackage->sczId);
925 ExitOnFailure(hr, "Failed to write package id to message buffer.");
926
927 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->bundlePackage.action);
928 ExitOnFailure(hr, "Failed to write action to message buffer.");
929
930 hr = BuffWriteNumber(&pbData, &cbData, fRollback);
931 ExitOnFailure(hr, "Failed to write rollback.");
932
933 hr = BuffWriteNumber(&pbData, &cbData, SUCCEEDED(pExecuteAction->bundlePackage.pPackage->hrCacheResult));
934 ExitOnFailure(hr, "Failed to write fCacheAvailable.");
935
936 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.sczParent);
937 ExitOnFailure(hr, "Failed to write the parent to the message buffer.");
938
939 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.sczIgnoreDependencies);
940 ExitOnFailure(hr, "Failed to write the list of dependencies to ignore to the message buffer.");
941
942 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.sczAncestors);
943 ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer.");
944
945 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->bundlePackage.sczEngineWorkingDirectory);
946 ExitOnFailure(hr, "Failed to write the custom working directory to the message buffer.");
947
948 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
949 ExitOnFailure(hr, "Failed to write variables.");
950
951 // send message
952 context.pfnGenericMessageHandler = pfnGenericMessageHandler;
953 context.pvContext = pvContext;
954
955 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
956 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE message to per-machine process.");
957
958 hr = static_cast<HRESULT>(dwResult);
959 *pRestart = context.restart;
960
961 LExit:
962 ReleaseMem(pbData);
963
964 return hr;
965 }
966
967 /*******************************************************************
968 ElevationExecuteExePackage -
969
970 *******************************************************************/
971 extern "C" HRESULT ElevationExecuteExePackage(
972 __in HANDLE hPipe,
973 __in BURN_EXECUTE_ACTION* pExecuteAction,
974 __in BURN_VARIABLES* pVariables,
975 __in BOOL fRollback,
976 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
977 __in LPVOID pvContext,
978 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
979 )
980 {
981 HRESULT hr = S_OK;
982 BYTE* pbData = NULL;
983 SIZE_T cbData = 0;
984 BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { };
985 DWORD dwResult = 0;
986
987 // serialize message data
988 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.pPackage->sczId);
989 ExitOnFailure(hr, "Failed to write package id to message buffer.");
990
991 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->exePackage.action);
992 ExitOnFailure(hr, "Failed to write action to message buffer.");
993
994 hr = BuffWriteNumber(&pbData, &cbData, fRollback);
995 ExitOnFailure(hr, "Failed to write rollback.");
996
997 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczAncestors);
998 ExitOnFailure(hr, "Failed to write the list of ancestors to the message buffer.");
999
1000 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->exePackage.sczEngineWorkingDirectory);
1001 ExitOnFailure(hr, "Failed to write the custom working directory to the message buffer.");
1002
1003 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
1004 ExitOnFailure(hr, "Failed to write variables.");
1005
1006 // send message
1007 context.pfnGenericMessageHandler = pfnGenericMessageHandler;
1008 context.pvContext = pvContext;
1009
1010 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
1011 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE message to per-machine process.");
1012
1013 hr = static_cast<HRESULT>(dwResult);
1014 *pRestart = context.restart;
1015
1016 LExit:
1017 ReleaseMem(pbData);
1018
1019 return hr;
1020 }
1021
1022 extern "C" HRESULT ElevationMsiBeginTransaction(
1023 __in HANDLE hPipe,
1024 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
1025 )
1026 {
1027 HRESULT hr = S_OK;
1028 BYTE* pbData = NULL;
1029 SIZE_T cbData = 0;
1030 DWORD dwResult = ERROR_SUCCESS;
1031
1032 // serialize message data
1033 hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczId);
1034 ExitOnFailure(hr, "Failed to write transaction name to message buffer.");
1035
1036 hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczLogPath);
1037 ExitOnFailure(hr, "Failed to write transaction log path to message buffer.");
1038
1039 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION, pbData, cbData, NULL, NULL, &dwResult);
1040 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION message to per-machine process.");
1041
1042 hr = static_cast<HRESULT>(dwResult);
1043
1044 LExit:
1045 ReleaseMem(pbData);
1046
1047 return hr;
1048 }
1049
1050 extern "C" HRESULT ElevationMsiCommitTransaction(
1051 __in HANDLE hPipe,
1052 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary,
1053 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
1054 __in LPVOID pvContext,
1055 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1056 )
1057 {
1058 HRESULT hr = S_OK;
1059 BYTE* pbData = NULL;
1060 SIZE_T cbData = 0;
1061 BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { };
1062 DWORD dwResult = ERROR_SUCCESS;
1063
1064 // serialize message data
1065 hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczId);
1066 ExitOnFailure(hr, "Failed to write transaction name to message buffer.");
1067
1068 hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczLogPath);
1069 ExitOnFailure(hr, "Failed to write transaction log path to message buffer.");
1070
1071 // send message
1072 context.pfnMessageHandler = pfnMessageHandler;
1073 context.pvContext = pvContext;
1074
1075 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1076 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION message to per-machine process.");
1077
1078 hr = static_cast<HRESULT>(dwResult);
1079 *pRestart = context.restart;
1080
1081 LExit:
1082 ReleaseMem(pbData);
1083
1084 return hr;
1085 }
1086
1087 extern "C" HRESULT ElevationMsiRollbackTransaction(
1088 __in HANDLE hPipe,
1089 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary,
1090 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
1091 __in LPVOID pvContext,
1092 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1093 )
1094 {
1095 HRESULT hr = S_OK;
1096 BYTE* pbData = NULL;
1097 SIZE_T cbData = 0;
1098 BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { };
1099 DWORD dwResult = ERROR_SUCCESS;
1100
1101 // serialize message data
1102 hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczId);
1103 ExitOnFailure(hr, "Failed to write transaction name to message buffer.");
1104
1105 hr = BuffWriteString(&pbData, &cbData, pRollbackBoundary->sczLogPath);
1106 ExitOnFailure(hr, "Failed to write transaction log path to message buffer.");
1107
1108 // send message
1109 context.pfnMessageHandler = pfnMessageHandler;
1110 context.pvContext = pvContext;
1111
1112 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1113 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION message to per-machine process.");
1114
1115 hr = static_cast<HRESULT>(dwResult);
1116 *pRestart = context.restart;
1117
1118 LExit:
1119 ReleaseMem(pbData);
1120
1121 return hr;
1122 }
1123
1124
1125
1126 /*******************************************************************
1127 ElevationExecuteMsiPackage -
1128
1129 *******************************************************************/
1130 extern "C" HRESULT ElevationExecuteMsiPackage(
1131 __in HANDLE hPipe,
1132 __in_opt HWND hwndParent,
1133 __in BURN_EXECUTE_ACTION* pExecuteAction,
1134 __in BURN_VARIABLES* pVariables,
1135 __in BOOL fRollback,
1136 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
1137 __in LPVOID pvContext,
1138 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1139 )
1140 {
1141 HRESULT hr = S_OK;
1142 BYTE* pbData = NULL;
1143 SIZE_T cbData = 0;
1144 BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { };
1145 DWORD dwResult = 0;
1146
1147 // serialize message data
1148 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
1149 ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
1150
1151 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msiPackage.pPackage->sczId);
1152 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1153
1154 hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent);
1155 ExitOnFailure(hr, "Failed to write parent hwnd to message buffer.");
1156
1157 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msiPackage.sczLogPath);
1158 ExitOnFailure(hr, "Failed to write package log to message buffer.");
1159
1160 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.actionMsiProperty);
1161 ExitOnFailure(hr, "Failed to write actionMsiProperty to message buffer.");
1162
1163 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.uiLevel);
1164 ExitOnFailure(hr, "Failed to write UI level to message buffer.");
1165
1166 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.fDisableExternalUiHandler);
1167 ExitOnFailure(hr, "Failed to write fDisableExternalUiHandler to message buffer.");
1168
1169 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.fileVersioning);
1170 ExitOnFailure(hr, "Failed to write fileVersioning to message buffer.");
1171
1172 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.action);
1173 ExitOnFailure(hr, "Failed to write action to message buffer.");
1174
1175 // Feature actions.
1176 for (DWORD i = 0; i < pExecuteAction->msiPackage.pPackage->Msi.cFeatures; ++i)
1177 {
1178 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.rgFeatures[i]);
1179 ExitOnFailure(hr, "Failed to write feature action to message buffer.");
1180 }
1181
1182 // Slipstream patches actions.
1183 for (DWORD i = 0; i < pExecuteAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++i)
1184 {
1185 BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pExecuteAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + i;
1186 BOOTSTRAPPER_ACTION_STATE* pAction = fRollback ? &pSlipstreamMsp->rollback : &pSlipstreamMsp->execute;
1187 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction);
1188 ExitOnFailure(hr, "Failed to write slipstream patch action to message buffer.");
1189 }
1190
1191 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
1192 ExitOnFailure(hr, "Failed to write variables.");
1193
1194
1195 // send message
1196 context.pfnMessageHandler = pfnMessageHandler;
1197 context.pvContext = pvContext;
1198
1199 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1200 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE message to per-machine process.");
1201
1202 hr = static_cast<HRESULT>(dwResult);
1203 *pRestart = context.restart;
1204
1205 LExit:
1206 ReleaseMem(pbData);
1207
1208 return hr;
1209 }
1210
1211 /*******************************************************************
1212 ElevationExecuteMspPackage -
1213
1214 *******************************************************************/
1215 extern "C" HRESULT ElevationExecuteMspPackage(
1216 __in HANDLE hPipe,
1217 __in_opt HWND hwndParent,
1218 __in BURN_EXECUTE_ACTION* pExecuteAction,
1219 __in BURN_VARIABLES* pVariables,
1220 __in BOOL fRollback,
1221 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
1222 __in LPVOID pvContext,
1223 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1224 )
1225 {
1226 HRESULT hr = S_OK;
1227 BYTE* pbData = NULL;
1228 SIZE_T cbData = 0;
1229 BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { };
1230 DWORD dwResult = 0;
1231
1232 // serialize message data
1233 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.pPackage->sczId);
1234 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1235
1236 hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent);
1237 ExitOnFailure(hr, "Failed to write parent hwnd to message buffer.");
1238
1239 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.sczTargetProductCode);
1240 ExitOnFailure(hr, "Failed to write target product code to message buffer.");
1241
1242 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.sczLogPath);
1243 ExitOnFailure(hr, "Failed to write package log to message buffer.");
1244
1245 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.actionMsiProperty);
1246 ExitOnFailure(hr, "Failed to write actionMsiProperty to message buffer.");
1247
1248 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.uiLevel);
1249 ExitOnFailure(hr, "Failed to write UI level to message buffer.");
1250
1251 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.fDisableExternalUiHandler);
1252 ExitOnFailure(hr, "Failed to write fDisableExternalUiHandler to message buffer.");
1253
1254 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.fileVersioning);
1255 ExitOnFailure(hr, "Failed to write fileVersioning to message buffer.");
1256
1257 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->mspTarget.action);
1258 ExitOnFailure(hr, "Failed to write action to message buffer.");
1259
1260 hr = BuffWriteNumber(&pbData, &cbData, pExecuteAction->mspTarget.cOrderedPatches);
1261 ExitOnFailure(hr, "Failed to write count of ordered patches to message buffer.");
1262
1263 for (DWORD i = 0; i < pExecuteAction->mspTarget.cOrderedPatches; ++i)
1264 {
1265 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage->sczId);
1266 ExitOnFailure(hr, "Failed to write ordered patch id to message buffer.");
1267 }
1268
1269 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
1270 ExitOnFailure(hr, "Failed to write variables.");
1271
1272 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
1273 ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
1274
1275 // send message
1276 context.pfnMessageHandler = pfnMessageHandler;
1277 context.pvContext = pvContext;
1278
1279 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1280 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE message to per-machine process.");
1281
1282 hr = static_cast<HRESULT>(dwResult);
1283 *pRestart = context.restart;
1284
1285 LExit:
1286 ReleaseMem(pbData);
1287
1288 return hr;
1289 }
1290
1291 /*******************************************************************
1292 ElevationExecuteMsuPackage -
1293
1294 *******************************************************************/
1295 extern "C" HRESULT ElevationExecuteMsuPackage(
1296 __in HANDLE hPipe,
1297 __in BURN_EXECUTE_ACTION* pExecuteAction,
1298 __in BOOL fRollback,
1299 __in BOOL fStopWusaService,
1300 __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
1301 __in LPVOID pvContext,
1302 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1303 )
1304 {
1305 HRESULT hr = S_OK;
1306 BYTE* pbData = NULL;
1307 SIZE_T cbData = 0;
1308 BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT context = { };
1309 DWORD dwResult = 0;
1310
1311 // serialize message data
1312 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msuPackage.pPackage->sczId);
1313 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1314
1315 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msuPackage.sczLogPath);
1316 ExitOnFailure(hr, "Failed to write package log to message buffer.");
1317
1318 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msuPackage.action);
1319 ExitOnFailure(hr, "Failed to write action to message buffer.");
1320
1321 hr = BuffWriteNumber(&pbData, &cbData, fRollback);
1322 ExitOnFailure(hr, "Failed to write rollback.");
1323
1324 hr = BuffWriteNumber(&pbData, &cbData, fStopWusaService);
1325 ExitOnFailure(hr, "Failed to write StopWusaService.");
1326
1327 // send message
1328 context.pfnGenericMessageHandler = pfnGenericMessageHandler;
1329 context.pvContext = pvContext;
1330
1331 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE, pbData, cbData, ProcessGenericExecuteMessages, &context, &dwResult);
1332 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE message to per-machine process.");
1333
1334 hr = static_cast<HRESULT>(dwResult);
1335 *pRestart = context.restart;
1336
1337 LExit:
1338 ReleaseMem(pbData);
1339
1340 return hr;
1341 }
1342
1343 extern "C" HRESULT ElevationUninstallMsiCompatiblePackage(
1344 __in HANDLE hPipe,
1345 __in_opt HWND hwndParent,
1346 __in BURN_EXECUTE_ACTION* pExecuteAction,
1347 __in BURN_VARIABLES* pVariables,
1348 __in BOOL fRollback,
1349 __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
1350 __in LPVOID pvContext,
1351 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
1352 )
1353 {
1354 HRESULT hr = S_OK;
1355 BYTE* pbData = NULL;
1356 SIZE_T cbData = 0;
1357 BURN_ELEVATION_MSI_MESSAGE_CONTEXT context = { };
1358 DWORD dwResult = 0;
1359
1360 // serialize message data
1361 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
1362 ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
1363
1364 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->sczId);
1365 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1366
1367 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.pParentPackage->compatiblePackage.compatibleEntry.sczId);
1368 ExitOnFailure(hr, "Failed to write compatible package id to message buffer.");
1369
1370 hr = BuffWritePointer(&pbData, &cbData, (DWORD_PTR)hwndParent);
1371 ExitOnFailure(hr, "Failed to write parent hwnd to message buffer.");
1372
1373 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->uninstallMsiCompatiblePackage.sczLogPath);
1374 ExitOnFailure(hr, "Failed to write package log to message buffer.");
1375
1376 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
1377 ExitOnFailure(hr, "Failed to write variables.");
1378
1379
1380 // send message
1381 context.pfnMessageHandler = pfnMessageHandler;
1382 context.pvContext = pvContext;
1383
1384 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE, pbData, cbData, ProcessMsiPackageMessages, &context, &dwResult);
1385 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE message to per-machine process.");
1386
1387 hr = static_cast<HRESULT>(dwResult);
1388 *pRestart = context.restart;
1389
1390 LExit:
1391 ReleaseMem(pbData);
1392
1393 return hr;
1394 }
1395
1396 extern "C" HRESULT ElevationExecutePackageProviderAction(
1397 __in HANDLE hPipe,
1398 __in BURN_EXECUTE_ACTION* pExecuteAction,
1399 __in BOOL fRollback
1400 )
1401 {
1402 HRESULT hr = S_OK;
1403 BYTE* pbData = NULL;
1404 SIZE_T cbData = 0;
1405 DWORD dwResult = 0;
1406
1407 // Serialize the message data.
1408 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageProvider.pPackage->sczId);
1409 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1410
1411 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
1412 ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
1413
1414 // Provider actions.
1415 for (DWORD i = 0; i < pExecuteAction->packageProvider.pPackage->cDependencyProviders; ++i)
1416 {
1417 BURN_DEPENDENCY_PROVIDER* pProvider = pExecuteAction->packageProvider.pPackage->rgDependencyProviders + i;
1418 BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->providerRollback : &pProvider->providerExecute;
1419 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction);
1420 ExitOnFailure(hr, "Failed to write provider action to message buffer.");
1421 }
1422
1423 // Send the message.
1424 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER, pbData, cbData, NULL, NULL, &dwResult);
1425 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER message to per-machine process.");
1426
1427 LExit:
1428 ReleaseMem(pbData);
1429
1430 return hr;
1431 }
1432
1433 extern "C" HRESULT ElevationExecutePackageDependencyAction(
1434 __in HANDLE hPipe,
1435 __in BURN_EXECUTE_ACTION* pExecuteAction,
1436 __in BOOL fRollback
1437 )
1438 {
1439 HRESULT hr = S_OK;
1440 BYTE* pbData = NULL;
1441 SIZE_T cbData = 0;
1442 DWORD dwResult = 0;
1443
1444 // Serialize the message data.
1445 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageDependency.pPackage->sczId);
1446 ExitOnFailure(hr, "Failed to write package id to message buffer.");
1447
1448 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
1449 ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
1450
1451 hr = BuffWriteString(&pbData, &cbData, pExecuteAction->packageDependency.sczBundleProviderKey);
1452 ExitOnFailure(hr, "Failed to write bundle dependency key to message buffer.");
1453
1454 // Dependent actions.
1455 for (DWORD i = 0; i < pExecuteAction->packageProvider.pPackage->cDependencyProviders; ++i)
1456 {
1457 BURN_DEPENDENCY_PROVIDER* pProvider = pExecuteAction->packageProvider.pPackage->rgDependencyProviders + i;
1458 BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->dependentRollback : &pProvider->dependentExecute;
1459 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction);
1460 ExitOnFailure(hr, "Failed to write dependent action to message buffer.");
1461 }
1462
1463 // Send the message.
1464 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY, pbData, cbData, NULL, NULL, &dwResult);
1465 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY message to per-machine process.");
1466
1467 LExit:
1468 ReleaseMem(pbData);
1469
1470 return hr;
1471 }
1472
1473 extern "C" HRESULT ElevationCleanCompatiblePackage(
1474 __in HANDLE hPipe,
1475 __in BURN_PACKAGE* pPackage
1476 )
1477 {
1478 HRESULT hr = S_OK;
1479 BYTE* pbData = NULL;
1480 SIZE_T cbData = 0;
1481 DWORD dwResult = 0;
1482
1483 // serialize message data
1484 hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
1485 ExitOnFailure(hr, "Failed to write clean package id to message buffer.");
1486
1487 hr = BuffWriteString(&pbData, &cbData, pPackage->compatiblePackage.compatibleEntry.sczId);
1488 ExitOnFailure(hr, "Failed to write compatible package id to message buffer.");
1489
1490 // send message
1491 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE, pbData, cbData, NULL, NULL, &dwResult);
1492 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE message to per-machine process.");
1493
1494 hr = (HRESULT)dwResult;
1495
1496 LExit:
1497 ReleaseMem(pbData);
1498
1499 return hr;
1500 }
1501
1502 /*******************************************************************
1503 ElevationCleanPackage -
1504
1505 *******************************************************************/
1506 extern "C" HRESULT ElevationCleanPackage(
1507 __in HANDLE hPipe,
1508 __in BURN_PACKAGE* pPackage
1509 )
1510 {
1511 HRESULT hr = S_OK;
1512 BYTE* pbData = NULL;
1513 SIZE_T cbData = 0;
1514 DWORD dwResult = 0;
1515
1516 // serialize message data
1517 hr = BuffWriteString(&pbData, &cbData, pPackage->sczId);
1518 ExitOnFailure(hr, "Failed to write clean package id to message buffer.");
1519
1520 // send message
1521 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE, pbData, cbData, NULL, NULL, &dwResult);
1522 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE message to per-machine process.");
1523
1524 hr = (HRESULT)dwResult;
1525
1526 LExit:
1527 ReleaseMem(pbData);
1528
1529 return hr;
1530 }
1531
1532 extern "C" HRESULT ElevationLaunchApprovedExe(
1533 __in HANDLE hPipe,
1534 __in BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe,
1535 __out DWORD* pdwProcessId
1536 )
1537 {
1538 HRESULT hr = S_OK;
1539 BYTE* pbData = NULL;
1540 SIZE_T cbData = 0;
1541 DWORD dwResult = 0;
1542 BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT context = { };
1543
1544 // Serialize message data.
1545 hr = BuffWriteString(&pbData, &cbData, pLaunchApprovedExe->sczId);
1546 ExitOnFailure(hr, "Failed to write approved exe id to message buffer.");
1547
1548 hr = BuffWriteString(&pbData, &cbData, pLaunchApprovedExe->sczArguments);
1549 ExitOnFailure(hr, "Failed to write approved exe arguments to message buffer.");
1550
1551 hr = BuffWriteNumber(&pbData, &cbData, pLaunchApprovedExe->dwWaitForInputIdleTimeout);
1552 ExitOnFailure(hr, "Failed to write approved exe WaitForInputIdle timeout to message buffer.");
1553
1554 // Send the message.
1555 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE, pbData, cbData, ProcessLaunchApprovedExeMessages, &context, &dwResult);
1556 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE message to per-machine process.");
1557
1558 hr = (HRESULT)dwResult;
1559 *pdwProcessId = context.dwProcessId;
1560
1561 LExit:
1562 ReleaseMem(pbData);
1563
1564 return hr;
1565 }
1566
1567 /*******************************************************************
1568 ElevationChildPumpMessages -
1569
1570 *******************************************************************/
1571 extern "C" HRESULT ElevationChildPumpMessages(
1572 __in HANDLE hPipe,
1573 __in HANDLE hCachePipe,
1574 __in BURN_APPROVED_EXES* pApprovedExes,
1575 __in BURN_CACHE* pCache,
1576 __in BURN_CONTAINERS* pContainers,
1577 __in BURN_PACKAGES* pPackages,
1578 __in BURN_PAYLOADS* pPayloads,
1579 __in BURN_VARIABLES* pVariables,
1580 __in BURN_REGISTRATION* pRegistration,
1581 __in BURN_USER_EXPERIENCE* pUserExperience,
1582 __out HANDLE* phLock,
1583 __out DWORD* pdwChildExitCode,
1584 __out BOOL* pfRestart,
1585 __out BOOL* pfApplying
1586 )
1587 {
1588 HRESULT hr = S_OK;
1589 BURN_ELEVATION_CHILD_MESSAGE_CONTEXT cacheContext = { };
1590 BURN_ELEVATION_CHILD_MESSAGE_CONTEXT context = { };
1591 HANDLE hCacheThread = NULL;
1592 BURN_PIPE_RESULT result = { };
1593 BOOL fDisabledAutomaticUpdates = FALSE;
1594
1595 cacheContext.hPipe = hCachePipe;
1596 cacheContext.pCache = pCache;
1597 cacheContext.pContainers = pContainers;
1598 cacheContext.pPackages = pPackages;
1599 cacheContext.pPayloads = pPayloads;
1600 cacheContext.pVariables = pVariables;
1601 cacheContext.pRegistration = pRegistration;
1602 cacheContext.pUserExperience = pUserExperience;
1603
1604 context.hPipe = hPipe;
1605 context.phLock = phLock;
1606 context.pfDisabledAutomaticUpdates = &fDisabledAutomaticUpdates;
1607 context.pfApplying = pfApplying;
1608 context.pApprovedExes = pApprovedExes;
1609 context.pCache = pCache;
1610 context.pContainers = pContainers;
1611 context.pPackages = pPackages;
1612 context.pPayloads = pPayloads;
1613 context.pVariables = pVariables;
1614 context.pRegistration = pRegistration;
1615 context.pUserExperience = pUserExperience;
1616
1617 hCacheThread = ::CreateThread(NULL, 0, ElevatedChildCacheThreadProc, &cacheContext, 0, NULL);
1618 ExitOnNullWithLastError(hCacheThread, hr, "Failed to create elevated cache thread.");
1619
1620 hr = BurnPipePumpMessages(hPipe, ProcessElevatedChildMessage, &context, &result);
1621 ExitOnFailure(hr, "Failed to pump messages in child process.");
1622
1623 // Wait for the cache thread and verify it gets the right result but don't fail if things
1624 // don't work out.
1625 WaitForElevatedChildCacheThread(hCacheThread, result.dwResult);
1626
1627 *pdwChildExitCode = result.dwResult;
1628 *pfRestart = result.fRestart;
1629
1630 LExit:
1631 ReleaseHandle(hCacheThread);
1632
1633 if (fDisabledAutomaticUpdates)
1634 {
1635 ElevationChildResumeAutomaticUpdates();
1636 }
1637
1638 return hr;
1639 }
1640
1641 extern "C" HRESULT ElevationChildResumeAutomaticUpdates()
1642 {
1643 HRESULT hr = S_OK;
1644
1645 LogId(REPORT_STANDARD, MSG_RESUME_AU_STARTING);
1646
1647 hr = WuaResumeAutomaticUpdates();
1648 ExitOnFailure(hr, "Failed to resume automatic updates after pausing them, continuing...");
1649
1650 LogId(REPORT_STANDARD, MSG_RESUME_AU_SUCCEEDED);
1651
1652 LExit:
1653 return hr;
1654 }
1655
1656 // internal function definitions
1657
1658 static HRESULT LaunchElevatedProcess(
1659 __in BURN_ENGINE_STATE* pEngineState,
1660 __in_opt HWND hwndParent
1661 )
1662 {
1663 HRESULT hr = S_OK;
1664 DWORD dwCurrentProcessId = ::GetCurrentProcessId();
1665 LPWSTR sczParameters = NULL;
1666 HANDLE hProcess = NULL;
1667 BURN_PIPE_CONNECTION* pConnection = &pEngineState->companionConnection;
1668
1669 hr = StrAllocFormatted(&sczParameters, L"-q -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_ELEVATED, pConnection->sczName, pConnection->sczSecret, dwCurrentProcessId);
1670 ExitOnFailure(hr, "Failed to allocate parameters for elevated process.");
1671
1672 if (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pEngineState->internalCommand.dwLoggingAttributes)
1673 {
1674 hr = StrAllocConcatFormatted(&sczParameters, L" -%ls=%ls", BURN_COMMANDLINE_SWITCH_LOG_MODE, L"x");
1675 ExitOnFailure(hr, "Failed to set log mode in elevated process command-line.");
1676 }
1677
1678 // Since ShellExecuteEx doesn't support passing inherited handles, don't bother with CoreAppendFileHandleSelfToCommandLine.
1679 // We could fallback to using ::DuplicateHandle to inject the file handle later if necessary.
1680 hr = ShelExec(pEngineState->sczBundleEngineWorkingPath, sczParameters, L"runas", NULL, SW_SHOWNA, hwndParent, &hProcess);
1681 ExitOnFailure(hr, "Failed to launch elevated child process: %ls", pEngineState->sczBundleEngineWorkingPath);
1682
1683 pConnection->dwProcessId = ::GetProcessId(hProcess);
1684 pConnection->hProcess = hProcess;
1685 hProcess = NULL;
1686
1687 LExit:
1688 ReleaseHandle(hProcess);
1689 ReleaseStr(sczParameters);
1690
1691 return hr;
1692 }
1693
1694 static DWORD WINAPI ElevatedChildCacheThreadProc(
1695 __in LPVOID lpThreadParameter
1696 )
1697 {
1698 HRESULT hr = S_OK;
1699 BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = reinterpret_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(lpThreadParameter);
1700 BOOL fComInitialized = FALSE;
1701 BURN_PIPE_RESULT result = { };
1702
1703 // initialize COM
1704 hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
1705 ExitOnFailure(hr, "Failed to initialize COM.");
1706 fComInitialized = TRUE;
1707
1708 hr = BurnPipePumpMessages(pContext->hPipe, ProcessElevatedChildCacheMessage, pContext, &result);
1709 ExitOnFailure(hr, "Failed to pump messages in child process.");
1710
1711 hr = (HRESULT)result.dwResult;
1712
1713 LExit:
1714 if (fComInitialized)
1715 {
1716 ::CoUninitialize();
1717 }
1718
1719 return (DWORD)hr;
1720 }
1721
1722 static HRESULT WaitForElevatedChildCacheThread(
1723 __in HANDLE hCacheThread,
1724 __in DWORD dwExpectedExitCode
1725 )
1726 {
1727 UNREFERENCED_PARAMETER(dwExpectedExitCode);
1728
1729 HRESULT hr = S_OK;
1730 DWORD dwExitCode = ERROR_SUCCESS;
1731
1732 hr = ThrdWaitForCompletion(hCacheThread, BURN_TIMEOUT, &dwExitCode);
1733 ExitOnFailure(hr, "Failed to wait for cache thread to complete.");
1734
1735 AssertSz(dwExitCode == dwExpectedExitCode, "Cache thread should have exited with the expected exit code.");
1736
1737 LExit:
1738 return hr;
1739 }
1740
1741 static HRESULT ProcessApplyInitializeMessages(
1742 __in PIPE_MESSAGE* pMsg,
1743 __in_opt LPVOID pvContext,
1744 __out DWORD* pdwResult
1745 )
1746 {
1747 HRESULT hr = S_OK;
1748 BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT*>(pvContext);
1749 BYTE* pbData = (BYTE*)pMsg->pvData;
1750 SIZE_T iData = 0;
1751 HRESULT hrStatus = S_OK;
1752 HRESULT hrBA = S_OK;
1753
1754 // Process the message.
1755 switch (pMsg->dwMessageType)
1756 {
1757 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN:
1758 pContext->fPauseCompleteNeeded = TRUE;
1759 hrBA = BACallbackOnPauseAUBegin(pContext->pBA);
1760 break;
1761
1762 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE:
1763 // read hrStatus
1764 hr = BuffReadNumber(pbData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&hrStatus));
1765 ExitOnFailure(hr, "Failed to read pause AU hrStatus.");
1766
1767 pContext->fPauseCompleteNeeded = FALSE;
1768 hrBA = BACallbackOnPauseAUComplete(pContext->pBA, hrStatus);
1769 break;
1770
1771 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN:
1772 if (pContext->fPauseCompleteNeeded)
1773 {
1774 pContext->fPauseCompleteNeeded = FALSE;
1775 hrBA = BACallbackOnPauseAUComplete(pContext->pBA, E_INVALIDSTATE);
1776 }
1777
1778 pContext->fSrpCompleteNeeded = TRUE;
1779 hrBA = BACallbackOnSystemRestorePointBegin(pContext->pBA);
1780 break;
1781
1782 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE:
1783 // read hrStatus
1784 hr = BuffReadNumber(pbData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&hrStatus));
1785 ExitOnFailure(hr, "Failed to read system restore point hrStatus.");
1786
1787 pContext->fSrpCompleteNeeded = FALSE;
1788 hrBA = BACallbackOnSystemRestorePointComplete(pContext->pBA, hrStatus);
1789 break;
1790
1791 default:
1792 hr = E_INVALIDARG;
1793 ExitOnRootFailure(hr, "Invalid apply initialize message.");
1794 break;
1795 }
1796
1797 *pdwResult = static_cast<DWORD>(hrBA);
1798
1799 LExit:
1800 return hr;
1801 }
1802
1803 static HRESULT ProcessBurnCacheMessages(
1804 __in PIPE_MESSAGE* pMsg,
1805 __in LPVOID pvContext,
1806 __out DWORD* pdwResult
1807 )
1808 {
1809 HRESULT hr = S_OK;
1810 SIZE_T iData = 0;
1811 BURN_ELEVATION_CACHE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CACHE_MESSAGE_CONTEXT*>(pvContext);
1812 BURN_CACHE_MESSAGE message = { };
1813 BOOL fProgressRoutine = FALSE;
1814
1815 // Process the message.
1816 switch (pMsg->dwMessageType)
1817 {
1818 case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN:
1819 // read message parameters
1820 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.begin.cacheStep));
1821 ExitOnFailure(hr, "Failed to read begin cache step.");
1822
1823 message.type = BURN_CACHE_MESSAGE_BEGIN;
1824 break;
1825
1826 case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE:
1827 // read message parameters
1828 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.complete.hrStatus));
1829 ExitOnFailure(hr, "Failed to read complete hresult.");
1830
1831 message.type = BURN_CACHE_MESSAGE_COMPLETE;
1832 break;
1833
1834 case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS:
1835 // read message parameters
1836 hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize);
1837 ExitOnFailure(hr, "Failed to read success file size.");
1838
1839 message.type = BURN_CACHE_MESSAGE_SUCCESS;
1840 break;
1841
1842 case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE:
1843 // read message parameters
1844 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.failure.cacheStep));
1845 ExitOnFailure(hr, "Failed to read failure cache step.");
1846
1847 message.type = BURN_CACHE_MESSAGE_FAILURE;
1848 break;
1849
1850 case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE:
1851 fProgressRoutine = TRUE;
1852 break;
1853
1854 default:
1855 hr = E_INVALIDARG;
1856 ExitOnRootFailure(hr, "Invalid burn cache message.");
1857 break;
1858 }
1859
1860 if (fProgressRoutine)
1861 {
1862 hr = ProcessProgressRoutineMessage(pMsg, pContext->pfnProgress, pContext->pvContext, pdwResult);
1863 }
1864 else
1865 {
1866 hr = pContext->pfnCacheMessageHandler(&message, pContext->pvContext);
1867 *pdwResult = static_cast<DWORD>(hr);
1868 }
1869
1870 LExit:
1871 return hr;
1872 }
1873
1874 static HRESULT ProcessGenericExecuteMessages(
1875 __in PIPE_MESSAGE* pMsg,
1876 __in LPVOID pvContext,
1877 __out DWORD* pdwResult
1878 )
1879 {
1880 HRESULT hr = S_OK;
1881 SIZE_T iData = 0;
1882 BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT*>(pvContext);
1883 LPWSTR sczMessage = NULL;
1884 DWORD cFiles = 0;
1885 LPWSTR* rgwzFiles = NULL;
1886 GENERIC_EXECUTE_MESSAGE message = { };
1887
1888 if (BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE == pMsg->dwMessageType)
1889 {
1890 hr = ProcessExecuteActionCompleteMessage((BYTE*)pMsg->pvData, pMsg->cbData, &pContext->restart, pdwResult);
1891 ExitOnFailure(hr, "Failed to process BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message.");
1892
1893 ExitFunction();
1894 }
1895
1896 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwUIHint);
1897 ExitOnFailure(hr, "Failed to allowed results.");
1898
1899 // Process the message.
1900 switch (pMsg->dwMessageType)
1901 {
1902 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS:
1903 message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
1904
1905 // read message parameters
1906 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.progress.dwPercentage);
1907 ExitOnFailure(hr, "Failed to read progress.");
1908 break;
1909
1910 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL:
1911 message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_CANCEL;
1912
1913 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.processCancel.dwProcessId);
1914 ExitOnFailure(hr, "Failed to read processId.");
1915 break;
1916
1917 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED:
1918 message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED;
1919 break;
1920
1921 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_COMPLETED:
1922 message.type = GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED;
1923 break;
1924
1925 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR:
1926 message.type = GENERIC_EXECUTE_MESSAGE_ERROR;
1927
1928 // read message parameters
1929 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.error.dwErrorCode);
1930 ExitOnFailure(hr, "Failed to read error code.");
1931
1932 hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage);
1933 ExitOnFailure(hr, "Failed to read error message.");
1934
1935 message.error.wzMessage = sczMessage;
1936 break;
1937
1938 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE:
1939 message.type = GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE;
1940
1941 // read message parameters
1942 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cFiles);
1943 ExitOnFailure(hr, "Failed to read file count.");
1944
1945 rgwzFiles = (LPWSTR*)MemAlloc(sizeof(LPWSTR*) * cFiles, TRUE);
1946 ExitOnNull(rgwzFiles, hr, E_OUTOFMEMORY, "Failed to allocate buffer for files in use.");
1947
1948 for (DWORD i = 0; i < cFiles; ++i)
1949 {
1950 hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &rgwzFiles[i]);
1951 ExitOnFailure(hr, "Failed to read file name: %u", i);
1952 }
1953
1954 message.filesInUse.cFiles = cFiles;
1955 message.filesInUse.rgwzFiles = (LPCWSTR*)rgwzFiles;
1956 break;
1957
1958 default:
1959 hr = E_INVALIDARG;
1960 ExitOnRootFailure(hr, "Invalid package message.");
1961 break;
1962 }
1963
1964 // send message
1965 *pdwResult = (DWORD)pContext->pfnGenericMessageHandler(&message, pContext->pvContext);
1966
1967 LExit:
1968 ReleaseStr(sczMessage);
1969
1970 if (rgwzFiles)
1971 {
1972 for (DWORD i = 0; i < cFiles; ++i)
1973 {
1974 ReleaseStr(rgwzFiles[i]);
1975 }
1976 MemFree(rgwzFiles);
1977 }
1978 return hr;
1979 }
1980
1981 static HRESULT ProcessMsiPackageMessages(
1982 __in PIPE_MESSAGE* pMsg,
1983 __in_opt LPVOID pvContext,
1984 __out DWORD* pdwResult
1985 )
1986 {
1987 HRESULT hr = S_OK;
1988 SIZE_T iData = 0;
1989 WIU_MSI_EXECUTE_MESSAGE message = { };
1990 DWORD cMsiData = 0;
1991 LPWSTR* rgwzMsiData = NULL;
1992 BURN_ELEVATION_MSI_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_MSI_MESSAGE_CONTEXT*>(pvContext);
1993 LPWSTR sczMessage = NULL;
1994 BOOL fRestartManager = FALSE;
1995
1996 if (BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE == pMsg->dwMessageType)
1997 {
1998 hr = ProcessExecuteActionCompleteMessage((BYTE*)pMsg->pvData, pMsg->cbData, &pContext->restart, pdwResult);
1999 ExitOnFailure(hr, "Failed to process BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message.");
2000
2001 ExitFunction();
2002 }
2003
2004 // Read MSI extended message data.
2005 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &cMsiData);
2006 ExitOnFailure(hr, "Failed to read MSI data count.");
2007
2008 if (cMsiData)
2009 {
2010 rgwzMsiData = (LPWSTR*)MemAlloc(sizeof(LPWSTR*) * cMsiData, TRUE);
2011 ExitOnNull(rgwzMsiData, hr, E_OUTOFMEMORY, "Failed to allocate buffer to read MSI data.");
2012
2013 for (DWORD i = 0; i < cMsiData; ++i)
2014 {
2015 hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &rgwzMsiData[i]);
2016 ExitOnFailure(hr, "Failed to read MSI data: %u", i);
2017 }
2018
2019 message.cData = cMsiData;
2020 message.rgwzData = (LPCWSTR*)rgwzMsiData;
2021 }
2022
2023 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.dwUIHint);
2024 ExitOnFailure(hr, "Failed to read UI flags.");
2025
2026 // Process the rest of the message.
2027 switch (pMsg->dwMessageType)
2028 {
2029 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS:
2030 // read message parameters
2031 message.type = WIU_MSI_EXECUTE_MESSAGE_PROGRESS;
2032
2033 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.progress.dwPercentage);
2034 ExitOnFailure(hr, "Failed to read progress.");
2035 break;
2036
2037 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR:
2038 // read message parameters
2039 message.type = WIU_MSI_EXECUTE_MESSAGE_ERROR;
2040
2041 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.error.dwErrorCode);
2042 ExitOnFailure(hr, "Failed to read error code.");
2043
2044 hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage);
2045 ExitOnFailure(hr, "Failed to read MSI execute error message.");
2046 message.error.wzMessage = sczMessage;
2047 break;
2048
2049 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE:
2050 // read message parameters
2051 message.type = WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE;
2052
2053 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, (DWORD*)&message.msiMessage.mt);
2054 ExitOnFailure(hr, "Failed to read MSI execute message type.");
2055
2056 hr = BuffReadString((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &sczMessage);
2057 ExitOnFailure(hr, "Failed to read MSI execute message.");
2058 message.msiMessage.wzMessage = sczMessage;
2059 break;
2060
2061 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE:
2062 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, (DWORD*)&fRestartManager);
2063 ExitOnFailure(hr, "Failed to read fRestartManager.");
2064
2065 message.type = fRestartManager ? WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE : WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE;
2066 message.msiFilesInUse.cFiles = cMsiData;
2067 message.msiFilesInUse.rgwzFiles = (LPCWSTR*)rgwzMsiData;
2068 break;
2069
2070 default:
2071 hr = E_INVALIDARG;
2072 ExitOnRootFailure(hr, "Invalid package message.");
2073 break;
2074 }
2075
2076 // send message
2077 *pdwResult = (DWORD)pContext->pfnMessageHandler(&message, pContext->pvContext);
2078
2079 LExit:
2080 ReleaseStr(sczMessage);
2081
2082 if (rgwzMsiData)
2083 {
2084 for (DWORD i = 0; i < cMsiData; ++i)
2085 {
2086 ReleaseStr(rgwzMsiData[i]);
2087 }
2088
2089 MemFree(rgwzMsiData);
2090 }
2091
2092 return hr;
2093 }
2094
2095 static HRESULT ProcessLaunchApprovedExeMessages(
2096 __in PIPE_MESSAGE* pMsg,
2097 __in_opt LPVOID pvContext,
2098 __out DWORD* pdwResult
2099 )
2100 {
2101 HRESULT hr = S_OK;
2102 SIZE_T iData = 0;
2103 BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_LAUNCH_APPROVED_EXE_MESSAGE_CONTEXT*>(pvContext);
2104 DWORD dwProcessId = 0;
2105
2106 // Process the message.
2107 switch (pMsg->dwMessageType)
2108 {
2109 case BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID:
2110 // read message parameters
2111 hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &dwProcessId);
2112 ExitOnFailure(hr, "Failed to read approved exe process id.");
2113 pContext->dwProcessId = dwProcessId;
2114 break;
2115
2116 default:
2117 hr = E_INVALIDARG;
2118 ExitOnRootFailure(hr, "Invalid launch approved exe message.");
2119 break;
2120 }
2121
2122 *pdwResult = static_cast<DWORD>(hr);
2123
2124 LExit:
2125 return hr;
2126 }
2127
2128 static HRESULT ProcessProgressRoutineMessage(
2129 __in PIPE_MESSAGE* pMsg,
2130 __in LPPROGRESS_ROUTINE pfnProgress,
2131 __in LPVOID pvContext,
2132 __out DWORD* pdwResult
2133 )
2134 {
2135 HRESULT hr = S_OK;
2136 SIZE_T iData = 0;
2137 LARGE_INTEGER liTotalFileSize = { };
2138 LARGE_INTEGER liTotalBytesTransferred = { };
2139 LARGE_INTEGER liStreamSize = { };
2140 LARGE_INTEGER liStreamBytesTransferred = { };
2141 DWORD dwStreamNumber = 0;
2142 DWORD dwCallbackReason = CALLBACK_CHUNK_FINISHED;
2143 HANDLE hSourceFile = INVALID_HANDLE_VALUE;
2144 HANDLE hDestinationFile = INVALID_HANDLE_VALUE;
2145
2146 hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD64*>(&liTotalFileSize.QuadPart));
2147 ExitOnFailure(hr, "Failed to read total file size for progress.");
2148
2149 hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD64*>(&liTotalBytesTransferred.QuadPart));
2150 ExitOnFailure(hr, "Failed to read total bytes transferred for progress.");
2151
2152 *pdwResult = pfnProgress(liTotalFileSize, liTotalBytesTransferred, liStreamSize, liStreamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, pvContext);
2153
2154 LExit:
2155 return hr;
2156 }
2157
2158 static HRESULT ProcessElevatedChildMessage(
2159 __in PIPE_MESSAGE* pMsg,
2160 __in_opt LPVOID pvContext,
2161 __out DWORD* pdwResult
2162 )
2163 {
2164 HRESULT hr = S_OK;
2165 BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(pvContext);
2166 HRESULT hrResult = S_OK;
2167 BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2168 BOOL fSendRestart = FALSE;
2169
2170 switch (pMsg->dwMessageType)
2171 {
2172 case BURN_ELEVATION_MESSAGE_TYPE_BEGIN_MSI_TRANSACTION:
2173 hrResult = OnMsiBeginTransaction(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
2174 break;
2175
2176 case BURN_ELEVATION_MESSAGE_TYPE_COMMIT_MSI_TRANSACTION:
2177 hrResult = OnMsiCommitTransaction(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2178 fSendRestart = TRUE;
2179 break;
2180
2181 case BURN_ELEVATION_MESSAGE_TYPE_ROLLBACK_MSI_TRANSACTION:
2182 hrResult = OnMsiRollbackTransaction(pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2183 fSendRestart = TRUE;
2184 break;
2185
2186 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE:
2187 hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->pPackages, pContext->phLock, pContext->pfDisabledAutomaticUpdates, pContext->pfApplying, (BYTE*)pMsg->pvData, pMsg->cbData);
2188 break;
2189
2190 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE:
2191 hrResult = OnApplyUninitialize(pContext->phLock, pContext->pfApplying, pContext->pfDisabledAutomaticUpdates);
2192 break;
2193
2194 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN:
2195 hrResult = OnSessionBegin(pContext->pCache, pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2196 break;
2197
2198 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_END:
2199 hrResult = OnSessionEnd(pContext->pCache, pContext->pPackages, pContext->pRegistration, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2200 break;
2201
2202 case BURN_ELEVATION_MESSAGE_TYPE_SAVE_STATE:
2203 hrResult = OnSaveState(pContext->pRegistration, (BYTE*)pMsg->pvData, pMsg->cbData);
2204 break;
2205
2206 case BURN_ELEVATION_MESSAGE_TYPE_PROCESS_DEPENDENT_REGISTRATION:
2207 hrResult = OnProcessDependentRegistration(pContext->pRegistration, (BYTE*)pMsg->pvData, pMsg->cbData);
2208 break;
2209
2210 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_RELATED_BUNDLE:
2211 hrResult = OnExecuteRelatedBundle(pContext->hPipe, pContext->pCache, &pContext->pRegistration->relatedBundles, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2212 fSendRestart = TRUE;
2213 break;
2214
2215 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_BUNDLE_PACKAGE:
2216 hrResult = OnExecuteBundlePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2217 fSendRestart = TRUE;
2218 break;
2219
2220 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_EXE_PACKAGE:
2221 hrResult = OnExecuteExePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2222 fSendRestart = TRUE;
2223 break;
2224
2225 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_PACKAGE:
2226 hrResult = OnExecuteMsiPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2227 fSendRestart = TRUE;
2228 break;
2229
2230 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSP_PACKAGE:
2231 hrResult = OnExecuteMspPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2232 fSendRestart = TRUE;
2233 break;
2234
2235 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSU_PACKAGE:
2236 hrResult = OnExecuteMsuPackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2237 fSendRestart = TRUE;
2238 break;
2239
2240 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_PROVIDER:
2241 hrResult = OnExecutePackageProviderAction(pContext->pPackages, &pContext->pRegistration->relatedBundles, (BYTE*)pMsg->pvData, pMsg->cbData);
2242 break;
2243
2244 case BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PACKAGE_DEPENDENCY:
2245 hrResult = OnExecutePackageDependencyAction(pContext->pPackages, &pContext->pRegistration->relatedBundles, (BYTE*)pMsg->pvData, pMsg->cbData);
2246 break;
2247
2248 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE:
2249 hrResult = OnCleanPackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
2250 break;
2251
2252 case BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE:
2253 hrResult = OnLaunchApprovedExe(pContext->hPipe, pContext->pApprovedExes, pContext->pCache, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData);
2254 break;
2255
2256 case BURN_ELEVATION_MESSAGE_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE:
2257 hrResult = OnUninstallMsiCompatiblePackage(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pVariables, (BYTE*)pMsg->pvData, pMsg->cbData, &restart);
2258 fSendRestart = TRUE;
2259 break;
2260
2261 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_COMPATIBLE_PACKAGE:
2262 hrResult = OnCleanCompatiblePackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
2263 break;
2264
2265 default:
2266 ExitWithRootFailure(hr, E_INVALIDARG, "Unexpected elevated message sent to child process, msg: %u", pMsg->dwMessageType);
2267 }
2268
2269 if (fSendRestart)
2270 {
2271 hr = ElevatedOnExecuteActionComplete(pContext->hPipe, restart);
2272 ExitOnFailure(hr, "ElevatedOnExecuteActionComplete failed.");
2273 }
2274
2275 *pdwResult = (DWORD)hrResult;
2276
2277 LExit:
2278 return hr;
2279 }
2280
2281 static HRESULT ProcessElevatedChildCacheMessage(
2282 __in PIPE_MESSAGE* pMsg,
2283 __in_opt LPVOID pvContext,
2284 __out DWORD* pdwResult
2285 )
2286 {
2287 HRESULT hr = S_OK;
2288 BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast<BURN_ELEVATION_CHILD_MESSAGE_CONTEXT*>(pvContext);
2289 HRESULT hrResult = S_OK;
2290
2291 switch (pMsg->dwMessageType)
2292 {
2293 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_PREPARE_PACKAGE:
2294 hrResult = OnCachePreparePackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
2295 break;
2296
2297 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD:
2298 hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pCache, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
2299 break;
2300
2301 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD:
2302 hrResult = OnCacheVerifyPayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData);
2303 break;
2304
2305 case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP:
2306 OnCacheCleanup(pContext->pCache);
2307 hrResult = S_OK;
2308 break;
2309
2310 case BURN_ELEVATION_MESSAGE_TYPE_CLEAN_PACKAGE:
2311 hrResult = OnCleanPackage(pContext->pCache, pContext->pPackages, (BYTE*)pMsg->pvData, pMsg->cbData);
2312 break;
2313
2314 default:
2315 hr = E_INVALIDARG;
2316 ExitOnRootFailure(hr, "Unexpected elevated cache message sent to child process, msg: %u", pMsg->dwMessageType);
2317 }
2318
2319 *pdwResult = (DWORD)hrResult;
2320
2321 LExit:
2322 return hr;
2323 }
2324
2325 static HRESULT ProcessExecuteActionCompleteMessage(
2326 __in BYTE* pbData,
2327 __in DWORD cbData,
2328 __out BOOTSTRAPPER_APPLY_RESTART* pRestart,
2329 __out DWORD* pdwResult
2330 )
2331 {
2332 HRESULT hr = S_OK;
2333 SIZE_T iData = 0;
2334
2335 hr = BuffReadNumber(pbData, cbData, &iData, reinterpret_cast<DWORD*>(pRestart));
2336 ExitOnFailure(hr, "Failed to read execute action restart result.");
2337
2338 *pdwResult = (DWORD)hr;
2339
2340 LExit:
2341 return hr;
2342 }
2343
2344 static HRESULT OnApplyInitialize(
2345 __in HANDLE hPipe,
2346 __in BURN_VARIABLES* pVariables,
2347 __in BURN_REGISTRATION* pRegistration,
2348 __in BURN_PACKAGES* pPackages,
2349 __in HANDLE* phLock,
2350 __in BOOL* pfDisabledWindowsUpdate,
2351 __in BOOL* pfApplying,
2352 __in BYTE* pbData,
2353 __in SIZE_T cbData
2354 )
2355 {
2356 HRESULT hr = S_OK;
2357 SIZE_T iData = 0;
2358 DWORD dwAction = 0;
2359 DWORD dwAUAction = 0;
2360 DWORD dwTakeSystemRestorePoint = 0;
2361 LPWSTR sczBundleName = NULL;
2362 HRESULT hrStatus = S_OK;
2363
2364 // Deserialize message data.
2365 hr = BuffReadNumber(pbData, cbData, &iData, &dwAction);
2366 ExitOnFailure(hr, "Failed to read action.");
2367
2368 hr = BuffReadNumber(pbData, cbData, &iData, &dwAUAction);
2369 ExitOnFailure(hr, "Failed to read update action.");
2370
2371 hr = BuffReadNumber(pbData, cbData, &iData, &dwTakeSystemRestorePoint);
2372 ExitOnFailure(hr, "Failed to read system restore point action.");
2373
2374 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2375 ExitOnFailure(hr, "Failed to read variables.");
2376
2377 // Initialize.
2378 hr = ApplyLock(TRUE, phLock);
2379 ExitOnFailure(hr, "Failed to acquire lock due to setup in other session.");
2380
2381 *pfApplying = TRUE;
2382
2383 // Detect.
2384 hr = ElevatedProcessDetect(pRegistration, pVariables, pPackages);
2385 ExitOnFailure(hr, "Failed to run detection in elevated process.");
2386
2387 // Attempt to pause AU with best effort.
2388 if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction || BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME == dwAUAction)
2389 {
2390 hr = ElevatedOnPauseAUBegin(hPipe);
2391 ExitOnFailure(hr, "ElevatedOnPauseAUBegin failed.");
2392
2393 LogId(REPORT_STANDARD, MSG_PAUSE_AU_STARTING);
2394
2395 hrStatus = hr = WuaPauseAutomaticUpdates();
2396 if (FAILED(hr))
2397 {
2398 LogId(REPORT_STANDARD, MSG_FAILED_PAUSE_AU, hr);
2399 hr = S_OK;
2400 }
2401 else
2402 {
2403 LogId(REPORT_STANDARD, MSG_PAUSE_AU_SUCCEEDED);
2404 if (BURN_AU_PAUSE_ACTION_IFELEVATED == dwAUAction)
2405 {
2406 *pfDisabledWindowsUpdate = TRUE;
2407 }
2408 }
2409
2410 hr = ElevatedOnPauseAUComplete(hPipe, hrStatus);
2411 ExitOnFailure(hr, "ElevatedOnPauseAUComplete failed.");
2412 }
2413
2414 if (dwTakeSystemRestorePoint)
2415 {
2416 hr = VariableGetString(pVariables, BURN_BUNDLE_NAME, &sczBundleName);
2417 if (FAILED(hr))
2418 {
2419 hr = S_OK;
2420 ExitFunction();
2421 }
2422
2423 hr = ElevatedOnSystemRestorePointBegin(hPipe);
2424 ExitOnFailure(hr, "ElevatedOnSystemRestorePointBegin failed.");
2425
2426 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_STARTING);
2427
2428 SRP_ACTION restoreAction = SRP_ACTION_UNKNOWN;
2429 switch (static_cast<BOOTSTRAPPER_ACTION>(dwAction))
2430 {
2431 case BOOTSTRAPPER_ACTION_INSTALL:
2432 restoreAction = SRP_ACTION_INSTALL;
2433 break;
2434 case BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL: __fallthrough;
2435 case BOOTSTRAPPER_ACTION_UNINSTALL:
2436 restoreAction = SRP_ACTION_UNINSTALL;
2437 break;
2438 default:
2439 restoreAction = SRP_ACTION_MODIFY;
2440 break;
2441 }
2442
2443 hrStatus = hr = SrpCreateRestorePoint(sczBundleName, restoreAction);
2444 if (SUCCEEDED(hr))
2445 {
2446 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_SUCCEEDED);
2447 }
2448 else if (E_NOTIMPL == hr)
2449 {
2450 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_DISABLED);
2451 hr = S_OK;
2452 }
2453 else
2454 {
2455 LogId(REPORT_STANDARD, MSG_SYSTEM_RESTORE_POINT_FAILED, hr);
2456 hr = S_OK;
2457 }
2458
2459 hr = ElevatedOnSystemRestorePointComplete(hPipe, hrStatus);
2460 ExitOnFailure(hr, "ElevatedOnSystemRestorePointComplete failed.");
2461 }
2462
2463 LExit:
2464 ReleaseStr(sczBundleName);
2465 return hr;
2466 }
2467
2468 static HRESULT ElevatedProcessDetect(
2469 __in BURN_REGISTRATION* pRegistration,
2470 __in BURN_VARIABLES* pVariables,
2471 __in BURN_PACKAGES* pPackages
2472 )
2473 {
2474 HRESULT hr = S_OK;
2475
2476 DetectReset(pRegistration, pPackages);
2477
2478 hr = RegistrationSetDynamicVariables(pRegistration, pVariables);
2479 ExitOnFailure(hr, "Failed to reset the dynamic registration variables during elevated detect.");
2480
2481 hr = RelatedBundlesInitializeForScope(TRUE, pRegistration, &pRegistration->relatedBundles);
2482 ExitOnFailure(hr, "Failed to initialize per-machine related bundles.");
2483
2484 for (DWORD i = 0; i < pPackages->cPackages; ++i)
2485 {
2486 BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
2487
2488 hr = DependencyDetectCompatibleEntry(pPackage, pRegistration);
2489 ExitOnFailure(hr, "Failed to detect per-machine compatible entry for package: %ls", pPackage->sczId);
2490
2491 switch (pPackage->type)
2492 {
2493 case BURN_PACKAGE_TYPE_MSI:
2494 hr = MsiEngineDetectCompatiblePackage(pPackage);
2495 ExitOnFailure(hr, "Failed to detect per-machine compatible package for package: %ls", pPackage->sczId);
2496
2497 break;
2498 }
2499 }
2500
2501 LExit:
2502 return hr;
2503 }
2504
2505 static HRESULT OnApplyUninitialize(
2506 __in HANDLE* phLock,
2507 __in BOOL* pfApplying,
2508 __in BOOL* pfDisabledAutomaticUpdates
2509 )
2510 {
2511 Assert(phLock);
2512
2513 // TODO: end system restore point.
2514
2515 *pfApplying = FALSE;
2516
2517 if (*pfDisabledAutomaticUpdates)
2518 {
2519 *pfDisabledAutomaticUpdates = FALSE;
2520
2521 ElevationChildResumeAutomaticUpdates();
2522 }
2523
2524 if (*phLock)
2525 {
2526 ::ReleaseMutex(*phLock);
2527 ::CloseHandle(*phLock);
2528 *phLock = NULL;
2529 }
2530
2531 return S_OK;
2532 }
2533
2534 static HRESULT OnSessionBegin(
2535 __in BURN_CACHE* pCache,
2536 __in BURN_REGISTRATION* pRegistration,
2537 __in BURN_VARIABLES* pVariables,
2538 __in BYTE* pbData,
2539 __in SIZE_T cbData
2540 )
2541 {
2542 HRESULT hr = S_OK;
2543 SIZE_T iData = 0;
2544 LPWSTR sczEngineWorkingPath = NULL;
2545 DWORD dwRegistrationOperations = 0;
2546 DWORD64 qwEstimatedSize = 0;
2547 DWORD dwRegistrationType = 0;
2548
2549 // Deserialize message data.
2550 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingPath);
2551 ExitOnFailure(hr, "Failed to read engine working path.");
2552
2553 hr = BuffReadString(pbData, cbData, &iData, &pRegistration->sczResumeCommandLine);
2554 ExitOnFailure(hr, "Failed to read resume command line.");
2555
2556 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDisableResume);
2557 ExitOnFailure(hr, "Failed to read resume flag.");
2558
2559 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationOperations);
2560 ExitOnFailure(hr, "Failed to read registration operations.");
2561
2562 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDetectedForeignProviderKeyBundleId);
2563 ExitOnFailure(hr, "Failed to read dependency registration action.");
2564
2565 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize);
2566 ExitOnFailure(hr, "Failed to read estimated size.");
2567
2568 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2569 ExitOnFailure(hr, "Failed to read dependency registration action.");
2570
2571 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2572 ExitOnFailure(hr, "Failed to read variables.");
2573
2574 // Begin session in per-machine process.
2575 hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pCache, pVariables, dwRegistrationOperations, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2576 ExitOnFailure(hr, "Failed to begin registration session.");
2577
2578 LExit:
2579 ReleaseStr(sczEngineWorkingPath);
2580
2581 return hr;
2582 }
2583
2584 static HRESULT OnSessionEnd(
2585 __in BURN_CACHE* pCache,
2586 __in BURN_PACKAGES* pPackages,
2587 __in BURN_REGISTRATION* pRegistration,
2588 __in BURN_VARIABLES* pVariables,
2589 __in BYTE* pbData,
2590 __in SIZE_T cbData
2591 )
2592 {
2593 HRESULT hr = S_OK;
2594 SIZE_T iData = 0;
2595 DWORD dwResumeMode = 0;
2596 DWORD dwRestart = 0;
2597 DWORD64 qwEstimatedSize = 0;
2598 DWORD dwRegistrationType = 0;
2599
2600 // Deserialize message data.
2601 hr = BuffReadNumber(pbData, cbData, &iData, &dwResumeMode);
2602 ExitOnFailure(hr, "Failed to read resume mode enum.");
2603
2604 hr = BuffReadNumber(pbData, cbData, &iData, &dwRestart);
2605 ExitOnFailure(hr, "Failed to read restart enum.");
2606
2607 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDetectedForeignProviderKeyBundleId);
2608 ExitOnFailure(hr, "Failed to read dependency registration action.");
2609
2610 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize);
2611 ExitOnFailure(hr, "Failed to read estimated size.");
2612
2613 hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2614 ExitOnFailure(hr, "Failed to read dependency registration action.");
2615
2616 // suspend session in per-machine process
2617 hr = RegistrationSessionEnd(pRegistration, pCache, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2618 ExitOnFailure(hr, "Failed to suspend registration session.");
2619
2620 LExit:
2621 return hr;
2622 }
2623
2624 static HRESULT OnSaveState(
2625 __in BURN_REGISTRATION* pRegistration,
2626 __in BYTE* pbData,
2627 __in SIZE_T cbData
2628 )
2629 {
2630 HRESULT hr = S_OK;
2631
2632 // save state in per-machine process
2633 hr = RegistrationSaveState(pRegistration, pbData, cbData);
2634 ExitOnFailure(hr, "Failed to save state.");
2635
2636 LExit:
2637 return hr;
2638 }
2639
2640 static HRESULT OnCachePreparePackage(
2641 __in BURN_CACHE* pCache,
2642 __in BURN_PACKAGES* pPackages,
2643 __in BYTE* pbData,
2644 __in SIZE_T cbData
2645 )
2646 {
2647 HRESULT hr = S_OK;
2648 SIZE_T iData = 0;
2649 LPWSTR scz = NULL;
2650 BURN_PACKAGE* pPackage = NULL;
2651
2652 // Deserialize message data.
2653 hr = BuffReadString(pbData, cbData, &iData, &scz);
2654 ExitOnFailure(hr, "Failed to read package id.");
2655
2656 if (scz && *scz)
2657 {
2658 hr = PackageFindById(pPackages, scz, &pPackage);
2659 ExitOnFailure(hr, "Failed to find package: %ls", scz);
2660 }
2661 else
2662 {
2663 hr = E_INVALIDARG;
2664 ExitOnRootFailure(hr, "Invalid data passed to cache prepare package.");
2665 }
2666
2667 hr = CachePreparePackage(pCache, pPackage);
2668 ExitOnFailure(hr, "Failed to prepare cache package.");
2669
2670 LExit:
2671 ReleaseStr(scz);
2672
2673 return hr;
2674 }
2675
2676 static HRESULT OnCacheCompletePayload(
2677 __in HANDLE hPipe,
2678 __in BURN_CACHE* pCache,
2679 __in BURN_PACKAGES* pPackages,
2680 __in BURN_PAYLOADS* pPayloads,
2681 __in BYTE* pbData,
2682 __in SIZE_T cbData
2683 )
2684 {
2685 HRESULT hr = S_OK;
2686 SIZE_T iData = 0;
2687 LPWSTR scz = NULL;
2688 BURN_PACKAGE* pPackage = NULL;
2689 BURN_PAYLOAD* pPayload = NULL;
2690 LPWSTR sczUnverifiedPath = NULL;
2691 BOOL fMove = FALSE;
2692
2693 // Deserialize message data.
2694 hr = BuffReadString(pbData, cbData, &iData, &scz);
2695 ExitOnFailure(hr, "Failed to read package id.");
2696
2697 if (scz && *scz)
2698 {
2699 hr = PackageFindById(pPackages, scz, &pPackage);
2700 ExitOnFailure(hr, "Failed to find package: %ls", scz);
2701 }
2702
2703 hr = BuffReadString(pbData, cbData, &iData, &scz);
2704 ExitOnFailure(hr, "Failed to read payload id.");
2705
2706 if (scz && *scz)
2707 {
2708 hr = PayloadFindById(pPayloads, scz, &pPayload);
2709 ExitOnFailure(hr, "Failed to find payload: %ls", scz);
2710 }
2711
2712 hr = BuffReadString(pbData, cbData, &iData, &sczUnverifiedPath);
2713 ExitOnFailure(hr, "Failed to read unverified path.");
2714
2715 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fMove);
2716 ExitOnFailure(hr, "Failed to read move flag.");
2717
2718 if (pPackage && pPayload) // complete payload.
2719 {
2720 hr = CacheCompletePayload(pCache, pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe);
2721 ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey);
2722 }
2723 else
2724 {
2725 hr = E_INVALIDARG;
2726 ExitOnRootFailure(hr, "Invalid data passed to cache complete payload.");
2727 }
2728
2729 LExit:
2730 ReleaseStr(sczUnverifiedPath);
2731 ReleaseStr(scz);
2732
2733 return hr;
2734 }
2735
2736 static HRESULT OnCacheVerifyPayload(
2737 __in HANDLE hPipe,
2738 __in BURN_PACKAGES* pPackages,
2739 __in BURN_PAYLOADS* pPayloads,
2740 __in BYTE* pbData,
2741 __in SIZE_T cbData
2742 )
2743 {
2744 HRESULT hr = S_OK;
2745 SIZE_T iData = 0;
2746 LPWSTR scz = NULL;
2747 BURN_PACKAGE* pPackage = NULL;
2748 BURN_PAYLOAD* pPayload = NULL;
2749
2750 // Deserialize message data.
2751 hr = BuffReadString(pbData, cbData, &iData, &scz);
2752 ExitOnFailure(hr, "Failed to read package id.");
2753
2754 if (scz && *scz)
2755 {
2756 hr = PackageFindById(pPackages, scz, &pPackage);
2757 ExitOnFailure(hr, "Failed to find package: %ls", scz);
2758 }
2759
2760 hr = BuffReadString(pbData, cbData, &iData, &scz);
2761 ExitOnFailure(hr, "Failed to read payload id.");
2762
2763 if (scz && *scz)
2764 {
2765 hr = PayloadFindById(pPayloads, scz, &pPayload);
2766 ExitOnFailure(hr, "Failed to find payload: %ls", scz);
2767 }
2768
2769 if (pPackage && pPayload)
2770 {
2771 if (!pPackage->sczCacheFolder)
2772 {
2773 hr = E_INVALIDSTATE;
2774 ExitOnRootFailure(hr, "Cache verify payload called without starting its package.");
2775 }
2776
2777 hr = CacheVerifyPayload(pPayload, pPackage->sczCacheFolder, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe);
2778 }
2779 else
2780 {
2781 hr = E_INVALIDARG;
2782 ExitOnRootFailure(hr, "Invalid data passed to cache verify payload.");
2783 }
2784 // Nothing should be logged on failure.
2785
2786 LExit:
2787 ReleaseStr(scz);
2788
2789 return hr;
2790 }
2791
2792 static void OnCacheCleanup(
2793 __in BURN_CACHE* pCache
2794 )
2795 {
2796 CacheCleanup(TRUE, pCache);
2797 }
2798
2799 static HRESULT OnProcessDependentRegistration(
2800 __in const BURN_REGISTRATION* pRegistration,
2801 __in BYTE* pbData,
2802 __in SIZE_T cbData
2803 )
2804 {
2805 HRESULT hr = S_OK;
2806 SIZE_T iData = 0;
2807 BURN_DEPENDENT_REGISTRATION_ACTION action = { };
2808
2809 // Deserialize message data.
2810 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&action.type);
2811 ExitOnFailure(hr, "Failed to read action type.");
2812
2813 hr = BuffReadString(pbData, cbData, &iData, &action.sczBundleId);
2814 ExitOnFailure(hr, "Failed to read bundle id.");
2815
2816 hr = BuffReadString(pbData, cbData, &iData, &action.sczDependentProviderKey);
2817 ExitOnFailure(hr, "Failed to read dependent provider key.");
2818
2819 // Execute the registration action.
2820 hr = DependencyProcessDependentRegistration(pRegistration, &action);
2821 ExitOnFailure(hr, "Failed to execute dependent registration action for provider key: %ls", action.sczDependentProviderKey);
2822
2823 LExit:
2824 // TODO: do the right thing here.
2825 //DependencyUninitializeRegistrationAction(&action);
2826 ReleaseStr(action.sczDependentProviderKey);
2827 ReleaseStr(action.sczBundleId)
2828
2829 return hr;
2830 }
2831
2832 static HRESULT OnExecuteRelatedBundle(
2833 __in HANDLE hPipe,
2834 __in BURN_CACHE* pCache,
2835 __in BURN_RELATED_BUNDLES* pRelatedBundles,
2836 __in BURN_VARIABLES* pVariables,
2837 __in BYTE* pbData,
2838 __in SIZE_T cbData,
2839 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
2840 )
2841 {
2842 HRESULT hr = S_OK;
2843 SIZE_T iData = 0;
2844 LPWSTR sczPackage = NULL;
2845 DWORD dwPlanRelationType = 0;
2846 DWORD dwRollback = 0;
2847 BURN_EXECUTE_ACTION executeAction = { };
2848 LPWSTR sczIgnoreDependencies = NULL;
2849 LPWSTR sczAncestors = NULL;
2850 LPWSTR sczEngineWorkingDirectory = NULL;
2851 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2852
2853 executeAction.type = BURN_EXECUTE_ACTION_TYPE_RELATED_BUNDLE;
2854
2855 // Deserialize message data.
2856 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
2857 ExitOnFailure(hr, "Failed to read related bundle id.");
2858
2859 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.relatedBundle.action);
2860 ExitOnFailure(hr, "Failed to read action.");
2861
2862 hr = BuffReadNumber(pbData, cbData, &iData, &dwPlanRelationType);
2863 ExitOnFailure(hr, "Failed to read planRelationType.");
2864
2865 hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback);
2866 ExitOnFailure(hr, "Failed to read rollback.");
2867
2868 hr = BuffReadString(pbData, cbData, &iData, &sczIgnoreDependencies);
2869 ExitOnFailure(hr, "Failed to read the list of dependencies to ignore.");
2870
2871 hr = BuffReadString(pbData, cbData, &iData, &sczAncestors);
2872 ExitOnFailure(hr, "Failed to read the list of ancestors.");
2873
2874 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingDirectory);
2875 ExitOnFailure(hr, "Failed to read the custom working directory.");
2876
2877 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2878 ExitOnFailure(hr, "Failed to read variables.");
2879
2880 hr = RelatedBundleFindById(pRelatedBundles, sczPackage, &executeAction.relatedBundle.pRelatedBundle);
2881 ExitOnFailure(hr, "Failed to find related bundle: %ls", sczPackage);
2882
2883 executeAction.relatedBundle.pRelatedBundle->planRelationType = (BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE)dwPlanRelationType;
2884
2885 // Pass the list of dependencies to ignore, if any, to the related bundle.
2886 if (sczIgnoreDependencies && *sczIgnoreDependencies)
2887 {
2888 hr = StrAllocString(&executeAction.relatedBundle.sczIgnoreDependencies, sczIgnoreDependencies, 0);
2889 ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
2890 }
2891
2892 // Pass the list of ancestors, if any, to the related bundle.
2893 if (sczAncestors && *sczAncestors)
2894 {
2895 hr = StrAllocString(&executeAction.relatedBundle.sczAncestors, sczAncestors, 0);
2896 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
2897 }
2898
2899 if (sczEngineWorkingDirectory && *sczEngineWorkingDirectory)
2900 {
2901 hr = StrAllocString(&executeAction.relatedBundle.sczEngineWorkingDirectory, sczEngineWorkingDirectory, 0);
2902 ExitOnFailure(hr, "Failed to allocate the custom working directory.");
2903 }
2904
2905 // Execute related bundle.
2906 hr = BundlePackageEngineExecuteRelatedBundle(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, pRestart);
2907 ExitOnFailure(hr, "Failed to execute related bundle.");
2908
2909 LExit:
2910 ReleaseStr(sczEngineWorkingDirectory);
2911 ReleaseStr(sczAncestors);
2912 ReleaseStr(sczIgnoreDependencies);
2913 ReleaseStr(sczPackage);
2914 PlanUninitializeExecuteAction(&executeAction);
2915
2916 return hr;
2917 }
2918
2919 static HRESULT OnExecuteBundlePackage(
2920 __in HANDLE hPipe,
2921 __in BURN_CACHE* pCache,
2922 __in BURN_PACKAGES* pPackages,
2923 __in BURN_VARIABLES* pVariables,
2924 __in BYTE* pbData,
2925 __in SIZE_T cbData,
2926 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
2927 )
2928 {
2929 HRESULT hr = S_OK;
2930 SIZE_T iData = 0;
2931 LPWSTR sczPackage = NULL;
2932 BOOL fRollback = FALSE;
2933 BOOL fCacheAvailable = FALSE;
2934 BURN_EXECUTE_ACTION executeAction = { };
2935 LPWSTR sczIgnoreDependencies = NULL;
2936 LPWSTR sczAncestors = NULL;
2937 LPWSTR sczEngineWorkingDirectory = NULL;
2938 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
2939
2940 executeAction.type = BURN_EXECUTE_ACTION_TYPE_BUNDLE_PACKAGE;
2941
2942 // Deserialize message data.
2943 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
2944 ExitOnFailure(hr, "Failed to read BUNDLE package id.");
2945
2946 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.bundlePackage.action);
2947 ExitOnFailure(hr, "Failed to read action.");
2948
2949 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
2950 ExitOnFailure(hr, "Failed to read rollback.");
2951
2952 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fCacheAvailable);
2953 ExitOnFailure(hr, "Failed to read fCacheAvailable.");
2954
2955 hr = BuffReadString(pbData, cbData, &iData, &executeAction.bundlePackage.sczParent);
2956 ExitOnFailure(hr, "Failed to read the parent.");
2957
2958 hr = BuffReadString(pbData, cbData, &iData, &sczIgnoreDependencies);
2959 ExitOnFailure(hr, "Failed to read the list of dependencies to ignore.");
2960
2961 hr = BuffReadString(pbData, cbData, &iData, &sczAncestors);
2962 ExitOnFailure(hr, "Failed to read the list of ancestors.");
2963
2964 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingDirectory);
2965 ExitOnFailure(hr, "Failed to read the custom working directory.");
2966
2967 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2968 ExitOnFailure(hr, "Failed to read variables.");
2969
2970 hr = PackageFindById(pPackages, sczPackage, &executeAction.bundlePackage.pPackage);
2971 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
2972
2973 if (BURN_PACKAGE_TYPE_BUNDLE != executeAction.bundlePackage.pPackage->type)
2974 {
2975 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not a BUNDLE package: %ls", sczPackage);
2976 }
2977
2978 // Pass the list of dependencies to ignore, if any, to the related bundle.
2979 if (sczIgnoreDependencies && *sczIgnoreDependencies)
2980 {
2981 hr = StrAllocString(&executeAction.bundlePackage.sczIgnoreDependencies, sczIgnoreDependencies, 0);
2982 ExitOnFailure(hr, "Failed to allocate the list of dependencies to ignore.");
2983 }
2984
2985 // Pass the list of ancestors, if any, to the related bundle.
2986 if (sczAncestors && *sczAncestors)
2987 {
2988 hr = StrAllocString(&executeAction.bundlePackage.sczAncestors, sczAncestors, 0);
2989 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
2990 }
2991
2992 if (sczEngineWorkingDirectory && *sczEngineWorkingDirectory)
2993 {
2994 hr = StrAllocString(&executeAction.bundlePackage.sczEngineWorkingDirectory, sczEngineWorkingDirectory, 0);
2995 ExitOnFailure(hr, "Failed to allocate the custom working directory.");
2996 }
2997
2998 // Execute BUNDLE package.
2999 hr = BundlePackageEngineExecutePackage(&executeAction, pCache, pVariables, fRollback, fCacheAvailable, GenericExecuteMessageHandler, hPipe, pRestart);
3000 ExitOnFailure(hr, "Failed to execute BUNDLE package.");
3001
3002 LExit:
3003 ReleaseStr(sczEngineWorkingDirectory);
3004 ReleaseStr(sczAncestors);
3005 ReleaseStr(sczIgnoreDependencies);
3006 ReleaseStr(sczPackage);
3007 PlanUninitializeExecuteAction(&executeAction);
3008
3009 return hr;
3010 }
3011
3012 static HRESULT OnExecuteExePackage(
3013 __in HANDLE hPipe,
3014 __in BURN_CACHE* pCache,
3015 __in BURN_PACKAGES* pPackages,
3016 __in BURN_VARIABLES* pVariables,
3017 __in BYTE* pbData,
3018 __in SIZE_T cbData,
3019 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3020 )
3021 {
3022 HRESULT hr = S_OK;
3023 SIZE_T iData = 0;
3024 LPWSTR sczPackage = NULL;
3025 DWORD dwRollback = 0;
3026 BURN_EXECUTE_ACTION executeAction = { };
3027 LPWSTR sczAncestors = NULL;
3028 LPWSTR sczEngineWorkingDirectory = NULL;
3029 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3030
3031 executeAction.type = BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE;
3032
3033 // Deserialize message data.
3034 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3035 ExitOnFailure(hr, "Failed to read EXE package id.");
3036
3037 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.exePackage.action);
3038 ExitOnFailure(hr, "Failed to read action.");
3039
3040 hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback);
3041 ExitOnFailure(hr, "Failed to read rollback.");
3042
3043 hr = BuffReadString(pbData, cbData, &iData, &sczAncestors);
3044 ExitOnFailure(hr, "Failed to read the list of ancestors.");
3045
3046 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingDirectory);
3047 ExitOnFailure(hr, "Failed to read the custom working directory.");
3048
3049 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
3050 ExitOnFailure(hr, "Failed to read variables.");
3051
3052 hr = PackageFindById(pPackages, sczPackage, &executeAction.exePackage.pPackage);
3053 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3054
3055 if (BURN_PACKAGE_TYPE_EXE != executeAction.exePackage.pPackage->type)
3056 {
3057 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an EXE package: %ls", sczPackage);
3058 }
3059
3060 // Pass the list of ancestors, if any, to the related bundle.
3061 if (sczAncestors && *sczAncestors)
3062 {
3063 hr = StrAllocString(&executeAction.exePackage.sczAncestors, sczAncestors, 0);
3064 ExitOnFailure(hr, "Failed to allocate the list of ancestors.");
3065 }
3066
3067 if (sczEngineWorkingDirectory && *sczEngineWorkingDirectory)
3068 {
3069 hr = StrAllocString(&executeAction.exePackage.sczEngineWorkingDirectory, sczEngineWorkingDirectory, 0);
3070 ExitOnFailure(hr, "Failed to allocate the custom working directory.");
3071 }
3072
3073 // Execute EXE package.
3074 hr = ExeEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), GenericExecuteMessageHandler, hPipe, pRestart);
3075 ExitOnFailure(hr, "Failed to execute EXE package.");
3076
3077 LExit:
3078 ReleaseStr(sczEngineWorkingDirectory);
3079 ReleaseStr(sczAncestors);
3080 ReleaseStr(sczPackage);
3081 PlanUninitializeExecuteAction(&executeAction);
3082
3083 return hr;
3084 }
3085
3086 static HRESULT OnExecuteMsiPackage(
3087 __in HANDLE hPipe,
3088 __in BURN_CACHE* pCache,
3089 __in BURN_PACKAGES* pPackages,
3090 __in BURN_VARIABLES* pVariables,
3091 __in BYTE* pbData,
3092 __in SIZE_T cbData,
3093 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3094 )
3095 {
3096 HRESULT hr = S_OK;
3097 SIZE_T iData = 0;
3098 LPWSTR sczPackage = NULL;
3099 HWND hwndParent = NULL;
3100 BOOL fRollback = FALSE;
3101 BURN_EXECUTE_ACTION executeAction = { };
3102 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3103
3104 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE;
3105
3106 // Deserialize message data.
3107 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
3108 ExitOnFailure(hr, "Failed to read rollback flag.");
3109
3110 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3111 ExitOnFailure(hr, "Failed to read MSI package id.");
3112
3113 hr = PackageFindById(pPackages, sczPackage, &executeAction.msiPackage.pPackage);
3114 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3115
3116 hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent);
3117 ExitOnFailure(hr, "Failed to read parent hwnd.");
3118
3119 hr = BuffReadString(pbData, cbData, &iData, &executeAction.msiPackage.sczLogPath);
3120 ExitOnFailure(hr, "Failed to read package log.");
3121
3122 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.actionMsiProperty);
3123 ExitOnFailure(hr, "Failed to read actionMsiProperty.");
3124
3125 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.uiLevel);
3126 ExitOnFailure(hr, "Failed to read UI level.");
3127
3128 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.fDisableExternalUiHandler);
3129 ExitOnFailure(hr, "Failed to read fDisableExternalUiHandler.");
3130
3131 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.fileVersioning);
3132 ExitOnFailure(hr, "Failed to read fileVersioning.");
3133
3134 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.action);
3135 ExitOnFailure(hr, "Failed to read action.");
3136
3137 // Read feature actions.
3138 if (executeAction.msiPackage.pPackage->Msi.cFeatures)
3139 {
3140 executeAction.msiPackage.rgFeatures = (BOOTSTRAPPER_FEATURE_ACTION*)MemAlloc(executeAction.msiPackage.pPackage->Msi.cFeatures * sizeof(BOOTSTRAPPER_FEATURE_ACTION), TRUE);
3141 ExitOnNull(executeAction.msiPackage.rgFeatures, hr, E_OUTOFMEMORY, "Failed to allocate memory for feature actions.");
3142
3143 for (DWORD i = 0; i < executeAction.msiPackage.pPackage->Msi.cFeatures; ++i)
3144 {
3145 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.rgFeatures[i]);
3146 ExitOnFailure(hr, "Failed to read feature action.");
3147 }
3148 }
3149
3150 // Read slipstream patches actions.
3151 if (executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages)
3152 {
3153 for (DWORD i = 0; i < executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++i)
3154 {
3155 BURN_SLIPSTREAM_MSP* pSlipstreamMsp = executeAction.msiPackage.pPackage->Msi.rgSlipstreamMsps + i;
3156 BOOTSTRAPPER_ACTION_STATE* pAction = fRollback ? &pSlipstreamMsp->rollback : &pSlipstreamMsp->execute;
3157 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction);
3158 ExitOnFailure(hr, "Failed to read slipstream action.");
3159 }
3160 }
3161
3162 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
3163 ExitOnFailure(hr, "Failed to read variables.");
3164
3165 if (BURN_PACKAGE_TYPE_MSI != executeAction.msiPackage.pPackage->type)
3166 {
3167 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSI package: %ls", sczPackage);
3168 }
3169
3170 // Execute MSI package.
3171 hr = MsiEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, pRestart);
3172 ExitOnFailure(hr, "Failed to execute MSI package.");
3173
3174 LExit:
3175 ReleaseStr(sczPackage);
3176 PlanUninitializeExecuteAction(&executeAction);
3177
3178 return hr;
3179 }
3180
3181 static HRESULT OnExecuteMspPackage(
3182 __in HANDLE hPipe,
3183 __in BURN_CACHE* pCache,
3184 __in BURN_PACKAGES* pPackages,
3185 __in BURN_VARIABLES* pVariables,
3186 __in BYTE* pbData,
3187 __in SIZE_T cbData,
3188 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3189 )
3190 {
3191 HRESULT hr = S_OK;
3192 SIZE_T iData = 0;
3193 LPWSTR sczPackage = NULL;
3194 HWND hwndParent = NULL;
3195 BOOL fRollback = FALSE;
3196 BURN_EXECUTE_ACTION executeAction = { };
3197 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3198
3199 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSP_TARGET;
3200
3201 // Deserialize message data.
3202 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3203 ExitOnFailure(hr, "Failed to read MSP package id.");
3204
3205 hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.pPackage);
3206 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3207
3208 hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent);
3209 ExitOnFailure(hr, "Failed to read parent hwnd.");
3210
3211 executeAction.mspTarget.fPerMachineTarget = TRUE; // we're in the elevated process, clearly we're targeting a per-machine product.
3212
3213 hr = BuffReadString(pbData, cbData, &iData, &executeAction.mspTarget.sczTargetProductCode);
3214 ExitOnFailure(hr, "Failed to read target product code.");
3215
3216 hr = BuffReadString(pbData, cbData, &iData, &executeAction.mspTarget.sczLogPath);
3217 ExitOnFailure(hr, "Failed to read package log.");
3218
3219 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.actionMsiProperty);
3220 ExitOnFailure(hr, "Failed to read actionMsiProperty.");
3221
3222 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.uiLevel);
3223 ExitOnFailure(hr, "Failed to read UI level.");
3224
3225 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.fDisableExternalUiHandler);
3226 ExitOnFailure(hr, "Failed to read fDisableExternalUiHandler.");
3227
3228 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.fileVersioning);
3229 ExitOnFailure(hr, "Failed to read fileVersioning.");
3230
3231 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.action);
3232 ExitOnFailure(hr, "Failed to read action.");
3233
3234 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.mspTarget.cOrderedPatches);
3235 ExitOnFailure(hr, "Failed to read count of ordered patches.");
3236
3237 if (executeAction.mspTarget.cOrderedPatches)
3238 {
3239 executeAction.mspTarget.rgOrderedPatches = (BURN_ORDERED_PATCHES*)MemAlloc(executeAction.mspTarget.cOrderedPatches * sizeof(BURN_ORDERED_PATCHES), TRUE);
3240 ExitOnNull(executeAction.mspTarget.rgOrderedPatches, hr, E_OUTOFMEMORY, "Failed to allocate memory for ordered patches.");
3241
3242 for (DWORD i = 0; i < executeAction.mspTarget.cOrderedPatches; ++i)
3243 {
3244 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3245 ExitOnFailure(hr, "Failed to read ordered patch package id.");
3246
3247 hr = PackageFindById(pPackages, sczPackage, &executeAction.mspTarget.rgOrderedPatches[i].pPackage);
3248 ExitOnFailure(hr, "Failed to find ordered patch package: %ls", sczPackage);
3249 }
3250 }
3251
3252 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
3253 ExitOnFailure(hr, "Failed to read variables.");
3254
3255 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
3256 ExitOnFailure(hr, "Failed to read rollback flag.");
3257
3258 if (BURN_PACKAGE_TYPE_MSP != executeAction.mspTarget.pPackage->type)
3259 {
3260 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSP package: %ls", sczPackage);
3261 }
3262
3263 // Execute MSP package.
3264 hr = MspEngineExecutePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, pRestart);
3265 ExitOnFailure(hr, "Failed to execute MSP package.");
3266
3267 LExit:
3268 ReleaseStr(sczPackage);
3269 PlanUninitializeExecuteAction(&executeAction);
3270
3271 return hr;
3272 }
3273
3274 static HRESULT OnExecuteMsuPackage(
3275 __in HANDLE hPipe,
3276 __in BURN_CACHE* pCache,
3277 __in BURN_PACKAGES* pPackages,
3278 __in BURN_VARIABLES* pVariables,
3279 __in BYTE* pbData,
3280 __in SIZE_T cbData,
3281 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3282 )
3283 {
3284 HRESULT hr = S_OK;
3285 SIZE_T iData = 0;
3286 LPWSTR sczPackage = NULL;
3287 DWORD dwRollback = 0;
3288 DWORD dwStopWusaService = 0;
3289 BURN_EXECUTE_ACTION executeAction = { };
3290 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3291
3292 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSU_PACKAGE;
3293
3294 // Deserialize message data.
3295 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3296 ExitOnFailure(hr, "Failed to read MSU package id.");
3297
3298 hr = BuffReadString(pbData, cbData, &iData, &executeAction.msuPackage.sczLogPath);
3299 ExitOnFailure(hr, "Failed to read package log.");
3300
3301 hr = BuffReadNumber(pbData, cbData, &iData, reinterpret_cast<DWORD*>(&executeAction.msuPackage.action));
3302 ExitOnFailure(hr, "Failed to read action.");
3303
3304 hr = BuffReadNumber(pbData, cbData, &iData, &dwRollback);
3305 ExitOnFailure(hr, "Failed to read rollback.");
3306
3307 hr = BuffReadNumber(pbData, cbData, &iData, &dwStopWusaService);
3308 ExitOnFailure(hr, "Failed to read StopWusaService.");
3309
3310 hr = PackageFindById(pPackages, sczPackage, &executeAction.msuPackage.pPackage);
3311 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3312
3313 if (BURN_PACKAGE_TYPE_MSU != executeAction.msuPackage.pPackage->type)
3314 {
3315 ExitWithRootFailure(hr, E_INVALIDARG, "Package is not an MSU package: %ls", sczPackage);
3316 }
3317
3318 // execute MSU package
3319 hr = MsuEngineExecutePackage(&executeAction, pCache, pVariables, static_cast<BOOL>(dwRollback), static_cast<BOOL>(dwStopWusaService), GenericExecuteMessageHandler, hPipe, pRestart);
3320 ExitOnFailure(hr, "Failed to execute MSU package.");
3321
3322 LExit:
3323 ReleaseStr(sczPackage);
3324 PlanUninitializeExecuteAction(&executeAction);
3325
3326 return hr;
3327 }
3328
3329 static HRESULT OnUninstallMsiCompatiblePackage(
3330 __in HANDLE hPipe,
3331 __in BURN_CACHE* pCache,
3332 __in BURN_PACKAGES* pPackages,
3333 __in BURN_VARIABLES* pVariables,
3334 __in BYTE* pbData,
3335 __in SIZE_T cbData,
3336 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
3337 )
3338 {
3339 HRESULT hr = S_OK;
3340 SIZE_T iData = 0;
3341 LPWSTR sczPackageId = NULL;
3342 LPWSTR sczCompatiblePackageId = NULL;
3343 HWND hwndParent = NULL;
3344 BOOL fRollback = FALSE;
3345 BURN_EXECUTE_ACTION executeAction = { };
3346 BURN_PACKAGE* pPackage = NULL;
3347 BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL;
3348 *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
3349
3350 executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE;
3351
3352 // Deserialize message data.
3353 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
3354 ExitOnFailure(hr, "Failed to read rollback flag.");
3355
3356 hr = BuffReadString(pbData, cbData, &iData, &sczPackageId);
3357 ExitOnFailure(hr, "Failed to read MSI package id.");
3358
3359 hr = BuffReadString(pbData, cbData, &iData, &sczCompatiblePackageId);
3360 ExitOnFailure(hr, "Failed to read MSI compatible package id.");
3361
3362 hr = BuffReadPointer(pbData, cbData, &iData, (DWORD_PTR*)&hwndParent);
3363 ExitOnFailure(hr, "Failed to read parent hwnd.");
3364
3365 hr = BuffReadString(pbData, cbData, &iData, &executeAction.uninstallMsiCompatiblePackage.sczLogPath);
3366 ExitOnFailure(hr, "Failed to read package log.");
3367
3368 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
3369 ExitOnFailure(hr, "Failed to read variables.");
3370
3371 hr = PackageFindById(pPackages, sczPackageId, &pPackage);
3372 ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId);
3373
3374 executeAction.uninstallMsiCompatiblePackage.pParentPackage = pPackage;
3375 pCompatiblePackage = &pPackage->compatiblePackage;
3376
3377 if (!pCompatiblePackage->fDetected || BURN_PACKAGE_TYPE_MSI != pCompatiblePackage->type || !pCompatiblePackage->compatibleEntry.sczId)
3378 {
3379 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible MSI package", sczPackageId);
3380 }
3381
3382 if (!sczCompatiblePackageId || !*sczCompatiblePackageId ||
3383 CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1))
3384 {
3385 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId);
3386 }
3387
3388 // Uninstall MSI compatible package.
3389 hr = MsiEngineUninstallCompatiblePackage(hwndParent, &executeAction, pCache, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, pRestart);
3390 ExitOnFailure(hr, "Failed to execute compatible MSI package.");
3391
3392 LExit:
3393 ReleaseStr(sczPackageId);
3394 ReleaseStr(sczCompatiblePackageId);
3395 PlanUninitializeExecuteAction(&executeAction);
3396
3397 return hr;
3398 }
3399
3400 static HRESULT OnExecutePackageProviderAction(
3401 __in BURN_PACKAGES* pPackages,
3402 __in BURN_RELATED_BUNDLES* pRelatedBundles,
3403 __in BYTE* pbData,
3404 __in SIZE_T cbData
3405 )
3406 {
3407 HRESULT hr = S_OK;
3408 SIZE_T iData = 0;
3409 LPWSTR sczPackage = NULL;
3410 BOOL fRollback = FALSE;
3411 BURN_EXECUTE_ACTION executeAction = { };
3412
3413 executeAction.type = BURN_EXECUTE_ACTION_TYPE_PACKAGE_PROVIDER;
3414
3415 // Deserialize the message data.
3416 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3417 ExitOnFailure(hr, "Failed to read package id from message buffer.");
3418
3419 // Find the package again.
3420 hr = PackageFindById(pPackages, sczPackage, &executeAction.packageProvider.pPackage);
3421 if (E_NOTFOUND == hr)
3422 {
3423 hr = PackageFindRelatedById(pRelatedBundles, sczPackage, &executeAction.packageProvider.pPackage);
3424 }
3425 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3426
3427 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
3428 ExitOnFailure(hr, "Failed to read rollback flag.");
3429
3430 // Read provider actions.
3431 for (DWORD i = 0; i < executeAction.packageProvider.pPackage->cDependencyProviders; ++i)
3432 {
3433 BURN_DEPENDENCY_PROVIDER* pProvider = executeAction.packageProvider.pPackage->rgDependencyProviders + i;
3434 BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->providerRollback : &pProvider->providerExecute;
3435 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction);
3436 ExitOnFailure(hr, "Failed to read provider action.");
3437 }
3438
3439 if (!executeAction.packageProvider.pPackage->fPerMachine)
3440 {
3441 ExitWithRootFailure(hr, E_INVALIDARG, "ExecutePackageProviderAction called for per-user package.");
3442 }
3443
3444 // Execute the package provider action.
3445 hr = DependencyExecutePackageProviderAction(&executeAction, fRollback);
3446 ExitOnFailure(hr, "Failed to execute package provider action.");
3447
3448 LExit:
3449 ReleaseStr(sczPackage);
3450 PlanUninitializeExecuteAction(&executeAction);
3451
3452 return hr;
3453 }
3454
3455 static HRESULT OnExecutePackageDependencyAction(
3456 __in BURN_PACKAGES* pPackages,
3457 __in BURN_RELATED_BUNDLES* pRelatedBundles,
3458 __in BYTE* pbData,
3459 __in SIZE_T cbData
3460 )
3461 {
3462 HRESULT hr = S_OK;
3463 SIZE_T iData = 0;
3464 LPWSTR sczPackage = NULL;
3465 BOOL fRollback = FALSE;
3466 BURN_EXECUTE_ACTION executeAction = { };
3467
3468 executeAction.type = BURN_EXECUTE_ACTION_TYPE_PACKAGE_DEPENDENCY;
3469
3470 // Deserialize the message data.
3471 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3472 ExitOnFailure(hr, "Failed to read package id from message buffer.");
3473
3474 // Find the package again.
3475 hr = PackageFindById(pPackages, sczPackage, &executeAction.packageDependency.pPackage);
3476 if (E_NOTFOUND == hr)
3477 {
3478 hr = PackageFindRelatedById(pRelatedBundles, sczPackage, &executeAction.packageDependency.pPackage);
3479 }
3480 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3481
3482 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
3483 ExitOnFailure(hr, "Failed to read rollback flag.");
3484
3485 hr = BuffReadString(pbData, cbData, &iData, &executeAction.packageDependency.sczBundleProviderKey);
3486 ExitOnFailure(hr, "Failed to read bundle dependency key from message buffer.");
3487
3488 // Read dependent actions.
3489 for (DWORD i = 0; i < executeAction.packageProvider.pPackage->cDependencyProviders; ++i)
3490 {
3491 BURN_DEPENDENCY_PROVIDER* pProvider = executeAction.packageProvider.pPackage->rgDependencyProviders + i;
3492 BURN_DEPENDENCY_ACTION* pAction = fRollback ? &pProvider->dependentRollback : &pProvider->dependentExecute;
3493 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction);
3494 ExitOnFailure(hr, "Failed to read dependent action.");
3495 }
3496
3497 // Execute the package dependency action.
3498 hr = DependencyExecutePackageDependencyAction(TRUE, &executeAction, fRollback);
3499 ExitOnFailure(hr, "Failed to execute package dependency action.");
3500
3501 LExit:
3502 ReleaseStr(sczPackage);
3503 PlanUninitializeExecuteAction(&executeAction);
3504
3505 return hr;
3506 }
3507
3508 static HRESULT CALLBACK BurnCacheMessageHandler(
3509 __in BURN_CACHE_MESSAGE* pMessage,
3510 __in LPVOID pvContext
3511 )
3512 {
3513 HRESULT hr = S_OK;
3514 DWORD dwResult = 0;
3515 HANDLE hPipe = (HANDLE)pvContext;
3516 BYTE* pbData = NULL;
3517 SIZE_T cbData = 0;
3518 DWORD dwMessage = 0;
3519
3520 switch (pMessage->type)
3521 {
3522 case BURN_CACHE_MESSAGE_BEGIN:
3523 // serialize message data
3524 hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep);
3525 ExitOnFailure(hr, "Failed to write cache step to message buffer.");
3526
3527 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN;
3528 break;
3529
3530 case BURN_CACHE_MESSAGE_COMPLETE:
3531 // serialize message data
3532 hr = BuffWriteNumber(&pbData, &cbData, pMessage->complete.hrStatus);
3533 ExitOnFailure(hr, "Failed to write error code to message buffer.");
3534
3535 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE;
3536 break;
3537
3538 case BURN_CACHE_MESSAGE_SUCCESS:
3539 hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize);
3540 ExitOnFailure(hr, "Failed to write file size to message buffer.");
3541
3542 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS;
3543 break;
3544
3545 case BURN_CACHE_MESSAGE_FAILURE:
3546 // serialize message data
3547 hr = BuffWriteNumber(&pbData, &cbData, pMessage->failure.cacheStep);
3548 ExitOnFailure(hr, "Failed to write cache step to message buffer.");
3549
3550 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE;
3551 break;
3552 }
3553
3554 // send message
3555 hr = BurnPipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult);
3556 ExitOnFailure(hr, "Failed to send burn cache message to per-user process.");
3557
3558 hr = dwResult;
3559
3560 LExit:
3561 ReleaseMem(pbData);
3562
3563 return hr;
3564 }
3565
3566 static DWORD CALLBACK ElevatedProgressRoutine(
3567 __in LARGE_INTEGER TotalFileSize,
3568 __in LARGE_INTEGER TotalBytesTransferred,
3569 __in LARGE_INTEGER /*StreamSize*/,
3570 __in LARGE_INTEGER /*StreamBytesTransferred*/,
3571 __in DWORD /*dwStreamNumber*/,
3572 __in DWORD /*dwCallbackReason*/,
3573 __in HANDLE /*hSourceFile*/,
3574 __in HANDLE /*hDestinationFile*/,
3575 __in_opt LPVOID lpData
3576 )
3577 {
3578 HRESULT hr = S_OK;
3579 DWORD dwResult = 0;
3580 HANDLE hPipe = (HANDLE)lpData;
3581 BYTE* pbData = NULL;
3582 SIZE_T cbData = 0;
3583 DWORD dwMessage = BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE;
3584
3585 hr = BuffWriteNumber64(&pbData, &cbData, TotalFileSize.QuadPart);
3586 ExitOnFailure(hr, "Failed to write total file size progress to message buffer.");
3587
3588 hr = BuffWriteNumber64(&pbData, &cbData, TotalBytesTransferred.QuadPart);
3589 ExitOnFailure(hr, "Failed to write total bytes transferred progress to message buffer.");
3590
3591 // send message
3592 hr = BurnPipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult);
3593 ExitOnFailure(hr, "Failed to send progress routine message to per-user process.");
3594
3595 LExit:
3596 ReleaseMem(pbData);
3597
3598 return dwResult;
3599 }
3600
3601 static int GenericExecuteMessageHandler(
3602 __in GENERIC_EXECUTE_MESSAGE* pMessage,
3603 __in LPVOID pvContext
3604 )
3605 {
3606 HRESULT hr = S_OK;
3607 int nResult = IDOK;
3608 HANDLE hPipe = (HANDLE)pvContext;
3609 BYTE* pbData = NULL;
3610 SIZE_T cbData = 0;
3611 DWORD dwMessage = 0;
3612
3613 hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwUIHint);
3614 ExitOnFailure(hr, "Failed to write UI flags.");
3615
3616 switch(pMessage->type)
3617 {
3618 case GENERIC_EXECUTE_MESSAGE_PROGRESS:
3619 // serialize message data
3620 hr = BuffWriteNumber(&pbData, &cbData, pMessage->progress.dwPercentage);
3621 ExitOnFailure(hr, "Failed to write progress percentage to message buffer.");
3622
3623 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS;
3624 break;
3625
3626 case GENERIC_EXECUTE_MESSAGE_PROCESS_CANCEL:
3627 hr = BuffWriteNumber(&pbData, &cbData, pMessage->processCancel.dwProcessId);
3628 ExitOnFailure(hr, "Failed to write progress percentage to message buffer.");
3629
3630 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL;
3631 break;
3632
3633 case GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED:
3634 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED;
3635 break;
3636
3637 case GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED:
3638 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_COMPLETED;
3639 break;
3640
3641 case GENERIC_EXECUTE_MESSAGE_ERROR:
3642 // serialize message data
3643 hr = BuffWriteNumber(&pbData, &cbData, pMessage->error.dwErrorCode);
3644 ExitOnFailure(hr, "Failed to write error code to message buffer.");
3645
3646 hr = BuffWriteString(&pbData, &cbData, pMessage->error.wzMessage);
3647 ExitOnFailure(hr, "Failed to write message to message buffer.");
3648
3649 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR;
3650 break;
3651
3652 case GENERIC_EXECUTE_MESSAGE_NETFX_FILES_IN_USE:
3653 hr = BuffWriteNumber(&pbData, &cbData, pMessage->filesInUse.cFiles);
3654 ExitOnFailure(hr, "Failed to count of files in use to message buffer.");
3655
3656 for (DWORD i = 0; i < pMessage->filesInUse.cFiles; ++i)
3657 {
3658 hr = BuffWriteString(&pbData, &cbData, pMessage->filesInUse.rgwzFiles[i]);
3659 ExitOnFailure(hr, "Failed to write file in use to message buffer.");
3660 }
3661
3662 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_NETFX_FILES_IN_USE;
3663 break;
3664 }
3665
3666 // send message
3667 hr = BurnPipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, reinterpret_cast<DWORD*>(&nResult));
3668 ExitOnFailure(hr, "Failed to send message to per-user process.");
3669
3670 LExit:
3671 ReleaseMem(pbData);
3672
3673 return nResult;
3674 }
3675
3676 static int MsiExecuteMessageHandler(
3677 __in WIU_MSI_EXECUTE_MESSAGE* pMessage,
3678 __in_opt LPVOID pvContext
3679 )
3680 {
3681 HRESULT hr = S_OK;
3682 int nResult = IDOK;
3683 HANDLE hPipe = (HANDLE)pvContext;
3684 BYTE* pbData = NULL;
3685 SIZE_T cbData = 0;
3686 DWORD dwMessage = 0;
3687 BOOL fRestartManager = FALSE;
3688
3689 // Always send any extra data via the struct first.
3690 hr = BuffWriteNumber(&pbData, &cbData, pMessage->cData);
3691 ExitOnFailure(hr, "Failed to write MSI data count to message buffer.");
3692
3693 for (DWORD i = 0; i < pMessage->cData; ++i)
3694 {
3695 hr = BuffWriteString(&pbData, &cbData, pMessage->rgwzData[i]);
3696 ExitOnFailure(hr, "Failed to write MSI data to message buffer.");
3697 }
3698
3699 hr = BuffWriteNumber(&pbData, &cbData, pMessage->dwUIHint);
3700 ExitOnFailure(hr, "Failed to write UI flags.");
3701
3702 switch (pMessage->type)
3703 {
3704 case WIU_MSI_EXECUTE_MESSAGE_PROGRESS:
3705 // serialize message data
3706 hr = BuffWriteNumber(&pbData, &cbData, pMessage->progress.dwPercentage);
3707 ExitOnFailure(hr, "Failed to write progress percentage to message buffer.");
3708
3709 // set message id
3710 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS;
3711 break;
3712
3713 case WIU_MSI_EXECUTE_MESSAGE_ERROR:
3714 // serialize message data
3715 hr = BuffWriteNumber(&pbData, &cbData, pMessage->error.dwErrorCode);
3716 ExitOnFailure(hr, "Failed to write error code to message buffer.");
3717
3718 hr = BuffWriteString(&pbData, &cbData, pMessage->error.wzMessage);
3719 ExitOnFailure(hr, "Failed to write message to message buffer.");
3720
3721 // set message id
3722 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR;
3723 break;
3724
3725 case WIU_MSI_EXECUTE_MESSAGE_MSI_MESSAGE:
3726 // serialize message data
3727 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pMessage->msiMessage.mt);
3728 ExitOnFailure(hr, "Failed to write MSI message type to message buffer.");
3729
3730 hr = BuffWriteString(&pbData, &cbData, pMessage->msiMessage.wzMessage);
3731 ExitOnFailure(hr, "Failed to write message to message buffer.");
3732
3733 // set message id
3734 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE;
3735 break;
3736
3737 case WIU_MSI_EXECUTE_MESSAGE_MSI_RM_FILES_IN_USE:
3738 fRestartManager = TRUE;
3739 __fallthrough;
3740 case WIU_MSI_EXECUTE_MESSAGE_MSI_FILES_IN_USE:
3741 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRestartManager);
3742 ExitOnFailure(hr, "Failed to write fRestartManager to message buffer.");
3743
3744 // set message id
3745 dwMessage = BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_FILES_IN_USE;
3746 break;
3747
3748 default:
3749 hr = E_UNEXPECTED;
3750 ExitOnFailure(hr, "Invalid MSI execute message type: %d", pMessage->type);
3751 }
3752
3753 // send message
3754 hr = BurnPipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, (DWORD*)&nResult);
3755 ExitOnFailure(hr, "Failed to send msi message to per-user process.");
3756
3757 LExit:
3758 ReleaseMem(pbData);
3759
3760 return nResult;
3761 }
3762
3763 static HRESULT OnCleanCompatiblePackage(
3764 __in BURN_CACHE* pCache,
3765 __in BURN_PACKAGES* pPackages,
3766 __in BYTE* pbData,
3767 __in SIZE_T cbData
3768 )
3769 {
3770 HRESULT hr = S_OK;
3771 SIZE_T iData = 0;
3772 LPWSTR sczPackageId = NULL;
3773 LPWSTR sczCompatiblePackageId = NULL;
3774 BURN_PACKAGE* pPackage = NULL;
3775 BURN_COMPATIBLE_PACKAGE* pCompatiblePackage = NULL;
3776
3777 // Deserialize message data.
3778 hr = BuffReadString(pbData, cbData, &iData, &sczPackageId);
3779 ExitOnFailure(hr, "Failed to read package id.");
3780
3781 hr = BuffReadString(pbData, cbData, &iData, &sczCompatiblePackageId);
3782 ExitOnFailure(hr, "Failed to read compatible package id.");
3783
3784 hr = PackageFindById(pPackages, sczPackageId, &pPackage);
3785 ExitOnFailure(hr, "Failed to find package: %ls", sczPackageId);
3786
3787 pCompatiblePackage = &pPackage->compatiblePackage;
3788
3789 if (!pCompatiblePackage->fDetected || !pCompatiblePackage->compatibleEntry.sczId || !pCompatiblePackage->sczCacheId || !*pCompatiblePackage->sczCacheId)
3790 {
3791 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package to clean.", sczPackageId);
3792 }
3793
3794 if (!sczCompatiblePackageId || !*sczCompatiblePackageId ||
3795 CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pCompatiblePackage->compatibleEntry.sczId, -1, sczCompatiblePackageId, -1))
3796 {
3797 ExitWithRootFailure(hr, E_INVALIDARG, "Package '%ls' has no compatible package with id: %ls", sczPackageId, sczCompatiblePackageId);
3798 }
3799
3800 // Remove the package from the cache.
3801 hr = CacheRemovePackage(pCache, TRUE, pCompatiblePackage->compatibleEntry.sczId, pCompatiblePackage->sczCacheId);
3802 ExitOnFailure(hr, "Failed to remove from cache compatible package: %ls", pCompatiblePackage->compatibleEntry.sczId);
3803
3804 LExit:
3805 ReleaseStr(sczPackageId);
3806 ReleaseStr(sczCompatiblePackageId);
3807 return hr;
3808 }
3809
3810 static HRESULT OnCleanPackage(
3811 __in BURN_CACHE* pCache,
3812 __in BURN_PACKAGES* pPackages,
3813 __in BYTE* pbData,
3814 __in SIZE_T cbData
3815 )
3816 {
3817 HRESULT hr = S_OK;
3818 SIZE_T iData = 0;
3819 LPWSTR sczPackage = NULL;
3820 BURN_PACKAGE* pPackage = NULL;
3821
3822 // Deserialize message data.
3823 hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
3824 ExitOnFailure(hr, "Failed to read package id.");
3825
3826 hr = PackageFindById(pPackages, sczPackage, &pPackage);
3827 ExitOnFailure(hr, "Failed to find package: %ls", sczPackage);
3828
3829 // Remove the package from the cache.
3830 hr = CacheRemovePackage(pCache, TRUE, pPackage->sczId, pPackage->sczCacheId);
3831 ExitOnFailure(hr, "Failed to remove from cache package: %ls", pPackage->sczId);
3832
3833 LExit:
3834 ReleaseStr(sczPackage);
3835 return hr;
3836 }
3837
3838 static HRESULT OnLaunchApprovedExe(
3839 __in HANDLE hPipe,
3840 __in BURN_APPROVED_EXES* pApprovedExes,
3841 __in BURN_CACHE* pCache,
3842 __in BURN_VARIABLES* pVariables,
3843 __in BYTE* pbData,
3844 __in SIZE_T cbData
3845 )
3846 {
3847 HRESULT hr = S_OK;
3848 SIZE_T iData = 0;
3849 BURN_LAUNCH_APPROVED_EXE launchApprovedExe = { };
3850 BURN_LAUNCH_APPROVED_EXE* pLaunchApprovedExe = &launchApprovedExe;
3851 BURN_APPROVED_EXE* pApprovedExe = NULL;
3852 HKEY hKey = NULL;
3853 DWORD dwProcessId = 0;
3854 BYTE* pbSendData = NULL;
3855 SIZE_T cbSendData = 0;
3856 DWORD dwResult = 0;
3857
3858 // Deserialize message data.
3859 hr = BuffReadString(pbData, cbData, &iData, &pLaunchApprovedExe->sczId);
3860 ExitOnFailure(hr, "Failed to read approved exe id.");
3861
3862 hr = BuffReadString(pbData, cbData, &iData, &pLaunchApprovedExe->sczArguments);
3863 ExitOnFailure(hr, "Failed to read approved exe arguments.");
3864
3865 hr = BuffReadNumber(pbData, cbData, &iData, &pLaunchApprovedExe->dwWaitForInputIdleTimeout);
3866 ExitOnFailure(hr, "Failed to read approved exe WaitForInputIdle timeout.");
3867
3868 hr = ApprovedExesFindById(pApprovedExes, pLaunchApprovedExe->sczId, &pApprovedExe);
3869 ExitOnFailure(hr, "The per-user process requested unknown approved exe with id: %ls", pLaunchApprovedExe->sczId);
3870
3871 LogId(REPORT_STANDARD, MSG_LAUNCH_APPROVED_EXE_SEARCH, pApprovedExe->sczKey, pApprovedExe->sczValueName ? pApprovedExe->sczValueName : L"", pApprovedExe->fWin64 ? L"yes" : L"no");
3872
3873 hr = RegOpenEx(HKEY_LOCAL_MACHINE, pApprovedExe->sczKey, KEY_QUERY_VALUE, pApprovedExe->fWin64 ? REG_KEY_64BIT : REG_KEY_32BIT, &hKey);
3874 ExitOnFailure(hr, "Failed to open the registry key for the approved exe path.");
3875
3876 hr = RegReadString(hKey, pApprovedExe->sczValueName, &pLaunchApprovedExe->sczExecutablePath);
3877 ExitOnFailure(hr, "Failed to read the value for the approved exe path.");
3878
3879 hr = ApprovedExesVerifySecureLocation(pCache, pVariables, pLaunchApprovedExe->sczExecutablePath);
3880 ExitOnFailure(hr, "Failed to verify the executable path is in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath);
3881 if (S_FALSE == hr)
3882 {
3883 LogStringLine(REPORT_STANDARD, "The executable path is not in a secure location: %ls", pLaunchApprovedExe->sczExecutablePath);
3884 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED));
3885 }
3886
3887 hr = ApprovedExesLaunch(pVariables, pLaunchApprovedExe, &dwProcessId);
3888 ExitOnFailure(hr, "Failed to launch approved exe: %ls", pLaunchApprovedExe->sczExecutablePath);
3889
3890 //send process id over pipe
3891 hr = BuffWriteNumber(&pbSendData, &cbSendData, dwProcessId);
3892 ExitOnFailure(hr, "Failed to write the approved exe process id to message buffer.");
3893
3894 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID, pbSendData, cbSendData, NULL, NULL, &dwResult);
3895 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID message to per-user process.");
3896
3897 LExit:
3898 ReleaseMem(pbSendData);
3899 ApprovedExesUninitializeLaunch(pLaunchApprovedExe);
3900 return hr;
3901 }
3902
3903 static HRESULT OnMsiBeginTransaction(
3904 __in BURN_PACKAGES* pPackages,
3905 __in BYTE* pbData,
3906 __in SIZE_T cbData
3907 )
3908 {
3909 HRESULT hr = S_OK;
3910 SIZE_T iData = 0;
3911 LPWSTR sczId = NULL;
3912 LPWSTR sczLogPath = NULL;
3913 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
3914
3915 // Deserialize message data.
3916 hr = BuffReadString(pbData, cbData, &iData, &sczId);
3917 ExitOnFailure(hr, "Failed to read rollback boundary id.");
3918
3919 hr = BuffReadString(pbData, cbData, &iData, &sczLogPath);
3920 ExitOnFailure(hr, "Failed to read transaction log path.");
3921
3922 hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary);
3923 ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId);
3924
3925 if (sczLogPath && *sczLogPath)
3926 {
3927 pRollbackBoundary->sczLogPath = sczLogPath;
3928 }
3929
3930 hr = MsiEngineBeginTransaction(pRollbackBoundary);
3931
3932 LExit:
3933 ReleaseStr(sczId);
3934 ReleaseStr(sczLogPath);
3935
3936 if (pRollbackBoundary)
3937 {
3938 pRollbackBoundary->sczLogPath = NULL;
3939 }
3940
3941 return hr;
3942 }
3943
3944 static HRESULT OnMsiCommitTransaction(
3945 __in BURN_PACKAGES* pPackages,
3946 __in BYTE* pbData,
3947 __in SIZE_T cbData,
3948 __out BOOTSTRAPPER_APPLY_RESTART *pRestart
3949 )
3950 {
3951 HRESULT hr = S_OK;
3952 SIZE_T iData = 0;
3953 LPWSTR sczId = NULL;
3954 LPWSTR sczLogPath = NULL;
3955 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
3956
3957 // Deserialize message data.
3958 hr = BuffReadString(pbData, cbData, &iData, &sczId);
3959 ExitOnFailure(hr, "Failed to read rollback boundary id.");
3960
3961 hr = BuffReadString(pbData, cbData, &iData, &sczLogPath);
3962 ExitOnFailure(hr, "Failed to read transaction log path.");
3963
3964 hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary);
3965 ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId);
3966
3967 if (sczLogPath && *sczLogPath)
3968 {
3969 pRollbackBoundary->sczLogPath = sczLogPath;
3970 }
3971
3972 hr = MsiEngineCommitTransaction(pRollbackBoundary, pRestart);
3973
3974 LExit:
3975 ReleaseStr(sczId);
3976 ReleaseStr(sczLogPath);
3977
3978 if (pRollbackBoundary)
3979 {
3980 pRollbackBoundary->sczLogPath = NULL;
3981 }
3982
3983 return hr;
3984 }
3985
3986 static HRESULT OnMsiRollbackTransaction(
3987 __in BURN_PACKAGES* pPackages,
3988 __in BYTE* pbData,
3989 __in SIZE_T cbData,
3990 __out BOOTSTRAPPER_APPLY_RESTART *pRestart
3991 )
3992 {
3993 HRESULT hr = S_OK;
3994 SIZE_T iData = 0;
3995 LPWSTR sczId = NULL;
3996 LPWSTR sczLogPath = NULL;
3997 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
3998
3999 // Deserialize message data.
4000 hr = BuffReadString(pbData, cbData, &iData, &sczId);
4001 ExitOnFailure(hr, "Failed to read rollback boundary id.");
4002
4003 hr = BuffReadString(pbData, cbData, &iData, &sczLogPath);
4004 ExitOnFailure(hr, "Failed to read transaction log path.");
4005
4006 hr = PackageFindRollbackBoundaryById(pPackages, sczId, &pRollbackBoundary);
4007 ExitOnFailure(hr, "Failed to find rollback boundary: %ls", sczId);
4008
4009 if (sczLogPath && *sczLogPath)
4010 {
4011 pRollbackBoundary->sczLogPath = sczLogPath;
4012 }
4013
4014 hr = MsiEngineRollbackTransaction(pRollbackBoundary, pRestart);
4015
4016 LExit:
4017 ReleaseStr(sczId);
4018 ReleaseStr(sczLogPath);
4019
4020 if (pRollbackBoundary)
4021 {
4022 pRollbackBoundary->sczLogPath = NULL;
4023 }
4024
4025 return hr;
4026 }
4027
4028 static HRESULT ElevatedOnPauseAUBegin(
4029 __in HANDLE hPipe
4030 )
4031 {
4032 HRESULT hr = S_OK;
4033 DWORD dwResult = 0;
4034
4035 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN, NULL, 0, NULL, NULL, &dwResult);
4036 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_BEGIN message to per-user process.");
4037
4038 LExit:
4039 return hr;
4040 }
4041
4042 static HRESULT ElevatedOnPauseAUComplete(
4043 __in HANDLE hPipe,
4044 __in HRESULT hrStatus
4045 )
4046 {
4047 HRESULT hr = S_OK;
4048 BYTE* pbSendData = NULL;
4049 SIZE_T cbSendData = 0;
4050 DWORD dwResult = 0;
4051
4052 hr = BuffWriteNumber(&pbSendData, &cbSendData, hrStatus);
4053 ExitOnFailure(hr, "Failed to write the pause au status to message buffer.");
4054
4055 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult);
4056 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE message to per-user process.");
4057
4058 LExit:
4059 ReleaseMem(pbSendData);
4060
4061 return hr;
4062 }
4063
4064 static HRESULT ElevatedOnSystemRestorePointBegin(
4065 __in HANDLE hPipe
4066 )
4067 {
4068 HRESULT hr = S_OK;
4069 DWORD dwResult = 0;
4070
4071 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN, NULL, 0, NULL, NULL, &dwResult);
4072 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN message to per-user process.");
4073
4074 LExit:
4075 return hr;
4076 }
4077
4078 static HRESULT ElevatedOnSystemRestorePointComplete(
4079 __in HANDLE hPipe,
4080 __in HRESULT hrStatus
4081 )
4082 {
4083 HRESULT hr = S_OK;
4084 BYTE* pbSendData = NULL;
4085 SIZE_T cbSendData = 0;
4086 DWORD dwResult = 0;
4087
4088 hr = BuffWriteNumber(&pbSendData, &cbSendData, hrStatus);
4089 ExitOnFailure(hr, "Failed to write the system restore point status to message buffer.");
4090
4091 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult);
4092 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE message to per-user process.");
4093
4094 LExit:
4095 ReleaseMem(pbSendData);
4096
4097 return hr;
4098 }
4099
4100 static HRESULT ElevatedOnExecuteActionComplete(
4101 __in HANDLE hPipe,
4102 __in BOOTSTRAPPER_APPLY_RESTART restart
4103 )
4104 {
4105 HRESULT hr = S_OK;
4106 BYTE* pbSendData = NULL;
4107 SIZE_T cbSendData = 0;
4108 DWORD dwResult = 0;
4109
4110 hr = BuffWriteNumber(&pbSendData, &cbSendData, restart);
4111 ExitOnFailure(hr, "Failed to write the restart type to message buffer.");
4112
4113 hr = BurnPipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE, pbSendData, cbSendData, NULL, NULL, &dwResult);
4114 ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ACTION_COMPLETE message to per-user process.");
4115
4116 LExit:
4117 ReleaseMem(pbSendData);
4118
4119 return hr;
4120 }