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

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

Generated by: LCOV version 1.10