merge the formfield patch from ooo-build
[ooovba.git] / extensions / source / plugin / win / winmgr.cxx
blob3eabdb244b9739dccde30a5e1ef50bfc6d106763
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: winmgr.cxx,v $
10 * $Revision: 1.16.90.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "vcl/svapp.hxx"
35 #include "tools/fsys.hxx"
36 #include "tools/urlobj.hxx"
37 #include "osl/mutex.hxx"
39 #include "rtl/string.hxx"
40 #include "rtl/ustring.hxx"
41 #include "rtl/ustrbuf.hxx"
43 #include "plugin/impl.hxx"
45 #pragma warning (push,1)
46 #pragma warning (disable:4005)
48 #include "tools/prewin.h"
50 #include <windows.h>
51 #include <string.h>
52 #include <tchar.h>
53 #include <winreg.h>
54 #include <winbase.h>
55 #include <objbase.h>
57 #include "tools/postwin.h"
59 #pragma warning (pop)
61 #include <list>
62 #include <map>
63 #include <algorithm>
66 using namespace rtl;
67 using namespace std;
68 using namespace osl;
69 using namespace com::sun::star::uno;
70 using namespace com::sun::star::plugin;
72 typedef map< OString, OUString, less< OString > > PluginLocationMap;
75 #if OSL_DEBUG_LEVEL > 1
76 #include <stdio.h>
78 static void logPlugin( OUString const & path_ )
80 static FILE * s_file = 0;
81 if (! s_file)
82 s_file = fopen( "d:\\plugins.log", "a+" );
83 OString path( OUStringToOString( path_, RTL_TEXTENCODING_ASCII_US ) );
84 fprintf( s_file, "%s\n", path.getStr() );
86 #endif
88 //__________________________________________________________________________________________________
89 static void addPluginsFromPath( const TCHAR * pPluginsPath, PluginLocationMap & rPlugins )
91 // append dll name pattern we are looking for
92 TCHAR arPluginsPath[MAX_PATH];
93 arPluginsPath[0] = 0;
95 if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
97 const char * p = ::getenv( "ProgramFiles" );
98 if (p)
100 ::lstrcpy( arPluginsPath, p );
101 pPluginsPath += 14;
104 ::lstrcat( arPluginsPath, pPluginsPath );
105 ::lstrcat( arPluginsPath, _T("\\") );
107 TCHAR arPluginsPattern[MAX_PATH];
108 ::lstrcpy( arPluginsPattern, arPluginsPath );
109 ::lstrcat( arPluginsPattern, _T("NP*.DLL") );
111 WIN32_FIND_DATA aFindData;
112 HANDLE hFind = ::FindFirstFile( arPluginsPattern, &aFindData );
114 while (hFind != INVALID_HANDLE_VALUE)
116 OString aName( aFindData.cFileName );
117 aName.toAsciiLowerCase();
119 // no netscape default plugin anymore...
120 // and no double plugin dlls
121 if ( !aName.equals( "npnul32.dll" ) &&
122 ! aName.equals( "npnrvp.dll" ) &&
123 rPlugins.find( aName ) == rPlugins.end())
125 TCHAR arComplete[MAX_PATH];
126 ::lstrcpy( arComplete, arPluginsPath );
127 ::lstrcat( arComplete, aFindData.cFileName );
129 OUString path( OStringToOUString( arComplete, RTL_TEXTENCODING_MS_1252 ) );
130 rPlugins[ aName ] = path;
131 #if OSL_DEBUG_LEVEL > 1
132 logPlugin( path );
133 #endif
136 if (! ::FindNextFile( hFind, &aFindData ))
137 break;
140 if (hFind != INVALID_HANDLE_VALUE)
141 ::FindClose( hFind );
143 //__________________________________________________________________________________________________
144 static void addPluginsFromPath( const OUString & rPath, PluginLocationMap & rPlugins )
146 TCHAR arPluginsPath[MAX_PATH];
147 DWORD dwPluginsPathSize = sizeof(arPluginsPath);
148 arPluginsPath[dwPluginsPathSize-1] = 0;
150 OString aStr( OUStringToOString( rPath, RTL_TEXTENCODING_MS_1252 ) );
151 ::strncpy( arPluginsPath, aStr.getStr(), dwPluginsPathSize );
153 addPluginsFromPath( arPluginsPath, rPlugins );
157 //__________________________________________________________________________________________________
158 static void add_IE_Plugins( PluginLocationMap & rPlugins )
160 HKEY hKey;
161 TCHAR arCurrent[MAX_PATH];
162 DWORD dwType, dwCurrentSize = sizeof(arCurrent);
164 if (::RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\IE4\\SETUP"),
165 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
167 if (::RegQueryValueEx( hKey, _T("Path"), NULL, &dwType,
168 (LPBYTE)arCurrent, &dwCurrentSize ) == ERROR_SUCCESS &&
169 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
171 // add \\Plugins
172 ::lstrcat( arCurrent, _T("\\Plugins") );
174 addPluginsFromPath( arCurrent, rPlugins );
176 ::RegCloseKey( hKey );
180 //--------------------------------------------------------------------------------------------------
181 static void add_NS_keys( HKEY hKey, PluginLocationMap & rPlugins )
183 TCHAR value[MAX_PATH];
184 DWORD dwType, size = sizeof(value);
186 // 4.7
187 size = sizeof(value);
188 if (::RegQueryValueEx(
189 hKey, _T("Plugins Directory"), NULL, &dwType,
190 (LPBYTE)value, &size ) == ERROR_SUCCESS &&
191 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
193 addPluginsFromPath( value, rPlugins );
195 // 6
196 size = sizeof(value);
197 if (::RegQueryValueEx(
198 hKey, _T("Install Directory"), NULL, &dwType,
199 (LPBYTE)value, &size ) == ERROR_SUCCESS &&
200 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
202 int n = size / sizeof (TCHAR);
203 if ('\\' != value[ n -2 ])
205 value[ n -1 ] = '\\';
206 value[ n ] = 0;
208 addPluginsFromPath( ::lstrcat( value, _T("Plugins") ), rPlugins );
210 size = sizeof(value);
211 if (::RegQueryValueEx(
212 hKey, _T("Plugins"), NULL, &dwType,
213 (LPBYTE)value, &size ) == ERROR_SUCCESS &&
214 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
216 addPluginsFromPath( value, rPlugins );
219 //--------------------------------------------------------------------------------------------------
220 static void add_NS_lookupRecursive( HKEY hKey, PluginLocationMap & rPlugins )
222 add_NS_keys( hKey, rPlugins );
224 TCHAR keyName[MAX_PATH];
225 DWORD dwIndex = 0, size = sizeof (keyName);
227 while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
229 size = sizeof (keyName);
230 HKEY hSubKey;
231 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
233 add_NS_lookupRecursive( hSubKey, rPlugins );
234 ::RegCloseKey( hSubKey );
236 ++dwIndex;
239 //__________________________________________________________________________________________________
240 static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
242 TCHAR value[MAX_PATH];
243 DWORD dwType, size = sizeof(value);
245 size = sizeof(value);
246 if (::RegQueryValueEx(
247 hKey, _T("Path"), NULL, &dwType,
248 (LPBYTE)value, &size ) == ERROR_SUCCESS &&
249 (dwType == REG_SZ || dwType == REG_EXPAND_SZ))
251 OUString aUPath( OStringToOUString( value, RTL_TEXTENCODING_MS_1252 ) );
252 INetURLObject aURL( aUPath );
253 OString aName( OUStringToOString( aURL.GetName().toAsciiLowerCase(), RTL_TEXTENCODING_MS_1252 ) );
255 // no netscape default plugin anymore...
256 // and no double plugin dlls
257 if ( !aName.equals( "npnul32.dll" ) &&
258 ! aName.equals( "npnrvp.dll" ) &&
259 rPlugins.find( aName ) == rPlugins.end())
261 rPlugins[ aName ] = aUPath;
262 #if OSL_DEBUG_LEVEL > 1
263 logPlugin( aUPath );
264 #endif
268 static void add_MozillaPlugin( HKEY hKey, PluginLocationMap & rPlugins )
270 TCHAR keyName[MAX_PATH];
271 DWORD dwIndex = 0, size = sizeof (keyName);
273 while (::RegEnumKeyEx( hKey, dwIndex, keyName, &size, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS)
275 size = sizeof (keyName);
276 HKEY hSubKey;
277 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
279 add_MozPlugin( hSubKey, rPlugins );
280 ::RegCloseKey( hSubKey );
282 ++dwIndex;
285 //__________________________________________________________________________________________________
286 static void add_NS_Plugins( PluginLocationMap & rPlugins )
288 HKEY hKey;
289 // Netscape
290 if (::RegOpenKeyEx(
291 HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
292 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
294 add_NS_lookupRecursive( hKey, rPlugins );
295 ::RegCloseKey( hKey );
297 // Mozilla
298 if (::RegOpenKeyEx(
299 HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
300 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
302 add_NS_lookupRecursive( hKey, rPlugins );
303 ::RegCloseKey( hKey );
305 // Mozilla - plugins
306 if (::RegOpenKeyEx(
307 HKEY_LOCAL_MACHINE, _T("Software\\MozillaPlugins"),
308 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
310 add_MozillaPlugin( hKey, rPlugins );
311 ::RegCloseKey( hKey );
315 //__________________________________________________________________________________________________
316 static void add_SO_Plugins( PluginLocationMap & rPlugins )
318 const Sequence< OUString > & rPaths = PluginManager::getAdditionalSearchPaths();
320 const OUString * pPaths = rPaths.getConstArray();
321 for ( UINT32 nPos = rPaths.getLength(); nPos--; )
323 addPluginsFromPath( pPaths[nPos], rPlugins );
327 //__________________________________________________________________________________________________
328 Sequence< PluginDescription > XPluginManager_Impl::impl_getPluginDescriptions(void) throw()
330 Guard< Mutex > aGuard( Mutex::getGlobalMutex() );
331 static Sequence<PluginDescription > s_aDescriptions( 0 );
332 static bool s_bInit = FALSE;
334 if (! s_bInit)
336 // collect all distinct plugin dlls
337 PluginLocationMap aPlugins;
338 add_SO_Plugins( aPlugins );
339 add_NS_Plugins( aPlugins );
340 add_IE_Plugins( aPlugins );
342 // collect mime types of plugin dlls
343 for ( PluginLocationMap::iterator iPos( aPlugins.begin() );
344 iPos != aPlugins.end();
345 ++iPos )
347 TCHAR arFileName[MAX_PATH];
348 DWORD dwDummy, dwSize;
350 // DLL name
351 OUString aName( (*iPos).second.getStr() );
353 OString aStr( OUStringToOString( aName, RTL_TEXTENCODING_MS_1252 ) );
354 ::strcpy( arFileName, aStr.getStr() );
355 dwSize = ::GetFileVersionInfoSize( arFileName, &dwDummy );
357 if ( !dwSize )
358 continue;
360 char * pVersionData = new char[dwSize];
361 if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
363 // optional comment
364 OUString aComment;
366 TCHAR * pInfo = NULL, * pInfo2 = NULL;
367 UINT nSize = 0;
368 if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\ProductName"),
369 (void**)&pInfo, &nSize ) && pInfo)
371 aComment.operator=( OStringToOUString( OString(pInfo), RTL_TEXTENCODING_MS_1252 ) );
374 // mandatory mime type and file extensions
375 if (::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\MIMEType"),
376 (void**)&pInfo, &nSize ) && pInfo &&
377 ::VerQueryValue( pVersionData, _T("\\StringFileInfo\\040904E4\\FileExtents"),
378 (void**)&pInfo2, &nSize ) && pInfo2)
380 OString aStr2( pInfo2 );
381 OString aExt( aStr2 );
382 OString aStr( pInfo );
383 OString aMIME( aStr );
384 aMIME.trim();
386 // count mime tokens
387 USHORT nToken = 0;
388 if (aMIME.getLength())
390 ++nToken;
391 for ( sal_Int32 n = aMIME.getLength(); n--; )
393 if (aMIME[ n ] == '|')
395 ++nToken;
399 sal_Int32 nIndex = 0, nIndex2 = 0;
401 UINT32 nStart = s_aDescriptions.getLength();
402 s_aDescriptions.realloc( nStart + nToken );
403 PluginDescription* pDescriptions = s_aDescriptions.getArray();
404 // for every MIME Type
405 sal_Int32 nTok = 0;
406 while (true)
408 if (nIndex < 0 || nIndex2 < 0)
409 break;
411 PluginDescription & rDescr = pDescriptions[nStart+nTok];
412 OString aMIMEToken( aMIME.getToken( 0, '|', nIndex ) );
413 OString aExtToken2( aExt.getToken( 0, '|', nIndex2 ) );
414 if( aMIMEToken.getLength() == 0 || aExtToken2.getLength() == 0 )
415 continue;
417 rDescr.Mimetype = OUString(
418 aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
419 if (! rDescr.Mimetype.getLength())
420 break;
422 OUString aExtToken( aExtToken2.getStr(), aExtToken2.getLength(), RTL_TEXTENCODING_MS_1252 );
423 rDescr.PluginName = aName;
424 rDescr.Description = aComment;
426 sal_Int32 nPos = 0, nLen = aExtToken.getLength();
427 OUString aExtensions( OUString::createFromAscii( nLen ? "*." : "*.*" ) );
429 for ( ; nPos < nLen; ++nPos )
431 sal_Unicode c = aExtToken[nPos];
432 switch (c)
434 case ',':
435 case ';':
436 aExtensions += OUString::createFromAscii( ";*." );
437 case ' ':
438 break;
439 case '*':
440 if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
442 ++nPos;
443 break;
445 default:
446 aExtensions += OUString( &c, 1 );
449 rDescr.Extension = aExtensions;
451 ++nTok;
454 if (nToken != nTok)
456 s_aDescriptions.realloc( nTok );
459 #if OSL_DEBUG_LEVEL > 1
460 else
461 DBG_ERROR( "### cannot get MIME type or extensions!" );
462 #endif
464 if (pVersionData)
465 delete[] pVersionData;
468 s_bInit = TRUE;
470 return s_aDescriptions;