• 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 "ConfigPropertySheet.h"
19 #include <WinServices.h>
20 extern "C"
21 {
22 #include <ClientCommon.h>
23 }
24 #include <process.h>
25 
26 // Custom events
27 
28 #define WM_DATAREADY		( WM_USER + 0x100 )
29 
30 
IMPLEMENT_DYNCREATE(CConfigPropertySheet,CPropertySheet)31 IMPLEMENT_DYNCREATE(CConfigPropertySheet, CPropertySheet)
32 
33 
34 //---------------------------------------------------------------------------------------------------------------------------
35 //	CConfigPropertySheet::CConfigPropertySheet
36 //---------------------------------------------------------------------------------------------------------------------------
37 
38 CConfigPropertySheet::CConfigPropertySheet()
39 :
40 	CPropertySheet(),
41 	m_browseDomainsRef( NULL ),
42 	m_thread( NULL ),
43 	m_threadExited( NULL )
44 {
45 	AddPage(&m_firstPage );
46 	AddPage(&m_secondPage);
47 	AddPage(&m_thirdPage);
48 
49 	InitializeCriticalSection( &m_lock );
50 }
51 
52 
53 //---------------------------------------------------------------------------------------------------------------------------
54 //	CConfigPropertySheet::~CConfigPropertySheet
55 //---------------------------------------------------------------------------------------------------------------------------
56 
~CConfigPropertySheet()57 CConfigPropertySheet::~CConfigPropertySheet()
58 {
59 	DeleteCriticalSection( &m_lock );
60 }
61 
62 
BEGIN_MESSAGE_MAP(CConfigPropertySheet,CPropertySheet)63 BEGIN_MESSAGE_MAP(CConfigPropertySheet, CPropertySheet)
64 	//{{AFX_MSG_MAP(CConfigPropertySheet)
65 	//}}AFX_MSG_MAP
66 	ON_MESSAGE( WM_DATAREADY, OnDataReady )
67 END_MESSAGE_MAP()
68 
69 
70 //---------------------------------------------------------------------------------------------------------------------------
71 //	CConfigPropertySheet::OnInitDialog
72 //---------------------------------------------------------------------------------------------------------------------------
73 
74 BOOL
75 CConfigPropertySheet::OnInitDialog()
76 {
77 	OSStatus err;
78 
79 	BOOL b = CPropertySheet::OnInitDialog();
80 
81 	err = SetupBrowsing();
82 	require_noerr( err, exit );
83 
84 exit:
85 
86 	return b;
87 }
88 
89 
90 //---------------------------------------------------------------------------------------------------------------------------
91 //	CConfigPropertySheet::OnCommand
92 //---------------------------------------------------------------------------------------------------------------------------
93 
94 BOOL
OnCommand(WPARAM wParam,LPARAM lParam)95 CConfigPropertySheet::OnCommand(WPARAM wParam, LPARAM lParam)
96 {
97    // Check if OK or Cancel was hit
98 
99    if ( ( wParam == ID_WIZFINISH ) || ( wParam == IDOK ) || ( wParam == IDCANCEL ) )
100    {
101       OnEndDialog();
102    }
103 
104    return CPropertySheet::OnCommand(wParam, lParam);
105 }
106 
107 
108 //---------------------------------------------------------------------------------------------------------------------------
109 //	CConfigPropertySheet::OnDataReady
110 //---------------------------------------------------------------------------------------------------------------------------
111 
112 LRESULT
OnDataReady(WPARAM inWParam,LPARAM inLParam)113 CConfigPropertySheet::OnDataReady(WPARAM inWParam, LPARAM inLParam)
114 {
115 	if (WSAGETSELECTERROR(inLParam) && !(HIWORD(inLParam)))
116 	{
117 		dlog( kDebugLevelError, "OnSocket: window error\n" );
118 	}
119 	else
120 	{
121 		SOCKET sock = (SOCKET) inWParam;
122 
123 		if ( m_browseDomainsRef && DNSServiceRefSockFD( m_browseDomainsRef ) == (int) sock )
124 		{
125 			DNSServiceProcessResult( m_browseDomainsRef );
126 		}
127 	}
128 
129 	return 0;
130 }
131 
132 
133 //---------------------------------------------------------------------------------------------------------------------------
134 //	CConfigPropertySheet::OnEndDialog
135 //---------------------------------------------------------------------------------------------------------------------------
136 
137 void
OnEndDialog()138 CConfigPropertySheet::OnEndDialog()
139 {
140 	OSStatus err;
141 
142 	err = TearDownBrowsing();
143 	check_noerr( err );
144 }
145 
146 
147 //---------------------------------------------------------------------------------------------------------------------------
148 //	CConfigPropertySheet::SetupBrowsing
149 //---------------------------------------------------------------------------------------------------------------------------
150 
151 OSStatus
SetupBrowsing()152 CConfigPropertySheet::SetupBrowsing()
153 {
154 	OSStatus err;
155 
156 	// Start browsing for browse domains
157 
158 	err = DNSServiceEnumerateDomains( &m_browseDomainsRef, kDNSServiceFlagsBrowseDomains, 0, BrowseDomainsReply, this );
159 	require_noerr( err, exit );
160 
161 	err = WSAAsyncSelect( DNSServiceRefSockFD( m_browseDomainsRef ), m_hWnd, WM_DATAREADY, FD_READ|FD_CLOSE );
162 	require_noerr( err, exit );
163 
164 exit:
165 
166 	if ( err )
167 	{
168 		TearDownBrowsing();
169 	}
170 
171 	return err;
172 }
173 
174 
175 //---------------------------------------------------------------------------------------------------------------------------
176 //	CConfigPropertySheet::TearDownBrowsing
177 //---------------------------------------------------------------------------------------------------------------------------
178 
179 OSStatus
TearDownBrowsing()180 CConfigPropertySheet::TearDownBrowsing()
181 {
182 	OSStatus err = kNoErr;
183 
184 	if ( m_browseDomainsRef )
185 	{
186 		err = WSAAsyncSelect( DNSServiceRefSockFD( m_browseDomainsRef ), m_hWnd, 0, 0 );
187 		check_noerr( err );
188 
189 		DNSServiceRefDeallocate( m_browseDomainsRef );
190 
191 		m_browseDomainsRef = NULL;
192 	}
193 
194 	return err;
195 }
196 
197 
198 //---------------------------------------------------------------------------------------------------------------------------
199 //	CConfigPropertySheet::DecodeDomainName
200 //---------------------------------------------------------------------------------------------------------------------------
201 
202 OSStatus
DecodeDomainName(const char * raw,CString & decoded)203 CConfigPropertySheet::DecodeDomainName( const char * raw, CString & decoded )
204 {
205 	char nextLabel[128] = "\0";
206 	char decodedDomainString[kDNSServiceMaxDomainName];
207     char * buffer = (char *) raw;
208     int labels = 0, i;
209     char text[64];
210 	const char *label[128];
211 	OSStatus	err;
212 
213 	// Initialize
214 
215 	decodedDomainString[0] = '\0';
216 
217     // Count the labels
218 
219 	while ( *buffer )
220 	{
221 		label[labels++] = buffer;
222 		buffer = (char *) GetNextLabel(buffer, text);
223     }
224 
225     buffer = (char*) raw;
226 
227     for (i = 0; i < labels; i++)
228 	{
229 		buffer = (char *)GetNextLabel(buffer, nextLabel);
230         strcat(decodedDomainString, nextLabel);
231         strcat(decodedDomainString, ".");
232     }
233 
234     // Remove trailing dot from domain name.
235 
236 	decodedDomainString[ strlen( decodedDomainString ) - 1 ] = '\0';
237 
238 	// Convert to Unicode
239 
240 	err = UTF8StringToStringObject( decodedDomainString, decoded );
241 
242 	return err;
243 }
244 
245 
246 //---------------------------------------------------------------------------------------------------------------------------
247 //	CConfigPropertySheet::BrowseDomainsReply
248 //---------------------------------------------------------------------------------------------------------------------------
249 
250 void DNSSD_API
BrowseDomainsReply(DNSServiceRef sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceErrorType errorCode,const char * replyDomain,void * context)251 CConfigPropertySheet::BrowseDomainsReply
252 							(
253 							DNSServiceRef			sdRef,
254 							DNSServiceFlags			flags,
255 							uint32_t				interfaceIndex,
256 							DNSServiceErrorType		errorCode,
257 							const char			*	replyDomain,
258 							void				*	context
259 							)
260 {
261 	CConfigPropertySheet	*	self = reinterpret_cast<CConfigPropertySheet*>(context);
262 	CString						decoded;
263 	OSStatus					err;
264 
265 	DEBUG_UNUSED( sdRef );
266 	DEBUG_UNUSED( interfaceIndex );
267 
268 	if ( errorCode )
269 	{
270 		goto exit;
271 	}
272 
273 	check( replyDomain );
274 
275 	// Ignore local domains
276 
277 	if ( strcmp( replyDomain, "local." ) == 0 )
278 	{
279 		goto exit;
280 	}
281 
282 	err = self->DecodeDomainName( replyDomain, decoded );
283 	require_noerr( err, exit );
284 
285 	// Remove trailing '.'
286 
287 	decoded.TrimRight( '.' );
288 
289 	if ( flags & kDNSServiceFlagsAdd )
290 	{
291 		self->m_browseDomains.push_back( decoded );
292 	}
293 	else
294 	{
295 		self->m_browseDomains.remove( decoded );
296 	}
297 
298 exit:
299 
300 	return;
301 }
302