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(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 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