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