aboutsummaryrefslogtreecommitdiff
path: root/src/balutil/BalBootstrapperEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/balutil/BalBootstrapperEngine.cpp')
-rw-r--r--src/balutil/BalBootstrapperEngine.cpp720
1 files changed, 720 insertions, 0 deletions
diff --git a/src/balutil/BalBootstrapperEngine.cpp b/src/balutil/BalBootstrapperEngine.cpp
new file mode 100644
index 00000000..945940c5
--- /dev/null
+++ b/src/balutil/BalBootstrapperEngine.cpp
@@ -0,0 +1,720 @@
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, public IMarshal
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 *ppvObject = static_cast<IMarshal*>(this);
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 DWORD* 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 DWORD64* pqwValue
137 )
138 {
139 HRESULT hr = S_OK;
140 BAENGINE_GETVARIABLEVERSION_ARGS args = { };
141 BAENGINE_GETVARIABLEVERSION_RESULTS results = { };
142
143 ExitOnNull(pqwValue, hr, E_INVALIDARG, "pqwValue is required");
144
145 args.cbSize = sizeof(args);
146 args.wzVariable = wzVariable;
147
148 results.cbSize = sizeof(results);
149
150 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_GETVARIABLEVERSION, &args, &results, m_pvBAEngineProcContext);
151
152 *pqwValue = results.qwValue;
153
154 LExit:
155 SecureZeroMemory(&results, sizeof(results));
156 return hr;
157 }
158
159 virtual STDMETHODIMP FormatString(
160 __in_z LPCWSTR wzIn,
161 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
162 __inout DWORD* pcchOut
163 )
164 {
165 HRESULT hr = S_OK;
166 BAENGINE_FORMATSTRING_ARGS args = { };
167 BAENGINE_FORMATSTRING_RESULTS results = { };
168
169 ExitOnNull(pcchOut, hr, E_INVALIDARG, "pcchOut is required");
170
171 args.cbSize = sizeof(args);
172 args.wzIn = wzIn;
173
174 results.cbSize = sizeof(results);
175 results.wzOut = wzOut;
176 results.cchOut = *pcchOut;
177
178 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_FORMATSTRING, &args, &results, m_pvBAEngineProcContext);
179
180 *pcchOut = results.cchOut;
181
182 LExit:
183 return hr;
184 }
185
186 virtual STDMETHODIMP EscapeString(
187 __in_z LPCWSTR wzIn,
188 __out_ecount_opt(*pcchOut) LPWSTR wzOut,
189 __inout DWORD* pcchOut
190 )
191 {
192 HRESULT hr = S_OK;
193 BAENGINE_ESCAPESTRING_ARGS args = { };
194 BAENGINE_ESCAPESTRING_RESULTS results = { };
195
196 ExitOnNull(pcchOut, hr, E_INVALIDARG, "pcchOut is required");
197
198 args.cbSize = sizeof(args);
199 args.wzIn = wzIn;
200
201 results.cbSize = sizeof(results);
202 results.wzOut = wzOut;
203 results.cchOut = *pcchOut;
204
205 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_ESCAPESTRING, &args, &results, m_pvBAEngineProcContext);
206
207 *pcchOut = results.cchOut;
208
209 LExit:
210 return hr;
211 }
212
213 virtual STDMETHODIMP EvaluateCondition(
214 __in_z LPCWSTR wzCondition,
215 __out BOOL* pf
216 )
217 {
218 HRESULT hr = S_OK;
219 BAENGINE_EVALUATECONDITION_ARGS args = { };
220 BAENGINE_EVALUATECONDITION_RESULTS results = { };
221
222 ExitOnNull(pf, hr, E_INVALIDARG, "pf is required");
223
224 args.cbSize = sizeof(args);
225 args.wzCondition = wzCondition;
226
227 results.cbSize = sizeof(results);
228
229 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_EVALUATECONDITION, &args, &results, m_pvBAEngineProcContext);
230
231 *pf = results.f;
232
233 LExit:
234 return hr;
235 }
236
237 virtual STDMETHODIMP Log(
238 __in BOOTSTRAPPER_LOG_LEVEL level,
239 __in_z LPCWSTR wzMessage
240 )
241 {
242 BAENGINE_LOG_ARGS args = { };
243 BAENGINE_LOG_RESULTS results = { };
244
245 args.cbSize = sizeof(args);
246 args.level = level;
247 args.wzMessage = wzMessage;
248
249 results.cbSize = sizeof(results);
250
251 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_LOG, &args, &results, m_pvBAEngineProcContext);
252 }
253
254 virtual STDMETHODIMP SendEmbeddedError(
255 __in DWORD dwErrorCode,
256 __in_z_opt LPCWSTR wzMessage,
257 __in DWORD dwUIHint,
258 __out int* pnResult
259 )
260 {
261 HRESULT hr = S_OK;
262 BAENGINE_SENDEMBEDDEDERROR_ARGS args = { };
263 BAENGINE_SENDEMBEDDEDERROR_RESULTS results = { };
264
265 ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required");
266
267 args.cbSize = sizeof(args);
268 args.dwErrorCode = dwErrorCode;
269 args.wzMessage = wzMessage;
270 args.dwUIHint = dwUIHint;
271
272 results.cbSize = sizeof(results);
273
274 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDERROR, &args, &results, m_pvBAEngineProcContext);
275
276 *pnResult = results.nResult;
277
278 LExit:
279 return hr;
280 }
281
282 virtual STDMETHODIMP SendEmbeddedProgress(
283 __in DWORD dwProgressPercentage,
284 __in DWORD dwOverallProgressPercentage,
285 __out int* pnResult
286 )
287 {
288 HRESULT hr = S_OK;
289 BAENGINE_SENDEMBEDDEDPROGRESS_ARGS args = { };
290 BAENGINE_SENDEMBEDDEDPROGRESS_RESULTS results = { };
291
292 ExitOnNull(pnResult, hr, E_INVALIDARG, "pnResult is required");
293
294 args.cbSize = sizeof(args);
295 args.dwProgressPercentage = dwProgressPercentage;
296 args.dwOverallProgressPercentage = dwOverallProgressPercentage;
297
298 results.cbSize = sizeof(results);
299
300 hr = m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SENDEMBEDDEDPROGRESS, &args, &results, m_pvBAEngineProcContext);
301
302 *pnResult = results.nResult;
303
304 LExit:
305 return hr;
306 }
307
308 virtual STDMETHODIMP SetUpdate(
309 __in_z_opt LPCWSTR wzLocalSource,
310 __in_z_opt LPCWSTR wzDownloadSource,
311 __in DWORD64 qwSize,
312 __in BOOTSTRAPPER_UPDATE_HASH_TYPE hashType,
313 __in_bcount_opt(cbHash) BYTE* rgbHash,
314 __in DWORD cbHash
315 )
316 {
317 BAENGINE_SETUPDATE_ARGS args = { };
318 BAENGINE_SETUPDATE_RESULTS results = { };
319
320 args.cbSize = sizeof(args);
321 args.wzLocalSource = wzLocalSource;
322 args.wzDownloadSource = wzDownloadSource;
323 args.qwSize = qwSize;
324 args.hashType = hashType;
325 args.rgbHash = rgbHash;
326 args.cbHash = cbHash;
327
328 results.cbSize = sizeof(results);
329
330 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETUPDATE, &args, &results, m_pvBAEngineProcContext);
331 }
332
333 virtual STDMETHODIMP SetLocalSource(
334 __in_z LPCWSTR wzPackageOrContainerId,
335 __in_z_opt LPCWSTR wzPayloadId,
336 __in_z LPCWSTR wzPath
337 )
338 {
339 BAENGINE_SETLOCALSOURCE_ARGS args = { };
340 BAENGINE_SETLOCALSOURCE_RESULTS results = { };
341
342 args.cbSize = sizeof(args);
343 args.wzPackageOrContainerId = wzPackageOrContainerId;
344 args.wzPayloadId = wzPayloadId;
345 args.wzPath = wzPath;
346
347 results.cbSize = sizeof(results);
348
349 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETLOCALSOURCE, &args, &results, m_pvBAEngineProcContext);
350 }
351
352 virtual STDMETHODIMP SetDownloadSource(
353 __in_z LPCWSTR wzPackageOrContainerId,
354 __in_z_opt LPCWSTR wzPayloadId,
355 __in_z LPCWSTR wzUrl,
356 __in_z_opt LPCWSTR wzUser,
357 __in_z_opt LPCWSTR wzPassword
358 )
359 {
360 BAENGINE_SETDOWNLOADSOURCE_ARGS args = { };
361 BAENGINE_SETDOWNLOADSOURCE_RESULTS results = { };
362
363 args.cbSize = sizeof(args);
364 args.wzPackageOrContainerId = wzPackageOrContainerId;
365 args.wzPayloadId = wzPayloadId;
366 args.wzUrl = wzUrl;
367 args.wzUser = wzUser;
368 args.wzPassword = wzPassword;
369
370 results.cbSize = sizeof(results);
371
372 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETDOWNLOADSOURCE, &args, &results, m_pvBAEngineProcContext);
373 }
374
375 virtual STDMETHODIMP SetVariableNumeric(
376 __in_z LPCWSTR wzVariable,
377 __in LONGLONG llValue
378 )
379 {
380 BAENGINE_SETVARIABLENUMERIC_ARGS args = { };
381 BAENGINE_SETVARIABLENUMERIC_RESULTS results = { };
382
383 args.cbSize = sizeof(args);
384 args.wzVariable = wzVariable;
385 args.llValue = llValue;
386
387 results.cbSize = sizeof(results);
388
389 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLENUMERIC, &args, &results, m_pvBAEngineProcContext);
390 }
391
392 virtual STDMETHODIMP SetVariableString(
393 __in_z LPCWSTR wzVariable,
394 __in_z_opt LPCWSTR wzValue
395 )
396 {
397 BAENGINE_SETVARIABLESTRING_ARGS args = { };
398 BAENGINE_SETVARIABLESTRING_RESULTS results = { };
399
400 args.cbSize = sizeof(args);
401 args.wzVariable = wzVariable;
402 args.wzValue = wzValue;
403
404 results.cbSize = sizeof(results);
405
406 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLESTRING, &args, &results, m_pvBAEngineProcContext);
407 }
408
409 virtual STDMETHODIMP SetVariableVersion(
410 __in_z LPCWSTR wzVariable,
411 __in DWORD64 qwValue
412 )
413 {
414 BAENGINE_SETVARIABLEVERSION_ARGS args = { };
415 BAENGINE_SETVARIABLEVERSION_RESULTS results = { };
416
417 args.cbSize = sizeof(args);
418 args.wzVariable = wzVariable;
419 args.qwValue = qwValue;
420
421 results.cbSize = sizeof(results);
422
423 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_SETVARIABLEVERSION, &args, &results, m_pvBAEngineProcContext);
424 }
425
426 virtual STDMETHODIMP CloseSplashScreen()
427 {
428 BAENGINE_CLOSESPLASHSCREEN_ARGS args = { };
429 BAENGINE_CLOSESPLASHSCREEN_RESULTS results = { };
430
431 args.cbSize = sizeof(args);
432
433 results.cbSize = sizeof(results);
434
435 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_CLOSESPLASHSCREEN, &args, &results, m_pvBAEngineProcContext);
436 }
437
438 virtual STDMETHODIMP Detect(
439 __in_opt HWND hwndParent
440 )
441 {
442 BAENGINE_DETECT_ARGS args = { };
443 BAENGINE_DETECT_RESULTS results = { };
444
445 args.cbSize = sizeof(args);
446 args.hwndParent = hwndParent;
447
448 results.cbSize = sizeof(results);
449
450 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_DETECT, &args, &results, m_pvBAEngineProcContext);
451 }
452
453 virtual STDMETHODIMP Plan(
454 __in BOOTSTRAPPER_ACTION action
455 )
456 {
457 BAENGINE_PLAN_ARGS args = { };
458 BAENGINE_PLAN_RESULTS results = { };
459
460 args.cbSize = sizeof(args);
461 args.action = action;
462
463 results.cbSize = sizeof(results);
464
465 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_PLAN, &args, &results, m_pvBAEngineProcContext);
466 }
467
468 virtual STDMETHODIMP Elevate(
469 __in_opt HWND hwndParent
470 )
471 {
472 BAENGINE_ELEVATE_ARGS args = { };
473 BAENGINE_ELEVATE_RESULTS results = { };
474
475 args.cbSize = sizeof(args);
476 args.hwndParent = hwndParent;
477
478 results.cbSize = sizeof(results);
479
480 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_ELEVATE, &args, &results, m_pvBAEngineProcContext);
481 }
482
483 virtual STDMETHODIMP Apply(
484 __in_opt HWND hwndParent
485 )
486 {
487 BAENGINE_APPLY_ARGS args = { };
488 BAENGINE_APPLY_RESULTS results = { };
489
490 args.cbSize = sizeof(args);
491 args.hwndParent = hwndParent;
492
493 results.cbSize = sizeof(results);
494
495 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_APPLY, &args, &results, m_pvBAEngineProcContext);
496 }
497
498 virtual STDMETHODIMP Quit(
499 __in DWORD dwExitCode
500 )
501 {
502 BAENGINE_QUIT_ARGS args = { };
503 BAENGINE_QUIT_RESULTS results = { };
504
505 args.cbSize = sizeof(args);
506 args.dwExitCode = dwExitCode;
507
508 results.cbSize = sizeof(results);
509
510 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_QUIT, &args, &results, m_pvBAEngineProcContext);
511 }
512
513 virtual STDMETHODIMP LaunchApprovedExe(
514 __in_opt HWND hwndParent,
515 __in_z LPCWSTR wzApprovedExeForElevationId,
516 __in_z_opt LPCWSTR wzArguments,
517 __in DWORD dwWaitForInputIdleTimeout
518 )
519 {
520 BAENGINE_LAUNCHAPPROVEDEXE_ARGS args = { };
521 BAENGINE_LAUNCHAPPROVEDEXE_RESULTS results = { };
522
523 args.cbSize = sizeof(args);
524 args.hwndParent = hwndParent;
525 args.wzApprovedExeForElevationId = wzApprovedExeForElevationId;
526 args.wzArguments = wzArguments;
527 args.dwWaitForInputIdleTimeout = dwWaitForInputIdleTimeout;
528
529 results.cbSize = sizeof(results);
530
531 return m_pfnBAEngineProc(BOOTSTRAPPER_ENGINE_MESSAGE_LAUNCHAPPROVEDEXE, &args, &results, m_pvBAEngineProcContext);
532 }
533
534public: // IMarshal
535 virtual STDMETHODIMP GetUnmarshalClass(
536 __in REFIID /*riid*/,
537 __in_opt LPVOID /*pv*/,
538 __in DWORD /*dwDestContext*/,
539 __reserved LPVOID /*pvDestContext*/,
540 __in DWORD /*mshlflags*/,
541 __out LPCLSID /*pCid*/
542 )
543 {
544 return E_NOTIMPL;
545 }
546
547 virtual STDMETHODIMP GetMarshalSizeMax(
548 __in REFIID riid,
549 __in_opt LPVOID /*pv*/,
550 __in DWORD dwDestContext,
551 __reserved LPVOID /*pvDestContext*/,
552 __in DWORD /*mshlflags*/,
553 __out DWORD *pSize
554 )
555 {
556 HRESULT hr = S_OK;
557
558 // We only support marshaling the IBootstrapperEngine interface in-proc.
559 if (__uuidof(IBootstrapperEngine) != riid)
560 {
561 // Skip logging the following message since it appears way too often in the log.
562 // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface."
563 ExitFunction1(hr = E_NOINTERFACE);
564 }
565 else if (0 == (MSHCTX_INPROC & dwDestContext))
566 {
567 hr = E_FAIL;
568 ExitOnRootFailure(hr, "Cannot marshal IBootstrapperEngine interface out of proc.");
569 }
570
571 // E_FAIL is used because E_INVALIDARG is not a supported return value.
572 ExitOnNull(pSize, hr, E_FAIL, "Invalid size output parameter is NULL.");
573
574 // Specify enough size to marshal just the interface pointer across threads.
575 *pSize = sizeof(LPVOID);
576
577 LExit:
578 return hr;
579 }
580
581 virtual STDMETHODIMP MarshalInterface(
582 __in IStream* pStm,
583 __in REFIID riid,
584 __in_opt LPVOID pv,
585 __in DWORD dwDestContext,
586 __reserved LPVOID /*pvDestContext*/,
587 __in DWORD /*mshlflags*/
588 )
589 {
590 HRESULT hr = S_OK;
591 IBootstrapperEngine *pThis = NULL;
592 ULONG ulWritten = 0;
593
594 // We only support marshaling the IBootstrapperEngine interface in-proc.
595 if (__uuidof(IBootstrapperEngine) != riid)
596 {
597 // Skip logging the following message since it appears way too often in the log.
598 // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface."
599 ExitFunction1(hr = E_NOINTERFACE);
600 }
601 else if (0 == (MSHCTX_INPROC & dwDestContext))
602 {
603 hr = E_FAIL;
604 ExitOnRootFailure(hr, "Cannot marshal IBootstrapperEngine interface out of proc.");
605 }
606
607 // "pv" may not be set, so we should us "this" otherwise.
608 if (pv)
609 {
610 pThis = reinterpret_cast<IBootstrapperEngine*>(pv);
611 }
612 else
613 {
614 pThis = static_cast<IBootstrapperEngine*>(this);
615 }
616
617 // E_INVALIDARG is not a supported return value.
618 ExitOnNull(pStm, hr, E_FAIL, "The marshaling stream parameter is NULL.");
619
620 // Marshal the interface pointer in-proc as is.
621 hr = pStm->Write(pThis, sizeof(pThis), &ulWritten);
622 if (STG_E_MEDIUMFULL == hr)
623 {
624 ExitOnFailure(hr, "Failed to write the stream because the stream is full.");
625 }
626 else if (FAILED(hr))
627 {
628 // All other STG error must be converted into E_FAIL based on IMarshal documentation.
629 hr = E_FAIL;
630 ExitOnFailure(hr, "Failed to write the IBootstrapperEngine interface pointer to the marshaling stream.");
631 }
632
633 LExit:
634 return hr;
635 }
636
637 virtual STDMETHODIMP UnmarshalInterface(
638 __in IStream* pStm,
639 __in REFIID riid,
640 __deref_out LPVOID* ppv
641 )
642 {
643 HRESULT hr = S_OK;
644 ULONG ulRead = 0;
645
646 // We only support marshaling the engine in-proc.
647 if (__uuidof(IBootstrapperEngine) != riid)
648 {
649 // Skip logging the following message since it appears way too often in the log.
650 // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface."
651 ExitFunction1(hr = E_NOINTERFACE);
652 }
653
654 // E_FAIL is used because E_INVALIDARG is not a supported return value.
655 ExitOnNull(pStm, hr, E_FAIL, "The marshaling stream parameter is NULL.");
656 ExitOnNull(ppv, hr, E_FAIL, "The interface output parameter is NULL.");
657
658 // Unmarshal the interface pointer in-proc as is.
659 hr = pStm->Read(*ppv, sizeof(LPVOID), &ulRead);
660 if (FAILED(hr))
661 {
662 // All STG errors must be converted into E_FAIL based on IMarshal documentation.
663 hr = E_FAIL;
664 ExitOnFailure(hr, "Failed to read the IBootstrapperEngine interface pointer from the marshaling stream.");
665 }
666
667 LExit:
668 return hr;
669 }
670
671 virtual STDMETHODIMP ReleaseMarshalData(
672 __in IStream* /*pStm*/
673 )
674 {
675 return E_NOTIMPL;
676 }
677
678 virtual STDMETHODIMP DisconnectObject(
679 __in DWORD /*dwReserved*/
680 )
681 {
682 return E_NOTIMPL;
683 }
684
685public:
686 CBalBootstrapperEngine(
687 __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc,
688 __in_opt LPVOID pvBAEngineProcContext
689 )
690 {
691 m_cReferences = 1;
692 m_pfnBAEngineProc = pfnBAEngineProc;
693 m_pvBAEngineProcContext = pvBAEngineProcContext;
694 }
695
696private:
697 long m_cReferences;
698 PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc;
699 LPVOID m_pvBAEngineProcContext;
700};
701
702HRESULT BalBootstrapperEngineCreate(
703 __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc,
704 __in_opt LPVOID pvBAEngineProcContext,
705 __out IBootstrapperEngine** ppBootstrapperEngine
706 )
707{
708 HRESULT hr = S_OK;
709 CBalBootstrapperEngine* pBootstrapperEngine = NULL;
710
711 pBootstrapperEngine = new CBalBootstrapperEngine(pfnBAEngineProc, pvBAEngineProcContext);
712 ExitOnNull(pBootstrapperEngine, hr, E_OUTOFMEMORY, "Failed to allocate new BalBootstrapperEngine object.");
713
714 hr = pBootstrapperEngine->QueryInterface(IID_PPV_ARGS(ppBootstrapperEngine));
715 ExitOnFailure(hr, "Failed to QI for IBootstrapperEngine from BalBootstrapperEngine object.");
716
717LExit:
718 ReleaseObject(pBootstrapperEngine);
719 return hr;
720}