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