• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; tab-width: 4 -*-
2  *
3  * Copyright (c) 2002-2004 Apple Computer, 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 
18 #include "SecondPage.h"
19 #include "resource.h"
20 
21 #include "ConfigPropertySheet.h"
22 #include "SharedSecret.h"
23 
24 #include <WinServices.h>
25 
26 #define MAX_KEY_LENGTH 255
27 
IMPLEMENT_DYNCREATE(CSecondPage,CPropertyPage)28 IMPLEMENT_DYNCREATE(CSecondPage, CPropertyPage)
29 
30 
31 //---------------------------------------------------------------------------------------------------------------------------
32 //	CSecondPage::CSecondPage
33 //---------------------------------------------------------------------------------------------------------------------------
34 
35 CSecondPage::CSecondPage()
36 :
37 	CPropertyPage(CSecondPage::IDD),
38 	m_setupKey( NULL )
39 {
40 	//{{AFX_DATA_INIT(CSecondPage)
41 	//}}AFX_DATA_INIT
42 
43 	OSStatus err;
44 
45 	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, 0,
46 	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_setupKey, NULL );
47 	check_noerr( err );
48 }
49 
50 
51 //---------------------------------------------------------------------------------------------------------------------------
52 //	CSecondPage::~CSecondPage
53 //---------------------------------------------------------------------------------------------------------------------------
54 
~CSecondPage()55 CSecondPage::~CSecondPage()
56 {
57 	if ( m_setupKey )
58 	{
59 		RegCloseKey( m_setupKey );
60 		m_setupKey = NULL;
61 	}
62 }
63 
64 
65 //---------------------------------------------------------------------------------------------------------------------------
66 //	CSecondPage::DoDataExchange
67 //---------------------------------------------------------------------------------------------------------------------------
68 
DoDataExchange(CDataExchange * pDX)69 void CSecondPage::DoDataExchange(CDataExchange* pDX)
70 {
71 	CPropertyPage::DoDataExchange(pDX);
72 	//{{AFX_DATA_MAP(CSecondPage)
73 	//}}AFX_DATA_MAP
74 	DDX_Control(pDX, IDC_CHECK1, m_advertiseServicesButton);
75 	DDX_Control(pDX, IDC_BUTTON1, m_sharedSecretButton);
76 	DDX_Control(pDX, IDC_COMBO2, m_regDomainsBox);
77 }
78 
BEGIN_MESSAGE_MAP(CSecondPage,CPropertyPage)79 BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
80 	//{{AFX_MSG_MAP(CSecondPage)
81 	//}}AFX_MSG_MAP
82 	ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedSharedSecret)
83 	ON_BN_CLICKED(IDC_CHECK1, OnBnClickedAdvertise)
84 	ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelChange)
85 	ON_CBN_EDITCHANGE(IDC_COMBO1, OnCbnEditChange)
86 	ON_CBN_EDITCHANGE(IDC_COMBO2, OnCbnEditChange)
87 	ON_CBN_SELCHANGE(IDC_COMBO2, OnCbnSelChange)
88 
89 END_MESSAGE_MAP()
90 
91 
92 //---------------------------------------------------------------------------------------------------------------------------
93 //	CSecondPage::SetModified
94 //---------------------------------------------------------------------------------------------------------------------------
95 
96 void CSecondPage::SetModified( BOOL bChanged )
97 {
98 	m_modified = bChanged;
99 
100 	CPropertyPage::SetModified( bChanged );
101 }
102 
103 
104 //---------------------------------------------------------------------------------------------------------------------------
105 //	CSecondPage::OnSetActive
106 //---------------------------------------------------------------------------------------------------------------------------
107 
108 BOOL
OnSetActive()109 CSecondPage::OnSetActive()
110 {
111 	CConfigPropertySheet	*	psheet;
112 	DWORD						err;
113 	BOOL						b = CPropertyPage::OnSetActive();
114 
115 	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
116 	require_quiet( psheet, exit );
117 
118 	m_modified = FALSE;
119 
120 	// Clear out what's there
121 
122 	EmptyComboBox( m_regDomainsBox );
123 
124 	// Now populate the registration domain box
125 
126 	err = Populate( m_regDomainsBox, m_setupKey, psheet->m_regDomains );
127 	check_noerr( err );
128 
129 exit:
130 
131 	return b;
132 }
133 
134 
135 //---------------------------------------------------------------------------------------------------------------------------
136 //	CSecondPage::OnOK
137 //---------------------------------------------------------------------------------------------------------------------------
138 
139 void
OnOK()140 CSecondPage::OnOK()
141 {
142 	if ( m_modified )
143 	{
144 		Commit();
145 	}
146 }
147 
148 
149 
150 //---------------------------------------------------------------------------------------------------------------------------
151 //	CSecondPage::Commit
152 //---------------------------------------------------------------------------------------------------------------------------
153 
154 void
Commit()155 CSecondPage::Commit()
156 {
157 	DWORD err;
158 
159 	if ( m_setupKey != NULL )
160 	{
161 		err = Commit( m_regDomainsBox, m_setupKey, m_advertiseServicesButton.GetCheck() == BST_CHECKED );
162 		check_noerr( err );
163 	}
164 }
165 
166 
167 //---------------------------------------------------------------------------------------------------------------------------
168 //	CSecondPage::Commit
169 //---------------------------------------------------------------------------------------------------------------------------
170 
171 OSStatus
Commit(CComboBox & box,HKEY key,DWORD enabled)172 CSecondPage::Commit( CComboBox & box, HKEY key, DWORD enabled )
173 {
174 	CString		selected;
175 	HKEY		subKey	= NULL;
176 	TCHAR		subKeyName[MAX_KEY_LENGTH];
177 	DWORD		cSubKeys = 0;
178 	DWORD		cbMaxSubKey;
179 	DWORD		cchMaxClass;
180 	DWORD		dwSize;
181 	int			i;
182 	OSStatus	err = kNoErr;
183 
184 	// First, remove all the entries that are there
185 
186     err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
187 	require_noerr( err, exit );
188 
189 	for ( i = 0; i < (int) cSubKeys; i++ )
190 	{
191 		dwSize = MAX_KEY_LENGTH;
192 
193 		err = RegEnumKeyEx( key, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
194 		require_noerr( err, exit );
195 
196 		err = RegDeleteKey( key, subKeyName );
197 		require_noerr( err, exit );
198 	}
199 
200 	// Get selected text
201 
202 	box.GetWindowText( selected );
203 
204 	// If we haven't seen this string before, add the string to the box and
205 	// the registry
206 
207 	if ( ( selected.GetLength() > 0 ) && ( box.FindStringExact( -1, selected ) == CB_ERR ) )
208 	{
209 		CString string;
210 
211 		box.AddString( selected );
212 
213 		err = RegQueryString( key, L"UserDefined", string );
214 		check_noerr( err );
215 
216 		if ( string.GetLength() )
217 		{
218 			string += L"," + selected;
219 		}
220 		else
221 		{
222 			string = selected;
223 		}
224 
225 		err = RegSetValueEx( key, L"UserDefined", 0, REG_SZ, (LPBYTE) (LPCTSTR) string, ( string.GetLength() + 1) * sizeof( TCHAR ) );
226 		check_noerr ( err );
227 	}
228 
229 	// Save selected text in registry.  This will trigger mDNSResponder to setup
230 	// DynDNS config again
231 
232 	err = RegCreateKeyEx( key, selected, 0,
233 	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &subKey, NULL );
234 	require_noerr( err, exit );
235 
236 	err = RegSetValueEx( subKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
237 	check_noerr( err );
238 
239 exit:
240 
241 	if ( subKey )
242 	{
243 		RegCloseKey( subKey );
244 		subKey = NULL;
245 	}
246 
247 	return err;
248 }
249 
250 
251 //---------------------------------------------------------------------------------------------------------------------------
252 //	CSecondPage::OnBnClickedSharedSecret
253 //---------------------------------------------------------------------------------------------------------------------------
254 
OnBnClickedSharedSecret()255 void CSecondPage::OnBnClickedSharedSecret()
256 {
257 	CString name;
258 
259 	m_regDomainsBox.GetWindowText( name );
260 
261 	CSharedSecret dlg;
262 
263 	dlg.Load( name );
264 
265 	if ( dlg.DoModal() == IDOK )
266 	{
267 		DWORD		wakeup = 0;
268 		DWORD		dwSize = sizeof( DWORD );
269 		OSStatus	err;
270 
271 		dlg.Commit( name );
272 
273 		// We have now updated the secret, however the system service
274 		// doesn't know about it yet.  So we're going to update the
275 		// registry with a dummy value which will cause the system
276 		// service to re-initialize it's DynDNS setup
277 		//
278 
279 		RegQueryValueEx( m_setupKey, L"Wakeup", NULL, NULL, (LPBYTE) &wakeup, &dwSize );
280 
281 		wakeup++;
282 
283 		err = RegSetValueEx( m_setupKey, L"Wakeup", 0, REG_DWORD, (LPBYTE) &wakeup, sizeof( DWORD ) );
284 		require_noerr( err, exit );
285 	}
286 
287 exit:
288 
289 	return;
290 }
291 
292 
293 //---------------------------------------------------------------------------------------------------------------------------
294 //	CSecondPage::OnBnClickedAdvertise
295 //---------------------------------------------------------------------------------------------------------------------------
296 
OnBnClickedAdvertise()297 void CSecondPage::OnBnClickedAdvertise()
298 {
299 	int state;
300 
301 	state = m_advertiseServicesButton.GetCheck();
302 
303 	m_regDomainsBox.EnableWindow( state );
304 	m_sharedSecretButton.EnableWindow( state );
305 
306 	SetModified( TRUE );
307 }
308 
309 
310 //---------------------------------------------------------------------------------------------------------------------------
311 //	CSecondPage::OnCbnSelChange
312 //---------------------------------------------------------------------------------------------------------------------------
313 
OnCbnSelChange()314 void CSecondPage::OnCbnSelChange()
315 {
316 	SetModified( TRUE );
317 }
318 
319 
320 //---------------------------------------------------------------------------------------------------------------------------
321 //	CSecondPage::OnCbnEditChange
322 //---------------------------------------------------------------------------------------------------------------------------
323 
OnCbnEditChange()324 void CSecondPage::OnCbnEditChange()
325 {
326 	SetModified( TRUE );
327 }
328 
329 
330 
331 //---------------------------------------------------------------------------------------------------------------------------
332 //	CSecondPage::OnAddRegistrationDomain
333 //---------------------------------------------------------------------------------------------------------------------------
334 
335 void
OnAddRegistrationDomain(CString & domain)336 CSecondPage::OnAddRegistrationDomain( CString & domain )
337 {
338 	int index = m_regDomainsBox.FindStringExact( -1, domain );
339 
340 	if ( index == CB_ERR )
341 	{
342 		m_regDomainsBox.AddString( domain );
343 	}
344 }
345 
346 
347 //---------------------------------------------------------------------------------------------------------------------------
348 //	CSecondPage::OnRemoveRegistrationDomain
349 //---------------------------------------------------------------------------------------------------------------------------
350 
351 void
OnRemoveRegistrationDomain(CString & domain)352 CSecondPage::OnRemoveRegistrationDomain( CString & domain )
353 {
354 	int index = m_regDomainsBox.FindStringExact( -1, domain );
355 
356 	if ( index != CB_ERR )
357 	{
358 		m_regDomainsBox.DeleteString( index );
359 	}
360 }
361 
362 
363 //---------------------------------------------------------------------------------------------------------------------------
364 //	CSecondPage::EmptyComboBox
365 //---------------------------------------------------------------------------------------------------------------------------
366 
367 void
EmptyComboBox(CComboBox & box)368 CSecondPage::EmptyComboBox( CComboBox & box )
369 {
370 	while ( box.GetCount() > 0 )
371 	{
372 		box.DeleteString( 0 );
373 	}
374 }
375 
376 
377 //---------------------------------------------------------------------------------------------------------------------------
378 //	CSecondPage::Populate
379 //---------------------------------------------------------------------------------------------------------------------------
380 
381 OSStatus
Populate(CComboBox & box,HKEY key,StringList & l)382 CSecondPage::Populate( CComboBox & box, HKEY key, StringList & l )
383 {
384 	CString		string;
385 	HKEY		subKey = NULL;
386 	DWORD		dwSize;
387 	DWORD		enabled = 0;
388 	TCHAR		subKeyName[MAX_KEY_LENGTH];
389 	DWORD		cSubKeys = 0;
390 	DWORD		cbMaxSubKey;
391 	DWORD		cchMaxClass;
392 	OSStatus	err;
393 
394 	err = RegQueryString( key, L"UserDefined", string );
395 
396 	if ( !err && string.GetLength() )
397 	{
398 		bool done = false;
399 
400 		while ( !done )
401 		{
402 			CString tok;
403 
404 			tok = string.SpanExcluding( L"," );
405 
406 			box.AddString( tok );
407 
408 			if ( tok != string )
409 			{
410 				// Get rid of that string and comma
411 
412 				string = string.Right( string.GetLength() - tok.GetLength() - 1 );
413 			}
414 			else
415 			{
416 				done = true;
417 			}
418 		}
419 	}
420 
421 	StringList::iterator it;
422 
423 	for ( it = l.begin(); it != l.end(); it++ )
424 	{
425 		if ( box.FindStringExact( -1, *it ) == CB_ERR )
426 		{
427 			box.AddString( *it );
428 		}
429 	}
430 
431 	err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
432 	require_noerr( err, exit );
433 
434 	if ( cSubKeys > 0 )
435 	{
436 		dwSize = MAX_KEY_LENGTH;
437 
438 		err = RegEnumKeyEx( key, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
439 		require_noerr( err, exit );
440 
441 		err = RegOpenKey( key, subKeyName, &subKey );
442 		require_noerr( err, exit );
443 
444 		dwSize = sizeof( DWORD );
445 		err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
446 		require_noerr( err, exit );
447 
448 		// See if it's there
449 
450 		if ( box.SelectString( -1, subKeyName ) == CB_ERR )
451 		{
452 			// If not, add it
453 
454 			box.AddString( subKeyName );
455 		}
456 
457 		box.SelectString( -1, subKeyName );
458 
459 		RegCloseKey( subKey );
460 		subKey = NULL;
461 	}
462 
463 exit:
464 
465 	m_advertiseServicesButton.SetCheck( ( !err && enabled ) ? BST_CHECKED : BST_UNCHECKED );
466 	m_regDomainsBox.EnableWindow( ( !err && enabled ) );
467 	m_sharedSecretButton.EnableWindow( (!err && enabled ) );
468 
469 	return err;
470 }
471 
472 
473 //---------------------------------------------------------------------------------------------------------------------------
474 //	CSecondPage::CreateKey
475 //---------------------------------------------------------------------------------------------------------------------------
476 
477 OSStatus
CreateKey(CString & name,DWORD enabled)478 CSecondPage::CreateKey( CString & name, DWORD enabled )
479 {
480 	HKEY		key = NULL;
481 	OSStatus	err;
482 
483 	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, (LPCTSTR) name, 0,
484 		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
485 	require_noerr( err, exit );
486 
487 	err = RegSetValueEx( key, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
488 	check_noerr( err );
489 
490 exit:
491 
492 	if ( key )
493 	{
494 		RegCloseKey( key );
495 	}
496 
497 	return err;
498 }
499 
500 
501 //---------------------------------------------------------------------------------------------------------------------------
502 //	CSecondPage::RegQueryString
503 //---------------------------------------------------------------------------------------------------------------------------
504 
505 OSStatus
RegQueryString(HKEY key,CString valueName,CString & value)506 CSecondPage::RegQueryString( HKEY key, CString valueName, CString & value )
507 {
508 	TCHAR	*	string;
509 	DWORD		stringLen;
510 	int			i;
511 	OSStatus	err;
512 
513 	stringLen	= 1024;
514 	string		= NULL;
515 	i			= 0;
516 
517 	do
518 	{
519 		if ( string )
520 		{
521 			free( string );
522 		}
523 
524 		string = (TCHAR*) malloc( stringLen );
525 		require_action( string, exit, err = kUnknownErr );
526 		*string = '\0';
527 
528 		err = RegQueryValueEx( key, valueName, 0, NULL, (LPBYTE) string, &stringLen );
529 
530 		i++;
531 	}
532 	while ( ( err == ERROR_MORE_DATA ) && ( i < 100 ) );
533 
534 	value = string;
535 
536 exit:
537 
538 	if ( string )
539 	{
540 		free( string );
541 	}
542 
543 	return err;
544 }
545