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