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 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_bridges.hxx" 26 27 #include "component.hxx" 28 29 #include "bridges/cpp_uno/shared/bridge.hxx" 30 31 #include "com/sun/star/uno/Reference.hxx" 32 #include "com/sun/star/uno/RuntimeException.hpp" 33 #include "com/sun/star/uno/XInterface.hpp" 34 #include "osl/diagnose.h" 35 #include "osl/mutex.hxx" 36 #include "osl/time.h" 37 #include "rtl/process.h" 38 #include "rtl/unload.h" 39 #include "rtl/ustrbuf.hxx" 40 #include "rtl/ustring.h" 41 #include "rtl/ustring.hxx" 42 #include "sal/types.h" 43 #include "uno/environment.h" 44 #include "uno/lbnames.h" 45 #include "uno/mapping.h" 46 #include "cppu/EnvDcp.hxx" 47 48 namespace bridges { namespace cpp_uno { namespace shared { 49 50 rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; 51 52 } } } 53 54 namespace { 55 56 #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \ 57 || (defined(__GNUC__) && defined(__APPLE__)) 58 static ::rtl::OUString * s_pStaticOidPart = 0; 59 #endif 60 61 const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW( () ) 62 { 63 #if ! ((defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \ 64 || (defined(__GNUC__) && defined(__APPLE__))) 65 static ::rtl::OUString * s_pStaticOidPart = 0; 66 #endif 67 if (! s_pStaticOidPart) 68 { 69 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 70 if (! s_pStaticOidPart) 71 { 72 ::rtl::OUStringBuffer aRet( 64 ); 73 aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); 74 // good guid 75 sal_uInt8 ar[16]; 76 ::rtl_getGlobalProcessId( ar ); 77 for ( sal_Int32 i = 0; i < 16; ++i ) 78 { 79 aRet.append( (sal_Int32)ar[i], 16 ); 80 } 81 #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \ 82 || (defined(__GNUC__) && defined(__APPLE__)) 83 s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() ); 84 #else 85 static ::rtl::OUString s_aStaticOidPart( 86 aRet.makeStringAndClear() ); 87 s_pStaticOidPart = &s_aStaticOidPart; 88 #endif 89 } 90 } 91 return *s_pStaticOidPart; 92 } 93 94 } 95 96 extern "C" { 97 98 static void s_stub_computeObjectIdentifier(va_list * pParam) 99 SAL_THROW( () ) 100 { 101 uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); 102 rtl_uString ** ppOId = va_arg(*pParam, rtl_uString **); 103 void * pInterface = va_arg(*pParam, void *); 104 105 106 OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" ); 107 if (pEnv && ppOId && pInterface) 108 { 109 if (*ppOId) 110 { 111 rtl_uString_release( *ppOId ); 112 *ppOId = 0; 113 } 114 115 try 116 { 117 ::com::sun::star::uno::Reference< 118 ::com::sun::star::uno::XInterface > xHome( 119 reinterpret_cast< ::com::sun::star::uno::XInterface * >( 120 pInterface ), 121 ::com::sun::star::uno::UNO_QUERY ); 122 OSL_ENSURE( xHome.is(), "### query to XInterface failed!" ); 123 if (xHome.is()) 124 { 125 // interface 126 ::rtl::OUStringBuffer oid( 64 ); 127 oid.append( reinterpret_cast< sal_Int64 >(xHome.get()), 16 ); 128 oid.append( (sal_Unicode)';' ); 129 // ;environment[context] 130 oid.append( 131 *reinterpret_cast< ::rtl::OUString const * >( 132 &((uno_Environment *) pEnv)->pTypeName ) ); 133 oid.append( (sal_Unicode)'[' ); 134 oid.append( 135 reinterpret_cast< sal_Int64 >( 136 ((uno_Environment *)pEnv)->pContext), 137 16 ); 138 // ];good guid 139 oid.append( cppu_cppenv_getStaticOIdPart() ); 140 ::rtl::OUString aRet( oid.makeStringAndClear() ); 141 ::rtl_uString_acquire( *ppOId = aRet.pData ); 142 } 143 } 144 catch (::com::sun::star::uno::RuntimeException &) 145 { 146 OSL_ENSURE( 147 0, "### RuntimeException occurred udring queryInterface()!" ); 148 } 149 } 150 } 151 152 static void SAL_CALL computeObjectIdentifier( 153 uno_ExtEnvironment * pExtEnv, rtl_uString ** ppOId, void * pInterface ) 154 SAL_THROW( () ) 155 { 156 uno_Environment_invoke(&pExtEnv->aBase, s_stub_computeObjectIdentifier, pExtEnv, ppOId, pInterface); 157 } 158 159 static void s_stub_acquireInterface(va_list * pParam) 160 SAL_THROW( () ) 161 { 162 /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *); 163 void * pCppI = va_arg(*pParam, void *); 164 165 reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire(); 166 } 167 168 static void SAL_CALL acquireInterface( uno_ExtEnvironment * pExtEnv, void * pCppI ) 169 SAL_THROW( () ) 170 { 171 uno_Environment_invoke(&pExtEnv->aBase, s_stub_acquireInterface, pExtEnv, pCppI); 172 } 173 174 static void s_stub_releaseInterface(va_list * pParam) 175 SAL_THROW( () ) 176 { 177 /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *); 178 void * pCppI = va_arg(*pParam, void *); 179 180 reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release(); 181 } 182 183 static void SAL_CALL releaseInterface( uno_ExtEnvironment * pExtEnv, void * pCppI ) 184 SAL_THROW( () ) 185 { 186 uno_Environment_invoke(&pExtEnv->aBase, s_stub_releaseInterface, pExtEnv, pCppI); 187 } 188 189 static void SAL_CALL environmentDisposing( uno_Environment * ) SAL_THROW( () ) 190 { 191 bridges::cpp_uno::shared::g_moduleCount.modCnt.release( 192 &bridges::cpp_uno::shared::g_moduleCount.modCnt ); 193 } 194 195 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload(TimeValue * pTime) SAL_THROW_EXTERN_C() { 196 return bridges::cpp_uno::shared::g_moduleCount.canUnload( 197 &bridges::cpp_uno::shared::g_moduleCount, pTime); 198 } 199 200 SAL_DLLPUBLIC_EXPORT void SAL_CALL uno_initEnvironment(uno_Environment * pCppEnv) 201 SAL_THROW_EXTERN_C() 202 { 203 OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" ); 204 OSL_ENSURE( 205 ::rtl_ustr_ascii_compare_WithLength( 206 pCppEnv->pTypeName->buffer, rtl_str_getLength(CPPU_CURRENT_LANGUAGE_BINDING_NAME), CPPU_CURRENT_LANGUAGE_BINDING_NAME ) 207 == 0, 208 "### wrong environment type!" ); 209 bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire( 210 &bridges::cpp_uno::shared::g_moduleCount.modCnt ); 211 ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier 212 = computeObjectIdentifier; 213 ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = acquireInterface; 214 ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = releaseInterface; 215 pCppEnv->environmentDisposing = environmentDisposing; 216 } 217 218 SAL_DLLPUBLIC_EXPORT void SAL_CALL uno_ext_getMapping( 219 uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo) 220 SAL_THROW_EXTERN_C() 221 { 222 OSL_ASSERT( ppMapping && pFrom && pTo ); 223 if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv) 224 { 225 uno_Mapping * pMapping = 0; 226 227 rtl::OUString from_envTypeName(cppu::EnvDcp::getTypeName(pFrom->pTypeName)); 228 rtl::OUString to_envTypeName(cppu::EnvDcp::getTypeName(pTo->pTypeName)); 229 230 if (0 == rtl_ustr_ascii_compare( 231 from_envTypeName.pData->buffer, 232 CPPU_CURRENT_LANGUAGE_BINDING_NAME ) && 233 0 == rtl_ustr_ascii_compare( 234 to_envTypeName.pData->buffer, UNO_LB_UNO )) 235 { 236 // ref count initially 1 237 pMapping = bridges::cpp_uno::shared::Bridge::createMapping( 238 pFrom->pExtEnv, pTo->pExtEnv, sal_True ); 239 ::uno_registerMapping( 240 &pMapping, bridges::cpp_uno::shared::freeMapping, 241 (uno_Environment *)pFrom->pExtEnv, 242 (uno_Environment *)pTo->pExtEnv, 0 ); 243 } 244 else if (0 == rtl_ustr_ascii_compare( 245 to_envTypeName.pData->buffer, 246 CPPU_CURRENT_LANGUAGE_BINDING_NAME ) && 247 0 == rtl_ustr_ascii_compare( 248 from_envTypeName.pData->buffer, UNO_LB_UNO )) 249 { 250 // ref count initially 1 251 pMapping = bridges::cpp_uno::shared::Bridge::createMapping( 252 pTo->pExtEnv, pFrom->pExtEnv, sal_False ); 253 ::uno_registerMapping( 254 &pMapping, bridges::cpp_uno::shared::freeMapping, 255 (uno_Environment *)pFrom->pExtEnv, 256 (uno_Environment *)pTo->pExtEnv, 0 ); 257 } 258 259 if (*ppMapping) 260 { 261 (*(*ppMapping)->release)( *ppMapping ); 262 } 263 if (pMapping) 264 *ppMapping = pMapping; 265 } 266 } 267 268 } 269