summaryrefslogtreecommitdiffstats
path: root/ipc/mscom/PassthruProxy.h
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/mscom/PassthruProxy.h')
-rw-r--r--ipc/mscom/PassthruProxy.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/ipc/mscom/PassthruProxy.h b/ipc/mscom/PassthruProxy.h
new file mode 100644
index 0000000000..afdb5c648e
--- /dev/null
+++ b/ipc/mscom/PassthruProxy.h
@@ -0,0 +1,127 @@
+/* -*- 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_PassthruProxy_h
+#define mozilla_mscom_PassthruProxy_h
+
+#include "mozilla/Atomics.h"
+#include "mozilla/mscom/ProxyStream.h"
+#include "mozilla/mscom/Ptr.h"
+#include "mozilla/NotNull.h"
+#if defined(MOZ_SANDBOX)
+# include "mozilla/SandboxSettings.h"
+#endif // defined(MOZ_SANDBOX)
+
+#include <objbase.h>
+
+namespace mozilla {
+namespace mscom {
+namespace detail {
+
+template <typename Iface>
+struct VTableSizer;
+
+template <>
+struct VTableSizer<IDispatch> {
+ enum { Size = 7 };
+};
+
+} // namespace detail
+
+class PassthruProxy final : public IMarshal, public IClientSecurity {
+ public:
+ template <typename Iface>
+ static RefPtr<Iface> Wrap(NotNull<Iface*> aIn) {
+ static_assert(detail::VTableSizer<Iface>::Size >= 3, "VTable too small");
+
+#if defined(MOZ_SANDBOX)
+ if (mozilla::GetEffectiveContentSandboxLevel() < 3) {
+ // The sandbox isn't strong enough to be a problem; no wrapping required
+ return aIn.get();
+ }
+
+ typename detail::EnvironmentSelector<Iface>::Type env;
+
+ RefPtr<PassthruProxy> passthru(new PassthruProxy(
+ &env, __uuidof(Iface), detail::VTableSizer<Iface>::Size, aIn));
+
+ RefPtr<Iface> result;
+ if (FAILED(passthru->QueryProxyInterface(getter_AddRefs(result)))) {
+ return nullptr;
+ }
+
+ return result;
+#else
+ // No wrapping required
+ return aIn.get();
+#endif // defined(MOZ_SANDBOX)
+ }
+
+ static HRESULT Register();
+
+ PassthruProxy();
+
+ // IUnknown
+ STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
+ STDMETHODIMP_(ULONG) AddRef() override;
+ STDMETHODIMP_(ULONG) Release() override;
+
+ // 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;
+
+ // IClientSecurity - we don't actually implement this interface, but its
+ // presence signals to mscom::IsProxy() that we are a proxy.
+ STDMETHODIMP QueryBlanket(IUnknown* aProxy, DWORD* aAuthnSvc,
+ DWORD* aAuthzSvc, OLECHAR** aSrvPrincName,
+ DWORD* aAuthnLevel, DWORD* aImpLevel,
+ void** aAuthInfo, DWORD* aCapabilities) override {
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP SetBlanket(IUnknown* aProxy, DWORD aAuthnSvc, DWORD aAuthzSvc,
+ OLECHAR* aSrvPrincName, DWORD aAuthnLevel,
+ DWORD aImpLevel, void* aAuthInfo,
+ DWORD aCapabilities) override {
+ return E_NOTIMPL;
+ }
+
+ STDMETHODIMP CopyProxy(IUnknown* aProxy, IUnknown** aOutCopy) override {
+ return E_NOTIMPL;
+ }
+
+ private:
+ PassthruProxy(ProxyStream::Environment* aEnv, REFIID aIidToWrap,
+ uint32_t aVTableSize, NotNull<IUnknown*> aObjToWrap);
+ ~PassthruProxy();
+
+ bool IsInitialMarshal() const { return !mStream; }
+ HRESULT QueryProxyInterface(void** aOutInterface);
+
+ Atomic<ULONG> mRefCnt;
+ IID mWrappedIid;
+ PreservedStreamPtr mPreservedStream;
+ RefPtr<IStream> mStream;
+ uint32_t mVTableSize;
+ IUnknown* mVTable;
+ bool mForgetPreservedStream;
+};
+
+} // namespace mscom
+} // namespace mozilla
+
+#endif // mozilla_mscom_PassthruProxy_h