1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "mozilla/mscom/FastMarshaler.h"
8
9 #include "mozilla/mscom/Utils.h"
10
11 #include <objbase.h>
12
13 namespace mozilla {
14 namespace mscom {
15
16 HRESULT
Create(IUnknown * aOuter,IUnknown ** aOutMarshalerUnk)17 FastMarshaler::Create(IUnknown* aOuter, IUnknown** aOutMarshalerUnk) {
18 MOZ_ASSERT(XRE_IsContentProcess());
19
20 if (!aOuter || !aOutMarshalerUnk) {
21 return E_INVALIDARG;
22 }
23
24 *aOutMarshalerUnk = nullptr;
25
26 HRESULT hr;
27 RefPtr<FastMarshaler> fm(new FastMarshaler(aOuter, &hr));
28 if (FAILED(hr)) {
29 return hr;
30 }
31
32 return fm->InternalQueryInterface(IID_IUnknown, (void**)aOutMarshalerUnk);
33 }
34
FastMarshaler(IUnknown * aOuter,HRESULT * aResult)35 FastMarshaler::FastMarshaler(IUnknown* aOuter, HRESULT* aResult)
36 : mRefCnt(0), mOuter(aOuter), mStdMarshalWeak(nullptr) {
37 *aResult =
38 ::CoGetStdMarshalEx(aOuter, SMEXF_SERVER, getter_AddRefs(mStdMarshalUnk));
39 if (FAILED(*aResult)) {
40 return;
41 }
42
43 *aResult =
44 mStdMarshalUnk->QueryInterface(IID_IMarshal, (void**)&mStdMarshalWeak);
45 if (FAILED(*aResult)) {
46 return;
47 }
48
49 // mStdMarshalWeak is weak
50 mStdMarshalWeak->Release();
51 }
52
53 HRESULT
InternalQueryInterface(REFIID riid,void ** ppv)54 FastMarshaler::InternalQueryInterface(REFIID riid, void** ppv) {
55 if (!ppv) {
56 return E_INVALIDARG;
57 }
58
59 if (riid == IID_IUnknown) {
60 RefPtr<IUnknown> punk(static_cast<IUnknown*>(&mInternalUnknown));
61 punk.forget(ppv);
62 return S_OK;
63 }
64
65 if (riid == IID_IMarshal) {
66 RefPtr<IMarshal> ptr(this);
67 ptr.forget(ppv);
68 return S_OK;
69 }
70
71 return mStdMarshalUnk->QueryInterface(riid, ppv);
72 }
73
74 ULONG
InternalAddRef()75 FastMarshaler::InternalAddRef() { return ++mRefCnt; }
76
77 ULONG
InternalRelease()78 FastMarshaler::InternalRelease() {
79 ULONG result = --mRefCnt;
80 if (!result) {
81 delete this;
82 }
83
84 return result;
85 }
86
87 DWORD
GetMarshalFlags(DWORD aDestContext,DWORD aMshlFlags)88 FastMarshaler::GetMarshalFlags(DWORD aDestContext, DWORD aMshlFlags) {
89 // Only worry about local contexts.
90 if (aDestContext != MSHCTX_LOCAL) {
91 return aMshlFlags;
92 }
93
94 return aMshlFlags | MSHLFLAGS_NOPING;
95 }
96
97 HRESULT
GetUnmarshalClass(REFIID riid,void * pv,DWORD dwDestContext,void * pvDestContext,DWORD mshlflags,CLSID * pCid)98 FastMarshaler::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext,
99 void* pvDestContext, DWORD mshlflags,
100 CLSID* pCid) {
101 if (!mStdMarshalWeak) {
102 return E_POINTER;
103 }
104
105 return mStdMarshalWeak->GetUnmarshalClass(
106 riid, pv, dwDestContext, pvDestContext,
107 GetMarshalFlags(dwDestContext, mshlflags), pCid);
108 }
109
110 HRESULT
GetMarshalSizeMax(REFIID riid,void * pv,DWORD dwDestContext,void * pvDestContext,DWORD mshlflags,DWORD * pSize)111 FastMarshaler::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext,
112 void* pvDestContext, DWORD mshlflags,
113 DWORD* pSize) {
114 if (!mStdMarshalWeak) {
115 return E_POINTER;
116 }
117
118 return mStdMarshalWeak->GetMarshalSizeMax(
119 riid, pv, dwDestContext, pvDestContext,
120 GetMarshalFlags(dwDestContext, mshlflags), pSize);
121 }
122
123 HRESULT
MarshalInterface(IStream * pStm,REFIID riid,void * pv,DWORD dwDestContext,void * pvDestContext,DWORD mshlflags)124 FastMarshaler::MarshalInterface(IStream* pStm, REFIID riid, void* pv,
125 DWORD dwDestContext, void* pvDestContext,
126 DWORD mshlflags) {
127 if (!mStdMarshalWeak) {
128 return E_POINTER;
129 }
130
131 return mStdMarshalWeak->MarshalInterface(
132 pStm, riid, pv, dwDestContext, pvDestContext,
133 GetMarshalFlags(dwDestContext, mshlflags));
134 }
135
136 HRESULT
UnmarshalInterface(IStream * pStm,REFIID riid,void ** ppv)137 FastMarshaler::UnmarshalInterface(IStream* pStm, REFIID riid, void** ppv) {
138 if (!mStdMarshalWeak) {
139 return E_POINTER;
140 }
141
142 return mStdMarshalWeak->UnmarshalInterface(pStm, riid, ppv);
143 }
144
145 HRESULT
ReleaseMarshalData(IStream * pStm)146 FastMarshaler::ReleaseMarshalData(IStream* pStm) {
147 if (!mStdMarshalWeak) {
148 return E_POINTER;
149 }
150
151 return mStdMarshalWeak->ReleaseMarshalData(pStm);
152 }
153
154 HRESULT
DisconnectObject(DWORD dwReserved)155 FastMarshaler::DisconnectObject(DWORD dwReserved) {
156 if (!mStdMarshalWeak) {
157 return E_POINTER;
158 }
159
160 return mStdMarshalWeak->DisconnectObject(dwReserved);
161 }
162
163 } // namespace mscom
164 } // namespace mozilla
165