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"
32 static char THIS_FILE
[] = __FILE__
;
35 #ifndef HeapEnableTerminationOnCorruption
36 # define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS) 1
40 // Stash away pointers to our resource DLLs
42 static HINSTANCE g_nonLocalizedResources
= NULL
;
43 static HINSTANCE g_localizedResources
= NULL
;
46 HINSTANCE
GetNonLocalizedResources()
48 return g_nonLocalizedResources
;
52 HINSTANCE
GetLocalizedResources()
54 return g_localizedResources
;
58 //---------------------------------------------------------------------------------------------------------------------------
59 // Static Declarations
60 //---------------------------------------------------------------------------------------------------------------------------
61 DEFINE_GUID(CLSID_ControlPanel
,
63 0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);
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" );
72 //===========================================================================================================================
74 //===========================================================================================================================
76 DEBUG_LOCAL OSStatus
MyRegDeleteKey( HKEY hKeyRoot
, LPTSTR lpSubKey
)
81 TCHAR szName
[MAX_PATH
];
85 // First, see if we can delete the key without having to recurse.
87 err
= RegDeleteKey( hKeyRoot
, lpSubKey
);
94 err
= RegOpenKeyEx( hKeyRoot
, lpSubKey
, 0, KEY_READ
, &hKey
);
95 require_noerr( err
, exit
);
97 // Check for an ending slash and add one if it is missing.
99 lpEnd
= lpSubKey
+ lstrlen(lpSubKey
);
101 if ( *( lpEnd
- 1 ) != TEXT( '\\' ) )
108 // Enumerate the keys
111 err
= RegEnumKeyEx(hKey
, 0, szName
, &dwSize
, NULL
, NULL
, NULL
, &ftWrite
);
117 lstrcpy (lpEnd
, szName
);
119 if ( !MyRegDeleteKey( hKeyRoot
, lpSubKey
) )
126 err
= RegEnumKeyEx( hKey
, 0, szName
, &dwSize
, NULL
, NULL
, NULL
, &ftWrite
);
137 // Try again to delete the key.
139 err
= RegDeleteKey(hKeyRoot
, lpSubKey
);
140 require_noerr( err
, exit
);
149 //---------------------------------------------------------------------------------------------------------------------------
151 //---------------------------------------------------------------------------------------------------------------------------
152 IMPLEMENT_DYNAMIC(CCPApp
, CWinApp
);
156 debug_initialize( kDebugOutputTypeWindowsEventLog
, "DNS-SD Control Panel", GetModuleHandle( NULL
) );
157 debug_set_property( kDebugPropertyTagPrintLevel
, kDebugLevelInfo
);
161 //---------------------------------------------------------------------------------------------------------------------------
163 //---------------------------------------------------------------------------------------------------------------------------
171 CCPApp::Register( LPCTSTR inClsidString
, LPCTSTR inName
, LPCTSTR inCanonicalName
, LPCTSTR inCategory
, LPCTSTR inLocalizedName
, LPCTSTR inInfoTip
, LPCTSTR inIconPath
, LPCTSTR inExePath
)
173 typedef struct RegistryBuilder RegistryBuilder
;
175 struct RegistryBuilder
188 TCHAR keyName
[ MAX_PATH
];
189 RegistryBuilder entries
[] =
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
}
204 // Register the registry entries.
206 n
= sizeof_array( entries
);
207 for( i
= 0; i
< n
; ++i
)
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
);
213 if ( entries
[ i
].data
)
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
);
228 //-----------------------------------------------------------
229 // CCPApp::Unregister
230 //-----------------------------------------------------------
232 CCPApp::Unregister( LPCTSTR clsidString
)
234 TCHAR keyName
[ MAX_PATH
* 2 ];
236 StringCbPrintf( keyName
, sizeof( keyName
), L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s", clsidString
);
237 MyRegDeleteKey( HKEY_LOCAL_MACHINE
, keyName
);
239 StringCbPrintf( keyName
, sizeof( keyName
), L
"CLSID\\%s", clsidString
);
240 MyRegDeleteKey( HKEY_CLASSES_ROOT
, keyName
);
245 //-----------------------------------------------------------
246 // CCPApp::InitInstance
247 //-----------------------------------------------------------
250 CCPApp::InitInstance()
252 CCommandLineInfo commandLine
;
253 wchar_t resource
[MAX_PATH
];
254 CString errorMessage
;
255 CString errorCaption
;
257 OSStatus err
= kNoErr
;
259 HeapSetInformation( NULL
, HeapEnableTerminationOnCorruption
, NULL
, 0 );
262 // initialize the debugging framework
264 debug_initialize( kDebugOutputTypeWindowsDebugger
, "ControlPanel", NULL
);
265 debug_set_property( kDebugPropertyTagPrintLevel
, kDebugLevelTrace
);
267 // Before we load the resources, let's load the error string
269 errorMessage
.LoadString( IDS_REINSTALL
);
270 errorCaption
.LoadString( IDS_REINSTALL_CAPTION
);
272 res
= PathForResource( NULL
, L
"ControlPanelResources.dll", resource
, MAX_PATH
);
273 err
= translate_errno( res
!= 0, kUnknownErr
, kUnknownErr
);
274 require_noerr( err
, exit
);
276 g_nonLocalizedResources
= LoadLibrary( resource
);
277 translate_errno( g_nonLocalizedResources
, GetLastError(), kUnknownErr
);
278 require_noerr( err
, exit
);
280 res
= PathForResource( NULL
, L
"ControlPanelLocalized.dll", resource
, MAX_PATH
);
281 err
= translate_errno( res
!= 0, kUnknownErr
, kUnknownErr
);
282 require_noerr( err
, exit
);
284 g_localizedResources
= LoadLibrary( resource
);
285 translate_errno( g_localizedResources
, GetLastError(), kUnknownErr
);
286 require_noerr( err
, exit
);
288 AfxSetResourceHandle( g_localizedResources
);
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.
294 InitCommonControls();
296 CWinApp::InitInstance();
298 AfxEnableControlContainer();
300 ParseCommandLine( commandLine
);
302 if ( commandLine
.m_nShellCommand
== CCommandLineInfo::AppRegister
)
304 CString localizedName
;
306 TCHAR iconPath
[ MAX_PATH
+ 12 ] = TEXT( "" );
307 TCHAR exePath
[ MAX_PATH
] = TEXT( "" );
311 nChars
= GetModuleFileName( NULL
, exePath
, sizeof_array( exePath
) );
313 err
= translate_errno( nChars
> 0, (OSStatus
) GetLastError(), kUnknownErr
);
315 require_noerr( err
, exit
);
317 StringCbPrintf( iconPath
, sizeof( iconPath
), L
"%s,-%d", exePath
, IDR_APPLET
);
319 localizedName
.LoadString( IDS_APPLET_NAME
);
320 toolTip
.LoadString( IDS_APPLET_TOOLTIP
);
322 Register( g_controlPanelGUID
, g_controlPanelName
, g_controlPanelCanonicalName
, g_controlPanelCategory
, localizedName
, toolTip
, iconPath
, exePath
);
324 else if ( commandLine
.m_nShellCommand
== CCommandLineInfo::AppUnregister
)
326 Unregister( g_controlPanelGUID
);
331 CConfigPropertySheet dlg
;
333 name
.LoadString( IDR_APPLET
);
334 dlg
.Construct( name
, NULL
, 0 );
340 INT_PTR nResponse
= dlg
.DoModal();
342 if (nResponse
== IDOK
)
344 // TODO: Place code here to handle when the dialog is
347 else if (nResponse
== IDCANCEL
)
349 // TODO: Place code here to handle when the dialog is
350 // dismissed with Cancel
355 MessageBox(NULL
, L
"", L
"", MB_OK
|MB_ICONEXCLAMATION
);
361 MessageBox( NULL
, L
"", L
"", MB_ICONERROR
| MB_OK
);
368 MessageBox( NULL
, errorMessage
, errorCaption
, MB_ICONERROR
| MB_OK
);
371 // Since the dialog has been closed, return FALSE so that we exit the
372 // application, rather than start the application's message pump.