bump product version to 4.1.6.2
[LibreOffice.git] / dtrans / source / win32 / dtobj / APNDataObject.cxx
blobeefa2fe17cb82d3d920440d3ceb0e73e91af5164
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "APNDataObject.hxx"
21 #include <osl/diagnose.h>
23 #include <systools/win32/comtools.hxx>
24 #ifdef __MINGW32__
25 #if defined __uuidof
26 #undef __uuidof
27 #endif
28 #define __uuidof(I) IID_##I
29 #endif
31 #define FREE_HGLOB_ON_RELEASE TRUE
32 #define KEEP_HGLOB_ON_RELEASE FALSE
34 //------------------------------------------------------------------------
35 // ctor
36 //------------------------------------------------------------------------
38 CAPNDataObject::CAPNDataObject( IDataObjectPtr rIDataObject ) :
39 m_rIDataObjectOrg( rIDataObject ),
40 m_hGlobal( NULL ),
41 m_nRefCnt( 0 )
44 OSL_ENSURE( m_rIDataObjectOrg.get( ), "constructing CAPNDataObject with empty data object" );
46 // we marshal the IDataObject interface pointer here so
47 // that it can be unmarshaled multiple times when this
48 // class will be used from another apartment
49 IStreamPtr pStm;
50 HRESULT hr = CreateStreamOnHGlobal( 0, KEEP_HGLOB_ON_RELEASE, &pStm );
52 OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
54 if ( SUCCEEDED( hr ) )
56 HRESULT hr_marshal = CoMarshalInterface(
57 pStm.get(),
58 __uuidof(IDataObject),
59 static_cast<LPUNKNOWN>(m_rIDataObjectOrg.get()),
60 MSHCTX_LOCAL,
61 NULL,
62 MSHLFLAGS_TABLEWEAK );
64 OSL_ENSURE( CO_E_NOTINITIALIZED != hr_marshal, "COM is not initialized" );
66 // marshalling may fail if COM is not initialized
67 // for the calling thread which is a program time
68 // error or because of stream errors which are runtime
69 // errors for instance E_OUTOFMEMORY etc.
71 hr = GetHGlobalFromStream(pStm.get(), &m_hGlobal );
73 OSL_ENSURE( E_INVALIDARG != hr, "invalid stream passed to GetHGlobalFromStream" );
75 // if the marshalling failed we free the
76 // global memory again and set m_hGlobal
77 // to a defined value
78 if (FAILED(hr_marshal))
80 OSL_FAIL("marshalling failed");
82 #if OSL_DEBUG_LEVEL > 0
83 HGLOBAL hGlobal =
84 #endif
85 GlobalFree(m_hGlobal);
86 OSL_ENSURE(NULL == hGlobal, "GlobalFree failed");
87 m_hGlobal = NULL;
92 CAPNDataObject::~CAPNDataObject( )
94 if (m_hGlobal)
96 IStreamPtr pStm;
97 HRESULT hr = CreateStreamOnHGlobal(m_hGlobal, FREE_HGLOB_ON_RELEASE, &pStm);
99 OSL_ENSURE( E_INVALIDARG != hr, "invalid args passed to CreateStreamOnHGlobal" );
101 if (SUCCEEDED(hr))
103 hr = CoReleaseMarshalData(pStm.get());
104 OSL_ENSURE(SUCCEEDED(hr), "CoReleaseMarshalData failed");
109 //------------------------------------------------------------------------
110 // IUnknown->QueryInterface
111 //------------------------------------------------------------------------
113 STDMETHODIMP CAPNDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
115 OSL_ASSERT( NULL != ppvObject );
117 if ( NULL == ppvObject )
118 return E_INVALIDARG;
120 HRESULT hr = E_NOINTERFACE;
121 *ppvObject = NULL;
123 if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
125 *ppvObject = static_cast< IUnknown* >( this );
126 ( (LPUNKNOWN)*ppvObject )->AddRef( );
127 hr = S_OK;
130 return hr;
133 //------------------------------------------------------------------------
134 // IUnknown->AddRef
135 //------------------------------------------------------------------------
137 STDMETHODIMP_(ULONG) CAPNDataObject::AddRef( )
139 return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
142 //------------------------------------------------------------------------
143 // IUnknown->Release
144 //------------------------------------------------------------------------
146 STDMETHODIMP_(ULONG) CAPNDataObject::Release( )
148 // we need a helper variable because it's not allowed to access
149 // a member variable after an object is destroyed
150 ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
152 if ( 0 == nRefCnt )
153 delete this;
155 return nRefCnt;
158 //------------------------------------------------------------------------
159 // IDataObject->GetData
160 //------------------------------------------------------------------------
162 STDMETHODIMP CAPNDataObject::GetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
164 HRESULT hr = m_rIDataObjectOrg->GetData( pFormatetc, pmedium );
166 if (RPC_E_WRONG_THREAD == hr)
168 IDataObjectPtr pIDOTmp;
169 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
171 if (SUCCEEDED(hr))
172 hr = pIDOTmp->GetData(pFormatetc, pmedium);
174 return hr;
177 //------------------------------------------------------------------------
178 // IDataObject->EnumFormatEtc
179 //------------------------------------------------------------------------
181 STDMETHODIMP CAPNDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
183 HRESULT hr = m_rIDataObjectOrg->EnumFormatEtc(dwDirection, ppenumFormatetc);
185 if (RPC_E_WRONG_THREAD == hr)
187 IDataObjectPtr pIDOTmp;
188 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
190 if (SUCCEEDED(hr))
191 hr = pIDOTmp->EnumFormatEtc(dwDirection, ppenumFormatetc);
193 return hr;
196 //------------------------------------------------------------------------
197 // IDataObject->QueryGetData
198 //------------------------------------------------------------------------
200 STDMETHODIMP CAPNDataObject::QueryGetData( LPFORMATETC pFormatetc )
202 HRESULT hr = m_rIDataObjectOrg->QueryGetData( pFormatetc );
204 if (RPC_E_WRONG_THREAD == hr)
206 IDataObjectPtr pIDOTmp;
207 hr = MarshalIDataObjectIntoCurrentApartment( &pIDOTmp );
209 if (SUCCEEDED(hr))
210 hr = pIDOTmp->QueryGetData(pFormatetc);
212 return hr;
215 //------------------------------------------------------------------------
216 // IDataObject->GetDataHere
217 //------------------------------------------------------------------------
219 STDMETHODIMP CAPNDataObject::GetDataHere( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
221 HRESULT hr = m_rIDataObjectOrg->GetDataHere(pFormatetc, pmedium);
223 if (RPC_E_WRONG_THREAD == hr)
225 IDataObjectPtr pIDOTmp;
226 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
228 if (SUCCEEDED(hr))
229 hr = pIDOTmp->GetDataHere(pFormatetc, pmedium);
231 return hr;
234 //------------------------------------------------------------------------
235 // IDataObject->GetCanonicalFormatEtc
236 //------------------------------------------------------------------------
238 STDMETHODIMP CAPNDataObject::GetCanonicalFormatEtc(LPFORMATETC pFormatectIn, LPFORMATETC pFormatetcOut)
240 HRESULT hr = m_rIDataObjectOrg->GetCanonicalFormatEtc( pFormatectIn, pFormatetcOut );
242 if (RPC_E_WRONG_THREAD == hr)
244 IDataObjectPtr pIDOTmp;
245 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
247 if (SUCCEEDED(hr))
248 hr = pIDOTmp->GetCanonicalFormatEtc(pFormatectIn, pFormatetcOut);
250 return hr;
253 //------------------------------------------------------------------------
254 // IDataObject->SetData
255 //------------------------------------------------------------------------
257 STDMETHODIMP CAPNDataObject::SetData( LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium, BOOL fRelease )
259 HRESULT hr = m_rIDataObjectOrg->SetData( pFormatetc, pmedium, fRelease );
261 if (RPC_E_WRONG_THREAD == hr)
263 IDataObjectPtr pIDOTmp;
264 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
266 if (SUCCEEDED(hr))
267 hr = pIDOTmp->SetData(pFormatetc, pmedium, fRelease);
269 return hr;
272 //------------------------------------------------------------------------
273 // IDataObject->DAdvise
274 //------------------------------------------------------------------------
276 STDMETHODIMP CAPNDataObject::DAdvise( LPFORMATETC pFormatetc, DWORD advf, LPADVISESINK pAdvSink, DWORD * pdwConnection )
278 HRESULT hr = m_rIDataObjectOrg->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
280 if (RPC_E_WRONG_THREAD == hr)
282 IDataObjectPtr pIDOTmp;
283 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
285 if (SUCCEEDED(hr))
286 hr = pIDOTmp->DAdvise(pFormatetc, advf, pAdvSink, pdwConnection);
288 return hr;
291 //------------------------------------------------------------------------
292 // IDataObject->DUnadvise
293 //------------------------------------------------------------------------
295 STDMETHODIMP CAPNDataObject::DUnadvise( DWORD dwConnection )
297 HRESULT hr = m_rIDataObjectOrg->DUnadvise( dwConnection );
299 if (RPC_E_WRONG_THREAD == hr)
301 IDataObjectPtr pIDOTmp;
302 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
304 if (SUCCEEDED(hr))
305 hr = pIDOTmp->DUnadvise(dwConnection);
307 return hr;
310 //------------------------------------------------------------------------
311 // IDataObject->EnumDAdvise
312 //------------------------------------------------------------------------
314 STDMETHODIMP CAPNDataObject::EnumDAdvise( LPENUMSTATDATA * ppenumAdvise )
316 HRESULT hr = m_rIDataObjectOrg->EnumDAdvise(ppenumAdvise);
318 if (RPC_E_WRONG_THREAD == hr)
320 IDataObjectPtr pIDOTmp;
321 hr = MarshalIDataObjectIntoCurrentApartment(&pIDOTmp);
323 if (SUCCEEDED(hr))
324 hr = pIDOTmp->EnumDAdvise(ppenumAdvise);
326 return hr;
329 //------------------------------------------------------------------------
330 // for our convenience
331 //------------------------------------------------------------------------
333 CAPNDataObject::operator IDataObject*( )
335 return static_cast< IDataObject* >( this );
338 //------------------------------------------------------------------------
339 // helper function
340 //------------------------------------------------------------------------
342 HRESULT CAPNDataObject::MarshalIDataObjectIntoCurrentApartment( IDataObject** ppIDataObj )
344 OSL_ASSERT(NULL != ppIDataObj);
346 *ppIDataObj = NULL;
347 HRESULT hr = E_FAIL;
349 if (m_hGlobal)
351 IStreamPtr pStm;
352 hr = CreateStreamOnHGlobal(m_hGlobal, KEEP_HGLOB_ON_RELEASE, &pStm);
354 OSL_ENSURE(E_INVALIDARG != hr, "CreateStreamOnHGlobal with invalid args called");
356 if (SUCCEEDED(hr))
358 hr = CoUnmarshalInterface(pStm.get(), __uuidof(IDataObject), (void**)ppIDataObj);
359 OSL_ENSURE(CO_E_NOTINITIALIZED != hr, "COM is not initialized");
362 return hr;
365 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */