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

Generated by: LCOV version 1.10