mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1368571: Modify handler and interceptor marshaling code so that it strips out any handlers from proxies that are destined for non-Gecko processes; r=jimm
MozReview-Commit-ID: A1lCqvbQYAF There is no clean API-based solution to this, so instead I went grovelling through the DCOM wire protocol and was able to write a function that converts handler OBJREFs into standard OBJREFs. See also: https://msdn.microsoft.com/en-us/library/cc226801 --HG-- extra : rebase_source : a650055c4adda3a1d99262e47f2b463074c6b935
This commit is contained in:
parent
5361fd6640
commit
230ddb60a5
@ -49,6 +49,7 @@ RCINCLUDE = 'AccessibleHandler.rc'
|
||||
# we add the prefix "Proxy" to all of the generated counterparts.
|
||||
DEFINES['ENTRY_PREFIX'] = 'Proxy'
|
||||
DEFINES['REGISTER_PROXY_DLL'] = True
|
||||
LIBRARY_DEFINES['MOZ_MSCOM_REMARSHAL_NO_HANDLER'] = True
|
||||
|
||||
# We want to generate distinct UUIDs on a per-channel basis, so we need
|
||||
# finer granularity than the standard preprocessor definitions offer.
|
||||
|
@ -490,6 +490,7 @@ ContentChild* ContentChild::sSingleton;
|
||||
ContentChild::ContentChild()
|
||||
: mID(uint64_t(-1))
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
, mMainChromeTid(0)
|
||||
, mMsaaID(0)
|
||||
#endif
|
||||
, mCanOverrideProcessName(true)
|
||||
@ -2422,10 +2423,14 @@ ContentChild::RecvFlushMemory(const nsString& reason)
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentChild::RecvActivateA11y(const uint32_t& aMsaaID)
|
||||
ContentChild::RecvActivateA11y(const uint32_t& aMainChromeTid,
|
||||
const uint32_t& aMsaaID)
|
||||
{
|
||||
#ifdef ACCESSIBILITY
|
||||
#ifdef XP_WIN
|
||||
MOZ_ASSERT(aMainChromeTid != 0);
|
||||
mMainChromeTid = aMainChromeTid;
|
||||
|
||||
MOZ_ASSERT(aMsaaID != 0);
|
||||
mMsaaID = aMsaaID;
|
||||
#endif // XP_WIN
|
||||
|
@ -388,7 +388,8 @@ public:
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvFlushMemory(const nsString& reason) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvActivateA11y(const uint32_t& aMsaaID) override;
|
||||
virtual mozilla::ipc::IPCResult RecvActivateA11y(const uint32_t& aMainChromeTid,
|
||||
const uint32_t& aMsaaID) override;
|
||||
virtual mozilla::ipc::IPCResult RecvShutdownA11y() override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvGarbageCollect() override;
|
||||
@ -499,6 +500,8 @@ public:
|
||||
ContentParentId GetID() const { return mID; }
|
||||
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
uint32_t GetChromeMainThreadId() const { return mMainChromeTid; }
|
||||
|
||||
uint32_t GetMsaaID() const { return mMsaaID; }
|
||||
#endif
|
||||
|
||||
@ -699,6 +702,11 @@ private:
|
||||
ContentParentId mID;
|
||||
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
/**
|
||||
* The thread ID of the main thread in the chrome process.
|
||||
*/
|
||||
uint32_t mMainChromeTid;
|
||||
|
||||
/**
|
||||
* This is an a11y-specific unique id for the content process that is
|
||||
* generated by the chrome process.
|
||||
|
@ -1365,9 +1365,10 @@ ContentParent::Init()
|
||||
if (nsIPresShell::IsAccessibilityActive()) {
|
||||
#if defined(XP_WIN)
|
||||
Unused <<
|
||||
SendActivateA11y(a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
|
||||
SendActivateA11y(::GetCurrentThreadId(),
|
||||
a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
|
||||
#else
|
||||
Unused << SendActivateA11y(0);
|
||||
Unused << SendActivateA11y(0, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@ -2773,9 +2774,10 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
// accessibility gets initiated in chrome process.
|
||||
#if defined(XP_WIN)
|
||||
Unused <<
|
||||
SendActivateA11y(a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
|
||||
SendActivateA11y(::GetCurrentThreadId(),
|
||||
a11y::AccessibleWrap::GetContentProcessIdFor(ChildID()));
|
||||
#else
|
||||
Unused << SendActivateA11y(0);
|
||||
Unused << SendActivateA11y(0, 0);
|
||||
#endif
|
||||
} else {
|
||||
// If possible, shut down accessibility in content process when
|
||||
|
@ -443,11 +443,13 @@ child:
|
||||
|
||||
/**
|
||||
* Start accessibility engine in content process.
|
||||
* @param aTid is the thread ID of the chrome process main thread. Only used
|
||||
* on Windows; pass 0 on other platforms.
|
||||
* @param aMsaaID is an a11y-specific unique id for the content process
|
||||
* that is generated by the chrome process. Only used on
|
||||
* Windows; pass 0 on other platforms.
|
||||
*/
|
||||
async ActivateA11y(uint32_t aMsaaID);
|
||||
async ActivateA11y(uint32_t aMainChromeTid, uint32_t aMsaaID);
|
||||
|
||||
/**
|
||||
* Shutdown accessibility engine in content process (if not in use).
|
||||
|
@ -6,11 +6,13 @@
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/mscom/DispatchForwarder.h"
|
||||
#include "mozilla/mscom/Interceptor.h"
|
||||
#include "mozilla/mscom/InterceptorLog.h"
|
||||
#include "mozilla/mscom/MainThreadInvoker.h"
|
||||
#include "mozilla/mscom/Objref.h"
|
||||
#include "mozilla/mscom/Registration.h"
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
#include "MainThreadUtils.h"
|
||||
@ -20,6 +22,7 @@
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
@ -142,6 +145,7 @@ Interceptor::GetClassForHandler(DWORD aDestContext, void* aDestContextPtr,
|
||||
aDestContext == MSHCTX_DIFFERENTMACHINE) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mEventSink);
|
||||
return mEventSink->GetHandler(WrapNotNull(aHandlerClsid));
|
||||
}
|
||||
@ -177,12 +181,60 @@ Interceptor::MarshalInterface(IStream* pStm, REFIID riid, void* pv,
|
||||
DWORD dwDestContext, void* pvDestContext,
|
||||
DWORD mshlflags)
|
||||
{
|
||||
HRESULT hr = mStdMarshal->MarshalInterface(pStm, riid, pv, dwDestContext,
|
||||
pvDestContext, mshlflags);
|
||||
HRESULT hr;
|
||||
|
||||
#if defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
// Save the current stream position
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = 0;
|
||||
|
||||
ULARGE_INTEGER objrefPos;
|
||||
|
||||
hr = pStm->Seek(seekTo, STREAM_SEEK_CUR, &objrefPos);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
#endif // defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
|
||||
hr = mStdMarshal->MarshalInterface(pStm, riid, pv, dwDestContext,
|
||||
pvDestContext, mshlflags);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
if (XRE_IsContentProcess()) {
|
||||
const DWORD chromeMainTid =
|
||||
dom::ContentChild::GetSingleton()->GetChromeMainThreadId();
|
||||
|
||||
/*
|
||||
* CoGetCallerTID() gives us the caller's thread ID when that thread resides
|
||||
* in a single-threaded apartment. Since our chrome main thread does live
|
||||
* inside an STA, we will therefore be able to check whether the caller TID
|
||||
* equals our chrome main thread TID. This enables us to distinguish
|
||||
* between our chrome thread vs other out-of-process callers.
|
||||
*/
|
||||
DWORD callerTid;
|
||||
if (::CoGetCallerTID(&callerTid) == S_FALSE && callerTid != chromeMainTid) {
|
||||
// The caller isn't our chrome process, so do not provide a handler.
|
||||
// First, seek back to the stream position that we prevously saved.
|
||||
seekTo.QuadPart = objrefPos.QuadPart;
|
||||
hr = pStm->Seek(seekTo, STREAM_SEEK_SET, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Now strip out the handler.
|
||||
if (!StripHandlerFromOBJREF(WrapNotNull(pStm))) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
#endif // defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
|
||||
return mEventSink->WriteHandlerPayload(WrapNotNull(pStm));
|
||||
}
|
||||
|
||||
|
@ -453,6 +453,7 @@ MainThreadHandoff::GetHandler(NotNull<CLSID*> aHandlerClsid)
|
||||
if (!mHandlerProvider) {
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return mHandlerProvider->GetHandler(aHandlerClsid);
|
||||
}
|
||||
|
||||
|
249
ipc/mscom/Objref.cpp
Normal file
249
ipc/mscom/Objref.cpp
Normal file
@ -0,0 +1,249 @@
|
||||
/* -*- 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/Objref.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include <guiddef.h>
|
||||
#include <objidl.h>
|
||||
|
||||
namespace {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
typedef uint64_t OID;
|
||||
typedef uint64_t OXID;
|
||||
typedef GUID IPID;
|
||||
|
||||
struct STDOBJREF
|
||||
{
|
||||
uint32_t mFlags;
|
||||
uint32_t mPublicRefs;
|
||||
OXID mOxid;
|
||||
OID mOid;
|
||||
IPID mIpid;
|
||||
};
|
||||
|
||||
enum STDOBJREF_FLAGS
|
||||
{
|
||||
SORF_PING = 0,
|
||||
SORF_NOPING = 0x1000
|
||||
};
|
||||
|
||||
struct DUALSTRINGARRAY
|
||||
{
|
||||
static size_t SizeFromNumEntries(const uint16_t aNumEntries)
|
||||
{
|
||||
return sizeof(mNumEntries) + sizeof(mSecurityOffset) +
|
||||
aNumEntries * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
size_t SizeOf() const
|
||||
{
|
||||
return SizeFromNumEntries(mNumEntries);
|
||||
}
|
||||
|
||||
uint16_t mNumEntries;
|
||||
uint16_t mSecurityOffset;
|
||||
uint16_t mStringArray[1]; // Length is mNumEntries
|
||||
};
|
||||
|
||||
struct OBJREF_STANDARD
|
||||
{
|
||||
size_t SizeOf() const
|
||||
{
|
||||
return sizeof(mStd) + mResAddr.SizeOf();
|
||||
}
|
||||
|
||||
STDOBJREF mStd;
|
||||
DUALSTRINGARRAY mResAddr;
|
||||
};
|
||||
|
||||
struct OBJREF_HANDLER
|
||||
{
|
||||
size_t SizeOf() const
|
||||
{
|
||||
return sizeof(mStd) + sizeof(mClsid) + mResAddr.SizeOf();
|
||||
}
|
||||
|
||||
STDOBJREF mStd;
|
||||
CLSID mClsid;
|
||||
DUALSTRINGARRAY mResAddr;
|
||||
};
|
||||
|
||||
enum OBJREF_FLAGS
|
||||
{
|
||||
OBJREF_TYPE_STANDARD = 0x00000001UL,
|
||||
OBJREF_TYPE_HANDLER = 0x00000002UL,
|
||||
OBJREF_TYPE_CUSTOM = 0x00000004UL,
|
||||
OBJREF_TYPE_EXTENDED = 0x00000008UL,
|
||||
};
|
||||
|
||||
struct OBJREF
|
||||
{
|
||||
size_t SizeOf() const
|
||||
{
|
||||
size_t size = sizeof(mSignature) + sizeof(mFlags) + sizeof(mIid);
|
||||
|
||||
switch (mFlags) {
|
||||
case OBJREF_TYPE_STANDARD:
|
||||
size += mObjRefStd.SizeOf();
|
||||
break;
|
||||
case OBJREF_TYPE_HANDLER:
|
||||
size += mObjRefHandler.SizeOf();
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unsupported OBJREF type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
uint32_t mSignature;
|
||||
uint32_t mFlags;
|
||||
IID mIid;
|
||||
union {
|
||||
OBJREF_STANDARD mObjRefStd;
|
||||
OBJREF_HANDLER mObjRefHandler;
|
||||
// There are others but we're not supporting them here
|
||||
};
|
||||
};
|
||||
|
||||
enum OBJREF_SIGNATURES
|
||||
{
|
||||
OBJREF_SIGNATURE = 0x574F454DUL
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct ByteArrayDeleter
|
||||
{
|
||||
void operator()(void* aPtr)
|
||||
{
|
||||
delete[] reinterpret_cast<uint8_t*>(aPtr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using VarStructUniquePtr = mozilla::UniquePtr<T, ByteArrayDeleter>;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
bool
|
||||
StripHandlerFromOBJREF(NotNull<IStream*> aStream)
|
||||
{
|
||||
// Get current stream position
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = 0;
|
||||
|
||||
ULARGE_INTEGER objrefPos;
|
||||
|
||||
HRESULT hr = aStream->Seek(seekTo, STREAM_SEEK_CUR, &objrefPos);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG bytesRead;
|
||||
|
||||
uint32_t signature;
|
||||
hr = aStream->Read(&signature, sizeof(signature), &bytesRead);
|
||||
if (FAILED(hr) || bytesRead != sizeof(signature) ||
|
||||
signature != OBJREF_SIGNATURE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t type;
|
||||
hr = aStream->Read(&type, sizeof(type), &bytesRead);
|
||||
if (FAILED(hr) || bytesRead != sizeof(type) ||
|
||||
type != OBJREF_TYPE_HANDLER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IID iid;
|
||||
hr = aStream->Read(&iid, sizeof(iid), &bytesRead);
|
||||
if (FAILED(hr) || bytesRead != sizeof(iid) || !IsValidGUID(iid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Seek past fixed-size STDOBJREF and CLSID
|
||||
seekTo.QuadPart = sizeof(STDOBJREF) + sizeof(CLSID);
|
||||
hr = aStream->Seek(seekTo, STREAM_SEEK_CUR, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
uint16_t numEntries;
|
||||
hr = aStream->Read(&numEntries, sizeof(numEntries), &bytesRead);
|
||||
if (FAILED(hr) || bytesRead != sizeof(numEntries)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll try to use a stack buffer if resAddrSize <= kMinDualStringArraySize
|
||||
const uint32_t kMinDualStringArraySize = 12;
|
||||
uint16_t staticResAddrBuf[kMinDualStringArraySize / sizeof(uint16_t)];
|
||||
|
||||
size_t resAddrSize = DUALSTRINGARRAY::SizeFromNumEntries(numEntries);
|
||||
|
||||
DUALSTRINGARRAY* resAddr;
|
||||
VarStructUniquePtr<DUALSTRINGARRAY> dynamicResAddrBuf;
|
||||
|
||||
if (resAddrSize <= kMinDualStringArraySize) {
|
||||
resAddr = reinterpret_cast<DUALSTRINGARRAY*>(staticResAddrBuf);
|
||||
} else {
|
||||
dynamicResAddrBuf.reset(
|
||||
reinterpret_cast<DUALSTRINGARRAY*>(new uint8_t[resAddrSize]));
|
||||
resAddr = dynamicResAddrBuf.get();
|
||||
}
|
||||
|
||||
resAddr->mNumEntries = numEntries;
|
||||
|
||||
// Because we've already read numEntries
|
||||
ULONG bytesToRead = resAddrSize - sizeof(numEntries);
|
||||
|
||||
hr = aStream->Read(&resAddr->mSecurityOffset, bytesToRead, &bytesRead);
|
||||
if (FAILED(hr) || bytesRead != bytesToRead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Signature doesn't change so we'll seek past that
|
||||
seekTo.QuadPart = objrefPos.QuadPart + sizeof(signature);
|
||||
hr = aStream->Seek(seekTo, STREAM_SEEK_SET, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG bytesWritten;
|
||||
|
||||
uint32_t newType = OBJREF_TYPE_STANDARD;
|
||||
hr = aStream->Write(&newType, sizeof(newType), &bytesWritten);
|
||||
if (FAILED(hr) || bytesWritten != sizeof(newType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip past IID and STDOBJREF since those don't change
|
||||
seekTo.QuadPart = sizeof(IID) + sizeof(STDOBJREF);
|
||||
hr = aStream->Seek(seekTo, STREAM_SEEK_CUR, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = aStream->Write(resAddr, resAddrSize, &bytesWritten);
|
||||
if (FAILED(hr) || bytesWritten != resAddrSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
32
ipc/mscom/Objref.h
Normal file
32
ipc/mscom/Objref.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- 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_Objref_h
|
||||
#define mozilla_mscom_Objref_h
|
||||
|
||||
#include "mozilla/NotNull.h"
|
||||
|
||||
struct IStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace mscom {
|
||||
|
||||
/**
|
||||
* Given a buffer containing a serialized proxy to an interface with a handler,
|
||||
* this function strips out the handler and converts it to a standard one.
|
||||
* @param aStream IStream whose pointer is positioned at the beginning of the
|
||||
* OBJREF to be stripped. There should be nothing else written
|
||||
* to the stream past the current OBJREF.
|
||||
* @return true if the handler was successfully stripped, otherwise false.
|
||||
*/
|
||||
bool
|
||||
StripHandlerFromOBJREF(NotNull<IStream*> aStream);
|
||||
|
||||
} // namespace mscom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_mscom_Objref_h
|
||||
|
@ -4,10 +4,12 @@
|
||||
* 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/. */
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
#if defined(ACCESSIBILITY)
|
||||
#include "mozilla/mscom/Registration.h"
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
#include "nsTArray.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "mozilla/mscom/Utils.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
@ -139,6 +141,8 @@ IsVtableIndexFromParentInterface(REFIID aInterface, unsigned long aVtableIndex)
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
bool
|
||||
IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom,
|
||||
unsigned long aVtableIndexHint)
|
||||
@ -223,6 +227,8 @@ IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom,
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
|
||||
} // namespace mscom
|
||||
|
@ -11,9 +11,7 @@
|
||||
#include "nsString.h"
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
#include <guiddef.h>
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
|
||||
struct IUnknown;
|
||||
|
||||
@ -31,8 +29,10 @@ void GUIDToString(REFGUID aGuid, nsAString& aOutString);
|
||||
#if defined(ACCESSIBILITY)
|
||||
bool IsVtableIndexFromParentInterface(REFIID aInterface,
|
||||
unsigned long aVtableIndex);
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
bool IsInterfaceEqualToOrInheritedFrom(REFIID aInterface, REFIID aFrom,
|
||||
unsigned long aVtableIndexHint);
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
|
||||
} // namespace mscom
|
||||
|
@ -12,6 +12,7 @@ EXPORTS.mozilla.mscom += [
|
||||
'COMPtrHolder.h',
|
||||
'EnsureMTA.h',
|
||||
'MainThreadRuntime.h',
|
||||
'Objref.h',
|
||||
'ProxyStream.h',
|
||||
'Ptr.h',
|
||||
'Utils.h',
|
||||
@ -21,6 +22,7 @@ UNIFIED_SOURCES += [
|
||||
'AgileReference.cpp',
|
||||
'EnsureMTA.cpp',
|
||||
'MainThreadRuntime.cpp',
|
||||
'Objref.cpp',
|
||||
'ProxyStream.cpp',
|
||||
'Utils.cpp',
|
||||
]
|
||||
@ -70,6 +72,8 @@ LOCAL_INCLUDES += [
|
||||
'/xpcom/build',
|
||||
]
|
||||
|
||||
DEFINES['MOZ_MSCOM_REMARSHAL_NO_HANDLER'] = True
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/mscom/Objref.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
#include <objbase.h>
|
||||
@ -48,7 +49,7 @@ Handler::Handler(IUnknown* aOuter, HRESULT* aResult)
|
||||
return;
|
||||
}
|
||||
|
||||
// mInnerMarshal is a weak ref
|
||||
// mUnmarshal is a weak ref
|
||||
mUnmarshal->Release();
|
||||
}
|
||||
|
||||
@ -169,14 +170,28 @@ Handler::MarshalInterface(IStream* pStm, REFIID riid, void* pv,
|
||||
RefPtr<IUnknown> unkToMarshal;
|
||||
HRESULT hr;
|
||||
|
||||
#if defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
LARGE_INTEGER seekTo;
|
||||
seekTo.QuadPart = 0;
|
||||
|
||||
ULARGE_INTEGER objrefPos;
|
||||
|
||||
// Save the current position as it points to the location where the OBJREF
|
||||
// will be written.
|
||||
hr = pStm->Seek(seekTo, STREAM_SEEK_CUR, &objrefPos);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// When marshaling without a handler, we just use the riid as passed in.
|
||||
REFIID marshalAs = riid;
|
||||
#else
|
||||
REFIID marshalAs = MarshalAs(riid);
|
||||
if (marshalAs == riid) {
|
||||
unkToMarshal = static_cast<IUnknown*>(pv);
|
||||
} else {
|
||||
hr = mInnerUnk->QueryInterface(marshalAs, getter_AddRefs(unkToMarshal));
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
#endif // defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
|
||||
hr = mInnerUnk->QueryInterface(marshalAs, getter_AddRefs(unkToMarshal));
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = mUnmarshal->MarshalInterface(pStm, marshalAs, unkToMarshal.get(),
|
||||
@ -185,6 +200,22 @@ Handler::MarshalInterface(IStream* pStm, REFIID riid, void* pv,
|
||||
return hr;
|
||||
}
|
||||
|
||||
#if defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
// Now the OBJREF has been written, so seek back to its beginning (the
|
||||
// position that we saved earlier).
|
||||
seekTo.QuadPart = objrefPos.QuadPart;
|
||||
hr = pStm->Seek(seekTo, STREAM_SEEK_SET, nullptr);
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
// Now strip out the handler.
|
||||
if (!StripHandlerFromOBJREF(WrapNotNull(pStm))) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
#else
|
||||
if (!HasPayload()) {
|
||||
return S_OK;
|
||||
}
|
||||
@ -192,6 +223,7 @@ Handler::MarshalInterface(IStream* pStm, REFIID riid, void* pv,
|
||||
// Unfortunately when COM re-marshals a proxy that prevouisly had a payload,
|
||||
// we must re-serialize it.
|
||||
return WriteHandlerPayload(pStm, marshalAs);
|
||||
#endif // defined(MOZ_MSCOM_REMARSHAL_NO_HANDLER)
|
||||
}
|
||||
|
||||
HRESULT
|
||||
|
@ -8,8 +8,10 @@ Library('mscom_oop')
|
||||
|
||||
SOURCES += [
|
||||
'../ActivationContext.cpp',
|
||||
'../Objref.cpp',
|
||||
'../Registration.cpp',
|
||||
'../StructStream.cpp',
|
||||
'../Utils.cpp',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
@ -26,6 +28,7 @@ OS_LIBS += [
|
||||
LIBRARY_DEFINES['UNICODE'] = True
|
||||
LIBRARY_DEFINES['_UNICODE'] = True
|
||||
LIBRARY_DEFINES['MOZ_NO_MOZALLOC'] = True
|
||||
LIBRARY_DEFINES['MOZ_MSCOM_REMARSHAL_NO_HANDLER'] = True
|
||||
|
||||
DISABLE_STL_WRAPPING = True
|
||||
NO_EXPAND_LIBS = True
|
||||
|
Loading…
Reference in New Issue
Block a user