diff options
Diffstat (limited to 'ipc/mscom/FastMarshaler.cpp')
-rw-r--r-- | ipc/mscom/FastMarshaler.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/ipc/mscom/FastMarshaler.cpp b/ipc/mscom/FastMarshaler.cpp new file mode 100644 index 0000000000..4ae62394a2 --- /dev/null +++ b/ipc/mscom/FastMarshaler.cpp @@ -0,0 +1,164 @@ +/* -*- 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/. */ + +#include "mozilla/mscom/FastMarshaler.h" + +#include "mozilla/mscom/Utils.h" + +#include <objbase.h> + +namespace mozilla { +namespace mscom { + +HRESULT +FastMarshaler::Create(IUnknown* aOuter, IUnknown** aOutMarshalerUnk) { + MOZ_ASSERT(XRE_IsContentProcess()); + + if (!aOuter || !aOutMarshalerUnk) { + return E_INVALIDARG; + } + + *aOutMarshalerUnk = nullptr; + + HRESULT hr; + RefPtr<FastMarshaler> fm(new FastMarshaler(aOuter, &hr)); + if (FAILED(hr)) { + return hr; + } + + return fm->InternalQueryInterface(IID_IUnknown, (void**)aOutMarshalerUnk); +} + +FastMarshaler::FastMarshaler(IUnknown* aOuter, HRESULT* aResult) + : mRefCnt(0), mOuter(aOuter), mStdMarshalWeak(nullptr) { + *aResult = + ::CoGetStdMarshalEx(aOuter, SMEXF_SERVER, getter_AddRefs(mStdMarshalUnk)); + if (FAILED(*aResult)) { + return; + } + + *aResult = + mStdMarshalUnk->QueryInterface(IID_IMarshal, (void**)&mStdMarshalWeak); + if (FAILED(*aResult)) { + return; + } + + // mStdMarshalWeak is weak + mStdMarshalWeak->Release(); +} + +HRESULT +FastMarshaler::InternalQueryInterface(REFIID riid, void** ppv) { + if (!ppv) { + return E_INVALIDARG; + } + + if (riid == IID_IUnknown) { + RefPtr<IUnknown> punk(static_cast<IUnknown*>(&mInternalUnknown)); + punk.forget(ppv); + return S_OK; + } + + if (riid == IID_IMarshal) { + RefPtr<IMarshal> ptr(this); + ptr.forget(ppv); + return S_OK; + } + + return mStdMarshalUnk->QueryInterface(riid, ppv); +} + +ULONG +FastMarshaler::InternalAddRef() { return ++mRefCnt; } + +ULONG +FastMarshaler::InternalRelease() { + ULONG result = --mRefCnt; + if (!result) { + delete this; + } + + return result; +} + +DWORD +FastMarshaler::GetMarshalFlags(DWORD aDestContext, DWORD aMshlFlags) { + // Only worry about local contexts. + if (aDestContext != MSHCTX_LOCAL) { + return aMshlFlags; + } + + return aMshlFlags | MSHLFLAGS_NOPING; +} + +HRESULT +FastMarshaler::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + CLSID* pCid) { + if (!mStdMarshalWeak) { + return E_POINTER; + } + + return mStdMarshalWeak->GetUnmarshalClass( + riid, pv, dwDestContext, pvDestContext, + GetMarshalFlags(dwDestContext, mshlflags), pCid); +} + +HRESULT +FastMarshaler::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + DWORD* pSize) { + if (!mStdMarshalWeak) { + return E_POINTER; + } + + return mStdMarshalWeak->GetMarshalSizeMax( + riid, pv, dwDestContext, pvDestContext, + GetMarshalFlags(dwDestContext, mshlflags), pSize); +} + +HRESULT +FastMarshaler::MarshalInterface(IStream* pStm, REFIID riid, void* pv, + DWORD dwDestContext, void* pvDestContext, + DWORD mshlflags) { + if (!mStdMarshalWeak) { + return E_POINTER; + } + + return mStdMarshalWeak->MarshalInterface( + pStm, riid, pv, dwDestContext, pvDestContext, + GetMarshalFlags(dwDestContext, mshlflags)); +} + +HRESULT +FastMarshaler::UnmarshalInterface(IStream* pStm, REFIID riid, void** ppv) { + if (!mStdMarshalWeak) { + return E_POINTER; + } + + return mStdMarshalWeak->UnmarshalInterface(pStm, riid, ppv); +} + +HRESULT +FastMarshaler::ReleaseMarshalData(IStream* pStm) { + if (!mStdMarshalWeak) { + return E_POINTER; + } + + return mStdMarshalWeak->ReleaseMarshalData(pStm); +} + +HRESULT +FastMarshaler::DisconnectObject(DWORD dwReserved) { + if (!mStdMarshalWeak) { + return E_POINTER; + } + + return mStdMarshalWeak->DisconnectObject(dwReserved); +} + +} // namespace mscom +} // namespace mozilla |