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.
19 #include "ControlPanelExe.h"
20 #include "ConfigDialog.h"
21 #include "ConfigPropertySheet.h"
24 #include <DebugServices.h>
25 #include "loclibrary.h"
31 static char THIS_FILE
[] = __FILE__
;
34 #ifndef HeapEnableTerminationOnCorruption
35 # define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS) 1
39 // Stash away pointers to our resource DLLs
41 static HINSTANCE g_nonLocalizedResources
= NULL
;
42 static HINSTANCE g_localizedResources
= NULL
;
45 HINSTANCE
GetNonLocalizedResources()
47 return g_nonLocalizedResources
;
51 HINSTANCE
GetLocalizedResources()
53 return g_localizedResources
;
57 //---------------------------------------------------------------------------------------------------------------------------
58 // Static Declarations
59 //---------------------------------------------------------------------------------------------------------------------------
60 DEFINE_GUID(CLSID_ControlPanel
,
62 0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);
64 static LPCTSTR g_controlPanelGUID
= TEXT( "{1207552C-0E59-4d9f-8554-F1F806CD7FA9}" );
65 static LPCTSTR g_controlPanelName
= TEXT( "Bonjour" );
66 static LPCTSTR g_controlPanelCanonicalName
= TEXT( "Apple.Bonjour" );
67 static LPCTSTR g_controlPanelCategory
= TEXT( "3,8" );
71 //===========================================================================================================================
73 //===========================================================================================================================
75 DEBUG_LOCAL OSStatus
MyRegDeleteKey( HKEY hKeyRoot
, LPTSTR lpSubKey
)
80 TCHAR szName
[MAX_PATH
];
84 // First, see if we can delete the key without having to recurse.
86 err
= RegDeleteKey( hKeyRoot
, lpSubKey
);
93 err
= RegOpenKeyEx( hKeyRoot
, lpSubKey
, 0, KEY_READ
, &hKey
);
94 require_noerr( err
, exit
);
96 // Check for an ending slash and add one if it is missing.
98 lpEnd
= lpSubKey
+ lstrlen(lpSubKey
);
100 if ( *( lpEnd
- 1 ) != TEXT( '\\' ) )
107 // Enumerate the keys
110 err
= RegEnumKeyEx(hKey
, 0, szName
, &dwSize
, NULL
, NULL
, NULL
, &ftWrite
);
116 lstrcpy (lpEnd
, szName
);
118 if ( !MyRegDeleteKey( hKeyRoot
, lpSubKey
) )
125 err
= RegEnumKeyEx( hKey
, 0, szName
, &dwSize
, NULL
, NULL
, NULL
, &ftWrite
);
136 // Try again to delete the key.
138 err
= RegDeleteKey(hKeyRoot
, lpSubKey
);
139 require_noerr( err
, exit
);
148 //---------------------------------------------------------------------------------------------------------------------------
150 //---------------------------------------------------------------------------------------------------------------------------
151 IMPLEMENT_DYNAMIC(CCPApp
, CWinApp
);
155 debug_initialize( kDebugOutputTypeWindowsEventLog
, "DNS-SD Control Panel", GetModuleHandle( NULL
) );
156 debug_set_property( kDebugPropertyTagPrintLevel
, kDebugLevelInfo
);
160 //---------------------------------------------------------------------------------------------------------------------------
162 //---------------------------------------------------------------------------------------------------------------------------
170 CCPApp::Register( LPCTSTR inClsidString
, LPCTSTR inName
, LPCTSTR inCanonicalName
, LPCTSTR inCategory
, LPCTSTR inLocalizedName
, LPCTSTR inInfoTip
, LPCTSTR inIconPath
, LPCTSTR inExePath
)
172 typedef struct RegistryBuilder RegistryBuilder
;
174 struct RegistryBuilder
187 TCHAR keyName
[ MAX_PATH
];
188 RegistryBuilder entries
[] =
190 { HKEY_LOCAL_MACHINE
, TEXT( "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s" ), NULL
, REG_SZ
, inName
},
191 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s" ), NULL
, NULL
, NULL
},
192 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s" ), TEXT( "System.ApplicationName" ), REG_SZ
, inCanonicalName
},
193 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s" ), TEXT( "System.ControlPanel.Category" ), REG_SZ
, inCategory
},
194 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s" ), TEXT( "LocalizedString" ), REG_SZ
, inLocalizedName
},
195 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s" ), TEXT( "InfoTip" ), REG_SZ
, inInfoTip
},
196 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s\\DefaultIcon" ), NULL
, REG_SZ
, inIconPath
},
197 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s\\Shell" ), NULL
, NULL
, NULL
},
198 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s\\Shell\\Open" ), NULL
, NULL
, NULL
},
199 { HKEY_CLASSES_ROOT
, TEXT( "CLSID\\%s\\Shell\\Open\\Command" ), NULL
, REG_SZ
, inExePath
}
203 // Register the registry entries.
205 n
= sizeof_array( entries
);
206 for( i
= 0; i
< n
; ++i
)
208 wsprintf( keyName
, entries
[ i
].subKey
, inClsidString
);
209 err
= RegCreateKeyEx( entries
[ i
].rootKey
, keyName
, 0, NULL
, REG_OPTION_NON_VOLATILE
, KEY_WRITE
, NULL
, &key
, NULL
);
210 require_noerr( err
, exit
);
212 if ( entries
[ i
].data
)
214 size
= (DWORD
)( ( lstrlen( entries
[ i
].data
) + 1 ) * sizeof( TCHAR
) );
215 err
= RegSetValueEx( key
, entries
[ i
].valueName
, 0, entries
[ i
].valueType
, (LPBYTE
) entries
[ i
].data
, size
);
216 require_noerr( err
, exit
);
227 //-----------------------------------------------------------
228 // CCPApp::Unregister
229 //-----------------------------------------------------------
231 CCPApp::Unregister( LPCTSTR clsidString
)
233 TCHAR keyName
[ MAX_PATH
* 2 ];
235 wsprintf( keyName
, L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s", clsidString
);
236 MyRegDeleteKey( HKEY_LOCAL_MACHINE
, keyName
);
238 wsprintf( keyName
, L
"CLSID\\%s", clsidString
);
239 MyRegDeleteKey( HKEY_CLASSES_ROOT
, keyName
);
244 //-----------------------------------------------------------
245 // CCPApp::InitInstance
246 //-----------------------------------------------------------
249 CCPApp::InitInstance()
251 CCommandLineInfo commandLine
;
252 wchar_t resource
[MAX_PATH
];
253 CString errorMessage
;
254 CString errorCaption
;
256 OSStatus err
= kNoErr
;
258 HeapSetInformation( NULL
, HeapEnableTerminationOnCorruption
, NULL
, 0 );
261 // initialize the debugging framework
263 debug_initialize( kDebugOutputTypeWindowsDebugger
, "ControlPanel", NULL
);
264 debug_set_property( kDebugPropertyTagPrintLevel
, kDebugLevelTrace
);
266 // Before we load the resources, let's load the error string
268 errorMessage
.LoadString( IDS_REINSTALL
);
269 errorCaption
.LoadString( IDS_REINSTALL_CAPTION
);
271 res
= PathForResource( NULL
, L
"ControlPanelResources.dll", resource
, MAX_PATH
);
272 err
= translate_errno( res
!= 0, kUnknownErr
, kUnknownErr
);
273 require_noerr( err
, exit
);
275 g_nonLocalizedResources
= LoadLibrary( resource
);
276 translate_errno( g_nonLocalizedResources
, GetLastError(), kUnknownErr
);
277 require_noerr( err
, exit
);
279 res
= PathForResource( NULL
, L
"ControlPanelLocalized.dll", resource
, MAX_PATH
);
280 err
= translate_errno( res
!= 0, kUnknownErr
, kUnknownErr
);
281 require_noerr( err
, exit
);
283 g_localizedResources
= LoadLibrary( resource
);
284 translate_errno( g_localizedResources
, GetLastError(), kUnknownErr
);
285 require_noerr( err
, exit
);
287 AfxSetResourceHandle( g_localizedResources
);
289 // InitCommonControls() is required on Windows XP if an application
290 // manifest specifies use of ComCtl32.dll version 6 or later to enable
291 // visual styles. Otherwise, any window creation will fail.
293 InitCommonControls();
295 CWinApp::InitInstance();
297 AfxEnableControlContainer();
299 ParseCommandLine( commandLine
);
301 if ( commandLine
.m_nShellCommand
== CCommandLineInfo::AppRegister
)
303 CString localizedName
;
305 TCHAR iconPath
[ MAX_PATH
+ 12 ] = TEXT( "" );
306 TCHAR exePath
[ MAX_PATH
] = TEXT( "" );
310 nChars
= GetModuleFileName( NULL
, exePath
, sizeof_array( exePath
) );
312 err
= translate_errno( nChars
> 0, (OSStatus
) GetLastError(), kUnknownErr
);
314 require_noerr( err
, exit
);
316 wsprintf( iconPath
, L
"%s,-%d", exePath
, IDR_APPLET
);
318 localizedName
.LoadString( IDS_APPLET_NAME
);
319 toolTip
.LoadString( IDS_APPLET_TOOLTIP
);
321 Register( g_controlPanelGUID
, g_controlPanelName
, g_controlPanelCanonicalName
, g_controlPanelCategory
, localizedName
, toolTip
, iconPath
, exePath
);
323 else if ( commandLine
.m_nShellCommand
== CCommandLineInfo::AppUnregister
)
325 Unregister( g_controlPanelGUID
);
330 CConfigPropertySheet dlg
;
332 name
.LoadString( IDR_APPLET
);
333 dlg
.Construct( name
, NULL
, 0 );
339 INT_PTR nResponse
= dlg
.DoModal();
341 if (nResponse
== IDOK
)
343 // TODO: Place code here to handle when the dialog is
346 else if (nResponse
== IDCANCEL
)
348 // TODO: Place code here to handle when the dialog is
349 // dismissed with Cancel
354 MessageBox(NULL
, L
"", L
"", MB_OK
|MB_ICONEXCLAMATION
);
360 MessageBox( NULL
, L
"", L
"", MB_ICONERROR
| MB_OK
);
367 MessageBox( NULL
, errorMessage
, errorCaption
, MB_ICONERROR
| MB_OK
);
370 // Since the dialog has been closed, return FALSE so that we exit the
371 // application, rather than start the application's message pump.