1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_dtrans.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir //------------------------------------------------------------------------
32*cdf0e10cSrcweir // includes
33*cdf0e10cSrcweir //------------------------------------------------------------------------
34*cdf0e10cSrcweir #include "APNDataObject.hxx"
35*cdf0e10cSrcweir #include <osl/diagnose.h>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <systools/win32/comtools.hxx>
38*cdf0e10cSrcweir #ifdef __MINGW32__
39*cdf0e10cSrcweir #define __uuidof(I) IID_##I
40*cdf0e10cSrcweir #endif
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir //------------------------------------------------------------------------
43*cdf0e10cSrcweir // defines
44*cdf0e10cSrcweir //------------------------------------------------------------------------
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #define FREE_HGLOB_ON_RELEASE	TRUE
47*cdf0e10cSrcweir #define KEEP_HGLOB_ON_RELEASE	FALSE
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir //------------------------------------------------------------------------
50*cdf0e10cSrcweir // ctor
51*cdf0e10cSrcweir //------------------------------------------------------------------------
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir CAPNDataObject::CAPNDataObject( IDataObjectPtr rIDataObject ) :
54*cdf0e10cSrcweir 	m_rIDataObjectOrg( rIDataObject ),
55*cdf0e10cSrcweir 	m_hGlobal( NULL ),
56*cdf0e10cSrcweir 	m_nRefCnt( 0 )
57*cdf0e10cSrcweir {
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir 	OSL_ENSURE( m_rIDataObjectOrg.get( ), "constructing CAPNDataObject with empty data object" );
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir 	// we marshal the IDataObject interface pointer here so
62*cdf0e10cSrcweir 	// that it can be unmarshaled multiple times when this
63*cdf0e10cSrcweir 	// class will be used from another apartment
64*cdf0e10cSrcweir 	IStreamPtr pStm;
65*cdf0e10cSrcweir 	HRESULT hr = CreateStreamOnHGlobal( 0, KEEP_HGLOB_ON_RELEASE, &pStm );
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir     OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir     if ( SUCCEEDED( hr ) )
70*cdf0e10cSrcweir 	{
71*cdf0e10cSrcweir 		HRESULT hr_marshal = CoMarshalInterface(
72*cdf0e10cSrcweir             pStm.get(),
73*cdf0e10cSrcweir 			__uuidof(IDataObject),
74*cdf0e10cSrcweir 			static_cast<LPUNKNOWN>(m_rIDataObjectOrg.get()),
75*cdf0e10cSrcweir 			MSHCTX_LOCAL,
76*cdf0e10cSrcweir 			NULL,
77*cdf0e10cSrcweir 			MSHLFLAGS_TABLEWEAK );
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir         OSL_ENSURE( CO_E_NOTINITIALIZED != hr_marshal, "COM is not initialized" );
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir         // marshalling may fail if COM is not initialized
82*cdf0e10cSrcweir         // for the calling thread which is a program time
83*cdf0e10cSrcweir         // error or because of stream errors which are runtime
84*cdf0e10cSrcweir         // errors for instance E_OUTOFMEMORY etc.
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir 		hr = GetHGlobalFromStream(pStm.get(), &m_hGlobal );
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir         OSL_ENSURE( E_INVALIDARG != hr, "invalid stream passed to GetHGlobalFromStream" );
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir         // if the marshalling failed we free the
91*cdf0e10cSrcweir         // global memory again and set m_hGlobal
92*cdf0e10cSrcweir         // to a defined value
93*cdf0e10cSrcweir         if (FAILED(hr_marshal))
94*cdf0e10cSrcweir         {
95*cdf0e10cSrcweir             OSL_ENSURE(sal_False, "marshalling failed");
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir             #if OSL_DEBUG_LEVEL > 0
98*cdf0e10cSrcweir             HGLOBAL hGlobal =
99*cdf0e10cSrcweir             #endif
100*cdf0e10cSrcweir                 GlobalFree(m_hGlobal);
101*cdf0e10cSrcweir             OSL_ENSURE(NULL == hGlobal, "GlobalFree failed");
102*cdf0e10cSrcweir             m_hGlobal = NULL;
103*cdf0e10cSrcweir         }
104*cdf0e10cSrcweir 	}
105*cdf0e10cSrcweir }
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir CAPNDataObject::~CAPNDataObject( )
108*cdf0e10cSrcweir {
109*cdf0e10cSrcweir 	if (m_hGlobal)
110*cdf0e10cSrcweir 	{
111*cdf0e10cSrcweir 		IStreamPtr pStm;
112*cdf0e10cSrcweir 		HRESULT  hr = CreateStreamOnHGlobal(m_hGlobal, FREE_HGLOB_ON_RELEASE, &pStm);
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir         OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir         if (SUCCEEDED(hr))
117*cdf0e10cSrcweir         {
118*cdf0e10cSrcweir 		    hr = CoReleaseMarshalData(pStm.get());
119*cdf0e10cSrcweir             OSL_ENSURE(SUCCEEDED(hr), "CoReleaseMarshalData failed");
120*cdf0e10cSrcweir         }
121*cdf0e10cSrcweir 	}
122*cdf0e10cSrcweir }
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir //------------------------------------------------------------------------
125*cdf0e10cSrcweir // IUnknown->QueryInterface
126*cdf0e10cSrcweir //------------------------------------------------------------------------
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir 	OSL_ASSERT( NULL != ppvObject );
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir 	if ( NULL == ppvObject )
133*cdf0e10cSrcweir 		return E_INVALIDARG;
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
136*cdf0e10cSrcweir 	*ppvObject = NULL;
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
139*cdf0e10cSrcweir 	{
140*cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
141*cdf0e10cSrcweir 		( (LPUNKNOWN)*ppvObject )->AddRef( );
142*cdf0e10cSrcweir 		hr = S_OK;
143*cdf0e10cSrcweir 	}
144*cdf0e10cSrcweir 
145*cdf0e10cSrcweir 	return hr;
146*cdf0e10cSrcweir }
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir //------------------------------------------------------------------------
149*cdf0e10cSrcweir // IUnknown->AddRef
150*cdf0e10cSrcweir //------------------------------------------------------------------------
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir STDMETHODIMP_(ULONG) CAPNDataObject::AddRef( )
153*cdf0e10cSrcweir {
154*cdf0e10cSrcweir 	return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
155*cdf0e10cSrcweir }
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir //------------------------------------------------------------------------
158*cdf0e10cSrcweir // IUnknown->Release
159*cdf0e10cSrcweir //------------------------------------------------------------------------
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir STDMETHODIMP_(ULONG) CAPNDataObject::Release( )
162*cdf0e10cSrcweir {
163*cdf0e10cSrcweir 	// we need a helper variable because it's not allowed to access
164*cdf0e10cSrcweir 	// a member variable after an object is destroyed
165*cdf0e10cSrcweir 	ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir 	if ( 0 == nRefCnt )
168*cdf0e10cSrcweir 		delete this;
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir 	return nRefCnt;
171*cdf0e10cSrcweir }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir //------------------------------------------------------------------------
174*cdf0e10cSrcweir // IDataObject->GetData
175*cdf0e10cSrcweir //------------------------------------------------------------------------
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
178*cdf0e10cSrcweir {
179*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->GetData( pFormatetc, pmedium );
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
182*cdf0e10cSrcweir 	{
183*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
184*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
187*cdf0e10cSrcweir 			hr = pIDOTmp->GetData(pFormatetc, pmedium);
188*cdf0e10cSrcweir 	}
189*cdf0e10cSrcweir 	return hr;
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir //------------------------------------------------------------------------
193*cdf0e10cSrcweir // IDataObject->EnumFormatEtc
194*cdf0e10cSrcweir //------------------------------------------------------------------------
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
197*cdf0e10cSrcweir {
198*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->EnumFormatEtc(dwDirection, ppenumFormatetc);
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
201*cdf0e10cSrcweir 	{
202*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
203*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
204*cdf0e10cSrcweir 
205*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
206*cdf0e10cSrcweir 			hr = pIDOTmp->EnumFormatEtc(dwDirection, ppenumFormatetc);
207*cdf0e10cSrcweir 	}
208*cdf0e10cSrcweir 	return hr;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir //------------------------------------------------------------------------
212*cdf0e10cSrcweir // IDataObject->QueryGetData
213*cdf0e10cSrcweir //------------------------------------------------------------------------
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::QueryGetData( LPFORMATETC pFormatetc )
216*cdf0e10cSrcweir {
217*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->QueryGetData( pFormatetc );
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
220*cdf0e10cSrcweir 	{
221*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
222*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment( &pIDOTmp );
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
225*cdf0e10cSrcweir 			hr = pIDOTmp->QueryGetData(pFormatetc);
226*cdf0e10cSrcweir 	}
227*cdf0e10cSrcweir 	return hr;
228*cdf0e10cSrcweir }
229*cdf0e10cSrcweir 
230*cdf0e10cSrcweir //------------------------------------------------------------------------
231*cdf0e10cSrcweir // IDataObject->GetDataHere
232*cdf0e10cSrcweir //------------------------------------------------------------------------
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
235*cdf0e10cSrcweir {
236*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->GetDataHere(pFormatetc, pmedium);
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
239*cdf0e10cSrcweir 	{
240*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
241*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
244*cdf0e10cSrcweir 			hr = pIDOTmp->GetDataHere(pFormatetc, pmedium);
245*cdf0e10cSrcweir 	}
246*cdf0e10cSrcweir 	return hr;
247*cdf0e10cSrcweir }
248*cdf0e10cSrcweir 
249*cdf0e10cSrcweir //------------------------------------------------------------------------
250*cdf0e10cSrcweir // IDataObject->GetCanonicalFormatEtc
251*cdf0e10cSrcweir //------------------------------------------------------------------------
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut)
254*cdf0e10cSrcweir {
255*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->GetCanonicalFormatEtc( pFormatectIn, pFormatetcOut );
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
258*cdf0e10cSrcweir 	{
259*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
260*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
263*cdf0e10cSrcweir 			hr = pIDOTmp->GetCanonicalFormatEtc(pFormatectIn, pFormatetcOut);
264*cdf0e10cSrcweir 	}
265*cdf0e10cSrcweir 	return hr;
266*cdf0e10cSrcweir }
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir //------------------------------------------------------------------------
269*cdf0e10cSrcweir // IDataObject->SetData
270*cdf0e10cSrcweir //------------------------------------------------------------------------
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease )
273*cdf0e10cSrcweir {
274*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->SetData( pFormatetc, pmedium, fRelease );
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
277*cdf0e10cSrcweir 	{
278*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
279*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
282*cdf0e10cSrcweir 			hr = pIDOTmp->SetData(pFormatetc, pmedium, fRelease);
283*cdf0e10cSrcweir 	}
284*cdf0e10cSrcweir 	return hr;
285*cdf0e10cSrcweir }
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir //------------------------------------------------------------------------
288*cdf0e10cSrcweir // IDataObject->DAdvise
289*cdf0e10cSrcweir //------------------------------------------------------------------------
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD * pdwConnection )
292*cdf0e10cSrcweir {
293*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
296*cdf0e10cSrcweir 	{
297*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
298*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
301*cdf0e10cSrcweir 			hr = pIDOTmp->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
302*cdf0e10cSrcweir 	}
303*cdf0e10cSrcweir 	return hr;
304*cdf0e10cSrcweir }
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir //------------------------------------------------------------------------
307*cdf0e10cSrcweir // IDataObject->DUnadvise
308*cdf0e10cSrcweir //------------------------------------------------------------------------
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::DUnadvise( DWORD dwConnection )
311*cdf0e10cSrcweir {
312*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->DUnadvise( dwConnection );
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
315*cdf0e10cSrcweir 	{
316*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
317*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
318*cdf0e10cSrcweir 
319*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
320*cdf0e10cSrcweir 			hr = pIDOTmp->DUnadvise(dwConnection);
321*cdf0e10cSrcweir 	}
322*cdf0e10cSrcweir 	return hr;
323*cdf0e10cSrcweir }
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir //------------------------------------------------------------------------
326*cdf0e10cSrcweir // IDataObject->EnumDAdvise
327*cdf0e10cSrcweir //------------------------------------------------------------------------
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir STDMETHODIMP CAPNDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
330*cdf0e10cSrcweir {
331*cdf0e10cSrcweir 	HRESULT hr = m_rIDataObjectOrg->EnumDAdvise(ppenumAdvise);
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir 	if (RPC_E_WRONG_THREAD == hr)
334*cdf0e10cSrcweir 	{
335*cdf0e10cSrcweir 		IDataObjectPtr pIDOTmp;
336*cdf0e10cSrcweir 		hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir 		if (SUCCEEDED(hr))
339*cdf0e10cSrcweir 			hr = pIDOTmp->EnumDAdvise(ppenumAdvise);
340*cdf0e10cSrcweir 	}
341*cdf0e10cSrcweir 	return hr;
342*cdf0e10cSrcweir }
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir //------------------------------------------------------------------------
345*cdf0e10cSrcweir // for our convenience
346*cdf0e10cSrcweir //------------------------------------------------------------------------
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir CAPNDataObject::operator IDataObject*( )
349*cdf0e10cSrcweir {
350*cdf0e10cSrcweir 	return static_cast< IDataObject* >( this );
351*cdf0e10cSrcweir }
352*cdf0e10cSrcweir 
353*cdf0e10cSrcweir //------------------------------------------------------------------------
354*cdf0e10cSrcweir // helper function
355*cdf0e10cSrcweir //------------------------------------------------------------------------
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir HRESULT CAPNDataObject::MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj )
358*cdf0e10cSrcweir {
359*cdf0e10cSrcweir 	OSL_ASSERT(NULL != ppIDataObj);
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir     *ppIDataObj = NULL;
362*cdf0e10cSrcweir     HRESULT hr = E_FAIL;
363*cdf0e10cSrcweir 
364*cdf0e10cSrcweir     if (m_hGlobal)
365*cdf0e10cSrcweir     {
366*cdf0e10cSrcweir 	    IStreamPtr pStm;
367*cdf0e10cSrcweir 	    hr = CreateStreamOnHGlobal(m_hGlobal, KEEP_HGLOB_ON_RELEASE, &pStm);
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir         OSL_ENSURE(E_INVALIDARG != hr, "CreateStreamOnHGlobal with invalid args called");
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir 	    if (SUCCEEDED(hr))
372*cdf0e10cSrcweir 	    {
373*cdf0e10cSrcweir 		    hr = CoUnmarshalInterface(pStm.get(), __uuidof(IDataObject), (void**)ppIDataObj);
374*cdf0e10cSrcweir             OSL_ENSURE(CO_E_NOTINITIALIZED != hr, "COM is not initialized");
375*cdf0e10cSrcweir 	    }
376*cdf0e10cSrcweir     }
377*cdf0e10cSrcweir 	return hr;
378*cdf0e10cSrcweir }
379