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