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