Update ooo320-m1
[ooovba.git] / extensions / source / plugin / aqua / macmgr.cxx
blob6ca1b763c2c1bad25acfb7a035bae567f4798107
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: macmgr.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "rtl/ustrbuf.hxx"
32 #include "rtl/strbuf.hxx"
34 #include "plugin/impl.hxx"
35 #include "osl/file.h"
36 #include "osl/module.hxx"
38 using namespace rtl;
39 using namespace std;
40 using namespace com::sun::star::uno;
41 using namespace com::sun::star::plugin;
43 namespace plugstringhelper
46 rtl::OUString getString( CFStringRef i_xString )
48 rtl::OUStringBuffer aBuf;
49 if( i_xString )
51 CFIndex nChars = CFStringGetLength( i_xString );
52 CFRange aRange = { 0, nChars };
53 aBuf.setLength( nChars );
54 CFStringGetCharacters( i_xString, aRange, static_cast< UniChar* >(const_cast<sal_Unicode*>(aBuf.getStr())) );
56 return aBuf.makeStringAndClear();
59 rtl::OUString getString( CFURLRef i_xURL )
61 CFStringRef xString = CFURLGetString( i_xURL );
62 return getString( xString );
65 CFMutableStringRef createString( const rtl::OUString& i_rString )
67 CFMutableStringRef xString = CFStringCreateMutable( NULL, 0 );
68 if( xString )
69 CFStringAppendCharacters( xString, i_rString.getStr(), i_rString.getLength() );
70 return xString;
73 CFURLRef createURL( const rtl::OUString& i_rString )
76 CFMutableStringRef xMutableString = createString( i_rString );
77 CFURLRef xURL = CFURLCreateWithString( NULL, xMutableString, NULL );
78 CFRelease( xMutableString );
79 return xURL;
82 rtl::OUString getURLFromPath( const rtl::OUString& i_rPath )
84 CFMutableStringRef xMutableString = createString( i_rPath );
85 CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true );
86 CFRelease( xMutableString );
87 CFStringRef xString = CFURLGetString( xURL );
88 rtl::OUString aRet = getString( xString );
89 CFRelease( xURL );
90 return aRet;
93 CFURLRef createURLFromPath( const rtl::OUString& i_rPath )
95 CFMutableStringRef xMutableString = createString( i_rPath );
96 CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true );
97 return xURL;
100 rtl::OUString CFURLtoOSLURL( CFURLRef i_xURL )
102 // make URL absolute
103 CFURLRef xAbsURL = CFURLCopyAbsoluteURL( i_xURL );
104 // copy system path
105 CFStringRef xSysPath = CFURLCopyFileSystemPath( xAbsURL ? xAbsURL : i_xURL, kCFURLPOSIXPathStyle );
106 if( xAbsURL )
107 CFRelease( xAbsURL );
108 rtl::OUString aSysPath( getString( xSysPath ) );
109 CFRelease( xSysPath );
110 rtl::OUString aFileURL;
111 osl_getFileURLFromSystemPath( aSysPath.pData, &aFileURL.pData );
112 return aFileURL;
117 using namespace plugstringhelper;
119 static int parsePlist( CFBundleRef i_xBundle, const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions )
121 CFTypeRef xMimeDict = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginMIMETypes"));
122 int nMimetypes = 0;
123 if( xMimeDict == 0 ||
124 CFGetTypeID(xMimeDict) != CFDictionaryGetTypeID() ||
125 (nMimetypes = CFDictionaryGetCount( static_cast<CFDictionaryRef>(xMimeDict))) <= 0 )
127 return 0;
130 // prepare an array of key and value refs
131 std::vector< CFTypeRef > aKeys( nMimetypes, CFTypeRef(NULL) );
132 std::vector< CFTypeRef > aValues( nMimetypes, CFTypeRef(NULL) );
133 CFDictionaryGetKeysAndValues(static_cast<CFDictionaryRef>(xMimeDict), &aKeys[0], &aValues[0] );
135 int nAdded = 0;
136 for( int i = 0; i < nMimetypes; i++ )
138 // get the mimetype
139 CFTypeRef xKey = aKeys[i];
140 if( ! xKey || CFGetTypeID(xKey) != CFStringGetTypeID() )
141 continue;
142 rtl::OUString aMimetype = getString( (CFStringRef)xKey );
144 // the correspoding value should be a dictionary
145 CFTypeRef xDict = aValues[i];
146 if( ! xDict || CFGetTypeID( xDict ) != CFDictionaryGetTypeID() )
147 continue;
149 // get the extension list
150 CFTypeRef xExtArray = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginExtensions" ) );
151 if( !xExtArray || CFGetTypeID( xExtArray ) != CFArrayGetTypeID() )
152 continue;
154 OUStringBuffer aExtBuf;
155 int nExtensions = CFArrayGetCount( (CFArrayRef)xExtArray );
156 for( int n = 0; n < nExtensions; n++ )
158 CFTypeRef xExt = CFArrayGetValueAtIndex( (CFArrayRef)xExtArray, n );
159 if( xExt && CFGetTypeID( xExt ) == CFStringGetTypeID() )
161 if( aExtBuf.getLength() > 0 )
162 aExtBuf.append( sal_Unicode(';') );
163 OUString aExt( getString( (CFStringRef)xExt ) );
164 if( aExt.indexOfAsciiL( "*.", 2 ) != 0 )
165 aExtBuf.appendAscii( "*." );
166 aExtBuf.append( aExt );
170 // get the description string
171 CFTypeRef xDescString = CFDictionaryGetValue( (CFDictionaryRef)xDict, CFSTR("WebPluginTypeDescription" ) );
172 if( !xDescString || CFGetTypeID( xDescString ) != CFStringGetTypeID() )
173 continue;
174 rtl::OUString aDescription = getString( (CFStringRef)xDescString );
176 PluginDescription* pNew = new PluginDescription;
177 // set plugin name (path to library)
178 pNew->PluginName = i_rBundleURL;
179 // set mimetype
180 pNew->Mimetype = aMimetype;
181 // set extension line
182 pNew->Extension = aExtBuf.makeStringAndClear();
183 // set description
184 pNew->Description= aDescription;
186 io_rDescriptions.push_back( pNew );
187 nAdded++;
189 #if OSL_DEBUG_LEVEL > 1
190 fprintf( stderr,
191 "Inserting from PList:\n"
192 " Mimetype: %s\n"
193 " Extension: %s\n"
194 " Description: %s\n",
195 OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(),
196 OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(),
197 OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr()
199 #endif
203 return nAdded;
206 static int parseMimeString( const rtl::OUString& i_rBundleURL , list< PluginDescription* >& io_rDescriptions, const char* i_pMime )
208 if( ! i_pMime )
209 return 0;
211 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
213 OStringBuffer aMIME;
214 aMIME.append( i_pMime );
216 if( aMIME.getLength() < 1 )
217 return 0;
219 OString aLine = aMIME.makeStringAndClear();
221 int nAdded = 0;
222 sal_Int32 nIndex = 0;
223 while( nIndex != -1 )
225 OString aType = aLine.getToken( 0, ';', nIndex );
227 sal_Int32 nTypeIndex = 0;
228 OString aMimetype = aType.getToken( 0, ':', nTypeIndex );
229 OString aExtLine = aType.getToken( 0, ':', nTypeIndex );
230 if( nTypeIndex < 0 ) // ensure at least three tokens
231 continue;
232 OString aDesc = aType.getToken( 0, ':', nTypeIndex );
234 // create extension list string
235 sal_Int32 nExtIndex = 0;
236 OStringBuffer aExtension;
237 while( nExtIndex != -1 )
239 OString aExt = aExtLine.getToken( 0, ',', nExtIndex);
240 if( aExt.indexOf( "*." ) != 0 )
241 aExtension.append( "*." );
242 aExtension.append( aExt );
243 if( nExtIndex != -1 )
244 aExtension.append( ';' );
247 PluginDescription* pNew = new PluginDescription;
248 // set plugin name (path to library)
249 pNew->PluginName = i_rBundleURL;
250 // set mimetype
251 pNew->Mimetype = OStringToOUString( aMimetype, aEncoding );
252 // set extension line
253 pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding );
254 // set description
255 pNew->Description= OStringToOUString( aDesc, aEncoding );
256 io_rDescriptions.push_back( pNew );
257 nAdded++;
259 #if OSL_DEBUG_LEVEL > 1
260 fprintf( stderr,
261 "Inserting from mime string:\n"
262 " Mimetype: %s\n"
263 " Extension: %s\n"
264 " Description: %s\n",
265 OUStringToOString( pNew->Mimetype, aEncoding ).getStr(),
266 OUStringToOString( pNew->Extension, aEncoding ).getStr(),
267 OUStringToOString( pNew->Description, aEncoding ).getStr()
269 #endif
271 return nAdded;
274 // this is so ugly it you want to tear your eyes out
275 static rtl::OUString GetNextPluginStringFromHandle(Handle h, short *index)
277 char* pPascalBytes = (*h + *index);
278 sal_uInt32 nLen = (unsigned char)pPascalBytes[0];
279 rtl::OStringBuffer aBuf( nLen );
280 aBuf.append( pPascalBytes+1, nLen );
281 *index += nLen + 1;
282 return rtl::OStringToOUString( aBuf.makeStringAndClear(), RTL_TEXTENCODING_UTF8 );
285 static int parseMimeResource( CFBundleRef i_xBundle,
286 oslModule& i_rMod,
287 const rtl::OUString& i_rBundleURL,
288 list< PluginDescription* >& io_rDescriptions )
290 int nAdded = 0;
291 // just to hurt our eyes more there is an alternative mimetype function plus the possibility
292 // of a resource fork. Must be a case of think different.
293 #if __LP64__
295 #else
296 SInt16
297 #endif
298 xRes = 0;
299 BPSupportedMIMETypes aMIMETypesStrangeStruct = {kBPSupportedMIMETypesStructVers_1, NULL, NULL};
301 BP_GetSupportedMIMETypesUPP pBPGetSupp = (BP_GetSupportedMIMETypesUPP)osl_getAsciiFunctionSymbol( i_rMod, "BP_GetSupportedMIMETypes" );
302 if( pBPGetSupp &&
303 noErr == pBPGetSupp( &aMIMETypesStrangeStruct, 0 ) &&
304 aMIMETypesStrangeStruct.typeStrings )
306 HLock( aMIMETypesStrangeStruct.typeStrings );
307 if( aMIMETypesStrangeStruct.infoStrings ) // it's possible some plugins have infoStrings missing
308 HLock( aMIMETypesStrangeStruct.infoStrings );
310 else // Try to get data from the resource fork
312 xRes = CFBundleOpenBundleResourceMap( i_xBundle );
313 if( xRes > 0 )
315 aMIMETypesStrangeStruct.typeStrings = Get1Resource('STR#', 128);
316 if( aMIMETypesStrangeStruct.typeStrings )
318 DetachResource( aMIMETypesStrangeStruct.typeStrings );
319 HLock( aMIMETypesStrangeStruct.typeStrings );
320 aMIMETypesStrangeStruct.infoStrings = Get1Resource('STR#', 127);
321 if( aMIMETypesStrangeStruct.infoStrings )
323 DetachResource( aMIMETypesStrangeStruct.infoStrings );
324 HLock( aMIMETypesStrangeStruct.infoStrings );
330 if( aMIMETypesStrangeStruct.typeStrings && aMIMETypesStrangeStruct.infoStrings )
332 short nVariantCount = (**(short**)aMIMETypesStrangeStruct.typeStrings) / 2;
333 // Fill in the info struct based on the data in the BPSupportedMIMETypes struct
334 // this is an array of pascal string of unknown (!) encoding
335 // whoever thought of this deserves a fair beating
336 short mimeIndex = 2;
337 short descriptionIndex = 2;
338 for( int i = 0; i < nVariantCount; i++ )
340 rtl::OUString aMimetype = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex );
341 rtl::OUString aExtLine = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.typeStrings, &mimeIndex );
342 rtl::OUString aDescription;
343 if( aMIMETypesStrangeStruct.infoStrings )
344 aDescription = GetNextPluginStringFromHandle( aMIMETypesStrangeStruct.infoStrings, &descriptionIndex );
346 // create extension list string
347 sal_Int32 nExtIndex = 0;
348 OUStringBuffer aExtension;
349 while( nExtIndex != -1 )
351 OUString aExt = aExtLine.getToken( 0, ',', nExtIndex);
352 if( aExt.indexOfAsciiL( "*.", 2 ) != 0 )
353 aExtension.appendAscii( "*." );
354 aExtension.append( aExt );
355 if( nExtIndex != -1 )
356 aExtension.append( sal_Unicode(';') );
359 PluginDescription* pNew = new PluginDescription;
360 // set plugin name (path to library)
361 pNew->PluginName = i_rBundleURL;
362 // set mimetype
363 pNew->Mimetype = aMimetype;
364 // set extension line
365 pNew->Extension = aExtension.makeStringAndClear();
366 // set description
367 pNew->Description= aDescription;
368 io_rDescriptions.push_back( pNew );
369 nAdded++;
371 #if OSL_DEBUG_LEVEL > 1
372 fprintf( stderr,
373 "Inserting from resource:\n"
374 " Mimetype: %s\n"
375 " Extension: %s\n"
376 " Description: %s\n",
377 OUStringToOString( pNew->Mimetype, RTL_TEXTENCODING_UTF8 ).getStr(),
378 OUStringToOString( pNew->Extension, RTL_TEXTENCODING_UTF8 ).getStr(),
379 OUStringToOString( pNew->Description, RTL_TEXTENCODING_UTF8 ).getStr()
381 #endif
386 // clean up
387 if( aMIMETypesStrangeStruct.typeStrings )
389 HUnlock( aMIMETypesStrangeStruct.typeStrings );
390 DisposeHandle( aMIMETypesStrangeStruct.typeStrings );
392 if( aMIMETypesStrangeStruct.infoStrings )
394 HUnlock( aMIMETypesStrangeStruct.infoStrings );
395 DisposeHandle( aMIMETypesStrangeStruct.infoStrings );
397 if( xRes )
398 CFBundleCloseBundleResourceMap( i_xBundle, xRes );
400 return nAdded;
403 // check some known bad plugins to avoid crashes
404 static bool checkBlackList( CFBundleRef i_xBundle )
406 rtl::OUString aBundleName;
407 CFTypeRef bundlename = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleName"));
408 if( bundlename && CFGetTypeID(bundlename) == CFStringGetTypeID() )
409 aBundleName = getString( static_cast<CFStringRef>(bundlename) );
411 rtl::OUString aBundleVersion;
412 CFTypeRef bundleversion = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("CFBundleVersion"));
413 if( bundleversion && CFGetTypeID(bundleversion) == CFStringGetTypeID() )
414 aBundleVersion = getString( static_cast<CFStringRef>(bundleversion) );
416 bool bReject = false;
417 // #i102735# VLC plugin prior to 1.0 tends to crash
418 if( aBundleName.equalsAscii( "VLC Plug-in" ) )
420 sal_Int32 nIndex = 0;
421 rtl::OUString aMajor( aBundleVersion.getToken( 0, '.', nIndex ) );
422 if( aMajor.toInt32() < 1 )
424 bReject = true;
427 // #i103674# Garmin Communicator Plugin crashes
428 else if( aBundleName.equalsAscii( "Garmin Communicator Plugin" ) )
430 bReject = true;
433 #if OSL_DEBUG_LEVEL > 1
434 if( bReject )
435 fprintf( stderr, "rejecting plugin \"%s\" version %s\n",
436 rtl::OUStringToOString( aBundleName, RTL_TEXTENCODING_UTF8 ).getStr(),
437 rtl::OUStringToOString( aBundleVersion, RTL_TEXTENCODING_UTF8 ).getStr()
439 #endif
441 return bReject;
444 static int getPluginDescriptions( CFBundleRef i_xBundle , list< PluginDescription* >& io_rDescriptions )
446 int nDescriptions = 0;
447 if( ! i_xBundle )
448 return nDescriptions;
450 if( checkBlackList( i_xBundle ) )
451 return 0;
453 rtl::OUString aPlugURL;
454 CFURLRef xURL = CFBundleCopyBundleURL( i_xBundle );
455 aPlugURL = getString( xURL );
456 CFRelease( xURL );
458 #if OSL_DEBUG_LEVEL > 1
459 rtl::OUString aPlugName, aPlugDescription;
460 CFTypeRef name = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginName"));
461 if( name && CFGetTypeID(name) == CFStringGetTypeID() )
462 aPlugName = getString( static_cast<CFStringRef>(name) );
464 CFTypeRef description = CFBundleGetValueForInfoDictionaryKey( i_xBundle, CFSTR("WebPluginDescription"));
465 if( description && CFGetTypeID(description) == CFStringGetTypeID() )
466 aPlugDescription = getString( static_cast<CFStringRef>(description) );
468 fprintf( stderr, "URL: %s\nname: %s\ndescription: %s\n",
469 rtl::OUStringToOString( aPlugURL, RTL_TEXTENCODING_UTF8 ).getStr(),
470 rtl::OUStringToOString( aPlugName, RTL_TEXTENCODING_UTF8 ).getStr(),
471 rtl::OUStringToOString( aPlugDescription, RTL_TEXTENCODING_UTF8 ).getStr()
473 #endif
476 // get location of plugin library
477 CFURLRef xLibURL = CFBundleCopyExecutableURL( i_xBundle );
478 if( ! xLibURL )
479 return 0;
480 // get the file system path
481 rtl::OUString aModuleURL( CFURLtoOSLURL( xLibURL ) );
482 CFRelease( xLibURL );
484 #if OSL_DEBUG_LEVEL > 1
485 fprintf( stderr, "exec URL = %s\n", rtl::OUStringToOString( aModuleURL, RTL_TEXTENCODING_UTF8 ).getStr() );
486 #endif
488 /* TODO: originally the C++ wrapper for oslModule was used here, but that led to
489 mysterious crashes in the event loop (pointing to heap corruption). Why using
490 the C style oslModule should fix this is completely unknown. It may be that
491 we have just hidden the heap corruption a little more.
493 oslModule aMod = osl_loadModule( aModuleURL.pData, SAL_LOADMODULE_DEFAULT );
494 if( ! aMod )
495 return 0;
497 // check for at least the init function of a plugin
498 if( ! osl_getAsciiFunctionSymbol( aMod, "NP_Initialize") &&
499 ! osl_getAsciiFunctionSymbol( aMod, "NP_GetEntryPoints" ) )
501 return 0;
504 // ask the plist of the bundle for mimetypes
505 nDescriptions = parsePlist( i_xBundle, aPlugURL, io_rDescriptions );
506 if( nDescriptions )
508 osl_unloadModule( aMod );
509 return nDescriptions;
512 // resolve the symbol that might get us the mimetypes
513 const char* (*pGetMimeDescription)() = (const char*(*)())osl_getAsciiFunctionSymbol( aMod, "_NP_GetMIMEDescription" );
514 if( pGetMimeDescription )
516 const char* pMime = pGetMimeDescription();
517 if( pMime )
519 nDescriptions = parseMimeString( aPlugURL, io_rDescriptions, pMime );
520 if( nDescriptions )
522 osl_unloadModule( aMod );
523 return nDescriptions;
528 // and as last resort check the resource of the bundle
529 nDescriptions = parseMimeResource( i_xBundle, aMod, aPlugURL, io_rDescriptions );
530 osl_unloadModule( aMod );
532 return nDescriptions;
535 // Unix specific implementation
536 static bool CheckPlugin( const rtl::OUString& rPath, list< PluginDescription* >& rDescriptions )
538 #if OSL_DEBUG_LEVEL > 1
539 fprintf( stderr, "Trying path %s ... ", rtl::OUStringToOString( rPath, RTL_TEXTENCODING_UTF8 ).getStr() );
540 #endif
541 CFURLRef xURL = createURL( rPath );
543 CFArrayRef xBundles = CFBundleCreateBundlesFromDirectory( NULL, xURL, CFSTR("plugin") );
544 if( ! xBundles )
545 return false;
547 CFIndex nBundles = CFArrayGetCount( xBundles );
549 #if OSL_DEBUG_LEVEL > 1
550 fprintf( stderr, "got %d bundles\n", (int)nBundles );
551 #endif
553 int nDescriptions = 0;
554 for( CFIndex i = 0; i < nBundles; i++ )
556 CFBundleRef xBundle = (CFBundleRef)CFArrayGetValueAtIndex( xBundles, i );
557 nDescriptions += getPluginDescriptions( xBundle, rDescriptions );
559 CFRelease( xBundle );
561 CFRelease( xBundles );
564 return nDescriptions > 0;
567 static rtl::OUString FindFolderURL( FSVolumeRefNum vRefNum, OSType folderType )
569 rtl::OUString aRet;
571 FSRef aFSRef;
572 OSErr err = FSFindFolder( vRefNum, folderType, kDontCreateFolder, &aFSRef );
573 if( err == noErr )
575 CFURLRef xURL = CFURLCreateFromFSRef( NULL, &aFSRef );
576 aRet = getString( xURL );
577 CFRelease( xURL );
580 return aRet;
583 Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw()
585 static Sequence<PluginDescription> aDescriptions;
586 static BOOL bHavePlugins = FALSE;
587 if( ! bHavePlugins )
589 std::list<PluginDescription*> aPlugins;
591 static const char* pNPXPluginPath = getenv( "MOZ_PLUGIN_PATH" );
593 // get directories
594 std::list< rtl::OUString > aPaths;
595 if( pNPXPluginPath )
597 CFMutableStringRef xMutableString = CFStringCreateMutable( NULL, 0 );
598 CFStringAppendCString( xMutableString, pNPXPluginPath, kCFStringEncodingUTF8 );
599 CFURLRef xURL = CFURLCreateWithFileSystemPath( NULL, xMutableString, kCFURLPOSIXPathStyle, true );
600 CFRelease( xMutableString );
601 aPaths.push_back( getString( xURL ) );
602 CFRelease( xURL );
605 rtl::OUString aPath = FindFolderURL( kUserDomain, kInternetPlugInFolderType );
606 if( aPath.getLength() )
607 aPaths.push_back( aPath );
608 aPath = FindFolderURL( kLocalDomain, kInternetPlugInFolderType );
609 if( aPath.getLength() )
610 aPaths.push_back( aPath );
611 aPath = FindFolderURL( kOnAppropriateDisk, kInternetPlugInFolderType );
612 if( aPath.getLength() )
613 aPaths.push_back( aPath );
616 const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() );
617 for( sal_Int32 i = 0; i < rPaths.getLength(); i++ )
619 aPaths.push_back( getURLFromPath( rPaths.getConstArray()[i] ) );
622 for( std::list< rtl::OUString >::const_iterator it = aPaths.begin(); it != aPaths.end(); ++it )
624 rtl::OUString aPath( *it );
625 #if OSL_DEBUG_LEVEL > 1
626 fprintf( stderr, "check path %s\n", rtl::OUStringToOString( *it, RTL_TEXTENCODING_UTF8 ).getStr() );
627 #endif
628 CheckPlugin( aPath, aPlugins );
632 // create return value
633 aDescriptions = Sequence<PluginDescription>( aPlugins.size() );
634 #if OSL_DEBUG_LEVEL > 1
635 fprintf( stderr, "found %d plugins\n", (int)aPlugins.size() );
636 #endif
637 list<PluginDescription*>::iterator iter;
638 sal_Int32 nPlug = 0;
639 for( iter = aPlugins.begin(); iter != aPlugins.end(); ++iter )
641 aDescriptions.getArray()[ nPlug++ ] = **iter;
642 delete *iter;
644 aPlugins.clear();
645 bHavePlugins = TRUE;
647 return aDescriptions;