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