1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2002-2007 Apple Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 Change History (most recent first):
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
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
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
34 #include "ControlPanelExe.h"
35 #include "ConfigDialog.h"
36 #include "ConfigPropertySheet.h"
39 #include <DebugServices.h>
45 static char THIS_FILE
[] = __FILE__
;
48 //---------------------------------------------------------------------------------------------------------------------------
49 // Static Declarations
50 //---------------------------------------------------------------------------------------------------------------------------
51 DEFINE_GUID(CLSID_ControlPanel
,
52 0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);
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" );
62 //===========================================================================================================================
64 //===========================================================================================================================
66 DEBUG_LOCAL OSStatus
MyRegDeleteKey( HKEY hKeyRoot
, LPTSTR lpSubKey
)
71 TCHAR szName
[MAX_PATH
];
75 // First, see if we can delete the key without having to recurse.
77 err
= RegDeleteKey( hKeyRoot
, lpSubKey
);
84 err
= RegOpenKeyEx( hKeyRoot
, lpSubKey
, 0, KEY_READ
, &hKey
);
85 require_noerr( err
, exit
);
87 // Check for an ending slash and add one if it is missing.
89 lpEnd
= lpSubKey
+ lstrlen(lpSubKey
);
91 if ( *( lpEnd
- 1 ) != TEXT( '\\' ) )
101 err
= RegEnumKeyEx(hKey
, 0, szName
, &dwSize
, NULL
, NULL
, NULL
, &ftWrite
);
107 lstrcpy (lpEnd
, szName
);
109 if ( !MyRegDeleteKey( hKeyRoot
, lpSubKey
) )
116 err
= RegEnumKeyEx( hKey
, 0, szName
, &dwSize
, NULL
, NULL
, NULL
, &ftWrite
);
127 // Try again to delete the key.
129 err
= RegDeleteKey(hKeyRoot
, lpSubKey
);
130 require_noerr( err
, exit
);
139 //---------------------------------------------------------------------------------------------------------------------------
141 //---------------------------------------------------------------------------------------------------------------------------
142 IMPLEMENT_DYNAMIC(CCPApp
, CWinApp
);
146 debug_initialize( kDebugOutputTypeWindowsEventLog
, "DNS-SD Control Panel", GetModuleHandle( NULL
) );
147 debug_set_property( kDebugPropertyTagPrintLevel
, kDebugLevelInfo
);
151 //---------------------------------------------------------------------------------------------------------------------------
153 //---------------------------------------------------------------------------------------------------------------------------
161 CCPApp::Register( LPCTSTR inClsidString
, LPCTSTR inName
, LPCTSTR inCategory
, LPCTSTR inLocalizedName
, LPCTSTR inInfoTip
, LPCTSTR inIconPath
, LPCTSTR inExePath
)
163 typedef struct RegistryBuilder RegistryBuilder
;
165 struct RegistryBuilder
178 TCHAR keyName
[ MAX_PATH
];
179 RegistryBuilder entries
[] =
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
}
194 // Register the registry entries.
196 n
= sizeof_array( entries
);
197 for( i
= 0; i
< n
; ++i
)
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
);
203 if ( entries
[ i
].data
)
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
);
218 //-----------------------------------------------------------
219 // CCPApp::Unregister
220 //-----------------------------------------------------------
222 CCPApp::Unregister( LPCTSTR clsidString
)
224 TCHAR keyName
[ MAX_PATH
* 2 ];
226 wsprintf( keyName
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s", clsidString
);
227 MyRegDeleteKey( HKEY_LOCAL_MACHINE
, keyName
);
229 wsprintf( keyName
, L
"CLSID\\%s", clsidString
);
230 MyRegDeleteKey( HKEY_CLASSES_ROOT
, keyName
);
235 //-----------------------------------------------------------
236 // CCPApp::InitInstance
237 //-----------------------------------------------------------
240 CCPApp::InitInstance()
242 CCommandLineInfo commandLine
;
243 OSStatus err
= kNoErr
;
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.
249 InitCommonControls();
251 CWinApp::InitInstance();
253 AfxEnableControlContainer();
255 ParseCommandLine( commandLine
);
257 if ( commandLine
.m_nShellCommand
== CCommandLineInfo::AppRegister
)
259 TCHAR iconPath
[ MAX_PATH
+ 12 ] = TEXT( "" );
260 TCHAR exePath
[ MAX_PATH
] = TEXT( "" );
264 nChars
= GetModuleFileName( NULL
, exePath
, sizeof_array( exePath
) );
265 err
= translate_errno( nChars
> 0, (OSStatus
) GetLastError(), kUnknownErr
);
266 require_noerr( err
, exit
);
268 wsprintf( iconPath
, L
"%s,-%d", exePath
, IDR_APPLET
);
270 Register( g_controlPanelGUID
, g_controlPanelName
, g_controlPanelCategory
, g_controlPanelName
, g_controlPanelInfoTip
, iconPath
, exePath
);
272 else if ( commandLine
.m_nShellCommand
== CCommandLineInfo::AppUnregister
)
274 Unregister( g_controlPanelGUID
);
279 CConfigPropertySheet dlg
;
281 name
.LoadString( IDR_APPLET
);
282 dlg
.Construct( name
, NULL
, 0 );
288 INT_PTR nResponse
= dlg
.DoModal();
290 if (nResponse
== IDOK
)
292 // TODO: Place code here to handle when the dialog is
295 else if (nResponse
== IDCANCEL
)
297 // TODO: Place code here to handle when the dialog is
298 // dismissed with Cancel
303 MessageBox(NULL
, L
"", L
"", MB_OK
|MB_ICONEXCLAMATION
);
309 MessageBox( NULL
, L
"", L
"", MB_ICONERROR
| MB_OK
);
314 // Since the dialog has been closed, return FALSE so that we exit the
315 // application, rather than start the application's message pump.