diff options
Diffstat (limited to 'ipc/mscom/oop/Handler.h')
-rw-r--r-- | ipc/mscom/oop/Handler.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/ipc/mscom/oop/Handler.h b/ipc/mscom/oop/Handler.h new file mode 100644 index 0000000000..a723064e5e --- /dev/null +++ b/ipc/mscom/oop/Handler.h @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_Handler_h +#define mozilla_mscom_Handler_h + +#if defined(MOZILLA_INTERNAL_API) +# error This code is NOT for internal Gecko use! +#endif // defined(MOZILLA_INTERNAL_API) + +#include <objidl.h> + +#include "mozilla/mscom/Aggregation.h" +#include "mozilla/NotNull.h" +#include "mozilla/RefPtr.h" + +/* WARNING! The code in this file may be loaded into the address spaces of other + processes! It MUST NOT link against xul.dll or other Gecko binaries! Only + inline code may be included! */ + +namespace mozilla { +namespace mscom { + +class Handler : public IMarshal { + public: + // IMarshal + STDMETHODIMP GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + CLSID* pCid) override; + STDMETHODIMP GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + DWORD* pSize) override; + STDMETHODIMP MarshalInterface(IStream* pStm, REFIID riid, void* pv, + DWORD dwDestContext, void* pvDestContext, + DWORD mshlflags) override; + STDMETHODIMP UnmarshalInterface(IStream* pStm, REFIID riid, + void** ppv) override; + STDMETHODIMP ReleaseMarshalData(IStream* pStm) override; + STDMETHODIMP DisconnectObject(DWORD dwReserved) override; + + /** + * This method allows the handler to return its own interfaces that override + * those interfaces that are exposed by the underlying COM proxy. + * @param aProxyUnknown is the IUnknown of the underlying COM proxy. This is + * provided to give the handler implementation an + * opportunity to acquire interfaces to the underlying + * remote object, if needed. + * @param aIid Interface requested, similar to IUnknown::QueryInterface + * @param aOutInterface Outparam for the resulting interface to return to the + * client. + * @return The usual HRESULT codes similarly to IUnknown::QueryInterface. + * If E_NOINTERFACE is returned, the proxy will be queried. + * If the handler is certain that this interface is not available, + * it can return S_FALSE to avoid querying the proxy. This will be + * translated to E_NOINTERFACE before it is returned to the client. + */ + virtual HRESULT QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, + void** aOutInterface) = 0; + /** + * Called when the implementer should deserialize data in aStream. + * @return S_OK on success; + * S_FALSE if the deserialization was successful but there was no + * data; HRESULT error code otherwise. + */ + virtual HRESULT ReadHandlerPayload(IStream* aStream, REFIID aIid) { + return S_FALSE; + } + + /** + * Unfortunately when COM marshals a proxy, it doesn't implicitly marshal + * the payload that was originally sent with the proxy. We must implement + * that code in the handler in order to make this happen. + */ + + /** + * This function allows the implementer to substitute a different interface + * for marshaling than the one that COM is intending to marshal. For example, + * the implementer might want to marshal a proxy for an interface that is + * derived from the requested interface. + * + * The default implementation is the identity function. + */ + virtual REFIID MarshalAs(REFIID aRequestedIid) { return aRequestedIid; } + + virtual HRESULT GetMarshalInterface(REFIID aMarshalAsIid, + NotNull<IUnknown*> aProxy, + NotNull<IID*> aOutIid, + NotNull<IUnknown**> aOutUnk); + + /** + * Called when the implementer must provide the size of the payload. + */ + virtual HRESULT GetHandlerPayloadSize(REFIID aIid, DWORD* aOutPayloadSize) { + if (!aOutPayloadSize) { + return E_INVALIDARG; + } + *aOutPayloadSize = 0; + return S_OK; + } + + /** + * Called when the implementer should serialize the payload data into aStream. + */ + virtual HRESULT WriteHandlerPayload(IStream* aStream, REFIID aIid) { + return S_OK; + } + + IUnknown* GetProxy() const { return mInnerUnk; } + + static HRESULT Register(REFCLSID aClsid); + static HRESULT Unregister(REFCLSID aClsid); + + protected: + Handler(IUnknown* aOuter, HRESULT* aResult); + virtual ~Handler() {} + bool HasPayload() const { return mHasPayload; } + IUnknown* GetOuter() const { return mOuter; } + + private: + ULONG mRefCnt; + IUnknown* mOuter; + RefPtr<IUnknown> mInnerUnk; + IMarshal* mUnmarshal; // WEAK + bool mHasPayload; + DECLARE_AGGREGATABLE(Handler); +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_Handler_h |