xref: /trunk/main/embedserv/source/embed/servprov.cxx (revision f3385db031069db3e0655c6a4d85518bf39a7b68)
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 
64 CurThreadData::CurThreadData()
65 {
66     m_hKey = osl_createThreadKey( (oslThreadKeyCallbackFunction)NULL );
67 }
68 
69 CurThreadData::~CurThreadData()
70 {
71     osl_destroyThreadKey(m_hKey);
72 }
73 
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 
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 
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 
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 
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
141 EmbedServer_Impl::queryInterface(
142     const uno::Type& aType )
143 {
144     uno::Any a=
145         ::cppu::queryInterface(
146             aType, static_cast<lang::XTypeProvider*>(this));
147     if( a == uno::Any())
148         return OWeakObject::queryInterface( aType);
149     else
150         return a;
151 }
152 
153 void SAL_CALL EmbedServer_Impl::acquire(  )
154 {
155     OWeakObject::acquire();
156 }
157 
158 void SAL_CALL EmbedServer_Impl::release(  )
159 {
160     OWeakObject::release();
161 }
162 
163 
164 // XTypeProvider --------------------------------------------------
165 uno::Sequence< uno::Type > SAL_CALL
166 EmbedServer_Impl::getTypes( )
167 {
168     static ::cppu::OTypeCollection *pCollection = 0;
169     if( ! pCollection )
170     {
171         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
172         if( ! pCollection )
173         {
174             static ::cppu::OTypeCollection collection(
175                 getCppuType(
176                     reinterpret_cast<uno::Reference< uno::XWeak>*>(0)),
177                 getCppuType(
178                     reinterpret_cast<
179                     uno::Reference< lang::XTypeProvider>*>(0)));
180             pCollection = &collection;
181         }
182     }
183     return (*pCollection).getTypes();
184 }
185 
186 uno::Sequence< sal_Int8 > SAL_CALL EmbedServer_Impl::getImplementationId()
187 {
188     static ::cppu::OImplementationId *pId = 0;
189     if( ! pId )
190     {
191         ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
192         if( ! pId )
193         {
194             static ::cppu::OImplementationId id( sal_False );
195             pId = &id;
196         }
197     }
198     return (*pId).getImplementationId();
199 }
200 
201 //===============================================================================
202 // EmbedProviderFactory_Impl
203 
204 EmbedProviderFactory_Impl::EmbedProviderFactory_Impl(const uno::Reference<lang::XMultiServiceFactory>& xFactory, const GUID* pGuid)
205     : m_refCount( 0L )
206     , m_xFactory( xFactory )
207     , m_guid( *pGuid )
208 {
209 }
210 
211 EmbedProviderFactory_Impl::~EmbedProviderFactory_Impl()
212 {
213 }
214 
215 sal_Bool EmbedProviderFactory_Impl::registerClass()
216 {
217     HRESULT hresult;
218 
219     o2u_attachCurrentThread();
220 
221     hresult = CoRegisterClassObject(
222             m_guid,
223             this,
224             CLSCTX_LOCAL_SERVER,
225             REGCLS_MULTIPLEUSE,
226             &m_factoryHandle);
227 
228     return (hresult == NOERROR);
229 }
230 
231 sal_Bool EmbedProviderFactory_Impl::deregisterClass()
232 {
233     HRESULT hresult = CoRevokeClassObject( m_factoryHandle );
234 
235     return (hresult == NOERROR);
236 }
237 
238 STDMETHODIMP EmbedProviderFactory_Impl::QueryInterface(REFIID riid, void FAR* FAR* ppv)
239 {
240     if(IsEqualIID(riid, IID_IUnknown))
241     {
242         AddRef();
243         *ppv = (IUnknown*) (IClassFactory*) this;
244         return NOERROR;
245     }
246     else if (IsEqualIID(riid, IID_IClassFactory))
247     {
248         AddRef();
249         *ppv = (IClassFactory*) this;
250         return NOERROR;
251     }
252 
253     *ppv = NULL;
254     return ResultFromScode(E_NOINTERFACE);
255 }
256 
257 STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::AddRef()
258 {
259     return osl_incrementInterlockedCount( &m_refCount);
260 }
261 
262 STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::Release()
263 {
264     ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex());
265     sal_Int32 nCount = --m_refCount;
266     if ( nCount == 0 )
267     {
268         delete this;
269     }
270 
271     return nCount;
272 }
273 
274 STDMETHODIMP EmbedProviderFactory_Impl::CreateInstance(IUnknown FAR* punkOuter,
275                                                        REFIID riid,
276                                                        void FAR* FAR* ppv)
277 {
278     punkOuter = NULL;
279 
280     IUnknown* pEmbedDocument = (IUnknown*)(IPersistStorage*)( new EmbedDocument_Impl( m_xFactory, &m_guid ) );
281 
282     return pEmbedDocument->QueryInterface( riid, ppv );
283 }
284 
285 STDMETHODIMP EmbedProviderFactory_Impl::LockServer( int /*fLock*/ )
286 {
287     return NOERROR;
288 }
289 
290 // Fix strange warnings about some
291 // ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
292 // warning C4505: 'xxx' : unreferenced local function has been removed
293 #if defined(_MSC_VER)
294 #pragma warning(disable: 4505)
295 #endif
296