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