1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 29 #include "system.h" 30 31 #include <osl/module.h> 32 #include <osl/diagnose.h> 33 #include <osl/file.h> 34 #include <osl/thread.h> 35 36 #include <stdlib.h> 37 #include <dlfcn.h> 38 39 int UnicodeToText(char *, size_t, const sal_Unicode *, sal_Int32); 40 41 // static data for holding SAL dll module and full path 42 static HMODULE hModSal; 43 static char szSalDir[ _MAX_PATH]; 44 static char szSalDrive[ _MAX_PATH]; 45 46 /*****************************************************************************/ 47 /* osl_loadModule */ 48 /*****************************************************************************/ 49 50 ULONG APIENTRY _DosLoadModule (PSZ pszObject, ULONG uObjectLen, PCSZ pszModule, 51 PHMODULE phmod) 52 { 53 APIRET rc; 54 rc = DosLoadModule( pszObject, uObjectLen, pszModule, phmod); 55 // YD 22/05/06 issue again if first call fails (why?) 56 if (rc == ERROR_INVALID_PARAMETER) 57 rc = DosLoadModule( pszObject, uObjectLen, pszModule, phmod); 58 return rc; 59 } 60 61 oslModule SAL_CALL osl_loadModule(rtl_uString *ustrModuleName, sal_Int32 nRtldMode) 62 { 63 HMODULE hModule; 64 BYTE szErrorMessage[256]; 65 APIRET rc; 66 oslModule pModule=0; 67 rtl_uString* ustrTmp = NULL; 68 69 OSL_ENSURE(ustrModuleName,"osl_loadModule : string is not valid"); 70 71 /* ensure ustrTmp hold valid string */ 72 if( osl_File_E_None != osl_getSystemPathFromFileURL( ustrModuleName, &ustrTmp ) ) 73 rtl_uString_assign( &ustrTmp, ustrModuleName ); 74 75 if( ustrTmp ) 76 { 77 char buffer[PATH_MAX]; 78 79 if( UnicodeToText( buffer, PATH_MAX, ustrTmp->buffer, ustrTmp->length ) ) 80 { 81 char drive[_MAX_DRIVE], dir[_MAX_DIR]; 82 char fname[_MAX_FNAME], ext[_MAX_EXT]; 83 char* dot; 84 // 21/02/2006 YD dll names must be 8.3: since .uno.dll files 85 // have hardcoded names, I'm truncating names here and also in 86 // the build system 87 _splitpath (buffer, drive, dir, fname, ext); 88 if (strlen(fname)>8) 89 fname[8] = 0; // truncate to 8.3 90 dot = strchr( fname, '.'); 91 if (dot) 92 *dot = '\0'; // truncate on dot 93 // if drive is not specified, remove starting \ from dir name 94 // so dll is loaded from LIBPATH 95 if (drive[0] == 0 && dir[0] == '\\' && dir[1] == '\\') { 96 while( dir[0] == '\\') 97 strcpy( dir, dir+1); 98 } 99 _makepath( buffer, drive, dir, fname, ext); 100 101 #if OSL_DEBUG_LEVEL>0 102 debug_printf("osl_loadModule module %s", buffer); 103 #endif 104 //rc = _DosLoadModule( szErrorMessage, sizeof( szErrorMessage), (PCSZ)buffer, &hModule); 105 //if (rc == NO_ERROR ) 106 hModule = dlopen( buffer, RTLD_LOCAL); 107 if (hModule != NULL ) 108 pModule = (oslModule)hModule; 109 else 110 { 111 if (rc == NO_ERROR ) 112 pModule = (oslModule)hModule; 113 else 114 { 115 sal_Char szError[ PATH_MAX*2 ]; 116 sprintf( szError, "Module: %s; rc: %d;\nReason: %s;\n" 117 "Please contact technical support and report above informations.\n\n", 118 buffer, rc, szErrorMessage ); 119 #if OSL_DEBUG_LEVEL>0 120 fprintf( stderr, szError); 121 #endif 122 //OSL_TRACE(szError); 123 #ifndef 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 } 130 } 131 } 132 133 rtl_uString_release( ustrTmp ); 134 135 return pModule; 136 } 137 138 /*****************************************************************************/ 139 /* osl_getModuleHandle */ 140 /*****************************************************************************/ 141 142 sal_Bool SAL_CALL 143 osl_getModuleHandle(rtl_uString *pModuleName, oslModule *pResult) 144 { 145 HMODULE hmod; 146 APIRET rc; 147 rc = DosQueryModuleHandle(pModuleName->buffer, &hmod); 148 if( rc == NO_ERROR) 149 { 150 *pResult = (oslModule) hmod; 151 return sal_True; 152 } 153 154 return sal_False; 155 } 156 157 /*****************************************************************************/ 158 /* osl_unloadModule */ 159 /*****************************************************************************/ 160 void SAL_CALL osl_unloadModule(oslModule Module) 161 { 162 #if OSL_DEBUG_LEVEL>0 163 if (!Module) 164 fprintf( stderr, "osl_unloadModule NULL HANDLE.\n"); 165 #endif 166 167 DosFreeModule((HMODULE)Module); 168 } 169 170 /*****************************************************************************/ 171 /* osl_getSymbol */ 172 /*****************************************************************************/ 173 void* SAL_CALL 174 osl_getSymbol(oslModule Module, rtl_uString* pSymbolName) 175 { 176 return (void *) osl_getFunctionSymbol(Module, pSymbolName); 177 } 178 179 /*****************************************************************************/ 180 /* osl_getFunctionSymbol */ 181 /*****************************************************************************/ 182 oslGenericFunction SAL_CALL osl_getFunctionSymbol( oslModule Module, rtl_uString *strSymbolName ) 183 { 184 rtl_String *symbolName = NULL; 185 oslGenericFunction address; 186 187 OSL_ASSERT(Module); 188 OSL_ASSERT(strSymbolName); 189 190 rtl_uString2String( 191 &symbolName, 192 strSymbolName->buffer, 193 strSymbolName->length, 194 RTL_TEXTENCODING_UTF8, 195 OUSTRING_TO_OSTRING_CVTFLAGS 196 ); 197 198 address=osl_getAsciiFunctionSymbol(Module, rtl_string_getStr(symbolName)); 199 rtl_string_release(symbolName); 200 201 return address; 202 } 203 204 /*****************************************************************************/ 205 /* osl_getAsciiFunctionSymbol */ 206 /*****************************************************************************/ 207 oslGenericFunction SAL_CALL 208 osl_getAsciiFunctionSymbol( oslModule Module, const sal_Char *pSymbol ) 209 { 210 PFN pFunction; 211 APIRET rc; 212 void* pHandle=0; 213 214 OSL_ENSURE(Module,"osl_getSymbol : module handle is not valid"); 215 OSL_ENSURE(Module,"osl_getSymbol : ustrSymbolName"); 216 217 if ( Module!= 0 && pSymbol != 0 ) 218 { 219 220 rc = DosQueryProcAddr( (HMODULE) Module, 0, (PCSZ)pSymbol, &pFunction ); 221 if( rc == NO_ERROR ) 222 { 223 pHandle = (void*)pFunction; 224 } 225 else 226 { 227 // YD try again adding the '_' prefix 228 char _pszSymbolName[255]; 229 strcpy( _pszSymbolName, "_"); 230 strcat( _pszSymbolName, pSymbol); 231 rc = DosQueryProcAddr( (HMODULE) Module, 0, (PCSZ)_pszSymbolName, &pFunction ); 232 if( rc == NO_ERROR ) 233 pHandle = (void*)pFunction; 234 } 235 236 } 237 238 return pHandle; 239 } 240 241 /*****************************************************************************/ 242 /* osl_getModuleURLFromAddress */ 243 /*****************************************************************************/ 244 sal_Bool SAL_CALL osl_getModuleURLFromAddress(void * addr, rtl_uString ** ppLibraryUrl) 245 { 246 //APIRET APIENTRY DosQueryModFromEIP (HMODULE *phMod, ULONG *pObjNum, 247 // ULONG BuffLen, PCHAR pBuff, ULONG *pOffset, ULONG Address) 248 HMODULE hMod; 249 ULONG ObjNum; 250 CHAR Buff[2*_MAX_PATH]; 251 ULONG Offset; 252 APIRET rc; 253 254 // get module handle (and name) 255 rc = DosQueryModFromEIP( &hMod, &ObjNum, sizeof( Buff), Buff, &Offset, (ULONG)addr); 256 if (rc) 257 return sal_False; 258 259 // get module full path 260 rc = DosQueryModuleName( hMod, sizeof( Buff), Buff); 261 if (rc) 262 return sal_False; 263 264 #if OSL_DEBUG_LEVEL > 1 265 OSL_TRACE("module.c::osl_getModuleURLFromAddress - %s\n", Buff); 266 #endif 267 268 // convert to URL 269 rtl_uString *ustrSysPath = NULL; 270 rtl_string2UString( &ustrSysPath, Buff, strlen(Buff), osl_getThreadTextEncoding(), OSTRING_TO_OUSTRING_CVTFLAGS ); 271 OSL_ASSERT(ustrSysPath != NULL); 272 osl_getFileURLFromSystemPath( ustrSysPath, ppLibraryUrl ); 273 rtl_uString_release( ustrSysPath ); 274 275 return sal_True; 276 } 277 278 /*****************************************************************************/ 279 /* osl_getModuleURLFromFunctionAddress */ 280 /*****************************************************************************/ 281 sal_Bool SAL_CALL osl_getModuleURLFromFunctionAddress( oslGenericFunction addr, rtl_uString ** ppLibraryUrl ) 282 { 283 return osl_getModuleURLFromAddress( ( void * )addr, ppLibraryUrl ); 284 } 285 286 /*****************************************************************************/ 287 288