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

Generated by: LCOV version 1.10