summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/Clients/BonjourExample/BonjourExample.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/Clients/BonjourExample/BonjourExample.cpp')
-rw-r--r--mDNSResponder/Clients/BonjourExample/BonjourExample.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/mDNSResponder/Clients/BonjourExample/BonjourExample.cpp b/mDNSResponder/Clients/BonjourExample/BonjourExample.cpp
new file mode 100644
index 00000000..f517456c
--- /dev/null
+++ b/mDNSResponder/Clients/BonjourExample/BonjourExample.cpp
@@ -0,0 +1,199 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "dns_sd.h"
+
+// Constants
+
+#define BONJOUR_EVENT ( WM_USER + 0x100 ) // Message sent to the Window when a Bonjour event occurs.
+
+// Prototypes
+
+static LRESULT CALLBACK WndProc( HWND inWindow, UINT inMsg, WPARAM inWParam, LPARAM inLParam );
+
+static void DNSSD_API
+ BrowserCallBack(
+ DNSServiceRef inServiceRef,
+ DNSServiceFlags inFlags,
+ uint32_t inIFI,
+ DNSServiceErrorType inError,
+ const char * inName,
+ const char * inType,
+ const char * inDomain,
+ void * inContext );
+
+// Globals
+
+DNSServiceRef gServiceRef = NULL;
+
+// Main entry point for application.
+
+int _tmain( int argc, _TCHAR *argv[] )
+{
+ HINSTANCE instance;
+ WNDCLASSEX wcex;
+ HWND wind;
+ MSG msg;
+ DNSServiceErrorType err;
+
+ (void) argc; // Unused
+ (void) argv; // Unused
+
+ // Create the window. This window won't actually be shown, but it demonstrates how to use Bonjour
+ // with Windows GUI applications by having Bonjour events processed as messages to a Window.
+
+ instance = GetModuleHandle( NULL );
+ assert( instance );
+
+ wcex.cbSize = sizeof( wcex );
+ wcex.style = 0;
+ wcex.lpfnWndProc = (WNDPROC) WndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = instance;
+ wcex.hIcon = NULL;
+ wcex.hCursor = NULL;
+ wcex.hbrBackground = NULL;
+ wcex.lpszMenuName = NULL;
+ wcex.lpszClassName = TEXT( "BonjourExample" );
+ wcex.hIconSm = NULL;
+ RegisterClassEx( &wcex );
+
+ wind = CreateWindow( wcex.lpszClassName, wcex.lpszClassName, 0, CW_USEDEFAULT, 0, CW_USEDEFAULT,
+ 0, NULL, NULL, instance, NULL );
+ assert( wind );
+
+ // Start browsing for services and associate the Bonjour browser with our window using the
+ // WSAAsyncSelect mechanism. Whenever something related to the Bonjour browser occurs, our
+ // private Windows message will be sent to our window so we can give Bonjour a chance to
+ // process it. This allows Bonjour to avoid using a secondary thread (and all the issues
+ // with synchronization that would introduce), but still process everything asynchronously.
+ // This also simplifies app code because Bonjour will only run when we explicitly call it.
+
+ err = DNSServiceBrowse(
+ &gServiceRef, // Receives reference to Bonjour browser object.
+ 0, // No flags.
+ kDNSServiceInterfaceIndexAny, // Browse on all network interfaces.
+ "_http._tcp", // Browse for HTTP service types.
+ NULL, // Browse on the default domain (e.g. local.).
+ BrowserCallBack, // Callback function when Bonjour events occur.
+ NULL ); // No callback context needed.
+ assert( err == kDNSServiceErr_NoError );
+
+ err = WSAAsyncSelect( (SOCKET) DNSServiceRefSockFD( gServiceRef ), wind, BONJOUR_EVENT, FD_READ | FD_CLOSE );
+ assert( err == kDNSServiceErr_NoError );
+
+ fprintf( stderr, "Browsing for _http._tcp\n" );
+
+ // Main event loop for the application. All Bonjour events are dispatched while in this loop.
+
+ while( GetMessage( &msg, NULL, 0, 0 ) )
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ // Clean up Bonjour. This is not strictly necessary since the normal process cleanup will
+ // close Bonjour socket(s) and release memory, but it's here to demonstrate how to do it.
+
+ if( gServiceRef )
+ {
+ WSAAsyncSelect( (SOCKET) DNSServiceRefSockFD( gServiceRef ), wind, BONJOUR_EVENT, 0 );
+ DNSServiceRefDeallocate( gServiceRef );
+ }
+ return( 0 );
+}
+
+// Callback for the Window. Bonjour events are delivered here.
+
+static LRESULT CALLBACK WndProc( HWND inWindow, UINT inMsg, WPARAM inWParam, LPARAM inLParam )
+{
+ LRESULT result;
+ DNSServiceErrorType err;
+
+ switch( inMsg )
+ {
+ case BONJOUR_EVENT:
+
+ // Process the Bonjour event. All Bonjour callbacks occur from within this function.
+ // If an error occurs while trying to process the result, it most likely means that
+ // something serious has gone wrong with Bonjour, such as it being terminated. This
+ // does not normally occur, but code should be prepared to handle it. If the error
+ // is ignored, the window will receive a constant stream of BONJOUR_EVENT messages so
+ // if an error occurs, we disassociate the DNSServiceRef from the window, deallocate
+ // it, and invalidate the reference so we don't try to deallocate it again on quit.
+ // Since this is a simple example app, if this error occurs, we quit the app too.
+
+ err = DNSServiceProcessResult( gServiceRef );
+ if( err != kDNSServiceErr_NoError )
+ {
+ fprintf( stderr, "### ERROR! serious Bonjour error: %d\n", err );
+
+ WSAAsyncSelect( (SOCKET) DNSServiceRefSockFD( gServiceRef ), inWindow, BONJOUR_EVENT, 0 );
+ DNSServiceRefDeallocate( gServiceRef );
+ gServiceRef = NULL;
+
+ PostQuitMessage( 0 );
+ }
+ result = 0;
+ break;
+
+ default:
+ result = DefWindowProc( inWindow, inMsg, inWParam, inLParam );
+ break;
+ }
+ return( result );
+}
+
+// Callback for Bonjour browser events. Called when services are added or removed.
+
+static void DNSSD_API
+ BrowserCallBack(
+ DNSServiceRef inServiceRef,
+ DNSServiceFlags inFlags,
+ uint32_t inIFI,
+ DNSServiceErrorType inError,
+ const char * inName,
+ const char * inType,
+ const char * inDomain,
+ void * inContext )
+{
+ (void) inServiceRef; // Unused
+ (void) inContext; // Unused
+
+ if( inError == kDNSServiceErr_NoError )
+ {
+ const char * action;
+ const char * more;
+
+ if( inFlags & kDNSServiceFlagsAdd ) action = "ADD";
+ else action = "RMV";
+ if( inFlags & kDNSServiceFlagsMoreComing ) more = " (MORE)";
+ else more = "";
+
+ fprintf( stderr, "%s %30s.%s%s on interface %d%s\n", action, inName, inType, inDomain, (int) inIFI, more );
+ }
+ else
+ {
+ fprintf( stderr, "Bonjour browser error occurred: %d\n", inError );
+ }
+}