diff options
Diffstat (limited to 'src/balutil/BalBootstrapperEngine.cpp')
-rw-r--r-- | src/balutil/BalBootstrapperEngine.cpp | 720 |
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 | |||
6 | class CBalBootstrapperEngine : public IBootstrapperEngine, public IMarshal | ||
7 | { | ||
8 | public: // 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 | |||
59 | public: // 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 | |||
534 | public: // 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 | |||
685 | public: | ||
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 | |||
696 | private: | ||
697 | long m_cReferences; | ||
698 | PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc; | ||
699 | LPVOID m_pvBAEngineProcContext; | ||
700 | }; | ||
701 | |||
702 | HRESULT 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 | |||
717 | LExit: | ||
718 | ReleaseObject(pBootstrapperEngine); | ||
719 | return hr; | ||
720 | } | ||