2017-08-18 00:54:28 +03:00
|
|
|
/* -*- 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;
|
|
|
|
}
|
|
|
|
|
2018-02-01 08:42:24 +03:00
|
|
|
if (IsCallerExternalProcess()) {
|
2017-08-18 00:54:28 +03:00
|
|
|
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
|