]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/ControlPanel/ControlPanelExe.cpp
mDNSResponder-214.3.2.tar.gz
[apple/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 Change History (most recent first):
18
19 $Log: ControlPanelExe.cpp,v $
20 Revision 1.3 2007/04/27 21:43:00 herscher
21 Update license info to Apache License, Version 2.0
22
23 Revision 1.2 2007/04/27 20:42:12 herscher
24 <rdar://problem/5078828> mDNS: Bonjour Control Panel for Windows doesn't work on Vista
25
26 Revision 1.1.2.1 2007/04/27 18:13:55 herscher
27 <rdar://problem/5078828> mDNS: Bonjour Control Panel for Windows doesn't work on Vista
28
29
30
31 */
32
33
34 #include "ControlPanelExe.h"
35 #include "ConfigDialog.h"
36 #include "ConfigPropertySheet.h"
37 #include "resource.h"
38
39 #include <DebugServices.h>
40
41
42 #ifdef _DEBUG
43 #define new DEBUG_NEW
44 #undef THIS_FILE
45 static char THIS_FILE[] = __FILE__;
46 #endif
47
48 //---------------------------------------------------------------------------------------------------------------------------
49 // Static Declarations
50 //---------------------------------------------------------------------------------------------------------------------------
51 DEFINE_GUID(CLSID_ControlPanel,
52 0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);
53
54 static LPCTSTR g_controlPanelGUID = TEXT( "{1207552C-0E59-4d9f-8554-F1F806CD7FA9}" );
55 static LPCTSTR g_controlPanelName = TEXT( "Bonjour Control Panel" );
56 static LPCTSTR g_controlPanelCategory = TEXT( "3,8" );
57 static LPCTSTR g_controlPanelLocalizedName = g_controlPanelName;
58 static LPCTSTR g_controlPanelInfoTip = TEXT( "Configures Wide-Area Bonjour" );
59
60 static CCPApp theApp;
61
62 //===========================================================================================================================
63 // MyRegDeleteKey
64 //===========================================================================================================================
65
66 DEBUG_LOCAL OSStatus MyRegDeleteKey( HKEY hKeyRoot, LPTSTR lpSubKey )
67 {
68 LPTSTR lpEnd;
69 OSStatus err;
70 DWORD dwSize;
71 TCHAR szName[MAX_PATH];
72 HKEY hKey;
73 FILETIME ftWrite;
74
75 // First, see if we can delete the key without having to recurse.
76
77 err = RegDeleteKey( hKeyRoot, lpSubKey );
78
79 if ( !err )
80 {
81 goto exit;
82 }
83
84 err = RegOpenKeyEx( hKeyRoot, lpSubKey, 0, KEY_READ, &hKey );
85 require_noerr( err, exit );
86
87 // Check for an ending slash and add one if it is missing.
88
89 lpEnd = lpSubKey + lstrlen(lpSubKey);
90
91 if ( *( lpEnd - 1 ) != TEXT( '\\' ) )
92 {
93 *lpEnd = TEXT('\\');
94 lpEnd++;
95 *lpEnd = TEXT('\0');
96 }
97
98 // Enumerate the keys
99
100 dwSize = MAX_PATH;
101 err = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite);
102
103 if ( !err )
104 {
105 do
106 {
107 lstrcpy (lpEnd, szName);
108
109 if ( !MyRegDeleteKey( hKeyRoot, lpSubKey ) )
110 {
111 break;
112 }
113
114 dwSize = MAX_PATH;
115
116 err = RegEnumKeyEx( hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite );
117
118 }
119 while ( !err );
120 }
121
122 lpEnd--;
123 *lpEnd = TEXT('\0');
124
125 RegCloseKey( hKey );
126
127 // Try again to delete the key.
128
129 err = RegDeleteKey(hKeyRoot, lpSubKey);
130 require_noerr( err, exit );
131
132 exit:
133
134 return err;
135 }
136
137
138
139 //---------------------------------------------------------------------------------------------------------------------------
140 // CCPApp::CCPApp
141 //---------------------------------------------------------------------------------------------------------------------------
142 IMPLEMENT_DYNAMIC(CCPApp, CWinApp);
143
144 CCPApp::CCPApp()
145 {
146 debug_initialize( kDebugOutputTypeWindowsEventLog, "DNS-SD Control Panel", GetModuleHandle( NULL ) );
147 debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelInfo );
148 }
149
150
151 //---------------------------------------------------------------------------------------------------------------------------
152 // CCPApp::~CCPApp
153 //---------------------------------------------------------------------------------------------------------------------------
154
155 CCPApp::~CCPApp()
156 {
157 }
158
159
160 void
161 CCPApp::Register( LPCTSTR inClsidString, LPCTSTR inName, LPCTSTR inCategory, LPCTSTR inLocalizedName, LPCTSTR inInfoTip, LPCTSTR inIconPath, LPCTSTR inExePath )
162 {
163 typedef struct RegistryBuilder RegistryBuilder;
164
165 struct RegistryBuilder
166 {
167 HKEY rootKey;
168 LPCTSTR subKey;
169 LPCTSTR valueName;
170 DWORD valueType;
171 LPCTSTR data;
172 };
173
174 OSStatus err;
175 size_t n;
176 size_t i;
177 HKEY key;
178 TCHAR keyName[ MAX_PATH ];
179 RegistryBuilder entries[] =
180 {
181 { HKEY_LOCAL_MACHINE, TEXT( "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s" ), NULL, REG_SZ, inName },
182 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s" ), NULL, NULL, NULL },
183 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s" ), TEXT( "System.ApplicationName" ), REG_SZ, inName },
184 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s" ), TEXT( "System.ControlPanel.Category" ), REG_SZ, inCategory },
185 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s" ), TEXT( "LocalizedString" ), REG_SZ, inLocalizedName },
186 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s" ), TEXT( "InfoTip" ), REG_SZ, inInfoTip },
187 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s\\DefaultIcon" ), NULL, REG_SZ, inIconPath },
188 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s\\Shell" ), NULL, NULL, NULL },
189 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s\\Shell\\Open" ), NULL, NULL, NULL },
190 { HKEY_CLASSES_ROOT, TEXT( "CLSID\\%s\\Shell\\Open\\Command" ), NULL, REG_SZ, inExePath }
191 };
192 DWORD size;
193
194 // Register the registry entries.
195
196 n = sizeof_array( entries );
197 for( i = 0; i < n; ++i )
198 {
199 wsprintf( keyName, entries[ i ].subKey, inClsidString );
200 err = RegCreateKeyEx( entries[ i ].rootKey, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL );
201 require_noerr( err, exit );
202
203 if ( entries[ i ].data )
204 {
205 size = (DWORD)( ( lstrlen( entries[ i ].data ) + 1 ) * sizeof( TCHAR ) );
206 err = RegSetValueEx( key, entries[ i ].valueName, 0, entries[ i ].valueType, (LPBYTE) entries[ i ].data, size );
207 require_noerr( err, exit );
208 }
209
210 RegCloseKey( key );
211 }
212
213 exit:
214 return;
215 }
216
217
218 //-----------------------------------------------------------
219 // CCPApp::Unregister
220 //-----------------------------------------------------------
221 void
222 CCPApp::Unregister( LPCTSTR clsidString )
223 {
224 TCHAR keyName[ MAX_PATH * 2 ];
225
226 wsprintf( keyName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s", clsidString );
227 MyRegDeleteKey( HKEY_LOCAL_MACHINE, keyName );
228
229 wsprintf( keyName, L"CLSID\\%s", clsidString );
230 MyRegDeleteKey( HKEY_CLASSES_ROOT, keyName );
231 }
232
233
234
235 //-----------------------------------------------------------
236 // CCPApp::InitInstance
237 //-----------------------------------------------------------
238
239 BOOL
240 CCPApp::InitInstance()
241 {
242 CCommandLineInfo commandLine;
243 OSStatus err = kNoErr;
244
245 // InitCommonControls() is required on Windows XP if an application
246 // manifest specifies use of ComCtl32.dll version 6 or later to enable
247 // visual styles. Otherwise, any window creation will fail.
248
249 InitCommonControls();
250
251 CWinApp::InitInstance();
252
253 AfxEnableControlContainer();
254
255 ParseCommandLine( commandLine );
256
257 if ( commandLine.m_nShellCommand == CCommandLineInfo::AppRegister )
258 {
259 TCHAR iconPath[ MAX_PATH + 12 ] = TEXT( "" );
260 TCHAR exePath[ MAX_PATH ] = TEXT( "" );
261 DWORD nChars;
262 OSStatus err;
263
264 nChars = GetModuleFileName( NULL, exePath, sizeof_array( exePath ) );
265 err = translate_errno( nChars > 0, (OSStatus) GetLastError(), kUnknownErr );
266 require_noerr( err, exit );
267
268 wsprintf( iconPath, L"%s,-%d", exePath, IDR_APPLET );
269
270 Register( g_controlPanelGUID, g_controlPanelName, g_controlPanelCategory, g_controlPanelName, g_controlPanelInfoTip, iconPath, exePath );
271 }
272 else if ( commandLine.m_nShellCommand == CCommandLineInfo::AppUnregister )
273 {
274 Unregister( g_controlPanelGUID );
275 }
276 else
277 {
278 CString name;
279 CConfigPropertySheet dlg;
280
281 name.LoadString( IDR_APPLET );
282 dlg.Construct( name, NULL, 0 );
283
284 m_pMainWnd = &dlg;
285
286 try
287 {
288 INT_PTR nResponse = dlg.DoModal();
289
290 if (nResponse == IDOK)
291 {
292 // TODO: Place code here to handle when the dialog is
293 // dismissed with OK
294 }
295 else if (nResponse == IDCANCEL)
296 {
297 // TODO: Place code here to handle when the dialog is
298 // dismissed with Cancel
299 }
300 }
301 catch (...)
302 {
303 MessageBox(NULL, L"", L"", MB_OK|MB_ICONEXCLAMATION);
304 }
305 }
306
307 if ( err )
308 {
309 MessageBox( NULL, L"", L"", MB_ICONERROR | MB_OK );
310 }
311
312 exit:
313
314 // Since the dialog has been closed, return FALSE so that we exit the
315 // application, rather than start the application's message pump.
316 return FALSE;
317 }