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