--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSServiceBrowser.m,v $
+Revision 1.18 2003/08/12 19:55:07 cheshire
+Update to APSL 2.0
+
+ */
+
+#import "BrowserController.h"
+
+#include "arpa/inet.h"
+
+void
+MyHandleMachMessage ( CFMachPortRef port, void * msg, CFIndex size, void * info )
+{
+ DNSServiceDiscovery_handleReply(msg);
+}
+
+void browse_reply (
+ DNSServiceBrowserReplyResultType resultType, // One of DNSServiceBrowserReplyResultType
+ const char *replyName,
+ const char *replyType,
+ const char *replyDomain,
+ DNSServiceDiscoveryReplyFlags flags, // DNS Service Discovery reply flags information
+ void *context
+ )
+{
+ [[NSApp delegate] updateBrowseWithResult:resultType name:[NSString stringWithUTF8String:replyName] type:[NSString stringWithUTF8String:replyType] domain:[NSString stringWithUTF8String:replyDomain] flags:flags];
+ return;
+}
+
+void enum_reply (
+ DNSServiceDomainEnumerationReplyResultType resultType,
+ const char *replyDomain,
+ DNSServiceDiscoveryReplyFlags flags,
+ void *context
+ )
+{
+ [[NSApp delegate] updateEnumWithResult:resultType domain:[NSString stringWithUTF8String:replyDomain] flags:flags];
+
+ return;
+}
+
+void resolve_reply (
+ struct sockaddr *interface,
+ struct sockaddr *address,
+ const char *txtRecord,
+ DNSServiceDiscoveryReplyFlags flags,
+ void *context
+ )
+{
+ [[NSApp delegate] resolveClientWithInterface:interface address:address txtRecord:[NSString stringWithUTF8String:txtRecord]];
+
+ return;
+}
+
+@implementation BrowserController //Begin implementation of BrowserController methods
+
+- (void)registerDefaults
+{
+ NSMutableDictionary *regDict = [NSMutableDictionary dictionary];
+
+ NSArray *typeArray = [NSArray arrayWithObjects:@"_ftp._tcp.", @"_tftp._tcp.",
+ @"_ssh._tcp.", @"_telnet._tcp.",
+ @"_http._tcp.",
+ @"_printer._tcp.", @"_ipp._tcp.",
+ @"_ichat._tcp.", @"_eppc._tcp.",
+ @"_afpovertcp._tcp.", @"_afpovertcp._tcp.", @"_MacOSXDupSuppress._tcp.", nil];
+ NSArray *nameArray = [NSArray arrayWithObjects:@"File Transfer (ftp)", @"Trivial File Transfer (tftp)",
+ @"Secure Shell (ssh)", @"Telnet",
+ @"Web Server (http)",
+ @"LPR Printer", @"IPP Printer",
+ @"iChat", @"Remote AppleEvents",
+ @"AppleShare Server", @"SMB File Server", @"Mystery Service", nil];
+
+ [regDict setObject:typeArray forKey:@"SrvTypeKeys"];
+ [regDict setObject:nameArray forKey:@"SrvNameKeys"];
+
+ [[NSUserDefaults standardUserDefaults] registerDefaults:regDict];
+}
+
+
+- (id)init
+{
+ [self registerDefaults];
+
+ browse_client = nil;
+
+ return [super init];
+}
+
+- (void)awakeFromNib //BrowserController startup procedure
+{
+ SrvType=NULL;
+ Domain=NULL;
+ srvtypeKeys = [NSMutableArray array]; //Define arrays for Type, Domain, and Name
+ srvnameKeys = [NSMutableArray array];
+
+ domainKeys = [NSMutableArray array];
+ [domainKeys retain];
+
+ nameKeys = [NSMutableArray array];
+ [nameKeys retain];
+
+ [srvtypeKeys retain]; //Keep arrays in memory until BrowserController closes
+ [srvnameKeys retain]; //Keep arrays in memory until BrowserController closes
+ [typeField setDataSource:self]; //Set application fields' data source to BrowserController
+ [typeField sizeLastColumnToFit]; //and set column sizes to use their whole table's width.
+ [nameField setDataSource:self];
+ [nameField sizeLastColumnToFit];
+ [domainField setDataSource:self];
+ [domainField sizeLastColumnToFit];
+
+ [nameField setDoubleAction:@selector(connect:)];
+
+ //[srvtypeKeys addObject:@"_ftp._tcp."]; //Add supported protocols and domains to their
+ //[srvnameKeys addObject:@"File Transfer (ftp)"];
+ //[srvtypeKeys addObject:@"_printer._tcp."]; //respective arrays
+ //[srvnameKeys addObject:@"Printer (lpr)"];
+ //[srvtypeKeys addObject:@"_http._tcp."]; //respective arrays
+ //[srvnameKeys addObject:@"Web Server (http)"];
+ //[srvtypeKeys addObject:@"_afp._tcp."]; //respective arrays
+ //[srvnameKeys addObject:@"AppleShare Server (afp)"];
+
+ [ipAddressField setStringValue:@""];
+ [portField setStringValue:@""];
+ [textField setStringValue:@""];
+
+ [srvtypeKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTypeKeys"]];
+ [srvnameKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvNameKeys"]];
+
+
+ [typeField reloadData]; //Reload (redraw) data in fields
+ [domainField reloadData];
+
+ [self loadDomains:self];
+
+}
+
+- (void)dealloc //Deallocation method
+{
+ [srvtypeKeys release];
+ [srvnameKeys release];
+ [nameKeys release];
+ [domainKeys release];
+}
+
+-(void)tableView:(NSTableView *)theTableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row
+{
+ if (row<0) return;
+}
+
+- (int)numberOfRowsInTableView:(NSTableView *)theTableView //Begin mandatory TableView methods
+{
+ if (theTableView == typeField)
+ {
+ return [srvnameKeys count];
+ }
+ if (theTableView == domainField)
+ {
+ return [domainKeys count];
+ }
+ if (theTableView == nameField)
+ {
+ return [nameKeys count];
+ }
+ if (theTableView == serviceDisplayTable)
+ {
+ return [srvnameKeys count];
+ }
+ return 0;
+}
+
+- (id)tableView:(NSTableView *)theTableView objectValueForTableColumn:(NSTableColumn *)theColumn row:(int)rowIndex
+{
+ if (theTableView == typeField)
+ {
+ return [srvnameKeys objectAtIndex:rowIndex];
+ }
+ if (theTableView == domainField)
+ {
+ return [domainKeys objectAtIndex:rowIndex];
+ }
+ if (theTableView == nameField)
+ {
+ return [[nameKeys sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:rowIndex];
+ }
+ if (theTableView == serviceDisplayTable)
+ {
+ if (theColumn == typeColumn) {
+ return [srvtypeKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == nameColumn) {
+ return [srvnameKeys objectAtIndex:rowIndex];
+ }
+ return 0;
+ }
+ else
+ return(0);
+} //End of mandatory TableView methods
+
+- (IBAction)handleTypeClick:(id)sender //Handle clicks for Type
+{
+ int index=[sender selectedRow]; //Find index of selected row
+ if (index==-1) return; //Error checking
+ SrvType = [srvtypeKeys objectAtIndex:index]; //Save desired Type
+ SrvName = [srvnameKeys objectAtIndex:index]; //Save desired Type
+
+ [ipAddressField setStringValue:@""];
+ [portField setStringValue:@""];
+ [textField setStringValue:@""];
+
+ [self update:SrvType Domain:Domain]; //If Type and Domain are set, update records
+}
+
+- (IBAction)handleDomainClick:(id)sender //Handle clicks for Domain
+{
+ int index=[sender selectedRow]; //Find index of selected row
+ if (index==-1) return; //Error checking
+ Domain = [domainKeys objectAtIndex:index]; //Save desired Domain
+
+ [ipAddressField setStringValue:@""];
+ [portField setStringValue:@""];
+ [textField setStringValue:@""];
+
+ if (SrvType!=NULL) [self update:SrvType Domain:Domain]; //If Type and Domain are set, update records
+}
+
+- (IBAction)handleNameClick:(id)sender //Handle clicks for Name
+{
+ int index=[sender selectedRow]; //Find index of selected row
+ if (index==-1) return; //Error checking
+ Name=[[nameKeys sortedArrayUsingSelector:@selector(compare:)] objectAtIndex:index]; //Save desired name
+
+ {
+ CFMachPortRef cfMachPort;
+ CFMachPortContext context;
+ Boolean shouldFreeInfo;
+ dns_service_discovery_ref dns_client;
+ mach_port_t port;
+ CFRunLoopSourceRef rls;
+
+ context.version = 1;
+ context.info = 0;
+ context.retain = NULL;
+ context.release = NULL;
+ context.copyDescription = NULL;
+
+ [ipAddressField setStringValue:@"?"];
+ [portField setStringValue:@"?"];
+ [textField setStringValue:@"?"];
+ // start an enumerator on the local server
+ dns_client = DNSServiceResolverResolve
+ (
+ (char *)[Name UTF8String],
+ (char *)[SrvType UTF8String],
+ (char *)(Domain?[Domain UTF8String]:""),
+ resolve_reply,
+ nil
+ );
+
+ port = DNSServiceDiscoveryMachPort(dns_client);
+
+ if (port) {
+ cfMachPort = CFMachPortCreateWithPort ( kCFAllocatorDefault, port, ( CFMachPortCallBack ) MyHandleMachMessage,&context,&shouldFreeInfo );
+
+ /* Create and add a run loop source for the port */
+ rls = CFMachPortCreateRunLoopSource(NULL, cfMachPort, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+ } else {
+ printf("Could not obtain client port\n");
+ return;
+ }
+ }
+}
+
+- (IBAction)loadDomains:(id)sender
+{
+ CFMachPortRef cfMachPort;
+ CFMachPortContext context;
+ Boolean shouldFreeInfo;
+ dns_service_discovery_ref dns_client;
+ mach_port_t port;
+ CFRunLoopSourceRef rls;
+
+ context.version = 1;
+ context.info = 0;
+ context.retain = NULL;
+ context.release = NULL;
+ context.copyDescription = NULL;
+
+ // start an enumerator on the local server
+ dns_client = DNSServiceDomainEnumerationCreate
+ (
+ 0,
+ enum_reply,
+ nil
+ );
+
+ port = DNSServiceDiscoveryMachPort(dns_client);
+
+ if (port) {
+ cfMachPort = CFMachPortCreateWithPort ( kCFAllocatorDefault, port, ( CFMachPortCallBack ) MyHandleMachMessage,&context,&shouldFreeInfo );
+
+ /* Create and add a run loop source for the port */
+ rls = CFMachPortCreateRunLoopSource(NULL, cfMachPort, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+ } else {
+ printf("Could not obtain client port\n");
+ return;
+ }
+}
+
+- (IBAction)update:theType Domain:theDomain; //The Big Kahuna: Fetch PTR records and update application
+{
+ const char * DomainC;
+ const char * TypeC=[theType UTF8String]; //Type in C string format
+
+ if (theDomain) {
+ DomainC = [theDomain UTF8String]; //Domain in C string format
+ } else {
+ DomainC = "";
+ }
+
+ [nameKeys removeAllObjects]; //Get rid of displayed records if we're going to go get new ones
+ [nameField reloadData]; //Reload (redraw) names to show the old data is gone
+
+ // get rid of the previous browser if one exists
+ if (browse_client) {
+ DNSServiceDiscoveryDeallocate(browse_client);
+ browse_client = nil;
+ }
+
+ // now create a browser to return the values for the nameField ...
+ {
+ CFMachPortRef cfMachPort;
+ CFMachPortContext context;
+ Boolean shouldFreeInfo;
+ mach_port_t port;
+ CFRunLoopSourceRef rls;
+
+ context.version = 1;
+ context.info = 0;
+ context.retain = NULL;
+ context.release = NULL;
+ context.copyDescription = NULL;
+
+ // start an enumerator on the local server
+ browse_client = DNSServiceBrowserCreate
+ (
+ (char *)TypeC,
+ (char *)DomainC,
+ browse_reply,
+ nil
+ );
+
+ port = DNSServiceDiscoveryMachPort(browse_client);
+
+ if (port) {
+ cfMachPort = CFMachPortCreateWithPort ( kCFAllocatorDefault, port, ( CFMachPortCallBack ) MyHandleMachMessage,&context,&shouldFreeInfo );
+
+ /* Create and add a run loop source for the port */
+ rls = CFMachPortCreateRunLoopSource(NULL, cfMachPort, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+ } else {
+ printf("Could not obtain client port\n");
+ return;
+ }
+ }
+
+}
+
+
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication //Quit when main window is closed
+{
+ return YES;
+}
+
+- (BOOL)windowShouldClose:(NSWindow *)sender //Save domains to our domain file when quitting
+{
+ [domainField reloadData];
+ return YES;
+}
+
+- (void)updateEnumWithResult:(int)resultType domain:(NSString *)domain flags:(int)flags
+{
+ // new domain received
+ if (DNSServiceDomainEnumerationReplyAddDomain == resultType || DNSServiceDomainEnumerationReplyAddDomainDefault == resultType) {
+ // add the domain to the list
+ [domainKeys addObject:domain];
+ } else {
+ // remove the domain from the list
+ NSEnumerator *dmnEnum = [domainKeys objectEnumerator];
+ NSString *aDomain = nil;
+
+ while (aDomain = [dmnEnum nextObject]) {
+ if ([aDomain isEqualToString:domain]) {
+ [domainKeys removeObject:domain];
+ break;
+ }
+ }
+ }
+ // update the domain table
+ [domainField reloadData];
+ return;
+}
+
+
+
+- (void)updateBrowseWithResult:(int)type name:(NSString *)name type:(NSString *)resulttype domain:(NSString *)domain flags:(int)flags
+{
+
+ //NSLog(@"Received result %@ %@ %@ %d", name, resulttype, domain, type);
+
+ if (([domain isEqualToString:Domain] || [domain isEqualToString:@"local."]) && [resulttype isEqualToString:SrvType]) {
+
+ if (type == DNSServiceBrowserReplyRemoveInstance) {
+ if ([nameKeys containsObject:name]) {
+ [nameKeys removeObject:name];
+ }
+ }
+ if (type == DNSServiceBrowserReplyAddInstance) {
+ if (![nameKeys containsObject:name]) {
+ [nameKeys addObject:name];
+ }
+ }
+
+ // If not expecting any more data, then reload (redraw) Name TableView with newly found data
+ if ((flags & kDNSServiceDiscoveryMoreRepliesImmediately) == 0)
+ [nameField reloadData];
+ }
+ return;
+}
+
+- (void)resolveClientWithInterface:(struct sockaddr *)interface address:(struct sockaddr *)address txtRecord:(NSString *)txtRecord
+{
+ if (address->sa_family != AF_INET) return; // For now we only handle IPv4
+ //printf("interface length = %d, port = %d, family = %d, address = %s\n", ((struct sockaddr_in *)interface)->sin_len, ((struct sockaddr_in *)interface)->sin_port, ((struct sockaddr_in *)interface)->sin_family, inet_ntoa(((struct in_addr)((struct sockaddr_in *)interface)->sin_addr)));
+ //printf("address length = %d, port = %d, family = %d, address = %s\n", ((struct sockaddr_in *)address)->sin_len, ((struct sockaddr_in *)address)->sin_port, ((struct sockaddr_in *)address)->sin_family, inet_ntoa(((struct in_addr)((struct sockaddr_in *)address)->sin_addr)));
+ NSString *ipAddr = [NSString stringWithCString:inet_ntoa(((struct in_addr)((struct sockaddr_in *)address)->sin_addr))];
+ int port = ((struct sockaddr_in *)address)->sin_port;
+
+ [ipAddressField setStringValue:ipAddr];
+ [portField setIntValue:port];
+ [textField setStringValue:txtRecord];
+
+ return;
+}
+
+- (void)connect:(id)sender
+{
+ NSString *ipAddr = [ipAddressField stringValue];
+ int port = [portField intValue];
+ NSString *txtRecord = [textField stringValue];
+
+ if (!txtRecord) txtRecord = @"";
+
+ if (!ipAddr || !port) return;
+
+ if ([SrvType isEqualToString:@"_ftp._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"ftp://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_tftp._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"tftp://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_ssh._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"ssh://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_telnet._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"telnet://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_http._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@:%d", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_printer._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"lpr://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_ipp._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"ipp://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_afpovertcp._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"afp://%@:%d/", ipAddr, port]]];
+ else if ([SrvType isEqualToString:@"_smb._tcp."]) [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"smb://%@:%d/", ipAddr, port]]];
+
+ return;
+}
+
+- (IBAction)handleTableClick:(id)sender
+{
+ //populate the text fields
+}
+
+- (IBAction)removeSelected:(id)sender
+{
+ // remove the selected row and force a refresh
+
+ int selectedRow = [serviceDisplayTable selectedRow];
+
+ if (selectedRow) {
+
+ [srvtypeKeys removeObjectAtIndex:selectedRow];
+ [srvnameKeys removeObjectAtIndex:selectedRow];
+
+ [[NSUserDefaults standardUserDefaults] setObject:srvtypeKeys forKey:@"SrvTypeKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvnameKeys forKey:@"SrvNameKeys"];
+
+ [typeField reloadData];
+ [serviceDisplayTable reloadData];
+ }
+}
+
+- (IBAction)addNewService:(id)sender
+{
+ // add new entries from the edit fields to the arrays for the defaults
+
+ if ([[serviceTypeField stringValue] length] && [[serviceNameField stringValue] length]) {
+ [srvtypeKeys addObject:[serviceTypeField stringValue]];
+ [srvnameKeys addObject:[serviceNameField stringValue]];
+
+ [[NSUserDefaults standardUserDefaults] setObject:srvtypeKeys forKey:@"SrvTypeKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvnameKeys forKey:@"SrvNameKeys"];
+
+ [typeField reloadData];
+ [serviceDisplayTable reloadData];
+ }
+
+}
+
+
+
+@end
\ No newline at end of file
--- /dev/null
+{
+ IBClasses = (
+ {
+ ACTIONS = {
+ addNewService = id;
+ connect = id;
+ editDomains = id;
+ handleDomainClick = id;
+ handleNameClick = id;
+ handleTableClick = id;
+ handleTypeClick = id;
+ loadDomains = id;
+ removeSelected = id;
+ };
+ CLASS = BrowserController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ domainEditField = id;
+ domainField = id;
+ domainWindow = id;
+ ipAddressField = id;
+ nameColumn = id;
+ nameField = id;
+ portField = id;
+ serviceDisplayTable = id;
+ serviceNameField = id;
+ serviceTypeField = id;
+ textField = id;
+ typeColumn = id;
+ typeField = id;
+ };
+ SUPERCLASS = NSObject;
+ },
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
+ );
+ IBVersion = 1;
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>14 102 356 240 0 0 1152 746 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>22 474 271 44 0 0 1152 746 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>273.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>220</integer>
+ <integer>201</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>6C35</string>
+</dict>
+</plist>
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSServiceReg.m,v $
+Revision 1.13 2003/08/12 19:55:07 cheshire
+Update to APSL 2.0
+
+ */
+
+#import "RegistrationController.h"
+
+#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
+
+void reg_reply (
+ int errorCode,
+ void *context
+ )
+{
+ // registration reply
+ printf("Got a reply from the server with error %d\n", errorCode);
+ return;
+}
+
+void
+MyHandleMachMessage ( CFMachPortRef port, void * msg, CFIndex size, void * info )
+{
+ DNSServiceDiscovery_handleReply(msg);
+}
+
+@implementation RegistrationController
+
+- (void)registerDefaults
+{
+ NSMutableDictionary *regDict = [NSMutableDictionary dictionary];
+
+ NSArray *typeArray = [NSArray arrayWithObjects:@"_ftp._tcp.", @"_ssh._tcp.", @"_tftp._tcp.", @"_http._tcp.", @"_printer._tcp.", @"_afpovertcp._tcp.", nil];
+ NSArray *nameArray = [NSArray arrayWithObjects:@"My ftp Server", @"My Computer", @"Testing Boot Image", @"A Web Server", @"SteveÕs Printer", @"Company AppleShare Server", nil];
+ NSArray *portArray = [NSArray arrayWithObjects:@"21", @"22", @"69", @"80", @"515", @"548", nil];
+ NSArray *domainArray = [NSArray arrayWithObjects:@"", @"", @"", @"", @"", @"", nil];
+ NSArray *textArray = [NSArray arrayWithObjects:@"", @"", @"image=mybootimage", @"path=/index.html", @"rn=lpt1", @"Vol=Public", nil];
+
+ [regDict setObject:typeArray forKey:@"SrvTypeKeys"];
+ [regDict setObject:nameArray forKey:@"SrvNameKeys"];
+ [regDict setObject:portArray forKey:@"SrvPortKeys"];
+ [regDict setObject:domainArray forKey:@"SrvDomainKeys"];
+ [regDict setObject:textArray forKey:@"SrvTextKeys"];
+
+ [[NSUserDefaults standardUserDefaults] registerDefaults:regDict];
+}
+
+- (id)init
+{
+ srvtypeKeys = [[NSMutableArray array] retain]; //Define arrays for Type, Domain, and Name
+ srvnameKeys = [[NSMutableArray array] retain];
+ srvportKeys = [[NSMutableArray array] retain];
+ srvdomainKeys = [[NSMutableArray array] retain];
+ srvtextKeys = [[NSMutableArray array] retain];
+
+ registeredDict = [[NSMutableDictionary alloc] init];
+
+ [self registerDefaults];
+ return [super init];
+}
+
+- (void)awakeFromNib //BrowserController startup procedure
+{
+ [srvtypeKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTypeKeys"]];
+ [srvnameKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvNameKeys"]];
+ [srvportKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvPortKeys"]];
+ [srvdomainKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvDomainKeys"]];
+ [srvtextKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTextKeys"]];
+
+ [serviceDisplayTable reloadData]; //Reload (redraw) data in fields
+
+}
+
+
+
+ - (IBAction)registerService:(id)sender
+{
+ int selectedRow = [serviceDisplayTable selectedRow];
+ CFRunLoopSourceRef rls;
+ uint16_t registerPort;
+ CFMachPortRef cfMachPort;
+ CFMachPortContext context;
+ Boolean shouldFreeInfo;
+ dns_service_discovery_ref dns_client;
+ mach_port_t port;
+
+ if (selectedRow < 0) {
+ return;
+ }
+
+ context.version = 1;
+ context.info = 0;
+ context.retain = NULL;
+ context.release = NULL;
+ context.copyDescription = NULL;
+
+ registerPort = [[srvportKeys objectAtIndex:selectedRow] intValue];
+
+ dns_client = DNSServiceRegistrationCreate
+ (
+ [[srvnameKeys objectAtIndex:selectedRow] UTF8String],
+ [[srvtypeKeys objectAtIndex:selectedRow] UTF8String],
+ [[srvdomainKeys objectAtIndex:selectedRow] UTF8String],
+ registerPort,
+ [[srvtextKeys objectAtIndex:selectedRow] UTF8String],
+ reg_reply,
+ nil
+ );
+
+ port = DNSServiceDiscoveryMachPort(dns_client);
+
+ if (port) {
+
+ //printf("port is %d\n", port);
+
+ cfMachPort = CFMachPortCreateWithPort ( kCFAllocatorDefault, port, ( CFMachPortCallBack ) MyHandleMachMessage,&context,&shouldFreeInfo );
+
+ rls = CFMachPortCreateRunLoopSource(NULL, cfMachPort, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+ [registeredDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)dns_client] forKey:[srvtypeKeys objectAtIndex:selectedRow]];
+ } else {
+ printf("Could not obtain client port\n");
+ }
+
+}
+
+- (IBAction)unregisterService:(id)sender
+{
+ int selectedRow = [serviceDisplayTable selectedRow];
+ NSString *key = [srvtypeKeys objectAtIndex:selectedRow];
+
+ NSNumber *refPtr = [registeredDict objectForKey:key];
+ dns_service_discovery_ref ref = (dns_service_discovery_ref)[refPtr unsignedIntValue];
+
+ if (ref) {
+ DNSServiceDiscoveryDeallocate(ref);
+ [registeredDict removeObjectForKey:key];
+ }
+}
+
+-(void)tableView:(NSTableView *)theTableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row
+{
+ if (row<0) return;
+}
+
+- (int)numberOfRowsInTableView:(NSTableView *)theTableView //Begin mandatory TableView methods
+{
+ return [srvtypeKeys count];
+}
+
+- (id)tableView:(NSTableView *)theTableView objectValueForTableColumn:(NSTableColumn *)theColumn row:(int)rowIndex
+{
+ if (theColumn == typeColumn) {
+ return [srvtypeKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == nameColumn) {
+ return [srvnameKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == portColumn) {
+ return [srvportKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == domainColumn) {
+ return [srvdomainKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == textColumn) {
+ return [srvtextKeys objectAtIndex:rowIndex];
+ }
+
+ return(0);
+} //End of mandatory TableView methods
+
+- (IBAction)removeSelected:(id)sender
+{
+ // remove the selected row and force a refresh
+
+ int selectedRow = [serviceDisplayTable selectedRow];
+
+ if (selectedRow) {
+
+ [srvtypeKeys removeObjectAtIndex:selectedRow];
+ [srvnameKeys removeObjectAtIndex:selectedRow];
+ [srvportKeys removeObjectAtIndex:selectedRow];
+ [srvdomainKeys removeObjectAtIndex:selectedRow];
+ [srvtextKeys removeObjectAtIndex:selectedRow];
+
+ [[NSUserDefaults standardUserDefaults] setObject:srvtypeKeys forKey:@"SrvTypeKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvnameKeys forKey:@"SrvNameKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvportKeys forKey:@"SrvPortKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvdomainKeys forKey:@"SrvDomainKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvtextKeys forKey:@"SrvTextKeys"];
+
+ [serviceDisplayTable reloadData];
+ }
+}
+
+- (IBAction)addNewService:(id)sender
+{
+ // add new entries from the edit fields to the arrays for the defaults
+
+ if ([[serviceTypeField stringValue] length] && [[serviceNameField stringValue] length] && [[serviceDomainField stringValue] length]&& [[servicePortField stringValue] length]) {
+ [srvtypeKeys addObject:[serviceTypeField stringValue]];
+ [srvnameKeys addObject:[serviceNameField stringValue]];
+ [srvportKeys addObject:[servicePortField stringValue]];
+ [srvdomainKeys addObject:[serviceDomainField stringValue]];
+ [srvtextKeys addObject:[serviceTextField stringValue]];
+
+ [[NSUserDefaults standardUserDefaults] setObject:srvtypeKeys forKey:@"SrvTypeKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvnameKeys forKey:@"SrvNameKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvportKeys forKey:@"SrvPortKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvdomainKeys forKey:@"SrvDomainKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvtextKeys forKey:@"SrvTextKeys"];
+
+ [serviceDisplayTable reloadData];
+ } else {
+ NSBeep();
+ }
+
+}
+
+
+
+@end
--- /dev/null
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {
+ addNewService = id;
+ registerService = id;
+ removeSelected = id;
+ unregisterService = id;
+ };
+ CLASS = RegistrationController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ domainColumn = NSTableColumn;
+ nameColumn = NSTableColumn;
+ portColumn = NSTableColumn;
+ serviceDisplayTable = NSTableView;
+ serviceDomainField = NSTextField;
+ serviceNameField = NSTextField;
+ servicePortField = NSTextField;
+ serviceTextField = NSTextField;
+ serviceTypeField = NSTextField;
+ textColumn = NSTableColumn;
+ typeColumn = NSTableColumn;
+ };
+ SUPERCLASS = NSObject;
+ }
+ );
+ IBVersion = 1;
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>32 111 356 240 0 0 1152 746 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>103 609 252 44 0 0 1152 746 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>273.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>243</integer>
+ <integer>21</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>6C30</string>
+</dict>
+</plist>
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSServiceRegistration.m,v $
+Revision 1.13 2003/08/12 19:55:07 cheshire
+Update to APSL 2.0
+
+ */
+
+#import "RegistrationController.h"
+
+#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
+
+void reg_reply (
+ int errorCode,
+ void *context
+ )
+{
+ // registration reply
+ printf("Got a reply from the server with error %d\n", errorCode);
+ return;
+}
+
+void
+MyHandleMachMessage ( CFMachPortRef port, void * msg, CFIndex size, void * info )
+{
+ DNSServiceDiscovery_handleReply(msg);
+}
+
+@implementation RegistrationController
+
+- (void)registerDefaults
+{
+ NSMutableDictionary *regDict = [NSMutableDictionary dictionary];
+
+ NSArray *typeArray = [NSArray arrayWithObjects:@"_ftp._tcp.", @"_ssh._tcp.", @"_tftp._tcp.", @"_http._tcp.", @"_printer._tcp.", @"_afpovertcp._tcp.", nil];
+ NSArray *nameArray = [NSArray arrayWithObjects:@"My ftp Server", @"My Computer", @"Testing Boot Image", @"A Web Server", @"SteveÕs Printer", @"Company AppleShare Server", nil];
+ NSArray *portArray = [NSArray arrayWithObjects:@"21", @"22", @"69", @"80", @"515", @"548", nil];
+ NSArray *domainArray = [NSArray arrayWithObjects:@"", @"", @"", @"", @"", @"", nil];
+ NSArray *textArray = [NSArray arrayWithObjects:@"", @"", @"image=mybootimage", @"path=/index.html", @"rn=lpt1", @"Vol=Public", nil];
+
+ [regDict setObject:typeArray forKey:@"SrvTypeKeys"];
+ [regDict setObject:nameArray forKey:@"SrvNameKeys"];
+ [regDict setObject:portArray forKey:@"SrvPortKeys"];
+ [regDict setObject:domainArray forKey:@"SrvDomainKeys"];
+ [regDict setObject:textArray forKey:@"SrvTextKeys"];
+
+ [[NSUserDefaults standardUserDefaults] registerDefaults:regDict];
+}
+
+- (id)init
+{
+ srvtypeKeys = [[NSMutableArray array] retain]; //Define arrays for Type, Domain, and Name
+ srvnameKeys = [[NSMutableArray array] retain];
+ srvportKeys = [[NSMutableArray array] retain];
+ srvdomainKeys = [[NSMutableArray array] retain];
+ srvtextKeys = [[NSMutableArray array] retain];
+
+ registeredDict = [[NSMutableDictionary alloc] init];
+
+ [self registerDefaults];
+ return [super init];
+}
+
+- (void)awakeFromNib //BrowserController startup procedure
+{
+ [srvtypeKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTypeKeys"]];
+ [srvnameKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvNameKeys"]];
+ [srvportKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvPortKeys"]];
+ [srvdomainKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvDomainKeys"]];
+ [srvtextKeys addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"SrvTextKeys"]];
+
+ [serviceDisplayTable reloadData]; //Reload (redraw) data in fields
+
+}
+
+
+
+ - (IBAction)registerService:(id)sender
+{
+ int selectedRow = [serviceDisplayTable selectedRow];
+ CFRunLoopSourceRef rls;
+ uint16_t registerPort;
+ CFMachPortRef cfMachPort;
+ CFMachPortContext context;
+ Boolean shouldFreeInfo;
+ dns_service_discovery_ref dns_client;
+ mach_port_t port;
+
+ if (selectedRow < 0) {
+ return;
+ }
+
+ context.version = 1;
+ context.info = 0;
+ context.retain = NULL;
+ context.release = NULL;
+ context.copyDescription = NULL;
+
+ registerPort = [[srvportKeys objectAtIndex:selectedRow] intValue];
+
+ dns_client = DNSServiceRegistrationCreate
+ (
+ [[srvnameKeys objectAtIndex:selectedRow] UTF8String],
+ [[srvtypeKeys objectAtIndex:selectedRow] UTF8String],
+ [[srvdomainKeys objectAtIndex:selectedRow] UTF8String],
+ registerPort,
+ [[srvtextKeys objectAtIndex:selectedRow] UTF8String],
+ reg_reply,
+ nil
+ );
+
+ port = DNSServiceDiscoveryMachPort(dns_client);
+
+ if (port) {
+
+ //printf("port is %d\n", port);
+
+ cfMachPort = CFMachPortCreateWithPort ( kCFAllocatorDefault, port, ( CFMachPortCallBack ) MyHandleMachMessage,&context,&shouldFreeInfo );
+
+ rls = CFMachPortCreateRunLoopSource(NULL, cfMachPort, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+ [registeredDict setObject:[NSNumber numberWithUnsignedInt:(unsigned int)dns_client] forKey:[srvtypeKeys objectAtIndex:selectedRow]];
+ } else {
+ printf("Could not obtain client port\n");
+ }
+
+}
+
+- (IBAction)unregisterService:(id)sender
+{
+ int selectedRow = [serviceDisplayTable selectedRow];
+ NSString *key = [srvtypeKeys objectAtIndex:selectedRow];
+
+ NSNumber *refPtr = [registeredDict objectForKey:key];
+ dns_service_discovery_ref ref = (dns_service_discovery_ref)[refPtr unsignedIntValue];
+
+ if (ref) {
+ DNSServiceDiscoveryDeallocate(ref);
+ [registeredDict removeObjectForKey:key];
+ }
+}
+
+-(void)tableView:(NSTableView *)theTableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row
+{
+ if (row<0) return;
+}
+
+- (int)numberOfRowsInTableView:(NSTableView *)theTableView //Begin mandatory TableView methods
+{
+ return [srvtypeKeys count];
+}
+
+- (id)tableView:(NSTableView *)theTableView objectValueForTableColumn:(NSTableColumn *)theColumn row:(int)rowIndex
+{
+ if (theColumn == typeColumn) {
+ return [srvtypeKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == nameColumn) {
+ return [srvnameKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == portColumn) {
+ return [srvportKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == domainColumn) {
+ return [srvdomainKeys objectAtIndex:rowIndex];
+ }
+ if (theColumn == textColumn) {
+ return [srvtextKeys objectAtIndex:rowIndex];
+ }
+
+ return(0);
+} //End of mandatory TableView methods
+
+- (IBAction)removeSelected:(id)sender
+{
+ // remove the selected row and force a refresh
+
+ int selectedRow = [serviceDisplayTable selectedRow];
+
+ if (selectedRow) {
+
+ [srvtypeKeys removeObjectAtIndex:selectedRow];
+ [srvnameKeys removeObjectAtIndex:selectedRow];
+ [srvportKeys removeObjectAtIndex:selectedRow];
+ [srvdomainKeys removeObjectAtIndex:selectedRow];
+ [srvtextKeys removeObjectAtIndex:selectedRow];
+
+ [[NSUserDefaults standardUserDefaults] setObject:srvtypeKeys forKey:@"SrvTypeKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvnameKeys forKey:@"SrvNameKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvportKeys forKey:@"SrvPortKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvdomainKeys forKey:@"SrvDomainKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvtextKeys forKey:@"SrvTextKeys"];
+
+ [serviceDisplayTable reloadData];
+ }
+}
+
+- (IBAction)addNewService:(id)sender
+{
+ // add new entries from the edit fields to the arrays for the defaults
+
+ if ([[serviceTypeField stringValue] length] && [[serviceNameField stringValue] length] && [[serviceDomainField stringValue] length]&& [[servicePortField stringValue] length]) {
+ [srvtypeKeys addObject:[serviceTypeField stringValue]];
+ [srvnameKeys addObject:[serviceNameField stringValue]];
+ [srvportKeys addObject:[servicePortField stringValue]];
+ [srvdomainKeys addObject:[serviceDomainField stringValue]];
+ [srvtextKeys addObject:[serviceTextField stringValue]];
+
+ [[NSUserDefaults standardUserDefaults] setObject:srvtypeKeys forKey:@"SrvTypeKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvnameKeys forKey:@"SrvNameKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvportKeys forKey:@"SrvPortKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvdomainKeys forKey:@"SrvDomainKeys"];
+ [[NSUserDefaults standardUserDefaults] setObject:srvtextKeys forKey:@"SrvTextKeys"];
+
+ [serviceDisplayTable reloadData];
+ } else {
+ NSBeep();
+ }
+
+}
+
+
+
+@end
--- /dev/null
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {
+ addNewService = id;
+ registerService = id;
+ removeSelected = id;
+ unregisterService = id;
+ };
+ CLASS = RegistrationController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ domainColumn = NSTableColumn;
+ nameColumn = NSTableColumn;
+ portColumn = NSTableColumn;
+ serviceDisplayTable = NSTableView;
+ serviceDomainField = NSTextField;
+ serviceNameField = NSTextField;
+ servicePortField = NSTextField;
+ serviceTextField = NSTextField;
+ serviceTypeField = NSTextField;
+ textColumn = NSTableColumn;
+ typeColumn = NSTableColumn;
+ };
+ SUPERCLASS = NSObject;
+ }
+ );
+ IBVersion = 1;
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>32 111 356 240 0 0 1152 746 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>103 609 252 44 0 0 1152 746 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>273.0</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>243</integer>
+ <integer>21</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>6C30</string>
+</dict>
+</plist>
include /Developer/Makefiles/pb_makefiles/platform.make
-MVERS = "mDNSResponder-58.8"
+MVERS = "mDNSResponder-58.8.1"
install:
cd "$(SRCROOT)/mDNSMacOSX"; pbxbuild install OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) DSTROOT=$(DSTROOT) MVERS=$(MVERS)
Change History (most recent first):
$Log: mDNS.c,v $
+Revision 1.307.2.13 2005/01/28 05:39:12 cheshire
+Remove LogMsg()
+
+Revision 1.307.2.12 2005/01/28 05:02:05 cheshire
+<rdar://problem/3770559> SUPan: Replace IP TTL 255 check with local-subnet check
+
+Revision 1.307.2.11 2005/01/28 04:03:23 cheshire
+<rdar://problem/3759302> SUPan: Current method of doing subtypes causes name collisions
+Summary: Pulled in ConstructServiceName, CountSubTypes and AllocateSubTypes from Tiger version.
+
+Revision 1.307.2.10 2004/06/18 17:28:18 cheshire
+<rdar://problem/3588761> Current method of doing subtypes causes name collisions
+
+Revision 1.307.2.9 2004/06/18 00:31:51 cheshire
+<rdar://problem/3617655> mDNSResponder escape handling inconsistent with BIND
+(Prerequisite for fixing <rdar://problem/3588761>)
+
Revision 1.307.2.8 2004/04/03 05:18:19 bradley
Added cast to fix signed/unsigned warning due to int promotion.
Don't kill the Extras list in mDNS_DeregisterService()
Revision 1.60 2002/09/19 23:47:35 cheshire
-Added mDNS_RegisterNoSuchService() function for assertion of non-existance
+Added mDNS_RegisterNoSuchService() function for assertion of non-existence
of a particular named service
Revision 1.59 2002/09/19 21:25:34 cheshire
return(mDNSfalse);
}
-mDNSlocal mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip)
+mDNSexport mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip)
{
switch(ip->type)
{
mDNSu8 c = (mDNSu8)*cstr++; // Read the character
if (c == '\\') // If escape character, check next character
{
- if (*cstr == '\\' || *cstr == '.') // If a second escape, or a dot,
- c = (mDNSu8)*cstr++; // just use the second character
- else if (mdnsIsDigit(cstr[0]) && mdnsIsDigit(cstr[1]) && mdnsIsDigit(cstr[2]))
- { // else, if three decimal digits,
- int v0 = cstr[0] - '0'; // then interpret as three-digit decimal
- int v1 = cstr[1] - '0';
- int v2 = cstr[2] - '0';
+ c = (mDNSu8)*cstr++; // Assume we'll just take the next character
+ if (mdnsIsDigit(cstr[-1]) && mdnsIsDigit(cstr[0]) && mdnsIsDigit(cstr[1]))
+ { // If three decimal digits,
+ int v0 = cstr[-1] - '0'; // then interpret as three-digit decimal
+ int v1 = cstr[ 0] - '0';
+ int v2 = cstr[ 1] - '0';
int val = v0 * 100 + v1 * 10 + v2;
- if (val <= 255) { c = (mDNSu8)val; cstr += 3; } // If valid value, use it
+ if (val <= 255) { c = (mDNSu8)val; cstr += 2; } // If valid three-digit decimal value, use it
}
}
*ptr++ = c; // Write the character
// In the case where there is no name (and ONLY in that case),
// a single-label subtype is allowed as the first label of a three-part "type"
- if (!name)
+ if (!name && type)
{
- const mDNSu8 *s2 = type->c + 1 + type->c[0];
- if (type->c[0] > 0 && type->c[0] < 0x40 &&
- s2[0] > 0 && s2[0] < 0x40 &&
- s2[1+s2[0]] > 0 && s2[1+s2[0]] < 0x40)
+ const mDNSu8 *s0 = type->c;
+ if (s0[0] && s0[0] < 0x40) // If legal first label (at least one character, and no more than 63)
{
- name = (domainlabel *)type;
- type = (domainname *)s2;
+ const mDNSu8 * s1 = s0 + 1 + s0[0];
+ if (s1[0] && s1[0] < 0x40) // and legal second label (at least one character, and no more than 63)
+ {
+ const mDNSu8 *s2 = s1 + 1 + s1[0];
+ if (s2[0] && s2[0] < 0x40 && s2[1+s2[0]] == 0) // and we have three and only three labels
+ {
+ static const mDNSu8 SubTypeLabel[5] = "\x04_sub";
+ src = s0; // Copy the first label
+ len = *src;
+ for (i=0; i <= len; i++) *dst++ = *src++;
+ for (i=0; i < (int)sizeof(SubTypeLabel); i++) *dst++ = SubTypeLabel[i];
+ type = (domainname *)s1;
+
+ // Special support for queries done by older versions of "Rendezvous Browser"
+ // For these queries, we retract the "._sub" we just added between the subtype and the main type
+ if (SameDomainName((domainname*)s0, (domainname*)"\x09_services\x07_dns-sd\x04_udp") ||
+ SameDomainName((domainname*)s0, (domainname*)"\x09_services\x05_mdns\x04_udp"))
+ dst -= sizeof(SubTypeLabel);
+ }
+ }
}
}
}
else
name = (domainlabel*)""; // Set this up to be non-null, to avoid errors if we have to call LogMsg() below
-
+
src = type->c; // Put the service type into the domain name
len = *src;
- if (len < 2 || len >= 0x40) { errormsg="Invalid service application protocol name"; goto fail; }
- if (src[1] != '_') { errormsg="Service application protocol name must begin with underscore"; goto fail; }
+ if (len < 2 || len >= 0x40 || (len > 15 && !SameDomainName(domain, (domainname*)"\x05" "local")))
+ {
+ errormsg="Application protocol name must be underscore plus 1-14 characters. See <http://www.dns-sd.org/ServiceTypes.html>";
+ goto fail;
+ }
+ if (src[1] != '_') { errormsg="Application protocol name must begin with underscore"; goto fail; }
for (i=2; i<=len; i++)
if (!mdnsIsLetter(src[i]) && !mdnsIsDigit(src[i]) && src[i] != '-' && src[i] != '_')
- { errormsg="Service application protocol name must contain only letters, digits, and hyphens"; goto fail; }
+ { errormsg="Application protocol name must contain only letters, digits, and hyphens"; goto fail; }
for (i=0; i<=len; i++) *dst++ = *src++;
len = *src;
- //if (len == 0 || len >= 0x40) { errormsg="Invalid service transport protocol name"; goto fail; }
if (!(len == 4 && src[1] == '_' &&
(((src[2] | 0x20) == 'u' && (src[3] | 0x20) == 'd') || ((src[2] | 0x20) == 't' && (src[3] | 0x20) == 'c')) &&
(src[4] | 0x20) == 'p'))
- { errormsg="Service transport protocol name must be _udp or _tcp"; goto fail; }
+ { errormsg="Transport protocol name must be _udp or _tcp"; goto fail; }
for (i=0; i<=len; i++) *dst++ = *src++;
-
+
if (*src) { errormsg="Service type must have only two labels"; goto fail; }
-
+
*dst = 0;
dst = AppendDomainName(fqdn, domain);
if (!dst) { errormsg="Service domain too long"; goto fail; }
return(responseptr);
}
+mDNSlocal mDNSBool AddressIsLocalSubnet(mDNS *const m, const mDNSInterfaceID InterfaceID, const mDNSAddr *addr)
+ {
+ NetworkInterfaceInfo *intf;
+
+ if (addr->type == mDNSAddrType_IPv4)
+ {
+ if (addr->ip.v4.b[0] == 169 && addr->ip.v4.b[1] == 254) return(mDNStrue);
+ for (intf = m->HostInterfaces; intf; intf = intf->next)
+ if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID)
+ if (((intf->ip.ip.v4.NotAnInteger ^ addr->ip.v4.NotAnInteger) & intf->mask.ip.v4.NotAnInteger) == 0)
+ return(mDNStrue);
+ }
+
+ if (addr->type == mDNSAddrType_IPv6)
+ {
+ if (addr->ip.v6.b[0] == 0xFE && addr->ip.v6.b[1] == 0x80) return(mDNStrue);
+ for (intf = m->HostInterfaces; intf; intf = intf->next)
+ if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID)
+ if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
+ (((intf->ip.ip.v6.l[1] ^ addr->ip.v6.l[1]) & intf->mask.ip.v6.l[1]) == 0) &&
+ (((intf->ip.ip.v6.l[2] ^ addr->ip.v6.l[2]) & intf->mask.ip.v6.l[2]) == 0) &&
+ (((intf->ip.ip.v6.l[3] ^ addr->ip.v6.l[3]) & intf->mask.ip.v6.l[3]) == 0))
+ return(mDNStrue);
+ }
+
+ return(mDNSfalse);
+ }
+
mDNSlocal void mDNSCoreReceiveQuery(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *srcaddr, const mDNSIPPort srcport, const mDNSAddr *dstaddr, mDNSIPPort dstport,
const mDNSInterfaceID InterfaceID)
{
- DNSMessage response;
- const mDNSu8 *responseend = mDNSNULL;
-
- verbosedebugf("Received Query from %#-15a:%d to %#-15a:%d on 0x%.8X with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
- srcaddr, (mDNSu16)srcport.b[0]<<8 | srcport.b[1],
- dstaddr, (mDNSu16)dstport.b[0]<<8 | dstport.b[1],
- InterfaceID,
- msg->h.numQuestions, msg->h.numQuestions == 1 ? ", " : "s,",
- msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
- msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
- msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s");
-
- responseend = ProcessQuery(m, msg, end, srcaddr, InterfaceID,
- (srcport.NotAnInteger != MulticastDNSPort.NotAnInteger), mDNSAddrIsDNSMulticast(dstaddr), &response);
-
- if (responseend) // If responseend is non-null, that means we built a unicast response packet
+ if (mDNSAddrIsDNSMulticast(dstaddr) || AddressIsLocalSubnet(m, InterfaceID, srcaddr))
{
- debugf("Unicast Response: %d Question%s, %d Answer%s, %d Additional%s to %#-15a:%d on %p/%ld",
- response.h.numQuestions, response.h.numQuestions == 1 ? "" : "s",
- response.h.numAnswers, response.h.numAnswers == 1 ? "" : "s",
- response.h.numAdditionals, response.h.numAdditionals == 1 ? "" : "s",
- srcaddr, (mDNSu16)srcport.b[0]<<8 | srcport.b[1], InterfaceID, srcaddr->type);
- mDNSSendDNSMessage(m, &response, responseend, InterfaceID, dstport, srcaddr, srcport);
+ DNSMessage response;
+ const mDNSu8 *responseend = mDNSNULL;
+
+ verbosedebugf("Received Query from %#-15a:%d to %#-15a:%d on 0x%.8X with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
+ srcaddr, (mDNSu16)srcport.b[0]<<8 | srcport.b[1],
+ dstaddr, (mDNSu16)dstport.b[0]<<8 | dstport.b[1],
+ InterfaceID,
+ msg->h.numQuestions, msg->h.numQuestions == 1 ? ", " : "s,",
+ msg->h.numAnswers, msg->h.numAnswers == 1 ? ", " : "s,",
+ msg->h.numAuthorities, msg->h.numAuthorities == 1 ? "y, " : "ies,",
+ msg->h.numAdditionals, msg->h.numAdditionals == 1 ? "" : "s");
+
+ responseend = ProcessQuery(m, msg, end, srcaddr, InterfaceID,
+ (srcport.NotAnInteger != MulticastDNSPort.NotAnInteger), mDNSAddrIsDNSMulticast(dstaddr), &response);
+
+ if (responseend) // If responseend is non-null, that means we built a unicast response packet
+ {
+ debugf("Unicast Response: %d Question%s, %d Answer%s, %d Additional%s to %#-15a:%d on %p/%ld",
+ response.h.numQuestions, response.h.numQuestions == 1 ? "" : "s",
+ response.h.numAnswers, response.h.numAnswers == 1 ? "" : "s",
+ response.h.numAdditionals, response.h.numAdditionals == 1 ? "" : "s",
+ srcaddr, (mDNSu16)srcport.b[0]<<8 | srcport.b[1], InterfaceID, srcaddr->type);
+ mDNSSendDNSMessage(m, &response, responseend, InterfaceID, dstport, srcaddr, srcport);
+ }
}
}
// Any code walking either list must use the CurrentQuestion and/or CurrentRecord mechanism to protect against this.
mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
const DNSMessage *const response, const mDNSu8 *end, const mDNSAddr *srcaddr, const mDNSAddr *dstaddr,
- const mDNSInterfaceID InterfaceID, mDNSu8 ttl)
+ const mDNSInterfaceID InterfaceID)
{
int i;
const mDNSu8 *ptr = LocateAnswers(response, end); // We ignore questions (if any) in a DNS response packet
(void)srcaddr; // Currently used only for display in debugging message
- verbosedebugf("Received Response from %#-15a addressed to %#-15a on %p TTL %d with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
- srcaddr, dstaddr, InterfaceID, ttl,
+ verbosedebugf("Received Response from %#-15a addressed to %#-15a on %p with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
+ srcaddr, dstaddr, InterfaceID,
response->h.numQuestions, response->h.numQuestions == 1 ? ", " : "s,",
response->h.numAnswers, response->h.numAnswers == 1 ? ", " : "s,",
response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
response->h.numAdditionals, response->h.numAdditionals == 1 ? "" : "s");
- // TTL should be 255
- // In the case of overlayed subnets that aren't using RFC 3442, some packets may incorrectly
- // go to the router first and then come back with a TTL of 254, so we allow that too.
- // Anything lower than 254 is a pretty good sign of an off-net spoofing attack.
- // Also, if we get a unicast response when we weren't expecting one, then we assume it is someone trying to spoof us
- if (ttl < 254 || (!mDNSAddrIsDNSMulticast(dstaddr) && (mDNSu32)(m->timenow - m->ExpectUnicastResponse) > (mDNSu32)mDNSPlatformOneSecond))
- {
- debugf("** Ignored apparent spoof mDNS Response from %#-15a to %#-15a TTL %d on %p with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
- srcaddr, dstaddr, ttl, InterfaceID,
- response->h.numQuestions, response->h.numQuestions == 1 ? ", " : "s,",
- response->h.numAnswers, response->h.numAnswers == 1 ? ", " : "s,",
- response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
- response->h.numAdditionals, response->h.numAdditionals == 1 ? "" : "s");
- return;
- }
+ // If we get a unicast response when we weren't expecting one, then we assume it is someone trying to spoof us
+ if (!mDNSAddrIsDNSMulticast(dstaddr))
+ if (!AddressIsLocalSubnet(m, InterfaceID, srcaddr) || (mDNSu32)(m->timenow - m->ExpectUnicastResponse) > (mDNSu32)(mDNSPlatformOneSecond*2))
+ {
+ debugf("** Ignored apparent spoof mDNS Response from %#-15a to %#-15a on %p with %2d Question%s %2d Answer%s %2d Authorit%s %2d Additional%s",
+ srcaddr, dstaddr, InterfaceID,
+ response->h.numQuestions, response->h.numQuestions == 1 ? ", " : "s,",
+ response->h.numAnswers, response->h.numAnswers == 1 ? ", " : "s,",
+ response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
+ response->h.numAdditionals, response->h.numAdditionals == 1 ? "" : "s");
+ return;
+ }
for (i = 0; i < totalrecords && ptr && ptr < end; i++)
{
mDNSexport void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *const dstaddr, const mDNSIPPort dstport,
- const mDNSInterfaceID InterfaceID, mDNSu8 ttl)
+ const mDNSInterfaceID InterfaceID, mDNSu8 unusedttl)
{
const mDNSu8 StdQ = kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery;
const mDNSu8 StdR = kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery;
const mDNSu8 QR_OP = (mDNSu8)(msg->h.flags.b[0] & kDNSFlag0_QROP_Mask);
+ (void)unusedttl;
+
// Read the integer parts which are in IETF byte-order (MSB first, LSB second)
mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
msg->h.numQuestions = (mDNSu16)((mDNSu16)ptr[0] << 8 | ptr[1]);
mDNS_Lock(m);
if (QR_OP == StdQ) mDNSCoreReceiveQuery (m, msg, end, srcaddr, srcport, dstaddr, dstport, InterfaceID);
- else if (QR_OP == StdR) mDNSCoreReceiveResponse(m, msg, end, srcaddr, dstaddr, InterfaceID, ttl);
+ else if (QR_OP == StdR) mDNSCoreReceiveResponse(m, msg, end, srcaddr, dstaddr, InterfaceID);
else debugf("Unknown DNS packet type %02X%02X (ignored)", msg->h.flags.b[0], msg->h.flags.b[1]);
// Packet reception often causes a change to the task list:
if (result == mStatus_MemFree)
{
- // If the PTR record or any of the subtype PTR record are still in the process of deregistering,
+ // If the PTR record or any of the subtype PTR records are still in the process of deregistering,
// don't pass on the NameConflict/MemFree message until every record is finished cleaning up.
mDNSu32 i;
if (sr->RR_PTR.resrec.RecordType != kDNSRecordTypeUnregistered) return;
// already set the first label of the record name to the subtype being registered
for (i=0; i<NumSubTypes; i++)
{
- domainlabel s = *(domainlabel*)&sr->SubTypes[i].resrec.name;
+ domainname st;
+ AssignDomainName(st, sr->SubTypes[i].resrec.name);
+ st.c[1+st.c[0]] = 0; // Only want the first label, not the whole FQDN (particularly for mDNS_RenameAndReregisterService())
+ AppendDomainName(&st, type);
mDNS_SetupResourceRecord(&sr->SubTypes[i], mDNSNULL, InterfaceID, kDNSType_PTR, kDefaultTTLforShared, kDNSRecordTypeShared, ServiceCallback, sr);
- if (ConstructServiceName(&sr->SubTypes[i].resrec.name, &s, type, domain) == mDNSNULL) return(mStatus_BadParamErr);
+ if (ConstructServiceName(&sr->SubTypes[i].resrec.name, mDNSNULL, &st, domain) == mDNSNULL) return(mStatus_BadParamErr);
AssignDomainName(sr->SubTypes[i].resrec.rdata->u.name, sr->RR_SRV.resrec.name);
sr->SubTypes[i].Additional1 = &sr->RR_SRV;
sr->SubTypes[i].Additional2 = &sr->RR_TXT;
Change History (most recent first):
$Log: mDNSClientAPI.h,v $
+Revision 1.114.2.10 2005/01/28 05:02:05 cheshire
+<rdar://problem/3770559> SUPan: Replace IP TTL 255 check with local-subnet check
+
Revision 1.114.2.9 2004/04/22 03:17:35 cheshire
Fix use of "struct __attribute__((__packed__))" so it only applies on GCC >= 2.9
Added APSL info
Revision 1.24 2002/09/19 23:47:35 cheshire
-Added mDNS_RegisterNoSuchService() function for assertion of non-existance
+Added mDNS_RegisterNoSuchService() function for assertion of non-existence
of a particular named service
Revision 1.23 2002/09/19 21:25:34 cheshire
// Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface()
mDNSInterfaceID InterfaceID;
mDNSAddr ip;
+ mDNSAddr mask;
+ char ifname[16];
mDNSBool Advertise; // Set Advertise to false if you are only searching on this interface
mDNSBool TxAndRx; // Set to false if not sending and receiving packets on this interface
};
extern char *GetRRDisplayString_rdb(mDNS *const m, const ResourceRecord *rr, RDataBody *rd);
#define GetRRDisplayString(m, rr) GetRRDisplayString_rdb((m), &(rr)->resrec, &(rr)->resrec.rdata->u)
extern mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2);
+extern mDNSBool mDNSAddrIsDNSMulticast(const mDNSAddr *ip);
extern void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText);
// ***************************************************************************
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: mDNSEmbeddedAPI.h,v $
+Revision 1.114.2.9 2004/04/22 03:17:35 cheshire
+Fix use of "struct __attribute__((__packed__))" so it only applies on GCC >= 2.9
+
+Revision 1.114.2.8 2004/03/30 06:55:37 cheshire
+Gave name to anonymous struct, to avoid errors on certain compilers.
+(Thanks to ramaprasad.kr@hp.com for reporting this.)
+
+Revision 1.114.2.7 2004/03/09 02:31:27 cheshire
+Remove erroneous underscore in 'packed_struct' (makes no difference now, but might in future)
+
+Revision 1.114.2.6 2004/03/02 02:55:25 cheshire
+<rdar://problem/3549576> Properly support "_services._dns-sd._udp" meta-queries
+
+Revision 1.114.2.5 2004/02/18 23:35:17 cheshire
+<rdar://problem/3488559>: Hard code domain enumeration functions to return ".local" only
+Also make mDNS_StopGetDomains() a no-op too, so that we don't get warning messages in syslog
+
+Revision 1.114.2.4 2004/01/28 23:29:20 cheshire
+Fix structure packing (only affects third-party Darwin developers)
+
+Revision 1.114.2.3 2003/12/05 00:03:34 cheshire
+<rdar://problem/3487869> Use buffer size MAX_ESCAPED_DOMAIN_NAME instead of 256
+
+Revision 1.114.2.2 2003/12/04 23:30:00 cheshire
+Add "#define MAX_ESCAPED_DOMAIN_NAME 1005", needed for Posix folder to build
+
+Revision 1.114.2.1 2003/12/03 11:07:58 cheshire
+<rdar://problem/3457718>: Stop and start of a service uses old ip address (with old port number)
+
+Revision 1.114 2003/08/29 19:44:15 cheshire
+<rdar://problem/3400967> Traffic reduction: Eliminate synchronized QUs when a new service appears
+1. Use m->RandomQueryDelay to impose a random delay in the range 0-500ms on queries
+ that already have at least one unique answer in the cache
+2. For these queries, go straight to QM, skipping QU
+
+Revision 1.113 2003/08/21 19:31:58 cheshire
+Cosmetic: Swap order of fields
+
+Revision 1.112 2003/08/21 19:27:36 cheshire
+<rdar://problem/3387878> Traffic reduction: No need to announce record for longer than TTL
+
+Revision 1.111 2003/08/21 02:21:50 cheshire
+<rdar://problem/3386473> Efficiency: Reduce repeated queries
+
+Revision 1.110 2003/08/20 23:39:31 cheshire
+<rdar://problem/3344098> Review syslog messages, and remove as appropriate
+
+Revision 1.109 2003/08/19 22:24:10 cheshire
+Comment change
+
+Revision 1.108 2003/08/19 22:20:00 cheshire
+<rdar://problem/3376721> Don't use IPv6 on interfaces that have a routable IPv4 address configured
+More minor refinements
+
+Revision 1.107 2003/08/19 06:48:25 cheshire
+<rdar://problem/3376552> Guard against excessive record updates
+Each record starts with 10 UpdateCredits.
+Every update consumes one UpdateCredit.
+UpdateCredits are replenished at a rate of one one per minute, up to a maximum of 10.
+As the number of UpdateCredits declines, the number of announcements is similarly scaled back.
+When fewer than 5 UpdateCredits remain, the first announcement is also delayed by an increasing amount.
+
+Revision 1.106 2003/08/19 04:49:28 cheshire
+<rdar://problem/3368159> Interaction between v4, v6 and dual-stack hosts not working quite right
+1. A dual-stack host should only suppress its own query if it sees the same query from other hosts on BOTH IPv4 and IPv6.
+2. When we see the first v4 (or first v6) member of a group, we re-trigger questions and probes on that interface.
+3. When we see the last v4 (or v6) member of a group go away, we revalidate all the records received on that interface.
+
+Revision 1.105 2003/08/19 02:33:37 cheshire
+Update comments
+
+Revision 1.104 2003/08/19 02:31:11 cheshire
+<rdar://problem/3378386> mDNSResponder overenthusiastic with final expiration queries
+Final expiration queries now only mark the question for sending on the particular interface
+pertaining to the record that's expiring.
+
+Revision 1.103 2003/08/18 19:05:44 cheshire
+<rdar://problem/3382423> UpdateRecord not working right
+Added "newrdlength" field to hold new length of updated rdata
+
+Revision 1.102 2003/08/16 03:39:00 cheshire
+<rdar://problem/3338440> InterfaceID -1 indicates "local only"
+
+Revision 1.101 2003/08/15 20:16:02 cheshire
+<rdar://problem/3366590> mDNSResponder takes too much RPRVT
+We want to avoid touching the rdata pages, so we don't page them in.
+1. RDLength was stored with the rdata, which meant touching the page just to find the length.
+ Moved this from the RData to the ResourceRecord object.
+2. To avoid unnecessarily touching the rdata just to compare it,
+ compute a hash of the rdata and store the hash in the ResourceRecord object.
+
+Revision 1.100 2003/08/14 19:29:04 cheshire
+<rdar://problem/3378473> Include cache records in SIGINFO output
+Moved declarations of DNSTypeName() and GetRRDisplayString to mDNSEmbeddedAPI.h so daemon.c can use them
+
+Revision 1.99 2003/08/14 02:17:05 cheshire
+<rdar://problem/3375491> Split generic ResourceRecord type into two separate types: AuthRecord and CacheRecord
+
+Revision 1.98 2003/08/12 19:56:23 cheshire
+Update to APSL 2.0
+
+Revision 1.97 2003/08/12 14:59:27 cheshire
+<rdar://problem/3374490> Rate-limiting blocks some legitimate responses
+When setting LastMCTime also record LastMCInterface. When checking LastMCTime to determine
+whether to suppress the response, also check LastMCInterface to see if it matches.
+
+Revision 1.96 2003/08/12 13:57:04 cheshire
+<rdar://problem/3323817> Improve cache performance
+Changed the number of hash table slots from 37 to 499
+
+Revision 1.95 2003/08/09 00:55:02 cheshire
+<rdar://problem/3366553> mDNSResponder is taking 20-30% of the CPU
+Don't scan the whole cache after every packet.
+
+Revision 1.94 2003/08/09 00:35:29 cheshire
+
+Revision 1.93 2003/08/08 18:55:48 cheshire
+<rdar://problem/3370365> Guard against time going backwards
+
+Revision 1.92 2003/08/08 18:36:04 cheshire
+<rdar://problem/3344154> Only need to revalidate on interface removal on platforms that have the PhantomInterfaces bug
+
+Revision 1.91 2003/08/06 21:33:39 cheshire
+Fix compiler warnings on PocketPC 2003 (Windows CE)
+
+Revision 1.90 2003/08/06 20:30:17 cheshire
+Add structure definition for rdataMX (not currently used, but good to have it for completeness)
+
+Revision 1.89 2003/08/06 18:58:19 cheshire
+Update comments
+
+Revision 1.88 2003/07/24 23:45:44 cheshire
+To eliminate compiler warnings, changed definition of mDNSBool from
+"unsigned char" to "int", since "int" is in fact truly the type that C uses
+for the result of comparison operators (a<b) and logical operators (a||b)
+
+Revision 1.87 2003/07/22 23:57:20 cheshire
+Move platform-layer function prototypes from mDNSEmbeddedAPI.h to mDNSPlatformFunctions.h where they belong
+
+Revision 1.86 2003/07/20 03:52:02 ksekar
+Bug #: <rdar://problem/3320722>: Feature: New Rendezvous APIs (#7875) (mDNSResponder component)
+Added error type for incompatibility between daemon and client versions
+
+Revision 1.85 2003/07/19 03:23:13 cheshire
+<rdar://problem/2986147> mDNSResponder needs to receive and cache larger records
+
+Revision 1.84 2003/07/18 23:52:12 cheshire
+To improve consistency of field naming, global search-and-replace:
+NextProbeTime -> NextScheduledProbe
+NextResponseTime -> NextScheduledResponse
+
+Revision 1.83 2003/07/18 00:29:59 cheshire
+<rdar://problem/3268878> Remove mDNSResponder version from packet header and use HINFO record instead
+
+Revision 1.82 2003/07/17 17:35:04 cheshire
+<rdar://problem/3325583> Rate-limit responses, to guard against packet flooding
+
+Revision 1.81 2003/07/16 05:01:36 cheshire
+Add fields 'LargeAnswers' and 'ExpectUnicastResponse' in preparation for
+<rdar://problem/3315761> Need to implement "unicast response" request, using top bit of qclass
+
+Revision 1.80 2003/07/15 01:55:12 cheshire
+<rdar://problem/3315777> Need to implement service registration with subtypes
+
+Revision 1.79 2003/07/13 02:28:00 cheshire
+<rdar://problem/3325166> SendResponses didn't all its responses
+Delete all references to RRInterfaceActive -- it's now superfluous
+
+Revision 1.78 2003/07/13 01:47:53 cheshire
+Fix one error and one warning in the Windows build
+
+Revision 1.77 2003/07/11 01:32:38 cheshire
+Syntactic cleanup (no change to funcationality): Now that we only have one host name,
+rename field "hostname1" to "hostname", and field "RR_A1" to "RR_A".
+
+Revision 1.76 2003/07/11 01:28:00 cheshire
+<rdar://problem/3161289> No more local.arpa
+
+Revision 1.75 2003/07/02 21:19:45 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.74 2003/07/02 02:41:23 cheshire
+<rdar://problem/2986146> mDNSResponder needs to start with a smaller cache and then grow it as needed
+
+Revision 1.73 2003/06/10 04:24:39 cheshire
+<rdar://problem/3283637> React when we observe other people query unsuccessfully for a record that's in our cache
+Some additional refinements:
+Don't try to do this for unicast-response queries
+better tracking of Qs and KAs in multi-packet KA lists
+
+Revision 1.72 2003/06/10 01:46:27 cheshire
+Add better comments explaining how these data structures are intended to be used from the client layer
+
+Revision 1.71 2003/06/07 06:45:05 cheshire
+<rdar://problem/3283666> No need for multiple machines to all be sending the same queries
+
+Revision 1.70 2003/06/07 04:50:53 cheshire
+<rdar://problem/3283637> React when we observe other people query unsuccessfully for a record that's in our cache
+
+Revision 1.69 2003/06/07 04:22:17 cheshire
+Add MsgBuffer for error log and debug messages
+
+Revision 1.68 2003/06/07 01:46:38 cheshire
+<rdar://problem/3283540> When query produces zero results, call mDNS_Reconfirm() on any antecedent records
+
+Revision 1.67 2003/06/07 01:22:14 cheshire
+<rdar://problem/3283516> mDNSResponder needs an mDNS_Reconfirm() function
+
+Revision 1.66 2003/06/07 00:59:43 cheshire
+<rdar://problem/3283454> Need some randomness to spread queries on the network
+
+Revision 1.65 2003/06/06 21:41:11 cheshire
+For consistency, mDNS_StopQuery() should return an mStatus result, just like all the other mDNSCore routines
+
+Revision 1.64 2003/06/06 21:38:55 cheshire
+Renamed 'NewData' as 'FreshData' (The data may not be new data, just a refresh of data that we
+already had in our cache. This refreshes our TTL on the data, but the data itself stays the same.)
+
+Revision 1.63 2003/06/06 17:20:14 cheshire
+For clarity, rename question fields name/rrtype/rrclass as qname/qtype/qclass
+(Global search-and-replace; no functional change to code execution.)
+
+Revision 1.62 2003/06/04 01:25:33 cheshire
+<rdar://problem/3274950> Cannot perform multi-packet known-answer suppression messages
+Display time interval between first and subsequent queries
+
+Revision 1.61 2003/06/03 05:02:16 cheshire
+<rdar://problem/3277080> Duplicate registrations not handled as efficiently as they should be
+
+Revision 1.60 2003/05/31 00:09:49 cheshire
+<rdar://problem/3274862> Add ability to discover what services are on a network
+
+Revision 1.59 2003/05/29 06:11:35 cheshire
+<rdar://problem/3272214>: Report if there appear to be too many "Resolve" callbacks
+
+Revision 1.58 2003/05/29 05:48:06 cheshire
+Minor fix for when generating printf warnings: mDNS_snprintf arguments are now 3,4
+
+Revision 1.57 2003/05/26 03:21:27 cheshire
+Tidy up address structure naming:
+mDNSIPAddr => mDNSv4Addr (for consistency with mDNSv6Addr)
+mDNSAddr.addr.ipv4 => mDNSAddr.ip.v4
+mDNSAddr.addr.ipv6 => mDNSAddr.ip.v6
+
+Revision 1.56 2003/05/26 03:01:27 cheshire
+<rdar://problem/3268904> sprintf/vsprintf-style functions are unsafe; use snprintf/vsnprintf instead
+
+Revision 1.55 2003/05/26 00:47:30 cheshire
+Comment clarification
+
+Revision 1.54 2003/05/24 16:39:48 cheshire
+<rdar://problem/3268631> SendResponses also needs to handle multihoming better
+
+Revision 1.53 2003/05/23 02:15:37 cheshire
+Fixed misleading use of the term "duplicate suppression" where it should have
+said "known answer suppression". (Duplicate answer suppression is something
+different, and duplicate question suppression is yet another thing, so the use
+of the completely vague term "duplicate suppression" was particularly bad.)
+
+Revision 1.52 2003/05/22 02:29:22 cheshire
+<rdar://problem/2984918> SendQueries needs to handle multihoming better
+Complete rewrite of SendQueries. Works much better now :-)
+
+Revision 1.51 2003/05/21 20:14:55 cheshire
+Fix comments and warnings
+
+Revision 1.50 2003/05/14 07:08:36 cheshire
+<rdar://problem/3159272> mDNSResponder should be smarter about reconfigurations
+Previously, when there was any network configuration change, mDNSResponder
+would tear down the entire list of active interfaces and start again.
+That was very disruptive, and caused the entire cache to be flushed,
+and caused lots of extra network traffic. Now it only removes interfaces
+that have really gone, and only adds new ones that weren't there before.
+
+Revision 1.49 2003/05/07 01:49:36 cheshire
+Remove "const" in ConstructServiceName prototype
+
+Revision 1.48 2003/05/07 00:18:44 cheshire
+Fix typo: "kDNSQClass_Mask" should be "kDNSClass_Mask"
+
+Revision 1.47 2003/05/06 00:00:46 cheshire
+<rdar://problem/3248914> Rationalize naming of domainname manipulation functions
+
+Revision 1.46 2003/04/30 20:39:09 cheshire
+Add comment
+
+Revision 1.45 2003/04/29 00:40:50 cheshire
+Fix compiler warnings
+
+Revision 1.44 2003/04/26 02:41:56 cheshire
+<rdar://problem/3241281> Change timenow from a local variable to a structure member
+
+Revision 1.43 2003/04/25 01:45:56 cheshire
+<rdar://problem/3240002> mDNS_RegisterNoSuchService needs to include a host name
+
+Revision 1.42 2003/04/15 20:58:31 jgraessl
+
+Bug #: 3229014
+Added a hash to lookup records in the cache.
+
+Revision 1.41 2003/04/15 18:09:13 jgraessl
+
+Bug #: 3228892
+Reviewed by: Stuart Cheshire
+Added code to keep track of when the next cache item will expire so we can
+call TidyRRCache only when necessary.
+
+Revision 1.40 2003/03/29 01:55:19 cheshire
+<rdar://problem/3212360> mDNSResponder sometimes suffers false self-conflicts when it sees its own packets
+Solution: Major cleanup of packet timing and conflict handling rules
+
+Revision 1.39 2003/03/27 03:30:55 cheshire
+<rdar://problem/3210018> Name conflicts not handled properly, resulting in memory corruption, and eventual crash
+Problem was that HostNameCallback() was calling mDNS_DeregisterInterface(), which is not safe in a callback
+Fixes:
+1. Make mDNS_DeregisterInterface() safe to call from a callback
+2. Make HostNameCallback() use mDNS_DeadvertiseInterface() instead
+ (it never really needed to deregister the interface at all)
+
+Revision 1.38 2003/03/15 04:40:36 cheshire
+Change type called "mDNSOpaqueID" to the more descriptive name "mDNSInterfaceID"
+
+Revision 1.37 2003/03/14 21:34:11 cheshire
+<rdar://problem/3176950> Can't setup and print to Lexmark PS printers via Airport Extreme
+Increase size of cache rdata from 512 to 768
+
+Revision 1.36 2003/03/05 03:38:35 cheshire
+Bug #: 3185731 Bogus error message in console: died or deallocated, but no record of client can be found!
+Fixed by leaving client in list after conflict, until client explicitly deallocates
+
+Revision 1.35 2003/02/21 02:47:54 cheshire
+Bug #: 3099194 mDNSResponder needs performance improvements
+Several places in the code were calling CacheRRActive(), which searched the entire
+question list every time, to see if this cache resource record answers any question.
+Instead, we now have a field "CRActiveQuestion" in the resource record structure
+
+Revision 1.34 2003/02/21 01:54:08 cheshire
+Bug #: 3099194 mDNSResponder needs performance improvements
+Switched to using new "mDNS_Execute" model (see "Implementer Notes.txt")
+
+Revision 1.33 2003/02/20 06:48:32 cheshire
+Bug #: 3169535 Xserve RAID needs to do interface-specific registrations
+Reviewed by: Josh Graessley, Bob Bradley
+
+Revision 1.32 2003/01/31 03:35:59 cheshire
+Bug #: 3147097 mDNSResponder sometimes fails to find the correct results
+When there were *two* active questions in the list, they were incorrectly
+finding *each other* and *both* being marked as duplicates of another question
+
+Revision 1.31 2003/01/29 02:46:37 cheshire
+Fix for IPv6:
+A physical interface is identified solely by its InterfaceID (not by IP and type).
+On a given InterfaceID, mDNSCore may send both v4 and v6 multicasts.
+In cases where the requested outbound protocol (v4 or v6) is not supported on
+that InterfaceID, the platform support layer should simply discard that packet.
+
+Revision 1.30 2003/01/29 01:47:08 cheshire
+Rename 'Active' to 'CRActive' or 'InterfaceActive' for improved clarity
+
+Revision 1.29 2003/01/28 05:23:43 cheshire
+Bug #: 3147097 mDNSResponder sometimes fails to find the correct results
+Add 'Active' flag for interfaces
+
+Revision 1.28 2003/01/28 01:35:56 cheshire
+Revise comment about ThisQInterval to reflect new semantics
+
+Revision 1.27 2003/01/13 23:49:42 jgraessl
+Merged changes for the following fixes in to top of tree:
+3086540 computer name changes not handled properly
+3124348 service name changes are not properly handled
+3124352 announcements sent in pairs, failing chattiness test
+
+Revision 1.26 2002/12/23 22:13:28 jgraessl
+
+Reviewed by: Stuart Cheshire
+Initial IPv6 support for mDNSResponder.
+
+Revision 1.25 2002/09/21 20:44:49 zarzycki
+Added APSL info
+
+Revision 1.24 2002/09/19 23:47:35 cheshire
+Added mDNS_RegisterNoSuchService() function for assertion of non-existence
+of a particular named service
+
+Revision 1.23 2002/09/19 21:25:34 cheshire
+mDNS_snprintf() doesn't need to be in a separate file
+
+Revision 1.22 2002/09/19 04:20:43 cheshire
+Remove high-ascii characters that confuse some systems
+
+Revision 1.21 2002/09/17 01:06:35 cheshire
+Change mDNS_AdvertiseLocalAddresses to be a parameter to mDNS_Init()
+
+Revision 1.20 2002/09/16 18:41:41 cheshire
+Merge in license terms from Quinn's copy, in preparation for Darwin release
+
+*/
+
+#ifndef __mDNSClientAPI_h
+#define __mDNSClientAPI_h
+
+#include <stdarg.h> // stdarg.h is required for for va_list support for the mDNS_vsnprintf declaration
+#include "mDNSDebug.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// ***************************************************************************
+// Function scope indicators
+
+// If you see "mDNSlocal" before a function name in a C file, it means the function is not callable outside this file
+#ifndef mDNSlocal
+#define mDNSlocal static
+#endif
+// If you see "mDNSexport" before a symbol in a C file, it means the symbol is exported for use by clients
+// For every "mDNSexport" in a C file, there needs to be a corresponding "extern" declaration in some header file
+// (When a C file #includes a header file, the "extern" declarations tell the compiler:
+// "This symbol exists -- but not necessarily in this C file.")
+#ifndef mDNSexport
+#define mDNSexport
+#endif
+
+// ***************************************************************************
+// Structure packing macro
+
+// If we're not using GNUC, it's not fatal.
+// Most compilers naturally pack the on-the-wire structures correctly anyway, so a plain "struct" is usually fine.
+// In the event that structures are not packed correctly, mDNS_Init() will detect this and report an error, so the
+// developer will know what's wrong, and can investigate what needs to be done on that compiler to provide proper packing.
+#ifndef packedstruct
+ #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
+ #define packedstruct struct __attribute__((__packed__))
+ #define packedunion union __attribute__((__packed__))
+ #else
+ #define packedstruct struct
+ #define packedunion union
+ #endif
+#endif
+
+// ***************************************************************************
+#if 0
+#pragma mark - DNS Resource Record class and type constants
+#endif
+
+typedef enum // From RFC 1035
+ {
+ kDNSClass_IN = 1, // Internet
+ kDNSClass_CS = 2, // CSNET
+ kDNSClass_CH = 3, // CHAOS
+ kDNSClass_HS = 4, // Hesiod
+ kDNSClass_NONE = 254, // Used in DNS UPDATE [RFC 2136]
+
+ kDNSClass_Mask = 0x7FFF,// Multicast DNS uses the bottom 15 bits to identify the record class...
+ kDNSClass_UniqueRRSet = 0x8000,// ... and the top bit indicates that all other cached records are now invalid
+
+ kDNSQClass_ANY = 255, // Not a DNS class, but a DNS query class, meaning "all classes"
+ kDNSQClass_UnicastResponse = 0x8000 // Top bit set in a question means "unicast response acceptable"
+ } DNS_ClassValues;
+
+typedef enum // From RFC 1035
+ {
+ kDNSType_A = 1, // 1 Address
+ kDNSType_NS, // 2 Name Server
+ kDNSType_MD, // 3 Mail Destination
+ kDNSType_MF, // 4 Mail Forwarder
+ kDNSType_CNAME, // 5 Canonical Name
+ kDNSType_SOA, // 6 Start of Authority
+ kDNSType_MB, // 7 Mailbox
+ kDNSType_MG, // 8 Mail Group
+ kDNSType_MR, // 9 Mail Rename
+ kDNSType_NULL, // 10 NULL RR
+ kDNSType_WKS, // 11 Well-known-service
+ kDNSType_PTR, // 12 Domain name pointer
+ kDNSType_HINFO, // 13 Host information
+ kDNSType_MINFO, // 14 Mailbox information
+ kDNSType_MX, // 15 Mail Exchanger
+ kDNSType_TXT, // 16 Arbitrary text string
+
+ kDNSType_AAAA = 28, // 28 IPv6 address
+ kDNSType_SRV = 33, // 33 Service record
+
+ kDNSQType_ANY = 255 // Not a DNS type, but a DNS query type, meaning "all types"
+ } DNS_TypeValues;
+
+// ***************************************************************************
+#if 0
+#pragma mark - Simple types
+#endif
+
+// mDNS defines its own names for these common types to simplify portability across
+// multiple platforms that may each have their own (different) names for these types.
+typedef int mDNSBool;
+typedef signed char mDNSs8;
+typedef unsigned char mDNSu8;
+typedef signed short mDNSs16;
+typedef unsigned short mDNSu16;
+#if _LP64
+typedef signed int mDNSs32;
+typedef unsigned int mDNSu32;
+#else
+typedef signed long mDNSs32;
+typedef unsigned long mDNSu32;
+#endif
+
+// To enforce useful type checking, we make mDNSInterfaceID be a pointer to a dummy struct
+// This way, mDNSInterfaceIDs can be assigned, and compared with each other, but not with other types
+// Declaring the type to be the typical generic "void *" would lack this type checking
+typedef struct mDNSInterfaceID_dummystruct { void *dummy; } *mDNSInterfaceID;
+
+// These types are for opaque two- and four-byte identifiers.
+// The "NotAnInteger" fields of the unions allow the value to be conveniently passed around in a
+// register for the sake of efficiency, and compared for equality or inequality, but don't forget --
+// just because it is in a register doesn't mean it is an integer. Operations like greater than,
+// less than, add, multiply, increment, decrement, etc., are undefined for opaque identifiers,
+// and if you make the mistake of trying to do those using the NotAnInteger field, then you'll
+// find you get code that doesn't work consistently on big-endian and little-endian machines.
+typedef packedunion { mDNSu8 b[2]; mDNSu16 NotAnInteger; } mDNSOpaque16;
+typedef packedunion { mDNSu8 b[4]; mDNSu32 NotAnInteger; } mDNSOpaque32;
+typedef packedunion { mDNSu8 b[16]; mDNSu16 w[8]; mDNSu32 l[4]; } mDNSOpaque128;
+
+typedef mDNSOpaque16 mDNSIPPort; // An IP port is a two-byte opaque identifier (not an integer)
+typedef mDNSOpaque32 mDNSv4Addr; // An IP address is a four-byte opaque identifier (not an integer)
+typedef mDNSOpaque128 mDNSv6Addr; // An IPv6 address is a 16-byte opaque identifier (not an integer)
+
+enum
+ {
+ mDNSAddrType_None = 0,
+ mDNSAddrType_IPv4 = 4,
+ mDNSAddrType_IPv6 = 6,
+ mDNSAddrType_Unknown = ~0 // Special marker value used in known answer list recording
+ };
+
+typedef struct
+ {
+ mDNSs32 type;
+ union { mDNSv6Addr v6; mDNSv4Addr v4; } ip;
+ } mDNSAddr;
+
+enum { mDNSfalse = 0, mDNStrue = 1 };
+
+#define mDNSNULL 0L
+
+enum
+ {
+ mStatus_Waiting = 1,
+ mStatus_NoError = 0,
+
+ // mDNS return values are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537)
+ // The top end of the range (FFFE FFFF) is used for error codes;
+ // the bottom end of the range (FFFE FF00) is used for non-error values;
+
+ // Error codes:
+ mStatus_UnknownErr = -65537, // 0xFFFE FFFF
+ mStatus_NoSuchNameErr = -65538,
+ mStatus_NoMemoryErr = -65539,
+ mStatus_BadParamErr = -65540,
+ mStatus_BadReferenceErr = -65541,
+ mStatus_BadStateErr = -65542,
+ mStatus_BadFlagsErr = -65543,
+ mStatus_UnsupportedErr = -65544,
+ mStatus_NotInitializedErr = -65545,
+ mStatus_NoCache = -65546,
+ mStatus_AlreadyRegistered = -65547,
+ mStatus_NameConflict = -65548,
+ mStatus_Invalid = -65549,
+ // = -65550,
+ mStatus_Incompatible = -65551,
+ mStatus_BadInterfaceErr = -65552,
+
+ // -65553 - -65789 currently unused
+
+ // Non-error values:
+ mStatus_GrowCache = -65790,
+ mStatus_ConfigChanged = -65791,
+ mStatus_MemFree = -65792 // 0xFFFE FF00
+ };
+
+typedef mDNSs32 mStatus;
+
+// RFC 1034/1035 specify that a domain label consists of a length byte plus up to 63 characters
+#define MAX_DOMAIN_LABEL 63
+typedef struct { mDNSu8 c[ 64]; } domainlabel; // One label: length byte and up to 63 characters
+
+// RFC 1034/1035 specify that a domain name, including length bytes, data bytes, and terminating zero, may be up to 255 bytes long
+#define MAX_DOMAIN_NAME 255
+typedef struct { mDNSu8 c[256]; } domainname; // Up to 255 bytes of length-prefixed domainlabels
+
+typedef struct { mDNSu8 c[256]; } UTF8str255; // Null-terminated C string
+
+// The longest legal textual form of a DNS name is 1005 bytes, including the C-string terminating NULL at the end.
+// Explanation:
+// When a native domainname object is converted to printable textual form using ConvertDomainNameToCString(),
+// non-printing characters are represented in the conventional DNS way, as '\ddd', where ddd is a three-digit decimal number.
+// The longest legal domain name is 255 bytes, in the form of four labels as shown below:
+// Length byte, 63 data bytes, length byte, 63 data bytes, length byte, 63 data bytes, length byte, 61 data bytes, zero byte.
+// Each label is encoded textually as characters followed by a trailing dot.
+// If every character has to be represented as a four-byte escape sequence, then this makes the maximum textual form four labels
+// plus the C-string terminating NULL as shown below:
+// 63*4+1 + 63*4+1 + 63*4+1 + 61*4+1 + 1 = 1005.
+// Note that MAX_ESCAPED_DOMAIN_LABEL is not normally used: If you're only decoding a single label, escaping is usually not required.
+// It is for domain names, where dots are used as label separators, that proper escaping is vital.
+#define MAX_ESCAPED_DOMAIN_LABEL 254
+#define MAX_ESCAPED_DOMAIN_NAME 1005
+
+// ***************************************************************************
+#if 0
+#pragma mark - Resource Record structures
+#endif
+
+// Authoritative Resource Records:
+// There are four basic types: Shared, Advisory, Unique, Known Unique
+
+// * Shared Resource Records do not have to be unique
+// -- Shared Resource Records are used for DNS-SD service PTRs
+// -- It is okay for several hosts to have RRs with the same name but different RDATA
+// -- We use a random delay on responses to reduce collisions when all the hosts respond to the same query
+// -- These RRs typically have moderately high TTLs (e.g. one hour)
+// -- These records are announced on startup and topology changes for the benefit of passive listeners
+// -- These records send a goodbye packet when deregistering
+//
+// * Advisory Resource Records are like Shared Resource Records, except they don't send a goodbye packet
+//
+// * Unique Resource Records should be unique among hosts within any given mDNS scope
+// -- The majority of Resource Records are of this type
+// -- If two entities on the network have RRs with the same name but different RDATA, this is a conflict
+// -- Responses may be sent immediately, because only one host should be responding to any particular query
+// -- These RRs typically have low TTLs (e.g. ten seconds)
+// -- On startup and after topology changes, a host issues queries to verify uniqueness
+
+// * Known Unique Resource Records are treated like Unique Resource Records, except that mDNS does
+// not have to verify their uniqueness because this is already known by other means (e.g. the RR name
+// is derived from the host's IP or Ethernet address, which is already known to be a unique identifier).
+
+// Summary of properties of different record types:
+// Probe? Does this record type send probes before announcing?
+// Conflict? Does this record type react if we observe an apparent conflict?
+// Goodbye? Does this record type send a goodbye packet on departure?
+//
+// Probe? Conflict? Goodbye? Notes
+// Unregistered Should not appear in any list (sanity check value)
+// Shared No No Yes e.g. Service PTR record
+// Deregistering No No Yes Shared record about to announce its departure and leave the list
+// Advisory No No No
+// Unique Yes Yes No Record intended to be unique -- will probe to verify
+// Verified Yes Yes No Record has completed probing, and is verified unique
+// KnownUnique No Yes No Record is assumed by other means to be unique
+
+// Valid lifecycle of a record:
+// Unregistered -> Shared -> Deregistering -(goodbye)-> Unregistered
+// Unregistered -> Advisory -> Unregistered
+// Unregistered -> Unique -(probe)-> Verified -> Unregistered
+// Unregistered -> KnownUnique -> Unregistered
+
+// Each Authoritative kDNSRecordType has only one bit set. This makes it easy to quickly see if a record
+// is one of a particular set of types simply by performing the appropriate bitwise masking operation.
+
+// Cache Resource Records (received from the network):
+// There are four basic types: Answer, Unique Answer, Additional, Unique Additional
+// Bit 7 (the top bit) of kDNSRecordType is always set for Cache Resource Records; always clear for Authoritative Resource Records
+// Bit 6 (value 0x40) is set for answer records; clear for additional records
+// Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
+
+enum
+ {
+ kDNSRecordTypeUnregistered = 0x00, // Not currently in any list
+ kDNSRecordTypeDeregistering = 0x01, // Shared record about to announce its departure and leave the list
+
+ kDNSRecordTypeUnique = 0x02, // Will become a kDNSRecordTypeVerified when probing is complete
+
+ kDNSRecordTypeAdvisory = 0x04, // Like Shared, but no goodbye packet
+ kDNSRecordTypeShared = 0x08, // Shared means record name does not have to be unique -- use random delay on responses
+ kDNSRecordTypeVerified = 0x10, // Unique means mDNS should check that name is unique (and then send immediate responses)
+ kDNSRecordTypeKnownUnique = 0x20, // Known Unique means mDNS can assume name is unique without checking
+
+ kDNSRecordTypeUniqueMask = (kDNSRecordTypeUnique | kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique),
+ kDNSRecordTypeActiveMask = (kDNSRecordTypeAdvisory | kDNSRecordTypeShared | kDNSRecordTypeVerified | kDNSRecordTypeKnownUnique),
+
+ kDNSRecordTypePacketAdd = 0x80, // Received in the Additional Section of a DNS Response
+ kDNSRecordTypePacketAddUnique = 0xA0, // Received in the Additional Section of a DNS Response with kDNSClass_UniqueRRSet set
+ kDNSRecordTypePacketAns = 0xC0, // Received in the Answer Section of a DNS Response
+ kDNSRecordTypePacketAnsUnique = 0xE0, // Received in the Answer Section of a DNS Response with kDNSClass_UniqueRRSet set
+
+ kDNSRecordTypePacketAnsMask = 0x40, // True for PacketAns and PacketAnsUnique
+ kDNSRecordTypePacketUniqueMask = 0x20 // True for PacketAddUnique and PacketAnsUnique
+ };
+
+typedef packedstruct { mDNSu16 priority; mDNSu16 weight; mDNSIPPort port; domainname target; } rdataSRV;
+typedef packedstruct { mDNSu16 preference; domainname exchange; } rdataMX;
+
+// StandardAuthRDSize is 264 (256+8), which is large enough to hold a maximum-sized SRV record
+// MaximumRDSize is 8K the absolute maximum we support (at least for now)
+#define StandardAuthRDSize 264
+#define MaximumRDSize 8192
+
+// InlineCacheRDSize is 64
+// Records received from the network with rdata this size or less have their rdata stored right in the CacheRecord object
+// Records received from the network with rdata larger than this have additional storage allocated for the rdata
+// A quick unscientific sample from a busy network at Apple with lots of machines revealed this:
+// 1461 records in cache
+// 292 were one-byte TXT records
+// 136 were four-byte A records
+// 184 were sixteen-byte AAAA records
+// 780 were various PTR, TXT and SRV records from 12-64 bytes
+// Only 69 records had rdata bigger than 64 bytes
+#define InlineCacheRDSize 64
+
+typedef union
+ {
+ mDNSu8 data[StandardAuthRDSize];
+ mDNSv4Addr ip; // For 'A' record
+ mDNSv6Addr ipv6; // For 'AAAA' record
+ domainname name; // For PTR and CNAME records
+ UTF8str255 txt; // For TXT record
+ rdataSRV srv; // For SRV record
+ rdataMX mx; // For MX record
+ } RDataBody;
+
+typedef struct
+ {
+ mDNSu16 MaxRDLength; // Amount of storage allocated for rdata (usually sizeof(RDataBody))
+ RDataBody u;
+ } RData;
+#define sizeofRDataHeader (sizeof(RData) - sizeof(RDataBody))
+
+typedef struct AuthRecord_struct AuthRecord;
+typedef struct CacheRecord_struct CacheRecord;
+typedef struct ResourceRecord_struct ResourceRecord;
+typedef struct DNSQuestion_struct DNSQuestion;
+typedef struct mDNS_struct mDNS;
+typedef struct mDNS_PlatformSupport_struct mDNS_PlatformSupport;
+
+// Note: Within an mDNSRecordCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Close(), mDNS_Execute()
+typedef void mDNSRecordCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
+
+// Note:
+// Restrictions: An mDNSRecordUpdateCallback may not make any mDNS API calls.
+// The intent of this callback is to allow the client to free memory, if necessary.
+// The internal data structures of the mDNS code may not be in a state where mDNS API calls may be made safely.
+typedef void mDNSRecordUpdateCallback(mDNS *const m, AuthRecord *const rr, RData *OldRData);
+
+struct ResourceRecord_struct
+ {
+ mDNSu8 RecordType; // See enum above
+ mDNSInterfaceID InterfaceID; // Set if this RR is specific to one interface
+ // For records received off the wire, InterfaceID is *always* set to the receiving interface
+ // For our authoritative records, InterfaceID is usually zero, except for those few records
+ // that are interface-specific (e.g. address records, especially linklocal addresses)
+ domainname name;
+ mDNSu16 rrtype;
+ mDNSu16 rrclass;
+ mDNSu32 rroriginalttl; // In seconds
+ mDNSu16 rdlength; // Size of the raw rdata, in bytes
+ mDNSu16 rdestimate; // Upper bound on size of rdata after name compression
+ mDNSu32 namehash; // Name-based (i.e. case insensitive) hash of name
+ mDNSu32 rdatahash; // 32-bit hash of the raw rdata
+ mDNSu32 rdnamehash; // Set if this rdata contains a domain name (e.g. PTR, SRV, CNAME etc.)
+ RData *rdata; // Pointer to storage for this rdata
+ };
+
+struct AuthRecord_struct
+ {
+ // For examples of how to set up this structure for use in mDNS_Register(),
+ // see mDNS_AdvertiseInterface() or mDNS_RegisterService().
+ // Basically, resrec and persistent metadata need to be set up before calling mDNS_Register().
+ // mDNS_SetupResourceRecord() is avaliable as a helper routine to set up most fields to sensible default values for you
+
+ AuthRecord *next; // Next in list; first element of structure for efficiency reasons
+ ResourceRecord resrec;
+
+ // Persistent metadata for Authoritative Records
+ AuthRecord *Additional1; // Recommended additional record to include in response
+ AuthRecord *Additional2; // Another additional
+ AuthRecord *DependentOn; // This record depends on another for its uniqueness checking
+ AuthRecord *RRSet; // This unique record is part of an RRSet
+ mDNSRecordCallback *RecordCallback; // Callback function to call for state changes
+ void *RecordContext; // Context parameter for the callback function
+ mDNSu8 HostTarget; // Set if the target of this record (PTR, CNAME, SRV, etc.) is our host name
+
+ // Transient state for Authoritative Records
+ mDNSu8 Acknowledged; // Set if we've given the success callback to the client
+ mDNSu8 ProbeCount; // Number of probes remaining before this record is valid (kDNSRecordTypeUnique)
+ mDNSu8 AnnounceCount; // Number of announcements remaining (kDNSRecordTypeShared)
+ mDNSu8 IncludeInProbe; // Set if this RR is being put into a probe right now
+ mDNSInterfaceID ImmedAnswer; // Someone on this interface issued a query we need to answer (all-ones for all interfaces)
+ mDNSInterfaceID ImmedAdditional; // Hint that we might want to also send this record, just to be helpful
+ mDNSInterfaceID SendRNow; // The interface this query is being sent on right now
+ mDNSv4Addr v4Requester; // Recent v4 query for this record, or all-ones if more than one recent query
+ mDNSv6Addr v6Requester; // Recent v6 query for this record, or all-ones if more than one recent query
+ AuthRecord *NextResponse; // Link to the next element in the chain of responses to generate
+ const mDNSu8 *NR_AnswerTo; // Set if this record was selected by virtue of being a direct answer to a question
+ AuthRecord *NR_AdditionalTo; // Set if this record was selected by virtue of being additional to another
+ mDNSs32 ThisAPInterval; // In platform time units: Current interval for announce/probe
+ mDNSs32 AnnounceUntil; // In platform time units: Creation time + TTL
+ mDNSs32 LastAPTime; // In platform time units: Last time we sent announcement/probe
+ mDNSs32 LastMCTime; // Last time we multicast this record (used to guard against packet-storm attacks)
+ mDNSInterfaceID LastMCInterface; // Interface this record was multicast on at the time LastMCTime was recorded
+ RData *NewRData; // Set if we are updating this record with new rdata
+ mDNSu16 newrdlength; // ... and the length of the new RData
+ mDNSRecordUpdateCallback *UpdateCallback;
+ mDNSu32 UpdateCredits; // Token-bucket rate limiting of excessive updates
+ mDNSs32 NextUpdateCredit; // Time next token is added to bucket
+ mDNSs32 UpdateBlocked; // Set if update delaying is in effect
+
+ RData rdatastorage; // Normally the storage is right here, except for oversized records
+ // rdatastorage MUST be the last thing in the structure -- when using oversized AuthRecords, extra bytes
+ // are appended after the end of the AuthRecord, logically augmenting the size of the rdatastorage
+ // DO NOT ADD ANY MORE FIELDS HERE
+ };
+
+struct CacheRecord_struct
+ {
+ CacheRecord *next; // Next in list; first element of structure for efficiency reasons
+ ResourceRecord resrec;
+
+ // Transient state for Cache Records
+ CacheRecord *NextInKAList; // Link to the next element in the chain of known answers to send
+ mDNSs32 TimeRcvd; // In platform time units
+ mDNSs32 NextRequiredQuery; // In platform time units
+ mDNSs32 LastUsed; // In platform time units
+ mDNSu32 UseCount; // Number of times this RR has been used to answer a question
+ DNSQuestion *CRActiveQuestion; // Points to an active question referencing this answer
+ mDNSu32 UnansweredQueries; // Number of times we've issued a query for this record without getting an answer
+ mDNSs32 LastUnansweredTime; // In platform time units; last time we incremented UnansweredQueries
+ mDNSu32 MPUnansweredQ; // Multi-packet query handling: Number of times we've seen a query for this record
+ mDNSs32 MPLastUnansweredQT; // Multi-packet query handling: Last time we incremented MPUnansweredQ
+ mDNSu32 MPUnansweredKA; // Multi-packet query handling: Number of times we've seen this record in a KA list
+ mDNSBool MPExpectingKA; // Multi-packet query handling: Set when we increment MPUnansweredQ; allows one KA
+ CacheRecord *NextInCFList; // Set if this is in the list of records we just received with the cache flush bit set
+
+ struct { mDNSu16 MaxRDLength; mDNSu8 data[InlineCacheRDSize]; } rdatastorage; // Storage for small records is right here
+ };
+
+typedef struct
+ {
+ CacheRecord r;
+ mDNSu8 _extradata[MaximumRDSize-InlineCacheRDSize]; // Glue on the necessary number of extra bytes
+ } LargeCacheRecord;
+
+typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo;
+
+struct NetworkInterfaceInfo_struct
+ {
+ // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
+ NetworkInterfaceInfo *next;
+
+ mDNSBool InterfaceActive; // InterfaceActive is set if interface is sending & receiving packets
+ // InterfaceActive is clear if interface is here to represent an address with A
+ // and/or AAAA records, but there is already an earlier representative for this
+ // physical interface which will be used for the actual sending & receiving
+ // packets (this status may change as interfaces are added and removed)
+ mDNSBool IPv4Available; // If InterfaceActive, set if v4 available on this InterfaceID
+ mDNSBool IPv6Available; // If InterfaceActive, set if v6 available on this InterfaceID
+
+ // Standard AuthRecords that every Responder host should have (one per active IP address)
+ AuthRecord RR_A; // 'A' or 'AAAA' (address) record for our ".local" name
+ AuthRecord RR_PTR; // PTR (reverse lookup) record
+ AuthRecord RR_HINFO;
+
+ // Client API fields: The client must set up these fields *before* calling mDNS_RegisterInterface()
+ mDNSInterfaceID InterfaceID;
+ mDNSAddr ip;
+ mDNSBool Advertise; // Set Advertise to false if you are only searching on this interface
+ mDNSBool TxAndRx; // Set to false if not sending and receiving packets on this interface
+ };
+
+typedef struct ExtraResourceRecord_struct ExtraResourceRecord;
+struct ExtraResourceRecord_struct
+ {
+ ExtraResourceRecord *next;
+ AuthRecord r;
+ // Note: Add any additional fields *before* the AuthRecord in this structure, not at the end.
+ // In some cases clients can allocate larger chunks of memory and set r->rdata->MaxRDLength to indicate
+ // that this extra memory is available, which would result in any fields after the AuthRecord getting smashed
+ };
+
+// Note: Within an mDNSServiceCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Close(), mDNS_Execute()
+typedef struct ServiceRecordSet_struct ServiceRecordSet;
+typedef void mDNSServiceCallback(mDNS *const m, ServiceRecordSet *const sr, mStatus result);
+struct ServiceRecordSet_struct
+ {
+ // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
+ // No fields need to be set up by the client prior to calling mDNS_RegisterService();
+ // all required data is passed as parameters to that function.
+ mDNSServiceCallback *ServiceCallback;
+ void *ServiceContext;
+ ExtraResourceRecord *Extras; // Optional list of extra AuthRecords attached to this service registration
+ mDNSu32 NumSubTypes;
+ AuthRecord *SubTypes;
+ mDNSBool Conflict; // Set if this record set was forcibly deregistered because of a conflict
+ domainname Host; // Set if this service record does not use the standard target host name
+ AuthRecord RR_ADV; // e.g. _services._dns-sd._udp.local. PTR _printer._tcp.local.
+ AuthRecord RR_PTR; // e.g. _printer._tcp.local. PTR Name._printer._tcp.local.
+ AuthRecord RR_SRV; // e.g. Name._printer._tcp.local. SRV 0 0 port target
+ AuthRecord RR_TXT; // e.g. Name._printer._tcp.local. TXT PrintQueueName
+ // Don't add any fields after AuthRecord RR_TXT.
+ // This is where the implicit extra space goes if we allocate a ServiceRecordSet containing an oversized RR_TXT record
+ };
+
+// ***************************************************************************
+#if 0
+#pragma mark - Question structures
+#endif
+
+// We record the last eight instances of each duplicate query
+// This gives us v4/v6 on each of Ethernet/AirPort and Firewire, and two free slots "for future expansion"
+// If the host has more active interfaces that this it is not fatal -- duplicate question suppression will degrade gracefully.
+// Since we will still remember the last eight, the busiest interfaces will still get the effective duplicate question suppression.
+#define DupSuppressInfoSize 8
+
+typedef struct
+ {
+ mDNSs32 Time;
+ mDNSInterfaceID InterfaceID;
+ mDNSs32 Type; // v4 or v6?
+ } DupSuppressInfo;
+
+// Note: Within an mDNSQuestionCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Close(), mDNS_Execute()
+typedef void mDNSQuestionCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, mDNSBool AddRecord);
+struct DNSQuestion_struct
+ {
+ // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
+ DNSQuestion *next;
+ mDNSu32 qnamehash;
+ mDNSs32 LastQTime; // Last scheduled transmission of this Q on *all* applicable interfaces
+ mDNSs32 ThisQInterval; // LastQTime + ThisQInterval is the next scheduled transmission of this Q
+ // ThisQInterval > 0 for an active question;
+ // ThisQInterval = 0 for a suspended question that's still in the list
+ // ThisQInterval = -1 for a cancelled question that's been removed from the list
+ mDNSu32 RecentAnswers; // Number of answers since the last time we sent this query
+ mDNSu32 CurrentAnswers; // Number of records currently in the cache that answer this question
+ mDNSu32 LargeAnswers; // Number of answers with rdata > 1024 bytes
+ mDNSu32 UniqueAnswers; // Number of answers received with kDNSClass_UniqueRRSet bit set
+ DNSQuestion *DuplicateOf;
+ DNSQuestion *NextInDQList;
+ DupSuppressInfo DupSuppress[DupSuppressInfoSize];
+ mDNSInterfaceID SendQNow; // The interface this query is being sent on right now
+ mDNSBool SendOnAll; // Set if we're sending this question on all active interfaces
+ mDNSs32 LastQTxTime; // Last time this Q was sent on one (but not necessarily all) interfaces
+
+ // Client API fields: The client must set up these fields *before* calling mDNS_StartQuery()
+ mDNSInterfaceID InterfaceID; // Non-zero if you want to issue link-local queries only on a single specific IP interface
+ domainname qname;
+ mDNSu16 qtype;
+ mDNSu16 qclass;
+ mDNSQuestionCallback *QuestionCallback;
+ void *QuestionContext;
+ };
+
+typedef struct
+ {
+ // Client API fields: The client must set up name and InterfaceID *before* calling mDNS_StartResolveService()
+ // When the callback is invoked, ip, port, TXTlen and TXTinfo will have been filled in with the results learned from the network.
+ domainname name;
+ mDNSInterfaceID InterfaceID; // ID of the interface the response was received on
+ mDNSAddr ip; // Remote (destination) IP address where this service can be accessed
+ mDNSIPPort port; // Port where this service can be accessed
+ mDNSu16 TXTlen;
+ mDNSu8 TXTinfo[2048]; // Additional demultiplexing information (e.g. LPR queue name)
+ } ServiceInfo;
+
+// Note: Within an mDNSServiceInfoQueryCallback mDNS all API calls are legal except mDNS_Init(), mDNS_Close(), mDNS_Execute()
+typedef struct ServiceInfoQuery_struct ServiceInfoQuery;
+typedef void mDNSServiceInfoQueryCallback(mDNS *const m, ServiceInfoQuery *query);
+struct ServiceInfoQuery_struct
+ {
+ // Internal state fields. These are used internally by mDNSCore; the client layer needn't be concerned with them.
+ // No fields need to be set up by the client prior to calling mDNS_StartResolveService();
+ // all required data is passed as parameters to that function.
+ // The ServiceInfoQuery structure memory is working storage for mDNSCore to discover the requested information
+ // and place it in the ServiceInfo structure. After the client has called mDNS_StopResolveService(), it may
+ // dispose of the ServiceInfoQuery structure while retaining the results in the ServiceInfo structure.
+ DNSQuestion qSRV;
+ DNSQuestion qTXT;
+ DNSQuestion qAv4;
+ DNSQuestion qAv6;
+ mDNSu8 GotSRV;
+ mDNSu8 GotTXT;
+ mDNSu8 GotADD;
+ mDNSu32 Answers;
+ ServiceInfo *info;
+ mDNSServiceInfoQueryCallback *ServiceInfoQueryCallback;
+ void *ServiceInfoQueryContext;
+ };
+
+// ***************************************************************************
+#if 0
+#pragma mark - Main mDNS object, used to hold all the mDNS state
+#endif
+
+typedef void mDNSCallback(mDNS *const m, mStatus result);
+
+#define CACHE_HASH_SLOTS 499
+
+enum
+ {
+ mDNS_KnownBug_PhantomInterfaces = 1
+ };
+
+struct mDNS_struct
+ {
+ // Internal state fields. These hold the main internal state of mDNSCore;
+ // the client layer needn't be concerned with them.
+ // No fields need to be set up by the client prior to calling mDNS_Init();
+ // all required data is passed as parameters to that function.
+
+ mDNS_PlatformSupport *p; // Pointer to platform-specific data of indeterminite size
+ mDNSu32 KnownBugs;
+ mDNSBool AdvertiseLocalAddresses;
+ mStatus mDNSPlatformStatus;
+ mDNSCallback *MainCallback;
+ void *MainContext;
+
+ // For debugging: To catch and report locking failures
+ mDNSu32 mDNS_busy; // Incremented between mDNS_Lock/mDNS_Unlock section
+ mDNSu32 mDNS_reentrancy; // Incremented when calling a client callback
+ mDNSu8 mDNS_shutdown; // Set when we're shutting down, allows us to skip some unnecessary steps
+ mDNSu8 lock_rrcache; // For debugging: Set at times when these lists may not be modified
+ mDNSu8 lock_Questions;
+ mDNSu8 lock_Records;
+ char MsgBuffer[80]; // Temp storage used while building error log messages
+
+ // Task Scheduling variables
+ mDNSs32 timenow; // The time that this particular activation of the mDNS code started
+ mDNSs32 timenow_last; // The time the last time we ran
+ mDNSs32 timenow_adjust; // Correction applied if we ever discover time went backwards
+ mDNSs32 NextScheduledEvent; // Derived from values below
+ mDNSs32 SuppressSending; // Don't send *any* packets during this time
+ mDNSs32 NextCacheCheck; // Next time to refresh cache record before it expires
+ mDNSs32 NextScheduledQuery; // Next time to send query in its exponential backoff sequence
+ mDNSs32 NextScheduledProbe; // Next time to probe for new authoritative record
+ mDNSs32 NextScheduledResponse; // Next time to send authoritative record(s) in responses
+ mDNSs32 ExpectUnicastResponse; // Set when we send a query with the kDNSQClass_UnicastResponse bit set
+ mDNSs32 RandomQueryDelay; // For de-synchronization of query packets on the wire
+ mDNSBool SendDeregistrations; // Set if we need to send deregistrations (immediately)
+ mDNSBool SendImmediateAnswers; // Set if we need to send answers (immediately -- or as soon as SuppressSending clears)
+ mDNSBool SleepState; // Set if we're sleeping (send no more packets)
+
+ // These fields only required for mDNS Searcher...
+ DNSQuestion *Questions; // List of all registered questions, active and inactive
+ DNSQuestion *NewQuestions; // Fresh questions not yet answered from cache
+ DNSQuestion *CurrentQuestion; // Next question about to be examined in AnswerLocalQuestions()
+ DNSQuestion *LocalOnlyQuestions; // Questions with InterfaceID set to ~0 ("local only")
+ DNSQuestion *NewLocalOnlyQuestions; // Fresh local-only questions not yet answered
+ mDNSu32 rrcache_size; // Total number of available cache entries
+ mDNSu32 rrcache_totalused; // Number of cache entries currently occupied
+ mDNSu32 rrcache_active; // Number of cache entries currently occupied by records that answer active questions
+ mDNSu32 rrcache_report;
+ CacheRecord *rrcache_free;
+ CacheRecord *rrcache_hash[CACHE_HASH_SLOTS];
+ CacheRecord **rrcache_tail[CACHE_HASH_SLOTS];
+ mDNSu32 rrcache_used[CACHE_HASH_SLOTS];
+
+ // Fields below only required for mDNS Responder...
+ domainlabel nicelabel; // Rich text label encoded using canonically precomposed UTF-8
+ domainlabel hostlabel; // Conforms to RFC 1034 "letter-digit-hyphen" ARPANET host name rules
+ domainname hostname; // Host Name, e.g. "Foo.local."
+ UTF8str255 HIHardware;
+ UTF8str255 HISoftware;
+ AuthRecord *ResourceRecords;
+ AuthRecord *DuplicateRecords; // Records currently 'on hold' because they are duplicates of existing records
+ AuthRecord *LocalOnlyRecords; // Local records registered with InterfaceID set to ~0 ("local only")
+ AuthRecord *NewLocalOnlyRecords; // Fresh local-only records not yet delivered to local-only questions
+ mDNSBool DiscardLocalOnlyRecords;// Set when we have "remove" events we need to deliver to local-only questions
+ AuthRecord *CurrentRecord; // Next AuthRecord about to be examined
+ NetworkInterfaceInfo *HostInterfaces;
+ mDNSs32 ProbeFailTime;
+ mDNSs32 NumFailedProbes;
+ mDNSs32 SuppressProbes;
+ };
+
+// ***************************************************************************
+#if 0
+#pragma mark - Useful Static Constants
+#endif
+
+extern const mDNSIPPort zeroIPPort;
+extern const mDNSv4Addr zeroIPAddr;
+extern const mDNSv6Addr zerov6Addr;
+extern const mDNSv4Addr onesIPv4Addr;
+extern const mDNSv6Addr onesIPv6Addr;
+extern const mDNSInterfaceID mDNSInterface_Any;
+
+extern const mDNSIPPort UnicastDNSPort;
+extern const mDNSIPPort MulticastDNSPort;
+extern const mDNSv4Addr AllDNSAdminGroup;
+extern const mDNSv4Addr AllDNSLinkGroup;
+extern const mDNSv6Addr AllDNSLinkGroupv6;
+extern const mDNSAddr AllDNSLinkGroup_v4;
+extern const mDNSAddr AllDNSLinkGroup_v6;
+
+// ***************************************************************************
+#if 0
+#pragma mark - Main Client Functions
+#endif
+
+// Every client should call mDNS_Init, passing in storage for the mDNS object, mDNS_PlatformSupport object, and rrcache.
+// The rrcachesize parameter is the size of (i.e. number of entries in) the rrcache array passed in.
+// Most clients use mDNS_Init_AdvertiseLocalAddresses. This causes mDNSCore to automatically
+// create the correct address records for all the hosts interfaces. If you plan to advertise
+// services being offered by the local machine, this is almost always what you want.
+// There are two cases where you might use mDNS_Init_DontAdvertiseLocalAddresses:
+// 1. A client-only device, that browses for services but doesn't advertise any of its own.
+// 2. A proxy-registration service, that advertises services being offered by other machines, and takes
+// the appropriate steps to manually create the correct address records for those other machines.
+// In principle, a proxy-like registration service could manually create address records for its own machine too,
+// but this would be pointless extra effort when using mDNS_Init_AdvertiseLocalAddresses does that for you.
+//
+// When mDNS has finished setting up the client's callback is called
+// A client can also spin and poll the mDNSPlatformStatus field to see when it changes from mStatus_Waiting to mStatus_NoError
+//
+// Call mDNS_Close to tidy up before exiting
+//
+// Call mDNS_Register with a completed AuthRecord object to register a resource record
+// If the resource record type is kDNSRecordTypeUnique (or kDNSknownunique) then if a conflicting resource record is discovered,
+// the resource record's mDNSRecordCallback will be called with error code mStatus_NameConflict. The callback should deregister
+// the record, and may then try registering the record again after picking a new name (e.g. by automatically appending a number).
+//
+// Call mDNS_StartQuery to initiate a query. mDNS will proceed to issue Multicast DNS query packets, and any time a response
+// is received containing a record which matches the question, the DNSQuestion's mDNSAnswerCallback function will be called
+// Call mDNS_StopQuery when no more answers are required
+//
+// Care should be taken on multi-threaded or interrupt-driven environments.
+// The main mDNS routines call mDNSPlatformLock() on entry and mDNSPlatformUnlock() on exit;
+// each platform layer needs to implement these appropriately for its respective platform.
+// For example, if the support code on a particular platform implements timer callbacks at interrupt time, then
+// mDNSPlatformLock/Unlock need to disable interrupts or do similar concurrency control to ensure that the mDNS
+// code is not entered by an interrupt-time timer callback while in the middle of processing a client call.
+
+extern mStatus mDNS_Init (mDNS *const m, mDNS_PlatformSupport *const p,
+ CacheRecord *rrcachestorage, mDNSu32 rrcachesize,
+ mDNSBool AdvertiseLocalAddresses,
+ mDNSCallback *Callback, void *Context);
+// See notes above on use of NoCache/ZeroCacheSize
+#define mDNS_Init_NoCache mDNSNULL
+#define mDNS_Init_ZeroCacheSize 0
+// See notes above on use of Advertise/DontAdvertiseLocalAddresses
+#define mDNS_Init_AdvertiseLocalAddresses mDNStrue
+#define mDNS_Init_DontAdvertiseLocalAddresses mDNSfalse
+#define mDNS_Init_NoInitCallback mDNSNULL
+#define mDNS_Init_NoInitCallbackContext mDNSNULL
+
+extern void mDNS_GrowCache (mDNS *const m, CacheRecord *storage, mDNSu32 numrecords);
+extern void mDNS_Close (mDNS *const m);
+extern mDNSs32 mDNS_Execute (mDNS *const m);
+
+extern mStatus mDNS_Register (mDNS *const m, AuthRecord *const rr);
+extern mStatus mDNS_Update (mDNS *const m, AuthRecord *const rr, mDNSu32 newttl,
+ const mDNSu16 newrdlength,
+ RData *const newrdata, mDNSRecordUpdateCallback *Callback);
+extern mStatus mDNS_Deregister(mDNS *const m, AuthRecord *const rr);
+
+extern mStatus mDNS_StartQuery(mDNS *const m, DNSQuestion *const question);
+extern mStatus mDNS_StopQuery (mDNS *const m, DNSQuestion *const question);
+extern mStatus mDNS_Reconfirm (mDNS *const m, CacheRecord *const cacherr);
+extern mStatus mDNS_ReconfirmByValue(mDNS *const m, ResourceRecord *const rr);
+
+// ***************************************************************************
+#if 0
+#pragma mark - Platform support functions that are accessible to the client layer too
+#endif
+
+extern mDNSs32 mDNSPlatformOneSecond;
+extern mDNSs32 mDNSPlatformTimeNow(void);
+
+// ***************************************************************************
+#if 0
+#pragma mark - General utility and helper functions
+#endif
+
+// mDNS_RegisterService is a single call to register the set of resource records associated with a given named service.
+//
+// mDNS_StartResolveService is single call which is equivalent to multiple calls to mDNS_StartQuery,
+// to find the IP address, port number, and demultiplexing information for a given named service.
+// As with mDNS_StartQuery, it executes asynchronously, and calls the ServiceInfoQueryCallback when the answer is
+// found. After the service is resolved, the client should call mDNS_StopResolveService to complete the transaction.
+// The client can also call mDNS_StopResolveService at any time to abort the transaction.
+//
+// mDNS_GetBrowseDomains is a special case of the mDNS_StartQuery call, where the resulting answers
+// are a list of PTR records indicating (in the rdata) domains that are recommended for browsing.
+// After getting the list of domains to browse, call mDNS_StopQuery to end the search.
+// mDNS_GetDefaultBrowseDomain returns the name of the domain that should be highlighted by default.
+//
+// mDNS_GetRegistrationDomains and mDNS_GetDefaultRegistrationDomain are the equivalent calls to get the list
+// of one or more domains that should be offered to the user as choices for where they may register their service,
+// and the default domain in which to register in the case where the user has made no selection.
+
+extern void mDNS_SetupResourceRecord(AuthRecord *rr, RData *RDataStorage, mDNSInterfaceID InterfaceID,
+ mDNSu16 rrtype, mDNSu32 ttl, mDNSu8 RecordType, mDNSRecordCallback Callback, void *Context);
+
+extern mStatus mDNS_RegisterService (mDNS *const m, ServiceRecordSet *sr,
+ const domainlabel *const name, const domainname *const type, const domainname *const domain,
+ const domainname *const host, mDNSIPPort port, const mDNSu8 txtinfo[], mDNSu16 txtlen,
+ AuthRecord *SubTypes, mDNSu32 NumSubTypes,
+ const mDNSInterfaceID InterfaceID, mDNSServiceCallback Callback, void *Context);
+extern mStatus mDNS_AddRecordToService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra, RData *rdata, mDNSu32 ttl);
+extern mStatus mDNS_RemoveRecordFromService(mDNS *const m, ServiceRecordSet *sr, ExtraResourceRecord *extra);
+extern mStatus mDNS_RenameAndReregisterService(mDNS *const m, ServiceRecordSet *const sr, const domainlabel *newname);
+extern mStatus mDNS_DeregisterService(mDNS *const m, ServiceRecordSet *sr);
+
+extern mStatus mDNS_RegisterNoSuchService(mDNS *const m, AuthRecord *const rr,
+ const domainlabel *const name, const domainname *const type, const domainname *const domain,
+ const domainname *const host,
+ const mDNSInterfaceID InterfaceID, mDNSRecordCallback Callback, void *Context);
+#define mDNS_DeregisterNoSuchService mDNS_Deregister
+
+extern mStatus mDNS_StartBrowse(mDNS *const m, DNSQuestion *const question,
+ const domainname *const srv, const domainname *const domain,
+ const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context);
+#define mDNS_StopBrowse mDNS_StopQuery
+
+extern mStatus mDNS_StartResolveService(mDNS *const m, ServiceInfoQuery *query, ServiceInfo *info, mDNSServiceInfoQueryCallback *Callback, void *Context);
+extern void mDNS_StopResolveService (mDNS *const m, ServiceInfoQuery *query);
+
+typedef enum
+ {
+ mDNS_DomainTypeBrowse = 0,
+ mDNS_DomainTypeBrowseDefault = 1,
+ mDNS_DomainTypeRegistration = 2,
+ mDNS_DomainTypeRegistrationDefault = 3
+ } mDNS_DomainType;
+
+extern mStatus mDNS_GetDomains(mDNS *const m, DNSQuestion *const question, mDNS_DomainType DomainType, const mDNSInterfaceID InterfaceID, mDNSQuestionCallback *Callback, void *Context);
+// In the Panther mDNSResponder we don't do unicast queries yet, so there's no point trying to do domain enumeration
+// mDNS_GetDomains() and mDNS_StopGetDomains() are set to be no-ops so that clients don't try to do browse/register operations that will fail
+//#define mDNS_StopGetDomains mDNS_StopQuery
+#define mDNS_StopGetDomains(m,q) ((void)(m),(void)(q))
+extern mStatus mDNS_AdvertiseDomains(mDNS *const m, AuthRecord *rr, mDNS_DomainType DomainType, const mDNSInterfaceID InterfaceID, char *domname);
+#define mDNS_StopAdvertiseDomains mDNS_Deregister
+
+// ***************************************************************************
+#if 0
+#pragma mark - DNS name utility functions
+#endif
+
+// In order to expose the full capabilities of the DNS protocol (which allows any arbitrary eight-bit values
+// in domain name labels, including unlikely characters like ascii nulls and even dots) all the mDNS APIs
+// work with DNS's native length-prefixed strings. For convenience in C, the following utility functions
+// are provided for converting between C's null-terminated strings and DNS's length-prefixed strings.
+
+// Assignment
+// A simple C structure assignment of a domainname can cause a protection fault by accessing unmapped memory,
+// because that object is defined to be 256 bytes long, but not all domainname objects are truly the full size.
+// This macro uses mDNSPlatformMemCopy() to make sure it only touches the actual bytes that are valid.
+#define AssignDomainName(DST, SRC) mDNSPlatformMemCopy((SRC).c, (DST).c, DomainNameLength(&(SRC)))
+
+// Comparison functions
+extern mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b);
+extern mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2);
+
+// Get total length of domain name, in native DNS format, including terminal root label
+// (e.g. length of "com." is 5 (length byte, three data bytes, final zero)
+extern mDNSu16 DomainNameLength(const domainname *const name);
+
+// Append functions to append one or more labels to an existing native format domain name:
+// AppendLiteralLabelString adds a single label from a literal C string, with no escape character interpretation.
+// AppendDNSNameString adds zero or more labels from a C string using conventional DNS dots-and-escaping interpretation
+// AppendDomainLabel adds a single label from a native format domainlabel
+// AppendDomainName adds zero or more labels from a native format domainname
+extern mDNSu8 *AppendLiteralLabelString(domainname *const name, const char *cstr);
+extern mDNSu8 *AppendDNSNameString (domainname *const name, const char *cstr);
+extern mDNSu8 *AppendDomainLabel (domainname *const name, const domainlabel *const label);
+extern mDNSu8 *AppendDomainName (domainname *const name, const domainname *const append);
+
+// Convert from null-terminated string to native DNS format:
+// The DomainLabel form makes a single label from a literal C string, with no escape character interpretation.
+// The DomainName form makes native format domain name from a C string using conventional DNS interpretation:
+// dots separate labels, and within each label, '\.' represents a literal dot, '\\' represents a literal
+// backslash and backslash with three decimal digits (e.g. \000) represents an arbitrary byte value.
+extern mDNSBool MakeDomainLabelFromLiteralString(domainlabel *const label, const char *cstr);
+extern mDNSu8 *MakeDomainNameFromDNSNameString (domainname *const name, const char *cstr);
+
+// Convert native format domainlabel or domainname back to C string format
+// IMPORTANT:
+// When using ConvertDomainLabelToCString, the target buffer must be MAX_ESCAPED_DOMAIN_LABEL (254) bytes long
+// to guarantee there will be no buffer overrun. It is only safe to use a buffer shorter than this in rare cases
+// where the label is known to be constrained somehow (for example, if the label is known to be either "_tcp" or "_udp").
+// Similarly, when using ConvertDomainNameToCString, the target buffer must be MAX_ESCAPED_DOMAIN_NAME (1005) bytes long.
+// See definitions of MAX_ESCAPED_DOMAIN_LABEL and MAX_ESCAPED_DOMAIN_NAME for more detailed explanation.
+extern char *ConvertDomainLabelToCString_withescape(const domainlabel *const name, char *cstr, char esc);
+#define ConvertDomainLabelToCString_unescaped(D,C) ConvertDomainLabelToCString_withescape((D), (C), 0)
+#define ConvertDomainLabelToCString(D,C) ConvertDomainLabelToCString_withescape((D), (C), '\\')
+extern char *ConvertDomainNameToCString_withescape(const domainname *const name, char *cstr, char esc);
+#define ConvertDomainNameToCString_unescaped(D,C) ConvertDomainNameToCString_withescape((D), (C), 0)
+#define ConvertDomainNameToCString(D,C) ConvertDomainNameToCString_withescape((D), (C), '\\')
+
+extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name[], domainlabel *const hostlabel);
+
+extern mDNSu8 *ConstructServiceName(domainname *const fqdn, const domainlabel *name, const domainname *type, const domainname *const domain);
+extern mDNSBool DeconstructServiceName(const domainname *const fqdn, domainlabel *const name, domainname *const type, domainname *const domain);
+
+// Note: Some old functions have been replaced by more sensibly-named versions.
+// You can uncomment the hash-defines below if you don't want to have to change your source code right away.
+// When updating your code, note that (unlike the old versions) *all* the new routines take the target object
+// as their first parameter.
+//#define ConvertCStringToDomainName(SRC,DST) MakeDomainNameFromDNSNameString((DST),(SRC))
+//#define ConvertCStringToDomainLabel(SRC,DST) MakeDomainLabelFromLiteralString((DST),(SRC))
+//#define AppendStringLabelToName(DST,SRC) AppendLiteralLabelString((DST),(SRC))
+//#define AppendStringNameToName(DST,SRC) AppendDNSNameString((DST),(SRC))
+//#define AppendDomainLabelToName(DST,SRC) AppendDomainLabel((DST),(SRC))
+//#define AppendDomainNameToName(DST,SRC) AppendDomainName((DST),(SRC))
+
+// ***************************************************************************
+#if 0
+#pragma mark - Other utility functions
+#endif
+
+extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg);
+extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
+extern char *DNSTypeName(mDNSu16 rrtype);
+extern char *GetRRDisplayString_rdb(mDNS *const m, const ResourceRecord *rr, RDataBody *rd);
+#define GetRRDisplayString(m, rr) GetRRDisplayString_rdb((m), &(rr)->resrec, &(rr)->resrec.rdata->u)
+extern mDNSBool mDNSSameAddress(const mDNSAddr *ip1, const mDNSAddr *ip2);
+extern void IncrementLabelSuffix(domainlabel *name, mDNSBool RichText);
+
+// ***************************************************************************
+#if 0
+#pragma mark - PlatformSupport interface
+#endif
+
+// This section defines the interface to the Platform Support layer.
+// Normal client code should not use any of types defined here, or directly call any of the functions defined here.
+// The definitions are placed here because sometimes clients do use these calls indirectly, via other supported client operations.
+// For example, AssignDomainName is a macro defined using mDNSPlatformMemCopy()
+
+typedef packedstruct
+ {
+ mDNSOpaque16 id;
+ mDNSOpaque16 flags;
+ mDNSu16 numQuestions;
+ mDNSu16 numAnswers;
+ mDNSu16 numAuthorities;
+ mDNSu16 numAdditionals;
+ } DNSMessageHeader;
+
+// We can send and receive packets up to 9000 bytes (Ethernet Jumbo Frame size, if that ever becomes widely used)
+// However, in the normal case we try to limit packets to 1500 bytes so that we don't get IP fragmentation on standard Ethernet
+// 40 (IPv6 header) + 8 (UDP header) + 12 (DNS message header) + 1440 (DNS message body) = 1500 total
+#define AbsoluteMaxDNSMessageData 8940
+#define NormalMaxDNSMessageData 1440
+typedef packedstruct
+ {
+ DNSMessageHeader h; // Note: Size 12 bytes
+ mDNSu8 data[AbsoluteMaxDNSMessageData]; // 40 (IPv6) + 8 (UDP) + 12 (DNS header) + 8940 (data) = 9000
+ } DNSMessage;
+
+// Every platform support module must provide the following functions.
+// mDNSPlatformInit() typically opens a communication endpoint, and starts listening for mDNS packets.
+// When Setup is complete, the platform support layer calls mDNSCoreInitComplete().
+// mDNSPlatformSendUDP() sends one UDP packet
+// When a packet is received, the PlatformSupport code calls mDNSCoreReceive()
+// mDNSPlatformClose() tidies up on exit
+// Note: mDNSPlatformMemAllocate/mDNSPlatformMemFree are only required for handling oversized resource records.
+// If your target platform has a well-defined specialized application, and you know that all the records it uses
+// are InlineCacheRDSize or less, then you can just make a simple mDNSPlatformMemAllocate() stub that always returns
+// NULL. InlineCacheRDSize is a compile-time constant, which is set by default to 64. If you need to handle records
+// a little larger than this and you don't want to have to implement run-time allocation and freeing, then you
+// can raise the value of this constant to a suitable value (at the expense of increased memory usage).
+extern mStatus mDNSPlatformInit (mDNS *const m);
+extern void mDNSPlatformClose (mDNS *const m);
+extern mStatus mDNSPlatformSendUDP(const mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end,
+ mDNSInterfaceID InterfaceID, mDNSIPPort srcport, const mDNSAddr *dst, mDNSIPPort dstport);
+
+extern void mDNSPlatformLock (const mDNS *const m);
+extern void mDNSPlatformUnlock (const mDNS *const m);
+
+extern void mDNSPlatformStrCopy (const void *src, void *dst);
+extern mDNSu32 mDNSPlatformStrLen (const void *src);
+extern void mDNSPlatformMemCopy (const void *src, void *dst, mDNSu32 len);
+extern mDNSBool mDNSPlatformMemSame (const void *src, const void *dst, mDNSu32 len);
+extern void mDNSPlatformMemZero ( void *dst, mDNSu32 len);
+extern void * mDNSPlatformMemAllocate (mDNSu32 len);
+extern void mDNSPlatformMemFree (void *mem);
+extern mStatus mDNSPlatformTimeInit (mDNSs32 *timenow);
+
+// The core mDNS code provides these functions, for the platform support code to call at appropriate times
+//
+// mDNS_GenerateFQDN() is called once on startup (typically from mDNSPlatformInit())
+// and then again on each subsequent change of the dot-local host name.
+//
+// mDNS_RegisterInterface() is used by the platform support layer to inform mDNSCore of what
+// physical and/or logical interfaces are available for sending and receiving packets.
+// Typically it is called on startup for each available interface, but register/deregister may be
+// called again later, on multiple occasions, to inform the core of interface configuration changes.
+// If set->Advertise is set non-zero, then mDNS_RegisterInterface() also registers the standard
+// resource records that should be associated with every publicised IP address/interface:
+// -- Name-to-address records (A/AAAA)
+// -- Address-to-name records (PTR)
+// -- Host information (HINFO)
+//
+// mDNSCoreInitComplete() is called when the platform support layer is finished.
+// Typically this is at the end of mDNSPlatformInit(), but may be later
+// (on platforms like OT that allow asynchronous initialization of the networking stack).
+//
+// mDNSCoreReceive() is called when a UDP packet is received
+//
+// mDNSCoreMachineSleep() is called when the machine sleeps or wakes
+// (This refers to heavyweight laptop-style sleep/wake that disables network access,
+// not lightweight second-by-second CPU power management modes.)
+
+extern void mDNS_GenerateFQDN(mDNS *const m);
+extern mStatus mDNS_RegisterInterface (mDNS *const m, NetworkInterfaceInfo *set);
+extern void mDNS_DeregisterInterface(mDNS *const m, NetworkInterfaceInfo *set);
+extern void mDNSCoreInitComplete(mDNS *const m, mStatus result);
+extern void mDNSCoreReceive(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
+ const mDNSAddr *const srcaddr, const mDNSIPPort srcport,
+ const mDNSAddr *const dstaddr, const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID, mDNSu8 ttl);
+extern void mDNSCoreMachineSleep(mDNS *const m, mDNSBool wake);
+
+// ***************************************************************************
+#if 0
+#pragma mark - Compile-Time assertion checks
+#endif
+
+// Some C compiler cleverness. We can make the compiler check certain things for
+// us, and report compile-time errors if anything is wrong. The usual way to do
+// this would be to use a run-time "if" statement, but then you don't find out
+// what's wrong until you run the software. This way, if the assertion condition
+// is false, the array size is negative, and the complier complains immediately.
+
+struct mDNS_CompileTimeAssertionChecks
+ {
+ // Check that the compiler generated our on-the-wire packet format structure definitions
+ // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
+ char assert0[(sizeof(rdataSRV) == 262 ) ? 1 : -1];
+ char assert1[(sizeof(DNSMessageHeader) == 12 ) ? 1 : -1];
+ char assert2[(sizeof(DNSMessage) == 12+AbsoluteMaxDNSMessageData) ? 1 : -1];
+ char assert3[(sizeof(mDNSs8) == 1 ) ? 1 : -1];
+ char assert4[(sizeof(mDNSu8) == 1 ) ? 1 : -1];
+ char assert5[(sizeof(mDNSs16) == 2 ) ? 1 : -1];
+ char assert6[(sizeof(mDNSu16) == 2 ) ? 1 : -1];
+ char assert7[(sizeof(mDNSs32) == 4 ) ? 1 : -1];
+ char assert8[(sizeof(mDNSu32) == 4 ) ? 1 : -1];
+ char assert9[(sizeof(mDNSOpaque16) == 2 ) ? 1 : -1];
+ char assertA[(sizeof(mDNSOpaque32) == 4 ) ? 1 : -1];
+ char assertB[(sizeof(mDNSOpaque128) == 16 ) ? 1 : -1];
+ };
+
+// ***************************************************************************
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
Change History (most recent first):
$Log: CFSocket.c,v $
+Revision 1.115.2.5 2005/01/28 05:02:06 cheshire
+<rdar://problem/3770559> SUPan: Replace IP TTL 255 check with local-subnet check
+
Revision 1.115.2.4 2004/04/23 00:34:06 cheshire
<rdar://problem/3628978>: mDNSResponder messages on wake
Take care to correctly update InterfaceIDs when a dormant interface comes back to life
mDNSIPPort senderPort, destPort = MulticastDNSPort;
NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)context;
mDNS *const m = info->m;
+ mDNSInterfaceID InterfaceID = info->ifinfo.InterfaceID;
DNSMessage packet;
struct sockaddr_storage from;
size_t fromlen = sizeof(from);
return;
}
- // Even though we indicated a specific interface in the IP_ADD_MEMBERSHIP call, a weirdness of the
- // sockets API means that even though this socket has only officially joined the multicast group
- // on one specific interface, the kernel will still deliver multicast packets to it no matter which
- // interface they arrive on. According to the official Unix Powers That Be, this is Not A Bug.
- // To work around this weirdness, we use the IP_RECVIF option to find the name of the interface
- // on which the packet arrived, and ignore the packet if it really arrived on some other interface.
- if (strcmp(info->ifa_name, packetifname))
+ if (mDNSAddrIsDNSMulticast(&destAddr))
{
- verbosedebugf("myCFSocketCallBack got a packet from %#a to %#a on interface %#a/%s (Ignored -- really arrived on interface %s)",
- &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name, packetifname);
- return;
+ // Even though we indicated a specific interface in the IP_ADD_MEMBERSHIP call, a weirdness of the
+ // sockets API means that even though this socket has only officially joined the multicast group
+ // on one specific interface, the kernel will still deliver multicast packets to it no matter which
+ // interface they arrive on. According to the official Unix Powers That Be, this is Not A Bug.
+ // To work around this weirdness, we use the IP_RECVIF option to find the name of the interface
+ // on which the packet arrived, and ignore the packet if it really arrived on some other interface.
+ if (strcmp(info->ifa_name, packetifname))
+ {
+ verbosedebugf("myCFSocketCallBack got a packet from %#a to %#a on interface %#a/%s (Ignored -- really arrived on interface %s)",
+ &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name, packetifname);
+ return;
+ }
+ else
+ verbosedebugf("myCFSocketCallBack got a packet from %#a to %#a on interface %#a/%s",
+ &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name);
}
else
- verbosedebugf("myCFSocketCallBack got a packet from %#a to %#a on interface %#a/%s",
- &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name);
+ {
+ verbosedebugf("myCFSocketCallBack got a unicast from %#a to %#a on interface %#a/%s packetifname %s)",
+ &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name, packetifname);
+ // Note: For unicast packets, try to find the matching mDNSCore interface object
+ // (though we may not be able to, for unicast packets received over something like a PPP link)
+ NetworkInterfaceInfo *intf = m->HostInterfaces;
+ while (intf && strcmp(intf->ifname, packetifname)) intf = intf->next;
+ if (intf) InterfaceID = intf->InterfaceID;
+ }
if (err < (int)sizeof(DNSMessageHeader)) { debugf("myCFSocketCallBack packet length (%d) too short", err); return; }
- mDNSCoreReceive(m, &packet, (unsigned char*)&packet + err, &senderAddr, senderPort, &destAddr, destPort, info->ifinfo.InterfaceID, ttl);
+ mDNSCoreReceive(m, &packet, (unsigned char*)&packet + err, &senderAddr, senderPort, &destAddr, destPort, InterfaceID, ttl);
}
if (err < 0 && (errno != EWOULDBLOCK || count == 0))
i->ifinfo.InterfaceID = mDNSNULL;
i->ifinfo.ip = ip;
+ SetupAddr(&i->ifinfo.mask, ifa->ifa_netmask);
+ strncpy(i->ifinfo.ifname, ifa->ifa_name, sizeof(i->ifinfo.ifname));
+ i->ifinfo.ifname[sizeof(i->ifinfo.ifname)-1] = 0;
i->ifinfo.Advertise = m->AdvertiseLocalAddresses;
i->ifinfo.TxAndRx = mDNSfalse; // For now; will be set up later at the end of UpdateInterfaceList
Change History (most recent first):
$Log: daemon.c,v $
+Revision 1.134.2.8 2005/01/28 04:03:24 cheshire
+<rdar://problem/3759302> SUPan: Current method of doing subtypes causes name collisions
+Summary: Pulled in ConstructServiceName, CountSubTypes and AllocateSubTypes from Tiger version.
+
+Revision 1.134.2.7 2004/06/18 17:28:19 cheshire
+<rdar://problem/3588761> Current method of doing subtypes causes name collisions
+
Revision 1.134.2.6 2004/04/06 19:50:36 cheshire
<rdar://problem/3605898> mDNSResponder will not launch if "nobody" user doesn't exist.
After more discussion, we've decided to use userid -2 if "nobody" user doesn't exist.
#include "mDNSClientAPI.h" // Defines the interface to the client layer above
#include "mDNSMacOSX.h" // Defines the specific types needed to run mDNS on this platform
+extern mDNSs32 CountSubTypes(char *regtype);
+extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p);
+
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
#define ENABLE_UDS 1
// Check other parameters
domainname t, d;
- if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Illegal regtype"; goto badparam; }
+ t.c[0] = 0;
+ mDNSs32 NumSubTypes = CountSubTypes(regtype);
+ if (NumSubTypes < 0 || NumSubTypes > 1) { errormsg = "Bad Service SubType"; goto badparam; }
+ if (NumSubTypes == 1 && !AppendDNSNameString(&t, regtype + strlen(regtype) + 1))
+ { errormsg = "Bad Service SubType"; goto badparam; }
+ if (!regtype[0] || !AppendDNSNameString(&t, regtype)) { errormsg = "Illegal regtype"; goto badparam; }
if (!MakeDomainNameFromDNSNameString(&d, *domain ? domain : "local.")) { errormsg = "Illegal domain"; goto badparam; }
// Allocate memory, and handle failure
if (CheckForExistingClient(client)) { err = mStatus_Invalid; errormsg = "Client id already in use"; goto fail; }
// Check for sub-types after the service type
- AuthRecord *SubTypes = mDNSNULL;
- mDNSu32 i, NumSubTypes = 0;
- char *comma = regtype;
- while (*comma && *comma != ',') comma++;
- if (*comma) // If we found a comma...
- {
- *comma = 0; // Overwrite the first comma with a nul
- char *p = comma + 1; // Start scanning from the next character
- while (*p)
- {
- if ( !(*p && *p != ',')) { errormsg = "Bad Service SubType"; goto badparam; }
- while (*p && *p != ',') p++;
- if (*p) *p++ = 0;
- NumSubTypes++;
- }
- }
+ mDNSs32 NumSubTypes = CountSubTypes(regtype);
+ if (NumSubTypes < 0) { errormsg = "Bad Service SubType"; goto badparam; }
// Check other parameters
domainlabel n;
DNSServiceRegistration *x = mallocL("DNSServiceRegistration", sizeof(*x) - sizeof(RDataBody) + size);
if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
- if (NumSubTypes)
- {
- SubTypes = mallocL("ServiceSubTypes", NumSubTypes * sizeof(AuthRecord));
- if (!SubTypes) { freeL("DNSServiceRegistration", x); err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
- for (i = 0; i < NumSubTypes; i++)
- {
- comma++; // Advance over the nul character
- MakeDomainNameFromDNSNameString(&SubTypes[i].resrec.name, comma);
- while (*comma) comma++; // Advance comma to point to the next terminating nul
- }
- }
+ AuthRecord *SubTypes = AllocateSubTypes(NumSubTypes, regtype);
+ if (NumSubTypes && !SubTypes)
+ { freeL("DNSServiceRegistration", x); err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }
// Set up object, and link into list
x->ClientMachPort = client;
mDNSNULL, port, // Host and port
txtinfo, data_len, // TXT data, length
SubTypes, NumSubTypes, // Subtypes
- mDNSInterface_Any, // Interace ID
+ mDNSInterface_Any, // Interface ID
RegCallback, x); // Callback and context
if (err) { AbortClient(client, x); errormsg = "mDNS_RegisterService"; goto fail; }
r->autorename = mDNStrue;
mDNS_DeregisterService(&mDNSStorage, &r->s);
}
+ udsserver_handle_configchange();
}
else if (result == mStatus_GrowCache)
{
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: dns_sd.h,v $
-Revision 1.3 2003/08/12 19:51:51 cheshire
-Update to APSL 2.0
-
-
- */
-
-#ifndef _DNS_SD_H
-#define _DNS_SD_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdint.h>
-#include <netinet/in.h>
-
-
-/* DNSServiceRef, DNSRecordRef
- *
- * Opaque internal data types.
- * Note: client is responsible for serializing access to these structures if
- * they are shared between concurrent threads.
- */
-
-typedef struct _DNSServiceRef_t *DNSServiceRef;
-typedef struct _DNSRecordRef_t *DNSRecordRef;
-
-/* General flags used in functions defined below */
-enum
- {
- kDNSServiceFlagsMoreComing = 1,
- kDNSServiceFlagsFinished = 0, /* i.e. bit not set */
- /* MoreComing indicates to a Browse callback that another result is
- * queued. Applications should not update their UI to display browse
- * results when the MoreComing flag is set, instead deferring the update
- * until the callback's flag is Finished. */
-
- kDNSServiceFlagsAdd = 2,
- kDNSServiceFlagsDefault = 4,
- kDNSServiceFlagsRemove = 0, /* i.e. bit not set */
- /* Flags for domain enumeration and browse reply callbacks.
- * "Default" applies only to enumeration and is only valid in
- * conjuction with "Add"
- */
-
- kDNSServiceFlagsNoAutoRename = 8,
- kDNSServiceFlagsAutoRename = 0, /* i.e. bit not set */
- /* Flag for specifying renaming behavior on name conflict when registering
- * non-shared records. NoAutorename is only valid if a name is explicitly
- * specified when registering a service (ie the default name is not used.)
- */
-
-
- kDNSServiceFlagsShared = 16,
- kDNSServiceFlagsUnique = 32,
- /* Flag for registering individual records on a connected
- * DNSServiceRef. Shared indicates that there may be multiple records
- * with this name on the network (e.g. PTR records). Unique indicates that the
- * record's name is to be unique on the network (e.g. SRV records).
- */
-
- kDNSServiceFlagsBrowseDomains = 64,
- kDNSServiceFlagsRegistrationDomains = 128
- /* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
- * BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
- * enumerates domains recommended for registration.
- */
- };
-
-/* possible error code values */
-enum
- {
- kDNSServiceErr_NoError = 0,
- kDNSServiceErr_Unknown = -65537, /* 0xFFFE FFFF */
- kDNSServiceErr_NoSuchName = -65538,
- kDNSServiceErr_NoMemory = -65539,
- kDNSServiceErr_BadParam = -65540,
- kDNSServiceErr_BadReference = -65541,
- kDNSServiceErr_BadState = -65542,
- kDNSServiceErr_BadFlags = -65543,
- kDNSServiceErr_Unsupported = -65544,
- kDNSServiceErr_NotInitialized = -65545,
- kDNSServiceErr_AlreadyRegistered = -65547,
- kDNSServiceErr_NameConflict = -65548,
- kDNSServiceErr_Invalid = -65549,
- kDNSServiceErr_Incompatible = -65551, /* client library incompatible with daemon */
- kDNSServiceErr_BadinterfaceIndex = -65552
- /* mDNS Error codes are in the range
- * FFFE FF00 (-65792) to FFFE FFFF (-65537) */
- };
-
-
-/* Maximum length, in bytes, of a domain name represented as an escaped C-String */
-#define kDNSServiceMaxDomainName 1005
-
-
-typedef uint32_t DNSServiceFlags;
-typedef int32_t DNSServiceErrorType;
-
-
-/*********************************************************************************************
- *
- * Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
- *
- *********************************************************************************************/
-
-
-/* DNSServiceRefSockFD()
- *
- * Access underlying Unix domain socket for an initialized DNSServiceRef.
- * The DNS Service Discovery implmementation uses this socket to communicate between
- * the client and the mDNSResponder daemon. The application MUST NOT directly read from
- * or write to this socket. Access to the socket is provided so that it can be used as a
- * run loop source, or in a select() loop: when data is available for reading on the socket,
- * DNSServiceProcessResult() should be called, which will extract the daemon's reply from
- * the socket, and pass it to the appropriate application callback. By using a run loop or
- * select(), results from the daemon can be processed asynchronously. Without using these
- * constructs, DNSServiceProcessResult() will block until the response from the daemon arrives.
- * The client is responsible for ensuring that the data on the socket is processed in a timely
- * fashion - the daemon may terminate its connection with a client that does not clear its
- * socket buffer.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls.
- *
- * return value: The DNSServiceRef's underlying socket descriptor, or -1 on
- * error.
- */
-
-int DNSServiceRefSockFD(DNSServiceRef sdRef);
-
-/* DNSServiceProcessResult()
- *
- * Read a reply from the daemon, calling the appropriate application callback. This call will
- * block until the daemon's response is received. Use DNSServiceRefSockFD() in
- * conjunction with a run loop or select() to determine the presence of a response from the
- * server before calling this function to process the reply without blocking. Call this function
- * at any point if it is acceptable to block until the daemon's response arrives. Note that the
- * client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is
- * a reply from the daemon - the daemon may terminate its connection with a client that does not
- * process the daemon's responses.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls
- * that take a callback parameter.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred.
- */
-
-DNSServiceErrorType DNSServiceProcessResult(DNSServiceRef sdRef);
-
-/* DNSServiceRefDeallocate()
- *
- * Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
- * Any services or records registered with this DNSServiceRef will be deregistered. Any
- * Browse, Resolve, or Query operations called with this reference will be terminated. If the
- * reference's underlying socket is used in a run loop or select() call, it should be removed BEFORE
- * DNSServiceRefDeallocate() is called, as this function closes the reference's socket.
- *
- * Note: This call is to be used only with the DNSServiceRef defined by this API. It is
- * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
- * DNSServiceDiscovery.h API.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls.
- *
- */
-
-void DNSServiceRefDeallocate(DNSServiceRef sdRef);
-
-
-/*********************************************************************************************
- *
- * Domain Enumeration
- *
- *********************************************************************************************/
-
-/* DNSServiceEnumerateDomains()
- *
- * Asynchronously enumerate domains available for browsing and registration.
- * Currently, the only domain returned is "local.", but other domains will be returned in future.
- *
- * The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
- * are to be found.
- *
- *
- * DNSServiceDomainEnumReply Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceEnumerateDomains().
- *
- * flags: Possible values are:
- * 1 (MoreComing)
- * 2 (Add/Remove)
- * 4 (Add Default)
- *
- * interfaceIndex: Specifies the interface on which the domain exists. (The index for a given
- * interface is determined via the if_nametoindex() family of calls.)
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
- * the failure that occurred (other parameters are undefined if errorCode is nonzero).
- *
- * replyDomain: The name of the domain.
- *
- * context: The context pointer passed to DNSServiceEnumerateDomains.
- *
- */
-
-typedef void (*DNSServiceDomainEnumReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *replyDomain,
- void *context
- );
-
-/* DNSServiceEnumerateDomains() Parameters:
- *
- *
- * sdRef: A pointer to an uninitialized sdRef. May be passed to
- * DNSServiceRefDeallocate() to cancel the enumeration.
- *
- * flags: Possible values are:
- * 0 (BrowseDomains) to enumerate domains recommended for browsing.
- * 32 (RegistrationDomains) to enumerate domains recommended for registration.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to look for domains.
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to enumerate domains on
- * all interfaces.
- *
- * callBack: The function to be called when a domain is found or the call asynchronously
- * fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is not invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSServiceEnumerateDomains
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceDomainEnumReply callBack,
- void *context /* may be NULL */
- );
-
-/*********************************************************************************************
- *
- * Service Registration
- *
- *********************************************************************************************/
-
-/* Register a service that is discovered via Browse() and Resolve() calls.
- *
- *
- * DNSServiceRegisterReply() Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceRegister().
- *
- * flags: Currently unused, reserved for future use.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred (including name conflicts, if the
- * kDNSServiceFlagsNoAutoRenameOnConflict flag was passed to the
- * callout.) Other parameters are undefined if errorCode is nonzero.
- *
- * name: The service name registered (if the application did not specify a name in
- * DNSServiceRegister(), this indicates what name was automatically chosen).
- *
- * regtype: The type of service registered, as it was passed to the callout.
- *
- * domain: The domain on which the service was registered (if the application did not
- * specify a domain in DNSServiceRegister(), this indicates the default domain
- * on which the service was registered).
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (*DNSServiceRegisterReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- const char *name,
- const char *regtype,
- const char *domain,
- void *context
- );
-
-/* DNSServiceRegister() Parameters:
- *
- * sdRef: A pointer to an uninitialized sdRef. If this call succeeds, the reference
- * may be passed to
- * DNSServiceRefDeallocate() to deregister the service.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to register the service
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to register on all
- * available interfaces. Pass -1 to register a service only on the local
- * machine (service will not be visible to remote hosts.)
- *
- * flags: Indicates the renaming behavior on name conflict (most applications
- * will pass 0). See flag definitions above for details.
- *
- * name: If non-NULL, specifies the service name to be registered.
- * Most applications will not specify a name, in which case the
- * computer name is used (this name is communicated to the client via
- * the callback).
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- *
- * domain: If non-NULL, specifies the domain on which to advertise the service.
- * Most applications will not specify a domain, instead automatically
- * registering in the default domain(s).
- *
- * host: If non-NULL, specifies the SRV target host name. Most applications
- * will not specify a host, instead automatically using the machine's
- * default host name(s). Note that specifying a non-NULL host does NOT
- * create an address record for that host - the application is responsible
- * for ensuring that the appropriate address record exists, or creating it
- * via DNSServiceRegisterRecord().
- *
- * port: The port on which the service accepts connections. Pass 0 for a
- * "placeholder" service (i.e. a service that will not be discovered by
- * browsing, but will cause a name conflict if another client tries to
- * register that same name.) Most clients will not use placeholder services.
- *
- * txtLen: The length of the txtRecord, in bytes. Must be zero if the txtRecord is NULL.
- *
- * txtRecord: The txt record rdata. May be NULL. Note that a non-NULL txtRecord
- * MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
- * <length byte> <data> ...
- *
- * callBack: The function to be called when the registration completes or asynchronously
- * fails. The client MAY pass NULL for the callback - The client will NOT be notified
- * of the default values picked on its behalf, and the client will NOT be notified of any
- * asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
- * of the service. The client may NOT pass the NoAutoRename flag if the callback is NULL.
- * The client may still deregister the service at any time via DNSServiceRefDeallocate().
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized.)
- *
- */
-
-DNSServiceErrorType DNSServiceRegister
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name, /* may be NULL */
- const char *regtype,
- const char *domain, /* may be NULL */
- const char *host, /* may be NULL */
- uint16_t port,
- uint16_t txtLen,
- const void *txtRecord, /* may be NULL */
- DNSServiceRegisterReply callBack, /* may be NULL */
- void *context /* may be NULL */
- );
-
-/* DNSServiceAddRecord()
- *
- * Add a record to a registered service. The name of the record will be the same as the
- * registered service's name.
- * The record can later be updated or deregistered by passing the RecordRef initialized
- * by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *
- *
- * Parameters;
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceRegister().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
- * call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * rrtype: The type of the record (e.g. TXT, SRV, etc), as defined in nameser.h.
- *
- * rdlen: The length, in bytes, of the rdata.
- *
- * rdata: The raw rdata to be contained in the added resource record.
- *
- * ttl: The time to live of the resource record, in seconds.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred (the RecordRef is not initialized).
- */
-
-DNSServiceErrorType DNSServiceAddRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint16_t rrtype,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
- );
-
-/* DNSServiceUpdateRecord
- *
- * Update a registered resource record. The record must either be:
- * - The primary txt record of a service registered via DNSServiceRegister()
- * - A record added to a registered service via DNSServiceAddRecord()
- * - An individual record registered by DNSServiceRegisterRecord()
- *
- *
- * Parameters:
- *
- * sdRef: A DNSServiceRef that was initialized by DNSServiceRegister()
- * or DNSServiceCreateConnection().
- *
- * RecordRef: A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the
- * service's primary txt record.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * rdlen: The length, in bytes, of the new rdata.
- *
- * rdata: The new rdata to be contained in the updated resource record.
- *
- * ttl: The time to live of the updated resource record, in seconds.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSServiceUpdateRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef, /* may be NULL */
- DNSServiceFlags flags,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
- );
-
-/* DNSServiceRemoveRecord
- *
- * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
- * an record registered individually via DNSServiceRegisterRecord().
- *
- * Parameters:
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceRegister() (if the
- * record being removed was registered via DNSServiceAddRecord()) or by
- * DNSServiceCreateConnection() (if the record being removed was registered via
- * DNSServiceRegisterRecord()).
- *
- * recordRef: A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
- * or DNSServiceRegisterRecord().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSServiceRemoveRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags
- );
-
-
-/*********************************************************************************************
- *
- * Service Discovery
- *
- *********************************************************************************************/
-
-
-/* Browse for instances of a service.
- *
- *
- * DNSServiceBrowseReply() Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceBrowse().
- *
- * flags: Possible values are MoreComing and Add/Remove. See flag definitions
- * for details.
- *
- * interfaceIndex: The interface on which the service is advertised. This index should
- * be passed to DNSServiceResolve() when resolving the service.
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * the errorCode is nonzero.
- *
- * serviceName: The service name discovered.
- *
- * regtype: The service type, as passed in to DNSServiceBrowse().
- *
- * domain: The domain on which the service was discovered (if the application did not
- * specify a domain in DNSServicBrowse(), this indicates the domain on which the
- * service was discovered.)
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (*DNSServiceBrowseReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *serviceName,
- const char *regtype,
- const char *replyDomain,
- void *context
- );
-
-/* DNSServiceBrowse() Parameters:
- *
- * sdRef: A pointer to an uninitialized sdRef. May be passed to
- * DNSServiceRefDeallocate() to terminate the browse.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to browse for services
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to browse on all available
- * interfaces. Pass -1 to only browse for services provided on the local host.
- *
- * regtype: The service type being browsed for followed by the protocol, separated by a
- * dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- *
- * domain: If non-NULL, specifies the domain on which to browse for services.
- * Most applications will not specify a domain, instead browsing on the
- * default domain(s).
- *
- * callBack: The function to be called when an instance of the service being browsed for
- * is found, or if the call asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is not invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSServiceBrowse
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *regtype,
- const char *domain, /* may be NULL */
- DNSServiceBrowseReply callBack,
- void *context /* may be NULL */
- );
-
-/* DNSServiceResolve()
- *
- * Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
- * txt record.
- *
- * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
- * DNSServiceQueryRecord() instead, as it is more efficient for this task.
- *
- * Note: When the desired results have been returned, the client MUST terminate the resolve by calling
- * DNSServiceRefDeallocate().
- *
- * Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record and
- * a single TXT record (the TXT record may be empty.) To resolve non-standard services with multiple
- * SRV or TXT records, DNSServiceQueryRecord() should be used.
- *
- * DNSServiceResolveReply Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceResolve().
- *
- * flags: Possible values are MoreComing and Add/Remove. See flag definitions
- * for details.
- *
- * interfaceIndex: The interface on which the service was resolved.
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * the errorCode is nonzero.
- *
- * fullname: The full service domain name, in the form <servicename>.<protocol>.<domain>.
- * (Any literal dots (".") are escaped with a backslash ("\."), and literal
- * backslashes are escaped with a second backslash ("\\"), e.g. a web server
- * named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.").
- * This is the appropriate format to pass to standard system DNS APIs such as
- * res_query(), or to the special-purpose functions included in this API that
- * take fullname parameters.
- *
- * hosttarget: The target hostname of the machine providing the service. This name can
- * be passed to functions like gethostbyname() to identify the host's IP address.
- *
- * port: The port number on which connections are accepted for this service.
- *
- * txtLen: The length of the txt record, in bytes.
- *
- * txtRecord: The service's primary txt record, in standard txt record format.
- *
-
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (*DNSServiceResolveReply)
- (
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullname,
- const char *hosttarget,
- uint16_t port,
- uint16_t txtLen,
- const char *txtRecord,
- void *context
- );
-
-/* DNSServiceResolve() Parameters
- *
- * sdRef: A pointer to an uninitialized sdRef. May be passed to
- * DNSServiceRefDeallocate() to terminate the resolve.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * interfaceIndex: The interface on which to resolve the service. The client should
- * pass the interface on which the servicename was discovered, i.e.
- * the interfaceIndex passed to the DNSServiceBrowseReply callback,
- * or 0 to resolve the named service on all available interfaces.
- *
- * name: The servicename to be resolved.
- *
- * regtype: The service type being resolved followed by the protocol, separated by a
- * dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- *
- * domain: The domain on which the service is registered, i.e. the domain passed
- * to the DNSServiceBrowseReply callback.
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-
-DNSServiceErrorType DNSServiceResolve
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name,
- const char *regtype,
- const char *domain,
- DNSServiceResolveReply callBack,
- void *context /* may be NULL */
- );
-
-
-/*********************************************************************************************
- *
- * Special Purpose Calls (most applications will not use these)
- *
- *********************************************************************************************/
-
-/* DNS Naming Conventions:
- *
- * The following functions refer to resource records by their full domain name, unlike the above
- * functions which divide the name into servicename/regtype/domain fields. In the above functions,
- * a dot (".") is considered to be a literal dot in the servicename field (e.g. "Dr. Pepper") and
- * a label separator in the regtype ("_ftp._tcp") or domain ("apple.com") fields. Literal dots in
- * the domain field would be escaped with a backslash, and literal backslashes would be escaped with
- * a second backslash (this is generally not an issue, as domain names on the Internet today almost
- * never use characters other than letters, digits, or hyphens, and the dots are label separators.)
- * Furthermore, this is transparent to the caller, so long as the fields are passed between functions
- * without manipulation. However, the following, special-purpose calls use a single, full domain name.
- * As such, all dots are considered to be label separators, unless escaped, and all backslashes are
- * considered to be escape characters, unless preceded by a second backslash. For example, the name
- * "Dr. Smith \ Dr. Johnson" could be passed literally as a service name parameter in the above calls,
- * but in the special purpose call, the dots and backslash would have to be escaped
- * (e.g. "Dr\. Smith \\ Dr\. Johnson._ftp._tcp.apple.com" for an ftp service on the apple.com domain.)
- */
-
-/* DNSServiceConstructFullName()
- *
- * Concatenate a three-part domain name (as returned by the above callbacks) into a properly-escaped
- * full domain name. Note that callbacks in the above functions ALREADY ESCAPE strings where necessary.
- *
- * Parameters:
- *
- * fullName: A pointer to a buffer that where the resulting full domain name is to be written.
- * The buffer must be kDNSServiceDiscoveryMaxDomainName (1005) bytes in length to
- * accommodate the longest legal domain name without buffer overrun.
- *
- * service: The service name - any dots or slashes must NOT be escaped.
- * May be NULL (to construct a PTR record name, e.g.
- * "_ftp._tcp.apple.com").
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp").
- *
- * domain: The domain name, e.g. "apple.com". Any literal dots or backslashes
- * must be escaped.
- *
- * return value: Returns 0 on success, -1 on error.
- *
- */
-
-int DNSServiceConstructFullName
- (
- char *fullName,
- const char *service, /* may be NULL */
- const char *regtype,
- const char *domain
- );
-
-/* DNSServiceCreateConnection()
- *
- * Create a connection to the daemon allowing efficient registration of
- * multiple individual records.
- *
- *
- * Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
- * the reference (via DNSServiceRefDeallocate()) severs the
- * connection and deregisters all records registered on this connection.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred (in which
- * case the DNSServiceRef is not initialized).
- */
-
-DNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef);
-
-
-/* DNSServiceRegisterRecord
- *
- * Register an individual resource record on a connected DNSServiceRef.
- *
- * Note that name conflicts occurring for records registered via this call must be handled
- * by the client in the callback.
- *
- *
- * DNSServiceRegisterRecordReply() parameters:
- *
- * sdRef: The connected DNSServiceRef initialized by
- * DNSServiceDiscoveryConnect().
- *
- * RecordRef: The DNSRecordRef initialized by DNSServiceRegisterRecord().
- *
- * flags: Currently unused, reserved for future use.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred (including name conflicts.)
- * Other parameters are undefined if errorCode is nonzero.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
- typedef void (*DNSServiceRegisterRecordReply)
- (
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- void *context
- );
-
-
-/* DNSServiceRegisterRecord() Parameters:
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceCreateConnection().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
- * call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- * (To deregister ALL records registered on a single connected DNSServiceRef
- * and deallocate each of their corresponding DNSServiceRecordRefs, call
- * DNSServiceRefDealloocate()).
- *
- * flags: Possible values are Shared/Unique (see flag type definitions for details).
- *
- * interfaceIndex: If non-zero, specifies the interface on which to register the record
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the record to be registered on all interfaces.
- * Passing -1 causes the record to only be visible on the local host.
- *
- * fullname: The full domain name of the resource record.
- *
- * rrtype: The numerical type of the resource record (e.g. PTR, SRV, etc), as defined
- * in nameser.h.
- *
- * rrclass: The class of the resource record, as defined in nameser.h (usually 1 for the
- * Internet class).
- *
- * rdlen: Length, in bytes, of the rdata.
- *
- * rdata: A pointer to the raw rdata, as it is to appear in the DNS record.
- *
- * ttl: The time to live of the resource record, in seconds.
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails (e.g. because of a name conflict.)
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSRecordRef is
- * not initialized.)
- */
-
-
-DNSServiceErrorType DNSServiceRegisterRecord
- (
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- DNSServiceRegisterRecordReply callBack,
- void *context /* may be NULL */
- );
-
-
-/* DNSServiceQueryRecord
- *
- * Query for an arbitrary DNS record.
- *
- *
- * DNSServiceQueryRecordReply() Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceQueryRecord().
- *
- * flags: Possible values are Finished/MoreComing.
- *
- * interfaceIndex: The interface on which the query was resolved (the index for a given
- * interface is determined via the if_nametoindex() family of calls).
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * errorCode is nonzero.
- *
- * fullname: The resource record's full domain name.
- *
- * rrtype: The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
- *
- * rrclass: The class of the resource record, as defined in nameser.h (usually 1).
- *
- * rdlen: The length, in bytes, of the resource record rdata.
- *
- * rdata: The raw rdata of the resource record.
- *
- * ttl: The resource record's time to live, in seconds.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (*DNSServiceQueryRecordReply)
- (
- DNSServiceRef DNSServiceRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- void *context
- );
-
-/* DNSServiceQueryRecord() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef.
- *
- * flags: Currently unused, reserved for future use.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to issue the query
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the name to be queried for on all
- * interfaces. Passing -1 causes the name to be queried for only on the
- * local host.
- *
- * fullname: The full domain name of the resource record to be queried for.
- *
- * rrtype: The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
- * as defined in nameser.h.
- *
- * rrclass: The class of the resource record, as defined in nameser.h
- * (usually 1 for the Internet class).
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized.)
- */
-
-DNSServiceErrorType DNSServiceQueryRecord
- (
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- DNSServiceQueryRecordReply callBack,
- void *context /* may be NULL */
- );
-
-/* DNSServiceReconfirmRecord
- *
- * Instruct the daemon to verify the validity of a resource record that appears to
- * be out of date (e.g. because tcp connection to a service's target failed.)
- * Causes the record to be flushed from the daemon's cache (as well as all other
- * daemons' caches on the network) if the record is determined to be invalid.
- *
- * Parameters:
- *
- * flags: Currently unused, reserved for future use.
- *
- * fullname: The resource record's full domain name.
- *
- * rrtype: The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
- *
- * rrclass: The class of the resource record, as defined in nameser.h (usually 1).
- *
- * rdlen: The length, in bytes, of the resource record rdata.
- *
- * rdata: The raw rdata of the resource record.
- *
- */
-
-void DNSServiceReconfirmRecord
- (
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata
- );
-
-
-#endif // _DNS_SD_H
-
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: mDNSMacOSX.c,v $
+Revision 1.115.2.4 2004/04/23 00:34:06 cheshire
+<rdar://problem/3628978>: mDNSResponder messages on wake
+Take care to correctly update InterfaceIDs when a dormant interface comes back to life
+
+Revision 1.115.2.3 2004/04/08 23:18:11 cheshire
+<rdar://problem/3609972> When interface turned off, browse "remove" events delivered with interface index zero
+Refinement from Bob Bradley: Should use "mDNS *const m" instead of referencing mDNSStorage directly
+
+Revision 1.115.2.2 2004/04/08 00:42:37 cheshire
+<rdar://problem/3609972> When interface turned off, browse "remove" events delivered with interface index zero
+Unify use of the InterfaceID field, and make code that walks the list respect the CurrentlyActive flag
+
+Revision 1.115.2.1 2004/04/07 01:08:15 cheshire
+<rdar://problem/3609972> When interface turned off, browse "remove" events delivered with interface index zero
+
+Revision 1.115 2003/09/10 00:45:55 cheshire
+<rdar://problem/3412328> Don't log "sendto failed" errors during the first two minutes of startup
+
+Revision 1.114 2003/08/27 02:55:13 cheshire
+<rdar://problem/3387910>: Bug: Don't report mDNSPlatformSendUDP sendto errno 64 (Host is down)
+
+Revision 1.113 2003/08/19 22:20:00 cheshire
+<rdar://problem/3376721> Don't use IPv6 on interfaces that have a routable IPv4 address configured
+More minor refinements
+
+Revision 1.112 2003/08/19 03:04:43 cheshire
+<rdar://problem/3376721> Don't use IPv6 on interfaces that have a routable IPv4 address configured
+
+Revision 1.111 2003/08/18 22:53:37 cheshire
+<rdar://problem/3382647> mDNSResponder divide by zero in mDNSPlatformTimeNow()
+
+Revision 1.110 2003/08/16 03:39:00 cheshire
+<rdar://problem/3338440> InterfaceID -1 indicates "local only"
+
+Revision 1.109 2003/08/15 02:19:49 cheshire
+<rdar://problem/3375225> syslog messages: myCFSocketCallBack recvfrom skt 6 error -1 errno 35
+Also limit number of messages to at most 100
+
+Revision 1.108 2003/08/12 22:24:52 cheshire
+<rdar://problem/3375225> syslog messages: myCFSocketCallBack recvfrom skt 6 error -1 errno 35
+This message indicates a kernel bug, but still we don't want to flood syslog.
+Do a sleep(1) after writing this log message, to limit the rate.
+
+Revision 1.107 2003/08/12 19:56:25 cheshire
+Update to APSL 2.0
+
+Revision 1.106 2003/08/12 13:48:32 cheshire
+Add comment explaining clockdivisor calculation
+
+Revision 1.105 2003/08/12 13:44:14 cheshire
+<rdar://problem/3370229> mDNSResponder *VERY* unhappy if time goes backwards
+Use mach_absolute_time() (which is guaranteed to always go forwards, resetting only on reboot)
+instead of gettimeofday() (which can jump back if the user manually changes their time/date)
+
+Revision 1.104 2003/08/12 13:12:07 cheshire
+Textual search/replace: Indicate local functions using "mDNSlocal" instead of "static"
+
+Revision 1.103 2003/08/08 18:36:04 cheshire
+<rdar://problem/3344154> Only need to revalidate on interface removal on platforms that have the PhantomInterfaces bug
+
+Revision 1.102 2003/08/06 00:14:52 cheshire
+<rdar://problem/3330324> Need to check IP TTL on responses
+Also add corresponding checks in the IPv6 code path
+
+Revision 1.101 2003/08/05 22:20:16 cheshire
+<rdar://problem/3330324> Need to check IP TTL on responses
+
+Revision 1.100 2003/08/05 21:18:50 cheshire
+<rdar://problem/3363185> mDNSResponder should ignore 6to4
+Only use interfaces that are marked as multicast-capable (IFF_MULTICAST)
+
+Revision 1.99 2003/08/05 20:13:52 cheshire
+<rdar://problem/3294080> mDNSResponder using IPv6 interfaces before they are ready
+Ignore interfaces with the IN6_IFF_NOTREADY flag set
+
+Revision 1.98 2003/07/20 03:38:51 ksekar
+Bug #: 3320722
+Completed support for Unix-domain socket based API.
+
+Revision 1.97 2003/07/19 03:15:16 cheshire
+Add generic MemAllocate/MemFree prototypes to mDNSPlatformFunctions.h,
+and add the obvious trivial implementations to each platform support layer
+
+Revision 1.96 2003/07/18 00:30:00 cheshire
+<rdar://problem/3268878> Remove mDNSResponder version from packet header and use HINFO record instead
+
+Revision 1.95 2003/07/12 03:15:20 cheshire
+<rdar://problem/3324848> After SCDynamicStore notification, mDNSResponder updates
+m->hostlabel even if user hasn't actually actually changed their dot-local hostname
+
+Revision 1.94 2003/07/03 00:51:54 cheshire
+<rdar://problem/3287213> When select() and recvmgs() disagree, get more info from kernel about the socket state
+
+Revision 1.93 2003/07/03 00:09:14 cheshire
+<rdar://problem/3286004> New APIs require a mDNSPlatformInterfaceIDfromInterfaceIndex() call
+Additional refinement suggested by Josh: Use info->scope_id instead of if_nametoindex(info->ifa_name);
+
+Revision 1.92 2003/07/02 21:19:51 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.91 2003/06/24 01:53:51 cheshire
+Minor update to comments
+
+Revision 1.90 2003/06/24 01:51:47 cheshire
+<rdar://problem/3303118> Oops: Double-dispose of sockets
+Don't need to close sockets: CFSocketInvalidate() does that for us
+
+Revision 1.89 2003/06/21 18:12:47 cheshire
+<rdar://problem/3296061> Rendezvous cannot handle interfaces whose total name is >3 chars
+One-line change: should say "IF_NAMESIZE", not sizeof(ifname)
+
+Revision 1.88 2003/06/12 23:38:37 cheshire
+<rdar://problem/3291162> mDNSResponder doesn't detect some configuration changes
+Also check that scope_id matches before concluding that two interfaces are the same
+
+Revision 1.87 2003/06/10 01:14:11 cheshire
+<rdar://problem/3286004> New APIs require a mDNSPlatformInterfaceIDfromInterfaceIndex() call
+
+Revision 1.86 2003/05/28 02:41:52 cheshire
+<rdar://problem/3034346> Time to remove Mac OS 9 UDP Port 53 legacy support
+
+Revision 1.85 2003/05/28 02:39:47 cheshire
+Minor change to debugging messages
+
+Revision 1.84 2003/05/27 22:29:40 cheshire
+Remove out-dated comment
+
+Revision 1.83 2003/05/26 03:21:29 cheshire
+Tidy up address structure naming:
+mDNSIPAddr => mDNSv4Addr (for consistency with mDNSv6Addr)
+mDNSAddr.addr.ipv4 => mDNSAddr.ip.v4
+mDNSAddr.addr.ipv6 => mDNSAddr.ip.v6
+
+Revision 1.82 2003/05/26 03:01:27 cheshire
+<rdar://problem/3268904> sprintf/vsprintf-style functions are unsafe; use snprintf/vsnprintf instead
+
+Revision 1.81 2003/05/24 02:06:42 cheshire
+<rdar://problem/3268480> IPv6 Multicast Loopback doesn't work
+Tried setting IPV6_MULTICAST_LOOP; it doesn't help.
+However, it is probably wise to have the code explicitly set this socket
+option anyway, in case the default changes in later versions of Unix.
+
+Revision 1.80 2003/05/24 02:02:24 cheshire
+<rdar://problem/3221880> if_indextoname consumes a lot of CPU
+Fix error in myIfIndexToName; was returning prematurely
+
+Revision 1.79 2003/05/23 23:07:44 cheshire
+<rdar://problem/3268199> Must not write to stderr when running as daemon
+
+Revision 1.78 2003/05/23 01:19:04 cheshire
+<rdar://problem/3267085> mDNSResponder needs to signal type of service to AirPort
+Mark packets as high-throughput/low-delay (i.e. lowest reliability) to get maximum 802.11 multicast rate
+
+Revision 1.77 2003/05/23 01:12:05 cheshire
+Minor code tidying
+
+Revision 1.76 2003/05/22 01:26:01 cheshire
+Tidy up log messages
+
+Revision 1.75 2003/05/22 00:07:09 cheshire
+<rdar://problem/3264366> myCFSocketCallBack recvfrom(5) error 1, errno 35
+Extra logging to determine whether there is a bug in CFSocket
+
+Revision 1.74 2003/05/21 20:20:12 cheshire
+Fix warnings (mainly printf format string warnings, like using "%d" where
+it should say "%lu", etc.) and improve error logging (use strerror()
+to include textual error message as well as numeric error in log messages).
+
+Revision 1.73 2003/05/21 17:56:29 ksekar
+Bug #: <rdar://problem/3191277>: mDNSResponder doesn't watch for IPv6 address changes
+
+Revision 1.72 2003/05/14 18:48:41 cheshire
+<rdar://problem/3159272> mDNSResponder should be smarter about reconfigurations
+More minor refinements:
+CFSocket.c needs to do *all* its mDNS_DeregisterInterface calls before freeing memory
+mDNS_DeregisterInterface revalidates cache record when *any* representative of an interface goes away
+
+Revision 1.71 2003/05/14 07:08:37 cheshire
+<rdar://problem/3159272> mDNSResponder should be smarter about reconfigurations
+Previously, when there was any network configuration change, mDNSResponder
+would tear down the entire list of active interfaces and start again.
+That was very disruptive, and caused the entire cache to be flushed,
+and caused lots of extra network traffic. Now it only removes interfaces
+that have really gone, and only adds new ones that weren't there before.
+
+Revision 1.70 2003/05/07 18:30:24 cheshire
+Fix signed/unsigned comparison warning
+
+Revision 1.69 2003/05/06 20:14:44 cheshire
+Change "tp" to "tv"
+
+Revision 1.68 2003/05/06 00:00:49 cheshire
+<rdar://problem/3248914> Rationalize naming of domainname manipulation functions
+
+Revision 1.67 2003/04/29 00:43:44 cheshire
+Fix compiler warnings
+
+Revision 1.66 2003/04/26 02:41:58 cheshire
+<rdar://problem/3241281> Change timenow from a local variable to a structure member
+
+Revision 1.65 2003/04/26 02:34:01 cheshire
+Add missing mDNSexport
+
+Revision 1.64 2003/04/15 16:48:06 jgraessl
+Bug #: 3228833
+Modified code in CFSocket notifier function to read all packets on the socket
+instead of reading only one packet every time the notifier was called.
+
+Revision 1.63 2003/04/15 16:33:50 jgraessl
+Bug #: 3221880
+Switched to our own copy of if_indextoname to improve performance.
+
+Revision 1.62 2003/03/28 01:55:44 cheshire
+Minor improvements to debugging messages
+
+Revision 1.61 2003/03/27 03:30:56 cheshire
+<rdar://problem/3210018> Name conflicts not handled properly, resulting in memory corruption, and eventual crash
+Problem was that HostNameCallback() was calling mDNS_DeregisterInterface(), which is not safe in a callback
+Fixes:
+1. Make mDNS_DeregisterInterface() safe to call from a callback
+2. Make HostNameCallback() use mDNS_DeadvertiseInterface() instead
+ (it never really needed to deregister the interface at all)
+
+Revision 1.60 2003/03/15 04:40:38 cheshire
+Change type called "mDNSOpaqueID" to the more descriptive name "mDNSInterfaceID"
+
+Revision 1.59 2003/03/11 01:23:26 cheshire
+Bug #: 3194246 mDNSResponder socket problems
+
+Revision 1.58 2003/03/06 01:43:04 cheshire
+Bug #: 3189097 Additional debugging code in mDNSResponder
+Improve "LIST_ALL_INTERFACES" output
+
+Revision 1.57 2003/03/05 22:36:27 cheshire
+Bug #: 3186338 Loopback doesn't work with mDNSResponder-27
+Temporary workaround: Skip loopback interface *only* if we found at least one v4 interface to use
+
+Revision 1.56 2003/03/05 01:50:38 cheshire
+Bug #: 3189097 Additional debugging code in mDNSResponder
+
+Revision 1.55 2003/02/21 01:54:09 cheshire
+Bug #: 3099194 mDNSResponder needs performance improvements
+Switched to using new "mDNS_Execute" model (see "Implementer Notes.txt")
+
+Revision 1.54 2003/02/20 06:48:35 cheshire
+Bug #: 3169535 Xserve RAID needs to do interface-specific registrations
+Reviewed by: Josh Graessley, Bob Bradley
+
+Revision 1.53 2003/01/29 02:21:23 cheshire
+Return mStatus_Invalid if can't send packet because socket not available
+
+Revision 1.52 2003/01/28 19:39:43 jgraessl
+Enabling AAAA over IPv4 support.
+
+Revision 1.51 2003/01/28 05:11:23 cheshire
+Fixed backwards comparison in SearchForInterfaceByName
+
+Revision 1.50 2003/01/13 23:49:44 jgraessl
+Merged changes for the following fixes in to top of tree:
+3086540 computer name changes not handled properly
+3124348 service name changes are not properly handled
+3124352 announcements sent in pairs, failing chattiness test
+
+Revision 1.49 2002/12/23 22:13:30 jgraessl
+Reviewed by: Stuart Cheshire
+Initial IPv6 support for mDNSResponder.
+
+Revision 1.48 2002/11/22 01:37:52 cheshire
+Bug #: 3108426 mDNSResponder is monitoring ServiceEntities instead of InterfaceEntities
+
+Revision 1.47 2002/09/21 20:44:51 zarzycki
+Added APSL info
+
+Revision 1.46 2002/09/19 21:25:35 cheshire
+mDNS_snprintf() doesn't need to be in a separate file
+
+Revision 1.45 2002/09/17 01:45:13 cheshire
+Add LIST_ALL_INTERFACES symbol for debugging
+
+Revision 1.44 2002/09/17 01:36:23 cheshire
+Move Puma support to CFSocketPuma.c
+
+Revision 1.43 2002/09/17 01:05:28 cheshire
+Change mDNS_AdvertiseLocalAddresses to be an Init parameter instead of a global
+
+Revision 1.42 2002/09/16 23:13:50 cheshire
+Minor code tidying
+
+ */
+
+// ***************************************************************************
+// mDNS-CFSocket.c:
+// Supporting routines to run mDNS on a CFRunLoop platform
+// ***************************************************************************
+
+// Open Transport 2.7.x on Mac OS 9 used to send Multicast DNS queries to UDP port 53,
+// before the Multicast DNS port was changed to 5353. For this reason, the mDNSResponder
+// in earlier versions of Mac OS X 10.2 Jaguar used to set mDNS_AllowPort53 to 1 to allow
+// it to also listen and answer queries on UDP port 53. Now that Transport 2.8 (included in
+// the Classic subsystem of Mac OS X 10.2 Jaguar) has been corrected to issue Multicast DNS
+// queries on UDP port 5353, this backwards-compatibility legacy support is no longer needed.
+#define mDNS_AllowPort53 0
+
+// For debugging, set LIST_ALL_INTERFACES to 1 to display all found interfaces,
+// including ones that mDNSResponder chooses not to use.
+#define LIST_ALL_INTERFACES 0
+
+// For enabling AAAA records over IPv4. Setting this to 0 sends only
+// A records over IPv4 and AAAA over IPv6. Setting this to 1 sends both
+// AAAA and A records over both IPv4 and IPv6.
+#define AAAA_OVER_V4 1
+
+#include "mDNSClientAPI.h" // Defines the interface provided to the client layer above
+#include "mDNSPlatformFunctions.h" // Defines the interface to the supporting layer below
+#include "mDNSMacOSX.h" // Defines the specific types needed to run mDNS on this platform
+
+#include <stdio.h>
+#include <unistd.h> // For select() and close()
+#include <stdarg.h> // For va_list support
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <sys/uio.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include <netinet/in.h> // For IP_RECVTTL
+#ifndef IP_RECVTTL
+#define IP_RECVTTL 24 /* bool; receive reception TTL w/dgram */
+#endif
+
+#include <netinet/in_systm.h> // For n_long, required by <netinet/ip.h> below
+#include <netinet/ip.h> // For IPTOS_LOWDELAY etc.
+#include <netinet6/in6_var.h> // For IN6_IFF_NOTREADY etc.
+
+// Code contributed by Dave Heller:
+// Define RUN_ON_PUMA_WITHOUT_IFADDRS to compile code that will
+// work on Mac OS X 10.1, which does not have the getifaddrs call.
+#define RUN_ON_PUMA_WITHOUT_IFADDRS 0
+#if RUN_ON_PUMA_WITHOUT_IFADDRS
+#include "CFSocketPuma.c"
+#else
+#include <ifaddrs.h>
+#endif
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOMessage.h>
+#include <mach/mach_time.h>
+
+// ***************************************************************************
+// Globals
+
+static mDNSu32 clockdivisor = 0;
+
+// ***************************************************************************
+// Macros
+
+#define mDNSSameIPv4Address(A,B) ((A).NotAnInteger == (B).NotAnInteger)
+#define mDNSSameIPv6Address(A,B) ((A).l[0] == (B).l[0] && (A).l[1] == (B).l[1] && (A).l[2] == (B).l[2] && (A).l[3] == (B).l[3])
+
+#define mDNSAddressIsAllDNSLinkGroup(X) ( \
+ ((X)->type == mDNSAddrType_IPv4 && mDNSSameIPv4Address((X)->ip.v4, AllDNSLinkGroup )) || \
+ ((X)->type == mDNSAddrType_IPv6 && mDNSSameIPv6Address((X)->ip.v6, AllDNSLinkGroupv6)) )
+
+// ***************************************************************************
+// Functions
+
+// Note, this uses mDNS_vsnprintf instead of standard "vsnprintf", because mDNS_vsnprintf knows
+// how to print special data types like IP addresses and length-prefixed domain names
+#if MDNS_DEBUGMSGS
+mDNSexport void debugf_(const char *format, ...)
+ {
+ unsigned char buffer[512];
+ va_list ptr;
+ va_start(ptr,format);
+ buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
+ va_end(ptr);
+ fprintf(stderr,"%s\n", buffer);
+ fflush(stderr);
+ }
+#endif
+
+#if MDNS_DEBUGMSGS > 1
+mDNSexport void verbosedebugf_(const char *format, ...)
+ {
+ unsigned char buffer[512];
+ va_list ptr;
+ va_start(ptr,format);
+ buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
+ va_end(ptr);
+ fprintf(stderr,"%s\n", buffer);
+ fflush(stderr);
+ }
+#endif
+
+mDNSexport void LogMsg(const char *format, ...)
+ {
+ unsigned char buffer[512];
+ va_list ptr;
+ va_start(ptr,format);
+ buffer[mDNS_vsnprintf((char *)buffer, sizeof(buffer), format, ptr)] = 0;
+ va_end(ptr);
+
+ extern int debug_mode;
+ if (debug_mode) // In debug_mode we write to stderr
+ {
+ fprintf(stderr,"%s\n", buffer);
+ fflush(stderr);
+ }
+ else // else, in production mode, we write to syslog
+ {
+ openlog("mDNSResponder", LOG_CONS | LOG_PERROR | LOG_PID, LOG_DAEMON);
+ syslog(LOG_ERR, "%s", buffer);
+ closelog();
+ }
+ }
+
+mDNSlocal struct ifaddrs* myGetIfAddrs(int refresh)
+ {
+ static struct ifaddrs *ifa = NULL;
+
+ if (refresh && ifa)
+ {
+ freeifaddrs(ifa);
+ ifa = NULL;
+ }
+
+ if (ifa == NULL) getifaddrs(&ifa);
+
+ return ifa;
+ }
+
+mDNSlocal int myIfIndexToName(u_short index, char* name)
+ {
+ struct ifaddrs *ifa;
+ for (ifa = myGetIfAddrs(0); ifa; ifa = ifa->ifa_next)
+ if (ifa->ifa_addr->sa_family == AF_LINK)
+ if (((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index == index)
+ { strncpy(name, ifa->ifa_name, IF_NAMESIZE); return 0; }
+ return -1;
+ }
+
+mDNSexport mDNSInterfaceID mDNSPlatformInterfaceIDfromInterfaceIndex(const mDNS *const m, mDNSu32 index)
+ {
+ NetworkInterfaceInfoOSX *i;
+ if (index == (uint32_t)~0) return((mDNSInterfaceID)~0);
+ if (index)
+ for (i = m->p->InterfaceList; i; i = i->next)
+ if (i->ifinfo.InterfaceID && i->scope_id == index) // Don't get tricked by inactive interfaces
+ return(i->ifinfo.InterfaceID);
+ return(mDNSNULL);
+ }
+
+mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(const mDNS *const m, mDNSInterfaceID id)
+ {
+ NetworkInterfaceInfoOSX *i;
+ if (id == (mDNSInterfaceID)~0) return((mDNSu32)~0);
+ if (id)
+ for (i = m->p->InterfaceList; i; i = i->next)
+ // Don't use i->ifinfo.InterfaceID here because we want to find inactive interfaces where that's not set
+ if ((mDNSInterfaceID)i == id)
+ return i->scope_id;
+ return 0;
+ }
+
+mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end,
+ mDNSInterfaceID InterfaceID, mDNSIPPort srcPort, const mDNSAddr *dst, mDNSIPPort dstPort)
+ {
+ #pragma unused(m)
+ NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)InterfaceID;
+ struct sockaddr_storage to;
+ int s, err;
+
+ if (!InterfaceID) { LogMsg("mDNSPlatformSendUDP ERROR! Cannot send from zero InterfaceID"); return mStatus_BadParamErr; }
+
+ if (dst->type == mDNSAddrType_IPv4)
+ {
+ struct sockaddr_in* sin_to = (struct sockaddr_in*)&to;
+ sin_to->sin_len = sizeof(*sin_to);
+ sin_to->sin_family = AF_INET;
+ sin_to->sin_port = dstPort.NotAnInteger;
+ sin_to->sin_addr.s_addr = dst->ip.v4.NotAnInteger;
+ }
+ else if (dst->type == mDNSAddrType_IPv6)
+ {
+ struct sockaddr_in6* sin6_to = (struct sockaddr_in6*)&to;
+ sin6_to->sin6_len = sizeof(*sin6_to);
+ sin6_to->sin6_family = AF_INET6;
+ sin6_to->sin6_port = dstPort.NotAnInteger;
+ sin6_to->sin6_flowinfo = 0;
+ sin6_to->sin6_addr = *(struct in6_addr*)&dst->ip.v6;
+ sin6_to->sin6_scope_id = info->scope_id;
+ }
+ else
+ {
+ LogMsg("mDNSPlatformSendUDP: dst is not an IPv4 or IPv6 address!\n");
+ return mStatus_BadParamErr;
+ }
+
+ if (srcPort.NotAnInteger == MulticastDNSPort.NotAnInteger)
+ {
+ if (dst->type == mDNSAddrType_IPv4) s = info->sktv4;
+ else if (dst->type == mDNSAddrType_IPv6) s = info->sktv6;
+ else s = -1;
+ }
+#if mDNS_AllowPort53
+ else if (srcPort.NotAnInteger == UnicastDNSPort.NotAnInteger && dst->type == mDNSAddrType_IPv4)
+ s = info->skt53;
+#endif
+ else { LogMsg("Source port %d not allowed", (mDNSu16)srcPort.b[0]<<8 | srcPort.b[1]); return(-1); }
+
+ if (s >= 0)
+ verbosedebugf("mDNSPlatformSendUDP: sending on InterfaceID %X %s/%d to %#a:%d skt %d",
+ InterfaceID, info->ifa_name, dst->type, dst, (mDNSu16)dstPort.b[0]<<8 | dstPort.b[1], s);
+ else
+ verbosedebugf("mDNSPlatformSendUDP: NOT sending on InterfaceID %X %s/%d (socket of this type not available)",
+ InterfaceID, info->ifa_name, dst->type, dst, (mDNSu16)dstPort.b[0]<<8 | dstPort.b[1]);
+
+ // Note: When sending, mDNSCore may often ask us to send both a v4 multicast packet and then a v6 multicast packet
+ // If we don't have the corresponding type of socket available, then return mStatus_Invalid
+ if (s < 0) return(mStatus_Invalid);
+
+ err = sendto(s, msg, (UInt8*)end - (UInt8*)msg, 0, (struct sockaddr *)&to, to.ss_len);
+ if (err < 0)
+ {
+ // Don't report EHOSTDOWN (i.e. ARP failure) to unicast destinations
+ if (errno == EHOSTDOWN && !mDNSAddressIsAllDNSLinkGroup(dst)) return(err);
+ // Don't report EHOSTUNREACH in the first two minutes after boot
+ // This is because mDNSResponder intentionally starts up early in the boot process (See <rdar://problem/3409090>)
+ // but this means that sometimes it starts before configd has finished setting up the multicast routing entries.
+ if (errno == EHOSTUNREACH && (mDNSu32)(m->timenow) < (mDNSu32)(mDNSPlatformOneSecond * 120)) return(err);
+ LogMsg("mDNSPlatformSendUDP sendto failed to send packet on InterfaceID %p %s/%ld to %#a:%d skt %d error %d errno %d (%s)",
+ InterfaceID, info->ifa_name, dst->type, dst, (mDNSu16)dstPort.b[0]<<8 | dstPort.b[1], s, err, errno, strerror(errno));
+ return(err);
+ }
+
+ return(mStatus_NoError);
+ }
+
+mDNSlocal ssize_t myrecvfrom(const int s, void *const buffer, const size_t max,
+ struct sockaddr *const from, size_t *const fromlen, mDNSAddr *dstaddr, char ifname[IF_NAMESIZE], mDNSu8 *ttl)
+ {
+ static unsigned int numLogMessages = 0;
+ struct iovec databuffers = { (char *)buffer, max };
+ struct msghdr msg;
+ ssize_t n;
+ struct cmsghdr *cmPtr;
+ char ancillary[1024];
+
+ *ttl = 255; // If kernel fails to provide TTL data (e.g. Jaguar doesn't) then assume the TTL was 255 as it should be
+
+ // Set up the message
+ msg.msg_name = (caddr_t)from;
+ msg.msg_namelen = *fromlen;
+ msg.msg_iov = &databuffers;
+ msg.msg_iovlen = 1;
+ msg.msg_control = (caddr_t)&ancillary;
+ msg.msg_controllen = sizeof(ancillary);
+ msg.msg_flags = 0;
+
+ // Receive the data
+ n = recvmsg(s, &msg, 0);
+ if (n<0)
+ {
+ if (errno != EWOULDBLOCK && numLogMessages++ < 100) LogMsg("CFSocket.c: recvmsg(%d) returned error %d errno %d", s, n, errno);
+ return(-1);
+ }
+ if (msg.msg_controllen < (int)sizeof(struct cmsghdr))
+ {
+ if (numLogMessages++ < 100) LogMsg("CFSocket.c: recvmsg(%d) msg.msg_controllen %d < sizeof(struct cmsghdr) %lu",
+ s, msg.msg_controllen, sizeof(struct cmsghdr));
+ return(-1);
+ }
+ if (msg.msg_flags & MSG_CTRUNC)
+ {
+ if (numLogMessages++ < 100) LogMsg("CFSocket.c: recvmsg(%d) msg.msg_flags & MSG_CTRUNC", s);
+ return(-1);
+ }
+
+ *fromlen = msg.msg_namelen;
+
+ // Parse each option out of the ancillary data.
+ for (cmPtr = CMSG_FIRSTHDR(&msg); cmPtr; cmPtr = CMSG_NXTHDR(&msg, cmPtr))
+ {
+ // debugf("myrecvfrom cmsg_level %d cmsg_type %d", cmPtr->cmsg_level, cmPtr->cmsg_type);
+ if (cmPtr->cmsg_level == IPPROTO_IP && cmPtr->cmsg_type == IP_RECVDSTADDR)
+ {
+ dstaddr->type = mDNSAddrType_IPv4;
+ dstaddr->ip.v4.NotAnInteger = *(u_int32_t*)CMSG_DATA(cmPtr);
+ }
+ if (cmPtr->cmsg_level == IPPROTO_IP && cmPtr->cmsg_type == IP_RECVIF)
+ {
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *)CMSG_DATA(cmPtr);
+ if (sdl->sdl_nlen < IF_NAMESIZE)
+ {
+ mDNSPlatformMemCopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
+ ifname[sdl->sdl_nlen] = 0;
+ // debugf("IP_RECVIF sdl_index %d, sdl_data %s len %d", sdl->sdl_index, ifname, sdl->sdl_nlen);
+ }
+ }
+ if (cmPtr->cmsg_level == IPPROTO_IP && cmPtr->cmsg_type == IP_RECVTTL)
+ {
+ *ttl = *(u_char*)CMSG_DATA(cmPtr);
+ }
+ if (cmPtr->cmsg_level == IPPROTO_IPV6 && cmPtr->cmsg_type == IPV6_PKTINFO)
+ {
+ struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmPtr);
+ dstaddr->type = mDNSAddrType_IPv6;
+ dstaddr->ip.v6 = *(mDNSv6Addr*)&ip6_info->ipi6_addr;
+ myIfIndexToName(ip6_info->ipi6_ifindex, ifname);
+ }
+ if (cmPtr->cmsg_level == IPPROTO_IPV6 && cmPtr->cmsg_type == IPV6_HOPLIMIT)
+ {
+ *ttl = *(int*)CMSG_DATA(cmPtr);
+ }
+ }
+
+ return(n);
+ }
+
+mDNSlocal void myCFSocketCallBack(CFSocketRef cfs, CFSocketCallBackType CallBackType, CFDataRef address, const void *data, void *context)
+ {
+ mDNSAddr senderAddr, destAddr;
+ mDNSIPPort senderPort, destPort = MulticastDNSPort;
+ NetworkInterfaceInfoOSX *info = (NetworkInterfaceInfoOSX *)context;
+ mDNS *const m = info->m;
+ DNSMessage packet;
+ struct sockaddr_storage from;
+ size_t fromlen = sizeof(from);
+ char packetifname[IF_NAMESIZE] = "";
+ int err, s1 = -1, skt = CFSocketGetNative(cfs);
+ int count = 0;
+
+ (void)address; // Parameter not used
+ (void)data; // Parameter not used
+
+ if (CallBackType != kCFSocketReadCallBack) LogMsg("myCFSocketCallBack: Why is CallBackType %d not kCFSocketReadCallBack?", CallBackType);
+
+#if mDNS_AllowPort53
+ if (cfs == info->cfs53) { s1 = info->skt53; destPort = UnicastDNSPort; }
+ else
+#endif
+ if (cfs == info->cfsv4) s1 = info->sktv4;
+ else if (cfs == info->cfsv6) s1 = info->sktv6;
+
+ if (s1 < 0 || s1 != skt)
+ {
+ LogMsg("myCFSocketCallBack: s1 %d native socket %d, cfs %p", s1, skt, cfs);
+#if mDNS_AllowPort53
+ LogMsg("myCFSocketCallBack: cfs53 %p, skt53 %d", info->cfs53, info->skt53);
+#endif
+ LogMsg("myCFSocketCallBack: cfsv4 %p, sktv4 %d", info->cfsv4, info->sktv4);
+ LogMsg("myCFSocketCallBack: cfsv6 %p, sktv6 %d", info->cfsv6, info->sktv6);
+ }
+
+ mDNSu8 ttl;
+ while ((err = myrecvfrom(s1, &packet, sizeof(packet), (struct sockaddr *)&from, &fromlen, &destAddr, packetifname, &ttl)) >= 0)
+ {
+ count++;
+ if (from.ss_family == AF_INET)
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in*)&from;
+ senderAddr.type = mDNSAddrType_IPv4;
+ senderAddr.ip.v4.NotAnInteger = sin->sin_addr.s_addr;
+ senderPort.NotAnInteger = sin->sin_port;
+ }
+ else if (from.ss_family == AF_INET6)
+ {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&from;
+ senderAddr.type = mDNSAddrType_IPv6;
+ senderAddr.ip.v6 = *(mDNSv6Addr*)&sin6->sin6_addr;
+ senderPort.NotAnInteger = sin6->sin6_port;
+ }
+ else
+ {
+ LogMsg("myCFSocketCallBack from is unknown address family %d", from.ss_family);
+ return;
+ }
+
+ // Even though we indicated a specific interface in the IP_ADD_MEMBERSHIP call, a weirdness of the
+ // sockets API means that even though this socket has only officially joined the multicast group
+ // on one specific interface, the kernel will still deliver multicast packets to it no matter which
+ // interface they arrive on. According to the official Unix Powers That Be, this is Not A Bug.
+ // To work around this weirdness, we use the IP_RECVIF option to find the name of the interface
+ // on which the packet arrived, and ignore the packet if it really arrived on some other interface.
+ if (strcmp(info->ifa_name, packetifname))
+ {
+ verbosedebugf("myCFSocketCallBack got a packet from %#a to %#a on interface %#a/%s (Ignored -- really arrived on interface %s)",
+ &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name, packetifname);
+ return;
+ }
+ else
+ verbosedebugf("myCFSocketCallBack got a packet from %#a to %#a on interface %#a/%s",
+ &senderAddr, &destAddr, &info->ifinfo.ip, info->ifa_name);
+
+ if (err < (int)sizeof(DNSMessageHeader)) { debugf("myCFSocketCallBack packet length (%d) too short", err); return; }
+
+ mDNSCoreReceive(m, &packet, (unsigned char*)&packet + err, &senderAddr, senderPort, &destAddr, destPort, info->ifinfo.InterfaceID, ttl);
+ }
+
+ if (err < 0 && (errno != EWOULDBLOCK || count == 0))
+ {
+ // Something is busted here.
+ // CFSocket says there is a packet, but myrecvfrom says there is not.
+ // Try calling select() to get another opinion.
+ // Find out about other socket parameter that can help understand why select() says the socket is ready for read
+ // All of this is racy, as data may have arrived after the call to select()
+ int save_errno = errno;
+ int so_error = -1;
+ int so_nread = -1;
+ int fionread = -1;
+ int solen = sizeof(int);
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(s1, &readfds);
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ int selectresult = select(s1+1, &readfds, NULL, NULL, &timeout);
+ if (getsockopt(s1, SOL_SOCKET, SO_ERROR, &so_error, &solen) == -1)
+ LogMsg("myCFSocketCallBack getsockopt(SO_ERROR) error %d", errno);
+ if (getsockopt(s1, SOL_SOCKET, SO_NREAD, &so_nread, &solen) == -1)
+ LogMsg("myCFSocketCallBack getsockopt(SO_NREAD) error %d", errno);
+ if (ioctl(s1, FIONREAD, &fionread) == -1)
+ LogMsg("myCFSocketCallBack ioctl(FIONREAD) error %d", errno);
+ static unsigned int numLogMessages = 0;
+ if (numLogMessages++ < 100)
+ LogMsg("myCFSocketCallBack recvfrom skt %d error %d errno %d (%s) select %d (%spackets waiting) so_error %d so_nread %d fionread %d count %d",
+ s1, err, save_errno, strerror(save_errno), selectresult, FD_ISSET(s1, &readfds) ? "" : "*NO* ", so_error, so_nread, fionread, count);
+ sleep(1); // After logging this error, rate limit so we don't flood syslog
+ }
+ }
+
+// This gets the text of the field currently labelled "Computer Name" in the Sharing Prefs Control Panel
+mDNSlocal void GetUserSpecifiedFriendlyComputerName(domainlabel *const namelabel)
+ {
+ CFStringEncoding encoding = kCFStringEncodingUTF8;
+ CFStringRef cfs = SCDynamicStoreCopyComputerName(NULL, &encoding);
+ if (cfs)
+ {
+ CFStringGetPascalString(cfs, namelabel->c, sizeof(*namelabel), kCFStringEncodingUTF8);
+ CFRelease(cfs);
+ }
+ }
+
+// This gets the text of the field currently labelled "Rendezvous Name" in the Sharing Prefs Control Panel
+mDNSlocal void GetUserSpecifiedRFC1034ComputerName(domainlabel *const namelabel)
+ {
+ CFStringRef cfs = SCDynamicStoreCopyLocalHostName(NULL);
+ if (cfs)
+ {
+ CFStringGetPascalString(cfs, namelabel->c, sizeof(*namelabel), kCFStringEncodingUTF8);
+ CFRelease(cfs);
+ }
+ }
+
+mDNSlocal mStatus SetupSocket(NetworkInterfaceInfoOSX *i, mDNSIPPort port, int *s, CFSocketRef *c)
+ {
+ const int on = 1;
+ const int twofivefive = 255;
+
+ if (*s >= 0) { LogMsg("SetupSocket ERROR: socket %d is already set", *s); return(-1); }
+ if (*c) { LogMsg("SetupSocket ERROR: CFSocketRef %p is already set", *c); return(-1); }
+
+ // Open the socket...
+ int skt = socket(i->sa_family, SOCK_DGRAM, IPPROTO_UDP);
+ if (skt < 0) { LogMsg("socket error %d errno %d (%s)", skt, errno, strerror(errno)); return(skt); }
+
+ // ... with a shared UDP port
+ mStatus err = setsockopt(skt, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - SO_REUSEPORT error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ if (i->sa_family == AF_INET)
+ {
+ // We want to receive destination addresses
+ err = setsockopt(skt, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - IP_RECVDSTADDR error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // We want to receive interface identifiers
+ err = setsockopt(skt, IPPROTO_IP, IP_RECVIF, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - IP_RECVIF error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // We want to receive packet TTL value so we can check it
+ err = setsockopt(skt, IPPROTO_IP, IP_RECVTTL, &on, sizeof(on));
+ // We ignore errors here -- we already know Jaguar doesn't support this, but we can get by without it
+
+ // Add multicast group membership on this interface
+ struct in_addr addr = { i->ifinfo.ip.ip.v4.NotAnInteger };
+ struct ip_mreq imr;
+ imr.imr_multiaddr.s_addr = AllDNSLinkGroup.NotAnInteger;
+ imr.imr_interface = addr;
+ err = setsockopt(skt, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr));
+ if (err < 0) { LogMsg("setsockopt - IP_ADD_MEMBERSHIP error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Specify outgoing interface too
+ err = setsockopt(skt, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));
+ if (err < 0) { LogMsg("setsockopt - IP_MULTICAST_IF error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Send unicast packets with TTL 255
+ err = setsockopt(skt, IPPROTO_IP, IP_TTL, &twofivefive, sizeof(twofivefive));
+ if (err < 0) { LogMsg("setsockopt - IP_TTL error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // And multicast packets with TTL 255 too
+ err = setsockopt(skt, IPPROTO_IP, IP_MULTICAST_TTL, &twofivefive, sizeof(twofivefive));
+ if (err < 0) { LogMsg("setsockopt - IP_MULTICAST_TTL error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Mark packets as high-throughput/low-delay (i.e. lowest reliability) to get maximum 802.11 multicast rate
+ const int ip_tosbits = IPTOS_LOWDELAY | IPTOS_THROUGHPUT;
+ err = setsockopt(skt, IPPROTO_IP, IP_TOS, &ip_tosbits, sizeof(ip_tosbits));
+ if (err < 0) { LogMsg("setsockopt - IP_TOS error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // And start listening for packets
+ struct sockaddr_in listening_sockaddr;
+ listening_sockaddr.sin_family = AF_INET;
+ listening_sockaddr.sin_port = port.NotAnInteger;
+ listening_sockaddr.sin_addr.s_addr = 0; // Want to receive multicasts AND unicasts on this socket
+ err = bind(skt, (struct sockaddr *) &listening_sockaddr, sizeof(listening_sockaddr));
+ if (err)
+ {
+ // If we fail to bind to port 53 (because we're not root), that's okay, just tidy up and silently continue
+ if (port.NotAnInteger == UnicastDNSPort.NotAnInteger) { close(skt); err = 0; }
+ else LogMsg("bind error %ld errno %d (%s)", err, errno, strerror(errno));
+ return(err);
+ }
+ }
+ else if (i->sa_family == AF_INET6)
+ {
+ // We want to receive destination addresses and receive interface identifiers
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - IPV6_PKTINFO error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // We want to receive packet hop count value so we can check it
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_HOPLIMIT, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - IPV6_HOPLIMIT error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // We want to receive only IPv6 packets, without this option, we may
+ // get IPv4 addresses as mapped addresses.
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - IPV6_V6ONLY error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Add multicast group membership on this interface
+ int interface_id = if_nametoindex(i->ifa_name);
+ struct ipv6_mreq i6mr;
+ i6mr.ipv6mr_interface = interface_id;
+ i6mr.ipv6mr_multiaddr = *(struct in6_addr*)&AllDNSLinkGroupv6;
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_JOIN_GROUP, &i6mr, sizeof(i6mr));
+ if (err < 0) { LogMsg("setsockopt - IPV6_JOIN_GROUP error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Specify outgoing interface too
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_IF, &interface_id, sizeof(interface_id));
+ if (err < 0) { LogMsg("setsockopt - IPV6_MULTICAST_IF error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Send unicast packets with TTL 255
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &twofivefive, sizeof(twofivefive));
+ if (err < 0) { LogMsg("setsockopt - IPV6_UNICAST_HOPS error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // And multicast packets with TTL 255 too
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &twofivefive, sizeof(twofivefive));
+ if (err < 0) { LogMsg("setsockopt - IPV6_MULTICAST_HOPS error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // Note: IPV6_TCLASS appears not to be implemented on OS X right now (or indeed on ANY version of Unix?)
+ #ifdef IPV6_TCLASS
+ // Mark packets as high-throughput/low-delay (i.e. lowest reliability) to get maximum 802.11 multicast rate
+ int tclass = IPTOS_LOWDELAY | IPTOS_THROUGHPUT; // This may not be right (since tclass is not implemented on OS X, I can't test it)
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_TCLASS, &tclass, sizeof(tclass));
+ if (err < 0) { LogMsg("setsockopt - IPV6_TCLASS error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+ #endif
+
+ // Want to receive our own packets
+ err = setsockopt(skt, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &on, sizeof(on));
+ if (err < 0) { LogMsg("setsockopt - IPV6_MULTICAST_LOOP error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+
+ // And start listening for packets
+ struct sockaddr_in6 listening_sockaddr6;
+ bzero(&listening_sockaddr6, sizeof(listening_sockaddr6));
+ listening_sockaddr6.sin6_len = sizeof(listening_sockaddr6);
+ listening_sockaddr6.sin6_family = AF_INET6;
+ listening_sockaddr6.sin6_port = port.NotAnInteger;
+ listening_sockaddr6.sin6_flowinfo = 0;
+// listening_sockaddr6.sin6_addr = IN6ADDR_ANY_INIT; // Want to receive multicasts AND unicasts on this socket
+ listening_sockaddr6.sin6_scope_id = 0;
+ err = bind(skt, (struct sockaddr *) &listening_sockaddr6, sizeof(listening_sockaddr6));
+ if (err) { LogMsg("bind error %ld errno %d (%s)", err, errno, strerror(errno)); return(err); }
+ }
+
+ fcntl(skt, F_SETFL, fcntl(skt, F_GETFL, 0) | O_NONBLOCK); // set non-blocking
+ *s = skt;
+ CFSocketContext myCFSocketContext = { 0, i->ifinfo.InterfaceID, NULL, NULL, NULL };
+ *c = CFSocketCreateWithNative(kCFAllocatorDefault, *s, kCFSocketReadCallBack, myCFSocketCallBack, &myCFSocketContext);
+ CFRunLoopSourceRef rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, *c, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+
+ return(err);
+ }
+
+mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
+ {
+ if (sa->sa_family == AF_INET)
+ {
+ struct sockaddr_in *ifa_addr = (struct sockaddr_in *)sa;
+ ip->type = mDNSAddrType_IPv4;
+ ip->ip.v4.NotAnInteger = ifa_addr->sin_addr.s_addr;
+ return(0);
+ }
+ else if (sa->sa_family == AF_INET6)
+ {
+ struct sockaddr_in6 *ifa_addr = (struct sockaddr_in6 *)sa;
+ ip->type = mDNSAddrType_IPv6;
+ if (IN6_IS_ADDR_LINKLOCAL(&ifa_addr->sin6_addr)) ifa_addr->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
+ ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
+ return(0);
+ }
+ else
+ {
+ LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
+ return(-1);
+ }
+ }
+
+mDNSlocal mStatus AddInterfaceToList(mDNS *const m, struct ifaddrs *ifa)
+ {
+ mDNSu32 scope_id = if_nametoindex(ifa->ifa_name);
+ mDNSAddr ip;
+ SetupAddr(&ip, ifa->ifa_addr);
+ NetworkInterfaceInfoOSX **p;
+ for (p = &m->p->InterfaceList; *p; p = &(*p)->next)
+ if (scope_id == (*p)->scope_id && mDNSSameAddress(&ip, &(*p)->ifinfo.ip))
+ {
+ debugf("AddInterfaceToList: Found existing interface %u with address %#a", scope_id, &ip);
+ (*p)->CurrentlyActive = mDNStrue;
+ return(0);
+ }
+
+ debugf("AddInterfaceToList: Making new interface %u with address %#a", scope_id, &ip);
+ NetworkInterfaceInfoOSX *i = (NetworkInterfaceInfoOSX *)mallocL("NetworkInterfaceInfoOSX", sizeof(*i));
+ if (!i) return(-1);
+ i->ifa_name = (char *)mallocL("NetworkInterfaceInfoOSX name", strlen(ifa->ifa_name) + 1);
+ if (!i->ifa_name) { freeL("NetworkInterfaceInfoOSX", i); return(-1); }
+ strcpy(i->ifa_name, ifa->ifa_name);
+
+ i->ifinfo.InterfaceID = mDNSNULL;
+ i->ifinfo.ip = ip;
+ i->ifinfo.Advertise = m->AdvertiseLocalAddresses;
+ i->ifinfo.TxAndRx = mDNSfalse; // For now; will be set up later at the end of UpdateInterfaceList
+
+ i->next = mDNSNULL;
+ i->m = m;
+ i->scope_id = scope_id;
+ i->CurrentlyActive = mDNStrue;
+ i->sa_family = ifa->ifa_addr->sa_family;
+ #if mDNS_AllowPort53
+ i->skt53 = -1;
+ i->cfs53 = NULL;
+ #endif
+ i->sktv4 = -1;
+ i->cfsv4 = NULL;
+ i->sktv6 = -1;
+ i->cfsv6 = NULL;
+
+ if (!i->ifa_name) return(-1);
+ *p = i;
+ return(0);
+ }
+
+mDNSlocal NetworkInterfaceInfoOSX *FindRoutableIPv4(mDNS *const m, mDNSu32 scope_id)
+ {
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ if (i->CurrentlyActive && i->scope_id == scope_id && i->ifinfo.ip.type == mDNSAddrType_IPv4)
+ if (!(i->ifinfo.ip.ip.v4.b[0] == 169 && i->ifinfo.ip.ip.v4.b[1] == 254))
+ return(i);
+ return(mDNSNULL);
+ }
+
+mDNSlocal mStatus UpdateInterfaceList(mDNS *const m)
+ {
+ mDNSBool foundav4 = mDNSfalse;
+ struct ifaddrs *ifa = myGetIfAddrs(1);
+ struct ifaddrs *theLoopback = NULL;
+ int err = (ifa != NULL) ? 0 : (errno != 0 ? errno : -1);
+ int InfoSocket = err ? -1 : socket(AF_INET6, SOCK_DGRAM, 0);
+ if (err) return(err);
+
+ // Set up the nice label
+ m->nicelabel.c[0] = 0;
+ GetUserSpecifiedFriendlyComputerName(&m->nicelabel);
+ if (m->nicelabel.c[0] == 0) MakeDomainLabelFromLiteralString(&m->nicelabel, "Macintosh");
+
+ // Set up the RFC 1034-compliant label
+ domainlabel hostlabel;
+ hostlabel.c[0] = 0;
+ GetUserSpecifiedRFC1034ComputerName(&hostlabel);
+ if (hostlabel.c[0] == 0) MakeDomainLabelFromLiteralString(&hostlabel, "Macintosh");
+ // If the user has changed their dot-local host name since the last time we checked, then update our local copy.
+ // If the user has not changed their dot-local host name, then leave ours alone (m->hostlabel may have gone through
+ // repeated conflict resolution to get to its current value, and if we reset it, we'll have to go through all that again.)
+ if (SameDomainLabel(m->p->userhostlabel.c, hostlabel.c))
+ debugf("Userhostlabel (%#s) unchanged since last time; not changing m->hostlabel (%#s)", m->p->userhostlabel.c, m->hostlabel.c);
+ else
+ {
+ debugf("Updating m->hostlabel to %#s", hostlabel.c);
+ m->p->userhostlabel = m->hostlabel = hostlabel;
+ mDNS_GenerateFQDN(m);
+ }
+
+ while (ifa)
+ {
+#if LIST_ALL_INTERFACES
+ if (ifa->ifa_addr->sa_family == AF_APPLETALK)
+ debugf("UpdateInterfaceList: %4s(%d) Flags %04X Family %2d is AF_APPLETALK",
+ ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
+ else if (ifa->ifa_addr->sa_family == AF_LINK)
+ debugf("UpdateInterfaceList: %4s(%d) Flags %04X Family %2d is AF_LINK",
+ ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
+ else if (ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6)
+ debugf("UpdateInterfaceList: %4s(%d) Flags %04X Family %2d not AF_INET (2) or AF_INET6 (30)",
+ ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
+ if (!(ifa->ifa_flags & IFF_UP))
+ debugf("UpdateInterfaceList: %4s(%d) Flags %04X Family %2d Interface not IFF_UP",
+ ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
+ if (ifa->ifa_flags & IFF_POINTOPOINT)
+ debugf("UpdateInterfaceList: %4s(%d) Flags %04X Family %2d Interface IFF_POINTOPOINT",
+ ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
+ if (ifa->ifa_flags & IFF_LOOPBACK)
+ debugf("UpdateInterfaceList: %4s(%d) Flags %04X Family %2d Interface IFF_LOOPBACK",
+ ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family);
+#endif
+ if ((ifa->ifa_addr->sa_family == AF_INET || ifa->ifa_addr->sa_family == AF_INET6) &&
+ (ifa->ifa_flags & IFF_MULTICAST) &&
+ (ifa->ifa_flags & IFF_UP) && !(ifa->ifa_flags & IFF_POINTOPOINT))
+ {
+ int ifru_flags6 = 0;
+ if (ifa->ifa_addr->sa_family == AF_INET6 && InfoSocket >= 0)
+ {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+ struct in6_ifreq ifr6;
+ bzero((char *)&ifr6, sizeof(ifr6));
+ strncpy(ifr6.ifr_name, ifa->ifa_name, sizeof(ifr6.ifr_name));
+ ifr6.ifr_addr = *sin6;
+ if (ioctl(InfoSocket, SIOCGIFAFLAG_IN6, &ifr6) != -1)
+ ifru_flags6 = ifr6.ifr_ifru.ifru_flags6;
+ verbosedebugf("%s %.16a %04X %04X", ifa->ifa_name, &sin6->sin6_addr, ifa->ifa_flags, ifru_flags6);
+ }
+ if (!(ifru_flags6 & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED | IN6_IFF_DEPRECATED | IN6_IFF_TEMPORARY)))
+ {
+ if (ifa->ifa_flags & IFF_LOOPBACK)
+ theLoopback = ifa;
+ else
+ {
+ AddInterfaceToList(m, ifa);
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ foundav4 = mDNStrue;
+ }
+ }
+ }
+ ifa = ifa->ifa_next;
+ }
+
+// Temporary workaround: Multicast loopback on IPv6 interfaces appears not to work.
+// In the interim, we skip loopback interface only if we found at least one v4 interface to use
+ if (!foundav4 && theLoopback)
+ AddInterfaceToList(m, theLoopback);
+
+ // Now the list is complete, set the TxAndRx setting for each interface.
+ // We always send and receive using IPv4.
+ // To reduce traffic, we send and receive using IPv6 only on interfaces that have no routable IPv4 address.
+ // Having a routable IPv4 address assigned is a reasonable indicator of being on a large configured network,
+ // which means there's a good chance that most or all the other devices on that network should also have v4.
+ // By doing this we lose the ability to talk to true v6-only devices on that link, but we cut the packet rate in half.
+ // At this time, reducing the packet rate is more important than v6-only devices on a large configured network,
+ // so we are willing to make that sacrifice.
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ if (i->CurrentlyActive)
+ {
+ mDNSBool txrx = ((i->ifinfo.ip.type == mDNSAddrType_IPv4) || !FindRoutableIPv4(m, i->scope_id));
+ if (i->ifinfo.TxAndRx != txrx)
+ {
+ i->ifinfo.TxAndRx = txrx;
+ i->CurrentlyActive = 2; // State change; need to deregister and reregister this interface
+ }
+ }
+
+ if (InfoSocket >= 0) close(InfoSocket);
+ return(err);
+ }
+
+mDNSlocal NetworkInterfaceInfoOSX *SearchForInterfaceByName(mDNS *const m, char *ifname, int type)
+ {
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ if (!strcmp(i->ifa_name, ifname) &&
+ i->CurrentlyActive &&
+ ((AAAA_OVER_V4 ) ||
+ (type == AF_INET && i->ifinfo.ip.type == mDNSAddrType_IPv4) ||
+ (type == AF_INET6 && i->ifinfo.ip.type == mDNSAddrType_IPv6) )) return(i);
+ return(NULL);
+ }
+
+mDNSlocal void SetupActiveInterfaces(mDNS *const m)
+ {
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ if (i->CurrentlyActive)
+ {
+ mStatus err = 0;
+ NetworkInterfaceInfo *n = &i->ifinfo;
+ NetworkInterfaceInfoOSX *alias = SearchForInterfaceByName(m, i->ifa_name, i->sa_family);
+ if (!alias) alias = i;
+
+ if (n->InterfaceID && n->InterfaceID != (mDNSInterfaceID)alias)
+ {
+ LogMsg("SetupActiveInterfaces ERROR! n->InterfaceID %p != alias %p", n->InterfaceID, alias);
+ n->InterfaceID = mDNSNULL;
+ }
+
+ if (!n->InterfaceID)
+ {
+ n->InterfaceID = (mDNSInterfaceID)alias;
+ mDNS_RegisterInterface(m, n);
+ debugf("SetupActiveInterfaces: Registered %s(%lu) InterfaceID %p %#a%s",
+ i->ifa_name, i->scope_id, alias, &n->ip, n->InterfaceActive ? " (Primary)" : "");
+ }
+
+ if (!n->TxAndRx)
+ debugf("SetupActiveInterfaces: No TX/Rx on %s(%lu) InterfaceID %p %#a", i->ifa_name, i->scope_id, alias, &n->ip);
+ else
+ {
+ if (i->sa_family == AF_INET && alias->sktv4 == -1)
+ {
+ #if mDNS_AllowPort53
+ err = SetupSocket(i, UnicastDNSPort, &alias->skt53, &alias->cfs53);
+ #endif
+ if (!err) err = SetupSocket(i, MulticastDNSPort, &alias->sktv4, &alias->cfsv4);
+ if (err == 0) debugf("SetupActiveInterfaces: v4 socket%2d %s(%lu) InterfaceID %p %#a", alias->sktv4, i->ifa_name, i->scope_id, n->InterfaceID, &n->ip);
+ else LogMsg("SetupActiveInterfaces: v4 socket%2d %s(%lu) InterfaceID %p %#a FAILED", alias->sktv4, i->ifa_name, i->scope_id, n->InterfaceID, &n->ip);
+ }
+
+ if (i->sa_family == AF_INET6 && alias->sktv6 == -1)
+ {
+ err = SetupSocket(i, MulticastDNSPort, &alias->sktv6, &alias->cfsv6);
+ if (err == 0) debugf("SetupActiveInterfaces: v6 socket%2d %s(%lu) InterfaceID %p %#a", alias->sktv6, i->ifa_name, i->scope_id, n->InterfaceID, &n->ip);
+ else LogMsg("SetupActiveInterfaces: v6 socket%2d %s(%lu) InterfaceID %p %#a FAILED", alias->sktv6, i->ifa_name, i->scope_id, n->InterfaceID, &n->ip);
+ }
+ }
+ }
+ }
+
+mDNSlocal void MarkAllInterfacesInactive(mDNS *const m)
+ {
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ i->CurrentlyActive = mDNSfalse;
+ }
+
+mDNSlocal mDNSu32 NumCacheRecordsForInterfaceID(mDNS *const m, mDNSInterfaceID id)
+ {
+ mDNSu32 slot, used = 0;
+ CacheRecord *rr;
+ for (slot = 0; slot < CACHE_HASH_SLOTS; slot++)
+ for (rr = m->rrcache_hash[slot]; rr; rr=rr->next)
+ if (rr->resrec.InterfaceID == id) used++;
+ return(used);
+ }
+
+mDNSlocal void ClearInactiveInterfaces(mDNS *const m)
+ {
+ // First pass:
+ // If an interface is going away, then deregister this from the mDNSCore.
+ // We also have to deregister it if the alias interface that it's using for its InterfaceID is going away.
+ // We have to do this because mDNSCore will use that InterfaceID when sending packets, and if the memory
+ // it refers to has gone away we'll crash.
+ // Don't actually close the sockets or free the memory yet: When the last representative of an interface goes away
+ // mDNSCore may want to send goodbye packets on that interface. (Not yet implemented, but a good idea anyway.)
+ NetworkInterfaceInfoOSX *i;
+ for (i = m->p->InterfaceList; i; i = i->next)
+ {
+ // 1. If this interface is no longer active, or its InterfaceID is changing, deregister it
+ NetworkInterfaceInfoOSX *alias = (NetworkInterfaceInfoOSX *)(i->ifinfo.InterfaceID);
+ NetworkInterfaceInfoOSX *newalias = SearchForInterfaceByName(m, i->ifa_name, i->sa_family);
+ if (!newalias) newalias = i;
+ if (i->ifinfo.InterfaceID && (!i->CurrentlyActive || (alias && !alias->CurrentlyActive) || i->CurrentlyActive == 2 || newalias != alias))
+ {
+ debugf("ClearInactiveInterfaces: Deregistering %#a", &i->ifinfo.ip);
+ mDNS_DeregisterInterface(m, &i->ifinfo);
+ i->ifinfo.InterfaceID = mDNSNULL;
+ }
+ }
+
+ // Second pass:
+ // Now that everything that's going to deregister has done so, we can close sockets and free the memory
+ NetworkInterfaceInfoOSX **p = &m->p->InterfaceList;
+ while (*p)
+ {
+ i = *p;
+ // 2. Close all our CFSockets. We'll recreate them later as necessary.
+ // (We may have previously had both v4 and v6, and we may not need both any more.)
+ // Note: MUST NOT close the underlying native BSD sockets.
+ // CFSocketInvalidate() will do that for us, in its own good time, which may not necessarily be immediately,
+ // because it first has to unhook the sockets from its select() call, before it can safely close them.
+ #if mDNS_AllowPort53
+ if (i->cfs53) { CFSocketInvalidate(i->cfs53); CFRelease(i->cfs53); }
+ i->skt53 = -1;
+ i->cfs53 = NULL;
+ #endif
+ if (i->cfsv4) { CFSocketInvalidate(i->cfsv4); CFRelease(i->cfsv4); }
+ if (i->cfsv6) { CFSocketInvalidate(i->cfsv6); CFRelease(i->cfsv6); }
+ i->sktv4 = i->sktv6 = -1;
+ i->cfsv4 = i->cfsv6 = NULL;
+
+ // 3. If no longer active, delete interface from list and free memory
+ if (!i->CurrentlyActive && NumCacheRecordsForInterfaceID(m, (mDNSInterfaceID)i) == 0)
+ {
+ debugf("ClearInactiveInterfaces: Deleting %#a", &i->ifinfo.ip);
+ *p = i->next;
+ if (i->ifa_name) freeL("NetworkInterfaceInfoOSX name", i->ifa_name);
+ freeL("NetworkInterfaceInfoOSX", i);
+ }
+ else
+ p = &i->next;
+ }
+ }
+
+mDNSlocal void NetworkChanged(SCDynamicStoreRef store, CFArrayRef changedKeys, void *context)
+ {
+ (void)store; // Parameter not used
+ (void)changedKeys; // Parameter not used
+ debugf("*** Network Configuration Change ***");
+
+ mDNS *const m = (mDNS *const)context;
+ MarkAllInterfacesInactive(m);
+ UpdateInterfaceList(m);
+ ClearInactiveInterfaces(m);
+ SetupActiveInterfaces(m);
+
+ if (m->MainCallback)
+ m->MainCallback(m, mStatus_ConfigChanged);
+ }
+
+mDNSlocal mStatus WatchForNetworkChanges(mDNS *const m)
+ {
+ mStatus err = -1;
+ SCDynamicStoreContext context = { 0, m, NULL, NULL, NULL };
+ SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("mDNSResponder"), NetworkChanged, &context);
+ CFStringRef key1 = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv4);
+ CFStringRef key2 = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainState, kSCEntNetIPv6);
+ CFStringRef key3 = SCDynamicStoreKeyCreateComputerName(NULL);
+ CFStringRef key4 = SCDynamicStoreKeyCreateHostNames(NULL);
+ CFStringRef pattern1 = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv4);
+ CFStringRef pattern2 = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetIPv6);
+
+ CFMutableArrayRef keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ CFMutableArrayRef patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ if (!store) { LogMsg("SCDynamicStoreCreate failed: %s\n", SCErrorString(SCError())); goto error; }
+ if (!key1 || !key2 || !key3 || !key4 || !keys || !pattern1 || !pattern2 || !patterns) goto error;
+
+ CFArrayAppendValue(keys, key1);
+ CFArrayAppendValue(keys, key2);
+ CFArrayAppendValue(keys, key3);
+ CFArrayAppendValue(keys, key4);
+ CFArrayAppendValue(patterns, pattern1);
+ CFArrayAppendValue(patterns, pattern2);
+ if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns))
+ { LogMsg("SCDynamicStoreSetNotificationKeys failed: %s\n", SCErrorString(SCError())); goto error; }
+
+ m->p->StoreRLS = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
+ if (!m->p->StoreRLS) { LogMsg("SCDynamicStoreCreateRunLoopSource failed: %s\n", SCErrorString(SCError())); goto error; }
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), m->p->StoreRLS, kCFRunLoopDefaultMode);
+ m->p->Store = store;
+ err = 0;
+ goto exit;
+
+error:
+ if (store) CFRelease(store);
+
+exit:
+ if (key1) CFRelease(key1);
+ if (key2) CFRelease(key2);
+ if (key3) CFRelease(key3);
+ if (key4) CFRelease(key4);
+ if (pattern1) CFRelease(pattern1);
+ if (pattern2) CFRelease(pattern2);
+ if (keys) CFRelease(keys);
+ if (patterns) CFRelease(patterns);
+
+ return(err);
+ }
+
+mDNSlocal void PowerChanged(void *refcon, io_service_t service, natural_t messageType, void *messageArgument)
+ {
+ mDNS *const m = (mDNS *const)refcon;
+ (void)service; // Parameter not used
+ switch(messageType)
+ {
+ case kIOMessageCanSystemPowerOff: debugf("PowerChanged kIOMessageCanSystemPowerOff (no action)"); break; // E0000240
+ case kIOMessageSystemWillPowerOff: debugf("PowerChanged kIOMessageSystemWillPowerOff"); mDNSCoreMachineSleep(m, true); break; // E0000250
+ case kIOMessageSystemWillNotPowerOff: debugf("PowerChanged kIOMessageSystemWillNotPowerOff (no action)"); break; // E0000260
+ case kIOMessageCanSystemSleep: debugf("PowerChanged kIOMessageCanSystemSleep (no action)"); break; // E0000270
+ case kIOMessageSystemWillSleep: debugf("PowerChanged kIOMessageSystemWillSleep"); mDNSCoreMachineSleep(m, true); break; // E0000280
+ case kIOMessageSystemWillNotSleep: debugf("PowerChanged kIOMessageSystemWillNotSleep (no action)"); break; // E0000290
+ case kIOMessageSystemHasPoweredOn: debugf("PowerChanged kIOMessageSystemHasPoweredOn"); mDNSCoreMachineSleep(m, false); break; // E0000300
+ default: debugf("PowerChanged unknown message %X", messageType); break;
+ }
+ IOAllowPowerChange(m->p->PowerConnection, (long)messageArgument);
+ }
+
+mDNSlocal mStatus WatchForPowerChanges(mDNS *const m)
+ {
+ IONotificationPortRef thePortRef;
+ m->p->PowerConnection = IORegisterForSystemPower(m, &thePortRef, PowerChanged, &m->p->PowerNotifier);
+ if (m->p->PowerConnection)
+ {
+ m->p->PowerRLS = IONotificationPortGetRunLoopSource(thePortRef);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), m->p->PowerRLS, kCFRunLoopDefaultMode);
+ return(mStatus_NoError);
+ }
+ return(-1);
+ }
+
+CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
+CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
+CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
+CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
+
+mDNSexport mDNSBool mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring)
+ {
+ int major = 0, minor = 0;
+ char letter = 0, prodname[256]="Mac OS X", prodvers[256]="", buildver[256]="?";
+ CFDictionaryRef vers = _CFCopySystemVersionDictionary();
+ if (vers)
+ {
+ CFStringRef cfprodname = CFDictionaryGetValue(vers, _kCFSystemVersionProductNameKey);
+ CFStringRef cfprodvers = CFDictionaryGetValue(vers, _kCFSystemVersionProductVersionKey);
+ CFStringRef cfbuildver = CFDictionaryGetValue(vers, _kCFSystemVersionBuildVersionKey);
+ if (cfprodname) CFStringGetCString(cfprodname, prodname, sizeof(prodname), kCFStringEncodingUTF8);
+ if (cfprodvers) CFStringGetCString(cfprodvers, prodvers, sizeof(prodvers), kCFStringEncodingUTF8);
+ if (cfbuildver) CFStringGetCString(cfbuildver, buildver, sizeof(buildver), kCFStringEncodingUTF8);
+ sscanf(buildver, "%d%c%d", &major, &letter, &minor);
+ CFRelease(vers);
+ }
+ if (HINFO_SWstring) mDNS_snprintf(HINFO_SWstring, 256, "%s %s (%s), %s", prodname, prodvers, buildver, mDNSResponderVersionString);
+ return(major);
+ }
+
+mDNSlocal mStatus mDNSPlatformInit_setup(mDNS *const m)
+ {
+ mStatus err;
+
+ m->hostlabel.c[0] = 0;
+
+ char *HINFO_HWstring = "Macintosh";
+ char HINFO_HWstring_buffer[256];
+ int get_model[2] = { CTL_HW, HW_MODEL };
+ size_t len_model = sizeof(HINFO_HWstring_buffer);
+ if (sysctl(get_model, 2, HINFO_HWstring_buffer, &len_model, NULL, 0) == 0)
+ HINFO_HWstring = HINFO_HWstring_buffer;
+
+ char HINFO_SWstring[256] = "";
+ if (mDNSMacOSXSystemBuildNumber(HINFO_SWstring) < 7) m->KnownBugs = mDNS_KnownBug_PhantomInterfaces;
+
+ mDNSu32 hlen = mDNSPlatformStrLen(HINFO_HWstring);
+ mDNSu32 slen = mDNSPlatformStrLen(HINFO_SWstring);
+ if (hlen + slen < 254)
+ {
+ m->HIHardware.c[0] = hlen;
+ m->HISoftware.c[0] = slen;
+ mDNSPlatformMemCopy(HINFO_HWstring, &m->HIHardware.c[1], hlen);
+ mDNSPlatformMemCopy(HINFO_SWstring, &m->HISoftware.c[1], slen);
+ }
+
+ m->p->InterfaceList = mDNSNULL;
+ m->p->userhostlabel.c[0] = 0;
+ UpdateInterfaceList(m);
+ SetupActiveInterfaces(m);
+
+ err = WatchForNetworkChanges(m);
+ if (err) return(err);
+
+ err = WatchForPowerChanges(m);
+ return(err);
+ }
+
+mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
+ {
+ mStatus result = mDNSPlatformInit_setup(m);
+ // We don't do asynchronous initialization on OS X, so by the time we get here the setup will already
+ // have succeeded or failed -- so if it succeeded, we should just call mDNSCoreInitComplete() immediately
+ if (result == mStatus_NoError) mDNSCoreInitComplete(m, mStatus_NoError);
+ return(result);
+ }
+
+mDNSexport void mDNSPlatformClose(mDNS *const m)
+ {
+ if (m->p->PowerConnection)
+ {
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m->p->PowerRLS, kCFRunLoopDefaultMode);
+ CFRunLoopSourceInvalidate(m->p->PowerRLS);
+ CFRelease(m->p->PowerRLS);
+ IODeregisterForSystemPower(&m->p->PowerNotifier);
+ m->p->PowerConnection = NULL;
+ m->p->PowerNotifier = NULL;
+ m->p->PowerRLS = NULL;
+ }
+
+ if (m->p->Store)
+ {
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m->p->StoreRLS, kCFRunLoopDefaultMode);
+ CFRunLoopSourceInvalidate(m->p->StoreRLS);
+ CFRelease(m->p->StoreRLS);
+ CFRelease(m->p->Store);
+ m->p->Store = NULL;
+ m->p->StoreRLS = NULL;
+ }
+
+ MarkAllInterfacesInactive(m);
+ ClearInactiveInterfaces(m);
+ }
+
+mDNSexport mDNSs32 mDNSPlatformOneSecond = 1000;
+
+mDNSexport mStatus mDNSPlatformTimeInit(mDNSs32 *timenow)
+ {
+ // Notes: Typical values for mach_timebase_info:
+ // tbi.numer = 1000 million
+ // tbi.denom = 33 million
+ // These are set such that (mach_absolute_time() * numer/denom) gives us nanoseconds;
+ // numer / denom = nanoseconds per hardware clock tick (e.g. 30);
+ // denom / numer = hardware clock ticks per nanosecond (e.g. 0.033)
+ // (denom*1000000) / numer = hardware clock ticks per millisecond (e.g. 33333)
+ // So: mach_absolute_time() / ((denom*1000000)/numer) = milliseconds
+ //
+ // Arithmetic notes:
+ // tbi.denom is at least 1, and not more than 2^32-1.
+ // Therefore (tbi.denom * 1000000) is at least one million, but cannot overflow a uint64_t.
+ // tbi.denom is at least 1, and not more than 2^32-1.
+ // Therefore clockdivisor should end up being a number roughly in the range 10^3 - 10^9.
+ // If clockdivisor is less than 10^3 then that means that the native clock frequency is less than 1MHz,
+ // which is unlikely on any current or future Macintosh.
+ // If clockdivisor is greater than 10^9 then that means the native clock frequency is greater than 1000GHz.
+ // When we ship Macs with clock frequencies above 1000GHz, we may have to update this code.
+ struct mach_timebase_info tbi;
+ kern_return_t result = mach_timebase_info(&tbi);
+ if (result != KERN_SUCCESS) return(result);
+ clockdivisor = ((uint64_t)tbi.denom * 1000000) / tbi.numer;
+ *timenow = mDNSPlatformTimeNow();
+ return(mStatus_NoError);
+ }
+
+mDNSexport mDNSs32 mDNSPlatformTimeNow(void)
+ {
+ if (clockdivisor == 0) { LogMsg("mDNSPlatformTimeNow called before mDNSPlatformTimeInit"); return(0); }
+ return((mDNSs32)(mach_absolute_time() / clockdivisor));
+ }
+
+// Locking is a no-op here, because we're single-threaded with a CFRunLoop, so we can never interrupt ourselves
+mDNSexport void mDNSPlatformLock (const mDNS *const m) { (void)m; }
+mDNSexport void mDNSPlatformUnlock (const mDNS *const m) { (void)m; }
+mDNSexport void mDNSPlatformStrCopy(const void *src, void *dst) { strcpy((char *)dst, (char *)src); }
+mDNSexport mDNSu32 mDNSPlatformStrLen (const void *src) { return(strlen((char*)src)); }
+mDNSexport void mDNSPlatformMemCopy(const void *src, void *dst, mDNSu32 len) { memcpy(dst, src, len); }
+mDNSexport mDNSBool mDNSPlatformMemSame(const void *src, const void *dst, mDNSu32 len) { return(memcmp(dst, src, len) == 0); }
+mDNSexport void mDNSPlatformMemZero( void *dst, mDNSu32 len) { bzero(dst, len); }
+mDNSexport void * mDNSPlatformMemAllocate(mDNSu32 len) { return(mallocL("mDNSPlatformMemAllocate", len)); }
+mDNSexport void mDNSPlatformMemFree (void *mem) { freeL("mDNSPlatformMemFree", mem); }
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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@
+ *
+ * This file is not normally used.
+ * It can be conditionally compiled in by defining RUN_ON_PUMA_WITHOUT_IFADDRS
+ * in CFSocket.c. It is included mainly as sample code for people building
+ * for other platforms that (like Puma) lack the getifaddrs() call.
+ * NOTE: YOU CANNOT use this code to build an mDNSResponder daemon for Puma
+ * that works just like the Jaguar one, because Puma lacks other necessary
+ * functionality (like the LibInfo support to receive MIG messages from clients).
+
+ Change History (most recent first):
+
+$Log: mDNSMacOSXPuma.c,v $
+Revision 1.4 2003/08/12 19:56:25 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:19:51 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:51 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/17 01:36:23 cheshire
+Move Puma support to CFSocketPuma.c
+
+ */
+
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#define ifaddrs ifa_info
+#ifndef ifa_broadaddr
+#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
+#endif
+#include <sys/cdefs.h>
+
+/* Our own header for the programs that need interface configuration info.
+ Include this file, instead of "unp.h". */
+
+#define IFA_NAME 16 /* same as IFNAMSIZ in <net/if.h> */
+#define IFA_HADDR 8 /* allow for 64-bit EUI-64 in future */
+
+struct ifa_info {
+ char ifa_name[IFA_NAME]; /* interface name, null terminated */
+ u_char ifa_haddr[IFA_HADDR]; /* hardware address */
+ u_short ifa_hlen; /* #bytes in hardware address: 0, 6, 8 */
+ short ifa_flags; /* IFF_xxx constants from <net/if.h> */
+ short ifa_myflags; /* our own IFI_xxx flags */
+ struct sockaddr *ifa_addr; /* primary address */
+ struct sockaddr *ifa_brdaddr;/* broadcast address */
+ struct sockaddr *ifa_dstaddr;/* destination address */
+ struct ifa_info *ifa_next; /* next of these structures */
+};
+
+#define IFI_ALIAS 1 /* ifa_addr is an alias */
+
+ /* function prototypes */
+struct ifa_info *get_ifa_info(int, int);
+struct ifa_info *Get_ifa_info(int, int);
+void free_ifa_info(struct ifa_info *);
+
+#define HAVE_SOCKADDR_SA_LEN 1
+
+struct ifa_info *
+get_ifa_info(int family, int doaliases)
+{
+ struct ifa_info *ifi, *ifihead, **ifipnext;
+ int sockfd, len, lastlen, flags, myflags;
+ char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
+ struct ifconf ifc;
+ struct ifreq *ifr, ifrcopy;
+ struct sockaddr_in *sinptr;
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ lastlen = 0;
+ len = 100 * sizeof(struct ifreq); /* initial buffer size guess */
+ for ( ; ; ) {
+ buf = (char *) malloc(len);
+ ifc.ifc_len = len;
+ ifc.ifc_buf = buf;
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
+ if (errno != EINVAL || lastlen != 0)
+ debugf("ioctl error");
+ } else {
+ if (ifc.ifc_len == lastlen)
+ break; /* success, len has not changed */
+ lastlen = ifc.ifc_len;
+ }
+ len += 10 * sizeof(struct ifreq); /* increment */
+ free(buf);
+ }
+ ifihead = NULL;
+ ifipnext = &ifihead;
+ lastname[0] = 0;
+/* end get_ifa_info1 */
+
+/* include get_ifa_info2 */
+ for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
+ ifr = (struct ifreq *) ptr;
+
+#ifdef HAVE_SOCKADDR_SA_LEN
+ len = MAX(sizeof(struct sockaddr), ifr->ifr_addr.sa_len);
+#else
+ switch (ifr->ifr_addr.sa_family) {
+#ifdef IPV6
+ case AF_INET6:
+ len = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ case AF_INET:
+ default:
+ len = sizeof(struct sockaddr);
+ break;
+ }
+#endif /* HAVE_SOCKADDR_SA_LEN */
+ ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */
+
+ if (ifr->ifr_addr.sa_family != family)
+ continue; /* ignore if not desired address family */
+
+ myflags = 0;
+ if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL)
+ *cptr = 0; /* replace colon will null */
+ if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) {
+ if (doaliases == 0)
+ continue; /* already processed this interface */
+ myflags = IFI_ALIAS;
+ }
+ memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
+
+ ifrcopy = *ifr;
+ ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy);
+ flags = ifrcopy.ifr_flags;
+ if ((flags & IFF_UP) == 0)
+ continue; /* ignore if interface not up */
+
+ ifi = (struct ifa_info *) calloc(1, sizeof(struct ifa_info));
+ *ifipnext = ifi; /* prev points to this new one */
+ ifipnext = &ifi->ifa_next; /* pointer to next one goes here */
+
+ ifi->ifa_flags = flags; /* IFF_xxx values */
+ ifi->ifa_myflags = myflags; /* IFI_xxx values */
+ memcpy(ifi->ifa_name, ifr->ifr_name, IFA_NAME);
+ ifi->ifa_name[IFA_NAME-1] = '\0';
+/* end get_ifa_info2 */
+/* include get_ifa_info3 */
+ switch (ifr->ifr_addr.sa_family) {
+ case AF_INET:
+ sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
+ if (ifi->ifa_addr == NULL) {
+ ifi->ifa_addr = (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in));
+ memcpy(ifi->ifa_addr, sinptr, sizeof(struct sockaddr_in));
+
+#ifdef SIOCGIFBRDADDR
+ if (flags & IFF_BROADCAST) {
+ ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy);
+ sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr;
+ ifi->ifa_brdaddr = (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in));
+ memcpy(ifi->ifa_brdaddr, sinptr, sizeof(struct sockaddr_in));
+ }
+#endif
+
+#ifdef SIOCGIFDSTADDR
+ if (flags & IFF_POINTOPOINT) {
+ ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy);
+ sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr;
+ ifi->ifa_dstaddr = (struct sockaddr *) calloc(1, sizeof(struct sockaddr_in));
+ memcpy(ifi->ifa_dstaddr, sinptr, sizeof(struct sockaddr_in));
+ }
+#endif
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ free(buf);
+ return(ifihead); /* pointer to first structure in linked list */
+}
+/* end get_ifa_info3 */
+
+/* include free_ifa_info */
+mDNSlocal void freeifaddrs(struct ifa_info *ifihead)
+{
+ struct ifa_info *ifi, *ifinext;
+
+ for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
+ if (ifi->ifa_addr != NULL)
+ free(ifi->ifa_addr);
+ if (ifi->ifa_brdaddr != NULL)
+ free(ifi->ifa_brdaddr);
+ if (ifi->ifa_dstaddr != NULL)
+ free(ifi->ifa_dstaddr);
+ ifinext = ifi->ifa_next; /* can't fetch ifa_next after free() */
+ free(ifi); /* the ifa_info{} itself */
+ }
+}
+/* end free_ifa_info */
+
+struct ifa_info *
+Get_ifa_info(int family, int doaliases)
+{
+ struct ifa_info *ifi;
+
+ if ( (ifi = get_ifa_info(family, doaliases)) == NULL)
+ debugf("get_ifa_info error");
+ return(ifi);
+}
+
+mDNSlocal int getifaddrs(struct ifa_info **ifalist)
+ {
+ *ifalist = get_ifa_info(PF_INET, false);
+ if( ifalist == nil )
+ return -1;
+ else
+ return(0);
+ }
path = dnssd_clientstub.c;
refType = 2;
};
- 0066920A04CC7AA80CCA2C71 = {
- isa = PBXTargetDependency;
- target = 0044D34804CC73600CCA2C71;
- };
00AD62A3032D799A0CCA2C71 = {
buildPhases = (
00AD62A4032D799A0CCA2C71,
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "";
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- HEADER_SEARCH_PATHS = "\"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\"";
+ HEADER_SEARCH_PATHS = "../mDNSShared \"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\"";
LIBRARY_SEARCH_PATHS = "";
MACOSX_DEPLOYMENT_TARGET = 10.2;
OPTIMIZATION_CFLAGS = "-O0";
- OTHER_CFLAGS = "-no-cpp-precomp -D__MACOSX__ -DMDNS_DEBUGMSGS=1 -DmDNSResponderVersion=$(MVERS)";
+ OTHER_CFLAGS = "-no-cpp-precomp -D__MACOSX__ -DMDNS_DEBUGMSGS=1 -DmDNSResponderVersion=$(MVERS) -DkDNSServiceFlagsRemove=0 -DkDNSServiceFlagsFinished=0";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = mDNSResponder.debug;
00AD62BC032D7A160CCA2C71,
00AD62BD032D7A1B0CCA2C71,
00AD62BE032D7A1D0CCA2C71,
- 0066920A04CC7AA80CCA2C71,
+ FF1B80C507AA1567000768F0,
+ FF1B80C607AA1569000768F0,
);
isa = PBXAggregateTarget;
name = "Build All";
00AD62A3032D799A0CCA2C71,
6575FC1C022EB76000000109,
0044D34804CC73600CCA2C71,
+ FF518DC907AA0BA60096AE13,
+ FFEF84D207AA10DF00171646,
);
};
08FB7794FE84155DC02AAC07 = {
children = (
+ FF518DCB07AA0C330096AE13,
08FB7795FE84155DC02AAC07,
6575FC1F022EB78C00000109,
6575FBFE022EAFA800000109,
09AB6884FE841BABC02AAC07,
65713D46025A293200000109,
00CA213D02786FC30CCA2C71,
+ FFEF84D607AA115900171646,
);
isa = PBXGroup;
name = "External Frameworks and Libraries";
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "";
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
- HEADER_SEARCH_PATHS = "\"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\"";
+ HEADER_SEARCH_PATHS = "../mDNSShared \"$(APPLE_INTERNAL_DEVELOPER_DIR)/Headers\"";
INSTALL_PATH = /usr/sbin;
LIBRARY_SEARCH_PATHS = "";
MACOSX_DEPLOYMENT_TARGET = 10.2;
- OTHER_CFLAGS = "-no-cpp-precomp -D__MACOSX__ -DmDNSResponderVersion=$(MVERS)";
+ OTHER_CFLAGS = "-no-cpp-precomp -D__MACOSX__ -DmDNSResponderVersion=$(MVERS) -DkDNSServiceFlagsRemove=0 -DkDNSServiceFlagsFinished=0";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = mDNSResponder;
REZ_EXECUTABLE = YES;
SECTORDER_FLAGS = "";
STRIPFLAGS = "-S";
+ USE_GCC3_PFE_SUPPORT = NO;
WARNING_CFLAGS = "-W -Wall -Wmissing-prototypes -Wno-four-char-constants -Wno-unknown-pragmas";
};
dependencies = (
6575FC1D022EB76000000109,
00AD62B8032D799A0CCA2C71,
0044D34F04CC73600CCA2C71,
+ FF72324E07AA0CB30012EE6F,
+ FFEF84D307AA10DF00171646,
);
isa = PBXGroup;
name = Products;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
INSTALL_PATH = /usr/bin;
MACOSX_DEPLOYMENT_TARGET = 10.2;
- OTHER_CFLAGS = "-no-cpp-precomp -DmDNSResponderVersion=$(MVERS)";
+ OTHER_CFLAGS = "-no-cpp-precomp -DmDNSResponderVersion=$(MVERS) -DkDNSServiceFlagsRemove=0";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
PRODUCT_NAME = mDNS;
settings = {
};
};
+//F50
+//F51
+//F52
+//F53
+//F54
+//FF0
+//FF1
+//FF2
+//FF3
+//FF4
+ FF1B80C507AA1567000768F0 = {
+ isa = PBXTargetDependency;
+ target = FF518DC907AA0BA60096AE13;
+ };
+ FF1B80C607AA1569000768F0 = {
+ isa = PBXTargetDependency;
+ target = FFEF84D207AA10DF00171646;
+ };
+ FF518DC607AA0BA60096AE13 = {
+ buildActionMask = 2147483647;
+ files = (
+ FF518DD907AA0C330096AE13,
+ FF518DDA07AA0C330096AE13,
+ FF518DDB07AA0C330096AE13,
+ FF518DDC07AA0C330096AE13,
+ FF518DDD07AA0C330096AE13,
+ FF518DDE07AA0C330096AE13,
+ FF518DDF07AA0C330096AE13,
+ FF518DE007AA0C330096AE13,
+ FF518DE207AA0C330096AE13,
+ FF518DE307AA0C330096AE13,
+ FF518DE407AA0C330096AE13,
+ FF518DE507AA0C330096AE13,
+ );
+ isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FF518DC707AA0BA60096AE13 = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FF518DC807AA0BA60096AE13 = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FF518DC907AA0BA60096AE13 = {
+ buildPhases = (
+ FF518DC607AA0BA60096AE13,
+ FF518DC707AA0BA60096AE13,
+ FF518DC807AA0BA60096AE13,
+ FF72324F07AA0CC20012EE6F,
+ FF72325007AA0CCA0012EE6F,
+ );
+ buildSettings = {
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ INSTALL_PATH = System/Library/Java/Extensions;
+ JAVA_ARCHIVE_CLASSES = YES;
+ JAVA_ARCHIVE_COMPRESSION = YES;
+ JAVA_ARCHIVE_TYPE = JAR;
+ JAVA_COMPILER_DEBUGGING_SYMBOLS = NO;
+ JAVA_COMPILER_TARGET_VM_VERSION = 1.2;
+ JAVA_SOURCE_SUBDIR = .;
+ LIBRARY_STYLE = STATIC;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_LIBTOOL_FLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = dns_sd;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+ };
+ dependencies = (
+ );
+ isa = PBXLibraryTarget;
+ name = dns_sd.jar;
+ productInstallPath = System/Library/Java/Extensions;
+ productName = dns_sd.jar;
+ productReference = FF72324E07AA0CB30012EE6F;
+ };
+ FF518DCB07AA0C330096AE13 = {
+ children = (
+ FF518DCC07AA0C330096AE13,
+ FF518DCD07AA0C330096AE13,
+ FF518DCE07AA0C330096AE13,
+ FF518DCF07AA0C330096AE13,
+ FF518DD007AA0C330096AE13,
+ FF518DD107AA0C330096AE13,
+ FF518DD207AA0C330096AE13,
+ FF518DD307AA0C330096AE13,
+ FF518DD407AA0C330096AE13,
+ FF518DD507AA0C330096AE13,
+ FF518DD607AA0C330096AE13,
+ FF518DD707AA0C330096AE13,
+ FF518DD807AA0C330096AE13,
+ );
+ isa = PBXGroup;
+ name = Java;
+ path = ../mDNSShared/Java;
+ refType = 2;
+ };
+ FF518DCC07AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = BaseListener.java;
+ path = ../mDNSShared/Java/BaseListener.java;
+ refType = 2;
+ };
+ FF518DCD07AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = BrowseListener.java;
+ path = ../mDNSShared/Java/BrowseListener.java;
+ refType = 2;
+ };
+ FF518DCE07AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = DNSRecord.java;
+ path = ../mDNSShared/Java/DNSRecord.java;
+ refType = 2;
+ };
+ FF518DCF07AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = DNSSD.java;
+ path = ../mDNSShared/Java/DNSSD.java;
+ refType = 2;
+ };
+ FF518DD007AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = DNSSDException.java;
+ path = ../mDNSShared/Java/DNSSDException.java;
+ refType = 2;
+ };
+ FF518DD107AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = DNSSDRegistration.java;
+ path = ../mDNSShared/Java/DNSSDRegistration.java;
+ refType = 2;
+ };
+ FF518DD207AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = DNSSDService.java;
+ path = ../mDNSShared/Java/DNSSDService.java;
+ refType = 2;
+ };
+ FF518DD307AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = DomainListener.java;
+ path = ../mDNSShared/Java/DomainListener.java;
+ refType = 2;
+ };
+ FF518DD407AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = JNISupport.c;
+ path = ../mDNSShared/Java/JNISupport.c;
+ refType = 2;
+ };
+ FF518DD507AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = QueryListener.java;
+ path = ../mDNSShared/Java/QueryListener.java;
+ refType = 2;
+ };
+ FF518DD607AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = RegisterListener.java;
+ path = ../mDNSShared/Java/RegisterListener.java;
+ refType = 2;
+ };
+ FF518DD707AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = ResolveListener.java;
+ path = ../mDNSShared/Java/ResolveListener.java;
+ refType = 2;
+ };
+ FF518DD807AA0C330096AE13 = {
+ fileEncoding = 30;
+ isa = PBXFileReference;
+ name = TXTRecord.java;
+ path = ../mDNSShared/Java/TXTRecord.java;
+ refType = 2;
+ };
+ FF518DD907AA0C330096AE13 = {
+ fileRef = FF518DCC07AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DDA07AA0C330096AE13 = {
+ fileRef = FF518DCD07AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DDB07AA0C330096AE13 = {
+ fileRef = FF518DCE07AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DDC07AA0C330096AE13 = {
+ fileRef = FF518DCF07AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DDD07AA0C330096AE13 = {
+ fileRef = FF518DD007AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DDE07AA0C330096AE13 = {
+ fileRef = FF518DD107AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DDF07AA0C330096AE13 = {
+ fileRef = FF518DD207AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DE007AA0C330096AE13 = {
+ fileRef = FF518DD307AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DE207AA0C330096AE13 = {
+ fileRef = FF518DD507AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DE307AA0C330096AE13 = {
+ fileRef = FF518DD607AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DE407AA0C330096AE13 = {
+ fileRef = FF518DD707AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF518DE507AA0C330096AE13 = {
+ fileRef = FF518DD807AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FF72324E07AA0CB30012EE6F = {
+ includeInIndex = 0;
+ isa = PBXZipArchiveReference;
+ path = dns_sd.jar;
+ refType = 3;
+ };
+ FF72324F07AA0CC20012EE6F = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "javah -force -classpath ${OBJROOT}/mDNSResponder.build/dns_sd.jar.build/JavaClasses/ -o ${OBJROOT}/mDNSResponder.build/dns_sd.jar.build/DNSSD.java.h com.apple.dnssd.AppleDNSSD com.apple.dnssd.AppleBrowser com.apple.dnssd.AppleResolver com.apple.dnssd.AppleRegistration com.apple.dnssd.AppleQuery com.apple.dnssd.AppleDomainEnum com.apple.dnssd.AppleService";
+ };
+ FF72325007AA0CCA0012EE6F = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ generatedFileNames = (
+ );
+ isa = PBXShellScriptBuildPhase;
+ neededFileNames = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "rm -f ${BUILD_DIR}/dns_sd";
+ };
+ FFEF84CE07AA10DF00171646 = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXHeadersBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FFEF84CF07AA10DF00171646 = {
+ buildActionMask = 2147483647;
+ files = (
+ FFEF84D407AA113100171646,
+ );
+ isa = PBXSourcesBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FFEF84D007AA10DF00171646 = {
+ buildActionMask = 2147483647;
+ files = (
+ FFEF84D707AA115900171646,
+ );
+ isa = PBXFrameworksBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FFEF84D107AA10DF00171646 = {
+ buildActionMask = 2147483647;
+ files = (
+ );
+ isa = PBXRezBuildPhase;
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ FFEF84D207AA10DF00171646 = {
+ buildPhases = (
+ FFEF84CE07AA10DF00171646,
+ FFEF84CF07AA10DF00171646,
+ FFEF84D007AA10DF00171646,
+ FFEF84D107AA10DF00171646,
+ );
+ buildSettings = {
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ HEADER_SEARCH_PATHS = "../mDNSShared \"$(SYSTEM_LIBRARY_DIR)/Frameworks/JavaVM.framework/Versions/A/Headers\" \"$(SYSTEM_LIBRARY_DIR)/Frameworks/JavaVM.framework/Versions/1.3.1/Headers\" \"$(OBJROOT)/mDNSResponder.build/dns_sd.jar.build\"";
+ INSTALL_PATH = /usr/lib/java;
+ LIBRARY_STYLE = DYNAMIC;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_LIBTOOL_FLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = libjdns_sd.jnilib;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+ };
+ comments = "Platform-specific JNI library that bridges dns_sd.jar to <dns_sd.h>.";
+ dependencies = (
+ FFEF84D807AA116400171646,
+ );
+ isa = PBXLibraryTarget;
+ name = libjdns_sd.jnilib;
+ productInstallPath = /usr/lib/java;
+ productName = libjdns_sd.jnilib;
+ productReference = FFEF84D307AA10DF00171646;
+ };
+ FFEF84D307AA10DF00171646 = {
+ isa = PBXLibraryReference;
+ path = libjdns_sd.jnilib;
+ refType = 3;
+ };
+ FFEF84D407AA113100171646 = {
+ fileRef = FF518DD407AA0C330096AE13;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FFEF84D607AA115900171646 = {
+ isa = PBXFrameworkReference;
+ name = JavaVM.framework;
+ path = /System/Library/Frameworks/JavaVM.framework;
+ refType = 0;
+ };
+ FFEF84D707AA115900171646 = {
+ fileRef = FFEF84D607AA115900171646;
+ isa = PBXBuildFile;
+ settings = {
+ };
+ };
+ FFEF84D807AA116400171646 = {
+ isa = PBXTargetDependency;
+ target = FF518DC907AA0BA60096AE13;
+ };
};
rootObject = 08FB7793FE84155DC02AAC07;
}
Change History (most recent first):
$Log: uds_daemon.c,v $
+Revision 1.22.2.4 2005/01/28 05:41:45 cheshire
+<rdar://problem/3924278> SUPan: Service advertisement in qmaster can yield zombie ads
+
+Revision 1.22.2.3 2005/01/28 04:03:24 cheshire
+<rdar://problem/3759302> SUPan: Current method of doing subtypes causes name collisions
+Summary: Pulled in ConstructServiceName, CountSubTypes and AllocateSubTypes from Tiger version.
+
+Revision 1.22.2.2 2004/06/18 17:28:19 cheshire
+<rdar://problem/3588761> Current method of doing subtypes causes name collisions
+
Revision 1.22.2.1 2003/12/05 00:03:35 cheshire
<rdar://problem/3487869> Use buffer size MAX_ESCAPED_DOMAIN_NAME instead of 256
CFRunLoopSourceRef rls;
CFSocketRef sr;
int sd;
- int errfd;
// state of read (in case message is read over several recv() calls)
transfer_state ts;
static void regservice_termination_callback(void *context);
static void process_service_registration(ServiceRecordSet *const srs);
static void regservice_callback(mDNS *const m, ServiceRecordSet *const srs, mStatus result);
-static void handle_add_request(request_state *rstate);
-static void handle_update_request(request_state *rstate);
+static mStatus handle_add_request(request_state *rstate);
+static mStatus handle_update_request(request_state *rstate);
static mStatus gen_rr_response(domainname *servicename, mDNSInterfaceID id, request_state *request, reply_state **rep);
static void append_reply(request_state *req, reply_state *rep);
static int build_domainname_from_strings(domainname *srv, char *name, char *regtype, char *domain);
static mStatus do_question(request_state *rstate, domainname *name, uint32_t ifi, uint16_t rrtype, int16_t rrclass);
static reply_state *format_enumeration_reply(request_state *rstate, char *domain, DNSServiceFlags flags, uint32_t ifi, DNSServiceErrorType err);
static void handle_enum_request(request_state *rstate);
-static void handle_regrecord_request(request_state *rstate);
+static mStatus handle_regrecord_request(request_state *rstate);
static void regrecord_callback(mDNS *const m, AuthRecord *const rr, mStatus result);
static void connected_registration_termination(void *context);
static void handle_reconfirm_request(request_state *rstate);
static AuthRecord *read_rr_from_ipc_msg(char *msgbuf, int ttl);
-static void handle_removerecord_request(request_state *rstate);
+static mStatus handle_removerecord_request(request_state *rstate);
static void reset_connected_rstate(request_state *rstate);
static int deliver_error(request_state *rstate, mStatus err);
static int deliver_async_error(request_state *rs, reply_op_t op, mStatus err);
for (req = all_requests; req; req = req->next)
{
srv = req->service;
- if (srv->autoname && !SameDomainLabel(srv->name.c, mDNSStorage.nicelabel.c))
+ if (srv && srv->autoname && !SameDomainLabel(srv->name.c, mDNSStorage.nicelabel.c))
{
srv->rename_on_memfree = 1;
err = mDNS_DeregisterService(&mDNSStorage, srv->srs);
if (rstate->hdr.flags & IPC_FLAGS_NOREPLY) rstate->no_reply = 1;
// check if primary socket is to be used for synchronous errors, else open new socket
- if (rstate->hdr.flags & IPC_FLAGS_REUSE_SOCKET)
- rstate->errfd = rstate->sd;
- else
- {
- if ((rstate->errfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
+ if ((rstate->hdr.flags & IPC_FLAGS_REUSE_SOCKET) == 0)
+ {
+ mStatus err = 0;
+ int nwritten;
+ int errfd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (errfd < 0)
{
my_perror("ERROR: socket");
- exit(1);
+ abort_request(rstate);
+ unlink_request(rstate);
+ return;
}
- if (fcntl(rstate->errfd, F_SETFL, O_NONBLOCK) < 0)
+ if (fcntl(errfd, F_SETFL, O_NONBLOCK) < 0)
{
my_perror("ERROR: could not set control socket to non-blocking mode");
abort_request(rstate);
bzero(&cliaddr, sizeof(cliaddr));
cliaddr.sun_family = AF_LOCAL;
strcpy(cliaddr.sun_path, ctrl_path);
- if (connect(rstate->errfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0)
+ if (connect(errfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr)) < 0)
{
my_perror("ERROR: connect");
abort_request(rstate);
unlink_request(rstate);
}
- }
-
-
-
- switch(rstate->hdr.op.request_op)
- {
- case resolve_request: handle_resolve_request(rstate); break;
- case query_request: handle_query_request(rstate); break;
- case browse_request: handle_browse_request(rstate); break;
- case reg_service_request: handle_regservice_request(rstate); break;
- case enumeration_request: handle_enum_request(rstate); break;
- case reg_record_request: handle_regrecord_request(rstate); break;
- case add_record_request: handle_add_request(rstate); break;
- case update_record_request: handle_update_request(rstate); break;
- case remove_record_request: handle_removerecord_request(rstate); break;
- case reconfirm_record_request: handle_reconfirm_request(rstate); break;
- default:
- debugf("ERROR: udsserver_recv_request - unsupported request type: %d", rstate->hdr.op.request_op);
- }
+ switch (rstate->hdr.op.request_op)
+ {
+ case reg_record_request: err = handle_regrecord_request (rstate); break;
+ case add_record_request: err = handle_add_request (rstate); break;
+ case update_record_request: err = handle_update_request (rstate); break;
+ case remove_record_request: err = handle_removerecord_request(rstate); break;
+ default: LogMsg("%3d: ERROR: udsserver_recv_request - unsupported request type: %d", rstate->sd, rstate->hdr.op);
+ }
+
+ nwritten = send(errfd, &err, sizeof(err), 0);
+ // On a freshly-created Unix Domain Socket, the kernel should *never* fail to buffer a four-byte write for us.
+ // If not, we don't attempt to handle this failure, but we do log it.
+ if (nwritten < (int)sizeof(err))
+ LogMsg("ERROR: failed to write error response back to caller: %d %d %s", nwritten, errno, strerror(errno));
+ close(errfd);
+ reset_connected_rstate(rstate); // Reset ready to accept the next request on this pipe
+ }
+ else
+ {
+ switch (rstate->hdr.op.request_op)
+ {
+ case resolve_request: handle_resolve_request (rstate); break;
+ case query_request: handle_query_request (rstate); break;
+ case browse_request: handle_browse_request (rstate); break;
+ case reg_service_request: handle_regservice_request(rstate); break;
+ case enumeration_request: handle_enum_request (rstate); break;
+ case reconfirm_record_request: handle_reconfirm_request (rstate); break;
+ default: LogMsg("%3d: ERROR: udsserver_recv_request - unsupported request type: %d", rstate->sd, rstate->hdr.op);
+ }
+ }
}
// mDNS operation functions. Each operation has 3 associated functions - a request handler that parses
freeL("question_termination_callback", q);
}
+// If there's a comma followed by another character,
+// FindFirstSubType overwrites the comma with a nul and returns the pointer to the next character.
+// Otherwise, it returns a pointer to the final nul at the end of the string
+static char *FindFirstSubType(char *p)
+ {
+ while (*p)
+ {
+ if (p[0] == '\\' && p[1]) p += 2;
+ else if (p[0] == ',' && p[1]) { *p++ = 0; return(p); }
+ else p++;
+ }
+ return(p);
+ }
+
+// If there's a comma followed by another character,
+// FindNextSubType overwrites the comma with a nul and returns the pointer to the next character.
+// If it finds an illegal unescaped dot in the subtype name, it returns mDNSNULL
+// Otherwise, it returns a pointer to the final nul at the end of the string
+static char *FindNextSubType(char *p)
+ {
+ while (*p)
+ {
+ if (p[0] == '\\' && p[1]) // If escape character
+ p += 2; // ignore following character
+ else if (p[0] == ',') // If we found a comma
+ {
+ if (p[1]) *p++ = 0;
+ return(p);
+ }
+ else if (p[0] == '.')
+ return(mDNSNULL);
+ else p++;
+ }
+ return(p);
+ }
+
+// Returns -1 if illegal subtype found
+extern mDNSs32 CountSubTypes(char *regtype);
+mDNSexport mDNSs32 CountSubTypes(char *regtype)
+ {
+ mDNSs32 NumSubTypes = 0;
+ char *stp = FindFirstSubType(regtype);
+ while (stp && *stp) // If we found a comma...
+ {
+ if (*stp == ',') return(-1);
+ NumSubTypes++;
+ stp = FindNextSubType(stp);
+ }
+ if (!stp) return(-1);
+ return(NumSubTypes);
+ }
+
+extern AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p);
+mDNSexport AuthRecord *AllocateSubTypes(mDNSs32 NumSubTypes, char *p)
+ {
+ AuthRecord *st = mDNSNULL;
+ if (NumSubTypes)
+ {
+ mDNSs32 i;
+ st = mallocL("ServiceSubTypes", NumSubTypes * sizeof(AuthRecord));
+ if (!st) return(mDNSNULL);
+ for (i = 0; i < NumSubTypes; i++)
+ {
+ while (*p) p++;
+ p++;
+ if (!MakeDomainNameFromDNSNameString(&st[i].resrec.name, p))
+ { freeL("ServiceSubTypes", st); return(mDNSNULL); }
+ }
+ }
+ return(st);
+ }
static void handle_browse_request(request_state *request)
{
char regtype[MAX_ESCAPED_DOMAIN_NAME], domain[MAX_ESCAPED_DOMAIN_NAME];
DNSQuestion *q;
domainname typedn, domdn;
+ mDNSs32 NumSubTypes;
char *ptr;
mStatus result;
if (interfaceIndex && !InterfaceID) goto bad_param;
q->QuestionContext = request;
q->QuestionCallback = browse_result_callback;
- if (!MakeDomainNameFromDNSNameString(&typedn, regtype) ||
+
+ typedn.c[0] = 0;
+ NumSubTypes = CountSubTypes(regtype);
+ if (NumSubTypes < 0 || NumSubTypes > 1) goto bad_param;
+ if (NumSubTypes == 1 && !AppendDNSNameString(&typedn, regtype + strlen(regtype) + 1)) goto bad_param;
+
+ if (!AppendDNSNameString(&typedn, regtype) ||
!MakeDomainNameFromDNSNameString(&domdn, domain[0] ? domain : "local."))
goto bad_param;
request->termination_context = q;
registered_service *r_srv;
int srs_size;
mStatus result;
+ mDNSs32 num_subtypes;
- char *sub, *rtype_ptr;
- int i, num_subtypes;
-
-
if (request->ts != t_complete)
{
LogMsg("ERROR: handle_regservice_request - transfer state != t_complete");
txtlen = get_short(&ptr);
txtdata = get_rdata(&ptr, txtlen);
- // count subtypes, replacing commas w/ whitespace
- rtype_ptr = regtype;
- num_subtypes = -1;
- while((sub = strsep(&rtype_ptr, ",")))
- if (*sub) num_subtypes++;
-
+ // Check for sub-types after the service type
+ num_subtypes = CountSubTypes(regtype);
+ if (num_subtypes < 0) goto bad_param;
+
if (!name[0]) n = (&mDNSStorage)->nicelabel;
else if (!MakeDomainLabelFromLiteralString(&n, name))
goto bad_param;
srs_size = sizeof(ServiceRecordSet) + (sizeof(RDataBody) > txtlen ? 0 : txtlen - sizeof(RDataBody));
r_srv->srs = mallocL("handle_regservice_request", srs_size);
if (!r_srv->srs) goto malloc_error;
- if (num_subtypes > 0)
- {
- r_srv->subtypes = mallocL("handle_regservice_request", num_subtypes * sizeof(AuthRecord));
- if (!r_srv->subtypes) goto malloc_error;
- sub = regtype + strlen(regtype) + 1;
- for (i = 0; i < num_subtypes; i++)
- {
- if (!MakeDomainNameFromDNSNameString(&(r_srv->subtypes + i)->resrec.name, sub))
- {
- freeL("handle_regservice_request", r_srv->subtypes);
- freeL("handle_regservice_request", r_srv);
- r_srv = NULL;
- goto bad_param;
- }
- sub += strlen(sub) + 1;
- }
- }
- else r_srv->subtypes = NULL;
+
+ r_srv->subtypes = AllocateSubTypes(num_subtypes, regtype);
+ if (num_subtypes && !r_srv->subtypes)
+ { freeL("handle_regservice_request", r_srv); r_srv = NULL; goto malloc_error; }
r_srv->request = request;
r_srv->autoname = (!name[0]);
}
}
-static void handle_add_request(request_state *rstate)
+static mStatus handle_add_request(request_state *rstate)
{
registered_record_entry *re;
ExtraResourceRecord *extra;
{
LogMsg("ERROR: handle_add_request - no service record set in request state");
deliver_error(rstate, mStatus_UnknownErr);
- return;
+ return(-1);
}
ptr = rstate->msgdata;
extra->r.resrec.rdlength = rdlen;
memcpy(&extra->r.rdatastorage.u.data, rdata, rdlen);
result = mDNS_AddRecordToService(&mDNSStorage, srs , extra, &extra->r.rdatastorage, ttl);
- deliver_error(rstate, result);
- reset_connected_rstate(rstate);
if (result)
{
freeL("handle_add_request", rstate->msgbuf);
rstate->msgbuf = NULL;
freeL("handle_add_request", extra);
- return;
+ return(result);
}
re = mallocL("handle_add_request", sizeof(registered_record_entry));
if (!re)
re->rr = &extra->r;
re->next = rstate->reg_recs;
rstate->reg_recs = re;
+ return(result);
}
-static void handle_update_request(request_state *rstate)
+static mStatus handle_update_request(request_state *rstate)
{
registered_record_entry *reptr;
AuthRecord *rr;
if (!rstate->service)
{
deliver_error(rstate, mStatus_BadParamErr);
- return;
+ return(-1);
}
rr = &rstate->service->srs->RR_TXT;
}
newrd->MaxRDLength = rdsize;
memcpy(&newrd->u, rdata, rdlen);
result = mDNS_Update(&mDNSStorage, rr, ttl, rdlen, newrd, update_callback);
- deliver_error(rstate, result);
- reset_connected_rstate(rstate);
+ return(result);
}
static void update_callback(mDNS *const m, AuthRecord *const rr, RData *oldrd)
}
-static void handle_regrecord_request(request_state *rstate)
+static mStatus handle_regrecord_request(request_state *rstate)
{
AuthRecord *rr;
regrecord_callback_context *rcc;
LogMsg("ERROR: handle_regrecord_request - transfer state != t_complete");
abort_request(rstate);
unlink_request(rstate);
- return;
+ return(-1);
}
rr = read_rr_from_ipc_msg(rstate->msgdata, 1);
- if (!rr)
- {
- deliver_error(rstate, mStatus_BadParamErr);
- return;
- }
+ if (!rr) return(mStatus_BadParamErr);
- rcc = mallocL("hanlde_regrecord_request", sizeof(regrecord_callback_context));
+ rcc = mallocL("handle_regrecord_request", sizeof(regrecord_callback_context));
if (!rcc) goto malloc_error;
rcc->rstate = rstate;
rcc->client_context = rstate->hdr.client_context;
rr->RecordCallback = regrecord_callback;
// allocate registration entry, link into list
- re = mallocL("hanlde_regrecord_request", sizeof(registered_record_entry));
+ re = mallocL("handle_regrecord_request", sizeof(registered_record_entry));
if (!re) goto malloc_error;
re->key = rstate->hdr.reg_index;
re->rr = rr;
}
result = mDNS_Register(&mDNSStorage, rr);
- deliver_error(rstate, result);
- reset_connected_rstate(rstate);
- return;
+ return(result);
malloc_error:
my_perror("ERROR: malloc");
- return;
+ return(-1);
}
static void regrecord_callback(mDNS *const m, AuthRecord *const rr, mStatus result)
-static void handle_removerecord_request(request_state *rstate)
+static mStatus handle_removerecord_request(request_state *rstate)
{
registered_record_entry *reptr, *prev = NULL;
mStatus err = mStatus_UnknownErr;
prev = reptr;
reptr = reptr->next;
}
- reset_connected_rstate(rstate);
- if (deliver_error(rstate, err) < 0)
- {
- abort_request(rstate);
- unlink_request(rstate);
- }
+ return(err);
}
}
// allocate context structures
- def = mallocL("hanlde_enum_request", sizeof(domain_enum_t));
+ def = mallocL("handle_enum_request", sizeof(domain_enum_t));
all = mallocL("handle_enum_request", sizeof(domain_enum_t));
term = mallocL("handle_enum_request", sizeof(enum_termination_t));
if (!def || !all || !term)
int nwritten = -1;
undelivered_error_t *undeliv;
- nwritten = send(rstate->errfd, &err, sizeof(mStatus), 0);
+ nwritten = send(rstate->sd, &err, sizeof(mStatus), 0);
if (nwritten < (int)sizeof(mStatus))
{
if (errno == EINTR || errno == EAGAIN)
}
undeliv->err = err;
undeliv->nwritten = nwritten;
- undeliv->sd = rstate->errfd;
+ undeliv->sd = rstate->sd;
rstate->u_err = undeliv;
return 0;
}
- if (rstate->errfd != rstate->sd) close(rstate->errfd);
return 0;
error:
- if (rstate->errfd != rstate->sd) close(rstate->errfd);
return -1;
}
CFSocketInvalidate(rs->sr);
CFRelease(rs->sr);
rs->sd = -1;
- if (rs->errfd >= 0) close(rs->errfd);
- rs->errfd = -1;
// free pending replies
rep = rs->replies;
Fix mistake in 1.8 -- INADDR_NONE is 0xFFFFFFFF, not 0
Revision 1.12 2003/04/16 02:11:07 cheshire
-Fixed mDNS_RegisterNoSuchService non-existance function so that it works again
+Fixed mDNS_RegisterNoSuchService non-existence function so that it works again
Revision 1.11 2003/03/31 22:49:35 cheshire
Add "$Log" header
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: BaseListener.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+ */
+
+
+package com.apple.dnssd;
+
+
+/** A base class for DNSSD listeners. */
+
+public interface BaseListener
+{
+ /** Called to report DNSSD operation failures.<P>
+
+ @param service
+ The service that encountered the failure.
+ <P>
+ @param errorCode
+ Indicates the failure that occurred. See {@link DNSSDException} for error codes.
+ */
+ void operationFailed( DNSSDService service, int errorCode);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: BrowseListener.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+ */
+
+
+package com.apple.dnssd;
+
+
+/** A listener that receives results from {@link DNSSD#browse}. */
+
+public interface BrowseListener extends BaseListener
+{
+ /** Called to report discovered services.<P>
+
+ @param browser
+ The active browse service.
+ <P>
+ @param flags
+ Possible values are DNSSD.MORE_COMING.
+ <P>
+ @param ifIndex
+ The interface on which the service is advertised. This index should be passed
+ to {@link DNSSD#resolve} when resolving the service.
+ <P>
+ @param serviceName
+ The service name discovered.
+ <P>
+ @param regType
+ The registration type, as passed in to DNSSD.browse().
+ <P>
+ @param domain
+ The domain in which the service was discovered.
+ */
+ void serviceFound( DNSSDService browser, int flags, int ifIndex,
+ String serviceName, String regType, String domain);
+
+ /** Called to report services which have been deregistered.<P>
+
+ @param browser
+ The active browse service.
+ <P>
+ @param flags
+ Possible values are DNSSD.MORE_COMING.
+ <P>
+ @param ifIndex
+ The interface on which the service is advertised.
+ <P>
+ @param serviceName
+ The service name which has deregistered.
+ <P>
+ @param regType
+ The registration type, as passed in to DNSSD.browse().
+ <P>
+ @param domain
+ The domain in which the service was discovered.
+ */
+ void serviceLost( DNSSDService browser, int flags, int ifIndex,
+ String serviceName, String regType, String domain);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSRecord.java,v $
+Revision 1.2 2004/12/11 03:00:59 rpantos
+<rdar://problem/3907498> Java DNSRecord API should be cleaned up
+
+Revision 1.1 2004/04/30 16:32:34 rpantos
+First checked in.
+
+
+ */
+
+
+package com.apple.dnssd;
+
+
+/**
+ Reference to a record returned by {@link DNSSDRegistration#addRecord}.<P>
+
+ Note: client is responsible for serializing access to these objects if
+ they are shared between concurrent threads.
+*/
+
+public interface DNSRecord
+{
+ /** Update a registered resource record.<P>
+ The record must either be the primary txt record of a service registered via DNSSD.register(),
+ or a record added to a registered service via addRecord().<P>
+
+ @param flags
+ Currently unused, reserved for future use.
+ <P>
+ @param rData
+ The new rdata to be contained in the updated resource record.
+ <P>
+ @param ttl
+ The time to live of the updated resource record, in seconds.
+ */
+ void update( int flags, byte[] rData, int ttl)
+ throws DNSSDException;
+
+ /** Remove a registered resource record.<P>
+ */
+ void remove()
+ throws DNSSDException;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSSD.java,v $
+Revision 1.4 2004/12/11 03:00:59 rpantos
+<rdar://problem/3907498> Java DNSRecord API should be cleaned up
+
+Revision 1.3 2004/11/12 03:23:08 rpantos
+rdar://problem/3809541 implement getIfIndexForName, getNameForIfIndex.
+
+Revision 1.2 2004/05/20 17:43:18 cheshire
+Fix invalid UTF-8 characters in file
+
+Revision 1.1 2004/04/30 16:32:34 rpantos
+First checked in.
+
+
+ This file declares and implements DNSSD, the central Java factory class
+ for doing DNS Service Discovery. It includes the mostly-abstract public
+ interface, as well as the Apple* implementation subclasses.
+
+ To do:
+ - implement network interface mappings
+ - RegisterRecord
+ */
+
+
+package com.apple.dnssd;
+
+
+/**
+ DNSSD provides access to DNS Service Discovery features of ZeroConf networking.<P>
+
+ It is a factory class that is used to invoke registration and discovery-related
+ operations. Most operations are non-blocking; clients are called back through an interface
+ with the result of an operation. Callbacks are made from a separate worker thread.<P>
+
+ For example, in this program<P>
+ <PRE><CODE>
+ class MyClient implements BrowseListener {
+ void lookForWebServers() {
+ myBrowser = DNSSD.browse("_http_.tcp", this);
+ }
+
+ public void serviceFound(DNSSDService browser, int flags, int ifIndex,
+ String serviceName, String regType, String domain) {}
+ ...
+ }</CODE></PRE>
+ <CODE>MyClient.serviceFound()</CODE> would be called for every HTTP server discovered in the
+ default browse domain(s).
+*/
+
+abstract public class DNSSD
+{
+ /** Flag indicates to a {@link BrowseListener} that another result is
+ queued. Applications should not update their UI to display browse
+ results if the MORE_COMING flag is set; they will be called at least once
+ more with the flag clear.
+ */
+ public static final int MORE_COMING = ( 1 << 0 );
+
+ /** If flag is set in a {@link DomainListener} callback, indicates that the result is the default domain. */
+ public static final int DEFAULT = ( 1 << 2 );
+
+ /** If flag is set, a name conflict will trigger an exception when registering non-shared records.<P>
+ A name must be explicitly specified when registering a service if this bit is set
+ (i.e. the default name may not not be used).
+ */
+ public static final int NO_AUTO_RENAME = ( 1 << 3 );
+
+ /** If flag is set, allow multiple records with this name on the network (e.g. PTR records)
+ when registering individual records on a {@link DNSSDRegistration}.
+ */
+ public static final int SHARED = ( 1 << 4 );
+
+ /** If flag is set, records with this name must be unique on the network (e.g. SRV records). */
+ public static final int UNIQUE = ( 1 << 5 );
+
+ /** Set flag when calling enumerateDomains() to restrict results to domains recommended for browsing. */
+ public static final int BROWSE_DOMAINS = ( 1 << 6 );
+ /** Set flag when calling enumerateDomains() to restrict results to domains recommended for registration. */
+ public static final int REGISTRATION_DOMAINS = ( 1 << 7 );
+
+ /** Maximum length, in bytes, of a domain name represented as an escaped C-String. */
+ public static final int MAX_DOMAIN_NAME = 1005;
+
+ /** Pass for ifIndex to specify all available interfaces. */
+ public static final int ALL_INTERFACES = 0;
+
+ /** Pass for ifIndex to specify the localhost interface. */
+ public static final int LOCALHOST_ONLY = -1;
+
+ /** Browse for instances of a service.<P>
+
+ Note: browsing consumes network bandwidth. Call {@link DNSSDService#stop} when you have finished browsing.<P>
+
+ @param flags
+ Currently ignored, reserved for future use.
+ <P>
+ @param ifIndex
+ If non-zero, specifies the interface on which to browse for services
+ (the index for a given interface is determined via the if_nametoindex()
+ family of calls.) Most applications will pass 0 to browse on all available
+ interfaces. Pass -1 to only browse for services provided on the local host.
+ <P>
+ @param regType
+ The registration type being browsed for followed by the protocol, separated by a
+ dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ <P>
+ @param domain
+ If non-null, specifies the domain on which to browse for services.
+ Most applications will not specify a domain, instead browsing on the
+ default domain(s).
+ <P>
+ @param listener
+ This object will get called when instances of the service are discovered (or disappear).
+ <P>
+ @return A {@link DNSSDService} that represents the active browse operation.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDService browse( int flags, int ifIndex, String regType, String domain, BrowseListener listener)
+ throws DNSSDException
+ { return getInstance()._makeBrowser( flags, ifIndex, regType, domain, listener); }
+
+ /** Browse for instances of a service. Use default flags, ifIndex and domain.<P>
+
+ @param regType
+ The registration type being browsed for followed by the protocol, separated by a
+ dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ <P>
+ @param listener
+ This object will get called when instances of the service are discovered (or disappear).
+ <P>
+ @return A {@link DNSSDService} that represents the active browse operation.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDService browse( String regType, BrowseListener listener)
+ throws DNSSDException
+ { return browse( 0, 0, regType, "", listener); }
+
+ /** Resolve a service name discovered via browse() to a target host name, port number, and txt record.<P>
+
+ Note: Applications should NOT use resolve() solely for txt record monitoring - use
+ queryRecord() instead, as it is more efficient for this task.<P>
+
+ Note: When the desired results have been returned, the client MUST terminate the resolve by
+ calling {@link DNSSDService#stop}.<P>
+
+ Note: resolve() behaves correctly for typical services that have a single SRV record and
+ a single TXT record (the TXT record may be empty.) To resolve non-standard services with
+ multiple SRV or TXT records, use queryRecord().<P>
+
+ @param flags
+ Currently ignored, reserved for future use.
+ <P>
+ @param ifIndex
+ The interface on which to resolve the service. The client should
+ pass the interface on which the serviceName was discovered (i.e.
+ the ifIndex passed to the serviceFound() callback)
+ or 0 to resolve the named service on all available interfaces.
+ <P>
+ @param serviceName
+ The servicename to be resolved.
+ <P>
+ @param regType
+ The registration type being resolved followed by the protocol, separated by a
+ dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ <P>
+ @param domain
+ The domain on which the service is registered, i.e. the domain passed
+ to the serviceFound() callback.
+ <P>
+ @param listener
+ This object will get called when the service is resolved.
+ <P>
+ @return A {@link DNSSDService} that represents the active resolve operation.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDService resolve( int flags, int ifIndex, String serviceName, String regType,
+ String domain, ResolveListener listener)
+ throws DNSSDException
+ { return getInstance()._resolve( flags, ifIndex, serviceName, regType, domain, listener); }
+
+ /** Register a service, to be discovered via browse() and resolve() calls.<P>
+ @param flags
+ Possible values are: NO_AUTO_RENAME.
+ <P>
+ @param ifIndex
+ If non-zero, specifies the interface on which to register the service
+ (the index for a given interface is determined via the if_nametoindex()
+ family of calls.) Most applications will pass 0 to register on all
+ available interfaces. Pass -1 to register a service only on the local
+ machine (service will not be visible to remote hosts).
+ <P>
+ @param serviceName
+ If non-null, specifies the service name to be registered.
+ Applications need not specify a name, in which case the
+ computer name is used (this name is communicated to the client via
+ the serviceRegistered() callback).
+ <P>
+ @param regType
+ The registration type being registered followed by the protocol, separated by a
+ dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ <P>
+ @param domain
+ If non-null, specifies the domain on which to advertise the service.
+ Most applications will not specify a domain, instead automatically
+ registering in the default domain(s).
+ <P>
+ @param host
+ If non-null, specifies the SRV target host name. Most applications
+ will not specify a host, instead automatically using the machine's
+ default host name(s). Note that specifying a non-null host does NOT
+ create an address record for that host - the application is responsible
+ for ensuring that the appropriate address record exists, or creating it
+ via {@link DNSSDRegistration#addRecord}.
+ <P>
+ @param port
+ The port on which the service accepts connections. Pass 0 for a
+ "placeholder" service (i.e. a service that will not be discovered by
+ browsing, but will cause a name conflict if another client tries to
+ register that same name.) Most clients will not use placeholder services.
+ <P>
+ @param txtRecord
+ The txt record rdata. May be null. Note that a non-null txtRecord
+ MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
+ <length byte> <data> ...
+ <P>
+ @param listener
+ This object will get called when the service is registered.
+ <P>
+ @return A {@link DNSSDRegistration} that controls the active registration.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDRegistration register( int flags, int ifIndex, String serviceName, String regType,
+ String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
+ throws DNSSDException
+ { return getInstance()._register( flags, ifIndex, serviceName, regType, domain, host, port, txtRecord, listener); }
+
+ /** Register a service, to be discovered via browse() and resolve() calls. Use default flags, ifIndex, domain, host and txtRecord.<P>
+ @param serviceName
+ If non-null, specifies the service name to be registered.
+ Applications need not specify a name, in which case the
+ computer name is used (this name is communicated to the client via
+ the serviceRegistered() callback).
+ <P>
+ @param regType
+ The registration type being registered followed by the protocol, separated by a
+ dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ <P>
+ @param port
+ The port on which the service accepts connections. Pass 0 for a
+ "placeholder" service (i.e. a service that will not be discovered by
+ browsing, but will cause a name conflict if another client tries to
+ register that same name.) Most clients will not use placeholder services.
+ <P>
+ @param listener
+ This object will get called when the service is registered.
+ <P>
+ @return A {@link DNSSDRegistration} that controls the active registration.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDRegistration register( String serviceName, String regType, int port, RegisterListener listener)
+ throws DNSSDException
+ { return register( 0, 0, serviceName, regType, null, null, port, null, listener); }
+
+ /** Query for an arbitrary DNS record.<P>
+ @param flags
+ Possible values are: MORE_COMING.
+ <P>
+ @param ifIndex
+ If non-zero, specifies the interface on which to issue the query
+ (the index for a given interface is determined via the if_nametoindex()
+ family of calls.) Passing 0 causes the name to be queried for on all
+ interfaces. Passing -1 causes the name to be queried for only on the
+ local host.
+ <P>
+ @param serviceName
+ The full domain name of the resource record to be queried for.
+ <P>
+ @param rrtype
+ The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
+ as defined in nameser.h.
+ <P>
+ @param rrclass
+ The class of the resource record, as defined in nameser.h
+ (usually 1 for the Internet class).
+ <P>
+ @param listener
+ This object will get called when the query completes.
+ <P>
+ @return A {@link DNSSDService} that controls the active query.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDService queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
+ int rrclass, QueryListener listener)
+ throws DNSSDException
+ { return getInstance()._queryRecord( flags, ifIndex, serviceName, rrtype, rrclass, listener); }
+
+ /** Asynchronously enumerate domains available for browsing and registration.<P>
+
+ Currently, the only domain returned is "local.", but other domains will be returned in future.<P>
+
+ The enumeration MUST be cancelled by calling {@link DNSSDService#stop} when no more domains
+ are to be found.<P>
+ @param flags
+ Possible values are: BROWSE_DOMAINS, REGISTRATION_DOMAINS.
+ <P>
+ @param ifIndex
+ If non-zero, specifies the interface on which to look for domains.
+ (the index for a given interface is determined via the if_nametoindex()
+ family of calls.) Most applications will pass 0 to enumerate domains on
+ all interfaces.
+ <P>
+ @param listener
+ This object will get called when domains are found.
+ <P>
+ @return A {@link DNSSDService} that controls the active enumeration.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static DNSSDService enumerateDomains( int flags, int ifIndex, DomainListener listener)
+ throws DNSSDException
+ { return getInstance()._enumerateDomains( flags, ifIndex, listener); }
+
+ /** Concatenate a three-part domain name (as provided to the listeners) into a
+ properly-escaped full domain name. Note that strings passed to listeners are
+ ALREADY ESCAPED where necessary.<P>
+ @param serviceName
+ The service name - any dots or slashes must NOT be escaped.
+ May be null (to construct a PTR record name, e.g. "_ftp._tcp.apple.com").
+ <P>
+ @param regType
+ The registration type followed by the protocol, separated by a dot (e.g. "_ftp._tcp").
+ <P>
+ @param domain
+ The domain name, e.g. "apple.com". Any literal dots or backslashes must be escaped.
+ <P>
+ @return The full domain name.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static String constructFullName( String serviceName, String regType, String domain)
+ throws DNSSDException
+ { return getInstance()._constructFullName( serviceName, regType, domain); }
+
+ /** Instruct the daemon to verify the validity of a resource record that appears to
+ be out of date. (e.g. because tcp connection to a service's target failed.) <P>
+
+ Causes the record to be flushed from the daemon's cache (as well as all other
+ daemons' caches on the network) if the record is determined to be invalid.<P>
+ @param flags
+ Currently unused, reserved for future use.
+ <P>
+ @param ifIndex
+ If non-zero, specifies the interface on which to reconfirm the record
+ (the index for a given interface is determined via the if_nametoindex()
+ family of calls.) Passing 0 causes the name to be reconfirmed on all
+ interfaces. Passing -1 causes the name to be reconfirmed only on the
+ local host.
+ <P>
+ @param fullName
+ The resource record's full domain name.
+ <P>
+ @param rrtype
+ The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
+ <P>
+ @param rrclass
+ The class of the resource record, as defined in nameser.h (usually 1).
+ <P>
+ @param rdata
+ The raw rdata of the resource record.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static void reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
+ int rrclass, byte[] rdata)
+ { getInstance()._reconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata); }
+
+ /** Return the canonical name of a particular interface index.<P>
+ @param ifIndex
+ A valid interface index. Must not be ALL_INTERFACES.
+ <P>
+ @return The name of the interface, which should match java.net.NetworkInterface.getName().
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static String getNameForIfIndex( int ifIndex)
+ { return getInstance()._getNameForIfIndex( ifIndex); }
+
+ /** Return the index of a named interface.<P>
+ @param ifName
+ A valid interface name. An example is java.net.NetworkInterface.getName().
+ <P>
+ @return The interface index.
+
+ @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>.
+ @see RuntimePermission
+ */
+ public static int getIfIndexForName( String ifName)
+ { return getInstance()._getIfIndexForName( ifName); }
+
+ protected DNSSD() {} // prevent direct instantiation
+
+ /** Return the single instance of DNSSD. */
+ static protected final DNSSD getInstance()
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if ( sm != null)
+ sm.checkPermission( new RuntimePermission( "getDNSSDInstance"));
+ return fInstance;
+ }
+
+ abstract protected DNSSDService _makeBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener listener)
+ throws DNSSDException;
+
+ abstract protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
+ String domain, ResolveListener listener)
+ throws DNSSDException;
+
+ abstract protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
+ String domain, String host, int port, TXTRecord txtRecord, RegisterListener listener)
+ throws DNSSDException;
+
+ abstract protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
+ int rrclass, QueryListener listener)
+ throws DNSSDException;
+
+ abstract protected DNSSDService _enumerateDomains( int flags, int ifIndex, DomainListener listener)
+ throws DNSSDException;
+
+ abstract protected String _constructFullName( String serviceName, String regType, String domain)
+ throws DNSSDException;
+
+ abstract protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
+ int rrclass, byte[] rdata);
+
+ abstract protected String _getNameForIfIndex( int ifIndex);
+
+ abstract protected int _getIfIndexForName( String ifName);
+
+ protected static DNSSD fInstance;
+
+ static
+ {
+ try
+ {
+ String name = System.getProperty( "com.apple.dnssd.DNSSD" );
+ if( name == null )
+ name = "com.apple.dnssd.AppleDNSSD"; // Fall back to Apple-provided class.
+ fInstance = (DNSSD) Class.forName( name ).newInstance();
+ }
+ catch( Exception e )
+ {
+ throw new InternalError( "cannot instantiate DNSSD" + e );
+ }
+ }
+}
+
+
+// Concrete implementation of DNSSDException
+class AppleDNSSDException extends DNSSDException
+{
+ public AppleDNSSDException( int errorCode) { fErrorCode = errorCode; }
+
+ public int getErrorCode() { return fErrorCode; }
+
+ public String getMessage()
+ {
+ final String kMessages[] = { // should probably be put into a resource or something
+ "UNKNOWN",
+ "NO_SUCH_NAME",
+ "NO_MEMORY",
+ "BAD_PARAM",
+ "BAD_REFERENCE",
+ "BAD_STATE",
+ "BAD_FLAGS",
+ "UNSUPPORTED",
+ "NOT_INITIALIZED",
+ "", // there is NO number 6
+ "ALREADY_REGISTERED",
+ "NAME_CONFLICT",
+ "INVALID",
+ "", // another MIA
+ "INCOMPATIBLE",
+ "BAD_INTERFACE_INDEX"
+ };
+
+ if ( fErrorCode <= UNKNOWN && fErrorCode > ( UNKNOWN - kMessages.length))
+ {
+ return "DNS-SD Error " + String.valueOf( fErrorCode) + ": " + kMessages[ UNKNOWN - fErrorCode];
+ }
+ else
+ return super.getMessage() + "(" + String.valueOf( fErrorCode) + ")";
+ }
+
+ protected int fErrorCode;
+}
+
+// The concrete, default implementation.
+class AppleDNSSD extends DNSSD
+{
+ static
+ {
+ System.loadLibrary( "jdns_sd");
+
+ int libInitResult = InitLibrary( 1);
+
+ if ( libInitResult != DNSSDException.NO_ERROR)
+ throw new InternalError( "cannot instantiate DNSSD: " + new AppleDNSSDException( libInitResult).getMessage());
+ }
+
+ static public boolean hasAutoCallbacks; // Set by InitLibrary() to value of AUTO_CALLBACKS
+
+ protected DNSSDService _makeBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client)
+ throws DNSSDException
+ {
+ return new AppleBrowser( flags, ifIndex, regType, domain, client);
+ }
+
+ protected DNSSDService _resolve( int flags, int ifIndex, String serviceName, String regType,
+ String domain, ResolveListener client)
+ throws DNSSDException
+ {
+ return new AppleResolver( flags, ifIndex, serviceName, regType, domain, client);
+ }
+
+ protected DNSSDRegistration _register( int flags, int ifIndex, String serviceName, String regType,
+ String domain, String host, int port, TXTRecord txtRecord, RegisterListener client)
+ throws DNSSDException
+ {
+ return new AppleRegistration( flags, ifIndex, serviceName, regType, domain, host, port,
+ ( txtRecord != null) ? txtRecord.getRawBytes() : null, client);
+ }
+
+ protected DNSSDService _queryRecord( int flags, int ifIndex, String serviceName, int rrtype,
+ int rrclass, QueryListener client)
+ throws DNSSDException
+ {
+ return new AppleQuery( flags, ifIndex, serviceName, rrtype, rrclass, client);
+ }
+
+ protected DNSSDService _enumerateDomains( int flags, int ifIndex, DomainListener listener)
+ throws DNSSDException
+ {
+ return new AppleDomainEnum( flags, ifIndex, listener);
+ }
+
+ protected String _constructFullName( String serviceName, String regType, String domain)
+ throws DNSSDException
+ {
+ String[] responseHolder = new String[1]; // lame maneuver to get around Java's lack of reference parameters
+
+ int rc = ConstructName( serviceName, regType, domain, responseHolder);
+ if ( rc != 0)
+ throw new AppleDNSSDException( rc);
+
+ return responseHolder[0];
+ }
+
+ protected void _reconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
+ int rrclass, byte[] rdata)
+ {
+ ReconfirmRecord( flags, ifIndex, fullName, rrtype, rrclass, rdata);
+ }
+
+ protected String _getNameForIfIndex( int ifIndex)
+ {
+ return GetNameForIfIndex( ifIndex);
+ }
+
+ protected int _getIfIndexForName( String ifName)
+ {
+ return GetIfIndexForName( ifName);
+ }
+
+
+ protected native int ConstructName( String serviceName, String regType, String domain, String[] pOut);
+
+ protected native void ReconfirmRecord( int flags, int ifIndex, String fullName, int rrtype,
+ int rrclass, byte[] rdata);
+
+ protected native String GetNameForIfIndex( int ifIndex);
+
+ protected native int GetIfIndexForName( String ifName);
+
+ protected static native int InitLibrary( int callerVersion);
+}
+
+class AppleService implements DNSSDService, Runnable
+{
+ public AppleService() { fNativeContext = 0; }
+
+ public void stop() { this.HaltOperation(); }
+
+ public void finalize() throws Throwable
+ {
+ this.stop();
+ super.finalize();
+ }
+
+ /* The run() method is used internally to schedule an update from another thread */
+ public void run()
+ {
+ this.ProcessResults();
+ }
+
+ /* Block for timeout ms (or forever if -1). Returns 1 if data present, 0 if timed out, -1 if not browsing. */
+ protected native int BlockForData( int msTimeout);
+
+ /* Call ProcessResults when data appears on socket descriptor. */
+ protected native void ProcessResults();
+
+ protected native void HaltOperation();
+
+ protected void ThrowOnErr( int rc) throws DNSSDException
+ {
+ if ( rc != 0)
+ throw new AppleDNSSDException( rc);
+ }
+
+ protected int /* warning */ fNativeContext; // Private storage for native side
+}
+
+
+// A ServiceThread calls AppleService.BlockForData() and schedules its client
+// when data appears.
+class ServiceThread extends Thread
+{
+ public ServiceThread( AppleService owner) { fOwner = owner; }
+
+ public void run()
+ {
+ int result;
+
+ while ( true )
+ {
+ result = fOwner.BlockForData( -1);
+ if ( result == 1)
+ {
+ fOwner.run();
+ }
+ else
+ break; // terminate thread
+ }
+ }
+
+ protected AppleService fOwner;
+}
+
+
+class AppleBrowser extends AppleService
+{
+ public AppleBrowser( int flags, int ifIndex, String regType, String domain, BrowseListener client)
+ throws DNSSDException
+ {
+ fClient = client;
+ this.ThrowOnErr( this.CreateBrowser( flags, ifIndex, regType, domain));
+ if ( !AppleDNSSD.hasAutoCallbacks)
+ new ServiceThread( this).start();
+ }
+
+ // Sets fNativeContext. Returns non-zero on error.
+ protected native int CreateBrowser( int flags, int ifIndex, String regType, String domain);
+
+ protected BrowseListener fClient;
+}
+
+class AppleResolver extends AppleService
+{
+ public AppleResolver( int flags, int ifIndex, String serviceName, String regType,
+ String domain, ResolveListener client)
+ throws DNSSDException
+ {
+ fClient = client;
+ this.ThrowOnErr( this.CreateResolver( flags, ifIndex, serviceName, regType, domain));
+ if ( !AppleDNSSD.hasAutoCallbacks)
+ new ServiceThread( this).start();
+ }
+
+ // Sets fNativeContext. Returns non-zero on error.
+ protected native int CreateResolver( int flags, int ifIndex, String serviceName, String regType,
+ String domain);
+
+ protected ResolveListener fClient;
+}
+
+// An AppleDNSRecord is a simple wrapper around a dns_sd DNSRecord.
+class AppleDNSRecord implements DNSRecord
+{
+ public AppleDNSRecord( AppleService owner)
+ {
+ fOwner = owner;
+ fRecord = 0; // record always starts out empty
+ }
+
+ public void update( int flags, byte[] rData, int ttl)
+ throws DNSSDException
+ {
+ this.ThrowOnErr( this.Update( flags, rData, ttl));
+ }
+
+ public void remove()
+ throws DNSSDException
+ {
+ this.ThrowOnErr( this.Remove());
+ }
+
+ protected int fRecord; // Really a DNSRecord; sizeof(int) == sizeof(void*) ?
+ protected AppleService fOwner;
+
+ protected void ThrowOnErr( int rc) throws DNSSDException
+ {
+ if ( rc != 0)
+ throw new AppleDNSSDException( rc);
+ }
+
+ protected native int Update( int flags, byte[] rData, int ttl);
+
+ protected native int Remove();
+}
+
+class AppleRegistration extends AppleService implements DNSSDRegistration
+{
+ public AppleRegistration( int flags, int ifIndex, String serviceName, String regType, String domain,
+ String host, int port, byte[] txtRecord, RegisterListener client)
+ throws DNSSDException
+ {
+ fClient = client;
+ this.ThrowOnErr( this.BeginRegister( ifIndex, flags, serviceName, regType, domain, host, port, txtRecord));
+ if ( !AppleDNSSD.hasAutoCallbacks)
+ new ServiceThread( this).start();
+ }
+
+ public DNSRecord addRecord( int flags, int rrType, byte[] rData, int ttl)
+ throws DNSSDException
+ {
+ AppleDNSRecord newRecord = new AppleDNSRecord( this);
+
+ this.ThrowOnErr( this.AddRecord( flags, rrType, rData, ttl, newRecord));
+
+ return newRecord;
+ }
+
+ public DNSRecord getTXTRecord()
+ throws DNSSDException
+ {
+ return new AppleDNSRecord( this); // A record with ref 0 is understood to be primary TXT record
+ }
+
+ // Sets fNativeContext. Returns non-zero on error.
+ protected native int BeginRegister( int ifIndex, int flags, String serviceName, String regType,
+ String domain, String host, int port, byte[] txtRecord);
+
+ // Sets fNativeContext. Returns non-zero on error.
+ protected native int AddRecord( int flags, int rrType, byte[] rData, int ttl, AppleDNSRecord destObj);
+
+ protected RegisterListener fClient;
+}
+
+class AppleQuery extends AppleService
+{
+ public AppleQuery( int flags, int ifIndex, String serviceName, int rrtype,
+ int rrclass, QueryListener client)
+ throws DNSSDException
+ {
+ fClient = client;
+ this.ThrowOnErr( this.CreateQuery( flags, ifIndex, serviceName, rrtype, rrclass));
+ if ( !AppleDNSSD.hasAutoCallbacks)
+ new ServiceThread( this).start();
+ }
+
+ // Sets fNativeContext. Returns non-zero on error.
+ protected native int CreateQuery( int flags, int ifIndex, String serviceName, int rrtype, int rrclass);
+
+ protected QueryListener fClient;
+}
+
+class AppleDomainEnum extends AppleService
+{
+ public AppleDomainEnum( int flags, int ifIndex, DomainListener listener)
+ throws DNSSDException
+ {
+ fClient = listener;
+ this.ThrowOnErr( this.BeginEnum( flags, ifIndex));
+ if ( !AppleDNSSD.hasAutoCallbacks)
+ new ServiceThread( this).start();
+ }
+
+ // Sets fNativeContext. Returns non-zero on error.
+ protected native int BeginEnum( int flags, int ifIndex);
+
+ protected DomainListener fClient;
+}
+
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSSDException.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+*/
+
+package com.apple.dnssd;
+
+
+/**
+ Used to report various DNS-SD-related error conditions.
+*/
+
+abstract public class DNSSDException extends Exception
+{
+ public static final int NO_ERROR = 0;
+ public static final int UNKNOWN = -65537;
+ public static final int NO_SUCH_NAME = -65538;
+ public static final int NO_MEMORY = -65539;
+ public static final int BAD_PARAM = -65540;
+ public static final int BAD_REFERENCE = -65541;
+ public static final int BAD_STATE = -65542;
+ public static final int BAD_FLAGS = -65543;
+ public static final int UNSUPPORTED = -65544;
+ public static final int NOT_INITIALIZED = -65545;
+ public static final int ALREADY_REGISTERED = -65547;
+ public static final int NAME_CONFLICT = -65548;
+ public static final int INVALID = -65549;
+ public static final int INCOMPATIBLE = -65551;
+ public static final int BAD_INTERFACE_INDEX = -65552;
+
+ /** Returns the sub-code that identifies the particular error. */
+ abstract public int getErrorCode();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSSDRegistration.java,v $
+Revision 1.2 2004/12/11 03:01:00 rpantos
+<rdar://problem/3907498> Java DNSRecord API should be cleaned up
+
+Revision 1.1 2004/04/30 16:32:34 rpantos
+First checked in.
+
+
+ This file declares the public interface to DNSSDRegistration, a DNSSDService
+ subclass that allows a client to control a service registration.
+ */
+
+
+package com.apple.dnssd;
+
+
+/** A tracking object for a registration created by {@link DNSSD#register}. */
+
+public interface DNSSDRegistration extends DNSSDService
+{
+ /** Get a reference to the primary TXT record of a registered service.<P>
+ The record can be updated by sending it an update() message.<P>
+
+ <P>
+ @return A {@link DNSRecord}.
+ If {@link DNSSDRegistration#stop} is called, the DNSRecord is also
+ invalidated and may not be used further.
+ */
+ DNSRecord getTXTRecord()
+ throws DNSSDException;
+
+ /** Add a record to a registered service.<P>
+ The name of the record will be the same as the registered service's name.<P>
+ The record can be updated or deregistered by sending it an update() or remove() message.<P>
+
+ @param flags
+ Currently unused, reserved for future use.
+ <P>
+ @param rrType
+ The type of the record (e.g. TXT, SRV, etc), as defined in nameser.h.
+ <P>
+ @param rData
+ The raw rdata to be contained in the added resource record.
+ <P>
+ @param ttl
+ The time to live of the resource record, in seconds.
+ <P>
+ @return A {@link DNSRecord} that may be passed to updateRecord() or removeRecord().
+ If {@link DNSSDRegistration#stop} is called, the DNSRecord is also
+ invalidated and may not be used further.
+ */
+ DNSRecord addRecord( int flags, int rrType, byte[] rData, int ttl)
+ throws DNSSDException;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DNSSDService.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:32:34 rpantos
+First checked in.
+
+ */
+
+
+package com.apple.dnssd;
+
+/** A tracking object for a service created by {@link DNSSD}. */
+
+public interface DNSSDService
+{
+ /**
+ Halt the active operation and free resources associated with the DNSSDService.<P>
+
+ Any services or records registered with this DNSSDService will be deregistered. Any
+ Browse, Resolve, or Query operations associated with this reference will be terminated.<P>
+
+ Note: if the service was initialized with DNSSD.register(), and an extra resource record was
+ added to the service via {@link DNSSDRegistration#addRecord}, the DNSRecord so created
+ is invalidated when this method is called - the DNSRecord may not be used afterward.
+ */
+ void stop();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: DomainListener.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+ */
+
+
+package com.apple.dnssd;
+
+
+/**
+ A listener that receives results from {@link DNSSD#enumerateDomains}.
+*/
+
+public interface DomainListener extends BaseListener
+{
+ /** Called to report discovered domains.<P>
+
+ @param domainEnum
+ The active domain enumerator.
+ @param flags
+ Possible values are: DNSSD.MORE_COMING, DNSSD.DEFAULT
+ <P>
+ @param ifIndex
+ Specifies the interface on which the domain exists. (The index for a given
+ interface is determined via the if_nametoindex() family of calls.)
+ <P>
+ @param domain
+ The name of the domain.
+ */
+ void domainFound( DNSSDService domainEnum, int flags, int ifIndex, String domain);
+
+ /** Called to report that a domain has disappeared.<P>
+
+ @param domainEnum
+ The active domain enumerator.
+ @param flags
+ Possible values are: DNSSD.MORE_COMING, DNSSD.DEFAULT
+ <P>
+ @param ifIndex
+ Specifies the interface on which the domain exists. (The index for a given
+ interface is determined via the if_nametoindex() family of calls.)
+ <P>
+ @param domain
+ The name of the domain.
+ */
+ void domainLost( DNSSDService domainEnum, int flags, int ifIndex, String domain);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: JNISupport.c,v $
+Revision 1.9 2004/12/11 03:01:00 rpantos
+<rdar://problem/3907498> Java DNSRecord API should be cleaned up
+
+Revision 1.8 2004/11/30 23:51:05 cheshire
+Remove double semicolons
+
+Revision 1.7 2004/11/23 08:12:04 shersche
+Implement if_nametoindex and if_indextoname for Win32 platforms
+
+Revision 1.6 2004/11/23 03:41:14 cheshire
+Change JNISupport.c to call if_indextoname & if_nametoindex directly.
+(May require some additional glue code to work on Windows.)
+
+Revision 1.5 2004/11/17 17:07:44 cheshire
+Updated comment about AUTO_CALLBACKS
+
+Revision 1.4 2004/11/12 03:23:09 rpantos
+rdar://problem/3809541 implement getIfIndexForName, getNameForIfIndex.
+
+Revision 1.3 2004/06/18 04:44:17 rpantos
+Adapt to API unification on Windows
+
+Revision 1.2 2004/05/28 23:34:42 ksekar
+<rdar://problem/3672903>: Java project build errors
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+
+ This file contains the platform support for DNSSD and related Java classes.
+ It is used to shim through to the underlying <dns_sd.h> API.
+ */
+
+// AUTO_CALLBACKS should be set to 1 if the underlying mDNS implementation fires response
+// callbacks automatically (as in the early Windows prototypes).
+// AUTO_CALLBACKS should be set to 0 if the client must call DNSServiceProcessResult() to
+// invoke response callbacks (as is true on Mac OS X, Posix, Windows, etc.).
+// (Invoking callbacks automatically on a different thread sounds attractive, but while
+// the client gains by not needing to add an event source to its main event loop, it loses
+// by being forced to deal with concurrency and locking, which can be a bigger burden.)
+#ifndef AUTO_CALLBACKS
+#define AUTO_CALLBACKS 0
+#endif
+
+#if !AUTO_CALLBACKS
+#ifdef _WIN32
+#include <winsock2.h>
+#else //_WIN32
+#include <sys/types.h>
+#include <sys/select.h>
+#endif // _WIN32
+#endif // AUTO_CALLBACKS
+
+#include <dns_sd.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef _WIN32
+#include <winsock2.h>
+#include <iphlpapi.h>
+static char * if_indextoname( DWORD ifIndex, char * nameBuff);
+static DWORD if_nametoindex( const char * nameStr );
+#define IF_NAMESIZE MAX_ADAPTER_NAME_LENGTH
+#else // _WIN32
+#include <sys/socket.h>
+#include <net/if.h>
+#endif // _WIN32
+#include <jni.h>
+
+#include "DNSSD.java.h"
+
+// convenience definition
+#ifdef __GNUC__
+#define _UNUSED __attribute__ ((unused))
+#else
+#define _UNUSED
+#endif
+
+enum {
+ kInterfaceVersion = 1 // Must match version in .jar file
+};
+
+typedef struct OpContext OpContext;
+
+struct OpContext
+{
+ DNSServiceRef ServiceRef;
+ JNIEnv *Env;
+ jobject JavaObj;
+ jobject ClientObj;
+ jmethodID Callback;
+ jmethodID Callback2;
+};
+
+// For AUTO_CALLBACKS, we must attach the callback thread to the Java VM prior to upcall.
+#if AUTO_CALLBACKS
+JavaVM *gJavaVM = NULL;
+#endif
+
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_InitLibrary( JNIEnv *pEnv, jclass cls,
+ jint callerVersion)
+{
+ /* Ensure that caller & interface versions match. */
+ if ( callerVersion != kInterfaceVersion)
+ return kDNSServiceErr_Incompatible;
+
+#if AUTO_CALLBACKS
+ {
+ jsize numVMs;
+
+ if ( 0 != JNI_GetCreatedJavaVMs( &gJavaVM, 1, &numVMs))
+ return kDNSServiceErr_BadState;
+ }
+#endif
+
+ // Set AppleDNSSD.hasAutoCallbacks
+ {
+#if AUTO_CALLBACKS
+ jboolean hasAutoC = JNI_TRUE;
+#else
+ jboolean hasAutoC = JNI_FALSE;
+#endif
+ jfieldID hasAutoCField = (*pEnv)->GetStaticFieldID( pEnv, cls, "hasAutoCallbacks", "Z");
+ (*pEnv)->SetStaticBooleanField( pEnv, cls, hasAutoCField, hasAutoC);
+ }
+
+ return kDNSServiceErr_NoError;
+}
+
+
+static const char* SafeGetUTFChars( JNIEnv *pEnv, jstring str)
+// Wrapper for JNI GetStringUTFChars() that returns NULL for null str.
+{
+ return str != NULL ? (*pEnv)->GetStringUTFChars( pEnv, str, 0) : NULL;
+}
+
+static void SafeReleaseUTFChars( JNIEnv *pEnv, jstring str, const char *buff)
+// Wrapper for JNI GetStringUTFChars() that handles null str.
+{
+ if ( str != NULL)
+ (*pEnv)->ReleaseStringUTFChars( pEnv, str, buff);
+}
+
+
+#if AUTO_CALLBACKS
+static void SetupCallbackState( JNIEnv **ppEnv)
+{
+ (*gJavaVM)->AttachCurrentThread( gJavaVM, (void**) ppEnv, NULL);
+}
+
+static void TeardownCallbackState( void )
+{
+ (*gJavaVM)->DetachCurrentThread( gJavaVM);
+}
+
+#else // AUTO_CALLBACKS
+
+static void SetupCallbackState( JNIEnv **ppEnv _UNUSED)
+{
+ // No setup necessary if ProcessResults() has been called
+}
+
+static void TeardownCallbackState( void )
+{
+ // No teardown necessary if ProcessResults() has been called
+}
+#endif // AUTO_CALLBACKS
+
+
+static OpContext *NewContext( JNIEnv *pEnv, jobject owner, const char *ownerClass,
+ const char *callbackName, const char *callbackSig)
+// Create and initialize a new OpContext.
+{
+ OpContext *pContext = (OpContext*) malloc( sizeof *pContext);
+
+ if ( pContext != NULL)
+ {
+ jfieldID clientField = (*pEnv)->GetFieldID( pEnv, (*pEnv)->GetObjectClass( pEnv, owner),
+ "fClient", ownerClass);
+
+ pContext->JavaObj = (*pEnv)->NewWeakGlobalRef( pEnv, owner); // must convert local ref to global to cache;
+ pContext->ClientObj = (*pEnv)->GetObjectField( pEnv, owner, clientField);
+ pContext->ClientObj = (*pEnv)->NewWeakGlobalRef( pEnv, pContext->ClientObj); // must convert local ref to global to cache
+ pContext->Callback = (*pEnv)->GetMethodID( pEnv,
+ (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
+ callbackName, callbackSig);
+ pContext->Callback2 = NULL; // not always used
+ }
+
+ return pContext;
+}
+
+
+static void ReportError( JNIEnv *pEnv, jobject target, jobject service, DNSServiceErrorType err)
+// Invoke operationFailed() method on target with err.
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, target);
+ jmethodID opFailed = (*pEnv)->GetMethodID( pEnv, cls, "operationFailed",
+ "(Lcom/apple/dnssd/DNSSDService;I)V");
+
+ (*pEnv)->CallVoidMethod( pEnv, target, opFailed, service, err);
+}
+
+JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_HaltOperation( JNIEnv *pEnv, jobject pThis)
+/* Deallocate the dns_sd service browser and set the Java object's fNativeContext field to 0. */
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+
+ if ( contextField != 0)
+ {
+ OpContext *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ if ( pContext != NULL)
+ {
+ (*pEnv)->SetIntField( pEnv, pThis, contextField, 0);
+ if ( pContext->ServiceRef != NULL)
+ DNSServiceRefDeallocate( pContext->ServiceRef);
+
+ (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->JavaObj);
+ (*pEnv)->DeleteWeakGlobalRef( pEnv, pContext->ClientObj);
+ free( pContext);
+ }
+ }
+}
+
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleService_BlockForData( JNIEnv *pEnv, jobject pThis, jint msTimeout)
+/* Block for timeout ms (or forever if -1). Returns 1 if data present, 0 if timed out, -1 if not browsing. */
+{
+#if AUTO_CALLBACKS
+ return -1; // BlockForData() not supported with AUTO_CALLBACKS
+#else // AUTO_CALLBACKS
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jint rc = -1;
+
+ if ( contextField != 0)
+ {
+ OpContext *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ if ( pContext != NULL)
+ {
+ fd_set readFDs;
+ int sd = DNSServiceRefSockFD( pContext->ServiceRef);
+ struct timeval timeout = { msTimeout / 1000, 10 * (msTimeout % 1000) };
+ struct timeval *pTimeout = msTimeout == -1 ? NULL : &timeout;
+
+ FD_ZERO( &readFDs);
+ FD_SET( sd, &readFDs);
+
+ rc = select( sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, pTimeout);
+ }
+ }
+
+ return rc;
+#endif // AUTO_CALLBACKS
+}
+
+
+JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleService_ProcessResults( JNIEnv *pEnv, jobject pThis)
+/* Call through to DNSServiceProcessResult() while data remains on socket. */
+{
+#if !AUTO_CALLBACKS // ProcessResults() not supported with AUTO_CALLBACKS
+
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ OpContext *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+
+ if ( pContext != NULL)
+ {
+ int sd = DNSServiceRefSockFD( pContext->ServiceRef);
+ fd_set readFDs;
+ struct timeval zeroTimeout = { 0, 0 };
+
+ pContext->Env = pEnv;
+
+ FD_ZERO( &readFDs);
+ FD_SET( sd, &readFDs);
+
+ while ( 0 < select( sd + 1, &readFDs, (fd_set*) NULL, (fd_set*) NULL, &zeroTimeout))
+ {
+ DNSServiceProcessResult( pContext->ServiceRef);
+ }
+ }
+#endif // AUTO_CALLBACKS
+}
+
+
+static void DNSSD_API ServiceBrowseReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode, const char *serviceName, const char *regtype,
+ const char *replyDomain, void *context)
+{
+ OpContext *pContext = (OpContext*) context;
+
+ SetupCallbackState( &pContext->Env);
+
+ if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
+ {
+ if ( errorCode == kDNSServiceErr_NoError)
+ {
+ (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
+ ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
+ pContext->JavaObj, flags, interfaceIndex,
+ (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
+ (*pContext->Env)->NewStringUTF( pContext->Env, regtype),
+ (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
+ }
+ else
+ ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
+ }
+
+ TeardownCallbackState();
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleBrowser_CreateBrowser( JNIEnv *pEnv, jobject pThis,
+ jint flags, jint ifIndex, jstring regType, jstring domain)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+
+ if ( contextField != 0)
+ pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/BrowseListener;", "serviceFound",
+ "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ else
+ err = kDNSServiceErr_BadParam;
+
+ if ( pContext != NULL)
+ {
+ const char *regStr = SafeGetUTFChars( pEnv, regType);
+ const char *domainStr = SafeGetUTFChars( pEnv, domain);
+
+ pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
+ (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
+ "serviceLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+
+ err = DNSServiceBrowse( &pContext->ServiceRef, flags, ifIndex, regStr, domainStr, ServiceBrowseReply, pContext);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ }
+
+ SafeReleaseUTFChars( pEnv, regType, regStr);
+ SafeReleaseUTFChars( pEnv, domain, domainStr);
+ }
+ else
+ err = kDNSServiceErr_NoMemory;
+
+ return err;
+}
+
+
+static void DNSSD_API ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget,
+ uint16_t port, uint16_t txtLen, const char *txtRecord, void *context)
+{
+ OpContext *pContext = (OpContext*) context;
+ jclass txtCls;
+ jmethodID txtCtor;
+ jbyteArray txtBytes;
+ jobject txtObj;
+ jbyte *pBytes;
+
+ SetupCallbackState( &pContext->Env);
+
+ txtCls = (*pContext->Env)->FindClass( pContext->Env, "com/apple/dnssd/TXTRecord");
+ txtCtor = (*pContext->Env)->GetMethodID( pContext->Env, txtCls, "<init>", "([B)V");
+
+ if ( pContext->ClientObj != NULL && pContext->Callback != NULL && txtCtor != NULL &&
+ NULL != ( txtBytes = (*pContext->Env)->NewByteArray( pContext->Env, txtLen)))
+ {
+ if ( errorCode == kDNSServiceErr_NoError)
+ {
+ // Since Java ints are defined to be big-endian, we canonicalize 'port' from a 16-bit
+ // pattern into a number here.
+ port = ( ((unsigned char*) &port)[0] << 8) | ((unsigned char*) &port)[1];
+
+ // Initialize txtBytes with contents of txtRecord
+ pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, txtBytes, NULL);
+ memcpy( pBytes, txtRecord, txtLen);
+ (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, txtBytes, pBytes, JNI_COMMIT);
+
+ // Construct txtObj with txtBytes
+ txtObj = (*pContext->Env)->NewObject( pContext->Env, txtCls, txtCtor, txtBytes);
+ (*pContext->Env)->DeleteLocalRef( pContext->Env, txtBytes);
+
+ (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+ pContext->JavaObj, flags, interfaceIndex,
+ (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
+ (*pContext->Env)->NewStringUTF( pContext->Env, hosttarget),
+ port, txtObj);
+ }
+ else
+ ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
+ }
+
+ TeardownCallbackState();
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleResolver_CreateResolver( JNIEnv *pEnv, jobject pThis,
+ jint flags, jint ifIndex, jstring serviceName, jstring regType, jstring domain)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+
+ if ( contextField != 0)
+ pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/ResolveListener;", "serviceResolved",
+ "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;Ljava/lang/String;ILcom/apple/dnssd/TXTRecord;)V");
+ else
+ err = kDNSServiceErr_BadParam;
+
+ if ( pContext != NULL)
+ {
+ const char *servStr = SafeGetUTFChars( pEnv, serviceName);
+ const char *regStr = SafeGetUTFChars( pEnv, regType);
+ const char *domainStr = SafeGetUTFChars( pEnv, domain);
+
+ err = DNSServiceResolve( &pContext->ServiceRef, flags, ifIndex,
+ servStr, regStr, domainStr, ServiceResolveReply, pContext);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ }
+
+ SafeReleaseUTFChars( pEnv, serviceName, servStr);
+ SafeReleaseUTFChars( pEnv, regType, regStr);
+ SafeReleaseUTFChars( pEnv, domain, domainStr);
+ }
+ else
+ err = kDNSServiceErr_NoMemory;
+
+ return err;
+}
+
+
+static void DNSSD_API ServiceRegisterReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags,
+ DNSServiceErrorType errorCode, const char *fullname,
+ const char *regType, const char *domain, void *context)
+{
+ OpContext *pContext = (OpContext*) context;
+
+ SetupCallbackState( &pContext->Env);
+
+ if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
+ {
+ if ( errorCode == kDNSServiceErr_NoError)
+ {
+ (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+ pContext->JavaObj, flags,
+ (*pContext->Env)->NewStringUTF( pContext->Env, fullname),
+ (*pContext->Env)->NewStringUTF( pContext->Env, regType),
+ (*pContext->Env)->NewStringUTF( pContext->Env, domain));
+ }
+ else
+ ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
+ }
+ TeardownCallbackState();
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_BeginRegister( JNIEnv *pEnv, jobject pThis,
+ jint ifIndex, jint flags, jstring serviceName, jstring regType,
+ jstring domain, jstring host, jint port, jbyteArray txtRecord)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+ jbyte *pBytes;
+ jsize numBytes;
+
+ if ( contextField != 0)
+ pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/RegisterListener;", "serviceRegistered",
+ "(Lcom/apple/dnssd/DNSSDRegistration;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+ else
+ err = kDNSServiceErr_BadParam;
+
+ if ( pContext != NULL)
+ {
+ const char *servStr = SafeGetUTFChars( pEnv, serviceName);
+ const char *regStr = SafeGetUTFChars( pEnv, regType);
+ const char *domainStr = SafeGetUTFChars( pEnv, domain);
+ const char *hostStr = SafeGetUTFChars( pEnv, host);
+
+ // Since Java ints are defined to be big-endian, we de-canonicalize 'port' from a
+ // big-endian number into a 16-bit pattern here.
+ uint16_t portBits = port;
+ portBits = ( ((unsigned char*) &portBits)[0] << 8) | ((unsigned char*) &portBits)[1];
+
+ pBytes = txtRecord ? (*pEnv)->GetByteArrayElements( pEnv, txtRecord, NULL) : NULL;
+ numBytes = txtRecord ? (*pEnv)->GetArrayLength( pEnv, txtRecord) : 0;
+
+ err = DNSServiceRegister( &pContext->ServiceRef, flags, ifIndex, servStr, regStr,
+ domainStr, hostStr, portBits,
+ numBytes, pBytes, ServiceRegisterReply, pContext);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ }
+
+ if ( pBytes != NULL)
+ (*pEnv)->ReleaseByteArrayElements( pEnv, txtRecord, pBytes, 0);
+
+ SafeReleaseUTFChars( pEnv, serviceName, servStr);
+ SafeReleaseUTFChars( pEnv, regType, regStr);
+ SafeReleaseUTFChars( pEnv, domain, domainStr);
+ SafeReleaseUTFChars( pEnv, host, hostStr);
+ }
+ else
+ err = kDNSServiceErr_NoMemory;
+
+ return err;
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRegistration_AddRecord( JNIEnv *pEnv, jobject pThis,
+ jint flags, jint rrType, jbyteArray rData, jint ttl, jobject destObj)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+ jbyte *pBytes;
+ jsize numBytes;
+ DNSRecordRef recRef;
+
+ if ( contextField != 0)
+ pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ if ( pContext == NULL || pContext->ServiceRef == NULL)
+ return kDNSServiceErr_BadParam;
+
+ pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
+ numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
+
+ err = DNSServiceAddRecord( pContext->ServiceRef, &recRef, flags, rrType, numBytes, pBytes, ttl);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetIntField( pEnv, destObj, recField, (jint) recRef);
+ }
+
+ if ( pBytes != NULL)
+ (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
+
+ return err;
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Update( JNIEnv *pEnv, jobject pThis,
+ jint flags, jbyteArray rData, jint ttl)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+ jbyte *pBytes;
+ jsize numBytes;
+ DNSRecordRef recRef = NULL;
+
+ if ( ownerField != 0)
+ {
+ jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
+ jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "I");
+ if ( contextField != 0)
+ pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, ownerObj, contextField);
+ }
+ if ( recField != 0)
+ recRef = (DNSRecordRef) (*pEnv)->GetIntField( pEnv, pThis, recField);
+ if ( pContext == NULL || pContext->ServiceRef == NULL)
+ return kDNSServiceErr_BadParam;
+
+ pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
+ numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
+
+ err = DNSServiceUpdateRecord( pContext->ServiceRef, recRef, flags, numBytes, pBytes, ttl);
+
+ if ( pBytes != NULL)
+ (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
+
+ return err;
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSRecord_Remove( JNIEnv *pEnv, jobject pThis)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+ DNSRecordRef recRef = NULL;
+
+ if ( ownerField != 0)
+ {
+ jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
+ jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "I");
+ if ( contextField != 0)
+ pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, ownerObj, contextField);
+ }
+ if ( recField != 0)
+ recRef = (DNSRecordRef) (*pEnv)->GetIntField( pEnv, pThis, recField);
+ if ( pContext == NULL || pContext->ServiceRef == NULL)
+ return kDNSServiceErr_BadParam;
+
+ err = DNSServiceRemoveRecord( pContext->ServiceRef, recRef, 0);
+
+ return err;
+}
+
+
+static void DNSSD_API ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode, const char *serviceName,
+ uint16_t rrtype, uint16_t rrclass, uint16_t rdlen,
+ const void *rdata, uint32_t ttl, void *context)
+{
+ OpContext *pContext = (OpContext*) context;
+ jbyteArray rDataObj;
+ jbyte *pBytes;
+
+ SetupCallbackState( &pContext->Env);
+
+ if ( pContext->ClientObj != NULL && pContext->Callback != NULL &&
+ NULL != ( rDataObj = (*pContext->Env)->NewByteArray( pContext->Env, rdlen)))
+ {
+ if ( errorCode == kDNSServiceErr_NoError)
+ {
+ // Initialize rDataObj with contents of rdata
+ pBytes = (*pContext->Env)->GetByteArrayElements( pContext->Env, rDataObj, NULL);
+ memcpy( pBytes, rdata, rdlen);
+ (*pContext->Env)->ReleaseByteArrayElements( pContext->Env, rDataObj, pBytes, JNI_COMMIT);
+
+ (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+ pContext->JavaObj, flags, interfaceIndex,
+ (*pContext->Env)->NewStringUTF( pContext->Env, serviceName),
+ rrtype, rrclass, rDataObj, ttl);
+ }
+ else
+ ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
+ }
+ TeardownCallbackState();
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleQuery_CreateQuery( JNIEnv *pEnv, jobject pThis,
+ jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+
+ if ( contextField != 0)
+ pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/QueryListener;", "queryAnswered",
+ "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;II[BI)V");
+ else
+ err = kDNSServiceErr_BadParam;
+
+ if ( pContext != NULL)
+ {
+ const char *servStr = SafeGetUTFChars( pEnv, serviceName);
+
+ err = DNSServiceQueryRecord( &pContext->ServiceRef, flags, ifIndex, servStr,
+ rrtype, rrclass, ServiceQueryReply, pContext);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ }
+
+ SafeReleaseUTFChars( pEnv, serviceName, servStr);
+ }
+ else
+ err = kDNSServiceErr_NoMemory;
+
+ return err;
+}
+
+
+static void DNSSD_API DomainEnumReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
+ DNSServiceErrorType errorCode, const char *replyDomain, void *context)
+{
+ OpContext *pContext = (OpContext*) context;
+
+ SetupCallbackState( &pContext->Env);
+
+ if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
+ {
+ if ( errorCode == kDNSServiceErr_NoError)
+ {
+ (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj,
+ ( flags & kDNSServiceFlagsAdd) != 0 ? pContext->Callback : pContext->Callback2,
+ pContext->JavaObj, flags, interfaceIndex,
+ (*pContext->Env)->NewStringUTF( pContext->Env, replyDomain));
+ }
+ else
+ ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
+ }
+ TeardownCallbackState();
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDomainEnum_BeginEnum( JNIEnv *pEnv, jobject pThis,
+ jint flags, jint ifIndex)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+
+ if ( contextField != 0)
+ pContext = NewContext( pEnv, pThis, "Lcom/apple/dnssd/DomainListener;", "domainFound",
+ "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
+ else
+ err = kDNSServiceErr_BadParam;
+
+ if ( pContext != NULL)
+ {
+ pContext->Callback2 = (*pEnv)->GetMethodID( pEnv,
+ (*pEnv)->GetObjectClass( pEnv, pContext->ClientObj),
+ "domainLost", "(Lcom/apple/dnssd/DNSSDService;IILjava/lang/String;)V");
+
+ err = DNSServiceEnumerateDomains( &pContext->ServiceRef, flags, ifIndex,
+ DomainEnumReply, pContext);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ }
+ }
+ else
+ err = kDNSServiceErr_NoMemory;
+
+ return err;
+}
+
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_ConstructName( JNIEnv *pEnv, jobject pThis _UNUSED,
+ jstring serviceName, jstring regtype, jstring domain, jobjectArray pOut)
+{
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+ const char *nameStr = SafeGetUTFChars( pEnv, serviceName);
+ const char *regStr = SafeGetUTFChars( pEnv, regtype);
+ const char *domStr = SafeGetUTFChars( pEnv, domain);
+ char buff[ kDNSServiceMaxDomainName + 1];
+
+ err = DNSServiceConstructFullName( buff, nameStr, regStr, domStr);
+
+ if ( err == kDNSServiceErr_NoError)
+ {
+ // pOut is expected to be a String[1] array.
+ (*pEnv)->SetObjectArrayElement( pEnv, pOut, 0, (*pEnv)->NewStringUTF( pEnv, buff));
+ }
+
+ SafeReleaseUTFChars( pEnv, serviceName, nameStr);
+ SafeReleaseUTFChars( pEnv, regtype, regStr);
+ SafeReleaseUTFChars( pEnv, domain, domStr);
+
+ return err;
+}
+
+JNIEXPORT void JNICALL Java_com_apple_dnssd_AppleDNSSD_ReconfirmRecord( JNIEnv *pEnv, jobject pThis _UNUSED,
+ jint flags, jint ifIndex, jstring fullName,
+ jint rrtype, jint rrclass, jbyteArray rdata)
+{
+ jbyte *pBytes;
+ jsize numBytes;
+ const char *nameStr = SafeGetUTFChars( pEnv, fullName);
+
+ pBytes = (*pEnv)->GetByteArrayElements( pEnv, rdata, NULL);
+ numBytes = (*pEnv)->GetArrayLength( pEnv, rdata);
+
+ DNSServiceReconfirmRecord( flags, ifIndex, nameStr, rrtype, rrclass, numBytes, pBytes);
+
+ if ( pBytes != NULL)
+ (*pEnv)->ReleaseByteArrayElements( pEnv, rdata, pBytes, 0);
+
+ SafeReleaseUTFChars( pEnv, fullName, nameStr);
+}
+
+#define LOCAL_ONLY_NAME "loo"
+
+JNIEXPORT jstring JNICALL Java_com_apple_dnssd_AppleDNSSD_GetNameForIfIndex( JNIEnv *pEnv, jobject pThis _UNUSED,
+ jint ifIndex)
+{
+ char *p = LOCAL_ONLY_NAME, nameBuff[IF_NAMESIZE];
+
+ if (ifIndex != kDNSServiceInterfaceIndexLocalOnly)
+ p = if_indextoname( ifIndex, nameBuff );
+
+ return (*pEnv)->NewStringUTF( pEnv, p);
+}
+
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleDNSSD_GetIfIndexForName( JNIEnv *pEnv, jobject pThis _UNUSED,
+ jstring ifName)
+{
+ uint32_t ifIndex = kDNSServiceInterfaceIndexLocalOnly;
+ const char *nameStr = SafeGetUTFChars( pEnv, ifName);
+
+ if (strcmp(nameStr, LOCAL_ONLY_NAME))
+ ifIndex = if_nametoindex( nameStr);
+
+ SafeReleaseUTFChars( pEnv, ifName, nameStr);
+
+ return ifIndex;
+}
+
+
+#if defined(_WIN32)
+static char*
+if_indextoname( DWORD ifIndex, char * nameBuff)
+{
+ PIP_ADAPTER_INFO pAdapterInfo = NULL;
+ PIP_ADAPTER_INFO pAdapter = NULL;
+ DWORD dwRetVal = 0;
+ char * ifName = NULL;
+ ULONG ulOutBufLen = 0;
+
+ if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
+ {
+ goto exit;
+ }
+
+ pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
+
+ if (pAdapterInfo == NULL)
+ {
+ goto exit;
+ }
+
+ dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
+
+ if (dwRetVal != NO_ERROR)
+ {
+ goto exit;
+ }
+
+ pAdapter = pAdapterInfo;
+ while (pAdapter)
+ {
+ if (pAdapter->Index == ifIndex)
+ {
+ // It would be better if we passed in the length of nameBuff to this
+ // function, so we would have absolute certainty that no buffer
+ // overflows would occur. Buffer overflows *shouldn't* occur because
+ // nameBuff is of size MAX_ADAPTER_NAME_LENGTH.
+ strcpy( nameBuff, pAdapter->AdapterName );
+ ifName = nameBuff;
+ break;
+ }
+
+ pAdapter = pAdapter->Next;
+ }
+
+exit:
+
+ if (pAdapterInfo != NULL)
+ {
+ free( pAdapterInfo );
+ pAdapterInfo = NULL;
+ }
+
+ return ifName;
+}
+
+
+static DWORD
+if_nametoindex( const char * nameStr )
+{
+ PIP_ADAPTER_INFO pAdapterInfo = NULL;
+ PIP_ADAPTER_INFO pAdapter = NULL;
+ DWORD dwRetVal = 0;
+ DWORD ifIndex = 0;
+ ULONG ulOutBufLen = 0;
+
+ if (GetAdaptersInfo( NULL, &ulOutBufLen) != ERROR_BUFFER_OVERFLOW)
+ {
+ goto exit;
+ }
+
+ pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
+
+ if (pAdapterInfo == NULL)
+ {
+ goto exit;
+ }
+
+ dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen );
+
+ if (dwRetVal != NO_ERROR)
+ {
+ goto exit;
+ }
+
+ pAdapter = pAdapterInfo;
+ while (pAdapter)
+ {
+ if (strcmp(pAdapter->AdapterName, nameStr) == 0)
+ {
+ ifIndex = pAdapter->Index;
+ break;
+ }
+
+ pAdapter = pAdapter->Next;
+ }
+
+exit:
+
+ if (pAdapterInfo != NULL)
+ {
+ free( pAdapterInfo );
+ pAdapterInfo = NULL;
+ }
+
+ return ifIndex;
+}
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: QueryListener.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+ */
+
+
+package com.apple.dnssd;
+
+
+/** A listener that receives results from {@link DNSSD#queryRecord}. */
+
+public interface QueryListener extends BaseListener
+{
+ /** Called when a record query has been completed.<P>
+
+ @param query
+ The active query object.
+ <P>
+ @param flags
+ Possible values are DNSSD.MORE_COMING.
+ <P>
+ @param ifIndex
+ The interface on which the query was resolved. (The index for a given
+ interface is determined via the if_nametoindex() family of calls.)
+ <P>
+ @param fullName
+ The resource record's full domain name.
+ <P>
+ @param rrtype
+ The resource record's type (e.g. PTR, SRV, etc) as defined by RFC 1035 and its updates.
+ <P>
+ @param rrclass
+ The class of the resource record, as defined by RFC 1035 and its updates.
+ <P>
+ @param rdata
+ The raw rdata of the resource record.
+ <P>
+ @param ttl
+ The resource record's time to live, in seconds.
+ */
+ void queryAnswered( DNSSDService query, int flags, int ifIndex, String fullName,
+ int rrtype, int rrclass, byte[] rdata, int ttl);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: RegisterListener.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+ */
+
+
+package com.apple.dnssd;
+
+
+/** A listener that receives results from {@link DNSSD#register}. */
+
+public interface RegisterListener extends BaseListener
+{
+ /** Called when a registration has been completed.<P>
+
+ @param registration
+ The active registration.
+ <P>
+ @param flags
+ Currently unused, reserved for future use.
+ <P>
+ @param serviceName
+ The service name registered (if the application did not specify a name in
+ DNSSD.register(), this indicates what name was automatically chosen).
+ <P>
+ @param regType
+ The type of service registered, as it was passed to DNSSD.register().
+ <P>
+ @param domain
+ The domain on which the service was registered. If the application did not
+ specify a domain in DNSSD.register(), this is the default domain
+ on which the service was registered.
+ */
+ void serviceRegistered( DNSSDRegistration registration, int flags, String serviceName,
+ String regType, String domain);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: ResolveListener.java,v $
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+*/
+
+
+package com.apple.dnssd;
+
+
+/** A listener that receives results from {@link DNSSD#resolve}. */
+
+public interface ResolveListener extends BaseListener
+{
+ /** Called when a service has been resolved.<P>
+
+ @param resolver
+ The active resolver object.
+ <P>
+ @param flags
+ Currently unused, reserved for future use.
+ <P>
+ @param fullName
+ The full service domain name, in the form <servicename>.<protocol>.<domain>.
+ (Any literal dots (".") are escaped with a backslash ("\."), and literal
+ backslashes are escaped with a second backslash ("\\"), e.g. a web server
+ named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.").
+ This is the appropriate format to pass to standard system DNS APIs such as
+ res_query(), or to the special-purpose functions included in this API that
+ take fullname parameters.
+ <P>
+ @param hostName
+ The target hostname of the machine providing the service. This name can
+ be passed to functions like queryRecord() to look up the host's IP address.
+ <P>
+ @param port
+ The port number on which connections are accepted for this service.
+ <P>
+ @param txtRecord
+ The service's primary txt record.
+ */
+ void serviceResolved( DNSSDService resolver, int flags, int ifIndex, String fullName,
+ String hostName, int port, TXTRecord txtRecord);
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: TXTRecord.java,v $
+Revision 1.5 2004/08/25 21:54:36 rpantos
+<rdar://problem/3773973> Fix getValue() for values containing '='.
+
+Revision 1.4 2004/08/04 01:04:50 rpantos
+<rdar://problems/3731579&3731582> Fix set(); add remove() & toString().
+
+Revision 1.3 2004/07/13 21:24:25 rpantos
+Fix for <rdar://problem/3701120>.
+
+Revision 1.2 2004/04/30 21:48:27 rpantos
+Change line endings for CVS.
+
+Revision 1.1 2004/04/30 16:29:35 rpantos
+First checked in.
+
+ To do:
+ - implement remove()
+ - fix set() to replace existing values
+ */
+
+
+package com.apple.dnssd;
+
+
+/**
+ Object used to construct and parse DNS-SD format TXT records.
+ For more info see <a href="http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt">DNS-Based Service Discovery</a>, section 6.
+*/
+
+public class TXTRecord
+{
+ /*
+ DNS-SD specifies that a TXT record corresponding to an SRV record consist of
+ a packed array of bytes, each preceded by a length byte. Each string
+ is an attribute-value pair.
+
+ The TXTRecord object stores the entire TXT data as a single byte array, traversing it
+ as need be to implement its various methods.
+ */
+
+ static final protected byte kAttrSep = '=';
+
+ protected byte[] fBytes;
+
+ /** Constructs a new, empty TXT record. */
+ public TXTRecord()
+ { fBytes = new byte[0]; }
+
+ /** Constructs a new TXT record from a byte array in the standard format. */
+ public TXTRecord( byte[] initBytes)
+ { fBytes = (byte[]) initBytes.clone(); }
+
+ /** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
+ @param key
+ The key name. Must be ASCII, with no '=' characters.
+ <P>
+ @param value
+ Value to be encoded into bytes using the default platform character set.
+ */
+ public void set( String key, String value)
+ {
+ byte[] valBytes = (value != null) ? value.getBytes() : null;
+ this.set( key, valBytes);
+ }
+
+ /** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
+ @param key
+ The key name. Must be ASCII, with no '=' characters.
+ <P>
+ @param value
+ Binary representation of the value.
+ */
+ public void set( String key, byte[] value)
+ {
+ byte[] keyBytes;
+ int valLen = (value != null) ? value.length : 0;
+
+ try {
+ keyBytes = key.getBytes( "US-ASCII");
+ }
+ catch ( java.io.UnsupportedEncodingException uee) {
+ throw new IllegalArgumentException();
+ }
+
+ for ( int i=0; i < keyBytes.length; i++)
+ if ( keyBytes[i] == '=')
+ throw new IllegalArgumentException();
+
+ if ( keyBytes.length + valLen >= 255)
+ throw new ArrayIndexOutOfBoundsException();
+
+ int prevLoc = this.remove( key);
+ if ( prevLoc == -1)
+ prevLoc = this.size();
+
+ this.insert( keyBytes, value, prevLoc);
+ }
+
+ protected void insert( byte[] keyBytes, byte[] value, int index)
+ // Insert a key-value pair at index
+ {
+ byte[] oldBytes = fBytes;
+ int valLen = (value != null) ? value.length : 0;
+ int insertion = 0;
+ byte newLen, avLen;
+
+ // locate the insertion point
+ for ( int i=0; i < index && insertion < fBytes.length; i++)
+ insertion += fBytes[ insertion] + 1;
+
+ avLen = (byte) ( keyBytes.length + valLen + (value != null ? 1 : 0));
+ newLen = (byte) ( avLen + oldBytes.length + 1);
+
+ fBytes = new byte[ newLen];
+ System.arraycopy( oldBytes, 0, fBytes, 0, insertion);
+ int secondHalfLen = oldBytes.length - insertion;
+ System.arraycopy( oldBytes, insertion, fBytes, newLen - secondHalfLen, secondHalfLen);
+ fBytes[ insertion] = avLen;
+ System.arraycopy( keyBytes, 0, fBytes, insertion + 1, keyBytes.length);
+ if ( value != null)
+ {
+ fBytes[ insertion + 1 + keyBytes.length] = kAttrSep;
+ System.arraycopy( value, 0, fBytes, insertion + keyBytes.length + 2, valLen);
+ }
+ }
+
+ /** Remove a key/value pair from the TXT record. Returns index it was at, or -1 if not found. */
+ public int remove( String key)
+ {
+ int avStart = 0;
+
+ for ( int i=0; avStart < fBytes.length; i++)
+ {
+ int avLen = fBytes[ avStart];
+ if ( key.length() <= avLen &&
+ ( key.length() == avLen || fBytes[ avStart + key.length() + 1] == kAttrSep))
+ {
+ String s = new String( fBytes, avStart + 1, key.length());
+ if ( 0 == key.compareToIgnoreCase( s))
+ {
+ byte[] oldBytes = fBytes;
+ fBytes = new byte[ oldBytes.length - avLen - 1];
+ System.arraycopy( oldBytes, 0, fBytes, 0, avStart);
+ System.arraycopy( oldBytes, avStart + avLen + 1, fBytes, avStart, oldBytes.length - avStart - avLen - 1);
+ return i;
+ }
+ }
+ avStart += avLen + 1;
+ }
+ return -1;
+ }
+
+ /** Return the number of keys in the TXT record. */
+ public int size()
+ {
+ int i, avStart;
+
+ for ( i=0, avStart=0; avStart < fBytes.length; i++)
+ avStart += fBytes[ avStart] + 1;
+ return i;
+ }
+
+ /** Return true if key is present in the TXT record, false if not. */
+ public boolean contains( String key)
+ {
+ String s = null;
+
+ for ( int i=0; null != ( s = this.getKey( i)); i++)
+ if ( 0 == key.compareToIgnoreCase( s))
+ return true;
+ return false;
+ }
+
+ /** Return a key in the TXT record by zero-based index. Returns null if index exceeds the total number of keys. */
+ public String getKey( int index)
+ {
+ int avStart = 0;
+
+ for ( int i=0; i < index && avStart < fBytes.length; i++)
+ avStart += fBytes[ avStart] + 1;
+
+ if ( avStart < fBytes.length)
+ {
+ int avLen = fBytes[ avStart];
+ int aLen = 0;
+
+ for ( aLen=0; aLen < avLen; aLen++)
+ if ( fBytes[ avStart + aLen + 1] == kAttrSep)
+ break;
+ return new String( fBytes, avStart + 1, aLen);
+ }
+ return null;
+ }
+
+ /**
+ Look up a key in the TXT record by zero-based index and return its value. <P>
+ Returns null if index exceeds the total number of keys.
+ Returns null if the key is present with no value.
+ */
+ public byte[] getValue( int index)
+ {
+ int avStart = 0;
+ byte[] value = null;
+
+ for ( int i=0; i < index && avStart < fBytes.length; i++)
+ avStart += fBytes[ avStart] + 1;
+
+ if ( avStart < fBytes.length)
+ {
+ int avLen = fBytes[ avStart];
+ int aLen = 0;
+
+ for ( aLen=0; aLen < avLen; aLen++)
+ {
+ if ( fBytes[ avStart + aLen + 1] == kAttrSep)
+ {
+ value = new byte[ avLen - aLen - 1];
+ System.arraycopy( fBytes, avStart + aLen + 2, value, 0, avLen - aLen - 1);
+ break;
+ }
+ }
+ }
+ return value;
+ }
+
+ /** Converts the result of getValue() to a string in the platform default character set. */
+ public String getValueAsString( int index)
+ {
+ byte[] value = this.getValue( index);
+ return value != null ? new String( value) : null;
+ }
+
+ /** Get the value associated with a key. Will be null if the key is not defined.
+ Array will have length 0 if the key is defined with an = but no value.<P>
+
+ @param forKey
+ The left-hand side of the key-value pair.
+ <P>
+ @return The binary representation of the value.
+ */
+ public byte[] getValue( String forKey)
+ {
+ String s = null;
+ int i;
+
+ for ( i=0; null != ( s = this.getKey( i)); i++)
+ if ( 0 == forKey.compareToIgnoreCase( s))
+ return this.getValue( i);
+ return null;
+ }
+
+ /** Converts the result of getValue() to a string in the platform default character set.<P>
+
+ @param forKey
+ The left-hand side of the key-value pair.
+ <P>
+ @return The value represented in the default platform character set.
+ */
+ public String getValueAsString( String forKey)
+ {
+ byte[] val = this.getValue( forKey);
+ return val != null ? new String( val) : null;
+ }
+
+ /** Return the contents of the TXT record as raw bytes. */
+ public byte[] getRawBytes() { return (byte[]) fBytes.clone(); }
+
+ /** Return a string representation of the object. */
+ public String toString()
+ {
+ String a, result = null;
+
+ for ( int i=0; null != ( a = this.getKey( i)); i++)
+ {
+ String av = String.valueOf( i) + "={" + a;
+ String val = this.getValueAsString( i);
+ if ( val != null)
+ av += "=" + val + "}";
+ else
+ av += "}";
+ if ( result == null)
+ result = av;
+ else
+ result = result + ", " + av;
+ }
+ return result != null ? result : "";
+ }
+}
+
/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: dns_sd.h,v $
-Revision 1.3 2003/08/12 19:51:51 cheshire
-Update to APSL 2.0
-
-
+ * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DNS_SD_H
#define _DNS_SD_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* standard calling convention under Win32 is __stdcall */
+#if defined(_WIN32)
+#define DNSSD_API __stdcall
+#else
+#define DNSSD_API
+#endif
+
+#if defined(__FreeBSD_version) && (__FreeBSD_version < 500000)
+/* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
#include <sys/types.h>
-#include <sys/socket.h>
+#elif defined(__sun__)
+#include <sys/types.h>
+#elif defined(_WIN32)
+#include <windows.h>
+#define _UNUSED
+#define bzero(a, b) memset(a, 0, b)
+typedef UINT8 uint8_t;
+typedef INT8 int8_t;
+typedef UINT16 uint16_t;
+typedef INT16 int16_t;
+typedef UINT32 uint32_t;
+typedef INT32 int32_t;
+#else
#include <stdint.h>
-#include <netinet/in.h>
-
+#endif
/* DNSServiceRef, DNSRecordRef
*
/* General flags used in functions defined below */
enum
{
- kDNSServiceFlagsMoreComing = 1,
- kDNSServiceFlagsFinished = 0, /* i.e. bit not set */
- /* MoreComing indicates to a Browse callback that another result is
- * queued. Applications should not update their UI to display browse
- * results when the MoreComing flag is set, instead deferring the update
- * until the callback's flag is Finished. */
-
- kDNSServiceFlagsAdd = 2,
- kDNSServiceFlagsDefault = 4,
- kDNSServiceFlagsRemove = 0, /* i.e. bit not set */
- /* Flags for domain enumeration and browse reply callbacks.
+ kDNSServiceFlagsMoreComing = 0x1,
+ /* MoreComing indicates to a callback that at least one more result is
+ * queued and will be delivered following immediately after this one.
+ * Applications should not update their UI to display browse
+ * results when the MoreComing flag is set, because this would
+ * result in a great deal of ugly flickering on the screen.
+ * Applications should instead wait until until MoreComing is not set,
+ * and then update their UI.
+ * When MoreComing is not set, that doesn't mean there will be no more
+ * answers EVER, just that there are no more answers immediately
+ * available right now at this instant. If more answers become available
+ * in the future they will be delivered as usual.
+ */
+
+ kDNSServiceFlagsAdd = 0x2,
+ kDNSServiceFlagsDefault = 0x4,
+ /* Flags for domain enumeration and browse/query reply callbacks.
* "Default" applies only to enumeration and is only valid in
- * conjuction with "Add"
+ * conjuction with "Add". An enumeration callback with the "Add"
+ * flag NOT set indicates a "Remove", i.e. the domain is no longer
+ * valid.
*/
- kDNSServiceFlagsNoAutoRename = 8,
- kDNSServiceFlagsAutoRename = 0, /* i.e. bit not set */
+ kDNSServiceFlagsNoAutoRename = 0x8,
/* Flag for specifying renaming behavior on name conflict when registering
- * non-shared records. NoAutorename is only valid if a name is explicitly
- * specified when registering a service (ie the default name is not used.)
+ * non-shared records. By default, name conflicts are automatically handled
+ * by renaming the service. NoAutoRename overrides this behavior - with this
+ * flag set, name conflicts will result in a callback. The NoAutorename flag
+ * is only valid if a name is explicitly specified when registering a service
+ * (i.e. the default name is not used.)
*/
-
- kDNSServiceFlagsShared = 16,
- kDNSServiceFlagsUnique = 32,
+ kDNSServiceFlagsShared = 0x10,
+ kDNSServiceFlagsUnique = 0x20,
/* Flag for registering individual records on a connected
- * DNSServiceRef. Shared indicates that there may be multiple records
+ * DNSServiceRef. Shared indicates that there may be multiple records
* with this name on the network (e.g. PTR records). Unique indicates that the
* record's name is to be unique on the network (e.g. SRV records).
*/
- kDNSServiceFlagsBrowseDomains = 64,
- kDNSServiceFlagsRegistrationDomains = 128
+ kDNSServiceFlagsBrowseDomains = 0x40,
+ kDNSServiceFlagsRegistrationDomains = 0x80,
/* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
* BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
* enumerates domains recommended for registration.
*/
+
+ kDNSServiceFlagsLongLivedQuery = 0x100,
+ /* Flag for creating a long-lived unicast query for the DNSServiceQueryRecord call. */
+
+ kDNSServiceFlagsAllowRemoteQuery = 0x200,
+ /* Flag for creating a record for which we will answer remote queries
+ * (queries from hosts more than one hop away; hosts not directly connected to the local link).
+ */
+
+ kDNSServiceFlagsForceMulticast = 0x400
+ /* Flag for signifying that a query or registration should be performed exclusively via multicast DNS,
+ * even for a name in a domain (e.g. foo.apple.com.) that would normally imply unicast DNS.
+ */
};
+/*
+ * The values for DNS Classes and Types are listed in RFC 1035, and are available
+ * on every OS in its DNS header file. Unfortunately every OS does not have the
+ * same header file containing DNS Class and Type constants, and the names of
+ * the constants are not consistent. For example, BIND 8 uses "T_A",
+ * BIND 9 uses "ns_t_a", Windows uses "DNS_TYPE_A", etc.
+ * For this reason, these constants are also listed here, so that code using
+ * the DNS-SD programming APIs can use these constants, so that the same code
+ * can compile on all our supported platforms.
+ */
+
+enum
+ {
+ kDNSServiceClass_IN = 1 /* Internet */
+ };
+
+enum
+ {
+ kDNSServiceType_A = 1, /* Host address. */
+ kDNSServiceType_NS = 2, /* Authoritative server. */
+ kDNSServiceType_MD = 3, /* Mail destination. */
+ kDNSServiceType_MF = 4, /* Mail forwarder. */
+ kDNSServiceType_CNAME = 5, /* Canonical name. */
+ kDNSServiceType_SOA = 6, /* Start of authority zone. */
+ kDNSServiceType_MB = 7, /* Mailbox domain name. */
+ kDNSServiceType_MG = 8, /* Mail group member. */
+ kDNSServiceType_MR = 9, /* Mail rename name. */
+ kDNSServiceType_NULL = 10, /* Null resource record. */
+ kDNSServiceType_WKS = 11, /* Well known service. */
+ kDNSServiceType_PTR = 12, /* Domain name pointer. */
+ kDNSServiceType_HINFO = 13, /* Host information. */
+ kDNSServiceType_MINFO = 14, /* Mailbox information. */
+ kDNSServiceType_MX = 15, /* Mail routing information. */
+ kDNSServiceType_TXT = 16, /* Text strings. */
+ kDNSServiceType_RP = 17, /* Responsible person. */
+ kDNSServiceType_AFSDB = 18, /* AFS cell database. */
+ kDNSServiceType_X25 = 19, /* X_25 calling address. */
+ kDNSServiceType_ISDN = 20, /* ISDN calling address. */
+ kDNSServiceType_RT = 21, /* Router. */
+ kDNSServiceType_NSAP = 22, /* NSAP address. */
+ kDNSServiceType_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
+ kDNSServiceType_SIG = 24, /* Security signature. */
+ kDNSServiceType_KEY = 25, /* Security key. */
+ kDNSServiceType_PX = 26, /* X.400 mail mapping. */
+ kDNSServiceType_GPOS = 27, /* Geographical position (withdrawn). */
+ kDNSServiceType_AAAA = 28, /* Ip6 Address. */
+ kDNSServiceType_LOC = 29, /* Location Information. */
+ kDNSServiceType_NXT = 30, /* Next domain (security). */
+ kDNSServiceType_EID = 31, /* Endpoint identifier. */
+ kDNSServiceType_NIMLOC = 32, /* Nimrod Locator. */
+ kDNSServiceType_SRV = 33, /* Server Selection. */
+ kDNSServiceType_ATMA = 34, /* ATM Address */
+ kDNSServiceType_NAPTR = 35, /* Naming Authority PoinTeR */
+ kDNSServiceType_KX = 36, /* Key Exchange */
+ kDNSServiceType_CERT = 37, /* Certification record */
+ kDNSServiceType_A6 = 38, /* IPv6 address (deprecates AAAA) */
+ kDNSServiceType_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
+ kDNSServiceType_SINK = 40, /* Kitchen sink (experimentatl) */
+ kDNSServiceType_OPT = 41, /* EDNS0 option (meta-RR) */
+ kDNSServiceType_TKEY = 249, /* Transaction key */
+ kDNSServiceType_TSIG = 250, /* Transaction signature. */
+ kDNSServiceType_IXFR = 251, /* Incremental zone transfer. */
+ kDNSServiceType_AXFR = 252, /* Transfer zone of authority. */
+ kDNSServiceType_MAILB = 253, /* Transfer mailbox records. */
+ kDNSServiceType_MAILA = 254, /* Transfer mail agent records. */
+ kDNSServiceType_ANY = 255 /* Wildcard match. */
+ };
+
+
/* possible error code values */
enum
{
kDNSServiceErr_AlreadyRegistered = -65547,
kDNSServiceErr_NameConflict = -65548,
kDNSServiceErr_Invalid = -65549,
+ kDNSServiceErr_Firewall = -65550,
kDNSServiceErr_Incompatible = -65551, /* client library incompatible with daemon */
- kDNSServiceErr_BadinterfaceIndex = -65552
+ kDNSServiceErr_BadInterfaceIndex = -65552,
+ kDNSServiceErr_Refused = -65553,
+ kDNSServiceErr_NoSuchRecord = -65554,
+ kDNSServiceErr_NoAuth = -65555,
+ kDNSServiceErr_NoSuchKey = -65556,
+ kDNSServiceErr_NATTraversal = -65557,
+ kDNSServiceErr_DoubleNAT = -65558,
+ kDNSServiceErr_BadTime = -65559
/* mDNS Error codes are in the range
* FFFE FF00 (-65792) to FFFE FFFF (-65537) */
};
-
+
/* Maximum length, in bytes, of a domain name represented as an escaped C-String */
+/* including the final trailing dot, and the C-String terminating NULL at the end */
+
#define kDNSServiceMaxDomainName 1005
+/*
+ * Notes on DNS Name Escaping
+ * -- or --
+ * "Why is kDNSServiceMaxDomainName 1005, when the maximum legal domain name is 255 bytes?"
+ *
+ * All strings used in DNS-SD are UTF-8 strings.
+ * With few exceptions, most are also escaped using standard DNS escaping rules:
+ *
+ * '\\' represents a single literal '\' in the name
+ * '\.' represents a single literal '.' in the name
+ * '\ddd', where ddd is a three-digit decimal value from 000 to 255,
+ * represents a single literal byte with that value.
+ * A bare unescaped '.' is a label separator, marking a boundary between domain and subdomain.
+ *
+ * The exceptions, that do not use escaping, are the routines where the full
+ * DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
+ * In these routines, the "servicename" is NOT escaped. It does not need to be, since
+ * it is, by definition, just a single literal string. Any characters in that string
+ * represent exactly what they are. The "regtype" portion is, technically speaking,
+ * escaped, but since legal regtypes are only allowed to contain letters, digits,
+ * and hyphens, the issue is moot. The "domain" portion is also escaped, though
+ * most domains in use on the public Internet today, like regtypes, don't contain
+ * any characters that need to be escaped. As DNS-SD becomes more popular, rich-text
+ * domains for service discovery will become common, so software should be written
+ * to cope with domains with escaping.
+ *
+ * For most software, these issues are transparent. When browsing, the discovered
+ * servicenames should simply be displayed as-is. When resolving, the discovered
+ * servicename/regtype/domain are simply passed unchanged to DNSServiceResolve().
+ * When a DNSServiceResolve() succeeds, the returned fullname is already in
+ * the correct format to pass to standard system DNS APIs such as res_query().
+ * For converting from servicename/regtype/domain to a single properly-escaped
+ * full DNS name, the helper function DNSServiceConstructFullName() is provided.
+ *
+ * The following (highly contrived) example illustrates the escaping process.
+ * Suppose you have an service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
+ * in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
+ * The full (escaped) DNS name of this service's SRV record would be:
+ * Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
+ */
+
+
+/*
+ * Constants for specifying an interface index
+ *
+ * Specific interface indexes are identified via a 32-bit unsigned integer returned
+ * by the if_nametoindex() family of calls.
+ *
+ * If the client passes 0 for interface index, that means "do the right thing",
+ * which (at present) means, "if the name is in an mDNS local multicast domain
+ * (e.g. 'local.', '254.169.in-addr.arpa.', '0.8.E.F.ip6.arpa.') then multicast
+ * on all applicable interfaces, otherwise send via unicast to the appropriate
+ * DNS server." Normally, most clients will use 0 for interface index to
+ * automatically get the default sensible behaviour.
+ *
+ * If the client passes a positive interface index, then for multicast names that
+ * indicates to do the operation only on that one interface. For unicast names the
+ * interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
+ *
+ * If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
+ * a service, then that service will be found *only* by other local clients
+ * on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly
+ * or kDNSServiceInterfaceIndexAny.
+ * If a client has a 'private' service, accessible only to other processes
+ * running on the same machine, this allows the client to advertise that service
+ * in a way such that it does not inadvertently appear in service lists on
+ * all the other machines on the network.
+ *
+ * If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing
+ * then it will find *all* records registered on that same local machine.
+ * Clients explicitly wishing to discover *only* LocalOnly services can
+ * accomplish this by inspecting the interfaceIndex of each service reported
+ * to their DNSServiceBrowseReply() callback function, and discarding those
+ * where the interface index is not kDNSServiceInterfaceIndexLocalOnly.
+ */
+
+#define kDNSServiceInterfaceIndexAny 0
+#define kDNSServiceInterfaceIndexLocalOnly ( (uint32_t) -1 )
+
typedef uint32_t DNSServiceFlags;
typedef int32_t DNSServiceErrorType;
/* DNSServiceRefSockFD()
*
* Access underlying Unix domain socket for an initialized DNSServiceRef.
- * The DNS Service Discovery implmementation uses this socket to communicate between
+ * The DNS Service Discovery implmementation uses this socket to communicate between
* the client and the mDNSResponder daemon. The application MUST NOT directly read from
* or write to this socket. Access to the socket is provided so that it can be used as a
- * run loop source, or in a select() loop: when data is available for reading on the socket,
- * DNSServiceProcessResult() should be called, which will extract the daemon's reply from
+ * run loop source, or in a select() loop: when data is available for reading on the socket,
+ * DNSServiceProcessResult() should be called, which will extract the daemon's reply from
* the socket, and pass it to the appropriate application callback. By using a run loop or
* select(), results from the daemon can be processed asynchronously. Without using these
* constructs, DNSServiceProcessResult() will block until the response from the daemon arrives.
* socket buffer.
*
* sdRef: A DNSServiceRef initialized by any of the DNSService calls.
- *
- * return value: The DNSServiceRef's underlying socket descriptor, or -1 on
+ *
+ * return value: The DNSServiceRef's underlying socket descriptor, or -1 on
* error.
*/
-
-int DNSServiceRefSockFD(DNSServiceRef sdRef);
+
+int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
+
/* DNSServiceProcessResult()
*
* Read a reply from the daemon, calling the appropriate application callback. This call will
- * block until the daemon's response is received. Use DNSServiceRefSockFD() in
+ * block until the daemon's response is received. Use DNSServiceRefSockFD() in
* conjunction with a run loop or select() to determine the presence of a response from the
* server before calling this function to process the reply without blocking. Call this function
* at any point if it is acceptable to block until the daemon's response arrives. Note that the
* an error code indicating the specific failure that occurred.
*/
-DNSServiceErrorType DNSServiceProcessResult(DNSServiceRef sdRef);
+DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
+
/* DNSServiceRefDeallocate()
*
* Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
* Any services or records registered with this DNSServiceRef will be deregistered. Any
- * Browse, Resolve, or Query operations called with this reference will be terminated. If the
- * reference's underlying socket is used in a run loop or select() call, it should be removed BEFORE
- * DNSServiceRefDeallocate() is called, as this function closes the reference's socket.
+ * Browse, Resolve, or Query operations called with this reference will be terminated.
+ *
+ * Note: If the reference's underlying socket is used in a run loop or select() call, it should
+ * be removed BEFORE DNSServiceRefDeallocate() is called, as this function closes the reference's
+ * socket.
+ *
+ * Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs
+ * created via this reference will be invalidated by this call - the resource records are
+ * deregistered, and their DNSRecordRefs may not be used in subsequent functions. Similarly,
+ * if the reference was initialized with DNSServiceRegister, and an extra resource record was
+ * added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call
+ * is invalidated when this function is called - the DNSRecordRef may not be used in subsequent
+ * functions.
*
* Note: This call is to be used only with the DNSServiceRef defined by this API. It is
- * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
+ * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
* DNSServiceDiscovery.h API.
*
* sdRef: A DNSServiceRef initialized by any of the DNSService calls.
*
*/
-void DNSServiceRefDeallocate(DNSServiceRef sdRef);
+void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
/*********************************************************************************************
- *
+ *
* Domain Enumeration
*
*********************************************************************************************/
/* DNSServiceEnumerateDomains()
- *
+ *
* Asynchronously enumerate domains available for browsing and registration.
- * Currently, the only domain returned is "local.", but other domains will be returned in future.
*
* The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
* are to be found.
*
+ * Note that the names returned are (like all of DNS-SD) UTF-8 strings,
+ * and are escaped using standard DNS escaping rules.
+ * (See "Notes on DNS Name Escaping" earlier in this file for more details.)
+ * A graphical browser displaying a hierarchical tree-structured view should cut
+ * the names at the bare dots to yield individual labels, then de-escape each
+ * label according to the escaping rules, and then display the resulting UTF-8 text.
*
* DNSServiceDomainEnumReply Callback Parameters:
*
* sdRef: The DNSServiceRef initialized by DNSServiceEnumerateDomains().
*
* flags: Possible values are:
- * 1 (MoreComing)
- * 2 (Add/Remove)
- * 4 (Add Default)
+ * kDNSServiceFlagsMoreComing
+ * kDNSServiceFlagsAdd
+ * kDNSServiceFlagsDefault
*
- * interfaceIndex: Specifies the interface on which the domain exists. (The index for a given
- * interface is determined via the if_nametoindex() family of calls.)
+ * interfaceIndex: Specifies the interface on which the domain exists. (The index for a given
+ * interface is determined via the if_nametoindex() family of calls.)
*
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
+ * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
* the failure that occurred (other parameters are undefined if errorCode is nonzero).
*
* replyDomain: The name of the domain.
*
* context: The context pointer passed to DNSServiceEnumerateDomains.
- *
+ *
*/
-typedef void (*DNSServiceDomainEnumReply)
+typedef void (DNSSD_API *DNSServiceDomainEnumReply)
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
- const char *replyDomain,
- void *context
+ const char *replyDomain,
+ void *context
);
-
+
+
/* DNSServiceEnumerateDomains() Parameters:
*
*
- * sdRef: A pointer to an uninitialized sdRef. May be passed to
- * DNSServiceRefDeallocate() to cancel the enumeration.
+ * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
+ * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
+ * and the enumeration operation will run indefinitely until the client
+ * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
*
* flags: Possible values are:
- * 0 (BrowseDomains) to enumerate domains recommended for browsing.
- * 32 (RegistrationDomains) to enumerate domains recommended for registration.
+ * kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing.
+ * kDNSServiceFlagsRegistrationDomains to enumerate domains recommended
+ * for registration.
*
* interfaceIndex: If non-zero, specifies the interface on which to look for domains.
* (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to enumerate domains on
- * all interfaces.
- *
- * callBack: The function to be called when a domain is found or the call asynchronously
+ * family of calls.) Most applications will pass 0 to enumerate domains on
+ * all interfaces. See "Constants for specifying an interface index" for more details.
+ *
+ * callBack: The function to be called when a domain is found or the call asynchronously
* fails.
*
- * context: An application context pointer which is passed to the callback function
+ * context: An application context pointer which is passed to the callback function
* (may be NULL).
*
* return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
+ * errors are delivered to the callback), otherwise returns an error code indicating
* the error that occurred (the callback is not invoked and the DNSServiceRef
* is not initialized.)
*/
-
-DNSServiceErrorType DNSServiceEnumerateDomains
+
+DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
(
DNSServiceRef *sdRef,
DNSServiceFlags flags,
void *context /* may be NULL */
);
+
/*********************************************************************************************
*
* Service Registration
*
*********************************************************************************************/
-
+
/* Register a service that is discovered via Browse() and Resolve() calls.
*
*
* DNSServiceRegisterReply() Callback Parameters:
- *
+ *
* sdRef: The DNSServiceRef initialized by DNSServiceRegister().
*
* flags: Currently unused, reserved for future use.
*
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
+ * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
* indicate the failure that occurred (including name conflicts, if the
- * kDNSServiceFlagsNoAutoRenameOnConflict flag was passed to the
+ * kDNSServiceFlagsNoAutoRename flag was passed to the
* callout.) Other parameters are undefined if errorCode is nonzero.
*
- * name: The service name registered (if the application did not specify a name in
+ * name: The service name registered (if the application did not specify a name in
* DNSServiceRegister(), this indicates what name was automatically chosen).
*
* regtype: The type of service registered, as it was passed to the callout.
* context: The context pointer that was passed to the callout.
*
*/
-
-typedef void (*DNSServiceRegisterReply)
+
+typedef void (DNSSD_API *DNSServiceRegisterReply)
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
DNSServiceErrorType errorCode,
- const char *name,
- const char *regtype,
- const char *domain,
- void *context
+ const char *name,
+ const char *regtype,
+ const char *domain,
+ void *context
);
-
+
+
/* DNSServiceRegister() Parameters:
*
- * sdRef: A pointer to an uninitialized sdRef. If this call succeeds, the reference
- * may be passed to
- * DNSServiceRefDeallocate() to deregister the service.
- *
+ * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
+ * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
+ * and the registration will remain active indefinitely until the client
+ * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
+ *
* interfaceIndex: If non-zero, specifies the interface on which to register the service
* (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to register on all
- * available interfaces. Pass -1 to register a service only on the local
- * machine (service will not be visible to remote hosts.)
+ * family of calls.) Most applications will pass 0 to register on all
+ * available interfaces. See "Constants for specifying an interface index" for more details.
*
* flags: Indicates the renaming behavior on name conflict (most applications
* will pass 0). See flag definitions above for details.
*
- * name: If non-NULL, specifies the service name to be registered.
- * Most applications will not specify a name, in which case the
- * computer name is used (this name is communicated to the client via
+ * name: If non-NULL, specifies the service name to be registered.
+ * Most applications will not specify a name, in which case the
+ * computer name is used (this name is communicated to the client via
* the callback).
*
- * regtype: The service type followed by the protocol, separated by a dot
+ * regtype: The service type followed by the protocol, separated by a dot
* (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ * New service types should be registered at htp://www.dns-sd.org/ServiceTypes.html.
*
* domain: If non-NULL, specifies the domain on which to advertise the service.
- * Most applications will not specify a domain, instead automatically
+ * Most applications will not specify a domain, instead automatically
* registering in the default domain(s).
*
* host: If non-NULL, specifies the SRV target host name. Most applications
* will not specify a host, instead automatically using the machine's
- * default host name(s). Note that specifying a non-NULL host does NOT
- * create an address record for that host - the application is responsible
+ * default host name(s). Note that specifying a non-NULL host does NOT
+ * create an address record for that host - the application is responsible
* for ensuring that the appropriate address record exists, or creating it
* via DNSServiceRegisterRecord().
*
- * port: The port on which the service accepts connections. Pass 0 for a
- * "placeholder" service (i.e. a service that will not be discovered by
- * browsing, but will cause a name conflict if another client tries to
- * register that same name.) Most clients will not use placeholder services.
+ * port: The port, in network byte order, on which the service accepts connections.
+ * Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
+ * by browsing, but will cause a name conflict if another client tries to
+ * register that same name). Most clients will not use placeholder services.
*
* txtLen: The length of the txtRecord, in bytes. Must be zero if the txtRecord is NULL.
*
- * txtRecord: The txt record rdata. May be NULL. Note that a non-NULL txtRecord
- * MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
+ * txtRecord: The txt record rdata. May be NULL. Note that a non-NULL txtRecord
+ * MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
* <length byte> <data> ...
*
* callBack: The function to be called when the registration completes or asynchronously
- * fails. The client MAY pass NULL for the callback - The client will NOT be notified
+ * fails. The client MAY pass NULL for the callback - The client will NOT be notified
* of the default values picked on its behalf, and the client will NOT be notified of any
- * asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
+ * asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
* of the service. The client may NOT pass the NoAutoRename flag if the callback is NULL.
* The client may still deregister the service at any time via DNSServiceRefDeallocate().
*
- * context: An application context pointer which is passed to the callback function
+ * context: An application context pointer which is passed to the callback function
* (may be NULL).
*
* return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
+ * errors are delivered to the callback), otherwise returns an error code indicating
* the error that occurred (the callback is never invoked and the DNSServiceRef
* is not initialized.)
*
*/
-DNSServiceErrorType DNSServiceRegister
+DNSServiceErrorType DNSSD_API DNSServiceRegister
(
DNSServiceRef *sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
const char *name, /* may be NULL */
- const char *regtype,
+ const char *regtype,
const char *domain, /* may be NULL */
const char *host, /* may be NULL */
uint16_t port,
DNSServiceRegisterReply callBack, /* may be NULL */
void *context /* may be NULL */
);
-
+
+
/* DNSServiceAddRecord()
*
* Add a record to a registered service. The name of the record will be the same as the
* registered service's name.
- * The record can later be updated or deregistered by passing the RecordRef initialized
+ * The record can later be updated or deregistered by passing the RecordRef initialized
* by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
*
- *
+ *
* Parameters;
*
* sdRef: A DNSServiceRef initialized by DNSServiceRegister().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
+ *
+ * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
* call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
+ * If the above DNSServiceRef is passed to DNSServiceRefDeallocate(), RecordRef is also
+ * invalidated and may not be used further.
*
* flags: Currently ignored, reserved for future use.
*
- * rrtype: The type of the record (e.g. TXT, SRV, etc), as defined in nameser.h.
+ * rrtype: The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc)
*
* rdlen: The length, in bytes, of the rdata.
*
* rdata: The raw rdata to be contained in the added resource record.
*
- * ttl: The time to live of the resource record, in seconds.
+ * ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value.
*
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
* error code indicating the error that occurred (the RecordRef is not initialized).
*/
-DNSServiceErrorType DNSServiceAddRecord
+DNSServiceErrorType DNSSD_API DNSServiceAddRecord
(
DNSServiceRef sdRef,
DNSRecordRef *RecordRef,
uint32_t ttl
);
+
/* DNSServiceUpdateRecord
*
* Update a registered resource record. The record must either be:
* error code indicating the error that occurred.
*/
-DNSServiceErrorType DNSServiceUpdateRecord
+DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
(
DNSServiceRef sdRef,
DNSRecordRef RecordRef, /* may be NULL */
uint32_t ttl
);
+
/* DNSServiceRemoveRecord
*
- * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
+ * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
* an record registered individually via DNSServiceRegisterRecord().
*
* Parameters:
* DNSServiceCreateConnection() (if the record being removed was registered via
* DNSServiceRegisterRecord()).
*
- * recordRef: A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
+ * recordRef: A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
* or DNSServiceRegisterRecord().
- *
+ *
* flags: Currently ignored, reserved for future use.
*
* return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
* error code indicating the error that occurred.
*/
-DNSServiceErrorType DNSServiceRemoveRecord
+DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
(
DNSServiceRef sdRef,
DNSRecordRef RecordRef,
*
*********************************************************************************************/
-
/* Browse for instances of a service.
*
*
*
* sdRef: The DNSServiceRef initialized by DNSServiceBrowse().
*
- * flags: Possible values are MoreComing and Add/Remove. See flag definitions
- * for details.
+ * flags: Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd.
+ * See flag definitions for details.
*
* interfaceIndex: The interface on which the service is advertised. This index should
- * be passed to DNSServiceResolve() when resolving the service.
+ * be passed to DNSServiceResolve() when resolving the service.
*
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
+ * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
* indicate the failure that occurred. Other parameters are undefined if
* the errorCode is nonzero.
*
- * serviceName: The service name discovered.
+ * serviceName: The discovered service name. This name should be displayed to the user,
+ * and stored for subsequent use in the DNSServiceResolve() call.
*
- * regtype: The service type, as passed in to DNSServiceBrowse().
+ * regtype: The service type, which is usually (but not always) the same as was passed
+ * to DNSServiceBrowse(). One case where the discovered service type may
+ * not be the same as the requested service type is when using subtypes:
+ * The client may want to browse for only those ftp servers that allow
+ * anonymous connections. The client will pass the string "_ftp._tcp,_anon"
+ * to DNSServiceBrowse(), but the type of the service that's discovered
+ * is simply "_ftp._tcp". The regtype for each discovered service instance
+ * should be stored along with the name, so that it can be passed to
+ * DNSServiceResolve() when the service is later resolved.
*
- * domain: The domain on which the service was discovered (if the application did not
- * specify a domain in DNSServicBrowse(), this indicates the domain on which the
- * service was discovered.)
+ * domain: The domain of the discovered service instance. This may or may not be the
+ * same as the domain that was passed to DNSServiceBrowse(). The domain for each
+ * discovered service instance should be stored along with the name, so that
+ * it can be passed to DNSServiceResolve() when the service is later resolved.
*
* context: The context pointer that was passed to the callout.
*
*/
-typedef void (*DNSServiceBrowseReply)
+typedef void (DNSSD_API *DNSServiceBrowseReply)
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
- const char *serviceName,
- const char *regtype,
- const char *replyDomain,
- void *context
+ const char *serviceName,
+ const char *regtype,
+ const char *replyDomain,
+ void *context
);
-
+
+
/* DNSServiceBrowse() Parameters:
*
- * sdRef: A pointer to an uninitialized sdRef. May be passed to
- * DNSServiceRefDeallocate() to terminate the browse.
+ * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
+ * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
+ * and the browse operation will run indefinitely until the client
+ * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
*
* flags: Currently ignored, reserved for future use.
*
* interfaceIndex: If non-zero, specifies the interface on which to browse for services
* (the index for a given interface is determined via the if_nametoindex()
* family of calls.) Most applications will pass 0 to browse on all available
- * interfaces. Pass -1 to only browse for services provided on the local host.
+ * interfaces. See "Constants for specifying an interface index" for more details.
*
- * regtype: The service type being browsed for followed by the protocol, separated by a
+ * regtype: The service type being browsed for followed by the protocol, separated by a
* dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
*
* domain: If non-NULL, specifies the domain on which to browse for services.
- * Most applications will not specify a domain, instead browsing on the
+ * Most applications will not specify a domain, instead browsing on the
* default domain(s).
*
- * callBack: The function to be called when an instance of the service being browsed for
+ * callBack: The function to be called when an instance of the service being browsed for
* is found, or if the call asynchronously fails.
*
- * context: An application context pointer which is passed to the callback function
+ * context: An application context pointer which is passed to the callback function
* (may be NULL).
*
* return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
+ * errors are delivered to the callback), otherwise returns an error code indicating
* the error that occurred (the callback is not invoked and the DNSServiceRef
* is not initialized.)
*/
-DNSServiceErrorType DNSServiceBrowse
+DNSServiceErrorType DNSSD_API DNSServiceBrowse
(
DNSServiceRef *sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
- const char *regtype,
+ const char *regtype,
const char *domain, /* may be NULL */
DNSServiceBrowseReply callBack,
void *context /* may be NULL */
);
+
/* DNSServiceResolve()
*
* Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
* txt record.
*
- * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
+ * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
* DNSServiceQueryRecord() instead, as it is more efficient for this task.
*
* Note: When the desired results have been returned, the client MUST terminate the resolve by calling
*
* sdRef: The DNSServiceRef initialized by DNSServiceResolve().
*
- * flags: Possible values are MoreComing and Add/Remove. See flag definitions
- * for details.
+ * flags: Currently unused, reserved for future use.
*
- * interfaceIndex: The interface on which the service was resolved.
+ * interfaceIndex: The interface on which the service was resolved.
*
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
+ * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
* indicate the failure that occurred. Other parameters are undefined if
* the errorCode is nonzero.
*
* fullname: The full service domain name, in the form <servicename>.<protocol>.<domain>.
- * (Any literal dots (".") are escaped with a backslash ("\."), and literal
- * backslashes are escaped with a second backslash ("\\"), e.g. a web server
- * named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.").
- * This is the appropriate format to pass to standard system DNS APIs such as
- * res_query(), or to the special-purpose functions included in this API that
- * take fullname parameters.
- *
- * hosttarget: The target hostname of the machine providing the service. This name can
+ * (This name is escaped following standard DNS rules, making it suitable for
+ * passing to standard system DNS APIs such as res_query(), or to the
+ * special-purpose functions included in this API that take fullname parameters.
+ * See "Notes on DNS Name Escaping" earlier in this file for more details.)
+ *
+ * hosttarget: The target hostname of the machine providing the service. This name can
* be passed to functions like gethostbyname() to identify the host's IP address.
*
- * port: The port number on which connections are accepted for this service.
+ * port: The port, in network byte order, on which connections are accepted for this service.
*
* txtLen: The length of the txt record, in bytes.
*
* txtRecord: The service's primary txt record, in standard txt record format.
*
-
+
* context: The context pointer that was passed to the callout.
*
*/
-typedef void (*DNSServiceResolveReply)
+typedef void (DNSSD_API *DNSServiceResolveReply)
(
DNSServiceRef sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
- const char *fullname,
+ const char *fullname,
const char *hosttarget,
uint16_t port,
uint16_t txtLen,
const char *txtRecord,
- void *context
+ void *context
);
-
+
+
/* DNSServiceResolve() Parameters
*
- * sdRef: A pointer to an uninitialized sdRef. May be passed to
- * DNSServiceRefDeallocate() to terminate the resolve.
+ * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
+ * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
+ * and the resolve operation will run indefinitely until the client
+ * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
*
* flags: Currently ignored, reserved for future use.
*
- * interfaceIndex: The interface on which to resolve the service. The client should
- * pass the interface on which the servicename was discovered, i.e.
- * the interfaceIndex passed to the DNSServiceBrowseReply callback,
- * or 0 to resolve the named service on all available interfaces.
+ * interfaceIndex: The interface on which to resolve the service. If this resolve call is
+ * as a result of a currently active DNSServiceBrowse() operation, then the
+ * interfaceIndex should be the index reported in the DNSServiceBrowseReply
+ * callback. If this resolve call is using information previously saved
+ * (e.g. in a preference file) for later use, then use interfaceIndex 0, because
+ * the desired service may now be reachable via a different physical interface.
+ * See "Constants for specifying an interface index" for more details.
*
- * name: The servicename to be resolved.
+ * name: The name of the service instance to be resolved, as reported to the
+ * DNSServiceBrowseReply() callback.
*
- * regtype: The service type being resolved followed by the protocol, separated by a
- * dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
+ * regtype: The type of the service instance to be resolved, as reported to the
+ * DNSServiceBrowseReply() callback.
*
- * domain: The domain on which the service is registered, i.e. the domain passed
- * to the DNSServiceBrowseReply callback.
+ * domain: The domain of the service instance to be resolved, as reported to the
+ * DNSServiceBrowseReply() callback.
*
- * callBack: The function to be called when a result is found, or if the call
+ * callBack: The function to be called when a result is found, or if the call
* asynchronously fails.
*
- * context: An application context pointer which is passed to the callback function
+ * context: An application context pointer which is passed to the callback function
* (may be NULL).
*
* return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
+ * errors are delivered to the callback), otherwise returns an error code indicating
* the error that occurred (the callback is never invoked and the DNSServiceRef
* is not initialized.)
*/
-
-DNSServiceErrorType DNSServiceResolve
+DNSServiceErrorType DNSSD_API DNSServiceResolve
(
DNSServiceRef *sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
- const char *name,
- const char *regtype,
- const char *domain,
+ const char *name,
+ const char *regtype,
+ const char *domain,
DNSServiceResolveReply callBack,
void *context /* may be NULL */
);
*
*********************************************************************************************/
-/* DNS Naming Conventions:
- *
- * The following functions refer to resource records by their full domain name, unlike the above
- * functions which divide the name into servicename/regtype/domain fields. In the above functions,
- * a dot (".") is considered to be a literal dot in the servicename field (e.g. "Dr. Pepper") and
- * a label separator in the regtype ("_ftp._tcp") or domain ("apple.com") fields. Literal dots in
- * the domain field would be escaped with a backslash, and literal backslashes would be escaped with
- * a second backslash (this is generally not an issue, as domain names on the Internet today almost
- * never use characters other than letters, digits, or hyphens, and the dots are label separators.)
- * Furthermore, this is transparent to the caller, so long as the fields are passed between functions
- * without manipulation. However, the following, special-purpose calls use a single, full domain name.
- * As such, all dots are considered to be label separators, unless escaped, and all backslashes are
- * considered to be escape characters, unless preceded by a second backslash. For example, the name
- * "Dr. Smith \ Dr. Johnson" could be passed literally as a service name parameter in the above calls,
- * but in the special purpose call, the dots and backslash would have to be escaped
- * (e.g. "Dr\. Smith \\ Dr\. Johnson._ftp._tcp.apple.com" for an ftp service on the apple.com domain.)
- */
-
-/* DNSServiceConstructFullName()
- *
- * Concatenate a three-part domain name (as returned by the above callbacks) into a properly-escaped
- * full domain name. Note that callbacks in the above functions ALREADY ESCAPE strings where necessary.
- *
- * Parameters:
- *
- * fullName: A pointer to a buffer that where the resulting full domain name is to be written.
- * The buffer must be kDNSServiceDiscoveryMaxDomainName (1005) bytes in length to
- * accommodate the longest legal domain name without buffer overrun.
- *
- * service: The service name - any dots or slashes must NOT be escaped.
- * May be NULL (to construct a PTR record name, e.g.
- * "_ftp._tcp.apple.com").
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp").
- *
- * domain: The domain name, e.g. "apple.com". Any literal dots or backslashes
- * must be escaped.
- *
- * return value: Returns 0 on success, -1 on error.
- *
- */
-
-int DNSServiceConstructFullName
- (
- char *fullName,
- const char *service, /* may be NULL */
- const char *regtype,
- const char *domain
- );
-
/* DNSServiceCreateConnection()
*
* Create a connection to the daemon allowing efficient registration of
* case the DNSServiceRef is not initialized).
*/
-DNSServiceErrorType DNSServiceCreateConnection(DNSServiceRef *sdRef);
+DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef);
/* DNSServiceRegisterRecord
*
- * Register an individual resource record on a connected DNSServiceRef.
+ * Register an individual resource record on a connected DNSServiceRef.
*
* Note that name conflicts occurring for records registered via this call must be handled
* by the client in the callback.
*
* sdRef: The connected DNSServiceRef initialized by
* DNSServiceDiscoveryConnect().
- *
- * RecordRef: The DNSRecordRef initialized by DNSServiceRegisterRecord().
+ *
+ * RecordRef: The DNSRecordRef initialized by DNSServiceRegisterRecord(). If the above
+ * DNSServiceRef is passed to DNSServiceRefDeallocate(), this DNSRecordRef is
+ * invalidated, and may not be used further.
*
* flags: Currently unused, reserved for future use.
*
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
+ * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
* indicate the failure that occurred (including name conflicts.)
* Other parameters are undefined if errorCode is nonzero.
*
* context: The context pointer that was passed to the callout.
*
*/
-
- typedef void (*DNSServiceRegisterRecordReply)
+
+ typedef void (DNSSD_API *DNSServiceRegisterRecordReply)
(
DNSServiceRef sdRef,
DNSRecordRef RecordRef,
DNSServiceFlags flags,
DNSServiceErrorType errorCode,
- void *context
+ void *context
);
-
-/* DNSServiceRegisterRecord() Parameters:
+
+/* DNSServiceRegisterRecord() Parameters:
*
* sdRef: A DNSServiceRef initialized by DNSServiceCreateConnection().
*
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
+ * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon succesfull completion of this
* call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- * (To deregister ALL records registered on a single connected DNSServiceRef
+ * (To deregister ALL records registered on a single connected DNSServiceRef
* and deallocate each of their corresponding DNSServiceRecordRefs, call
* DNSServiceRefDealloocate()).
*
- * flags: Possible values are Shared/Unique (see flag type definitions for details).
- *
+ * flags: Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique
+ * (see flag type definitions for details).
+ *
* interfaceIndex: If non-zero, specifies the interface on which to register the record
* (the index for a given interface is determined via the if_nametoindex()
* family of calls.) Passing 0 causes the record to be registered on all interfaces.
- * Passing -1 causes the record to only be visible on the local host.
+ * See "Constants for specifying an interface index" for more details.
*
* fullname: The full domain name of the resource record.
*
- * rrtype: The numerical type of the resource record (e.g. PTR, SRV, etc), as defined
- * in nameser.h.
+ * rrtype: The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
*
- * rrclass: The class of the resource record, as defined in nameser.h (usually 1 for the
- * Internet class).
+ * rrclass: The class of the resource record (usually kDNSServiceClass_IN)
*
* rdlen: Length, in bytes, of the rdata.
*
* rdata: A pointer to the raw rdata, as it is to appear in the DNS record.
*
- * ttl: The time to live of the resource record, in seconds.
+ * ttl: The time to live of the resource record, in seconds. Pass 0 to use a default value.
*
- * callBack: The function to be called when a result is found, or if the call
+ * callBack: The function to be called when a result is found, or if the call
* asynchronously fails (e.g. because of a name conflict.)
*
- * context: An application context pointer which is passed to the callback function
+ * context: An application context pointer which is passed to the callback function
* (may be NULL).
*
* return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
+ * errors are delivered to the callback), otherwise returns an error code indicating
* the error that occurred (the callback is never invoked and the DNSRecordRef is
* not initialized.)
*/
-
-DNSServiceErrorType DNSServiceRegisterRecord
+DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
(
DNSServiceRef sdRef,
DNSRecordRef *RecordRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
- const char *fullname,
+ const char *fullname,
uint16_t rrtype,
uint16_t rrclass,
uint16_t rdlen,
* DNSServiceQueryRecordReply() Callback Parameters:
*
* sdRef: The DNSServiceRef initialized by DNSServiceQueryRecord().
- *
- * flags: Possible values are Finished/MoreComing.
*
- * interfaceIndex: The interface on which the query was resolved (the index for a given
+ * flags: Possible values are kDNSServiceFlagsMoreComing and
+ * kDNSServiceFlagsAdd. The Add flag is NOT set for PTR records
+ * with a ttl of 0, i.e. "Remove" events.
+ *
+ * interfaceIndex: The interface on which the query was resolved (the index for a given
* interface is determined via the if_nametoindex() family of calls).
+ * See "Constants for specifying an interface index" for more details.
*
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
+ * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
+ * indicate the failure that occurred. Other parameters are undefined if
* errorCode is nonzero.
*
* fullname: The resource record's full domain name.
*
- * rrtype: The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
+ * rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
*
- * rrclass: The class of the resource record, as defined in nameser.h (usually 1).
+ * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
*
* rdlen: The length, in bytes, of the resource record rdata.
*
*
*/
-typedef void (*DNSServiceQueryRecordReply)
+typedef void (DNSSD_API *DNSServiceQueryRecordReply)
(
DNSServiceRef DNSServiceRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
DNSServiceErrorType errorCode,
- const char *fullname,
+ const char *fullname,
uint16_t rrtype,
uint16_t rrclass,
uint16_t rdlen,
const void *rdata,
uint32_t ttl,
- void *context
+ void *context
);
+
/* DNSServiceQueryRecord() Parameters:
*
- * sdRef: A pointer to an uninitialized DNSServiceRef.
+ * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
+ * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
+ * and the query operation will run indefinitely until the client
+ * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
+ *
+ * flags: Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
+ * query in a non-local domain. Without setting this flag, unicast queries
+ * will be one-shot - that is, only answers available at the time of the call
+ * will be returned. By setting this flag, answers (including Add and Remove
+ * events) that become available after the initial call is made will generate
+ * callbacks. This flag has no effect on link-local multicast queries.
*
- * flags: Currently unused, reserved for future use.
- *
* interfaceIndex: If non-zero, specifies the interface on which to issue the query
* (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the name to be queried for on all
- * interfaces. Passing -1 causes the name to be queried for only on the
- * local host.
+ * family of calls.) Passing 0 causes the name to be queried for on all
+ * interfaces. See "Constants for specifying an interface index" for more details.
*
* fullname: The full domain name of the resource record to be queried for.
*
- * rrtype: The numerical type of the resource record to be queried for (e.g. PTR, SRV, etc)
- * as defined in nameser.h.
+ * rrtype: The numerical type of the resource record to be queried for
+ * (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
*
- * rrclass: The class of the resource record, as defined in nameser.h
- * (usually 1 for the Internet class).
+ * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
*
- * callBack: The function to be called when a result is found, or if the call
+ * callBack: The function to be called when a result is found, or if the call
* asynchronously fails.
*
- * context: An application context pointer which is passed to the callback function
+ * context: An application context pointer which is passed to the callback function
* (may be NULL).
*
* return value: Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
+ * errors are delivered to the callback), otherwise returns an error code indicating
* the error that occurred (the callback is never invoked and the DNSServiceRef
* is not initialized.)
*/
-
-DNSServiceErrorType DNSServiceQueryRecord
+
+DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
(
DNSServiceRef *sdRef,
DNSServiceFlags flags,
uint32_t interfaceIndex,
- const char *fullname,
+ const char *fullname,
uint16_t rrtype,
uint16_t rrclass,
DNSServiceQueryRecordReply callBack,
void *context /* may be NULL */
);
+
/* DNSServiceReconfirmRecord
*
- * Instruct the daemon to verify the validity of a resource record that appears to
- * be out of date (e.g. because tcp connection to a service's target failed.)
- * Causes the record to be flushed from the daemon's cache (as well as all other
+ * Instruct the daemon to verify the validity of a resource record that appears to
+ * be out of date (e.g. because tcp connection to a service's target failed.)
+ * Causes the record to be flushed from the daemon's cache (as well as all other
* daemons' caches on the network) if the record is determined to be invalid.
*
* Parameters:
*
* flags: Currently unused, reserved for future use.
*
+ * interfaceIndex: If non-zero, specifies the interface of the record in question.
+ * Passing 0 causes all instances of this record to be reconfirmed.
+ *
* fullname: The resource record's full domain name.
*
- * rrtype: The resource record's type (e.g. PTR, SRV, etc) as defined in nameser.h.
+ * rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
*
- * rrclass: The class of the resource record, as defined in nameser.h (usually 1).
+ * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
*
* rdlen: The length, in bytes, of the resource record rdata.
*
* rdata: The raw rdata of the resource record.
*
*/
-
-void DNSServiceReconfirmRecord
+
+void DNSSD_API DNSServiceReconfirmRecord
(
DNSServiceFlags flags,
uint32_t interfaceIndex,
- const char *fullname,
+ const char *fullname,
uint16_t rrtype,
uint16_t rrclass,
uint16_t rdlen,
);
-#endif // _DNS_SD_H
+/*********************************************************************************************
+ *
+ * General Utility Functions
+ *
+ *********************************************************************************************/
+
+/* DNSServiceConstructFullName()
+ *
+ * Concatenate a three-part domain name (as returned by the above callbacks) into a
+ * properly-escaped full domain name. Note that callbacks in the above functions ALREADY ESCAPE
+ * strings where necessary.
+ *
+ * Parameters:
+ *
+ * fullName: A pointer to a buffer that where the resulting full domain name is to be written.
+ * The buffer must be kDNSServiceMaxDomainName (1005) bytes in length to
+ * accommodate the longest legal domain name without buffer overrun.
+ *
+ * service: The service name - any dots or backslashes must NOT be escaped.
+ * May be NULL (to construct a PTR record name, e.g.
+ * "_ftp._tcp.apple.com.").
+ *
+ * regtype: The service type followed by the protocol, separated by a dot
+ * (e.g. "_ftp._tcp").
+ *
+ * domain: The domain name, e.g. "apple.com.". Literal dots or backslashes,
+ * if any, must be escaped, e.g. "1st\. Floor.apple.com."
+ *
+ * return value: Returns 0 on success, -1 on error.
+ *
+ */
+
+int DNSSD_API DNSServiceConstructFullName
+ (
+ char *fullName,
+ const char *service, /* may be NULL */
+ const char *regtype,
+ const char *domain
+ );
+
+
+/*********************************************************************************************
+ *
+ * TXT Record Construction Functions
+ *
+ *********************************************************************************************/
+
+/*
+ * A typical calling sequence for TXT record construction is something like:
+ *
+ * Client allocates storage for TXTRecord data (e.g. declare buffer on the stack)
+ * TXTRecordCreate();
+ * TXTRecordSetValue();
+ * TXTRecordSetValue();
+ * TXTRecordSetValue();
+ * ...
+ * DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
+ * TXTRecordDeallocate();
+ * Explicitly deallocate storage for TXTRecord data (if not allocated on the stack)
+ */
+
+
+/* TXTRecordRef
+ *
+ * Opaque internal data type.
+ * Note: Represents a DNS-SD TXT record.
+ */
+
+typedef struct _TXTRecordRef_t { char privatedata[16]; } TXTRecordRef;
+
+
+/* TXTRecordCreate()
+ *
+ * Creates a new empty TXTRecordRef referencing the specified storage.
+ *
+ * If the buffer parameter is NULL, or the specified storage size is not
+ * large enough to hold a key subsequently added using TXTRecordSetValue(),
+ * then additional memory will be added as needed using malloc().
+ *
+ * On some platforms, when memory is low, malloc() may fail. In this
+ * case, TXTRecordSetValue() will return kDNSServiceErr_NoMemory, and this
+ * error condition will need to be handled as appropriate by the caller.
+ *
+ * You can avoid the need to handle this error condition if you ensure
+ * that the storage you initially provide is large enough to hold all
+ * the key/value pairs that are to be added to the record.
+ * The caller can precompute the exact length required for all of the
+ * key/value pairs to be added, or simply provide a fixed-sized buffer
+ * known in advance to be large enough.
+ * A no-value (key-only) key requires (1 + key length) bytes.
+ * A key with empty value requires (1 + key length + 1) bytes.
+ * A key with non-empty value requires (1 + key length + 1 + value length).
+ * For most applications, DNS-SD TXT records are generally
+ * less than 100 bytes, so in most cases a simple fixed-sized
+ * 256-byte buffer will be more than sufficient.
+ * Recommended size limits for DNS-SD TXT Records are discussed in
+ * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
+ *
+ * Note: When passing parameters to and from these TXT record APIs,
+ * the key name does not include the '=' character. The '=' character
+ * is the separator between the key and value in the on-the-wire
+ * packet format; it is not part of either the key or the value.
+ *
+ * txtRecord: A pointer to an uninitialized TXTRecordRef.
+ *
+ * bufferLen: The size of the storage provided in the "buffer" parameter.
+ *
+ * buffer: The storage used to hold the TXTRecord data.
+ * This storage must remain valid for as long as
+ * the TXTRecordRef.
+ */
+
+void DNSSD_API TXTRecordCreate
+ (
+ TXTRecordRef *txtRecord,
+ uint16_t bufferLen,
+ void *buffer
+ );
+
+
+/* TXTRecordDeallocate()
+ *
+ * Releases any resources allocated in the course of preparing a TXT Record
+ * using TXTRecordCreate()/TXTRecordSetValue()/TXTRecordRemoveValue().
+ * Ownership of the buffer provided in TXTRecordCreate() returns to the client.
+ *
+ * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
+ *
+ */
+
+void DNSSD_API TXTRecordDeallocate
+ (
+ TXTRecordRef *txtRecord
+ );
+
+
+/* TXTRecordSetValue()
+ *
+ * Adds a key (optionally with value) to a TXTRecordRef. If the "key" already
+ * exists in the TXTRecordRef, then the current value will be replaced with
+ * the new value.
+ * Keys may exist in four states with respect to a given TXT record:
+ * - Absent (key does not appear at all)
+ * - Present with no value ("key" appears alone)
+ * - Present with empty value ("key=" appears in TXT record)
+ * - Present with non-empty value ("key=value" appears in TXT record)
+ * For more details refer to "Data Syntax for DNS-SD TXT Records" in
+ * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
+ *
+ * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
+ *
+ * key: A null-terminated string which only contains printable ASCII
+ * values (0x20-0x7E), excluding '=' (0x3D). Keys should be
+ * 8 characters or less (not counting the terminating null).
+ *
+ * valueSize: The size of the value.
+ *
+ * value: Any binary value. For values that represent
+ * textual data, UTF-8 is STRONGLY recommended.
+ * For values that represent textual data, valueSize
+ * should NOT include the terminating null (if any)
+ * at the end of the string.
+ * If NULL, then "key" will be added with no value.
+ * If non-NULL but valueSize is zero, then "key=" will be
+ * added with empty value.
+ *
+ * return value: Returns kDNSServiceErr_NoError on success.
+ * Returns kDNSServiceErr_Invalid if the "key" string contains
+ * illegal characters.
+ * Returns kDNSServiceErr_NoMemory if adding this key would
+ * exceed the available storage.
+ */
+
+DNSServiceErrorType DNSSD_API TXTRecordSetValue
+ (
+ TXTRecordRef *txtRecord,
+ const char *key,
+ uint8_t valueSize, /* may be zero */
+ const void *value /* may be NULL */
+ );
+
+
+/* TXTRecordRemoveValue()
+ *
+ * Removes a key from a TXTRecordRef. The "key" must be an
+ * ASCII string which exists in the TXTRecordRef.
+ *
+ * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
+ *
+ * key: A key name which exists in the TXTRecordRef.
+ *
+ * return value: Returns kDNSServiceErr_NoError on success.
+ * Returns kDNSServiceErr_NoSuchKey if the "key" does not
+ * exist in the TXTRecordRef.
+ *
+ */
+
+DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
+ (
+ TXTRecordRef *txtRecord,
+ const char *key
+ );
+
+
+/* TXTRecordGetLength()
+ *
+ * Allows you to determine the length of the raw bytes within a TXTRecordRef.
+ *
+ * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
+ *
+ * return value: Returns the size of the raw bytes inside a TXTRecordRef
+ * which you can pass directly to DNSServiceRegister() or
+ * to DNSServiceUpdateRecord().
+ * Returns 0 if the TXTRecordRef is empty.
+ *
+ */
+
+uint16_t DNSSD_API TXTRecordGetLength
+ (
+ const TXTRecordRef *txtRecord
+ );
+
+
+/* TXTRecordGetBytesPtr()
+ *
+ * Allows you to retrieve a pointer to the raw bytes within a TXTRecordRef.
+ *
+ * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
+ *
+ * return value: Returns a pointer to the raw bytes inside the TXTRecordRef
+ * which you can pass directly to DNSServiceRegister() or
+ * to DNSServiceUpdateRecord().
+ *
+ */
+
+const void * DNSSD_API TXTRecordGetBytesPtr
+ (
+ const TXTRecordRef *txtRecord
+ );
+
+
+/*********************************************************************************************
+ *
+ * TXT Record Parsing Functions
+ *
+ *********************************************************************************************/
+
+/*
+ * A typical calling sequence for TXT record parsing is something like:
+ *
+ * Receive TXT record data in DNSServiceResolve() callback
+ * if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
+ * val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
+ * val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
+ * ...
+ * bcopy(val1ptr, myval1, len1);
+ * bcopy(val2ptr, myval2, len2);
+ * ...
+ * return;
+ *
+ * If you wish to retain the values after return from the DNSServiceResolve()
+ * callback, then you need to copy the data to your own storage using bcopy()
+ * or similar, as shown in the example above.
+ *
+ * If for some reason you need to parse a TXT record you built yourself
+ * using the TXT record construction functions above, then you can do
+ * that using TXTRecordGetLength and TXTRecordGetBytesPtr calls:
+ * TXTRecordGetValue(TXTRecordGetLength(x), TXTRecordGetBytesPtr(x), key, &len);
+ *
+ * Most applications only fetch keys they know about from a TXT record and
+ * ignore the rest.
+ * However, some debugging tools wish to fetch and display all keys.
+ * To do that, use the TXTRecordGetCount() and TXTRecordGetItemAtIndex() calls.
+ */
+
+/* TXTRecordContainsKey()
+ *
+ * Allows you to determine if a given TXT Record contains a specified key.
+ *
+ * txtLen: The size of the received TXT Record.
+ *
+ * txtRecord: Pointer to the received TXT Record bytes.
+ *
+ * key: A null-terminated ASCII string containing the key name.
+ *
+ * return value: Returns 1 if the TXT Record contains the specified key.
+ * Otherwise, it returns 0.
+ *
+ */
+
+int DNSSD_API TXTRecordContainsKey
+ (
+ uint16_t txtLen,
+ const void *txtRecord,
+ const char *key
+ );
+
+
+/* TXTRecordGetValuePtr()
+ *
+ * Allows you to retrieve the value for a given key from a TXT Record.
+ *
+ * txtLen: The size of the received TXT Record
+ *
+ * txtRecord: Pointer to the received TXT Record bytes.
+ *
+ * key: A null-terminated ASCII string containing the key name.
+ *
+ * valueLen: On output, will be set to the size of the "value" data.
+ *
+ * return value: Returns NULL if the key does not exist in this TXT record,
+ * or exists with no value (to differentiate between
+ * these two cases use TXTRecordContainsKey()).
+ * Returns pointer to location within TXT Record bytes
+ * if the key exists with empty or non-empty value.
+ * For empty value, valueLen will be zero.
+ * For non-empty value, valueLen will be length of value data.
+ */
+
+const void * DNSSD_API TXTRecordGetValuePtr
+ (
+ uint16_t txtLen,
+ const void *txtRecord,
+ const char *key,
+ uint8_t *valueLen
+ );
+
+
+/* TXTRecordGetCount()
+ *
+ * Returns the number of keys stored in the TXT Record. The count
+ * can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
+ *
+ * txtLen: The size of the received TXT Record.
+ *
+ * txtRecord: Pointer to the received TXT Record bytes.
+ *
+ * return value: Returns the total number of keys in the TXT Record.
+ *
+ */
+
+uint16_t DNSSD_API TXTRecordGetCount
+ (
+ uint16_t txtLen,
+ const void *txtRecord
+ );
+
+
+/* TXTRecordGetItemAtIndex()
+ *
+ * Allows you to retrieve a key name and value pointer, given an index into
+ * a TXT Record. Legal index values range from zero to TXTRecordGetCount()-1.
+ * It's also possible to iterate through keys in a TXT record by simply
+ * calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
+ * and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
+ *
+ * On return:
+ * For keys with no value, *value is set to NULL and *valueLen is zero.
+ * For keys with empty value, *value is non-NULL and *valueLen is zero.
+ * For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
+ *
+ * txtLen: The size of the received TXT Record.
+ *
+ * txtRecord: Pointer to the received TXT Record bytes.
+ *
+ * index: An index into the TXT Record.
+ *
+ * keyBufLen: The size of the string buffer being supplied.
+ *
+ * key: A string buffer used to store the key name.
+ * On return, the buffer contains a null-terminated C string
+ * giving the key name. DNS-SD TXT keys are usually
+ * 8 characters or less. To hold the maximum possible
+ * key name, the buffer should be 256 bytes long.
+ *
+ * valueLen: On output, will be set to the size of the "value" data.
+ *
+ * value: On output, *value is set to point to location within TXT
+ * Record bytes that holds the value data.
+ *
+ * return value: Returns kDNSServiceErr_NoError on success.
+ * Returns kDNSServiceErr_NoMemory if keyBufLen is too short.
+ * Returns kDNSServiceErr_Invalid if index is greater than
+ * TXTRecordGetCount()-1.
+ */
+
+DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
+ (
+ uint16_t txtLen,
+ const void *txtRecord,
+ uint16_t index,
+ uint16_t keyBufLen,
+ char *key,
+ uint8_t *valueLen,
+ const void **value
+ );
+
+#ifdef __APPLE_API_PRIVATE
+
+/*
+ * Mac OS X specific functionality
+ * 3rd party clients of this API should not depend on future support or availability of this routine
+ */
+
+/* DNSServiceSetDefaultDomainForUser()
+ *
+ * Set the default domain for the caller's UID. Future browse and registration
+ * calls by this user that do not specify an explicit domain will browse and
+ * register in this wide-area domain in addition to .local. In addition, this
+ * domain will be returned as a Browse domain via domain enumeration calls.
+ *
+ *
+ * Parameters:
+ *
+ * flags: Pass kDNSServiceFlagsAdd to add a domain for a user. Call without
+ * this flag set to clear a previously added domain.
+ *
+ * domain: The domain to be used for the caller's UID.
+ *
+ * return value: Returns kDNSServiceErr_NoError on succeses, otherwise returns
+ * an error code indicating the error that occurred
+ */
+
+DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser
+ (
+ DNSServiceFlags flags,
+ const char *domain
+ );
+
+#endif //__APPLE_API_PRIVATE
+
+#ifdef __cplusplus
+ }
+#endif
+#endif /* _DNS_SD_H */
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Application", "ApplicationVS2002.vcproj", "{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = All
+ ConfigName.1 = Debug
+ ConfigName.2 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.ActiveCfg = All|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.Build.0 = All|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.ActiveCfg = Debug|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.Build.0 = Debug|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.ActiveCfg = Release|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
--- /dev/null
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="Application"
+ ProjectGUID="{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="FALSE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StdAfx.h"
+ PrecompiledHeaderFile=".\Debug/Application.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ SuppressStartupBanner="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="ws2_32.lib nafxcwd.lib LIBCMTD.lib"
+ OutputFile="Rendezvous Browser Debug.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreDefaultLibraryNames="wsock32.lib;nafxcwd.lib;LIBCMTD.lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/Application.pdb"
+ SubSystem="2"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/Application.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_AFXDLL;_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="FALSE"
+ OptimizeForWindowsApplication="FALSE"
+ AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Release/Application.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="1"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ SuppressStartupBanner="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="ws2_32.lib nafxcw.lib LIBCMT.lib"
+ OutputFile="Rendezvous Browser.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreDefaultLibraryNames="wsock32.lib;nafxcw.lib;LIBCMT.lib"
+ ProgramDatabaseFile=".\Release/Application.pdb"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/Application.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_AFXDLL;NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="All|Win32"
+ OutputDirectory="All"
+ IntermediateDirectory="All"
+ ConfigurationType="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="">
+ <File
+ RelativePath="Sources\AboutDialog.cpp">
+ </File>
+ <File
+ RelativePath="Sources\AboutDialog.h">
+ </File>
+ <File
+ RelativePath="Sources\Application.cpp">
+ </File>
+ <File
+ RelativePath="Sources\Application.h">
+ </File>
+ <File
+ RelativePath="Sources\ChooserDialog.cpp">
+ </File>
+ <File
+ RelativePath="Sources\ChooserDialog.h">
+ </File>
+ <File
+ RelativePath="Sources\StdAfx.cpp">
+ </File>
+ <File
+ RelativePath="Sources\StdAfx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;rc">
+ <File
+ RelativePath="Resources\Application.ico">
+ </File>
+ <File
+ RelativePath="Resources\Application.rc">
+ </File>
+ <File
+ RelativePath="Resources\Application.rc2">
+ </File>
+ <File
+ RelativePath=".\Resources\Resource.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Rendezvous"
+ Filter="">
+ <File
+ RelativePath="..\..\..\DNSServices\DNSServices.c">
+ </File>
+ <File
+ RelativePath="..\..\..\..\mDNSCore\mDNS.c">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSWin32.c">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Application", "ApplicationVS2003.vcproj", "{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ All = All
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.ActiveCfg = All|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.Build.0 = All|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.ActiveCfg = Debug|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.Build.0 = Debug|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.ActiveCfg = Release|Win32
+ {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="Application"
+ ProjectGUID="{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
+ Keyword="MFCProj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="FALSE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="StdAfx.h"
+ PrecompiledHeaderFile=".\Debug/Application.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ SuppressStartupBanner="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="ws2_32.lib nafxcwd.lib LIBCMTD.lib"
+ OutputFile="Rendezvous Browser Debug.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreDefaultLibraryNames="wsock32.lib;nafxcwd.lib;LIBCMTD.lib"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile=".\Debug/Application.pdb"
+ SubSystem="2"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="FALSE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/Application.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_AFXDLL;_DEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="1"
+ UseOfMFC="1"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="0"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="FALSE"
+ OptimizeForWindowsApplication="FALSE"
+ AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ StringPooling="TRUE"
+ MinimalRebuild="FALSE"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ RuntimeTypeInfo="TRUE"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Release/Application.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="1"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ SuppressStartupBanner="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ CompileAs="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/MACHINE:I386"
+ AdditionalDependencies="ws2_32.lib nafxcw.lib LIBCMT.lib"
+ OutputFile="Rendezvous Browser.exe"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreDefaultLibraryNames="wsock32.lib;nafxcw.lib;LIBCMT.lib"
+ ProgramDatabaseFile=".\Release/Application.pdb"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"/>
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="TRUE"
+ SuppressStartupBanner="TRUE"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/Application.tlb"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_AFXDLL;NDEBUG"
+ Culture="1033"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="All|Win32"
+ OutputDirectory="All"
+ IntermediateDirectory="All"
+ ConfigurationType="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="">
+ <File
+ RelativePath="Sources\AboutDialog.cpp">
+ </File>
+ <File
+ RelativePath="Sources\AboutDialog.h">
+ </File>
+ <File
+ RelativePath="Sources\Application.cpp">
+ </File>
+ <File
+ RelativePath="Sources\Application.h">
+ </File>
+ <File
+ RelativePath="Sources\ChooserDialog.cpp">
+ </File>
+ <File
+ RelativePath="Sources\ChooserDialog.h">
+ </File>
+ <File
+ RelativePath="Sources\StdAfx.cpp">
+ </File>
+ <File
+ RelativePath="Sources\StdAfx.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;rc">
+ <File
+ RelativePath="Resources\Application.ico">
+ </File>
+ <File
+ RelativePath="Resources\Application.rc">
+ </File>
+ <File
+ RelativePath="Resources\Application.rc2">
+ </File>
+ <File
+ RelativePath=".\Resources\Resource.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="Rendezvous"
+ Filter="">
+ <File
+ RelativePath="..\..\..\DNSServices\DNSServices.c">
+ </File>
+ <File
+ RelativePath="..\..\..\..\mDNSCore\mDNS.c">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSWin32.c">
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+// Microsoft Visual C++ generated resource script.
+//
+#include "Resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "Resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif //_WIN32\r\n"
+ "#include ""Resources\\Application.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAIN_ICON ICON "Application.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_CHOOSER_DIALOG DIALOGEX 0, 0, 332, 252
+STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Rendezvous Browser for Windows"
+MENU IDR_CHOOSER_DIALOG_MENU
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ CONTROL "",IDC_CHOOSER_LIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
+ LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,116,8,208,136
+ CONTROL "",IDC_SERVICE_LIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
+ LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,8,100,136
+ CONTROL "",IDC_DOMAIN_LIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
+ LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,152,100,92
+ GROUPBOX "Information",IDC_STATIC,116,148,208,96
+ RTEXT "Name:",IDC_STATIC,122,164,38,8
+ LTEXT "My Device",IDC_INFO_NAME_TEXT,164,164,152,10,SS_SUNKEN
+ RTEXT "Text:",IDC_STATIC,122,203,38,8
+ LTEXT "Information About My Device",IDC_INFO_TEXT_TEXT,164,203,
+ 152,34,SS_NOPREFIX | SS_SUNKEN
+ RTEXT "IP address:",IDC_STATIC,122,177,38,8
+ LTEXT "123.124.125.126:1234",IDC_INFO_IP_TEXT,164,177,152,10,
+ SS_SUNKEN
+ RTEXT "Interface:",IDC_STATIC,122,190,38,8
+ LTEXT "123.124.125.126",IDC_INFO_INTERFACE_TEXT,164,190,152,10,
+ SS_SUNKEN
+END
+
+IDD_ABOUT_DIALOG DIALOGEX 0, 0, 244, 73
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
+CAPTION "About Rendezvous Browser"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ ICON IDR_MAIN_ICON,IDC_ABOUT_APP_ICON,12,12,20,20
+ LTEXT "Rendezvous Browser for Windows",IDC_ABOUT_APP_NAME_TEXT,
+ 44,11,192,12
+ LTEXT "Version 1.0d2",IDC_ABOUT_APP_VERSION_TEXT,44,25,192,8
+ LTEXT "Copyright (C) 2002-2003 Apple Computer, Inc.",
+ IDC_ABOUT_COPYRIGHT_TEXT,4,60,156,8
+ DEFPUSHBUTTON "OK",IDOK,192,52,44,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Quick & Dirty 1 day hack by Bob Bradley"
+ VALUE "CompanyName", "Apple Computer, Inc."
+ VALUE "FileDescription", "Rendezvous Browser for Windows"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "Rendezvous Browser for Windows"
+ VALUE "LegalCopyright", "Copyright (C) Apple Computer, Inc. 2001"
+ VALUE "OriginalFilename", "RendezvousBrowser.exe"
+ VALUE "ProductName", "Rendezvous Browser for Windows"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_CHOOSER_DIALOG_MENU MENU
+BEGIN
+ POPUP "File"
+ BEGIN
+ MENUITEM "Close &Window\tCtrl+W", ID_FILE_CLOSE
+ MENUITEM SEPARATOR
+ MENUITEM "Exit", ID_FILE_EXIT
+ END
+ POPUP "Help"
+ BEGIN
+ MENUITEM "About Rendezvous Browser...", ID_HELP_ABOUT
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_CHOOSER_DIALOG_MENU_ACCELERATORS ACCELERATORS
+BEGIN
+ "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
+ "W", ID_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RT_MANIFEST
+//
+
+1 RT_MANIFEST
+BEGIN
+ 0x3f3c, 0x6d78, 0x206c, 0x6576, 0x7372, 0x6f69, 0x3d6e, 0x3122, 0x302e,
+ 0x2022, 0x6e65, 0x6f63, 0x6964, 0x676e, 0x223d, 0x5455, 0x2d46, 0x2238,
+ 0x7320, 0x6174, 0x646e, 0x6c61, 0x6e6f, 0x3d65, 0x7922, 0x7365, 0x3f22,
+ 0x203e, 0x0a0d, 0x613c, 0x7373, 0x6d65, 0x6c62, 0x2079, 0x0a0d, 0x2020,
+ 0x7820, 0x6c6d, 0x736e, 0x223d, 0x7275, 0x3a6e, 0x6373, 0x6568, 0x616d,
+ 0x2d73, 0x696d, 0x7263, 0x736f, 0x666f, 0x2d74, 0x6f63, 0x3a6d, 0x7361,
+ 0x2e6d, 0x3176, 0x2022, 0x0a0d, 0x2020, 0x6d20, 0x6e61, 0x6669, 0x7365,
+ 0x5674, 0x7265, 0x6973, 0x6e6f, 0x223d, 0x2e31, 0x2230, 0x0d3e, 0x3c0a,
+ 0x7361, 0x6573, 0x626d, 0x796c, 0x6449, 0x6e65, 0x6974, 0x7974, 0x0d20,
+ 0x200a, 0x2020, 0x7020, 0x6f72, 0x6563, 0x7373, 0x726f, 0x7241, 0x6863,
+ 0x7469, 0x6365, 0x7574, 0x6572, 0x223d, 0x3878, 0x2236, 0x0d20, 0x200a,
+ 0x2020, 0x7620, 0x7265, 0x6973, 0x6e6f, 0x223d, 0x2e35, 0x2e31, 0x2e30,
+ 0x2230, 0x0a0d, 0x2020, 0x2020, 0x7974, 0x6570, 0x223d, 0x6977, 0x336e,
+ 0x2232, 0x0a0d, 0x2020, 0x2020, 0x616e, 0x656d, 0x223d, 0x7041, 0x2e70,
+ 0x7865, 0x2265, 0x3e2f, 0x0a0d, 0x2020, 0x2020, 0x643c, 0x7365, 0x7263,
+ 0x7069, 0x6974, 0x6e6f, 0x413e, 0x7269, 0x6f50, 0x7472, 0x4120, 0x6d64,
+ 0x6e69, 0x5520, 0x6974, 0x696c, 0x7974, 0x2f3c, 0x6564, 0x6373, 0x6972,
+ 0x7470, 0x6f69, 0x3e6e, 0x0a0d, 0x2020, 0x2020, 0x643c, 0x7065, 0x6e65,
+ 0x6564, 0x636e, 0x3e79, 0x0a0d, 0x2020, 0x2020, 0x643c, 0x7065, 0x6e65,
+ 0x6564, 0x746e, 0x7341, 0x6573, 0x626d, 0x796c, 0x0d3e, 0x200a, 0x2020,
+ 0x3c20, 0x7361, 0x6573, 0x626d, 0x796c, 0x6449, 0x6e65, 0x6974, 0x7974,
+ 0x0a0d, 0x2020, 0x2020, 0x2020, 0x2020, 0x7420, 0x7079, 0x3d65, 0x7722,
+ 0x6e69, 0x3233, 0x0d22, 0x200a, 0x2020, 0x2020, 0x2020, 0x2020, 0x616e,
+ 0x656d, 0x223d, 0x694d, 0x7263, 0x736f, 0x666f, 0x2e74, 0x6957, 0x646e,
+ 0x776f, 0x2e73, 0x6f43, 0x6d6d, 0x6e6f, 0x432d, 0x6e6f, 0x7274, 0x6c6f,
+ 0x2273, 0x0a0d, 0x2020, 0x2020, 0x2020, 0x2020, 0x7620, 0x7265, 0x6973,
+ 0x6e6f, 0x223d, 0x2e36, 0x2e30, 0x2e30, 0x2230, 0x0a0d, 0x2020, 0x2020,
+ 0x2020, 0x2020, 0x7020, 0x6275, 0x696c, 0x4b63, 0x7965, 0x6f54, 0x656b,
+ 0x3d6e, 0x3622, 0x3935, 0x6235, 0x3436, 0x3431, 0x6334, 0x6663, 0x6431,
+ 0x2266, 0x0a0d, 0x2020, 0x2020, 0x2020, 0x2020, 0x6c20, 0x6e61, 0x7567,
+ 0x6761, 0x3d65, 0x2a22, 0x0d22, 0x200a, 0x2020, 0x2020, 0x2020, 0x2020,
+ 0x7270, 0x636f, 0x7365, 0x6f73, 0x4172, 0x6372, 0x6968, 0x6574, 0x7463,
+ 0x7275, 0x3d65, 0x7822, 0x3638, 0x2f22, 0x0d3e, 0x200a, 0x2020, 0x3c20,
+ 0x642f, 0x7065, 0x6e65, 0x6564, 0x746e, 0x7341, 0x6573, 0x626d, 0x796c,
+ 0x0d3e, 0x200a, 0x2020, 0x3c20, 0x642f, 0x7065, 0x6e65, 0x6564, 0x636e,
+ 0x3e79, 0x0a0d, 0x2f3c, 0x7361, 0x6573, 0x626d, 0x796c, 0x0d3e, "\012"
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_ABOUTBOX "&About Rendezvous Browser"
+ IDS_CHOOSER_DOMAIN_COLUMN_NAME "Domains"
+ IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed."
+ IDS_CHOOSER_SERVICE_COLUMN_NAME "Services"
+ IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME "Name"
+ IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME "IP Address"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+#include "Resources\Application.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: Application.rc2,v $
+Revision 1.1 2003/08/21 02:06:46 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.2 2003/08/20 07:06:34 bradley
+Update to APSL 2.0. Updated change history to match other mDNSResponder files.
+
+Revision 1.1 2002/09/20 06:12:48 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
--- /dev/null
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Application.rc
+//
+#define IDS_ABOUTBOX 101
+#define IDS_CHOOSER_DOMAIN_COLUMN_NAME 102
+#define IDP_SOCKETS_INIT_FAILED 103
+#define IDS_CHOOSER_SERVICE_COLUMN_NAME 104
+#define IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME 105
+#define IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME 106
+#define IDC_NAME_TEXT2 124
+#define IDC_INFO_NAME_TEXT 124
+#define IDC_DESCRIPTION_TEXT2 125
+#define IDC_INFO_TEXT_TEXT 125
+#define IDC_IP_TEXT2 126
+#define IDC_INFO_IP_TEXT 126
+#define IDC_IP_TEXT3 127
+#define IDC_INFO_INTERFACE_TEXT 127
+#define IDR_MAIN_ICON 128
+#define IDR_CHOOSER_DIALOG_MENU 136
+#define IDD_CHOOSER_DIALOG 143
+#define IDD_ABOUT_DIALOG 144
+#define IDR_CHOOSER_DIALOG_MENU_ACCELERATORS 146
+#define IDC_CHOOSER_LIST 1000
+#define IDC_SERVICE_LIST2 1001
+#define IDC_SERVICE_LIST 1001
+#define IDC_SERVICE_LIST3 1002
+#define IDC_DOMAIN_LIST 1002
+#define IDC_ABOUT_APP_NAME_TEXT 1105
+#define IDC_ABOUT_APP_VERSION_TEXT 1106
+#define IDC_ABOUT_COPYRIGHT_TEXT 1107
+#define IDC_ABOUT_APP_ICON 1108
+#define ID_FILE_EXIT 32771
+#define ID_HELP_ABOUT 32806
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 164
+#define _APS_NEXT_COMMAND_VALUE 32809
+#define _APS_NEXT_CONTROL_VALUE 1182
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: AboutDialog.cpp,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.4 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/20 06:12:49 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#include <stdlib.h>
+
+#include "stdafx.h"
+
+#include "AboutDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//===========================================================================================================================
+// Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP(AboutDialog, CDialog)
+ //{{AFX_MSG_MAP(AboutDialog)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+//===========================================================================================================================
+// AboutDialog
+//===========================================================================================================================
+
+AboutDialog::AboutDialog(CWnd* pParent /*=NULL*/)
+ : CDialog(AboutDialog::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(AboutDialog)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+}
+
+//===========================================================================================================================
+// OnInitDialog
+//===========================================================================================================================
+
+BOOL AboutDialog::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+ return( true );
+}
+
+//===========================================================================================================================
+// DoDataExchange
+//===========================================================================================================================
+
+void AboutDialog::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(AboutDialog)
+ // NOTE: the ClassWizard will add DDX and DDV calls here
+ //}}AFX_DATA_MAP
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: AboutDialog.h,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.4 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/20 06:12:50 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#if !defined(AFX_ABOUTDIALOG_H__4B8A04B2_9735_4F4A_AFCA_15F85FB3D763__INCLUDED_)
+#define AFX_ABOUTDIALOG_H__4B8A04B2_9735_4F4A_AFCA_15F85FB3D763__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "Resource.h"
+
+//===========================================================================================================================
+// AboutDialog
+//===========================================================================================================================
+
+class AboutDialog : public CDialog
+{
+ public:
+
+ // Creation/Deletion
+
+ AboutDialog(CWnd* pParent = NULL); // standard constructor
+
+ //{{AFX_DATA(AboutDialog)
+ enum { IDD = IDD_ABOUT_DIALOG };
+ // NOTE: the ClassWizard will add data members here
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(AboutDialog)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+ protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(AboutDialog)
+ virtual BOOL OnInitDialog();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_ABOUTDIALOG_H__4B8A04B2_9735_4F4A_AFCA_15F85FB3D763__INCLUDED_)
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: Application.cpp,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.5 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.4 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.3 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.2 2002/09/20 08:37:34 bradley
+Increased the DNS record cache from the default of 64 to 512 entries for larger networks.
+
+Revision 1.1 2002/09/20 06:12:51 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#include <assert.h>
+
+#include "DNSServices.h"
+
+#include "Application.h"
+
+#include "ChooserDialog.h"
+
+#include "stdafx.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//===========================================================================================================================
+// Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP(Application, CWinApp)
+ //{{AFX_MSG_MAP(Application)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG
+ ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+//===========================================================================================================================
+// Globals
+//===========================================================================================================================
+
+Application gApp;
+
+//===========================================================================================================================
+// Application
+//===========================================================================================================================
+
+Application::Application( void )
+{
+ //
+}
+
+//===========================================================================================================================
+// InitInstance
+//===========================================================================================================================
+
+BOOL Application::InitInstance()
+{
+ DNSStatus err;
+
+ // WinSock initialization.
+
+ if( !AfxSocketInit() )
+ {
+ AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+ return( FALSE );
+ }
+
+ // Standard MFC initialization.
+
+#if( !defined( AFX_DEPRECATED ) )
+ #ifdef _AFXDLL
+ Enable3dControls(); // Call this when using MFC in a shared DLL
+ #else
+ Enable3dControlsStatic(); // Call this when linking to MFC statically
+ #endif
+#endif
+
+ InitCommonControls();
+
+ // Set up DNS Services.
+
+ err = DNSServicesInitialize( 0, 512 );
+ assert( err == kDNSNoErr );
+
+ // Create the chooser dialog.
+
+ ChooserDialog * dialog;
+
+ m_pMainWnd = NULL;
+ dialog = new ChooserDialog;
+ dialog->Create( IDD_CHOOSER_DIALOG );
+ m_pMainWnd = dialog;
+ dialog->ShowWindow( SW_SHOW );
+
+ return( true );
+}
+
+//===========================================================================================================================
+// ExitInstance
+//===========================================================================================================================
+
+int Application::ExitInstance( void )
+{
+ // Clean up DNS Services.
+
+ DNSServicesFinalize();
+ return( 0 );
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: Application.h,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.4 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/20 06:12:51 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#if !defined(AFX_ADMIN_H__8663733F_6A15_439F_B568_F5A0125CD572__INCLUDED_)
+#define AFX_ADMIN_H__8663733F_6A15_439F_B568_F5A0125CD572__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "stdafx.h"
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "Resource.h"
+
+//===========================================================================================================================
+// Globals
+//===========================================================================================================================
+
+extern class Application gApp;
+
+//===========================================================================================================================
+// Application
+//===========================================================================================================================
+
+class Application : public CWinApp
+{
+ public:
+
+ // Creation/Deletion
+
+ Application();
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(Application)
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance( void );
+ //}}AFX_VIRTUAL
+
+ //{{AFX_MSG(Application)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_ADMIN_H__8663733F_6A15_439F_B568_F5A0125CD572__INCLUDED_)
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: ChooserDialog.cpp,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.7 2003/08/20 06:45:56 bradley
+Updated for IP address changes in DNSServices. Added support for browsing for Xserve RAID.
+
+Revision 1.6 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.5 2003/07/13 01:03:55 cheshire
+Diffs provided by Bob Bradley to provide provide proper display of Unicode names
+
+Revision 1.4 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.3 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.2 2002/09/20 08:39:21 bradley
+Make sure each resolved item matches the selected service type to handle resolved that may have
+been queued up on the Windows Message Loop. Reduce column to fit when scrollbar is present.
+
+Revision 1.1 2002/09/20 06:12:52 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "stdafx.h"
+
+#include "DNSServices.h"
+
+#include "Application.h"
+#include "AboutDialog.h"
+#include "Resource.h"
+
+#include "ChooserDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#if 0
+#pragma mark == Constants ==
+#endif
+
+//===========================================================================================================================
+// Constants
+//===========================================================================================================================
+
+// Menus
+
+enum
+{
+ kChooserMenuIndexFile = 0,
+ kChooserMenuIndexHelp = 1
+};
+
+// Domain List
+
+#define kDomainListDefaultDomainColumnIndex 0
+#define kDomainListDefaultDomainColumnWidth 140
+
+// Service List
+
+#define kServiceListDefaultServiceColumnIndex 0
+#define kServiceListDefaultServiceColumnWidth 140
+
+// Chooser List
+
+#define kChooserListDefaultNameColumnIndex 0
+#define kChooserListDefaultNameColumnWidth 162
+
+#define kChooserListDefaultIPColumnIndex 1
+#define kChooserListDefaultIPColumnWidth 126
+
+// Windows User Messages
+
+#define WM_USER_DOMAIN_ADD ( WM_USER + 0x100 )
+#define WM_USER_DOMAIN_REMOVE ( WM_USER + 0x101 )
+#define WM_USER_SERVICE_ADD ( WM_USER + 0x102 )
+#define WM_USER_SERVICE_REMOVE ( WM_USER + 0x103 )
+#define WM_USER_RESOLVE ( WM_USER + 0x104 )
+
+#if 0
+#pragma mark == Constants - Service Table ==
+#endif
+
+//===========================================================================================================================
+// Constants - Service Table
+//===========================================================================================================================
+
+struct KnownServiceEntry
+{
+ const char * serviceType;
+ const char * description;
+ const char * urlScheme;
+ bool useText;
+};
+
+static const KnownServiceEntry kKnownServiceTable[] =
+{
+ { "_airport._tcp.", "AirPort Base Station", "acp://", false },
+ { "_afpovertcp._tcp.", "AppleShare Server", "afp://", false },
+ { "_ftp._tcp.", "File Transfer (FTP)", "ftp://", false },
+ { "_ichat._tcp.", "iChat", "ichat://", false },
+ { "_printer._tcp.", "Printer (LPD)", "ldp://", false },
+ { "_eppc._tcp.", "Remote AppleEvents", "eppc://", false },
+ { "_ssh._tcp.", "Secure Shell (SSH)", "ssh://", false },
+ { "_tftp._tcp.", "Trivial File Transfer (TFTP)", "tftp://", false },
+ { "_http._tcp.", "Web Server (HTTP)", "http://", true },
+ { "_smb._tcp.", "Windows File Sharing", "smb://", false },
+ { "_xserveraid._tcp.", "Xserve RAID", "xsr://", false },
+ { NULL, NULL, NULL, false },
+};
+
+#if 0
+#pragma mark == Structures ==
+#endif
+
+//===========================================================================================================================
+// Structures
+//===========================================================================================================================
+
+struct DomainEventInfo
+{
+ DNSBrowserEventType eventType;
+ CString domain;
+ DNSNetworkAddress ifIP;
+};
+
+struct ServiceEventInfo
+{
+ DNSBrowserEventType eventType;
+ std::string name;
+ std::string type;
+ std::string domain;
+ DNSNetworkAddress ifIP;
+};
+
+#if 0
+#pragma mark == Prototypes ==
+#endif
+
+//===========================================================================================================================
+// Prototypes
+//===========================================================================================================================
+
+static void
+ BrowserCallBack(
+ void * inContext,
+ DNSBrowserRef inRef,
+ DNSStatus inStatusCode,
+ const DNSBrowserEvent * inEvent );
+
+static char * DNSNetworkAddressToString( const DNSNetworkAddress *inAddr, char *outString );
+
+static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject );
+
+#if 0
+#pragma mark == Message Map ==
+#endif
+
+//===========================================================================================================================
+// Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP(ChooserDialog, CDialog)
+ //{{AFX_MSG_MAP(ChooserDialog)
+ ON_WM_SYSCOMMAND()
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_DOMAIN_LIST, OnDomainListChanged)
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_SERVICE_LIST, OnServiceListChanged)
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHOOSER_LIST, OnChooserListChanged)
+ ON_NOTIFY(NM_DBLCLK, IDC_CHOOSER_LIST, OnChooserListDoubleClick)
+ ON_COMMAND(ID_HELP_ABOUT, OnAbout)
+ ON_WM_INITMENUPOPUP()
+ ON_WM_ACTIVATE()
+ ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
+ ON_COMMAND(ID_FILE_EXIT, OnExit)
+ ON_WM_CLOSE()
+ ON_WM_NCDESTROY()
+ //}}AFX_MSG_MAP
+ ON_MESSAGE( WM_USER_DOMAIN_ADD, OnDomainAdd )
+ ON_MESSAGE( WM_USER_DOMAIN_REMOVE, OnDomainRemove )
+ ON_MESSAGE( WM_USER_SERVICE_ADD, OnServiceAdd )
+ ON_MESSAGE( WM_USER_SERVICE_REMOVE, OnServiceRemove )
+ ON_MESSAGE( WM_USER_RESOLVE, OnResolve )
+END_MESSAGE_MAP()
+
+#if 0
+#pragma mark == Routines ==
+#endif
+
+//===========================================================================================================================
+// ChooserDialog
+//===========================================================================================================================
+
+ChooserDialog::ChooserDialog( CWnd *inParent )
+ : CDialog( ChooserDialog::IDD, inParent)
+{
+ //{{AFX_DATA_INIT(ChooserDialog)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+
+ // Load menu accelerator table.
+
+ mMenuAcceleratorTable = ::LoadAccelerators( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDR_CHOOSER_DIALOG_MENU_ACCELERATORS ) );
+ assert( mMenuAcceleratorTable );
+
+ mBrowser = NULL;
+ mIsServiceBrowsing = false;
+}
+
+//===========================================================================================================================
+// ~ChooserDialog
+//===========================================================================================================================
+
+ChooserDialog::~ChooserDialog( void )
+{
+ if( mBrowser )
+ {
+ DNSStatus err;
+
+ err = DNSBrowserRelease( mBrowser, 0 );
+ assert( err == kDNSNoErr );
+ }
+}
+
+//===========================================================================================================================
+// DoDataExchange
+//===========================================================================================================================
+
+void ChooserDialog::DoDataExchange( CDataExchange *pDX )
+{
+ CDialog::DoDataExchange(pDX);
+
+ //{{AFX_DATA_MAP(ChooserDialog)
+ DDX_Control(pDX, IDC_SERVICE_LIST, mServiceList);
+ DDX_Control(pDX, IDC_DOMAIN_LIST, mDomainList);
+ DDX_Control(pDX, IDC_CHOOSER_LIST, mChooserList);
+ //}}AFX_DATA_MAP
+}
+
+//===========================================================================================================================
+// OnInitDialog
+//===========================================================================================================================
+
+BOOL ChooserDialog::OnInitDialog( void )
+{
+ BOOL result;
+ CString tempString;
+ DNSStatus err;
+
+ // Initialize our parent.
+
+ CDialog::OnInitDialog();
+
+ // Set up the Domain List.
+
+ result = tempString.LoadString( IDS_CHOOSER_DOMAIN_COLUMN_NAME );
+ assert( result );
+ mDomainList.InsertColumn( 0, tempString, LVCFMT_LEFT, kDomainListDefaultDomainColumnWidth );
+
+ // Set up the Service List.
+
+ result = tempString.LoadString( IDS_CHOOSER_SERVICE_COLUMN_NAME );
+ assert( result );
+ mServiceList.InsertColumn( 0, tempString, LVCFMT_LEFT, kServiceListDefaultServiceColumnWidth );
+
+ PopulateServicesList();
+
+ // Set up the Chooser List.
+
+ result = tempString.LoadString( IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME );
+ assert( result );
+ mChooserList.InsertColumn( 0, tempString, LVCFMT_LEFT, kChooserListDefaultNameColumnWidth );
+
+ result = tempString.LoadString( IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME );
+ assert( result );
+ mChooserList.InsertColumn( 1, tempString, LVCFMT_LEFT, kChooserListDefaultIPColumnWidth );
+
+ // Set up the other controls.
+
+ UpdateInfoDisplay();
+
+ // Start browsing for domains.
+
+ err = DNSBrowserCreate( 0, BrowserCallBack, this, &mBrowser );
+ assert( err == kDNSNoErr );
+
+ err = DNSBrowserStartDomainSearch( mBrowser, 0 );
+ assert( err == kDNSNoErr );
+
+ return( true );
+}
+
+//===========================================================================================================================
+// OnFileClose
+//===========================================================================================================================
+
+void ChooserDialog::OnFileClose()
+{
+ OnClose();
+}
+
+//===========================================================================================================================
+// OnActivate
+//===========================================================================================================================
+
+void ChooserDialog::OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized )
+{
+ // Always make the active window the "main" window so modal dialogs work better and the app quits after closing
+ // the last window.
+
+ gApp.m_pMainWnd = this;
+
+ CDialog::OnActivate(nState, pWndOther, bMinimized);
+}
+
+//===========================================================================================================================
+// PostNcDestroy
+//===========================================================================================================================
+
+void ChooserDialog::PostNcDestroy()
+{
+ // Call the base class to do the normal cleanup.
+
+ delete this;
+}
+
+//===========================================================================================================================
+// PreTranslateMessage
+//===========================================================================================================================
+
+BOOL ChooserDialog::PreTranslateMessage(MSG* pMsg)
+{
+ BOOL result;
+
+ result = false;
+ assert( mMenuAcceleratorTable );
+ if( mMenuAcceleratorTable )
+ {
+ result = ::TranslateAccelerator( m_hWnd, mMenuAcceleratorTable, pMsg );
+ }
+ if( !result )
+ {
+ result = CDialog::PreTranslateMessage( pMsg );
+ }
+ return( result );
+}
+
+//===========================================================================================================================
+// OnInitMenuPopup
+//===========================================================================================================================
+
+void ChooserDialog::OnInitMenuPopup( CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu )
+{
+ CDialog::OnInitMenuPopup( pPopupMenu, nIndex, bSysMenu );
+
+ switch( nIndex )
+ {
+ case kChooserMenuIndexFile:
+ break;
+
+ case kChooserMenuIndexHelp:
+ break;
+
+ default:
+ break;
+ }
+}
+
+//===========================================================================================================================
+// OnExit
+//===========================================================================================================================
+
+void ChooserDialog::OnExit()
+{
+ AfxPostQuitMessage( 0 );
+}
+
+//===========================================================================================================================
+// OnAbout
+//===========================================================================================================================
+
+void ChooserDialog::OnAbout()
+{
+ AboutDialog dialog;
+
+ dialog.DoModal();
+}
+
+//===========================================================================================================================
+// OnSysCommand
+//===========================================================================================================================
+
+void ChooserDialog::OnSysCommand( UINT inID, LPARAM inParam )
+{
+ CDialog::OnSysCommand( inID, inParam );
+}
+
+//===========================================================================================================================
+// OnClose
+//===========================================================================================================================
+
+void ChooserDialog::OnClose()
+{
+ StopBrowsing();
+
+ gApp.m_pMainWnd = this;
+ DestroyWindow();
+}
+
+//===========================================================================================================================
+// OnNcDestroy
+//===========================================================================================================================
+
+void ChooserDialog::OnNcDestroy()
+{
+ gApp.m_pMainWnd = this;
+
+ CDialog::OnNcDestroy();
+}
+
+//===========================================================================================================================
+// OnDomainListChanged
+//===========================================================================================================================
+
+void ChooserDialog::OnDomainListChanged( NMHDR *pNMHDR, LRESULT *pResult )
+{
+ UNUSED_ALWAYS( pNMHDR );
+
+ // Domain list changes have similar effects to service list changes so reuse that code path by calling it here.
+
+ OnServiceListChanged( NULL, NULL );
+
+ *pResult = 0;
+}
+
+//===========================================================================================================================
+// OnServiceListChanged
+//===========================================================================================================================
+
+void ChooserDialog::OnServiceListChanged( NMHDR *pNMHDR, LRESULT *pResult )
+{
+ int selectedType;
+ int selectedDomain;
+
+ UNUSED_ALWAYS( pNMHDR );
+
+ // Stop any existing service search.
+
+ StopBrowsing();
+
+ // If a domain and service type are selected, start searching for the service type on the domain.
+
+ selectedType = mServiceList.GetNextItem( -1, LVNI_SELECTED );
+ selectedDomain = mDomainList.GetNextItem( -1, LVNI_SELECTED );
+
+ if( ( selectedType >= 0 ) && ( selectedDomain >= 0 ) )
+ {
+ CString type;
+ CString domain;
+
+ type = mServiceTypes[ selectedType ].serviceType.c_str();
+ domain = mDomainList.GetItemText( selectedDomain, 0 );
+
+ StartBrowsing( type, domain );
+ }
+
+ if( pResult )
+ {
+ *pResult = 0;
+ }
+}
+
+//===========================================================================================================================
+// OnChooserListChanged
+//===========================================================================================================================
+
+void ChooserDialog::OnChooserListChanged( NMHDR *pNMHDR, LRESULT *pResult )
+{
+ UNUSED_ALWAYS( pNMHDR );
+
+ UpdateInfoDisplay();
+ *pResult = 0;
+}
+
+//===========================================================================================================================
+// OnChooserListDoubleClick
+//===========================================================================================================================
+
+void ChooserDialog::OnChooserListDoubleClick( NMHDR *pNMHDR, LRESULT *pResult )
+{
+ int selectedItem;
+
+ UNUSED_ALWAYS( pNMHDR );
+
+ // Display the service instance if it is selected. Otherwise, clear all the info.
+
+ selectedItem = mChooserList.GetNextItem( -1, LVNI_SELECTED );
+ if( selectedItem >= 0 )
+ {
+ ServiceInstanceInfo * p;
+ CString url;
+ const KnownServiceEntry * service;
+
+ assert( selectedItem < (int) mServiceInstances.size() );
+ p = &mServiceInstances[ selectedItem ];
+
+ // Search for a known service type entry that matches.
+
+ for( service = kKnownServiceTable; service->serviceType; ++service )
+ {
+ if( p->type == service->serviceType )
+ {
+ break;
+ }
+ }
+ if( service->serviceType )
+ {
+ // Create a URL representing the service instance. Special case for SMB (no port number).
+
+ if( strcmp( service->serviceType, "_smb._tcp" ) == 0 )
+ {
+ url.Format( "%s%s/", service->urlScheme, (const char *) p->ip.c_str() );
+ }
+ else
+ {
+ const char * text;
+
+ text = service->useText ? p->text.c_str() : "";
+ url.Format( "%s%s/%s", service->urlScheme, (const char *) p->ip.c_str(), text );
+ }
+
+ // Let the system open the URL in the correct app.
+
+ ShellExecute( NULL, "open", url, "", "c:\\", SW_SHOWNORMAL );
+ }
+ }
+ *pResult = 0;
+}
+
+//===========================================================================================================================
+// OnCancel
+//===========================================================================================================================
+
+void ChooserDialog::OnCancel()
+{
+ // Do nothing.
+}
+
+//===========================================================================================================================
+// PopulateServicesList
+//===========================================================================================================================
+
+void ChooserDialog::PopulateServicesList( void )
+{
+ ServiceTypeVector::iterator i;
+ CString name;
+
+ // Add a fixed list of known services.
+
+ if( mServiceTypes.empty() )
+ {
+ const KnownServiceEntry * service;
+
+ for( service = kKnownServiceTable; service->serviceType; ++service )
+ {
+ ServiceTypeInfo info;
+
+ info.serviceType = service->serviceType;
+ info.description = service->description;
+ info.urlScheme = service->urlScheme;
+ mServiceTypes.push_back( info );
+ }
+ }
+
+ // Add each service to the list.
+
+ for( i = mServiceTypes.begin(); i != mServiceTypes.end(); ++i )
+ {
+ UTF8StringToStringObject( ( *i ).description.c_str(), name );
+ mServiceList.InsertItem( mServiceList.GetItemCount(), name );
+ }
+
+ // Select the first service type by default.
+
+ if( !mServiceTypes.empty() )
+ {
+ mServiceList.SetItemState( 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
+ }
+}
+
+//===========================================================================================================================
+// UpdateInfoDisplay
+//===========================================================================================================================
+
+void ChooserDialog::UpdateInfoDisplay( void )
+{
+ int selectedItem;
+ std::string name;
+ CString s;
+ std::string ip;
+ std::string ifIP;
+ std::string text;
+ CWnd * item;
+
+ // Display the service instance if it is selected. Otherwise, clear all the info.
+
+ selectedItem = mChooserList.GetNextItem( -1, LVNI_SELECTED );
+ if( selectedItem >= 0 )
+ {
+ ServiceInstanceInfo * p;
+
+ assert( selectedItem < (int) mServiceInstances.size() );
+ p = &mServiceInstances[ selectedItem ];
+
+ name = p->name;
+ ip = p->ip;
+ ifIP = p->ifIP;
+ text = p->text;
+
+ // Sync up the list items with the actual data (IP address may change).
+
+ mChooserList.SetItemText( selectedItem, 1, ip.c_str() );
+ }
+
+ // Name
+
+ item = (CWnd *) this->GetDlgItem( IDC_INFO_NAME_TEXT );
+ assert( item );
+ UTF8StringToStringObject( name.c_str(), s );
+ item->SetWindowText( s );
+
+ // IP
+
+ item = (CWnd *) this->GetDlgItem( IDC_INFO_IP_TEXT );
+ assert( item );
+ item->SetWindowText( ip.c_str() );
+
+ // Interface
+
+ item = (CWnd *) this->GetDlgItem( IDC_INFO_INTERFACE_TEXT );
+ assert( item );
+ item->SetWindowText( ifIP.c_str() );
+
+ // Text
+
+ if( text.size() > 255 )
+ {
+ text.resize( 255 );
+ }
+ item = (CWnd *) this->GetDlgItem( IDC_INFO_TEXT_TEXT );
+ assert( item );
+ item->SetWindowText( text.c_str() );
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+// OnDomainAdd
+//===========================================================================================================================
+
+LONG ChooserDialog::OnDomainAdd( WPARAM inWParam, LPARAM inLParam )
+{
+ DomainEventInfo * p;
+ std::auto_ptr < DomainEventInfo > pAutoPtr;
+ int n;
+ int i;
+ CString domain;
+ CString s;
+ bool found;
+
+ UNUSED_ALWAYS( inWParam );
+
+ assert( inLParam );
+ p = reinterpret_cast <DomainEventInfo *> ( inLParam );
+ pAutoPtr.reset( p );
+
+ // Search to see if we already know about this domain. If not, add it to the list.
+
+ found = false;
+ domain = p->domain;
+ n = mDomainList.GetItemCount();
+ for( i = 0; i < n; ++i )
+ {
+ s = mDomainList.GetItemText( i, 0 );
+ if( s == domain )
+ {
+ found = true;
+ break;
+ }
+ }
+ if( !found )
+ {
+ int selectedItem;
+
+ mDomainList.InsertItem( n, domain );
+
+ // If no domains are selected and the domain being added is a default domain, select it.
+
+ selectedItem = mDomainList.GetNextItem( -1, LVNI_SELECTED );
+ if( ( selectedItem < 0 ) && ( p->eventType == kDNSBrowserEventTypeAddDefaultDomain ) )
+ {
+ mDomainList.SetItemState( n, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
+ }
+ }
+ return( 0 );
+}
+
+//===========================================================================================================================
+// OnDomainRemove
+//===========================================================================================================================
+
+LONG ChooserDialog::OnDomainRemove( WPARAM inWParam, LPARAM inLParam )
+{
+ DomainEventInfo * p;
+ std::auto_ptr < DomainEventInfo > pAutoPtr;
+ int n;
+ int i;
+ CString domain;
+ CString s;
+ bool found;
+
+ UNUSED_ALWAYS( inWParam );
+
+ assert( inLParam );
+ p = reinterpret_cast <DomainEventInfo *> ( inLParam );
+ pAutoPtr.reset( p );
+
+ // Search to see if we know about this domain. If so, remove it from the list.
+
+ found = false;
+ domain = p->domain;
+ n = mDomainList.GetItemCount();
+ for( i = 0; i < n; ++i )
+ {
+ s = mDomainList.GetItemText( i, 0 );
+ if( s == domain )
+ {
+ found = true;
+ break;
+ }
+ }
+ if( found )
+ {
+ mDomainList.DeleteItem( i );
+ }
+ return( 0 );
+}
+
+//===========================================================================================================================
+// OnServiceAdd
+//===========================================================================================================================
+
+LONG ChooserDialog::OnServiceAdd( WPARAM inWParam, LPARAM inLParam )
+{
+ ServiceEventInfo * p;
+ std::auto_ptr < ServiceEventInfo > pAutoPtr;
+
+ UNUSED_ALWAYS( inWParam );
+
+ assert( inLParam );
+ p = reinterpret_cast <ServiceEventInfo *> ( inLParam );
+ pAutoPtr.reset( p );
+
+ return( 0 );
+}
+
+//===========================================================================================================================
+// OnServiceRemove
+//===========================================================================================================================
+
+LONG ChooserDialog::OnServiceRemove( WPARAM inWParam, LPARAM inLParam )
+{
+ ServiceEventInfo * p;
+ std::auto_ptr < ServiceEventInfo > pAutoPtr;
+ bool found;
+ int n;
+ int i;
+
+ UNUSED_ALWAYS( inWParam );
+
+ assert( inLParam );
+ p = reinterpret_cast <ServiceEventInfo *> ( inLParam );
+ pAutoPtr.reset( p );
+
+ // Search to see if we know about this service instance. If so, remove it from the list.
+
+ found = false;
+ n = (int) mServiceInstances.size();
+ for( i = 0; i < n; ++i )
+ {
+ ServiceInstanceInfo * q;
+
+ // If the name, type, domain, and interface match, treat it as the same service instance.
+
+ q = &mServiceInstances[ i ];
+ if( ( p->name == q->name ) &&
+ ( p->type == q->type ) &&
+ ( p->domain == q->domain ) )
+ {
+ found = true;
+ break;
+ }
+ }
+ if( found )
+ {
+ mChooserList.DeleteItem( i );
+ assert( i < (int) mServiceInstances.size() );
+ mServiceInstances.erase( mServiceInstances.begin() + i );
+ }
+ return( 0 );
+}
+
+//===========================================================================================================================
+// OnResolve
+//===========================================================================================================================
+
+LONG ChooserDialog::OnResolve( WPARAM inWParam, LPARAM inLParam )
+{
+ ServiceInstanceInfo * p;
+ std::auto_ptr < ServiceInstanceInfo > pAutoPtr;
+ int selectedType;
+ int n;
+ int i;
+ bool found;
+
+ UNUSED_ALWAYS( inWParam );
+
+ assert( inLParam );
+ p = reinterpret_cast <ServiceInstanceInfo *> ( inLParam );
+ pAutoPtr.reset( p );
+
+ // Make sure it is for an item of the correct type. This handles any resolves that may have been queued up.
+
+ selectedType = mServiceList.GetNextItem( -1, LVNI_SELECTED );
+ assert( selectedType >= 0 );
+ if( selectedType >= 0 )
+ {
+ assert( selectedType <= (int) mServiceTypes.size() );
+ if( p->type != mServiceTypes[ selectedType ].serviceType )
+ {
+ goto exit;
+ }
+ }
+
+ // Search to see if we know about this service instance. If so, update its info. Otherwise, add it to the list.
+
+ found = false;
+ n = (int) mServiceInstances.size();
+ for( i = 0; i < n; ++i )
+ {
+ ServiceInstanceInfo * q;
+
+ // If the name, type, domain, and interface matches, treat it as the same service instance.
+
+ q = &mServiceInstances[ i ];
+ if( ( p->name == q->name ) &&
+ ( p->type == q->type ) &&
+ ( p->domain == q->domain ) &&
+ ( p->ifIP == q->ifIP ) )
+ {
+ found = true;
+ break;
+ }
+ }
+ if( found )
+ {
+ mServiceInstances[ i ] = *p;
+ }
+ else
+ {
+ CString s;
+
+ mServiceInstances.push_back( *p );
+ UTF8StringToStringObject( p->name.c_str(), s );
+ mChooserList.InsertItem( n, s );
+ mChooserList.SetItemText( n, 1, p->ip.c_str() );
+
+ // If this is the only item, select it.
+
+ if( n == 0 )
+ {
+ mChooserList.SetItemState( n, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
+ }
+ }
+ UpdateInfoDisplay();
+
+exit:
+ return( 0 );
+}
+
+//===========================================================================================================================
+// StartBrowsing
+//===========================================================================================================================
+
+void ChooserDialog::StartBrowsing( const char *inType, const char *inDomain )
+{
+ DNSStatus err;
+
+ assert( mServiceInstances.empty() );
+ assert( mChooserList.GetItemCount() == 0 );
+ assert( !mIsServiceBrowsing );
+
+ mChooserList.DeleteAllItems();
+ mServiceInstances.clear();
+
+ mIsServiceBrowsing = true;
+ err = DNSBrowserStartServiceSearch( mBrowser, kDNSBrowserFlagAutoResolve, inType, inDomain );
+ assert( err == kDNSNoErr );
+}
+
+//===========================================================================================================================
+// StopBrowsing
+//===========================================================================================================================
+
+void ChooserDialog::StopBrowsing( void )
+{
+ // If searching, stop.
+
+ if( mIsServiceBrowsing )
+ {
+ DNSStatus err;
+
+ mIsServiceBrowsing = false;
+ err = DNSBrowserStopServiceSearch( mBrowser, 0 );
+ assert( err == kDNSNoErr );
+ }
+
+ // Remove all service instances.
+
+ mChooserList.DeleteAllItems();
+ assert( mChooserList.GetItemCount() == 0 );
+ mServiceInstances.clear();
+ assert( mServiceInstances.empty() );
+ UpdateInfoDisplay();
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+// BrowserCallBack
+//===========================================================================================================================
+
+static void
+ BrowserCallBack(
+ void * inContext,
+ DNSBrowserRef inRef,
+ DNSStatus inStatusCode,
+ const DNSBrowserEvent * inEvent )
+{
+ ChooserDialog * dialog;
+ UINT message;
+ BOOL posted;
+
+ UNUSED_ALWAYS( inStatusCode );
+ UNUSED_ALWAYS( inRef );
+
+ // Check parameters.
+
+ assert( inContext );
+ dialog = reinterpret_cast <ChooserDialog *> ( inContext );
+
+ try
+ {
+ switch( inEvent->type )
+ {
+ case kDNSBrowserEventTypeRelease:
+ break;
+
+ // Domains
+
+ case kDNSBrowserEventTypeAddDomain:
+ case kDNSBrowserEventTypeAddDefaultDomain:
+ case kDNSBrowserEventTypeRemoveDomain:
+ {
+ DomainEventInfo * domain;
+ std::auto_ptr < DomainEventInfo > domainAutoPtr;
+
+ domain = new DomainEventInfo;
+ domainAutoPtr.reset( domain );
+
+ domain->eventType = inEvent->type;
+ domain->domain = inEvent->data.addDomain.domain;
+ domain->ifIP = inEvent->data.addDomain.interfaceIP;
+
+ message = ( inEvent->type == kDNSBrowserEventTypeRemoveDomain ) ? WM_USER_DOMAIN_REMOVE : WM_USER_DOMAIN_ADD;
+ posted = ::PostMessage( dialog->GetSafeHwnd(), message, 0, (LPARAM) domain );
+ assert( posted );
+ if( posted )
+ {
+ domainAutoPtr.release();
+ }
+ break;
+ }
+
+ // Services
+
+ case kDNSBrowserEventTypeAddService:
+ case kDNSBrowserEventTypeRemoveService:
+ {
+ ServiceEventInfo * service;
+ std::auto_ptr < ServiceEventInfo > serviceAutoPtr;
+
+ service = new ServiceEventInfo;
+ serviceAutoPtr.reset( service );
+
+ service->eventType = inEvent->type;
+ service->name = inEvent->data.addService.name;
+ service->type = inEvent->data.addService.type;
+ service->domain = inEvent->data.addService.domain;
+ service->ifIP = inEvent->data.addService.interfaceIP;
+
+ message = ( inEvent->type == kDNSBrowserEventTypeAddService ) ? WM_USER_SERVICE_ADD : WM_USER_SERVICE_REMOVE;
+ posted = ::PostMessage( dialog->GetSafeHwnd(), message, 0, (LPARAM) service );
+ assert( posted );
+ if( posted )
+ {
+ serviceAutoPtr.release();
+ }
+ break;
+ }
+
+ // Resolves
+
+ case kDNSBrowserEventTypeResolved:
+ {
+ ServiceInstanceInfo * serviceInstance;
+ std::auto_ptr < ServiceInstanceInfo > serviceInstanceAutoPtr;
+ char s[ 32 ];
+
+ serviceInstance = new ServiceInstanceInfo;
+ serviceInstanceAutoPtr.reset( serviceInstance );
+
+ serviceInstance->name = inEvent->data.resolved->name;
+ serviceInstance->type = inEvent->data.resolved->type;
+ serviceInstance->domain = inEvent->data.resolved->domain;
+ serviceInstance->ip = DNSNetworkAddressToString( &inEvent->data.resolved->address, s );
+ serviceInstance->ifIP = DNSNetworkAddressToString( &inEvent->data.resolved->interfaceIP, s );
+ serviceInstance->text = inEvent->data.resolved->textRecord;
+
+ posted = ::PostMessage( dialog->GetSafeHwnd(), WM_USER_RESOLVE, 0, (LPARAM) serviceInstance );
+ assert( posted );
+ if( posted )
+ {
+ serviceInstanceAutoPtr.release();
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ catch( ... )
+ {
+ // Don't let exceptions escape.
+ }
+}
+
+//===========================================================================================================================
+// DNSNetworkAddressToString
+//
+// Note: Currently only supports IPv4 network addresses.
+//===========================================================================================================================
+
+static char * DNSNetworkAddressToString( const DNSNetworkAddress *inAddr, char *outString )
+{
+ const DNSUInt8 * p;
+ DNSUInt16 port;
+
+ p = inAddr->u.ipv4.addr.v8;
+ port = ntohs( inAddr->u.ipv4.port.v16 );
+ if( port != kDNSPortInvalid )
+ {
+ sprintf( outString, "%u.%u.%u.%u:%u", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ], port );
+ }
+ else
+ {
+ sprintf( outString, "%u.%u.%u.%u", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] );
+ }
+ return( outString );
+}
+
+//===========================================================================================================================
+// UTF8StringToStringObject
+//===========================================================================================================================
+
+static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject )
+{
+ DWORD 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 = 0;
+
+exit:
+ if( unicode )
+ {
+ free( unicode );
+ }
+ return( err );
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: ChooserDialog.h,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.4 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/20 06:12:52 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#if !defined(AFX_CHOOSERDIALOG_H__AC258704_B307_4901_9F98_A0AC022FD8AC__INCLUDED_)
+#define AFX_CHOOSERDIALOG_H__AC258704_B307_4901_9F98_A0AC022FD8AC__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <string>
+#include <vector>
+
+#include "afxcmn.h"
+
+#include "Resource.h"
+
+#include "DNSServices.h"
+
+//===========================================================================================================================
+// Structures
+//===========================================================================================================================
+
+struct ServiceInstanceInfo
+{
+ std::string name;
+ std::string type;
+ std::string domain;
+ std::string ip;
+ std::string text;
+ std::string ifIP;
+};
+
+struct ServiceTypeInfo
+{
+ std::string serviceType;
+ std::string description;
+ std::string urlScheme;
+};
+
+//===========================================================================================================================
+// ChooserDialog
+//===========================================================================================================================
+
+class ChooserDialog : public CDialog
+{
+ public:
+
+ ChooserDialog(CWnd* pParent = NULL);
+ virtual ~ChooserDialog( void );
+
+ //{{AFX_DATA(ChooserDialog)
+ enum { IDD = IDD_CHOOSER_DIALOG };
+ CListCtrl mServiceList;
+ CListCtrl mDomainList;
+ CListCtrl mChooserList;
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(ChooserDialog)
+ public:
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ virtual void PostNcDestroy();
+ //}}AFX_VIRTUAL
+
+ protected:
+
+ typedef std::vector < ServiceInstanceInfo > ServiceInstanceVector;
+ typedef std::vector < ServiceTypeInfo > ServiceTypeVector;
+
+ HACCEL mMenuAcceleratorTable;
+ DNSBrowserRef mBrowser;
+ BOOL mIsServiceBrowsing;
+ ServiceInstanceVector mServiceInstances;
+ ServiceTypeVector mServiceTypes;
+
+ public:
+
+ void PopulateServicesList( void );
+ void UpdateInfoDisplay( void );
+
+ void StartBrowsing( const char *inType, const char *inDomain );
+ void StopBrowsing( void );
+
+ protected:
+
+ //{{AFX_MSG(ChooserDialog)
+ virtual BOOL OnInitDialog();
+ afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+ afx_msg void OnDomainListChanged(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnServiceListChanged(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnChooserListChanged(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnChooserListDoubleClick(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnAbout();
+ afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
+ afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
+ afx_msg void OnFileClose();
+ virtual void OnCancel();
+ afx_msg void OnExit();
+ afx_msg void OnClose();
+ afx_msg void OnNcDestroy();
+ //}}AFX_MSG
+ afx_msg LONG OnDomainAdd( WPARAM inWParam, LPARAM inLParam );
+ afx_msg LONG OnDomainRemove( WPARAM inWParam, LPARAM inLParam );
+ afx_msg LONG OnServiceAdd( WPARAM inWParam, LPARAM inLParam );
+ afx_msg LONG OnServiceRemove( WPARAM inWParam, LPARAM inLParam );
+ afx_msg LONG OnResolve( WPARAM inWParam, LPARAM inLParam );
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CHOOSERDIALOG_H__AC258704_B307_4901_9F98_A0AC022FD8AC__INCLUDED_)
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: StdAfx.cpp,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.4 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:55 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/20 06:12:53 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#include "stdafx.h"
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: StdAfx.h,v $
+Revision 1.1 2003/08/21 02:06:47 bradley
+Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
+
+Revision 1.4 2003/08/12 19:56:28 cheshire
+Update to APSL 2.0
+
+Revision 1.3 2003/07/02 21:20:06 cheshire
+<rdar://problem/3313413> Update copyright notices, etc., in source code comments
+
+Revision 1.2 2002/09/21 20:44:56 zarzycki
+Added APSL info
+
+Revision 1.1 2002/09/20 06:12:53 bradley
+Rendezvous Browser for Windows
+
+*/
+
+#if !defined(AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_)
+#define AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxsock.h> // MFC socket extensions
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#include <stdlib.h>
+
+#include "DNSServices.h"
+
+#include "Application.h"
+
+#include "ChooserDialog.h"
+
+#endif // !defined(AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_)
--- /dev/null
+; CLW file contains information for the MFC ClassWizard
+
+[General Info]
+Version=1
+LastClass=BrowserDialog
+LastTemplate=CDialog
+NewFileInclude1=#include "stdafx.h"
+NewFileInclude2=#include "Application.h"
+
+ClassCount=3
+Class1=Application
+Class2=BrowserDialog
+
+ResourceCount=3
+Resource2=IDR_MAINFRAME
+Resource3=IDD_APPLICATION_DIALOG
+
+[CLS:Application]
+Type=0
+HeaderFile=Application.h
+ImplementationFile=Application.cpp
+Filter=N
+
+[CLS:BrowserDialog]
+Type=0
+HeaderFile=BrowserDialog.h
+ImplementationFile=BrowserDialog.cpp
+Filter=D
+
+
+[DLG:IDD_APPLICATION_DIALOG]
+Type=1
+ControlCount=3
+Control1=IDOK,button,1342242817
+Control2=IDCANCEL,button,1342242816
+Control3=IDC_STATIC,static,1342308352
+Class=BrowserDialog
--- /dev/null
+# Microsoft eMbedded Visual Tools Project File - Name="Application" - Package Owner=<4>
+# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (WCE ARMV4) Application" 0xa301
+# TARGTYPE "Win32 (WCE emulator) Application" 0xa601
+
+CFG=Application - Win32 (WCE emulator) Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "Application.vcn".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "Application.vcn" CFG="Application - Win32 (WCE emulator) Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Application - Win32 (WCE emulator) Release" (based on "Win32 (WCE emulator) Application")
+!MESSAGE "Application - Win32 (WCE emulator) Debug" (based on "Win32 (WCE emulator) Application")
+!MESSAGE "Application - Win32 (WCE ARMV4) Release" (based on "Win32 (WCE ARMV4) Application")
+!MESSAGE "Application - Win32 (WCE ARMV4) Debug" (based on "Win32 (WCE ARMV4) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+# PROP ATL_Project 2
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "emulatorRel"
+# PROP BASE Intermediate_Dir "emulatorRel"
+# PROP BASE CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
+# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "emulatorRel"
+# PROP Intermediate_Dir "emulatorRel"
+# PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
+# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
+# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "NDEBUG" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /Yu"stdafx.h" /Gs8192 /GF /O2 /c
+# ADD CPP /nologo /W3 /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "NDEBUG" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /Gs8192 /GF /O2 /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /MACHINE:IX86
+# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /MACHINE:IX86
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "emulatorDbg"
+# PROP BASE Intermediate_Dir "emulatorDbg"
+# PROP BASE CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
+# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "emulatorDbg"
+# PROP Intermediate_Dir "emulatorDbg"
+# PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
+# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
+# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /Yu"stdafx.h" /Gs8192 /GF /c
+# ADD CPP /nologo /W3 /WX /Zi /Od /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /FR /Gs8192 /GF /c
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /MACHINE:IX86
+# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /MACHINE:IX86
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ARMV4Rel"
+# PROP BASE Intermediate_Dir "ARMV4Rel"
+# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
+# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "ARMV4Rel"
+# PROP Intermediate_Dir "ARMV4Rel"
+# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
+# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
+# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
+CPP=clarm.exe
+# ADD BASE CPP /nologo /W3 /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_AFXDLL" /Yu"stdafx.h" /O2 /M$(CECrtMT) /c
+# ADD CPP /nologo /W3 /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_AFXDLL" /O2 /M$(CECrtMT) /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
+# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+# PROP BASE Use_MFC 2
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "ARMV4Dbg"
+# PROP BASE Intermediate_Dir "ARMV4Dbg"
+# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
+# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "ARMV4Dbg"
+# PROP Intermediate_Dir "ARMV4Dbg"
+# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
+# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
+# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
+CPP=clarm.exe
+# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /Yu"stdafx.h" /M$(CECrtMTDebug) /c
+# ADD CPP /nologo /W3 /Zi /Od /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /M$(CECrtMTDebug) /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
+# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
+
+!ENDIF
+
+# Begin Target
+
+# Name "Application - Win32 (WCE emulator) Release"
+# Name "Application - Win32 (WCE emulator) Debug"
+# Name "Application - Win32 (WCE ARMV4) Release"
+# Name "Application - Win32 (WCE ARMV4) Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Sources\Application.cpp
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_APPLI=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_APPLI=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_APPLI=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_APPLI=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Sources\Application.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Sources\BrowserDialog.cpp
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_BROWS=\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_BROWS=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_BROWS=\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_BROWS=\
+ ".\Sources\Application.h"\
+ ".\Sources\BrowserDialog.h"\
+ ".\Sources\StdAfx.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Sources\BrowserDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Sources\StdAfx.cpp
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_STDAF=\
+ ".\Sources\StdAfx.h"\
+
+# ADD CPP /Yc"stdafx.h"
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_STDAF=\
+ ".\Sources\StdAfx.h"\
+
+# ADD CPP /Yc"stdafx.h"
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_STDAF=\
+ ".\Sources\StdAfx.h"\
+
+# ADD CPP /Yc"stdafx.h"
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_STDAF=\
+ ".\Sources\StdAfx.h"\
+
+# ADD CPP /Yc"stdafx.h"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Sources\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Resources\Application.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resources\Application.rc
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resources\Application.rc2
+# PROP Exclude_From_Scan -1
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resources\newres.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resources\Resource.h
+# End Source File
+# End Group
+# Begin Group "Rendezvous"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\DNSServices\DNSServices.c
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DNSSE=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DNSSE=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DNSSE=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DNSSE=\
+ "..\..\..\DNSServices\DNSServices.h"\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DNSServices\DNSServices.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\mDNS.c
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_MDNS_=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_MDNS_=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_MDNS_=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_MDNS_=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\mDNSClientAPI.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\mDNSDebug.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\mDNSPlatformFunctions.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\mDNSWin32.c
+
+!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_MDNSW=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+ "..\..\..\mDNSWin32.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_MDNSW=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+ "..\..\..\mDNSWin32.h"\
+
+# ADD CPP /W3
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_MDNSW=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+ "..\..\..\mDNSWin32.h"\
+
+
+!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_MDNSW=\
+ "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+ "..\..\..\..\mDNSCore\mDNSDebug.h"\
+ "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
+ "..\..\..\mDNSWin32.h"\
+
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\mDNSWin32.h
+# End Source File
+# End Group
+# End Target
+# End Project
--- /dev/null
+Microsoft eMbedded Visual Tools Workspace File, Format Version 4.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Application"=.\Application.vcp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+//Microsoft eMbedded Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "newres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""newres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#endif //_WIN32\r\n"
+ "#include ""Resources\\Application.rc2"" // non-Microsoft eMbedded Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#include ""wceres.rc"" // WCE-specific components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON DISCARDABLE "Application.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_APPLICATION_DIALOG DIALOG DISCARDABLE 0, 0, 139, 153
+STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION
+EXSTYLE WS_EX_APPWINDOW | 0x80000000L
+CAPTION "Rendezvous Browser"
+FONT 8, "System"
+BEGIN
+ CONTROL "List1",IDC_BROWSE_LIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER |
+ WS_BORDER | WS_TABSTOP,7,7,125,141
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "Apple Computer, Inc.\0"
+ VALUE "FileDescription", "Rendezvous Browser for Windows CE\0"
+ VALUE "FileVersion", "1, 0, 0, 1\0"
+ VALUE "InternalName", "Application\0"
+ VALUE "LegalCopyright", "Copyright © 2003 Apple Computer, Inc.\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "Application.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "Rendezvous Browser for Windows CE\0"
+ VALUE "ProductVersion", "1, 0, 0, 1\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_APPLICATION_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 132
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 146
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDP_SOCKETS_INIT_FAILED "Windows CE sockets initialization failed."
+ IDS_BROWSER_LIST_COLUMN_NAME "Name"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+#include "Resources\Application.rc2" // non-Microsoft eMbedded Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#include "wceres.rc" // WCE-specific components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
--- /dev/null
+//
+// APPLICATION.RC2 - resources Microsoft eMbedded Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft eMbedded Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
--- /dev/null
+#ifndef __NEWRES_H__
+#define __NEWRES_H__
+
+#define SHMENUBAR RCDATA
+#if !(defined(_WIN32_WCE_PSPC) && (_WIN32_WCE >= 300))
+ #undef HDS_HORZ
+ #undef HDS_BUTTONS
+ #undef HDS_HIDDEN
+
+ #include <commctrl.h>
+ // for MenuBar
+ #define I_IMAGENONE (-2)
+ #define NOMENU 0xFFFF
+ #define IDS_SHNEW 1
+ #define IDM_SHAREDNEW 10
+ #define IDM_SHAREDNEWDEFAULT 11
+
+ // for Tab Control
+ #define TCS_SCROLLOPPOSITE 0x0001 // assumes multiline tab
+ #define TCS_BOTTOM 0x0002
+ #define TCS_RIGHT 0x0002
+ #define TCS_VERTICAL 0x0080
+ #define TCS_MULTISELECT 0x0004 // allow multi-select in button mode
+ #define TCS_FLATBUTTONS 0x0008
+#endif //_WIN32_WCE_PSPC
+
+
+#endif //__NEWRES_H__
--- /dev/null
+//{{NO_DEPENDENCIES}}
+// Microsoft eMbedded Visual C++ generated include file.
+// Used by Application.rc
+//
+#define IDD_APPLICATION_DIALOG 102
+#define IDP_SOCKETS_INIT_FAILED 103
+#define IDS_BROWSER_LIST_COLUMN_NAME 104
+#define IDR_MAINFRAME 128
+#define IDC_BROWSE_LIST 1000
+#define IDC_IP_TEXT 1003
+#define IDC_TXT_TEXT 1004
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 129
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1005
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: Application.cpp,v $
+Revision 1.1 2003/08/21 02:16:10 bradley
+Rendezvous Browser for HTTP services for Windows CE/PocketPC.
+
+*/
+
+#include "stdafx.h"
+
+#include "DNSServices.h"
+
+#include "BrowserDialog.h"
+
+#include "Application.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//===========================================================================================================================
+// Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP(Application, CWinApp)
+ //{{AFX_MSG_MAP(Application)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+//===========================================================================================================================
+// Globals
+//===========================================================================================================================
+
+Application gApp;
+
+//===========================================================================================================================
+// Application
+//===========================================================================================================================
+
+Application::Application()
+ : CWinApp()
+{
+ //
+}
+
+//===========================================================================================================================
+// InitInstance
+//===========================================================================================================================
+
+BOOL Application::InitInstance()
+{
+ DNSStatus err;
+ BrowserDialog dialog;
+ BOOL dnsInitialized;
+
+ dnsInitialized = FALSE;
+
+ if( !AfxSocketInit() )
+ {
+ AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+ goto exit;
+ }
+
+ err = DNSServicesInitialize( kDNSFlagAdvertise, 0 );
+ if( err )
+ {
+ AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+ goto exit;
+ }
+ dnsInitialized = TRUE;
+
+ // Display the main browser dialog.
+
+ m_pMainWnd = &dialog;
+ dialog.DoModal();
+
+ // Dialog has been closed. Return false to exit the app and not start the app's message pump.
+
+exit:
+ if( dnsInitialized )
+ {
+ DNSServicesFinalize();
+ }
+ return( FALSE );
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: Application.h,v $
+Revision 1.1 2003/08/21 02:16:10 bradley
+Rendezvous Browser for HTTP services for Windows CE/PocketPC.
+
+*/
+
+#if !defined(AFX_APPLICATION_H__E2E51302_D643_458E_A7A5_5157233D1E5C__INCLUDED_)
+#define AFX_APPLICATION_H__E2E51302_D643_458E_A7A5_5157233D1E5C__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "Resource.h"
+
+//===========================================================================================================================
+// Application
+//===========================================================================================================================
+
+class Application : public CWinApp
+{
+ public:
+
+ Application();
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(Application)
+ public:
+ virtual BOOL InitInstance();
+ //}}AFX_VIRTUAL
+
+ //{{AFX_MSG(Application)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_APPLICATION_H__E2E51302_D643_458E_A7A5_5157233D1E5C__INCLUDED_)
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: BrowserDialog.cpp,v $
+Revision 1.1 2003/08/21 02:16:10 bradley
+Rendezvous Browser for HTTP services for Windows CE/PocketPC.
+
+*/
+
+#include "stdafx.h"
+
+#include "Application.h"
+
+#include "DNSServices.h"
+
+#include "BrowserDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//===========================================================================================================================
+// Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP(BrowserDialog, CDialog)
+ //{{AFX_MSG_MAP(BrowserDialog)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject );
+
+//===========================================================================================================================
+// BrowserDialog
+//===========================================================================================================================
+
+BrowserDialog::BrowserDialog( CWnd *inParent )
+ : CDialog( BrowserDialog::IDD, inParent )
+{
+ //{{AFX_DATA_INIT(BrowserDialog)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+
+ // Note that LoadIcon does not require a subsequent DestroyIcon in Win32.
+
+ mIcon = AfxGetApp()->LoadIcon( IDR_MAINFRAME );
+}
+
+//===========================================================================================================================
+// DoDataExchange
+//===========================================================================================================================
+
+void BrowserDialog::DoDataExchange( CDataExchange *pDX )
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(BrowserDialog)
+ DDX_Control(pDX, IDC_BROWSE_LIST, mBrowserList);
+ //}}AFX_DATA_MAP
+}
+
+//===========================================================================================================================
+// OnInitDialog
+//===========================================================================================================================
+
+BOOL BrowserDialog::OnInitDialog()
+{
+ CString s;
+
+ CDialog::OnInitDialog();
+
+ // Set the icon for this dialog. The framework does this automatically when the application's main window is not a dialog.
+
+ SetIcon( mIcon, TRUE ); // Set big icon
+ SetIcon( mIcon, FALSE ); // Set small icon
+
+ CenterWindow( GetDesktopWindow() );
+
+ // Set up the list.
+
+ CRect rect;
+
+ s.LoadString( IDS_BROWSER_LIST_COLUMN_NAME );
+ mBrowserList.GetWindowRect( rect );
+ mBrowserList.InsertColumn( 0, s, LVCFMT_LEFT, rect.Width() - 8 );
+
+ // Start browsing for services.
+
+ DNSStatus err;
+
+ err = DNSBrowserCreate( 0, BrowserCallBack, this, &mBrowser );
+ if( err )
+ {
+ AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+ goto exit;
+ }
+
+ err = DNSBrowserStartServiceSearch( mBrowser, 0, "_http._tcp", NULL );
+ if( err )
+ {
+ AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+ goto exit;
+ }
+
+exit:
+ return( TRUE );
+}
+
+//===========================================================================================================================
+// BrowserCallBack [static]
+//===========================================================================================================================
+
+void
+ BrowserDialog::BrowserCallBack(
+ void * inContext,
+ DNSBrowserRef inRef,
+ DNSStatus inStatusCode,
+ const DNSBrowserEvent * inEvent )
+{
+ BrowserDialog * dialog;
+
+ DNS_UNUSED( inStatusCode );
+ dialog = reinterpret_cast < BrowserDialog * > ( inContext );
+
+ switch( inEvent->type )
+ {
+ case kDNSBrowserEventTypeAddService:
+ dialog->BrowserAddService( inEvent->data.addService.name );
+ break;
+
+ case kDNSBrowserEventTypeRemoveService:
+ dialog->BrowserRemoveService( inEvent->data.removeService.name );
+ break;
+
+ default:
+ break;
+ }
+}
+
+//===========================================================================================================================
+// BrowserAddService
+//===========================================================================================================================
+
+void BrowserDialog::BrowserAddService( const char *inName )
+{
+ BrowserEntry newEntry;
+ INT_PTR n;
+ INT_PTR i;
+
+ UTF8StringToStringObject( inName, newEntry.name );
+
+ n = mBrowserEntries.GetSize();
+ for( i = 0; i < n; ++i )
+ {
+ BrowserEntry & entry = mBrowserEntries.ElementAt( i );
+
+ if( entry.name.CompareNoCase( newEntry.name ) == 0 )
+ {
+ break;
+ }
+ }
+ if( i >= n )
+ {
+ mBrowserEntries.Add( newEntry );
+ mBrowserList.InsertItem( i, newEntry.name );
+ }
+}
+
+//===========================================================================================================================
+// BrowserRemoveService
+//===========================================================================================================================
+
+void BrowserDialog::BrowserRemoveService( const char *inName )
+{
+ BrowserEntry newEntry;
+ INT_PTR n;
+ INT_PTR i;
+
+ UTF8StringToStringObject( inName, newEntry.name );
+
+ n = mBrowserEntries.GetSize();
+ for( i = 0; i < n; ++i )
+ {
+ BrowserEntry & entry = mBrowserEntries.ElementAt( i );
+
+ if( entry.name.CompareNoCase( newEntry.name ) == 0 )
+ {
+ break;
+ }
+ }
+ if( i < n )
+ {
+ mBrowserEntries.RemoveAt( i );
+ mBrowserList.DeleteItem( i );
+ }
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+// UTF8StringToStringObject
+//===========================================================================================================================
+
+static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject )
+{
+ DWORD err;
+ int n;
+ wchar_t * unicode;
+
+ unicode = NULL;
+
+ n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, NULL, 0 );
+ if( n > 0 )
+ {
+ unicode = (wchar_t *) malloc( (size_t)( n * sizeof( wchar_t ) ) );
+ if( !unicode ) { err = ERROR_INSUFFICIENT_BUFFER; goto exit; };
+
+ n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, unicode, n );
+ inObject = unicode;
+ }
+ else
+ {
+ inObject = "";
+ }
+ err = 0;
+
+exit:
+ if( unicode )
+ {
+ free( unicode );
+ }
+ return( err );
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: BrowserDialog.h,v $
+Revision 1.1 2003/08/21 02:16:10 bradley
+Rendezvous Browser for HTTP services for Windows CE/PocketPC.
+
+*/
+
+#if !defined(AFX_BROWSERDIALOG_H__DECC5C82_C1C6_4630_B8D5_E1DDE570A061__INCLUDED_)
+#define AFX_BROWSERDIALOG_H__DECC5C82_C1C6_4630_B8D5_E1DDE570A061__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "afxtempl.h"
+#include "Resource.h"
+
+#include "DNSServices.h"
+
+//===========================================================================================================================
+// BrowserDialog
+//===========================================================================================================================
+
+class BrowserDialog : public CDialog
+{
+ public:
+
+ BrowserDialog( CWnd *inParent = NULL );
+
+ //{{AFX_DATA(BrowserDialog)
+ enum { IDD = IDD_APPLICATION_DIALOG };
+ CListCtrl mBrowserList;
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(BrowserDialog)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+ static void
+ BrowserCallBack(
+ void * inContext,
+ DNSBrowserRef inRef,
+ DNSStatus inStatusCode,
+ const DNSBrowserEvent * inEvent );
+
+ void BrowserAddService( const char *inName );
+ void BrowserRemoveService( const char *inName );
+
+ protected:
+
+ struct BrowserEntry
+ {
+ CString name;
+ };
+
+
+ HICON mIcon;
+ DNSBrowserRef mBrowser;
+ CArray < BrowserEntry, BrowserEntry > mBrowserEntries;
+
+ // Generated message map functions
+ //{{AFX_MSG(BrowserDialog)
+ virtual BOOL OnInitDialog();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_BROWSERDIALOG_H__DECC5C82_C1C6_4630_B8D5_E1DDE570A061__INCLUDED_)
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: StdAfx.cpp,v $
+Revision 1.1 2003/08/21 02:16:10 bradley
+Rendezvous Browser for HTTP services for Windows CE/PocketPC.
+
+*/
+
+#include "stdafx.h"
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: StdAfx.h,v $
+Revision 1.1 2003/08/21 02:16:10 bradley
+Rendezvous Browser for HTTP services for Windows CE/PocketPC.
+
+*/
+
+#if !defined(AFX_STDAFX_H__7F91E52B_CF39_429D_837D_599CE0B2B3D6__INCLUDED_)
+#define AFX_STDAFX_H__7F91E52B_CF39_429D_837D_599CE0B2B3D6__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+
+#if defined(_AFXDLL)
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#endif
+
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxsock.h> // MFC socket extensions
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__7F91E52B_CF39_429D_837D_599CE0B2B3D6__INCLUDED_)
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: Tool.c,v $
+Revision 1.7 2003/08/20 07:06:34 bradley
+Update to APSL 2.0. Updated change history to match other mDNSResponder files.
+
+Revision 1.6 2003/08/20 06:50:55 bradley
+Updated to latest internal version of the Rendezvous for Windows code: Re-did everything to support
+the latest DNSServices APIs (proxies, record updates, etc.); Added support for testing the platform
+neutral DNSServices-based emulation layer for the Mac OS X DNSServiceDiscovery API.
+
+*/
+
+#if( defined( _MSC_VER ) )
+ #pragma warning( disable:4068 ) // Disable "unknown pragma" warning for "pragma unused".
+ #pragma warning( disable:4127 ) // Disable "conditional expression is constant" warning for debug macros.
+ #pragma warning( disable:4311 ) // Disable "type cast : pointer truncation from void *const to int".
+
+ // No stdint.h with Visual C++ so emulate it here.
+
+ typedef signed char int8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
+ typedef unsigned char uint8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
+ typedef signed short int16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
+ typedef unsigned short uint16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
+ typedef signed long int32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
+ typedef unsigned long uint32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
+#else
+ #include <stdint.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if( __MACH__ )
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+
+ #include <signal.h>
+ #include <unistd.h>
+
+ #include <CoreServices/CoreServices.h>
+#else
+ #define WIN32_LEAN_AND_MEAN
+
+ #include <winsock2.h>
+ #include <windows.h>
+#endif
+
+#include "DNSServices.h"
+#include "DNSServiceDiscovery.h"
+
+//===========================================================================================================================
+// Macros
+//===========================================================================================================================
+
+#if( !TARGET_OS_MAC )
+ #define require_action_string( X, LABEL, ACTION, STR ) \
+ do \
+ { \
+ if( !( X ) ) \
+ { \
+ fprintf( stderr, "%s\n", ( STR ) ); \
+ { ACTION; } \
+ goto LABEL; \
+ } \
+ } while( 0 )
+
+ #define require_string( X, LABEL, STR ) \
+ do \
+ { \
+ if( !( X ) ) \
+ { \
+ fprintf( stderr, "%s\n", ( STR ) ); \
+ goto LABEL; \
+ \
+ } \
+ } while( 0 )
+
+ #define require_noerr_string( ERR, LABEL, STR ) \
+ do \
+ { \
+ if( ( ERR ) != 0 ) \
+ { \
+ fprintf( stderr, "%s (%ld)\n", ( STR ), ( ERR ) ); \
+ goto LABEL; \
+ } \
+ } while( 0 )
+#endif
+
+//===========================================================================================================================
+// Prototypes
+//===========================================================================================================================
+
+int main( int argc, char* argv[] );
+static void Usage( void );
+static int ProcessArgs( int argc, char* argv[] );
+static DNSStatus ProcessPreset( int inPreset );
+
+#if( __MACH__ )
+ static void SigIntHandler( int inSignalNumber );
+#endif
+
+#if( defined( WINVER ) )
+ static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent );
+#endif
+
+static void BrowserCallBack( void *inContext, DNSBrowserRef inRef, DNSStatus inStatusCode, const DNSBrowserEvent *inEvent );
+static void ResolverCallBack( void *inContext, DNSResolverRef inRef, DNSStatus inStatusCode, const DNSResolverEvent *inEvent );
+
+static void
+ RegistrationCallBack(
+ void * inContext,
+ DNSRegistrationRef inRef,
+ DNSStatus inStatusCode,
+ const DNSRegistrationEvent * inEvent );
+
+static void
+ HostRegistrationCallBack(
+ void * inContext,
+ DNSHostRegistrationRef inRef,
+ DNSStatus inStatusCode,
+ void * inData );
+
+static void
+ EmulatedBrowserCallBack(
+ DNSServiceBrowserReplyResultType inResult,
+ const char * inName,
+ const char * inType,
+ const char * inDomain,
+ DNSServiceDiscoveryReplyFlags inFlags,
+ void * inContext );
+
+static void
+ EmulatedDomainEnumerationCallBack(
+ DNSServiceDomainEnumerationReplyResultType inResult,
+ const char * inDomain,
+ DNSServiceDiscoveryReplyFlags inFlags,
+ void * inContext );
+
+static void
+ EmulatedResolverCallBack(
+ struct sockaddr * inInterfaceAddr,
+ struct sockaddr * inAddr,
+ const char * inTextRecord,
+ DNSServiceDiscoveryReplyFlags inFlags,
+ void * inContext );
+
+static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult, void *inContext );
+
+static char * IPv4ToString( DNSOpaque32 inIP, char *outString );
+
+//===========================================================================================================================
+// Globals
+//===========================================================================================================================
+
+#if( defined( WINVER ) )
+ static volatile int gQuit = 0;
+#endif
+
+static int gPrintTXTRecords = 1;
+
+// Presets
+
+typedef struct PresetData PresetData;
+struct PresetData
+{
+ int argc;
+ char * argv[ 16 ];
+};
+
+#if 0
+#pragma mark == Presets ==
+#endif
+
+static const PresetData gPresets[] =
+{
+ /* 01 */ { 2, { "rendezvous", "-bbd" } },
+ /* 02 */ { 4, { "rendezvous", "-bs", "_airport._tcp", "local." } },
+ /* 03 */ { 4, { "rendezvous", "-bs", "_xserveraid._tcp", "local." } },
+ /* 04 */ { 3, { "rendezvous", "-rdb", "apple.com" } },
+ /* 05 */ { 7, { "rendezvous", "-rs", "My Fake AirPort", "_airport._tcp", "local.", "1234", "My Fake Info" } },
+ /* 06 */ { 7, { "rendezvous", "-rs", "My Fake Xserve RAID", "_xserveraid._tcp", "local.", "1234", "My Fake Info" } },
+ /* 07 */ { 7, { "rendezvous", "-rs", "My Fake Web Server", "_http._tcp", "local.", "8080", "index.html" } },
+ /* 08 */ { 9, { "rendezvous", "-rps", "www.apple.com", "17.254.0.91", "Apple Web Server", "_http._tcp", "local.", "80", "index.html" } },
+};
+
+const int gPresetsCount = sizeof( gPresets ) / sizeof( gPresets[ 0 ] );
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+// main
+//===========================================================================================================================
+
+int main( int argc, char* argv[] )
+{
+ DNSStatus err;
+
+ // Set up DNS Services and install a Console Control Handler to handle things like control-c signals.
+
+ err = DNSServicesInitialize( kDNSFlagAdvertise, 0 );
+ require_noerr_string( err, exit, "could not initialize Rendezvous" );
+
+#if( __MACH__ )
+ signal( SIGINT, SigIntHandler );
+#endif
+
+#if( defined( WINVER ) )
+ SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
+#endif
+
+ ProcessArgs( argc, argv );
+
+exit:
+ DNSServicesFinalize();
+ return( err );
+}
+
+//===========================================================================================================================
+// Usage
+//===========================================================================================================================
+
+static void Usage( void )
+{
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "rendezvous - Rendezvous Tool 1.0d1\n" );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, " -bbd 'b'rowse for 'b'rowsing 'd'omains\n" );
+ fprintf( stderr, " -brd 'b'rowse for 'r'egistration 'd'omains\n" );
+ fprintf( stderr, " -bs <type> <domain> 'b'rowse for 's'ervices\n" );
+ fprintf( stderr, " -lsi <name> <type> <domain> 'l'ookup 's'ervice 'i'nstance\n" );
+ fprintf( stderr, " -rdb[d] <domain> 'r'egister 'd'omain for 'b'rowsing ['d'efault]\n" );
+ fprintf( stderr, " -rdr[d] <domain> 'r'egister 'd'omain for 'r'egistration ['d'efault]\n" );
+ fprintf( stderr, " -rs <name> <type> <domain> <port> <txt> 'r'egister 's'ervice\n" );
+ fprintf( stderr, " -rps <host> <ip> <name> <type> <domain> <port> <txt> 'r'egister 'p'roxy 's'ervice\n" );
+ fprintf( stderr, " -rnss <name> <type> <domain> 'r'egister 'n'o 's'uch 's'ervice\n" );
+
+ fprintf( stderr, " -ebs <type> <domain> 'e'mulated 'b'rowse for 's'ervices\n" );
+ fprintf( stderr, " -ebd <registration/browse> 'e'mulated 'b'rowse for 'd'omains\n" );
+ fprintf( stderr, " -elsi <name> <type> <domain> 'e'mulated 'l'ookup 's'ervice 'i'nstance\n" );
+ fprintf( stderr, " -ers <name> <type> <domain> <port> <txt> 'e'mulated 'r'egister 's'ervice\n" );
+
+ fprintf( stderr, " -h[elp] 'h'elp\n" );
+ fprintf( stderr, "\n" );
+
+ fprintf( stderr, " -1 Preset 1 (browse for browsing domains) rendezvous -bbd\n" );
+ fprintf( stderr, " -2 Preset 2 (browse for AirPort) rendezvous -bs \"_airport._tcp\" \"local.\"\n" );
+ fprintf( stderr, " -3 Preset 3 (browse for Xserve RAID) rendezvous -bs \"_xserveraid._tcp\" \"local.\"\n" );
+ fprintf( stderr, " -4 Preset 4 (register apple.com domain) rendezvous -rdb \"apple.com\"\n" );
+ fprintf( stderr, " -5 Preset 5 (register fake AirPort) rendezvous -rs \"My Fake AirPort\" \"_airport._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
+ fprintf( stderr, " -6 Preset 6 (register fake Xserve RAID) rendezvous -rs \"My Fake Xserve RAID\" \"_xserveraid._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
+ fprintf( stderr, " -7 Preset 7 (register fake web server) rendezvous -rs \"My Fake Web Server\" \"_http._tcp\" \"local.\" 8080 \"index.html\"\n" );
+ fprintf( stderr, "\n" );
+}
+
+//===========================================================================================================================
+// ProcessArgs
+//===========================================================================================================================
+
+static int ProcessArgs( int argc, char* argv[] )
+{
+ DNSStatus err;
+ int i;
+ const char * name;
+ const char * type;
+ const char * domain;
+ int port;
+ const char * text;
+ size_t textSize;
+ DNSBrowserRef browser;
+ DNSResolverFlags resolverFlags;
+ DNSDomainRegistrationType domainType;
+ const char * label;
+ const char * host;
+ const char * ip;
+ unsigned int b[ 4 ];
+ DNSNetworkAddress addr;
+ dns_service_discovery_ref emulatedRef;
+
+ // Parse the command line arguments (ignore first argument since it's just the program name).
+
+ require_action_string( argc >= 2, exit, err = kDNSBadParamErr, "no arguments specified" );
+
+ for( i = 1; i < argc; ++i )
+ {
+ if( strcmp( argv[ i ], "-bbd" ) == 0 )
+ {
+ // 'b'rowse for 'b'rowsing 'd'omains
+
+ fprintf( stdout, "browsing for browsing domains\n" );
+
+ err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
+ require_noerr_string( err, exit, "create browser failed" );
+
+ err = DNSBrowserStartDomainSearch( browser, 0 );
+ require_noerr_string( err, exit, "start domain search failed" );
+ }
+ else if( strcmp( argv[ i ], "-brd" ) == 0 )
+ {
+ // 'b'rowse for 'r'egistration 'd'omains
+
+ fprintf( stdout, "browsing for registration domains\n" );
+
+ err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
+ require_noerr_string( err, exit, "create browser failed" );
+
+ err = DNSBrowserStartDomainSearch( browser, kDNSBrowserFlagRegistrationDomainsOnly );
+ require_noerr_string( err, exit, "start domain search failed" );
+ }
+ else if( strcmp( argv[ i ], "-bs" ) == 0 )
+ {
+ // 'b'rowse for 's'ervices <type> <domain>
+
+ require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ type = argv[ i++ ];
+ domain = argv[ i ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "browsing for \"%s.%s\"\n", type, domain );
+
+ err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
+ require_noerr_string( err, exit, "create browser failed" );
+
+ err = DNSBrowserStartServiceSearch( browser, kDNSBrowserFlagAutoResolve, type, domain );
+ require_noerr_string( err, exit, "start service search failed" );
+ }
+ else if( strcmp( argv[ i ], "-lsi" ) == 0 )
+ {
+ // 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
+
+ require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ name = argv[ i++ ];
+ type = argv[ i++ ];
+ domain = argv[ i ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "resolving \"%s.%s.%s\"\n", name, type, domain );
+
+ resolverFlags = kDNSResolverFlagOnlyIfUnique |
+ kDNSResolverFlagAutoReleaseByName;
+ err = DNSResolverCreate( resolverFlags, name, type, domain, ResolverCallBack, 0, NULL, NULL );
+ require_noerr_string( err, exit, "create resolver failed" );
+ }
+ else if( ( strcmp( argv[ i ], "-rdb" ) == 0 ) || ( strcmp( argv[ i ], "-rdbd" ) == 0 ) )
+ {
+ // 'r'egister 'd'omain for 'b'rowsing ['d'efault] <domain>
+
+ require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ if( strcmp( argv[ i ], "-rdb" ) == 0 )
+ {
+ domainType = kDNSDomainRegistrationTypeBrowse;
+ label = "";
+ }
+ else
+ {
+ domainType = kDNSDomainRegistrationTypeBrowseDefault;
+ label = "default ";
+ }
+ ++i;
+ domain = argv[ i ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "registering \"%s\" as %sbrowse domain\n", domain, label );
+
+ err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL );
+ require_noerr_string( err, exit, "create domain registration failed" );
+ }
+ else if( ( strcmp( argv[ i ], "-rdr" ) == 0 ) || ( strcmp( argv[ i ], "-rdrd" ) == 0 ) )
+ {
+ // 'r'egister 'd'omain for 'r'egistration ['d'efault] <domain>
+
+ require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ if( strcmp( argv[ i ], "-rdr" ) == 0 )
+ {
+ domainType = kDNSDomainRegistrationTypeRegistration;
+ label = "";
+ }
+ else
+ {
+ domainType = kDNSDomainRegistrationTypeRegistrationDefault;
+ label = "default ";
+ }
+ ++i;
+ domain = argv[ i ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "registering \"%s\" as %sregistration domain\n", domain, label );
+
+ err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL );
+ require_noerr_string( err, exit, "create domain registration failed" );
+ }
+ else if( strcmp( argv[ i ], "-rs" ) == 0 )
+ {
+ // 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
+
+ require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ name = argv[ i++ ];
+ type = argv[ i++ ];
+ domain = argv[ i++ ];
+ port = atoi( argv[ i++ ] );
+ text = argv[ i ];
+ textSize = strlen( text );
+ if( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );
+
+ err = DNSRegistrationCreate( 0, name, type, domain, (DNSPort) port, text, (DNSCount) textSize, NULL, NULL,
+ RegistrationCallBack, NULL, NULL );
+ require_noerr_string( err, exit, "create registration failed" );
+ }
+ else if( strcmp( argv[ i ], "-rps" ) == 0 )
+ {
+ DNSHostRegistrationFlags hostFlags;
+
+ // 'r'egister 'p'roxy 's'ervice <name> <type> <domain> <port> <txt>
+
+ require_action_string( argc > ( i + 7 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ host = argv[ i++ ];
+ ip = argv[ i++ ];
+ name = argv[ i++ ];
+ type = argv[ i++ ];
+ domain = argv[ i++ ];
+ port = atoi( argv[ i++ ] );
+ text = argv[ i ];
+ textSize = strlen( text );
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+
+ sscanf( ip, "%u.%u.%u.%u", &b[ 0 ], &b[ 1 ], &b[ 2 ], &b[ 3 ] );
+ addr.addressType = kDNSNetworkAddressTypeIPv4;
+ addr.u.ipv4.addr.v32 = (DNSUInt32)( ( b[ 0 ] << 24 ) | ( b[ 1 ] << 16 ) | ( b[ 2 ] << 8 ) | ( b[ 3 ] << 0 ) );
+
+ fprintf( stdout, "registering proxy service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );
+
+ hostFlags = kDNSHostRegistrationFlagOnlyIfNotFound | kDNSHostRegistrationFlagAutoRenameOnConflict;
+ err = DNSHostRegistrationCreate( hostFlags, host, domain, &addr, NULL,
+ HostRegistrationCallBack, NULL, NULL );
+ require_noerr_string( err, exit, "create host registration failed" );
+
+ err = DNSRegistrationCreate( 0, name, type, domain, (DNSPort) port, text, (DNSCount) textSize, host, NULL,
+ RegistrationCallBack, NULL, NULL );
+ require_noerr_string( err, exit, "create registration failed" );
+ }
+ else if( strcmp( argv[ i ], "-rnss" ) == 0 )
+ {
+ // 'r'egister 'n'o 's'uch 's'ervice <name> <type> <domain>
+
+ require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ name = argv[ i++ ];
+ type = argv[ i++ ];
+ domain = argv[ i++ ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "registering no-such-service \"%s.%s.%s\"\n", name, type, domain );
+
+ err = DNSNoSuchServiceRegistrationCreate( 0, name, type, domain, NULL, RegistrationCallBack, NULL, NULL );
+ require_noerr_string( err, exit, "create no-such-service registration failed" );
+ }
+ else if( strcmp( argv[ i ], "-ebs" ) == 0 )
+ {
+ // 'e'mulated 'b'rowse for 's'ervices <type> <domain>
+
+ require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ type = argv[ i++ ];
+ domain = argv[ i ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "emulated browsing for \"%s.%s\"\n", type, domain );
+
+ emulatedRef = DNSServiceBrowserCreate( type, domain, EmulatedBrowserCallBack, NULL );
+ require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated browser failed" );
+ }
+ else if( strcmp( argv[ i ], "-ebd" ) == 0 )
+ {
+ int registrationOnly;
+
+ // 'e'mulated 'b'rowse for 'd'omains <registration/browse>
+
+ require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ type = argv[ i++ ];
+ if( strcmp( type, "registration" ) == 0 )
+ {
+ registrationOnly = 1;
+ }
+ else if( strcmp( type, "browse" ) == 0 )
+ {
+ registrationOnly = 0;
+ }
+ else
+ {
+ require_action_string( 0, exit, err = kDNSBadParamErr, "invalid browse type" );
+ }
+ fprintf( stdout, "emulated browsing for %s domains\n", type );
+
+ emulatedRef = DNSServiceDomainEnumerationCreate( registrationOnly, EmulatedDomainEnumerationCallBack, NULL );
+ require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated domain browser failed" );
+ }
+ else if( strcmp( argv[ i ], "-elsi" ) == 0 )
+ {
+ // 'e'mulated 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
+
+ require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ name = argv[ i++ ];
+ type = argv[ i++ ];
+ domain = argv[ i ];
+ if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "emulated resolving \"%s.%s.%s\"\n", name, type, domain );
+
+ emulatedRef = DNSServiceResolverResolve( name, type, domain, EmulatedResolverCallBack, NULL );
+ require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated resolver failed" );
+ }
+ else if( strcmp( argv[ i ], "-ers" ) == 0 )
+ {
+ // 'e'mulated 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
+
+ require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" );
+ ++i;
+ name = argv[ i++ ];
+ type = argv[ i++ ];
+ domain = argv[ i++ ];
+ port = atoi( argv[ i++ ] );
+ text = argv[ i ];
+ textSize = strlen( text );
+ if( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) )
+ {
+ domain = "local.";
+ }
+ fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );
+
+ emulatedRef = DNSServiceRegistrationCreate( name, type, domain, (uint16_t) port, text,
+ EmulatedRegistrationCallBack, NULL );
+ require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated registration failed" );
+ }
+ else if( ( argv[ i ][ 0 ] == '-' ) && isdigit( argv[ i ][ 1 ] ) )
+ {
+ // Preset
+
+ ProcessPreset( atoi( &argv[ i ][ 1 ] ) );
+ err = 0;
+ goto exit;
+ }
+ else if( strcmp( argv[ i ], "-q" ) == 0 )
+ {
+ // Quiet (no text records)
+
+ gPrintTXTRecords = 0;
+ }
+ else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || ( strcmp( argv[ i ], "-h" ) == 0 ) )
+ {
+ // Help
+
+ Usage();
+ err = 0;
+ goto exit;
+ }
+ else
+ {
+ // Unknown parameter.
+
+ require_action_string( 0, exit, err = kDNSBadParamErr, "unknown parameter" );
+ goto exit;
+ }
+ }
+
+ // Run until control-C'd.
+
+ #if( __MACH__ )
+ CFRunLoopRun();
+ #endif
+
+ #if( defined( WINVER ) )
+ while( !gQuit )
+ {
+ Sleep( 200 );
+ }
+ #endif
+
+ err = kDNSNoErr;
+
+exit:
+ if( err )
+ {
+ Usage();
+ }
+ return( err );
+}
+
+//===========================================================================================================================
+// ProcessPreset
+//===========================================================================================================================
+
+static DNSStatus ProcessPreset( int inPreset )
+{
+ DNSStatus err;
+
+ require_action_string( ( inPreset > 0 ) && ( inPreset <= gPresetsCount ), exit, err = kDNSBadParamErr, "invalid preset" );
+
+ err = ProcessArgs( gPresets[ inPreset - 1 ].argc, (char **) gPresets[ inPreset - 1 ].argv );
+
+exit:
+ return( err );
+}
+
+#if( __MACH__ )
+//===========================================================================================================================
+// SigIntHandler
+//===========================================================================================================================
+
+static void SigIntHandler( int inSignalNumber )
+{
+ DNS_UNUSED( inSignalNumber );
+
+ signal( SIGINT, SIG_DFL );
+ CFRunLoopStop( CFRunLoopGetCurrent() );
+}
+#endif
+
+#if( defined( WINVER ) )
+//===========================================================================================================================
+// ConsoleControlHandler
+//===========================================================================================================================
+
+static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent )
+{
+ BOOL handled;
+
+ handled = 0;
+ switch( inControlEvent )
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ case CTRL_CLOSE_EVENT:
+ case CTRL_LOGOFF_EVENT:
+ case CTRL_SHUTDOWN_EVENT:
+ gQuit = 1;
+ handled = 1;
+ break;
+
+ default:
+ break;
+ }
+ return( handled );
+}
+#endif
+
+//===========================================================================================================================
+// BrowserCallBack
+//===========================================================================================================================
+
+static void BrowserCallBack( void *inContext, DNSBrowserRef inRef, DNSStatus inStatusCode, const DNSBrowserEvent *inEvent )
+{
+ char ifIP[ 32 ];
+ char ip[ 32 ];
+
+ DNS_UNUSED( inContext );
+ DNS_UNUSED( inRef );
+ DNS_UNUSED( inStatusCode );
+
+ switch( inEvent->type )
+ {
+ case kDNSBrowserEventTypeRelease:
+ break;
+
+ case kDNSBrowserEventTypeAddDomain:
+ fprintf( stdout, "domain \"%s\" added on interface 0x%08X (%s)\n",
+ inEvent->data.addDomain.domain,
+ (int) inEvent->data.addDomain.interfaceID,
+ IPv4ToString( inEvent->data.addDomain.interfaceIP.u.ipv4.addr, ifIP ) );
+ break;
+
+ case kDNSBrowserEventTypeAddDefaultDomain:
+ fprintf( stdout, "default domain \"%s\" added on interface 0x%08X (%s)\n",
+ inEvent->data.addDefaultDomain.domain,
+ (int) inEvent->data.addDefaultDomain.interfaceID,
+ IPv4ToString( inEvent->data.addDefaultDomain.interfaceIP.u.ipv4.addr, ifIP ) );
+ break;
+
+ case kDNSBrowserEventTypeRemoveDomain:
+ fprintf( stdout, "domain \"%s\" removed on interface 0x%08X (%s)\n",
+ inEvent->data.removeDomain.domain,
+ (int) inEvent->data.removeDomain.interfaceID,
+ IPv4ToString( inEvent->data.removeDomain.interfaceIP.u.ipv4.addr, ifIP ) );
+ break;
+
+ case kDNSBrowserEventTypeAddService:
+ fprintf( stdout, "service \"%s.%s%s\" added on interface 0x%08X (%s)\n",
+ inEvent->data.addService.name,
+ inEvent->data.addService.type,
+ inEvent->data.addService.domain,
+ (int) inEvent->data.addService.interfaceID,
+ IPv4ToString( inEvent->data.addService.interfaceIP.u.ipv4.addr, ifIP ) );
+ break;
+
+ case kDNSBrowserEventTypeRemoveService:
+ fprintf( stdout, "service \"%s.%s%s\" removed on interface 0x%08X (%s)\n",
+ inEvent->data.removeService.name,
+ inEvent->data.removeService.type,
+ inEvent->data.removeService.domain,
+ (int) inEvent->data.removeService.interfaceID,
+ IPv4ToString( inEvent->data.removeService.interfaceIP.u.ipv4.addr, ifIP ) );
+ break;
+
+ case kDNSBrowserEventTypeResolved:
+ {
+ const uint8_t * p;
+ const uint8_t * end;
+ int i;
+
+ fprintf( stdout, "resolved \"%s.%s%s\" to %s:%u on interface 0x%08X (%s)%s\n",
+ inEvent->data.resolved->name,
+ inEvent->data.resolved->type,
+ inEvent->data.resolved->domain,
+ IPv4ToString( inEvent->data.resolved->address.u.ipv4.addr, ip ),
+ ( inEvent->data.resolved->address.u.ipv4.port.v8[ 0 ] << 8 ) |
+ inEvent->data.resolved->address.u.ipv4.port.v8[ 1 ],
+ (int) inEvent->data.resolved->interfaceID,
+ IPv4ToString( inEvent->data.resolved->interfaceIP.u.ipv4.addr, ifIP ),
+ ( inEvent->data.resolved->textRecordRawSize > 0 ) ? " with text:" : "" );
+
+ p = (const uint8_t *) inEvent->data.resolved->textRecordRaw;
+ end = p + inEvent->data.resolved->textRecordRawSize;
+ i = 0;
+
+ if( gPrintTXTRecords )
+ {
+ while( p < end )
+ {
+ uint8_t size;
+
+ size = *p++;
+ if( ( p + size ) > end )
+ {
+ fprintf( stdout, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
+ break;
+ }
+ fprintf( stdout, "%5d (%3d bytes): \"%.*s\"\n", i, size, size, p );
+ p += size;
+ ++i;
+ }
+ fprintf( stdout, "\n" );
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+//===========================================================================================================================
+// ResolverCallBack
+//===========================================================================================================================
+
+static void ResolverCallBack( void *inContext, DNSResolverRef inRef, DNSStatus inStatusCode, const DNSResolverEvent *inEvent )
+{
+ char ifIP[ 32 ];
+ char ip[ 32 ];
+
+ DNS_UNUSED( inContext );
+ DNS_UNUSED( inRef );
+ DNS_UNUSED( inStatusCode );
+
+ switch( inEvent->type )
+ {
+ case kDNSResolverEventTypeResolved:
+ {
+ const uint8_t * p;
+ const uint8_t * end;
+ int i;
+
+ fprintf( stdout, "resolved \"%s.%s%s\" to %s:%u on interface 0x%08X (%s)%s\n",
+ inEvent->data.resolved.name,
+ inEvent->data.resolved.type,
+ inEvent->data.resolved.domain,
+ IPv4ToString( inEvent->data.resolved.address.u.ipv4.addr, ip ),
+ ( inEvent->data.resolved.address.u.ipv4.port.v8[ 0 ] << 8 ) |
+ inEvent->data.resolved.address.u.ipv4.port.v8[ 1 ],
+ (int) inEvent->data.resolved.interfaceID,
+ IPv4ToString( inEvent->data.resolved.interfaceIP.u.ipv4.addr, ifIP ),
+ ( inEvent->data.resolved.textRecordRawSize > 0 ) ? " with text:" : "" );
+
+ p = (const uint8_t *) inEvent->data.resolved.textRecordRaw;
+ end = p + inEvent->data.resolved.textRecordRawSize;
+ i = 0;
+
+ if( gPrintTXTRecords )
+ {
+ while( p < end )
+ {
+ uint8_t size;
+
+ size = *p++;
+ if( ( p + size ) > end )
+ {
+ fprintf( stdout, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
+ break;
+ }
+ fprintf( stdout, "%5d (%3d bytes): \"%.*s\"\n", i, size, size, p );
+ p += size;
+ ++i;
+ }
+ fprintf( stdout, "\n" );
+ }
+ break;
+ }
+
+ case kDNSResolverEventTypeRelease:
+ break;
+
+ default:
+ break;
+ }
+}
+
+//===========================================================================================================================
+// RegistrationCallBack
+//===========================================================================================================================
+
+static void
+ RegistrationCallBack(
+ void * inContext,
+ DNSRegistrationRef inRef,
+ DNSStatus inStatusCode,
+ const DNSRegistrationEvent * inEvent )
+{
+ DNS_UNUSED( inContext );
+ DNS_UNUSED( inRef );
+ DNS_UNUSED( inStatusCode );
+
+ switch( inEvent->type )
+ {
+ case kDNSRegistrationEventTypeRelease:
+ break;
+
+ case kDNSRegistrationEventTypeRegistered:
+ fprintf( stdout, "name registered and active\n" );
+ break;
+
+ case kDNSRegistrationEventTypeNameCollision:
+ fprintf( stdout, "name in use, please choose another name\n" );
+ break;
+
+ default:
+ break;
+ }
+}
+
+//===========================================================================================================================
+// HostRegistrationCallBack
+//===========================================================================================================================
+
+static void
+ HostRegistrationCallBack(
+ void * inContext,
+ DNSHostRegistrationRef inRef,
+ DNSStatus inStatusCode,
+ void * inData )
+{
+ DNS_UNUSED( inContext );
+ DNS_UNUSED( inRef );
+ DNS_UNUSED( inData );
+
+ if( inStatusCode == kDNSNoErr )
+ {
+ fprintf( stdout, "host name registered and active\n" );
+ }
+ else if( inStatusCode == kDNSNameConflictErr )
+ {
+ fprintf( stdout, "host name in use, please choose another name\n" );
+ }
+ else
+ {
+ fprintf( stdout, "unknown host registration status (%ld)\n", inStatusCode );
+ }
+}
+
+//===========================================================================================================================
+// EmulatedBrowserCallBack
+//===========================================================================================================================
+
+static void
+ EmulatedBrowserCallBack(
+ DNSServiceBrowserReplyResultType inResult,
+ const char * inName,
+ const char * inType,
+ const char * inDomain,
+ DNSServiceDiscoveryReplyFlags inFlags,
+ void * inContext )
+{
+ DNS_UNUSED( inFlags );
+ DNS_UNUSED( inContext );
+
+ if( inResult == DNSServiceBrowserReplyAddInstance )
+ {
+ fprintf( stdout, "\"%s.%s%s\" service added emulated\n", inName, inType, inDomain );
+ }
+ else if( inResult == DNSServiceBrowserReplyRemoveInstance )
+ {
+ fprintf( stdout, "\"%s.%s%s\" service removed emulated\n", inName, inType, inDomain );
+ }
+ else
+ {
+ fprintf( stdout, "### unknown emulated browser callback result (%d)\n", inResult );
+ }
+}
+
+//===========================================================================================================================
+// EmulatedDomainEnumerationCallBack
+//===========================================================================================================================
+
+static void
+ EmulatedDomainEnumerationCallBack(
+ DNSServiceDomainEnumerationReplyResultType inResult,
+ const char * inDomain,
+ DNSServiceDiscoveryReplyFlags inFlags,
+ void * inContext )
+{
+ DNS_UNUSED( inFlags );
+ DNS_UNUSED( inContext );
+
+ if( inResult == DNSServiceDomainEnumerationReplyAddDomain )
+ {
+ fprintf( stdout, "\"%s\" domain added emulated\n", inDomain );
+ }
+ else if( inResult == DNSServiceDomainEnumerationReplyAddDomainDefault )
+ {
+ fprintf( stdout, "\"%s\" default domain added emulated\n", inDomain );
+ }
+ else if( inResult == DNSServiceDomainEnumerationReplyRemoveDomain )
+ {
+ fprintf( stdout, "\"%s\" domain removed emulated\n", inDomain );
+ }
+ else
+ {
+ fprintf( stdout, "### unknown emulated domain enumeration callback result (%d)\n", inResult );
+ }
+}
+
+//===========================================================================================================================
+// EmulatedResolverCallBack
+//===========================================================================================================================
+
+static void
+ EmulatedResolverCallBack(
+ struct sockaddr * inInterfaceAddr,
+ struct sockaddr * inAddr,
+ const char * inTextRecord,
+ DNSServiceDiscoveryReplyFlags inFlags,
+ void * inContext )
+{
+ struct sockaddr_in * ifSin4;
+ struct sockaddr_in * sin4;
+ char ifIP[ 64 ];
+ char ip[ 64 ];
+
+ DNS_UNUSED( inFlags );
+ DNS_UNUSED( inContext );
+
+ ifSin4 = (struct sockaddr_in *) inInterfaceAddr;
+ sin4 = (struct sockaddr_in *) inAddr;
+
+ fprintf( stdout, "service resolved to %s:%d on interface %s with text \"%s\"\n",
+ IPv4ToString( *( (DNSOpaque32 *) &sin4->sin_addr.s_addr ), ip ),
+ ntohs( sin4->sin_port ),
+ IPv4ToString( *( (DNSOpaque32 *) &ifSin4->sin_addr.s_addr ), ifIP ),
+ inTextRecord ? inTextRecord : "" );
+}
+
+//===========================================================================================================================
+// EmulatedResolverCallBack
+//===========================================================================================================================
+
+static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult, void *inContext )
+{
+ DNS_UNUSED( inContext );
+
+ if( inResult == kDNSServiceDiscoveryNoError )
+ {
+ fprintf( stdout, "service name registered successfully\n" );
+ }
+ else
+ {
+ fprintf( stdout, "service registration failed( %d)\n", inResult );
+ }
+}
+
+//===========================================================================================================================
+// IPv4ToString
+//===========================================================================================================================
+
+static char * IPv4ToString( DNSOpaque32 inIP, char *outString )
+{
+ sprintf( outString, "%u.%u.%u.%u", inIP.v8[ 0 ], inIP.v8[ 1 ], inIP.v8[ 2 ], inIP.v8[ 3 ] );
+ return( outString );
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: ToolPrefixWindows.h,v $
+Revision 1.2 2003/08/20 07:06:34 bradley
+Update to APSL 2.0. Updated change history to match other mDNSResponder files.
+
+Revision 1.1 2003/08/20 06:01:19 bradley
+Prefix files for CodeWarrior Windows builds to set compile options.
+
+*/
+
+#ifndef __TOOL_PREFIX_WINDOWS__
+#define __TOOL_PREFIX_WINDOWS__
+
+#define DEBUG 0
+
+#endif // __TOOL_PREFIX_WINDOWS__
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * 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: ToolPrefixWindowsDebug.h,v $
+Revision 1.2 2003/08/20 07:06:34 bradley
+Update to APSL 2.0. Updated change history to match other mDNSResponder files.
+
+Revision 1.1 2003/08/20 06:01:19 bradley
+Prefix files for CodeWarrior Windows builds to set compile options.
+
+*/
+
+#ifndef __TOOL_PREFIX_WINDOWS_DEBUG__
+#define __TOOL_PREFIX_WINDOWS_DEBUG__
+
+#define DEBUG 1
+#define MDNS_DEBUGMSGS 1
+
+#endif // __TOOL_PREFIX_WINDOWS_DEBUG__
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tool", "ToolWin32VS2002.vcproj", "{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = all
+ ConfigName.1 = Debug
+ ConfigName.2 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.ActiveCfg = all|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.Build.0 = all|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.ActiveCfg = Debug|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.Build.0 = Debug|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.ActiveCfg = Release|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
--- /dev/null
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="Tool"
+ ProjectGUID="{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ StringPooling="TRUE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="FALSE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ BrowseInformation="1"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(OutDir)/Tool.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/Tool.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="FALSE"
+ DisableLanguageExtensions="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(OutDir)/Tool.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ <Configuration
+ Name="all|Win32"
+ OutputDirectory="all"
+ IntermediateDirectory="all"
+ ConfigurationType="1">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Rendezvous"
+ Filter="">
+ <File
+ RelativePath="..\..\DNSServices\DNSServiceDiscovery.c">
+ </File>
+ <File
+ RelativePath="..\..\DNSServices\DNSServiceDiscovery.h">
+ </File>
+ <File
+ RelativePath="..\..\DNSServices\DNSServices.c">
+ </File>
+ <File
+ RelativePath="..\..\DNSServices\DNSServices.h">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNS.c">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNSClientAPI.h">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNSDebug.h">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNSPlatformFunctions.h">
+ </File>
+ <File
+ RelativePath="..\..\mDNSWin32.c">
+ </File>
+ <File
+ RelativePath="..\..\mDNSWin32.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath="Tool.c">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tool", "ToolWin32VS2003.vcproj", "{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ all = all
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.ActiveCfg = all|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.Build.0 = all|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.ActiveCfg = Debug|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.Build.0 = Debug|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.ActiveCfg = Release|Win32
+ {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
--- /dev/null
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="Tool"
+ ProjectGUID="{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="1"
+ CharacterSet="1">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ StringPooling="TRUE"
+ MinimalRebuild="TRUE"
+ BasicRuntimeChecks="3"
+ SmallerTypeCheck="FALSE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ BrowseInformation="1"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(OutDir)/Tool.exe"
+ LinkIncremental="2"
+ GenerateDebugInformation="TRUE"
+ ProgramDatabaseFile="$(OutDir)/Tool.pdb"
+ SubSystem="1"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ StringPooling="TRUE"
+ ExceptionHandling="FALSE"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="FALSE"
+ DisableLanguageExtensions="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="2"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ Detect64BitPortabilityProblems="TRUE"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(OutDir)/Tool.exe"
+ LinkIncremental="1"
+ GenerateDebugInformation="TRUE"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="all|Win32"
+ OutputDirectory="all"
+ IntermediateDirectory="all"
+ ConfigurationType="1">
+ <Tool
+ Name="VCCLCompilerTool"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Rendezvous"
+ Filter="">
+ <File
+ RelativePath="..\..\DNSServices\DNSServiceDiscovery.c">
+ </File>
+ <File
+ RelativePath="..\..\DNSServices\DNSServiceDiscovery.h">
+ </File>
+ <File
+ RelativePath="..\..\DNSServices\DNSServices.c">
+ </File>
+ <File
+ RelativePath="..\..\DNSServices\DNSServices.h">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNS.c">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNSClientAPI.h">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNSDebug.h">
+ </File>
+ <File
+ RelativePath="..\..\..\mDNSCore\mDNSPlatformFunctions.h">
+ </File>
+ <File
+ RelativePath="..\..\mDNSWin32.c">
+ </File>
+ <File
+ RelativePath="..\..\mDNSWin32.h">
+ </File>
+ </Filter>
+ <File
+ RelativePath="Tool.c">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Application", "ApplicationVS2002.vcproj", "{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = All
- ConfigName.1 = Debug
- ConfigName.2 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.ActiveCfg = All|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.Build.0 = All|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.ActiveCfg = Debug|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.Build.0 = Debug|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.ActiveCfg = Release|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+++ /dev/null
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="Application"
- ProjectGUID="{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
- Keyword="MFCProj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- UseOfMFC="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG"
- StringPooling="TRUE"
- MinimalRebuild="FALSE"
- BasicRuntimeChecks="3"
- SmallerTypeCheck="FALSE"
- RuntimeLibrary="1"
- BufferSecurityCheck="TRUE"
- EnableFunctionLevelLinking="FALSE"
- ForceConformanceInForLoopScope="TRUE"
- RuntimeTypeInfo="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderThrough="StdAfx.h"
- PrecompiledHeaderFile=".\Debug/Application.pch"
- AssemblerListingLocation=".\Debug/"
- ObjectFile=".\Debug/"
- ProgramDataBaseFileName=".\Debug/"
- BrowseInformation="1"
- WarningLevel="4"
- WarnAsError="TRUE"
- SuppressStartupBanner="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="ws2_32.lib nafxcwd.lib LIBCMTD.lib"
- OutputFile="Rendezvous Browser Debug.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreDefaultLibraryNames="wsock32.lib;nafxcwd.lib;LIBCMTD.lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\Debug/Application.pdb"
- SubSystem="2"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="FALSE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\Debug/Application.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_AFXDLL;_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\Release"
- IntermediateDirectory=".\Release"
- ConfigurationType="1"
- UseOfMFC="1"
- CharacterSet="2"
- WholeProgramOptimization="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- GlobalOptimizations="TRUE"
- InlineFunctionExpansion="0"
- FavorSizeOrSpeed="2"
- OmitFramePointers="FALSE"
- OptimizeForWindowsApplication="FALSE"
- AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
- StringPooling="TRUE"
- MinimalRebuild="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableFunctionLevelLinking="FALSE"
- ForceConformanceInForLoopScope="TRUE"
- RuntimeTypeInfo="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderThrough="stdafx.h"
- PrecompiledHeaderFile=".\Release/Application.pch"
- AssemblerListingLocation=".\Release/"
- ObjectFile=".\Release/"
- ProgramDataBaseFileName=".\Release/"
- BrowseInformation="1"
- WarningLevel="4"
- WarnAsError="TRUE"
- SuppressStartupBanner="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="ws2_32.lib nafxcw.lib LIBCMT.lib"
- OutputFile="Rendezvous Browser.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreDefaultLibraryNames="wsock32.lib;nafxcw.lib;LIBCMT.lib"
- ProgramDatabaseFile=".\Release/Application.pdb"
- SubSystem="2"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\Release/Application.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_AFXDLL;NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="All|Win32"
- OutputDirectory="All"
- IntermediateDirectory="All"
- ConfigurationType="1">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Source Files"
- Filter="">
- <File
- RelativePath="Sources\AboutDialog.cpp">
- </File>
- <File
- RelativePath="Sources\AboutDialog.h">
- </File>
- <File
- RelativePath="Sources\Application.cpp">
- </File>
- <File
- RelativePath="Sources\Application.h">
- </File>
- <File
- RelativePath="Sources\ChooserDialog.cpp">
- </File>
- <File
- RelativePath="Sources\ChooserDialog.h">
- </File>
- <File
- RelativePath="Sources\StdAfx.cpp">
- </File>
- <File
- RelativePath="Sources\StdAfx.h">
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;rc">
- <File
- RelativePath="Resources\Application.ico">
- </File>
- <File
- RelativePath="Resources\Application.rc">
- </File>
- <File
- RelativePath="Resources\Application.rc2">
- </File>
- <File
- RelativePath=".\Resources\Resource.h">
- </File>
- </Filter>
- <Filter
- Name="Rendezvous"
- Filter="">
- <File
- RelativePath="..\..\..\DNSServices\DNSServices.c">
- </File>
- <File
- RelativePath="..\..\..\..\mDNSCore\mDNS.c">
- </File>
- <File
- RelativePath="..\..\..\mDNSWin32.c">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Application", "ApplicationVS2003.vcproj", "{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- All = All
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.ActiveCfg = All|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.All.Build.0 = All|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.ActiveCfg = Debug|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Debug.Build.0 = Debug|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.ActiveCfg = Release|Win32
- {EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="Application"
- ProjectGUID="{EDE4B529-4CF5-4A49-9B6F-C10F0EA24278}"
- Keyword="MFCProj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- UseOfMFC="1"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
- PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG"
- StringPooling="TRUE"
- MinimalRebuild="FALSE"
- BasicRuntimeChecks="3"
- SmallerTypeCheck="FALSE"
- RuntimeLibrary="1"
- BufferSecurityCheck="TRUE"
- EnableFunctionLevelLinking="FALSE"
- ForceConformanceInForLoopScope="TRUE"
- RuntimeTypeInfo="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderThrough="StdAfx.h"
- PrecompiledHeaderFile=".\Debug/Application.pch"
- AssemblerListingLocation=".\Debug/"
- ObjectFile=".\Debug/"
- ProgramDataBaseFileName=".\Debug/"
- BrowseInformation="1"
- WarningLevel="4"
- WarnAsError="TRUE"
- SuppressStartupBanner="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="ws2_32.lib nafxcwd.lib LIBCMTD.lib"
- OutputFile="Rendezvous Browser Debug.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreDefaultLibraryNames="wsock32.lib;nafxcwd.lib;LIBCMTD.lib"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile=".\Debug/Application.pdb"
- SubSystem="2"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="_DEBUG"
- MkTypLibCompatible="FALSE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\Debug/Application.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_AFXDLL;_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory=".\Release"
- IntermediateDirectory=".\Release"
- ConfigurationType="1"
- UseOfMFC="1"
- CharacterSet="2"
- WholeProgramOptimization="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="1"
- GlobalOptimizations="TRUE"
- InlineFunctionExpansion="0"
- FavorSizeOrSpeed="2"
- OmitFramePointers="FALSE"
- OptimizeForWindowsApplication="FALSE"
- AdditionalIncludeDirectories=".\Resources;..\;..\..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\..\DNSServices"
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
- StringPooling="TRUE"
- MinimalRebuild="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableFunctionLevelLinking="FALSE"
- ForceConformanceInForLoopScope="TRUE"
- RuntimeTypeInfo="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderThrough="stdafx.h"
- PrecompiledHeaderFile=".\Release/Application.pch"
- AssemblerListingLocation=".\Release/"
- ObjectFile=".\Release/"
- ProgramDataBaseFileName=".\Release/"
- BrowseInformation="1"
- WarningLevel="4"
- WarnAsError="TRUE"
- SuppressStartupBanner="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalOptions="/MACHINE:I386"
- AdditionalDependencies="ws2_32.lib nafxcw.lib LIBCMT.lib"
- OutputFile="Rendezvous Browser.exe"
- LinkIncremental="1"
- SuppressStartupBanner="TRUE"
- IgnoreDefaultLibraryNames="wsock32.lib;nafxcw.lib;LIBCMT.lib"
- ProgramDatabaseFile=".\Release/Application.pdb"
- SubSystem="2"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"/>
- <Tool
- Name="VCMIDLTool"
- PreprocessorDefinitions="NDEBUG"
- MkTypLibCompatible="TRUE"
- SuppressStartupBanner="TRUE"
- TargetEnvironment="1"
- TypeLibraryName=".\Release/Application.tlb"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_AFXDLL;NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="All|Win32"
- OutputDirectory="All"
- IntermediateDirectory="All"
- ConfigurationType="1">
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="">
- <File
- RelativePath="Sources\AboutDialog.cpp">
- </File>
- <File
- RelativePath="Sources\AboutDialog.h">
- </File>
- <File
- RelativePath="Sources\Application.cpp">
- </File>
- <File
- RelativePath="Sources\Application.h">
- </File>
- <File
- RelativePath="Sources\ChooserDialog.cpp">
- </File>
- <File
- RelativePath="Sources\ChooserDialog.h">
- </File>
- <File
- RelativePath="Sources\StdAfx.cpp">
- </File>
- <File
- RelativePath="Sources\StdAfx.h">
- </File>
- </Filter>
- <Filter
- Name="Resource Files"
- Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;rc">
- <File
- RelativePath="Resources\Application.ico">
- </File>
- <File
- RelativePath="Resources\Application.rc">
- </File>
- <File
- RelativePath="Resources\Application.rc2">
- </File>
- <File
- RelativePath=".\Resources\Resource.h">
- </File>
- </Filter>
- <Filter
- Name="Rendezvous"
- Filter="">
- <File
- RelativePath="..\..\..\DNSServices\DNSServices.c">
- </File>
- <File
- RelativePath="..\..\..\..\mDNSCore\mDNS.c">
- </File>
- <File
- RelativePath="..\..\..\mDNSWin32.c">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+++ /dev/null
-// Microsoft Visual C++ generated resource script.
-//
-#include "Resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "Resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""afxres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
- "#define _AFX_NO_OLE_RESOURCES\r\n"
- "#define _AFX_NO_TRACKER_RESOURCES\r\n"
- "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
- "\r\n"
- "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
- "#ifdef _WIN32\r\n"
- "LANGUAGE 9, 1\r\n"
- "#pragma code_page(1252)\r\n"
- "#endif //_WIN32\r\n"
- "#include ""Resources\\Application.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
- "#include ""afxres.rc"" // Standard components\r\n"
- "#endif\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDR_MAIN_ICON ICON "Application.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_CHOOSER_DIALOG DIALOGEX 0, 0, 332, 252
-STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
- WS_SYSMENU
-EXSTYLE WS_EX_APPWINDOW
-CAPTION "Rendezvous Browser for Windows"
-MENU IDR_CHOOSER_DIALOG_MENU
-FONT 8, "MS Sans Serif", 0, 0, 0x0
-BEGIN
- CONTROL "",IDC_CHOOSER_LIST,"SysListView32",LVS_REPORT |
- LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
- LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,116,8,208,136
- CONTROL "",IDC_SERVICE_LIST,"SysListView32",LVS_REPORT |
- LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
- LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,8,100,136
- CONTROL "",IDC_DOMAIN_LIST,"SysListView32",LVS_REPORT |
- LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT |
- LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,152,100,92
- GROUPBOX "Information",IDC_STATIC,116,148,208,96
- RTEXT "Name:",IDC_STATIC,122,164,38,8
- LTEXT "My Device",IDC_INFO_NAME_TEXT,164,164,152,10,SS_SUNKEN
- RTEXT "Text:",IDC_STATIC,122,203,38,8
- LTEXT "Information About My Device",IDC_INFO_TEXT_TEXT,164,203,
- 152,34,SS_NOPREFIX | SS_SUNKEN
- RTEXT "IP address:",IDC_STATIC,122,177,38,8
- LTEXT "123.124.125.126:1234",IDC_INFO_IP_TEXT,164,177,152,10,
- SS_SUNKEN
- RTEXT "Interface:",IDC_STATIC,122,190,38,8
- LTEXT "123.124.125.126",IDC_INFO_INTERFACE_TEXT,164,190,152,10,
- SS_SUNKEN
-END
-
-IDD_ABOUT_DIALOG DIALOGEX 0, 0, 244, 73
-STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
-CAPTION "About Rendezvous Browser"
-FONT 8, "MS Sans Serif", 0, 0, 0x0
-BEGIN
- ICON IDR_MAIN_ICON,IDC_ABOUT_APP_ICON,12,12,20,20
- LTEXT "Rendezvous Browser for Windows",IDC_ABOUT_APP_NAME_TEXT,
- 44,11,192,12
- LTEXT "Version 1.0d2",IDC_ABOUT_APP_VERSION_TEXT,44,25,192,8
- LTEXT "Copyright (C) 2002-2003 Apple Computer, Inc.",
- IDC_ABOUT_COPYRIGHT_TEXT,4,60,156,8
- DEFPUSHBUTTON "OK",IDOK,192,52,44,14
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,1
- PRODUCTVERSION 1,0,0,1
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x1L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "Comments", "Quick & Dirty 1 day hack by Bob Bradley"
- VALUE "CompanyName", "Apple Computer, Inc."
- VALUE "FileDescription", "Rendezvous Browser for Windows"
- VALUE "FileVersion", "1, 0, 0, 1"
- VALUE "InternalName", "Rendezvous Browser for Windows"
- VALUE "LegalCopyright", "Copyright (C) Apple Computer, Inc. 2001"
- VALUE "OriginalFilename", "RendezvousBrowser.exe"
- VALUE "ProductName", "Rendezvous Browser for Windows"
- VALUE "ProductVersion", "1, 0, 0, 1"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Menu
-//
-
-IDR_CHOOSER_DIALOG_MENU MENU
-BEGIN
- POPUP "File"
- BEGIN
- MENUITEM "Close &Window\tCtrl+W", ID_FILE_CLOSE
- MENUITEM SEPARATOR
- MENUITEM "Exit", ID_FILE_EXIT
- END
- POPUP "Help"
- BEGIN
- MENUITEM "About Rendezvous Browser...", ID_HELP_ABOUT
- END
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Accelerator
-//
-
-IDR_CHOOSER_DIALOG_MENU_ACCELERATORS ACCELERATORS
-BEGIN
- "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
- "W", ID_FILE_CLOSE, VIRTKEY, CONTROL, NOINVERT
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// RT_MANIFEST
-//
-
-1 RT_MANIFEST
-BEGIN
- 0x3f3c, 0x6d78, 0x206c, 0x6576, 0x7372, 0x6f69, 0x3d6e, 0x3122, 0x302e,
- 0x2022, 0x6e65, 0x6f63, 0x6964, 0x676e, 0x223d, 0x5455, 0x2d46, 0x2238,
- 0x7320, 0x6174, 0x646e, 0x6c61, 0x6e6f, 0x3d65, 0x7922, 0x7365, 0x3f22,
- 0x203e, 0x0a0d, 0x613c, 0x7373, 0x6d65, 0x6c62, 0x2079, 0x0a0d, 0x2020,
- 0x7820, 0x6c6d, 0x736e, 0x223d, 0x7275, 0x3a6e, 0x6373, 0x6568, 0x616d,
- 0x2d73, 0x696d, 0x7263, 0x736f, 0x666f, 0x2d74, 0x6f63, 0x3a6d, 0x7361,
- 0x2e6d, 0x3176, 0x2022, 0x0a0d, 0x2020, 0x6d20, 0x6e61, 0x6669, 0x7365,
- 0x5674, 0x7265, 0x6973, 0x6e6f, 0x223d, 0x2e31, 0x2230, 0x0d3e, 0x3c0a,
- 0x7361, 0x6573, 0x626d, 0x796c, 0x6449, 0x6e65, 0x6974, 0x7974, 0x0d20,
- 0x200a, 0x2020, 0x7020, 0x6f72, 0x6563, 0x7373, 0x726f, 0x7241, 0x6863,
- 0x7469, 0x6365, 0x7574, 0x6572, 0x223d, 0x3878, 0x2236, 0x0d20, 0x200a,
- 0x2020, 0x7620, 0x7265, 0x6973, 0x6e6f, 0x223d, 0x2e35, 0x2e31, 0x2e30,
- 0x2230, 0x0a0d, 0x2020, 0x2020, 0x7974, 0x6570, 0x223d, 0x6977, 0x336e,
- 0x2232, 0x0a0d, 0x2020, 0x2020, 0x616e, 0x656d, 0x223d, 0x7041, 0x2e70,
- 0x7865, 0x2265, 0x3e2f, 0x0a0d, 0x2020, 0x2020, 0x643c, 0x7365, 0x7263,
- 0x7069, 0x6974, 0x6e6f, 0x413e, 0x7269, 0x6f50, 0x7472, 0x4120, 0x6d64,
- 0x6e69, 0x5520, 0x6974, 0x696c, 0x7974, 0x2f3c, 0x6564, 0x6373, 0x6972,
- 0x7470, 0x6f69, 0x3e6e, 0x0a0d, 0x2020, 0x2020, 0x643c, 0x7065, 0x6e65,
- 0x6564, 0x636e, 0x3e79, 0x0a0d, 0x2020, 0x2020, 0x643c, 0x7065, 0x6e65,
- 0x6564, 0x746e, 0x7341, 0x6573, 0x626d, 0x796c, 0x0d3e, 0x200a, 0x2020,
- 0x3c20, 0x7361, 0x6573, 0x626d, 0x796c, 0x6449, 0x6e65, 0x6974, 0x7974,
- 0x0a0d, 0x2020, 0x2020, 0x2020, 0x2020, 0x7420, 0x7079, 0x3d65, 0x7722,
- 0x6e69, 0x3233, 0x0d22, 0x200a, 0x2020, 0x2020, 0x2020, 0x2020, 0x616e,
- 0x656d, 0x223d, 0x694d, 0x7263, 0x736f, 0x666f, 0x2e74, 0x6957, 0x646e,
- 0x776f, 0x2e73, 0x6f43, 0x6d6d, 0x6e6f, 0x432d, 0x6e6f, 0x7274, 0x6c6f,
- 0x2273, 0x0a0d, 0x2020, 0x2020, 0x2020, 0x2020, 0x7620, 0x7265, 0x6973,
- 0x6e6f, 0x223d, 0x2e36, 0x2e30, 0x2e30, 0x2230, 0x0a0d, 0x2020, 0x2020,
- 0x2020, 0x2020, 0x7020, 0x6275, 0x696c, 0x4b63, 0x7965, 0x6f54, 0x656b,
- 0x3d6e, 0x3622, 0x3935, 0x6235, 0x3436, 0x3431, 0x6334, 0x6663, 0x6431,
- 0x2266, 0x0a0d, 0x2020, 0x2020, 0x2020, 0x2020, 0x6c20, 0x6e61, 0x7567,
- 0x6761, 0x3d65, 0x2a22, 0x0d22, 0x200a, 0x2020, 0x2020, 0x2020, 0x2020,
- 0x7270, 0x636f, 0x7365, 0x6f73, 0x4172, 0x6372, 0x6968, 0x6574, 0x7463,
- 0x7275, 0x3d65, 0x7822, 0x3638, 0x2f22, 0x0d3e, 0x200a, 0x2020, 0x3c20,
- 0x642f, 0x7065, 0x6e65, 0x6564, 0x746e, 0x7341, 0x6573, 0x626d, 0x796c,
- 0x0d3e, 0x200a, 0x2020, 0x3c20, 0x642f, 0x7065, 0x6e65, 0x6564, 0x636e,
- 0x3e79, 0x0a0d, 0x2f3c, 0x7361, 0x6573, 0x626d, 0x796c, 0x0d3e, "\012"
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// String Table
-//
-
-STRINGTABLE
-BEGIN
- IDS_ABOUTBOX "&About Rendezvous Browser"
- IDS_CHOOSER_DOMAIN_COLUMN_NAME "Domains"
- IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed."
- IDS_CHOOSER_SERVICE_COLUMN_NAME "Services"
- IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME "Name"
- IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME "IP Address"
-END
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-#define _AFX_NO_SPLITTER_RESOURCES
-#define _AFX_NO_OLE_RESOURCES
-#define _AFX_NO_TRACKER_RESOURCES
-#define _AFX_NO_PROPERTY_RESOURCES
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE 9, 1
-#pragma code_page(1252)
-#endif //_WIN32
-#include "Resources\Application.rc2" // non-Microsoft Visual C++ edited resources
-#include "afxres.rc" // Standard components
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: Application.rc2,v $
-Revision 1.1 2003/08/21 02:06:46 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.2 2003/08/20 07:06:34 bradley
-Update to APSL 2.0. Updated change history to match other mDNSResponder files.
-
-Revision 1.1 2002/09/20 06:12:48 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#ifdef APSTUDIO_INVOKED
- #error this file is not editable by Microsoft Visual C++
-#endif //APSTUDIO_INVOKED
+++ /dev/null
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by Application.rc
-//
-#define IDS_ABOUTBOX 101
-#define IDS_CHOOSER_DOMAIN_COLUMN_NAME 102
-#define IDP_SOCKETS_INIT_FAILED 103
-#define IDS_CHOOSER_SERVICE_COLUMN_NAME 104
-#define IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME 105
-#define IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME 106
-#define IDC_NAME_TEXT2 124
-#define IDC_INFO_NAME_TEXT 124
-#define IDC_DESCRIPTION_TEXT2 125
-#define IDC_INFO_TEXT_TEXT 125
-#define IDC_IP_TEXT2 126
-#define IDC_INFO_IP_TEXT 126
-#define IDC_IP_TEXT3 127
-#define IDC_INFO_INTERFACE_TEXT 127
-#define IDR_MAIN_ICON 128
-#define IDR_CHOOSER_DIALOG_MENU 136
-#define IDD_CHOOSER_DIALOG 143
-#define IDD_ABOUT_DIALOG 144
-#define IDR_CHOOSER_DIALOG_MENU_ACCELERATORS 146
-#define IDC_CHOOSER_LIST 1000
-#define IDC_SERVICE_LIST2 1001
-#define IDC_SERVICE_LIST 1001
-#define IDC_SERVICE_LIST3 1002
-#define IDC_DOMAIN_LIST 1002
-#define IDC_ABOUT_APP_NAME_TEXT 1105
-#define IDC_ABOUT_APP_VERSION_TEXT 1106
-#define IDC_ABOUT_COPYRIGHT_TEXT 1107
-#define IDC_ABOUT_APP_ICON 1108
-#define ID_FILE_EXIT 32771
-#define ID_HELP_ABOUT 32806
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 164
-#define _APS_NEXT_COMMAND_VALUE 32809
-#define _APS_NEXT_CONTROL_VALUE 1182
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: AboutDialog.cpp,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.4 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.3 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.2 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.1 2002/09/20 06:12:49 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#include <stdlib.h>
-
-#include "stdafx.h"
-
-#include "AboutDialog.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-//===========================================================================================================================
-// Message Map
-//===========================================================================================================================
-
-BEGIN_MESSAGE_MAP(AboutDialog, CDialog)
- //{{AFX_MSG_MAP(AboutDialog)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-//===========================================================================================================================
-// AboutDialog
-//===========================================================================================================================
-
-AboutDialog::AboutDialog(CWnd* pParent /*=NULL*/)
- : CDialog(AboutDialog::IDD, pParent)
-{
- //{{AFX_DATA_INIT(AboutDialog)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
-}
-
-//===========================================================================================================================
-// OnInitDialog
-//===========================================================================================================================
-
-BOOL AboutDialog::OnInitDialog()
-{
- CDialog::OnInitDialog();
- return( true );
-}
-
-//===========================================================================================================================
-// DoDataExchange
-//===========================================================================================================================
-
-void AboutDialog::DoDataExchange(CDataExchange* pDX)
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(AboutDialog)
- // NOTE: the ClassWizard will add DDX and DDV calls here
- //}}AFX_DATA_MAP
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: AboutDialog.h,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.4 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.3 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.2 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.1 2002/09/20 06:12:50 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#if !defined(AFX_ABOUTDIALOG_H__4B8A04B2_9735_4F4A_AFCA_15F85FB3D763__INCLUDED_)
-#define AFX_ABOUTDIALOG_H__4B8A04B2_9735_4F4A_AFCA_15F85FB3D763__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "Resource.h"
-
-//===========================================================================================================================
-// AboutDialog
-//===========================================================================================================================
-
-class AboutDialog : public CDialog
-{
- public:
-
- // Creation/Deletion
-
- AboutDialog(CWnd* pParent = NULL); // standard constructor
-
- //{{AFX_DATA(AboutDialog)
- enum { IDD = IDD_ABOUT_DIALOG };
- // NOTE: the ClassWizard will add data members here
- //}}AFX_DATA
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(AboutDialog)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
- protected:
-
- // Generated message map functions
- //{{AFX_MSG(AboutDialog)
- virtual BOOL OnInitDialog();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_ABOUTDIALOG_H__4B8A04B2_9735_4F4A_AFCA_15F85FB3D763__INCLUDED_)
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: Application.cpp,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.5 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.4 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.3 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.2 2002/09/20 08:37:34 bradley
-Increased the DNS record cache from the default of 64 to 512 entries for larger networks.
-
-Revision 1.1 2002/09/20 06:12:51 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#include <assert.h>
-
-#include "DNSServices.h"
-
-#include "Application.h"
-
-#include "ChooserDialog.h"
-
-#include "stdafx.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-//===========================================================================================================================
-// Message Map
-//===========================================================================================================================
-
-BEGIN_MESSAGE_MAP(Application, CWinApp)
- //{{AFX_MSG_MAP(Application)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG
- ON_COMMAND(ID_HELP, CWinApp::OnHelp)
-END_MESSAGE_MAP()
-
-//===========================================================================================================================
-// Globals
-//===========================================================================================================================
-
-Application gApp;
-
-//===========================================================================================================================
-// Application
-//===========================================================================================================================
-
-Application::Application( void )
-{
- //
-}
-
-//===========================================================================================================================
-// InitInstance
-//===========================================================================================================================
-
-BOOL Application::InitInstance()
-{
- DNSStatus err;
-
- // WinSock initialization.
-
- if( !AfxSocketInit() )
- {
- AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
- return( FALSE );
- }
-
- // Standard MFC initialization.
-
-#if( !defined( AFX_DEPRECATED ) )
- #ifdef _AFXDLL
- Enable3dControls(); // Call this when using MFC in a shared DLL
- #else
- Enable3dControlsStatic(); // Call this when linking to MFC statically
- #endif
-#endif
-
- InitCommonControls();
-
- // Set up DNS Services.
-
- err = DNSServicesInitialize( 0, 512 );
- assert( err == kDNSNoErr );
-
- // Create the chooser dialog.
-
- ChooserDialog * dialog;
-
- m_pMainWnd = NULL;
- dialog = new ChooserDialog;
- dialog->Create( IDD_CHOOSER_DIALOG );
- m_pMainWnd = dialog;
- dialog->ShowWindow( SW_SHOW );
-
- return( true );
-}
-
-//===========================================================================================================================
-// ExitInstance
-//===========================================================================================================================
-
-int Application::ExitInstance( void )
-{
- // Clean up DNS Services.
-
- DNSServicesFinalize();
- return( 0 );
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: Application.h,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.4 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.3 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.2 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.1 2002/09/20 06:12:51 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#if !defined(AFX_ADMIN_H__8663733F_6A15_439F_B568_F5A0125CD572__INCLUDED_)
-#define AFX_ADMIN_H__8663733F_6A15_439F_B568_F5A0125CD572__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include "stdafx.h"
-
-#ifndef __AFXWIN_H__
- #error include 'stdafx.h' before including this file for PCH
-#endif
-
-#include "Resource.h"
-
-//===========================================================================================================================
-// Globals
-//===========================================================================================================================
-
-extern class Application gApp;
-
-//===========================================================================================================================
-// Application
-//===========================================================================================================================
-
-class Application : public CWinApp
-{
- public:
-
- // Creation/Deletion
-
- Application();
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(Application)
- public:
- virtual BOOL InitInstance();
- virtual int ExitInstance( void );
- //}}AFX_VIRTUAL
-
- //{{AFX_MSG(Application)
- // NOTE - the ClassWizard will add and remove member functions here.
- // DO NOT EDIT what you see in these blocks of generated code !
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_ADMIN_H__8663733F_6A15_439F_B568_F5A0125CD572__INCLUDED_)
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: ChooserDialog.cpp,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.7 2003/08/20 06:45:56 bradley
-Updated for IP address changes in DNSServices. Added support for browsing for Xserve RAID.
-
-Revision 1.6 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.5 2003/07/13 01:03:55 cheshire
-Diffs provided by Bob Bradley to provide provide proper display of Unicode names
-
-Revision 1.4 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.3 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.2 2002/09/20 08:39:21 bradley
-Make sure each resolved item matches the selected service type to handle resolved that may have
-been queued up on the Windows Message Loop. Reduce column to fit when scrollbar is present.
-
-Revision 1.1 2002/09/20 06:12:52 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#include <algorithm>
-#include <memory>
-
-#include "stdafx.h"
-
-#include "DNSServices.h"
-
-#include "Application.h"
-#include "AboutDialog.h"
-#include "Resource.h"
-
-#include "ChooserDialog.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-#if 0
-#pragma mark == Constants ==
-#endif
-
-//===========================================================================================================================
-// Constants
-//===========================================================================================================================
-
-// Menus
-
-enum
-{
- kChooserMenuIndexFile = 0,
- kChooserMenuIndexHelp = 1
-};
-
-// Domain List
-
-#define kDomainListDefaultDomainColumnIndex 0
-#define kDomainListDefaultDomainColumnWidth 140
-
-// Service List
-
-#define kServiceListDefaultServiceColumnIndex 0
-#define kServiceListDefaultServiceColumnWidth 140
-
-// Chooser List
-
-#define kChooserListDefaultNameColumnIndex 0
-#define kChooserListDefaultNameColumnWidth 162
-
-#define kChooserListDefaultIPColumnIndex 1
-#define kChooserListDefaultIPColumnWidth 126
-
-// Windows User Messages
-
-#define WM_USER_DOMAIN_ADD ( WM_USER + 0x100 )
-#define WM_USER_DOMAIN_REMOVE ( WM_USER + 0x101 )
-#define WM_USER_SERVICE_ADD ( WM_USER + 0x102 )
-#define WM_USER_SERVICE_REMOVE ( WM_USER + 0x103 )
-#define WM_USER_RESOLVE ( WM_USER + 0x104 )
-
-#if 0
-#pragma mark == Constants - Service Table ==
-#endif
-
-//===========================================================================================================================
-// Constants - Service Table
-//===========================================================================================================================
-
-struct KnownServiceEntry
-{
- const char * serviceType;
- const char * description;
- const char * urlScheme;
- bool useText;
-};
-
-static const KnownServiceEntry kKnownServiceTable[] =
-{
- { "_airport._tcp.", "AirPort Base Station", "acp://", false },
- { "_afpovertcp._tcp.", "AppleShare Server", "afp://", false },
- { "_ftp._tcp.", "File Transfer (FTP)", "ftp://", false },
- { "_ichat._tcp.", "iChat", "ichat://", false },
- { "_printer._tcp.", "Printer (LPD)", "ldp://", false },
- { "_eppc._tcp.", "Remote AppleEvents", "eppc://", false },
- { "_ssh._tcp.", "Secure Shell (SSH)", "ssh://", false },
- { "_tftp._tcp.", "Trivial File Transfer (TFTP)", "tftp://", false },
- { "_http._tcp.", "Web Server (HTTP)", "http://", true },
- { "_smb._tcp.", "Windows File Sharing", "smb://", false },
- { "_xserveraid._tcp.", "Xserve RAID", "xsr://", false },
- { NULL, NULL, NULL, false },
-};
-
-#if 0
-#pragma mark == Structures ==
-#endif
-
-//===========================================================================================================================
-// Structures
-//===========================================================================================================================
-
-struct DomainEventInfo
-{
- DNSBrowserEventType eventType;
- CString domain;
- DNSNetworkAddress ifIP;
-};
-
-struct ServiceEventInfo
-{
- DNSBrowserEventType eventType;
- std::string name;
- std::string type;
- std::string domain;
- DNSNetworkAddress ifIP;
-};
-
-#if 0
-#pragma mark == Prototypes ==
-#endif
-
-//===========================================================================================================================
-// Prototypes
-//===========================================================================================================================
-
-static void
- BrowserCallBack(
- void * inContext,
- DNSBrowserRef inRef,
- DNSStatus inStatusCode,
- const DNSBrowserEvent * inEvent );
-
-static char * DNSNetworkAddressToString( const DNSNetworkAddress *inAddr, char *outString );
-
-static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject );
-
-#if 0
-#pragma mark == Message Map ==
-#endif
-
-//===========================================================================================================================
-// Message Map
-//===========================================================================================================================
-
-BEGIN_MESSAGE_MAP(ChooserDialog, CDialog)
- //{{AFX_MSG_MAP(ChooserDialog)
- ON_WM_SYSCOMMAND()
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_DOMAIN_LIST, OnDomainListChanged)
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_SERVICE_LIST, OnServiceListChanged)
- ON_NOTIFY(LVN_ITEMCHANGED, IDC_CHOOSER_LIST, OnChooserListChanged)
- ON_NOTIFY(NM_DBLCLK, IDC_CHOOSER_LIST, OnChooserListDoubleClick)
- ON_COMMAND(ID_HELP_ABOUT, OnAbout)
- ON_WM_INITMENUPOPUP()
- ON_WM_ACTIVATE()
- ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
- ON_COMMAND(ID_FILE_EXIT, OnExit)
- ON_WM_CLOSE()
- ON_WM_NCDESTROY()
- //}}AFX_MSG_MAP
- ON_MESSAGE( WM_USER_DOMAIN_ADD, OnDomainAdd )
- ON_MESSAGE( WM_USER_DOMAIN_REMOVE, OnDomainRemove )
- ON_MESSAGE( WM_USER_SERVICE_ADD, OnServiceAdd )
- ON_MESSAGE( WM_USER_SERVICE_REMOVE, OnServiceRemove )
- ON_MESSAGE( WM_USER_RESOLVE, OnResolve )
-END_MESSAGE_MAP()
-
-#if 0
-#pragma mark == Routines ==
-#endif
-
-//===========================================================================================================================
-// ChooserDialog
-//===========================================================================================================================
-
-ChooserDialog::ChooserDialog( CWnd *inParent )
- : CDialog( ChooserDialog::IDD, inParent)
-{
- //{{AFX_DATA_INIT(ChooserDialog)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
-
- // Load menu accelerator table.
-
- mMenuAcceleratorTable = ::LoadAccelerators( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDR_CHOOSER_DIALOG_MENU_ACCELERATORS ) );
- assert( mMenuAcceleratorTable );
-
- mBrowser = NULL;
- mIsServiceBrowsing = false;
-}
-
-//===========================================================================================================================
-// ~ChooserDialog
-//===========================================================================================================================
-
-ChooserDialog::~ChooserDialog( void )
-{
- if( mBrowser )
- {
- DNSStatus err;
-
- err = DNSBrowserRelease( mBrowser, 0 );
- assert( err == kDNSNoErr );
- }
-}
-
-//===========================================================================================================================
-// DoDataExchange
-//===========================================================================================================================
-
-void ChooserDialog::DoDataExchange( CDataExchange *pDX )
-{
- CDialog::DoDataExchange(pDX);
-
- //{{AFX_DATA_MAP(ChooserDialog)
- DDX_Control(pDX, IDC_SERVICE_LIST, mServiceList);
- DDX_Control(pDX, IDC_DOMAIN_LIST, mDomainList);
- DDX_Control(pDX, IDC_CHOOSER_LIST, mChooserList);
- //}}AFX_DATA_MAP
-}
-
-//===========================================================================================================================
-// OnInitDialog
-//===========================================================================================================================
-
-BOOL ChooserDialog::OnInitDialog( void )
-{
- BOOL result;
- CString tempString;
- DNSStatus err;
-
- // Initialize our parent.
-
- CDialog::OnInitDialog();
-
- // Set up the Domain List.
-
- result = tempString.LoadString( IDS_CHOOSER_DOMAIN_COLUMN_NAME );
- assert( result );
- mDomainList.InsertColumn( 0, tempString, LVCFMT_LEFT, kDomainListDefaultDomainColumnWidth );
-
- // Set up the Service List.
-
- result = tempString.LoadString( IDS_CHOOSER_SERVICE_COLUMN_NAME );
- assert( result );
- mServiceList.InsertColumn( 0, tempString, LVCFMT_LEFT, kServiceListDefaultServiceColumnWidth );
-
- PopulateServicesList();
-
- // Set up the Chooser List.
-
- result = tempString.LoadString( IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME );
- assert( result );
- mChooserList.InsertColumn( 0, tempString, LVCFMT_LEFT, kChooserListDefaultNameColumnWidth );
-
- result = tempString.LoadString( IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME );
- assert( result );
- mChooserList.InsertColumn( 1, tempString, LVCFMT_LEFT, kChooserListDefaultIPColumnWidth );
-
- // Set up the other controls.
-
- UpdateInfoDisplay();
-
- // Start browsing for domains.
-
- err = DNSBrowserCreate( 0, BrowserCallBack, this, &mBrowser );
- assert( err == kDNSNoErr );
-
- err = DNSBrowserStartDomainSearch( mBrowser, 0 );
- assert( err == kDNSNoErr );
-
- return( true );
-}
-
-//===========================================================================================================================
-// OnFileClose
-//===========================================================================================================================
-
-void ChooserDialog::OnFileClose()
-{
- OnClose();
-}
-
-//===========================================================================================================================
-// OnActivate
-//===========================================================================================================================
-
-void ChooserDialog::OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized )
-{
- // Always make the active window the "main" window so modal dialogs work better and the app quits after closing
- // the last window.
-
- gApp.m_pMainWnd = this;
-
- CDialog::OnActivate(nState, pWndOther, bMinimized);
-}
-
-//===========================================================================================================================
-// PostNcDestroy
-//===========================================================================================================================
-
-void ChooserDialog::PostNcDestroy()
-{
- // Call the base class to do the normal cleanup.
-
- delete this;
-}
-
-//===========================================================================================================================
-// PreTranslateMessage
-//===========================================================================================================================
-
-BOOL ChooserDialog::PreTranslateMessage(MSG* pMsg)
-{
- BOOL result;
-
- result = false;
- assert( mMenuAcceleratorTable );
- if( mMenuAcceleratorTable )
- {
- result = ::TranslateAccelerator( m_hWnd, mMenuAcceleratorTable, pMsg );
- }
- if( !result )
- {
- result = CDialog::PreTranslateMessage( pMsg );
- }
- return( result );
-}
-
-//===========================================================================================================================
-// OnInitMenuPopup
-//===========================================================================================================================
-
-void ChooserDialog::OnInitMenuPopup( CMenu *pPopupMenu, UINT nIndex, BOOL bSysMenu )
-{
- CDialog::OnInitMenuPopup( pPopupMenu, nIndex, bSysMenu );
-
- switch( nIndex )
- {
- case kChooserMenuIndexFile:
- break;
-
- case kChooserMenuIndexHelp:
- break;
-
- default:
- break;
- }
-}
-
-//===========================================================================================================================
-// OnExit
-//===========================================================================================================================
-
-void ChooserDialog::OnExit()
-{
- AfxPostQuitMessage( 0 );
-}
-
-//===========================================================================================================================
-// OnAbout
-//===========================================================================================================================
-
-void ChooserDialog::OnAbout()
-{
- AboutDialog dialog;
-
- dialog.DoModal();
-}
-
-//===========================================================================================================================
-// OnSysCommand
-//===========================================================================================================================
-
-void ChooserDialog::OnSysCommand( UINT inID, LPARAM inParam )
-{
- CDialog::OnSysCommand( inID, inParam );
-}
-
-//===========================================================================================================================
-// OnClose
-//===========================================================================================================================
-
-void ChooserDialog::OnClose()
-{
- StopBrowsing();
-
- gApp.m_pMainWnd = this;
- DestroyWindow();
-}
-
-//===========================================================================================================================
-// OnNcDestroy
-//===========================================================================================================================
-
-void ChooserDialog::OnNcDestroy()
-{
- gApp.m_pMainWnd = this;
-
- CDialog::OnNcDestroy();
-}
-
-//===========================================================================================================================
-// OnDomainListChanged
-//===========================================================================================================================
-
-void ChooserDialog::OnDomainListChanged( NMHDR *pNMHDR, LRESULT *pResult )
-{
- UNUSED_ALWAYS( pNMHDR );
-
- // Domain list changes have similar effects to service list changes so reuse that code path by calling it here.
-
- OnServiceListChanged( NULL, NULL );
-
- *pResult = 0;
-}
-
-//===========================================================================================================================
-// OnServiceListChanged
-//===========================================================================================================================
-
-void ChooserDialog::OnServiceListChanged( NMHDR *pNMHDR, LRESULT *pResult )
-{
- int selectedType;
- int selectedDomain;
-
- UNUSED_ALWAYS( pNMHDR );
-
- // Stop any existing service search.
-
- StopBrowsing();
-
- // If a domain and service type are selected, start searching for the service type on the domain.
-
- selectedType = mServiceList.GetNextItem( -1, LVNI_SELECTED );
- selectedDomain = mDomainList.GetNextItem( -1, LVNI_SELECTED );
-
- if( ( selectedType >= 0 ) && ( selectedDomain >= 0 ) )
- {
- CString type;
- CString domain;
-
- type = mServiceTypes[ selectedType ].serviceType.c_str();
- domain = mDomainList.GetItemText( selectedDomain, 0 );
-
- StartBrowsing( type, domain );
- }
-
- if( pResult )
- {
- *pResult = 0;
- }
-}
-
-//===========================================================================================================================
-// OnChooserListChanged
-//===========================================================================================================================
-
-void ChooserDialog::OnChooserListChanged( NMHDR *pNMHDR, LRESULT *pResult )
-{
- UNUSED_ALWAYS( pNMHDR );
-
- UpdateInfoDisplay();
- *pResult = 0;
-}
-
-//===========================================================================================================================
-// OnChooserListDoubleClick
-//===========================================================================================================================
-
-void ChooserDialog::OnChooserListDoubleClick( NMHDR *pNMHDR, LRESULT *pResult )
-{
- int selectedItem;
-
- UNUSED_ALWAYS( pNMHDR );
-
- // Display the service instance if it is selected. Otherwise, clear all the info.
-
- selectedItem = mChooserList.GetNextItem( -1, LVNI_SELECTED );
- if( selectedItem >= 0 )
- {
- ServiceInstanceInfo * p;
- CString url;
- const KnownServiceEntry * service;
-
- assert( selectedItem < (int) mServiceInstances.size() );
- p = &mServiceInstances[ selectedItem ];
-
- // Search for a known service type entry that matches.
-
- for( service = kKnownServiceTable; service->serviceType; ++service )
- {
- if( p->type == service->serviceType )
- {
- break;
- }
- }
- if( service->serviceType )
- {
- // Create a URL representing the service instance. Special case for SMB (no port number).
-
- if( strcmp( service->serviceType, "_smb._tcp" ) == 0 )
- {
- url.Format( "%s%s/", service->urlScheme, (const char *) p->ip.c_str() );
- }
- else
- {
- const char * text;
-
- text = service->useText ? p->text.c_str() : "";
- url.Format( "%s%s/%s", service->urlScheme, (const char *) p->ip.c_str(), text );
- }
-
- // Let the system open the URL in the correct app.
-
- ShellExecute( NULL, "open", url, "", "c:\\", SW_SHOWNORMAL );
- }
- }
- *pResult = 0;
-}
-
-//===========================================================================================================================
-// OnCancel
-//===========================================================================================================================
-
-void ChooserDialog::OnCancel()
-{
- // Do nothing.
-}
-
-//===========================================================================================================================
-// PopulateServicesList
-//===========================================================================================================================
-
-void ChooserDialog::PopulateServicesList( void )
-{
- ServiceTypeVector::iterator i;
- CString name;
-
- // Add a fixed list of known services.
-
- if( mServiceTypes.empty() )
- {
- const KnownServiceEntry * service;
-
- for( service = kKnownServiceTable; service->serviceType; ++service )
- {
- ServiceTypeInfo info;
-
- info.serviceType = service->serviceType;
- info.description = service->description;
- info.urlScheme = service->urlScheme;
- mServiceTypes.push_back( info );
- }
- }
-
- // Add each service to the list.
-
- for( i = mServiceTypes.begin(); i != mServiceTypes.end(); ++i )
- {
- UTF8StringToStringObject( ( *i ).description.c_str(), name );
- mServiceList.InsertItem( mServiceList.GetItemCount(), name );
- }
-
- // Select the first service type by default.
-
- if( !mServiceTypes.empty() )
- {
- mServiceList.SetItemState( 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
- }
-}
-
-//===========================================================================================================================
-// UpdateInfoDisplay
-//===========================================================================================================================
-
-void ChooserDialog::UpdateInfoDisplay( void )
-{
- int selectedItem;
- std::string name;
- CString s;
- std::string ip;
- std::string ifIP;
- std::string text;
- CWnd * item;
-
- // Display the service instance if it is selected. Otherwise, clear all the info.
-
- selectedItem = mChooserList.GetNextItem( -1, LVNI_SELECTED );
- if( selectedItem >= 0 )
- {
- ServiceInstanceInfo * p;
-
- assert( selectedItem < (int) mServiceInstances.size() );
- p = &mServiceInstances[ selectedItem ];
-
- name = p->name;
- ip = p->ip;
- ifIP = p->ifIP;
- text = p->text;
-
- // Sync up the list items with the actual data (IP address may change).
-
- mChooserList.SetItemText( selectedItem, 1, ip.c_str() );
- }
-
- // Name
-
- item = (CWnd *) this->GetDlgItem( IDC_INFO_NAME_TEXT );
- assert( item );
- UTF8StringToStringObject( name.c_str(), s );
- item->SetWindowText( s );
-
- // IP
-
- item = (CWnd *) this->GetDlgItem( IDC_INFO_IP_TEXT );
- assert( item );
- item->SetWindowText( ip.c_str() );
-
- // Interface
-
- item = (CWnd *) this->GetDlgItem( IDC_INFO_INTERFACE_TEXT );
- assert( item );
- item->SetWindowText( ifIP.c_str() );
-
- // Text
-
- if( text.size() > 255 )
- {
- text.resize( 255 );
- }
- item = (CWnd *) this->GetDlgItem( IDC_INFO_TEXT_TEXT );
- assert( item );
- item->SetWindowText( text.c_str() );
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-// OnDomainAdd
-//===========================================================================================================================
-
-LONG ChooserDialog::OnDomainAdd( WPARAM inWParam, LPARAM inLParam )
-{
- DomainEventInfo * p;
- std::auto_ptr < DomainEventInfo > pAutoPtr;
- int n;
- int i;
- CString domain;
- CString s;
- bool found;
-
- UNUSED_ALWAYS( inWParam );
-
- assert( inLParam );
- p = reinterpret_cast <DomainEventInfo *> ( inLParam );
- pAutoPtr.reset( p );
-
- // Search to see if we already know about this domain. If not, add it to the list.
-
- found = false;
- domain = p->domain;
- n = mDomainList.GetItemCount();
- for( i = 0; i < n; ++i )
- {
- s = mDomainList.GetItemText( i, 0 );
- if( s == domain )
- {
- found = true;
- break;
- }
- }
- if( !found )
- {
- int selectedItem;
-
- mDomainList.InsertItem( n, domain );
-
- // If no domains are selected and the domain being added is a default domain, select it.
-
- selectedItem = mDomainList.GetNextItem( -1, LVNI_SELECTED );
- if( ( selectedItem < 0 ) && ( p->eventType == kDNSBrowserEventTypeAddDefaultDomain ) )
- {
- mDomainList.SetItemState( n, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
- }
- }
- return( 0 );
-}
-
-//===========================================================================================================================
-// OnDomainRemove
-//===========================================================================================================================
-
-LONG ChooserDialog::OnDomainRemove( WPARAM inWParam, LPARAM inLParam )
-{
- DomainEventInfo * p;
- std::auto_ptr < DomainEventInfo > pAutoPtr;
- int n;
- int i;
- CString domain;
- CString s;
- bool found;
-
- UNUSED_ALWAYS( inWParam );
-
- assert( inLParam );
- p = reinterpret_cast <DomainEventInfo *> ( inLParam );
- pAutoPtr.reset( p );
-
- // Search to see if we know about this domain. If so, remove it from the list.
-
- found = false;
- domain = p->domain;
- n = mDomainList.GetItemCount();
- for( i = 0; i < n; ++i )
- {
- s = mDomainList.GetItemText( i, 0 );
- if( s == domain )
- {
- found = true;
- break;
- }
- }
- if( found )
- {
- mDomainList.DeleteItem( i );
- }
- return( 0 );
-}
-
-//===========================================================================================================================
-// OnServiceAdd
-//===========================================================================================================================
-
-LONG ChooserDialog::OnServiceAdd( WPARAM inWParam, LPARAM inLParam )
-{
- ServiceEventInfo * p;
- std::auto_ptr < ServiceEventInfo > pAutoPtr;
-
- UNUSED_ALWAYS( inWParam );
-
- assert( inLParam );
- p = reinterpret_cast <ServiceEventInfo *> ( inLParam );
- pAutoPtr.reset( p );
-
- return( 0 );
-}
-
-//===========================================================================================================================
-// OnServiceRemove
-//===========================================================================================================================
-
-LONG ChooserDialog::OnServiceRemove( WPARAM inWParam, LPARAM inLParam )
-{
- ServiceEventInfo * p;
- std::auto_ptr < ServiceEventInfo > pAutoPtr;
- bool found;
- int n;
- int i;
-
- UNUSED_ALWAYS( inWParam );
-
- assert( inLParam );
- p = reinterpret_cast <ServiceEventInfo *> ( inLParam );
- pAutoPtr.reset( p );
-
- // Search to see if we know about this service instance. If so, remove it from the list.
-
- found = false;
- n = (int) mServiceInstances.size();
- for( i = 0; i < n; ++i )
- {
- ServiceInstanceInfo * q;
-
- // If the name, type, domain, and interface match, treat it as the same service instance.
-
- q = &mServiceInstances[ i ];
- if( ( p->name == q->name ) &&
- ( p->type == q->type ) &&
- ( p->domain == q->domain ) )
- {
- found = true;
- break;
- }
- }
- if( found )
- {
- mChooserList.DeleteItem( i );
- assert( i < (int) mServiceInstances.size() );
- mServiceInstances.erase( mServiceInstances.begin() + i );
- }
- return( 0 );
-}
-
-//===========================================================================================================================
-// OnResolve
-//===========================================================================================================================
-
-LONG ChooserDialog::OnResolve( WPARAM inWParam, LPARAM inLParam )
-{
- ServiceInstanceInfo * p;
- std::auto_ptr < ServiceInstanceInfo > pAutoPtr;
- int selectedType;
- int n;
- int i;
- bool found;
-
- UNUSED_ALWAYS( inWParam );
-
- assert( inLParam );
- p = reinterpret_cast <ServiceInstanceInfo *> ( inLParam );
- pAutoPtr.reset( p );
-
- // Make sure it is for an item of the correct type. This handles any resolves that may have been queued up.
-
- selectedType = mServiceList.GetNextItem( -1, LVNI_SELECTED );
- assert( selectedType >= 0 );
- if( selectedType >= 0 )
- {
- assert( selectedType <= (int) mServiceTypes.size() );
- if( p->type != mServiceTypes[ selectedType ].serviceType )
- {
- goto exit;
- }
- }
-
- // Search to see if we know about this service instance. If so, update its info. Otherwise, add it to the list.
-
- found = false;
- n = (int) mServiceInstances.size();
- for( i = 0; i < n; ++i )
- {
- ServiceInstanceInfo * q;
-
- // If the name, type, domain, and interface matches, treat it as the same service instance.
-
- q = &mServiceInstances[ i ];
- if( ( p->name == q->name ) &&
- ( p->type == q->type ) &&
- ( p->domain == q->domain ) &&
- ( p->ifIP == q->ifIP ) )
- {
- found = true;
- break;
- }
- }
- if( found )
- {
- mServiceInstances[ i ] = *p;
- }
- else
- {
- CString s;
-
- mServiceInstances.push_back( *p );
- UTF8StringToStringObject( p->name.c_str(), s );
- mChooserList.InsertItem( n, s );
- mChooserList.SetItemText( n, 1, p->ip.c_str() );
-
- // If this is the only item, select it.
-
- if( n == 0 )
- {
- mChooserList.SetItemState( n, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED );
- }
- }
- UpdateInfoDisplay();
-
-exit:
- return( 0 );
-}
-
-//===========================================================================================================================
-// StartBrowsing
-//===========================================================================================================================
-
-void ChooserDialog::StartBrowsing( const char *inType, const char *inDomain )
-{
- DNSStatus err;
-
- assert( mServiceInstances.empty() );
- assert( mChooserList.GetItemCount() == 0 );
- assert( !mIsServiceBrowsing );
-
- mChooserList.DeleteAllItems();
- mServiceInstances.clear();
-
- mIsServiceBrowsing = true;
- err = DNSBrowserStartServiceSearch( mBrowser, kDNSBrowserFlagAutoResolve, inType, inDomain );
- assert( err == kDNSNoErr );
-}
-
-//===========================================================================================================================
-// StopBrowsing
-//===========================================================================================================================
-
-void ChooserDialog::StopBrowsing( void )
-{
- // If searching, stop.
-
- if( mIsServiceBrowsing )
- {
- DNSStatus err;
-
- mIsServiceBrowsing = false;
- err = DNSBrowserStopServiceSearch( mBrowser, 0 );
- assert( err == kDNSNoErr );
- }
-
- // Remove all service instances.
-
- mChooserList.DeleteAllItems();
- assert( mChooserList.GetItemCount() == 0 );
- mServiceInstances.clear();
- assert( mServiceInstances.empty() );
- UpdateInfoDisplay();
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-// BrowserCallBack
-//===========================================================================================================================
-
-static void
- BrowserCallBack(
- void * inContext,
- DNSBrowserRef inRef,
- DNSStatus inStatusCode,
- const DNSBrowserEvent * inEvent )
-{
- ChooserDialog * dialog;
- UINT message;
- BOOL posted;
-
- UNUSED_ALWAYS( inStatusCode );
- UNUSED_ALWAYS( inRef );
-
- // Check parameters.
-
- assert( inContext );
- dialog = reinterpret_cast <ChooserDialog *> ( inContext );
-
- try
- {
- switch( inEvent->type )
- {
- case kDNSBrowserEventTypeRelease:
- break;
-
- // Domains
-
- case kDNSBrowserEventTypeAddDomain:
- case kDNSBrowserEventTypeAddDefaultDomain:
- case kDNSBrowserEventTypeRemoveDomain:
- {
- DomainEventInfo * domain;
- std::auto_ptr < DomainEventInfo > domainAutoPtr;
-
- domain = new DomainEventInfo;
- domainAutoPtr.reset( domain );
-
- domain->eventType = inEvent->type;
- domain->domain = inEvent->data.addDomain.domain;
- domain->ifIP = inEvent->data.addDomain.interfaceIP;
-
- message = ( inEvent->type == kDNSBrowserEventTypeRemoveDomain ) ? WM_USER_DOMAIN_REMOVE : WM_USER_DOMAIN_ADD;
- posted = ::PostMessage( dialog->GetSafeHwnd(), message, 0, (LPARAM) domain );
- assert( posted );
- if( posted )
- {
- domainAutoPtr.release();
- }
- break;
- }
-
- // Services
-
- case kDNSBrowserEventTypeAddService:
- case kDNSBrowserEventTypeRemoveService:
- {
- ServiceEventInfo * service;
- std::auto_ptr < ServiceEventInfo > serviceAutoPtr;
-
- service = new ServiceEventInfo;
- serviceAutoPtr.reset( service );
-
- service->eventType = inEvent->type;
- service->name = inEvent->data.addService.name;
- service->type = inEvent->data.addService.type;
- service->domain = inEvent->data.addService.domain;
- service->ifIP = inEvent->data.addService.interfaceIP;
-
- message = ( inEvent->type == kDNSBrowserEventTypeAddService ) ? WM_USER_SERVICE_ADD : WM_USER_SERVICE_REMOVE;
- posted = ::PostMessage( dialog->GetSafeHwnd(), message, 0, (LPARAM) service );
- assert( posted );
- if( posted )
- {
- serviceAutoPtr.release();
- }
- break;
- }
-
- // Resolves
-
- case kDNSBrowserEventTypeResolved:
- {
- ServiceInstanceInfo * serviceInstance;
- std::auto_ptr < ServiceInstanceInfo > serviceInstanceAutoPtr;
- char s[ 32 ];
-
- serviceInstance = new ServiceInstanceInfo;
- serviceInstanceAutoPtr.reset( serviceInstance );
-
- serviceInstance->name = inEvent->data.resolved->name;
- serviceInstance->type = inEvent->data.resolved->type;
- serviceInstance->domain = inEvent->data.resolved->domain;
- serviceInstance->ip = DNSNetworkAddressToString( &inEvent->data.resolved->address, s );
- serviceInstance->ifIP = DNSNetworkAddressToString( &inEvent->data.resolved->interfaceIP, s );
- serviceInstance->text = inEvent->data.resolved->textRecord;
-
- posted = ::PostMessage( dialog->GetSafeHwnd(), WM_USER_RESOLVE, 0, (LPARAM) serviceInstance );
- assert( posted );
- if( posted )
- {
- serviceInstanceAutoPtr.release();
- }
- break;
- }
-
- default:
- break;
- }
- }
- catch( ... )
- {
- // Don't let exceptions escape.
- }
-}
-
-//===========================================================================================================================
-// DNSNetworkAddressToString
-//
-// Note: Currently only supports IPv4 network addresses.
-//===========================================================================================================================
-
-static char * DNSNetworkAddressToString( const DNSNetworkAddress *inAddr, char *outString )
-{
- const DNSUInt8 * p;
- DNSUInt16 port;
-
- p = inAddr->u.ipv4.addr.v8;
- port = ntohs( inAddr->u.ipv4.port.v16 );
- if( port != kDNSPortInvalid )
- {
- sprintf( outString, "%u.%u.%u.%u:%u", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ], port );
- }
- else
- {
- sprintf( outString, "%u.%u.%u.%u", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] );
- }
- return( outString );
-}
-
-//===========================================================================================================================
-// UTF8StringToStringObject
-//===========================================================================================================================
-
-static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject )
-{
- DWORD 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 = 0;
-
-exit:
- if( unicode )
- {
- free( unicode );
- }
- return( err );
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: ChooserDialog.h,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.4 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.3 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.2 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.1 2002/09/20 06:12:52 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#if !defined(AFX_CHOOSERDIALOG_H__AC258704_B307_4901_9F98_A0AC022FD8AC__INCLUDED_)
-#define AFX_CHOOSERDIALOG_H__AC258704_B307_4901_9F98_A0AC022FD8AC__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include <string>
-#include <vector>
-
-#include "afxcmn.h"
-
-#include "Resource.h"
-
-#include "DNSServices.h"
-
-//===========================================================================================================================
-// Structures
-//===========================================================================================================================
-
-struct ServiceInstanceInfo
-{
- std::string name;
- std::string type;
- std::string domain;
- std::string ip;
- std::string text;
- std::string ifIP;
-};
-
-struct ServiceTypeInfo
-{
- std::string serviceType;
- std::string description;
- std::string urlScheme;
-};
-
-//===========================================================================================================================
-// ChooserDialog
-//===========================================================================================================================
-
-class ChooserDialog : public CDialog
-{
- public:
-
- ChooserDialog(CWnd* pParent = NULL);
- virtual ~ChooserDialog( void );
-
- //{{AFX_DATA(ChooserDialog)
- enum { IDD = IDD_CHOOSER_DIALOG };
- CListCtrl mServiceList;
- CListCtrl mDomainList;
- CListCtrl mChooserList;
- //}}AFX_DATA
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(ChooserDialog)
- public:
- virtual BOOL PreTranslateMessage(MSG* pMsg);
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- virtual void PostNcDestroy();
- //}}AFX_VIRTUAL
-
- protected:
-
- typedef std::vector < ServiceInstanceInfo > ServiceInstanceVector;
- typedef std::vector < ServiceTypeInfo > ServiceTypeVector;
-
- HACCEL mMenuAcceleratorTable;
- DNSBrowserRef mBrowser;
- BOOL mIsServiceBrowsing;
- ServiceInstanceVector mServiceInstances;
- ServiceTypeVector mServiceTypes;
-
- public:
-
- void PopulateServicesList( void );
- void UpdateInfoDisplay( void );
-
- void StartBrowsing( const char *inType, const char *inDomain );
- void StopBrowsing( void );
-
- protected:
-
- //{{AFX_MSG(ChooserDialog)
- virtual BOOL OnInitDialog();
- afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
- afx_msg void OnDomainListChanged(NMHDR* pNMHDR, LRESULT* pResult);
- afx_msg void OnServiceListChanged(NMHDR* pNMHDR, LRESULT* pResult);
- afx_msg void OnChooserListChanged(NMHDR* pNMHDR, LRESULT* pResult);
- afx_msg void OnChooserListDoubleClick(NMHDR* pNMHDR, LRESULT* pResult);
- afx_msg void OnAbout();
- afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu);
- afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
- afx_msg void OnFileClose();
- virtual void OnCancel();
- afx_msg void OnExit();
- afx_msg void OnClose();
- afx_msg void OnNcDestroy();
- //}}AFX_MSG
- afx_msg LONG OnDomainAdd( WPARAM inWParam, LPARAM inLParam );
- afx_msg LONG OnDomainRemove( WPARAM inWParam, LPARAM inLParam );
- afx_msg LONG OnServiceAdd( WPARAM inWParam, LPARAM inLParam );
- afx_msg LONG OnServiceRemove( WPARAM inWParam, LPARAM inLParam );
- afx_msg LONG OnResolve( WPARAM inWParam, LPARAM inLParam );
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_CHOOSERDIALOG_H__AC258704_B307_4901_9F98_A0AC022FD8AC__INCLUDED_)
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: StdAfx.cpp,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.4 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.3 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.2 2002/09/21 20:44:55 zarzycki
-Added APSL info
-
-Revision 1.1 2002/09/20 06:12:53 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#include "stdafx.h"
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: StdAfx.h,v $
-Revision 1.1 2003/08/21 02:06:47 bradley
-Moved Rendezvous Browser for non-Windows CE into Windows sub-folder.
-
-Revision 1.4 2003/08/12 19:56:28 cheshire
-Update to APSL 2.0
-
-Revision 1.3 2003/07/02 21:20:06 cheshire
-<rdar://problem/3313413> Update copyright notices, etc., in source code comments
-
-Revision 1.2 2002/09/21 20:44:56 zarzycki
-Added APSL info
-
-Revision 1.1 2002/09/20 06:12:53 bradley
-Rendezvous Browser for Windows
-
-*/
-
-#if !defined(AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_)
-#define AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
-
-#include <afxwin.h> // MFC core and standard components
-#include <afxext.h> // MFC extensions
-#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
-#ifndef _AFX_NO_AFXCMN_SUPPORT
-#include <afxcmn.h> // MFC support for Windows Common Controls
-#endif // _AFX_NO_AFXCMN_SUPPORT
-
-#include <afxsock.h> // MFC socket extensions
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#include <stdlib.h>
-
-#include "DNSServices.h"
-
-#include "Application.h"
-
-#include "ChooserDialog.h"
-
-#endif // !defined(AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_)
+++ /dev/null
-; CLW file contains information for the MFC ClassWizard
-
-[General Info]
-Version=1
-LastClass=BrowserDialog
-LastTemplate=CDialog
-NewFileInclude1=#include "stdafx.h"
-NewFileInclude2=#include "Application.h"
-
-ClassCount=3
-Class1=Application
-Class2=BrowserDialog
-
-ResourceCount=3
-Resource2=IDR_MAINFRAME
-Resource3=IDD_APPLICATION_DIALOG
-
-[CLS:Application]
-Type=0
-HeaderFile=Application.h
-ImplementationFile=Application.cpp
-Filter=N
-
-[CLS:BrowserDialog]
-Type=0
-HeaderFile=BrowserDialog.h
-ImplementationFile=BrowserDialog.cpp
-Filter=D
-
-
-[DLG:IDD_APPLICATION_DIALOG]
-Type=1
-ControlCount=3
-Control1=IDOK,button,1342242817
-Control2=IDCANCEL,button,1342242816
-Control3=IDC_STATIC,static,1342308352
-Class=BrowserDialog
+++ /dev/null
-# Microsoft eMbedded Visual Tools Project File - Name="Application" - Package Owner=<4>
-# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (WCE ARMV4) Application" 0xa301
-# TARGTYPE "Win32 (WCE emulator) Application" 0xa601
-
-CFG=Application - Win32 (WCE emulator) Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "Application.vcn".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "Application.vcn" CFG="Application - Win32 (WCE emulator) Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "Application - Win32 (WCE emulator) Release" (based on "Win32 (WCE emulator) Application")
-!MESSAGE "Application - Win32 (WCE emulator) Debug" (based on "Win32 (WCE emulator) Application")
-!MESSAGE "Application - Win32 (WCE ARMV4) Release" (based on "Win32 (WCE ARMV4) Application")
-!MESSAGE "Application - Win32 (WCE ARMV4) Debug" (based on "Win32 (WCE ARMV4) Application")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-# PROP ATL_Project 2
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-# PROP BASE Use_MFC 2
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "emulatorRel"
-# PROP BASE Intermediate_Dir "emulatorRel"
-# PROP BASE CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
-# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 2
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "emulatorRel"
-# PROP Intermediate_Dir "emulatorRel"
-# PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
-# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
-# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
-CPP=cl.exe
-# ADD BASE CPP /nologo /W3 /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "NDEBUG" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /Yu"stdafx.h" /Gs8192 /GF /O2 /c
-# ADD CPP /nologo /W3 /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "NDEBUG" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /Gs8192 /GF /O2 /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /MACHINE:IX86
-# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /MACHINE:IX86
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-# PROP BASE Use_MFC 2
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "emulatorDbg"
-# PROP BASE Intermediate_Dir "emulatorDbg"
-# PROP BASE CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
-# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 2
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "emulatorDbg"
-# PROP Intermediate_Dir "emulatorDbg"
-# PROP CPU_ID "{32E52003-403E-442D-BE48-DE10F8C6131D}"
-# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
-# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "_X86_" /d "x86" /d "_i386_" /d "_AFXDLL" /r
-CPP=cl.exe
-# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /Yu"stdafx.h" /Gs8192 /GF /c
-# ADD CPP /nologo /W3 /WX /Zi /Od /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "_i386_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_X86_" /D "x86" /D "_WIN32_WCE_CEPC" /D "_AFXDLL" /FR /Gs8192 /GF /c
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /MACHINE:IX86
-# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /MACHINE:IX86
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-# PROP BASE Use_MFC 2
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "ARMV4Rel"
-# PROP BASE Intermediate_Dir "ARMV4Rel"
-# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
-# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 2
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "ARMV4Rel"
-# PROP Intermediate_Dir "ARMV4Rel"
-# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
-# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
-# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
-CPP=clarm.exe
-# ADD BASE CPP /nologo /W3 /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_AFXDLL" /Yu"stdafx.h" /O2 /M$(CECrtMT) /c
-# ADD CPP /nologo /W3 /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_AFXDLL" /O2 /M$(CECrtMT) /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
-# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-# PROP BASE Use_MFC 2
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "ARMV4Dbg"
-# PROP BASE Intermediate_Dir "ARMV4Dbg"
-# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
-# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 2
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "ARMV4Dbg"
-# PROP Intermediate_Dir "ARMV4Dbg"
-# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}"
-# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-RSC=rc.exe
-# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
-# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /d "_AFXDLL" /r
-CPP=clarm.exe
-# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /Yu"stdafx.h" /M$(CECrtMTDebug) /c
-# ADD CPP /nologo /W3 /Zi /Od /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /M$(CECrtMTDebug) /c
-# SUBTRACT CPP /YX /Yc /Yu
-MTL=midl.exe
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
-# ADD LINK32 ws2.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM
-
-!ENDIF
-
-# Begin Target
-
-# Name "Application - Win32 (WCE emulator) Release"
-# Name "Application - Win32 (WCE emulator) Debug"
-# Name "Application - Win32 (WCE ARMV4) Release"
-# Name "Application - Win32 (WCE ARMV4) Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\Sources\Application.cpp
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-DEP_CPP_APPLI=\
- "..\..\..\DNSServices\DNSServices.h"\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-DEP_CPP_APPLI=\
- "..\..\..\DNSServices\DNSServices.h"\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-DEP_CPP_APPLI=\
- "..\..\..\DNSServices\DNSServices.h"\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-DEP_CPP_APPLI=\
- "..\..\..\DNSServices\DNSServices.h"\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\Sources\Application.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Sources\BrowserDialog.cpp
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-DEP_CPP_BROWS=\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-DEP_CPP_BROWS=\
- "..\..\..\DNSServices\DNSServices.h"\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-DEP_CPP_BROWS=\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-DEP_CPP_BROWS=\
- ".\Sources\Application.h"\
- ".\Sources\BrowserDialog.h"\
- ".\Sources\StdAfx.h"\
-
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\Sources\BrowserDialog.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Sources\StdAfx.cpp
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-DEP_CPP_STDAF=\
- ".\Sources\StdAfx.h"\
-
-# ADD CPP /Yc"stdafx.h"
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-DEP_CPP_STDAF=\
- ".\Sources\StdAfx.h"\
-
-# ADD CPP /Yc"stdafx.h"
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-DEP_CPP_STDAF=\
- ".\Sources\StdAfx.h"\
-
-# ADD CPP /Yc"stdafx.h"
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-DEP_CPP_STDAF=\
- ".\Sources\StdAfx.h"\
-
-# ADD CPP /Yc"stdafx.h"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\Sources\StdAfx.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\Resources\Application.ico
-# End Source File
-# Begin Source File
-
-SOURCE=.\Resources\Application.rc
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\Resources\Application.rc2
-# PROP Exclude_From_Scan -1
-# PROP BASE Exclude_From_Build 1
-# PROP Exclude_From_Build 1
-# End Source File
-# Begin Source File
-
-SOURCE=.\Resources\newres.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\Resources\Resource.h
-# End Source File
-# End Group
-# Begin Group "Rendezvous"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=..\..\..\DNSServices\DNSServices.c
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-DEP_CPP_DNSSE=\
- "..\..\..\DNSServices\DNSServices.h"\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-DEP_CPP_DNSSE=\
- "..\..\..\DNSServices\DNSServices.h"\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-DEP_CPP_DNSSE=\
- "..\..\..\DNSServices\DNSServices.h"\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-DEP_CPP_DNSSE=\
- "..\..\..\DNSServices\DNSServices.h"\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\DNSServices\DNSServices.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\mDNSCore\mDNS.c
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-DEP_CPP_MDNS_=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-DEP_CPP_MDNS_=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-DEP_CPP_MDNS_=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-DEP_CPP_MDNS_=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
-
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\mDNSCore\mDNSClientAPI.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\mDNSCore\mDNSDebug.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\..\mDNSCore\mDNSPlatformFunctions.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\mDNSWin32.c
-
-!IF "$(CFG)" == "Application - Win32 (WCE emulator) Release"
-
-DEP_CPP_MDNSW=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
- "..\..\..\mDNSWin32.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
-
-DEP_CPP_MDNSW=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
- "..\..\..\mDNSWin32.h"\
-
-# ADD CPP /W3
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
-
-DEP_CPP_MDNSW=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
- "..\..\..\mDNSWin32.h"\
-
-
-!ELSEIF "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
-
-DEP_CPP_MDNSW=\
- "..\..\..\..\mDNSCore\mDNSClientAPI.h"\
- "..\..\..\..\mDNSCore\mDNSDebug.h"\
- "..\..\..\..\mDNSCore\mDNSPlatformFunctions.h"\
- "..\..\..\mDNSWin32.h"\
-
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\mDNSWin32.h
-# End Source File
-# End Group
-# End Target
-# End Project
+++ /dev/null
-Microsoft eMbedded Visual Tools Workspace File, Format Version 4.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "Application"=.\Application.vcp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
+++ /dev/null
-//Microsoft eMbedded Visual C++ generated resource script.
-//
-#include "resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include "afxres.h"
-#include "newres.h"
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE
-BEGIN
- "#include ""afxres.h""\r\n"
- "#include ""newres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE DISCARDABLE
-BEGIN
- "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
- "#define _AFX_NO_OLE_RESOURCES\r\n"
- "#define _AFX_NO_TRACKER_RESOURCES\r\n"
- "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
- "\r\n"
- "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
- "#ifdef _WIN32\r\n"
- "LANGUAGE 9, 1\r\n"
- "#pragma code_page(1252)\r\n"
- "#endif //_WIN32\r\n"
- "#include ""Resources\\Application.rc2"" // non-Microsoft eMbedded Visual C++ edited resources\r\n"
- "#include ""afxres.rc"" // Standard components\r\n"
- "#include ""wceres.rc"" // WCE-specific components\r\n"
- "#endif\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDR_MAINFRAME ICON DISCARDABLE "Application.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_APPLICATION_DIALOG DIALOG DISCARDABLE 0, 0, 139, 153
-STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION
-EXSTYLE WS_EX_APPWINDOW | 0x80000000L
-CAPTION "Rendezvous Browser"
-FONT 8, "System"
-BEGIN
- CONTROL "List1",IDC_BROWSE_LIST,"SysListView32",LVS_REPORT |
- LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER |
- WS_BORDER | WS_TABSTOP,7,7,125,141
-END
-
-
-#ifndef _MAC
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,1
- PRODUCTVERSION 1,0,0,1
- FILEFLAGSMASK 0x3fL
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x1L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904b0"
- BEGIN
- VALUE "Comments", "\0"
- VALUE "CompanyName", "Apple Computer, Inc.\0"
- VALUE "FileDescription", "Rendezvous Browser for Windows CE\0"
- VALUE "FileVersion", "1, 0, 0, 1\0"
- VALUE "InternalName", "Application\0"
- VALUE "LegalCopyright", "Copyright © 2003 Apple Computer, Inc.\0"
- VALUE "LegalTrademarks", "\0"
- VALUE "OriginalFilename", "Application.exe\0"
- VALUE "PrivateBuild", "\0"
- VALUE "ProductName", "Rendezvous Browser for Windows CE\0"
- VALUE "ProductVersion", "1, 0, 0, 1\0"
- VALUE "SpecialBuild", "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
-
-#endif // !_MAC
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO DISCARDABLE
-BEGIN
- IDD_APPLICATION_DIALOG, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 132
- TOPMARGIN, 7
- BOTTOMMARGIN, 146
- END
-END
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// String Table
-//
-
-STRINGTABLE DISCARDABLE
-BEGIN
- IDP_SOCKETS_INIT_FAILED "Windows CE sockets initialization failed."
- IDS_BROWSER_LIST_COLUMN_NAME "Name"
-END
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-#define _AFX_NO_SPLITTER_RESOURCES
-#define _AFX_NO_OLE_RESOURCES
-#define _AFX_NO_TRACKER_RESOURCES
-#define _AFX_NO_PROPERTY_RESOURCES
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE 9, 1
-#pragma code_page(1252)
-#endif //_WIN32
-#include "Resources\Application.rc2" // non-Microsoft eMbedded Visual C++ edited resources
-#include "afxres.rc" // Standard components
-#include "wceres.rc" // WCE-specific components
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
+++ /dev/null
-//
-// APPLICATION.RC2 - resources Microsoft eMbedded Visual C++ does not edit directly
-//
-
-#ifdef APSTUDIO_INVOKED
- #error this file is not editable by Microsoft eMbedded Visual C++
-#endif //APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Add manually edited resources here...
-
-/////////////////////////////////////////////////////////////////////////////
+++ /dev/null
-#ifndef __NEWRES_H__
-#define __NEWRES_H__
-
-#define SHMENUBAR RCDATA
-#if !(defined(_WIN32_WCE_PSPC) && (_WIN32_WCE >= 300))
- #undef HDS_HORZ
- #undef HDS_BUTTONS
- #undef HDS_HIDDEN
-
- #include <commctrl.h>
- // for MenuBar
- #define I_IMAGENONE (-2)
- #define NOMENU 0xFFFF
- #define IDS_SHNEW 1
- #define IDM_SHAREDNEW 10
- #define IDM_SHAREDNEWDEFAULT 11
-
- // for Tab Control
- #define TCS_SCROLLOPPOSITE 0x0001 // assumes multiline tab
- #define TCS_BOTTOM 0x0002
- #define TCS_RIGHT 0x0002
- #define TCS_VERTICAL 0x0080
- #define TCS_MULTISELECT 0x0004 // allow multi-select in button mode
- #define TCS_FLATBUTTONS 0x0008
-#endif //_WIN32_WCE_PSPC
-
-
-#endif //__NEWRES_H__
+++ /dev/null
-//{{NO_DEPENDENCIES}}
-// Microsoft eMbedded Visual C++ generated include file.
-// Used by Application.rc
-//
-#define IDD_APPLICATION_DIALOG 102
-#define IDP_SOCKETS_INIT_FAILED 103
-#define IDS_BROWSER_LIST_COLUMN_NAME 104
-#define IDR_MAINFRAME 128
-#define IDC_BROWSE_LIST 1000
-#define IDC_IP_TEXT 1003
-#define IDC_TXT_TEXT 1004
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 129
-#define _APS_NEXT_COMMAND_VALUE 32771
-#define _APS_NEXT_CONTROL_VALUE 1005
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: Application.cpp,v $
-Revision 1.1 2003/08/21 02:16:10 bradley
-Rendezvous Browser for HTTP services for Windows CE/PocketPC.
-
-*/
-
-#include "stdafx.h"
-
-#include "DNSServices.h"
-
-#include "BrowserDialog.h"
-
-#include "Application.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-//===========================================================================================================================
-// Message Map
-//===========================================================================================================================
-
-BEGIN_MESSAGE_MAP(Application, CWinApp)
- //{{AFX_MSG_MAP(Application)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-//===========================================================================================================================
-// Globals
-//===========================================================================================================================
-
-Application gApp;
-
-//===========================================================================================================================
-// Application
-//===========================================================================================================================
-
-Application::Application()
- : CWinApp()
-{
- //
-}
-
-//===========================================================================================================================
-// InitInstance
-//===========================================================================================================================
-
-BOOL Application::InitInstance()
-{
- DNSStatus err;
- BrowserDialog dialog;
- BOOL dnsInitialized;
-
- dnsInitialized = FALSE;
-
- if( !AfxSocketInit() )
- {
- AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
- goto exit;
- }
-
- err = DNSServicesInitialize( kDNSFlagAdvertise, 0 );
- if( err )
- {
- AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
- goto exit;
- }
- dnsInitialized = TRUE;
-
- // Display the main browser dialog.
-
- m_pMainWnd = &dialog;
- dialog.DoModal();
-
- // Dialog has been closed. Return false to exit the app and not start the app's message pump.
-
-exit:
- if( dnsInitialized )
- {
- DNSServicesFinalize();
- }
- return( FALSE );
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: Application.h,v $
-Revision 1.1 2003/08/21 02:16:10 bradley
-Rendezvous Browser for HTTP services for Windows CE/PocketPC.
-
-*/
-
-#if !defined(AFX_APPLICATION_H__E2E51302_D643_458E_A7A5_5157233D1E5C__INCLUDED_)
-#define AFX_APPLICATION_H__E2E51302_D643_458E_A7A5_5157233D1E5C__INCLUDED_
-
-#if _MSC_VER >= 1000
-#pragma once
-#endif // _MSC_VER >= 1000
-
-#ifndef __AFXWIN_H__
- #error include 'stdafx.h' before including this file for PCH
-#endif
-
-#include "Resource.h"
-
-//===========================================================================================================================
-// Application
-//===========================================================================================================================
-
-class Application : public CWinApp
-{
- public:
-
- Application();
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(Application)
- public:
- virtual BOOL InitInstance();
- //}}AFX_VIRTUAL
-
- //{{AFX_MSG(Application)
- // NOTE - the ClassWizard will add and remove member functions here.
- // DO NOT EDIT what you see in these blocks of generated code !
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_APPLICATION_H__E2E51302_D643_458E_A7A5_5157233D1E5C__INCLUDED_)
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: BrowserDialog.cpp,v $
-Revision 1.1 2003/08/21 02:16:10 bradley
-Rendezvous Browser for HTTP services for Windows CE/PocketPC.
-
-*/
-
-#include "stdafx.h"
-
-#include "Application.h"
-
-#include "DNSServices.h"
-
-#include "BrowserDialog.h"
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-//===========================================================================================================================
-// Message Map
-//===========================================================================================================================
-
-BEGIN_MESSAGE_MAP(BrowserDialog, CDialog)
- //{{AFX_MSG_MAP(BrowserDialog)
- //}}AFX_MSG_MAP
-END_MESSAGE_MAP()
-
-static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject );
-
-//===========================================================================================================================
-// BrowserDialog
-//===========================================================================================================================
-
-BrowserDialog::BrowserDialog( CWnd *inParent )
- : CDialog( BrowserDialog::IDD, inParent )
-{
- //{{AFX_DATA_INIT(BrowserDialog)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
-
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32.
-
- mIcon = AfxGetApp()->LoadIcon( IDR_MAINFRAME );
-}
-
-//===========================================================================================================================
-// DoDataExchange
-//===========================================================================================================================
-
-void BrowserDialog::DoDataExchange( CDataExchange *pDX )
-{
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(BrowserDialog)
- DDX_Control(pDX, IDC_BROWSE_LIST, mBrowserList);
- //}}AFX_DATA_MAP
-}
-
-//===========================================================================================================================
-// OnInitDialog
-//===========================================================================================================================
-
-BOOL BrowserDialog::OnInitDialog()
-{
- CString s;
-
- CDialog::OnInitDialog();
-
- // Set the icon for this dialog. The framework does this automatically when the application's main window is not a dialog.
-
- SetIcon( mIcon, TRUE ); // Set big icon
- SetIcon( mIcon, FALSE ); // Set small icon
-
- CenterWindow( GetDesktopWindow() );
-
- // Set up the list.
-
- CRect rect;
-
- s.LoadString( IDS_BROWSER_LIST_COLUMN_NAME );
- mBrowserList.GetWindowRect( rect );
- mBrowserList.InsertColumn( 0, s, LVCFMT_LEFT, rect.Width() - 8 );
-
- // Start browsing for services.
-
- DNSStatus err;
-
- err = DNSBrowserCreate( 0, BrowserCallBack, this, &mBrowser );
- if( err )
- {
- AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
- goto exit;
- }
-
- err = DNSBrowserStartServiceSearch( mBrowser, 0, "_http._tcp", NULL );
- if( err )
- {
- AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
- goto exit;
- }
-
-exit:
- return( TRUE );
-}
-
-//===========================================================================================================================
-// BrowserCallBack [static]
-//===========================================================================================================================
-
-void
- BrowserDialog::BrowserCallBack(
- void * inContext,
- DNSBrowserRef inRef,
- DNSStatus inStatusCode,
- const DNSBrowserEvent * inEvent )
-{
- BrowserDialog * dialog;
-
- DNS_UNUSED( inStatusCode );
- dialog = reinterpret_cast < BrowserDialog * > ( inContext );
-
- switch( inEvent->type )
- {
- case kDNSBrowserEventTypeAddService:
- dialog->BrowserAddService( inEvent->data.addService.name );
- break;
-
- case kDNSBrowserEventTypeRemoveService:
- dialog->BrowserRemoveService( inEvent->data.removeService.name );
- break;
-
- default:
- break;
- }
-}
-
-//===========================================================================================================================
-// BrowserAddService
-//===========================================================================================================================
-
-void BrowserDialog::BrowserAddService( const char *inName )
-{
- BrowserEntry newEntry;
- INT_PTR n;
- INT_PTR i;
-
- UTF8StringToStringObject( inName, newEntry.name );
-
- n = mBrowserEntries.GetSize();
- for( i = 0; i < n; ++i )
- {
- BrowserEntry & entry = mBrowserEntries.ElementAt( i );
-
- if( entry.name.CompareNoCase( newEntry.name ) == 0 )
- {
- break;
- }
- }
- if( i >= n )
- {
- mBrowserEntries.Add( newEntry );
- mBrowserList.InsertItem( i, newEntry.name );
- }
-}
-
-//===========================================================================================================================
-// BrowserRemoveService
-//===========================================================================================================================
-
-void BrowserDialog::BrowserRemoveService( const char *inName )
-{
- BrowserEntry newEntry;
- INT_PTR n;
- INT_PTR i;
-
- UTF8StringToStringObject( inName, newEntry.name );
-
- n = mBrowserEntries.GetSize();
- for( i = 0; i < n; ++i )
- {
- BrowserEntry & entry = mBrowserEntries.ElementAt( i );
-
- if( entry.name.CompareNoCase( newEntry.name ) == 0 )
- {
- break;
- }
- }
- if( i < n )
- {
- mBrowserEntries.RemoveAt( i );
- mBrowserList.DeleteItem( i );
- }
-}
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-// UTF8StringToStringObject
-//===========================================================================================================================
-
-static DWORD UTF8StringToStringObject( const char *inUTF8, CString &inObject )
-{
- DWORD err;
- int n;
- wchar_t * unicode;
-
- unicode = NULL;
-
- n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, NULL, 0 );
- if( n > 0 )
- {
- unicode = (wchar_t *) malloc( (size_t)( n * sizeof( wchar_t ) ) );
- if( !unicode ) { err = ERROR_INSUFFICIENT_BUFFER; goto exit; };
-
- n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, unicode, n );
- inObject = unicode;
- }
- else
- {
- inObject = "";
- }
- err = 0;
-
-exit:
- if( unicode )
- {
- free( unicode );
- }
- return( err );
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: BrowserDialog.h,v $
-Revision 1.1 2003/08/21 02:16:10 bradley
-Rendezvous Browser for HTTP services for Windows CE/PocketPC.
-
-*/
-
-#if !defined(AFX_BROWSERDIALOG_H__DECC5C82_C1C6_4630_B8D5_E1DDE570A061__INCLUDED_)
-#define AFX_BROWSERDIALOG_H__DECC5C82_C1C6_4630_B8D5_E1DDE570A061__INCLUDED_
-
-#if _MSC_VER >= 1000
-#pragma once
-#endif // _MSC_VER >= 1000
-
-#include "afxtempl.h"
-#include "Resource.h"
-
-#include "DNSServices.h"
-
-//===========================================================================================================================
-// BrowserDialog
-//===========================================================================================================================
-
-class BrowserDialog : public CDialog
-{
- public:
-
- BrowserDialog( CWnd *inParent = NULL );
-
- //{{AFX_DATA(BrowserDialog)
- enum { IDD = IDD_APPLICATION_DIALOG };
- CListCtrl mBrowserList;
- //}}AFX_DATA
-
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(BrowserDialog)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
-
- static void
- BrowserCallBack(
- void * inContext,
- DNSBrowserRef inRef,
- DNSStatus inStatusCode,
- const DNSBrowserEvent * inEvent );
-
- void BrowserAddService( const char *inName );
- void BrowserRemoveService( const char *inName );
-
- protected:
-
- struct BrowserEntry
- {
- CString name;
- };
-
-
- HICON mIcon;
- DNSBrowserRef mBrowser;
- CArray < BrowserEntry, BrowserEntry > mBrowserEntries;
-
- // Generated message map functions
- //{{AFX_MSG(BrowserDialog)
- virtual BOOL OnInitDialog();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
-};
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_BROWSERDIALOG_H__DECC5C82_C1C6_4630_B8D5_E1DDE570A061__INCLUDED_)
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: StdAfx.cpp,v $
-Revision 1.1 2003/08/21 02:16:10 bradley
-Rendezvous Browser for HTTP services for Windows CE/PocketPC.
-
-*/
-
-#include "stdafx.h"
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: StdAfx.h,v $
-Revision 1.1 2003/08/21 02:16:10 bradley
-Rendezvous Browser for HTTP services for Windows CE/PocketPC.
-
-*/
-
-#if !defined(AFX_STDAFX_H__7F91E52B_CF39_429D_837D_599CE0B2B3D6__INCLUDED_)
-#define AFX_STDAFX_H__7F91E52B_CF39_429D_837D_599CE0B2B3D6__INCLUDED_
-
-#if _MSC_VER >= 1000
-#pragma once
-#endif // _MSC_VER >= 1000
-
-
-
-#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
-
-#include <afxwin.h> // MFC core and standard components
-#include <afxext.h> // MFC extensions
-
-#if defined(_AFXDLL)
-#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
-#endif
-
-#ifndef _AFX_NO_AFXCMN_SUPPORT
-#include <afxcmn.h> // MFC support for Windows Common Controls
-#endif // _AFX_NO_AFXCMN_SUPPORT
-
-#include <afxsock.h> // MFC socket extensions
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_STDAFX_H__7F91E52B_CF39_429D_837D_599CE0B2B3D6__INCLUDED_)
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: Tool.c,v $
-Revision 1.7 2003/08/20 07:06:34 bradley
-Update to APSL 2.0. Updated change history to match other mDNSResponder files.
-
-Revision 1.6 2003/08/20 06:50:55 bradley
-Updated to latest internal version of the Rendezvous for Windows code: Re-did everything to support
-the latest DNSServices APIs (proxies, record updates, etc.); Added support for testing the platform
-neutral DNSServices-based emulation layer for the Mac OS X DNSServiceDiscovery API.
-
-*/
-
-#if( defined( _MSC_VER ) )
- #pragma warning( disable:4068 ) // Disable "unknown pragma" warning for "pragma unused".
- #pragma warning( disable:4127 ) // Disable "conditional expression is constant" warning for debug macros.
- #pragma warning( disable:4311 ) // Disable "type cast : pointer truncation from void *const to int".
-
- // No stdint.h with Visual C++ so emulate it here.
-
- typedef signed char int8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
- typedef unsigned char uint8_t; // C99 stdint.h not supported in VC++/VS.NET yet.
- typedef signed short int16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
- typedef unsigned short uint16_t; // C99 stdint.h not supported in VC++/VS.NET yet.
- typedef signed long int32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
- typedef unsigned long uint32_t; // C99 stdint.h not supported in VC++/VS.NET yet.
-#else
- #include <stdint.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#if( __MACH__ )
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
-
- #include <signal.h>
- #include <unistd.h>
-
- #include <CoreServices/CoreServices.h>
-#else
- #define WIN32_LEAN_AND_MEAN
-
- #include <winsock2.h>
- #include <windows.h>
-#endif
-
-#include "DNSServices.h"
-#include "DNSServiceDiscovery.h"
-
-//===========================================================================================================================
-// Macros
-//===========================================================================================================================
-
-#if( !TARGET_OS_MAC )
- #define require_action_string( X, LABEL, ACTION, STR ) \
- do \
- { \
- if( !( X ) ) \
- { \
- fprintf( stderr, "%s\n", ( STR ) ); \
- { ACTION; } \
- goto LABEL; \
- } \
- } while( 0 )
-
- #define require_string( X, LABEL, STR ) \
- do \
- { \
- if( !( X ) ) \
- { \
- fprintf( stderr, "%s\n", ( STR ) ); \
- goto LABEL; \
- \
- } \
- } while( 0 )
-
- #define require_noerr_string( ERR, LABEL, STR ) \
- do \
- { \
- if( ( ERR ) != 0 ) \
- { \
- fprintf( stderr, "%s (%ld)\n", ( STR ), ( ERR ) ); \
- goto LABEL; \
- } \
- } while( 0 )
-#endif
-
-//===========================================================================================================================
-// Prototypes
-//===========================================================================================================================
-
-int main( int argc, char* argv[] );
-static void Usage( void );
-static int ProcessArgs( int argc, char* argv[] );
-static DNSStatus ProcessPreset( int inPreset );
-
-#if( __MACH__ )
- static void SigIntHandler( int inSignalNumber );
-#endif
-
-#if( defined( WINVER ) )
- static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent );
-#endif
-
-static void BrowserCallBack( void *inContext, DNSBrowserRef inRef, DNSStatus inStatusCode, const DNSBrowserEvent *inEvent );
-static void ResolverCallBack( void *inContext, DNSResolverRef inRef, DNSStatus inStatusCode, const DNSResolverEvent *inEvent );
-
-static void
- RegistrationCallBack(
- void * inContext,
- DNSRegistrationRef inRef,
- DNSStatus inStatusCode,
- const DNSRegistrationEvent * inEvent );
-
-static void
- HostRegistrationCallBack(
- void * inContext,
- DNSHostRegistrationRef inRef,
- DNSStatus inStatusCode,
- void * inData );
-
-static void
- EmulatedBrowserCallBack(
- DNSServiceBrowserReplyResultType inResult,
- const char * inName,
- const char * inType,
- const char * inDomain,
- DNSServiceDiscoveryReplyFlags inFlags,
- void * inContext );
-
-static void
- EmulatedDomainEnumerationCallBack(
- DNSServiceDomainEnumerationReplyResultType inResult,
- const char * inDomain,
- DNSServiceDiscoveryReplyFlags inFlags,
- void * inContext );
-
-static void
- EmulatedResolverCallBack(
- struct sockaddr * inInterfaceAddr,
- struct sockaddr * inAddr,
- const char * inTextRecord,
- DNSServiceDiscoveryReplyFlags inFlags,
- void * inContext );
-
-static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult, void *inContext );
-
-static char * IPv4ToString( DNSOpaque32 inIP, char *outString );
-
-//===========================================================================================================================
-// Globals
-//===========================================================================================================================
-
-#if( defined( WINVER ) )
- static volatile int gQuit = 0;
-#endif
-
-static int gPrintTXTRecords = 1;
-
-// Presets
-
-typedef struct PresetData PresetData;
-struct PresetData
-{
- int argc;
- char * argv[ 16 ];
-};
-
-#if 0
-#pragma mark == Presets ==
-#endif
-
-static const PresetData gPresets[] =
-{
- /* 01 */ { 2, { "rendezvous", "-bbd" } },
- /* 02 */ { 4, { "rendezvous", "-bs", "_airport._tcp", "local." } },
- /* 03 */ { 4, { "rendezvous", "-bs", "_xserveraid._tcp", "local." } },
- /* 04 */ { 3, { "rendezvous", "-rdb", "apple.com" } },
- /* 05 */ { 7, { "rendezvous", "-rs", "My Fake AirPort", "_airport._tcp", "local.", "1234", "My Fake Info" } },
- /* 06 */ { 7, { "rendezvous", "-rs", "My Fake Xserve RAID", "_xserveraid._tcp", "local.", "1234", "My Fake Info" } },
- /* 07 */ { 7, { "rendezvous", "-rs", "My Fake Web Server", "_http._tcp", "local.", "8080", "index.html" } },
- /* 08 */ { 9, { "rendezvous", "-rps", "www.apple.com", "17.254.0.91", "Apple Web Server", "_http._tcp", "local.", "80", "index.html" } },
-};
-
-const int gPresetsCount = sizeof( gPresets ) / sizeof( gPresets[ 0 ] );
-
-#if 0
-#pragma mark -
-#endif
-
-//===========================================================================================================================
-// main
-//===========================================================================================================================
-
-int main( int argc, char* argv[] )
-{
- DNSStatus err;
-
- // Set up DNS Services and install a Console Control Handler to handle things like control-c signals.
-
- err = DNSServicesInitialize( kDNSFlagAdvertise, 0 );
- require_noerr_string( err, exit, "could not initialize Rendezvous" );
-
-#if( __MACH__ )
- signal( SIGINT, SigIntHandler );
-#endif
-
-#if( defined( WINVER ) )
- SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
-#endif
-
- ProcessArgs( argc, argv );
-
-exit:
- DNSServicesFinalize();
- return( err );
-}
-
-//===========================================================================================================================
-// Usage
-//===========================================================================================================================
-
-static void Usage( void )
-{
- fprintf( stderr, "\n" );
- fprintf( stderr, "rendezvous - Rendezvous Tool 1.0d1\n" );
- fprintf( stderr, "\n" );
- fprintf( stderr, " -bbd 'b'rowse for 'b'rowsing 'd'omains\n" );
- fprintf( stderr, " -brd 'b'rowse for 'r'egistration 'd'omains\n" );
- fprintf( stderr, " -bs <type> <domain> 'b'rowse for 's'ervices\n" );
- fprintf( stderr, " -lsi <name> <type> <domain> 'l'ookup 's'ervice 'i'nstance\n" );
- fprintf( stderr, " -rdb[d] <domain> 'r'egister 'd'omain for 'b'rowsing ['d'efault]\n" );
- fprintf( stderr, " -rdr[d] <domain> 'r'egister 'd'omain for 'r'egistration ['d'efault]\n" );
- fprintf( stderr, " -rs <name> <type> <domain> <port> <txt> 'r'egister 's'ervice\n" );
- fprintf( stderr, " -rps <host> <ip> <name> <type> <domain> <port> <txt> 'r'egister 'p'roxy 's'ervice\n" );
- fprintf( stderr, " -rnss <name> <type> <domain> 'r'egister 'n'o 's'uch 's'ervice\n" );
-
- fprintf( stderr, " -ebs <type> <domain> 'e'mulated 'b'rowse for 's'ervices\n" );
- fprintf( stderr, " -ebd <registration/browse> 'e'mulated 'b'rowse for 'd'omains\n" );
- fprintf( stderr, " -elsi <name> <type> <domain> 'e'mulated 'l'ookup 's'ervice 'i'nstance\n" );
- fprintf( stderr, " -ers <name> <type> <domain> <port> <txt> 'e'mulated 'r'egister 's'ervice\n" );
-
- fprintf( stderr, " -h[elp] 'h'elp\n" );
- fprintf( stderr, "\n" );
-
- fprintf( stderr, " -1 Preset 1 (browse for browsing domains) rendezvous -bbd\n" );
- fprintf( stderr, " -2 Preset 2 (browse for AirPort) rendezvous -bs \"_airport._tcp\" \"local.\"\n" );
- fprintf( stderr, " -3 Preset 3 (browse for Xserve RAID) rendezvous -bs \"_xserveraid._tcp\" \"local.\"\n" );
- fprintf( stderr, " -4 Preset 4 (register apple.com domain) rendezvous -rdb \"apple.com\"\n" );
- fprintf( stderr, " -5 Preset 5 (register fake AirPort) rendezvous -rs \"My Fake AirPort\" \"_airport._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
- fprintf( stderr, " -6 Preset 6 (register fake Xserve RAID) rendezvous -rs \"My Fake Xserve RAID\" \"_xserveraid._tcp\" \"local.\" 1234 \"My Fake Info\"\n" );
- fprintf( stderr, " -7 Preset 7 (register fake web server) rendezvous -rs \"My Fake Web Server\" \"_http._tcp\" \"local.\" 8080 \"index.html\"\n" );
- fprintf( stderr, "\n" );
-}
-
-//===========================================================================================================================
-// ProcessArgs
-//===========================================================================================================================
-
-static int ProcessArgs( int argc, char* argv[] )
-{
- DNSStatus err;
- int i;
- const char * name;
- const char * type;
- const char * domain;
- int port;
- const char * text;
- size_t textSize;
- DNSBrowserRef browser;
- DNSResolverFlags resolverFlags;
- DNSDomainRegistrationType domainType;
- const char * label;
- const char * host;
- const char * ip;
- unsigned int b[ 4 ];
- DNSNetworkAddress addr;
- dns_service_discovery_ref emulatedRef;
-
- // Parse the command line arguments (ignore first argument since it's just the program name).
-
- require_action_string( argc >= 2, exit, err = kDNSBadParamErr, "no arguments specified" );
-
- for( i = 1; i < argc; ++i )
- {
- if( strcmp( argv[ i ], "-bbd" ) == 0 )
- {
- // 'b'rowse for 'b'rowsing 'd'omains
-
- fprintf( stdout, "browsing for browsing domains\n" );
-
- err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
- require_noerr_string( err, exit, "create browser failed" );
-
- err = DNSBrowserStartDomainSearch( browser, 0 );
- require_noerr_string( err, exit, "start domain search failed" );
- }
- else if( strcmp( argv[ i ], "-brd" ) == 0 )
- {
- // 'b'rowse for 'r'egistration 'd'omains
-
- fprintf( stdout, "browsing for registration domains\n" );
-
- err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
- require_noerr_string( err, exit, "create browser failed" );
-
- err = DNSBrowserStartDomainSearch( browser, kDNSBrowserFlagRegistrationDomainsOnly );
- require_noerr_string( err, exit, "start domain search failed" );
- }
- else if( strcmp( argv[ i ], "-bs" ) == 0 )
- {
- // 'b'rowse for 's'ervices <type> <domain>
-
- require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- type = argv[ i++ ];
- domain = argv[ i ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "browsing for \"%s.%s\"\n", type, domain );
-
- err = DNSBrowserCreate( 0, BrowserCallBack, NULL, &browser );
- require_noerr_string( err, exit, "create browser failed" );
-
- err = DNSBrowserStartServiceSearch( browser, kDNSBrowserFlagAutoResolve, type, domain );
- require_noerr_string( err, exit, "start service search failed" );
- }
- else if( strcmp( argv[ i ], "-lsi" ) == 0 )
- {
- // 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
-
- require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- name = argv[ i++ ];
- type = argv[ i++ ];
- domain = argv[ i ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "resolving \"%s.%s.%s\"\n", name, type, domain );
-
- resolverFlags = kDNSResolverFlagOnlyIfUnique |
- kDNSResolverFlagAutoReleaseByName;
- err = DNSResolverCreate( resolverFlags, name, type, domain, ResolverCallBack, 0, NULL, NULL );
- require_noerr_string( err, exit, "create resolver failed" );
- }
- else if( ( strcmp( argv[ i ], "-rdb" ) == 0 ) || ( strcmp( argv[ i ], "-rdbd" ) == 0 ) )
- {
- // 'r'egister 'd'omain for 'b'rowsing ['d'efault] <domain>
-
- require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
- if( strcmp( argv[ i ], "-rdb" ) == 0 )
- {
- domainType = kDNSDomainRegistrationTypeBrowse;
- label = "";
- }
- else
- {
- domainType = kDNSDomainRegistrationTypeBrowseDefault;
- label = "default ";
- }
- ++i;
- domain = argv[ i ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "registering \"%s\" as %sbrowse domain\n", domain, label );
-
- err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL );
- require_noerr_string( err, exit, "create domain registration failed" );
- }
- else if( ( strcmp( argv[ i ], "-rdr" ) == 0 ) || ( strcmp( argv[ i ], "-rdrd" ) == 0 ) )
- {
- // 'r'egister 'd'omain for 'r'egistration ['d'efault] <domain>
-
- require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
- if( strcmp( argv[ i ], "-rdr" ) == 0 )
- {
- domainType = kDNSDomainRegistrationTypeRegistration;
- label = "";
- }
- else
- {
- domainType = kDNSDomainRegistrationTypeRegistrationDefault;
- label = "default ";
- }
- ++i;
- domain = argv[ i ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "registering \"%s\" as %sregistration domain\n", domain, label );
-
- err = DNSDomainRegistrationCreate( 0, domain, domainType, NULL );
- require_noerr_string( err, exit, "create domain registration failed" );
- }
- else if( strcmp( argv[ i ], "-rs" ) == 0 )
- {
- // 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
-
- require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- name = argv[ i++ ];
- type = argv[ i++ ];
- domain = argv[ i++ ];
- port = atoi( argv[ i++ ] );
- text = argv[ i ];
- textSize = strlen( text );
- if( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );
-
- err = DNSRegistrationCreate( 0, name, type, domain, (DNSPort) port, text, (DNSCount) textSize, NULL, NULL,
- RegistrationCallBack, NULL, NULL );
- require_noerr_string( err, exit, "create registration failed" );
- }
- else if( strcmp( argv[ i ], "-rps" ) == 0 )
- {
- DNSHostRegistrationFlags hostFlags;
-
- // 'r'egister 'p'roxy 's'ervice <name> <type> <domain> <port> <txt>
-
- require_action_string( argc > ( i + 7 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- host = argv[ i++ ];
- ip = argv[ i++ ];
- name = argv[ i++ ];
- type = argv[ i++ ];
- domain = argv[ i++ ];
- port = atoi( argv[ i++ ] );
- text = argv[ i ];
- textSize = strlen( text );
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
-
- sscanf( ip, "%u.%u.%u.%u", &b[ 0 ], &b[ 1 ], &b[ 2 ], &b[ 3 ] );
- addr.addressType = kDNSNetworkAddressTypeIPv4;
- addr.u.ipv4.addr.v32 = (DNSUInt32)( ( b[ 0 ] << 24 ) | ( b[ 1 ] << 16 ) | ( b[ 2 ] << 8 ) | ( b[ 3 ] << 0 ) );
-
- fprintf( stdout, "registering proxy service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );
-
- hostFlags = kDNSHostRegistrationFlagOnlyIfNotFound | kDNSHostRegistrationFlagAutoRenameOnConflict;
- err = DNSHostRegistrationCreate( hostFlags, host, domain, &addr, NULL,
- HostRegistrationCallBack, NULL, NULL );
- require_noerr_string( err, exit, "create host registration failed" );
-
- err = DNSRegistrationCreate( 0, name, type, domain, (DNSPort) port, text, (DNSCount) textSize, host, NULL,
- RegistrationCallBack, NULL, NULL );
- require_noerr_string( err, exit, "create registration failed" );
- }
- else if( strcmp( argv[ i ], "-rnss" ) == 0 )
- {
- // 'r'egister 'n'o 's'uch 's'ervice <name> <type> <domain>
-
- require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- name = argv[ i++ ];
- type = argv[ i++ ];
- domain = argv[ i++ ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "registering no-such-service \"%s.%s.%s\"\n", name, type, domain );
-
- err = DNSNoSuchServiceRegistrationCreate( 0, name, type, domain, NULL, RegistrationCallBack, NULL, NULL );
- require_noerr_string( err, exit, "create no-such-service registration failed" );
- }
- else if( strcmp( argv[ i ], "-ebs" ) == 0 )
- {
- // 'e'mulated 'b'rowse for 's'ervices <type> <domain>
-
- require_action_string( argc > ( i + 2 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- type = argv[ i++ ];
- domain = argv[ i ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "emulated browsing for \"%s.%s\"\n", type, domain );
-
- emulatedRef = DNSServiceBrowserCreate( type, domain, EmulatedBrowserCallBack, NULL );
- require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated browser failed" );
- }
- else if( strcmp( argv[ i ], "-ebd" ) == 0 )
- {
- int registrationOnly;
-
- // 'e'mulated 'b'rowse for 'd'omains <registration/browse>
-
- require_action_string( argc > ( i + 1 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- type = argv[ i++ ];
- if( strcmp( type, "registration" ) == 0 )
- {
- registrationOnly = 1;
- }
- else if( strcmp( type, "browse" ) == 0 )
- {
- registrationOnly = 0;
- }
- else
- {
- require_action_string( 0, exit, err = kDNSBadParamErr, "invalid browse type" );
- }
- fprintf( stdout, "emulated browsing for %s domains\n", type );
-
- emulatedRef = DNSServiceDomainEnumerationCreate( registrationOnly, EmulatedDomainEnumerationCallBack, NULL );
- require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated domain browser failed" );
- }
- else if( strcmp( argv[ i ], "-elsi" ) == 0 )
- {
- // 'e'mulated 'l'ookup 's'ervice 'i'nstance <name> <type> <domain>
-
- require_action_string( argc > ( i + 3 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- name = argv[ i++ ];
- type = argv[ i++ ];
- domain = argv[ i ];
- if( ( domain[ 0 ] == '\0' ) || ( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "emulated resolving \"%s.%s.%s\"\n", name, type, domain );
-
- emulatedRef = DNSServiceResolverResolve( name, type, domain, EmulatedResolverCallBack, NULL );
- require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated resolver failed" );
- }
- else if( strcmp( argv[ i ], "-ers" ) == 0 )
- {
- // 'e'mulated 'r'egister 's'ervice <name> <type> <domain> <port> <txt>
-
- require_action_string( argc > ( i + 5 ), exit, err = kDNSBadParamErr, "missing arguments" );
- ++i;
- name = argv[ i++ ];
- type = argv[ i++ ];
- domain = argv[ i++ ];
- port = atoi( argv[ i++ ] );
- text = argv[ i ];
- textSize = strlen( text );
- if( ( domain[ 0 ] == '.' ) && ( domain[ 1 ] == '\0' ) )
- {
- domain = "local.";
- }
- fprintf( stdout, "registering service \"%s.%s.%s\" port %d text \"%s\"\n", name, type, domain, port, text );
-
- emulatedRef = DNSServiceRegistrationCreate( name, type, domain, (uint16_t) port, text,
- EmulatedRegistrationCallBack, NULL );
- require_action_string( emulatedRef, exit, err = kDNSUnknownErr, "create emulated registration failed" );
- }
- else if( ( argv[ i ][ 0 ] == '-' ) && isdigit( argv[ i ][ 1 ] ) )
- {
- // Preset
-
- ProcessPreset( atoi( &argv[ i ][ 1 ] ) );
- err = 0;
- goto exit;
- }
- else if( strcmp( argv[ i ], "-q" ) == 0 )
- {
- // Quiet (no text records)
-
- gPrintTXTRecords = 0;
- }
- else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || ( strcmp( argv[ i ], "-h" ) == 0 ) )
- {
- // Help
-
- Usage();
- err = 0;
- goto exit;
- }
- else
- {
- // Unknown parameter.
-
- require_action_string( 0, exit, err = kDNSBadParamErr, "unknown parameter" );
- goto exit;
- }
- }
-
- // Run until control-C'd.
-
- #if( __MACH__ )
- CFRunLoopRun();
- #endif
-
- #if( defined( WINVER ) )
- while( !gQuit )
- {
- Sleep( 200 );
- }
- #endif
-
- err = kDNSNoErr;
-
-exit:
- if( err )
- {
- Usage();
- }
- return( err );
-}
-
-//===========================================================================================================================
-// ProcessPreset
-//===========================================================================================================================
-
-static DNSStatus ProcessPreset( int inPreset )
-{
- DNSStatus err;
-
- require_action_string( ( inPreset > 0 ) && ( inPreset <= gPresetsCount ), exit, err = kDNSBadParamErr, "invalid preset" );
-
- err = ProcessArgs( gPresets[ inPreset - 1 ].argc, (char **) gPresets[ inPreset - 1 ].argv );
-
-exit:
- return( err );
-}
-
-#if( __MACH__ )
-//===========================================================================================================================
-// SigIntHandler
-//===========================================================================================================================
-
-static void SigIntHandler( int inSignalNumber )
-{
- DNS_UNUSED( inSignalNumber );
-
- signal( SIGINT, SIG_DFL );
- CFRunLoopStop( CFRunLoopGetCurrent() );
-}
-#endif
-
-#if( defined( WINVER ) )
-//===========================================================================================================================
-// ConsoleControlHandler
-//===========================================================================================================================
-
-static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent )
-{
- BOOL handled;
-
- handled = 0;
- switch( inControlEvent )
- {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- gQuit = 1;
- handled = 1;
- break;
-
- default:
- break;
- }
- return( handled );
-}
-#endif
-
-//===========================================================================================================================
-// BrowserCallBack
-//===========================================================================================================================
-
-static void BrowserCallBack( void *inContext, DNSBrowserRef inRef, DNSStatus inStatusCode, const DNSBrowserEvent *inEvent )
-{
- char ifIP[ 32 ];
- char ip[ 32 ];
-
- DNS_UNUSED( inContext );
- DNS_UNUSED( inRef );
- DNS_UNUSED( inStatusCode );
-
- switch( inEvent->type )
- {
- case kDNSBrowserEventTypeRelease:
- break;
-
- case kDNSBrowserEventTypeAddDomain:
- fprintf( stdout, "domain \"%s\" added on interface 0x%08X (%s)\n",
- inEvent->data.addDomain.domain,
- (int) inEvent->data.addDomain.interfaceID,
- IPv4ToString( inEvent->data.addDomain.interfaceIP.u.ipv4.addr, ifIP ) );
- break;
-
- case kDNSBrowserEventTypeAddDefaultDomain:
- fprintf( stdout, "default domain \"%s\" added on interface 0x%08X (%s)\n",
- inEvent->data.addDefaultDomain.domain,
- (int) inEvent->data.addDefaultDomain.interfaceID,
- IPv4ToString( inEvent->data.addDefaultDomain.interfaceIP.u.ipv4.addr, ifIP ) );
- break;
-
- case kDNSBrowserEventTypeRemoveDomain:
- fprintf( stdout, "domain \"%s\" removed on interface 0x%08X (%s)\n",
- inEvent->data.removeDomain.domain,
- (int) inEvent->data.removeDomain.interfaceID,
- IPv4ToString( inEvent->data.removeDomain.interfaceIP.u.ipv4.addr, ifIP ) );
- break;
-
- case kDNSBrowserEventTypeAddService:
- fprintf( stdout, "service \"%s.%s%s\" added on interface 0x%08X (%s)\n",
- inEvent->data.addService.name,
- inEvent->data.addService.type,
- inEvent->data.addService.domain,
- (int) inEvent->data.addService.interfaceID,
- IPv4ToString( inEvent->data.addService.interfaceIP.u.ipv4.addr, ifIP ) );
- break;
-
- case kDNSBrowserEventTypeRemoveService:
- fprintf( stdout, "service \"%s.%s%s\" removed on interface 0x%08X (%s)\n",
- inEvent->data.removeService.name,
- inEvent->data.removeService.type,
- inEvent->data.removeService.domain,
- (int) inEvent->data.removeService.interfaceID,
- IPv4ToString( inEvent->data.removeService.interfaceIP.u.ipv4.addr, ifIP ) );
- break;
-
- case kDNSBrowserEventTypeResolved:
- {
- const uint8_t * p;
- const uint8_t * end;
- int i;
-
- fprintf( stdout, "resolved \"%s.%s%s\" to %s:%u on interface 0x%08X (%s)%s\n",
- inEvent->data.resolved->name,
- inEvent->data.resolved->type,
- inEvent->data.resolved->domain,
- IPv4ToString( inEvent->data.resolved->address.u.ipv4.addr, ip ),
- ( inEvent->data.resolved->address.u.ipv4.port.v8[ 0 ] << 8 ) |
- inEvent->data.resolved->address.u.ipv4.port.v8[ 1 ],
- (int) inEvent->data.resolved->interfaceID,
- IPv4ToString( inEvent->data.resolved->interfaceIP.u.ipv4.addr, ifIP ),
- ( inEvent->data.resolved->textRecordRawSize > 0 ) ? " with text:" : "" );
-
- p = (const uint8_t *) inEvent->data.resolved->textRecordRaw;
- end = p + inEvent->data.resolved->textRecordRawSize;
- i = 0;
-
- if( gPrintTXTRecords )
- {
- while( p < end )
- {
- uint8_t size;
-
- size = *p++;
- if( ( p + size ) > end )
- {
- fprintf( stdout, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
- break;
- }
- fprintf( stdout, "%5d (%3d bytes): \"%.*s\"\n", i, size, size, p );
- p += size;
- ++i;
- }
- fprintf( stdout, "\n" );
- }
- break;
- }
-
- default:
- break;
- }
-}
-
-//===========================================================================================================================
-// ResolverCallBack
-//===========================================================================================================================
-
-static void ResolverCallBack( void *inContext, DNSResolverRef inRef, DNSStatus inStatusCode, const DNSResolverEvent *inEvent )
-{
- char ifIP[ 32 ];
- char ip[ 32 ];
-
- DNS_UNUSED( inContext );
- DNS_UNUSED( inRef );
- DNS_UNUSED( inStatusCode );
-
- switch( inEvent->type )
- {
- case kDNSResolverEventTypeResolved:
- {
- const uint8_t * p;
- const uint8_t * end;
- int i;
-
- fprintf( stdout, "resolved \"%s.%s%s\" to %s:%u on interface 0x%08X (%s)%s\n",
- inEvent->data.resolved.name,
- inEvent->data.resolved.type,
- inEvent->data.resolved.domain,
- IPv4ToString( inEvent->data.resolved.address.u.ipv4.addr, ip ),
- ( inEvent->data.resolved.address.u.ipv4.port.v8[ 0 ] << 8 ) |
- inEvent->data.resolved.address.u.ipv4.port.v8[ 1 ],
- (int) inEvent->data.resolved.interfaceID,
- IPv4ToString( inEvent->data.resolved.interfaceIP.u.ipv4.addr, ifIP ),
- ( inEvent->data.resolved.textRecordRawSize > 0 ) ? " with text:" : "" );
-
- p = (const uint8_t *) inEvent->data.resolved.textRecordRaw;
- end = p + inEvent->data.resolved.textRecordRawSize;
- i = 0;
-
- if( gPrintTXTRecords )
- {
- while( p < end )
- {
- uint8_t size;
-
- size = *p++;
- if( ( p + size ) > end )
- {
- fprintf( stdout, "\n### MALFORMED TXT RECORD (length byte too big for record)\n\n" );
- break;
- }
- fprintf( stdout, "%5d (%3d bytes): \"%.*s\"\n", i, size, size, p );
- p += size;
- ++i;
- }
- fprintf( stdout, "\n" );
- }
- break;
- }
-
- case kDNSResolverEventTypeRelease:
- break;
-
- default:
- break;
- }
-}
-
-//===========================================================================================================================
-// RegistrationCallBack
-//===========================================================================================================================
-
-static void
- RegistrationCallBack(
- void * inContext,
- DNSRegistrationRef inRef,
- DNSStatus inStatusCode,
- const DNSRegistrationEvent * inEvent )
-{
- DNS_UNUSED( inContext );
- DNS_UNUSED( inRef );
- DNS_UNUSED( inStatusCode );
-
- switch( inEvent->type )
- {
- case kDNSRegistrationEventTypeRelease:
- break;
-
- case kDNSRegistrationEventTypeRegistered:
- fprintf( stdout, "name registered and active\n" );
- break;
-
- case kDNSRegistrationEventTypeNameCollision:
- fprintf( stdout, "name in use, please choose another name\n" );
- break;
-
- default:
- break;
- }
-}
-
-//===========================================================================================================================
-// HostRegistrationCallBack
-//===========================================================================================================================
-
-static void
- HostRegistrationCallBack(
- void * inContext,
- DNSHostRegistrationRef inRef,
- DNSStatus inStatusCode,
- void * inData )
-{
- DNS_UNUSED( inContext );
- DNS_UNUSED( inRef );
- DNS_UNUSED( inData );
-
- if( inStatusCode == kDNSNoErr )
- {
- fprintf( stdout, "host name registered and active\n" );
- }
- else if( inStatusCode == kDNSNameConflictErr )
- {
- fprintf( stdout, "host name in use, please choose another name\n" );
- }
- else
- {
- fprintf( stdout, "unknown host registration status (%ld)\n", inStatusCode );
- }
-}
-
-//===========================================================================================================================
-// EmulatedBrowserCallBack
-//===========================================================================================================================
-
-static void
- EmulatedBrowserCallBack(
- DNSServiceBrowserReplyResultType inResult,
- const char * inName,
- const char * inType,
- const char * inDomain,
- DNSServiceDiscoveryReplyFlags inFlags,
- void * inContext )
-{
- DNS_UNUSED( inFlags );
- DNS_UNUSED( inContext );
-
- if( inResult == DNSServiceBrowserReplyAddInstance )
- {
- fprintf( stdout, "\"%s.%s%s\" service added emulated\n", inName, inType, inDomain );
- }
- else if( inResult == DNSServiceBrowserReplyRemoveInstance )
- {
- fprintf( stdout, "\"%s.%s%s\" service removed emulated\n", inName, inType, inDomain );
- }
- else
- {
- fprintf( stdout, "### unknown emulated browser callback result (%d)\n", inResult );
- }
-}
-
-//===========================================================================================================================
-// EmulatedDomainEnumerationCallBack
-//===========================================================================================================================
-
-static void
- EmulatedDomainEnumerationCallBack(
- DNSServiceDomainEnumerationReplyResultType inResult,
- const char * inDomain,
- DNSServiceDiscoveryReplyFlags inFlags,
- void * inContext )
-{
- DNS_UNUSED( inFlags );
- DNS_UNUSED( inContext );
-
- if( inResult == DNSServiceDomainEnumerationReplyAddDomain )
- {
- fprintf( stdout, "\"%s\" domain added emulated\n", inDomain );
- }
- else if( inResult == DNSServiceDomainEnumerationReplyAddDomainDefault )
- {
- fprintf( stdout, "\"%s\" default domain added emulated\n", inDomain );
- }
- else if( inResult == DNSServiceDomainEnumerationReplyRemoveDomain )
- {
- fprintf( stdout, "\"%s\" domain removed emulated\n", inDomain );
- }
- else
- {
- fprintf( stdout, "### unknown emulated domain enumeration callback result (%d)\n", inResult );
- }
-}
-
-//===========================================================================================================================
-// EmulatedResolverCallBack
-//===========================================================================================================================
-
-static void
- EmulatedResolverCallBack(
- struct sockaddr * inInterfaceAddr,
- struct sockaddr * inAddr,
- const char * inTextRecord,
- DNSServiceDiscoveryReplyFlags inFlags,
- void * inContext )
-{
- struct sockaddr_in * ifSin4;
- struct sockaddr_in * sin4;
- char ifIP[ 64 ];
- char ip[ 64 ];
-
- DNS_UNUSED( inFlags );
- DNS_UNUSED( inContext );
-
- ifSin4 = (struct sockaddr_in *) inInterfaceAddr;
- sin4 = (struct sockaddr_in *) inAddr;
-
- fprintf( stdout, "service resolved to %s:%d on interface %s with text \"%s\"\n",
- IPv4ToString( *( (DNSOpaque32 *) &sin4->sin_addr.s_addr ), ip ),
- ntohs( sin4->sin_port ),
- IPv4ToString( *( (DNSOpaque32 *) &ifSin4->sin_addr.s_addr ), ifIP ),
- inTextRecord ? inTextRecord : "" );
-}
-
-//===========================================================================================================================
-// EmulatedResolverCallBack
-//===========================================================================================================================
-
-static void EmulatedRegistrationCallBack( DNSServiceRegistrationReplyErrorType inResult, void *inContext )
-{
- DNS_UNUSED( inContext );
-
- if( inResult == kDNSServiceDiscoveryNoError )
- {
- fprintf( stdout, "service name registered successfully\n" );
- }
- else
- {
- fprintf( stdout, "service registration failed( %d)\n", inResult );
- }
-}
-
-//===========================================================================================================================
-// IPv4ToString
-//===========================================================================================================================
-
-static char * IPv4ToString( DNSOpaque32 inIP, char *outString )
-{
- sprintf( outString, "%u.%u.%u.%u", inIP.v8[ 0 ], inIP.v8[ 1 ], inIP.v8[ 2 ], inIP.v8[ 3 ] );
- return( outString );
-}
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: ToolPrefixWindows.h,v $
-Revision 1.2 2003/08/20 07:06:34 bradley
-Update to APSL 2.0. Updated change history to match other mDNSResponder files.
-
-Revision 1.1 2003/08/20 06:01:19 bradley
-Prefix files for CodeWarrior Windows builds to set compile options.
-
-*/
-
-#ifndef __TOOL_PREFIX_WINDOWS__
-#define __TOOL_PREFIX_WINDOWS__
-
-#define DEBUG 0
-
-#endif // __TOOL_PREFIX_WINDOWS__
+++ /dev/null
-/*
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * 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: ToolPrefixWindowsDebug.h,v $
-Revision 1.2 2003/08/20 07:06:34 bradley
-Update to APSL 2.0. Updated change history to match other mDNSResponder files.
-
-Revision 1.1 2003/08/20 06:01:19 bradley
-Prefix files for CodeWarrior Windows builds to set compile options.
-
-*/
-
-#ifndef __TOOL_PREFIX_WINDOWS_DEBUG__
-#define __TOOL_PREFIX_WINDOWS_DEBUG__
-
-#define DEBUG 1
-#define MDNS_DEBUGMSGS 1
-
-#endif // __TOOL_PREFIX_WINDOWS_DEBUG__
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 7.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tool", "ToolWin32VS2002.vcproj", "{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- ConfigName.0 = all
- ConfigName.1 = Debug
- ConfigName.2 = Release
- EndGlobalSection
- GlobalSection(ProjectDependencies) = postSolution
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.ActiveCfg = all|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.Build.0 = all|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.ActiveCfg = Debug|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.Build.0 = Debug|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.ActiveCfg = Release|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+++ /dev/null
-<?xml version="1.0" encoding = "Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.00"
- Name="Tool"
- ProjectGUID="{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="1">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- StringPooling="TRUE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- SmallerTypeCheck="FALSE"
- RuntimeLibrary="1"
- BufferSecurityCheck="TRUE"
- ForceConformanceInForLoopScope="TRUE"
- UsePrecompiledHeader="2"
- BrowseInformation="1"
- WarningLevel="4"
- WarnAsError="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- OutputFile="$(OutDir)/Tool.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/Tool.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="1"
- WholeProgramOptimization="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="2"
- FavorSizeOrSpeed="2"
- OmitFramePointers="TRUE"
- AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableFunctionLevelLinking="FALSE"
- DisableLanguageExtensions="FALSE"
- ForceConformanceInForLoopScope="TRUE"
- UsePrecompiledHeader="2"
- WarningLevel="4"
- WarnAsError="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- OutputFile="$(OutDir)/Tool.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- <Configuration
- Name="all|Win32"
- OutputDirectory="all"
- IntermediateDirectory="all"
- ConfigurationType="1">
- <Tool
- Name="VCCLCompilerTool"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- </Configuration>
- </Configurations>
- <Files>
- <Filter
- Name="Rendezvous"
- Filter="">
- <File
- RelativePath="..\..\DNSServices\DNSServiceDiscovery.c">
- </File>
- <File
- RelativePath="..\..\DNSServices\DNSServiceDiscovery.h">
- </File>
- <File
- RelativePath="..\..\DNSServices\DNSServices.c">
- </File>
- <File
- RelativePath="..\..\DNSServices\DNSServices.h">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNS.c">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNSClientAPI.h">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNSDebug.h">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNSPlatformFunctions.h">
- </File>
- <File
- RelativePath="..\..\mDNSWin32.c">
- </File>
- <File
- RelativePath="..\..\mDNSWin32.h">
- </File>
- </Filter>
- <File
- RelativePath="Tool.c">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+++ /dev/null
-Microsoft Visual Studio Solution File, Format Version 8.00
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tool", "ToolWin32VS2003.vcproj", "{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
- ProjectSection(ProjectDependencies) = postProject
- EndProjectSection
-EndProject
-Global
- GlobalSection(SolutionConfiguration) = preSolution
- all = all
- Debug = Debug
- Release = Release
- EndGlobalSection
- GlobalSection(ProjectConfiguration) = postSolution
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.ActiveCfg = all|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.all.Build.0 = all|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.ActiveCfg = Debug|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Debug.Build.0 = Debug|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.ActiveCfg = Release|Win32
- {F66EFE7E-50A6-44D4-87C7-742B303BA852}.Release.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- EndGlobalSection
- GlobalSection(ExtensibilityAddIns) = postSolution
- EndGlobalSection
-EndGlobal
+++ /dev/null
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="Tool"
- ProjectGUID="{F66EFE7E-50A6-44D4-87C7-742B303BA852}"
- Keyword="Win32Proj">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Debug|Win32"
- OutputDirectory="Debug"
- IntermediateDirectory="Debug"
- ConfigurationType="1"
- CharacterSet="1">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- StringPooling="TRUE"
- MinimalRebuild="TRUE"
- BasicRuntimeChecks="3"
- SmallerTypeCheck="FALSE"
- RuntimeLibrary="1"
- BufferSecurityCheck="TRUE"
- ForceConformanceInForLoopScope="TRUE"
- UsePrecompiledHeader="2"
- BrowseInformation="1"
- WarningLevel="4"
- WarnAsError="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="4"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- OutputFile="$(OutDir)/Tool.exe"
- LinkIncremental="2"
- GenerateDebugInformation="TRUE"
- ProgramDatabaseFile="$(OutDir)/Tool.pdb"
- SubSystem="1"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="Release"
- IntermediateDirectory="Release"
- ConfigurationType="1"
- CharacterSet="1"
- WholeProgramOptimization="FALSE">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- InlineFunctionExpansion="2"
- FavorSizeOrSpeed="2"
- OmitFramePointers="TRUE"
- AdditionalIncludeDirectories="..\..\..\mDNSCore;..\..\..\mDNSWindows;..\..\DNSServices"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
- StringPooling="TRUE"
- ExceptionHandling="FALSE"
- RuntimeLibrary="0"
- BufferSecurityCheck="FALSE"
- EnableFunctionLevelLinking="FALSE"
- DisableLanguageExtensions="FALSE"
- ForceConformanceInForLoopScope="TRUE"
- UsePrecompiledHeader="2"
- WarningLevel="4"
- WarnAsError="TRUE"
- Detect64BitPortabilityProblems="TRUE"
- DebugInformationFormat="3"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"
- AdditionalDependencies="ws2_32.lib"
- OutputFile="$(OutDir)/Tool.exe"
- LinkIncremental="1"
- GenerateDebugInformation="TRUE"
- SubSystem="1"
- OptimizeReferences="2"
- EnableCOMDATFolding="2"
- TargetMachine="1"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="all|Win32"
- OutputDirectory="all"
- IntermediateDirectory="all"
- ConfigurationType="1">
- <Tool
- Name="VCCLCompilerTool"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLinkerTool"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCWebDeploymentTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Rendezvous"
- Filter="">
- <File
- RelativePath="..\..\DNSServices\DNSServiceDiscovery.c">
- </File>
- <File
- RelativePath="..\..\DNSServices\DNSServiceDiscovery.h">
- </File>
- <File
- RelativePath="..\..\DNSServices\DNSServices.c">
- </File>
- <File
- RelativePath="..\..\DNSServices\DNSServices.h">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNS.c">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNSClientAPI.h">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNSDebug.h">
- </File>
- <File
- RelativePath="..\..\..\mDNSCore\mDNSPlatformFunctions.h">
- </File>
- <File
- RelativePath="..\..\mDNSWin32.c">
- </File>
- <File
- RelativePath="..\..\mDNSWin32.h">
- </File>
- </Filter>
- <File
- RelativePath="Tool.c">
- </File>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
//---------------------------------------------------------------------------------------------------------------------------
/*! @function DNSNoSuchServiceRegistrationCreate
- @abstract Creates a registration object and publish the registration to assert non-existance of a particular service.
+ @abstract Creates a registration object and publish the registration to assert non-existence of a particular service.
@param inFlags
Flags to control the registration process.