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 const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW( () ) 57 { 58 static ::rtl::OUString s_aStaticOidPart = []() { 59 ::rtl::OUStringBuffer aRet( 64 ); 60 aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); 61 // good guid 62 sal_uInt8 ar[16]; 63 ::rtl_getGlobalProcessId(ar); 64 for ( sal_Int32 i = 0; i < 16; ++i ) 65 { 66 aRet.append( (sal_Int32)ar[i], 16 ); 67 } 68 return aRet.makeStringAndClear(); 69 }(); 70 return s_aStaticOidPart; 71 72 } 73 74 } 75 76 extern "C" { 77 78 static void s_stub_computeObjectIdentifier(va_list * pParam) 79 SAL_THROW( () ) 80 { 81 uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); 82 rtl_uString ** ppOId = va_arg(*pParam, rtl_uString **); 83 void * pInterface = va_arg(*pParam, void *); 84 85 86 OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" ); 87 if (pEnv && ppOId && pInterface) 88 { 89 if (*ppOId) 90 { 91 rtl_uString_release( *ppOId ); 92 *ppOId = 0; 93 } 94 95 try 96 { 97 ::com::sun::star::uno::Reference< 98 ::com::sun::star::uno::XInterface > xHome( 99 reinterpret_cast< ::com::sun::star::uno::XInterface * >( 100 pInterface ), 101 ::com::sun::star::uno::UNO_QUERY ); 102 OSL_ENSURE( xHome.is(), "### query to XInterface failed!" ); 103 if (xHome.is()) 104 { 105 // interface 106 ::rtl::OUStringBuffer oid( 64 ); 107 oid.append( reinterpret_cast< sal_Int64 >(xHome.get()), 16 ); 108 oid.append( (sal_Unicode)';' ); 109 // ;environment[context] 110 oid.append( 111 *reinterpret_cast< ::rtl::OUString const * >( 112 &((uno_Environment *) pEnv)->pTypeName ) ); 113 oid.append( (sal_Unicode)'[' ); 114 oid.append( 115 reinterpret_cast< sal_Int64 >( 116 ((uno_Environment *)pEnv)->pContext), 117 16 ); 118 // ];good guid 119 oid.append( cppu_cppenv_getStaticOIdPart() ); 120 ::rtl::OUString aRet( oid.makeStringAndClear() ); 121 ::rtl_uString_acquire( *ppOId = aRet.pData ); 122 } 123 } 124 catch (::com::sun::star::uno::RuntimeException &) 125 { 126 OSL_ENSURE( 127 0, "### RuntimeException occurred udring queryInterface()!" ); 128 } 129 } 130 } 131 132 static void SAL_CALL computeObjectIdentifier( 133 uno_ExtEnvironment * pExtEnv, rtl_uString ** ppOId, void * pInterface ) 134 SAL_THROW( () ) 135 { 136 uno_Environment_invoke(&pExtEnv->aBase, s_stub_computeObjectIdentifier, pExtEnv, ppOId, pInterface); 137 } 138 139 static void s_stub_acquireInterface(va_list * pParam) 140 SAL_THROW( () ) 141 { 142 /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *); 143 void * pCppI = va_arg(*pParam, void *); 144 145 reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire(); 146 } 147 148 static void SAL_CALL acquireInterface( uno_ExtEnvironment * pExtEnv, void * pCppI ) 149 SAL_THROW( () ) 150 { 151 uno_Environment_invoke(&pExtEnv->aBase, s_stub_acquireInterface, pExtEnv, pCppI); 152 } 153 154 static void s_stub_releaseInterface(va_list * pParam) 155 SAL_THROW( () ) 156 { 157 /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *); 158 void * pCppI = va_arg(*pParam, void *); 159 160 reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release(); 161 } 162 163 static void SAL_CALL releaseInterface( uno_ExtEnvironment * pExtEnv, void * pCppI ) 164 SAL_THROW( () ) 165 { 166 uno_Environment_invoke(&pExtEnv->aBase, s_stub_releaseInterface, pExtEnv, pCppI); 167 } 168 169 static void SAL_CALL environmentDisposing( uno_Environment * ) SAL_THROW( () ) 170 { 171 bridges::cpp_uno::shared::g_moduleCount.modCnt.release( 172 &bridges::cpp_uno::shared::g_moduleCount.modCnt ); 173 } 174 175 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_canUnload(TimeValue * pTime) SAL_THROW_EXTERN_C() { 176 return bridges::cpp_uno::shared::g_moduleCount.canUnload( 177 &bridges::cpp_uno::shared::g_moduleCount, pTime); 178 } 179 180 SAL_DLLPUBLIC_EXPORT void SAL_CALL uno_initEnvironment(uno_Environment * pCppEnv) 181 SAL_THROW_EXTERN_C() 182 { 183 OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" ); 184 OSL_ENSURE( 185 ::rtl_ustr_ascii_compare_WithLength( 186 pCppEnv->pTypeName->buffer, rtl_str_getLength(CPPU_CURRENT_LANGUAGE_BINDING_NAME), CPPU_CURRENT_LANGUAGE_BINDING_NAME ) 187 == 0, 188 "### wrong environment type!" ); 189 bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire( 190 &bridges::cpp_uno::shared::g_moduleCount.modCnt ); 191 ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier 192 = computeObjectIdentifier; 193 ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = acquireInterface; 194 ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = releaseInterface; 195 pCppEnv->environmentDisposing = environmentDisposing; 196 } 197 198 SAL_DLLPUBLIC_EXPORT void SAL_CALL uno_ext_getMapping( 199 uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo) 200 SAL_THROW_EXTERN_C() 201 { 202 OSL_ASSERT( ppMapping && pFrom && pTo ); 203 if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv) 204 { 205 uno_Mapping * pMapping = 0; 206 207 rtl::OUString from_envTypeName(cppu::EnvDcp::getTypeName(pFrom->pTypeName)); 208 rtl::OUString to_envTypeName(cppu::EnvDcp::getTypeName(pTo->pTypeName)); 209 210 if (0 == rtl_ustr_ascii_compare( 211 from_envTypeName.pData->buffer, 212 CPPU_CURRENT_LANGUAGE_BINDING_NAME ) && 213 0 == rtl_ustr_ascii_compare( 214 to_envTypeName.pData->buffer, UNO_LB_UNO )) 215 { 216 // ref count initially 1 217 pMapping = bridges::cpp_uno::shared::Bridge::createMapping( 218 pFrom->pExtEnv, pTo->pExtEnv, sal_True ); 219 ::uno_registerMapping( 220 &pMapping, bridges::cpp_uno::shared::freeMapping, 221 (uno_Environment *)pFrom->pExtEnv, 222 (uno_Environment *)pTo->pExtEnv, 0 ); 223 } 224 else if (0 == rtl_ustr_ascii_compare( 225 to_envTypeName.pData->buffer, 226 CPPU_CURRENT_LANGUAGE_BINDING_NAME ) && 227 0 == rtl_ustr_ascii_compare( 228 from_envTypeName.pData->buffer, UNO_LB_UNO )) 229 { 230 // ref count initially 1 231 pMapping = bridges::cpp_uno::shared::Bridge::createMapping( 232 pTo->pExtEnv, pFrom->pExtEnv, sal_False ); 233 ::uno_registerMapping( 234 &pMapping, bridges::cpp_uno::shared::freeMapping, 235 (uno_Environment *)pFrom->pExtEnv, 236 (uno_Environment *)pTo->pExtEnv, 0 ); 237 } 238 239 if (*ppMapping) 240 { 241 (*(*ppMapping)->release)( *ppMapping ); 242 } 243 if (pMapping) 244 *ppMapping = pMapping; 245 } 246 } 247 248 } 249