Revert "Imported Upstream version 1096.40.7"
[platform/upstream/mdnsresponder.git] / mDNSWindows / ControlPanel / ControlPanelExe.cpp
1 /* -*- Mode: C; tab-width: 4 -*-
2  *
3  * Copyright (c) 2002-2007 Apple Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  * 
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18     
19 #include "ControlPanelExe.h"
20 #include "ConfigDialog.h"
21 #include "ConfigPropertySheet.h"
22 #include "resource.h"
23
24 #include <DebugServices.h>
25 #include "loclibrary.h"
26 #include <strsafe.h>
27
28
29 #ifdef _DEBUG
30 #define new DEBUG_NEW
31 #undef THIS_FILE
32 static char THIS_FILE[] = __FILE__;
33 #endif
34
35 #ifndef HeapEnableTerminationOnCorruption
36 #       define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS) 1
37 #endif
38
39
40 // Stash away pointers to our resource DLLs
41
42 static HINSTANCE g_nonLocalizedResources        = NULL;
43 static HINSTANCE g_localizedResources           = NULL;
44
45
46 HINSTANCE       GetNonLocalizedResources()
47 {
48         return g_nonLocalizedResources;
49 }
50
51
52 HINSTANCE       GetLocalizedResources()
53 {
54         return g_localizedResources;
55 }
56
57
58 //---------------------------------------------------------------------------------------------------------------------------
59 //      Static Declarations
60 //---------------------------------------------------------------------------------------------------------------------------
61 DEFINE_GUID(CLSID_ControlPanel, 
62
63 0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);
64
65 static LPCTSTR g_controlPanelGUID                       =       TEXT( "{1207552C-0E59-4d9f-8554-F1F806CD7FA9}" );
66 static LPCTSTR g_controlPanelName                       =       TEXT( "Bonjour" );
67 static LPCTSTR g_controlPanelCanonicalName      =       TEXT( "Apple.Bonjour" );
68 static LPCTSTR g_controlPanelCategory           =       TEXT( "3,8" );
69
70 static CCPApp theApp;
71
72 //===========================================================================================================================
73 //      MyRegDeleteKey
74 //===========================================================================================================================
75
76 DEBUG_LOCAL OSStatus MyRegDeleteKey( HKEY hKeyRoot, LPTSTR lpSubKey )
77 {
78     LPTSTR lpEnd;
79     OSStatus err;
80     DWORD dwSize;
81     TCHAR szName[MAX_PATH];
82     HKEY hKey;
83     FILETIME ftWrite;
84
85     // First, see if we can delete the key without having to recurse.
86
87     err = RegDeleteKey( hKeyRoot, lpSubKey );
88
89     if ( !err )
90         {
91                 goto exit;
92         }
93
94     err = RegOpenKeyEx( hKeyRoot, lpSubKey, 0, KEY_READ, &hKey );
95         require_noerr( err, exit );
96
97     // Check for an ending slash and add one if it is missing.
98
99     lpEnd = lpSubKey + lstrlen(lpSubKey);
100
101     if ( *( lpEnd - 1 ) != TEXT( '\\' ) ) 
102     {
103         *lpEnd =  TEXT('\\');
104         lpEnd++;
105         *lpEnd =  TEXT('\0');
106     }
107
108     // Enumerate the keys
109
110     dwSize = MAX_PATH;
111     err = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite);
112
113     if ( !err ) 
114     {
115         do
116                 {
117             lstrcpy (lpEnd, szName);
118
119             if ( !MyRegDeleteKey( hKeyRoot, lpSubKey ) )
120                         {
121                 break;
122             }
123
124             dwSize = MAX_PATH;
125
126             err = RegEnumKeyEx( hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite );
127
128         }
129                 while ( !err );
130     }
131
132     lpEnd--;
133     *lpEnd = TEXT('\0');
134
135     RegCloseKey( hKey );
136
137     // Try again to delete the key.
138
139     err = RegDeleteKey(hKeyRoot, lpSubKey);
140         require_noerr( err, exit );
141
142 exit:
143
144         return err;
145 }
146
147
148
149 //---------------------------------------------------------------------------------------------------------------------------
150 //      CCPApp::CCPApp
151 //---------------------------------------------------------------------------------------------------------------------------
152 IMPLEMENT_DYNAMIC(CCPApp, CWinApp);
153
154 CCPApp::CCPApp()
155 {
156         debug_initialize( kDebugOutputTypeWindowsEventLog, "DNS-SD Control Panel", GetModuleHandle( NULL ) );
157         debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelInfo );
158 }
159
160
161 //---------------------------------------------------------------------------------------------------------------------------
162 //      CCPApp::~CCPApp
163 //---------------------------------------------------------------------------------------------------------------------------
164
165 CCPApp::~CCPApp()
166 {
167 }
168
169
170 void
171 CCPApp::Register( LPCTSTR inClsidString, LPCTSTR inName, LPCTSTR inCanonicalName, LPCTSTR inCategory, LPCTSTR inLocalizedName, LPCTSTR inInfoTip, LPCTSTR inIconPath, LPCTSTR inExePath )
172 {
173         typedef struct  RegistryBuilder         RegistryBuilder;
174         
175         struct  RegistryBuilder
176         {
177                 HKEY            rootKey;
178                 LPCTSTR         subKey;
179                 LPCTSTR         valueName;
180                 DWORD           valueType;
181                 LPCTSTR         data;
182         };
183         
184         OSStatus                        err;
185         size_t                          n;
186         size_t                          i;
187         HKEY                            key;
188         TCHAR                           keyName[ MAX_PATH ];
189         RegistryBuilder         entries[] = 
190         {
191                 { HKEY_LOCAL_MACHINE,   TEXT( "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s" ),  NULL,                                                                   REG_SZ,         inName },
192                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s" ),                                                                                                                                                    NULL,                                                                   NULL,           NULL },
193                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s" ),                                                                                                                                                    TEXT( "System.ApplicationName" ),               REG_SZ,         inCanonicalName },
194                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s" ),                                                                                                                                                    TEXT( "System.ControlPanel.Category" ), REG_SZ,         inCategory },
195                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s" ),                                                                                                                                                    TEXT( "LocalizedString" ),                              REG_SZ,         inLocalizedName },
196                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s" ),                                                                                                                                                    TEXT( "InfoTip" ),                                              REG_SZ,         inInfoTip },
197                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s\\DefaultIcon" ),                                                                                                                               NULL,                                                                   REG_SZ,         inIconPath },
198                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s\\Shell" ),                                                                                                                                             NULL,                                                                   NULL,           NULL },
199                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s\\Shell\\Open" ),                                                                                                                               NULL,                                                                   NULL,           NULL },
200                 { HKEY_CLASSES_ROOT,    TEXT( "CLSID\\%s\\Shell\\Open\\Command" ),                                                                                                              NULL,                                                                   REG_SZ,         inExePath }
201         };
202         DWORD                           size;
203         
204         // Register the registry entries.
205
206         n = sizeof_array( entries );
207         for( i = 0; i < n; ++i )
208         {
209                 StringCbPrintf( keyName, sizeof( keyName ), entries[ i ].subKey, inClsidString );
210                 err = RegCreateKeyEx( entries[ i ].rootKey, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL );
211                 require_noerr( err, exit );
212                 
213                 if ( entries[ i ].data )
214                 {
215                         size = (DWORD)( ( lstrlen( entries[ i ].data ) + 1 ) * sizeof( TCHAR ) );
216                         err = RegSetValueEx( key, entries[ i ].valueName, 0, entries[ i ].valueType, (LPBYTE) entries[ i ].data, size );
217                         require_noerr( err, exit );
218                 }
219
220                 RegCloseKey( key );
221         }
222         
223 exit:
224         return;
225 }
226
227
228 //-----------------------------------------------------------
229 //      CCPApp::Unregister
230 //-----------------------------------------------------------
231 void
232 CCPApp::Unregister( LPCTSTR clsidString )
233 {
234         TCHAR keyName[ MAX_PATH * 2 ];
235
236         StringCbPrintf( keyName, sizeof( keyName ), L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s", clsidString );
237         MyRegDeleteKey( HKEY_LOCAL_MACHINE, keyName );
238
239         StringCbPrintf( keyName, sizeof( keyName ), L"CLSID\\%s", clsidString );
240         MyRegDeleteKey( HKEY_CLASSES_ROOT, keyName );
241 }
242
243
244
245 //-----------------------------------------------------------
246 //      CCPApp::InitInstance
247 //-----------------------------------------------------------
248
249 BOOL
250 CCPApp::InitInstance()
251 {
252         CCommandLineInfo        commandLine;
253         wchar_t                         resource[MAX_PATH];
254         CString                         errorMessage;
255         CString                         errorCaption;
256         int                                     res;
257         OSStatus                        err = kNoErr;
258
259         HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
260
261         //
262         // initialize the debugging framework
263         //
264         debug_initialize( kDebugOutputTypeWindowsDebugger, "ControlPanel", NULL );
265         debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelTrace );
266
267         // Before we load the resources, let's load the error string
268
269         errorMessage.LoadString( IDS_REINSTALL );
270         errorCaption.LoadString( IDS_REINSTALL_CAPTION );
271
272         res = PathForResource( NULL, L"ControlPanelResources.dll", resource, MAX_PATH );
273         err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
274         require_noerr( err, exit );
275
276         g_nonLocalizedResources = LoadLibrary( resource );
277         translate_errno( g_nonLocalizedResources, GetLastError(), kUnknownErr );
278         require_noerr( err, exit );
279
280         res = PathForResource( NULL, L"ControlPanelLocalized.dll", resource, MAX_PATH );
281         err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
282         require_noerr( err, exit );
283
284         g_localizedResources = LoadLibrary( resource );
285         translate_errno( g_localizedResources, GetLastError(), kUnknownErr );
286         require_noerr( err, exit );
287
288         AfxSetResourceHandle( g_localizedResources );
289
290         // InitCommonControls() is required on Windows XP if an application
291         // manifest specifies use of ComCtl32.dll version 6 or later to enable
292         // visual styles.  Otherwise, any window creation will fail.
293
294         InitCommonControls();
295
296         CWinApp::InitInstance();
297
298         AfxEnableControlContainer();
299
300         ParseCommandLine( commandLine );
301
302         if ( commandLine.m_nShellCommand == CCommandLineInfo::AppRegister )
303         {
304                 CString         localizedName;
305                 CString         toolTip;
306                 TCHAR           iconPath[ MAX_PATH + 12 ]       = TEXT( "" );
307                 TCHAR           exePath[ MAX_PATH ]                     = TEXT( "" );
308                 DWORD           nChars;
309                 OSStatus        err;
310
311                 nChars = GetModuleFileName( NULL, exePath, sizeof_array( exePath ) );
312
313                 err = translate_errno( nChars > 0, (OSStatus) GetLastError(), kUnknownErr );
314
315                 require_noerr( err, exit );
316
317                 StringCbPrintf( iconPath, sizeof( iconPath ), L"%s,-%d", exePath, IDR_APPLET );
318
319                 localizedName.LoadString( IDS_APPLET_NAME );
320                 toolTip.LoadString( IDS_APPLET_TOOLTIP );
321
322                 Register( g_controlPanelGUID, g_controlPanelName, g_controlPanelCanonicalName, g_controlPanelCategory, localizedName, toolTip, iconPath, exePath );
323         }
324         else if ( commandLine.m_nShellCommand == CCommandLineInfo::AppUnregister )
325         {
326                 Unregister( g_controlPanelGUID );
327         }
328         else
329         {
330                 CString                                 name;
331                 CConfigPropertySheet    dlg;
332                 
333                 name.LoadString( IDR_APPLET );
334                 dlg.Construct( name, NULL, 0 );
335
336                 m_pMainWnd = &dlg;
337
338                 try
339                 {
340                         INT_PTR nResponse = dlg.DoModal();
341                 
342                         if (nResponse == IDOK)
343                         {
344                                 // TODO: Place code here to handle when the dialog is
345                                 //  dismissed with OK
346                         }
347                         else if (nResponse == IDCANCEL)
348                         {
349                                 // TODO: Place code here to handle when the dialog is
350                                 //  dismissed with Cancel
351                         }
352                 }
353                 catch (...)
354                 {
355                         MessageBox(NULL, L"", L"", MB_OK|MB_ICONEXCLAMATION);
356                 }
357         }
358
359         if ( err )
360         {
361                 MessageBox( NULL, L"", L"", MB_ICONERROR | MB_OK );
362         }
363
364 exit:
365
366         if ( err )
367         {
368                 MessageBox( NULL, errorMessage, errorCaption, MB_ICONERROR | MB_OK );
369         }
370
371         // Since the dialog has been closed, return FALSE so that we exit the
372         //  application, rather than start the application's message pump.
373         return FALSE;
374 }