LCOV - code coverage report
Current view: top level - libreoffice/jvmfwk/plugins/sunmajor/pluginlib - sunjavaplugin.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 245 0.0 %
Date: 2012-12-27 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #ifdef WNT
      22             : # include <stdio.h>
      23             : # include <sys/stat.h>
      24             : # include <windows.h>
      25             : #endif
      26             : 
      27             : #ifdef ANDROID
      28             : # include <dlfcn.h>
      29             : #endif
      30             : 
      31             : #if OSL_DEBUG_LEVEL > 0
      32             : #include <stdio.h>
      33             : #endif
      34             : #include <string.h>
      35             : 
      36             : #include "boost/scoped_array.hpp"
      37             : #include "osl/diagnose.h"
      38             : #include "rtl/ustring.hxx"
      39             : #include "rtl/ustrbuf.hxx"
      40             : #include "osl/module.hxx"
      41             : #include "osl/mutex.hxx"
      42             : #include "osl/thread.hxx"
      43             : #include "osl/file.hxx"
      44             : #include "rtl/instance.hxx"
      45             : #include "osl/getglobalmutex.hxx"
      46             : #include <setjmp.h>
      47             : #include <signal.h>
      48             : #include <stack>
      49             : 
      50             : #include "jni.h"
      51             : #include "rtl/byteseq.hxx"
      52             : #include "jvmfwk/vendorplugin.h"
      53             : #include "util.hxx"
      54             : #include "sunversion.hxx"
      55             : #include "vendorlist.hxx"
      56             : #include "diagnostics.h"
      57             : 
      58             : #ifdef ANDROID
      59             : #include <osl/detail/android-bootstrap.h>
      60             : #endif
      61             : 
      62             : #if defined HAVE_VALGRIND_HEADERS
      63             : #include <valgrind/valgrind.h>
      64             : #else
      65             : #define RUNNING_ON_VALGRIND 0
      66             : #endif
      67             : 
      68             : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
      69             : #define SUN_MICRO "Sun Microsystems Inc."
      70             : 
      71             : using namespace osl;
      72             : using namespace std;
      73             : using namespace jfw_plugin;
      74             : 
      75             : using ::rtl::OUString;
      76             : using ::rtl::OUStringBuffer;
      77             : using ::rtl::OString;
      78             : 
      79             : namespace {
      80             : 
      81             : struct PluginMutex: public ::rtl::Static<osl::Mutex, PluginMutex> {};
      82             : 
      83             : #if defined UNX
      84           0 : OString getPluginJarPath(
      85             :     const OUString & sVendor,
      86             :     const OUString& sLocation,
      87             :     const OUString& sVersion)
      88             : {
      89           0 :     OString ret;
      90           0 :     OUString sName1(RTL_CONSTASCII_USTRINGPARAM("javaplugin.jar"));
      91           0 :     OUString sName2(RTL_CONSTASCII_USTRINGPARAM("plugin.jar"));
      92           0 :     OUString sPath;
      93           0 :     if ( sVendor == SUN_MICRO )
      94             :     {
      95           0 :         SunVersion ver142("1.4.2-ea");
      96           0 :         SunVersion ver150("1.5.0-ea");
      97           0 :         SunVersion ver(sVersion);
      98             :         OSL_ASSERT(ver142 && ver150 && ver);
      99             : 
     100           0 :         OUString sName;
     101           0 :         if (ver < ver142)
     102             :         {
     103           0 :             sName = sName1;
     104             :         }
     105           0 :         else if (ver < ver150)
     106             :         {//this will cause ea, beta etc. to have plugin.jar in path.
     107             :             //but this does not harm. 1.5.0-beta < 1.5.0
     108           0 :             sName = sName2;
     109             :         }
     110           0 :         if (!sName.isEmpty())
     111             :         {
     112           0 :             sName = sLocation + OUSTR("/lib/") + sName;
     113           0 :             OSL_VERIFY(
     114             :                 osl_getSystemPathFromFileURL(sName.pData, & sPath.pData)
     115             :                 == osl_File_E_None);
     116           0 :         }
     117             :     }
     118             :     else
     119             :     {
     120           0 :         char sep[] =  {SAL_PATHSEPARATOR, 0};
     121           0 :         OUString sName(sLocation + OUSTR("/lib/") + sName1);
     122           0 :         OUString sPath1;
     123           0 :         OUString sPath2;
     124           0 :         if (osl_getSystemPathFromFileURL(sName.pData, & sPath1.pData)
     125             :             == osl_File_E_None)
     126             :         {
     127           0 :             sName = sLocation + OUSTR("/lib/") + sName2;
     128           0 :             if (osl_getSystemPathFromFileURL(sName.pData, & sPath2.pData)
     129             :                 == osl_File_E_None)
     130             :             {
     131           0 :                 sPath = sPath1 + OUString::createFromAscii(sep) + sPath2;
     132             :             }
     133             :         }
     134           0 :         OSL_ASSERT(!sPath.isEmpty());
     135             :     }
     136           0 :     ret = rtl::OUStringToOString(sPath, osl_getThreadTextEncoding());
     137             : 
     138           0 :     return ret;
     139             : }
     140             : #endif // UNX
     141             : 
     142             : 
     143           0 : JavaInfo* createJavaInfo(const rtl::Reference<VendorBase> & info)
     144             : {
     145           0 :     JavaInfo* pInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo));
     146           0 :     if (pInfo == NULL)
     147           0 :         return NULL;
     148           0 :     rtl::OUString sVendor = info->getVendor();
     149           0 :     pInfo->sVendor = sVendor.pData;
     150           0 :     rtl_uString_acquire(sVendor.pData);
     151           0 :     rtl::OUString sHome = info->getHome();
     152           0 :     pInfo->sLocation = sHome.pData;
     153           0 :     rtl_uString_acquire(pInfo->sLocation);
     154           0 :     rtl::OUString sVersion = info->getVersion();
     155           0 :     pInfo->sVersion = sVersion.pData;
     156           0 :     rtl_uString_acquire(pInfo->sVersion);
     157           0 :     pInfo->nFeatures = info->supportsAccessibility() ? 1 : 0;
     158           0 :     pInfo->nRequirements = info->needsRestart() ? JFW_REQUIRE_NEEDRESTART : 0;
     159           0 :     rtl::OUStringBuffer buf(1024);
     160           0 :     buf.append(info->getRuntimeLibrary());
     161           0 :     if (!info->getLibraryPaths().isEmpty())
     162             :     {
     163           0 :         buf.appendAscii("\n");
     164           0 :         buf.append(info->getLibraryPaths());
     165           0 :         buf.appendAscii("\n");
     166             :     }
     167             : 
     168           0 :     rtl::OUString sVendorData = buf.makeStringAndClear();
     169             :     rtl::ByteSequence byteSeq( (sal_Int8*) sVendorData.pData->buffer,
     170           0 :                                sVendorData.getLength() * sizeof(sal_Unicode));
     171           0 :     pInfo->arVendorData = byteSeq.get();
     172           0 :     rtl_byte_sequence_acquire(pInfo->arVendorData);
     173             : 
     174           0 :     return pInfo;
     175             : }
     176             : 
     177           0 : rtl::OUString getRuntimeLib(const rtl::ByteSequence & data)
     178             : {
     179           0 :     const sal_Unicode* chars = (sal_Unicode*) data.getConstArray();
     180           0 :     sal_Int32 len = data.getLength();
     181           0 :     rtl::OUString sData(chars, len / 2);
     182             :     //the runtime lib is on the first line
     183           0 :     sal_Int32 index = 0;
     184           0 :     rtl::OUString aToken = sData.getToken( 0, '\n', index);
     185             : 
     186           0 :     return aToken;
     187             : }
     188             : 
     189             : jmp_buf jmp_jvm_abort;
     190             : sig_atomic_t g_bInGetJavaVM = 0;
     191             : 
     192           0 : extern "C" void JNICALL abort_handler()
     193             : {
     194             :     // If we are within JNI_CreateJavaVM then we jump back into getJavaVM
     195           0 :     if( g_bInGetJavaVM != 0 )
     196             :     {
     197           0 :         fprintf( stderr, "JavaVM: JNI_CreateJavaVM called _exit, caught by abort_handler in javavm.cxx\n");
     198           0 :         longjmp( jmp_jvm_abort, 0);
     199             :     }
     200           0 : }
     201             : 
     202             : }
     203             : 
     204             : extern "C"
     205           0 : javaPluginError jfw_plugin_getAllJavaInfos(
     206             :     rtl_uString *sVendor,
     207             :     rtl_uString *sMinVersion,
     208             :     rtl_uString *sMaxVersion,
     209             :     rtl_uString  * *arExcludeList,
     210             :     sal_Int32  nLenList,
     211             :     JavaInfo*** parJavaInfo,
     212             :     sal_Int32 *nLenInfoList)
     213             : {
     214             :     OSL_ASSERT(sVendor);
     215             :     OSL_ASSERT(sMinVersion);
     216             :     OSL_ASSERT(sMaxVersion);
     217             :     OSL_ASSERT(parJavaInfo);
     218             :     OSL_ASSERT(parJavaInfo);
     219             :     OSL_ASSERT(nLenInfoList);
     220           0 :     if (!sVendor || !sMinVersion || !sMaxVersion || !parJavaInfo || !nLenInfoList)
     221           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     222             : 
     223             :     //nLenlist contains the number of element in arExcludeList.
     224             :     //If no exclude list is provided then nLenList must be 0
     225             :     OSL_ASSERT( ! (arExcludeList == NULL && nLenList > 0));
     226           0 :     if (arExcludeList == NULL && nLenList > 0)
     227           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     228             : 
     229           0 :     OUString ouVendor(sVendor);
     230           0 :     OUString ouMinVer(sMinVersion);
     231           0 :     OUString ouMaxVer(sMaxVersion);
     232             : 
     233             :     OSL_ASSERT(!ouVendor.isEmpty());
     234           0 :     if (ouVendor.isEmpty())
     235           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     236             : 
     237           0 :     JavaInfo** arInfo = NULL;
     238             : 
     239             :     //Find all JREs
     240             :     vector<rtl::Reference<VendorBase> > vecInfos =
     241           0 :         getAllJREInfos();
     242           0 :     vector<rtl::Reference<VendorBase> > vecVerifiedInfos;
     243             : 
     244             :     typedef vector<rtl::Reference<VendorBase> >::iterator it;
     245           0 :     for (it i= vecInfos.begin(); i != vecInfos.end(); ++i)
     246             :     {
     247           0 :         const rtl::Reference<VendorBase>& cur = *i;
     248             : 
     249           0 :         if (ouVendor.equals(cur->getVendor()) == sal_False)
     250           0 :             continue;
     251             : 
     252           0 :         if (!ouMinVer.isEmpty())
     253             :         {
     254             :             try
     255             :             {
     256           0 :                 if (cur->compareVersions(sMinVersion) == -1)
     257           0 :                     continue;
     258             :             }
     259           0 :             catch (MalformedVersionException&)
     260             :             {
     261             :                 //The minVersion was not recognized as valid for this vendor.
     262             :                 JFW_ENSURE(
     263             :                     0,OUSTR("[Java framework]sunjavaplugin does not know version: ")
     264             :                     + ouMinVer + OUSTR(" for vendor: ") + cur->getVendor()
     265             :                     + OUSTR(" .Check minimum Version.") );
     266           0 :                 return JFW_PLUGIN_E_WRONG_VERSION_FORMAT;
     267             :             }
     268             :         }
     269             : 
     270           0 :         if (!ouMaxVer.isEmpty())
     271             :         {
     272             :             try
     273             :             {
     274           0 :                 if (cur->compareVersions(sMaxVersion) == 1)
     275           0 :                     continue;
     276             :             }
     277           0 :             catch (MalformedVersionException&)
     278             :             {
     279             :                 //The maxVersion was not recognized as valid for this vendor.
     280             :                 JFW_ENSURE(
     281             :                     0,OUSTR("[Java framework]sunjavaplugin does not know version: ")
     282             :                     + ouMaxVer + OUSTR(" for vendor: ") + cur->getVendor()
     283             :                     + OUSTR(" .Check maximum Version.") );
     284           0 :                 return JFW_PLUGIN_E_WRONG_VERSION_FORMAT;
     285             :             }
     286             :         }
     287             : 
     288           0 :         bool bExclude = false;
     289           0 :         for (int j = 0; j < nLenList; j++)
     290             :         {
     291           0 :             rtl::OUString sExVer(arExcludeList[j]);
     292             :             try
     293             :             {
     294           0 :                 if (cur->compareVersions(sExVer) == 0)
     295             :                 {
     296           0 :                     bExclude = true;
     297             :                     break;
     298             :                 }
     299             :             }
     300           0 :             catch (MalformedVersionException&)
     301             :             {
     302             :                 //The excluded version was not recognized as valid for this vendor.
     303             :                 JFW_ENSURE(
     304             :                     0,OUSTR("[Java framework]sunjavaplugin does not know version: ")
     305             :                     + sExVer + OUSTR(" for vendor: ") + cur->getVendor()
     306             :                     + OUSTR(" .Check excluded versions.") );
     307           0 :                 return JFW_PLUGIN_E_WRONG_VERSION_FORMAT;
     308             :             }
     309           0 :         }
     310           0 :         if (bExclude == true)
     311           0 :             continue;
     312             : 
     313           0 :         vecVerifiedInfos.push_back(*i);
     314             :     }
     315             :     //Now vecVerifiedInfos contains all those JREs which meet the version requirements
     316             :     //Transfer them into the array that is passed out.
     317           0 :     arInfo = (JavaInfo**) rtl_allocateMemory(vecVerifiedInfos.size() * sizeof (JavaInfo*));
     318           0 :     int j = 0;
     319             :     typedef vector<rtl::Reference<VendorBase> >::const_iterator cit;
     320           0 :     for (cit ii = vecVerifiedInfos.begin(); ii != vecVerifiedInfos.end(); ++ii, ++j)
     321             :     {
     322           0 :         arInfo[j] = createJavaInfo(*ii);
     323             :     }
     324           0 :     *nLenInfoList = vecVerifiedInfos.size();
     325             : 
     326             : 
     327           0 :     *parJavaInfo = arInfo;
     328           0 :     return JFW_PLUGIN_E_NONE;
     329             : }
     330             : 
     331             : extern "C"
     332           0 : javaPluginError jfw_plugin_getJavaInfoByPath(
     333             :     rtl_uString *path,
     334             :     rtl_uString *sVendor,
     335             :     rtl_uString *sMinVersion,
     336             :     rtl_uString *sMaxVersion,
     337             :     rtl_uString  *  *arExcludeList,
     338             :     sal_Int32  nLenList,
     339             :     JavaInfo ** ppInfo)
     340             : {
     341           0 :     javaPluginError errorcode = JFW_PLUGIN_E_NONE;
     342             : 
     343             :     OSL_ASSERT(path);
     344             :     OSL_ASSERT(sVendor);
     345             :     OSL_ASSERT(sMinVersion);
     346             :     OSL_ASSERT(sMaxVersion);
     347           0 :     if (!path || !sVendor || !sMinVersion || !sMaxVersion || !ppInfo)
     348           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     349           0 :     OUString ouPath(path);
     350             :     OSL_ASSERT(!ouPath.isEmpty());
     351           0 :     if (ouPath.isEmpty())
     352           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     353             : 
     354             :     //nLenlist contains the number of element in arExcludeList.
     355             :     //If no exclude list is provided then nLenList must be 0
     356             :     OSL_ASSERT( ! (arExcludeList == NULL && nLenList > 0));
     357           0 :     if (arExcludeList == NULL && nLenList > 0)
     358           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     359             : 
     360           0 :     OUString ouVendor(sVendor);
     361           0 :     OUString ouMinVer(sMinVersion);
     362           0 :     OUString ouMaxVer(sMaxVersion);
     363             : 
     364             :     OSL_ASSERT(!ouVendor.isEmpty());
     365           0 :     if (ouVendor.isEmpty())
     366           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     367             : 
     368           0 :     rtl::Reference<VendorBase> aVendorInfo = getJREInfoByPath(ouPath);
     369           0 :     if (aVendorInfo.is() == sal_False)
     370           0 :         return JFW_PLUGIN_E_NO_JRE;
     371             : 
     372             :     //Check if the detected JRE matches the version requirements
     373           0 :     if (ouVendor.equals(aVendorInfo->getVendor()) == sal_False)
     374           0 :         return JFW_PLUGIN_E_NO_JRE;
     375             : 
     376           0 :     if (!ouMinVer.isEmpty())
     377             :     {
     378           0 :         int nRes = 0;
     379             :         try
     380             :         {
     381           0 :             nRes = aVendorInfo->compareVersions(ouMinVer);
     382             :         }
     383           0 :         catch (MalformedVersionException&)
     384             :         {
     385             :             //The minVersion was not recognized as valid for this vendor.
     386             :             JFW_ENSURE(
     387             :                 0,OUSTR("[Java framework]sunjavaplugin does not know version: ")
     388             :                 + ouMinVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor()
     389             :                 + OUSTR(" .Check minimum Version.") );
     390           0 :             return JFW_PLUGIN_E_WRONG_VERSION_FORMAT;
     391             :         }
     392           0 :         if (nRes < 0)
     393           0 :             return JFW_PLUGIN_E_FAILED_VERSION;
     394             :     }
     395             : 
     396           0 :     if (!ouMaxVer.isEmpty())
     397             :     {
     398           0 :         int nRes = 0;
     399             :         try
     400             :         {
     401           0 :             nRes = aVendorInfo->compareVersions(ouMaxVer);
     402             :         }
     403           0 :         catch (MalformedVersionException&)
     404             :         {
     405             :             //The maxVersion was not recognized as valid for this vendor.
     406             :             JFW_ENSURE(
     407             :                 0,OUSTR("[Java framework]sunjavaplugin does not know version: ")
     408             :                 + ouMaxVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor()
     409             :                 + OUSTR(" .Check maximum Version.") );
     410           0 :             return JFW_PLUGIN_E_WRONG_VERSION_FORMAT;
     411             :         }
     412           0 :         if (nRes > 0)
     413           0 :             return JFW_PLUGIN_E_FAILED_VERSION;
     414             :     }
     415             : 
     416           0 :     for (int i = 0; i < nLenList; i++)
     417             :     {
     418           0 :         rtl::OUString sExVer(arExcludeList[i]);
     419           0 :         int nRes = 0;
     420             :         try
     421             :         {
     422           0 :             nRes = aVendorInfo->compareVersions(sExVer);
     423             :         }
     424           0 :         catch (MalformedVersionException&)
     425             :         {
     426             :             //The excluded version was not recognized as valid for this vendor.
     427             :             JFW_ENSURE(
     428             :                 0,OUSTR("[Java framework]sunjavaplugin does not know version: ")
     429             :                 + sExVer + OUSTR(" for vendor: ") + aVendorInfo->getVendor()
     430             :                 + OUSTR(" .Check excluded versions.") );
     431           0 :             return JFW_PLUGIN_E_WRONG_VERSION_FORMAT;
     432             :         }
     433           0 :         if (nRes == 0)
     434           0 :             return JFW_PLUGIN_E_FAILED_VERSION;
     435           0 :     }
     436           0 :     *ppInfo = createJavaInfo(aVendorInfo);
     437             : 
     438           0 :     return errorcode;
     439             : }
     440             : 
     441             : #if defined(WNT)
     442             : 
     443             : // Load msvcr71.dll using an explicit full path from where it is
     444             : // present as bundled with the JRE. In case it is not found where we
     445             : // think it should be, do nothing, and just let the implicit loading
     446             : // that happens when loading the JVM take care of it.
     447             : 
     448             : static void load_msvcr71(LPCWSTR jvm_dll)
     449             : {
     450             :     wchar_t msvcr71_dll[MAX_PATH];
     451             :     wchar_t *slash;
     452             : 
     453             :     if (wcslen(jvm_dll) > MAX_PATH - 15)
     454             :         return;
     455             : 
     456             :     wcscpy(msvcr71_dll, jvm_dll);
     457             : 
     458             :     // First check if msvcr71.dll is in the same folder as jvm.dll. It
     459             :     // normally isn't, at least up to 1.6.0_22, but who knows if it
     460             :     // might be in the future.
     461             :     slash = wcsrchr(msvcr71_dll, L'\\');
     462             : 
     463             :     if (!slash)
     464             :     {
     465             :         // Huh, weird path to jvm.dll. Oh well.
     466             :         return;
     467             :     }
     468             : 
     469             :     wcscpy(slash+1, L"msvcr71.dll");
     470             :     if (LoadLibraryW(msvcr71_dll))
     471             :         return;
     472             : 
     473             :     // Then check if msvcr71.dll is in the parent folder of where
     474             :     // jvm.dll is. That is currently (1.6.0_22) as far as I know the
     475             :     // normal case.
     476             :     *slash = 0;
     477             :     slash = wcsrchr(msvcr71_dll, L'\\');
     478             : 
     479             :     if (!slash)
     480             :         return;
     481             : 
     482             :     wcscpy(slash+1, L"msvcr71.dll");
     483             :     LoadLibraryW(msvcr71_dll);
     484             : }
     485             : 
     486             : // Check if the jvm DLL imports msvcr71.dll, and in that case try
     487             : // loading it explicitly. In case something goes wrong, do nothing,
     488             : // and just let the implicit loading try to take care of it.
     489             : static void do_msvcr71_magic(rtl_uString *jvm_dll)
     490             : {
     491             :     FILE *f;
     492             :     rtl_uString* Module;
     493             :     oslFileError nError;
     494             :     struct stat st;
     495             :     PIMAGE_DOS_HEADER dos_hdr;
     496             :     IMAGE_NT_HEADERS *nt_hdr;
     497             :     IMAGE_IMPORT_DESCRIPTOR *imports;
     498             : 
     499             :     nError = osl_getSystemPathFromFileURL(jvm_dll, &Module);
     500             : 
     501             :     if ( osl_File_E_None != nError )
     502             :         rtl_uString_assign(&Module, jvm_dll);
     503             : 
     504             :     f = _wfopen(reinterpret_cast<LPCWSTR>(Module->buffer), L"rb");
     505             : 
     506             :     if (fstat(fileno(f), &st) == -1)
     507             :     {
     508             :         fclose(f);
     509             :         return;
     510             :     }
     511             : 
     512             :     dos_hdr = (PIMAGE_DOS_HEADER) malloc(st.st_size);
     513             : 
     514             :     if (fread(dos_hdr, st.st_size, 1, f) != 1 ||
     515             :         memcmp(dos_hdr, "MZ", 2) != 0 ||
     516             :         dos_hdr->e_lfanew < 0 ||
     517             :         dos_hdr->e_lfanew > (LONG) (st.st_size - sizeof(IMAGE_NT_HEADERS)))
     518             :     {
     519             :         free(dos_hdr);
     520             :         fclose(f);
     521             :         return;
     522             :     }
     523             : 
     524             :     fclose(f);
     525             : 
     526             :     nt_hdr = (IMAGE_NT_HEADERS *) ((char *)dos_hdr + dos_hdr->e_lfanew);
     527             : 
     528             :     imports = (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + nt_hdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
     529             : 
     530             :     while (imports <= (IMAGE_IMPORT_DESCRIPTOR *) ((char *) dos_hdr + st.st_size - sizeof (IMAGE_IMPORT_DESCRIPTOR)) &&
     531             :            imports->Name != 0 &&
     532             :            imports->Name < (DWORD) st.st_size)
     533             :     {
     534             :         // Intentional use of sizeof("msvcr71.dll") here to include the terminating zero byte
     535             :         if (strnicmp((char *) dos_hdr + imports->Name, "msvcr71.dll", sizeof("msvcr71.dll")) == 0)
     536             :         {
     537             :             load_msvcr71(reinterpret_cast<LPCWSTR>(Module->buffer));
     538             :             break;
     539             :         }
     540             :         imports++;
     541             :     }
     542             : 
     543             :     free(dos_hdr);
     544             : }
     545             : 
     546             : #endif
     547             : 
     548             : /** starts a Java Virtual Machine.
     549             :     <p>
     550             :     The function shall ensure, that the VM does not abort the process
     551             :     during instantiation.
     552             :     </p>
     553             :  */
     554             : extern "C"
     555           0 : javaPluginError jfw_plugin_startJavaVirtualMachine(
     556             :     const JavaInfo *pInfo,
     557             :     const JavaVMOption* arOptions,
     558             :     sal_Int32 cOptions,
     559             :     JavaVM ** ppVm,
     560             :     JNIEnv ** ppEnv)
     561             : {
     562             :     // unless guard is volatile the following warning occurs on gcc:
     563             :     // warning: variable 't' might be clobbered by `longjmp' or `vfork'
     564           0 :     volatile osl::MutexGuard guard(PluginMutex::get());
     565             :     // unless errorcode is volatile the following warning occurs on gcc:
     566             :     // warning: variable 'errorcode' might be clobbered by `longjmp' or `vfork'
     567           0 :     volatile javaPluginError errorcode = JFW_PLUGIN_E_NONE;
     568           0 :     if ( pInfo == NULL || ppVm == NULL || ppEnv == NULL)
     569           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     570             :     //Check if the Vendor (pInfo->sVendor) is supported by this plugin
     571           0 :     if ( ! isVendorSupported(pInfo->sVendor))
     572           0 :         return JFW_PLUGIN_E_WRONG_VENDOR;
     573           0 :     rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData);
     574             :     JFW_TRACE2(OUSTR("[Java framework] Using Java runtime library: ")
     575             :               + sRuntimeLib + OUSTR(".\n"));
     576             : 
     577             : #ifndef ANDROID
     578             :     // On linux we load jvm with RTLD_GLOBAL. This is necessary for debugging, because
     579             :     // libjdwp.so need a symbol (fork1) from libjvm which it only gets if the jvm is loaded
     580             :     // witd RTLD_GLOBAL. On Solaris libjdwp.so is correctly linked with libjvm.so
     581           0 :     oslModule moduleRt = 0;
     582             : #if defined(LINUX)
     583           0 :     if ((moduleRt = osl_loadModule(sRuntimeLib.pData,
     584           0 :                                    SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_NOW)) == 0 )
     585             : #else
     586             : #if defined(WNT)
     587             :     do_msvcr71_magic(sRuntimeLib.pData);
     588             : #endif
     589             :     if ((moduleRt = osl_loadModule(sRuntimeLib.pData, SAL_LOADMODULE_DEFAULT)) == 0)
     590             : #endif
     591             :      {
     592             :          JFW_ENSURE(0, OUSTR("[Java framework]sunjavaplugin" SAL_DLLEXTENSION
     593             :                              " could not load Java runtime library: \n")
     594             :                     + sRuntimeLib + OUSTR("\n"));
     595             :          JFW_TRACE0(OUSTR("[Java framework]sunjavaplugin" SAL_DLLEXTENSION
     596             :                              " could not load Java runtime library: \n")
     597             :                     + sRuntimeLib +  OUSTR("\n"));
     598           0 :          return JFW_PLUGIN_E_VM_CREATION_FAILED;
     599             :      }
     600             : 
     601             : #ifdef UNX
     602             :     //Setting the JAVA_HOME is needed for awt
     603           0 :     rtl::OUString javaHome(RTL_CONSTASCII_USTRINGPARAM("JAVA_HOME="));
     604           0 :     rtl::OUString sPathLocation;
     605           0 :     osl_getSystemPathFromFileURL(pInfo->sLocation, & sPathLocation.pData);
     606           0 :     javaHome += sPathLocation;
     607             :     rtl::OString osJavaHome = rtl::OUStringToOString(
     608           0 :         javaHome, osl_getThreadTextEncoding());
     609           0 :     putenv(strdup(osJavaHome.getStr()));
     610             : #endif
     611             : 
     612             :     typedef jint JNICALL JNI_InitArgs_Type(void *);
     613             :     typedef jint JNICALL JNI_CreateVM_Type(JavaVM **, JNIEnv **, void *);
     614             :     rtl::OUString sSymbolCreateJava(
     615           0 :             RTL_CONSTASCII_USTRINGPARAM("JNI_CreateJavaVM"));
     616             : 
     617             :     JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *) osl_getFunctionSymbol(
     618           0 :         moduleRt, sSymbolCreateJava.pData);
     619           0 :     if (!pCreateJavaVM)
     620             :     {
     621             :         OSL_ASSERT(0);
     622             :         rtl::OString sLib = rtl::OUStringToOString(
     623           0 :             sRuntimeLib, osl_getThreadTextEncoding());
     624             :         rtl::OString sSymbol = rtl::OUStringToOString(
     625           0 :             sSymbolCreateJava, osl_getThreadTextEncoding());
     626             :         fprintf(stderr,"[Java framework]sunjavaplugin" SAL_DLLEXTENSION
     627             :                 "Java runtime library: %s does not export symbol %s !\n",
     628           0 :                 sLib.getStr(), sSymbol.getStr());
     629           0 :         return JFW_PLUGIN_E_VM_CREATION_FAILED;
     630             :     }
     631             : 
     632             :     // Valgrind typically emits many false errors when executing JIT'ed JVM
     633             :     // code, so force the JVM into interpreted mode:
     634           0 :     bool forceInterpreted = RUNNING_ON_VALGRIND > 0;
     635             : 
     636             :     // Some testing with Java 1.4 showed that JavaVMOption.optionString has to
     637             :     // be encoded with the system encoding (i.e., osl_getThreadTextEncoding):
     638             :     JavaVMInitArgs vm_args;
     639             : 
     640           0 :     sal_Int32 nOptions = 1 + cOptions + (forceInterpreted ? 1 : 0);
     641             :         //TODO: check for overflow
     642           0 :     boost::scoped_array<JavaVMOption> sarOptions(new JavaVMOption[nOptions]);
     643           0 :     JavaVMOption * options = sarOptions.get();
     644             : 
     645             :     // We set an abort handler which is called when the VM calls _exit during
     646             :     // JNI_CreateJavaVM. This happens when the LD_LIBRARY_PATH does not contain
     647             :     // all some directories of the Java installation. This is necessary for
     648             :     // all versions below 1.5.1
     649           0 :     int n = 0;
     650           0 :     options[n].optionString= (char *) "abort";
     651           0 :     options[n].extraInfo= (void* )(sal_IntPtr)abort_handler;
     652           0 :     ++n;
     653           0 :     rtl::OString sClassPathProp("-Djava.class.path=");
     654           0 :     rtl::OString sClassPathOption;
     655           0 :     for (int i = 0; i < cOptions; i++)
     656             :     {
     657             : #ifdef UNX
     658             :     // Until java 1.5 we need to put a plugin.jar or javaplugin.jar (<1.4.2)
     659             :     // in the class path in order to have applet support.
     660           0 :         rtl::OString sClassPath = arOptions[i].optionString;
     661           0 :         if (sClassPath.match(sClassPathProp, 0) == sal_True)
     662             :         {
     663           0 :             char sep[] =  {SAL_PATHSEPARATOR, 0};
     664           0 :             OString sAddPath = getPluginJarPath(pInfo->sVendor, pInfo->sLocation,pInfo->sVersion);
     665           0 :             if (!sAddPath.isEmpty())
     666           0 :                 sClassPathOption = sClassPath + rtl::OString(sep) + sAddPath;
     667             :             else
     668           0 :                 sClassPathOption = sClassPath;
     669           0 :             options[n].optionString = (char *) sClassPathOption.getStr();
     670           0 :             options[n].extraInfo = arOptions[i].extraInfo;
     671             :         }
     672             :         else
     673             :         {
     674             : #endif
     675           0 :             options[n].optionString = arOptions[i].optionString;
     676           0 :             options[n].extraInfo = arOptions[i].extraInfo;
     677             : #ifdef UNX
     678             :         }
     679             : #endif
     680             : #if OSL_DEBUG_LEVEL >= 2
     681             :         JFW_TRACE2("VM option: " << options[n].optionString << "\n");
     682             : #endif
     683           0 :         ++n;
     684           0 :     }
     685           0 :     if (forceInterpreted) {
     686           0 :         options[n].optionString = const_cast<char *>("-Xint");
     687           0 :         options[n].extraInfo = 0;
     688           0 :         ++n;
     689             :     }
     690             : 
     691             : #ifdef MACOSX
     692             :     vm_args.version= JNI_VERSION_1_4; // issue 88987
     693             : #else
     694           0 :     vm_args.version= JNI_VERSION_1_2;
     695             : #endif
     696           0 :     vm_args.options= options;
     697           0 :     vm_args.nOptions= nOptions;
     698           0 :     vm_args.ignoreUnrecognized= JNI_TRUE;
     699             : 
     700             :     /* We set a global flag which is used by the abort handler in order to
     701             :        determine whether it is  should use longjmp to get back into this function.
     702             :        That is, the abort handler determines if it is on the same stack as this function
     703             :        and then jumps back into this function.
     704             :     */
     705           0 :     g_bInGetJavaVM = 1;
     706             :     jint err;
     707           0 :     JavaVM * pJavaVM = 0;
     708           0 :     memset( jmp_jvm_abort, 0, sizeof(jmp_jvm_abort));
     709           0 :     int jmpval= setjmp( jmp_jvm_abort );
     710             :     /* If jmpval is not "0" then this point was reached by a longjmp in the
     711             :        abort_handler, which was called indirectly by JNI_CreateVM.
     712             :     */
     713           0 :     if( jmpval == 0)
     714             :     {
     715             :         //returns negative number on failure
     716           0 :         err= pCreateJavaVM(&pJavaVM, ppEnv, &vm_args);
     717           0 :         g_bInGetJavaVM = 0;
     718             :     }
     719             :     else
     720             :         // set err to a positive number, so as or recognize that an abort (longjmp)
     721             :         //occurred
     722           0 :         err= 1;
     723             : 
     724           0 :     if(err != 0)
     725             :     {
     726           0 :         if( err < 0)
     727             :         {
     728             :             fprintf(stderr,"[Java framework] sunjavaplugin" SAL_DLLEXTENSION
     729           0 :                     "Can not create Java Virtual Machine\n");
     730           0 :             errorcode = JFW_PLUGIN_E_VM_CREATION_FAILED;
     731             :         }
     732           0 :         else if( err > 0)
     733             :         {
     734             :             fprintf(stderr,"[Java framework] sunjavaplugin" SAL_DLLEXTENSION
     735           0 :                     "Can not create JavaVirtualMachine, abort handler was called.\n");
     736           0 :             errorcode = JFW_PLUGIN_E_VM_CREATION_FAILED;
     737             :         }
     738             :     }
     739             :     else
     740             :     {
     741           0 :         *ppVm = pJavaVM;
     742             :         JFW_TRACE2("[Java framework] sunjavaplugin" SAL_DLLEXTENSION " has created a VM.\n");
     743             :     }
     744             : #else
     745             :     (void) arOptions;
     746             :     (void) cOptions;
     747             :     // On Android we always have a Java VM as we only expect this code
     748             :     // to be run in an Android app anyway.
     749             :     *ppVm = lo_get_javavm();
     750             :     fprintf(stderr, "lo_get_javavm returns %p", *ppVm);
     751             : #endif
     752             : 
     753           0 :    return errorcode;
     754             : }
     755             : 
     756             : extern "C"
     757           0 : javaPluginError jfw_plugin_existJRE(const JavaInfo *pInfo, sal_Bool *exist)
     758             : {
     759           0 :     javaPluginError ret = JFW_PLUGIN_E_NONE;
     760           0 :     if (!pInfo || !exist)
     761           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     762           0 :     ::rtl::OUString sLocation(pInfo->sLocation);
     763             : 
     764           0 :     if (sLocation.isEmpty())
     765           0 :         return JFW_PLUGIN_E_INVALID_ARG;
     766           0 :     ::osl::DirectoryItem item;
     767           0 :     ::osl::File::RC rc_item = ::osl::DirectoryItem::get(sLocation, item);
     768           0 :     if (::osl::File::E_None == rc_item)
     769             :     {
     770           0 :         *exist = sal_True;
     771             :     }
     772           0 :     else if (::osl::File::E_NOENT == rc_item)
     773             :     {
     774           0 :         *exist = sal_False;
     775             :     }
     776             :     else
     777             :     {
     778           0 :         ret = JFW_PLUGIN_E_ERROR;
     779             :     }
     780             : #ifdef MACOSX
     781             :     //We can have the situation that the JavaVM runtime library is not
     782             :     //contained within JAVA_HOME. Then the check for JAVA_HOME would return
     783             :     //true although the runtime library may not be loadable.
     784             :     if (ret == JFW_PLUGIN_E_NONE && *exist == sal_True)
     785             :     {
     786             :         rtl::OUString sRuntimeLib = getRuntimeLib(pInfo->arVendorData);
     787             :         JFW_TRACE2(OUSTR("[Java framework] Checking existence of Java runtime library.\n"));
     788             : 
     789             :         ::osl::DirectoryItem itemRt;
     790             :         ::osl::File::RC rc_itemRt = ::osl::DirectoryItem::get(sRuntimeLib, itemRt);
     791             :         if (::osl::File::E_None == rc_itemRt)
     792             :         {
     793             :             *exist = sal_True;
     794             :             JFW_TRACE2(OUSTR("[Java framework] Java runtime library exist: ")
     795             :               + sRuntimeLib + OUSTR("\n"));
     796             : 
     797             :         }
     798             :         else if (::osl::File::E_NOENT == rc_itemRt)
     799             :         {
     800             :             *exist = sal_False;
     801             :             JFW_TRACE2(OUSTR("[Java framework] Java runtime library does not exist: ")
     802             :                        + sRuntimeLib + OUSTR("\n"));
     803             :         }
     804             :         else
     805             :         {
     806             :             ret = JFW_PLUGIN_E_ERROR;
     807             :             JFW_TRACE2(OUSTR("[Java framework] Error while looking for Java runtime library: ")
     808             :                        + sRuntimeLib + OUSTR(" \n"));
     809             :         }
     810             :     }
     811             : #endif
     812           0 :     return ret;
     813             : }
     814             : 
     815             : 
     816             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10