1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*87d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*87d2adbcSAndrew Rist  * distributed with this work for additional information
6*87d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*87d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*87d2adbcSAndrew Rist  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*87d2adbcSAndrew Rist  *
13*87d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist  * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*87d2adbcSAndrew Rist  * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist  * under the License.
19*87d2adbcSAndrew Rist  *
20*87d2adbcSAndrew Rist  *************************************************************/
21*87d2adbcSAndrew Rist 
22*87d2adbcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sal.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //------------------------------------------------------------------------
28cdf0e10cSrcweir // includes
29cdf0e10cSrcweir //------------------------------------------------------------------------
30cdf0e10cSrcweir #include <osl/diagnose.h>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #ifndef _TWRAPPERDATAOBJECT_HXX_
33cdf0e10cSrcweir #include "XTDataObject.hxx"
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <windows.h>
37cdf0e10cSrcweir #include <ole2.h>
38cdf0e10cSrcweir #include <memory>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir //------------------------------------------------------------------------
41cdf0e10cSrcweir // namespace directives
42cdf0e10cSrcweir //------------------------------------------------------------------------
43cdf0e10cSrcweir 
44cdf0e10cSrcweir 
45cdf0e10cSrcweir //============================================================================
46cdf0e10cSrcweir // OTWrapperDataObject
47cdf0e10cSrcweir //============================================================================
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //------------------------------------------------------------------------
50cdf0e10cSrcweir // ctor
51cdf0e10cSrcweir //------------------------------------------------------------------------
52cdf0e10cSrcweir 
CXTDataObject(LONG nRefCntInitVal)53cdf0e10cSrcweir CXTDataObject::CXTDataObject( LONG nRefCntInitVal ) :
54cdf0e10cSrcweir 	m_nRefCnt( nRefCntInitVal )
55cdf0e10cSrcweir {
56cdf0e10cSrcweir }
57cdf0e10cSrcweir 
58cdf0e10cSrcweir //------------------------------------------------------------------------
59cdf0e10cSrcweir // dtor
60cdf0e10cSrcweir //------------------------------------------------------------------------
61cdf0e10cSrcweir 
~CXTDataObject()62cdf0e10cSrcweir CXTDataObject::~CXTDataObject( )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir }
65cdf0e10cSrcweir 
66cdf0e10cSrcweir //------------------------------------------------------------------------
67cdf0e10cSrcweir // IUnknown->QueryInterface
68cdf0e10cSrcweir //------------------------------------------------------------------------
69cdf0e10cSrcweir 
QueryInterface(REFIID iid,LPVOID * ppvObject)70cdf0e10cSrcweir STDMETHODIMP CXTDataObject::QueryInterface( REFIID iid, LPVOID* ppvObject )
71cdf0e10cSrcweir {
72cdf0e10cSrcweir 	OSL_ASSERT( NULL != ppvObject );
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 	if ( NULL == ppvObject )
75cdf0e10cSrcweir 		return E_INVALIDARG;
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	*ppvObject = NULL;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IDataObject ) == iid ) )
82cdf0e10cSrcweir 	{
83cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
84cdf0e10cSrcweir 		( (LPUNKNOWN)*ppvObject )->AddRef( );
85cdf0e10cSrcweir 		hr = S_OK;
86cdf0e10cSrcweir 	}
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	return hr;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir //------------------------------------------------------------------------
92cdf0e10cSrcweir // IUnknown->AddRef
93cdf0e10cSrcweir //------------------------------------------------------------------------
94cdf0e10cSrcweir 
STDMETHODIMP_(ULONG)95cdf0e10cSrcweir STDMETHODIMP_(ULONG) CXTDataObject::AddRef( )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir 	return static_cast< ULONG >( InterlockedIncrement( &m_nRefCnt ) );
98cdf0e10cSrcweir }
99cdf0e10cSrcweir 
100cdf0e10cSrcweir //------------------------------------------------------------------------
101cdf0e10cSrcweir // IUnknown->Release
102cdf0e10cSrcweir //------------------------------------------------------------------------
103cdf0e10cSrcweir 
STDMETHODIMP_(ULONG)104cdf0e10cSrcweir STDMETHODIMP_(ULONG) CXTDataObject::Release( )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir 	// we need a helper variable because it's
107cdf0e10cSrcweir 	// not allowed to access a member variable
108cdf0e10cSrcweir 	// after an object is destroyed
109cdf0e10cSrcweir 	ULONG nRefCnt = static_cast< ULONG >( InterlockedDecrement( &m_nRefCnt ) );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 	if ( 0 == nRefCnt )
112cdf0e10cSrcweir 	{
113cdf0e10cSrcweir 		delete this;
114cdf0e10cSrcweir 	}
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 	return nRefCnt;
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir //------------------------------------------------------------------------
120cdf0e10cSrcweir // IDataObject->GetData
121cdf0e10cSrcweir // warning: 'goto' ahead (to easy error handling without using exceptions)
122cdf0e10cSrcweir //------------------------------------------------------------------------
123cdf0e10cSrcweir 
GetData(LPFORMATETC pFormatetc,LPSTGMEDIUM pmedium)124cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetData(LPFORMATETC pFormatetc, LPSTGMEDIUM pmedium )
125cdf0e10cSrcweir {
126cdf0e10cSrcweir 	OSL_ASSERT( ( NULL != pFormatetc ) &&
127cdf0e10cSrcweir 				( !IsBadReadPtr( (LPVOID)pFormatetc, sizeof( FORMATETC ) ) ) );
128cdf0e10cSrcweir 	OSL_ASSERT( ( NULL != pmedium ) &&
129cdf0e10cSrcweir 				( !IsBadWritePtr( (LPVOID)pmedium, sizeof( STGMEDIUM ) ) ) );
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 	if ( ( NULL == pFormatetc ) || ( NULL == pmedium ) )
132cdf0e10cSrcweir 		return E_INVALIDARG;
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	HRESULT hr = E_FAIL;
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	if ( CF_TEXT == pFormatetc->cfFormat )
137cdf0e10cSrcweir 	{
138cdf0e10cSrcweir 		char     buff[] = "Hello World, How are you!";
139cdf0e10cSrcweir 		LPSTREAM lpStream;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir 		hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
142cdf0e10cSrcweir 		if ( SUCCEEDED( hr ) )
143cdf0e10cSrcweir 		{
144cdf0e10cSrcweir 			hr = lpStream->Write( buff, sizeof( buff ) * sizeof( char ), NULL );
145cdf0e10cSrcweir 			if ( SUCCEEDED( hr ) )
146cdf0e10cSrcweir 			{
147cdf0e10cSrcweir 				HGLOBAL hGlob;
148cdf0e10cSrcweir 
149cdf0e10cSrcweir 				GetHGlobalFromStream( lpStream, &hGlob );
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 				pmedium->tymed          = TYMED_HGLOBAL;
152cdf0e10cSrcweir 				pmedium->hGlobal        = hGlob;
153cdf0e10cSrcweir 				pmedium->pUnkForRelease = NULL;
154cdf0e10cSrcweir 			}
155cdf0e10cSrcweir 			lpStream->Release( );
156cdf0e10cSrcweir 			hr = S_OK;
157cdf0e10cSrcweir 		}
158cdf0e10cSrcweir 		else
159cdf0e10cSrcweir 		{
160cdf0e10cSrcweir 			pmedium->tymed = TYMED_NULL;
161cdf0e10cSrcweir 		}
162cdf0e10cSrcweir 	}
163cdf0e10cSrcweir 	else if ( CF_UNICODETEXT == pFormatetc->cfFormat )
164cdf0e10cSrcweir 	{
165cdf0e10cSrcweir 		WCHAR     buff[] = L"Hello World, How are you!";
166cdf0e10cSrcweir 		LPSTREAM lpStream;
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 		hr = CreateStreamOnHGlobal( NULL, FALSE, &lpStream );
169cdf0e10cSrcweir 		if ( SUCCEEDED( hr ) )
170cdf0e10cSrcweir 		{
171cdf0e10cSrcweir 			hr = lpStream->Write( buff, sizeof( buff ) * sizeof( WCHAR ), NULL );
172cdf0e10cSrcweir 			if ( SUCCEEDED( hr ) )
173cdf0e10cSrcweir 			{
174cdf0e10cSrcweir 				HGLOBAL hGlob;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir 				GetHGlobalFromStream( lpStream, &hGlob );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 				pmedium->tymed          = TYMED_HGLOBAL;
179cdf0e10cSrcweir 				pmedium->hGlobal        = hGlob;
180cdf0e10cSrcweir 				pmedium->pUnkForRelease = NULL;
181cdf0e10cSrcweir 			}
182cdf0e10cSrcweir 			lpStream->Release( );
183cdf0e10cSrcweir 			hr = S_OK;
184cdf0e10cSrcweir 		}
185cdf0e10cSrcweir 		else
186cdf0e10cSrcweir 		{
187cdf0e10cSrcweir 			pmedium->tymed = TYMED_NULL;
188cdf0e10cSrcweir 		}
189cdf0e10cSrcweir 	}
190cdf0e10cSrcweir 
191cdf0e10cSrcweir 	return hr;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir //------------------------------------------------------------------------
195cdf0e10cSrcweir // IDataObject->EnumFormatEtc
196cdf0e10cSrcweir //------------------------------------------------------------------------
197cdf0e10cSrcweir 
EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC ** ppenumFormatetc)198cdf0e10cSrcweir STDMETHODIMP CXTDataObject::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC** ppenumFormatetc )
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	if ( ( NULL == ppenumFormatetc ) || ( DATADIR_SET == dwDirection ) )
201cdf0e10cSrcweir 		return E_INVALIDARG;
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 	*ppenumFormatetc = NULL;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 	HRESULT hr = E_FAIL;
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 	if ( DATADIR_GET == dwDirection )
208cdf0e10cSrcweir 	{
209cdf0e10cSrcweir 		*ppenumFormatetc = new CEnumFormatEtc( this );
210cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppenumFormatetc )->AddRef( );
211cdf0e10cSrcweir 		hr = S_OK;
212cdf0e10cSrcweir 	}
213cdf0e10cSrcweir 
214cdf0e10cSrcweir 	return hr;
215cdf0e10cSrcweir }
216cdf0e10cSrcweir 
217cdf0e10cSrcweir //------------------------------------------------------------------------
218cdf0e10cSrcweir // IDataObject->QueryGetData
219cdf0e10cSrcweir //------------------------------------------------------------------------
220cdf0e10cSrcweir 
QueryGetData(LPFORMATETC pFormatetc)221cdf0e10cSrcweir STDMETHODIMP CXTDataObject::QueryGetData( LPFORMATETC pFormatetc )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir 	return E_NOTIMPL;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir //------------------------------------------------------------------------
227cdf0e10cSrcweir // IDataObject->GetDataHere
228cdf0e10cSrcweir //------------------------------------------------------------------------
229cdf0e10cSrcweir 
GetDataHere(LPFORMATETC,LPSTGMEDIUM)230cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetDataHere( LPFORMATETC, LPSTGMEDIUM )
231cdf0e10cSrcweir {
232cdf0e10cSrcweir 	return E_NOTIMPL;
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir //------------------------------------------------------------------------
236cdf0e10cSrcweir // IDataObject->GetCanonicalFormatEtc
237cdf0e10cSrcweir //------------------------------------------------------------------------
238cdf0e10cSrcweir 
GetCanonicalFormatEtc(LPFORMATETC,LPFORMATETC)239cdf0e10cSrcweir STDMETHODIMP CXTDataObject::GetCanonicalFormatEtc( LPFORMATETC, LPFORMATETC )
240cdf0e10cSrcweir {
241cdf0e10cSrcweir 	return E_NOTIMPL;
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir //------------------------------------------------------------------------
245cdf0e10cSrcweir // IDataObject->SetData
246cdf0e10cSrcweir //------------------------------------------------------------------------
247cdf0e10cSrcweir 
SetData(LPFORMATETC,LPSTGMEDIUM,BOOL)248cdf0e10cSrcweir STDMETHODIMP CXTDataObject::SetData( LPFORMATETC, LPSTGMEDIUM, BOOL )
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	return E_NOTIMPL;
251cdf0e10cSrcweir }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir //------------------------------------------------------------------------
254cdf0e10cSrcweir // IDataObject->DAdvise
255cdf0e10cSrcweir //------------------------------------------------------------------------
256cdf0e10cSrcweir 
DAdvise(LPFORMATETC,DWORD,LPADVISESINK,DWORD *)257cdf0e10cSrcweir STDMETHODIMP CXTDataObject::DAdvise( LPFORMATETC, DWORD, LPADVISESINK, DWORD * )
258cdf0e10cSrcweir {
259cdf0e10cSrcweir 	return E_NOTIMPL;
260cdf0e10cSrcweir }
261cdf0e10cSrcweir 
262cdf0e10cSrcweir //------------------------------------------------------------------------
263cdf0e10cSrcweir // IDataObject->DUnadvise
264cdf0e10cSrcweir //------------------------------------------------------------------------
265cdf0e10cSrcweir 
DUnadvise(DWORD)266cdf0e10cSrcweir STDMETHODIMP CXTDataObject::DUnadvise( DWORD )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir 	return E_NOTIMPL;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir //------------------------------------------------------------------------
272cdf0e10cSrcweir // IDataObject->EnumDAdvise
273cdf0e10cSrcweir //------------------------------------------------------------------------
274cdf0e10cSrcweir 
EnumDAdvise(LPENUMSTATDATA *)275cdf0e10cSrcweir STDMETHODIMP CXTDataObject::EnumDAdvise( LPENUMSTATDATA * )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir 	return E_NOTIMPL;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir //------------------------------------------------------------------------
281cdf0e10cSrcweir // for our convenience
282cdf0e10cSrcweir //------------------------------------------------------------------------
283cdf0e10cSrcweir 
operator IDataObject*()284cdf0e10cSrcweir CXTDataObject::operator IDataObject*( )
285cdf0e10cSrcweir {
286cdf0e10cSrcweir 	return static_cast< IDataObject* >( this );
287cdf0e10cSrcweir }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 
290cdf0e10cSrcweir //============================================================================
291cdf0e10cSrcweir // CEnumFormatEtc
292cdf0e10cSrcweir //============================================================================
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 
295cdf0e10cSrcweir //----------------------------------------------------------------------------
296cdf0e10cSrcweir // ctor
297cdf0e10cSrcweir //----------------------------------------------------------------------------
298cdf0e10cSrcweir 
CEnumFormatEtc(LPUNKNOWN pUnkDataObj)299cdf0e10cSrcweir CEnumFormatEtc::CEnumFormatEtc( LPUNKNOWN pUnkDataObj ) :
300cdf0e10cSrcweir 	m_nRefCnt( 0 ),
301cdf0e10cSrcweir 	m_pUnkDataObj( pUnkDataObj ),
302cdf0e10cSrcweir 	m_nCurrentPos( 0 )
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	m_cfFormats[0] = CF_UNICODETEXT;
305cdf0e10cSrcweir 	m_cfFormats[1] = CF_TEXT;
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
308cdf0e10cSrcweir //----------------------------------------------------------------------------
309cdf0e10cSrcweir // dtor
310cdf0e10cSrcweir //----------------------------------------------------------------------------
311cdf0e10cSrcweir 
~CEnumFormatEtc()312cdf0e10cSrcweir CEnumFormatEtc::~CEnumFormatEtc( )
313cdf0e10cSrcweir {
314cdf0e10cSrcweir }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir //----------------------------------------------------------------------------
317cdf0e10cSrcweir // IUnknown->QueryInterface
318cdf0e10cSrcweir //----------------------------------------------------------------------------
319cdf0e10cSrcweir 
QueryInterface(REFIID iid,LPVOID * ppvObject)320cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::QueryInterface( REFIID iid, LPVOID* ppvObject )
321cdf0e10cSrcweir {
322cdf0e10cSrcweir 	if ( NULL == ppvObject )
323cdf0e10cSrcweir 		return E_INVALIDARG;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 	HRESULT hr = E_NOINTERFACE;
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 	*ppvObject = NULL;
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 	if ( ( __uuidof( IUnknown ) == iid ) || ( __uuidof( IEnumFORMATETC ) == iid ) )
330cdf0e10cSrcweir 	{
331cdf0e10cSrcweir 		*ppvObject = static_cast< IUnknown* >( this );
332cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppvObject )->AddRef( );
333cdf0e10cSrcweir 		hr = S_OK;
334cdf0e10cSrcweir 	}
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 	return hr;
337cdf0e10cSrcweir }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir //----------------------------------------------------------------------------
340cdf0e10cSrcweir // IUnknown->AddRef
341cdf0e10cSrcweir //----------------------------------------------------------------------------
342cdf0e10cSrcweir 
STDMETHODIMP_(ULONG)343cdf0e10cSrcweir STDMETHODIMP_(ULONG) CEnumFormatEtc::AddRef( )
344cdf0e10cSrcweir {
345cdf0e10cSrcweir 	// keep the dataobject alive
346cdf0e10cSrcweir 	m_pUnkDataObj->AddRef( );
347cdf0e10cSrcweir 	return InterlockedIncrement( &m_nRefCnt );
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir //----------------------------------------------------------------------------
351cdf0e10cSrcweir // IUnknown->Release
352cdf0e10cSrcweir //----------------------------------------------------------------------------
353cdf0e10cSrcweir 
STDMETHODIMP_(ULONG)354cdf0e10cSrcweir STDMETHODIMP_(ULONG) CEnumFormatEtc::Release( )
355cdf0e10cSrcweir {
356cdf0e10cSrcweir 	// release the outer dataobject
357cdf0e10cSrcweir 	m_pUnkDataObj->Release( );
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 	// we need a helper variable because it's
360cdf0e10cSrcweir 	// not allowed to access a member variable
361cdf0e10cSrcweir 	// after an object is destroyed
362cdf0e10cSrcweir 	ULONG nRefCnt = InterlockedDecrement( &m_nRefCnt );
363cdf0e10cSrcweir 	if ( 0 == nRefCnt )
364cdf0e10cSrcweir 		delete this;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 	return nRefCnt;
367cdf0e10cSrcweir }
368cdf0e10cSrcweir 
369cdf0e10cSrcweir //----------------------------------------------------------------------------
370cdf0e10cSrcweir // IEnumFORMATETC->Next
371cdf0e10cSrcweir //----------------------------------------------------------------------------
372cdf0e10cSrcweir 
Next(ULONG celt,LPFORMATETC rgelt,ULONG * pceltFetched)373cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Next( ULONG celt, LPFORMATETC rgelt, ULONG* pceltFetched )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir 	OSL_ASSERT( ( ( celt > 0 ) && ( NULL != rgelt ) ) ||
376cdf0e10cSrcweir 				( ( 0 == celt ) && ( NULL == rgelt ) ) );
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 	if ( ( 0 != celt ) && ( NULL == rgelt ) )
379cdf0e10cSrcweir 		return E_INVALIDARG;
380cdf0e10cSrcweir 
381cdf0e10cSrcweir 	ULONG   ulFetched = 0;
382cdf0e10cSrcweir 	ULONG   ulToFetch = celt;
383cdf0e10cSrcweir 	HRESULT hr        = S_FALSE;
384cdf0e10cSrcweir 
385cdf0e10cSrcweir 	while( ( m_nCurrentPos < sizeof( m_cfFormats ) ) && ( ulToFetch > 0 ) )
386cdf0e10cSrcweir 	{
387cdf0e10cSrcweir 		OSL_ASSERT( !IsBadWritePtr( (LPVOID)rgelt, sizeof( FORMATETC ) ) );
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 		rgelt->cfFormat = m_cfFormats[m_nCurrentPos];
390cdf0e10cSrcweir 		rgelt->ptd      = NULL;
391cdf0e10cSrcweir 		rgelt->dwAspect = DVASPECT_CONTENT;
392cdf0e10cSrcweir 		rgelt->lindex   = -1;
393cdf0e10cSrcweir 		rgelt->tymed    = TYMED_HGLOBAL;
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 		++m_nCurrentPos;
396cdf0e10cSrcweir 		++rgelt;
397cdf0e10cSrcweir 		--ulToFetch;
398cdf0e10cSrcweir 		++ulFetched;
399cdf0e10cSrcweir 	}
400cdf0e10cSrcweir 
401cdf0e10cSrcweir 	if ( ulFetched == celt )
402cdf0e10cSrcweir 		hr = S_OK;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir 	if ( NULL != pceltFetched )
405cdf0e10cSrcweir 	{
406cdf0e10cSrcweir 		OSL_ASSERT( !IsBadWritePtr( (LPVOID)pceltFetched, sizeof( ULONG ) ) );
407cdf0e10cSrcweir 		*pceltFetched = ulFetched;
408cdf0e10cSrcweir 	}
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 	return hr;
411cdf0e10cSrcweir }
412cdf0e10cSrcweir 
413cdf0e10cSrcweir //----------------------------------------------------------------------------
414cdf0e10cSrcweir // IEnumFORMATETC->Skip
415cdf0e10cSrcweir //----------------------------------------------------------------------------
416cdf0e10cSrcweir 
Skip(ULONG celt)417cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Skip( ULONG celt )
418cdf0e10cSrcweir {
419cdf0e10cSrcweir 	HRESULT hr = S_FALSE;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 	if ( ( m_nCurrentPos + celt ) < sizeof( m_cfFormats ) )
422cdf0e10cSrcweir 	{
423cdf0e10cSrcweir 		m_nCurrentPos += celt;
424cdf0e10cSrcweir 		hr = S_OK;
425cdf0e10cSrcweir 	}
426cdf0e10cSrcweir 
427cdf0e10cSrcweir 	return hr;
428cdf0e10cSrcweir }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir //----------------------------------------------------------------------------
431cdf0e10cSrcweir // IEnumFORMATETC->Reset
432cdf0e10cSrcweir //----------------------------------------------------------------------------
433cdf0e10cSrcweir 
Reset()434cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Reset( )
435cdf0e10cSrcweir {
436cdf0e10cSrcweir 	m_nCurrentPos = 0;
437cdf0e10cSrcweir 	return S_OK;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir //----------------------------------------------------------------------------
441cdf0e10cSrcweir // IEnumFORMATETC->Clone
442cdf0e10cSrcweir //----------------------------------------------------------------------------
443cdf0e10cSrcweir 
Clone(IEnumFORMATETC ** ppenum)444cdf0e10cSrcweir STDMETHODIMP CEnumFormatEtc::Clone( IEnumFORMATETC** ppenum )
445cdf0e10cSrcweir {
446cdf0e10cSrcweir 	OSL_ASSERT( NULL != ppenum );
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	if ( NULL == ppenum )
449cdf0e10cSrcweir 		return E_INVALIDARG;
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 	HRESULT hr = E_FAIL;
452cdf0e10cSrcweir 
453cdf0e10cSrcweir 	*ppenum = NULL;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir 	CEnumFormatEtc* pCEnumFEtc = new CEnumFormatEtc( m_pUnkDataObj );
456cdf0e10cSrcweir 	if ( NULL != pCEnumFEtc )
457cdf0e10cSrcweir 	{
458cdf0e10cSrcweir 		pCEnumFEtc->m_nCurrentPos = m_nCurrentPos;
459cdf0e10cSrcweir 		*ppenum = static_cast< IEnumFORMATETC* >( pCEnumFEtc );
460cdf0e10cSrcweir 		static_cast< LPUNKNOWN >( *ppenum )->AddRef( );
461cdf0e10cSrcweir 		hr = NOERROR;
462cdf0e10cSrcweir 	}
463cdf0e10cSrcweir 
464cdf0e10cSrcweir 	return hr;
465cdf0e10cSrcweir }
466cdf0e10cSrcweir 
467