merged tag LIBREOFFICE_3_2_99_3
[LibreOffice.git] / extensions / source / plugin / win / winmgr.cxx
blobdb90cfbf7a45072c54a07b91de0599f8ebadd1d9
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"
48 #include <windows.h>
49 #include <string.h>
50 #include <tchar.h>
51 #include <winreg.h>
52 #include <winbase.h>
53 #include <objbase.h>
55 #include "tools/postwin.h"
57 #pragma warning (pop)
59 #include <list>
60 #include <map>
61 #include <algorithm>
64 using namespace rtl;
65 using namespace std;
66 using namespace osl;
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
74 #include <stdio.h>
76 static void logPlugin( OUString const & path_ )
78 static FILE * s_file = 0;
79 if (! s_file)
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() );
84 #endif
86 //__________________________________________________________________________________________________
87 static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
89 // append dll name pattern we are looking for
90 TCHAR arPluginsPath[MAX_PATH];
91 arPluginsPath[0] = 0;
93 if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
95 const char * p = ::getenv( "ProgramFiles" );
96 if (p)
98 ::lstrcpy( arPluginsPath, p );
99 pPluginsPath += 14;
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
130 logPlugin( path );
131 #endif
134 if (! ::FindNextFile( hFind, &aFindData ))
135 break;
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 )
158 HKEY hKey;
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))
169 // add \\Plugins
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);
184 // 4.7
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 );
193 // 6
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 ] = '\\';
204 value[ n ] = 0;
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);
228 HKEY hSubKey;
229 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
231 add_NS_lookupRecursive( hSubKey, rPlugins );
232 ::RegCloseKey( hSubKey );
234 ++dwIndex;
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
261 logPlugin( aUPath );
262 #endif
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);
274 HKEY hSubKey;
275 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
277 add_MozPlugin( hSubKey, rPlugins );
278 ::RegCloseKey( hSubKey );
280 ++dwIndex;
283 //__________________________________________________________________________________________________
284 static void add_NS_Plugins( PluginLocationMap & rPlugins )
286 HKEY hKey;
287 // Netscape
288 if (::RegOpenKeyEx(
289 HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
290 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
292 add_NS_lookupRecursive( hKey, rPlugins );
293 ::RegCloseKey( hKey );
295 // Mozilla
296 if (::RegOpenKeyEx(
297 HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
298 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
300 add_NS_lookupRecursive( hKey, rPlugins );
301 ::RegCloseKey( hKey );
303 // Mozilla - plugins
304 if (::RegOpenKeyEx(
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;
332 if (! s_bInit)
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();
343 ++iPos )
345 TCHAR arFileName[MAX_PATH];
346 DWORD dwDummy, dwSize;
348 // DLL name
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 );
355 if ( !dwSize )
356 continue;
358 char * pVersionData = new char[dwSize];
359 if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
361 // optional comment
362 OUString aComment;
364 TCHAR * pInfo = NULL, * pInfo2 = NULL;
365 UINT nSize = 0;
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 );
382 aMIME.trim();
384 // count mime tokens
385 USHORT nToken = 0;
386 if (aMIME.getLength())
388 ++nToken;
389 for ( sal_Int32 n = aMIME.getLength(); n--; )
391 if (aMIME[ n ] == '|')
393 ++nToken;
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
403 sal_Int32 nTok = 0;
404 while (true)
406 if (nIndex < 0 || nIndex2 < 0)
407 break;
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 )
413 continue;
415 rDescr.Mimetype = OUString(
416 aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
417 if (! rDescr.Mimetype.getLength())
418 break;
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];
430 switch (c)
432 case ',':
433 case ';':
434 aExtensions += OUString::createFromAscii( ";*." );
435 case ' ':
436 break;
437 case '*':
438 if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
440 ++nPos;
441 break;
443 default:
444 aExtensions += OUString( &c, 1 );
447 rDescr.Extension = aExtensions;
449 ++nTok;
452 if (nToken != nTok)
454 s_aDescriptions.realloc( nTok );
457 #if OSL_DEBUG_LEVEL > 1
458 else
459 DBG_ERROR( "### cannot get MIME type or extensions!" );
460 #endif
462 if (pVersionData)
463 delete[] pVersionData;
466 s_bInit = TRUE;
468 return s_aDescriptions;
472 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */