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