]> git.saurik.com Git - apple/mdnsresponder.git/blobdiff - mDNSWindows/Applications/ExplorerPlugin/ExplorerBarWindow.cpp
mDNSResponder-87.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / Applications / ExplorerPlugin / ExplorerBarWindow.cpp
diff --git a/mDNSWindows/Applications/ExplorerPlugin/ExplorerBarWindow.cpp b/mDNSWindows/Applications/ExplorerPlugin/ExplorerBarWindow.cpp
deleted file mode 100644 (file)
index 7ca9f2a..0000000
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
-
-    Change History (most recent first):
-    
-$Log: ExplorerBarWindow.cpp,v $
-Revision 1.5  2004/04/15 01:00:05  bradley
-Removed support for automatically querying for A/AAAA records when resolving names. Platforms
-without .local name resolving support will need to manually query for A/AAAA records as needed.
-
-Revision 1.4  2004/04/09 21:03:15  bradley
-Changed port numbers to use network byte order for consistency with other platforms.
-
-Revision 1.3  2004/04/08 09:43:43  bradley
-Changed callback calling conventions to __stdcall so they can be used with C# delegates.
-
-Revision 1.2  2004/02/21 04:36:19  bradley
-Enable dot local name lookups now that the NSP is being installed.
-
-Revision 1.1  2004/01/30 03:01:56  bradley
-Explorer Plugin to browse for Rendezvous-enabled Web and FTP servers from within Internet Explorer.
-
-*/
-
-#include       "StdAfx.h"
-
-#include       "CommonServices.h"
-#include       "DebugServices.h"
-#include       "DNSSD.h"
-
-#include       "ExplorerBar.h"
-#include       "LoginDialog.h"
-#include       "Resource.h"
-
-#include       "ExplorerBarWindow.h"
-
-// MFC Debugging
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-#if 0
-#pragma mark == Constants ==
-#endif
-
-//===========================================================================================================================
-//     Constants
-//===========================================================================================================================
-
-// Control IDs
-
-#define        IDC_EXPLORER_TREE                               1234
-
-// Private Messages
-
-#define        WM_PRIVATE_SERVICE_ADD                  ( WM_USER + 0x100 )
-#define        WM_PRIVATE_SERVICE_REMOVE               ( WM_USER + 0x101 )
-#define        WM_PRIVATE_RESOLVE                              ( WM_USER + 0x102 )
-
-// TXT records
-
-#define        kTXTRecordKeyPath                               "path="
-#define        kTXTRecordKeyPathSize                   sizeof_string( kTXTRecordKeyPath )
-
-#if 0
-#pragma mark == Prototypes ==
-#endif
-
-//===========================================================================================================================
-//     Prototypes
-//===========================================================================================================================
-
-DEBUG_LOCAL int                        FindServiceArrayIndex( const ServiceInfoArray &inArray, const ServiceInfo &inService, int &outIndex );
-DEBUG_LOCAL OSStatus   UTF8StringToStringObject( const char *inUTF8, CString &inObject );
-
-#if 0
-#pragma mark == Message Map ==
-#endif
-
-//===========================================================================================================================
-//     Message Map
-//===========================================================================================================================
-
-BEGIN_MESSAGE_MAP( ExplorerBarWindow, CWnd )
-       ON_WM_CREATE()
-       ON_WM_DESTROY()
-       ON_WM_SIZE()
-       ON_NOTIFY( NM_DBLCLK, IDC_EXPLORER_TREE, OnDoubleClick )
-       ON_MESSAGE( WM_PRIVATE_SERVICE_ADD, OnServiceAdd )
-       ON_MESSAGE( WM_PRIVATE_SERVICE_REMOVE, OnServiceRemove )
-       ON_MESSAGE( WM_PRIVATE_RESOLVE, OnResolve )
-END_MESSAGE_MAP()
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-//     ExplorerBarWindow
-//===========================================================================================================================
-
-ExplorerBarWindow::ExplorerBarWindow( void )
-{
-       mOwner                          = NULL;
-       mResolveServiceRef      = NULL;
-}
-
-//===========================================================================================================================
-//     ~ExplorerBarWindow
-//===========================================================================================================================
-
-ExplorerBarWindow::~ExplorerBarWindow( void )
-{
-       //
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-//     OnCreate
-//===========================================================================================================================
-
-int    ExplorerBarWindow::OnCreate( LPCREATESTRUCT inCreateStruct )
-{
-       AFX_MANAGE_STATE( AfxGetStaticModuleState() );
-       
-       OSStatus                err;
-       CRect                   rect;
-       CString                 s;
-       
-       err = CWnd::OnCreate( inCreateStruct );
-       require_noerr( err, exit );
-       
-       GetClientRect( rect );
-       mTree.Create( WS_TABSTOP | WS_VISIBLE | WS_CHILD | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES, rect, this, 
-               IDC_EXPLORER_TREE );
-       
-       err = DNSServiceInitialize( kDNSServiceInitializeFlagsNone, 0 );
-       if( err != kNoErr )
-       {
-               // Cannot talk to the mDNSResponder service. Show the error message and exit (with kNoErr so they can see it).
-               
-               s.LoadString( IDS_RENDEZVOUS_NOT_AVAILABLE );
-               mTree.InsertItem( s, 0, 0, TVI_ROOT, TVI_LAST );
-               err = kNoErr;
-               goto exit;
-       }
-       
-       ServiceHandlerEntry *           e;
-       
-       // Web Site Handler
-       
-       e = new ServiceHandlerEntry;
-       check( e );
-       e->type                         = "_http._tcp";
-       e->urlScheme            = "http://";
-       e->ref                          = NULL;
-       e->treeItem                     = NULL;
-       e->treeFirst            = true;
-       e->obj                          = this;
-       e->needsLogin           = false;
-       mServiceHandlers.Add( e );
-       
-       s.LoadString( IDS_WEB_SITES );
-       e->treeItem = mTree.InsertItem( s, 0, 0 );
-       mTree.Expand( e->treeItem, TVE_EXPAND );
-       
-       err = DNSServiceBrowse( &e->ref, 0, 0, e->type, NULL, BrowseCallBack, e );
-       require_noerr( err, exit );
-
-       // FTP Site Handler
-       
-       e = new ServiceHandlerEntry;
-       check( e );
-       e->type                         = "_ftp._tcp";
-       e->urlScheme            = "ftp://";
-       e->ref                          = NULL;
-       e->treeItem                     = NULL;
-       e->treeFirst            = true;
-       e->obj                          = this;
-       e->needsLogin           = true;
-       mServiceHandlers.Add( e );
-       
-       s.LoadString( IDS_FTP_SITES );
-       e->treeItem = mTree.InsertItem( s, 0, 0 );
-       mTree.Expand( e->treeItem, TVE_EXPAND );
-       
-       err = DNSServiceBrowse( &e->ref, 0, 0, e->type, NULL, BrowseCallBack, e );
-       require_noerr( err, exit );
-       
-exit:
-       return( err );
-}
-
-//===========================================================================================================================
-//     OnDestroy
-//===========================================================================================================================
-
-void   ExplorerBarWindow::OnDestroy( void ) 
-{
-       // Stop any resolves that may still be pending (shouldn't be any).
-       
-       StopResolve();
-       
-       // Clean up the service handlers.
-       
-       int             i;
-       int             n;
-       
-       n = (int) mServiceHandlers.GetSize();
-       for( i = 0; i < n; ++i )
-       {
-               delete mServiceHandlers[ i ];
-       }
-       
-       DNSServiceFinalize();
-       CWnd::OnDestroy();
-}
-
-//===========================================================================================================================
-//     OnSize
-//===========================================================================================================================
-
-void   ExplorerBarWindow::OnSize( UINT inType, int inX, int inY ) 
-{
-       CWnd::OnSize( inType, inX, inY );
-       mTree.MoveWindow( 0, 0, inX, inY );
-}
-
-//===========================================================================================================================
-//     OnDoubleClick
-//===========================================================================================================================
-
-void   ExplorerBarWindow::OnDoubleClick( NMHDR *inNMHDR, LRESULT *outResult )
-{
-       HTREEITEM                       item;
-       ServiceInfo *           service;
-       OSStatus                        err;
-       
-       DEBUG_UNUSED( inNMHDR );
-       
-       item = mTree.GetSelectedItem();
-       require( item, exit );
-       
-       service = reinterpret_cast < ServiceInfo * > ( mTree.GetItemData( item ) );
-       require_quiet( service, exit );
-       
-       err = StartResolve( service );
-       require_noerr( err, exit );
-
-exit:
-       *outResult = 0;
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-//     BrowseCallBack
-//===========================================================================================================================
-
-void CALLBACK_COMPAT
-       ExplorerBarWindow::BrowseCallBack(
-               DNSServiceRef                   inRef,
-               DNSServiceFlags                 inFlags,
-               uint32_t                                inInterfaceIndex,
-               DNSServiceErrorType     inErrorCode,
-               const char *                    inName, 
-               const char *                    inType, 
-               const char *                    inDomain,       
-               void *                                  inContext )
-{
-       ServiceHandlerEntry *           obj;
-       ServiceInfo *                           service;
-       OSStatus                                        err;
-       
-       DEBUG_UNUSED( inRef );
-       
-       service = NULL;
-       
-       require_noerr( inErrorCode, exit );
-       obj = reinterpret_cast < ServiceHandlerEntry * > ( inContext );
-       check( obj );
-       check( obj->obj );
-       
-       try
-       {
-               // Post a message to the main thread so it can handle it since MFC is not thread safe.
-               
-               service = new ServiceInfo;
-               require_action( service, exit, err = kNoMemoryErr );
-               
-               err = UTF8StringToStringObject( inName, service->displayName );
-               check_noerr( err );
-               
-               service->name = strdup( inName );
-               require_action( service->name, exit, err = kNoMemoryErr );
-               
-               service->type = strdup( inType );
-               require_action( service->type, exit, err = kNoMemoryErr );
-               
-               service->domain = strdup( inDomain );
-               require_action( service->domain, exit, err = kNoMemoryErr );
-               
-               service->ifi            = inInterfaceIndex;
-               service->handler        = obj;
-               
-               DWORD           message;
-               BOOL            ok;
-               
-               message = ( inFlags & kDNSServiceFlagsAdd ) ? WM_PRIVATE_SERVICE_ADD : WM_PRIVATE_SERVICE_REMOVE;
-               ok = ::PostMessage( obj->obj->GetSafeHwnd(), message, 0, (LPARAM) service );
-               check( ok );
-               if( ok )
-               {
-                       service = NULL;
-               }
-       }
-       catch( ... )
-       {
-               dlog( kDebugLevelError, "BrowseCallBack: exception thrown\n" );
-       }
-       
-exit:
-       if( service )
-       {
-               delete service;
-       }
-}
-
-//===========================================================================================================================
-//     OnServiceAdd
-//===========================================================================================================================
-
-LONG   ExplorerBarWindow::OnServiceAdd( WPARAM inWParam, LPARAM inLParam )
-{
-       ServiceInfo *                           service;
-       ServiceHandlerEntry *           handler;
-       int                                                     cmp;
-       int                                                     index;
-       
-       DEBUG_UNUSED( inWParam );
-       
-       service = reinterpret_cast < ServiceInfo * > ( inLParam );
-       check( service );
-       handler = service->handler; 
-       check( handler );
-       
-       cmp = FindServiceArrayIndex( handler->array, *service, index );
-       if( cmp == 0 )
-       {
-               // Found a match so update the item. The index is index + 1 so subtract 1.
-               
-               index -= 1;
-               check( index < handler->array.GetSize() );
-               
-               service->item = handler->array[ index ]->item;
-               delete handler->array[ index ];
-               handler->array[ index ] = service;
-               mTree.SetItemText( service->item, service->displayName );
-               mTree.SetItemData( service->item, (DWORD_PTR) service );
-       }
-       else
-       {
-               HTREEITEM               afterItem;
-               
-               // Insert the new item in sorted order.
-               
-               afterItem = ( index > 0 ) ? handler->array[ index - 1 ]->item : TVI_FIRST;
-               handler->array.InsertAt( index, service );
-               service->item = mTree.InsertItem( service->displayName, handler->treeItem, afterItem );
-               mTree.SetItemData( service->item, (DWORD_PTR) service );
-               
-               // Make sure the item is visible if this is the first time a service was added.
-       
-               if( handler->treeFirst )
-               {
-                       handler->treeFirst = false;
-                       mTree.EnsureVisible( service->item );
-               }
-       }
-       return( 0 );
-}
-
-//===========================================================================================================================
-//     OnServiceRemove
-//===========================================================================================================================
-
-LONG   ExplorerBarWindow::OnServiceRemove( WPARAM inWParam, LPARAM inLParam )
-{
-       ServiceInfo *                           service;
-       ServiceHandlerEntry *           handler;
-       int                                                     cmp;
-       int                                                     index;
-       
-       DEBUG_UNUSED( inWParam );
-       
-       service = reinterpret_cast < ServiceInfo * > ( inLParam );
-       check( service );
-       handler = service->handler; 
-       check( handler );
-       
-       // Search to see if we know about this service instance. If so, remove it from the list.
-       
-       cmp = FindServiceArrayIndex( handler->array, *service, index );
-       check( cmp == 0 );
-       if( cmp == 0 )
-       {
-               // Found a match remove the item. The index is index + 1 so subtract 1.
-               
-               index -= 1;
-               check( index < handler->array.GetSize() );
-               
-               mTree.DeleteItem( handler->array[ index ]->item );
-               delete handler->array[ index ];
-               handler->array.RemoveAt( index );
-       }
-       delete service;
-       return( 0 );
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-//     StartResolve
-//===========================================================================================================================
-
-OSStatus       ExplorerBarWindow::StartResolve( ServiceInfo *inService )
-{
-       OSStatus                err;
-       
-       check( inService );
-       
-       // Stop any current resolve that may be in progress.
-       
-       StopResolve();
-       
-       // Resolve the service.
-       
-       err = DNSServiceResolve( &mResolveServiceRef, kDNSServiceFlagsNone, inService->ifi, 
-               inService->name, inService->type, inService->domain, ResolveCallBack, inService->handler );
-       require_noerr( err, exit );
-       
-exit:
-       return( err );
-}
-
-//===========================================================================================================================
-//     StopResolve
-//===========================================================================================================================
-
-void   ExplorerBarWindow::StopResolve( void )
-{
-       if( mResolveServiceRef )
-       {
-               DNSServiceRefDeallocate( mResolveServiceRef );
-               mResolveServiceRef = NULL;
-       }
-}
-
-//===========================================================================================================================
-//     ResolveCallBack
-//===========================================================================================================================
-
-void CALLBACK_COMPAT
-       ExplorerBarWindow::ResolveCallBack(
-               DNSServiceRef                   inRef,
-               DNSServiceFlags                 inFlags,
-               uint32_t                                inInterfaceIndex,
-               DNSServiceErrorType             inErrorCode,
-               const char *                    inFullName,     
-               const char *                    inHostName, 
-               uint16_t                                inPort,
-               uint16_t                                inTXTSize,
-               const char *                    inTXT,
-               void *                                  inContext )
-{
-       ExplorerBarWindow *                     obj;
-       ServiceHandlerEntry *           handler;
-       OSStatus                                        err;
-       
-       DEBUG_UNUSED( inRef );
-       DEBUG_UNUSED( inFlags );
-       DEBUG_UNUSED( inErrorCode );
-       DEBUG_UNUSED( inFullName );
-       
-       require_noerr( inErrorCode, exit );
-       handler = (ServiceHandlerEntry *) inContext;
-       check( handler );
-       obj = handler->obj;
-       check( obj );
-       
-       try
-       {
-               ResolveInfo *           resolve;
-               BOOL                            ok;
-               
-               dlog( kDebugLevelNotice, "resolved %s on ifi %d to %s\n", inFullName, inInterfaceIndex, inHostName );
-               
-               // Stop resolving after the first good result.
-               
-               obj->StopResolve();
-               
-               // Post a message to the main thread so it can handle it since MFC is not thread safe.
-               
-               resolve = new ResolveInfo;
-               require_action( resolve, exit, err = kNoMemoryErr );
-               
-               UTF8StringToStringObject( inHostName, resolve->host );
-               resolve->port           = ntohs( inPort );
-               resolve->ifi            = inInterfaceIndex;
-               resolve->handler        = handler;
-               
-               err = resolve->txt.SetData( inTXT, inTXTSize );
-               check_noerr( err );
-               
-               ok = ::PostMessage( obj->GetSafeHwnd(), WM_PRIVATE_RESOLVE, 0, (LPARAM) resolve );
-               check( ok );
-               if( !ok )
-               {
-                       delete resolve;
-               }
-       }
-       catch( ... )
-       {
-               dlog( kDebugLevelError, "ResolveCallBack: exception thrown\n" );
-       }
-
-exit:
-       return;
-}
-
-//===========================================================================================================================
-//     OnResolve
-//===========================================================================================================================
-
-LONG   ExplorerBarWindow::OnResolve( WPARAM inWParam, LPARAM inLParam )
-{
-       ResolveInfo *           resolve;
-       CString                         url;
-       uint8_t *                       path;
-       size_t                          pathSize;
-       char *                          pathPrefix;
-       CString                         username;
-       CString                         password;
-       
-       DEBUG_UNUSED( inWParam );
-       
-       resolve = reinterpret_cast < ResolveInfo * > ( inLParam );
-       check( resolve );
-               
-       // Get login info if needed.
-       
-       if( resolve->handler->needsLogin )
-       {
-               LoginDialog             dialog;
-               
-               if( !dialog.GetLogin( username, password ) )
-               {
-                       goto exit;
-               }
-       }
-       
-       // If the HTTP TXT record is a "path=" entry, use it as the resource path. Otherwise, use "/".
-       
-       pathPrefix = "";
-       if( strcmp( resolve->handler->type, "_http._tcp" ) == 0 )
-       {
-               resolve->txt.GetData( &path, &pathSize );
-               if( pathSize > 0 )
-               {
-                       pathSize = *path++;
-               }
-               if( ( pathSize > kTXTRecordKeyPathSize ) && ( memicmp( path, kTXTRecordKeyPath, kTXTRecordKeyPathSize ) == 0 )  )
-               {
-                       path            += kTXTRecordKeyPathSize;
-                       pathSize        -= kTXTRecordKeyPathSize;
-               }
-               else if( pathSize == 0 )
-               {
-                       path            = (uint8_t *) "/";
-                       pathSize        = 1;
-               }
-               if( *path != '/' )
-               {
-                       pathPrefix = "/";
-               }
-       }
-       else
-       {
-               path                    = (uint8_t *) "";
-               pathSize                = 1;
-       }
-
-       // Build the URL in the following format:
-       //
-       // <urlScheme>[<username>[:<password>]@]<name/ip>[<path>]
-
-       url.AppendFormat( TEXT( "%S" ), resolve->handler->urlScheme );                                  // URL Scheme
-       if( username.GetLength() > 0 )
-       {
-               url.AppendFormat( TEXT( "%s" ), username );                                                                     // Username
-               if( password.GetLength() > 0 )
-               {
-                       url.AppendFormat( TEXT( ":%s" ), password );                                                    // Password
-               }
-               url.AppendFormat( TEXT( "@" ) );
-       }
-       
-       url += resolve->host;                                                                                                                   // Host
-       url.AppendFormat( TEXT( ":%d" ), resolve->port );                                                               // :Port
-       url.AppendFormat( TEXT( "%S" ), pathPrefix );                                                                   // Path Prefix ("/" or empty).
-       url.AppendFormat( TEXT( "%.*S" ), (int) pathSize, (char *) path );                              // Path (possibly empty).
-       
-       // Tell Internet Explorer to go to the URL.
-       
-       check( mOwner );
-       mOwner->GoToURL( url );
-
-exit:
-       delete resolve;
-       return( 0 );
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-//     FindServiceArrayIndex
-//===========================================================================================================================
-
-DEBUG_LOCAL int        FindServiceArrayIndex( const ServiceInfoArray &inArray, const ServiceInfo &inService, int &outIndex )
-{
-       int             result;
-       int             lo;
-       int             hi;
-       int             mid;
-       
-       result  = -1;
-       mid             = 0;
-       lo              = 0;
-       hi              = (int)( inArray.GetSize() - 1 );
-       while( lo <= hi )
-       {
-               mid = ( lo + hi ) / 2;
-               result = inService.displayName.CompareNoCase( inArray[ mid ]->displayName );
-               if( result == 0 )
-               {
-                       result = ( (int) inService.ifi ) - ( (int) inArray[ mid ]->ifi );
-               }
-               if( result == 0 )
-               {
-                       break;
-               }
-               else if( result < 0 )
-               {
-                       hi = mid - 1;
-               }
-               else
-               {
-                       lo = mid + 1;
-               }
-       }
-       if( result == 0 )
-       {
-               mid += 1;       // Bump index so new item is inserted after matching item.
-       }
-       else if( result > 0 )
-       {
-               mid += 1;
-       }
-       outIndex = mid;
-       return( result );
-}
-
-//===========================================================================================================================
-//     UTF8StringToStringObject
-//===========================================================================================================================
-
-DEBUG_LOCAL OSStatus   UTF8StringToStringObject( const char *inUTF8, CString &inObject )
-{
-       OSStatus                err;
-       int                             n;
-       BSTR                    unicode;
-       
-       unicode = NULL;
-       
-       n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, NULL, 0 );
-       if( n > 0 )
-       {
-               unicode = (BSTR) malloc( (size_t)( n * sizeof( wchar_t ) ) );
-               if( !unicode )
-               {
-                       err = ERROR_INSUFFICIENT_BUFFER;
-                       goto exit;
-               }
-
-               n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, unicode, n );
-               try
-               {
-                       inObject = unicode;
-               }
-               catch( ... )
-               {
-                       err = ERROR_NO_UNICODE_TRANSLATION;
-                       goto exit;
-               }
-       }
-       else
-       {
-               inObject = "";
-       }
-       err = ERROR_SUCCESS;
-       
-exit:
-       if( unicode )
-       {
-               free( unicode );
-       }
-       return( err );
-}