diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-03-03 22:12:55 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-03-03 22:37:42 -0600 |
commit | 4bdf4846de8c96a1c2ad5e9ea791b575e3b0e37d (patch) | |
tree | 0374faf18d7643e36d26dce3e5e0f1821cd230f5 | |
parent | 5f4829e678c9c5cd5e581b0075cfa4a6b263c66e (diff) | |
download | wix-4bdf4846de8c96a1c2ad5e9ea791b575e3b0e37d.tar.gz wix-4bdf4846de8c96a1c2ad5e9ea791b575e3b0e37d.tar.bz2 wix-4bdf4846de8c96a1c2ad5e9ea791b575e3b0e37d.zip |
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
-rw-r--r-- | src/balutil/BalBootstrapperEngine.cpp | 166 |
1 files changed, 15 insertions, 151 deletions
diff --git a/src/balutil/BalBootstrapperEngine.cpp b/src/balutil/BalBootstrapperEngine.cpp index 8a78b127..8e40f7ae 100644 --- a/src/balutil/BalBootstrapperEngine.cpp +++ b/src/balutil/BalBootstrapperEngine.cpp | |||
@@ -3,7 +3,7 @@ | |||
3 | #include "precomp.h" | 3 | #include "precomp.h" |
4 | 4 | ||
5 | 5 | ||
6 | class CBalBootstrapperEngine : public IBootstrapperEngine, public IMarshal | 6 | class CBalBootstrapperEngine : public IBootstrapperEngine |
7 | { | 7 | { |
8 | public: // IUnknown | 8 | public: // IUnknown |
9 | virtual STDMETHODIMP QueryInterface( | 9 | virtual STDMETHODIMP QueryInterface( |
@@ -24,7 +24,7 @@ public: // IUnknown | |||
24 | } | 24 | } |
25 | else if (::IsEqualIID(IID_IMarshal, riid)) | 25 | else if (::IsEqualIID(IID_IMarshal, riid)) |
26 | { | 26 | { |
27 | *ppvObject = static_cast<IMarshal*>(this); | 27 | return m_pFreeThreadedMarshaler->QueryInterface(riid, ppvObject); |
28 | } | 28 | } |
29 | else if (::IsEqualIID(IID_IUnknown, riid)) | 29 | else if (::IsEqualIID(IID_IUnknown, riid)) |
30 | { | 30 | { |
@@ -561,158 +561,12 @@ public: // IBootstrapperEngine | |||
561 | return hr; | 561 | return hr; |
562 | } | 562 | } |
563 | 563 | ||
564 | public: // IMarshal | 564 | public: |
565 | virtual STDMETHODIMP GetUnmarshalClass( | 565 | HRESULT Init() |
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 | ) | ||
711 | { | 566 | { |
712 | return E_NOTIMPL; | 567 | return ::CoCreateFreeThreadedMarshaler(this, &m_pFreeThreadedMarshaler); |
713 | } | 568 | } |
714 | 569 | ||
715 | public: | ||
716 | CBalBootstrapperEngine( | 570 | CBalBootstrapperEngine( |
717 | __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc, | 571 | __in PFN_BOOTSTRAPPER_ENGINE_PROC pfnBAEngineProc, |
718 | __in_opt LPVOID pvBAEngineProcContext | 572 | __in_opt LPVOID pvBAEngineProcContext |
@@ -721,12 +575,19 @@ public: | |||
721 | m_cReferences = 1; | 575 | m_cReferences = 1; |
722 | m_pfnBAEngineProc = pfnBAEngineProc; | 576 | m_pfnBAEngineProc = pfnBAEngineProc; |
723 | m_pvBAEngineProcContext = pvBAEngineProcContext; | 577 | m_pvBAEngineProcContext = pvBAEngineProcContext; |
578 | m_pFreeThreadedMarshaler = NULL; | ||
579 | } | ||
580 | |||
581 | ~CBalBootstrapperEngine() | ||
582 | { | ||
583 | ReleaseObject(m_pFreeThreadedMarshaler); | ||
724 | } | 584 | } |
725 | 585 | ||
726 | private: | 586 | private: |
727 | long m_cReferences; | 587 | long m_cReferences; |
728 | PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc; | 588 | PFN_BOOTSTRAPPER_ENGINE_PROC m_pfnBAEngineProc; |
729 | LPVOID m_pvBAEngineProcContext; | 589 | LPVOID m_pvBAEngineProcContext; |
590 | IUnknown* m_pFreeThreadedMarshaler; | ||
730 | }; | 591 | }; |
731 | 592 | ||
732 | HRESULT BalBootstrapperEngineCreate( | 593 | HRESULT BalBootstrapperEngineCreate( |
@@ -741,6 +602,9 @@ HRESULT BalBootstrapperEngineCreate( | |||
741 | pBootstrapperEngine = new CBalBootstrapperEngine(pfnBAEngineProc, pvBAEngineProcContext); | 602 | pBootstrapperEngine = new CBalBootstrapperEngine(pfnBAEngineProc, pvBAEngineProcContext); |
742 | ExitOnNull(pBootstrapperEngine, hr, E_OUTOFMEMORY, "Failed to allocate new BalBootstrapperEngine object."); | 603 | ExitOnNull(pBootstrapperEngine, hr, E_OUTOFMEMORY, "Failed to allocate new BalBootstrapperEngine object."); |
743 | 604 | ||
605 | hr = pBootstrapperEngine->Init(); | ||
606 | ExitOnFailure(hr, "Failed to initialize CBalBootstrapperEngine."); | ||
607 | |||
744 | hr = pBootstrapperEngine->QueryInterface(IID_PPV_ARGS(ppBootstrapperEngine)); | 608 | hr = pBootstrapperEngine->QueryInterface(IID_PPV_ARGS(ppBootstrapperEngine)); |
745 | ExitOnFailure(hr, "Failed to QI for IBootstrapperEngine from BalBootstrapperEngine object."); | 609 | ExitOnFailure(hr, "Failed to QI for IBootstrapperEngine from BalBootstrapperEngine object."); |
746 | 610 | ||