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 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 156 void SAL_CALL EmbedServer_Impl::acquire( ) throw(uno::RuntimeException) 157 { 158 OWeakObject::acquire(); 159 } 160 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 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 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 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 217 EmbedProviderFactory_Impl::~EmbedProviderFactory_Impl() 218 { 219 } 220 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 237 sal_Bool EmbedProviderFactory_Impl::deregisterClass() 238 { 239 HRESULT hresult = CoRevokeClassObject( m_factoryHandle ); 240 241 return (hresult == NOERROR); 242 } 243 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 263 STDMETHODIMP_(ULONG) EmbedProviderFactory_Impl::AddRef() 264 { 265 return osl_incrementInterlockedCount( &m_refCount); 266 } 267 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 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 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