@joebigelow / wix / commits / 4bdf4846

Rely on the free-threaded marshaler for IBootstrapperEngine marshalling

It is the supported way to provide the direct pointer when marshalling, just like we were doing before. #4386

Sean Hall committed Mar 3, 2021 at 22:12 UTC 4bdf4846de8c96a1c2ad5e9ea791b575e3b0e37d
1 file changed +15 -151
src/balutil/BalBootstrapperEngine.cpp
+15 -151
@@ -3,7 +3,7 @@
3 #include "precomp.h"
4
5
6 -class CBalBootstrapperEngine : public IBootstrapperEngine, public IMarshal
6 +class CBalBootstrapperEngine : public IBootstrapperEngine
7 {
8 public: // IUnknown
9 virtual STDMETHODIMP QueryInterface(
@@ -24,7 +24,7 @@ public: // IUnknown
24 }
25 else if (::IsEqualIID(IID_IMarshal, riid))
26 {
27 - *ppvObject = static_cast<IMarshal*>(this);
27 + return m_pFreeThreadedMarshaler->QueryInterface(riid, ppvObject);
28 }
29 else if (::IsEqualIID(IID_IUnknown, riid))
30 {
@@ -561,158 +561,12 @@ public: // IBootstrapperEngine
561 return hr;
562 }
563
564 -public: // IMarshal
565 - virtual STDMETHODIMP GetUnmarshalClass(
566 - __in REFIID /*riid*/,
567 - __in_opt LPVOID /*pv*/,
568 - __in DWORD /*dwDestContext*/,
569 - __reserved LPVOID /*pvDestContext*/,
570 - __in DWORD /*mshlflags*/,
571 - __out LPCLSID /*pCid*/
572 - )
573 - {
574 - return E_NOTIMPL;
575 - }
576 -
577 - virtual STDMETHODIMP GetMarshalSizeMax(
578 - __in REFIID riid,
579 - __in_opt LPVOID /*pv*/,
580 - __in DWORD dwDestContext,
581 - __reserved LPVOID /*pvDestContext*/,
582 - __in DWORD /*mshlflags*/,
583 - __out DWORD *pSize
584 - )
585 - {
586 - HRESULT hr = S_OK;
587 -
588 - // We only support marshaling the IBootstrapperEngine interface in-proc.
589 - if (__uuidof(IBootstrapperEngine) != riid)
590 - {
591 - // Skip logging the following message since it appears way too often in the log.
592 - // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface."
593 - ExitFunction1(hr = E_NOINTERFACE);
594 - }
595 - else if (0 == (MSHCTX_INPROC & dwDestContext))
596 - {
597 - hr = E_FAIL;
598 - ExitOnRootFailure(hr, "Cannot marshal IBootstrapperEngine interface out of proc.");
599 - }
600 -
601 - // E_FAIL is used because E_INVALIDARG is not a supported return value.
602 - ExitOnNull(pSize, hr, E_FAIL, "Invalid size output parameter is NULL.");
603 -
604 - // Specify enough size to marshal just the interface pointer across threads.
605 - *pSize = sizeof(LPVOID);
606 -
607 - LExit:
608 - return hr;
609 - }
610 -
611 - virtual STDMETHODIMP MarshalInterface(
612 - __in IStream* pStm,
613 - __in REFIID riid,
614 - __in_opt LPVOID pv,
615 - __in DWORD dwDestContext,
616 - __reserved LPVOID /*pvDestContext*/,
617 - __in DWORD /*mshlflags*/
618 - )
619 - {
620 - HRESULT hr = S_OK;
621 - IBootstrapperEngine *pThis = NULL;
622 - ULONG ulWritten = 0;
623 -
624 - // We only support marshaling the IBootstrapperEngine interface in-proc.
625 - if (__uuidof(IBootstrapperEngine) != riid)
626 - {
627 - // Skip logging the following message since it appears way too often in the log.
628 - // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface."
629 - ExitFunction1(hr = E_NOINTERFACE);
630 - }
631 - else if (0 == (MSHCTX_INPROC & dwDestContext))
632 - {
633 - hr = E_FAIL;
634 - ExitOnRootFailure(hr, "Cannot marshal IBootstrapperEngine interface out of proc.");
635 - }
636 -
637 - // "pv" may not be set, so we should us "this" otherwise.
638 - if (pv)
639 - {
640 - pThis = reinterpret_cast<IBootstrapperEngine*>(pv);
641 - }
642 - else
643 - {
644 - pThis = static_cast<IBootstrapperEngine*>(this);
645 - }
646 -
647 - // E_INVALIDARG is not a supported return value.
648 - ExitOnNull(pStm, hr, E_FAIL, "The marshaling stream parameter is NULL.");
649 -
650 - // Marshal the interface pointer in-proc as is.
651 - hr = pStm->Write(pThis, sizeof(pThis), &ulWritten);
652 - if (STG_E_MEDIUMFULL == hr)
653 - {
654 - ExitOnFailure(hr, "Failed to write the stream because the stream is full.");
655 - }
656 - else if (FAILED(hr))
657 - {
658 - // All other STG error must be converted into E_FAIL based on IMarshal documentation.
659 - hr = E_FAIL;
660 - ExitOnFailure(hr, "Failed to write the IBootstrapperEngine interface pointer to the marshaling stream.");
661 - }
662 -
663 - LExit:
664 - return hr;
665 - }
666 -
667 - virtual STDMETHODIMP UnmarshalInterface(
668 - __in IStream* pStm,
669 - __in REFIID riid,
670 - __deref_out LPVOID* ppv
671 - )
672 - {
673 - HRESULT hr = S_OK;
674 - ULONG ulRead = 0;
675 -
676 - // We only support marshaling the engine in-proc.
677 - if (__uuidof(IBootstrapperEngine) != riid)
678 - {
679 - // Skip logging the following message since it appears way too often in the log.
680 - // "Unexpected IID requested to be marshalled. BootstrapperEngineForApplication can only marshal the IBootstrapperEngine interface."
681 - ExitFunction1(hr = E_NOINTERFACE);
682 - }
683 -
684 - // E_FAIL is used because E_INVALIDARG is not a supported return value.
685 - ExitOnNull(pStm, hr, E_FAIL, "The marshaling stream parameter is NULL.");
686 - ExitOnNull(ppv, hr, E_FAIL, "The interface output parameter is NULL.");
687 -
688 - // Unmarshal the interface pointer in-proc as is.
689 - hr = pStm->Read(*ppv, sizeof(LPVOID), &ulRead);
690 - if (FAILED(hr))
691 - {
692 - // All STG errors must be converted into E_FAIL based on IMarshal documentation.
693 - hr = E_FAIL;
694 - ExitOnFailure(hr, "Failed to read the IBootstrapperEngine interface pointer from the marshaling stream.");
695 - }
696 -
697 - LExit:
698 - return hr;
699 - }
700 -
701 - virtual STDMETHODIMP ReleaseMarshalData(
702 - __in IStream* /*pStm*/
703 - )
704 - {
705 - return E_NOTIMPL;
706 - }
707 -
708 - virtual STDMETHODIMP DisconnectObject(
709 - __in DWORD /*dwReserved*/
710 - )
564 +public:
565 + HRESULT Init()
566 {
712 - return E_NOTIMPL;
567 + return ::CoCreateFreeThreadedMarshaler(this, &m_pFreeThreadedMarshaler);
568 }
569
715 -public:
570 CBalBootstrapperEngine(
571 __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc,
572 __in_opt LPVOID pvBAEngineProcContext
@@ -721,12 +575,19 @@ public:
575 m_cReferences = 1;
576 m_pfnBAEngineProc = pfnBAEngineProc;
577 m_pvBAEngineProcContext = pvBAEngineProcContext;
578 + m_pFreeThreadedMarshaler = NULL;
579 + }
580 +
581 + ~CBalBootstrapperEngine()
582 + {
583 + ReleaseObject(m_pFreeThreadedMarshaler);
584 }
585
586 private:
587 long m_cReferences;
588 PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc;
589 LPVOID m_pvBAEngineProcContext;
590 + IUnknown* m_pFreeThreadedMarshaler;
591 };
592
593 HRESULT BalBootstrapperEngineCreate(
@@ -741,6 +602,9 @@ HRESULT BalBootstrapperEngineCreate(
602 pBootstrapperEngine = new CBalBootstrapperEngine(pfnBAEngineProc, pvBAEngineProcContext);
603 ExitOnNull(pBootstrapperEngine, hr, E_OUTOFMEMORY, "Failed to allocate new BalBootstrapperEngine object.");
604
605 + hr = pBootstrapperEngine->Init();
606 + ExitOnFailure(hr, "Failed to initialize CBalBootstrapperEngine.");
607 +
608 hr = pBootstrapperEngine->QueryInterface(IID_PPV_ARGS(ppBootstrapperEngine));
609 ExitOnFailure(hr, "Failed to QI for IBootstrapperEngine from BalBootstrapperEngine object.");
610