]>
Commit | Line | Data |
---|---|---|
67c8f8a1 A |
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, \r | |
52 | 0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);\r | |
53 | \r | |
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 ) );\r | |
265 | err = translate_errno( nChars > 0, (OSStatus) GetLastError(), kUnknownErr );\r | |
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 | } |