bump product version to 4.1.6.2
[LibreOffice.git] / extensions / source / plugin / win / winmgr.cxx
bloba5535dec0c6d0ab920d89a7d233c52e6d2efa54c
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 ************************************************************************/
30 #include <prewin.h>
31 #include <postwin.h>
32 #undef OPTIONAL
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"
44 #if defined _MSC_VER
45 #pragma warning (push,1)
46 #pragma warning (disable:4005)
47 #endif
49 #include <string.h>
50 #include <tchar.h>
51 #include <objbase.h>
53 #if defined _MSC_VER
54 #pragma warning (pop)
55 #endif
57 #include <list>
58 #include <map>
59 #include <algorithm>
62 using namespace std;
63 using namespace osl;
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];
75 arPluginsPath[0] = 0;
77 if (::rtl_str_indexOfStr( pPluginsPath, "%programfiles%" ) == 0)
79 const char * p = ::getenv( "ProgramFiles" );
80 if (p)
82 ::lstrcpy( arPluginsPath, p );
83 pPluginsPath += 14;
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 ))
115 break;
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 )
138 HKEY hKey;
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))
149 // add \\Plugins
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];
162 DWORD dwType, size;
164 // 4.7
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 );
173 // 6
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 ] = '\\';
184 value[ n ] = 0;
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);
208 HKEY hSubKey;
209 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
211 add_NS_lookupRecursive( hSubKey, rPlugins );
212 ::RegCloseKey( hSubKey );
214 ++dwIndex;
217 //__________________________________________________________________________________________________
218 static void add_MozPlugin( HKEY hKey, PluginLocationMap & rPlugins )
220 TCHAR value[MAX_PATH];
221 DWORD dwType, size;
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);
251 HKEY hSubKey;
252 if (::RegOpenKeyEx( hKey, keyName, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS)
254 add_MozPlugin( hSubKey, rPlugins );
255 ::RegCloseKey( hSubKey );
257 ++dwIndex;
260 //__________________________________________________________________________________________________
261 static void add_NS_Plugins( PluginLocationMap & rPlugins )
263 HKEY hKey;
264 // Netscape
265 if (::RegOpenKeyEx(
266 HKEY_LOCAL_MACHINE, _T("Software\\Netscape"),
267 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
269 add_NS_lookupRecursive( hKey, rPlugins );
270 ::RegCloseKey( hKey );
272 // Mozilla
273 if (::RegOpenKeyEx(
274 HKEY_LOCAL_MACHINE, _T("Software\\Mozilla"),
275 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
277 add_NS_lookupRecursive( hKey, rPlugins );
278 ::RegCloseKey( hKey );
280 // Mozilla - plugins
281 if (::RegOpenKeyEx(
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;
309 if (! s_bInit)
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();
320 ++iPos )
322 TCHAR arFileName[MAX_PATH];
323 DWORD dwDummy, dwSize;
325 // DLL name
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 );
332 if ( !dwSize )
333 continue;
335 char * pVersionData = new char[dwSize];
336 if (pVersionData && ::GetFileVersionInfo( arFileName, 0, dwSize, pVersionData ))
338 // optional comment
339 OUString aComment;
341 TCHAR * pInfo = NULL, * pInfo2 = NULL;
342 UINT nSize = 0;
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 );
357 aMIME.trim();
359 // count mime tokens
360 USHORT nToken = 0;
361 if (aMIME.getLength())
363 ++nToken;
364 for ( sal_Int32 n = aMIME.getLength(); n--; )
366 if (aMIME[ n ] == '|')
368 ++nToken;
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
378 sal_Int32 nTok = 0;
379 while (true)
381 if (nIndex < 0 || nIndex2 < 0)
382 break;
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() )
388 continue;
390 rDescr.Mimetype = OUString(
391 aMIMEToken.getStr(), aMIMEToken.getLength(), RTL_TEXTENCODING_MS_1252 );
392 if (! rDescr.Mimetype.getLength())
393 break;
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];
405 switch (c)
407 case ',':
408 case ';':
409 aExtensions += ";*.";
410 case ' ':
411 break;
412 case '*':
413 if (nPos < (nLen-1) && aExtToken[ nPos+1 ] == '.')
415 ++nPos;
416 break;
418 default:
419 aExtensions += OUString( &c, 1 );
422 rDescr.Extension = aExtensions;
424 ++nTok;
427 if (nToken != nTok)
429 s_aDescriptions.realloc( nTok );
432 #if OSL_DEBUG_LEVEL > 1
433 else
434 OSL_FAIL( "### cannot get MIME type or extensions!" );
435 #endif
437 if (pVersionData)
438 delete[] pVersionData;
441 s_bInit = TRUE;
443 return s_aDescriptions;
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */