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