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 25 #include <osl/module.h> 26 #include <osl/diagnose.h> 27 #include <osl/file.h> 28 #include <osl/thread.h> 29 30 #include <stdlib.h> 31 #include <dlfcn.h> 32 33 #include "system.h" 34 35 /* implemented in file.cxx */ 36 int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32); 37 38 /*****************************************************************************/ 39 /* osl_loadModule */ 40 /*****************************************************************************/ 41 42 oslModule SAL_CALL osl_loadModule(rtl_uString *ustrModuleName, sal_Int32 nRtldMode) 43 { 44 oslModule pModule=0; 45 rtl_uString* ustrTmp = NULL; 46 47 OSL_ENSURE(ustrModuleName,"osl_loadModule : string is not valid"); 48 49 /* ensure ustrTmp hold valid string */ 50 if (osl_File_E_None != osl_getSystemPathFromFileURL(ustrModuleName, &ustrTmp)) 51 rtl_uString_assign(&ustrTmp, ustrModuleName); 52 53 if (ustrTmp) 54 { 55 char buffer[PATH_MAX]; 56 57 if (UnicodeToText(buffer, PATH_MAX, ustrTmp->buffer, ustrTmp->length)) 58 pModule = osl_loadAsciiModule(buffer, nRtldMode); 59 rtl_uString_release(ustrTmp); 60 } 61 62 return pModule; 63 } 64 65 /*****************************************************************************/ 66 /* osl_loadAsciiModule */ 67 /*****************************************************************************/ 68 69 oslModule SAL_CALL osl_loadAsciiModule(const sal_Char *pszModuleName, sal_Int32 nRtldMode) 70 { 71 char drive[_MAX_DRIVE], dir[_MAX_DIR]; 72 char fname[_MAX_FNAME], ext[_MAX_EXT]; 73 char buffer[PATH_MAX]; 74 char* dot; 75 void* hModule; 76 77 if (!pszModuleName) 78 return NULL; 79 80 // 21/02/2006 YD dll names must be 8.3: since .uno.dll files 81 // have hardcoded names, I'm truncating names here and also in 82 // the build system 83 _splitpath (pszModuleName, drive, dir, fname, ext); 84 if (strlen(fname)>8) 85 fname[8] = 0; // truncate to 8.3 86 dot = strchr( fname, '.'); 87 if (dot) 88 *dot = '\0'; // truncate on dot 89 90 // if drive is not specified, remove starting \ from dir name 91 // so dll is loaded from LIBPATH 92 if (drive[0] == 0 && dir[0] == '\\' && dir[1] == '\\') { 93 while( dir[0] == '\\') 94 strcpy( dir, dir+1); 95 } 96 _makepath( buffer, drive, dir, fname, ext); 97 98 #if OSL_DEBUG_LEVEL>1 99 debug_printf("osl_loadModule module %s", buffer); 100 #endif 101 102 hModule = dlopen( buffer, RTLD_LOCAL); 103 if (hModule != NULL) 104 return (oslModule)hModule; 105 106 // do not show in case rc=2 ENOENT, we must parse dlerror 107 // string to detect it 108 char* err = dlerror(); 109 if (!err) 110 return NULL; 111 112 if (strstr( err, "rc=2") != NULL) 113 return NULL; 114 115 sal_Char szError[ PATH_MAX*2 ]; 116 sprintf( szError, "Module: %s;\n error: %s;\n\n" 117 "Please contact technical support and report above informations.\n\n", 118 buffer, err); 119 #if OSL_DEBUG_LEVEL>0 120 debug_printf("osl_loadModule error %s", szError); 121 #endif 122 123 #if (OSL_DEBUG_LEVEL==0) || !defined(OSL_DEBUG_LEVEL) 124 WinMessageBox(HWND_DESKTOP,HWND_DESKTOP, 125 szError, "Critical error: DosLoadModule failed", 126 0, MB_ERROR | MB_OK | MB_MOVEABLE); 127 #endif 128 129 return NULL; 130 } 131 132 /*****************************************************************************/ 133 /* osl_getModuleHandle */ 134 /*****************************************************************************/ 135 136 sal_Bool SAL_CALL 137 osl_getModuleHandle(rtl_uString *pModuleName, oslModule *pResult) 138 { 139 HMODULE hmod; 140 APIRET rc; 141 142 OSL_ENSURE(pModuleName,"osl_loadModule : string is not valid"); 143 144 if (pModuleName) 145 { 146 char buffer[PATH_MAX]; 147 148 if (UnicodeToText(buffer, PATH_MAX, pModuleName->buffer, 149 pModuleName->length)) 150 { 151 rc = DosQueryModuleHandle(buffer, &hmod); 152 if( rc == NO_ERROR) 153 { 154 *pResult = (oslModule) hmod; 155 return sal_True; 156 } 157 } 158 } 159 160 return sal_False; 161 } 162 163 /*****************************************************************************/ 164 /* osl_unloadModule */ 165 /*****************************************************************************/ 166 void SAL_CALL osl_unloadModule(oslModule hModule) 167 { 168 if (hModule) 169 { 170 int nRet = dlclose(hModule); 171 #if OSL_DEBUG_LEVEL > 1 172 if (nRet != 0) 173 { 174 debug_printf( "osl_unloadModule failed with %s\n", dlerror()); 175 } 176 #else 177 (void) nRet; 178 #endif /* if OSL_DEBUG_LEVEL */ 179 } 180 } 181 182 /*****************************************************************************/ 183 /* osl_getSymbol */ 184 /*****************************************************************************/ 185 void* SAL_CALL 186 osl_getSymbol(oslModule Module, rtl_uString* pSymbolName) 187 { 188 return (void *) osl_getFunctionSymbol(Module, pSymbolName); 189 } 190 191 /*****************************************************************************/ 192 /* osl_getFunctionSymbol */ 193 /*****************************************************************************/ 194 oslGenericFunction SAL_CALL osl_getFunctionSymbol( oslModule Module, rtl_uString *strSymbolName ) 195 { 196 rtl_String *symbolName = NULL; 197 oslGenericFunction address; 198 199 OSL_ASSERT(Module); 200 OSL_ASSERT(strSymbolName); 201 202 rtl_uString2String( 203 &symbolName, 204 strSymbolName->buffer, 205 strSymbolName->length, 206 RTL_TEXTENCODING_UTF8, 207 OUSTRING_TO_OSTRING_CVTFLAGS 208 ); 209 210 address=osl_getAsciiFunctionSymbol(Module, rtl_string_getStr(symbolName)); 211 rtl_string_release(symbolName); 212 213 return address; 214 } 215 216 /*****************************************************************************/ 217 /* osl_getAsciiFunctionSymbol */ 218 /*****************************************************************************/ 219 oslGenericFunction SAL_CALL 220 osl_getAsciiFunctionSymbol( oslModule Module, const sal_Char *pSymbol ) 221 { 222 PFN pFunction; 223 APIRET rc; 224 void* pHandle=0; 225 226 OSL_ENSURE(Module,"osl_getSymbol : module handle is not valid"); 227 OSL_ENSURE(Module,"osl_getSymbol : ustrSymbolName"); 228 229 if ( Module!= 0 && pSymbol != 0 ) 230 { 231 232 rc = DosQueryProcAddr( (HMODULE) Module, 0, (PCSZ)pSymbol, &pFunction ); 233 if( rc == NO_ERROR ) 234 { 235 pHandle = (void*)pFunction; 236 } 237 else 238 { 239 // YD try again adding the '_' prefix 240 char _pszSymbolName[255]; 241 strcpy( _pszSymbolName, "_"); 242 strcat( _pszSymbolName, pSymbol); 243 rc = DosQueryProcAddr( (HMODULE) Module, 0, (PCSZ)_pszSymbolName, &pFunction ); 244 if( rc == NO_ERROR ) 245 pHandle = (void*)pFunction; 246 } 247 248 } 249 250 return pHandle; 251 } 252 253 /*****************************************************************************/ 254 /* osl_getModuleURLFromAddress */ 255 /*****************************************************************************/ 256 sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl) 257 { 258 //APIRET APIENTRY DosQueryModFromEIP (HMODULE *phMod, ULONG *pObjNum, 259 // ULONG BuffLen, PCHAR pBuff, ULONG *pOffset, ULONG Address) 260 HMODULE hMod; 261 ULONG ObjNum; 262 CHAR Buff[2*_MAX_PATH]; 263 ULONG Offset; 264 APIRET rc; 265 266 // get module handle (and name) 267 rc = DosQueryModFromEIP( &hMod, &ObjNum, sizeof( Buff), Buff, &Offset, (ULONG)addr); 268 if (rc) 269 return sal_False; 270 271 // get module full path 272 rc = DosQueryModuleName( hMod, sizeof( Buff), Buff); 273 if (rc) 274 return sal_False; 275 276 #if OSL_DEBUG_LEVEL > 1 277 OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s\n", Buff); 278 #endif 279 280 // convert to URL 281 rtl_uString *ustrSysPath = NULL; 282 rtl_string2UString( &ustrSysPath, Buff, strlen(Buff), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS ); 283 OSL_ASSERT(ustrSysPath != NULL); 284 osl_getFileURLFromSystemPath( ustrSysPath, ppLibraryUrl ); 285 rtl_uString_release( ustrSysPath ); 286 287 return sal_True; 288 } 289 290 /*****************************************************************************/ 291 /* osl_getModuleURLFromFunctionAddress */ 292 /*****************************************************************************/ 293 sal_Bool SAL_CALL osl_getModuleURLFromFunctionAddress( oslGenericFunction addr, rtl_uString ** ppLibraryUrl ) 294 { 295 return osl_getModuleURLFromAddress( ( void * )addr, ppLibraryUrl ); 296 } 297 298 /*****************************************************************************/ 299 300