aboutsummaryrefslogtreecommitdiff
path: root/src/balutil/inc/BalBaseBootstrapperApplication.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/balutil/inc/BalBaseBootstrapperApplication.h900
1 files changed, 900 insertions, 0 deletions
diff --git a/src/balutil/inc/BalBaseBootstrapperApplication.h b/src/balutil/inc/BalBaseBootstrapperApplication.h
new file mode 100644
index 00000000..ac354e7b
--- /dev/null
+++ b/src/balutil/inc/BalBaseBootstrapperApplication.h
@@ -0,0 +1,900 @@
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 <windows.h>
4#include <msiquery.h>
5
6#include "BootstrapperEngine.h"
7#include "BootstrapperApplication.h"
8#include "IBootstrapperEngine.h"
9#include "IBootstrapperApplication.h"
10
11#include "balutil.h"
12#include "balretry.h"
13
14class CBalBaseBootstrapperApplication : public IBootstrapperApplication
15{
16public: // IUnknown
17 virtual STDMETHODIMP QueryInterface(
18 __in REFIID riid,
19 __out LPVOID *ppvObject
20 )
21 {
22 if (!ppvObject)
23 {
24 return E_INVALIDARG;
25 }
26
27 *ppvObject = NULL;
28
29 if (::IsEqualIID(__uuidof(IBootstrapperApplication), riid))
30 {
31 *ppvObject = static_cast<IBootstrapperApplication*>(this);
32 }
33 else if (::IsEqualIID(IID_IUnknown, riid))
34 {
35 *ppvObject = static_cast<IUnknown*>(this);
36 }
37 else // no interface for requested iid
38 {
39 return E_NOINTERFACE;
40 }
41
42 AddRef();
43 return S_OK;
44 }
45
46 virtual STDMETHODIMP_(ULONG) AddRef()
47 {
48 return ::InterlockedIncrement(&this->m_cReferences);
49 }
50
51 virtual STDMETHODIMP_(ULONG) Release()
52 {
53 long l = ::InterlockedDecrement(&this->m_cReferences);
54 if (0 < l)
55 {
56 return l;
57 }
58
59 delete this;
60 return 0;
61 }
62
63public: // IBootstrapperApplication
64 virtual STDMETHODIMP OnStartup()
65 {
66 return S_OK;
67 }
68
69 virtual STDMETHODIMP OnShutdown(
70 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* /*pAction*/
71 )
72 {
73 return S_OK;
74 }
75
76 virtual STDMETHODIMP OnSystemShutdown(
77 __in DWORD dwEndSession,
78 __inout BOOL* pfCancel
79 )
80 {
81 HRESULT hr = S_OK;
82
83 // Allow requests to shut down when critical or not applying.
84 *pfCancel = !(ENDSESSION_CRITICAL & dwEndSession || !m_fApplying);
85
86 return hr;
87 }
88
89 virtual STDMETHODIMP OnDetectBegin(
90 __in BOOL /*fInstalled*/,
91 __in DWORD /*cPackages*/,
92 __inout BOOL* pfCancel
93 )
94 {
95 *pfCancel |= CheckCanceled();
96 return S_OK;
97 }
98
99 virtual STDMETHODIMP OnDetectForwardCompatibleBundle(
100 __in_z LPCWSTR /*wzBundleId*/,
101 __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/,
102 __in_z LPCWSTR /*wzBundleTag*/,
103 __in BOOL /*fPerMachine*/,
104 __in DWORD64 /*dw64Version*/,
105 __inout BOOL* pfCancel,
106 __inout BOOL* /*pfIgnoreBundle*/
107 )
108 {
109 *pfCancel |= CheckCanceled();
110 return S_OK;
111 }
112
113 virtual STDMETHODIMP OnDetectUpdateBegin(
114 __in_z LPCWSTR /*wzUpdateLocation*/,
115 __inout BOOL* pfCancel,
116 __inout BOOL* /*pfSkip*/
117 )
118 {
119 *pfCancel |= CheckCanceled();
120 return S_OK;
121 }
122
123 virtual STDMETHODIMP OnDetectUpdate(
124 __in_z LPCWSTR /*wzUpdateLocation*/,
125 __in DWORD64 /*dw64Size*/,
126 __in DWORD64 /*dw64Version*/,
127 __in_z LPCWSTR /*wzTitle*/,
128 __in_z LPCWSTR /*wzSummary*/,
129 __in_z LPCWSTR /*wzContentType*/,
130 __in_z LPCWSTR /*wzContent*/,
131 __inout BOOL* pfCancel,
132 __inout BOOL* /*pfStopProcessingUpdates*/
133 )
134 {
135 *pfCancel |= CheckCanceled();
136 return S_OK;
137 }
138
139 virtual STDMETHODIMP OnDetectUpdateComplete(
140 __in HRESULT /*hrStatus*/,
141 __inout BOOL* /*pfIgnoreError*/
142 )
143 {
144 return S_OK;
145 }
146
147 virtual STDMETHODIMP OnDetectRelatedBundle(
148 __in_z LPCWSTR /*wzBundleId*/,
149 __in BOOTSTRAPPER_RELATION_TYPE /*relationType*/,
150 __in_z LPCWSTR /*wzBundleTag*/,
151 __in BOOL /*fPerMachine*/,
152 __in DWORD64 /*dw64Version*/,
153 __in BOOTSTRAPPER_RELATED_OPERATION /*operation*/,
154 __inout BOOL* pfCancel
155 )
156 {
157 *pfCancel |= CheckCanceled();
158 return S_OK;
159 }
160
161 virtual STDMETHODIMP OnDetectPackageBegin(
162 __in_z LPCWSTR /*wzPackageId*/,
163 __inout BOOL* pfCancel
164 )
165 {
166 *pfCancel |= CheckCanceled();
167 return S_OK;
168 }
169
170 virtual STDMETHODIMP OnDetectCompatibleMsiPackage(
171 __in_z LPCWSTR /*wzPackageId*/,
172 __in_z LPCWSTR /*wzCompatiblePackageId*/,
173 __in DWORD64 /*dw64CompatiblePackageVersion*/,
174 __inout BOOL* pfCancel
175 )
176 {
177 *pfCancel |= CheckCanceled();
178 return S_OK;
179 }
180
181 virtual STDMETHODIMP OnDetectRelatedMsiPackage(
182 __in_z LPCWSTR /*wzPackageId*/,
183 __in_z LPCWSTR /*wzUpgradeCode*/,
184 __in_z LPCWSTR /*wzProductCode*/,
185 __in BOOL /*fPerMachine*/,
186 __in DWORD64 /*dw64Version*/,
187 __in BOOTSTRAPPER_RELATED_OPERATION /*operation*/,
188 __inout BOOL* pfCancel
189 )
190 {
191 *pfCancel |= CheckCanceled();
192 return S_OK;
193 }
194
195 virtual STDMETHODIMP OnDetectTargetMsiPackage(
196 __in_z LPCWSTR /*wzPackageId*/,
197 __in_z LPCWSTR /*wzProductCode*/,
198 __in BOOTSTRAPPER_PACKAGE_STATE /*patchState*/,
199 __inout BOOL* pfCancel
200 )
201 {
202 *pfCancel |= CheckCanceled();
203 return S_OK;
204 }
205
206 virtual STDMETHODIMP OnDetectMsiFeature(
207 __in_z LPCWSTR /*wzPackageId*/,
208 __in_z LPCWSTR /*wzFeatureId*/,
209 __in BOOTSTRAPPER_FEATURE_STATE /*state*/,
210 __inout BOOL* pfCancel
211 )
212 {
213 *pfCancel |= CheckCanceled();
214 return S_OK;
215 }
216
217 virtual STDMETHODIMP OnDetectPackageComplete(
218 __in_z LPCWSTR /*wzPackageId*/,
219 __in HRESULT /*hrStatus*/,
220 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/
221 )
222 {
223 return S_OK;
224 }
225
226 virtual STDMETHODIMP OnDetectComplete(
227 __in HRESULT /*hrStatus*/
228 )
229 {
230 return S_OK;
231 }
232
233 virtual STDMETHODIMP OnPlanBegin(
234 __in DWORD /*cPackages*/,
235 __inout BOOL* pfCancel
236 )
237 {
238 *pfCancel |= CheckCanceled();
239 return S_OK;
240 }
241
242 virtual STDMETHODIMP OnPlanRelatedBundle(
243 __in_z LPCWSTR /*wzBundleId*/,
244 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
245 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/,
246 __inout BOOL* pfCancel
247 )
248 {
249 *pfCancel |= CheckCanceled();
250 return S_OK;
251 }
252
253 virtual STDMETHODIMP OnPlanPackageBegin(
254 __in_z LPCWSTR /*wzPackageId*/,
255 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
256 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/,
257 __inout BOOL* pfCancel
258 )
259 {
260 *pfCancel |= CheckCanceled();
261 return S_OK;
262 }
263
264 virtual STDMETHODIMP OnPlanCompatibleMsiPackageBegin(
265 __in_z LPCWSTR /*wzPackageId*/,
266 __in_z LPCWSTR /*wzCompatiblePackageId*/,
267 __in DWORD64 /*dw64CompatiblePackageVersion*/,
268 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
269 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/,
270 __inout BOOL* pfCancel
271 )
272 {
273 *pfCancel |= CheckCanceled();
274 return S_OK;
275 }
276
277 virtual STDMETHODIMP OnPlanCompatibleMsiPackageComplete(
278 __in_z LPCWSTR /*wzPackageId*/,
279 __in_z LPCWSTR /*wzCompatiblePackageId*/,
280 __in HRESULT /*hrStatus*/,
281 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/,
282 __in BOOTSTRAPPER_REQUEST_STATE /*requested*/,
283 __in BOOTSTRAPPER_ACTION_STATE /*execute*/,
284 __in BOOTSTRAPPER_ACTION_STATE /*rollback*/
285 )
286 {
287 return S_OK;
288 }
289
290 virtual STDMETHODIMP OnPlanTargetMsiPackage(
291 __in_z LPCWSTR /*wzPackageId*/,
292 __in_z LPCWSTR /*wzProductCode*/,
293 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
294 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestedState*/,
295 __inout BOOL* pfCancel
296 )
297 {
298 *pfCancel |= CheckCanceled();
299 return S_OK;
300 }
301
302 virtual STDMETHODIMP OnPlanMsiFeature(
303 __in_z LPCWSTR /*wzPackageId*/,
304 __in_z LPCWSTR /*wzFeatureId*/,
305 __in BOOTSTRAPPER_FEATURE_STATE /*recommendedState*/,
306 __inout BOOTSTRAPPER_FEATURE_STATE* /*pRequestedState*/,
307 __inout BOOL* pfCancel
308 )
309 {
310 *pfCancel |= CheckCanceled();
311 return S_OK;
312 }
313
314 virtual STDMETHODIMP OnPlanPackageComplete(
315 __in_z LPCWSTR /*wzPackageId*/,
316 __in HRESULT /*hrStatus*/,
317 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/,
318 __in BOOTSTRAPPER_REQUEST_STATE /*requested*/,
319 __in BOOTSTRAPPER_ACTION_STATE /*execute*/,
320 __in BOOTSTRAPPER_ACTION_STATE /*rollback*/
321 )
322 {
323 return S_OK;
324 }
325
326 virtual STDMETHODIMP OnPlanComplete(
327 __in HRESULT /*hrStatus*/
328 )
329 {
330 return S_OK;
331 }
332
333 virtual STDMETHODIMP OnApplyBegin(
334 __in DWORD /*dwPhaseCount*/,
335 __inout BOOL* pfCancel
336 )
337 {
338 m_fApplying = TRUE;
339
340 m_dwProgressPercentage = 0;
341 m_dwOverallProgressPercentage = 0;
342
343 *pfCancel |= CheckCanceled();
344 return S_OK;
345 }
346
347 virtual STDMETHODIMP OnElevateBegin(
348 __inout BOOL* pfCancel
349 )
350 {
351 *pfCancel |= CheckCanceled();
352 return S_OK;
353 }
354
355 virtual STDMETHODIMP OnElevateComplete(
356 __in HRESULT /*hrStatus*/
357 )
358 {
359 return S_OK;
360 }
361
362 virtual STDMETHODIMP OnProgress(
363 __in DWORD dwProgressPercentage,
364 __in DWORD dwOverallProgressPercentage,
365 __inout BOOL* pfCancel
366 )
367 {
368 HRESULT hr = S_OK;
369 int nResult = IDNOACTION;
370
371 m_dwProgressPercentage = dwProgressPercentage;
372 m_dwOverallProgressPercentage = dwOverallProgressPercentage;
373
374 if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_display)
375 {
376 hr = m_pEngine->SendEmbeddedProgress(m_dwProgressPercentage, m_dwOverallProgressPercentage, &nResult);
377 BalExitOnFailure(hr, "Failed to send embedded overall progress.");
378
379 if (IDERROR == nResult)
380 {
381 hr = E_FAIL;
382 }
383 else if (IDCANCEL == nResult)
384 {
385 *pfCancel = TRUE;
386 }
387 }
388
389 LExit:
390 *pfCancel |= CheckCanceled();
391 return hr;
392 }
393
394 virtual STDMETHODIMP OnError(
395 __in BOOTSTRAPPER_ERROR_TYPE errorType,
396 __in_z LPCWSTR wzPackageId,
397 __in DWORD dwCode,
398 __in_z LPCWSTR /*wzError*/,
399 __in DWORD /*dwUIHint*/,
400 __in DWORD /*cData*/,
401 __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/,
402 __in int /*nRecommendation*/,
403 __inout int* pResult
404 )
405 {
406 BalRetryErrorOccurred(wzPackageId, dwCode);
407
408 if (CheckCanceled())
409 {
410 *pResult = IDCANCEL;
411 }
412 else if (BOOTSTRAPPER_DISPLAY_FULL == m_display)
413 {
414 if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType)
415 {
416 *pResult = IDTRYAGAIN;
417 }
418 }
419
420 return S_OK;
421 }
422
423 virtual STDMETHODIMP OnRegisterBegin(
424 __inout BOOL* pfCancel
425 )
426 {
427 *pfCancel |= CheckCanceled();
428 return S_OK;
429 }
430
431 virtual STDMETHODIMP OnRegisterComplete(
432 __in HRESULT /*hrStatus*/
433 )
434 {
435 return S_OK;
436 }
437
438 virtual STDMETHODIMP OnCacheBegin(
439 __inout BOOL* pfCancel
440 )
441 {
442 *pfCancel |= CheckCanceled();
443 return S_OK;
444 }
445
446 virtual STDMETHODIMP OnCachePackageBegin(
447 __in_z LPCWSTR /*wzPackageId*/,
448 __in DWORD /*cCachePayloads*/,
449 __in DWORD64 /*dw64PackageCacheSize*/,
450 __inout BOOL* pfCancel
451 )
452 {
453 *pfCancel |= CheckCanceled();
454 return S_OK;
455 }
456
457 virtual STDMETHODIMP OnCacheAcquireBegin(
458 __in_z LPCWSTR wzPackageOrContainerId,
459 __in_z_opt LPCWSTR wzPayloadId,
460 __in BOOTSTRAPPER_CACHE_OPERATION /*operation*/,
461 __in_z LPCWSTR /*wzSource*/,
462 __inout BOOL* pfCancel
463 )
464 {
465 BalRetryStartPackage(BALRETRY_TYPE_CACHE, wzPackageOrContainerId, wzPayloadId);
466 *pfCancel |= CheckCanceled();
467 return S_OK;
468 }
469
470 virtual STDMETHODIMP OnCacheAcquireProgress(
471 __in_z LPCWSTR /*wzPackageOrContainerId*/,
472 __in_z_opt LPCWSTR /*wzPayloadId*/,
473 __in DWORD64 /*dw64Progress*/,
474 __in DWORD64 /*dw64Total*/,
475 __in DWORD /*dwOverallPercentage*/,
476 __inout BOOL* pfCancel
477 )
478 {
479 HRESULT hr = S_OK;
480 int nResult = IDNOACTION;
481
482 // Send progress even though we don't update the numbers to at least give the caller an opportunity
483 // to cancel.
484 if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_display)
485 {
486 hr = m_pEngine->SendEmbeddedProgress(m_dwProgressPercentage, m_dwOverallProgressPercentage, &nResult);
487 BalExitOnFailure(hr, "Failed to send embedded cache progress.");
488
489 if (IDERROR == nResult)
490 {
491 hr = E_FAIL;
492 }
493 else if (IDCANCEL == nResult)
494 {
495 *pfCancel = TRUE;
496 }
497 }
498
499 LExit:
500 *pfCancel |= CheckCanceled();
501 return hr;
502 }
503
504 virtual STDMETHODIMP OnResolveSource(
505 __in_z LPCWSTR /*wzPackageOrContainerId*/,
506 __in_z_opt LPCWSTR /*wzPayloadId*/,
507 __in_z LPCWSTR /*wzLocalSource*/,
508 __in_z_opt LPCWSTR /*wzDownloadSource*/,
509 __in BOOTSTRAPPER_RESOLVESOURCE_ACTION /*recommendation*/,
510 __inout BOOTSTRAPPER_RESOLVESOURCE_ACTION* /*pAction*/,
511 __inout BOOL* pfCancel
512 )
513 {
514 *pfCancel |= CheckCanceled();
515 return S_OK;
516 }
517
518 virtual STDMETHODIMP OnCacheAcquireComplete(
519 __in_z LPCWSTR wzPackageOrContainerId,
520 __in_z_opt LPCWSTR wzPayloadId,
521 __in HRESULT hrStatus,
522 __in BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION /*recommendation*/,
523 __inout BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION* pAction
524 )
525 {
526 HRESULT hr = S_OK;
527 BOOL fRetry = FALSE;
528
529 if (CheckCanceled())
530 {
531 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT));
532 }
533
534 hr = BalRetryEndPackage(BALRETRY_TYPE_CACHE, wzPackageOrContainerId, wzPayloadId, hrStatus, &fRetry);
535 ExitOnFailure(hr, "BalRetryEndPackage for cache failed");
536
537 if (fRetry)
538 {
539 *pAction = BOOTSTRAPPER_CACHEACQUIRECOMPLETE_ACTION_RETRY;
540 }
541
542 LExit:
543 return hr;
544 }
545
546 virtual STDMETHODIMP OnCacheVerifyBegin(
547 __in_z LPCWSTR /*wzPackageId*/,
548 __in_z LPCWSTR /*wzPayloadId*/,
549 __inout BOOL* pfCancel
550 )
551 {
552 *pfCancel |= CheckCanceled();
553 return S_OK;
554 }
555
556 virtual STDMETHODIMP OnCacheVerifyComplete(
557 __in_z LPCWSTR /*wzPackageId*/,
558 __in_z LPCWSTR /*wzPayloadId*/,
559 __in HRESULT /*hrStatus*/,
560 __in BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION /*recommendation*/,
561 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction
562 )
563 {
564 if (CheckCanceled())
565 {
566 *pAction = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
567 }
568
569 return S_OK;
570 }
571
572 virtual STDMETHODIMP OnCachePackageComplete(
573 __in_z LPCWSTR /*wzPackageId*/,
574 __in HRESULT /*hrStatus*/,
575 __in BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION /*recommendation*/,
576 __inout BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION* pAction
577 )
578 {
579 if (CheckCanceled())
580 {
581 *pAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
582 }
583
584 return S_OK;
585 }
586
587 virtual STDMETHODIMP OnCacheComplete(
588 __in HRESULT /*hrStatus*/
589 )
590 {
591 return S_OK;
592 }
593
594 virtual STDMETHODIMP OnExecuteBegin(
595 __in DWORD /*cExecutingPackages*/,
596 __inout BOOL* pfCancel
597 )
598 {
599 *pfCancel |= CheckCanceled();
600 return S_OK;
601 }
602
603 virtual STDMETHODIMP OnExecutePackageBegin(
604 __in_z LPCWSTR wzPackageId,
605 __in BOOL fExecute,
606 __inout BOOL* pfCancel
607 )
608 {
609 // Only track retry on execution (not rollback).
610 if (fExecute)
611 {
612 BalRetryStartPackage(BALRETRY_TYPE_EXECUTE, wzPackageId, NULL);
613 }
614
615 m_fRollingBack = !fExecute;
616 *pfCancel |= CheckCanceled();
617 return S_OK;
618 }
619
620 virtual STDMETHODIMP OnExecutePatchTarget(
621 __in_z LPCWSTR /*wzPackageId*/,
622 __in_z LPCWSTR /*wzTargetProductCode*/,
623 __inout BOOL* pfCancel
624 )
625 {
626 *pfCancel |= CheckCanceled();
627 return S_OK;
628 }
629
630 virtual STDMETHODIMP OnExecuteProgress(
631 __in_z LPCWSTR /*wzPackageId*/,
632 __in DWORD /*dwProgressPercentage*/,
633 __in DWORD /*dwOverallProgressPercentage*/,
634 __inout BOOL* pfCancel
635 )
636 {
637 HRESULT hr = S_OK;
638 int nResult = IDNOACTION;
639
640 // Send progress even though we don't update the numbers to at least give the caller an opportunity
641 // to cancel.
642 if (BOOTSTRAPPER_DISPLAY_EMBEDDED == m_display)
643 {
644 hr = m_pEngine->SendEmbeddedProgress(m_dwProgressPercentage, m_dwOverallProgressPercentage, &nResult);
645 BalExitOnFailure(hr, "Failed to send embedded execute progress.");
646
647 if (IDERROR == nResult)
648 {
649 hr = E_FAIL;
650 }
651 else if (IDCANCEL == nResult)
652 {
653 *pfCancel = TRUE;
654 }
655 }
656
657 LExit:
658 *pfCancel |= CheckCanceled();
659 return hr;
660 }
661
662 virtual STDMETHODIMP OnExecuteMsiMessage(
663 __in_z LPCWSTR /*wzPackageId*/,
664 __in INSTALLMESSAGE /*messageType*/,
665 __in DWORD /*dwUIHint*/,
666 __in_z LPCWSTR /*wzMessage*/,
667 __in DWORD /*cData*/,
668 __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/,
669 __in int /*nRecommendation*/,
670 __inout int* pResult
671 )
672 {
673 if (CheckCanceled())
674 {
675 *pResult = IDCANCEL;
676 }
677
678 return S_OK;
679 }
680
681 virtual STDMETHODIMP OnExecuteFilesInUse(
682 __in_z LPCWSTR /*wzPackageId*/,
683 __in DWORD /*cFiles*/,
684 __in_ecount_z(cFiles) LPCWSTR* /*rgwzFiles*/,
685 __in int /*nRecommendation*/,
686 __inout int* pResult
687 )
688 {
689 if (CheckCanceled())
690 {
691 *pResult = IDCANCEL;
692 }
693
694 return S_OK;
695 }
696
697 virtual STDMETHODIMP OnExecutePackageComplete(
698 __in_z LPCWSTR wzPackageId,
699 __in HRESULT hrStatus,
700 __in BOOTSTRAPPER_APPLY_RESTART /*restart*/,
701 __in BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION /*recommendation*/,
702 __inout BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION* pAction
703 )
704 {
705 HRESULT hr = S_OK;
706 BOOL fRetry = FALSE;
707
708 if (CheckCanceled())
709 {
710 ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT));
711 }
712
713 hr = BalRetryEndPackage(BALRETRY_TYPE_EXECUTE, wzPackageId, NULL, hrStatus, &fRetry);
714 ExitOnFailure(hr, "BalRetryEndPackage for execute failed");
715
716 if (fRetry)
717 {
718 *pAction = BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RETRY;
719 }
720
721 LExit:
722 return hr;
723 }
724
725 virtual STDMETHODIMP OnExecuteComplete(
726 __in HRESULT /*hrStatus*/
727 )
728 {
729 return S_OK;
730 }
731
732 virtual STDMETHODIMP OnUnregisterBegin(
733 __inout BOOL* pfCancel
734 )
735 {
736 *pfCancel |= CheckCanceled();
737 return S_OK;
738 }
739
740 virtual STDMETHODIMP OnUnregisterComplete(
741 __in HRESULT /*hrStatus*/
742 )
743 {
744 return S_OK;
745 }
746
747 virtual STDMETHODIMP OnApplyComplete(
748 __in HRESULT /*hrStatus*/,
749 __in BOOTSTRAPPER_APPLY_RESTART restart,
750 __in BOOTSTRAPPER_APPLYCOMPLETE_ACTION /*recommendation*/,
751 __inout BOOTSTRAPPER_APPLYCOMPLETE_ACTION* pAction
752 )
753 {
754 HRESULT hr = S_OK;
755 BOOL fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart;
756 BOOL fShouldBlockRestart = BOOTSTRAPPER_DISPLAY_FULL <= m_display && BOOTSTRAPPER_RESTART_PROMPT >= m_restart;
757
758 if (fRestartRequired && !fShouldBlockRestart)
759 {
760 *pAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART;
761 }
762
763 m_fApplying = FALSE;
764
765 return hr;
766 }
767
768 virtual STDMETHODIMP OnLaunchApprovedExeBegin(
769 __inout BOOL* pfCancel
770 )
771 {
772 *pfCancel |= CheckCanceled();
773 return S_OK;
774 }
775
776 virtual STDMETHODIMP OnLaunchApprovedExeComplete(
777 __in HRESULT /*hrStatus*/,
778 __in DWORD /*dwProcessId*/
779 )
780 {
781 return S_OK;
782 }
783
784 virtual STDMETHODIMP_(HRESULT) BAProc(
785 __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/,
786 __in const LPVOID /*pvArgs*/,
787 __inout LPVOID /*pvResults*/,
788 __in_opt LPVOID /*pvContext*/
789 )
790 {
791 return E_NOTIMPL;
792 }
793
794 virtual STDMETHODIMP_(void) BAProcFallback(
795 __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/,
796 __in const LPVOID /*pvArgs*/,
797 __inout LPVOID /*pvResults*/,
798 __inout HRESULT* /*phr*/,
799 __in_opt LPVOID /*pvContext*/
800 )
801 {
802 }
803
804protected:
805 //
806 // PromptCancel - prompts the user to close (if not forced).
807 //
808 virtual BOOL PromptCancel(
809 __in HWND hWnd,
810 __in BOOL fForceCancel,
811 __in_z_opt LPCWSTR wzMessage,
812 __in_z_opt LPCWSTR wzCaption
813 )
814 {
815 ::EnterCriticalSection(&m_csCanceled);
816
817 // Only prompt the user to close if we have not canceled already.
818 if (!m_fCanceled)
819 {
820 if (fForceCancel)
821 {
822 m_fCanceled = TRUE;
823 }
824 else
825 {
826 m_fCanceled = (IDYES == ::MessageBoxW(hWnd, wzMessage, wzCaption, MB_YESNO | MB_ICONEXCLAMATION));
827 }
828 }
829
830 ::LeaveCriticalSection(&m_csCanceled);
831
832 return m_fCanceled;
833 }
834
835 //
836 // CheckCanceled - waits if the cancel dialog is up and checks to see if the user canceled the operation.
837 //
838 BOOL CheckCanceled()
839 {
840 ::EnterCriticalSection(&m_csCanceled);
841 ::LeaveCriticalSection(&m_csCanceled);
842 return m_fRollingBack ? FALSE : m_fCanceled;
843 }
844
845 BOOL IsRollingBack()
846 {
847 return m_fRollingBack;
848 }
849
850 BOOL IsCanceled()
851 {
852 return m_fCanceled;
853 }
854
855 CBalBaseBootstrapperApplication(
856 __in IBootstrapperEngine* pEngine,
857 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
858 __in DWORD dwRetryCount = 0,
859 __in DWORD dwRetryTimeout = 1000
860 )
861 {
862 m_cReferences = 1;
863 m_display = pArgs->pCommand->display;
864 m_restart = pArgs->pCommand->restart;
865
866 pEngine->AddRef();
867 m_pEngine = pEngine;
868
869 ::InitializeCriticalSection(&m_csCanceled);
870 m_fCanceled = FALSE;
871 m_fApplying = FALSE;
872 m_fRollingBack = FALSE;
873
874 BalRetryInitialize(dwRetryCount, dwRetryTimeout);
875 }
876
877 virtual ~CBalBaseBootstrapperApplication()
878 {
879 BalRetryUninitialize();
880 ::DeleteCriticalSection(&m_csCanceled);
881
882 ReleaseNullObject(m_pEngine);
883 }
884
885protected:
886 CRITICAL_SECTION m_csCanceled;
887 BOOL m_fCanceled;
888
889private:
890 long m_cReferences;
891 BOOTSTRAPPER_DISPLAY m_display;
892 BOOTSTRAPPER_RESTART m_restart;
893 IBootstrapperEngine* m_pEngine;
894
895 BOOL m_fApplying;
896 BOOL m_fRollingBack;
897
898 DWORD m_dwProgressPercentage;
899 DWORD m_dwOverallProgressPercentage;
900};