mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-03 15:26:07 +00:00

Previously, we only did this when IsCallerExternalProcess() returned false. There are three reasons for changing this: 1. There seem to be cases where IsCallerExternalProcess() returns true even when marshaling for a COM query in the MTA. 2. After bug 1627084, we pre-build a11y handler payloads on the main thread for bulk fetch calls. That will marshal interceptors. However, IsCallerExternalProcess() can't work in that case because it's not running on the thread on which the COM call is being handled. 3. If MSHLFLAGS_NOPING is used, Release calls from remote clients are never sent to the server. So, as soon as we use NOPING for our parent process, we're already going to leak references, even if we don't use NOPING for external callers. Put another way, as soon as we use NOPING for one caller, we may as well use it for all callers because COM pinging will never release the object anyway. Differential Revision: https://phabricator.services.mozilla.com/D84778
165 lines
3.9 KiB
C++
165 lines
3.9 KiB
C++
/* -*- 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
|