merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / plugin / win / winmgr.cxx
blobe4a9d9732c2457b7645aaea27c6149738b71063e
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"
47 #include <windows.h>
48 #include <string.h>
49 #include <tchar.h>
50 #include <winreg.h>
51 #include <winbase.h>
52 #include <objbase.h>
54 #include "tools/postwin.h"
56 #pragma warning (pop)
58 #include <list>
59 #include <map>
60 #include <algorithm>
63 using namespace rtl;
64 using namespace std;
65 using namespace osl;
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
73 #include <stdio.h>
75 static void logPlugin( OUString const & path_ )
77 static FILE * s_file = 0;
78 if (! s_file)
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() );
83 #endif
85 //__________________________________________________________________________________________________
86 static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
88 // append dll name pattern we are looking for
89 TCHAR arPluginsPath[MAX_PATH];
90 arPluginsPath[0] = 0;
92 if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
94 const char * p = ::getenv( "ProgramFiles" );
95 if (p)
97 ::lstrcpy( arPluginsPath, p );
98 pPluginsPath += 14;
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
129 logPlugin( path );
130 #endif
133 if (! ::FindNextFile( hFind, &aFindData ))
134 break;
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 )
157 HKEY hKey;
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))
168 // add \\Plugins
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);
183 // 4.7
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 );
192 // 6
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 ] = '\\';
203 value[ n ] = 0;
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);
227 HKEY hSubKey;
228 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
230 add_NS_lookupRecursive( hSubKey, rPlugins );
231 ::RegCloseKey( hSubKey );
233 ++dwIndex;
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
260 logPlugin( aUPath );
261 #endif
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);
273 HKEY hSubKey;
274 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
276 add_MozPlugin( hSubKey, rPlugins );
277 ::RegCloseKey( hSubKey );
279 ++dwIndex;
282 //__________________________________________________________________________________________________
283 static void add_NS_Plugins( PluginLocationMap & rPlugins )
285 HKEY hKey;
286 // Netscape
287 if (::RegOpenKeyEx(
288 HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
289 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
291 add_NS_lookupRecursive( hKey, rPlugins );
292 ::RegCloseKey( hKey );
294 // Mozilla
295 if (::RegOpenKeyEx(
296 HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
297 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
299 add_NS_lookupRecursive( hKey, rPlugins );
300 ::RegCloseKey( hKey );
302 // Mozilla - plugins
303 if (::RegOpenKeyEx(
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;
331 if (! s_bInit)
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();
342 ++iPos )
344 TCHAR arFileName[MAX_PATH];
345 DWORD dwDummy, dwSize;
347 // DLL name
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 );
354 if ( !dwSize )
355 continue;
357 char * pVersionData = new char[dwSize];
358 if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
360 // optional comment
361 OUString aComment;
363 TCHAR * pInfo = NULL, * pInfo2 = NULL;
364 UINT nSize = 0;
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 );
381 aMIME.trim();
383 // count mime tokens
384 USHORT nToken = 0;
385 if (aMIME.getLength())
387 ++nToken;
388 for ( sal_Int32 n = aMIME.getLength(); n--; )
390 if (aMIME[ n ] == '|')
392 ++nToken;
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
402 sal_Int32 nTok = 0;
403 while (true)
405 if (nIndex < 0 || nIndex2 < 0)
406 break;
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 )
412 continue;
414 rDescr.Mimetype = OUString(
415 aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
416 if (! rDescr.Mimetype.getLength())
417 break;
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];
429 switch (c)
431 case ',':
432 case ';':
433 aExtensions += OUString::createFromAscii( ";*." );
434 case ' ':
435 break;
436 case '*':
437 if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
439 ++nPos;
440 break;
442 default:
443 aExtensions += OUString( &c, 1 );
446 rDescr.Extension = aExtensions;
448 ++nTok;
451 if (nToken != nTok)
453 s_aDescriptions.realloc( nTok );
456 #if OSL_DEBUG_LEVEL > 1
457 else
458 DBG_ERROR( "### cannot get MIME type or extensions!" );
459 #endif
461 if (pVersionData)
462 delete[] pVersionData;
465 s_bInit = TRUE;
467 return s_aDescriptions;