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