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