xref: /trunk/main/embedserv/source/embed/servprov.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 #if defined(_MSC_VER) && (_MSC_VER > 1310)
28 #pragma warning(disable : 4917 4555)
29 #endif
30 
31 #include "stdafx.h"
32 #include "servprov.hxx"
33 #include "embeddoc.hxx"
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <osl/mutex.hxx>
37 #include <osl/thread.h>
38 
39 using namespace com::sun::star;
40 
41 const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = {
42     &OID_WriterTextServer,
43     &OID_WriterOASISTextServer,
44     &OID_CalcServer,
45     &OID_CalcOASISServer,
46     &OID_DrawingServer,
47     &OID_DrawingOASISServer,
48     &OID_PresentationServer,
49     &OID_PresentationOASISServer,
50     &OID_MathServer,
51     &OID_MathOASISServer
52 };
53 
54 class CurThreadData
55 {
56     public:
57         CurThreadData();
58         virtual ~CurThreadData();
59 
60         sal_Bool SAL_CALL setData(void *pData);
61 
62         void* SAL_CALL getData();
63 
64     protected:
65         oslThreadKey m_hKey;
66 };
67 
68 CurThreadData::CurThreadData()
69 {
70     m_hKey = osl_createThreadKey( (oslThreadKeyCallbackFunction)NULL );
71 }
72 
73 CurThreadData::~CurThreadData()
74 {
75     osl_destroyThreadKey(m_hKey);
76 }
77 
78 sal_Bool CurThreadData::setData(void *pData)
79 {
80     OSL_ENSURE( m_hKey, "No thread key!\n" );
81     return (osl_setThreadKeyData(m_hKey, pData));
82 }
83 
84 void *CurThreadData::getData()
85 {
86     OSL_ENSURE( m_hKey, "No thread key!\n" );
87     return (osl_getThreadKeyData(m_hKey));
88 }
89 
90 
91 // CoInitializeEx *
92 typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *ptrCoInitEx)( LPVOID, DWORD);
93 // CoInitialize *
94 typedef DECLSPEC_IMPORT HRESULT (STDAPICALLTYPE *ptrCoInit)( LPVOID);
95 
96 void o2u_attachCurrentThread()
97 {
98     static CurThreadData oleThreadData;
99 
100     if ( oleThreadData.getData() != 0 )
101     {
102         HINSTANCE inst= LoadLibrary( _T("ole32.dll"));
103         if( inst )
104         {
105             HRESULT hr;
106             ptrCoInitEx initFuncEx= (ptrCoInitEx)GetProcAddress( inst, _T("CoInitializeEx"));
107             if( initFuncEx)
108                 hr= initFuncEx( NULL, COINIT_MULTITHREADED);
109             else
110             {
111                 ptrCoInit initFunc= (ptrCoInit)GetProcAddress( inst,_T("CoInitialize"));
112                 if( initFunc)
113                     hr= initFunc( NULL);
114             }
115         }
116         oleThreadData.setData((void*)sal_True);
117     }
118 }
119 
120 
121 //===============================================================================
122 // EmbedServer_Impl
123 
124 EmbedServer_Impl::EmbedServer_Impl( const uno::Reference<lang::XMultiServiceFactory>& xFactory):
125     m_xFactory( xFactory)
126 {
127     for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
128     {
129         m_pOLEFactories[nInd] = new EmbedProviderFactory_Impl( m_xFactory, guidList[nInd] );
130         m_pOLEFactories[nInd]->registerClass();
131     }
132 }
133 
134 EmbedServer_Impl::~EmbedServer_Impl()
135 {
136     for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
137     {
138         if ( m_pOLEFactories[nInd] )
139             m_pOLEFactories[nInd]->deregisterClass();
140     }
141 }
142 
143 // XInterface --------------------------------------------------
144 uno::Any SAL_CALL
145 EmbedServer_Impl::queryInterface(
146     const uno::Type& aType )
147     throw(
148         uno::RuntimeException
149     )
150 {
151     uno::Any a=
152         ::cppu::queryInterface(
153             aType, static_cast<lang::XTypeProvider*>(this));
154     if( a == uno::Any())
155         return OWeakObject::queryInterface( aType);
156     else
157         return a;
158 }
159 
160 void SAL_CALL EmbedServer_Impl::acquire(  ) throw(uno::RuntimeException)
161 {
162     OWeakObject::acquire();
163 }
164 
165 void SAL_CALL EmbedServer_Impl::release(  ) throw (uno::RuntimeException)
166 {
167     OWeakObject::release();
168 }
169 
170 
171 // XTypeProvider --------------------------------------------------
172 uno::Sequence< uno::Type > SAL_CALL
173 EmbedServer_Impl::getTypes( )
174     throw(
175         uno::RuntimeException
176     )
177 {
178     static ::cppu::OTypeCollection *pCollection = 0;
179     if( ! pCollection )
180     {
181         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
182         if( ! pCollection )
183         {
184             static ::cppu::OTypeCollection collection(
185                 getCppuType(
186                     reinterpret_cast<uno::Reference< uno::XWeak>*>(0)),
187                 getCppuType(
188                     reinterpret_cast<
189                     uno::Reference< lang::XTypeProvider>*>(0)));
190             pCollection = &collection;
191         }
192     }
193     return (*pCollection).getTypes();
194 }
195 
196 uno::Sequence< sal_Int8 > SAL_CALL EmbedServer_Impl::getImplementationId() throw(uno::RuntimeException)
197 {
198     static ::cppu::OImplementationId *pId = 0;
199     if( ! pId )
200     {
201         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
202         if( ! pId )
203         {
204             static ::cppu::OImplementationId id( sal_False );
205             pId = &id;
206         }
207     }
208     return (*pId).getImplementationId();
209 }
210 
211 //===============================================================================
212 // EmbedProviderFactory_Impl
213 
214 EmbedProviderFactory_Impl::EmbedProviderFactory_Impl(const uno::Reference<lang::XMultiServiceFactory>& xFactory, const GUID* pGuid)
215     : m_refCount( 0L )
216     , m_xFactory( xFactory )
217     , m_guid( *pGuid )
218 {
219 }
220 
221 EmbedProviderFactory_Impl::~EmbedProviderFactory_Impl()
222 {
223 }
224 
225 sal_Bool EmbedProviderFactory_Impl::registerClass()
226 {
227     HRESULT hresult;
228 
229     o2u_attachCurrentThread();
230 
231     hresult = CoRegisterClassObject(
232             m_guid,
233             this,
234             CLSCTX_LOCAL_SERVER,
235             REGCLS_MULTIPLEUSE,
236             &m_factoryHandle);
237 
238     return (hresult == NOERROR);
239 }
240 
241 sal_Bool EmbedProviderFactory_Impl::deregisterClass()
242 {
243     HRESULT hresult = CoRevokeClassObject( m_factoryHandle );
244 
245     return (hresult == NOERROR);
246 }
247 
248 STDMETHODIMP EmbedProviderFactory_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
249 {
250     if(IsEqualIID(riid, IID_IUnknown))
251     {
252         AddRef();
253         *ppv = (IUnknown*) (IClassFactory*) this;
254         return NOERROR;
255     }
256     else if (IsEqualIID(riid, IID_IClassFactory))
257     {
258         AddRef();
259         *ppv = (IClassFactory*) this;
260         return NOERROR;
261     }
262 
263     *ppv = NULL;
264     return ResultFromScode(E_NOINTERFACE);
265 }
266 
267 STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::AddRef()
268 {
269     return osl_incrementInterlockedCount( &m_refCount);
270 }
271 
272 STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::Release()
273 {
274     ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex());
275     sal_Int32 nCount = --m_refCount;
276     if ( nCount == 0 )
277     {
278         delete this;
279     }
280 
281     return nCount;
282 }
283 
284 STDMETHODIMP EmbedProviderFactory_Impl::CreateInstance(IUnknown FAR* punkOuter,
285                                                        REFIID riid,
286                                                        void FAR* FAR* ppv)
287 {
288     punkOuter = NULL;
289 
290     IUnknown* pEmbedDocument = (IUnknown*)(IPersistStorage*)( new EmbedDocument_Impl( m_xFactory, &m_guid ) );
291 
292     return pEmbedDocument->QueryInterface( riid, ppv );
293 }
294 
295 STDMETHODIMP EmbedProviderFactory_Impl::LockServer( int /*fLock*/ )
296 {
297     return NOERROR;
298 }
299 
300 // Fix strange warnings about some
301 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
302 // warning C4505: 'xxx' : unreferenced local function has been removed
303 #if defined(_MSC_VER)
304 #pragma warning(disable: 4505)
305 #endif
306