Home | History | Annotate | Download | only in ControlPanel
      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