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 "BrowsingPage.h"
19#include "resource.h"
20
21#include "ConfigPropertySheet.h"
22
23#include <WinServices.h>
24
25#define MAX_KEY_LENGTH 255
26
27
28IMPLEMENT_DYNCREATE(CBrowsingPage, CPropertyPage)
29
30
31//---------------------------------------------------------------------------------------------------------------------------
32//	CBrowsingPage::CBrowsingPage
33//---------------------------------------------------------------------------------------------------------------------------
34
35CBrowsingPage::CBrowsingPage()
36:
37	CPropertyPage(CBrowsingPage::IDD)
38{
39	//{{AFX_DATA_INIT(CBrowsingPage)
40	//}}AFX_DATA_INIT
41
42	m_firstTime = true;
43}
44
45
46//---------------------------------------------------------------------------------------------------------------------------
47//	CBrowsingPage::~CBrowsingPage
48//---------------------------------------------------------------------------------------------------------------------------
49
50CBrowsingPage::~CBrowsingPage()
51{
52}
53
54
55//---------------------------------------------------------------------------------------------------------------------------
56//	CBrowsingPage::DoDataExchange
57//---------------------------------------------------------------------------------------------------------------------------
58
59void CBrowsingPage::DoDataExchange(CDataExchange* pDX)
60{
61	CPropertyPage::DoDataExchange(pDX);
62	//{{AFX_DATA_MAP(CBrowsingPage)
63	//}}AFX_DATA_MAP
64	DDX_Control(pDX, IDC_BROWSE_LIST, m_browseListCtrl);
65	DDX_Control(pDX, IDC_REMOVE_BROWSE_DOMAIN, m_removeButton);
66}
67
68BEGIN_MESSAGE_MAP(CBrowsingPage, CPropertyPage)
69	//{{AFX_MSG_MAP(CBrowsingPage)
70	//}}AFX_MSG_MAP
71	ON_BN_CLICKED(IDC_ADD_BROWSE_DOMAIN, OnBnClickedAddBrowseDomain)
72	ON_BN_CLICKED(IDC_REMOVE_BROWSE_DOMAIN, OnBnClickedRemoveBrowseDomain)
73	ON_NOTIFY(LVN_ITEMCHANGED, IDC_BROWSE_LIST, OnLvnItemchangedBrowseList)
74END_MESSAGE_MAP()
75
76
77//---------------------------------------------------------------------------------------------------------------------------
78//	CBrowsingPage::SetModified
79//---------------------------------------------------------------------------------------------------------------------------
80
81void CBrowsingPage::SetModified( BOOL bChanged )
82{
83	m_modified = bChanged;
84
85	CPropertyPage::SetModified( bChanged );
86}
87
88
89//---------------------------------------------------------------------------------------------------------------------------
90//	CBrowsingPage::OnSetActive
91//---------------------------------------------------------------------------------------------------------------------------
92
93BOOL
94CBrowsingPage::OnSetActive()
95{
96	CConfigPropertySheet	*	psheet;
97	HKEY						key = NULL;
98	HKEY						subKey = NULL;
99	DWORD						dwSize;
100	DWORD						enabled;
101	DWORD						err;
102	TCHAR						subKeyName[MAX_KEY_LENGTH];
103	DWORD						cSubKeys = 0;
104	DWORD						cbMaxSubKey;
105	DWORD						cchMaxClass;
106	int							nIndex;
107    DWORD						i;
108	BOOL						b = CPropertyPage::OnSetActive();
109
110	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
111	require_quiet( psheet, exit );
112
113	m_modified = FALSE;
114
115	if ( m_firstTime )
116	{
117		m_browseListCtrl.SetExtendedStyle((m_browseListCtrl.GetStyle() & (~LVS_EX_GRIDLINES))|LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
118
119		m_browseListCtrl.InsertColumn(0, L"", LVCFMT_LEFT, 20 );
120		m_browseListCtrl.InsertColumn(1, L"", LVCFMT_LEFT, 345);
121
122		m_firstTime = false;
123	}
124
125	m_initialized = false;
126
127	// Clear out what's there
128
129	m_browseListCtrl.DeleteAllItems();
130
131	// Now populate the browse domain box
132
133	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSBrowseDomains, 0,
134		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &key, NULL );
135	require_noerr( err, exit );
136
137	// Get information about this node
138
139    err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
140	require_noerr( err, exit );
141
142	for ( i = 0; i < cSubKeys; i++)
143	{
144		dwSize = MAX_KEY_LENGTH;
145
146		err = RegEnumKeyEx( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
147		require_noerr( err, exit );
148
149		err = RegOpenKey( key, subKeyName, &subKey );
150		require_noerr( err, exit );
151
152		dwSize = sizeof( DWORD );
153		err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
154		require_noerr( err, exit );
155
156		nIndex = m_browseListCtrl.InsertItem( m_browseListCtrl.GetItemCount(), L"");
157		m_browseListCtrl.SetItemText( nIndex, 1, subKeyName );
158		m_browseListCtrl.SetCheck( nIndex, enabled );
159
160		RegCloseKey( subKey );
161		subKey = NULL;
162    }
163
164	m_browseListCtrl.SortItems( SortFunc, (DWORD_PTR) this );
165
166	m_removeButton.EnableWindow( FALSE );
167
168exit:
169
170	if ( subKey )
171	{
172		RegCloseKey( subKey );
173	}
174
175	if ( key )
176	{
177		RegCloseKey( key );
178	}
179
180	m_initialized = true;
181
182	return b;
183}
184
185
186
187//---------------------------------------------------------------------------------------------------------------------------
188//	CBrowsingPage::OnOK
189//---------------------------------------------------------------------------------------------------------------------------
190
191void
192CBrowsingPage::OnOK()
193{
194	if ( m_modified )
195	{
196		Commit();
197	}
198}
199
200
201
202//---------------------------------------------------------------------------------------------------------------------------
203//	CBrowsingPage::Commit
204//---------------------------------------------------------------------------------------------------------------------------
205
206void
207CBrowsingPage::Commit()
208{
209	HKEY		key		= NULL;
210	HKEY		subKey	= NULL;
211	TCHAR		subKeyName[MAX_KEY_LENGTH];
212	DWORD		cSubKeys = 0;
213	DWORD		cbMaxSubKey;
214	DWORD		cchMaxClass;
215	DWORD		dwSize;
216	int			i;
217	DWORD		err;
218
219	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSBrowseDomains, 0,
220	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &key, NULL );
221	require_noerr( err, exit );
222
223	// First, remove all the entries that are there
224
225    err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );
226	require_noerr( err, exit );
227
228	for ( i = 0; i < (int) cSubKeys; i++ )
229	{
230		dwSize = MAX_KEY_LENGTH;
231
232		err = RegEnumKeyEx( key, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
233		require_noerr( err, exit );
234
235		err = RegDeleteKey( key, subKeyName );
236		require_noerr( err, exit );
237	}
238
239	// Now re-populate
240
241	for ( i = 0; i < m_browseListCtrl.GetItemCount(); i++ )
242	{
243		DWORD enabled = (DWORD) m_browseListCtrl.GetCheck( i );
244
245		err = RegCreateKeyEx( key, m_browseListCtrl.GetItemText( i, 1 ), 0,
246		                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, NULL, &subKey, NULL );
247		require_noerr( err, exit );
248
249		err = RegSetValueEx( subKey, L"Enabled", NULL, REG_DWORD, (LPBYTE) &enabled, sizeof( enabled ) );
250		require_noerr( err, exit );
251
252		RegCloseKey( subKey );
253		subKey = NULL;
254	}
255
256exit:
257
258	if ( subKey )
259	{
260		RegCloseKey( subKey );
261	}
262
263	if ( key )
264	{
265		RegCloseKey( key );
266	}
267}
268
269
270
271//---------------------------------------------------------------------------------------------------------------------------
272//	CBrowsingPage::OnBnClickedAddBrowseDomain
273//---------------------------------------------------------------------------------------------------------------------------
274
275void
276CBrowsingPage::OnBnClickedAddBrowseDomain()
277{
278	CAddBrowseDomain dlg( GetParent() );
279
280	if ( ( dlg.DoModal() == IDOK ) && ( dlg.m_text.GetLength() > 0 ) )
281	{
282		int nIndex;
283
284		nIndex = m_browseListCtrl.InsertItem( m_browseListCtrl.GetItemCount(), L"");
285		m_browseListCtrl.SetItemText( nIndex, 1, dlg.m_text );
286		m_browseListCtrl.SetCheck( nIndex, 1 );
287
288		m_browseListCtrl.SortItems( SortFunc, (DWORD_PTR) this );
289
290		m_browseListCtrl.Invalidate();
291
292		SetModified( TRUE );
293	}
294}
295
296
297//---------------------------------------------------------------------------------------------------------------------------
298//	CBrowsingPage::OnBnClickedRemoveBrowseDomain
299//---------------------------------------------------------------------------------------------------------------------------
300
301void
302CBrowsingPage::OnBnClickedRemoveBrowseDomain()
303{
304	UINT	selectedCount = m_browseListCtrl.GetSelectedCount();
305	int		nItem = -1;
306	UINT	i;
307
308	// Update all of the selected items.
309
310	for ( i = 0; i < selectedCount; i++ )
311	{
312		nItem = m_browseListCtrl.GetNextItem( -1, LVNI_SELECTED );
313		check( nItem != -1 );
314
315		m_browseListCtrl.DeleteItem( nItem );
316
317		SetModified( TRUE );
318	}
319
320	m_removeButton.EnableWindow( FALSE );
321}
322
323
324void
325CBrowsingPage::OnLvnItemchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
326{
327	if ( m_browseListCtrl.GetSelectedCount() )
328	{
329		m_removeButton.EnableWindow( TRUE );
330	}
331
332	if ( m_initialized )
333	{
334		NM_LISTVIEW * pNMListView = (NM_LISTVIEW*)pNMHDR;
335
336		BOOL bPrevState = (BOOL) ( ( ( pNMListView->uOldState & LVIS_STATEIMAGEMASK ) >> 12 ) - 1 );
337
338		if ( bPrevState < 0 )
339		{
340			bPrevState = 0;
341		}
342
343
344		BOOL bChecked = ( BOOL ) ( ( ( pNMListView->uNewState & LVIS_STATEIMAGEMASK ) >> 12) - 1 );
345
346		if ( bChecked < 0 )
347		{
348			bChecked = 0;
349		}
350
351		if ( bPrevState != bChecked )
352		{
353			SetModified( TRUE );
354		}
355	}
356
357	*pResult = 0;
358}
359
360
361
362int CALLBACK
363CBrowsingPage::SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
364{
365	CString str1;
366	CString	str2;
367	int		ret = 0;
368
369	CBrowsingPage * self = reinterpret_cast<CBrowsingPage*>( lParamSort );
370	require_quiet( self, exit );
371
372	str1 = self->m_browseListCtrl.GetItemText( (int) lParam1, 1 );
373	str2 = self->m_browseListCtrl.GetItemText( (int) lParam2, 1 );
374
375	ret = str1.Compare( str2 );
376
377exit:
378
379	return ret;
380}
381
382
383// CAddBrowseDomain dialog
384
385IMPLEMENT_DYNAMIC(CAddBrowseDomain, CDialog)
386CAddBrowseDomain::CAddBrowseDomain(CWnd* pParent /*=NULL*/)
387	: CDialog(CAddBrowseDomain::IDD, pParent)
388{
389}
390
391CAddBrowseDomain::~CAddBrowseDomain()
392{
393}
394
395void CAddBrowseDomain::DoDataExchange(CDataExchange* pDX)
396{
397	CDialog::DoDataExchange(pDX);
398	DDX_Control(pDX, IDC_COMBO1, m_comboBox);
399}
400
401
402BOOL
403CAddBrowseDomain::OnInitDialog()
404{
405	CConfigPropertySheet	*	psheet;
406	CConfigPropertySheet::StringList::iterator		it;
407
408	BOOL b = CDialog::OnInitDialog();
409
410	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
411	require_quiet( psheet, exit );
412
413	for ( it = psheet->m_browseDomains.begin(); it != psheet->m_browseDomains.end(); it++ )
414	{
415		CString text = *it;
416
417		if ( m_comboBox.FindStringExact( -1, *it ) == CB_ERR )
418		{
419			m_comboBox.AddString( *it );
420		}
421	}
422
423exit:
424
425	return b;
426}
427
428
429void
430CAddBrowseDomain::OnOK()
431{
432	m_comboBox.GetWindowText( m_text );
433
434	CDialog::OnOK();
435}
436
437
438
439BEGIN_MESSAGE_MAP(CAddBrowseDomain, CDialog)
440END_MESSAGE_MAP()
441
442