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 ************************************************************************/
33 #include "vcl/svapp.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"
44 #pragma warning (push,1)
45 #pragma warning (disable:4005)
63 using namespace com::sun::star::uno
;
64 using namespace com::sun::star::plugin
;
67 typedef map
< OString
, OUString
, less
< OString
> > PluginLocationMap
;
70 static void addPluginsFromPath( const TCHAR
* pPluginsPath
, PluginLocationMap
& rPlugins
)
72 // append dll name pattern we are looking for
73 TCHAR arPluginsPath
[MAX_PATH
];
76 if (::rtl_str_indexOfStr( pPluginsPath
, "%programfiles%" ) == 0)
78 const char * p
= ::getenv( "ProgramFiles" );
81 ::lstrcpy( arPluginsPath
, p
);
85 ::lstrcat( arPluginsPath
, pPluginsPath
);
86 ::lstrcat( arPluginsPath
, _T("\\") );
88 TCHAR arPluginsPattern
[MAX_PATH
];
89 ::lstrcpy( arPluginsPattern
, arPluginsPath
);
90 ::lstrcat( arPluginsPattern
, _T("NP*.DLL") );
92 WIN32_FIND_DATA aFindData
;
93 HANDLE hFind
= ::FindFirstFile( arPluginsPattern
, &aFindData
);
95 while (hFind
!= INVALID_HANDLE_VALUE
)
97 OString aName
= OString( aFindData
.cFileName
).toAsciiLowerCase();
99 // no netscape default plugin anymore...
100 // and no double plugin dlls
101 if ( !aName
.equals( "npnul32.dll" ) &&
102 ! aName
.equals( "npnrvp.dll" ) &&
103 rPlugins
.find( aName
) == rPlugins
.end())
105 TCHAR arComplete
[MAX_PATH
];
106 ::lstrcpy( arComplete
, arPluginsPath
);
107 ::lstrcat( arComplete
, aFindData
.cFileName
);
109 OUString
path( OStringToOUString( arComplete
, RTL_TEXTENCODING_MS_1252
) );
110 rPlugins
[ aName
] = path
;
113 if (! ::FindNextFile( hFind
, &aFindData
))
117 if (hFind
!= INVALID_HANDLE_VALUE
)
118 ::FindClose( hFind
);
121 static void addPluginsFromPath( const OUString
& rPath
, PluginLocationMap
& rPlugins
)
123 TCHAR arPluginsPath
[MAX_PATH
];
124 DWORD dwPluginsPathSize
= sizeof(arPluginsPath
);
125 arPluginsPath
[dwPluginsPathSize
-1] = 0;
127 OString
aStr( OUStringToOString( rPath
, RTL_TEXTENCODING_MS_1252
) );
128 ::strncpy( arPluginsPath
, aStr
.getStr(), dwPluginsPathSize
);
130 addPluginsFromPath( arPluginsPath
, rPlugins
);
135 static void add_IE_Plugins( PluginLocationMap
& rPlugins
)
138 TCHAR arCurrent
[MAX_PATH
];
139 DWORD dwType
, dwCurrentSize
= sizeof(arCurrent
);
141 if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE
, _T("Software\\Microsoft\\IE4\\SETUP"),
142 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
144 if (::RegQueryValueEx( hKey
, _T("Path"), NULL
, &dwType
,
145 (LPBYTE
)arCurrent
, &dwCurrentSize
) == ERROR_SUCCESS
&&
146 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
149 ::lstrcat( arCurrent
, _T("\\Plugins") );
151 addPluginsFromPath( arCurrent
, rPlugins
);
153 ::RegCloseKey( hKey
);
158 static void add_NS_keys( HKEY hKey
, PluginLocationMap
& rPlugins
)
160 TCHAR value
[MAX_PATH
];
164 size
= sizeof(value
);
165 if (::RegQueryValueEx(
166 hKey
, _T("Plugins Directory"), NULL
, &dwType
,
167 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
168 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
170 addPluginsFromPath( value
, rPlugins
);
173 size
= sizeof(value
);
174 if (::RegQueryValueEx(
175 hKey
, _T("Install Directory"), NULL
, &dwType
,
176 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
177 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
179 int n
= size
/ sizeof (TCHAR
);
180 if ('\\' != value
[ n
-2 ])
182 value
[ n
-1 ] = '\\';
185 addPluginsFromPath( ::lstrcat( value
, _T("Plugins") ), rPlugins
);
187 size
= sizeof(value
);
188 if (::RegQueryValueEx(
189 hKey
, _T("Plugins"), NULL
, &dwType
,
190 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
191 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
193 addPluginsFromPath( value
, rPlugins
);
197 static void add_NS_lookupRecursive( HKEY hKey
, PluginLocationMap
& rPlugins
)
199 add_NS_keys( hKey
, rPlugins
);
201 TCHAR keyName
[MAX_PATH
];
202 DWORD dwIndex
= 0, size
= sizeof (keyName
);
204 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
206 size
= sizeof (keyName
);
208 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
210 add_NS_lookupRecursive( hSubKey
, rPlugins
);
211 ::RegCloseKey( hSubKey
);
217 static void add_MozPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
219 TCHAR value
[MAX_PATH
];
222 size
= sizeof(value
);
223 if (::RegQueryValueEx(
224 hKey
, _T("Path"), NULL
, &dwType
,
225 (LPBYTE
)value
, &size
) == ERROR_SUCCESS
&&
226 (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
))
228 OUString
aUPath( OStringToOUString( value
, RTL_TEXTENCODING_MS_1252
) );
229 INetURLObject
aURL( aUPath
);
230 OString
aName( OUStringToOString( aURL
.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252
) );
232 // no netscape default plugin anymore...
233 // and no double plugin dlls
234 if ( !aName
.equals( "npnul32.dll" ) &&
235 ! aName
.equals( "npnrvp.dll" ) &&
236 rPlugins
.find( aName
) == rPlugins
.end())
238 rPlugins
[ aName
] = aUPath
;
242 static void add_MozillaPlugin( HKEY hKey
, PluginLocationMap
& rPlugins
)
244 TCHAR keyName
[MAX_PATH
];
245 DWORD dwIndex
= 0, size
= sizeof (keyName
);
247 while (::RegEnumKeyEx( hKey
, dwIndex
, keyName
, &size
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
249 size
= sizeof (keyName
);
251 if (::RegOpenKeyEx( hKey
, keyName
, 0, KEY_READ
, &hSubKey
) == ERROR_SUCCESS
)
253 add_MozPlugin( hSubKey
, rPlugins
);
254 ::RegCloseKey( hSubKey
);
260 static void add_NS_Plugins( PluginLocationMap
& rPlugins
)
265 HKEY_LOCAL_MACHINE
, _T("Software\\Netscape"),
266 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
268 add_NS_lookupRecursive( hKey
, rPlugins
);
269 ::RegCloseKey( hKey
);
273 HKEY_LOCAL_MACHINE
, _T("Software\\Mozilla"),
274 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
276 add_NS_lookupRecursive( hKey
, rPlugins
);
277 ::RegCloseKey( hKey
);
281 HKEY_LOCAL_MACHINE
, _T("Software\\MozillaPlugins"),
282 0, KEY_READ
, &hKey
) == ERROR_SUCCESS
)
284 add_MozillaPlugin( hKey
, rPlugins
);
285 ::RegCloseKey( hKey
);
290 static void add_SO_Plugins( PluginLocationMap
& rPlugins
)
292 const Sequence
< OUString
> & rPaths
= PluginManager::getAdditionalSearchPaths();
294 const OUString
* pPaths
= rPaths
.getConstArray();
295 for ( UINT32 nPos
= rPaths
.getLength(); nPos
--; )
297 addPluginsFromPath( pPaths
[nPos
], rPlugins
);
302 Sequence
< PluginDescription
> XPluginManager_Impl::impl_getPluginDescriptions() throw(css::uno::RuntimeException
, std::exception
)
304 Guard
< Mutex
> aGuard( Mutex::getGlobalMutex() );
305 static Sequence
<PluginDescription
> s_aDescriptions( 0 );
306 static bool s_bInit
= FALSE
;
310 // collect all distinct plugin dlls
311 PluginLocationMap aPlugins
;
312 add_SO_Plugins( aPlugins
);
313 add_NS_Plugins( aPlugins
);
314 add_IE_Plugins( aPlugins
);
316 // collect mime types of plugin dlls
317 for ( PluginLocationMap::iterator
iPos( aPlugins
.begin() );
318 iPos
!= aPlugins
.end();
321 TCHAR arFileName
[MAX_PATH
];
322 DWORD dwDummy
, dwSize
;
325 OUString
aName( (*iPos
).second
.getStr() );
327 OString
aStr( OUStringToOString( aName
, RTL_TEXTENCODING_MS_1252
) );
328 ::strcpy( arFileName
, aStr
.getStr() );
329 dwSize
= ::GetFileVersionInfoSize( arFileName
, &dwDummy
);
334 char * pVersionData
= new char[dwSize
];
335 if (::GetFileVersionInfo( arFileName
, 0, dwSize
, pVersionData
))
340 TCHAR
* pInfo
= NULL
, * pInfo2
= NULL
;
342 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\ProductName"),
343 (void**)&pInfo
, &nSize
) && pInfo
)
345 aComment
.operator=( OStringToOUString( OString(pInfo
), RTL_TEXTENCODING_MS_1252
) );
348 // mandatory mime type and file extensions
349 if (::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\MIMEType"),
350 (void**)&pInfo
, &nSize
) && pInfo
&&
351 ::VerQueryValue( pVersionData
, _T("\\StringFileInfo\\040904E4\\FileExtents"),
352 (void**)&pInfo2
, &nSize
) && pInfo2
)
354 OString
aExt( pInfo2
);
355 OString
aMIME( pInfo
);
360 if (aMIME
.getLength())
363 for ( sal_Int32 n
= aMIME
.getLength(); n
--; )
365 if (aMIME
[ n
] == '|')
371 sal_Int32 nIndex
= 0, nIndex2
= 0;
373 UINT32 nStart
= s_aDescriptions
.getLength();
374 s_aDescriptions
.realloc( nStart
+ nToken
);
375 PluginDescription
* pDescriptions
= s_aDescriptions
.getArray();
376 // for every MIME Type
380 if (nIndex
< 0 || nIndex2
< 0)
383 PluginDescription
& rDescr
= pDescriptions
[nStart
+nTok
];
384 OString
aMIMEToken( aMIME
.getToken( 0, '|', nIndex
) );
385 OString
aExtToken2( aExt
.getToken( 0, '|', nIndex2
) );
386 if( aMIMEToken
.isEmpty() || aExtToken2
.isEmpty() )
389 rDescr
.Mimetype
= OUString(
390 aMIMEToken
.getStr(), aMIMEToken
.getLength(), RTL_TEXTENCODING_MS_1252
);
391 if (! rDescr
.Mimetype
.getLength())
394 OUString
aExtToken( aExtToken2
.getStr(), aExtToken2
.getLength(), RTL_TEXTENCODING_MS_1252
);
395 rDescr
.PluginName
= aName
;
396 rDescr
.Description
= aComment
;
398 sal_Int32 nPos
= 0, nLen
= aExtToken
.getLength();
399 OUString aExtensions
= nLen
? OUString("*.") : OUString("*.*");
401 for ( ; nPos
< nLen
; ++nPos
)
403 sal_Unicode c
= aExtToken
[nPos
];
408 aExtensions
+= ";*.";
412 if (nPos
< (nLen
-1) && aExtToken
[ nPos
+1 ] == '.')
418 aExtensions
+= OUString( &c
, 1 );
421 rDescr
.Extension
= aExtensions
;
428 s_aDescriptions
.realloc( nTok
);
431 #if OSL_DEBUG_LEVEL > 1
433 OSL_FAIL( "### cannot get MIME type or extensions!" );
436 delete[] pVersionData
;
441 return s_aDescriptions
;
445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */