LCOV - code coverage report
Current view: top level - jvmfwk/plugins/sunmajor/pluginlib - sunjavaplugin.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 137 245 55.9 %
Date: 2012-08-25 Functions: 6 8 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 85 309 27.5 %

           Branch data     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_H
      63                 :            : #include <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                 :          4 : OString getPluginJarPath(
      85                 :            :     const OUString & sVendor,
      86                 :            :     const OUString& sLocation,
      87                 :            :     const OUString& sVersion)
      88                 :            : {
      89                 :          4 :     OString ret;
      90         [ +  - ]:          4 :     OUString sName1(RTL_CONSTASCII_USTRINGPARAM("javaplugin.jar"));
      91         [ +  - ]:          4 :     OUString sName2(RTL_CONSTASCII_USTRINGPARAM("plugin.jar"));
      92                 :          4 :     OUString sPath;
      93         [ -  + ]:          4 :     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                 :          4 :         char sep[] =  {SAL_PATHSEPARATOR, 0};
     121         [ +  - ]:          4 :         OUString sName(sLocation + OUSTR("/lib/") + sName1);
     122                 :          4 :         OUString sPath1;
     123                 :          4 :         OUString sPath2;
     124 [ +  - ][ +  - ]:          4 :         if (osl_getSystemPathFromFileURL(sName.pData, & sPath1.pData)
     125                 :            :             == osl_File_E_None)
     126                 :            :         {
     127         [ +  - ]:          4 :             sName = sLocation + OUSTR("/lib/") + sName2;
     128 [ +  - ][ +  - ]:          4 :             if (osl_getSystemPathFromFileURL(sName.pData, & sPath2.pData)
     129                 :            :                 == osl_File_E_None)
     130                 :            :             {
     131                 :          4 :                 sPath = sPath1 + OUString::createFromAscii(sep) + sPath2;
     132                 :            :             }
     133                 :            :         }
     134                 :          4 :         OSL_ASSERT(!sPath.isEmpty());
     135                 :            :     }
     136 [ +  - ][ +  - ]:          4 :     ret = rtl::OUStringToOString(sPath, osl_getThreadTextEncoding());
     137                 :            : 
     138                 :          4 :     return ret;
     139                 :            : }
     140                 :            : #endif // UNX
     141                 :            : 
     142                 :            : 
     143                 :          6 : JavaInfo* createJavaInfo(const rtl::Reference<VendorBase> & info)
     144                 :            : {
     145                 :          6 :     JavaInfo* pInfo = (JavaInfo*) rtl_allocateMemory(sizeof(JavaInfo));
     146         [ -  + ]:          6 :     if (pInfo == NULL)
     147                 :          0 :         return NULL;
     148         [ +  - ]:          6 :     rtl::OUString sVendor = info->getVendor();
     149                 :          6 :     pInfo->sVendor = sVendor.pData;
     150                 :          6 :     rtl_uString_acquire(sVendor.pData);
     151         [ +  - ]:          6 :     rtl::OUString sHome = info->getHome();
     152                 :          6 :     pInfo->sLocation = sHome.pData;
     153                 :          6 :     rtl_uString_acquire(pInfo->sLocation);
     154         [ +  - ]:          6 :     rtl::OUString sVersion = info->getVersion();
     155                 :          6 :     pInfo->sVersion = sVersion.pData;
     156                 :          6 :     rtl_uString_acquire(pInfo->sVersion);
     157 [ +  - ][ +  - ]:          6 :     pInfo->nFeatures = info->supportsAccessibility() ? 1 : 0;
     158 [ +  - ][ +  - ]:          6 :     pInfo->nRequirements = info->needsRestart() ? JFW_REQUIRE_NEEDRESTART : 0;
     159                 :          6 :     rtl::OUStringBuffer buf(1024);
     160 [ +  - ][ +  - ]:          6 :     buf.append(info->getRuntimeLibrary());
     161 [ +  - ][ +  - ]:          6 :     if (!info->getLibraryPaths().isEmpty())
     162                 :            :     {
     163         [ +  - ]:          6 :         buf.appendAscii("\n");
     164 [ +  - ][ +  - ]:          6 :         buf.append(info->getLibraryPaths());
     165         [ +  - ]:          6 :         buf.appendAscii("\n");
     166                 :            :     }
     167                 :            : 
     168         [ +  - ]:          6 :     rtl::OUString sVendorData = buf.makeStringAndClear();
     169                 :            :     rtl::ByteSequence byteSeq( (sal_Int8*) sVendorData.pData->buffer,
     170         [ +  - ]:          6 :                                sVendorData.getLength() * sizeof(sal_Unicode));
     171                 :          6 :     pInfo->arVendorData = byteSeq.get();
     172                 :          6 :     rtl_byte_sequence_acquire(pInfo->arVendorData);
     173                 :            : 
     174                 :          6 :     return pInfo;
     175                 :            : }
     176                 :            : 
     177                 :          4 : rtl::OUString getRuntimeLib(const rtl::ByteSequence & data)
     178                 :            : {
     179                 :          4 :     const sal_Unicode* chars = (sal_Unicode*) data.getConstArray();
     180                 :          4 :     sal_Int32 len = data.getLength();
     181                 :          4 :     rtl::OUString sData(chars, len / 2);
     182                 :            :     //the runtime lib is on the first line
     183                 :          4 :     sal_Int32 index = 0;
     184                 :          4 :     rtl::OUString aToken = sData.getToken( 0, '\n', index);
     185                 :            : 
     186                 :          4 :     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                 :         12 : 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                 :         12 :     javaPluginError errorcode = JFW_PLUGIN_E_NONE;
     342                 :            : 
     343                 :            :     OSL_ASSERT(path);
     344                 :            :     OSL_ASSERT(sVendor);
     345                 :            :     OSL_ASSERT(sMinVersion);
     346                 :            :     OSL_ASSERT(sMaxVersion);
     347 [ +  - ][ +  - ]:         12 :     if (!path || !sVendor || !sMinVersion || !sMaxVersion || !ppInfo)
         [ +  - ][ +  - ]
                 [ -  + ]
     348                 :          0 :         return JFW_PLUGIN_E_INVALID_ARG;
     349                 :         12 :     OUString ouPath(path);
     350                 :            :     OSL_ASSERT(!ouPath.isEmpty());
     351         [ -  + ]:         12 :     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 [ -  + ][ #  # ]:         12 :     if (arExcludeList == NULL && nLenList > 0)
     358                 :          0 :         return JFW_PLUGIN_E_INVALID_ARG;
     359                 :            : 
     360                 :         12 :     OUString ouVendor(sVendor);
     361                 :         12 :     OUString ouMinVer(sMinVersion);
     362                 :         12 :     OUString ouMaxVer(sMaxVersion);
     363                 :            : 
     364                 :            :     OSL_ASSERT(!ouVendor.isEmpty());
     365         [ -  + ]:         12 :     if (ouVendor.isEmpty())
     366                 :          0 :         return JFW_PLUGIN_E_INVALID_ARG;
     367                 :            : 
     368         [ +  - ]:         12 :     rtl::Reference<VendorBase> aVendorInfo = getJREInfoByPath(ouPath);
     369         [ -  + ]:         12 :     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 [ +  - ][ +  + ]:         12 :     if (ouVendor.equals(aVendorInfo->getVendor()) == sal_False)
     374                 :          6 :         return JFW_PLUGIN_E_NO_JRE;
     375                 :            : 
     376         [ +  - ]:          6 :     if (!ouMinVer.isEmpty())
     377                 :            :     {
     378                 :          6 :         int nRes = 0;
     379                 :            :         try
     380                 :            :         {
     381         [ +  - ]:          6 :             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         [ -  + ]:          6 :         if (nRes < 0)
     393                 :          0 :             return JFW_PLUGIN_E_FAILED_VERSION;
     394                 :            :     }
     395                 :            : 
     396         [ -  + ]:          6 :     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         [ -  + ]:          6 :     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         [ +  - ]:          6 :     *ppInfo = createJavaInfo(aVendorInfo);
     437                 :            : 
     438 [ +  - ][ #  # ]:         12 :     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                 :          4 : 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 [ +  - ][ +  - ]:          4 :     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                 :          4 :     volatile javaPluginError errorcode = JFW_PLUGIN_E_NONE;
     568 [ +  - ][ +  - ]:          4 :     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 [ +  - ][ -  + ]:          4 :     if ( ! isVendorSupported(pInfo->sVendor))
     572                 :          0 :         return JFW_PLUGIN_E_WRONG_VENDOR;
     573                 :          4 :     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                 :          4 :     oslModule moduleRt = 0;
     582                 :            : #if defined(LINUX)
     583 [ -  + ][ +  - ]:          4 :     if ((moduleRt = osl_loadModule(sRuntimeLib.pData,
     584                 :          4 :                                    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         [ +  - ]:          4 :     rtl::OUString javaHome(RTL_CONSTASCII_USTRINGPARAM("JAVA_HOME="));
     604                 :          4 :     rtl::OUString sPathLocation;
     605         [ +  - ]:          4 :     osl_getSystemPathFromFileURL(pInfo->sLocation, & sPathLocation.pData);
     606                 :          4 :     javaHome += sPathLocation;
     607                 :            :     rtl::OString osJavaHome = rtl::OUStringToOString(
     608 [ +  - ][ +  - ]:          4 :         javaHome, osl_getThreadTextEncoding());
     609                 :          4 :     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         [ +  - ]:          4 :             RTL_CONSTASCII_USTRINGPARAM("JNI_CreateJavaVM"));
     616                 :            : 
     617                 :            :     JNI_CreateVM_Type * pCreateJavaVM = (JNI_CreateVM_Type *) osl_getFunctionSymbol(
     618         [ +  - ]:          4 :         moduleRt, sSymbolCreateJava.pData);
     619         [ -  + ]:          4 :     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                 :          4 :     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         [ -  + ]:          4 :     sal_Int32 nOptions = 1 + cOptions + (forceInterpreted ? 1 : 0);
     641                 :            :         //TODO: check for overflow
     642         [ +  - ]:          4 :     boost::scoped_array<JavaVMOption> sarOptions(new JavaVMOption[nOptions]);
     643                 :          4 :     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                 :          4 :     int n = 0;
     650                 :          4 :     options[n].optionString= (char *) "abort";
     651                 :          4 :     options[n].extraInfo= (void* )(sal_IntPtr)abort_handler;
     652                 :          4 :     ++n;
     653                 :          4 :     rtl::OString sClassPathProp("-Djava.class.path=");
     654                 :          4 :     rtl::OString sClassPathOption;
     655         [ +  + ]:         20 :     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                 :         16 :         rtl::OString sClassPath = arOptions[i].optionString;
     661         [ +  + ]:         16 :         if (sClassPath.match(sClassPathProp, 0) == sal_True)
     662                 :            :         {
     663                 :          4 :             char sep[] =  {SAL_PATHSEPARATOR, 0};
     664         [ +  - ]:          4 :             OString sAddPath = getPluginJarPath(pInfo->sVendor, pInfo->sLocation,pInfo->sVersion);
     665         [ +  - ]:          4 :             if (!sAddPath.isEmpty())
     666                 :          4 :                 sClassPathOption = sClassPath + rtl::OString(sep) + sAddPath;
     667                 :            :             else
     668                 :          0 :                 sClassPathOption = sClassPath;
     669                 :          4 :             options[n].optionString = (char *) sClassPathOption.getStr();
     670                 :          4 :             options[n].extraInfo = arOptions[i].extraInfo;
     671                 :            :         }
     672                 :            :         else
     673                 :            :         {
     674                 :            : #endif
     675                 :         12 :             options[n].optionString = arOptions[i].optionString;
     676                 :         12 :             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                 :         16 :         ++n;
     684                 :         16 :     }
     685         [ -  + ]:          4 :     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                 :          4 :     vm_args.version= JNI_VERSION_1_2;
     695                 :            : #endif
     696                 :          4 :     vm_args.options= options;
     697                 :          4 :     vm_args.nOptions= nOptions;
     698                 :          4 :     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                 :          4 :     g_bInGetJavaVM = 1;
     706                 :            :     jint err;
     707                 :          4 :     JavaVM * pJavaVM = 0;
     708                 :          4 :     memset( jmp_jvm_abort, 0, sizeof(jmp_jvm_abort));
     709                 :          4 :     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         [ +  - ]:          4 :     if( jmpval == 0)
     714                 :            :     {
     715                 :            :         //returns negative number on failure
     716         [ +  - ]:          4 :         err= pCreateJavaVM(&pJavaVM, ppEnv, &vm_args);
     717                 :          4 :         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         [ -  + ]:          4 :     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                 :          4 :         *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 [ +  - ][ +  - ]:          4 :    return errorcode;
     754                 :            : }
     755                 :            : 
     756                 :            : extern "C"
     757                 :        101 : javaPluginError jfw_plugin_existJRE(const JavaInfo *pInfo, sal_Bool *exist)
     758                 :            : {
     759                 :        101 :     javaPluginError ret = JFW_PLUGIN_E_NONE;
     760 [ +  - ][ -  + ]:        101 :     if (!pInfo || !exist)
     761                 :          0 :         return JFW_PLUGIN_E_INVALID_ARG;
     762                 :        101 :     ::rtl::OUString sLocation(pInfo->sLocation);
     763                 :            : 
     764         [ -  + ]:        101 :     if (sLocation.isEmpty())
     765                 :          0 :         return JFW_PLUGIN_E_INVALID_ARG;
     766                 :        101 :     ::osl::DirectoryItem item;
     767         [ +  - ]:        101 :     ::osl::File::RC rc_item = ::osl::DirectoryItem::get(sLocation, item);
     768         [ +  - ]:        101 :     if (::osl::File::E_None == rc_item)
     769                 :            :     {
     770                 :        101 :         *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         [ +  - ]:        101 :     return ret;
     813                 :            : }
     814                 :            : 
     815                 :            : 
     816                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10