1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 /*
29     Windows shell extensions need to be approved in order to be used by the
30     Windows shell for clarification read the following section from the
31     Microsoft Developers Network Library (MSDN) see
32     http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_int/shell_int_extending/extensionhandlers/shell_ext.asp
33 
34 
35     <MSDN>
36     Shell extension handlers run in the Shell process. Because it is a system process,
37     the administrator of a Windows NT system can limit Shell extension handlers to
38     those on an approved list by setting the EnforceShellExtensionSecurity value of the
39     HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer key to 1
40     (one).
41     To place a Shell extension handler on the approved list, create a REG_SZ value whose
42     name is the string form of the handler's GUID under
43     HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved.
44 
45     The Shell does not use the value that is assigned to the GUID, but it should be set to
46     make inspecting the registry easier.
47 
48     Your setup application can add values to the Approved key only if the person installing
49     the application has sufficient privileges. If the attempt to add an extension handler
50     fails, you should inform the user that administrative privileges are required to fully
51     install the application. If the handler is essential to the application, you should fail
52     the setup and notify the user to contact an administrator.
53 
54     While there is no need to add values to the Approved key on Windows 95 or Windows 98
55     systems, there is no harm in doing so. The system will simply ignore them. However, there
56     is no guarantee that the key will exist on these systems. Your setup program must be able
57     to handle this case.
58     </MSDN>
59 
60     We add the following entries to the respective registry key
61     "{C52AF81D-F7A0-4AAB-8E87-F80A60CCD396}"="OpenOffice.org Column Handler"
62     "{087B3AE3-E237-4467-B8DB-5A38AB959AC9}"="OpenOffice.org Infotip Handler"
63     "{63542C48-9552-494A-84F7-73AA6A7C99C1}"="OpenOffice.org Property Sheet Handler"
64     "{3B092F0C-7696-40E3-A80F-68D74DA84210}"="OpenOffice.org Thumbnail Viewer"
65 
66     These shell extensions are implemented in the 'shell' project. We ignore registration
67     failures because of insufficient privileges. The reason is: On systems which restrict the
68     use of shell extensions by applying the aforementioned policy probably only people with
69     sufficient privileges are allowed to install applications anyway. On systems where the
70     use of shell extensions is not restricted registration failures because of insufficient
71     prviliges have no negative effect because the shell extensions will work anyhow.
72 */
73 
74 #ifdef _MSC_VER
75 #pragma warning(push, 1) /* disable warnings within system headers */
76 #endif
77 #define WIN32_LEAN_AND_MEAN
78 #include <windows.h>
79 #include <msiquery.h>
80 #ifdef _MSC_VER
81 #pragma warning(pop)
82 #endif
83 
84 #include <malloc.h>
85 
86 #ifdef UNICODE
87 #define _UNICODE
88 #endif
89 #include <tchar.h>
90 
91 struct RegistryEntry
92 {
93     TCHAR* Key;
94     TCHAR* Value;
95 };
96 
97 RegistryEntry ColumnHandler = { TEXT("{C52AF81D-F7A0-4AAB-8E87-F80A60CCD396}"), TEXT("OpenOffice.org Column Handler") };
98 RegistryEntry InfotipHandler = { TEXT("{087B3AE3-E237-4467-B8DB-5A38AB959AC9}"), TEXT("OpenOffice.org Infotip Handler") };
99 RegistryEntry PropHandler = { TEXT("{63542C48-9552-494A-84F7-73AA6A7C99C1}"), TEXT("OpenOffice.org Property Sheet Handler") };
100 RegistryEntry ThumbViewer = { TEXT("{3B092F0C-7696-40E3-A80F-68D74DA84210}"), TEXT("OpenOffice.org Thumbnail Viewer") };
101 
102 BOOL GetMsiProp( MSIHANDLE hMSI, const char* pPropName, char** ppValue )
103 {
104     DWORD sz = 0;
105    	if ( MsiGetProperty( hMSI, pPropName, 0, &sz ) == ERROR_MORE_DATA )
106    	{
107        	sz++;
108        	DWORD nbytes = sz * sizeof( char );
109        	char* buff = reinterpret_cast<char*>( malloc( nbytes ) );
110        	ZeroMemory( buff, nbytes );
111        	MsiGetProperty( hMSI, pPropName, buff, &sz );
112    		*ppValue = buff;
113 
114 		return TRUE;
115 	}
116 
117 	return FALSE;
118 }
119 
120 bool IsVersionNT64( MSIHANDLE hMSI )
121 {
122     char* pVal = NULL;
123 
124 	if ( GetMsiProp( hMSI, "VersionNT64", &pVal ) && pVal )
125 	{
126 		free( pVal );
127 		return true;
128 	}
129 
130 	return false;
131 }
132 
133 
134 
135 
136 /*
137     Called during installation when the module "Windows Explorer Extensions" is
138     selected.
139 */
140 extern "C" UINT __stdcall InstallExecSequenceEntry(MSIHANDLE hMSI)
141 {
142     //MessageBox(NULL, TEXT("InstallExecSequenceEntry"), TEXT("Pythonmsi"), MB_OK | MB_ICONINFORMATION);
143     HKEY hKey;
144 
145 
146 // 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
147 // in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
148 // Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
149 // extensions\source\activex\main\so_activex.cpp
150 #ifndef KEY_WOW64_64KEY
151 	#define KEY_WOW64_64KEY	(0x0100)
152 #endif
153 
154 	if (IsVersionNT64(hMSI))
155 	{
156 		// Open Windows 64 Bit Registry
157 		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),0, KEY_WRITE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
158 		{
159 			RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
160 			RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
161 			RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
162 			RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
163 
164 			RegCloseKey(hKey);
165 		}
166 
167 		// Open Windows 32 Bit Registry on Win64 maschine
168 
169 		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),0, KEY_WRITE, &hKey ) == ERROR_SUCCESS)
170 		{
171 			RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
172 			RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
173 			RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
174 			RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
175 
176 			RegCloseKey(hKey);
177 		}
178 
179 
180 	} else
181 	{
182 		if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hKey) == ERROR_SUCCESS)
183 		{
184 			RegSetValueEx(hKey, ColumnHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ColumnHandler.Value), _tcslen(ColumnHandler.Value) + 1);
185 			RegSetValueEx(hKey, InfotipHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(InfotipHandler.Value), _tcslen(InfotipHandler.Value) + 1);
186 			RegSetValueEx(hKey, PropHandler.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(PropHandler.Value), _tcslen(PropHandler.Value) + 1);
187 			RegSetValueEx(hKey, ThumbViewer.Key, 0, REG_SZ, reinterpret_cast<const BYTE*>(ThumbViewer.Value), _tcslen(ThumbViewer.Value) + 1);
188 
189 			RegCloseKey(hKey);
190 		}
191 	}
192     return ERROR_SUCCESS;
193 }
194 
195 /*
196     Called during deinstallation when the module "Windows Explorer Extensions" has
197     been installed.
198 */
199 extern "C" UINT __stdcall DeinstallExecSequenceEntry(MSIHANDLE)
200 {
201     //MessageBox(NULL, TEXT("DeinstallExecSequenceEntry"), TEXT("Pythonmsi"), MB_OK | MB_ICONINFORMATION);
202     HKEY hKey;
203     if (RegOpenKey(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), &hKey) == ERROR_SUCCESS)
204     {
205         RegDeleteValue(hKey, ColumnHandler.Key);
206         RegDeleteValue(hKey, InfotipHandler.Key);
207         RegDeleteValue(hKey, PropHandler.Key);
208         RegDeleteValue(hKey, ThumbViewer.Key);
209 
210         RegCloseKey(hKey);
211     }
212     return ERROR_SUCCESS;
213 }
214