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 // Registrar.cpp: Implementierung der Klasse Registrar.
23 //
24 //////////////////////////////////////////////////////////////////////
25 
26 #include "registrar.hxx"
27 
28 #ifndef _REGISTRYVALUEIMPL_HXX_
29 #include "RegistryValueImpl.hxx"
30 #endif
31 #include "windowsregistry.hxx"
32 #include "registryexception.hxx"
33 
34 #include <assert.h>
35 #ifdef _MSC_VER
36 #pragma warning(disable: 4350 4482)
37 #include "strsafe.h"
38 #endif
39 
40 //----------------------------------------------------------
41 #ifdef DEBUG
42 inline void OutputDebugStringFormat( LPCTSTR pFormat, ... )
43 {
44 	TCHAR    buffer[1024];
45 	va_list  args;
46 
47 	va_start( args, pFormat );
48 	StringCchVPrintf( buffer, sizeof(buffer), pFormat, args );
49 	OutputDebugString( buffer );
50 }
51 #else
52 static inline void OutputDebugStringFormat( LPCTSTR, ... )
53 {
54 }
55 #endif
56 //----------------------------------------------------------
57 
58 const int MSWORD                     = 0x1;
59 const int MSEXCEL                    = 0x2;
60 const int MSPOWERPOINT               = 0x4;
61 const int DEFAULT_HTML_EDITOR_FOR_IE = 0x8;
62 const int HTML_EDITOR				 = 0x10;
63 const int DEFAULT_SHELL_HTML_EDITOR  = 0x20;
64 
65 namespace /* private */
66 {
67     const std::wstring HTM_OPENWITHLIST = L".htm\\OpenWithList";
68     const std::wstring APPLICATIONS = L"Applications";
69     const std::wstring SHELL_EDIT_COMMAND = L"shell\\edit\\command";
70     const std::wstring HTML_EDIT = L"HTML Edit";
71     const std::wstring HTML_EDIT_DISPLAY_NAME = L"Edit Display Name";
72     const std::wstring SHELL_EDIT_COMMAND_BACKUP = L"Shell Edit Cmd";
73     const std::wstring DEFAULT_HTML_EDITOR = L"Default HTML Editor";
74     const std::wstring MS_IE_DEF_HTML_EDITOR = L"Software\\Microsoft\\Internet Explorer\\Default HTML Editor";
75     const std::wstring MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD = L"Software\\Microsoft\\Internet Explorer\\Default HTML Editor\\shell\\edit\\command";
76 }
77 
78 Registrar::Registrar(const RegistrationContextInformation& RegContext) :
79 	m_ContextInformation(RegContext),
80     FORWARD_KEY_PREFIX(L"Apache OpenOffice"),
81     DEFAULT_VALUE_NAME(L""),
82     BACKUP_VALUE_NAME(L"Backup"),
83     PRIVATE_BACKUP_KEY_NAME(L"Apache OpenOffice.reg4msdocmsi"),//PRIVATE_BACKUP_KEY_NAME(L"soffice6.bak"),
84     REGISTRATION_STATE(L"Reg4MsDocState")
85 {
86     m_RootKey = WindowsRegistry().GetClassesRootKey();
87 }
88 
89 Registrar::~Registrar()
90 {
91 }
92 
93 void Registrar::RegisterForMsWord() const
94 {
95     assert(m_RootKey.get());
96 
97     RegisterForMsOfficeApplication(
98         m_ContextInformation.GetWordDocumentFileExtension(),
99         m_ContextInformation.GetWordDocumentDisplayName(),
100         m_ContextInformation.GetWordDocumentDefaultIconEntry(),
101         m_ContextInformation.GetWordDocumentDefaultShellCommand(),
102         m_ContextInformation.ShellNewCommandDisplayName(),
103         RegistrationContextInformation::Writer);
104 
105     RegisterForMsOfficeApplication(
106         m_ContextInformation.GetWordTemplateFileExtension(),
107         m_ContextInformation.GetWordTemplateDisplayName(),
108         m_ContextInformation.GetWordTemplateDefaultIconEntry(),
109         m_ContextInformation.GetWordTemplateDefaultShellCommand(),
110         m_ContextInformation.ShellNewCommandDisplayName(),
111         RegistrationContextInformation::Writer);
112 
113     RegisterForMsOfficeApplication(
114         m_ContextInformation.GetRtfDocumentFileExtension(),
115         m_ContextInformation.GetRtfDocumentDisplayName(),
116         m_ContextInformation.GetRtfDocumentDefaultIconEntry(),
117         m_ContextInformation.GetRtfDocumentDefaultShellCommand(),
118         m_ContextInformation.ShellNewCommandDisplayName(),
119         RegistrationContextInformation::Writer);
120 
121     SaveRegisteredFor(MSWORD);
122 }
123 
124 void Registrar::UnregisterForMsWord() const
125 {
126 	assert(m_RootKey.get());
127 
128 	try
129 	{
130 		UnregisterForMsOfficeApplication(
131 			m_ContextInformation.GetWordDocumentFileExtension());
132 	}
133 	catch(RegistryKeyNotFoundException&)
134 	{}
135 
136 	try
137 	{
138 		UnregisterForMsOfficeApplication(
139 			m_ContextInformation.GetWordTemplateFileExtension());
140 	}
141 	catch(RegistryKeyNotFoundException&)
142 	{}
143 
144 	try
145 	{
146 		UnregisterForMsOfficeApplication(
147 			m_ContextInformation.GetRtfDocumentFileExtension());
148 	}
149 	catch(RegistryKeyNotFoundException&)
150 	{}
151 
152 	SaveNotRegisteredFor(MSWORD);
153 }
154 
155 bool Registrar::QueryPreselectForMsApplication(const std::wstring& file_extension) const
156 {
157     bool preselect = false;
158 
159     // We use HKCR else we would not see that a registration for
160     // MS Office applications already exist if we are about to
161     // register in HKCU\Software\Classes
162     RegistryKey root_key = WindowsRegistry().GetClassesRootKey();
163 
164 	if (!root_key->HasSubKey(file_extension))
165 	{
166         preselect = true;
167         OutputDebugStringFormat( TEXT("QueryPreselect: No SubKey found for (%s), preselected!\n"), file_extension.c_str() );
168     }
169     else
170     {
171         RegistryKey RegKey = root_key->OpenSubKey(file_extension, false);
172 
173         if (RegKey->HasValue(DEFAULT_VALUE_NAME))
174 	    {
175 		    RegistryValue RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
176 
177 		    if (REG_SZ == RegVal->GetType() &&
178 		        IsOpenOfficeRegisteredForMsApplication(RegVal->GetDataAsUniString()))
179             {
180 			    preselect = true;
181                 OutputDebugStringFormat( TEXT("QueryPreselect: (%s) registered to Office, preselected!\n"), file_extension.c_str() );
182             }
183             else if ( (REG_SZ == RegVal->GetType()) && ! root_key->HasSubKey( RegVal->GetDataAsUniString() ) )
184             {
185 			    preselect = true;
186                 OutputDebugStringFormat( TEXT("QueryPreselect: (%s) registered but destination is empty, preselected!\n"), file_extension.c_str() );
187             }
188 	    }
189         else
190         {
191             preselect = true;
192             OutputDebugStringFormat( TEXT("QueryPreselect: No default found for SubKey (%s), preselected!\n"), file_extension.c_str() );
193         }
194     }
195     return preselect;
196 }
197 
198 bool Registrar::QueryPreselectMsWordRegistration() const
199 {
200     return QueryPreselectForMsApplication(
201         m_ContextInformation.GetWordDocumentFileExtension());
202 }
203 
204 void Registrar::RegisterForMsExcel() const
205 {
206     assert(m_RootKey.get());
207 
208 	RegisterForMsOfficeApplication(
209 		m_ContextInformation.GetExcelSheetFileExtension(),
210 		m_ContextInformation.GetExcelSheetDisplayName(),
211 		m_ContextInformation.GetExcelSheetDefaultIconEntry(),
212 		m_ContextInformation.GetExcelSheetDefaultShellCommand(),
213 		m_ContextInformation.ShellNewCommandDisplayName(),
214         RegistrationContextInformation::Calc);
215 
216 	RegisterForMsOfficeApplication(
217 		m_ContextInformation.GetExcelTemplateFileExtension(),
218 		m_ContextInformation.GetExcelTemplateDisplayName(),
219 		m_ContextInformation.GetExcelTemplateDefaultIconEntry(),
220 		m_ContextInformation.GetExcelTemplateDefaultShellCommand(),
221 		m_ContextInformation.ShellNewCommandDisplayName(),
222         RegistrationContextInformation::Calc);
223 
224     SaveRegisteredFor(MSEXCEL);
225 }
226 
227 void Registrar::UnregisterForMsExcel() const
228 {
229     assert(m_RootKey.get());
230 
231 	try
232 	{
233 		UnregisterForMsOfficeApplication(
234 			m_ContextInformation.GetExcelSheetFileExtension());
235 	}
236 	catch(RegistryKeyNotFoundException&)
237 	{}
238 
239 	try
240 	{
241 		UnregisterForMsOfficeApplication(
242 			m_ContextInformation.GetExcelTemplateFileExtension());
243 	}
244 	catch(RegistryKeyNotFoundException&)
245 	{}
246 
247     SaveNotRegisteredFor(MSEXCEL);
248 }
249 
250 bool Registrar::QueryPreselectMsExcelRegistration() const
251 {
252     return QueryPreselectForMsApplication(
253         m_ContextInformation.GetExcelSheetFileExtension());
254 }
255 
256 void Registrar::RegisterForMsPowerPoint() const
257 {
258     assert(m_RootKey.get());
259 
260     RegisterForMsOfficeApplication(
261         m_ContextInformation.GetPowerPointDocumentFileExtension(),
262         m_ContextInformation.GetPowerPointDocumentDisplayName(),
263         m_ContextInformation.GetPowerPointDocumentDefaultIconEntry(),
264         m_ContextInformation.GetPowerPointDocumentDefaultShellCommand(),
265         m_ContextInformation.ShellNewCommandDisplayName(),
266         RegistrationContextInformation::Impress);
267 
268     RegisterForMsOfficeApplication(
269         m_ContextInformation.GetPowerPointShowFileExtension(),
270         m_ContextInformation.GetPowerPointShowDisplayName(),
271         m_ContextInformation.GetPowerPointShowDefaultIconEntry(),
272         m_ContextInformation.GetPowerPointShowDefaultShellCommand(),
273         m_ContextInformation.ShellNewCommandDisplayName(),
274         RegistrationContextInformation::Impress);
275 
276     RegisterForMsOfficeApplication(
277         m_ContextInformation.GetPowerPointTemplateFileExtension(),
278         m_ContextInformation.GetPowerPointTemplateDisplayName(),
279         m_ContextInformation.GetPowerPointTemplateDefaultIconEntry(),
280         m_ContextInformation.GetPowerPointTemplateDefaultShellCommand(),
281         m_ContextInformation.ShellNewCommandDisplayName(),
282         RegistrationContextInformation::Impress);
283 
284     SaveRegisteredFor(MSPOWERPOINT);
285 }
286 
287 void Registrar::UnregisterForMsPowerPoint() const
288 {
289     assert(m_RootKey.get());
290 
291 	try
292 	{
293 		UnregisterForMsOfficeApplication(
294 			m_ContextInformation.GetPowerPointDocumentFileExtension());
295 	}
296 	catch(RegistryKeyNotFoundException&)
297 	{}
298 
299 	try
300 	{
301 		UnregisterForMsOfficeApplication(
302 			m_ContextInformation.GetPowerPointShowFileExtension());
303 	}
304 	catch(RegistryKeyNotFoundException&)
305 	{}
306 
307 	try
308 	{
309 		UnregisterForMsOfficeApplication(
310 			m_ContextInformation.GetPowerPointTemplateFileExtension());
311 	}
312 	catch(RegistryKeyNotFoundException&)
313 	{}
314 
315     SaveNotRegisteredFor(MSPOWERPOINT);
316 }
317 
318 //-----------------------------------------
319 /*
320 */
321 bool Registrar::QueryPreselectMsPowerPointRegistration() const
322 {
323     return QueryPreselectForMsApplication( m_ContextInformation.GetPowerPointDocumentFileExtension()) &&
324            QueryPreselectForMsApplication( m_ContextInformation.GetPowerPointShowFileExtension());
325 }
326 
327 //-----------------------------------------
328 /** The documentation says we have to
329       make the following entries to register
330       a html editor for the Internet Explorer
331       HKCR\.htm\OpenWithList\App Friendly Name\shell\edit\command
332       But the reality shows that this works only
333       with Internet Explorer 5.x
334       Internet Explorer 6.0 wants the follwoing
335       entries:
336       HKCR\.htm\OpenWithList\App.exe
337       HKCR\Applications\App.ex\shell\edit\command
338 */
339 void Registrar::RegisterAsHtmlEditorForInternetExplorer() const
340 {
341     assert(m_RootKey.get());
342 
343     std::wstring OOFriendlyAppName = m_ContextInformation.GetOpenOfficeFriendlyAppName();
344 
345     std::wstring RegKeyName = HTM_OPENWITHLIST + std::wstring(L"\\") + OOFriendlyAppName;
346     RegistryKey RegKey = m_RootKey->CreateSubKey(RegKeyName);
347 
348     RegKey = RegKey->CreateSubKey(SHELL_EDIT_COMMAND);
349 
350     RegistryValue RegVal(
351         new RegistryValueImpl(
352             DEFAULT_VALUE_NAME,
353             m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
354                                                           RegistrationContextInformation::Writer)));
355 
356     RegKey->SetValue(RegVal);
357 
358     RegKeyName = APPLICATIONS + std::wstring(L"\\") + OOFriendlyAppName;
359     RegKey = m_RootKey->CreateSubKey(RegKeyName);
360 
361     RegVal->SetName(L"FriendlyAppName");
362     RegVal->SetValue(OOFriendlyAppName);
363     RegKey->SetValue(RegVal);
364 
365     RegKey = RegKey->CreateSubKey(SHELL_EDIT_COMMAND);
366     RegVal->SetName(DEFAULT_VALUE_NAME);
367     RegVal->SetValue(
368         m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
369                                                       RegistrationContextInformation::Writer));
370     RegKey->SetValue(RegVal);
371 
372     SaveRegisteredFor(HTML_EDITOR);
373 }
374 
375 void Registrar::UnregisterAsHtmlEditorForInternetExplorer() const
376 {
377     assert(m_RootKey.get());
378 
379 	try
380 	{
381 		std::wstring OOFriendlyAppName = m_ContextInformation.GetOpenOfficeFriendlyAppName();
382 
383         RegistryKey aRegKey = m_RootKey->OpenSubKey( APPLICATIONS );
384         if ( aRegKey->HasSubKey( OOFriendlyAppName ) )
385 		    aRegKey->DeleteSubKeyTree( OOFriendlyAppName );
386 
387         aRegKey = m_RootKey->OpenSubKey( HTM_OPENWITHLIST );
388         if ( aRegKey->HasSubKey( OOFriendlyAppName ) )
389 		    aRegKey->DeleteSubKeyTree( OOFriendlyAppName );
390 	}
391     catch(RegistryKeyNotFoundException&)
392 	{}
393 
394     SaveNotRegisteredFor(HTML_EDITOR);
395 }
396 
397 void Registrar::RegisterAsDefaultHtmlEditorForInternetExplorer() const
398 {
399     assert(m_RootKey.get());
400 
401     RegistryKey RegistrationRootKey = GetRootKeyForDefHtmlEditorForIERegistration();
402 
403     RegistryKey RegKey = RegistrationRootKey->CreateSubKey(MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD);
404 
405     RegistryValue RegVal = RegistryValue(new RegistryValueImpl(DEFAULT_VALUE_NAME, L""));
406 
407     if (RegKey->HasValue(DEFAULT_VALUE_NAME))
408 	{
409         RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
410 
411         std::wstring CmdLine = RegVal->GetDataAsUniString();
412 
413         if (std::wstring::npos == CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
414         {
415             RegistryKey BackupRegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME + L"\\" + DEFAULT_HTML_EDITOR);
416 
417             if (RegKey->HasValue(DEFAULT_VALUE_NAME))
418                 BackupRegKey->CopyValue(RegKey, DEFAULT_VALUE_NAME);
419 
420             RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
421             if (RegKey->HasValue(L"Description"))
422                 BackupRegKey->CopyValue(RegKey, L"Description");
423         }
424     }
425 
426     RegVal->SetValue(
427         m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
428                                                       RegistrationContextInformation::Writer));
429     RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD);
430     RegKey->SetValue(RegVal);
431 
432     RegVal->SetName(L"Description");
433     RegVal->SetValue(m_ContextInformation.GetOpenOfficeFriendlyAppName());
434     RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
435     RegKey->SetValue(RegVal);
436 
437     SaveRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE);
438 }
439 
440 void Registrar::UnregisterAsDefaultHtmlEditorForInternetExplorer() const
441 {
442     assert(m_RootKey.get());
443 
444     RegistryKey RegistrationRootKey = GetRootKeyForDefHtmlEditorForIERegistration();
445 
446     RegistryKey RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR_SHL_EDIT_CMD);
447 
448     if (RegKey->HasValue(DEFAULT_VALUE_NAME))
449     {
450         RegistryValue RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
451 
452         std::wstring CmdLine = RegVal->GetDataAsUniString();
453 
454         if (std::wstring::npos != CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
455         {
456             RegistryKey BackupRegKey = m_RootKey->OpenSubKey(PRIVATE_BACKUP_KEY_NAME);
457 
458             if (BackupRegKey->HasSubKey(DEFAULT_HTML_EDITOR))
459             {
460                 BackupRegKey = BackupRegKey->OpenSubKey(DEFAULT_HTML_EDITOR);
461 
462                 if (BackupRegKey->HasValue(DEFAULT_VALUE_NAME))
463                     RegKey->CopyValue(BackupRegKey, DEFAULT_VALUE_NAME);
464                 else
465                     RegKey->DeleteValue(DEFAULT_VALUE_NAME);
466 
467                 RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
468 
469                 if (BackupRegKey->HasValue(L"Description"))
470                     RegKey->CopyValue(BackupRegKey, L"Description");
471                 else
472                     RegKey->DeleteValue(L"Description");
473             }
474             else
475             {
476                 RegKey->DeleteValue(DEFAULT_VALUE_NAME);
477                 RegKey = RegistrationRootKey->OpenSubKey(MS_IE_DEF_HTML_EDITOR);
478                 RegKey->DeleteValue(L"Description");
479             }
480         }
481     }
482 
483     SaveNotRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE);
484 }
485 
486 void Registrar::RegisterAsDefaultShellHtmlEditor() const
487 {
488     assert(m_RootKey.get());
489 
490     RegistryKey RegKey = m_RootKey->CreateSubKey(L".htm");
491 
492     RegistryValue RegVal = RegistryValue(
493         new RegistryValueImpl(DEFAULT_VALUE_NAME, L""));
494 
495     if (RegKey->HasValue(DEFAULT_VALUE_NAME))
496         RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
497 
498     std::wstring HtmFwdKey = RegVal->GetDataAsUniString();
499     if (0 == HtmFwdKey.length() || !m_RootKey->HasSubKey(HtmFwdKey))
500         HtmFwdKey = L".htm";
501 
502     RegKey = m_RootKey->CreateSubKey(HtmFwdKey + L"\\" + SHELL_EDIT_COMMAND);
503 
504 	if (RegKey->HasValue(DEFAULT_VALUE_NAME))
505 	{
506 		RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
507 
508 		std::wstring CmdLine = RegVal->GetDataAsUniString();
509 
510 		// backup old values if we are not in place
511 		if (std::wstring::npos == CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
512 		{
513 			RegistryKey BackupRegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME + L"\\" + HTML_EDIT);
514 			BackupRegKey->CopyValue(RegKey, DEFAULT_VALUE_NAME, SHELL_EDIT_COMMAND_BACKUP);
515 		}
516 	}
517 
518     RegVal->SetValue(
519         m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open,
520                                                       RegistrationContextInformation::Writer));
521 
522     RegKey->SetValue(RegVal);
523 
524     SaveRegisteredFor(DEFAULT_SHELL_HTML_EDITOR);
525 }
526 
527 void Registrar::UnregisterAsDefaultShellHtmlEditor() const
528 {
529     assert(m_RootKey.get());
530 
531 	try
532 	{
533 		RegistryKey RegKey = m_RootKey->OpenSubKey(L".htm");
534 
535 		RegistryValue RegVal = RegistryValue(
536 			new RegistryValueImpl(DEFAULT_VALUE_NAME, L""));
537 
538 		if (RegKey->HasValue(DEFAULT_VALUE_NAME))
539 			RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
540 
541 		std::wstring HtmFwdKey = RegVal->GetDataAsUniString();
542 
543 		if (0 == HtmFwdKey.length() || !m_RootKey->HasSubKey(HtmFwdKey))
544 			HtmFwdKey = L".htm";
545 
546 		RegKey = m_RootKey->OpenSubKey(HtmFwdKey + L"\\" + SHELL_EDIT_COMMAND);
547 
548 		RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
549 
550 		std::wstring CmdLine = RegVal->GetDataAsUniString();
551 
552 		if (std::wstring::npos != CmdLine.find(m_ContextInformation.GetOpenOfficeExecutableName()))
553 		{
554 			RegistryKey BackupRegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME + L"\\" + HTML_EDIT);
555 
556 			if (BackupRegKey->HasValue(SHELL_EDIT_COMMAND_BACKUP))
557 				RegKey->CopyValue(BackupRegKey, SHELL_EDIT_COMMAND_BACKUP, DEFAULT_VALUE_NAME);
558 			else
559 				RegKey->DeleteValue(DEFAULT_VALUE_NAME);
560 		}
561 	}
562     catch(RegistryKeyNotFoundException&)
563 	{
564 	}
565 
566     SaveNotRegisteredFor(DEFAULT_SHELL_HTML_EDITOR);
567 }
568 
569 void Registrar::SaveRegisteredFor(int State) const
570 {
571     assert(m_RootKey.get());
572 
573     int NewState = GetRegisterState();
574     NewState |= State;
575     SetRegisterState(NewState);
576 }
577 
578 void Registrar::SaveNotRegisteredFor(int State) const
579 {
580     assert(m_RootKey.get());
581 
582     int NewState = GetRegisterState();
583     NewState &= ~State;
584     SetRegisterState(NewState);
585 }
586 
587 int Registrar::GetRegisterState() const
588 {
589     int State = 0;
590 
591     RegistryKey RegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME);
592 
593     if (RegKey->HasValue(REGISTRATION_STATE))
594     {
595         RegistryValue RegVal = RegKey->GetValue(REGISTRATION_STATE);
596         if (REG_DWORD == RegVal->GetType())
597             State = RegVal->GetDataAsInt();
598     }
599 
600     return State;
601 }
602 
603 void Registrar::SetRegisterState(int NewState) const
604 {
605     RegistryKey RegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME);
606     RegistryValue RegVal = RegistryValue(new RegistryValueImpl(REGISTRATION_STATE, NewState));
607     RegKey->SetValue(RegVal);
608 }
609 
610 bool Registrar::IsRegisteredFor(int State) const
611 {
612     assert(m_RootKey.get());
613 
614     RegistryKey RegKey = m_RootKey->CreateSubKey(PRIVATE_BACKUP_KEY_NAME);
615 
616     int SavedState = 0;
617 
618     if (RegKey->HasValue(REGISTRATION_STATE))
619     {
620         RegistryValue RegVal = RegKey->GetValue(REGISTRATION_STATE);
621         if (REG_DWORD == RegVal->GetType())
622             SavedState = RegVal->GetDataAsInt();
623     }
624 
625 	return ((SavedState & State) == State);
626 }
627 
628 //--------------------------------------
629 /** Restore the last registration state (necessary for
630 	Setup repair) */
631 void Registrar::RepairRegistrationState() const
632 {
633     assert(m_RootKey.get());
634 
635 	if (IsRegisteredFor(MSWORD))
636 		RegisterForMsWord();
637 
638 	if (IsRegisteredFor(MSEXCEL))
639 		RegisterForMsExcel();
640 
641 	if (IsRegisteredFor(MSPOWERPOINT))
642 		RegisterForMsPowerPoint();
643 
644 	if (IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
645 		RegisterAsDefaultHtmlEditorForInternetExplorer();
646 
647 	if (IsRegisteredFor(HTML_EDITOR))
648 		RegisterAsHtmlEditorForInternetExplorer();
649 
650 	if (IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
651 		RegisterAsDefaultShellHtmlEditor();
652 }
653 
654 /** Unregisters all and delete all Registry keys we have written */
655 void Registrar::UnregisterAllAndCleanUpRegistry() const
656 {
657 	assert(m_RootKey.get());
658 
659 	if (IsRegisteredFor(MSWORD))
660 		UnregisterForMsWord();
661 
662 	if (IsRegisteredFor(MSEXCEL))
663 		UnregisterForMsExcel();
664 
665 	if (IsRegisteredFor(MSPOWERPOINT))
666 		UnregisterForMsPowerPoint();
667 
668 	if (IsRegisteredFor(DEFAULT_HTML_EDITOR_FOR_IE))
669 		UnregisterAsDefaultHtmlEditorForInternetExplorer();
670 
671 	if (IsRegisteredFor(HTML_EDITOR))
672 		UnregisterAsHtmlEditorForInternetExplorer();
673 
674 	if (IsRegisteredFor(DEFAULT_SHELL_HTML_EDITOR))
675 		UnregisterAsDefaultShellHtmlEditor();
676 
677 	if (m_RootKey->HasSubKey(PRIVATE_BACKUP_KEY_NAME))
678 	    m_RootKey->DeleteSubKeyTree(PRIVATE_BACKUP_KEY_NAME);
679 }
680 
681 void Registrar::RegisterForMsOfficeApplication(
682     const std::wstring& FileExtension,
683     const std::wstring& DocumentDisplayName,
684     const std::wstring& DefaultIconEntry,
685     const std::wstring& DefaultShellCommand,
686     const std::wstring& ShellNewCommandDisplayName,
687     const RegistrationContextInformation::OFFICE_APPLICATION eOfficeApp) const
688 {
689     assert(m_RootKey.get());
690 
691 	std::wstring ForwardKeyName = FORWARD_KEY_PREFIX + FileExtension;
692 
693 	RegistryKey ForwardKey = m_RootKey->CreateSubKey(ForwardKeyName);
694 	RegistryValue RegVal(new RegistryValueImpl(std::wstring(DEFAULT_VALUE_NAME), DocumentDisplayName));
695 	ForwardKey->SetValue(RegVal);
696 
697 	RegistryKey RegKey = ForwardKey->CreateSubKey(L"DefaultIcon");
698 	RegVal->SetValue(DefaultIconEntry);
699 	RegKey->SetValue(RegVal);
700 
701 	RegistryKey RegKeyShell = ForwardKey->CreateSubKey(L"shell");
702 	RegVal->SetValue(DefaultShellCommand);
703 	RegKeyShell->SetValue(RegVal);
704 
705 	RegKey = RegKeyShell->CreateSubKey(L"new");
706 	RegVal->SetValue(ShellNewCommandDisplayName);
707 	RegKey->SetValue(RegVal);
708 
709 	RegKey = RegKey->CreateSubKey(L"command");
710 	RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::New, eOfficeApp));
711 	RegKey->SetValue(RegVal);
712 
713 	RegKey = RegKeyShell->CreateSubKey(L"open\\command");
714 	RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Open, eOfficeApp));
715 	RegKey->SetValue(RegVal);
716 
717 	RegKey = RegKeyShell->CreateSubKey(L"print\\command");
718 	RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Print, eOfficeApp));
719 	RegKey->SetValue(RegVal);
720 
721 	RegKey = RegKeyShell->CreateSubKey(L"printto\\command");
722 	RegVal->SetValue(m_ContextInformation.GetOpenOfficeCommandline(RegistrationContextInformation::Printto, eOfficeApp));
723 	RegKey->SetValue(RegVal);
724 
725     // set the new forward key under the appropriate extension
726 	RegKey = m_RootKey->CreateSubKey(FileExtension);
727 
728 	if (RegKey->HasValue(DEFAULT_VALUE_NAME))
729 	{
730 		RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
731 
732 		if (REG_SZ == RegVal->GetType())
733 		{
734 			std::wstring str = RegVal->GetDataAsUniString();
735 			if (!IsOpenOfficeRegisteredForMsApplication(str))
736 				ForwardKey->CopyValue(RegKey, DEFAULT_VALUE_NAME, BACKUP_VALUE_NAME);
737 		}
738 	}
739 
740 	RegVal->SetValue(ForwardKeyName);
741 	RegKey->SetValue(RegVal);
742 }
743 
744 void Registrar::UnregisterForMsOfficeApplication(const std::wstring& FileExtension) const
745 {
746     std::wstring FwdRegKeyName = FORWARD_KEY_PREFIX + FileExtension;
747 
748     if (m_RootKey->HasSubKey(FileExtension))
749     {
750         RegistryKey RegKey = m_RootKey->OpenSubKey(FileExtension);
751 
752         if (RegKey->HasValue(DEFAULT_VALUE_NAME))
753         {
754             RegistryValue RegVal = RegKey->GetValue(DEFAULT_VALUE_NAME);
755             if (REG_SZ == RegVal->GetType() &&
756                 IsOpenOfficeRegisteredForMsApplication(RegVal->GetDataAsUniString()))
757             {
758                 RegistryKey FwdRegKey = m_RootKey->CreateSubKey(FwdRegKeyName);
759 
760                 if (FwdRegKey->HasValue(BACKUP_VALUE_NAME))
761                     RegKey->CopyValue(FwdRegKey, BACKUP_VALUE_NAME, DEFAULT_VALUE_NAME);
762                 else
763                     RegKey->DeleteValue(DEFAULT_VALUE_NAME);
764             }
765         }
766     }
767 
768     if (m_RootKey->HasSubKey(FwdRegKeyName))
769         m_RootKey->DeleteSubKeyTree(FwdRegKeyName);
770 }
771 
772 RegistryKey Registrar::GetRootKeyForDefHtmlEditorForIERegistration() const
773 {
774     return WindowsRegistry().GetLocalMachineKey();
775 }
776 
777 bool Registrar::IsOpenOfficeRegisteredForMsApplication(const std::wstring& DocumentExtensionDefValue) const
778 {
779     return (std::wstring::npos != DocumentExtensionDefValue.find(FORWARD_KEY_PREFIX));
780 }
781