extensions/Library_pl.mk | 4 extensions/source/plugin/aqua/macmgr.cxx | 654 ------------------------------- extensions/source/plugin/aqua/macmgr.mm | 654 +++++++++++++++++++++++++++++++ 3 files changed, 655 insertions(+), 657 deletions(-)
New commits: commit 29f897054d472746ce0cf59a39142ec5ec3114c1 Author: Matúš Kukan <matus.ku...@gmail.com> Date: Mon Jan 9 12:41:51 2012 +0100 extensions/Library_pl: move macmgr.cxx -> macmgr.mm diff --git a/extensions/Library_pl.mk b/extensions/Library_pl.mk index cf74ce8..b6a3700 100644 --- a/extensions/Library_pl.mk +++ b/extensions/Library_pl.mk @@ -93,10 +93,8 @@ ifeq ($(GUI),UNX) ifeq ($(GUIBASE),aqua) -$(eval $(call gb_Library_add_exception_objects,pl,\ - extensions/source/plugin/aqua/macmgr \ -)) $(eval $(call gb_Library_add_objcxxobjects,pl,\ + extensions/source/plugin/aqua/macmgr \ extensions/source/plugin/aqua/sysplug \ )) diff --git a/extensions/source/plugin/aqua/macmgr.cxx b/extensions/source/plugin/aqua/macmgr.cxx deleted file mode 100644 index 3b69845..0000000 --- a/extensions/source/plugin/aqua/macmgr.cxx +++ /dev/null @@ -1,654 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#include "rtl/ustrbuf.hxx" -#include "rtl/strbuf.hxx" - -#include "plugin/impl.hxx" -#include "osl/file.h" -#include "osl/module.hxx" - -using namespace std; -using namespace com::sun::star::uno; -using namespace com::sun::star::plugin; - -using ::rtl::OUString; -using ::rtl::OString; -using ::rtl::OUStringBuffer; -using ::rtl::OStringBuffer; -using ::rtl::OUStringToOString; -using ::rtl::OStringToOUString; - -namespace plugstringhelper -{ - -rtl::OUString getString( CFStringRef i_xString ) -{ - rtl::OUStringBuffer aBuf; - if( i_xString ) - { - CFIndex nChars = CFStringGetLength( i_xString ); - CFRange aRange = { 0, nChars }; - aBuf.setLength( nChars ); - CFStringGetCharacters( i_xString, aRange, static_cast< UniChar* >(const_cast<sal_Unicode*>(aBuf.getStr())) ); - } - return aBuf.makeStringAndClear(); -} - -rtl::OUString getString( CFURLRef i_xURL ) -{ - CFStringRef xString = CFURLGetString( i_xURL ); - return getString( xString ); -} - -CFMutableStringRef createString( const rtl::OUString& i_rString ) -{ - CFMutableStringRef xString = CFStringCreateMutable( NULL, 0 ); - if( xString ) - CFStringAppendCharacters( xString, i_rString.getStr(), i_rString.getLength() ); - return xString; -} - -CFURLRef createURL( const rtl::OUString& i_rString ) -{ - - CFMutableStringRef xMutableString = createString( i_rString ); - CFURLRef xURL = CFURLCreateWithString( NULL, xMutableString, NULL ); - CFRelease( xMutableString ); - return xURL; -} - -rtl::OUString getURLFromPath( const rtl::OUString& i_rPath ) -{ - CFMutableStringRef xMutableString = createString( i_rPath ); - CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); - CFRelease( xMutableString ); - CFStringRef xString = CFURLGetString( xURL ); - rtl::OUString aRet = getString( xString ); - CFRelease( xURL ); - return aRet; -} - -CFURLRef createURLFromPath( const rtl::OUString& i_rPath ) -{ - CFMutableStringRef xMutableString = createString( i_rPath ); - CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); - return xURL; -} - -rtl::OUString CFURLtoOSLURL( CFURLRef i_xURL ) -{ - // make URL absolute - CFURLRef xAbsURL = CFURLCopyAbsoluteURL( i_xURL ); - // copy system path - CFStringRef xSysPath = CFURLCopyFileSystemPath( xAbsURL ? xAbsURL : i_xURL, kCFURLPOSIXPathStyle ); - if( xAbsURL ) - CFRelease( xAbsURL ); - rtl::OUString aSysPath( getString( xSysPath ) ); - CFRelease( xSysPath ); - rtl::OUString aFileURL; - osl_getFileURLFromSystemPath( aSysPath.pData, &aFileURL.pData ); - return aFileURL; -} - -} - -using namespace plugstringhelper; - -static int parsePlist( CFBundleRef i_xBundle, const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions ) -{ - CFTypeRef xMimeDict = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginMIMETypes")); - int nMimetypes = 0; - if( xMimeDict == 0 || - CFGetTypeID(xMimeDict) != CFDictionaryGetTypeID() || - (nMimetypes = CFDictionaryGetCount( static_cast<CFDictionaryRef>(xMimeDict))) <= 0 ) - { - return 0; - } - - // prepare an array of key and value refs - std::vector< CFTypeRef > aKeys( nMimetypes, CFTypeRef(NULL) ); - std::vector< CFTypeRef > aValues( nMimetypes, CFTypeRef(NULL) ); - CFDictionaryGetKeysAndValues(static_cast<CFDictionaryRef>(xMimeDict), &aKeys[0], &aValues[0] ); - - int nAdded = 0; - for( int i = 0; i < nMimetypes; i++ ) - { - // get the mimetype - CFTypeRef xKey = aKeys[i]; - if( ! xKey || CFGetTypeID(xKey) != CFStringGetTypeID() ) - continue; - rtl::OUString aMimetype = getString( (CFStringRef)xKey ); - - // the correspoding value should be a dictionary - CFTypeRef xDict = aValues[i]; - if( ! xDict || CFGetTypeID( xDict ) != CFDictionaryGetTypeID() ) - continue; - - // get the extension list - CFTypeRef xExtArray = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginExtensions" ) ); - if( !xExtArray || CFGetTypeID( xExtArray ) != CFArrayGetTypeID() ) - continue; - - OUStringBuffer aExtBuf; - int nExtensions = CFArrayGetCount( (CFArrayRef)xExtArray ); - for( int n = 0; n < nExtensions; n++ ) - { - CFTypeRef xExt = CFArrayGetValueAtIndex( (CFArrayRef)xExtArray, n ); - if( xExt && CFGetTypeID( xExt ) == CFStringGetTypeID() ) - { - if( aExtBuf.getLength() > 0 ) - aExtBuf.append( sal_Unicode(';') ); - OUString aExt( getString( (CFStringRef)xExt ) ); - if( aExt.indexOfAsciiL( "*.", 2 ) != 0 ) - aExtBuf.appendAscii( "*." ); - aExtBuf.append( aExt ); - } - } - - // get the description string - CFTypeRef xDescString = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginTypeDescription" ) ); - if( !xDescString || CFGetTypeID( xDescString ) != CFStringGetTypeID() ) - continue; - rtl::OUString aDescription = getString( (CFStringRef)xDescString ); - - PluginDescription* pNew = new PluginDescription; - // set plugin name (path to library) - pNew->PluginName = i_rBundleURL; - // set mimetype - pNew->Mimetype = aMimetype; - // set extension line - pNew->Extension = aExtBuf.makeStringAndClear(); - // set description - pNew->Description= aDescription; - - io_rDescriptions.push_back( pNew ); - nAdded++; - -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, - "Inserting from PList:\n" - " Mimetype: %s\n" - " Extension: %s\n" - " Description: %s\n", - OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr() - ); -#endif - - } - - return nAdded; -} - -static int parseMimeString( const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions, const char* i_pMime ) -{ - if( ! i_pMime ) - return 0; - - rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); - - OStringBuffer aMIME; - aMIME.append( i_pMime ); - - if( aMIME.getLength() < 1 ) - return 0; - - OString aLine = aMIME.makeStringAndClear(); - - int nAdded = 0; - sal_Int32 nIndex = 0; - while( nIndex != -1 ) - { - OString aType = aLine.getToken( 0, ';', nIndex ); - - sal_Int32 nTypeIndex = 0; - OString aMimetype = aType.getToken( 0, ':', nTypeIndex ); - OString aExtLine = aType.getToken( 0, ':', nTypeIndex ); - if( nTypeIndex < 0 ) // ensure at least three tokens - continue; - OString aDesc = aType.getToken( 0, ':', nTypeIndex ); - - // create extension list string - sal_Int32 nExtIndex = 0; - OStringBuffer aExtension; - while( nExtIndex != -1 ) - { - OString aExt = aExtLine.getToken( 0, ',', nExtIndex); - if( aExt.indexOf( "*." ) != 0 ) - aExtension.append( "*." ); - aExtension.append( aExt ); - if( nExtIndex != -1 ) - aExtension.append( ';' ); - } - - PluginDescription* pNew = new PluginDescription; - // set plugin name (path to library) - pNew->PluginName = i_rBundleURL; - // set mimetype - pNew->Mimetype = OStringToOUString( aMimetype, aEncoding ); - // set extension line - pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding ); - // set description - pNew->Description= OStringToOUString( aDesc, aEncoding ); - io_rDescriptions.push_back( pNew ); - nAdded++; - -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, - "Inserting from mime string:\n" - " Mimetype: %s\n" - " Extension: %s\n" - " Description: %s\n", - OUStringToOString( pNew->Mimetype, aEncoding ).getStr(), - OUStringToOString( pNew->Extension, aEncoding ).getStr(), - OUStringToOString( pNew->Description, aEncoding ).getStr() - ); -#endif - } - return nAdded; -} - -// this is so ugly it you want to tear your eyes out -static rtl::OUString GetNextPluginStringFromHandle(Handle h, short *index) -{ - char* pPascalBytes = (*h + *index); - sal_uInt32 nLen = (unsigned char)pPascalBytes[0]; - rtl::OStringBuffer aBuf( nLen ); - aBuf.append( pPascalBytes+1, nLen ); - *index += nLen + 1; - return rtl::OStringToOUString( aBuf.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); -} - -static int parseMimeResource( CFBundleRef i_xBundle, - oslModule& i_rMod, - const rtl::OUString& i_rBundleURL, - list< PluginDescription* >& io_rDescriptions ) -{ - int nAdded = 0; - // just to hurt our eyes more there is an alternative mimetype function plus the possibility - // of a resource fork. Must be a case of think different. - #if __LP64__ - int - #else - SInt16 - #endif - xRes = 0; - BPSupportedMIMETypes aMIMETypesStrangeStruct = {kBPSupportedMIMETypesStructVers_1, NULL, NULL}; - - BP_GetSupportedMIMETypesUPP pBPGetSupp = (BP_GetSupportedMIMETypesUPP)osl_getAsciiFunctionSymbol( i_rMod, "BP_GetSupportedMIMETypes" ); - if( pBPGetSupp && - noErr == pBPGetSupp( &aMIMETypesStrangeStruct, 0 ) && - aMIMETypesStrangeStruct.typeStrings ) - { - HLock( aMIMETypesStrangeStruct.typeStrings ); - if( aMIMETypesStrangeStruct.infoStrings ) // it's possible some plugins have infoStrings missing - HLock( aMIMETypesStrangeStruct.infoStrings ); - } - else // Try to get data from the resource fork - { - xRes = CFBundleOpenBundleResourceMap( i_xBundle ); - if( xRes > 0 ) - { - aMIMETypesStrangeStruct.typeStrings = Get1Resource('STR#', 128); - if( aMIMETypesStrangeStruct.typeStrings ) - { - DetachResource( aMIMETypesStrangeStruct.typeStrings ); - HLock( aMIMETypesStrangeStruct.typeStrings ); - aMIMETypesStrangeStruct.infoStrings = Get1Resource('STR#', 127); - if( aMIMETypesStrangeStruct.infoStrings ) - { - DetachResource( aMIMETypesStrangeStruct.infoStrings ); - HLock( aMIMETypesStrangeStruct.infoStrings ); - } - } - } - } - - if( aMIMETypesStrangeStruct.typeStrings && aMIMETypesStrangeStruct.infoStrings ) - { - short nVariantCount = (**(short**)aMIMETypesStrangeStruct.typeStrings) / 2; - // Fill in the info struct based on the data in the BPSupportedMIMETypes struct - // this is an array of pascal string of unknown (!) encoding - // whoever thought of this deserves a fair beating - short mimeIndex = 2; - short descriptionIndex = 2; - for( int i = 0; i < nVariantCount; i++ ) - { - rtl::OUString aMimetype = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex ); - rtl::OUString aExtLine = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex ); - rtl::OUString aDescription; - if( aMIMETypesStrangeStruct.infoStrings ) - aDescription = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.infoStrings, &descriptionIndex ); - - // create extension list string - sal_Int32 nExtIndex = 0; - OUStringBuffer aExtension; - while( nExtIndex != -1 ) - { - OUString aExt = aExtLine.getToken( 0, ',', nExtIndex); - if( aExt.indexOfAsciiL( "*.", 2 ) != 0 ) - aExtension.appendAscii( "*." ); - aExtension.append( aExt ); - if( nExtIndex != -1 ) - aExtension.append( sal_Unicode(';') ); - } - - PluginDescription* pNew = new PluginDescription; - // set plugin name (path to library) - pNew->PluginName = i_rBundleURL; - // set mimetype - pNew->Mimetype = aMimetype; - // set extension line - pNew->Extension = aExtension.makeStringAndClear(); - // set description - pNew->Description= aDescription; - io_rDescriptions.push_back( pNew ); - nAdded++; - - #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, - "Inserting from resource:\n" - " Mimetype: %s\n" - " Extension: %s\n" - " Description: %s\n", - OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(), - OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr() - ); - #endif - } - } - - - // clean up - if( aMIMETypesStrangeStruct.typeStrings ) - { - HUnlock( aMIMETypesStrangeStruct.typeStrings ); - DisposeHandle( aMIMETypesStrangeStruct.typeStrings ); - } - if( aMIMETypesStrangeStruct.infoStrings ) - { - HUnlock( aMIMETypesStrangeStruct.infoStrings ); - DisposeHandle( aMIMETypesStrangeStruct.infoStrings ); - } - if( xRes ) - CFBundleCloseBundleResourceMap( i_xBundle, xRes ); - - return nAdded; -} - -// check some known bad plugins to avoid crashes -static bool checkBlackList( CFBundleRef i_xBundle ) -{ - rtl::OUString aBundleName; - CFTypeRef bundlename = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleName")); - if( bundlename && CFGetTypeID(bundlename) == CFStringGetTypeID() ) - aBundleName = getString( static_cast<CFStringRef>(bundlename) ); - - rtl::OUString aBundleVersion; - CFTypeRef bundleversion = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleVersion")); - if( bundleversion && CFGetTypeID(bundleversion) == CFStringGetTypeID() ) - aBundleVersion = getString( static_cast<CFStringRef>(bundleversion) ); - - bool bReject = false; - // #i102735# VLC plugin prior to 1.0 tends to crash - if( aBundleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VLC Plug-in" ) ) ) - { - sal_Int32 nIndex = 0; - rtl::OUString aMajor( aBundleVersion.getToken( 0, '.', nIndex ) ); - if( aMajor.toInt32() < 1 ) - { - bReject = true; - } - } - // #i103674# Garmin Communicator Plugin crashes - else if( aBundleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Garmin Communicator Plugin" ) ) ) - { - bReject = true; - } - - #if OSL_DEBUG_LEVEL > 1 - if( bReject ) - fprintf( stderr, "rejecting plugin \"%s\" version %s\n", - rtl::OUStringToOString( aBundleName, RTL_TEXTENCODING_UTF8 ).getStr(), - rtl::OUStringToOString( aBundleVersion, RTL_TEXTENCODING_UTF8 ).getStr() - ); - #endif - - return bReject; -} - -static int getPluginDescriptions( CFBundleRef i_xBundle , list< PluginDescription* >& io_rDescriptions ) -{ - int nDescriptions = 0; - if( ! i_xBundle ) - return nDescriptions; - - if( checkBlackList( i_xBundle ) ) - return 0; - - rtl::OUString aPlugURL; - CFURLRef xURL = CFBundleCopyBundleURL( i_xBundle ); - aPlugURL = getString( xURL ); - CFRelease( xURL ); - - #if OSL_DEBUG_LEVEL > 1 - rtl::OUString aPlugName, aPlugDescription; - CFTypeRef name = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginName")); - if( name && CFGetTypeID(name) == CFStringGetTypeID() ) - aPlugName = getString( static_cast<CFStringRef>(name) ); - - CFTypeRef description = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginDescription")); - if( description && CFGetTypeID(description) == CFStringGetTypeID() ) - aPlugDescription = getString( static_cast<CFStringRef>(description) ); - - fprintf( stderr, "URL: %s\nname: %s\ndescription: %s\n", - rtl::OUStringToOString( aPlugURL, RTL_TEXTENCODING_UTF8 ).getStr(), - rtl::OUStringToOString( aPlugName, RTL_TEXTENCODING_UTF8 ).getStr(), - rtl::OUStringToOString( aPlugDescription, RTL_TEXTENCODING_UTF8 ).getStr() - ); - #endif - - - // get location of plugin library - CFURLRef xLibURL = CFBundleCopyExecutableURL( i_xBundle ); - if( ! xLibURL ) - return 0; - // get the file system path - rtl::OUString aModuleURL( CFURLtoOSLURL( xLibURL ) ); - CFRelease( xLibURL ); - - #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "exec URL = %s\n", rtl::OUStringToOString( aModuleURL, RTL_TEXTENCODING_UTF8 ).getStr() ); - #endif - - /* TODO: originally the C++ wrapper for oslModule was used here, but that led to - mysterious crashes in the event loop (pointing to heap corruption). Why using - the C style oslModule should fix this is completely unknown. It may be that - we have just hidden the heap corruption a little more. - */ - oslModule aMod = osl_loadModule( aModuleURL.pData, SAL_LOADMODULE_DEFAULT ); - if( ! aMod ) - return 0; - - // check for at least the init function of a plugin - if( ! osl_getAsciiFunctionSymbol( aMod, "NP_Initialize") && - ! osl_getAsciiFunctionSymbol( aMod, "NP_GetEntryPoints" ) ) - { - return 0; - } - - // ask the plist of the bundle for mimetypes - nDescriptions = parsePlist( i_xBundle, aPlugURL, io_rDescriptions ); - if( nDescriptions ) - { - osl_unloadModule( aMod ); - return nDescriptions; - } - - // resolve the symbol that might get us the mimetypes - const char* (*pGetMimeDescription)() = (const char*(*)())osl_getAsciiFunctionSymbol( aMod, "_NP_GetMIMEDescription" ); - if( pGetMimeDescription ) - { - const char* pMime = pGetMimeDescription(); - if( pMime ) - { - nDescriptions = parseMimeString( aPlugURL, io_rDescriptions, pMime ); - if( nDescriptions ) - { - osl_unloadModule( aMod ); - return nDescriptions; - } - } - } - - // and as last resort check the resource of the bundle - nDescriptions = parseMimeResource( i_xBundle, aMod, aPlugURL, io_rDescriptions ); - osl_unloadModule( aMod ); - - return nDescriptions; -} - -// Unix specific implementation -static bool CheckPlugin( const rtl::OUString& rPath, list< PluginDescription* >& rDescriptions ) -{ -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "Trying path %s ... ", rtl::OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getStr() ); -#endif - CFURLRef xURL = createURL( rPath ); - - CFArrayRef xBundles = CFBundleCreateBundlesFromDirectory( NULL, xURL, CFSTR("plugin") ); - if( ! xBundles ) - return false; - - CFIndex nBundles = CFArrayGetCount( xBundles ); - -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "got %d bundles\n", (int)nBundles ); -#endif - - int nDescriptions = 0; - for( CFIndex i = 0; i < nBundles; i++ ) - { - CFBundleRef xBundle = (CFBundleRef)CFArrayGetValueAtIndex( xBundles, i ); - nDescriptions += getPluginDescriptions( xBundle, rDescriptions ); - - CFRelease( xBundle ); - } - CFRelease( xBundles ); - - - return nDescriptions > 0; -} - -static rtl::OUString FindFolderURL( FSVolumeRefNum vRefNum, OSType folderType ) -{ - rtl::OUString aRet; - - FSRef aFSRef; - OSErr err = FSFindFolder( vRefNum, folderType, kDontCreateFolder, &aFSRef ); - if( err == noErr ) - { - CFURLRef xURL = CFURLCreateFromFSRef( NULL, &aFSRef ); - aRet = getString( xURL ); - CFRelease( xURL ); - } - - return aRet; -} - -Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw() -{ - static Sequence<PluginDescription> aDescriptions; - static sal_Bool bHavePlugins = sal_False; - if( ! bHavePlugins ) - { - std::list<PluginDescription*> aPlugins; - - static const char* pNPXPluginPath = getenv( "MOZ_PLUGIN_PATH" ); - - // get directories - std::list< rtl::OUString > aPaths; - if( pNPXPluginPath ) - { - CFMutableStringRef xMutableString = CFStringCreateMutable( NULL, 0 ); - CFStringAppendCString( xMutableString, pNPXPluginPath, kCFStringEncodingUTF8 ); - CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); - CFRelease( xMutableString ); - aPaths.push_back( getString( xURL ) ); - CFRelease( xURL ); - } - - rtl::OUString aPath = FindFolderURL( kUserDomain, kInternetPlugInFolderType ); - if( aPath.getLength() ) - aPaths.push_back( aPath ); - aPath = FindFolderURL( kLocalDomain, kInternetPlugInFolderType ); - if( aPath.getLength() ) - aPaths.push_back( aPath ); - aPath = FindFolderURL( kOnAppropriateDisk, kInternetPlugInFolderType ); - if( aPath.getLength() ) - aPaths.push_back( aPath ); - - - const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() ); - for( sal_Int32 i = 0; i < rPaths.getLength(); i++ ) - { - aPaths.push_back( getURLFromPath( rPaths.getConstArray()[i] ) ); - } - - for( std::list< rtl::OUString >::const_iterator it = aPaths.begin(); it != aPaths.end(); ++it ) - { - rtl::OUString aPath( *it ); -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "check path %s\n", rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() ); -#endif - CheckPlugin( aPath, aPlugins ); - } - - - // create return value - aDescriptions = Sequence<PluginDescription>( aPlugins.size() ); -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "found %d plugins\n", (int)aPlugins.size() ); -#endif - list<PluginDescription*>::iterator iter; - sal_Int32 nPlug = 0; - for( iter = aPlugins.begin(); iter != aPlugins.end(); ++iter ) - { - aDescriptions.getArray()[ nPlug++ ] = **iter; - delete *iter; - } - aPlugins.clear(); - bHavePlugins = sal_True; - } - return aDescriptions; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/extensions/source/plugin/aqua/macmgr.mm b/extensions/source/plugin/aqua/macmgr.mm new file mode 100644 index 0000000..3b69845 --- /dev/null +++ b/extensions/source/plugin/aqua/macmgr.mm @@ -0,0 +1,654 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "rtl/ustrbuf.hxx" +#include "rtl/strbuf.hxx" + +#include "plugin/impl.hxx" +#include "osl/file.h" +#include "osl/module.hxx" + +using namespace std; +using namespace com::sun::star::uno; +using namespace com::sun::star::plugin; + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OUStringBuffer; +using ::rtl::OStringBuffer; +using ::rtl::OUStringToOString; +using ::rtl::OStringToOUString; + +namespace plugstringhelper +{ + +rtl::OUString getString( CFStringRef i_xString ) +{ + rtl::OUStringBuffer aBuf; + if( i_xString ) + { + CFIndex nChars = CFStringGetLength( i_xString ); + CFRange aRange = { 0, nChars }; + aBuf.setLength( nChars ); + CFStringGetCharacters( i_xString, aRange, static_cast< UniChar* >(const_cast<sal_Unicode*>(aBuf.getStr())) ); + } + return aBuf.makeStringAndClear(); +} + +rtl::OUString getString( CFURLRef i_xURL ) +{ + CFStringRef xString = CFURLGetString( i_xURL ); + return getString( xString ); +} + +CFMutableStringRef createString( const rtl::OUString& i_rString ) +{ + CFMutableStringRef xString = CFStringCreateMutable( NULL, 0 ); + if( xString ) + CFStringAppendCharacters( xString, i_rString.getStr(), i_rString.getLength() ); + return xString; +} + +CFURLRef createURL( const rtl::OUString& i_rString ) +{ + + CFMutableStringRef xMutableString = createString( i_rString ); + CFURLRef xURL = CFURLCreateWithString( NULL, xMutableString, NULL ); + CFRelease( xMutableString ); + return xURL; +} + +rtl::OUString getURLFromPath( const rtl::OUString& i_rPath ) +{ + CFMutableStringRef xMutableString = createString( i_rPath ); + CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); + CFRelease( xMutableString ); + CFStringRef xString = CFURLGetString( xURL ); + rtl::OUString aRet = getString( xString ); + CFRelease( xURL ); + return aRet; +} + +CFURLRef createURLFromPath( const rtl::OUString& i_rPath ) +{ + CFMutableStringRef xMutableString = createString( i_rPath ); + CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); + return xURL; +} + +rtl::OUString CFURLtoOSLURL( CFURLRef i_xURL ) +{ + // make URL absolute + CFURLRef xAbsURL = CFURLCopyAbsoluteURL( i_xURL ); + // copy system path + CFStringRef xSysPath = CFURLCopyFileSystemPath( xAbsURL ? xAbsURL : i_xURL, kCFURLPOSIXPathStyle ); + if( xAbsURL ) + CFRelease( xAbsURL ); + rtl::OUString aSysPath( getString( xSysPath ) ); + CFRelease( xSysPath ); + rtl::OUString aFileURL; + osl_getFileURLFromSystemPath( aSysPath.pData, &aFileURL.pData ); + return aFileURL; +} + +} + +using namespace plugstringhelper; + +static int parsePlist( CFBundleRef i_xBundle, const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions ) +{ + CFTypeRef xMimeDict = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginMIMETypes")); + int nMimetypes = 0; + if( xMimeDict == 0 || + CFGetTypeID(xMimeDict) != CFDictionaryGetTypeID() || + (nMimetypes = CFDictionaryGetCount( static_cast<CFDictionaryRef>(xMimeDict))) <= 0 ) + { + return 0; + } + + // prepare an array of key and value refs + std::vector< CFTypeRef > aKeys( nMimetypes, CFTypeRef(NULL) ); + std::vector< CFTypeRef > aValues( nMimetypes, CFTypeRef(NULL) ); + CFDictionaryGetKeysAndValues(static_cast<CFDictionaryRef>(xMimeDict), &aKeys[0], &aValues[0] ); + + int nAdded = 0; + for( int i = 0; i < nMimetypes; i++ ) + { + // get the mimetype + CFTypeRef xKey = aKeys[i]; + if( ! xKey || CFGetTypeID(xKey) != CFStringGetTypeID() ) + continue; + rtl::OUString aMimetype = getString( (CFStringRef)xKey ); + + // the correspoding value should be a dictionary + CFTypeRef xDict = aValues[i]; + if( ! xDict || CFGetTypeID( xDict ) != CFDictionaryGetTypeID() ) + continue; + + // get the extension list + CFTypeRef xExtArray = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginExtensions" ) ); + if( !xExtArray || CFGetTypeID( xExtArray ) != CFArrayGetTypeID() ) + continue; + + OUStringBuffer aExtBuf; + int nExtensions = CFArrayGetCount( (CFArrayRef)xExtArray ); + for( int n = 0; n < nExtensions; n++ ) + { + CFTypeRef xExt = CFArrayGetValueAtIndex( (CFArrayRef)xExtArray, n ); + if( xExt && CFGetTypeID( xExt ) == CFStringGetTypeID() ) + { + if( aExtBuf.getLength() > 0 ) + aExtBuf.append( sal_Unicode(';') ); + OUString aExt( getString( (CFStringRef)xExt ) ); + if( aExt.indexOfAsciiL( "*.", 2 ) != 0 ) + aExtBuf.appendAscii( "*." ); + aExtBuf.append( aExt ); + } + } + + // get the description string + CFTypeRef xDescString = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginTypeDescription" ) ); + if( !xDescString || CFGetTypeID( xDescString ) != CFStringGetTypeID() ) + continue; + rtl::OUString aDescription = getString( (CFStringRef)xDescString ); + + PluginDescription* pNew = new PluginDescription; + // set plugin name (path to library) + pNew->PluginName = i_rBundleURL; + // set mimetype + pNew->Mimetype = aMimetype; + // set extension line + pNew->Extension = aExtBuf.makeStringAndClear(); + // set description + pNew->Description= aDescription; + + io_rDescriptions.push_back( pNew ); + nAdded++; + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "Inserting from PList:\n" + " Mimetype: %s\n" + " Extension: %s\n" + " Description: %s\n", + OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr() + ); +#endif + + } + + return nAdded; +} + +static int parseMimeString( const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions, const char* i_pMime ) +{ + if( ! i_pMime ) + return 0; + + rtl_TextEncoding aEncoding = osl_getThreadTextEncoding(); + + OStringBuffer aMIME; + aMIME.append( i_pMime ); + + if( aMIME.getLength() < 1 ) + return 0; + + OString aLine = aMIME.makeStringAndClear(); + + int nAdded = 0; + sal_Int32 nIndex = 0; + while( nIndex != -1 ) + { + OString aType = aLine.getToken( 0, ';', nIndex ); + + sal_Int32 nTypeIndex = 0; + OString aMimetype = aType.getToken( 0, ':', nTypeIndex ); + OString aExtLine = aType.getToken( 0, ':', nTypeIndex ); + if( nTypeIndex < 0 ) // ensure at least three tokens + continue; + OString aDesc = aType.getToken( 0, ':', nTypeIndex ); + + // create extension list string + sal_Int32 nExtIndex = 0; + OStringBuffer aExtension; + while( nExtIndex != -1 ) + { + OString aExt = aExtLine.getToken( 0, ',', nExtIndex); + if( aExt.indexOf( "*." ) != 0 ) + aExtension.append( "*." ); + aExtension.append( aExt ); + if( nExtIndex != -1 ) + aExtension.append( ';' ); + } + + PluginDescription* pNew = new PluginDescription; + // set plugin name (path to library) + pNew->PluginName = i_rBundleURL; + // set mimetype + pNew->Mimetype = OStringToOUString( aMimetype, aEncoding ); + // set extension line + pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding ); + // set description + pNew->Description= OStringToOUString( aDesc, aEncoding ); + io_rDescriptions.push_back( pNew ); + nAdded++; + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "Inserting from mime string:\n" + " Mimetype: %s\n" + " Extension: %s\n" + " Description: %s\n", + OUStringToOString( pNew->Mimetype, aEncoding ).getStr(), + OUStringToOString( pNew->Extension, aEncoding ).getStr(), + OUStringToOString( pNew->Description, aEncoding ).getStr() + ); +#endif + } + return nAdded; +} + +// this is so ugly it you want to tear your eyes out +static rtl::OUString GetNextPluginStringFromHandle(Handle h, short *index) +{ + char* pPascalBytes = (*h + *index); + sal_uInt32 nLen = (unsigned char)pPascalBytes[0]; + rtl::OStringBuffer aBuf( nLen ); + aBuf.append( pPascalBytes+1, nLen ); + *index += nLen + 1; + return rtl::OStringToOUString( aBuf.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); +} + +static int parseMimeResource( CFBundleRef i_xBundle, + oslModule& i_rMod, + const rtl::OUString& i_rBundleURL, + list< PluginDescription* >& io_rDescriptions ) +{ + int nAdded = 0; + // just to hurt our eyes more there is an alternative mimetype function plus the possibility + // of a resource fork. Must be a case of think different. + #if __LP64__ + int + #else + SInt16 + #endif + xRes = 0; + BPSupportedMIMETypes aMIMETypesStrangeStruct = {kBPSupportedMIMETypesStructVers_1, NULL, NULL}; + + BP_GetSupportedMIMETypesUPP pBPGetSupp = (BP_GetSupportedMIMETypesUPP)osl_getAsciiFunctionSymbol( i_rMod, "BP_GetSupportedMIMETypes" ); + if( pBPGetSupp && + noErr == pBPGetSupp( &aMIMETypesStrangeStruct, 0 ) && + aMIMETypesStrangeStruct.typeStrings ) + { + HLock( aMIMETypesStrangeStruct.typeStrings ); + if( aMIMETypesStrangeStruct.infoStrings ) // it's possible some plugins have infoStrings missing + HLock( aMIMETypesStrangeStruct.infoStrings ); + } + else // Try to get data from the resource fork + { + xRes = CFBundleOpenBundleResourceMap( i_xBundle ); + if( xRes > 0 ) + { + aMIMETypesStrangeStruct.typeStrings = Get1Resource('STR#', 128); + if( aMIMETypesStrangeStruct.typeStrings ) + { + DetachResource( aMIMETypesStrangeStruct.typeStrings ); + HLock( aMIMETypesStrangeStruct.typeStrings ); + aMIMETypesStrangeStruct.infoStrings = Get1Resource('STR#', 127); + if( aMIMETypesStrangeStruct.infoStrings ) + { + DetachResource( aMIMETypesStrangeStruct.infoStrings ); + HLock( aMIMETypesStrangeStruct.infoStrings ); + } + } + } + } + + if( aMIMETypesStrangeStruct.typeStrings && aMIMETypesStrangeStruct.infoStrings ) + { + short nVariantCount = (**(short**)aMIMETypesStrangeStruct.typeStrings) / 2; + // Fill in the info struct based on the data in the BPSupportedMIMETypes struct + // this is an array of pascal string of unknown (!) encoding + // whoever thought of this deserves a fair beating + short mimeIndex = 2; + short descriptionIndex = 2; + for( int i = 0; i < nVariantCount; i++ ) + { + rtl::OUString aMimetype = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex ); + rtl::OUString aExtLine = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex ); + rtl::OUString aDescription; + if( aMIMETypesStrangeStruct.infoStrings ) + aDescription = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.infoStrings, &descriptionIndex ); + + // create extension list string + sal_Int32 nExtIndex = 0; + OUStringBuffer aExtension; + while( nExtIndex != -1 ) + { + OUString aExt = aExtLine.getToken( 0, ',', nExtIndex); + if( aExt.indexOfAsciiL( "*.", 2 ) != 0 ) + aExtension.appendAscii( "*." ); + aExtension.append( aExt ); + if( nExtIndex != -1 ) + aExtension.append( sal_Unicode(';') ); + } + + PluginDescription* pNew = new PluginDescription; + // set plugin name (path to library) + pNew->PluginName = i_rBundleURL; + // set mimetype + pNew->Mimetype = aMimetype; + // set extension line + pNew->Extension = aExtension.makeStringAndClear(); + // set description + pNew->Description= aDescription; + io_rDescriptions.push_back( pNew ); + nAdded++; + + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "Inserting from resource:\n" + " Mimetype: %s\n" + " Extension: %s\n" + " Description: %s\n", + OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(), + OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr() + ); + #endif + } + } + + + // clean up + if( aMIMETypesStrangeStruct.typeStrings ) + { + HUnlock( aMIMETypesStrangeStruct.typeStrings ); + DisposeHandle( aMIMETypesStrangeStruct.typeStrings ); + } + if( aMIMETypesStrangeStruct.infoStrings ) + { + HUnlock( aMIMETypesStrangeStruct.infoStrings ); + DisposeHandle( aMIMETypesStrangeStruct.infoStrings ); + } + if( xRes ) + CFBundleCloseBundleResourceMap( i_xBundle, xRes ); + + return nAdded; +} + +// check some known bad plugins to avoid crashes +static bool checkBlackList( CFBundleRef i_xBundle ) +{ + rtl::OUString aBundleName; + CFTypeRef bundlename = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleName")); + if( bundlename && CFGetTypeID(bundlename) == CFStringGetTypeID() ) + aBundleName = getString( static_cast<CFStringRef>(bundlename) ); + + rtl::OUString aBundleVersion; + CFTypeRef bundleversion = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleVersion")); + if( bundleversion && CFGetTypeID(bundleversion) == CFStringGetTypeID() ) + aBundleVersion = getString( static_cast<CFStringRef>(bundleversion) ); + + bool bReject = false; + // #i102735# VLC plugin prior to 1.0 tends to crash + if( aBundleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VLC Plug-in" ) ) ) + { + sal_Int32 nIndex = 0; + rtl::OUString aMajor( aBundleVersion.getToken( 0, '.', nIndex ) ); + if( aMajor.toInt32() < 1 ) + { + bReject = true; + } + } + // #i103674# Garmin Communicator Plugin crashes + else if( aBundleName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Garmin Communicator Plugin" ) ) ) + { + bReject = true; + } + + #if OSL_DEBUG_LEVEL > 1 + if( bReject ) + fprintf( stderr, "rejecting plugin \"%s\" version %s\n", + rtl::OUStringToOString( aBundleName, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( aBundleVersion, RTL_TEXTENCODING_UTF8 ).getStr() + ); + #endif + + return bReject; +} + +static int getPluginDescriptions( CFBundleRef i_xBundle , list< PluginDescription* >& io_rDescriptions ) +{ + int nDescriptions = 0; + if( ! i_xBundle ) + return nDescriptions; + + if( checkBlackList( i_xBundle ) ) + return 0; + + rtl::OUString aPlugURL; + CFURLRef xURL = CFBundleCopyBundleURL( i_xBundle ); + aPlugURL = getString( xURL ); + CFRelease( xURL ); + + #if OSL_DEBUG_LEVEL > 1 + rtl::OUString aPlugName, aPlugDescription; + CFTypeRef name = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginName")); + if( name && CFGetTypeID(name) == CFStringGetTypeID() ) + aPlugName = getString( static_cast<CFStringRef>(name) ); + + CFTypeRef description = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginDescription")); + if( description && CFGetTypeID(description) == CFStringGetTypeID() ) + aPlugDescription = getString( static_cast<CFStringRef>(description) ); + + fprintf( stderr, "URL: %s\nname: %s\ndescription: %s\n", + rtl::OUStringToOString( aPlugURL, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( aPlugName, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( aPlugDescription, RTL_TEXTENCODING_UTF8 ).getStr() + ); + #endif + + + // get location of plugin library + CFURLRef xLibURL = CFBundleCopyExecutableURL( i_xBundle ); + if( ! xLibURL ) + return 0; + // get the file system path + rtl::OUString aModuleURL( CFURLtoOSLURL( xLibURL ) ); + CFRelease( xLibURL ); + + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "exec URL = %s\n", rtl::OUStringToOString( aModuleURL, RTL_TEXTENCODING_UTF8 ).getStr() ); + #endif + + /* TODO: originally the C++ wrapper for oslModule was used here, but that led to + mysterious crashes in the event loop (pointing to heap corruption). Why using + the C style oslModule should fix this is completely unknown. It may be that + we have just hidden the heap corruption a little more. + */ + oslModule aMod = osl_loadModule( aModuleURL.pData, SAL_LOADMODULE_DEFAULT ); + if( ! aMod ) + return 0; + + // check for at least the init function of a plugin + if( ! osl_getAsciiFunctionSymbol( aMod, "NP_Initialize") && + ! osl_getAsciiFunctionSymbol( aMod, "NP_GetEntryPoints" ) ) + { + return 0; + } + + // ask the plist of the bundle for mimetypes + nDescriptions = parsePlist( i_xBundle, aPlugURL, io_rDescriptions ); + if( nDescriptions ) + { + osl_unloadModule( aMod ); + return nDescriptions; + } + + // resolve the symbol that might get us the mimetypes + const char* (*pGetMimeDescription)() = (const char*(*)())osl_getAsciiFunctionSymbol( aMod, "_NP_GetMIMEDescription" ); + if( pGetMimeDescription ) + { + const char* pMime = pGetMimeDescription(); + if( pMime ) + { + nDescriptions = parseMimeString( aPlugURL, io_rDescriptions, pMime ); + if( nDescriptions ) + { + osl_unloadModule( aMod ); + return nDescriptions; + } + } + } + + // and as last resort check the resource of the bundle + nDescriptions = parseMimeResource( i_xBundle, aMod, aPlugURL, io_rDescriptions ); + osl_unloadModule( aMod ); + + return nDescriptions; +} + +// Unix specific implementation +static bool CheckPlugin( const rtl::OUString& rPath, list< PluginDescription* >& rDescriptions ) +{ +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "Trying path %s ... ", rtl::OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getStr() ); +#endif + CFURLRef xURL = createURL( rPath ); + + CFArrayRef xBundles = CFBundleCreateBundlesFromDirectory( NULL, xURL, CFSTR("plugin") ); + if( ! xBundles ) + return false; + + CFIndex nBundles = CFArrayGetCount( xBundles ); + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "got %d bundles\n", (int)nBundles ); +#endif + + int nDescriptions = 0; + for( CFIndex i = 0; i < nBundles; i++ ) + { + CFBundleRef xBundle = (CFBundleRef)CFArrayGetValueAtIndex( xBundles, i ); + nDescriptions += getPluginDescriptions( xBundle, rDescriptions ); + + CFRelease( xBundle ); + } + CFRelease( xBundles ); + + + return nDescriptions > 0; +} + +static rtl::OUString FindFolderURL( FSVolumeRefNum vRefNum, OSType folderType ) +{ + rtl::OUString aRet; + + FSRef aFSRef; + OSErr err = FSFindFolder( vRefNum, folderType, kDontCreateFolder, &aFSRef ); + if( err == noErr ) + { + CFURLRef xURL = CFURLCreateFromFSRef( NULL, &aFSRef ); + aRet = getString( xURL ); + CFRelease( xURL ); + } + + return aRet; +} + +Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw() +{ + static Sequence<PluginDescription> aDescriptions; + static sal_Bool bHavePlugins = sal_False; + if( ! bHavePlugins ) + { + std::list<PluginDescription*> aPlugins; + + static const char* pNPXPluginPath = getenv( "MOZ_PLUGIN_PATH" ); + + // get directories + std::list< rtl::OUString > aPaths; + if( pNPXPluginPath ) + { + CFMutableStringRef xMutableString = CFStringCreateMutable( NULL, 0 ); + CFStringAppendCString( xMutableString, pNPXPluginPath, kCFStringEncodingUTF8 ); + CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true ); + CFRelease( xMutableString ); + aPaths.push_back( getString( xURL ) ); + CFRelease( xURL ); + } + + rtl::OUString aPath = FindFolderURL( kUserDomain, kInternetPlugInFolderType ); + if( aPath.getLength() ) + aPaths.push_back( aPath ); + aPath = FindFolderURL( kLocalDomain, kInternetPlugInFolderType ); + if( aPath.getLength() ) + aPaths.push_back( aPath ); + aPath = FindFolderURL( kOnAppropriateDisk, kInternetPlugInFolderType ); + if( aPath.getLength() ) + aPaths.push_back( aPath ); + + + const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() ); + for( sal_Int32 i = 0; i < rPaths.getLength(); i++ ) + { + aPaths.push_back( getURLFromPath( rPaths.getConstArray()[i] ) ); + } + + for( std::list< rtl::OUString >::const_iterator it = aPaths.begin(); it != aPaths.end(); ++it ) + { + rtl::OUString aPath( *it ); +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "check path %s\n", rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() ); +#endif + CheckPlugin( aPath, aPlugins ); + } + + + // create return value + aDescriptions = Sequence<PluginDescription>( aPlugins.size() ); +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "found %d plugins\n", (int)aPlugins.size() ); +#endif + list<PluginDescription*>::iterator iter; + sal_Int32 nPlug = 0; + for( iter = aPlugins.begin(); iter != aPlugins.end(); ++iter ) + { + aDescriptions.getArray()[ nPlug++ ] = **iter; + delete *iter; + } + aPlugins.clear(); + bHavePlugins = sal_True; + } + return aDescriptions; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________ Libreoffice-commits mailing list Libreoffice-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits