1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_mscom_MainThreadHandoff_h 8 #define mozilla_mscom_MainThreadHandoff_h 9 10 #include <utility> 11 12 #include "mozilla/Assertions.h" 13 #include "mozilla/Mutex.h" 14 #include "mozilla/mscom/Interceptor.h" 15 #include "mozilla/mscom/MainThreadInvoker.h" 16 #include "mozilla/mscom/Utils.h" 17 #include "nsTArray.h" 18 19 namespace mozilla { 20 namespace mscom { 21 22 // {9a907000-7829-47f1-80eb-f67a26f47b34} 23 DEFINE_GUID(IID_IMainThreadHandoff, 0x9a907000, 0x7829, 0x47f1, 0x80, 0xeb, 24 0xf6, 0x7a, 0x26, 0xf4, 0x7b, 0x34); 25 26 struct IMainThreadHandoff : public IInterceptorSink { 27 virtual STDMETHODIMP GetHandlerProvider(IHandlerProvider** aProvider) = 0; 28 }; 29 30 struct ArrayData; 31 32 class MainThreadHandoff final : public IMainThreadHandoff, 33 public ICallFrameWalker { 34 public: 35 static HRESULT Create(IHandlerProvider* aHandlerProvider, 36 IInterceptorSink** aOutput); 37 38 template <typename Interface> WrapInterface(STAUniquePtr<Interface> aTargetInterface,Interface ** aOutInterface)39 static HRESULT WrapInterface(STAUniquePtr<Interface> aTargetInterface, 40 Interface** aOutInterface) { 41 return WrapInterface<Interface>(std::move(aTargetInterface), nullptr, 42 aOutInterface); 43 } 44 45 template <typename Interface> WrapInterface(STAUniquePtr<Interface> aTargetInterface,IHandlerProvider * aHandlerProvider,Interface ** aOutInterface)46 static HRESULT WrapInterface(STAUniquePtr<Interface> aTargetInterface, 47 IHandlerProvider* aHandlerProvider, 48 Interface** aOutInterface) { 49 MOZ_ASSERT(!IsProxy(aTargetInterface.get())); 50 RefPtr<IInterceptorSink> handoff; 51 HRESULT hr = 52 MainThreadHandoff::Create(aHandlerProvider, getter_AddRefs(handoff)); 53 if (FAILED(hr)) { 54 return hr; 55 } 56 return CreateInterceptor(std::move(aTargetInterface), handoff, 57 aOutInterface); 58 } 59 60 // IUnknown 61 STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override; 62 STDMETHODIMP_(ULONG) AddRef() override; 63 STDMETHODIMP_(ULONG) Release() override; 64 65 // ICallFrameEvents 66 STDMETHODIMP OnCall(ICallFrame* aFrame) override; 67 68 // IInterceptorSink 69 STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) override; 70 STDMETHODIMP GetHandler(NotNull<CLSID*> aHandlerClsid) override; 71 STDMETHODIMP GetHandlerPayloadSize(NotNull<IInterceptor*> aInterceptor, 72 NotNull<DWORD*> aOutPayloadSize) override; 73 STDMETHODIMP WriteHandlerPayload(NotNull<IInterceptor*> aInterceptor, 74 NotNull<IStream*> aStream) override; 75 STDMETHODIMP_(REFIID) MarshalAs(REFIID aIid) override; 76 STDMETHODIMP DisconnectHandlerRemotes() override; 77 STDMETHODIMP IsInterfaceMaybeSupported(REFIID aIid) override; 78 79 // IMainThreadHandoff GetHandlerProvider(IHandlerProvider ** aProvider)80 STDMETHODIMP GetHandlerProvider(IHandlerProvider** aProvider) override { 81 RefPtr<IHandlerProvider> provider = mHandlerProvider; 82 provider.forget(aProvider); 83 return mHandlerProvider ? S_OK : S_FALSE; 84 } 85 86 // ICallFrameWalker 87 STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam, 88 BOOL aIsOutParam) override; 89 90 private: 91 explicit MainThreadHandoff(IHandlerProvider* aHandlerProvider); 92 ~MainThreadHandoff(); 93 HRESULT FixArrayElements(ICallFrame* aFrame, const ArrayData& aArrayData); 94 HRESULT FixIServiceProvider(ICallFrame* aFrame); 95 96 private: 97 ULONG mRefCnt; 98 RefPtr<IWeakReference> mInterceptor; 99 RefPtr<IHandlerProvider> mHandlerProvider; 100 }; 101 102 } // namespace mscom 103 } // namespace mozilla 104 105 #endif // mozilla_mscom_MainThreadHandoff_h 106