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 ************************************************************************/
34 #include "vcl/svapp.hxx"
35 #include "tools/urlobj.hxx"
36 #include "osl/mutex.hxx"
38 #include "rtl/string.hxx"
39 #include "rtl/ustring.hxx"
40 #include "rtl/ustrbuf.hxx"
42 #include "plugin/impl.hxx"
45 #pragma warning (push,1)
46 #pragma warning (disable:4005)
64 using namespace com::sun::star::uno
;
65 using namespace com::sun::star::plugin
;
68 typedef map
< OString
, OUString
, less
< OString
> > PluginLocationMap
;
70 //__________________________________________________________________________________________________
71 static void addPluginsFromPath( const TCHAR
* pPluginsPath
, PluginLocationMap
& rPlugins
)
73 // append dll name pattern we are looking for
74 TCHAR arPluginsPath
[MAX_PATH
];
77 if (::rtl_str_indexOfStr( pPluginsPath
, "%programfiles%" ) == 0)
79 const char * p
= ::getenv( "ProgramFiles" );
82 ::lstrcpy( arPluginsPath
, p
);
86 ::lstrcat( arPluginsPath
, pPluginsPath
);
87 ::lstrcat( arPluginsPath
, _T("\\") );
89 TCHAR arPluginsPattern
[MAX_PATH
];
90 ::lstrcpy( arPluginsPattern
, arPluginsPath
);
91 ::lstrcat( arPluginsPattern
, _T("NP*.DLL") );
93 WIN32_FIND_DATA aFindData
;
94 HANDLE hFind
= ::FindFirstFile( arPluginsPattern
, &aFindData
);
96 while (hFind
!= INVALID_HANDLE_VALUE
)
98 OString aName
= OString( aFindData
.cFileName
).toAsciiLowerCase();
100 // no netscape default plugin anymore...
101 // and no double plugin dlls
102 if ( !aName
.equals( "npnul32.dll" ) &&
103 ! aName
.equals( "npnrvp.dll" ) &&
104 rPlugins
.find( aName
) == rPlugins
.end())
106 TCHAR arComplete
[MAX_PATH
];
107 ::lstrcpy( arComplete
, arPluginsPath
);
108 ::lstrcat( arComplete
, aFindData
.cFileName
);
110 OUString
path( OStringToOUString( arComplete
, RTL_TEXTENCODING_MS_1252
) );
111 rPlugins
[ aName
] = path
;
114 if (! ::FindNextFile( hFind
, &aFindData
))
118 if (hFind
!= INVALID_HANDLE_VALUE
)
119 ::FindClose( hFind
);
121 //__________________________________________________________________________________________________
122 static void addPluginsFromPath( const OUString
& rPath
, PluginLocationMap
& rPlugins
)
124 TCHAR arPluginsPath
[MAX_PATH
];
125 DWORD dwPluginsPathSize
= sizeof(arPluginsPath
);
126 arPluginsPath
[dwPluginsPathSize
-1] = 0;
128 OString
aStr( OUStringToOString( rPath
, RTL_TEXTENCODING_MS_1252
) );
129 ::strncpy( arPluginsPath
, aStr
.getStr(), dwPluginsPathSize
);
131 addPluginsFromPath( arPluginsPath
, rPlugins
);
135 //__________________________________________________________________________________________________
136 static void add_IE_Plugins( PluginLocationMap
& rPlugins
)
139 TCHAR arCurrent
[MAX_PATH
];
140 DWORD dwType
, dwCurrentSize
= sizeof(arCurrent
);
142 if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE
, _T("Software\\Microsoft\\IE4\\SETUP"),
143 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
145 if (::RegQueryValueEx( hKey
, _T("Path"), NULL
, &dwType
,
146 (LPBYTE
)arCurrent
, &dwCurrentSize
) == ERROR_SUCCESS
&&
147 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
150 ::lstrcat( arCurrent
, _T("\\Plugins") );
152 addPluginsFromPath( arCurrent
, rPlugins
);
154 ::RegCloseKey( hKey
);
158 //--------------------------------------------------------------------------------------------------
159 static void add_NS_keys( HKEY hKey
, PluginLocationMap
& rPlugins
)
161 TCHAR value
[MAX_PATH
];
165 size
= sizeof(value
);
166 if (::RegQueryValueEx(
167 hKey
, _T("Plugins Directory"), NULL
, &dwType
,
168 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
169 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
171 addPluginsFromPath( value
, rPlugins
);
174 size
= sizeof(value
);
175 if (::RegQueryValueEx(
176 hKey
, _T("Install Directory"), NULL
, &dwType
,
177 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
178 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
180 int n
= size
/ sizeof (TCHAR
);
181 if ('\\' != value
[ n
-2 ])
183 value
[ n
-1 ] = '\\';
186 addPluginsFromPath( ::lstrcat( value
, _T("Plugins") ), rPlugins
);
188 size
= sizeof(value
);
189 if (::RegQueryValueEx(
190 hKey
, _T("Plugins"), NULL
, &dwType
,
191 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
192 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
194 addPluginsFromPath( value
, rPlugins
);
197 //--------------------------------------------------------------------------------------------------
198 static void add_NS_lookupRecursive( HKEY hKey
, PluginLocationMap
& rPlugins
)
200 add_NS_keys( hKey
, rPlugins
);
202 TCHAR keyName
[MAX_PATH
];
203 DWORD dwIndex
= 0, size
= sizeof (keyName
);
205 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
207 size
= sizeof (keyName
);
209 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
211 add_NS_lookupRecursive( hSubKey
, rPlugins
);
212 ::RegCloseKey( hSubKey
);
217 //__________________________________________________________________________________________________
218 static void add_MozPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
220 TCHAR value
[MAX_PATH
];
223 size
= sizeof(value
);
224 if (::RegQueryValueEx(
225 hKey
, _T("Path"), NULL
, &dwType
,
226 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
227 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
229 OUString
aUPath( OStringToOUString( value
, RTL_TEXTENCODING_MS_1252
) );
230 INetURLObject
aURL( aUPath
);
231 OString
aName( OUStringToOString( aURL
.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252
) );
233 // no netscape default plugin anymore...
234 // and no double plugin dlls
235 if ( !aName
.equals( "npnul32.dll" ) &&
236 ! aName
.equals( "npnrvp.dll" ) &&
237 rPlugins
.find( aName
) == rPlugins
.end())
239 rPlugins
[ aName
] = aUPath
;
243 static void add_MozillaPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
245 TCHAR keyName
[MAX_PATH
];
246 DWORD dwIndex
= 0, size
= sizeof (keyName
);
248 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
250 size
= sizeof (keyName
);
252 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
254 add_MozPlugin( hSubKey
, rPlugins
);
255 ::RegCloseKey( hSubKey
);
260 //__________________________________________________________________________________________________
261 static void add_NS_Plugins( PluginLocationMap
& rPlugins
)
266 HKEY_LOCAL_MACHINE
, _T("Software\\Netscape"),
267 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
269 add_NS_lookupRecursive( hKey
, rPlugins
);
270 ::RegCloseKey( hKey
);
274 HKEY_LOCAL_MACHINE
, _T("Software\\Mozilla"),
275 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
277 add_NS_lookupRecursive( hKey
, rPlugins
);
278 ::RegCloseKey( hKey
);
282 HKEY_LOCAL_MACHINE
, _T("Software\\MozillaPlugins"),
283 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
285 add_MozillaPlugin( hKey
, rPlugins
);
286 ::RegCloseKey( hKey
);
290 //__________________________________________________________________________________________________
291 static void add_SO_Plugins( PluginLocationMap
& rPlugins
)
293 const Sequence
< OUString
> & rPaths
= PluginManager::getAdditionalSearchPaths();
295 const OUString
* pPaths
= rPaths
.getConstArray();
296 for ( UINT32 nPos
= rPaths
.getLength(); nPos
--; )
298 addPluginsFromPath( pPaths
[nPos
], rPlugins
);
302 //__________________________________________________________________________________________________
303 Sequence
< PluginDescription
> XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
305 Guard
< Mutex
> aGuard( Mutex::getGlobalMutex() );
306 static Sequence
<PluginDescription
> s_aDescriptions( 0 );
307 static bool s_bInit
= FALSE
;
311 // collect all distinct plugin dlls
312 PluginLocationMap aPlugins
;
313 add_SO_Plugins( aPlugins
);
314 add_NS_Plugins( aPlugins
);
315 add_IE_Plugins( aPlugins
);
317 // collect mime types of plugin dlls
318 for ( PluginLocationMap::iterator
iPos( aPlugins
.begin() );
319 iPos
!= aPlugins
.end();
322 TCHAR arFileName
[MAX_PATH
];
323 DWORD dwDummy
, dwSize
;
326 OUString
aName( (*iPos
).second
.getStr() );
328 OString
aStr( OUStringToOString( aName
, RTL_TEXTENCODING_MS_1252
) );
329 ::strcpy( arFileName
, aStr
.getStr() );
330 dwSize
= ::GetFileVersionInfoSize( arFileName
, &dwDummy
);
335 char * pVersionData
= new char[dwSize
];
336 if (pVersionData
&& ::GetFileVersionInfo( arFileName
, 0, dwSize
, pVersionData
))
341 TCHAR
* pInfo
= NULL
, * pInfo2
= NULL
;
343 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\ProductName"),
344 (void**)&pInfo
, &nSize
) && pInfo
)
346 aComment
.operator=( OStringToOUString( OString(pInfo
), RTL_TEXTENCODING_MS_1252
) );
349 // mandatory mime type and file extensions
350 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\MIMEType"),
351 (void**)&pInfo
, &nSize
) && pInfo
&&
352 ::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\FileExtents"),
353 (void**)&pInfo2
, &nSize
) && pInfo2
)
355 OString
aExt( pInfo2
);
356 OString
aMIME( pInfo
);
361 if (aMIME
.getLength())
364 for ( sal_Int32 n
= aMIME
.getLength(); n
--; )
366 if (aMIME
[ n
] == '|')
372 sal_Int32 nIndex
= 0, nIndex2
= 0;
374 UINT32 nStart
= s_aDescriptions
.getLength();
375 s_aDescriptions
.realloc( nStart
+ nToken
);
376 PluginDescription
* pDescriptions
= s_aDescriptions
.getArray();
377 // for every MIME Type
381 if (nIndex
< 0 || nIndex2
< 0)
384 PluginDescription
& rDescr
= pDescriptions
[nStart
+nTok
];
385 OString
aMIMEToken( aMIME
.getToken( 0, '|', nIndex
) );
386 OString
aExtToken2( aExt
.getToken( 0, '|', nIndex2
) );
387 if( aMIMEToken
.isEmpty() || aExtToken2
.isEmpty() )
390 rDescr
.Mimetype
= OUString(
391 aMIMEToken
.getStr(), aMIMEToken
.getLength(), RTL_TEXTENCODING_MS_1252
);
392 if (! rDescr
.Mimetype
.getLength())
395 OUString
aExtToken( aExtToken2
.getStr(), aExtToken2
.getLength(), RTL_TEXTENCODING_MS_1252
);
396 rDescr
.PluginName
= aName
;
397 rDescr
.Description
= aComment
;
399 sal_Int32 nPos
= 0, nLen
= aExtToken
.getLength();
400 OUString aExtensions
= nLen
? OUString("*.") : OUString("*.*");
402 for ( ; nPos
< nLen
; ++nPos
)
404 sal_Unicode c
= aExtToken
[nPos
];
409 aExtensions
+= ";*.";
413 if (nPos
< (nLen
-1) && aExtToken
[ nPos
+1 ] == '.')
419 aExtensions
+= OUString( &c
, 1 );
422 rDescr
.Extension
= aExtensions
;
429 s_aDescriptions
.realloc( nTok
);
432 #if OSL_DEBUG_LEVEL > 1
434 OSL_FAIL( "### cannot get MIME type or extensions!" );
438 delete[] pVersionData
;
443 return s_aDescriptions
;
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */