summaryrefslogtreecommitdiffstats
path: root/ipc/mscom/oop/Handler.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/mscom/oop/Handler.h')
-rw-r--r--ipc/mscom/oop/Handler.h134
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