1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/types.h>
21 
22 #include <embservconst.h>
23 #include "inprocembobj.h"
24 
25 namespace inprocserv
26 {
27 
28 namespace {
29 
SetName(LPCOLESTR pszNameFromOutside,wchar_t * & pOwnName)30 void SetName( LPCOLESTR pszNameFromOutside, wchar_t*& pOwnName )
31 {
32     if ( !pszNameFromOutside )
33         return;
34 
35     // copy the string
36     size_t nLen = 0;
37     while( pszNameFromOutside[nLen] != 0 )
38         nLen++;
39 
40     if ( pOwnName )
41     {
42         delete[] pOwnName;
43         pOwnName = nullptr;
44     }
45 
46     pOwnName = new wchar_t[nLen+1];
47     for ( size_t nInd = 0; nInd < nLen; nInd++ )
48         pOwnName[nInd] = pszNameFromOutside[nInd];
49     pOwnName[nLen] = 0;
50 }
51 
InsertAdviseLinkToList(const ComSmart<OleWrapperAdviseSink> & pOwnAdvise,ComSmart<OleWrapperAdviseSink> pAdvises[])52 DWORD InsertAdviseLinkToList( const ComSmart<OleWrapperAdviseSink>& pOwnAdvise, ComSmart< OleWrapperAdviseSink > pAdvises[] )
53 {
54     // the result should start from 1 in case of success, the element 0 can be used for own needs
55     DWORD nResult = 0;
56 
57     if ( pOwnAdvise )
58     {
59         for ( DWORD nInd = 1; nInd < DEFAULT_ARRAY_LEN && nResult == 0; nInd++ )
60         {
61             if ( pAdvises[nInd] == pOwnAdvise )
62             {
63                 nResult = nInd;
64             }
65             else if ( pAdvises[nInd] == nullptr )
66             {
67                 pAdvises[nInd] = pOwnAdvise;
68                 nResult = nInd;
69             }
70         }
71     }
72 
73     return nResult;
74 }
75 
76 }
77 
CheckDefHandler()78 BOOL InprocEmbedDocument_Impl::CheckDefHandler()
79 {
80     // set the own listener
81     if ( m_pOleAdvises[0] == nullptr )
82     {
83         m_pOleAdvises[0] = new OleWrapperAdviseSink();
84     }
85     else
86     {
87         if ( m_pOleAdvises[0]->IsClosed() )
88         {
89             if ( m_pDefHandler )
90             {
91                 // deregister all the listeners
92 
93                 ComSmart< IOleObject > pOleObject;
94                 HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
95                 if ( SUCCEEDED( hr ) && pOleObject )
96                 {
97                     for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ )
98                         if ( m_pOleAdvises[nInd] )
99                         {
100                             DWORD nID = m_pOleAdvises[nInd]->GetRegID();
101                             pOleObject->Unadvise( nID );
102                             m_pOleAdvises[nInd]->SetRegID( 0 );
103                         }
104 
105                     pOleObject->SetClientSite( nullptr );
106                 }
107 
108                 ComSmart< IDataObject > pIDataObject;
109                 hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
110                 if ( SUCCEEDED( hr ) && pIDataObject )
111                 {
112                     for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ )
113                         if ( m_pDataAdvises[nInd] )
114                         {
115                             DWORD nID = m_pDataAdvises[nInd]->GetRegID();
116                             pIDataObject->DUnadvise( nID );
117                             m_pDataAdvises[nInd]->SetRegID( 0 );
118                         }
119                 }
120 
121                 ComSmart< IViewObject > pIViewObject;
122                 hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
123                 if ( SUCCEEDED( hr ) && pIViewObject )
124                 {
125                     if ( m_pViewAdvise )
126                         pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), nullptr );
127                 }
128 
129                 ComSmart< IPersistStorage > pPersist;
130                 hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
131                 if ( SUCCEEDED( hr ) && pPersist )
132                 {
133                     // disconnect the old wrapper from the storage
134                     pPersist->HandsOffStorage();
135                 }
136 
137                 m_pDefHandler = nullptr;
138             }
139 
140             m_pOleAdvises[0]->UnsetClosed();
141         }
142     }
143 
144     if ( m_nCallsOnStack )
145         return FALSE;
146 
147     if ( !m_pDefHandler )
148     {
149         // create a new default inprocess handler
150         HRESULT hr = OleCreateDefaultHandler( m_guid, nullptr, IID_IUnknown, reinterpret_cast<void**>(&m_pDefHandler) );
151         if ( SUCCEEDED( hr ) )
152         {
153             if ( m_nInitMode == INIT_FROM_STORAGE )
154             {
155                 ComSmart< IPersistStorage > pPersist;
156                 hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
157 
158                 ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
159                 if ( SUCCEEDED( hr ) && pPersist && m_pStorage )
160                     hr = pPersist->InitNew( m_pStorage.get() );
161             }
162             else if ( m_nInitMode == LOAD_FROM_STORAGE )
163             {
164                 ComSmart< IPersistStorage > pPersist;
165                 hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
166 
167                 ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
168                 if ( SUCCEEDED( hr ) && pPersist && m_pStorage )
169                     hr = pPersist->Load( m_pStorage.get() );
170             }
171             else if ( m_nInitMode == LOAD_FROM_FILE )
172             {
173                 ComSmart< IPersistFile > pPersistFile;
174                 hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersistFile) );
175 
176                 ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
177                 if ( SUCCEEDED( hr ) && pPersistFile && m_pFileName )
178                     hr = pPersistFile->Load( m_pFileName, m_nFileOpenMode );
179             }
180         }
181 
182         if ( !SUCCEEDED( hr ) || !m_pDefHandler )
183         {
184             m_pDefHandler = nullptr;
185             return FALSE;
186         }
187 
188         // register all the listeners new
189 
190         ComSmart< IOleObject > pOleObject;
191         hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
192         if ( SUCCEEDED( hr ) && pOleObject )
193         {
194             if ( m_pClientSite )
195                 pOleObject->SetClientSite( m_pClientSite.get() );
196 
197             for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ )
198                 if ( m_pOleAdvises[nInd] )
199                 {
200                     DWORD nRegID = 0;
201                     if ( SUCCEEDED( pOleObject->Advise( m_pOleAdvises[nInd].get(), &nRegID ) ) && nRegID > 0 )
202                         m_pOleAdvises[nInd]->SetRegID( nRegID );
203                 }
204         }
205 
206         ComSmart< IDataObject > pIDataObject;
207         hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
208         if ( SUCCEEDED( hr ) && pIDataObject )
209         {
210             for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ )
211                 if ( m_pDataAdvises[nInd] )
212                 {
213                     DWORD nRegID = 0;
214                     if ( SUCCEEDED( pIDataObject->DAdvise( m_pDataAdvises[nInd]->GetFormatEtc(), m_pDataAdvises[nInd]->GetDataAdviseFlag(), m_pDataAdvises[nInd].get(), &nRegID ) ) && nRegID > 0 )
215                         m_pDataAdvises[nInd]->SetRegID( nRegID );
216                 }
217         }
218 
219         ComSmart< IViewObject > pIViewObject;
220         hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
221         if ( SUCCEEDED( hr ) && pIViewObject )
222         {
223             if ( m_pViewAdvise )
224                 pIViewObject->SetAdvise( m_pViewAdvise->GetAspect(), m_pViewAdvise->GetViewAdviseFlag(), m_pViewAdvise.get() );
225         }
226     }
227 
228 
229     return TRUE;
230 }
231 
Clean()232 void InprocEmbedDocument_Impl::Clean()
233 {
234     m_pDefHandler = nullptr;
235 
236     // no DisconnectOrigAdvise() call here, since it is no explicit disconnection
237     for ( DWORD nInd = 0; nInd < DEFAULT_ARRAY_LEN; nInd++ )
238     {
239         if ( m_pOleAdvises[nInd] )
240         {
241             ComSmart< OleWrapperAdviseSink > pAdvise = m_pOleAdvises[nInd];
242             m_pOleAdvises[nInd] = nullptr;
243         }
244 
245         if ( m_pDataAdvises[nInd] )
246         {
247             ComSmart< OleWrapperAdviseSink > pAdvise = m_pDataAdvises[nInd];
248             m_pDataAdvises[nInd] = nullptr;
249         }
250     }
251 
252     m_pViewAdvise = nullptr;
253 
254     m_nInitMode = NOINIT;
255     m_pStorage = nullptr;
256 
257     if ( m_pOleContainer )
258     {
259         m_pOleContainer->LockContainer( FALSE );
260         m_pOleContainer = nullptr;
261     }
262 
263     m_pClientSite = nullptr;
264 
265     m_nFileOpenMode = 0;
266     if ( m_pFileName )
267     {
268         delete m_pFileName;
269         m_pFileName = nullptr;
270     }
271 }
272 
273 // IUnknown
274 
QueryInterface(REFIID riid,void FAR * FAR * ppv)275 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::QueryInterface( REFIID riid, void FAR* FAR* ppv )
276 {
277     if(IsEqualIID(riid, IID_IUnknown))
278     {
279         AddRef();
280         *ppv = static_cast<IUnknown*>(static_cast<IPersistStorage*>(this));
281         return S_OK;
282     }
283     else if (IsEqualIID(riid, IID_IPersist))
284     {
285         AddRef();
286         *ppv = static_cast<IPersist*>(static_cast<IPersistStorage*>(this));
287         return S_OK;
288     }
289     else if (IsEqualIID(riid, IID_IPersistStorage))
290     {
291         AddRef();
292         *ppv = static_cast<IPersistStorage*>(this);
293         return S_OK;
294     }
295     else if (IsEqualIID(riid, IID_IDataObject))
296     {
297         AddRef();
298         *ppv = static_cast<IDataObject*>(this);
299         return S_OK;
300     }
301     else if (IsEqualIID(riid, IID_IOleObject))
302     {
303         AddRef();
304         *ppv = static_cast<IOleObject*>(this);
305         return S_OK;
306     }
307     else if (IsEqualIID(riid, IID_IPersistFile))
308     {
309         AddRef();
310         *ppv = static_cast<IPersistFile*>(this);
311         return S_OK;
312     }
313     else if (IsEqualIID(riid, IID_IRunnableObject))
314     {
315         AddRef();
316         *ppv = static_cast<IRunnableObject*>(this);
317         return S_OK;
318     }
319     else if (IsEqualIID(riid, IID_IViewObject))
320     {
321         AddRef();
322         *ppv = static_cast<IViewObject*>(this);
323         return S_OK;
324     }
325     else if (IsEqualIID(riid, IID_IViewObject2))
326     {
327         AddRef();
328         *ppv = static_cast<IViewObject2*>(this);
329         return S_OK;
330     }
331     else if (IsEqualIID(riid, IID_IOleCache))
332     {
333         AddRef();
334         *ppv = static_cast<IOleCache*>(&m_aInternalCache);
335         return S_OK;
336     }
337     else if (IsEqualIID(riid, IID_IOleCache2))
338     {
339         AddRef();
340         *ppv = static_cast<IOleCache2*>(&m_aInternalCache);
341         return S_OK;
342     }
343     else if (IsEqualIID(riid, IID_IOleWindow))
344     {
345         AddRef();
346         *ppv = static_cast<IOleWindow*>(this);
347         return S_OK;
348     }
349     else if (IsEqualIID(riid, IID_IOleInPlaceObject))
350     {
351         AddRef();
352         *ppv = static_cast<IOleInPlaceObject*>(this);
353         return S_OK;
354     }
355     else if (IsEqualIID(riid, IID_IDispatch))
356     {
357         AddRef();
358         *ppv = static_cast<IDispatch*>(this);
359         return S_OK;
360     }
361 
362     *ppv = nullptr;
363     return ResultFromScode(E_NOINTERFACE);
364 }
365 
366 
STDMETHODIMP_(ULONG)367 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::AddRef()
368 {
369     return ++m_refCount;
370 }
371 
372 
STDMETHODIMP_(ULONG)373 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::Release()
374 {
375     // unfortunately there are reentrance problems in mfc that have to be workarounded
376     sal_Int32 nCount = m_refCount > 0 ? --m_refCount : 0;
377     if ( nCount == 0 && !m_bDeleted )
378     {
379         // deleting of this object can trigger deleting of mfc objects that will try to delete this object one more time
380         m_bDeleted = TRUE;
381 
382         Clean();
383         delete this;
384     }
385     return nCount;
386 }
387 
388 // IPersist
389 
GetClassID(CLSID * pClassId)390 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClassID( CLSID* pClassId )
391 {
392     *pClassId = m_guid;
393     return S_OK;
394 }
395 
396 // IPersistStorage
397 
IsDirty()398 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::IsDirty()
399 {
400     if ( m_pDefHandler == nullptr || m_pOleAdvises[0] == nullptr || m_pOleAdvises[0]->IsClosed() )
401         return S_FALSE;
402 
403     if ( CheckDefHandler() )
404     {
405         ComSmart< IPersistStorage > pPersist;
406         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
407 
408         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
409         if ( SUCCEEDED( hr ) && pPersist )
410             return pPersist->IsDirty();
411     }
412 
413     return E_FAIL;
414 }
415 
416 
InitNew(IStorage * pStg)417 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InitNew( IStorage *pStg )
418 {
419     if ( CheckDefHandler() )
420     {
421         ComSmart< IPersistStorage > pPersist;
422         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
423 
424         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
425         if ( SUCCEEDED( hr ) && pPersist )
426         {
427             hr = pPersist->InitNew( pStg );
428             if ( SUCCEEDED( hr ) )
429             {
430                 m_nInitMode = INIT_FROM_STORAGE;
431                 m_pStorage = pStg;
432 
433                 m_nFileOpenMode = 0;
434                 if ( m_pFileName )
435                 {
436                     delete[] m_pFileName;
437                     m_pFileName = nullptr;
438                 }
439             }
440 
441             return hr;
442         }
443     }
444 
445     return E_FAIL;
446 }
447 
448 
Load(IStorage * pStg)449 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Load( IStorage *pStg )
450 {
451     if ( CheckDefHandler() )
452     {
453         ComSmart< IPersistStorage > pPersist;
454         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
455 
456         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
457         if ( SUCCEEDED( hr ) && pPersist )
458         {
459             hr = pPersist->Load( pStg );
460             if ( SUCCEEDED( hr ) )
461             {
462                 m_nInitMode = LOAD_FROM_STORAGE;
463                 m_pStorage = pStg;
464 
465                 m_nFileOpenMode = 0;
466                 if ( m_pFileName )
467                 {
468                     delete[] m_pFileName;
469                     m_pFileName = nullptr;
470                 }
471             }
472 
473             return hr;
474         }
475     }
476 
477     return E_FAIL;
478 }
479 
480 
Save(IStorage * pStgSave,BOOL fSameAsLoad)481 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Save( IStorage *pStgSave, BOOL fSameAsLoad )
482 {
483     if ( fSameAsLoad && ( m_pDefHandler == nullptr || m_pOleAdvises[0] == nullptr || m_pOleAdvises[0]->IsClosed() ) )
484         return S_OK;
485 
486     if ( CheckDefHandler() )
487     {
488         ComSmart< IPersistStorage > pPersist;
489         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
490 
491         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
492         if ( SUCCEEDED( hr ) && pPersist )
493             return pPersist->Save( pStgSave, fSameAsLoad );
494     }
495 
496     return E_FAIL;
497 }
498 
499 
SaveCompleted(IStorage * pStgNew)500 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( IStorage *pStgNew )
501 {
502     if ( m_pDefHandler == nullptr || m_pOleAdvises[0] == nullptr || m_pOleAdvises[0]->IsClosed() )
503     {
504         if ( pStgNew )
505             m_pStorage = pStgNew;
506 
507         return S_OK;
508     }
509 
510     if ( CheckDefHandler() )
511     {
512         ComSmart< IPersistStorage > pPersist;
513         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
514 
515         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
516         if ( SUCCEEDED( hr ) && pPersist )
517         {
518             hr = pPersist->SaveCompleted( pStgNew );
519             if ( SUCCEEDED( hr ) )
520             {
521                 m_nInitMode = LOAD_FROM_STORAGE;
522                 if ( pStgNew )
523                 {
524                     m_pStorage = pStgNew;
525                 }
526 
527                 m_nFileOpenMode = 0;
528                 if ( m_pFileName )
529                 {
530                     delete[] m_pFileName;
531                     m_pFileName = nullptr;
532                 }
533             }
534 
535             return hr;
536         }
537     }
538 
539     return E_FAIL;
540 }
541 
542 
HandsOffStorage()543 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::HandsOffStorage()
544 {
545     if ( CheckDefHandler() )
546     {
547         ComSmart< IPersistStorage > pPersist;
548         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistStorage, reinterpret_cast<void**>(&pPersist) );
549 
550         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
551         if ( SUCCEEDED( hr ) && pPersist )
552         {
553             hr = pPersist->HandsOffStorage();
554             if ( SUCCEEDED( hr ) )
555             {
556                 m_pStorage = nullptr;
557             }
558 
559             return hr;
560         }
561     }
562 
563     return E_FAIL;
564 }
565 
566 // IPersistFile
567 
Load(LPCOLESTR pszFileName,DWORD dwMode)568 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Load( LPCOLESTR pszFileName, DWORD dwMode )
569 {
570     if ( CheckDefHandler() && pszFileName )
571     {
572         ComSmart< IPersistFile > pPersist;
573         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
574 
575         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
576         if ( SUCCEEDED( hr ) && pPersist )
577         {
578             hr = pPersist->Load( pszFileName, dwMode );
579             if ( SUCCEEDED( hr ) )
580             {
581                 m_nInitMode = LOAD_FROM_FILE;
582                 if ( m_pStorage )
583                     m_pStorage = nullptr;
584 
585                 m_nFileOpenMode = dwMode;
586                 // copy the string
587                 SetName( pszFileName, m_pFileName );
588             }
589 
590             return hr;
591         }
592     }
593 
594     return E_FAIL;
595 }
596 
597 
Save(LPCOLESTR pszFileName,BOOL fRemember)598 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Save( LPCOLESTR pszFileName, BOOL fRemember )
599 {
600     if ( CheckDefHandler() )
601     {
602         ComSmart< IPersistFile > pPersist;
603         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
604 
605         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
606         if ( SUCCEEDED( hr ) && pPersist )
607             return pPersist->Save( pszFileName, fRemember );
608     }
609 
610     return E_FAIL;
611 }
612 
613 
SaveCompleted(LPCOLESTR pszFileName)614 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SaveCompleted( LPCOLESTR pszFileName )
615 {
616     if ( CheckDefHandler() )
617     {
618         ComSmart< IPersistFile > pPersist;
619         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
620 
621         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
622         if ( SUCCEEDED( hr ) && pPersist )
623         {
624             hr = pPersist->SaveCompleted( pszFileName );
625             if ( SUCCEEDED( hr ) )
626             {
627                 m_nInitMode = LOAD_FROM_STORAGE;
628                 if ( m_pStorage )
629                     m_pStorage = nullptr;
630 
631                 m_nFileOpenMode = STGM_READWRITE; // was just written
632                 // copy the string
633                 SetName( pszFileName, m_pFileName );
634             }
635         }
636 
637     }
638 
639     return E_FAIL;
640 }
641 
642 
GetCurFile(LPOLESTR * ppszFileName)643 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetCurFile( LPOLESTR *ppszFileName )
644 {
645     if ( CheckDefHandler() )
646     {
647         ComSmart< IPersistFile > pPersist;
648         HRESULT hr = m_pDefHandler->QueryInterface( IID_IPersistFile, reinterpret_cast<void**>(&pPersist) );
649 
650         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
651         if ( SUCCEEDED( hr ) && pPersist )
652             return pPersist->GetCurFile( ppszFileName );
653     }
654 
655     return E_FAIL;
656 }
657 
658 // IOleObject
659 
SetClientSite(IOleClientSite * pSite)660 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetClientSite( IOleClientSite* pSite )
661 {
662     if ( pSite == m_pClientSite.get() )
663         return S_OK;
664 
665     if ( !pSite )
666     {
667         m_pClientSite = nullptr;
668         if ( m_pOleContainer )
669         {
670             m_pOleContainer->LockContainer( FALSE );
671             m_pOleContainer = nullptr;
672         }
673     }
674 
675     if ( CheckDefHandler() )
676     {
677         ComSmart< IOleObject > pOleObject;
678         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
679 
680         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
681         if ( SUCCEEDED( hr ) && pOleObject )
682         {
683             HRESULT hr2 = pOleObject->SetClientSite( pSite );
684             if ( SUCCEEDED( hr2 ) )
685             {
686                 m_pClientSite = pSite;
687 
688                 if ( m_pOleContainer )
689                 {
690                     m_pOleContainer->LockContainer( FALSE );
691                     m_pOleContainer = nullptr;
692                 }
693 
694                 m_pClientSite->GetContainer( &m_pOleContainer );
695                 if ( m_pOleContainer )
696                     m_pOleContainer->LockContainer( TRUE );
697             }
698 
699             return hr2;
700         }
701     }
702 
703     return E_FAIL;
704 }
705 
706 
GetClientSite(IOleClientSite ** pSite)707 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClientSite( IOleClientSite** pSite )
708 {
709     if ( CheckDefHandler() )
710     {
711         ComSmart< IOleObject > pOleObject;
712         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
713 
714         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
715         if ( SUCCEEDED( hr ) && pOleObject )
716             return pOleObject->GetClientSite( pSite );
717     }
718 
719     return E_FAIL;
720 }
721 
722 
SetHostNames(LPCOLESTR szContainerApp,LPCOLESTR szContainerObj)723 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetHostNames( LPCOLESTR szContainerApp, LPCOLESTR szContainerObj )
724 {
725 
726     if ( CheckDefHandler() )
727     {
728         ComSmart< IOleObject > pOleObject;
729         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
730 
731         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
732         if ( SUCCEEDED( hr ) && pOleObject )
733         {
734             hr = pOleObject->SetHostNames( szContainerApp, szContainerObj );
735         }
736     }
737 
738     return S_OK;
739 }
740 
741 
Close(DWORD dwSaveOption)742 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Close( DWORD dwSaveOption )
743 {
744     HRESULT ret = S_OK;
745     if ( m_pDefHandler && CheckDefHandler() )
746     {
747         // no need to close if there is no default handler.
748         ComSmart< IOleObject > pOleObject;
749         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
750 
751         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
752         if ( SUCCEEDED( hr ) && pOleObject )
753         {
754             hr = pOleObject->Close( dwSaveOption );
755             if (!SUCCEEDED(hr))
756                ret = hr;
757             hr = CoDisconnectObject( static_cast<IUnknown*>(static_cast<IPersistStorage*>(this)), 0 );
758             if (!SUCCEEDED(hr) && SUCCEEDED(ret))
759                ret = hr;
760         }
761     }
762 
763     // if the object is closed from outside that means that it should go to uninitialized state
764     Clean();
765 
766     return ret;
767 }
768 
769 
SetMoniker(DWORD dwWhichMoniker,IMoniker * pmk)770 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetMoniker( DWORD dwWhichMoniker, IMoniker * pmk )
771 {
772     if ( CheckDefHandler() )
773     {
774         ComSmart< IOleObject > pOleObject;
775         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
776 
777         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
778         if ( SUCCEEDED( hr ) && pOleObject )
779             return pOleObject->SetMoniker( dwWhichMoniker, pmk );
780     }
781 
782     return E_FAIL;
783 }
784 
785 
GetMoniker(DWORD dwAssign,DWORD dwWhichMoniker,IMoniker ** ppmk)786 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker ** ppmk )
787 {
788     if ( CheckDefHandler() )
789     {
790         ComSmart< IOleObject > pOleObject;
791         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
792 
793         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
794         if ( SUCCEEDED( hr ) && pOleObject )
795             return pOleObject->GetMoniker( dwAssign, dwWhichMoniker, ppmk );
796     }
797 
798     return E_FAIL;
799 }
800 
801 
InitFromData(IDataObject * pDataObject,BOOL fCreation,DWORD dwReserved)802 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InitFromData( IDataObject * pDataObject, BOOL fCreation, DWORD dwReserved )
803 {
804     if ( CheckDefHandler() )
805     {
806         ComSmart< IOleObject > pOleObject;
807         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
808 
809         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
810         if ( SUCCEEDED( hr ) && pOleObject )
811             return pOleObject->InitFromData( pDataObject, fCreation, dwReserved );
812     }
813 
814     return E_FAIL;
815 }
816 
817 
GetClipboardData(DWORD dwReserved,IDataObject ** ppDataObject)818 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetClipboardData( DWORD dwReserved, IDataObject ** ppDataObject )
819 {
820     if ( CheckDefHandler() )
821     {
822         ComSmart< IOleObject > pOleObject;
823         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
824 
825         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
826         if ( SUCCEEDED( hr ) && pOleObject )
827             return pOleObject->GetClipboardData( dwReserved, ppDataObject );
828     }
829 
830     return E_FAIL;
831 }
832 
833 
DoVerb(LONG iVerb,LPMSG pMsg,IOleClientSite * pActiveSite,LONG nLong,HWND hWin,LPCRECT pRect)834 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::DoVerb(
835     LONG iVerb,
836     LPMSG pMsg,
837     IOleClientSite *pActiveSite,
838     LONG nLong,
839     HWND hWin,
840     LPCRECT pRect )
841 {
842     if ( CheckDefHandler() )
843     {
844         ComSmart< IOleObject > pOleObject;
845         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
846 
847         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
848         if ( SUCCEEDED( hr ) && pOleObject )
849         {
850             hr = pOleObject->DoVerb( iVerb, pMsg, pActiveSite, nLong, hWin, pRect );
851             return hr;
852         }
853 
854     }
855 
856     return E_FAIL;
857 }
858 
859 
EnumVerbs(IEnumOLEVERB ** ppEnumOleVerb)860 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumVerbs( IEnumOLEVERB ** ppEnumOleVerb )
861 {
862     if ( CheckDefHandler() )
863     {
864         ComSmart< IOleObject > pOleObject;
865         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
866 
867         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
868         if ( SUCCEEDED( hr ) && pOleObject )
869             return pOleObject->EnumVerbs( ppEnumOleVerb );
870     }
871 
872     return E_FAIL;
873 }
874 
875 
Update()876 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Update()
877 {
878 
879     if ( m_pDefHandler && CheckDefHandler() )
880     {
881         ComSmart< IOleObject > pOleObject;
882         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
883 
884         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
885         if ( SUCCEEDED( hr ) && pOleObject )
886             return pOleObject->Update();
887     }
888 
889     return S_OK;
890 }
891 
892 
IsUpToDate()893 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::IsUpToDate()
894 {
895     if ( CheckDefHandler() )
896     {
897         ComSmart< IOleObject > pOleObject;
898         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
899 
900         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
901         if ( SUCCEEDED( hr ) && pOleObject )
902             return pOleObject->IsUpToDate();
903     }
904 
905     return E_FAIL;
906 }
907 
908 
GetUserClassID(CLSID * pClsid)909 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetUserClassID( CLSID *pClsid )
910 {
911     if ( pClsid )
912         *pClsid = m_guid;
913 
914     return S_OK;
915 }
916 
917 
GetUserType(DWORD dwFormOfType,LPOLESTR * pszUserType)918 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetUserType( DWORD dwFormOfType, LPOLESTR * pszUserType )
919 {
920     if ( CheckDefHandler() )
921     {
922         ComSmart< IOleObject > pOleObject;
923         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
924 
925         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
926         if ( SUCCEEDED( hr ) && pOleObject )
927             return pOleObject->GetUserType( dwFormOfType, pszUserType );
928     }
929 
930     return E_FAIL;
931 }
932 
933 
SetExtent(DWORD dwDrawAspect,SIZEL * psizel)934 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetExtent( DWORD dwDrawAspect, SIZEL *psizel )
935 {
936     if ( CheckDefHandler() )
937     {
938         ComSmart< IOleObject > pOleObject;
939         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
940 
941         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
942         if ( SUCCEEDED( hr ) && pOleObject )
943             return pOleObject->SetExtent( dwDrawAspect, psizel );
944     }
945 
946     return E_FAIL;
947 }
948 
949 
GetExtent(DWORD dwDrawAspect,SIZEL * psizel)950 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, SIZEL * psizel )
951 {
952     if ( CheckDefHandler() )
953     {
954         ComSmart< IOleObject > pOleObject;
955         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
956 
957         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
958         if ( SUCCEEDED( hr ) && pOleObject )
959             return pOleObject->GetExtent( dwDrawAspect, psizel );
960     }
961 
962     return E_FAIL;
963 }
964 
965 
Advise(IAdviseSink * pAdvSink,DWORD * pdwConnection)966 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Advise( IAdviseSink *pAdvSink, DWORD *pdwConnection )
967 {
968 
969     if ( !pdwConnection )
970         return E_FAIL;
971 
972     // CheckDefHandler will set the listener, avoid reusing of old listener
973     if ( DEFAULT_ARRAY_LEN > *pdwConnection && *pdwConnection > 0 && m_pOleAdvises[*pdwConnection] )
974     {
975         m_pOleAdvises[*pdwConnection]->DisconnectOrigAdvise();
976         m_pOleAdvises[*pdwConnection] = nullptr;
977     }
978 
979     if ( pAdvSink && CheckDefHandler() )
980     {
981         ComSmart< IOleObject > pOleObject;
982         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
983 
984         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
985         if ( SUCCEEDED( hr ) && pOleObject )
986         {
987             ComSmart<IAdviseSink> aListener(pAdvSink);
988             ComSmart<OleWrapperAdviseSink> pOwnAdvise(new OleWrapperAdviseSink(aListener));
989             DWORD nRegID = 0;
990 
991             if ( SUCCEEDED( pOleObject->Advise( pOwnAdvise.get(), &nRegID ) ) && nRegID > 0 )
992             {
993                 pOwnAdvise->SetRegID( nRegID );
994                 *pdwConnection = InsertAdviseLinkToList( pOwnAdvise, m_pOleAdvises );
995                 if ( *pdwConnection )
996                     return S_OK;
997                 else
998                     pOleObject->Unadvise( nRegID );
999             }
1000         }
1001     }
1002 
1003     // return success always for now
1004     return S_OK;
1005 }
1006 
1007 
Unadvise(DWORD dwConnection)1008 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Unadvise( DWORD dwConnection )
1009 {
1010     if ( DEFAULT_ARRAY_LEN > dwConnection && dwConnection > 0 && m_pOleAdvises[dwConnection] )
1011     {
1012         if ( m_pDefHandler )
1013         {
1014             ComSmart< IOleObject > pOleObject;
1015             HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
1016 
1017             ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1018             if ( SUCCEEDED( hr ) && pOleObject )
1019             {
1020                 DWORD nID = m_pOleAdvises[dwConnection]->GetRegID();
1021                 pOleObject->Unadvise( nID );
1022             }
1023         }
1024 
1025         m_pOleAdvises[dwConnection]->DisconnectOrigAdvise();
1026         m_pOleAdvises[dwConnection] = nullptr;
1027 
1028         return S_OK;
1029     }
1030 
1031     return E_FAIL;
1032 }
1033 
1034 
EnumAdvise(IEnumSTATDATA **)1035 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumAdvise( IEnumSTATDATA ** /*ppenumAdvise*/ )
1036 {
1037     return E_NOTIMPL;
1038 }
1039 
1040 
GetMiscStatus(DWORD dwAspect,DWORD * pdwStatus)1041 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetMiscStatus( DWORD dwAspect, DWORD * pdwStatus )
1042 {
1043     if ( CheckDefHandler() )
1044     {
1045         ComSmart< IOleObject > pOleObject;
1046         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
1047 
1048         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1049         if ( SUCCEEDED( hr ) && pOleObject )
1050             return pOleObject->GetMiscStatus( dwAspect, pdwStatus );
1051     }
1052 
1053     return E_FAIL;
1054 }
1055 
1056 
SetColorScheme(LOGPALETTE * pLogpal)1057 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetColorScheme( LOGPALETTE * pLogpal )
1058 {
1059     if ( CheckDefHandler() )
1060     {
1061         ComSmart< IOleObject > pOleObject;
1062         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleObject, reinterpret_cast<void**>(&pOleObject) );
1063 
1064         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1065         if ( SUCCEEDED( hr ) && pOleObject )
1066             return pOleObject->SetColorScheme( pLogpal );
1067     }
1068 
1069     return E_FAIL;
1070 }
1071 
1072 //IDataObject
1073 
GetData(FORMATETC * pFormatetc,STGMEDIUM * pMedium)1074 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
1075 {
1076     if ( CheckDefHandler() )
1077     {
1078         ComSmart< IDataObject > pIDataObject;
1079         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1080 
1081         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1082         if ( SUCCEEDED( hr ) && pIDataObject )
1083             return pIDataObject->GetData( pFormatetc, pMedium );
1084     }
1085 
1086     return E_FAIL;
1087 }
1088 
1089 
GetDataHere(FORMATETC * pFormatetc,STGMEDIUM * pMedium)1090 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetDataHere( FORMATETC * pFormatetc, STGMEDIUM * pMedium )
1091 {
1092     if ( CheckDefHandler() )
1093     {
1094         ComSmart< IDataObject > pIDataObject;
1095         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1096 
1097         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1098         if ( SUCCEEDED( hr ) && pIDataObject )
1099             return pIDataObject->GetDataHere( pFormatetc, pMedium );
1100     }
1101 
1102     return E_FAIL;
1103 }
1104 
1105 
QueryGetData(FORMATETC * pFormatetc)1106 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::QueryGetData( FORMATETC * pFormatetc )
1107 {
1108     if ( CheckDefHandler() )
1109     {
1110         ComSmart< IDataObject > pIDataObject;
1111         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1112 
1113         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1114         if ( SUCCEEDED( hr ) && pIDataObject )
1115             return pIDataObject->QueryGetData( pFormatetc );
1116     }
1117 
1118     return E_FAIL;
1119 }
1120 
1121 
GetCanonicalFormatEtc(FORMATETC * pFormatetcIn,FORMATETC * pFormatetcOut)1122 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetCanonicalFormatEtc( FORMATETC * pFormatetcIn, FORMATETC * pFormatetcOut )
1123 {
1124     if ( CheckDefHandler() )
1125     {
1126         ComSmart< IDataObject > pIDataObject;
1127         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1128 
1129         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1130         if ( SUCCEEDED( hr ) && pIDataObject )
1131             return pIDataObject->GetCanonicalFormatEtc( pFormatetcIn, pFormatetcOut );
1132     }
1133 
1134     return E_FAIL;
1135 }
1136 
1137 
SetData(FORMATETC * pFormatetc,STGMEDIUM * pMedium,BOOL fRelease)1138 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetData( FORMATETC * pFormatetc, STGMEDIUM * pMedium, BOOL fRelease )
1139 {
1140     if ( CheckDefHandler() )
1141     {
1142         ComSmart< IDataObject > pIDataObject;
1143         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1144 
1145         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1146         if ( SUCCEEDED( hr ) && pIDataObject )
1147             return pIDataObject->SetData( pFormatetc, pMedium, fRelease );
1148     }
1149 
1150     return E_FAIL;
1151 }
1152 
1153 
EnumFormatEtc(DWORD dwDirection,IEnumFORMATETC ** ppFormatetc)1154 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumFormatEtc( DWORD dwDirection, IEnumFORMATETC ** ppFormatetc )
1155 {
1156     if ( CheckDefHandler() )
1157     {
1158         ComSmart< IDataObject > pIDataObject;
1159         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1160 
1161         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1162         if ( SUCCEEDED( hr ) && pIDataObject )
1163             return pIDataObject->EnumFormatEtc( dwDirection, ppFormatetc );
1164     }
1165 
1166     return E_FAIL;
1167 }
1168 
1169 
DAdvise(FORMATETC * pFormatetc,DWORD advf,IAdviseSink * pAdvSink,DWORD * pdwConnection)1170 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::DAdvise( FORMATETC * pFormatetc, DWORD advf, IAdviseSink * pAdvSink, DWORD * pdwConnection )
1171 {
1172 
1173     if ( !pdwConnection )
1174         return E_FAIL;
1175 
1176     // avoid reusing of the old listener
1177     if ( m_pDefHandler && DEFAULT_ARRAY_LEN > *pdwConnection && *pdwConnection > 0 && m_pDataAdvises[*pdwConnection] )
1178     {
1179         m_pDataAdvises[*pdwConnection]->DisconnectOrigAdvise();
1180         m_pDataAdvises[*pdwConnection] = nullptr;
1181     }
1182 
1183     if ( pAdvSink && CheckDefHandler() )
1184     {
1185         ComSmart< IDataObject > pIDataObject;
1186         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1187 
1188         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1189         if ( SUCCEEDED( hr ) && pIDataObject )
1190         {
1191             ComSmart< OleWrapperAdviseSink > pOwnAdvise( new OleWrapperAdviseSink( ComSmart<IAdviseSink>( pAdvSink ), pFormatetc, advf ) );
1192             DWORD nRegID = 0;
1193 
1194             if ( SUCCEEDED( pIDataObject->DAdvise( pFormatetc, advf, pOwnAdvise.get(), &nRegID ) ) && nRegID > 0 )
1195             {
1196                 pOwnAdvise->SetRegID( nRegID );
1197                 *pdwConnection = InsertAdviseLinkToList( pOwnAdvise, m_pDataAdvises );
1198                 if ( *pdwConnection )
1199                     return S_OK;
1200                 else
1201                     pIDataObject->DUnadvise( nRegID );
1202             }
1203         }
1204     }
1205 
1206     // return success always for now
1207     return S_OK;
1208 }
1209 
1210 
DUnadvise(DWORD dwConnection)1211 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::DUnadvise( DWORD dwConnection )
1212 {
1213     if ( m_pDefHandler && DEFAULT_ARRAY_LEN > dwConnection && dwConnection > 0 && m_pDataAdvises[dwConnection] )
1214     {
1215         if ( CheckDefHandler() )
1216         {
1217             ComSmart< IDataObject > pIDataObject;
1218             HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1219 
1220             ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1221             if ( SUCCEEDED( hr ) && pIDataObject )
1222             {
1223                 DWORD nID = m_pDataAdvises[dwConnection]->GetRegID();
1224                 pIDataObject->DUnadvise( nID );
1225             }
1226         }
1227 
1228         m_pDataAdvises[dwConnection]->DisconnectOrigAdvise();
1229         m_pDataAdvises[dwConnection] = nullptr;
1230 
1231         return S_OK;
1232     }
1233 
1234     return E_FAIL;
1235 }
1236 
1237 
EnumDAdvise(IEnumSTATDATA ** ppenumAdvise)1238 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::EnumDAdvise( IEnumSTATDATA ** ppenumAdvise )
1239 {
1240     if ( CheckDefHandler() )
1241     {
1242         ComSmart< IDataObject > pIDataObject;
1243         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDataObject, reinterpret_cast<void**>(&pIDataObject) );
1244 
1245         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1246         if ( SUCCEEDED( hr ) && pIDataObject )
1247             return pIDataObject->EnumDAdvise( ppenumAdvise );
1248     }
1249 
1250     return E_FAIL;
1251 }
1252 
1253 // IRunnableObject
1254 
GetRunningClass(LPCLSID lpClsid)1255 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetRunningClass( LPCLSID lpClsid )
1256 {
1257     if ( CheckDefHandler() )
1258     {
1259         ComSmart< IRunnableObject > pIRunObj;
1260         HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
1261 
1262         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1263         if ( SUCCEEDED( hr ) && pIRunObj )
1264             return pIRunObj->GetRunningClass( lpClsid );
1265     }
1266 
1267     return E_FAIL;
1268 }
1269 
1270 
Run(LPBINDCTX pbc)1271 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Run( LPBINDCTX pbc )
1272 {
1273     if ( CheckDefHandler() )
1274     {
1275         ComSmart< IRunnableObject > pIRunObj;
1276         HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
1277 
1278         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1279         if ( SUCCEEDED( hr ) && pIRunObj )
1280             return pIRunObj->Run( pbc );
1281     }
1282 
1283     return E_FAIL;
1284 }
1285 
IsRunning()1286 BOOL STDMETHODCALLTYPE InprocEmbedDocument_Impl::IsRunning()
1287 {
1288     if (CheckDefHandler())
1289     {
1290         ComSmart< IRunnableObject > pIRunObj;
1291         HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
1292 
1293         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1294         if ( SUCCEEDED( hr ) && pIRunObj )
1295             return pIRunObj->IsRunning();
1296     }
1297 
1298     return FALSE;
1299 }
1300 
LockRunning(BOOL fLock,BOOL fLastUnlockCloses)1301 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::LockRunning( BOOL fLock, BOOL fLastUnlockCloses )
1302 {
1303     if ( CheckDefHandler() )
1304     {
1305         ComSmart< IRunnableObject > pIRunObj;
1306         HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
1307 
1308         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1309         if ( SUCCEEDED( hr ) && pIRunObj )
1310             return pIRunObj->LockRunning( fLock, fLastUnlockCloses );
1311     }
1312 
1313     return E_FAIL;
1314 }
1315 
1316 
SetContainedObject(BOOL fContained)1317 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetContainedObject( BOOL fContained)
1318 {
1319     if ( CheckDefHandler() )
1320     {
1321         ComSmart< IRunnableObject > pIRunObj;
1322         HRESULT hr = m_pDefHandler->QueryInterface( IID_IRunnableObject, reinterpret_cast<void**>(&pIRunObj) );
1323 
1324         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1325         if ( SUCCEEDED( hr ) && pIRunObj )
1326             return pIRunObj->SetContainedObject( fContained );
1327     }
1328 
1329     return E_FAIL;
1330 }
1331 
1332 
1333 // IViewObject methods
1334 
Draw(DWORD dwDrawAspect,LONG lindex,void * pvAspect,DVTARGETDEVICE * ptd,HDC hdcTargetDev,HDC hdcDraw,LPCRECTL lprcBounds,LPCRECTL lprcWBounds,BOOL (STDMETHODCALLTYPE * pfnContinue)(ULONG_PTR dwContinue),ULONG_PTR dwContinue)1335 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Draw( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL ( STDMETHODCALLTYPE *pfnContinue )( ULONG_PTR dwContinue ), ULONG_PTR dwContinue )
1336 {
1337     if ( CheckDefHandler() )
1338     {
1339         ComSmart< IViewObject > pIViewObject;
1340         HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
1341 
1342         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1343         if ( SUCCEEDED( hr ) && pIViewObject )
1344             return pIViewObject->Draw( dwDrawAspect, lindex, pvAspect, ptd, hdcTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue );
1345     }
1346 
1347     return E_FAIL;
1348 }
1349 
1350 
GetColorSet(DWORD dwDrawAspect,LONG lindex,void * pvAspect,DVTARGETDEVICE * ptd,HDC hicTargetDev,LOGPALETTE ** ppColorSet)1351 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetColorSet( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **ppColorSet )
1352 {
1353     if ( CheckDefHandler() )
1354     {
1355         ComSmart< IViewObject > pIViewObject;
1356         HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
1357 
1358         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1359         if ( SUCCEEDED( hr ) && pIViewObject )
1360             return pIViewObject->GetColorSet( dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, ppColorSet );
1361     }
1362 
1363     return E_FAIL;
1364 }
1365 
1366 
Freeze(DWORD dwDrawAspect,LONG lindex,void * pvAspect,DWORD * pdwFreeze)1367 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Freeze( DWORD dwDrawAspect, LONG lindex, void *pvAspect, DWORD *pdwFreeze )
1368 {
1369     if ( CheckDefHandler() )
1370     {
1371         ComSmart< IViewObject > pIViewObject;
1372         HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
1373 
1374         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1375         if ( SUCCEEDED( hr ) && pIViewObject )
1376             return pIViewObject->Freeze( dwDrawAspect, lindex, pvAspect, pdwFreeze );
1377     }
1378 
1379     return E_FAIL;
1380 }
1381 
1382 
Unfreeze(DWORD dwFreeze)1383 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Unfreeze( DWORD dwFreeze )
1384 {
1385     if ( CheckDefHandler() )
1386     {
1387         ComSmart< IViewObject > pIViewObject;
1388         HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
1389 
1390         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1391         if ( SUCCEEDED( hr ) && pIViewObject )
1392             return pIViewObject->Unfreeze( dwFreeze );
1393     }
1394 
1395     return E_FAIL;
1396 }
1397 
1398 
SetAdvise(DWORD aspects,DWORD advf,IAdviseSink * pAdvSink)1399 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetAdvise( DWORD aspects, DWORD advf, IAdviseSink *pAdvSink )
1400 {
1401 
1402     // CheckDefHandler will set the listener, avoid reusing of old listener
1403     if ( m_pViewAdvise )
1404     {
1405         m_pViewAdvise->DisconnectOrigAdvise();
1406         m_pViewAdvise = nullptr;
1407     }
1408 
1409     if ( pAdvSink && CheckDefHandler() )
1410     {
1411         ComSmart< IViewObject > pIViewObject;
1412         HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject, reinterpret_cast<void**>(&pIViewObject) );
1413 
1414         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1415         if ( SUCCEEDED( hr ) && pIViewObject )
1416         {
1417             ComSmart<IAdviseSink> aListener(pAdvSink);
1418             ComSmart<OleWrapperAdviseSink> pOwnAdvise(new OleWrapperAdviseSink(aListener, aspects, advf));
1419 
1420             if ( SUCCEEDED( pIViewObject->SetAdvise( aspects, advf, pOwnAdvise.get() ) ) )
1421             {
1422                 m_pViewAdvise = pOwnAdvise;
1423                 return S_OK;
1424             }
1425         }
1426     }
1427 
1428     return S_OK;
1429 }
1430 
1431 
GetAdvise(DWORD * pAspects,DWORD * pAdvf,IAdviseSink ** ppAdvSink)1432 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetAdvise( DWORD *pAspects, DWORD *pAdvf, IAdviseSink **ppAdvSink )
1433 {
1434     if ( !ppAdvSink )
1435         return E_INVALIDARG;
1436 
1437     if ( m_pViewAdvise )
1438     {
1439         if ( pAspects )
1440             *pAspects = m_pViewAdvise->GetAspect();
1441 
1442         if ( pAdvf )
1443             *pAdvf = m_pViewAdvise->GetViewAdviseFlag();
1444 
1445         *ppAdvSink = m_pViewAdvise->GetOrigAdvise().get();
1446         if ( *ppAdvSink )
1447             (*ppAdvSink)->AddRef();
1448     }
1449     else
1450         *ppAdvSink = nullptr;
1451 
1452     return S_OK;
1453 }
1454 
1455 // IViewObject2 methods
1456 
GetExtent(DWORD dwDrawAspect,LONG lindex,DVTARGETDEVICE * ptd,LPSIZEL lpsizel)1457 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetExtent( DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE *ptd, LPSIZEL lpsizel )
1458 {
1459     if ( CheckDefHandler() )
1460     {
1461         ComSmart< IViewObject2 > pIViewObject2;
1462         HRESULT hr = m_pDefHandler->QueryInterface( IID_IViewObject2, reinterpret_cast<void**>(&pIViewObject2) );
1463 
1464         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1465         if ( SUCCEEDED( hr ) && pIViewObject2 )
1466             return pIViewObject2->GetExtent( dwDrawAspect, lindex, ptd, lpsizel );
1467     }
1468 
1469     return E_FAIL;
1470 }
1471 
1472 
1473 // IOleWindow methods
1474 
GetWindow(HWND * phwnd)1475 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetWindow( HWND *phwnd )
1476 {
1477     if ( CheckDefHandler() )
1478     {
1479         ComSmart< IOleWindow > pIOleWindow;
1480         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleWindow, reinterpret_cast<void**>(&pIOleWindow) );
1481 
1482         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1483         if ( SUCCEEDED( hr ) && pIOleWindow )
1484             return pIOleWindow->GetWindow( phwnd );
1485     }
1486 
1487     return E_FAIL;
1488 }
1489 
1490 
ContextSensitiveHelp(BOOL fEnterMode)1491 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::ContextSensitiveHelp( BOOL fEnterMode )
1492 {
1493     if ( CheckDefHandler() )
1494     {
1495         ComSmart< IOleWindow > pIOleWindow;
1496         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleWindow, reinterpret_cast<void**>(&pIOleWindow) );
1497 
1498         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1499         if ( SUCCEEDED( hr ) && pIOleWindow )
1500             return pIOleWindow->ContextSensitiveHelp( fEnterMode );
1501     }
1502 
1503     return E_FAIL;
1504 }
1505 
1506 
1507 // IOleInPlaceObject methods
1508 
InPlaceDeactivate()1509 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InPlaceDeactivate()
1510 {
1511     if ( CheckDefHandler() )
1512     {
1513         ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
1514         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
1515 
1516         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1517         if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
1518             return pIOleInPlaceObject->InPlaceDeactivate();
1519     }
1520 
1521     return E_FAIL;
1522 }
1523 
1524 
UIDeactivate()1525 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::UIDeactivate()
1526 {
1527     if ( CheckDefHandler() )
1528     {
1529         ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
1530         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
1531 
1532         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1533         if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
1534             return pIOleInPlaceObject->UIDeactivate();
1535     }
1536 
1537     return E_FAIL;
1538 }
1539 
1540 
SetObjectRects(LPCRECT lprcPosRect,LPCRECT lprcClipRect)1541 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::SetObjectRects( LPCRECT lprcPosRect, LPCRECT lprcClipRect )
1542 {
1543     if ( CheckDefHandler() )
1544     {
1545         ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
1546         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
1547 
1548         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1549         if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
1550             return pIOleInPlaceObject->SetObjectRects( lprcPosRect, lprcClipRect );
1551     }
1552 
1553     return E_FAIL;
1554 }
1555 
1556 
ReactivateAndUndo()1557 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::ReactivateAndUndo()
1558 {
1559     if ( CheckDefHandler() )
1560     {
1561         ComSmart< IOleInPlaceObject > pIOleInPlaceObject;
1562         HRESULT hr = m_pDefHandler->QueryInterface( IID_IOleInPlaceObject, reinterpret_cast<void**>(&pIOleInPlaceObject) );
1563 
1564         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1565         if ( SUCCEEDED( hr ) && pIOleInPlaceObject )
1566             return pIOleInPlaceObject->ReactivateAndUndo();
1567     }
1568 
1569     return E_FAIL;
1570 }
1571 
1572 
1573 // IDispatch methods
1574 
GetTypeInfoCount(UINT * pctinfo)1575 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfoCount( UINT *pctinfo )
1576 {
1577     if ( CheckDefHandler() )
1578     {
1579         ComSmart< IDispatch > pIDispatch;
1580         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
1581 
1582         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1583         if ( SUCCEEDED( hr ) && pIDispatch )
1584             return pIDispatch->GetTypeInfoCount( pctinfo );
1585     }
1586 
1587     return E_FAIL;
1588 }
1589 
1590 
GetTypeInfo(UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)1591 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo )
1592 {
1593     if ( CheckDefHandler() )
1594     {
1595         ComSmart< IDispatch > pIDispatch;
1596         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
1597 
1598         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1599         if ( SUCCEEDED( hr ) && pIDispatch )
1600             return pIDispatch->GetTypeInfo( iTInfo, lcid, ppTInfo );
1601     }
1602 
1603     return E_FAIL;
1604 }
1605 
1606 
GetIDsOfNames(REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)1607 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::GetIDsOfNames( REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId )
1608 {
1609     if ( CheckDefHandler() )
1610     {
1611         ComSmart< IDispatch > pIDispatch;
1612         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
1613 
1614         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1615         if ( SUCCEEDED( hr ) && pIDispatch )
1616             return pIDispatch->GetIDsOfNames( riid, rgszNames, cNames, lcid, rgDispId );
1617     }
1618 
1619     return E_FAIL;
1620 }
1621 
1622 
Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)1623 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::Invoke( DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr )
1624 {
1625     if ( CheckDefHandler() )
1626     {
1627         ComSmart< IDispatch > pIDispatch;
1628         HRESULT hr = m_pDefHandler->QueryInterface( IID_IDispatch, reinterpret_cast<void**>(&pIDispatch) );
1629 
1630         ULONGGuard aGuard( &m_nCallsOnStack ); // avoid reentrance problem
1631         if ( SUCCEEDED( hr ) && pIDispatch )
1632             return pIDispatch->Invoke( dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr );
1633     }
1634 
1635     return E_FAIL;
1636 }
1637 
1638 
1639 // InternalCacheWrapper
1640 
1641 
1642 // IUnknown
1643 
QueryInterface(REFIID riid,void FAR * FAR * ppv)1644 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::QueryInterface( REFIID riid, void FAR* FAR* ppv )
1645 {
1646     return m_rOwnDocument.QueryInterface( riid, ppv );
1647 }
1648 
1649 
STDMETHODIMP_(ULONG)1650 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::InternalCacheWrapper::AddRef()
1651 {
1652     return m_rOwnDocument.AddRef();
1653 }
1654 
1655 
STDMETHODIMP_(ULONG)1656 COM_DECLSPEC_NOTHROW STDMETHODIMP_(ULONG) InprocEmbedDocument_Impl::InternalCacheWrapper::Release()
1657 {
1658     return m_rOwnDocument.Release();
1659 }
1660 
1661 // IOleCache methods
1662 
Cache(FORMATETC * pformatetc,DWORD advf,DWORD * pdwConnection)1663 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Cache( FORMATETC *pformatetc, DWORD advf, DWORD *pdwConnection )
1664 {
1665     if ( m_rOwnDocument.CheckDefHandler() )
1666     {
1667         ComSmart< IOleCache > pIOleCache;
1668         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
1669 
1670         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1671         if ( SUCCEEDED( hr ) && pIOleCache )
1672             return pIOleCache->Cache( pformatetc, advf, pdwConnection );
1673     }
1674 
1675     return E_FAIL;
1676 }
1677 
1678 
Uncache(DWORD dwConnection)1679 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::Uncache( DWORD dwConnection )
1680 {
1681     if ( m_rOwnDocument.CheckDefHandler() )
1682     {
1683         ComSmart< IOleCache > pIOleCache;
1684         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
1685 
1686         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1687         if ( SUCCEEDED( hr ) && pIOleCache )
1688             return pIOleCache->Uncache( dwConnection );
1689     }
1690 
1691     return E_FAIL;
1692 }
1693 
1694 
EnumCache(IEnumSTATDATA ** ppenumSTATDATA)1695 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::EnumCache( IEnumSTATDATA **ppenumSTATDATA )
1696 {
1697     if ( m_rOwnDocument.CheckDefHandler() )
1698     {
1699         ComSmart< IOleCache > pIOleCache;
1700         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
1701 
1702         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1703         if ( SUCCEEDED( hr ) && pIOleCache )
1704             return pIOleCache->EnumCache( ppenumSTATDATA );
1705     }
1706 
1707     return E_FAIL;
1708 }
1709 
1710 
InitCache(IDataObject * pDataObject)1711 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::InitCache( IDataObject *pDataObject )
1712 {
1713     if ( m_rOwnDocument.CheckDefHandler() )
1714     {
1715         ComSmart< IOleCache > pIOleCache;
1716         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
1717 
1718         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1719         if ( SUCCEEDED( hr ) && pIOleCache )
1720             return pIOleCache->InitCache( pDataObject );
1721     }
1722 
1723     return E_FAIL;
1724 }
1725 
1726 
SetData(FORMATETC * pformatetc,STGMEDIUM * pmedium,BOOL fRelease)1727 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::SetData( FORMATETC *pformatetc, STGMEDIUM *pmedium, BOOL fRelease )
1728 {
1729     if ( m_rOwnDocument.CheckDefHandler() )
1730     {
1731         ComSmart< IOleCache > pIOleCache;
1732         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache, reinterpret_cast<void**>(&pIOleCache) );
1733 
1734         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1735         if ( SUCCEEDED( hr ) && pIOleCache )
1736             return pIOleCache->SetData( pformatetc, pmedium, fRelease );
1737     }
1738 
1739     return E_FAIL;
1740 }
1741 
1742 // IOleCache2 methods
1743 
UpdateCache(LPDATAOBJECT pDataObject,DWORD grfUpdf,LPVOID pReserved)1744 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::UpdateCache( LPDATAOBJECT pDataObject, DWORD grfUpdf, LPVOID pReserved )
1745 {
1746     if ( m_rOwnDocument.CheckDefHandler() )
1747     {
1748         ComSmart< IOleCache2 > pIOleCache2;
1749         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache2, reinterpret_cast<void**>(&pIOleCache2) );
1750 
1751         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1752         if ( SUCCEEDED( hr ) && pIOleCache2 )
1753             return pIOleCache2->UpdateCache( pDataObject, grfUpdf, pReserved );
1754     }
1755 
1756     return E_FAIL;
1757 }
1758 
1759 
DiscardCache(DWORD dwDiscardOptions)1760 COM_DECLSPEC_NOTHROW STDMETHODIMP InprocEmbedDocument_Impl::InternalCacheWrapper::DiscardCache( DWORD dwDiscardOptions )
1761 {
1762     if ( m_rOwnDocument.CheckDefHandler() )
1763     {
1764         ComSmart< IOleCache2 > pIOleCache2;
1765         HRESULT hr = m_rOwnDocument.GetDefHandler()->QueryInterface( IID_IOleCache2, reinterpret_cast<void**>(&pIOleCache2) );
1766 
1767         ULONGGuard aGuard( &m_rOwnDocument.m_nCallsOnStack ); // avoid reentrance problem
1768         if ( SUCCEEDED( hr ) && pIOleCache2 )
1769             return pIOleCache2->DiscardCache( dwDiscardOptions );
1770     }
1771 
1772     return E_FAIL;
1773 }
1774 
1775 }; // namespace inprocserv
1776 
1777 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1778