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