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 #include "register.hxx"
29 #include "registryexception.hxx"
30 #include "registrationcontextinformation.hxx"
31 #include "userregistrar.hxx"
32 #include "windowsregistry.hxx"
33 #include "stringconverter.hxx"
34 #include "msihelper.hxx"
35 
36 #ifdef _MSC_VER
37 #pragma warning(push, 1) /* disable warnings within system headers */
38 #pragma warning(disable: 4917)
39 #endif
40 #include <shlobj.h>
41 #ifdef _MSC_VER
42 #pragma warning(pop)
43 #endif
44 
45 
46 #include <assert.h>
47 #ifdef _MSC_VER
48 #pragma warning(disable: 4350)
49 #endif
50 
51 typedef std::auto_ptr<Registrar> RegistrarPtr;
52 
53 namespace /* private */
54 {
55     RegistrarPtr CreateRegistrar(bool InstallForAllUser, const RegistrationContextInformation& RegCtx)
56     {
57         RegistrarPtr RegPtr;
58 
59         if (InstallForAllUser)
60             RegPtr = RegistrarPtr(new Registrar(RegCtx));
61         else
62             RegPtr = RegistrarPtr(new UserRegistrar(RegCtx));
63 
64         return RegPtr;
65     }
66 } // namespace private
67 
68 bool query_preselect_registration_for_ms_application(MSIHANDLE handle, int Register)
69 {
70     bool preselect = false;
71 
72     try
73     {
74         RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
75         RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
76 
77         if (Register & MSWORD)
78             preselect = CurrentRegistrar->QueryPreselectMsWordRegistration();
79         else if (Register & MSEXCEL)
80             preselect = CurrentRegistrar->QueryPreselectMsExcelRegistration();
81         else if (Register & MSPOWERPOINT)
82             preselect = CurrentRegistrar->QueryPreselectMsPowerPointRegistration();
83     }
84     catch(RegistryException&)
85     {
86         assert(false);
87     }
88     return preselect;
89 }
90 
91 //-----------------------------------------
92 // registers StarOffice for MS document
93 // types and as default HTML editor if
94 // specified
95 //-----------------------------------------
96 
97 void Register4MsDoc(MSIHANDLE handle, int Register)
98 {
99     try
100     {
101         RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
102         RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
103 
104         if ((Register & MSWORD))
105             CurrentRegistrar->RegisterForMsWord();
106 
107         if ((Register & MSEXCEL))
108             CurrentRegistrar->RegisterForMsExcel();
109 
110         if ((Register & MSPOWERPOINT))
111             CurrentRegistrar->RegisterForMsPowerPoint();
112 
113         if ((Register & HTML_EDITOR))
114             CurrentRegistrar->RegisterAsHtmlEditorForInternetExplorer();
115 
116         if ((Register & DEFAULT_SHELL_HTML_EDITOR))
117         {
118             CurrentRegistrar->RegisterAsDefaultHtmlEditorForInternetExplorer();
119             CurrentRegistrar->RegisterAsDefaultShellHtmlEditor();
120         }
121     }
122     catch(RegistryException&)
123     {
124         assert(false);
125     }
126 
127     if (Register)
128         SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
129 }
130 
131 void Unregister4MsDoc(MSIHANDLE handle, int Unregister)
132 {
133     try
134     {
135         RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
136         RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
137 
138         if ((Unregister & MSWORD) && CurrentRegistrar->IsRegisteredFor(MSWORD))
139             CurrentRegistrar->UnregisterForMsWord();
140 
141         if ((Unregister & HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(HTML_EDITOR))
142             CurrentRegistrar->UnregisterAsHtmlEditorForInternetExplorer();
143 
144         if ((Unregister & MSEXCEL) && CurrentRegistrar->IsRegisteredFor(MSEXCEL))
145             CurrentRegistrar->UnregisterForMsExcel();
146 
147         if ((Unregister & MSPOWERPOINT) && CurrentRegistrar->IsRegisteredFor(MSPOWERPOINT))
148             CurrentRegistrar->UnregisterForMsPowerPoint();
149 
150         if ((Unregister & DEFAULT_HTML_EDITOR_FOR_IE) && CurrentRegistrar->IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
151             CurrentRegistrar->UnregisterAsDefaultHtmlEditorForInternetExplorer();
152 
153         if ((Unregister & DEFAULT_SHELL_HTML_EDITOR) && CurrentRegistrar->IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
154             CurrentRegistrar->UnregisterAsDefaultShellHtmlEditor();
155     }
156     catch(RegistryException&)
157     {
158         assert(false);
159     }
160 
161 	if (Unregister)
162 		SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
163 }
164 
165 //-----------------------------------------
166 // restores the entries for the selected
167 // registry entries
168 // Algorithm:
169 //
170 // 1.
171 // Target key exist (e.g. '.doc')
172 // Default value == soffice.?
173 // Backup key != empty
174 // Action: Replace Default value with backup
175 // key
176 //
177 // 2.
178 // Target key exist
179 // Default value == soffice.?
180 // Backup key == empty
181 // Action: delete default value
182 //
183 // 3.
184 // Target key exist
185 // Default value != soffice.?
186 // Action: nop
187 //
188 // 4.
189 // Target key does not exist
190 // Action: nop
191 //-----------------------------------------
192 
193 void Unregister4MsDocAll(MSIHANDLE handle)
194 {
195     try
196     {
197         RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
198         RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
199 
200         CurrentRegistrar->UnregisterAllAndCleanUpRegistry();
201     }
202     catch(RegistryException&)
203     {
204         assert(false);
205     }
206 }
207 
208 //-----------------------------------------
209 // restores lost settings formerly made
210 // with Register4MsDoc
211 //-----------------------------------------
212 
213 void RepairRegister4MsDocSettings(MSIHANDLE handle)
214 {
215     try
216     {
217         RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
218         RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
219 
220         CurrentRegistrar->RepairRegistrationState();
221     }
222     catch(RegistryException&)
223     {
224         assert(false);
225     }
226 }
227 
228 bool IsRegisteredFor(MSIHANDLE handle, int State)
229 {
230     bool Registered = false;
231 
232     try
233     {
234         RegistrationContextInformation RegContext(handle, GetOfficeExecutablePath(handle));
235         RegistrarPtr CurrentRegistrar = CreateRegistrar(IsAllUserInstallation(handle), RegContext);
236 
237         Registered = CurrentRegistrar->IsRegisteredFor(State);
238     }
239     catch(RegistryException&)
240     {
241         assert(false);
242     }
243     return Registered;
244 }
245 
246 #define SO60_UNINSTALL_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\StarOffice 6.0"
247 #define SO_BACKUP_KEY      L"soffice6.bak"
248 #define REGMSDOCSTATE      L"Reg4MsDocState"
249 #define SOFTWARE_CLASSES   L"Software\\Classes"
250 
251 int FixReturnRegistrationState(MSIHANDLE handle)
252 {
253 	int registration_state = 0;
254 
255 	try
256 	{
257 		WindowsRegistry registry;
258 
259 		RegistryValue rv_regmsdocstate = RegistryValue(
260 			new RegistryValueImpl(REGMSDOCSTATE, 0));
261 
262 		RegistryKey so_bak_key;
263 
264 		if (IsAllUserInstallation(handle))
265 		{
266 			RegistryKey hkcr_key = registry.GetClassesRootKey();
267 
268 			if (hkcr_key->HasSubKey(SO_BACKUP_KEY))
269 				so_bak_key = hkcr_key->OpenSubKey(SO_BACKUP_KEY);
270 			else
271 				so_bak_key = hkcr_key->CreateSubKey(SO_BACKUP_KEY);
272 
273 			if (!so_bak_key->HasValue(REGMSDOCSTATE))
274 			{
275 				// set a defined value
276 				so_bak_key->SetValue(rv_regmsdocstate);
277 
278 				RegistryKey hklm_key = registry.GetLocalMachineKey();
279 
280 				if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
281 				{
282 					RegistryKey so_uninst_key =
283 						hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);
284 
285 					if (so_uninst_key->HasValue(REGMSDOCSTATE))
286 						so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
287 				}
288 			}
289 		}
290 		else
291 		{
292 			RegistryKey hkcu_classes_key =
293 				registry.GetCurrentUserKey()->OpenSubKey(SOFTWARE_CLASSES);
294 
295 			so_bak_key = hkcu_classes_key->CreateSubKey(SO_BACKUP_KEY);
296 
297 			if (!so_bak_key->HasValue(REGMSDOCSTATE))
298 			{
299 				// set a defined value
300 				so_bak_key->SetValue(rv_regmsdocstate);
301 
302 				RegistryKey hklm_sftw_classes =
303 					registry.GetLocalMachineKey()->OpenSubKey(SOFTWARE_CLASSES, false);
304 
305 				RegistryKey so_bak_key_old;
306 
307 				if (hklm_sftw_classes->HasSubKey(SO_BACKUP_KEY))
308 				{
309 					so_bak_key_old = hklm_sftw_classes->OpenSubKey(SO_BACKUP_KEY, false);
310 
311 					if (so_bak_key_old->HasValue(REGMSDOCSTATE))
312 						so_bak_key->CopyValue(so_bak_key_old, REGMSDOCSTATE);
313 				}
314 				else // try the uninstall key
315 				{
316 					RegistryKey hklm_key = registry.GetLocalMachineKey();
317 
318 					if (hklm_key->HasSubKey(SO60_UNINSTALL_KEY))
319 					{
320 						RegistryKey so_uninst_key =
321 							hklm_key->OpenSubKey(SO60_UNINSTALL_KEY);
322 
323 						if (so_uninst_key->HasValue(REGMSDOCSTATE))
324 							so_bak_key->CopyValue(so_uninst_key, REGMSDOCSTATE);
325 					}
326 				}
327 			}
328 		}
329 
330 		rv_regmsdocstate = so_bak_key->GetValue(REGMSDOCSTATE);
331 		registration_state = rv_regmsdocstate->GetDataAsInt();
332 	}
333 	catch(RegistryException&)
334 	{
335 		registration_state = 0;
336 	}
337 
338 	return registration_state;
339 }
340 
341