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