/* -*- 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 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 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 punk(static_cast(&mInternalUnknown)); punk.forget(ppv); return S_OK; } if (riid == IID_IMarshal) { RefPtr 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; } if (IsCallerExternalProcess()) { return aMshlFlags; } // The caller is our parent main thread. Disable ping functionality. 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