summaryrefslogtreecommitdiff
path: root/src/api/burn/balutil/BalBootstrapperEngine.cpp
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-04-22 05:46:03 -0700
committerRob Mensching <rob@firegiant.com>2021-04-29 16:41:44 -0700
commitc00516901e6b67e398396b14fe7682d0376f8643 (patch)
treeb0d62089a1c5700c7f2c3e3790750bf2d8ea33c0 /src/api/burn/balutil/BalBootstrapperEngine.cpp
parent8eb98efd2175d9ece2e4639d43081667af9a4990 (diff)
downloadwix-c00516901e6b67e398396b14fe7682d0376f8643.tar.gz
wix-c00516901e6b67e398396b14fe7682d0376f8643.tar.bz2
wix-c00516901e6b67e398396b14fe7682d0376f8643.zip
Move balutil into API/burn
Diffstat (limited to 'src/api/burn/balutil/BalBootstrapperEngine.cpp')
-rw-r--r--src/api/burn/balutil/BalBootstrapperEngine.cpp629
1 files changed, 629 insertions, 0 deletions
diff --git a/src/api/burn/balutil/BalBootstrapperEngine.cpp b/src/api/burn/balutil/BalBootstrapperEngine.cpp
new file mode 100644
index 00000000..301b88a5
--- /dev/null
+++ b/src/api/burn/balutil/BalBootstrapperEngine.cpp
@@ -0,0 +1,629 @@
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
6class CBalBootstrapperEngine : public IBootstrapperEngine
7{
8public: // IUnknown
9 virtual STDMETHODIMP QueryInterface(
10 __in REFIID riid,
11 __out LPVOID *ppvObject
12 )
13 {
14 if (!ppvObject)
15 {
16 return E_INVALIDARG;
17 }
18
19 *ppvObject = NULL;
20
21 if (::IsEqualIID(__uuidof(IBootstrapperEngine), riid))
22 {
23 *ppvObject = static_cast<IBootstrapperEngine*>(this);
24 }
25 else if (::IsEqualIID(IID_IMarshal, riid))
26 {
27 return m_pFreeThreadedMarshaler->QueryInterface(riid, ppvObject);
28 }
29 else if (::IsEqualIID(IID_IUnknown, riid))
30 {
31 *ppvObject = reinterpret_cast<IUnknown*>(this);
32 }
33 else // no interface for requested iid
34 {
35 return E_NOINTERFACE;
36 }
37
38 AddRef();
39 return S_OK;
40 }
41
42 virtual STDMETHODIMP_(ULONG) AddRef()
43 {
44 return ::InterlockedIncrement(&this->m_cReferences);
45 }
46
47 virtual STDMETHODIMP_(ULONG) Release()
48 {
49 long l = ::InterlockedDecrement(&this->m_cReferences);
50 if (0 < l)
51 {
52 return l;
53 }
54
55 delete this;
56 return 0;
57 }
58
59public: // IBootstrapperEngine
60 virtual STDMETHODIMP GetPackageCount(
61 __out DWORD* pcPackages
62 )
63 {
64 HRESULT hr = S_OK;
65 BAENGINE_GETPACKAGECOUNT_ARGS args = { };
66 BAENGINE_GETPACKAGECOUNT_RESULTS results = { };
67
68 ExitOnNull(pcPackages, hr, E_INVALIDARG, "pcPackages is required");
69
70 args.cbSize = sizeof(args);
71
72 results.cbSize = sizeof(results);
73
74 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETPACKAGECOUNT, &args, &results, m_pvBAEngineProcContext);
75
76 *pcPackages = results.cPackages;
77
78 LExit:
79 return hr;
80 }
81
82 virtual STDMETHODIMP GetVariableNumeric(
83 __in_z LPCWSTR wzVariable,
84 __out LONGLONG* pllValue
85 )
86 {
87 HRESULT hr = S_OK;
88 BAENGINE_GETVARIABLENUMERIC_ARGS args = { };
89 BAENGINE_GETVARIABLENUMERIC_RESULTS results = { };
90
91 ExitOnNull(pllValue, hr, E_INVALIDARG, "pllValue is required");
92
93 args.cbSize = sizeof(args);
94 args.wzVariable = wzVariable;
95
96 results.cbSize = sizeof(results);
97
98 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLENUMERIC, &args, &results, m_pvBAEngineProcContext);
99
100 *pllValue = results.llValue;
101
102 LExit:
103 SecureZeroMemory(&results, sizeof(results));
104 return hr;
105 }
106
107 virtual STDMETHODIMP GetVariableString(
108 __in_z LPCWSTR wzVariable,
109 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
110 __inout SIZE_T* pcchValue
111 )
112 {
113 HRESULT hr = S_OK;
114 BAENGINE_GETVARIABLESTRING_ARGS args = { };
115 BAENGINE_GETVARIABLESTRING_RESULTS results = { };
116
117 ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required");
118
119 args.cbSize = sizeof(args);
120 args.wzVariable = wzVariable;
121
122 results.cbSize = sizeof(results);
123 results.wzValue = wzValue;
124 results.cchValue = *pcchValue;
125
126 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLESTRING, &args, &results, m_pvBAEngineProcContext);
127
128 *pcchValue = results.cchValue;
129
130 LExit:
131 return hr;
132 }
133
134 virtual STDMETHODIMP GetVariableVersion(
135 __in_z LPCWSTR wzVariable,
136 __out_ecount_opt(*pcchValue) LPWSTR wzValue,
137 __inout SIZE_T* pcchValue
138 )
139 {
140 HRESULT hr = S_OK;
141 BAENGINE_GETVARIABLEVERSION_ARGS args = { };
142 BAENGINE_GETVARIABLEVERSION_RESULTS results = { };
143
144 ExitOnNull(pcchValue, hr, E_INVALIDARG, "pcchValue is required");
145
146 args.cbSize = sizeof(args);
147 args.wzVariable = wzVariable;
148
149 results.cbSize = sizeof(results);
150 results.wzValue = wzValue;
151 results.cchValue = *pcchValue;
152
153 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLEVERSION, &args, &results, m_pvBAEngineProcContext);
154
155 *pcchValue = results.cchValue;
156
157 LExit:
158 return hr;
159 }
160
161 virtual STDMETHODIMP FormatString(
162 __in_z LPCWSTR wzIn,
163 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
164 __inout SIZE_T* pcchOut
165 )
166 {
167 HRESULT hr = S_OK;
168 BAENGINE_FORMATSTRING_ARGS args = { };
169 BAENGINE_FORMATSTRING_RESULTS results = { };
170
171 ExitOnNull(pcchOut, hr, E_INVALIDARG, "pcchOut is required");
172
173 args.cbSize = sizeof(args);
174 args.wzIn = wzIn;
175
176 results.cbSize = sizeof(results);
177 results.wzOut = wzOut;
178 results.cchOut = *pcchOut;
179
180 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_FORMATSTRING, &args, &results, m_pvBAEngineProcContext);
181
182 *pcchOut = results.cchOut;
183
184 LExit:
185 return hr;
186 }
187
188 virtual STDMETHODIMP EscapeString(
189 __in_z LPCWSTR wzIn,
190 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
191 __inout SIZE_T* pcchOut
192 )
193 {
194 HRESULT hr = S_OK;
195 BAENGINE_ESCAPESTRING_ARGS args = { };
196 BAENGINE_ESCAPESTRING_RESULTS results = { };
197
198 ExitOnNull(pcchOut, hr, E_INVALIDARG, "pcchOut is required");
199
200 args.cbSize = sizeof(args);
201 args.wzIn = wzIn;
202
203 results.cbSize = sizeof(results);
204 results.wzOut = wzOut;
205 results.cchOut = *pcchOut;
206
207 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_ESCAPESTRING, &args, &results, m_pvBAEngineProcContext);
208
209 *pcchOut = results.cchOut;
210
211 LExit:
212 return hr;
213 }
214
215 virtual STDMETHODIMP EvaluateCondition(
216 __in_z LPCWSTR wzCondition,
217 __out BOOL* pf
218 )
219 {
220 HRESULT hr = S_OK;
221 BAENGINE_EVALUATECONDITION_ARGS args = { };
222 BAENGINE_EVALUATECONDITION_RESULTS results = { };
223
224 ExitOnNull(pf, hr, E_INVALIDARG, "pf is required");
225
226 args.cbSize = sizeof(args);
227 args.wzCondition = wzCondition;
228
229 results.cbSize = sizeof(results);
230
231 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_EVALUATECONDITION, &args, &results, m_pvBAEngineProcContext);
232
233 *pf = results.f;
234
235 LExit:
236 return hr;
237 }
238
239 virtual STDMETHODIMP Log(
240 __in BOOTSTRAPPER_LOG_LEVEL level,
241 __in_z LPCWSTR wzMessage
242 )
243 {
244 BAENGINE_LOG_ARGS args = { };
245 BAENGINE_LOG_RESULTS results = { };
246
247 args.cbSize = sizeof(args);
248 args.level = level;
249 args.wzMessage = wzMessage;
250
251 results.cbSize = sizeof(results);
252
253 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_LOG, &args, &results, m_pvBAEngineProcContext);
254 }
255
256 virtual STDMETHODIMP SendEmbeddedError(
257 __in DWORD dwErrorCode,
258 __in_z_opt LPCWSTR wzMessage,
259 __in DWORD dwUIHint,
260 __out int* pnResult
261 )
262 {
263 HRESULT hr = S_OK;
264 BAENGINE_SENDEMBEDDEDERROR_ARGS args = { };
265 BAENGINE_SENDEMBEDDEDERROR_RESULTS results = { };
266
267 ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required");
268
269 args.cbSize = sizeof(args);
270 args.dwErrorCode = dwErrorCode;
271 args.wzMessage = wzMessage;
272 args.dwUIHint = dwUIHint;
273
274 results.cbSize = sizeof(results);
275
276 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDERROR, &args, &results, m_pvBAEngineProcContext);
277
278 *pnResult = results.nResult;
279
280 LExit:
281 return hr;
282 }
283
284 virtual STDMETHODIMP SendEmbeddedProgress(
285 __in DWORD dwProgressPercentage,
286 __in DWORD dwOverallProgressPercentage,
287 __out int* pnResult
288 )
289 {
290 HRESULT hr = S_OK;
291 BAENGINE_SENDEMBEDDEDPROGRESS_ARGS args = { };
292 BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS results = { };
293
294 ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required");
295
296 args.cbSize = sizeof(args);
297 args.dwProgressPercentage = dwProgressPercentage;
298 args.dwOverallProgressPercentage = dwOverallProgressPercentage;
299
300 results.cbSize = sizeof(results);
301
302 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDPROGRESS, &args, &results, m_pvBAEngineProcContext);
303
304 *pnResult = results.nResult;
305
306 LExit:
307 return hr;
308 }
309
310 virtual STDMETHODIMP SetUpdate(
311 __in_z_opt LPCWSTR wzLocalSource,
312 __in_z_opt LPCWSTR wzDownloadSource,
313 __in DWORD64 qwSize,
314 __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashType,
315 __in_bcount_opt(cbHash) BYTE* rgbHash,
316 __in DWORD cbHash
317 )
318 {
319 BAENGINE_SETUPDATE_ARGS args = { };
320 BAENGINE_SETUPDATE_RESULTS results = { };
321
322 args.cbSize = sizeof(args);
323 args.wzLocalSource = wzLocalSource;
324 args.wzDownloadSource = wzDownloadSource;
325 args.qwSize = qwSize;
326 args.hashType = hashType;
327 args.rgbHash = rgbHash;
328 args.cbHash = cbHash;
329
330 results.cbSize = sizeof(results);
331
332 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATE, &args, &results, m_pvBAEngineProcContext);
333 }
334
335 virtual STDMETHODIMP SetLocalSource(
336 __in_z LPCWSTR wzPackageOrContainerId,
337 __in_z_opt LPCWSTR wzPayloadId,
338 __in_z LPCWSTR wzPath
339 )
340 {
341 BAENGINE_SETLOCALSOURCE_ARGS args = { };
342 BAENGINE_SETLOCALSOURCE_RESULTS results = { };
343
344 args.cbSize = sizeof(args);
345 args.wzPackageOrContainerId = wzPackageOrContainerId;
346 args.wzPayloadId = wzPayloadId;
347 args.wzPath = wzPath;
348
349 results.cbSize = sizeof(results);
350
351 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETLOCALSOURCE, &args, &results, m_pvBAEngineProcContext);
352 }
353
354 virtual STDMETHODIMP SetDownloadSource(
355 __in_z LPCWSTR wzPackageOrContainerId,
356 __in_z_opt LPCWSTR wzPayloadId,
357 __in_z LPCWSTR wzUrl,
358 __in_z_opt LPCWSTR wzUser,
359 __in_z_opt LPCWSTR wzPassword
360 )
361 {
362 BAENGINE_SETDOWNLOADSOURCE_ARGS args = { };
363 BAENGINE_SETDOWNLOADSOURCE_RESULTS results = { };
364
365 args.cbSize = sizeof(args);
366 args.wzPackageOrContainerId = wzPackageOrContainerId;
367 args.wzPayloadId = wzPayloadId;
368 args.wzUrl = wzUrl;
369 args.wzUser = wzUser;
370 args.wzPassword = wzPassword;
371
372 results.cbSize = sizeof(results);
373
374 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETDOWNLOADSOURCE, &args, &results, m_pvBAEngineProcContext);
375 }
376
377 virtual STDMETHODIMP SetVariableNumeric(
378 __in_z LPCWSTR wzVariable,
379 __in LONGLONG llValue
380 )
381 {
382 BAENGINE_SETVARIABLENUMERIC_ARGS args = { };
383 BAENGINE_SETVARIABLENUMERIC_RESULTS results = { };
384
385 args.cbSize = sizeof(args);
386 args.wzVariable = wzVariable;
387 args.llValue = llValue;
388
389 results.cbSize = sizeof(results);
390
391 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLENUMERIC, &args, &results, m_pvBAEngineProcContext);
392 }
393
394 virtual STDMETHODIMP SetVariableString(
395 __in_z LPCWSTR wzVariable,
396 __in_z_opt LPCWSTR wzValue,
397 __in BOOL fFormatted
398 )
399 {
400 BAENGINE_SETVARIABLESTRING_ARGS args = { };
401 BAENGINE_SETVARIABLESTRING_RESULTS results = { };
402
403 args.cbSize = sizeof(args);
404 args.wzVariable = wzVariable;
405 args.wzValue = wzValue;
406 args.fFormatted = fFormatted;
407
408 results.cbSize = sizeof(results);
409
410 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLESTRING, &args, &results, m_pvBAEngineProcContext);
411 }
412
413 virtual STDMETHODIMP SetVariableVersion(
414 __in_z LPCWSTR wzVariable,
415 __in_z_opt LPCWSTR wzValue
416 )
417 {
418 BAENGINE_SETVARIABLEVERSION_ARGS args = { };
419 BAENGINE_SETVARIABLEVERSION_RESULTS results = { };
420
421 args.cbSize = sizeof(args);
422 args.wzVariable = wzVariable;
423 args.wzValue = wzValue;
424
425 results.cbSize = sizeof(results);
426
427 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLEVERSION, &args, &results, m_pvBAEngineProcContext);
428 }
429
430 virtual STDMETHODIMP CloseSplashScreen()
431 {
432 BAENGINE_CLOSESPLASHSCREEN_ARGS args = { };
433 BAENGINE_CLOSESPLASHSCREEN_RESULTS results = { };
434
435 args.cbSize = sizeof(args);
436
437 results.cbSize = sizeof(results);
438
439 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_CLOSESPLASHSCREEN, &args, &results, m_pvBAEngineProcContext);
440 }
441
442 virtual STDMETHODIMP Detect(
443 __in_opt HWND hwndParent
444 )
445 {
446 BAENGINE_DETECT_ARGS args = { };
447 BAENGINE_DETECT_RESULTS results = { };
448
449 args.cbSize = sizeof(args);
450 args.hwndParent = hwndParent;
451
452 results.cbSize = sizeof(results);
453
454 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_DETECT, &args, &results, m_pvBAEngineProcContext);
455 }
456
457 virtual STDMETHODIMP Plan(
458 __in BOOTSTRAPPER_ACTION action
459 )
460 {
461 BAENGINE_PLAN_ARGS args = { };
462 BAENGINE_PLAN_RESULTS results = { };
463
464 args.cbSize = sizeof(args);
465 args.action = action;
466
467 results.cbSize = sizeof(results);
468
469 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_PLAN, &args, &results, m_pvBAEngineProcContext);
470 }
471
472 virtual STDMETHODIMP Elevate(
473 __in_opt HWND hwndParent
474 )
475 {
476 BAENGINE_ELEVATE_ARGS args = { };
477 BAENGINE_ELEVATE_RESULTS results = { };
478
479 args.cbSize = sizeof(args);
480 args.hwndParent = hwndParent;
481
482 results.cbSize = sizeof(results);
483
484 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_ELEVATE, &args, &results, m_pvBAEngineProcContext);
485 }
486
487 virtual STDMETHODIMP Apply(
488 __in HWND hwndParent
489 )
490 {
491 BAENGINE_APPLY_ARGS args = { };
492 BAENGINE_APPLY_RESULTS results = { };
493
494 args.cbSize = sizeof(args);
495 args.hwndParent = hwndParent;
496
497 results.cbSize = sizeof(results);
498
499 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_APPLY, &args, &results, m_pvBAEngineProcContext);
500 }
501
502 virtual STDMETHODIMP Quit(
503 __in DWORD dwExitCode
504 )
505 {
506 BAENGINE_QUIT_ARGS args = { };
507 BAENGINE_QUIT_RESULTS results = { };
508
509 args.cbSize = sizeof(args);
510 args.dwExitCode = dwExitCode;
511
512 results.cbSize = sizeof(results);
513
514 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_QUIT, &args, &results, m_pvBAEngineProcContext);
515 }
516
517 virtual STDMETHODIMP LaunchApprovedExe(
518 __in_opt HWND hwndParent,
519 __in_z LPCWSTR wzApprovedExeForElevationId,
520 __in_z_opt LPCWSTR wzArguments,
521 __in DWORD dwWaitForInputIdleTimeout
522 )
523 {
524 BAENGINE_LAUNCHAPPROVEDEXE_ARGS args = { };
525 BAENGINE_LAUNCHAPPROVEDEXE_RESULTS results = { };
526
527 args.cbSize = sizeof(args);
528 args.hwndParent = hwndParent;
529 args.wzApprovedExeForElevationId = wzApprovedExeForElevationId;
530 args.wzArguments = wzArguments;
531 args.dwWaitForInputIdleTimeout = dwWaitForInputIdleTimeout;
532
533 results.cbSize = sizeof(results);
534
535 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE, &args, &results, m_pvBAEngineProcContext);
536 }
537
538 virtual STDMETHODIMP SetUpdateSource(
539 __in_z LPCWSTR wzUrl
540 )
541 {
542 BAENGINE_SETUPDATESOURCE_ARGS args = { };
543 BAENGINE_SETUPDATESOURCE_RESULTS results = { };
544
545 args.cbSize = sizeof(args);
546 args.wzUrl = wzUrl;
547
548 results.cbSize = sizeof(results);
549
550 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATESOURCE, &args, &results, m_pvBAEngineProcContext);
551 }
552
553 virtual STDMETHODIMP CompareVersions(
554 __in_z LPCWSTR wzVersion1,
555 __in_z LPCWSTR wzVersion2,
556 __out int* pnResult
557 )
558 {
559 HRESULT hr = S_OK;
560 BAENGINE_COMPAREVERSIONS_ARGS args = { };
561 BAENGINE_COMPAREVERSIONS_RESULTS results = { };
562
563 ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required");
564
565 args.cbSize = sizeof(args);
566 args.wzVersion1 = wzVersion1;
567 args.wzVersion2 = wzVersion2;
568
569 results.cbSize = sizeof(results);
570
571 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_COMPAREVERSIONS, &args, &results, m_pvBAEngineProcContext);
572
573 *pnResult = results.nResult;
574
575 LExit:
576 return hr;
577 }
578
579public:
580 HRESULT Init()
581 {
582 return ::CoCreateFreeThreadedMarshaler(this, &m_pFreeThreadedMarshaler);
583 }
584
585 CBalBootstrapperEngine(
586 __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc,
587 __in_opt LPVOID pvBAEngineProcContext
588 )
589 {
590 m_cReferences = 1;
591 m_pfnBAEngineProc = pfnBAEngineProc;
592 m_pvBAEngineProcContext = pvBAEngineProcContext;
593 m_pFreeThreadedMarshaler = NULL;
594 }
595
596 ~CBalBootstrapperEngine()
597 {
598 ReleaseObject(m_pFreeThreadedMarshaler);
599 }
600
601private:
602 long m_cReferences;
603 PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc;
604 LPVOID m_pvBAEngineProcContext;
605 IUnknown* m_pFreeThreadedMarshaler;
606};
607
608HRESULT BalBootstrapperEngineCreate(
609 __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc,
610 __in_opt LPVOID pvBAEngineProcContext,
611 __out IBootstrapperEngine** ppBootstrapperEngine
612 )
613{
614 HRESULT hr = S_OK;
615 CBalBootstrapperEngine* pBootstrapperEngine = NULL;
616
617 pBootstrapperEngine = new CBalBootstrapperEngine(pfnBAEngineProc, pvBAEngineProcContext);
618 ExitOnNull(pBootstrapperEngine, hr, E_OUTOFMEMORY, "Failed to allocate new BalBootstrapperEngine object.");
619
620 hr = pBootstrapperEngine->Init();
621 ExitOnFailure(hr, "Failed to initialize CBalBootstrapperEngine.");
622
623 hr = pBootstrapperEngine->QueryInterface(IID_PPV_ARGS(ppBootstrapperEngine));
624 ExitOnFailure(hr, "Failed to QI for IBootstrapperEngine from BalBootstrapperEngine object.");
625
626LExit:
627 ReleaseObject(pBootstrapperEngine);
628 return hr;
629}