1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #include "vcl/svapp.hxx"
32 #include "tools/fsys.hxx"
33 #include "tools/urlobj.hxx"
34 #include "osl/mutex.hxx"
36 #include "rtl/string.hxx"
37 #include "rtl/ustring.hxx"
38 #include "rtl/ustrbuf.hxx"
40 #include "plugin/impl.hxx"
42 #pragma warning (push,1)
43 #pragma warning (disable:4005)
45 #include "tools/prewin.h"
54 #include "tools/postwin.h"
66 using namespace com::sun::star::uno
;
67 using namespace com::sun::star::plugin
;
69 typedef map
< OString
, OUString
, less
< OString
> > PluginLocationMap
;
72 #if OSL_DEBUG_LEVEL > 1
75 static void logPlugin( OUString
const & path_
)
77 static FILE * s_file
= 0;
79 s_file
= fopen( "d:\\plugins.log", "a+" );
80 OString
path( OUStringToOString( path_
, RTL_TEXTENCODING_ASCII_US
) );
81 fprintf( s_file
, "%s\n", path
.getStr() );
85 //__________________________________________________________________________________________________
86 static void addPluginsFromPath( const TCHAR
* pPluginsPath
, PluginLocationMap
& rPlugins
)
88 // append dll name pattern we are looking for
89 TCHAR arPluginsPath
[MAX_PATH
];
92 if (::rtl_str_indexOfStr( pPluginsPath
, "%programfiles%" ) == 0)
94 const char * p
= ::getenv( "ProgramFiles" );
97 ::lstrcpy( arPluginsPath
, p
);
101 ::lstrcat( arPluginsPath
, pPluginsPath
);
102 ::lstrcat( arPluginsPath
, _T("\\") );
104 TCHAR arPluginsPattern
[MAX_PATH
];
105 ::lstrcpy( arPluginsPattern
, arPluginsPath
);
106 ::lstrcat( arPluginsPattern
, _T("NP*.DLL") );
108 WIN32_FIND_DATA aFindData
;
109 HANDLE hFind
= ::FindFirstFile( arPluginsPattern
, &aFindData
);
111 while (hFind
!= INVALID_HANDLE_VALUE
)
113 OString
aName( aFindData
.cFileName
);
114 aName
.toAsciiLowerCase();
116 // no netscape default plugin anymore...
117 // and no double plugin dlls
118 if ( !aName
.equals( "npnul32.dll" ) &&
119 ! aName
.equals( "npnrvp.dll" ) &&
120 rPlugins
.find( aName
) == rPlugins
.end())
122 TCHAR arComplete
[MAX_PATH
];
123 ::lstrcpy( arComplete
, arPluginsPath
);
124 ::lstrcat( arComplete
, aFindData
.cFileName
);
126 OUString
path( OStringToOUString( arComplete
, RTL_TEXTENCODING_MS_1252
) );
127 rPlugins
[ aName
] = path
;
128 #if OSL_DEBUG_LEVEL > 1
133 if (! ::FindNextFile( hFind
, &aFindData
))
137 if (hFind
!= INVALID_HANDLE_VALUE
)
138 ::FindClose( hFind
);
140 //__________________________________________________________________________________________________
141 static void addPluginsFromPath( const OUString
& rPath
, PluginLocationMap
& rPlugins
)
143 TCHAR arPluginsPath
[MAX_PATH
];
144 DWORD dwPluginsPathSize
= sizeof(arPluginsPath
);
145 arPluginsPath
[dwPluginsPathSize
-1] = 0;
147 OString
aStr( OUStringToOString( rPath
, RTL_TEXTENCODING_MS_1252
) );
148 ::strncpy( arPluginsPath
, aStr
.getStr(), dwPluginsPathSize
);
150 addPluginsFromPath( arPluginsPath
, rPlugins
);
154 //__________________________________________________________________________________________________
155 static void add_IE_Plugins( PluginLocationMap
& rPlugins
)
158 TCHAR arCurrent
[MAX_PATH
];
159 DWORD dwType
, dwCurrentSize
= sizeof(arCurrent
);
161 if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE
, _T("Software\\Microsoft\\IE4\\SETUP"),
162 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
164 if (::RegQueryValueEx( hKey
, _T("Path"), NULL
, &dwType
,
165 (LPBYTE
)arCurrent
, &dwCurrentSize
) == ERROR_SUCCESS
&&
166 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
169 ::lstrcat( arCurrent
, _T("\\Plugins") );
171 addPluginsFromPath( arCurrent
, rPlugins
);
173 ::RegCloseKey( hKey
);
177 //--------------------------------------------------------------------------------------------------
178 static void add_NS_keys( HKEY hKey
, PluginLocationMap
& rPlugins
)
180 TCHAR value
[MAX_PATH
];
181 DWORD dwType
, size
= sizeof(value
);
184 size
= sizeof(value
);
185 if (::RegQueryValueEx(
186 hKey
, _T("Plugins Directory"), NULL
, &dwType
,
187 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
188 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
190 addPluginsFromPath( value
, rPlugins
);
193 size
= sizeof(value
);
194 if (::RegQueryValueEx(
195 hKey
, _T("Install Directory"), NULL
, &dwType
,
196 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
197 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
199 int n
= size
/ sizeof (TCHAR
);
200 if ('\\' != value
[ n
-2 ])
202 value
[ n
-1 ] = '\\';
205 addPluginsFromPath( ::lstrcat( value
, _T("Plugins") ), rPlugins
);
207 size
= sizeof(value
);
208 if (::RegQueryValueEx(
209 hKey
, _T("Plugins"), NULL
, &dwType
,
210 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
211 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
213 addPluginsFromPath( value
, rPlugins
);
216 //--------------------------------------------------------------------------------------------------
217 static void add_NS_lookupRecursive( HKEY hKey
, PluginLocationMap
& rPlugins
)
219 add_NS_keys( hKey
, rPlugins
);
221 TCHAR keyName
[MAX_PATH
];
222 DWORD dwIndex
= 0, size
= sizeof (keyName
);
224 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
226 size
= sizeof (keyName
);
228 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
230 add_NS_lookupRecursive( hSubKey
, rPlugins
);
231 ::RegCloseKey( hSubKey
);
236 //__________________________________________________________________________________________________
237 static void add_MozPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
239 TCHAR value
[MAX_PATH
];
240 DWORD dwType
, size
= sizeof(value
);
242 size
= sizeof(value
);
243 if (::RegQueryValueEx(
244 hKey
, _T("Path"), NULL
, &dwType
,
245 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
246 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
248 OUString
aUPath( OStringToOUString( value
, RTL_TEXTENCODING_MS_1252
) );
249 INetURLObject
aURL( aUPath
);
250 OString
aName( OUStringToOString( aURL
.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252
) );
252 // no netscape default plugin anymore...
253 // and no double plugin dlls
254 if ( !aName
.equals( "npnul32.dll" ) &&
255 ! aName
.equals( "npnrvp.dll" ) &&
256 rPlugins
.find( aName
) == rPlugins
.end())
258 rPlugins
[ aName
] = aUPath
;
259 #if OSL_DEBUG_LEVEL > 1
265 static void add_MozillaPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
267 TCHAR keyName
[MAX_PATH
];
268 DWORD dwIndex
= 0, size
= sizeof (keyName
);
270 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
272 size
= sizeof (keyName
);
274 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
276 add_MozPlugin( hSubKey
, rPlugins
);
277 ::RegCloseKey( hSubKey
);
282 //__________________________________________________________________________________________________
283 static void add_NS_Plugins( PluginLocationMap
& rPlugins
)
288 HKEY_LOCAL_MACHINE
, _T("Software\\Netscape"),
289 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
291 add_NS_lookupRecursive( hKey
, rPlugins
);
292 ::RegCloseKey( hKey
);
296 HKEY_LOCAL_MACHINE
, _T("Software\\Mozilla"),
297 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
299 add_NS_lookupRecursive( hKey
, rPlugins
);
300 ::RegCloseKey( hKey
);
304 HKEY_LOCAL_MACHINE
, _T("Software\\MozillaPlugins"),
305 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
307 add_MozillaPlugin( hKey
, rPlugins
);
308 ::RegCloseKey( hKey
);
312 //__________________________________________________________________________________________________
313 static void add_SO_Plugins( PluginLocationMap
& rPlugins
)
315 const Sequence
< OUString
> & rPaths
= PluginManager::getAdditionalSearchPaths();
317 const OUString
* pPaths
= rPaths
.getConstArray();
318 for ( UINT32 nPos
= rPaths
.getLength(); nPos
--; )
320 addPluginsFromPath( pPaths
[nPos
], rPlugins
);
324 //__________________________________________________________________________________________________
325 Sequence
< PluginDescription
> XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
327 Guard
< Mutex
> aGuard( Mutex::getGlobalMutex() );
328 static Sequence
<PluginDescription
> s_aDescriptions( 0 );
329 static bool s_bInit
= FALSE
;
333 // collect all distinct plugin dlls
334 PluginLocationMap aPlugins
;
335 add_SO_Plugins( aPlugins
);
336 add_NS_Plugins( aPlugins
);
337 add_IE_Plugins( aPlugins
);
339 // collect mime types of plugin dlls
340 for ( PluginLocationMap::iterator
iPos( aPlugins
.begin() );
341 iPos
!= aPlugins
.end();
344 TCHAR arFileName
[MAX_PATH
];
345 DWORD dwDummy
, dwSize
;
348 OUString
aName( (*iPos
).second
.getStr() );
350 OString
aStr( OUStringToOString( aName
, RTL_TEXTENCODING_MS_1252
) );
351 ::strcpy( arFileName
, aStr
.getStr() );
352 dwSize
= ::GetFileVersionInfoSize( arFileName
, &dwDummy
);
357 char * pVersionData
= new char[dwSize
];
358 if (pVersionData
&& ::GetFileVersionInfo( arFileName
, 0, dwSize
, pVersionData
))
363 TCHAR
* pInfo
= NULL
, * pInfo2
= NULL
;
365 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\ProductName"),
366 (void**)&pInfo
, &nSize
) && pInfo
)
368 aComment
.operator=( OStringToOUString( OString(pInfo
), RTL_TEXTENCODING_MS_1252
) );
371 // mandatory mime type and file extensions
372 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\MIMEType"),
373 (void**)&pInfo
, &nSize
) && pInfo
&&
374 ::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\FileExtents"),
375 (void**)&pInfo2
, &nSize
) && pInfo2
)
377 OString
aStr2( pInfo2
);
378 OString
aExt( aStr2
);
379 OString
aStr( pInfo
);
380 OString
aMIME( aStr
);
385 if (aMIME
.getLength())
388 for ( sal_Int32 n
= aMIME
.getLength(); n
--; )
390 if (aMIME
[ n
] == '|')
396 sal_Int32 nIndex
= 0, nIndex2
= 0;
398 UINT32 nStart
= s_aDescriptions
.getLength();
399 s_aDescriptions
.realloc( nStart
+ nToken
);
400 PluginDescription
* pDescriptions
= s_aDescriptions
.getArray();
401 // for every MIME Type
405 if (nIndex
< 0 || nIndex2
< 0)
408 PluginDescription
& rDescr
= pDescriptions
[nStart
+nTok
];
409 OString
aMIMEToken( aMIME
.getToken( 0, '|', nIndex
) );
410 OString
aExtToken2( aExt
.getToken( 0, '|', nIndex2
) );
411 if( aMIMEToken
.getLength() == 0 || aExtToken2
.getLength() == 0 )
414 rDescr
.Mimetype
= OUString(
415 aMIMEToken
.getStr(), aMIMEToken
.getLength(), RTL_TEXTENCODING_MS_1252
);
416 if (! rDescr
.Mimetype
.getLength())
419 OUString
aExtToken( aExtToken2
.getStr(), aExtToken2
.getLength(), RTL_TEXTENCODING_MS_1252
);
420 rDescr
.PluginName
= aName
;
421 rDescr
.Description
= aComment
;
423 sal_Int32 nPos
= 0, nLen
= aExtToken
.getLength();
424 OUString
aExtensions( OUString::createFromAscii( nLen
? "*." : "*.*" ) );
426 for ( ; nPos
< nLen
; ++nPos
)
428 sal_Unicode c
= aExtToken
[nPos
];
433 aExtensions
+= OUString::createFromAscii( ";*." );
437 if (nPos
< (nLen
-1) && aExtToken
[ nPos
+1 ] == '.')
443 aExtensions
+= OUString( &c
, 1 );
446 rDescr
.Extension
= aExtensions
;
453 s_aDescriptions
.realloc( nTok
);
456 #if OSL_DEBUG_LEVEL > 1
458 DBG_ERROR( "### cannot get MIME type or extensions!" );
462 delete[] pVersionData
;
467 return s_aDescriptions
;