LCOV - code coverage report
Current view: top level - jvmfwk/plugins/sunmajor/pluginlib - util.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 373 438 85.2 %
Date: 2014-04-14 Functions: 31 32 96.9 %
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             : #include <config_features.h>
      21             : #include <config_folders.h>
      22             : 
      23             : #include "util.hxx"
      24             : 
      25             : #include "osl/process.h"
      26             : #include "osl/security.hxx"
      27             : #include "osl/file.hxx"
      28             : #include "osl/module.hxx"
      29             : #include "rtl/byteseq.hxx"
      30             : #include "rtl/ustrbuf.hxx"
      31             : #include "rtl/instance.hxx"
      32             : #include "salhelper/linkhelper.hxx"
      33             : #include "salhelper/thread.hxx"
      34             : #include "boost/noncopyable.hpp"
      35             : #include "boost/scoped_array.hpp"
      36             : #include "com/sun/star/uno/Sequence.hxx"
      37             : #include <utility>
      38             : #include <algorithm>
      39             : #include <map>
      40             : 
      41             : #if defined WNT
      42             : #if defined _MSC_VER
      43             : #pragma warning(push, 1)
      44             : #endif
      45             : #include <windows.h>
      46             : #if defined _MSC_VER
      47             : #pragma warning(pop)
      48             : #endif
      49             : #endif
      50             : #include <string.h>
      51             : 
      52             : #include "sunjre.hxx"
      53             : #include "vendorlist.hxx"
      54             : #include "diagnostics.h"
      55             : 
      56             : using namespace osl;
      57             : using namespace std;
      58             : 
      59             : using ::rtl::Reference;
      60             : 
      61             : #ifdef WNT
      62             : #define HKEY_SUN_JRE L"Software\\JavaSoft\\Java Runtime Environment"
      63             : #define HKEY_SUN_SDK L"Software\\JavaSoft\\Java Development Kit"
      64             : #endif
      65             : 
      66             : #ifdef UNX
      67             : #if !(defined MACOSX && defined X86_64)
      68             : namespace {
      69             : char const *g_arJavaNames[] = {
      70             :     "",
      71             :     "j2re",
      72             :     "j2se",
      73             :     "j2sdk",
      74             :     "jdk",
      75             :     "jre",
      76             :     "java",
      77             :     "Home",
      78             :     "IBMJava2-ppc-142"
      79             : };
      80             : /* These are directory names which could contain multiple java installations.
      81             :  */
      82             : char const *g_arCollectDirs[] = {
      83             :     "",
      84             : #ifndef JVM_ONE_PATH_CHECK
      85             :     "j2re/",
      86             :     "j2se/",
      87             :     "j2sdk/",
      88             :     "jdk/",
      89             :     "jre/",
      90             :     "java/",
      91             : #endif
      92             :     "jvm/"
      93             : };
      94             : 
      95             : /* These are directories in which a java installation is
      96             :    looked for.
      97             : */
      98             : char const *g_arSearchPaths[] = {
      99             : #ifdef MACOSX
     100             :     "",
     101             :     "Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin",
     102             :     "System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/"
     103             : #else
     104             : #ifndef JVM_ONE_PATH_CHECK
     105             :     "",
     106             :     "usr/",
     107             :     "usr/local/",
     108             :     "usr/local/IBMJava2-ppc-142",
     109             :     "usr/local/j2sdk1.3.1",
     110             : #ifdef X86_64
     111             :     "usr/lib64/",
     112             : #endif
     113             :     "usr/lib/",
     114             :     "usr/bin/"
     115             : #else
     116             :     JVM_ONE_PATH_CHECK
     117             : #endif
     118             : #endif
     119             : };
     120             : }
     121             : #endif
     122             : #endif //  UNX
     123             : 
     124             : namespace jfw_plugin
     125             : {
     126             : extern VendorSupportMapEntry gVendorMap[];
     127             : 
     128             : #if defined WNT
     129             : bool getSDKInfoFromRegistry(vector<OUString> & vecHome);
     130             : bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome);
     131             : #endif
     132             : 
     133             : bool decodeOutput(const OString& s, OUString* out);
     134             : 
     135             : 
     136             : 
     137             : namespace
     138             : {
     139           1 :     OUString getLibraryLocation()
     140             :     {
     141           1 :         OUString libraryFileUrl;
     142           1 :         OSL_VERIFY(osl::Module::getUrlFromAddress((void *)(sal_IntPtr)getLibraryLocation, libraryFileUrl));
     143           1 :         return getDirFromFile(libraryFileUrl);
     144             :     }
     145             : 
     146             :     struct InitBootstrap
     147             :     {
     148           1 :         rtl::Bootstrap * operator()(const OUString& sIni)
     149             :         {
     150           1 :             static rtl::Bootstrap aInstance(sIni);
     151           1 :             return & aInstance;
     152             : 
     153             :         }
     154             :    };
     155             : 
     156             :    struct InitBootstrapData
     157             :    {
     158           1 :        OUString const & operator()()
     159             :        {
     160           1 :            static OUString sIni;
     161           1 :             OUStringBuffer buf( 255);
     162           1 :             buf.append( getLibraryLocation());
     163             : #if HAVE_FEATURE_MACOSX_MACLIKE_APP_STRUCTURE
     164             :             buf.appendAscii( "/../" LIBO_ETC_FOLDER );
     165             : #endif
     166           1 :             buf.appendAscii( SAL_CONFIGFILE("/sunjavaplugin") );
     167           1 :             sIni = buf.makeStringAndClear();
     168             :             JFW_TRACE2("[Java framework] sunjavaplugin: "
     169             :                        "Using configuration file \n" +  sIni);
     170           1 :             return sIni;
     171             :         }
     172             :    };
     173             : }
     174             : 
     175           4 : rtl::Bootstrap * getBootstrap()
     176             : {
     177             :     return rtl_Instance< rtl::Bootstrap, InitBootstrap,
     178             :         ::osl::MutexGuard, ::osl::GetGlobalMutex,
     179             :         OUString, InitBootstrapData >::create(
     180           4 :             InitBootstrap(), ::osl::GetGlobalMutex(), InitBootstrapData());
     181             : }
     182             : 
     183             : 
     184             : 
     185             : 
     186             : class FileHandleGuard: private boost::noncopyable
     187             : {
     188             : public:
     189           4 :     inline FileHandleGuard(oslFileHandle & rHandle) SAL_THROW(()):
     190           4 :         m_rHandle(rHandle) {}
     191             : 
     192             :     inline ~FileHandleGuard() SAL_THROW(());
     193             : 
     194        7213 :     inline oslFileHandle & getHandle() SAL_THROW(()) { return m_rHandle; }
     195             : 
     196             : private:
     197             :     oslFileHandle & m_rHandle;
     198             : };
     199             : 
     200           4 : inline FileHandleGuard::~FileHandleGuard() SAL_THROW(())
     201             : {
     202           4 :     if (m_rHandle != 0)
     203             :     {
     204           4 :         if (osl_closeFile(m_rHandle) != osl_File_E_None)
     205             :         {
     206             :             OSL_FAIL("unexpected situation");
     207             :         }
     208             :     }
     209           4 : }
     210             : 
     211             : 
     212           2 : class FileHandleReader
     213             : {
     214             : public:
     215             :     enum Result
     216             :     {
     217             :         RESULT_OK,
     218             :         RESULT_EOF,
     219             :         RESULT_ERROR
     220             :     };
     221             : 
     222           2 :     inline FileHandleReader(oslFileHandle & rHandle) SAL_THROW(()):
     223           2 :         m_aGuard(rHandle), m_nSize(0), m_nIndex(0), m_bLf(false) {}
     224             : 
     225             :     Result readLine(OString * pLine) SAL_THROW(());
     226             : 
     227             : private:
     228             :     enum { BUFFER_SIZE = 1024 };
     229             : 
     230             :     sal_Char m_aBuffer[BUFFER_SIZE];
     231             :     FileHandleGuard m_aGuard;
     232             :     int m_nSize;
     233             :     int m_nIndex;
     234             :     bool m_bLf;
     235             : };
     236             : 
     237             : FileHandleReader::Result
     238         104 : FileHandleReader::readLine(OString * pLine)
     239             :     SAL_THROW(())
     240             : {
     241             :     OSL_ENSURE(pLine, "specification violation");
     242             : 
     243        7246 :     for (bool bEof = true;; bEof = false)
     244             :     {
     245        7246 :         if (m_nIndex == m_nSize)
     246             :         {
     247        7211 :             sal_uInt64 nRead = 0;
     248        7211 :             switch (osl_readFile(
     249        7211 :                         m_aGuard.getHandle(), m_aBuffer, sizeof(m_aBuffer), &nRead))
     250             :             {
     251             :             case osl_File_E_PIPE: //HACK! for windows
     252           0 :                 nRead = 0;
     253             :             case osl_File_E_None:
     254        7211 :                 if (nRead == 0)
     255             :                 {
     256           2 :                     m_bLf = false;
     257           4 :                     return bEof ? RESULT_EOF : RESULT_OK;
     258             :                 }
     259        7209 :                 m_nIndex = 0;
     260        7209 :                 m_nSize = static_cast< int >(nRead);
     261        7209 :                 break;
     262             :             case osl_File_E_INTR:
     263           0 :                 continue;
     264             : 
     265             :             default:
     266           0 :                 return RESULT_ERROR;
     267             :             }
     268             :         }
     269             : 
     270        7244 :         if (m_bLf && m_aBuffer[m_nIndex] == 0x0A)
     271           0 :             ++m_nIndex;
     272        7244 :         m_bLf = false;
     273             : 
     274        7244 :         int nStart = m_nIndex;
     275       33370 :         while (m_nIndex != m_nSize)
     276       18984 :             switch (m_aBuffer[m_nIndex++])
     277             :             {
     278             :             case 0x0D:
     279           0 :                 m_bLf = true;
     280             :             case 0x0A:
     281         204 :                 *pLine += OString(m_aBuffer + nStart,
     282         204 :                                        m_nIndex - 1 - nStart);
     283             :                     //TODO! check for overflow, and not very efficient
     284         102 :                 return RESULT_OK;
     285             :             }
     286             : 
     287        7142 :         *pLine += OString(m_aBuffer + nStart, m_nIndex - nStart);
     288             :             //TODO! check for overflow, and not very efficient
     289        7142 :     }
     290             : }
     291             : 
     292             : class AsynchReader: public salhelper::Thread
     293             : {
     294             :     size_t  m_nDataSize;
     295             :     boost::scoped_array<sal_Char> m_arData;
     296             : 
     297             :     bool m_bError;
     298             :     bool m_bDone;
     299             :     FileHandleGuard m_aGuard;
     300             : 
     301           4 :     virtual ~AsynchReader() {}
     302             : 
     303             :     void execute() SAL_OVERRIDE;
     304             : public:
     305             : 
     306             :     AsynchReader(oslFileHandle & rHandle);
     307             : 
     308             :     /** only call this function after this thread has finished.
     309             : 
     310             :         That is, call join on this instance and then call getData.
     311             : 
     312             :      */
     313             :     OString getData();
     314             : };
     315             : 
     316           2 : AsynchReader::AsynchReader(oslFileHandle & rHandle):
     317             :     Thread("jvmfwkAsyncReader"), m_nDataSize(0), m_bError(false),
     318           2 :     m_bDone(false), m_aGuard(rHandle)
     319             : {
     320           2 : }
     321             : 
     322           0 : OString AsynchReader::getData()
     323             : {
     324           0 :     return OString(m_arData.get(), m_nDataSize);
     325             : }
     326             : 
     327           2 : void AsynchReader::execute()
     328             : {
     329           2 :     const sal_uInt64 BUFFER_SIZE = 4096;
     330             :     sal_Char aBuffer[BUFFER_SIZE];
     331             :     while (true)
     332             :     {
     333             :         sal_uInt64 nRead;
     334             :         //the function blocks until something could be read or the pipe closed.
     335           2 :         switch (osl_readFile(
     336           2 :                     m_aGuard.getHandle(), aBuffer, BUFFER_SIZE, &nRead))
     337             :         {
     338             :         case osl_File_E_PIPE: //HACK! for windows
     339           0 :             nRead = 0;
     340             :         case osl_File_E_None:
     341           2 :             break;
     342             :         default:
     343           0 :             m_bError = true;
     344           2 :             return;
     345             :         }
     346             : 
     347           2 :         if (nRead == 0)
     348             :         {
     349           2 :             m_bDone = true;
     350           4 :             break;
     351             :         }
     352           0 :         else if (nRead <= BUFFER_SIZE)
     353             :         {
     354             :             //Save the data we have in m_arData into a temporary array
     355           0 :             boost::scoped_array<sal_Char> arTmp( new sal_Char[m_nDataSize]);
     356           0 :             memcpy(arTmp.get(), m_arData.get(), m_nDataSize);
     357             :             //Enlarge m_arData to hold the newly read data
     358           0 :             m_arData.reset(new sal_Char[(size_t)(m_nDataSize + nRead)]);
     359             :             //Copy back the data that was already in m_arData
     360           0 :             memcpy(m_arData.get(), arTmp.get(), m_nDataSize);
     361             :             //Add the newly read data to m_arData
     362           0 :             memcpy(m_arData.get() + m_nDataSize, aBuffer, (size_t) nRead);
     363           0 :             m_nDataSize += (size_t) nRead;
     364             :         }
     365           0 :     }
     366             : }
     367             : 
     368           4 : static bool isEnvVarSetToOne(const OUString &aVar)
     369             : {
     370           4 :     OUString aValue;
     371           4 :     getBootstrap()->getFrom(aVar, aValue);
     372           4 :     return aValue == "1";
     373             : }
     374             : 
     375           2 : bool getJavaProps(const OUString & exePath,
     376             : #ifdef JVM_ONE_PATH_CHECK
     377             :                   const OUString & homePath,
     378             : #endif
     379             :                   std::vector<std::pair<OUString, OUString> >& props,
     380             :                   bool * bProcessRun)
     381             : {
     382           2 :     bool ret = false;
     383             : 
     384             :     OSL_ASSERT(!exePath.isEmpty());
     385           2 :     OUString usStartDir;
     386             :     //We need to set the CLASSPATH in case the office is started from
     387             :     //a different directory. The JREProperties.class is expected to reside
     388             :     //next to the plugin.
     389           4 :     OUString sThisLib;
     390           2 :     if (osl_getModuleURLFromAddress((void *) (sal_IntPtr)& getJavaProps,
     391           2 :                                     & sThisLib.pData) == sal_False)
     392           0 :         return false;
     393           2 :     sThisLib = getDirFromFile(sThisLib);
     394           4 :     OUString sClassPath;
     395           2 :     if (osl_getSystemPathFromFileURL(sThisLib.pData, & sClassPath.pData)
     396             :         != osl_File_E_None)
     397           0 :         return false;
     398             : 
     399             :     //check if we shall examine a Java for accessibility support
     400             :     //If the bootstrap variable is "1" then we pass the argument
     401             :     //"noaccessibility" to JREProperties.class. This will prevent
     402             :     //that it calls   java.awt.Toolkit.getDefaultToolkit();
     403           2 :     bool bNoAccessibility = isEnvVarSetToOne("JFW_PLUGIN_DO_NOT_CHECK_ACCESSIBILITY");
     404             : 
     405             :     //prepare the arguments
     406           2 :     sal_Int32 cArgs = 3;
     407           4 :     OUString arg1 = "-classpath";// + sClassPath;
     408           4 :     OUString arg2 = sClassPath;
     409           4 :     OUString arg3("JREProperties");
     410           4 :     OUString arg4 = "noaccessibility";
     411           2 :     rtl_uString *args[4] = {arg1.pData, arg2.pData, arg3.pData};
     412             : 
     413             : #ifdef UNX
     414             :     // Java is no longer required for a11y - we use atk directly.
     415           2 :     bNoAccessibility = !isEnvVarSetToOne("JFW_PLUGIN_FORCE_ACCESSIBILITY");
     416             : #endif
     417             : 
     418             :     // Only add the fourth param if the bootstrap parameter is set.
     419           2 :     if (bNoAccessibility)
     420             :     {
     421           2 :         args[3] = arg4.pData;
     422           2 :         cArgs = 4;
     423             :     }
     424             : 
     425           2 :     oslProcess javaProcess= 0;
     426           2 :     oslFileHandle fileOut= 0;
     427           2 :     oslFileHandle fileErr= 0;
     428             : 
     429           4 :     FileHandleReader stdoutReader(fileOut);
     430           4 :     rtl::Reference< AsynchReader > stderrReader(new AsynchReader(fileErr));
     431             : 
     432             :     JFW_TRACE2("\n[Java framework] Executing: " + exePath + ".\n");
     433             :     oslProcessError procErr =
     434             :         osl_executeProcess_WithRedirectedIO( exePath.pData,//usExe.pData,
     435             :                                              args,
     436             :                                              cArgs,                 //sal_uInt32   nArguments,
     437             :                                              osl_Process_HIDDEN, //oslProcessOption Options,
     438             :                                              NULL, //oslSecurity Security,
     439             :                                              usStartDir.pData,//usStartDir.pData,//usWorkDir.pData, //rtl_uString *strWorkDir,
     440             :                                              NULL, //rtl_uString *strEnvironment[],
     441             :                                              0, //  sal_uInt32   nEnvironmentVars,
     442             :                                              &javaProcess, //oslProcess *pProcess,
     443             :                                              NULL,//oslFileHandle *pChildInputWrite,
     444             :                                              &fileOut,//oslFileHandle *pChildOutputRead,
     445           2 :                                              &fileErr);//oslFileHandle *pChildErrorRead);
     446             : 
     447           2 :     if( procErr != osl_Process_E_None)
     448             :     {
     449             :         JFW_TRACE2("[Java framework] Execution failed. \n");
     450           0 :         *bProcessRun = false;
     451           0 :         return ret;
     452             :     }
     453             :     else
     454             :     {
     455             :         JFW_TRACE2("[Java framework] Java executed successfully.\n");
     456           2 :         *bProcessRun = true;
     457             :     }
     458             : 
     459             :     //Start asynchronous reading (different thread) of error stream
     460           2 :     stderrReader->launch();
     461             : 
     462             :     //Use this thread to read output stream
     463           2 :     FileHandleReader::Result rs = FileHandleReader::RESULT_OK;
     464             :     while (true)
     465             :     {
     466         104 :         OString aLine;
     467         104 :         rs = stdoutReader.readLine( & aLine);
     468         104 :         if (rs != FileHandleReader::RESULT_OK)
     469           2 :             break;
     470         204 :         OUString sLine;
     471         102 :         if (!decodeOutput(aLine, &sLine))
     472           0 :             continue;
     473             :         JFW_TRACE2("[Java framework]:\" " << sLine << " \".\n");
     474         102 :         sLine = sLine.trim();
     475         102 :         if (sLine.isEmpty())
     476           0 :             continue;
     477             :         //The JREProperties class writes key value pairs, separated by '='
     478         102 :         sal_Int32 index = sLine.indexOf('=', 0);
     479             :         OSL_ASSERT(index != -1);
     480         204 :         OUString sKey = sLine.copy(0, index);
     481         204 :         OUString sVal = sLine.copy(index + 1);
     482             : 
     483             : #ifdef JVM_ONE_PATH_CHECK
     484             :         //replace absolute path by linux distro link
     485             :         OUString sHomeProperty("java.home");
     486             :         if(sHomeProperty.equals(sKey))
     487             :         {
     488             :             sVal = homePath + "/jre";
     489             :         }
     490             : #endif
     491             : 
     492         102 :         props.push_back(std::make_pair(sKey, sVal));
     493         102 :     }
     494             : 
     495           2 :     if (rs != FileHandleReader::RESULT_ERROR && !props.empty())
     496           2 :         ret = true;
     497             : 
     498             :     //process error stream data
     499           2 :     stderrReader->join();
     500             :     JFW_TRACE2("[Java framework]  Java wrote to stderr:\" "
     501             :                << stderrReader->getData().getStr() << " \".\n");
     502             : 
     503           2 :     TimeValue waitMax= {5 ,0};
     504           2 :     procErr = osl_joinProcessWithTimeout(javaProcess, &waitMax);
     505             :     OSL_ASSERT(procErr == osl_Process_E_None);
     506           2 :     osl_freeProcessHandle(javaProcess);
     507           4 :     return ret;
     508             : }
     509             : 
     510             : /* converts the properties printed by JREProperties.class into
     511             :     readable strings. The strings are encoded as integer values separated
     512             :     by spaces.
     513             :  */
     514         102 : bool decodeOutput(const OString& s, OUString* out)
     515             : {
     516             :     OSL_ASSERT(out != 0);
     517         102 :     OUStringBuffer buff(512);
     518         102 :     sal_Int32 nIndex = 0;
     519        5456 :     do
     520             :     {
     521        5456 :         OString aToken = s.getToken( 0, ' ', nIndex );
     522        5456 :         if (!aToken.isEmpty())
     523             :         {
     524       18882 :             for (sal_Int32 i = 0; i < aToken.getLength(); ++i)
     525             :             {
     526       13528 :                 if (aToken[i] < '0' || aToken[i] > '9')
     527           0 :                     return false;
     528             :             }
     529        5354 :             sal_Unicode value = (sal_Unicode)(aToken.toInt32());
     530        5354 :             buff.append(value);
     531        5456 :         }
     532        5456 :     } while (nIndex >= 0);
     533             : 
     534         102 :     *out = buff.makeStringAndClear();
     535         102 :     return true;
     536             : }
     537             : 
     538             : 
     539             : #if defined WNT
     540             : void createJavaInfoFromWinReg(std::vector<rtl::Reference<VendorBase> > & vecInfos)
     541             : {
     542             :         // Get Java s from registry
     543             :     std::vector<OUString> vecJavaHome;
     544             :     if(getSDKInfoFromRegistry(vecJavaHome))
     545             :     {
     546             :         // create impl objects
     547             :         typedef std::vector<OUString>::iterator ItHome;
     548             :         for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end();
     549             :             it_home++)
     550             :         {
     551             :             getJREInfoByPath(*it_home, vecInfos);
     552             :         }
     553             :     }
     554             : 
     555             :     vecJavaHome.clear();
     556             :     if(getJREInfoFromRegistry(vecJavaHome))
     557             :     {
     558             :         typedef std::vector<OUString>::iterator ItHome;
     559             :         for(ItHome it_home= vecJavaHome.begin(); it_home != vecJavaHome.end();
     560             :             it_home++)
     561             :         {
     562             :             getJREInfoByPath(*it_home, vecInfos);
     563             :         }
     564             :    }
     565             : }
     566             : 
     567             : 
     568             : bool getJavaInfoFromRegistry(const wchar_t* szRegKey,
     569             :                              vector<OUString>& vecJavaHome)
     570             : {
     571             :     HKEY    hRoot;
     572             :     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ENUMERATE_SUB_KEYS, &hRoot)
     573             :         == ERROR_SUCCESS)
     574             :     {
     575             :         DWORD dwIndex = 0;
     576             :         const DWORD BUFFSIZE = 1024;
     577             :         wchar_t bufVersion[BUFFSIZE];
     578             :         DWORD nNameLen = BUFFSIZE;
     579             :         FILETIME fileTime;
     580             :         nNameLen = sizeof(bufVersion);
     581             : 
     582             :         // Iterate over all subkeys of HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment
     583             :         while (RegEnumKeyExW(hRoot, dwIndex, bufVersion, &nNameLen, NULL, NULL, NULL, &fileTime) != ERROR_NO_MORE_ITEMS)
     584             :         {
     585             :             HKEY    hKey;
     586             :             // Open a Java Runtime Environment sub key, e.g. "1.4.0"
     587             :             if (RegOpenKeyExW(hRoot, bufVersion, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
     588             :             {
     589             :                 DWORD   dwType;
     590             :                 DWORD   dwTmpPathLen= 0;
     591             :                 // Get the path to the JavaHome every JRE entry
     592             :                 // Find out how long the string for JavaHome is and allocate memory to hold the path
     593             :                 if( RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, NULL, &dwTmpPathLen)== ERROR_SUCCESS)
     594             :                 {
     595             :                     char* szTmpPath= (char *) malloc( dwTmpPathLen);
     596             :                     // Get the path for the runtime lib
     597             :                     if(RegQueryValueExW(hKey, L"JavaHome", 0, &dwType, (unsigned char*) szTmpPath, &dwTmpPathLen) == ERROR_SUCCESS)
     598             :                     {
     599             :                         // There can be several version entries refering with the same JavaHome,e.g 1.4 and 1.4.1
     600             :                         OUString usHome((sal_Unicode*) szTmpPath);
     601             :                         // check if there is already an entry with the same JavaHomeruntime lib
     602             :                         // if so, we use the one with the more accurate version
     603             :                         bool bAppend= true;
     604             :                         OUString usHomeUrl;
     605             :                         if (osl_getFileURLFromSystemPath(usHome.pData, & usHomeUrl.pData) ==
     606             :                             osl_File_E_None)
     607             :                         {
     608             :                             //iterate over the vector with java home strings
     609             :                             typedef vector<OUString>::iterator ItHome;
     610             :                             for(ItHome itHome= vecJavaHome.begin();
     611             :                                 itHome != vecJavaHome.end(); itHome++)
     612             :                             {
     613             :                                 if(usHomeUrl.equals(*itHome))
     614             :                                 {
     615             :                                     bAppend= false;
     616             :                                     break;
     617             :                                 }
     618             :                             }
     619             :                             // Save the home dir
     620             :                             if(bAppend)
     621             :                             {
     622             :                                 vecJavaHome.push_back(usHomeUrl);
     623             :                             }
     624             :                         }
     625             :                     }
     626             :                     free( szTmpPath);
     627             :                     RegCloseKey(hKey);
     628             :                 }
     629             :             }
     630             :             dwIndex ++;
     631             :             nNameLen = BUFFSIZE;
     632             :         }
     633             :         RegCloseKey(hRoot);
     634             :     }
     635             :     return true;
     636             : }
     637             : 
     638             : 
     639             : 
     640             : bool getSDKInfoFromRegistry(vector<OUString> & vecHome)
     641             : {
     642             :     return getJavaInfoFromRegistry(HKEY_SUN_SDK, vecHome);
     643             : }
     644             : 
     645             : bool getJREInfoFromRegistry(vector<OUString>& vecJavaHome)
     646             : {
     647             :     return getJavaInfoFromRegistry(HKEY_SUN_JRE, vecJavaHome);
     648             : }
     649             : 
     650             : #endif // WNT
     651             : 
     652           2 : void bubbleSortVersion(vector<rtl::Reference<VendorBase> >& vec)
     653             : {
     654           2 :     if(vec.empty())
     655           2 :         return;
     656           2 :     int size= vec.size() - 1;
     657           2 :     int cIter= 0;
     658             :     // sort for version
     659           2 :     for(int i= 0; i < size; i++)
     660             :     {
     661           0 :         for(int j= size; j > 0 + cIter; j--)
     662             :         {
     663           0 :             rtl::Reference<VendorBase>& cur= vec.at(j);
     664           0 :             rtl::Reference<VendorBase>& next= vec.at(j-1);
     665             : 
     666           0 :             int nCmp = 0;
     667             :             // comparing invalid SunVersion s is possible, they will be less than a
     668             :             // valid version
     669             : 
     670             :             //check if version of current is recognized, by comparing it with itself
     671             :             try
     672             :             {
     673           0 :                 cur->compareVersions(cur->getVersion());
     674             :             }
     675           0 :             catch (MalformedVersionException &)
     676             :             {
     677           0 :                 nCmp = -1; // current < next
     678             :             }
     679             :             //The version of cur is valid, now compare with the second version
     680           0 :             if (nCmp == 0)
     681             :             {
     682             :                 try
     683             :                 {
     684           0 :                     nCmp = cur->compareVersions(next->getVersion());
     685             :                 }
     686           0 :                 catch (MalformedVersionException & )
     687             :                 {
     688             :                     //The second version is invalid, therefor it is regardes less.
     689           0 :                     nCmp = 1;
     690             :                 }
     691             :             }
     692           0 :             if(nCmp == 1) // cur > next
     693             :             {
     694           0 :                 rtl::Reference<VendorBase> less = next;
     695           0 :                 vec.at(j-1)= cur;
     696           0 :                 vec.at(j)= less;
     697             :             }
     698             :         }
     699           0 :         ++cIter;
     700             :     }
     701             : }
     702             : 
     703             : 
     704          12 : bool getJREInfoFromBinPath(
     705             :     const OUString& path, vector<rtl::Reference<VendorBase> > & vecInfos)
     706             : {
     707             :     // file:///c:/jre/bin
     708             :     //map:       jre/bin/java.exe
     709          12 :     bool ret = false;
     710             : 
     711         204 :     for ( sal_Int32 pos = 0;
     712         102 :           gVendorMap[pos].sVendorName != NULL; ++pos )
     713             :     {
     714          92 :         vector<OUString> vecPaths;
     715          92 :         getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc;
     716             : 
     717          92 :         int size = 0;
     718          92 :         char const* const* arExePaths = (*pFunc)(&size);
     719          92 :         vecPaths = getVectorFromCharArray(arExePaths, size);
     720             : 
     721             :         //make sure argument path does not end with '/'
     722         182 :         OUString sBinPath = path;
     723          92 :         if (path.endsWith("/"))
     724           0 :             sBinPath = path.copy(0, path.getLength() - 1);
     725             : 
     726             :         typedef vector<OUString>::const_iterator c_it;
     727         352 :         for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i)
     728             :         {
     729             :             //the map contains e.g. jre/bin/java.exe
     730             :             //get the directory where the executable is contained
     731         262 :             OUString sHome;
     732         262 :             sal_Int32 index = i->lastIndexOf('/');
     733         262 :             if (index == -1)
     734             :             {
     735             :                 //map contained only : "java.exe, then the argument
     736             :                 //path is already the home directory
     737          62 :                 sHome = sBinPath;
     738             :             }
     739             :             else
     740             :             {
     741             :                 // jre/bin/jre -> jre/bin
     742         200 :                 OUString sMapPath(i->getStr(), index);
     743         200 :                 index = sBinPath.lastIndexOf(sMapPath);
     744         200 :                 if (index != -1
     745         120 :                     && (index + sMapPath.getLength() == sBinPath.getLength())
     746         320 :                     && sBinPath[index - 1] == '/')
     747             :                 {
     748          72 :                     sHome = sBinPath.copy(index - 1);
     749         200 :                 }
     750             :             }
     751         262 :             if (!sHome.isEmpty())
     752             :             {
     753         134 :                 ret = getJREInfoByPath(sHome, vecInfos);
     754         134 :                 if (ret)
     755           2 :                     break;
     756             :             }
     757         260 :         }
     758          92 :         if (ret)
     759           2 :             break;
     760          90 :     }
     761          12 :     return ret;
     762             : }
     763             : 
     764           2 : vector<Reference<VendorBase> > getAllJREInfos()
     765             : {
     766           2 :     vector<Reference<VendorBase> > vecInfos;
     767             : 
     768             : #if defined WNT
     769             :     // Get Javas from the registry
     770             :     createJavaInfoFromWinReg(vecInfos);
     771             : #endif // WNT
     772             : 
     773             : #ifndef JVM_ONE_PATH_CHECK
     774           2 :     createJavaInfoFromJavaHome(vecInfos);
     775             :     //this function should be called after createJavaInfoDirScan.
     776             :     //Otherwise in SDKs Java may be started twice
     777           2 :      createJavaInfoFromPath(vecInfos);
     778             : #endif
     779             : 
     780             : #ifdef UNX
     781           2 :     createJavaInfoDirScan(vecInfos);
     782             : #endif
     783             : 
     784           2 :     bubbleSortVersion(vecInfos);
     785           2 :     return vecInfos;
     786             : }
     787             : 
     788             : 
     789         608 : vector<OUString> getVectorFromCharArray(char const * const * ar, int size)
     790             : {
     791         608 :     vector<OUString> vec;
     792        2370 :     for( int i = 0; i < size; i++)
     793             :     {
     794        1762 :         OUString s(ar[i], strlen(ar[i]), RTL_TEXTENCODING_UTF8);
     795        1762 :         vec.push_back(s);
     796        1762 :     }
     797         608 :     return vec;
     798             : }
     799         170 : bool getJREInfoByPath(const OUString& path,
     800             :                       std::vector<rtl::Reference<VendorBase> > & vecInfos)
     801             : {
     802         170 :     bool ret = false;
     803             : 
     804         170 :     rtl::Reference<VendorBase> aInfo = getJREInfoByPath(path);
     805         170 :     if (aInfo.is())
     806             :     {
     807          28 :         ret = true;
     808             :         vector<rtl::Reference<VendorBase> >::const_iterator it_impl= std::find_if(
     809          28 :             vecInfos.begin(),vecInfos.end(), InfoFindSame(aInfo->getHome()));
     810          28 :         if(it_impl == vecInfos.end())
     811             :         {
     812           2 :             vecInfos.push_back(aInfo);
     813             :         }
     814             :     }
     815         170 :     return ret;
     816             : }
     817             : 
     818             : /** Checks if the path is a directory. Links are resolved.
     819             :     In case of an error the returned string has the length 0.
     820             :     Otherwise the returned string is the "resolved" file URL.
     821             :  */
     822         170 : OUString resolveDirPath(const OUString & path)
     823             : {
     824         170 :     OUString ret;
     825             :     salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type |
     826         340 :                                        osl_FileStatus_Mask_FileURL);
     827         170 :     if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None)
     828             :     {
     829             :         //check if this is a directory
     830          86 :         if (aResolver.m_aStatus.getFileType() == FileStatus::Directory)
     831             :         {
     832             : #ifndef JVM_ONE_PATH_CHECK
     833          84 :             ret = aResolver.m_aStatus.getFileURL();
     834             : #else
     835             :             ret = path;
     836             : #endif
     837             :         }
     838             :     }
     839         340 :     return ret;
     840             : }
     841             : /** Checks if the path is a file. If it is a link to a file than
     842             :     it is resolved.
     843             :  */
     844        1471 : OUString resolveFilePath(const OUString & path)
     845             : {
     846        1471 :     OUString ret;
     847             :     salhelper::LinkResolver aResolver(osl_FileStatus_Mask_Type |
     848        2942 :                                        osl_FileStatus_Mask_FileURL);
     849        1471 :     if (aResolver.fetchFileStatus(path) == osl::FileBase::E_None)
     850             :     {
     851             :         //check if this is a file
     852          12 :         if (aResolver.m_aStatus.getFileType() == FileStatus::Regular)
     853             :         {
     854             : #ifndef JVM_ONE_PATH_CHECK
     855           8 :             ret = aResolver.m_aStatus.getFileURL();
     856             : #else
     857             :             ret = path;
     858             : #endif
     859             :         }
     860             :     }
     861        2942 :     return ret;
     862             : }
     863             : 
     864         170 : rtl::Reference<VendorBase> getJREInfoByPath(
     865             :     const OUString& path)
     866             : {
     867         170 :     rtl::Reference<VendorBase> ret;
     868         170 :     static vector<OUString> vecBadPaths;
     869             : 
     870         170 :     static map<OUString, rtl::Reference<VendorBase> > mapJREs;
     871             :     typedef map<OUString, rtl::Reference<VendorBase> >::const_iterator MapIt;
     872             :     typedef map<OUString, rtl::Reference<VendorBase> > MAPJRE;
     873         340 :     OUString sFilePath;
     874             :     typedef vector<OUString>::const_iterator cit_path;
     875         340 :     vector<pair<OUString, OUString> > props;
     876             : 
     877         340 :     OUString sResolvedDir = resolveDirPath(path);
     878             :     // If this path is invalid then there is no chance to find a JRE here
     879         170 :     if (sResolvedDir.isEmpty())
     880          86 :         return 0;
     881             : 
     882             :     //check if the directory path is good, that is a JRE was already recognized.
     883             :     //Then we need not detect it again
     884             :     //For example, a sun JKD contains <jdk>/bin/java and <jdk>/jre/bin/java.
     885             :     //When <jdk>/bin/java has been found then we need not find <jdk>/jre/bin/java.
     886             :     //Otherwise we would execute java two times for evers JDK found.
     887             :     MapIt entry2 = find_if(mapJREs.begin(), mapJREs.end(),
     888          84 :                            SameOrSubDirJREMap(sResolvedDir));
     889          84 :     if (entry2 != mapJREs.end())
     890             :     {
     891             :         JFW_TRACE2(OUString("[Java framework] sunjavaplugin")
     892             :                    + SAL_DLLEXTENSION + ": "
     893             :                    + "JRE found again (detected before): " + sResolvedDir
     894             :                    + ".\n");
     895          20 :         return entry2->second;
     896             :     }
     897             : 
     898        1136 :     for ( sal_Int32 pos = 0;
     899         568 :           gVendorMap[pos].sVendorName != NULL; ++pos )
     900             :     {
     901         512 :         vector<OUString> vecPaths;
     902         512 :         getJavaExePaths_func pFunc = gVendorMap[pos].getJavaFunc;
     903             : 
     904         512 :         int size = 0;
     905         512 :         char const* const* arExePaths = (*pFunc)(&size);
     906         512 :         vecPaths = getVectorFromCharArray(arExePaths, size);
     907             : 
     908         512 :         bool bBreak = false;
     909             :         typedef vector<OUString>::const_iterator c_it;
     910        1975 :         for (c_it i = vecPaths.begin(); i != vecPaths.end(); ++i)
     911             :         {
     912             :             //if the path is a link, then resolve it
     913             :             //check if the executable exists at all
     914             : 
     915             :             //path can be only "file:///". Then do not append a '/'
     916             :             //sizeof counts the terminating 0
     917        1471 :             OUString sFullPath;
     918        1471 :             if (path.getLength() == sizeof("file:///") - 1)
     919           4 :                 sFullPath = sResolvedDir + (*i);
     920             :             else
     921        5868 :                 sFullPath = sResolvedDir +
     922        7335 :                 OUString("/") + (*i);
     923             : 
     924             : 
     925        1471 :             sFilePath = resolveFilePath(sFullPath);
     926             : 
     927        1471 :             if (sFilePath.isEmpty())
     928             :             {
     929             :                 //The file path (to java exe) is not valid
     930        1463 :                 cit_path ifull = find(vecBadPaths.begin(), vecBadPaths.end(), sFullPath);
     931        1463 :                 if (ifull == vecBadPaths.end())
     932          87 :                     vecBadPaths.push_back(sFullPath);
     933        1463 :                 continue;
     934             :             }
     935             : 
     936           8 :             cit_path ifile = find(vecBadPaths.begin(), vecBadPaths.end(), sFilePath);
     937           8 :             if (ifile != vecBadPaths.end())
     938           0 :                 continue;
     939             : 
     940           8 :             MapIt entry =  mapJREs.find(sFilePath);
     941           8 :             if (entry != mapJREs.end())
     942             :             {
     943             :                 JFW_TRACE2(OUString("[Java framework] sunjavaplugin")
     944             :                    + SAL_DLLEXTENSION + ": "
     945             :                    + "JRE found again (detected before): " + sFilePath
     946             :                    + ".\n");
     947             : 
     948           6 :                 return entry->second;
     949             :             }
     950             : 
     951           2 :             bool bProcessRun= false;
     952           2 :             if (getJavaProps(sFilePath,
     953             : #ifdef JVM_ONE_PATH_CHECK
     954             :                              sResolvedDir,
     955             : #endif
     956           2 :                              props, & bProcessRun) == false)
     957             :             {
     958             :                 //The java executable could not be run or the system properties
     959             :                 //could not be retrieved. We can assume that this java is corrupt.
     960           0 :                 vecBadPaths.push_back(sFilePath);
     961             :                 //If there was a java executable, that could be run but we did not get
     962             :                 //the system properties, then we also assume that the whole Java installation
     963             :                 //does not work. In a jdk there are two executables. One in jdk/bin and the other
     964             :                 //in jdk/jre/bin. We do not search any further, because we assume that if one java
     965             :                 //does not work then the other does not work as well. This saves us to run java
     966             :                 //again which is quite costly.
     967           0 :                 if (bProcessRun == true)
     968             :                 {
     969             :                     // 1.3.1 special treatment: jdk/bin/java and /jdk/jre/bin/java are links to
     970             :                     //a script, named .java_wrapper. The script starts jdk/bin/sparc/native_threads/java
     971             :                     //or jdk/jre/bin/sparc/native_threads/java. The script uses the name with which it was
     972             :                     //invoked to build the path to the executable. It we start the script directy as .java_wrapper
     973             :                     //then it tries to start a jdk/.../native_threads/.java_wrapper. Therefore the link, which
     974             :                     //is named java, must be used to start the script.
     975             :                     getJavaProps(sFullPath,
     976             : #ifdef JVM_ONE_PATH_CHECK
     977             :                                  sResolvedDir,
     978             : #endif
     979           0 :                                  props, & bProcessRun);
     980             :                     // Either we found a working 1.3.1
     981             :                     //Or the java is broken. In both cases we stop searchin under this "root" directory
     982           0 :                     bBreak = true;
     983           0 :                     break;
     984             :                 }
     985             :                 //sFilePath is no working java executable. We continue with another possible
     986             :                 //path.
     987             :                 else
     988             :                 {
     989           0 :                     continue;
     990             :                 }
     991             :             }
     992             :             //sFilePath is a java and we could get the system properties. We proceed with this
     993             :             //java.
     994             :             else
     995             :             {
     996           2 :                 bBreak = true;
     997           2 :                 break;
     998             :             }
     999           0 :         }
    1000         506 :         if (bBreak)
    1001           2 :             break;
    1002         504 :     }
    1003             : 
    1004          58 :     if (props.empty())
    1005          56 :         return rtl::Reference<VendorBase>();
    1006             : 
    1007             :     //find java.vendor property
    1008             :     typedef vector<pair<OUString, OUString> >::const_iterator c_ip;
    1009           4 :     OUString sVendor("java.vendor");
    1010           4 :     OUString sVendorName;
    1011             : 
    1012          92 :     for (c_ip i = props.begin(); i != props.end(); ++i)
    1013             :     {
    1014          92 :         if (sVendor.equals(i->first))
    1015             :         {
    1016           2 :             sVendorName = i->second;
    1017           2 :             break;
    1018             :         }
    1019             :     }
    1020             : 
    1021           2 :     if (!sVendorName.isEmpty())
    1022             :     {
    1023             :         //find the creator func for the respective vendor name
    1024           8 :         for ( sal_Int32 c = 0;
    1025           4 :               gVendorMap[c].sVendorName != NULL; ++c )
    1026             :         {
    1027           4 :             OUString sNameMap(gVendorMap[c].sVendorName, strlen(gVendorMap[c].sVendorName),
    1028           4 :                               RTL_TEXTENCODING_ASCII_US);
    1029           4 :             if (sNameMap.equals(sVendorName))
    1030             :             {
    1031           2 :                 ret = createInstance(gVendorMap[c].createFunc, props);
    1032           2 :                 break;
    1033             :             }
    1034           2 :         }
    1035             :     }
    1036           2 :     if (!ret.is())
    1037           0 :         vecBadPaths.push_back(sFilePath);
    1038             :     else
    1039             :     {
    1040             :         JFW_TRACE2(OUString("[Java framework] sunjavaplugin")
    1041             :                    + SAL_DLLEXTENSION + ": "
    1042             :                    + "Found JRE: " + sResolvedDir
    1043             :                    + " \n at: " + path + ".\n");
    1044             : 
    1045           2 :         mapJREs.insert(MAPJRE::value_type(sResolvedDir, ret));
    1046           2 :         mapJREs.insert(MAPJRE::value_type(sFilePath, ret));
    1047             :     }
    1048             : 
    1049         172 :     return ret;
    1050             : }
    1051             : 
    1052           2 : Reference<VendorBase> createInstance(createInstance_func pFunc,
    1053             :                                      vector<pair<OUString, OUString> > properties)
    1054             : {
    1055             : 
    1056           2 :     Reference<VendorBase> aBase = (*pFunc)();
    1057           2 :     if (aBase.is())
    1058             :     {
    1059           2 :         if (aBase->initialize(properties) == false)
    1060           0 :             aBase = 0;
    1061             :     }
    1062           2 :     return aBase;
    1063             : }
    1064             : 
    1065           3 : inline OUString getDirFromFile(const OUString& usFilePath)
    1066             : {
    1067           3 :     sal_Int32 index = usFilePath.lastIndexOf('/');
    1068           3 :     return usFilePath.copy(0, index);
    1069             : }
    1070             : 
    1071           2 : void createJavaInfoFromPath(vector<rtl::Reference<VendorBase> >& vecInfos)
    1072             : {
    1073             : // Get Java from PATH environment variable
    1074           2 :     static OUString sCurDir(".");
    1075           2 :     static OUString sParentDir("..");
    1076           2 :     char *szPath= getenv("PATH");
    1077           2 :     if(szPath)
    1078             :     {
    1079           2 :         OUString usAllPath(szPath, strlen(szPath), osl_getThreadTextEncoding());
    1080           2 :         sal_Int32 nIndex = 0;
    1081          12 :         do
    1082             :         {
    1083          12 :             OUString usToken = usAllPath.getToken( 0, SAL_PATHSEPARATOR, nIndex );
    1084          24 :             OUString usTokenUrl;
    1085          12 :             if(File::getFileURLFromSystemPath(usToken, usTokenUrl) == File::E_None)
    1086             :             {
    1087          12 :                 if(!usTokenUrl.isEmpty())
    1088             :                 {
    1089          12 :                     OUString usBin;
    1090             :                     // "."
    1091          12 :                     if(usTokenUrl.equals(sCurDir))
    1092             :                     {
    1093           0 :                         OUString usWorkDirUrl;
    1094           0 :                         if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDirUrl.pData))
    1095           0 :                             usBin= usWorkDirUrl;
    1096             :                     }
    1097             :                     // ".."
    1098          12 :                     else if(usTokenUrl.equals(sParentDir))
    1099             :                     {
    1100           0 :                         OUString usWorkDir;
    1101           0 :                         if(osl_Process_E_None == osl_getProcessWorkingDir(&usWorkDir.pData))
    1102           0 :                             usBin= getDirFromFile(usWorkDir);
    1103             :                     }
    1104             :                     else
    1105             :                     {
    1106          12 :                         usBin = usTokenUrl;
    1107             :                     }
    1108          12 :                     if(!usBin.isEmpty())
    1109             :                     {
    1110          12 :                         getJREInfoFromBinPath(usBin, vecInfos);
    1111          12 :                     }
    1112             :                 }
    1113          12 :             }
    1114             :         }
    1115          14 :         while ( nIndex >= 0 );
    1116             :     }
    1117           2 : }
    1118             : 
    1119           2 : void createJavaInfoFromJavaHome(vector<rtl::Reference<VendorBase> >& vecInfos)
    1120             : {
    1121             :     // Get Java from JAVA_HOME environment
    1122           2 :     char *szJavaHome= getenv("JAVA_HOME");
    1123           2 :     if(szJavaHome)
    1124             :     {
    1125           0 :         OUString sHome(szJavaHome,strlen(szJavaHome),osl_getThreadTextEncoding());
    1126           0 :         OUString sHomeUrl;
    1127           0 :         if(File::getFileURLFromSystemPath(sHome, sHomeUrl) == File::E_None)
    1128             :         {
    1129           0 :             getJREInfoByPath(sHomeUrl, vecInfos);
    1130           0 :         }
    1131             :     }
    1132           2 : }
    1133             : 
    1134           2 : bool makeDriveLetterSame(OUString * fileURL)
    1135             : {
    1136           2 :     bool ret = false;
    1137           2 :     DirectoryItem item;
    1138           2 :     if (DirectoryItem::get(*fileURL, item) == File::E_None)
    1139             :     {
    1140           2 :         FileStatus status(osl_FileStatus_Mask_FileURL);
    1141           2 :         if (item.getFileStatus(status) == File::E_None)
    1142             :         {
    1143           2 :             *fileURL = status.getFileURL();
    1144           2 :             ret = true;
    1145           2 :         }
    1146             :     }
    1147           2 :     return ret;
    1148             : }
    1149             : 
    1150             : #ifdef UNX
    1151             : #ifdef SOLARIS
    1152             : 
    1153             : void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
    1154             : {
    1155             :     JFW_TRACE2("\n[Java framework] Checking \"/usr/jdk/latest\"\n");
    1156             :     getJREInfoByPath("file:////usr/jdk/latest", vecInfos);
    1157             : }
    1158             : 
    1159             : #elif defined MACOSX && defined X86_64
    1160             : 
    1161             : void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
    1162             : {
    1163             :     // Oracle Java 7
    1164             :     getJREInfoByPath("file:///Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home", vecInfos);
    1165             : }
    1166             : 
    1167             : #else
    1168           2 : void createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
    1169             : {
    1170             :     OUString excMessage = "[Java framework] sunjavaplugin: "
    1171           2 :                           "Error in function createJavaInfoDirScan in util.cxx.";
    1172           2 :     int cJavaNames= sizeof(g_arJavaNames) / sizeof(char*);
    1173           4 :     boost::scoped_array<OUString> sarJavaNames(new OUString[cJavaNames]);
    1174           2 :     OUString *arNames = sarJavaNames.get();
    1175          20 :     for(int i= 0; i < cJavaNames; i++)
    1176          36 :         arNames[i] = OUString(g_arJavaNames[i], strlen(g_arJavaNames[i]),
    1177          18 :                               RTL_TEXTENCODING_UTF8);
    1178             : 
    1179           2 :     int cSearchPaths= sizeof(g_arSearchPaths) / sizeof(char*);
    1180           4 :     boost::scoped_array<OUString> sarPathNames(new OUString[cSearchPaths]);
    1181           2 :     OUString *arPaths = sarPathNames.get();
    1182          16 :     for(int c = 0; c < cSearchPaths; c++)
    1183          28 :         arPaths[c] = OUString(g_arSearchPaths[c], strlen(g_arSearchPaths[c]),
    1184          14 :                                RTL_TEXTENCODING_UTF8);
    1185             : 
    1186           2 :     int cCollectDirs = sizeof(g_arCollectDirs) / sizeof(char*);
    1187           4 :     boost::scoped_array<OUString> sarCollectDirs(new OUString[cCollectDirs]);
    1188           2 :     OUString *arCollectDirs = sarCollectDirs.get();
    1189          18 :     for(int d = 0; d < cCollectDirs; d++)
    1190          32 :         arCollectDirs[d] = OUString(g_arCollectDirs[d], strlen(g_arCollectDirs[d]),
    1191          16 :                                RTL_TEXTENCODING_UTF8);
    1192             : 
    1193             : 
    1194             : 
    1195           4 :     OUString usFile("file:///");
    1196          16 :     for( int ii = 0; ii < cSearchPaths; ii ++)
    1197             :     {
    1198          14 :         OUString usDir1(usFile + arPaths[ii]);
    1199          28 :         DirectoryItem item;
    1200          14 :         if(DirectoryItem::get(usDir1, item) == File::E_None)
    1201             :         {
    1202          90 :             for(int j= 0; j < cCollectDirs; j++)
    1203             :             {
    1204          80 :                 OUString usDir2(usDir1 + arCollectDirs[j]);
    1205             :                 // prevent that we scan the whole /usr, /usr/lib, etc directories
    1206          80 :                 if (!arCollectDirs[j].isEmpty())
    1207             :                 {
    1208             :                     //usr/java/xxx
    1209             :                     //Examin every subdirectory
    1210          70 :                     Directory aCollectionDir(usDir2);
    1211             : 
    1212          70 :                     Directory::RC openErr = aCollectionDir.open();
    1213          70 :                     switch (openErr)
    1214             :                     {
    1215             :                     case File::E_None:
    1216           4 :                         break;
    1217             :                     case File::E_NOENT:
    1218             :                     case File::E_NOTDIR:
    1219          66 :                         continue;
    1220             :                     case File::E_ACCES:
    1221             :                         JFW_TRACE2(OUString("[Java framework] sunjavaplugin: ")
    1222             :                                    + "Could not read directory " + usDir2
    1223             :                                    + " because of missing access rights.");
    1224           0 :                         continue;
    1225             :                     default:
    1226             :                         JFW_TRACE2(OUString("[Java framework] sunjavaplugin: ")
    1227             :                                    + "Could not read directory "
    1228             :                                    + usDir2 + ". Osl file error: "
    1229             :                                    + OUString::number(openErr));
    1230           0 :                         continue;
    1231             :                     }
    1232             : 
    1233           4 :                     DirectoryItem curIt;
    1234           4 :                     File::RC errNext = File::E_None;
    1235          30 :                     while( (errNext = aCollectionDir.getNextItem(curIt)) == File::E_None)
    1236             :                     {
    1237          22 :                         FileStatus aStatus(osl_FileStatus_Mask_FileURL);
    1238          22 :                         File::RC errStatus = File::E_None;
    1239          22 :                         if ((errStatus = curIt.getFileStatus(aStatus)) != File::E_None)
    1240             :                         {
    1241             :                             JFW_TRACE2(excMessage + "getFileStatus failed with error "
    1242             :                                 + OUString::number(errStatus));
    1243           0 :                             continue;
    1244             :                         }
    1245             :                         JFW_TRACE2(OUString("[Java framework] sunjavaplugin: ") +
    1246             :                                    "Checking if directory: " + aStatus.getFileURL() +
    1247             :                                    " is a Java. \n");
    1248             : 
    1249          22 :                         getJREInfoByPath(aStatus.getFileURL(),vecInfos);
    1250          22 :                     }
    1251             : 
    1252             :                     JFW_ENSURE(errNext == File::E_None || errNext == File::E_NOENT,
    1253             :                                 OUString("[Java framework] sunjavaplugin: ")
    1254             :                                 + "Error while iterating over contens of "
    1255             :                                 + usDir2 + ". Osl file error: "
    1256           4 :                                 + OUString::number(openErr));
    1257             :                 }
    1258             :                 else
    1259             :                 {
    1260             :                     //usr/java
    1261             :                     //When we look directly into a dir like /usr, /usr/lib, etc. then we only
    1262             :                     //look for certain java directories, such as jre, jdk, etc. Whe do not want
    1263             :                     //to examine the whole directory because of performance reasons.
    1264          10 :                     DirectoryItem item2;
    1265          10 :                     if(DirectoryItem::get(usDir2, item2) == File::E_None)
    1266             :                     {
    1267         100 :                         for( int k= 0; k < cJavaNames; k++)
    1268             :                         {
    1269             :                             // /usr/java/j2re1.4.0
    1270          90 :                             OUString usDir3(usDir2 + arNames[k]);
    1271             : 
    1272         180 :                             DirectoryItem item3;
    1273          90 :                             if(DirectoryItem::get(usDir3, item) == File::E_None)
    1274             :                             {
    1275             :                                 //remove trailing '/'
    1276          14 :                                 sal_Int32 islash = usDir3.lastIndexOf('/');
    1277          28 :                                 if (islash == usDir3.getLength() - 1
    1278          24 :                                     && (islash
    1279          10 :                                         > RTL_CONSTASCII_LENGTH("file://")))
    1280           8 :                                     usDir3 = usDir3.copy(0, islash);
    1281          14 :                                 getJREInfoByPath(usDir3,vecInfos);
    1282             :                             }
    1283          90 :                         }
    1284          10 :                     }
    1285             :                 }
    1286          14 :             }
    1287             :         }
    1288          16 :     }
    1289           2 : }
    1290             : #endif // ifdef SOLARIS
    1291             : #endif // ifdef UNX
    1292             : }
    1293             : 
    1294             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10