Revert "Imported Upstream version 1096.40.7"
[platform/upstream/mdnsresponder.git] / mDNSWindows / ControlPanel / ConfigPropertySheet.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
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
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
57 CConfigPropertySheet::~CConfigPropertySheet()
58 {
59         DeleteCriticalSection( &m_lock );
60 }
61
62
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
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
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
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
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
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
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_s(decodedDomainString, sizeof(decodedDomainString), nextLabel);
231         strcat_s(decodedDomainString, sizeof(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
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 }