diff options
Diffstat (limited to 'src')
| -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 | ||
