aboutsummaryrefslogtreecommitdiff
path: root/src/engine/userexperience.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/engine/userexperience.cpp2122
1 files changed, 2122 insertions, 0 deletions
diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp
new file mode 100644
index 00000000..8d5271aa
--- /dev/null
+++ b/src/engine/userexperience.cpp
@@ -0,0 +1,2122 @@
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// internal function declarations
6
7static int FilterResult(
8 __in DWORD dwAllowedResults,
9 __in int nResult
10 );
11
12static HRESULT FilterExecuteResult(
13 __in BURN_USER_EXPERIENCE* pUserExperience,
14 __in HRESULT hrStatus,
15 __in BOOL fRollback,
16 __in BOOL fCancel,
17 __in LPCWSTR sczEventName
18 );
19
20
21// function definitions
22
23/*******************************************************************
24 UserExperienceParseFromXml -
25
26*******************************************************************/
27extern "C" HRESULT UserExperienceParseFromXml(
28 __in BURN_USER_EXPERIENCE* pUserExperience,
29 __in IXMLDOMNode* pixnBundle
30 )
31{
32 HRESULT hr = S_OK;
33 IXMLDOMNode* pixnUserExperienceNode = NULL;
34
35 // select UX node
36 hr = XmlSelectSingleNode(pixnBundle, L"UX", &pixnUserExperienceNode);
37 if (S_FALSE == hr)
38 {
39 hr = E_NOTFOUND;
40 }
41 ExitOnFailure(hr, "Failed to select user experience node.");
42
43 // parse splash screen
44 hr = XmlGetYesNoAttribute(pixnUserExperienceNode, L"SplashScreen", &pUserExperience->fSplashScreen);
45 if (E_NOTFOUND != hr)
46 {
47 ExitOnFailure(hr, "Failed to to get UX/@SplashScreen");
48 }
49
50 // parse payloads
51 hr = PayloadsParseFromXml(&pUserExperience->payloads, NULL, NULL, pixnUserExperienceNode);
52 ExitOnFailure(hr, "Failed to parse user experience payloads.");
53
54 // make sure we have at least one payload
55 if (0 == pUserExperience->payloads.cPayloads)
56 {
57 hr = E_UNEXPECTED;
58 ExitOnFailure(hr, "Too few UX payloads.");
59 }
60
61LExit:
62 ReleaseObject(pixnUserExperienceNode);
63
64 return hr;
65}
66
67/*******************************************************************
68 UserExperienceUninitialize -
69
70*******************************************************************/
71extern "C" void UserExperienceUninitialize(
72 __in BURN_USER_EXPERIENCE* pUserExperience
73 )
74{
75 ReleaseStr(pUserExperience->sczTempDirectory);
76 PayloadsUninitialize(&pUserExperience->payloads);
77
78 // clear struct
79 memset(pUserExperience, 0, sizeof(BURN_USER_EXPERIENCE));
80}
81
82/*******************************************************************
83 UserExperienceLoad -
84
85*******************************************************************/
86extern "C" HRESULT UserExperienceLoad(
87 __in BURN_USER_EXPERIENCE* pUserExperience,
88 __in BOOTSTRAPPER_ENGINE_CONTEXT* pEngineContext,
89 __in BOOTSTRAPPER_COMMAND* pCommand
90 )
91{
92 HRESULT hr = S_OK;
93 BOOTSTRAPPER_CREATE_ARGS args = { };
94 BOOTSTRAPPER_CREATE_RESULTS results = { };
95
96 args.cbSize = sizeof(BOOTSTRAPPER_CREATE_ARGS);
97 args.pCommand = pCommand;
98 args.pfnBootstrapperEngineProc = EngineForApplicationProc;
99 args.pvBootstrapperEngineProcContext = pEngineContext;
100 args.qwEngineAPIVersion = MAKEQWORDVERSION(0, 0, 0, 5); // TODO: need to decide whether to keep this, and if so when to update it.
101
102 results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS);
103
104 // Load BA DLL.
105 pUserExperience->hUXModule = ::LoadLibraryExW(pUserExperience->payloads.rgPayloads[0].sczLocalFilePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
106 ExitOnNullWithLastError(pUserExperience->hUXModule, hr, "Failed to load UX DLL.");
107
108 // Get BootstrapperApplicationCreate entry-point.
109 PFN_BOOTSTRAPPER_APPLICATION_CREATE pfnCreate = (PFN_BOOTSTRAPPER_APPLICATION_CREATE)::GetProcAddress(pUserExperience->hUXModule, "BootstrapperApplicationCreate");
110 ExitOnNullWithLastError(pfnCreate, hr, "Failed to get BootstrapperApplicationCreate entry-point");
111
112 // Create BA.
113 hr = pfnCreate(&args, &results);
114 ExitOnFailure(hr, "Failed to create BA.");
115
116 pUserExperience->pfnBAProc = results.pfnBootstrapperApplicationProc;
117 pUserExperience->pvBAProcContext = results.pvBootstrapperApplicationProcContext;
118
119LExit:
120 return hr;
121}
122
123/*******************************************************************
124 UserExperienceUnload -
125
126*******************************************************************/
127extern "C" HRESULT UserExperienceUnload(
128 __in BURN_USER_EXPERIENCE* pUserExperience
129 )
130{
131 HRESULT hr = S_OK;
132
133 if (pUserExperience->hUXModule)
134 {
135 // Get BootstrapperApplicationDestroy entry-point and call it if it exists.
136 PFN_BOOTSTRAPPER_APPLICATION_DESTROY pfnDestroy = (PFN_BOOTSTRAPPER_APPLICATION_DESTROY)::GetProcAddress(pUserExperience->hUXModule, "BootstrapperApplicationDestroy");
137 if (pfnDestroy)
138 {
139 pfnDestroy();
140 }
141
142 // Free BA DLL.
143 if (!::FreeLibrary(pUserExperience->hUXModule))
144 {
145 hr = HRESULT_FROM_WIN32(::GetLastError());
146 TraceError(hr, "Failed to unload BA DLL.");
147 }
148 pUserExperience->hUXModule = NULL;
149 }
150
151//LExit:
152 return hr;
153}
154
155extern "C" HRESULT UserExperienceEnsureWorkingFolder(
156 __in LPCWSTR wzBundleId,
157 __deref_out_z LPWSTR* psczUserExperienceWorkingFolder
158 )
159{
160 HRESULT hr = S_OK;
161 LPWSTR sczWorkingFolder = NULL;
162
163 hr = CacheEnsureWorkingFolder(wzBundleId, &sczWorkingFolder);
164 ExitOnFailure(hr, "Failed to create working folder.");
165
166 hr = StrAllocFormatted(psczUserExperienceWorkingFolder, L"%ls%ls\\", sczWorkingFolder, L".ba");
167 ExitOnFailure(hr, "Failed to calculate the bootstrapper application working path.");
168
169 hr = DirEnsureExists(*psczUserExperienceWorkingFolder, NULL);
170 ExitOnFailure(hr, "Failed create bootstrapper application working folder.");
171
172LExit:
173 ReleaseStr(sczWorkingFolder);
174
175 return hr;
176}
177
178
179extern "C" HRESULT UserExperienceRemove(
180 __in BURN_USER_EXPERIENCE* pUserExperience
181 )
182{
183 HRESULT hr = S_OK;
184
185 // Remove temporary UX directory
186 if (pUserExperience->sczTempDirectory)
187 {
188 hr = DirEnsureDeleteEx(pUserExperience->sczTempDirectory, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE);
189 TraceError(hr, "Could not delete bootstrapper application folder. Some files will be left in the temp folder.");
190 }
191
192//LExit:
193 return hr;
194}
195
196extern "C" int UserExperienceSendError(
197 __in BURN_USER_EXPERIENCE* pUserExperience,
198 __in BOOTSTRAPPER_ERROR_TYPE errorType,
199 __in_z_opt LPCWSTR wzPackageId,
200 __in HRESULT hrCode,
201 __in_z_opt LPCWSTR wzError,
202 __in DWORD uiFlags,
203 __in int nRecommendation
204 )
205{
206 int nResult = nRecommendation;
207 DWORD dwCode = HRESULT_CODE(hrCode);
208 LPWSTR sczError = NULL;
209
210 // If no error string was provided, try to get the error string from the HRESULT.
211 if (!wzError)
212 {
213 if (SUCCEEDED(StrAllocFromError(&sczError, hrCode, NULL)))
214 {
215 wzError = sczError;
216 }
217 }
218
219 UserExperienceOnError(pUserExperience, errorType, wzPackageId, dwCode, wzError, uiFlags, 0, NULL, &nResult); // ignore return value.
220
221 ReleaseStr(sczError);
222 return nResult;
223}
224
225extern "C" HRESULT UserExperienceActivateEngine(
226 __in BURN_USER_EXPERIENCE* pUserExperience,
227 __out_opt BOOL* pfActivated
228 )
229{
230 HRESULT hr = S_OK;
231 BOOL fActivated;
232
233 ::EnterCriticalSection(&pUserExperience->csEngineActive);
234 if (InterlockedCompareExchange(reinterpret_cast<LONG*>(&pUserExperience->fEngineActive), TRUE, FALSE))
235 {
236 AssertSz(FALSE, "Engine should have been deactivated before activating it.");
237
238 fActivated = FALSE;
239 hr = HRESULT_FROM_WIN32(ERROR_INVALID_STATE);
240 }
241 else
242 {
243 fActivated = TRUE;
244 }
245 ::LeaveCriticalSection(&pUserExperience->csEngineActive);
246
247 if (pfActivated)
248 {
249 *pfActivated = fActivated;
250 }
251 ExitOnRootFailure(hr, "Engine active cannot be changed because it was already in that state.");
252
253LExit:
254 return hr;
255}
256
257extern "C" void UserExperienceDeactivateEngine(
258 __in BURN_USER_EXPERIENCE* pUserExperience
259 )
260{
261 BOOL fActive = InterlockedExchange(reinterpret_cast<LONG*>(&pUserExperience->fEngineActive), FALSE);
262 fActive = fActive; // prevents warning in "ship" build.
263 AssertSz(fActive, "Engine should have be active before deactivating it.");
264}
265
266extern "C" HRESULT UserExperienceEnsureEngineInactive(
267 __in BURN_USER_EXPERIENCE* pUserExperience
268 )
269{
270 HRESULT hr = pUserExperience->fEngineActive ? HRESULT_FROM_WIN32(ERROR_BUSY) : S_OK;
271 ExitOnRootFailure(hr, "Engine is active, cannot proceed.");
272
273LExit:
274 return hr;
275}
276
277extern "C" void UserExperienceExecuteReset(
278 __in BURN_USER_EXPERIENCE* pUserExperience
279 )
280{
281 pUserExperience->hrApplyError = S_OK;
282 pUserExperience->hwndApply = NULL;
283}
284
285extern "C" void UserExperienceExecutePhaseComplete(
286 __in BURN_USER_EXPERIENCE* pUserExperience,
287 __in HRESULT hrResult
288 )
289{
290 if (FAILED(hrResult))
291 {
292 pUserExperience->hrApplyError = hrResult;
293 }
294}
295
296EXTERN_C BAAPI UserExperienceOnApplyBegin(
297 __in BURN_USER_EXPERIENCE* pUserExperience,
298 __in DWORD dwPhaseCount
299 )
300{
301 HRESULT hr = S_OK;
302 BA_ONAPPLYBEGIN_ARGS args = { };
303 BA_ONAPPLYBEGIN_RESULTS results = { };
304
305 args.cbSize = sizeof(args);
306 args.dwPhaseCount = dwPhaseCount;
307
308 results.cbSize = sizeof(results);
309
310 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYBEGIN, &args, &results, pUserExperience->pvBAProcContext);
311 ExitOnFailure(hr, "BA OnApplyBegin failed.");
312
313 if (results.fCancel)
314 {
315 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
316 }
317
318LExit:
319 return hr;
320}
321
322EXTERN_C BAAPI UserExperienceOnApplyComplete(
323 __in BURN_USER_EXPERIENCE* pUserExperience,
324 __in HRESULT hrStatus,
325 __in BOOTSTRAPPER_APPLY_RESTART restart,
326 __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction
327 )
328{
329 HRESULT hr = S_OK;
330 BA_ONAPPLYCOMPLETE_ARGS args = { };
331 BA_ONAPPLYCOMPLETE_RESULTS results = { };
332
333 args.cbSize = sizeof(args);
334 args.hrStatus = hrStatus;
335 args.restart = restart;
336 args.recommendation = *pAction;
337
338 results.cbSize = sizeof(results);
339 results.action = *pAction;
340
341 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
342 ExitOnFailure(hr, "BA OnApplyComplete failed.");
343
344 *pAction = results.action;
345
346LExit:
347 return hr;
348}
349
350EXTERN_C BAAPI UserExperienceOnCacheAcquireBegin(
351 __in BURN_USER_EXPERIENCE* pUserExperience,
352 __in_z_opt LPCWSTR wzPackageOrContainerId,
353 __in_z_opt LPCWSTR wzPayloadId,
354 __in BOOTSTRAPPER_CACHE_OPERATION operation,
355 __in_z LPCWSTR wzSource
356 )
357{
358 HRESULT hr = S_OK;
359 BA_ONCACHEACQUIREBEGIN_ARGS args = { };
360 BA_ONCACHEACQUIREBEGIN_RESULTS results = { };
361
362 args.cbSize = sizeof(args);
363 args.wzPackageOrContainerId = wzPackageOrContainerId;
364 args.wzPayloadId = wzPayloadId;
365 args.operation = operation;
366 args.wzSource = wzSource;
367
368 results.cbSize = sizeof(results);
369
370 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREBEGIN, &args, &results, pUserExperience->pvBAProcContext);
371 ExitOnFailure(hr, "BA OnCacheAcquireBegin failed.");
372
373 if (results.fCancel)
374 {
375 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
376 }
377
378LExit:
379 return hr;
380}
381
382EXTERN_C BAAPI UserExperienceOnCacheAcquireComplete(
383 __in BURN_USER_EXPERIENCE* pUserExperience,
384 __in_z_opt LPCWSTR wzPackageOrContainerId,
385 __in_z_opt LPCWSTR wzPayloadId,
386 __in HRESULT hrStatus,
387 __inout BOOL* pfRetry
388 )
389{
390 HRESULT hr = S_OK;
391 BA_ONCACHEACQUIRECOMPLETE_ARGS args = { };
392 BA_ONCACHEACQUIRECOMPLETE_RESULTS results = { };
393
394 args.cbSize = sizeof(args);
395 args.wzPackageOrContainerId = wzPackageOrContainerId;
396 args.wzPayloadId = wzPayloadId;
397 args.hrStatus = hrStatus;
398 args.recommendation = *pfRetry ? BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY : BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_NONE;
399
400 results.cbSize = sizeof(results);
401 results.action = args.recommendation;
402
403 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIRECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
404 ExitOnFailure(hr, "BA OnCacheAcquireComplete failed.");
405
406 if (FAILED(hrStatus))
407 {
408 *pfRetry = BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY == results.action;
409 }
410
411LExit:
412 return hr;
413}
414
415EXTERN_C BAAPI UserExperienceOnCacheAcquireProgress(
416 __in BURN_USER_EXPERIENCE* pUserExperience,
417 __in_z_opt LPCWSTR wzPackageOrContainerId,
418 __in_z_opt LPCWSTR wzPayloadId,
419 __in DWORD64 dw64Progress,
420 __in DWORD64 dw64Total,
421 __in DWORD dwOverallPercentage
422 )
423{
424 HRESULT hr = S_OK;
425 BA_ONCACHEACQUIREPROGRESS_ARGS args = { };
426 BA_ONCACHEACQUIREPROGRESS_RESULTS results = { };
427
428 args.cbSize = sizeof(args);
429 args.wzPackageOrContainerId = wzPackageOrContainerId;
430 args.wzPayloadId = wzPayloadId;
431 args.dw64Progress = dw64Progress;
432 args.dw64Total = dw64Total;
433 args.dwOverallPercentage = dwOverallPercentage;
434
435 results.cbSize = sizeof(results);
436
437 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEACQUIREPROGRESS, &args, &results, pUserExperience->pvBAProcContext);
438 ExitOnFailure(hr, "BA OnCacheAcquireProgress failed.");
439
440 if (results.fCancel)
441 {
442 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
443 }
444
445LExit:
446 return hr;
447}
448
449EXTERN_C BAAPI UserExperienceOnCacheBegin(
450 __in BURN_USER_EXPERIENCE* pUserExperience
451 )
452{
453 HRESULT hr = S_OK;
454 BA_ONCACHEBEGIN_ARGS args = { };
455 BA_ONCACHEBEGIN_RESULTS results = { };
456
457 args.cbSize = sizeof(args);
458
459 results.cbSize = sizeof(results);
460
461 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
462 ExitOnFailure(hr, "BA OnCacheBegin failed.");
463
464 if (results.fCancel)
465 {
466 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
467 }
468
469LExit:
470 return hr;
471}
472
473EXTERN_C BAAPI UserExperienceOnCacheComplete(
474 __in BURN_USER_EXPERIENCE* pUserExperience,
475 __in HRESULT hrStatus
476 )
477{
478 HRESULT hr = S_OK;
479 BA_ONCACHECOMPLETE_ARGS args = { };
480 BA_ONCACHECOMPLETE_RESULTS results = { };
481
482 args.cbSize = sizeof(args);
483 args.hrStatus = hrStatus;
484
485 results.cbSize = sizeof(results);
486
487 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
488 ExitOnFailure(hr, "BA OnCacheComplete failed.");
489
490LExit:
491 return hr;
492}
493
494EXTERN_C BAAPI UserExperienceOnCachePackageBegin(
495 __in BURN_USER_EXPERIENCE* pUserExperience,
496 __in_z LPCWSTR wzPackageId,
497 __in DWORD cCachePayloads,
498 __in DWORD64 dw64PackageCacheSize
499 )
500{
501 HRESULT hr = S_OK;
502 BA_ONCACHEPACKAGEBEGIN_ARGS args = { };
503 BA_ONCACHEPACKAGEBEGIN_RESULTS results = { };
504
505 args.cbSize = sizeof(args);
506 args.wzPackageId = wzPackageId;
507 args.cCachePayloads = cCachePayloads;
508 args.dw64PackageCacheSize = dw64PackageCacheSize;
509
510 results.cbSize = sizeof(results);
511
512 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
513 ExitOnFailure(hr, "BA OnCachePackageBegin failed.");
514
515 if (results.fCancel)
516 {
517 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
518 }
519
520LExit:
521 return hr;
522}
523
524EXTERN_C BAAPI UserExperienceOnCachePackageComplete(
525 __in BURN_USER_EXPERIENCE* pUserExperience,
526 __in_z LPCWSTR wzPackageId,
527 __in HRESULT hrStatus,
528 __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction
529 )
530{
531 HRESULT hr = S_OK;
532 BA_ONCACHEPACKAGECOMPLETE_ARGS args = { };
533 BA_ONCACHEPACKAGECOMPLETE_RESULTS results = { };
534
535 args.cbSize = sizeof(args);
536 args.wzPackageId = wzPackageId;
537 args.hrStatus = hrStatus;
538 args.recommendation = *pAction;
539
540 results.cbSize = sizeof(results);
541 results.action = *pAction;
542
543 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
544 ExitOnFailure(hr, "BA OnCachePackageComplete failed.");
545
546 if (FAILED(hrStatus))
547 {
548 *pAction = results.action;
549 }
550
551LExit:
552 return hr;
553}
554
555EXTERN_C BAAPI UserExperienceOnCacheVerifyBegin(
556 __in BURN_USER_EXPERIENCE* pUserExperience,
557 __in_z_opt LPCWSTR wzPackageOrContainerId,
558 __in_z_opt LPCWSTR wzPayloadId
559 )
560{
561 HRESULT hr = S_OK;
562 BA_ONCACHEVERIFYBEGIN_ARGS args = { };
563 BA_ONCACHEVERIFYBEGIN_RESULTS results = { };
564
565 args.cbSize = sizeof(args);
566 args.wzPackageOrContainerId = wzPackageOrContainerId;
567 args.wzPayloadId = wzPayloadId;
568
569 results.cbSize = sizeof(results);
570
571 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYBEGIN, &args, &results, pUserExperience->pvBAProcContext);
572 ExitOnFailure(hr, "BA OnCacheVerifyBegin failed.");
573
574 if (results.fCancel)
575 {
576 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
577 }
578
579LExit:
580 return hr;
581}
582
583EXTERN_C BAAPI UserExperienceOnCacheVerifyComplete(
584 __in BURN_USER_EXPERIENCE* pUserExperience,
585 __in_z_opt LPCWSTR wzPackageOrContainerId,
586 __in_z_opt LPCWSTR wzPayloadId,
587 __in HRESULT hrStatus,
588 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction
589 )
590{
591 HRESULT hr = S_OK;
592 BA_ONCACHEVERIFYCOMPLETE_ARGS args = { };
593 BA_ONCACHEVERIFYCOMPLETE_RESULTS results = { };
594
595 args.cbSize = sizeof(args);
596 args.wzPackageOrContainerId = wzPackageOrContainerId;
597 args.wzPayloadId = wzPayloadId;
598 args.hrStatus = hrStatus;
599 args.recommendation = *pAction;
600
601 results.cbSize = sizeof(results);
602 results.action = *pAction;
603
604 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYCOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
605 ExitOnFailure(hr, "BA OnCacheVerifyComplete failed.");
606
607 if (FAILED(hrStatus))
608 {
609 *pAction = results.action;
610 }
611
612LExit:
613 return hr;
614}
615
616EXTERN_C BAAPI UserExperienceOnDetectBegin(
617 __in BURN_USER_EXPERIENCE* pUserExperience,
618 __in BOOL fInstalled,
619 __in DWORD cPackages
620 )
621{
622 HRESULT hr = S_OK;
623 BA_ONDETECTBEGIN_ARGS args = { };
624 BA_ONDETECTBEGIN_RESULTS results = { };
625
626 args.cbSize = sizeof(args);
627 args.cPackages = cPackages;
628 args.fInstalled = fInstalled;
629
630 results.cbSize = sizeof(results);
631
632 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, &args, &results, pUserExperience->pvBAProcContext);
633 ExitOnFailure(hr, "BA OnDetectBegin failed.");
634
635 if (results.fCancel)
636 {
637 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
638 }
639
640LExit:
641 return hr;
642}
643
644EXTERN_C BAAPI UserExperienceOnDetectCompatibleMsiPackage(
645 __in BURN_USER_EXPERIENCE* pUserExperience,
646 __in_z LPCWSTR wzPackageId,
647 __in_z LPCWSTR wzCompatiblePackageId,
648 __in DWORD64 dw64CompatiblePackageVersion
649 )
650{
651 HRESULT hr = S_OK;
652 BA_ONDETECTCOMPATIBLEMSIPACKAGE_ARGS args = { };
653 BA_ONDETECTCOMPATIBLEMSIPACKAGE_RESULTS results = { };
654
655 args.cbSize = sizeof(args);
656 args.wzPackageId = wzPackageId;
657 args.wzCompatiblePackageId = wzCompatiblePackageId;
658 args.dw64CompatiblePackageVersion = dw64CompatiblePackageVersion;
659
660 results.cbSize = sizeof(results);
661
662 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPATIBLEMSIPACKAGE, &args, &results, pUserExperience->pvBAProcContext);
663 ExitOnFailure(hr, "BA OnDetectCompatibleMsiPackage failed.");
664
665 if (results.fCancel)
666 {
667 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
668 }
669
670LExit:
671 return hr;
672}
673
674EXTERN_C BAAPI UserExperienceOnDetectComplete(
675 __in BURN_USER_EXPERIENCE* pUserExperience,
676 __in HRESULT hrStatus
677 )
678{
679 HRESULT hr = S_OK;
680 BA_ONDETECTCOMPLETE_ARGS args = { };
681 BA_ONDETECTCOMPLETE_RESULTS results = { };
682
683 args.cbSize = sizeof(args);
684 args.hrStatus = hrStatus;
685
686 results.cbSize = sizeof(results);
687
688 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTCOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
689 ExitOnFailure(hr, "BA OnDetectComplete failed.");
690
691LExit:
692 return hr;
693}
694
695EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle(
696 __in BURN_USER_EXPERIENCE* pUserExperience,
697 __in_z LPCWSTR wzBundleId,
698 __in BOOTSTRAPPER_RELATION_TYPE relationType,
699 __in_z LPCWSTR wzBundleTag,
700 __in BOOL fPerMachine,
701 __in DWORD64 dw64Version,
702 __inout BOOL* pfIgnoreBundle
703 )
704{
705 HRESULT hr = S_OK;
706 BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS args = { };
707 BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS results = { };
708
709 args.cbSize = sizeof(args);
710 args.wzBundleId = wzBundleId;
711 args.relationType = relationType;
712 args.wzBundleTag = wzBundleTag;
713 args.fPerMachine = fPerMachine;
714 args.dw64Version = dw64Version;
715
716 results.cbSize = sizeof(results);
717 results.fIgnoreBundle = *pfIgnoreBundle;
718
719 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, &args, &results, pUserExperience->pvBAProcContext);
720 ExitOnFailure(hr, "BA OnDetectForwardCompatibleBundle failed.");
721
722 if (results.fCancel)
723 {
724 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
725 }
726 *pfIgnoreBundle = results.fIgnoreBundle;
727
728LExit:
729 return hr;
730}
731
732EXTERN_C BAAPI UserExperienceOnDetectMsiFeature(
733 __in BURN_USER_EXPERIENCE* pUserExperience,
734 __in_z LPCWSTR wzPackageId,
735 __in_z LPCWSTR wzFeatureId,
736 __in BOOTSTRAPPER_FEATURE_STATE state
737 )
738{
739 HRESULT hr = S_OK;
740 BA_ONDETECTMSIFEATURE_ARGS args = { };
741 BA_ONDETECTMSIFEATURE_RESULTS results = { };
742
743 args.cbSize = sizeof(args);
744 args.wzPackageId = wzPackageId;
745 args.wzFeatureId = wzFeatureId;
746 args.state = state;
747
748 results.cbSize = sizeof(results);
749
750 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTMSIFEATURE, &args, &results, pUserExperience->pvBAProcContext);
751 ExitOnFailure(hr, "BA OnDetectMsiFeature failed.");
752
753 if (results.fCancel)
754 {
755 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
756 }
757
758LExit:
759 return hr;
760}
761
762EXTERN_C BAAPI UserExperienceOnDetectPackageBegin(
763 __in BURN_USER_EXPERIENCE* pUserExperience,
764 __in_z LPCWSTR wzPackageId
765 )
766{
767 HRESULT hr = S_OK;
768 BA_ONDETECTPACKAGEBEGIN_ARGS args = { };
769 BA_ONDETECTPACKAGEBEGIN_RESULTS results = { };
770
771 args.cbSize = sizeof(args);
772 args.wzPackageId = wzPackageId;
773
774 results.cbSize = sizeof(results);
775
776 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
777 ExitOnFailure(hr, "BA OnDetectPackageBegin failed.");
778
779 if (results.fCancel)
780 {
781 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
782 }
783
784LExit:
785 return hr;
786}
787
788EXTERN_C BAAPI UserExperienceOnDetectPackageComplete(
789 __in BURN_USER_EXPERIENCE* pUserExperience,
790 __in_z LPCWSTR wzPackageId,
791 __in HRESULT hrStatus,
792 __in BOOTSTRAPPER_PACKAGE_STATE state
793 )
794{
795 HRESULT hr = S_OK;
796 BA_ONDETECTPACKAGECOMPLETE_ARGS args = { };
797 BA_ONDETECTPACKAGECOMPLETE_RESULTS results = { };
798
799 args.cbSize = sizeof(args);
800 args.wzPackageId = wzPackageId;
801 args.hrStatus = hrStatus;
802 args.state = state;
803
804 results.cbSize = sizeof(results);
805
806 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTPACKAGECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
807 ExitOnFailure(hr, "BA OnDetectPackageComplete failed.");
808
809LExit:
810 return hr;
811}
812
813EXTERN_C BAAPI UserExperienceOnDetectRelatedBundle(
814 __in BURN_USER_EXPERIENCE* pUserExperience,
815 __in_z LPCWSTR wzBundleId,
816 __in BOOTSTRAPPER_RELATION_TYPE relationType,
817 __in_z LPCWSTR wzBundleTag,
818 __in BOOL fPerMachine,
819 __in DWORD64 dw64Version,
820 __in BOOTSTRAPPER_RELATED_OPERATION operation
821 )
822{
823 HRESULT hr = S_OK;
824 BA_ONDETECTRELATEDBUNDLE_ARGS args = { };
825 BA_ONDETECTRELATEDBUNDLE_RESULTS results = { };
826
827 args.cbSize = sizeof(args);
828 args.wzBundleId = wzBundleId;
829 args.relationType = relationType;
830 args.wzBundleTag = wzBundleTag;
831 args.fPerMachine = fPerMachine;
832 args.dw64Version = dw64Version;
833 args.operation = operation;
834
835 results.cbSize = sizeof(results);
836
837 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDBUNDLE, &args, &results, pUserExperience->pvBAProcContext);
838 ExitOnFailure(hr, "BA OnDetectRelatedBundle failed.");
839
840 if (results.fCancel)
841 {
842 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
843 }
844
845LExit:
846 return hr;
847}
848
849EXTERN_C BAAPI UserExperienceOnDetectRelatedMsiPackage(
850 __in BURN_USER_EXPERIENCE* pUserExperience,
851 __in_z LPCWSTR wzPackageId,
852 __in_z LPCWSTR wzUpgradeCode,
853 __in_z LPCWSTR wzProductCode,
854 __in BOOL fPerMachine,
855 __in DWORD64 dw64Version,
856 __in BOOTSTRAPPER_RELATED_OPERATION operation
857 )
858{
859 HRESULT hr = S_OK;
860 BA_ONDETECTRELATEDMSIPACKAGE_ARGS args = { };
861 BA_ONDETECTRELATEDMSIPACKAGE_RESULTS results = { };
862
863 args.cbSize = sizeof(args);
864 args.wzPackageId = wzPackageId;
865 args.wzUpgradeCode = wzUpgradeCode;
866 args.wzProductCode = wzProductCode;
867 args.fPerMachine = fPerMachine;
868 args.dw64Version = dw64Version;
869 args.operation = operation;
870
871 results.cbSize = sizeof(results);
872
873 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTRELATEDMSIPACKAGE, &args, &results, pUserExperience->pvBAProcContext);
874 ExitOnFailure(hr, "BA OnDetectRelatedMsiPackage failed.");
875
876 if (results.fCancel)
877 {
878 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
879 }
880
881LExit:
882 return hr;
883}
884
885EXTERN_C BAAPI UserExperienceOnDetectTargetMsiPackage(
886 __in BURN_USER_EXPERIENCE* pUserExperience,
887 __in_z LPCWSTR wzPackageId,
888 __in_z LPCWSTR wzProductCode,
889 __in BOOTSTRAPPER_PACKAGE_STATE patchState
890 )
891{
892 HRESULT hr = S_OK;
893 BA_ONDETECTTARGETMSIPACKAGE_ARGS args = { };
894 BA_ONDETECTTARGETMSIPACKAGE_RESULTS results = { };
895
896 args.cbSize = sizeof(args);
897 args.wzPackageId = wzPackageId;
898 args.wzProductCode = wzProductCode;
899 args.patchState = patchState;
900
901 results.cbSize = sizeof(results);
902
903 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTTARGETMSIPACKAGE, &args, &results, pUserExperience->pvBAProcContext);
904 ExitOnFailure(hr, "BA OnDetectTargetMsiPackage failed.");
905
906 if (results.fCancel)
907 {
908 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
909 }
910
911LExit:
912 return hr;
913}
914
915EXTERN_C BAAPI UserExperienceOnDetectUpdate(
916 __in BURN_USER_EXPERIENCE* pUserExperience,
917 __in_z LPCWSTR wzUpdateLocation,
918 __in DWORD64 dw64Size,
919 __in DWORD64 dw64Version,
920 __in_z_opt LPCWSTR wzTitle,
921 __in_z_opt LPCWSTR wzSummary,
922 __in_z_opt LPCWSTR wzContentType,
923 __in_z_opt LPCWSTR wzContent,
924 __inout BOOL* pfStopProcessingUpdates
925 )
926{
927 HRESULT hr = S_OK;
928 BA_ONDETECTUPDATE_ARGS args = { };
929 BA_ONDETECTUPDATE_RESULTS results = { };
930
931 args.cbSize = sizeof(args);
932 args.wzUpdateLocation = wzUpdateLocation;
933 args.dw64Size = dw64Size;
934 args.dw64Version = dw64Version;
935 args.wzTitle = wzTitle;
936 args.wzSummary = wzSummary;
937 args.wzContentType = wzContentType;
938 args.wzContent = wzContent;
939
940 results.cbSize = sizeof(results);
941 results.fStopProcessingUpdates = *pfStopProcessingUpdates;
942
943 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, &args, &results, pUserExperience->pvBAProcContext);
944 ExitOnFailure(hr, "BA OnDetectUpdate failed.");
945
946 if (results.fCancel)
947 {
948 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
949 }
950 *pfStopProcessingUpdates = results.fStopProcessingUpdates;
951
952LExit:
953 return hr;
954}
955
956EXTERN_C BAAPI UserExperienceOnDetectUpdateBegin(
957 __in BURN_USER_EXPERIENCE* pUserExperience,
958 __in_z LPCWSTR wzUpdateLocation,
959 __inout BOOL* pfSkip
960 )
961{
962 HRESULT hr = S_OK;
963 BA_ONDETECTUPDATEBEGIN_ARGS args = { };
964 BA_ONDETECTUPDATEBEGIN_RESULTS results = { };
965
966 args.cbSize = sizeof(args);
967 args.wzUpdateLocation = wzUpdateLocation;
968
969 results.cbSize = sizeof(results);
970 results.fSkip = *pfSkip;
971
972 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
973 ExitOnFailure(hr, "BA OnDetectUpdateBegin failed.");
974
975 if (results.fCancel)
976 {
977 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
978 }
979 *pfSkip = results.fSkip;
980
981LExit:
982 return hr;
983}
984
985EXTERN_C BAAPI UserExperienceOnDetectUpdateComplete(
986 __in BURN_USER_EXPERIENCE* pUserExperience,
987 __in HRESULT hrStatus,
988 __inout BOOL* pfIgnoreError
989 )
990{
991 HRESULT hr = S_OK;
992 BA_ONDETECTUPDATECOMPLETE_ARGS args = { };
993 BA_ONDETECTUPDATECOMPLETE_RESULTS results = { };
994
995 args.cbSize = sizeof(args);
996 args.hrStatus = hrStatus;
997
998 results.cbSize = sizeof(results);
999 results.fIgnoreError = *pfIgnoreError;
1000
1001 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1002 ExitOnFailure(hr, "BA OnDetectUpdateComplete failed.");
1003
1004 if (FAILED(hrStatus))
1005 {
1006 *pfIgnoreError = results.fIgnoreError;
1007 }
1008
1009LExit:
1010 return hr;
1011}
1012
1013EXTERN_C BAAPI UserExperienceOnElevateBegin(
1014 __in BURN_USER_EXPERIENCE* pUserExperience
1015 )
1016{
1017 HRESULT hr = S_OK;
1018 BA_ONELEVATEBEGIN_ARGS args = { };
1019 BA_ONELEVATEBEGIN_RESULTS results = { };
1020
1021 args.cbSize = sizeof(args);
1022
1023 results.cbSize = sizeof(results);
1024
1025 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1026 ExitOnFailure(hr, "BA OnElevateBegin failed.");
1027
1028 if (results.fCancel)
1029 {
1030 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1031 }
1032
1033LExit:
1034 return hr;
1035}
1036
1037EXTERN_C BAAPI UserExperienceOnElevateComplete(
1038 __in BURN_USER_EXPERIENCE* pUserExperience,
1039 __in HRESULT hrStatus
1040 )
1041{
1042 HRESULT hr = S_OK;
1043 BA_ONELEVATECOMPLETE_ARGS args = { };
1044 BA_ONELEVATECOMPLETE_RESULTS results = { };
1045
1046 args.cbSize = sizeof(args);
1047 args.hrStatus = hrStatus;
1048
1049 results.cbSize = sizeof(results);
1050
1051 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONELEVATECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1052 ExitOnFailure(hr, "BA OnElevateComplete failed.");
1053
1054LExit:
1055 return hr;
1056}
1057
1058EXTERN_C BAAPI UserExperienceOnError(
1059 __in BURN_USER_EXPERIENCE* pUserExperience,
1060 __in BOOTSTRAPPER_ERROR_TYPE errorType,
1061 __in_z_opt LPCWSTR wzPackageId,
1062 __in DWORD dwCode,
1063 __in_z_opt LPCWSTR wzError,
1064 __in DWORD dwUIHint,
1065 __in DWORD cData,
1066 __in_ecount_z_opt(cData) LPCWSTR* rgwzData,
1067 __inout int* pnResult
1068 )
1069{
1070 HRESULT hr = S_OK;
1071 BA_ONERROR_ARGS args = { };
1072 BA_ONERROR_RESULTS results = { };
1073
1074 args.cbSize = sizeof(args);
1075 args.errorType = errorType;
1076 args.wzPackageId = wzPackageId;
1077 args.dwCode = dwCode;
1078 args.wzError = wzError;
1079 args.dwUIHint = dwUIHint;
1080 args.cData = cData;
1081 args.rgwzData = rgwzData;
1082 args.nRecommendation = *pnResult;
1083
1084 results.cbSize = sizeof(results);
1085 results.nResult = *pnResult;
1086
1087 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONERROR, &args, &results, pUserExperience->pvBAProcContext);
1088 ExitOnFailure(hr, "BA OnError failed.");
1089
1090 *pnResult = results.nResult;
1091
1092LExit:
1093 return hr;
1094}
1095
1096EXTERN_C BAAPI UserExperienceOnExecuteBegin(
1097 __in BURN_USER_EXPERIENCE* pUserExperience,
1098 __in DWORD cExecutingPackages
1099 )
1100{
1101 HRESULT hr = S_OK;
1102 BA_ONEXECUTEBEGIN_ARGS args = { };
1103 BA_ONEXECUTEBEGIN_RESULTS results = { };
1104
1105 args.cbSize = sizeof(args);
1106 args.cExecutingPackages = cExecutingPackages;
1107
1108 results.cbSize = sizeof(results);
1109
1110 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1111 ExitOnFailure(hr, "BA OnExecuteBegin failed.");
1112
1113 if (results.fCancel)
1114 {
1115 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1116 }
1117
1118LExit:
1119 return hr;
1120}
1121
1122EXTERN_C BAAPI UserExperienceOnExecuteComplete(
1123 __in BURN_USER_EXPERIENCE* pUserExperience,
1124 __in HRESULT hrStatus
1125 )
1126{
1127 HRESULT hr = S_OK;
1128 BA_ONEXECUTECOMPLETE_ARGS args = { };
1129 BA_ONEXECUTECOMPLETE_RESULTS results = { };
1130
1131 args.cbSize = sizeof(args);
1132 args.hrStatus = hrStatus;
1133
1134 results.cbSize = sizeof(results);
1135
1136 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1137 ExitOnFailure(hr, "BA OnExecuteComplete failed.");
1138
1139LExit:
1140 return hr;
1141}
1142
1143EXTERN_C BAAPI UserExperienceOnExecuteFilesInUse(
1144 __in BURN_USER_EXPERIENCE* pUserExperience,
1145 __in_z LPCWSTR wzPackageId,
1146 __in DWORD cFiles,
1147 __in_ecount_z_opt(cFiles) LPCWSTR* rgwzFiles,
1148 __inout int* pnResult
1149 )
1150{
1151 HRESULT hr = S_OK;
1152 BA_ONEXECUTEFILESINUSE_ARGS args = { };
1153 BA_ONEXECUTEFILESINUSE_RESULTS results = { };
1154
1155 args.cbSize = sizeof(args);
1156 args.wzPackageId = wzPackageId;
1157 args.cFiles = cFiles;
1158 args.rgwzFiles = rgwzFiles;
1159 args.nRecommendation = *pnResult;
1160
1161 results.cbSize = sizeof(results);
1162 results.nResult = *pnResult;
1163
1164 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEFILESINUSE, &args, &results, pUserExperience->pvBAProcContext);
1165 ExitOnFailure(hr, "BA OnExecuteFilesInUse failed.");
1166
1167 *pnResult = results.nResult;
1168
1169LExit:
1170 return hr;
1171}
1172
1173EXTERN_C BAAPI UserExperienceOnExecuteMsiMessage(
1174 __in BURN_USER_EXPERIENCE* pUserExperience,
1175 __in_z LPCWSTR wzPackageId,
1176 __in INSTALLMESSAGE messageType,
1177 __in DWORD dwUIHint,
1178 __in_z LPCWSTR wzMessage,
1179 __in DWORD cData,
1180 __in_ecount_z_opt(cData) LPCWSTR* rgwzData,
1181 __inout int* pnResult
1182 )
1183{
1184 HRESULT hr = S_OK;
1185 BA_ONEXECUTEMSIMESSAGE_ARGS args = { };
1186 BA_ONEXECUTEMSIMESSAGE_RESULTS results = { };
1187
1188 args.cbSize = sizeof(args);
1189 args.wzPackageId = wzPackageId;
1190 args.messageType = messageType;
1191 args.dwUIHint = dwUIHint;
1192 args.wzMessage = wzMessage;
1193 args.cData = cData;
1194 args.rgwzData = rgwzData;
1195 args.nRecommendation = *pnResult;
1196
1197 results.cbSize = sizeof(results);
1198 results.nResult = *pnResult;
1199
1200 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEMSIMESSAGE, &args, &results, pUserExperience->pvBAProcContext);
1201 ExitOnFailure(hr, "BA OnExecuteMsiMessage failed.");
1202
1203 *pnResult = results.nResult;
1204
1205LExit:
1206 return hr;
1207}
1208
1209EXTERN_C BAAPI UserExperienceOnExecutePackageBegin(
1210 __in BURN_USER_EXPERIENCE* pUserExperience,
1211 __in_z LPCWSTR wzPackageId,
1212 __in BOOL fExecute
1213 )
1214{
1215 HRESULT hr = S_OK;
1216 BA_ONEXECUTEPACKAGEBEGIN_ARGS args = { };
1217 BA_ONEXECUTEPACKAGEBEGIN_RESULTS results = { };
1218
1219 args.cbSize = sizeof(args);
1220 args.wzPackageId = wzPackageId;
1221 args.fExecute = fExecute;
1222
1223 results.cbSize = sizeof(results);
1224
1225 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1226 ExitOnFailure(hr, "BA OnExecutePackageBegin failed.");
1227
1228 if (results.fCancel)
1229 {
1230 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1231 }
1232
1233LExit:
1234 return hr;
1235}
1236
1237EXTERN_C BAAPI UserExperienceOnExecutePackageComplete(
1238 __in BURN_USER_EXPERIENCE* pUserExperience,
1239 __in_z LPCWSTR wzPackageId,
1240 __in HRESULT hrStatus,
1241 __in BOOTSTRAPPER_APPLY_RESTART restart,
1242 __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction
1243 )
1244{
1245 HRESULT hr = S_OK;
1246 BA_ONEXECUTEPACKAGECOMPLETE_ARGS args = { };
1247 BA_ONEXECUTEPACKAGECOMPLETE_RESULTS results = { };
1248
1249 args.cbSize = sizeof(args);
1250 args.wzPackageId = wzPackageId;
1251 args.hrStatus = hrStatus;
1252 args.restart = restart;
1253 args.recommendation = *pAction;
1254
1255 results.cbSize = sizeof(results);
1256 results.action = *pAction;
1257
1258 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPACKAGECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1259 ExitOnFailure(hr, "BA OnExecutePackageComplete failed.");
1260
1261 *pAction = results.action;
1262
1263LExit:
1264 return hr;
1265}
1266
1267EXTERN_C BAAPI UserExperienceOnExecutePatchTarget(
1268 __in BURN_USER_EXPERIENCE* pUserExperience,
1269 __in_z LPCWSTR wzPackageId,
1270 __in_z LPCWSTR wzTargetProductCode
1271 )
1272{
1273 HRESULT hr = S_OK;
1274 BA_ONEXECUTEPATCHTARGET_ARGS args = { };
1275 BA_ONEXECUTEPATCHTARGET_RESULTS results = { };
1276
1277 args.cbSize = sizeof(args);
1278 args.wzPackageId = wzPackageId;
1279 args.wzTargetProductCode = wzTargetProductCode;
1280
1281 results.cbSize = sizeof(results);
1282
1283 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPATCHTARGET, &args, &results, pUserExperience->pvBAProcContext);
1284 ExitOnFailure(hr, "BA OnExecutePatchTarget failed.");
1285
1286 if (results.fCancel)
1287 {
1288 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1289 }
1290
1291LExit:
1292 return hr;
1293}
1294
1295EXTERN_C BAAPI UserExperienceOnExecuteProgress(
1296 __in BURN_USER_EXPERIENCE* pUserExperience,
1297 __in_z LPCWSTR wzPackageId,
1298 __in DWORD dwProgressPercentage,
1299 __in DWORD dwOverallPercentage,
1300 __out int* pnResult
1301 )
1302{
1303 HRESULT hr = S_OK;
1304 BA_ONEXECUTEPROGRESS_ARGS args = { };
1305 BA_ONEXECUTEPROGRESS_RESULTS results = { };
1306
1307 args.cbSize = sizeof(args);
1308 args.wzPackageId = wzPackageId;
1309 args.dwProgressPercentage = dwProgressPercentage;
1310 args.dwOverallPercentage = dwOverallPercentage;
1311
1312 results.cbSize = sizeof(results);
1313
1314 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONEXECUTEPROGRESS, &args, &results, pUserExperience->pvBAProcContext);
1315 ExitOnFailure(hr, "BA OnExecuteProgress failed.");
1316
1317LExit:
1318 if (FAILED(hr))
1319 {
1320 *pnResult = IDERROR;
1321 }
1322 else if (results.fCancel)
1323 {
1324 *pnResult = IDCANCEL;
1325 }
1326 else
1327 {
1328 *pnResult = IDNOACTION;
1329 }
1330 return hr;
1331}
1332
1333EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeBegin(
1334 __in BURN_USER_EXPERIENCE* pUserExperience
1335 )
1336{
1337 HRESULT hr = S_OK;
1338 BA_ONLAUNCHAPPROVEDEXEBEGIN_ARGS args = { };
1339 BA_ONLAUNCHAPPROVEDEXEBEGIN_RESULTS results = { };
1340
1341 args.cbSize = sizeof(args);
1342
1343 results.cbSize = sizeof(results);
1344
1345 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1346 ExitOnFailure(hr, "BA OnLaunchApprovedExeBegin failed.");
1347
1348 if (results.fCancel)
1349 {
1350 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1351 }
1352
1353LExit:
1354 return hr;
1355}
1356
1357EXTERN_C BAAPI UserExperienceOnLaunchApprovedExeComplete(
1358 __in BURN_USER_EXPERIENCE* pUserExperience,
1359 __in HRESULT hrStatus,
1360 __in DWORD dwProcessId
1361 )
1362{
1363 HRESULT hr = S_OK;
1364 BA_ONLAUNCHAPPROVEDEXECOMPLETE_ARGS args = { };
1365 BA_ONLAUNCHAPPROVEDEXECOMPLETE_RESULTS results = { };
1366
1367 args.cbSize = sizeof(args);
1368 args.hrStatus = hrStatus;
1369 args.dwProcessId = dwProcessId;
1370
1371 results.cbSize = sizeof(results);
1372
1373 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1374 ExitOnFailure(hr, "BA OnLaunchApprovedExeComplete failed.");
1375
1376LExit:
1377 return hr;
1378}
1379
1380EXTERN_C BAAPI UserExperienceOnPlanBegin(
1381 __in BURN_USER_EXPERIENCE* pUserExperience,
1382 __in DWORD cPackages
1383 )
1384{
1385 HRESULT hr = S_OK;
1386 BA_ONPLANBEGIN_ARGS args = { };
1387 BA_ONPLANBEGIN_RESULTS results = { };
1388
1389 args.cbSize = sizeof(args);
1390 args.cPackages = cPackages;
1391
1392 results.cbSize = sizeof(results);
1393
1394 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1395 ExitOnFailure(hr, "BA OnPlanBegin failed.");
1396
1397 if (results.fCancel)
1398 {
1399 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1400 }
1401
1402LExit:
1403 return hr;
1404}
1405
1406EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageBegin(
1407 __in BURN_USER_EXPERIENCE* pUserExperience,
1408 __in_z LPCWSTR wzPackageId,
1409 __in_z LPCWSTR wzCompatiblePackageId,
1410 __in DWORD64 dw64CompatiblePackageVersion,
1411 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
1412 )
1413{
1414 HRESULT hr = S_OK;
1415 BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_ARGS args = { };
1416 BA_ONPLANCOMPATIBLEMSIPACKAGEBEGIN_RESULTS results = { };
1417
1418 args.cbSize = sizeof(args);
1419 args.wzPackageId = wzPackageId;
1420 args.wzCompatiblePackageId = wzCompatiblePackageId;
1421 args.dw64CompatiblePackageVersion = dw64CompatiblePackageVersion;
1422 args.recommendedState = *pRequestedState;
1423
1424 results.cbSize = sizeof(results);
1425 results.requestedState = *pRequestedState;
1426
1427 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1428 ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageBegin failed.");
1429
1430 if (results.fCancel)
1431 {
1432 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1433 }
1434 *pRequestedState = results.requestedState;
1435
1436LExit:
1437 return hr;
1438}
1439
1440EXTERN_C BAAPI UserExperienceOnPlanCompatibleMsiPackageComplete(
1441 __in BURN_USER_EXPERIENCE* pUserExperience,
1442 __in_z LPCWSTR wzPackageId,
1443 __in_z LPCWSTR wzCompatiblePackageId,
1444 __in HRESULT hrStatus,
1445 __in BOOTSTRAPPER_PACKAGE_STATE state,
1446 __in BOOTSTRAPPER_REQUEST_STATE requested,
1447 __in BOOTSTRAPPER_ACTION_STATE execute,
1448 __in BOOTSTRAPPER_ACTION_STATE rollback
1449 )
1450{
1451 HRESULT hr = S_OK;
1452 BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_ARGS args = { };
1453 BA_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE_RESULTS results = { };
1454
1455 args.cbSize = sizeof(args);
1456 args.wzPackageId = wzPackageId;
1457 args.wzCompatiblePackageId = wzCompatiblePackageId;
1458 args.hrStatus = hrStatus;
1459 args.state = state;
1460 args.requested = requested;
1461 args.execute = execute;
1462 args.rollback = rollback;
1463
1464 results.cbSize = sizeof(results);
1465
1466 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPATIBLEMSIPACKAGECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1467 ExitOnFailure(hr, "BA OnPlanCompatibleMsiPackageComplete failed.");
1468
1469LExit:
1470 return hr;
1471}
1472
1473EXTERN_C BAAPI UserExperienceOnPlanMsiFeature(
1474 __in BURN_USER_EXPERIENCE* pUserExperience,
1475 __in_z LPCWSTR wzPackageId,
1476 __in_z LPCWSTR wzFeatureId,
1477 __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState
1478 )
1479{
1480 HRESULT hr = S_OK;
1481 BA_ONPLANMSIFEATURE_ARGS args = { };
1482 BA_ONPLANMSIFEATURE_RESULTS results = { };
1483
1484 args.cbSize = sizeof(args);
1485 args.wzPackageId = wzPackageId;
1486 args.wzFeatureId = wzFeatureId;
1487 args.recommendedState = *pRequestedState;
1488
1489 results.cbSize = sizeof(results);
1490 results.requestedState = *pRequestedState;
1491
1492 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIFEATURE, &args, &results, pUserExperience->pvBAProcContext);
1493 ExitOnFailure(hr, "BA OnPlanMsiFeature failed.");
1494
1495 if (results.fCancel)
1496 {
1497 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1498 }
1499 *pRequestedState = results.requestedState;
1500
1501LExit:
1502 return hr;
1503}
1504
1505EXTERN_C BAAPI UserExperienceOnPlanComplete(
1506 __in BURN_USER_EXPERIENCE* pUserExperience,
1507 __in HRESULT hrStatus
1508 )
1509{
1510 HRESULT hr = S_OK;
1511 BA_ONPLANCOMPLETE_ARGS args = { };
1512 BA_ONPLANCOMPLETE_RESULTS results = { };
1513
1514 args.cbSize = sizeof(args);
1515 args.hrStatus = hrStatus;
1516
1517 results.cbSize = sizeof(results);
1518
1519 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1520 ExitOnFailure(hr, "BA OnPlanComplete failed.");
1521
1522LExit:
1523 return hr;
1524}
1525
1526EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1527 __in BURN_USER_EXPERIENCE* pUserExperience,
1528 __in_z LPCWSTR wzPackageId,
1529 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
1530 )
1531{
1532 HRESULT hr = S_OK;
1533 BA_ONPLANPACKAGEBEGIN_ARGS args = { };
1534 BA_ONPLANPACKAGEBEGIN_RESULTS results = { };
1535
1536 args.cbSize = sizeof(args);
1537 args.wzPackageId = wzPackageId;
1538 args.recommendedState = *pRequestedState;
1539
1540 results.cbSize = sizeof(results);
1541 results.requestedState = *pRequestedState;
1542
1543 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1544 ExitOnFailure(hr, "BA OnPlanPackageBegin failed.");
1545
1546 if (results.fCancel)
1547 {
1548 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1549 }
1550 *pRequestedState = results.requestedState;
1551
1552LExit:
1553 return hr;
1554}
1555
1556EXTERN_C BAAPI UserExperienceOnPlanPackageComplete(
1557 __in BURN_USER_EXPERIENCE* pUserExperience,
1558 __in_z LPCWSTR wzPackageId,
1559 __in HRESULT hrStatus,
1560 __in BOOTSTRAPPER_PACKAGE_STATE state,
1561 __in BOOTSTRAPPER_REQUEST_STATE requested,
1562 __in BOOTSTRAPPER_ACTION_STATE execute,
1563 __in BOOTSTRAPPER_ACTION_STATE rollback
1564 )
1565{
1566 HRESULT hr = S_OK;
1567 BA_ONPLANPACKAGECOMPLETE_ARGS args = { };
1568 BA_ONPLANPACKAGECOMPLETE_RESULTS results = { };
1569
1570 args.cbSize = sizeof(args);
1571 args.wzPackageId = wzPackageId;
1572 args.hrStatus = hrStatus;
1573 args.state = state;
1574 args.requested = requested;
1575 args.execute = execute;
1576 args.rollback = rollback;
1577
1578 results.cbSize = sizeof(results);
1579
1580 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGECOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1581 ExitOnFailure(hr, "BA OnPlanPackageComplete failed.");
1582
1583LExit:
1584 return hr;
1585}
1586
1587EXTERN_C BAAPI UserExperienceOnPlanRelatedBundle(
1588 __in BURN_USER_EXPERIENCE* pUserExperience,
1589 __in_z LPCWSTR wzBundleId,
1590 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
1591 )
1592{
1593 HRESULT hr = S_OK;
1594 BA_ONPLANRELATEDBUNDLE_ARGS args = { };
1595 BA_ONPLANRELATEDBUNDLE_RESULTS results = { };
1596
1597 args.cbSize = sizeof(args);
1598 args.wzBundleId = wzBundleId;
1599 args.recommendedState = *pRequestedState;
1600
1601 results.cbSize = sizeof(results);
1602 results.requestedState = *pRequestedState;
1603
1604 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE, &args, &results, pUserExperience->pvBAProcContext);
1605 ExitOnFailure(hr, "BA OnPlanRelatedBundle failed.");
1606
1607 if (results.fCancel)
1608 {
1609 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1610 }
1611 *pRequestedState = results.requestedState;
1612
1613LExit:
1614 return hr;
1615}
1616
1617EXTERN_C BAAPI UserExperienceOnPlanTargetMsiPackage(
1618 __in BURN_USER_EXPERIENCE* pUserExperience,
1619 __in_z LPCWSTR wzPackageId,
1620 __in_z LPCWSTR wzProductCode,
1621 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
1622 )
1623{
1624 HRESULT hr = S_OK;
1625 BA_ONPLANTARGETMSIPACKAGE_ARGS args = { };
1626 BA_ONPLANTARGETMSIPACKAGE_RESULTS results = { };
1627
1628 args.cbSize = sizeof(args);
1629 args.wzPackageId = wzPackageId;
1630 args.wzProductCode = wzProductCode;
1631 args.recommendedState = *pRequestedState;
1632
1633 results.cbSize = sizeof(results);
1634 results.requestedState = *pRequestedState;
1635
1636 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANTARGETMSIPACKAGE, &args, &results, pUserExperience->pvBAProcContext);
1637 ExitOnFailure(hr, "BA OnPlanTargetMsiPackage failed.");
1638
1639 if (results.fCancel)
1640 {
1641 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1642 }
1643 *pRequestedState = results.requestedState;
1644
1645LExit:
1646 return hr;
1647}
1648
1649EXTERN_C BAAPI UserExperienceOnProgress(
1650 __in BURN_USER_EXPERIENCE* pUserExperience,
1651 __in BOOL fRollback,
1652 __in DWORD dwProgressPercentage,
1653 __in DWORD dwOverallPercentage
1654 )
1655{
1656 HRESULT hr = S_OK;
1657 BA_ONPROGRESS_ARGS args = { };
1658 BA_ONPROGRESS_RESULTS results = { };
1659
1660 args.cbSize = sizeof(args);
1661 args.dwProgressPercentage = dwProgressPercentage;
1662 args.dwOverallPercentage = dwOverallPercentage;
1663
1664 results.cbSize = sizeof(results);
1665
1666 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONPROGRESS, &args, &results, pUserExperience->pvBAProcContext);
1667 hr = FilterExecuteResult(pUserExperience, hr, fRollback, results.fCancel, L"OnProgress");
1668
1669 return hr;
1670}
1671
1672EXTERN_C BAAPI UserExperienceOnRegisterBegin(
1673 __in BURN_USER_EXPERIENCE* pUserExperience
1674 )
1675{
1676 HRESULT hr = S_OK;
1677 BA_ONREGISTERBEGIN_ARGS args = { };
1678 BA_ONREGISTERBEGIN_RESULTS results = { };
1679
1680 args.cbSize = sizeof(args);
1681
1682 results.cbSize = sizeof(results);
1683
1684 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1685 ExitOnFailure(hr, "BA OnRegisterBegin failed.");
1686
1687 if (results.fCancel)
1688 {
1689 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1690 }
1691
1692LExit:
1693 return hr;
1694}
1695
1696EXTERN_C BAAPI UserExperienceOnRegisterComplete(
1697 __in BURN_USER_EXPERIENCE* pUserExperience,
1698 __in HRESULT hrStatus
1699 )
1700{
1701 HRESULT hr = S_OK;
1702 BA_ONREGISTERCOMPLETE_ARGS args = { };
1703 BA_ONREGISTERCOMPLETE_RESULTS results = { };
1704
1705 args.cbSize = sizeof(args);
1706 args.hrStatus = hrStatus;
1707
1708 results.cbSize = sizeof(results);
1709
1710 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERCOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1711 ExitOnFailure(hr, "BA OnRegisterComplete failed.");
1712
1713LExit:
1714 return hr;
1715}
1716
1717EXTERN_C BAAPI UserExperienceOnResolveSource(
1718 __in BURN_USER_EXPERIENCE* pUserExperience,
1719 __in_z LPCWSTR wzPackageOrContainerId,
1720 __in_z_opt LPCWSTR wzPayloadId,
1721 __in_z LPCWSTR wzLocalSource,
1722 __in_z_opt LPCWSTR wzDownloadSource,
1723 __inout BOOTSTRAPPER_RESOLVESOURCE_ACTION* pAction
1724 )
1725{
1726 HRESULT hr = S_OK;
1727 BA_ONRESOLVESOURCE_ARGS args = { };
1728 BA_ONRESOLVESOURCE_RESULTS results = { };
1729
1730 args.cbSize = sizeof(args);
1731 args.wzPackageOrContainerId = wzPackageOrContainerId;
1732 args.wzPayloadId = wzPayloadId;
1733 args.wzLocalSource = wzLocalSource;
1734 args.wzDownloadSource = wzDownloadSource;
1735 args.recommendation = *pAction;
1736
1737 results.cbSize = sizeof(results);
1738 results.action = *pAction;
1739
1740 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONRESOLVESOURCE, &args, &results, pUserExperience->pvBAProcContext);
1741 ExitOnFailure(hr, "BA OnResolveSource failed.");
1742
1743 if (results.fCancel)
1744 {
1745 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1746 }
1747 else
1748 {
1749 *pAction = results.action;
1750 }
1751
1752LExit:
1753 return hr;
1754}
1755
1756EXTERN_C BAAPI UserExperienceOnShutdown(
1757 __in BURN_USER_EXPERIENCE* pUserExperience,
1758 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction
1759 )
1760{
1761 HRESULT hr = S_OK;
1762 BA_ONSHUTDOWN_ARGS args = { };
1763 BA_ONSHUTDOWN_RESULTS results = { };
1764
1765 args.cbSize = sizeof(args);
1766
1767 results.cbSize = sizeof(results);
1768 results.action = *pAction;
1769
1770 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN, &args, &results, pUserExperience->pvBAProcContext);
1771 ExitOnFailure(hr, "BA OnShutdown failed.");
1772
1773 *pAction = results.action;
1774
1775LExit:
1776 return hr;
1777}
1778
1779EXTERN_C BAAPI UserExperienceOnStartup(
1780 __in BURN_USER_EXPERIENCE* pUserExperience
1781 )
1782{
1783 HRESULT hr = S_OK;
1784 BA_ONSTARTUP_ARGS args = { };
1785 BA_ONSTARTUP_RESULTS results = { };
1786
1787 args.cbSize = sizeof(args);
1788
1789 results.cbSize = sizeof(results);
1790
1791 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP, &args, &results, pUserExperience->pvBAProcContext);
1792 ExitOnFailure(hr, "BA OnStartup failed.");
1793
1794LExit:
1795 return hr;
1796}
1797
1798EXTERN_C BAAPI UserExperienceOnSystemShutdown(
1799 __in BURN_USER_EXPERIENCE* pUserExperience,
1800 __in DWORD dwEndSession,
1801 __inout BOOL* pfCancel
1802 )
1803{
1804 HRESULT hr = S_OK;
1805 BA_ONSYSTEMSHUTDOWN_ARGS args = { };
1806 BA_ONSYSTEMSHUTDOWN_RESULTS results = { };
1807
1808 args.cbSize = sizeof(args);
1809 args.dwEndSession = dwEndSession;
1810
1811 results.cbSize = sizeof(results);
1812 results.fCancel = *pfCancel;
1813
1814 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN, &args, &results, pUserExperience->pvBAProcContext);
1815 ExitOnFailure(hr, "BA OnSystemShutdown failed.");
1816
1817 *pfCancel = results.fCancel;
1818
1819LExit:
1820 return hr;
1821}
1822
1823EXTERN_C BAAPI UserExperienceOnUnregisterBegin(
1824 __in BURN_USER_EXPERIENCE* pUserExperience
1825 )
1826{
1827 HRESULT hr = S_OK;
1828 BA_ONUNREGISTERBEGIN_ARGS args = { };
1829 BA_ONUNREGISTERBEGIN_RESULTS results = { };
1830
1831 args.cbSize = sizeof(args);
1832
1833 results.cbSize = sizeof(results);
1834
1835 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &args, &results, pUserExperience->pvBAProcContext);
1836 ExitOnFailure(hr, "BA OnUnregisterBegin failed.");
1837
1838 if (results.fCancel)
1839 {
1840 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1841 }
1842
1843LExit:
1844 return hr;
1845}
1846
1847EXTERN_C BAAPI UserExperienceOnUnregisterComplete(
1848 __in BURN_USER_EXPERIENCE* pUserExperience,
1849 __in HRESULT hrStatus
1850 )
1851{
1852 HRESULT hr = S_OK;
1853 BA_ONUNREGISTERCOMPLETE_ARGS args = { };
1854 BA_ONUNREGISTERCOMPLETE_RESULTS results = { };
1855
1856 args.cbSize = sizeof(args);
1857 args.hrStatus = hrStatus;
1858
1859 results.cbSize = sizeof(results);
1860
1861 hr = pUserExperience->pfnBAProc(BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERCOMPLETE, &args, &results, pUserExperience->pvBAProcContext);
1862 ExitOnFailure(hr, "BA OnUnregisterComplete failed.");
1863
1864LExit:
1865 return hr;
1866}
1867
1868extern "C" int UserExperienceCheckExecuteResult(
1869 __in BURN_USER_EXPERIENCE* pUserExperience,
1870 __in BOOL fRollback,
1871 __in DWORD dwAllowedResults,
1872 __in int nResult
1873 )
1874{
1875 // Do not allow canceling while rolling back.
1876 if (fRollback && (IDCANCEL == nResult || IDABORT == nResult))
1877 {
1878 nResult = IDNOACTION;
1879 }
1880 else if (FAILED(pUserExperience->hrApplyError) && !fRollback) // if we failed cancel except not during rollback.
1881 {
1882 nResult = IDCANCEL;
1883 }
1884
1885 nResult = FilterResult(dwAllowedResults, nResult);
1886 return nResult;
1887}
1888
1889extern "C" HRESULT UserExperienceInterpretResult(
1890 __in BURN_USER_EXPERIENCE* /*pUserExperience*/,
1891 __in DWORD dwAllowedResults,
1892 __in int nResult
1893 )
1894{
1895 int nFilteredResult = FilterResult(dwAllowedResults, nResult);
1896 return IDOK == nFilteredResult || IDNOACTION == nFilteredResult ? S_OK : IDCANCEL == nFilteredResult || IDABORT == nFilteredResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
1897}
1898
1899extern "C" HRESULT UserExperienceInterpretExecuteResult(
1900 __in BURN_USER_EXPERIENCE* pUserExperience,
1901 __in BOOL fRollback,
1902 __in DWORD dwAllowedResults,
1903 __in int nResult
1904 )
1905{
1906 HRESULT hr = S_OK;
1907
1908 // If we failed return that error unless this is rollback which should roll on.
1909 if (FAILED(pUserExperience->hrApplyError) && !fRollback)
1910 {
1911 hr = pUserExperience->hrApplyError;
1912 }
1913 else
1914 {
1915 int nCheckedResult = UserExperienceCheckExecuteResult(pUserExperience, fRollback, dwAllowedResults, nResult);
1916 hr = IDOK == nCheckedResult || IDNOACTION == nCheckedResult ? S_OK : IDCANCEL == nCheckedResult || IDABORT == nCheckedResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
1917 }
1918
1919 return hr;
1920}
1921
1922
1923// internal functions
1924
1925static int FilterResult(
1926 __in DWORD dwAllowedResults,
1927 __in int nResult
1928 )
1929{
1930 if (IDNOACTION == nResult || IDERROR == nResult) // do nothing and errors pass through.
1931 {
1932 }
1933 else
1934 {
1935 switch (dwAllowedResults)
1936 {
1937 case MB_OK:
1938 nResult = IDOK;
1939 break;
1940
1941 case MB_OKCANCEL:
1942 if (IDOK == nResult || IDYES == nResult)
1943 {
1944 nResult = IDOK;
1945 }
1946 else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult)
1947 {
1948 nResult = IDCANCEL;
1949 }
1950 else
1951 {
1952 nResult = IDNOACTION;
1953 }
1954 break;
1955
1956 case MB_ABORTRETRYIGNORE:
1957 if (IDCANCEL == nResult || IDABORT == nResult)
1958 {
1959 nResult = IDABORT;
1960 }
1961 else if (IDRETRY == nResult || IDTRYAGAIN == nResult)
1962 {
1963 nResult = IDRETRY;
1964 }
1965 else if (IDIGNORE == nResult)
1966 {
1967 nResult = IDIGNORE;
1968 }
1969 else
1970 {
1971 nResult = IDNOACTION;
1972 }
1973 break;
1974
1975 case MB_YESNO:
1976 if (IDOK == nResult || IDYES == nResult)
1977 {
1978 nResult = IDYES;
1979 }
1980 else if (IDCANCEL == nResult || IDABORT == nResult || IDNO == nResult)
1981 {
1982 nResult = IDNO;
1983 }
1984 else
1985 {
1986 nResult = IDNOACTION;
1987 }
1988 break;
1989
1990 case MB_YESNOCANCEL:
1991 if (IDOK == nResult || IDYES == nResult)
1992 {
1993 nResult = IDYES;
1994 }
1995 else if (IDNO == nResult)
1996 {
1997 nResult = IDNO;
1998 }
1999 else if (IDCANCEL == nResult || IDABORT == nResult)
2000 {
2001 nResult = IDCANCEL;
2002 }
2003 else
2004 {
2005 nResult = IDNOACTION;
2006 }
2007 break;
2008
2009 case MB_RETRYCANCEL:
2010 if (IDRETRY == nResult || IDTRYAGAIN == nResult)
2011 {
2012 nResult = IDRETRY;
2013 }
2014 else if (IDCANCEL == nResult || IDABORT == nResult)
2015 {
2016 nResult = IDABORT;
2017 }
2018 else
2019 {
2020 nResult = IDNOACTION;
2021 }
2022 break;
2023
2024 case MB_CANCELTRYCONTINUE:
2025 if (IDCANCEL == nResult || IDABORT == nResult)
2026 {
2027 nResult = IDABORT;
2028 }
2029 else if (IDRETRY == nResult || IDTRYAGAIN == nResult)
2030 {
2031 nResult = IDRETRY;
2032 }
2033 else if (IDCONTINUE == nResult || IDIGNORE == nResult)
2034 {
2035 nResult = IDCONTINUE;
2036 }
2037 else
2038 {
2039 nResult = IDNOACTION;
2040 }
2041 break;
2042
2043 case WIU_MB_OKIGNORECANCELRETRY: // custom Windows Installer utility return code.
2044 if (IDOK == nResult || IDYES == nResult)
2045 {
2046 nResult = IDOK;
2047 }
2048 else if (IDCONTINUE == nResult || IDIGNORE == nResult)
2049 {
2050 nResult = IDIGNORE;
2051 }
2052 else if (IDCANCEL == nResult || IDABORT == nResult)
2053 {
2054 nResult = IDCANCEL;
2055 }
2056 else if (IDRETRY == nResult || IDTRYAGAIN == nResult || IDNO == nResult)
2057 {
2058 nResult = IDRETRY;
2059 }
2060 else
2061 {
2062 nResult = IDNOACTION;
2063 }
2064 break;
2065
2066 case MB_RETRYTRYAGAIN: // custom return code.
2067 if (IDRETRY != nResult && IDTRYAGAIN != nResult)
2068 {
2069 nResult = IDNOACTION;
2070 }
2071 break;
2072
2073 default:
2074 AssertSz(FALSE, "Unknown allowed results.");
2075 break;
2076 }
2077 }
2078
2079 return nResult;
2080}
2081
2082// This filters the BA's responses to events during apply.
2083// If an apply thread failed, then return its error so this thread will bail out.
2084// During rollback, the BA can't cancel.
2085static HRESULT FilterExecuteResult(
2086 __in BURN_USER_EXPERIENCE* pUserExperience,
2087 __in HRESULT hrStatus,
2088 __in BOOL fRollback,
2089 __in BOOL fCancel,
2090 __in LPCWSTR sczEventName
2091 )
2092{
2093 HRESULT hr = hrStatus;
2094 HRESULT hrApplyError = pUserExperience->hrApplyError; // make sure to use the same value for the whole method, since it can be changed in other threads.
2095
2096 // If we failed return that error unless this is rollback which should roll on.
2097 if (FAILED(hrApplyError) && !fRollback)
2098 {
2099 hr = hrApplyError;
2100 }
2101 else if (fRollback)
2102 {
2103 if (fCancel)
2104 {
2105 LogId(REPORT_STANDARD, MSG_APPLY_CANCEL_IGNORED_DURING_ROLLBACK, sczEventName);
2106 }
2107 // TODO: since cancel isn't allowed, should the BA's HRESULT be ignored as well?
2108 // In the previous code, they could still alter rollback by returning IDERROR.
2109 }
2110 else
2111 {
2112 ExitOnFailure(hr, "BA %ls failed.", sczEventName);
2113
2114 if (fCancel)
2115 {
2116 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
2117 }
2118 }
2119
2120LExit:
2121 return hr;
2122}