1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_extensions.hxx"
32 #include "vcl/svapp.hxx"
33 #include "tools/fsys.hxx"
34 #include "tools/urlobj.hxx"
35 #include "osl/mutex.hxx"
37 #include "rtl/string.hxx"
38 #include "rtl/ustring.hxx"
39 #include "rtl/ustrbuf.hxx"
41 #include "plugin/impl.hxx"
43 #pragma warning (push,1)
44 #pragma warning (disable:4005)
46 #include "tools/prewin.h"
55 #include "tools/postwin.h"
67 using namespace com::sun::star::uno
;
68 using namespace com::sun::star::plugin
;
70 typedef map
< OString
, OUString
, less
< OString
> > PluginLocationMap
;
73 #if OSL_DEBUG_LEVEL > 1
76 static void logPlugin( OUString
const & path_
)
78 static FILE * s_file
= 0;
80 s_file
= fopen( "d:\\plugins.log", "a+" );
81 OString
path( OUStringToOString( path_
, RTL_TEXTENCODING_ASCII_US
) );
82 fprintf( s_file
, "%s\n", path
.getStr() );
86 //__________________________________________________________________________________________________
87 static void addPluginsFromPath( const TCHAR
* pPluginsPath
, PluginLocationMap
& rPlugins
)
89 // append dll name pattern we are looking for
90 TCHAR arPluginsPath
[MAX_PATH
];
93 if (::rtl_str_indexOfStr( pPluginsPath
, "%programfiles%" ) == 0)
95 const char * p
= ::getenv( "ProgramFiles" );
98 ::lstrcpy( arPluginsPath
, p
);
102 ::lstrcat( arPluginsPath
, pPluginsPath
);
103 ::lstrcat( arPluginsPath
, _T("\\") );
105 TCHAR arPluginsPattern
[MAX_PATH
];
106 ::lstrcpy( arPluginsPattern
, arPluginsPath
);
107 ::lstrcat( arPluginsPattern
, _T("NP*.DLL") );
109 WIN32_FIND_DATA aFindData
;
110 HANDLE hFind
= ::FindFirstFile( arPluginsPattern
, &aFindData
);
112 while (hFind
!= INVALID_HANDLE_VALUE
)
114 OString
aName( aFindData
.cFileName
);
115 aName
.toAsciiLowerCase();
117 // no netscape default plugin anymore...
118 // and no double plugin dlls
119 if ( !aName
.equals( "npnul32.dll" ) &&
120 ! aName
.equals( "npnrvp.dll" ) &&
121 rPlugins
.find( aName
) == rPlugins
.end())
123 TCHAR arComplete
[MAX_PATH
];
124 ::lstrcpy( arComplete
, arPluginsPath
);
125 ::lstrcat( arComplete
, aFindData
.cFileName
);
127 OUString
path( OStringToOUString( arComplete
, RTL_TEXTENCODING_MS_1252
) );
128 rPlugins
[ aName
] = path
;
129 #if OSL_DEBUG_LEVEL > 1
134 if (! ::FindNextFile( hFind
, &aFindData
))
138 if (hFind
!= INVALID_HANDLE_VALUE
)
139 ::FindClose( hFind
);
141 //__________________________________________________________________________________________________
142 static void addPluginsFromPath( const OUString
& rPath
, PluginLocationMap
& rPlugins
)
144 TCHAR arPluginsPath
[MAX_PATH
];
145 DWORD dwPluginsPathSize
= sizeof(arPluginsPath
);
146 arPluginsPath
[dwPluginsPathSize
-1] = 0;
148 OString
aStr( OUStringToOString( rPath
, RTL_TEXTENCODING_MS_1252
) );
149 ::strncpy( arPluginsPath
, aStr
.getStr(), dwPluginsPathSize
);
151 addPluginsFromPath( arPluginsPath
, rPlugins
);
155 //__________________________________________________________________________________________________
156 static void add_IE_Plugins( PluginLocationMap
& rPlugins
)
159 TCHAR arCurrent
[MAX_PATH
];
160 DWORD dwType
, dwCurrentSize
= sizeof(arCurrent
);
162 if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE
, _T("Software\\Microsoft\\IE4\\SETUP"),
163 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
165 if (::RegQueryValueEx( hKey
, _T("Path"), NULL
, &dwType
,
166 (LPBYTE
)arCurrent
, &dwCurrentSize
) == ERROR_SUCCESS
&&
167 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
170 ::lstrcat( arCurrent
, _T("\\Plugins") );
172 addPluginsFromPath( arCurrent
, rPlugins
);
174 ::RegCloseKey( hKey
);
178 //--------------------------------------------------------------------------------------------------
179 static void add_NS_keys( HKEY hKey
, PluginLocationMap
& rPlugins
)
181 TCHAR value
[MAX_PATH
];
182 DWORD dwType
, size
= sizeof(value
);
185 size
= sizeof(value
);
186 if (::RegQueryValueEx(
187 hKey
, _T("Plugins Directory"), NULL
, &dwType
,
188 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
189 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
191 addPluginsFromPath( value
, rPlugins
);
194 size
= sizeof(value
);
195 if (::RegQueryValueEx(
196 hKey
, _T("Install Directory"), NULL
, &dwType
,
197 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
198 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
200 int n
= size
/ sizeof (TCHAR
);
201 if ('\\' != value
[ n
-2 ])
203 value
[ n
-1 ] = '\\';
206 addPluginsFromPath( ::lstrcat( value
, _T("Plugins") ), rPlugins
);
208 size
= sizeof(value
);
209 if (::RegQueryValueEx(
210 hKey
, _T("Plugins"), NULL
, &dwType
,
211 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
212 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
214 addPluginsFromPath( value
, rPlugins
);
217 //--------------------------------------------------------------------------------------------------
218 static void add_NS_lookupRecursive( HKEY hKey
, PluginLocationMap
& rPlugins
)
220 add_NS_keys( hKey
, rPlugins
);
222 TCHAR keyName
[MAX_PATH
];
223 DWORD dwIndex
= 0, size
= sizeof (keyName
);
225 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
227 size
= sizeof (keyName
);
229 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
231 add_NS_lookupRecursive( hSubKey
, rPlugins
);
232 ::RegCloseKey( hSubKey
);
237 //__________________________________________________________________________________________________
238 static void add_MozPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
240 TCHAR value
[MAX_PATH
];
241 DWORD dwType
, size
= sizeof(value
);
243 size
= sizeof(value
);
244 if (::RegQueryValueEx(
245 hKey
, _T("Path"), NULL
, &dwType
,
246 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
247 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
249 OUString
aUPath( OStringToOUString( value
, RTL_TEXTENCODING_MS_1252
) );
250 INetURLObject
aURL( aUPath
);
251 OString
aName( OUStringToOString( aURL
.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252
) );
253 // no netscape default plugin anymore...
254 // and no double plugin dlls
255 if ( !aName
.equals( "npnul32.dll" ) &&
256 ! aName
.equals( "npnrvp.dll" ) &&
257 rPlugins
.find( aName
) == rPlugins
.end())
259 rPlugins
[ aName
] = aUPath
;
260 #if OSL_DEBUG_LEVEL > 1
266 static void add_MozillaPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
268 TCHAR keyName
[MAX_PATH
];
269 DWORD dwIndex
= 0, size
= sizeof (keyName
);
271 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
273 size
= sizeof (keyName
);
275 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
277 add_MozPlugin( hSubKey
, rPlugins
);
278 ::RegCloseKey( hSubKey
);
283 //__________________________________________________________________________________________________
284 static void add_NS_Plugins( PluginLocationMap
& rPlugins
)
289 HKEY_LOCAL_MACHINE
, _T("Software\\Netscape"),
290 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
292 add_NS_lookupRecursive( hKey
, rPlugins
);
293 ::RegCloseKey( hKey
);
297 HKEY_LOCAL_MACHINE
, _T("Software\\Mozilla"),
298 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
300 add_NS_lookupRecursive( hKey
, rPlugins
);
301 ::RegCloseKey( hKey
);
305 HKEY_LOCAL_MACHINE
, _T("Software\\MozillaPlugins"),
306 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
308 add_MozillaPlugin( hKey
, rPlugins
);
309 ::RegCloseKey( hKey
);
313 //__________________________________________________________________________________________________
314 static void add_SO_Plugins( PluginLocationMap
& rPlugins
)
316 const Sequence
< OUString
> & rPaths
= PluginManager::getAdditionalSearchPaths();
318 const OUString
* pPaths
= rPaths
.getConstArray();
319 for ( UINT32 nPos
= rPaths
.getLength(); nPos
--; )
321 addPluginsFromPath( pPaths
[nPos
], rPlugins
);
325 //__________________________________________________________________________________________________
326 Sequence
< PluginDescription
> XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
328 Guard
< Mutex
> aGuard( Mutex::getGlobalMutex() );
329 static Sequence
<PluginDescription
> s_aDescriptions( 0 );
330 static bool s_bInit
= FALSE
;
334 // collect all distinct plugin dlls
335 PluginLocationMap aPlugins
;
336 add_SO_Plugins( aPlugins
);
337 add_NS_Plugins( aPlugins
);
338 add_IE_Plugins( aPlugins
);
340 // collect mime types of plugin dlls
341 for ( PluginLocationMap::iterator
iPos( aPlugins
.begin() );
342 iPos
!= aPlugins
.end();
345 TCHAR arFileName
[MAX_PATH
];
346 DWORD dwDummy
, dwSize
;
349 OUString
aName( (*iPos
).second
.getStr() );
351 OString
aStr( OUStringToOString( aName
, RTL_TEXTENCODING_MS_1252
) );
352 ::strcpy( arFileName
, aStr
.getStr() );
353 dwSize
= ::GetFileVersionInfoSize( arFileName
, &dwDummy
);
358 char * pVersionData
= new char[dwSize
];
359 if (pVersionData
&& ::GetFileVersionInfo( arFileName
, 0, dwSize
, pVersionData
))
364 TCHAR
* pInfo
= NULL
, * pInfo2
= NULL
;
366 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\ProductName"),
367 (void**)&pInfo
, &nSize
) && pInfo
)
369 aComment
.operator=( OStringToOUString( OString(pInfo
), RTL_TEXTENCODING_MS_1252
) );
372 // mandatory mime type and file extensions
373 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\MIMEType"),
374 (void**)&pInfo
, &nSize
) && pInfo
&&
375 ::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\FileExtents"),
376 (void**)&pInfo2
, &nSize
) && pInfo2
)
378 OString
aStr2( pInfo2
);
379 OString
aExt( aStr2
);
380 OString
aStr( pInfo
);
381 OString
aMIME( aStr
);
386 if (aMIME
.getLength())
389 for ( sal_Int32 n
= aMIME
.getLength(); n
--; )
391 if (aMIME
[ n
] == '|')
397 sal_Int32 nIndex
= 0, nIndex2
= 0;
399 UINT32 nStart
= s_aDescriptions
.getLength();
400 s_aDescriptions
.realloc( nStart
+ nToken
);
401 PluginDescription
* pDescriptions
= s_aDescriptions
.getArray();
402 // for every MIME Type
406 if (nIndex
< 0 || nIndex2
< 0)
409 PluginDescription
& rDescr
= pDescriptions
[nStart
+nTok
];
410 OString
aMIMEToken( aMIME
.getToken( 0, '|', nIndex
) );
411 OString
aExtToken2( aExt
.getToken( 0, '|', nIndex2
) );
412 if( aMIMEToken
.getLength() == 0 || aExtToken2
.getLength() == 0 )
415 rDescr
.Mimetype
= OUString(
416 aMIMEToken
.getStr(), aMIMEToken
.getLength(), RTL_TEXTENCODING_MS_1252
);
417 if (! rDescr
.Mimetype
.getLength())
420 OUString
aExtToken( aExtToken2
.getStr(), aExtToken2
.getLength(), RTL_TEXTENCODING_MS_1252
);
421 rDescr
.PluginName
= aName
;
422 rDescr
.Description
= aComment
;
424 sal_Int32 nPos
= 0, nLen
= aExtToken
.getLength();
425 OUString
aExtensions( OUString::createFromAscii( nLen
? "*." : "*.*" ) );
427 for ( ; nPos
< nLen
; ++nPos
)
429 sal_Unicode c
= aExtToken
[nPos
];
434 aExtensions
+= OUString::createFromAscii( ";*." );
438 if (nPos
< (nLen
-1) && aExtToken
[ nPos
+1 ] == '.')
444 aExtensions
+= OUString( &c
, 1 );
447 rDescr
.Extension
= aExtensions
;
454 s_aDescriptions
.realloc( nTok
);
457 #if OSL_DEBUG_LEVEL > 1
459 DBG_ERROR( "### cannot get MIME type or extensions!" );
463 delete[] pVersionData
;
468 return s_aDescriptions
;
472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */