]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/ControlPanel/SecondPage.cpp
mDNSResponder-108.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / ControlPanel / SecondPage.cpp
1 /*
2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22
23 Change History (most recent first):
24
25 $Log: SecondPage.cpp,v $
26 Revision 1.6 2005/10/05 20:46:50 herscher
27 <rdar://problem/4192011> Move Wide-Area preferences to another part of the registry so they don't removed during an update-install.
28
29 Revision 1.5 2005/04/05 04:15:46 shersche
30 RegQueryString was returning uninitialized strings if the registry key couldn't be found, so always initialize strings before checking the registry key.
31
32 Revision 1.4 2005/04/05 03:52:14 shersche
33 <rdar://problem/4066485> Registering with shared secret key doesn't work. Additionally, mDNSResponder wasn't dynamically re-reading it's DynDNS setup after setting a shared secret key.
34
35 Revision 1.3 2005/03/03 19:55:22 shersche
36 <rdar://problem/4034481> ControlPanel source code isn't saving CVS log info
37
38
39 */
40
41 #include "SecondPage.h"
42 #include "resource.h"
43
44 #include "ConfigPropertySheet.h"
45 #include "SharedSecret.h"
46
47 #include <WinServices.h>
48
49 IMPLEMENT_DYNCREATE(CSecondPage, CPropertyPage)
50
51
52 //---------------------------------------------------------------------------------------------------------------------------
53 // CSecondPage::CSecondPage
54 //---------------------------------------------------------------------------------------------------------------------------
55
56 CSecondPage::CSecondPage()
57 :
58 CPropertyPage(CSecondPage::IDD),
59 m_setupKey( NULL )
60 {
61 //{{AFX_DATA_INIT(CSecondPage)
62 //}}AFX_DATA_INIT
63
64 OSStatus err;
65
66 err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, &m_setupKey );
67 check_noerr( err );
68 }
69
70
71 //---------------------------------------------------------------------------------------------------------------------------
72 // CSecondPage::~CSecondPage
73 //---------------------------------------------------------------------------------------------------------------------------
74
75 CSecondPage::~CSecondPage()
76 {
77 if ( m_setupKey )
78 {
79 RegCloseKey( m_setupKey );
80 m_setupKey = NULL;
81 }
82 }
83
84
85 //---------------------------------------------------------------------------------------------------------------------------
86 // CSecondPage::DoDataExchange
87 //---------------------------------------------------------------------------------------------------------------------------
88
89 void CSecondPage::DoDataExchange(CDataExchange* pDX)
90 {
91 CPropertyPage::DoDataExchange(pDX);
92 //{{AFX_DATA_MAP(CSecondPage)
93 //}}AFX_DATA_MAP
94 DDX_Control(pDX, IDC_CHECK1, m_advertiseServicesButton);
95 DDX_Control(pDX, IDC_BUTTON1, m_sharedSecretButton);
96 DDX_Control(pDX, IDC_COMBO2, m_regDomainsBox);
97 }
98
99 BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
100 //{{AFX_MSG_MAP(CSecondPage)
101 //}}AFX_MSG_MAP
102 ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedSharedSecret)
103 ON_BN_CLICKED(IDC_CHECK1, OnBnClickedAdvertise)
104 ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelChange)
105 ON_CBN_EDITCHANGE(IDC_COMBO1, OnCbnEditChange)
106 ON_CBN_EDITCHANGE(IDC_COMBO2, OnCbnEditChange)
107 ON_CBN_SELCHANGE(IDC_COMBO2, OnCbnSelChange)
108
109 END_MESSAGE_MAP()
110
111
112 //---------------------------------------------------------------------------------------------------------------------------
113 // CSecondPage::SetModified
114 //---------------------------------------------------------------------------------------------------------------------------
115
116 void CSecondPage::SetModified( BOOL bChanged )
117 {
118 m_modified = bChanged;
119
120 CPropertyPage::SetModified( bChanged );
121 }
122
123
124 //---------------------------------------------------------------------------------------------------------------------------
125 // CSecondPage::OnSetActive
126 //---------------------------------------------------------------------------------------------------------------------------
127
128 BOOL
129 CSecondPage::OnSetActive()
130 {
131 CConfigPropertySheet * psheet;
132 DWORD dwSize;
133 DWORD enabled;
134 DWORD err;
135 BOOL b = CPropertyPage::OnSetActive();
136
137 psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
138 require_quiet( psheet, exit );
139
140 m_modified = FALSE;
141
142 // Clear out what's there
143
144 EmptyComboBox( m_regDomainsBox );
145
146 // Now populate the registration domain box
147
148 err = Populate( m_regDomainsBox, m_setupKey, psheet->m_regDomains );
149 check_noerr( err );
150
151 dwSize = sizeof( DWORD );
152 err = RegQueryValueEx( m_setupKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
153 m_advertiseServicesButton.SetCheck( ( !err && enabled ) ? BST_CHECKED : BST_UNCHECKED );
154 m_regDomainsBox.EnableWindow( ( !err && enabled ) );
155 m_sharedSecretButton.EnableWindow( (!err && enabled ) );
156
157 exit:
158
159 return b;
160 }
161
162
163 //---------------------------------------------------------------------------------------------------------------------------
164 // CSecondPage::OnOK
165 //---------------------------------------------------------------------------------------------------------------------------
166
167 void
168 CSecondPage::OnOK()
169 {
170 if ( m_modified )
171 {
172 Commit();
173 }
174 }
175
176
177
178 //---------------------------------------------------------------------------------------------------------------------------
179 // CSecondPage::Commit
180 //---------------------------------------------------------------------------------------------------------------------------
181
182 void
183 CSecondPage::Commit()
184 {
185 DWORD err;
186
187 if ( m_setupKey != NULL )
188 {
189 err = Commit( m_regDomainsBox, m_setupKey, m_advertiseServicesButton.GetCheck() == BST_CHECKED );
190 check_noerr( err );
191 }
192 }
193
194
195 //---------------------------------------------------------------------------------------------------------------------------
196 // CSecondPage::Commit
197 //---------------------------------------------------------------------------------------------------------------------------
198
199 OSStatus
200 CSecondPage::Commit( CComboBox & box, HKEY key, DWORD enabled )
201 {
202 CString selected;
203 OSStatus err = kNoErr;
204
205 // Get selected text
206
207 box.GetWindowText( selected );
208
209 // If we haven't seen this string before, add the string to the box and
210 // the registry
211
212 if ( ( selected.GetLength() > 0 ) && ( box.FindStringExact( -1, selected ) == CB_ERR ) )
213 {
214 CString string;
215
216 box.AddString( selected );
217
218 err = RegQueryString( key, L"UserDefined", string );
219 check_noerr( err );
220
221 if ( string.GetLength() )
222 {
223 string += L"," + selected;
224 }
225 else
226 {
227 string = selected;
228 }
229
230 err = RegSetValueEx( key, L"UserDefined", 0, REG_SZ, (LPBYTE) (LPCTSTR) string, ( string.GetLength() + 1) * sizeof( TCHAR ) );
231 check_noerr ( err );
232 }
233
234 // Save selected text in registry. This will trigger mDNSResponder to setup
235 // DynDNS config again
236
237 err = RegSetValueEx( key, L"", 0, REG_SZ, (LPBYTE) (LPCTSTR) selected, ( selected.GetLength() + 1 ) * sizeof( TCHAR ) );
238 check_noerr( err );
239
240 err = RegSetValueEx( key, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
241 check_noerr( err );
242
243 return err;
244 }
245
246
247 //---------------------------------------------------------------------------------------------------------------------------
248 // CSecondPage::OnBnClickedSharedSecret
249 //---------------------------------------------------------------------------------------------------------------------------
250
251 void CSecondPage::OnBnClickedSharedSecret()
252 {
253 CString name;
254
255 m_regDomainsBox.GetWindowText( name );
256
257 CSharedSecret dlg;
258
259 dlg.m_key = name;
260
261 if ( dlg.DoModal() == IDOK )
262 {
263 DWORD wakeup = 0;
264 DWORD dwSize = sizeof( DWORD );
265 OSStatus err;
266
267 dlg.Commit( name );
268
269 // We have now updated the secret, however the system service
270 // doesn't know about it yet. So we're going to update the
271 // registry with a dummy value which will cause the system
272 // service to re-initialize it's DynDNS setup
273 //
274
275 RegQueryValueEx( m_setupKey, L"Wakeup", NULL, NULL, (LPBYTE) &wakeup, &dwSize );
276
277 wakeup++;
278
279 err = RegSetValueEx( m_setupKey, L"Wakeup", 0, REG_DWORD, (LPBYTE) &wakeup, sizeof( DWORD ) );
280 require_noerr( err, exit );
281 }
282
283 exit:
284
285 return;
286 }
287
288
289 //---------------------------------------------------------------------------------------------------------------------------
290 // CSecondPage::OnBnClickedAdvertise
291 //---------------------------------------------------------------------------------------------------------------------------
292
293 void CSecondPage::OnBnClickedAdvertise()
294 {
295 int state;
296
297 state = m_advertiseServicesButton.GetCheck();
298
299 m_regDomainsBox.EnableWindow( state );
300 m_sharedSecretButton.EnableWindow( state );
301
302 SetModified( TRUE );
303 }
304
305
306 //---------------------------------------------------------------------------------------------------------------------------
307 // CSecondPage::OnCbnSelChange
308 //---------------------------------------------------------------------------------------------------------------------------
309
310 void CSecondPage::OnCbnSelChange()
311 {
312 SetModified( TRUE );
313 }
314
315
316 //---------------------------------------------------------------------------------------------------------------------------
317 // CSecondPage::OnCbnEditChange
318 //---------------------------------------------------------------------------------------------------------------------------
319
320 void CSecondPage::OnCbnEditChange()
321 {
322 SetModified( TRUE );
323 }
324
325
326
327 //---------------------------------------------------------------------------------------------------------------------------
328 // CSecondPage::OnAddRegistrationDomain
329 //---------------------------------------------------------------------------------------------------------------------------
330
331 void
332 CSecondPage::OnAddRegistrationDomain( CString & domain )
333 {
334 int index = m_regDomainsBox.FindStringExact( -1, domain );
335
336 if ( index == CB_ERR )
337 {
338 m_regDomainsBox.AddString( domain );
339 }
340 }
341
342
343 //---------------------------------------------------------------------------------------------------------------------------
344 // CSecondPage::OnRemoveRegistrationDomain
345 //---------------------------------------------------------------------------------------------------------------------------
346
347 void
348 CSecondPage::OnRemoveRegistrationDomain( CString & domain )
349 {
350 int index = m_regDomainsBox.FindStringExact( -1, domain );
351
352 if ( index != CB_ERR )
353 {
354 m_regDomainsBox.DeleteString( index );
355 }
356 }
357
358
359 //---------------------------------------------------------------------------------------------------------------------------
360 // CSecondPage::EmptyComboBox
361 //---------------------------------------------------------------------------------------------------------------------------
362
363 void
364 CSecondPage::EmptyComboBox( CComboBox & box )
365 {
366 while ( box.GetCount() > 0 )
367 {
368 box.DeleteString( 0 );
369 }
370 }
371
372
373 //---------------------------------------------------------------------------------------------------------------------------
374 // CSecondPage::Populate
375 //---------------------------------------------------------------------------------------------------------------------------
376
377 OSStatus
378 CSecondPage::Populate( CComboBox & box, HKEY key, StringList & l )
379 {
380 TCHAR rawString[kDNSServiceMaxDomainName + 1];
381 DWORD rawStringLen;
382 CString string;
383 OSStatus err;
384
385 err = RegQueryString( key, L"UserDefined", string );
386
387 if ( !err && string.GetLength() )
388 {
389 bool done = false;
390
391 while ( !done )
392 {
393 CString tok;
394
395 tok = string.SpanExcluding( L"," );
396
397 box.AddString( tok );
398
399 if ( tok != string )
400 {
401 // Get rid of that string and comma
402
403 string = string.Right( string.GetLength() - tok.GetLength() - 1 );
404 }
405 else
406 {
407 done = true;
408 }
409 }
410 }
411
412 StringList::iterator it;
413
414 for ( it = l.begin(); it != l.end(); it++ )
415 {
416 if ( box.FindStringExact( -1, *it ) == CB_ERR )
417 {
418 box.AddString( *it );
419 }
420 }
421
422 // Now look to see if there is a selected string, and if so,
423 // select it
424
425 rawString[0] = '\0';
426
427 rawStringLen = sizeof( rawString );
428
429 err = RegQueryValueEx( key, L"", 0, NULL, (LPBYTE) rawString, &rawStringLen );
430
431 string = rawString;
432
433 if ( !err && ( string.GetLength() != 0 ) )
434 {
435 // See if it's there
436
437 if ( box.SelectString( -1, string ) == CB_ERR )
438 {
439 // If not, add it
440
441 box.AddString( string );
442 }
443
444 box.SelectString( -1, string );
445 }
446
447 return err;
448 }
449
450
451 //---------------------------------------------------------------------------------------------------------------------------
452 // CSecondPage::CreateKey
453 //---------------------------------------------------------------------------------------------------------------------------
454
455 OSStatus
456 CSecondPage::CreateKey( CString & name, DWORD enabled )
457 {
458 HKEY key = NULL;
459 OSStatus err;
460
461 err = RegCreateKey( HKEY_LOCAL_MACHINE, (LPCTSTR) name, &key );
462 require_noerr( err, exit );
463
464 err = RegSetValueEx( key, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
465 check_noerr( err );
466
467 exit:
468
469 if ( key )
470 {
471 RegCloseKey( key );
472 }
473
474 return err;
475 }
476
477
478 //---------------------------------------------------------------------------------------------------------------------------
479 // CSecondPage::RegQueryString
480 //---------------------------------------------------------------------------------------------------------------------------
481
482 OSStatus
483 CSecondPage::RegQueryString( HKEY key, CString valueName, CString & value )
484 {
485 TCHAR * string;
486 DWORD stringLen;
487 int i;
488 OSStatus err;
489
490 stringLen = 1024;
491 string = NULL;
492 i = 0;
493
494 do
495 {
496 if ( string )
497 {
498 free( string );
499 }
500
501 string = (TCHAR*) malloc( stringLen );
502 require_action( string, exit, err = kUnknownErr );
503 *string = '\0';
504
505 err = RegQueryValueEx( key, valueName, 0, NULL, (LPBYTE) string, &stringLen );
506
507 i++;
508 }
509 while ( ( err == ERROR_MORE_DATA ) && ( i < 100 ) );
510
511 value = string;
512
513 exit:
514
515 if ( string )
516 {
517 free( string );
518 }
519
520 return err;
521 }