merge in oc-release history after reset to master
diff --git a/Android.mk b/Android.mk
index 5d6160a..21143a3 100644
--- a/Android.mk
+++ b/Android.mk
@@ -12,11 +12,8 @@
     -fno-strict-aliasing \
     -D_GNU_SOURCE \
     -DHAVE_IPV6 \
-    -DHAVE_LINUX \
     -DNOT_HAVE_SA_LEN \
     -DPLATFORM_NO_RLIMIT \
-    -DTARGET_OS_LINUX \
-    -DUSES_NETLINK \
     -DMDNS_DEBUGMSGS=0 \
     -DMDNS_UDS_SERVERPATH=\"/dev/socket/mdnsd\" \
     -DMDNS_USERNAME=\"mdnsr\" \
@@ -30,44 +27,150 @@
     -Wno-unused-parameter \
     -Werror=implicit-function-declaration \
 
+daemonSources := mDNSCore/mDNS.c            \
+                 mDNSCore/DNSDigest.c       \
+                 mDNSCore/uDNS.c            \
+                 mDNSCore/DNSCommon.c       \
+                 mDNSShared/uds_daemon.c    \
+                 mDNSShared/mDNSDebug.c     \
+                 mDNSShared/dnssd_ipc.c     \
+                 mDNSShared/GenLinkedList.c \
+                 mDNSShared/PlatformCommon.c \
+                 mDNSPosix/PosixDaemon.c    \
+                 mDNSPosix/mDNSPosix.c      \
+                 mDNSPosix/mDNSUNP.c
+
+daemonIncludes := external/mdnsresponder/mDNSCore  \
+                  external/mdnsresponder/mDNSShared \
+                  external/mdnsresponder/mDNSPosix
+
 #########################
 
 include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES :=  mDNSPosix/PosixDaemon.c    \
-                    mDNSPosix/mDNSPosix.c      \
-                    mDNSPosix/mDNSUNP.c        \
-                    mDNSCore/mDNS.c            \
-                    mDNSCore/DNSDigest.c       \
-                    mDNSCore/uDNS.c            \
-                    mDNSCore/DNSCommon.c       \
-                    mDNSShared/uds_daemon.c    \
-                    mDNSShared/mDNSDebug.c     \
-                    mDNSShared/dnssd_ipc.c     \
-                    mDNSShared/GenLinkedList.c \
-                    mDNSShared/PlatformCommon.c
-
+LOCAL_SRC_FILES :=  $(daemonSources)
 LOCAL_MODULE := mdnsd
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_C_INCLUDES := external/mdnsresponder/mDNSPosix \
-                    external/mdnsresponder/mDNSCore  \
-                    external/mdnsresponder/mDNSShared
+LOCAL_C_INCLUDES := $(daemonIncludes)
 
-LOCAL_CFLAGS := $(commonFlags) -DMDNS_VERSIONSTR_NODTS=1
+LOCAL_CFLAGS := \
+  $(commonFlags) \
+  -DTARGET_OS_LINUX \
+  -DMDNS_VERSIONSTR_NODTS=1 \
+  -DHAVE_LINUX \
+  -DUSES_NETLINK \
 
 LOCAL_STATIC_LIBRARIES := $(commonLibs) libc
 LOCAL_FORCE_STATIC_EXECUTABLE := true
 LOCAL_INIT_RC := mdnsd.rc
 include $(BUILD_EXECUTABLE)
 
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES :=  $(daemonSources)
+LOCAL_MODULE := mdnsd
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES := $(daemonIncludes)
+
+LOCAL_CFLAGS := \
+  $(commonFlags) \
+  -DMDNS_VERSIONSTR_NODTS=1 \
+
+LOCAL_CFLAGS_linux := -DTARGET_OS_LINUX -DHAVE_LINUX -DUSES_NETLINK
+LOCAL_CFLAGS_darwin := -DTARGET_OS_MAC
+
+LOCAL_STATIC_LIBRARIES := $(commonLibs)
+include $(BUILD_HOST_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+  mDNSWindows/SystemService/main.c    \
+  mDNSWindows/SystemService/Service.c \
+  mDNSWindows/Secret.c                \
+  mDNSWindows/mDNSWin32.c             \
+  mDNSShared/dnssd_ipc.c              \
+  mDNSShared/uds_daemon.c             \
+  mDNSShared/mDNSDebug.c              \
+  mDNSShared/GenLinkedList.c          \
+  mDNSShared/DebugServices.c          \
+  mDNSCore/DNSDigest.c                \
+  mDNSCore/DNSCommon.c                \
+  mDNSCore/uDNS.c                     \
+  mDNSCore/mDNS.c                     \
+  android/windows_firewall_dummy.c
+
+LOCAL_MODULE := mdnsd
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+mdnsd_generated_sources := $(call local-generated-sources-dir)
+event_log_h := $(mdnsd_generated_sources)/EventLog.h
+event_log_o := $(mdnsd_generated_sources)/EventLog.o
+event_log_rc := $(mdnsd_generated_sources)/EventLog.rc
+
+event_log_mc := external/mdnsresponder/mDNSWindows/SystemService/EventLog.mc
+mingw_bin := prebuilts/gcc/$(HOST_PREBUILT_TAG)/host/x86_64-w64-mingw32-4.8/bin
+windmc := $(mingw_bin)/x86_64-w64-mingw32-windmc
+windres := $(mingw_bin)/x86_64-w64-mingw32-windres
+
+$(event_log_h) $(event_log_o): $(event_log_mc)
+	@echo "Generating EventLog messages"
+	@mkdir -p $(mdnsd_generated_sources)
+	@$(windmc) -r$(mdnsd_generated_sources) -h$(mdnsd_generated_sources) $<
+	@$(windres) -F pe-i386 -I$(mdnsd_generated_sources) $(event_log_rc) $(event_log_o)
+
+LOCAL_GENERATED_SOURCES := \
+  $(mdnsd_generated_sources)/EventLog.h \
+  $(mdnsd_generated_sources)/EventLog.o
+
+LOCAL_C_INCLUDES := \
+  external/mdnsresponder/mDNSShared \
+  external/mdnsresponder/mDNSCore \
+  external/mdnsresponder/mDNSWindows/SystemService \
+  external/mdnsresponder/mDNSWindows \
+  external/mdnsresponder/android/caseMapping \
+  $(mdnsd_generated_sources)
+
+LOCAL_CFLAGS := $(commonFlags) \
+  -DMDNS_VERSIONSTR_NODTS=1 \
+  -DTARGET_OS_WINDOWS \
+  -DTARGET_OS_WIN32 \
+  -DWIN32 \
+  -DNDEBUG \
+  -D_CONSOLE \
+  -D_WIN32_LEAN_AND_MEAN \
+  -DUSE_TCP_LOOPBACK \
+  -DPLATFORM_NO_STRSEP \
+  -DPLATFORM_NO_EPIPE \
+  -DPLATFORM_NO_RLIMIT \
+  -DPID_FILE='""' \
+  -DUNICODE \
+  -D_UNICODE \
+  -D_CRT_SECURE_NO_DEPRECATE \
+  -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 \
+  -D_LEGACY_NAT_TRAVERSAL \
+  -include stdint.h \
+  -include winsock2.h \
+  -include ws2ipdef.h \
+  -include wincrypt.h \
+  -include netioapi.h \
+  -Wno-sign-compare \
+  -Wno-empty-body
+
+LOCAL_LDFLAGS := -lws2_32 -liphlpapi -lpowrprof -lnetapi32 -municode
+
+
+LOCAL_MODULE_HOST_OS := windows
+
+LOCAL_STATIC_LIBRARIES := $(commonLibs)
+include $(BUILD_HOST_EXECUTABLE)
 ##########################
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(commonSources)
 LOCAL_MODULE := libmdnssd
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := $(commonFlags)
+LOCAL_CFLAGS := $(commonFlags) -DTARGET_OS_LINUX -DHAVE_LINUX -DUSES_NETLINK
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc
 LOCAL_SHARED_LIBRARIES := $(commonLibs)
 LOCAL_EXPORT_C_INCLUDE_DIRS := external/mdnsresponder/mDNSShared
@@ -77,18 +180,58 @@
 LOCAL_SRC_FILES := $(commonSources)
 LOCAL_MODULE := libmdnssd
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := $(commonFlags)
+LOCAL_CFLAGS := $(commonFlags) -DTARGET_OS_LINUX -DHAVE_LINUX -DUSES_NETLINK
 LOCAL_STATIC_LIBRARIES := $(commonLibs)
 LOCAL_EXPORT_C_INCLUDE_DIRS := external/mdnsresponder/mDNSShared
 include $(BUILD_STATIC_LIBRARY)
 
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(commonSources)
+LOCAL_SRC_FILES_windows := mDNSWindows/DLL/dllmain.c
+LOCAL_MODULE := libmdnssd
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(commonFlags)
+LOCAL_CFLAGS_windows := \
+  -DTARGET_OS_WINDOWS \
+  -DWIN32 \
+  -DNDEBUG \
+  -D_WINDOWS \
+  -D_USERDLL \
+  -D_MDNS_DEBUGMSGS=0 \
+  -D_WIN32_LEAN_AND_MEAN \
+  -D_SSIZE_T \
+  -DUSE_TCP_LOOPBACK \
+  -D_CRT_SECURE_NO_DEPRECATE \
+  -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 \
+  -DNOT_HAVE_SA_LENGTH \
+  -Wno-unknown-pragmas \
+  -Wno-sign-compare \
+  -Wno-overflow \
+  -include stdint.h \
+  -include winsock2.h \
+  -include ws2ipdef.h \
+  -include wincrypt.h \
+  -include iphlpapi.h \
+  -include netioapi.h \
+  -include stdlib.h \
+  -include stdio.h
+
+LOCAL_CFLAGS_linux := -DTARGET_OS_LINUX -DHAVE_LINUX -DUSES_NETLINK
+LOCAL_CFLAGS_darwin := -DTARGET_OS_MAC
+LOCAL_STATIC_LIBRARIES := $(commonLibs)
+LOCAL_EXPORT_C_INCLUDE_DIRS := external/mdnsresponder/mDNSShared
+LOCAL_C_INCLUDES_windows := external/mdnsresponder/mDNSShared external/mdnsresponder/mDNSWindows
+LOCAL_C_INCLUDES_windows += external/mdnsresponder/android/caseMapping
+LOCAL_MODULE_HOST_OS := darwin linux windows
+include $(BUILD_HOST_STATIC_LIBRARY)
+
 ############################
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := Clients/dns-sd.c Clients/ClientCommon.c
 LOCAL_MODULE := dnssd
 LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := $(commonFlags)
+LOCAL_CFLAGS := $(commonFlags) -DTARGET_OS_LINUX -DHAVE_LINUX -DUSES_NETLINK
 LOCAL_SYSTEM_SHARED_LIBRARIES := libc
 LOCAL_SHARED_LIBRARIES := libmdnssd libcutils liblog
 include $(BUILD_EXECUTABLE)
@@ -123,7 +266,10 @@
                 -UMDNS_DEBUGMSGS \
                 -DMDNS_DEBUGMSGS=0 \
                 -DSO_REUSEADDR \
-                -DUNICAST_DISABLED
+                -DUNICAST_DISABLED \
+                -DTARGET_OS_LINUX \
+                -DHAVE_LINUX \
+                -DUSES_NETLINK
 
 ifeq ($(TARGET_BUILD_TYPE),debug)
   LOCAL_CFLAGS += -O0 -UNDEBUG -fno-omit-frame-pointer
diff --git a/android/caseMapping/Iphlpapi.h b/android/caseMapping/Iphlpapi.h
new file mode 100644
index 0000000..4d08efd
--- /dev/null
+++ b/android/caseMapping/Iphlpapi.h
@@ -0,0 +1 @@
+#include <iphlpapi.h>
diff --git a/android/caseMapping/README b/android/caseMapping/README
new file mode 100644
index 0000000..951082f
--- /dev/null
+++ b/android/caseMapping/README
@@ -0,0 +1,3 @@
+Windows filesystems, and consequently Windows C include files, are
+case-insensitive. This folder provides alternately-cased versions of header
+files for cases where that becomes a problem.
diff --git a/android/caseMapping/Resource.h b/android/caseMapping/Resource.h
new file mode 100644
index 0000000..f4649ed
--- /dev/null
+++ b/android/caseMapping/Resource.h
@@ -0,0 +1 @@
+#include <resource.h>
diff --git a/android/caseMapping/Ws2tcpip.h b/android/caseMapping/Ws2tcpip.h
new file mode 100644
index 0000000..8fc8783
--- /dev/null
+++ b/android/caseMapping/Ws2tcpip.h
@@ -0,0 +1 @@
+#include <ws2tcpip.h>
diff --git a/android/caseMapping/ipExport.h b/android/caseMapping/ipExport.h
new file mode 100644
index 0000000..76ed79f
--- /dev/null
+++ b/android/caseMapping/ipExport.h
@@ -0,0 +1 @@
+#include <ipexport.h>
diff --git a/android/windows_firewall_dummy.c b/android/windows_firewall_dummy.c
new file mode 100644
index 0000000..f4d25ce
--- /dev/null
+++ b/android/windows_firewall_dummy.c
@@ -0,0 +1,10 @@
+int mDNSIsFileAndPrintSharingEnabled(int *ignored) {
+  (void)ignored;
+  return 0;
+}
+
+int mDNSAddToFirewall(const char* ignored, const char* also_ignored) {
+  (void)ignored;
+  (void)also_ignored;
+  return 0;
+}
diff --git a/mDNSCore/mDNSEmbeddedAPI.h b/mDNSCore/mDNSEmbeddedAPI.h
index 5c3115c..44f7ec0 100755
--- a/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSCore/mDNSEmbeddedAPI.h
@@ -54,6 +54,17 @@
 #ifndef __mDNSClientAPI_h
 #define __mDNSClientAPI_h
 
+/* MinGW thinks "#define interface struct" is a cute way to do ObjC
+ * compatibility. Everything is terrible.
+ */
+#ifdef _WIN32
+#ifndef interface
+#warning "MinGW no longer does weird things with 'interface'. "\
+         "You can remove this code."
+#endif /* ! interface */
+#undef interface
+#endif /* _WIN32 */
+
 #if defined(EFI32) || defined(EFI64) || defined(EFIX64)
 // EFI doesn't have stdarg.h unless it's building with GCC.
 #include "Tiano.h"
diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c
index a8ac88a..5e47657 100644
--- a/mDNSPosix/mDNSPosix.c
+++ b/mDNSPosix/mDNSPosix.c
@@ -1357,13 +1357,27 @@
 	strcpy((char *)dst, (char *)src);
 	}
 
-// mDNS core calls this routine to copy C strings while taking the destination
-// buffer size into account.
-// On the Posix platform this maps directly to the ANSI C strncpy.
-mDNSexport mDNSu32  mDNSPlatformStrLCopy(void *dst, const void *src, mDNSu32 dstlen)
-	{
-	return (strlcpy((char *)dst, (const char *)src, dstlen));
-	}
+mDNSexport mDNSu32  mDNSPlatformStrLCopy(void *dst, const void *src, mDNSu32 len)
+{
+#if HAVE_STRLCPY
+    return ((mDNSu32)strlcpy((char *)dst, (const char *)src, len));
+#else
+    size_t srcLen;
+
+    srcLen = strlen((const char *)src);
+    if (srcLen < len)
+    {
+        memcpy(dst, src, srcLen + 1);
+    }
+    else if (len > 0)
+    {
+        memcpy(dst, src, len - 1);
+        ((char *)dst)[len - 1] = '\0';
+    }
+
+    return ((mDNSu32)srcLen);
+#endif
+}
 
 // mDNS core calls this routine to get the length of a C string.
 // On the Posix platform this maps directly to the ANSI C strlen.
diff --git a/mDNSShared/uds_daemon.c b/mDNSShared/uds_daemon.c
index e269be6..fd214ac 100644
--- a/mDNSShared/uds_daemon.c
+++ b/mDNSShared/uds_daemon.c
@@ -21,7 +21,6 @@
 #else
 #include <fcntl.h>
 #include <errno.h>
-#include <cutils/log.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1628,7 +1627,6 @@
 	if (!request->msgptr)
 		{
 		LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd);
-		android_errorWriteWithInfoLog(0x534e4554, "25852056", -1, NULL, 0);
 		return(mStatus_BadParamErr);
 		}
 
diff --git a/mDNSWindows/ControlPanel/BrowsingPage.cpp b/mDNSWindows/ControlPanel/BrowsingPage.cpp
new file mode 100755
index 0000000..20b5c6d
--- /dev/null
+++ b/mDNSWindows/ControlPanel/BrowsingPage.cpp
@@ -0,0 +1,441 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BrowsingPage.h"
+#include "resource.h"
+
+#include "ConfigPropertySheet.h"
+
+#include <WinServices.h>
+    
+#define MAX_KEY_LENGTH 255
+
+
+IMPLEMENT_DYNCREATE(CBrowsingPage, CPropertyPage)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::CBrowsingPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CBrowsingPage::CBrowsingPage()
+:
+	CPropertyPage(CBrowsingPage::IDD)
+{
+	//{{AFX_DATA_INIT(CBrowsingPage)
+	//}}AFX_DATA_INIT
+
+	m_firstTime = true;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::~CBrowsingPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CBrowsingPage::~CBrowsingPage()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CBrowsingPage::DoDataExchange(CDataExchange* pDX)
+{
+	CPropertyPage::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CBrowsingPage)
+	//}}AFX_DATA_MAP
+	DDX_Control(pDX, IDC_BROWSE_LIST, m_browseListCtrl);
+	DDX_Control(pDX, IDC_REMOVE_BROWSE_DOMAIN, m_removeButton);
+}
+
+BEGIN_MESSAGE_MAP(CBrowsingPage, CPropertyPage)
+	//{{AFX_MSG_MAP(CBrowsingPage)
+	//}}AFX_MSG_MAP
+	ON_BN_CLICKED(IDC_ADD_BROWSE_DOMAIN, OnBnClickedAddBrowseDomain)
+	ON_BN_CLICKED(IDC_REMOVE_BROWSE_DOMAIN, OnBnClickedRemoveBrowseDomain)
+	ON_NOTIFY(LVN_ITEMCHANGED, IDC_BROWSE_LIST, OnLvnItemchangedBrowseList)
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::SetModified
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CBrowsingPage::SetModified( BOOL bChanged )
+{
+	m_modified = bChanged;
+
+	CPropertyPage::SetModified( bChanged );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::OnSetActive
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CBrowsingPage::OnSetActive()
+{
+	CConfigPropertySheet	*	psheet;
+	HKEY						key = NULL;
+	HKEY						subKey = NULL;
+	DWORD						dwSize;
+	DWORD						enabled;
+	DWORD						err;
+	TCHAR						subKeyName[MAX_KEY_LENGTH];
+	DWORD						cSubKeys = 0;
+	DWORD						cbMaxSubKey;
+	DWORD						cchMaxClass;
+	int							nIndex;
+    DWORD						i; 
+	BOOL						b = CPropertyPage::OnSetActive();
+
+	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
+	require_quiet( psheet, exit );
+	
+	m_modified = FALSE;
+
+	if ( m_firstTime )
+	{
+		m_browseListCtrl.SetExtendedStyle((m_browseListCtrl.GetStyle() & (~LVS_EX_GRIDLINES))|LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT);
+
+		m_browseListCtrl.InsertColumn(0, L"", LVCFMT_LEFT, 20 );
+		m_browseListCtrl.InsertColumn(1, L"", LVCFMT_LEFT, 345);
+
+		m_firstTime = false;
+	}
+
+	m_initialized = false;
+
+	// Clear out what's there
+
+	m_browseListCtrl.DeleteAllItems();
+
+	// Now populate the browse domain box
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSBrowseDomains, 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	// Get information about this node
+
+    err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+	require_noerr( err, exit );
+
+	for ( i = 0; i < cSubKeys; i++)
+	{	
+		dwSize = MAX_KEY_LENGTH;
+            
+		err = RegEnumKeyEx( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+		require_noerr( err, exit );
+
+		err = RegOpenKey( key, subKeyName, &subKey );
+		require_noerr( err, exit );
+
+		dwSize = sizeof( DWORD );
+		err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+		require_noerr( err, exit );
+
+		nIndex = m_browseListCtrl.InsertItem( m_browseListCtrl.GetItemCount(), L"");
+		m_browseListCtrl.SetItemText( nIndex, 1, subKeyName );
+		m_browseListCtrl.SetCheck( nIndex, enabled );
+
+		RegCloseKey( subKey );
+		subKey = NULL;
+    }
+
+	m_browseListCtrl.SortItems( SortFunc, (DWORD_PTR) this );
+
+	m_removeButton.EnableWindow( FALSE );
+ 
+exit:
+
+	if ( subKey )
+	{
+		RegCloseKey( subKey );
+	}
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	m_initialized = true;
+
+	return b;
+}
+
+ 
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::OnOK
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CBrowsingPage::OnOK()
+{
+	if ( m_modified )
+	{
+		Commit();
+	}
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CBrowsingPage::Commit()
+{
+	HKEY		key		= NULL;
+	HKEY		subKey	= NULL;
+	TCHAR		subKeyName[MAX_KEY_LENGTH];
+	DWORD		cSubKeys = 0;
+	DWORD		cbMaxSubKey;
+	DWORD		cchMaxClass;
+	DWORD		dwSize;
+	int			i;
+	DWORD		err;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSBrowseDomains, 0,
+	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	// First, remove all the entries that are there
+
+    err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+	require_noerr( err, exit );
+
+	for ( i = 0; i < (int) cSubKeys; i++ )
+	{	
+		dwSize = MAX_KEY_LENGTH;
+            
+		err = RegEnumKeyEx( key, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+		require_noerr( err, exit );
+			
+		err = RegDeleteKey( key, subKeyName );
+		require_noerr( err, exit );
+	}
+
+	// Now re-populate
+
+	for ( i = 0; i < m_browseListCtrl.GetItemCount(); i++ )
+	{
+		DWORD enabled = (DWORD) m_browseListCtrl.GetCheck( i );
+
+		err = RegCreateKeyEx( key, m_browseListCtrl.GetItemText( i, 1 ), 0,
+		                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &subKey, NULL );
+		require_noerr( err, exit );
+
+		err = RegSetValueEx( subKey, L"Enabled", NULL, REG_DWORD, (LPBYTE) &enabled, sizeof( enabled ) );
+		require_noerr( err, exit );
+
+		RegCloseKey( subKey );
+		subKey = NULL;
+	}
+	
+exit:
+
+	if ( subKey )
+	{
+		RegCloseKey( subKey );
+	}
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::OnBnClickedAddBrowseDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CBrowsingPage::OnBnClickedAddBrowseDomain()
+{
+	CAddBrowseDomain dlg( GetParent() );
+
+	if ( ( dlg.DoModal() == IDOK ) && ( dlg.m_text.GetLength() > 0 ) )
+	{
+		int nIndex;
+
+		nIndex = m_browseListCtrl.InsertItem( m_browseListCtrl.GetItemCount(), L"");
+		m_browseListCtrl.SetItemText( nIndex, 1, dlg.m_text );
+		m_browseListCtrl.SetCheck( nIndex, 1 );
+
+		m_browseListCtrl.SortItems( SortFunc, (DWORD_PTR) this );
+
+		m_browseListCtrl.Invalidate();
+
+		SetModified( TRUE );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage::OnBnClickedRemoveBrowseDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CBrowsingPage::OnBnClickedRemoveBrowseDomain()
+{
+	UINT	selectedCount = m_browseListCtrl.GetSelectedCount();
+	int		nItem = -1;
+	UINT	i;
+
+	// Update all of the selected items.
+
+	for ( i = 0; i < selectedCount; i++ )
+	{
+		nItem = m_browseListCtrl.GetNextItem( -1, LVNI_SELECTED );
+		check( nItem != -1 );
+
+		m_browseListCtrl.DeleteItem( nItem );
+
+		SetModified( TRUE );
+	}
+
+	m_removeButton.EnableWindow( FALSE );
+}
+
+
+void
+CBrowsingPage::OnLvnItemchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
+{
+	if ( m_browseListCtrl.GetSelectedCount() )
+	{
+		m_removeButton.EnableWindow( TRUE );
+	}
+
+	if ( m_initialized )
+	{
+		NM_LISTVIEW * pNMListView = (NM_LISTVIEW*)pNMHDR; 
+	 
+		BOOL bPrevState = (BOOL) ( ( ( pNMListView->uOldState & LVIS_STATEIMAGEMASK ) >> 12 ) - 1 ); 
+	 
+		if ( bPrevState < 0 )
+		{
+			bPrevState = 0;
+		}
+
+
+		BOOL bChecked = ( BOOL ) ( ( ( pNMListView->uNewState & LVIS_STATEIMAGEMASK ) >> 12) - 1 ); 
+	 
+		if ( bChecked < 0 )
+		{
+			bChecked = 0;
+		}
+
+		if ( bPrevState != bChecked )
+		{
+			SetModified( TRUE );
+		}
+	}
+
+	*pResult = 0;
+}
+
+
+
+int CALLBACK 
+CBrowsingPage::SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
+{
+	CString str1;
+	CString	str2;
+	int		ret = 0;
+
+	CBrowsingPage * self = reinterpret_cast<CBrowsingPage*>( lParamSort );
+	require_quiet( self, exit );
+
+	str1 = self->m_browseListCtrl.GetItemText( (int) lParam1, 1 );
+	str2 = self->m_browseListCtrl.GetItemText( (int) lParam2, 1 );
+
+	ret = str1.Compare( str2 );
+
+exit:
+
+	return ret;
+}
+
+
+// CAddBrowseDomain dialog
+
+IMPLEMENT_DYNAMIC(CAddBrowseDomain, CDialog)
+CAddBrowseDomain::CAddBrowseDomain(CWnd* pParent /*=NULL*/)
+	: CDialog(CAddBrowseDomain::IDD, pParent)
+{
+}
+
+CAddBrowseDomain::~CAddBrowseDomain()
+{
+}
+
+void CAddBrowseDomain::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_COMBO1, m_comboBox);
+}
+
+
+BOOL
+CAddBrowseDomain::OnInitDialog()
+{
+	CConfigPropertySheet	*	psheet;
+	CConfigPropertySheet::StringList::iterator		it;
+	
+	BOOL b = CDialog::OnInitDialog();
+
+	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
+	require_quiet( psheet, exit );
+
+	for ( it = psheet->m_browseDomains.begin(); it != psheet->m_browseDomains.end(); it++ )
+	{
+		CString text = *it;
+
+		if ( m_comboBox.FindStringExact( -1, *it ) == CB_ERR )
+		{
+			m_comboBox.AddString( *it );
+		}
+	}
+
+exit:
+
+	return b;
+}
+
+
+void
+CAddBrowseDomain::OnOK()
+{
+	m_comboBox.GetWindowText( m_text );
+
+	CDialog::OnOK();
+}
+
+
+
+BEGIN_MESSAGE_MAP(CAddBrowseDomain, CDialog)
+END_MESSAGE_MAP()
+
diff --git a/mDNSWindows/ControlPanel/BrowsingPage.h b/mDNSWindows/ControlPanel/BrowsingPage.h
new file mode 100755
index 0000000..4711b36
--- /dev/null
+++ b/mDNSWindows/ControlPanel/BrowsingPage.h
@@ -0,0 +1,156 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+#include <list>
+#include "afxcmn.h"
+
+#include "afxwin.h"
+
+
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CBrowsingPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CBrowsingPage : public CPropertyPage
+{
+public:
+	CBrowsingPage();
+	~CBrowsingPage();
+
+protected:
+
+	//{{AFX_DATA(CBrowsingPage)
+	enum { IDD = IDR_APPLET_PAGE3 };
+	//}}AFX_DATA
+
+	//{{AFX_VIRTUAL(CBrowsingPage)
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+	//}}AFX_VIRTUAL
+
+	DECLARE_DYNCREATE(CBrowsingPage)
+
+	//{{AFX_MSG(CBrowsingPage)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+	
+private:
+	
+	typedef std::list<CString> StringList;
+
+	afx_msg BOOL
+	OnSetActive();
+	
+	afx_msg void
+	OnOK();
+	
+	void
+	SetModified( BOOL bChanged = TRUE );
+	
+	void
+	Commit();
+
+	BOOL			m_modified;
+
+public:
+private:
+
+	static int CALLBACK 
+
+	SortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+
+
+
+	CListCtrl	m_browseListCtrl;
+
+	bool		m_initialized;
+
+	bool		m_firstTime;
+
+
+
+public:
+
+
+
+	afx_msg void OnBnClickedAddBrowseDomain();
+
+	afx_msg void OnBnClickedRemoveBrowseDomain();
+
+	afx_msg void OnLvnItemchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult);
+
+	CButton m_removeButton;
+
+};
+
+
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CAddBrowseDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+
+class CAddBrowseDomain : public CDialog
+
+{
+
+	DECLARE_DYNAMIC(CAddBrowseDomain)
+
+
+
+public:
+
+	CAddBrowseDomain(CWnd* pParent = NULL);   // standard constructor
+
+	virtual ~CAddBrowseDomain();
+
+
+
+// Dialog Data
+
+	enum { IDD = IDR_ADD_BROWSE_DOMAIN };
+
+
+
+protected:
+
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+	virtual BOOL OnInitDialog();
+
+	virtual void OnOK();
+
+	DECLARE_MESSAGE_MAP()
+
+public:
+
+	CComboBox	m_comboBox;
+
+	CString		m_text;
+
+};
+
diff --git a/mDNSWindows/ControlPanel/ConfigDialog.cpp b/mDNSWindows/ControlPanel/ConfigDialog.cpp
new file mode 100755
index 0000000..ad59066
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ConfigDialog.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "ConfigDialog.h"
+#include "ControlPanel.h"
+
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+IMPLEMENT_DYNCREATE(CConfigDialog, CDialog)
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigDialog::CConfigDialog
+//---------------------------------------------------------------------------------------------------------------------------
+
+CConfigDialog::CConfigDialog()
+	: CDialog(CConfigDialog::IDD, NULL)
+{
+	//{{AFX_DATA_INIT(CConfigDialog)
+	//}}AFX_DATA_INIT
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigDialog::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CConfigDialog::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CConfigDialog)
+	//}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CConfigDialog, CDialog)
+	//{{AFX_MSG_MAP(CConfigDialog)
+	//}}AFX_MSG_MAP
+END_MESSAGE_MAP()
diff --git a/mDNSWindows/ControlPanel/ConfigDialog.h b/mDNSWindows/ControlPanel/ConfigDialog.h
new file mode 100644
index 0000000..fa8df5f
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ConfigDialog.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigDialog
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CConfigDialog : public CDialog
+{
+public:
+
+	CConfigDialog();
+
+protected:
+
+	//{{AFX_DATA(CConfigDialog)
+	enum { IDD = IDR_APPLET };
+	//}}AFX_DATA
+
+	//{{AFX_VIRTUAL(CConfigDialog)
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+	//}}AFX_VIRTUAL
+
+	//{{AFX_MSG(CConfigDialog)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+
+	DECLARE_DYNCREATE(CConfigDialog)
+};
diff --git a/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp b/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp
new file mode 100755
index 0000000..5fae955
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp
@@ -0,0 +1,301 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ConfigPropertySheet.h"
+#include <WinServices.h>
+extern "C"
+{
+#include <ClientCommon.h>
+}
+#include <process.h>
+
+// Custom events
+
+#define WM_DATAREADY		( WM_USER + 0x100 )
+
+
+IMPLEMENT_DYNCREATE(CConfigPropertySheet, CPropertySheet)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::CConfigPropertySheet
+//---------------------------------------------------------------------------------------------------------------------------
+
+CConfigPropertySheet::CConfigPropertySheet()
+:
+	CPropertySheet(),
+	m_browseDomainsRef( NULL ),
+	m_thread( NULL ),
+	m_threadExited( NULL )
+{
+	AddPage(&m_firstPage );
+	AddPage(&m_secondPage);
+	AddPage(&m_thirdPage);
+
+	InitializeCriticalSection( &m_lock );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::~CConfigPropertySheet
+//---------------------------------------------------------------------------------------------------------------------------
+
+CConfigPropertySheet::~CConfigPropertySheet()
+{
+	DeleteCriticalSection( &m_lock );
+}
+
+
+BEGIN_MESSAGE_MAP(CConfigPropertySheet, CPropertySheet)
+	//{{AFX_MSG_MAP(CConfigPropertySheet)
+	//}}AFX_MSG_MAP
+	ON_MESSAGE( WM_DATAREADY, OnDataReady )
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::OnInitDialog
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CConfigPropertySheet::OnInitDialog()
+{
+	OSStatus err;
+
+	BOOL b = CPropertySheet::OnInitDialog();
+
+	err = SetupBrowsing();
+	require_noerr( err, exit );
+
+exit:
+
+	return b;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::OnCommand
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CConfigPropertySheet::OnCommand(WPARAM wParam, LPARAM lParam)
+{
+   // Check if OK or Cancel was hit
+
+   if ( ( wParam == ID_WIZFINISH ) || ( wParam == IDOK ) || ( wParam == IDCANCEL ) ) 
+   {
+      OnEndDialog();
+   }
+
+   return CPropertySheet::OnCommand(wParam, lParam);
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::OnDataReady
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CConfigPropertySheet::OnDataReady(WPARAM inWParam, LPARAM inLParam)
+{
+	if (WSAGETSELECTERROR(inLParam) && !(HIWORD(inLParam)))
+	{
+		dlog( kDebugLevelError, "OnSocket: window error\n" );
+	}
+	else
+	{
+		SOCKET sock = (SOCKET) inWParam;
+
+		if ( m_browseDomainsRef && DNSServiceRefSockFD( m_browseDomainsRef ) == (int) sock )
+		{
+			DNSServiceProcessResult( m_browseDomainsRef );
+		}
+	}
+
+	return 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::OnEndDialog
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CConfigPropertySheet::OnEndDialog()
+{
+	OSStatus err;
+
+	err = TearDownBrowsing();
+	check_noerr( err );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::SetupBrowsing
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CConfigPropertySheet::SetupBrowsing()
+{
+	OSStatus err;
+
+	// Start browsing for browse domains
+
+	err = DNSServiceEnumerateDomains( &m_browseDomainsRef, kDNSServiceFlagsBrowseDomains, 0, BrowseDomainsReply, this );
+	require_noerr( err, exit );
+
+	err = WSAAsyncSelect( DNSServiceRefSockFD( m_browseDomainsRef ), m_hWnd, WM_DATAREADY, FD_READ|FD_CLOSE );
+	require_noerr( err, exit );
+
+exit:
+
+	if ( err )
+	{
+		TearDownBrowsing();
+	}
+
+	return err;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::TearDownBrowsing
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CConfigPropertySheet::TearDownBrowsing()
+{
+	OSStatus err = kNoErr;
+
+	if ( m_browseDomainsRef )
+	{
+		err = WSAAsyncSelect( DNSServiceRefSockFD( m_browseDomainsRef ), m_hWnd, 0, 0 );
+		check_noerr( err );
+
+		DNSServiceRefDeallocate( m_browseDomainsRef );
+	
+		m_browseDomainsRef = NULL;
+	}
+
+	return err;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::DecodeDomainName
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CConfigPropertySheet::DecodeDomainName( const char * raw, CString & decoded )
+{
+	char nextLabel[128] = "\0";
+	char decodedDomainString[kDNSServiceMaxDomainName];
+    char * buffer = (char *) raw;
+    int labels = 0, i;
+    char text[64];
+	const char *label[128];
+	OSStatus	err;
+    
+	// Initialize
+
+	decodedDomainString[0] = '\0';
+
+    // Count the labels
+
+	while ( *buffer )
+	{
+		label[labels++] = buffer;
+		buffer = (char *) GetNextLabel(buffer, text);
+    }
+        
+    buffer = (char*) raw;
+
+    for (i = 0; i < labels; i++)
+	{
+		buffer = (char *)GetNextLabel(buffer, nextLabel);
+        strcat(decodedDomainString, nextLabel);
+        strcat(decodedDomainString, ".");
+    }
+    
+    // Remove trailing dot from domain name.
+    
+	decodedDomainString[ strlen( decodedDomainString ) - 1 ] = '\0';
+
+	// Convert to Unicode
+
+	err = UTF8StringToStringObject( decodedDomainString, decoded );
+
+	return err;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet::BrowseDomainsReply
+//---------------------------------------------------------------------------------------------------------------------------
+
+void DNSSD_API
+CConfigPropertySheet::BrowseDomainsReply
+							(
+							DNSServiceRef			sdRef,
+							DNSServiceFlags			flags,
+							uint32_t				interfaceIndex,
+							DNSServiceErrorType		errorCode,
+							const char			*	replyDomain,
+							void				*	context
+							)
+{
+	CConfigPropertySheet	*	self = reinterpret_cast<CConfigPropertySheet*>(context);
+	CString						decoded;
+	OSStatus					err;
+
+	DEBUG_UNUSED( sdRef );
+	DEBUG_UNUSED( interfaceIndex );
+
+	if ( errorCode )
+	{
+		goto exit;
+	}
+
+	check( replyDomain );
+	
+	// Ignore local domains
+
+	if ( strcmp( replyDomain, "local." ) == 0 )
+	{
+		goto exit;
+	}
+
+	err = self->DecodeDomainName( replyDomain, decoded );
+	require_noerr( err, exit );
+
+	// Remove trailing '.'
+
+	decoded.TrimRight( '.' );
+
+	if ( flags & kDNSServiceFlagsAdd )
+	{
+		self->m_browseDomains.push_back( decoded );
+	}
+	else
+	{
+		self->m_browseDomains.remove( decoded );
+	}
+
+exit:
+
+	return;
+}
diff --git a/mDNSWindows/ControlPanel/ConfigPropertySheet.h b/mDNSWindows/ControlPanel/ConfigPropertySheet.h
new file mode 100755
index 0000000..9e4fda8
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ConfigPropertySheet.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ConfigPropertySheet_h
+#define _ConfigPropertySheet_h
+
+#include "stdafx.h"
+#include "ServicesPage.h"
+#include "RegistrationPage.h"
+#include "BrowsingPage.h"
+
+#include <RegNames.h>
+#include <dns_sd.h>
+#include <list>
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CConfigPropertySheet
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CConfigPropertySheet : public CPropertySheet
+{
+public:
+
+	CConfigPropertySheet();
+	virtual ~CConfigPropertySheet();
+
+	typedef std::list<CString> StringList;
+
+	StringList	m_browseDomains;
+
+protected:
+
+	CServicesPage		m_firstPage;
+	CRegistrationPage	m_secondPage;
+	CBrowsingPage		m_thirdPage;
+
+	//{{AFX_VIRTUAL(CConfigPropertySheet)
+	//}}AFX_VIRTUAL
+
+	DECLARE_DYNCREATE(CConfigPropertySheet)
+
+	//{{AFX_MSG(CConfigPropertySheet)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+
+	afx_msg BOOL	OnInitDialog();
+	afx_msg BOOL	OnCommand( WPARAM wParam, LPARAM lParam );
+	afx_msg LRESULT	OnDataReady( WPARAM inWParam, LPARAM inLParam );
+	afx_msg LRESULT	OnRegistryChanged( WPARAM inWParam, LPARAM inLParam );
+	void			OnEndDialog();
+
+private:
+
+	OSStatus
+	SetupBrowsing();
+
+	OSStatus
+	TearDownBrowsing();
+
+	OSStatus
+	DecodeDomainName( const char * raw, CString & decoded );
+
+	static void DNSSD_API
+	BrowseDomainsReply
+				(
+				DNSServiceRef			sdRef,
+				DNSServiceFlags			flags,
+				uint32_t				interfaceIndex,
+				DNSServiceErrorType		errorCode,
+				const char			*	replyDomain,
+				void				*	context
+				);
+
+	// This thread will watch for registry changes
+
+	static unsigned WINAPI
+	WatchRegistry
+				(
+				LPVOID inParam
+				);
+
+	HKEY				m_statusKey;
+	HANDLE				m_thread;
+	HANDLE				m_threadExited;
+	DNSServiceRef		m_browseDomainsRef;
+	CRITICAL_SECTION	m_lock;
+};
+
+
+#endif
diff --git a/mDNSWindows/ControlPanel/ControlPanel.cpp b/mDNSWindows/ControlPanel/ControlPanel.cpp
new file mode 100755
index 0000000..4bf5df3
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanel.cpp
@@ -0,0 +1,380 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+    
+#include "ControlPanel.h"
+#include "ConfigDialog.h"
+#include "ConfigPropertySheet.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+static CCPApp theApp;
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	GetControlPanelApp
+//---------------------------------------------------------------------------------------------------------------------------
+
+CCPApp*
+GetControlPanelApp()
+{
+	CCPApp * pApp = (CCPApp*) AfxGetApp();
+
+	check( pApp );
+	check( pApp->IsKindOf( RUNTIME_CLASS( CCPApp ) ) );
+
+	return pApp;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CPlApplet
+//---------------------------------------------------------------------------------------------------------------------------
+
+LONG APIENTRY
+CPlApplet(HWND hWndCPl, UINT uMsg, LONG lParam1, LONG lParam2)
+{
+	AFX_MANAGE_STATE(AfxGetStaticModuleState());
+
+	CCPApp * pApp = GetControlPanelApp();
+
+	return ( LONG ) pApp->OnCplMsg(hWndCPl, uMsg, lParam1, lParam2);
+}
+
+
+IMPLEMENT_DYNAMIC(CCPApplet, CCmdTarget);
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::CCPApplet
+//---------------------------------------------------------------------------------------------------------------------------
+
+CCPApplet::CCPApplet(UINT resourceId, UINT descId, CRuntimeClass * uiClass)
+:
+	m_resourceId(resourceId),
+	m_descId(descId),
+	m_uiClass(uiClass),
+	m_pageNumber(0)
+{
+	check( uiClass );
+	check( uiClass->IsDerivedFrom( RUNTIME_CLASS( CDialog ) ) || 
+	       uiClass->IsDerivedFrom( RUNTIME_CLASS( CPropertySheet ) ) );
+
+	m_name.LoadString(resourceId);
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::~CCPApplet
+//---------------------------------------------------------------------------------------------------------------------------
+
+CCPApplet::~CCPApplet()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::OnStartParms
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApplet::OnStartParms(CWnd * pParentWnd, LPCTSTR extra)
+{
+	DEBUG_UNUSED( pParentWnd );
+
+	if ( extra )
+	{
+		m_pageNumber = ::_ttoi( extra ) - 1;
+	}
+
+	return 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::OnRun
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApplet::OnRun(CWnd* pParentWnd)
+{
+	LRESULT		lResult = 1;
+	CWnd	*	pWnd;
+
+	InitCommonControls();
+
+	pWnd = (CWnd*) m_uiClass->CreateObject(); 
+
+	if ( pWnd )
+	{
+		lResult = ERROR_SUCCESS;
+
+		if ( pWnd->IsKindOf( RUNTIME_CLASS( CPropertySheet ) ) )
+		{
+			CPropertySheet * pSheet = (CPropertySheet*) pWnd;
+
+			pSheet->Construct(m_name, pParentWnd, m_pageNumber);
+
+			pSheet->DoModal();
+		}
+		else
+		{
+			check( pWnd->IsKindOf( RUNTIME_CLASS( CDialog ) ) );
+
+			CDialog * pDialog = (CDialog*) pWnd;
+
+      		pDialog->DoModal();
+    	}
+
+		delete pWnd;
+  	}
+
+	return lResult;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::OnInquire
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApplet::OnInquire(CPLINFO* pInfo)
+{
+	pInfo->idIcon = m_resourceId;
+	pInfo->idName = m_resourceId;
+	pInfo->idInfo = m_descId;
+	pInfo->lData  = reinterpret_cast<LONG>(this);
+
+	return 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::OnNewInquire
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApplet::OnNewInquire(NEWCPLINFO* pInfo)
+{
+	DEBUG_UNUSED( pInfo );
+
+	return 1;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::OnSelect
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApplet::OnSelect()
+{
+	return 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet::OnStop
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApplet::OnStop()
+{
+	return 0;
+}
+
+
+IMPLEMENT_DYNAMIC(CCPApp, CWinApp);
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::CCPApp
+//---------------------------------------------------------------------------------------------------------------------------
+
+CCPApp::CCPApp()
+{
+	debug_initialize( kDebugOutputTypeWindowsEventLog, "DNS-SD Control Panel", GetModuleHandle( NULL ) );
+	debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelInfo );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::~CCPApp
+//---------------------------------------------------------------------------------------------------------------------------
+
+CCPApp::~CCPApp()
+{
+	while ( !m_applets.IsEmpty() )
+	{
+    	delete m_applets.RemoveHead();
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::AddApplet
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CCPApp::AddApplet( CCPApplet * applet )
+{
+	check( applet );
+
+	m_applets.AddTail( applet );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::OnInit
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApp::OnInit()
+{
+	CCPApplet * applet;
+
+	try
+	{
+		applet = new CCPApplet( IDR_APPLET, IDS_APPLET_DESCRIPTION, RUNTIME_CLASS( CConfigPropertySheet ) );
+	}
+	catch (...)
+	{
+		applet = NULL;
+	}
+   
+	require_action( applet, exit, kNoMemoryErr );
+	
+	AddApplet( applet );
+
+exit:
+
+	return m_applets.GetCount();
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::OnExit
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApp::OnExit()
+{
+  return 1;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::OnCplMsg
+//---------------------------------------------------------------------------------------------------------------------------
+
+LRESULT
+CCPApp::OnCplMsg(HWND hWndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
+{
+	LRESULT lResult = 1;
+
+	switch ( uMsg )
+	{
+		case CPL_INIT:
+		{
+			lResult = OnInit();
+		}
+		break;
+
+		case CPL_EXIT:
+		{
+			lResult = OnExit();
+		}
+		break;
+
+		case CPL_GETCOUNT:
+		{      
+    		lResult = m_applets.GetCount();
+  		}
+		break;
+
+		default:
+  		{
+    		POSITION pos = m_applets.FindIndex( lParam1 );
+			check( pos );
+
+			CCPApplet * applet = m_applets.GetAt( pos );  
+			check( applet );
+
+    		switch (uMsg)
+    		{
+      			case CPL_INQUIRE:
+      			{
+					LPCPLINFO pInfo = reinterpret_cast<LPCPLINFO>(lParam2);
+        			lResult = applet->OnInquire(pInfo);
+				}  
+        		break;
+
+				case CPL_NEWINQUIRE:
+      			{
+        			LPNEWCPLINFO pInfo = reinterpret_cast<LPNEWCPLINFO>(lParam2);
+					lResult = applet->OnNewInquire(pInfo);
+				}  
+        		break;
+
+				case CPL_STARTWPARMS:
+      			{
+        			CWnd * pParentWnd = CWnd::FromHandle(hWndCPl);
+        			LPCTSTR lpszExtra = reinterpret_cast<LPCTSTR>(lParam2);
+        			lResult = applet->OnStartParms(pParentWnd, lpszExtra);
+				}
+				break;
+
+				case CPL_DBLCLK:
+				{
+        			CWnd* pParentWnd = CWnd::FromHandle(hWndCPl);
+        			lResult = applet->OnRun(pParentWnd);
+				}
+        		break;
+
+				case CPL_SELECT:
+				{
+        			lResult = applet->OnSelect();
+				}
+				break;
+
+				case CPL_STOP:
+				{
+					lResult = applet->OnStop();
+				}
+				break;
+
+				default:
+				{
+					// TRACE(_T("Warning, Received an unknown control panel message:%d\n"), uMsg);
+					lResult = 1;
+				}
+				break;
+    		}
+  		}
+		break;
+	}
+
+	return lResult;
+}
diff --git a/mDNSWindows/ControlPanel/ControlPanel.def b/mDNSWindows/ControlPanel/ControlPanel.def
new file mode 100644
index 0000000..3cb05eb
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanel.def
@@ -0,0 +1,20 @@
+; -*- tab-width: 4 -*-
+;
+; Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+; 
+;     http://www.apache.org/licenses/LICENSE-2.0
+; 
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+    
+LIBRARY	"Bonjour"
+
+EXPORTS
+	CPlApplet
diff --git a/mDNSWindows/ControlPanel/ControlPanel.h b/mDNSWindows/ControlPanel/ControlPanel.h
new file mode 100644
index 0000000..dec5e58
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanel.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+    
+#pragma once
+
+#include "stdafx.h"
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApplet
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CCPApplet : public CCmdTarget
+{
+public:
+
+	CCPApplet( UINT nResourceID, UINT nDescriptionID, CRuntimeClass* pUIClass );
+
+	virtual ~CCPApplet();
+
+protected:
+
+	virtual LRESULT OnRun(CWnd* pParentWnd);
+	virtual LRESULT OnStartParms(CWnd* pParentWnd, LPCTSTR lpszExtra);
+	virtual LRESULT OnInquire(CPLINFO* pInfo);
+	virtual LRESULT OnNewInquire(NEWCPLINFO* pInfo);
+	virtual LRESULT OnSelect();
+	virtual LRESULT OnStop();
+
+	CRuntimeClass	*	m_uiClass;
+	UINT				m_resourceId;
+	UINT				m_descId;
+	CString				m_name;
+	int					m_pageNumber;
+  
+	friend class CCPApp;
+
+	DECLARE_DYNAMIC(CCPApplet);
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CCPApp : public CWinApp
+{
+public:
+
+	CCPApp();
+	virtual ~CCPApp();
+
+	void AddApplet( CCPApplet* pApplet );
+
+protected:
+
+	CList<CCPApplet*, CCPApplet*&> m_applets;
+
+	friend LONG APIENTRY
+	CPlApplet(HWND hWndCPl, UINT uMsg, LONG lParam1, LONG lParam2);
+
+	virtual LRESULT OnCplMsg(HWND hWndCPl, UINT msg, LPARAM lp1, LPARAM lp2);
+	virtual LRESULT OnInit();
+	virtual LRESULT OnExit();
+
+	DECLARE_DYNAMIC(CCPApp);
+};
+
+
+CCPApp * GetControlPanelApp();
diff --git a/mDNSWindows/ControlPanel/ControlPanel.rc b/mDNSWindows/ControlPanel/ControlPanel.rc
new file mode 100644
index 0000000..1df3e90
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanel.rc
@@ -0,0 +1,141 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+#include "WinVersRes.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"

+    "#include ""WinVersRes.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"

+    "LANGUAGE 9, 1\r\n"

+    "#pragma code_page(1252)\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_APPLET              ICON                    "res\\controlpanel.ico"

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x2L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "Bonjour Control Panel"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "InternalName", "ControlPanel.cpl"

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "OriginalFilename", "ControlPanel.cpl"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// String Table

+//

+

+STRINGTABLE

+BEGIN

+	IDS_REINSTALL    "Bonjour Control Panel cannot run because some of its required files are missing.  Please reinstall Bonjour Control Panel."

+	IDS_REINSTALL_CAPTION "Bonjour"

+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)

+LANGUAGE 9, 1

+#pragma code_page(1252)

+#include "afxres.rc"     // Standard components

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/mDNSWindows/ControlPanel/ControlPanel.vcproj b/mDNSWindows/ControlPanel/ControlPanel.vcproj
new file mode 100755
index 0000000..2f2d0ab
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanel.vcproj
@@ -0,0 +1,727 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="ControlPanel"

+	ProjectGUID="{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}"

+	RootNamespace="ControlPanel"

+	Keyword="MFCProj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="false"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderThrough=""

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="0"

+				DisableSpecificWarnings="4311;4312"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="../DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="2"

+				SuppressStartupBanner="true"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderThrough=""

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="0"

+				DisableSpecificWarnings="4311;4312"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="../DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="2"

+				SuppressStartupBanner="true"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel64.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="false"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="false"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="true"

+				TreatWChar_tAsBuiltInType="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				DisableSpecificWarnings="4702"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="../DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                  &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="false"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="true"

+				TreatWChar_tAsBuiltInType="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				DisableSpecificWarnings="4702"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="../DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel64.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                  &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+			>

+			<File

+				RelativePath="ConfigDialog.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="ConfigPropertySheet.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath=".\ControlPanelExe.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\ServicesPage.cpp"

+				>

+			</File>

+			<File

+				RelativePath="RegistrationPage.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\loclibrary.c"

+				>

+			</File>

+			<File

+				RelativePath="stdafx.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="BrowsingPage.cpp"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl"

+			>

+			<File

+				RelativePath="ConfigDialog.h"

+				>

+			</File>

+			<File

+				RelativePath="ConfigPropertySheet.h"

+				>

+			</File>

+			<File

+				RelativePath=".\ControlPanelExe.h"

+				>

+			</File>

+			<File

+				RelativePath=".\ServicesPage.h"

+				>

+			</File>

+			<File

+				RelativePath="RegistrationPage.h"

+				>

+			</File>

+			<File

+				RelativePath="..\loclibrary.h"

+				>

+			</File>

+			<File

+				RelativePath="Resource.h"

+				>

+			</File>

+			<File

+				RelativePath="stdafx.h"

+				>

+			</File>

+			<File

+				RelativePath="BrowsingPage.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"

+			>

+			<File

+				RelativePath="res\configurator.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\controlpanel.ico"

+				>

+			</File>

+			<File

+				RelativePath=".\ControlPanel.rc"

+				>

+			</File>

+			<File

+				RelativePath=".\res\ControlPanel.rc2"

+				>

+			</File>

+			<File

+				RelativePath=".\res\EnergySaver.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\failure.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\success.ico"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Support"

+			>

+			<File

+				RelativePath="..\..\Clients\ClientCommon.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\Clients\ClientCommon.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dns_sd.h"

+				>

+			</File>

+			<File

+				RelativePath="..\Secret.c"

+				>

+			</File>

+			<File

+				RelativePath="..\Secret.h"

+				>

+			</File>

+			<File

+				RelativePath="..\WinServices.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\WinServices.h"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/ControlPanel/ControlPanelDll.rc b/mDNSWindows/ControlPanel/ControlPanelDll.rc
new file mode 100644
index 0000000..5d1f495
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelDll.rc
@@ -0,0 +1,123 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+#include "WinVersRes.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

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x1L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904e4"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "Bonjour Configuration Applet"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "InternalName", "Bonjour.cpl"

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "OriginalFilename", "Bonjour.cpl"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1252

+    END

+END

+

+

+#ifdef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// TEXTINCLUDE

+//

+

+1 TEXTINCLUDE 

+BEGIN

+    "resource.h\0"

+END

+

+2 TEXTINCLUDE 

+BEGIN

+    "#include ""afxres.h""\r\n"

+    "#include ""WinVersRes.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"

+    "LANGUAGE 9, 1\r\n"

+    "#pragma code_page(1252)\r\n"

+    "#include ""afxres.rc""         // Standard components\r\n"

+    "#include ""ControlPanel.rc""\r\n"

+    "#endif\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+#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)

+LANGUAGE 9, 1

+#pragma code_page(1252)

+#include "afxres.rc"         // Standard components

+#include "ControlPanel.rc"

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

diff --git a/mDNSWindows/ControlPanel/ControlPanelExe.cpp b/mDNSWindows/ControlPanel/ControlPanelExe.cpp
new file mode 100755
index 0000000..36447d1
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelExe.cpp
@@ -0,0 +1,373 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2007 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+    
+#include "ControlPanelExe.h"
+#include "ConfigDialog.h"
+#include "ConfigPropertySheet.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+#include "loclibrary.h"
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#ifndef HeapEnableTerminationOnCorruption
+#	define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS) 1
+#endif
+
+
+// Stash away pointers to our resource DLLs
+
+static HINSTANCE g_nonLocalizedResources	= NULL;
+static HINSTANCE g_localizedResources		= NULL;
+
+
+HINSTANCE	GetNonLocalizedResources()
+{
+	return g_nonLocalizedResources;
+}
+
+
+HINSTANCE	GetLocalizedResources()
+{
+	return g_localizedResources;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	Static Declarations
+//---------------------------------------------------------------------------------------------------------------------------
+DEFINE_GUID(CLSID_ControlPanel, 
+
+0x1207552c, 0xe59, 0x4d9f, 0x85, 0x54, 0xf1, 0xf8, 0x6, 0xcd, 0x7f, 0xa9);
+
+static LPCTSTR g_controlPanelGUID			=	TEXT( "{1207552C-0E59-4d9f-8554-F1F806CD7FA9}" );
+static LPCTSTR g_controlPanelName			=	TEXT( "Bonjour" );
+static LPCTSTR g_controlPanelCanonicalName	=	TEXT( "Apple.Bonjour" );
+static LPCTSTR g_controlPanelCategory		=	TEXT( "3,8" );
+
+static CCPApp theApp;
+
+//===========================================================================================================================
+//	MyRegDeleteKey
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus MyRegDeleteKey( HKEY hKeyRoot, LPTSTR lpSubKey )
+{
+    LPTSTR lpEnd;
+    OSStatus err;
+    DWORD dwSize;
+    TCHAR szName[MAX_PATH];
+    HKEY hKey;
+    FILETIME ftWrite;
+
+    // First, see if we can delete the key without having to recurse.
+
+    err = RegDeleteKey( hKeyRoot, lpSubKey );
+
+    if ( !err )
+	{
+		goto exit;
+	}
+
+    err = RegOpenKeyEx( hKeyRoot, lpSubKey, 0, KEY_READ, &hKey );
+	require_noerr( err, exit );
+
+    // Check for an ending slash and add one if it is missing.
+
+    lpEnd = lpSubKey + lstrlen(lpSubKey);
+
+    if ( *( lpEnd - 1 ) != TEXT( '\\' ) ) 
+    {
+        *lpEnd =  TEXT('\\');
+        lpEnd++;
+        *lpEnd =  TEXT('\0');
+    }
+
+    // Enumerate the keys
+
+    dwSize = MAX_PATH;
+    err = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite);
+
+    if ( !err ) 
+    {
+        do
+		{
+            lstrcpy (lpEnd, szName);
+
+            if ( !MyRegDeleteKey( hKeyRoot, lpSubKey ) )
+			{
+                break;
+            }
+
+            dwSize = MAX_PATH;
+
+            err = RegEnumKeyEx( hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite );
+
+        }
+		while ( !err );
+    }
+
+    lpEnd--;
+    *lpEnd = TEXT('\0');
+
+    RegCloseKey( hKey );
+
+    // Try again to delete the key.
+
+    err = RegDeleteKey(hKeyRoot, lpSubKey);
+	require_noerr( err, exit );
+
+exit:
+
+	return err;
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::CCPApp
+//---------------------------------------------------------------------------------------------------------------------------
+IMPLEMENT_DYNAMIC(CCPApp, CWinApp);
+
+CCPApp::CCPApp()
+{
+	debug_initialize( kDebugOutputTypeWindowsEventLog, "DNS-SD Control Panel", GetModuleHandle( NULL ) );
+	debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelInfo );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CCPApp::~CCPApp
+//---------------------------------------------------------------------------------------------------------------------------
+
+CCPApp::~CCPApp()
+{
+}
+
+
+void
+CCPApp::Register( LPCTSTR inClsidString, LPCTSTR inName, LPCTSTR inCanonicalName, LPCTSTR inCategory, LPCTSTR inLocalizedName, LPCTSTR inInfoTip, LPCTSTR inIconPath, LPCTSTR inExePath )
+{
+	typedef struct	RegistryBuilder		RegistryBuilder;
+	
+	struct	RegistryBuilder
+	{
+		HKEY		rootKey;
+		LPCTSTR		subKey;
+		LPCTSTR		valueName;
+		DWORD		valueType;
+		LPCTSTR		data;
+	};
+	
+	OSStatus			err;
+	size_t				n;
+	size_t				i;
+	HKEY				key;
+	TCHAR				keyName[ MAX_PATH ];
+	RegistryBuilder		entries[] = 
+	{
+		{ HKEY_LOCAL_MACHINE,	TEXT( "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s" ),	NULL,									REG_SZ,		inName },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s" ),																			NULL,									NULL,		NULL },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s" ),																			TEXT( "System.ApplicationName" ),		REG_SZ,		inCanonicalName },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s" ),																			TEXT( "System.ControlPanel.Category" ),	REG_SZ,		inCategory },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s" ),																			TEXT( "LocalizedString" ),				REG_SZ,		inLocalizedName },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s" ),																			TEXT( "InfoTip" ),						REG_SZ,		inInfoTip },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s\\DefaultIcon" ),																NULL,									REG_SZ,		inIconPath },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s\\Shell" ),																		NULL,									NULL,		NULL },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s\\Shell\\Open" ),																NULL,									NULL,		NULL },
+		{ HKEY_CLASSES_ROOT,	TEXT( "CLSID\\%s\\Shell\\Open\\Command" ),														NULL,									REG_SZ,		inExePath }
+	};
+	DWORD				size;
+	
+	// Register the registry entries.
+
+	n = sizeof_array( entries );
+	for( i = 0; i < n; ++i )
+	{
+		wsprintf( keyName, entries[ i ].subKey, inClsidString );		
+		err = RegCreateKeyEx( entries[ i ].rootKey, keyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, NULL );
+		require_noerr( err, exit );
+		
+		if ( entries[ i ].data )
+		{
+			size = (DWORD)( ( lstrlen( entries[ i ].data ) + 1 ) * sizeof( TCHAR ) );
+			err = RegSetValueEx( key, entries[ i ].valueName, 0, entries[ i ].valueType, (LPBYTE) entries[ i ].data, size );
+			require_noerr( err, exit );
+		}
+
+		RegCloseKey( key );
+	}
+	
+exit:
+	return;
+}
+
+
+//-----------------------------------------------------------
+//	CCPApp::Unregister
+//-----------------------------------------------------------
+void
+CCPApp::Unregister( LPCTSTR clsidString )
+{
+	TCHAR keyName[ MAX_PATH * 2 ];
+
+	wsprintf( keyName, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ControlPanel\\NameSpace\\%s", clsidString );							
+	MyRegDeleteKey( HKEY_LOCAL_MACHINE, keyName );
+
+	wsprintf( keyName, L"CLSID\\%s", clsidString );
+	MyRegDeleteKey( HKEY_CLASSES_ROOT, keyName );
+}
+
+
+
+//-----------------------------------------------------------
+//	CCPApp::InitInstance
+//-----------------------------------------------------------
+
+BOOL
+CCPApp::InitInstance()
+{
+	CCommandLineInfo	commandLine;
+	wchar_t				resource[MAX_PATH];
+	CString				errorMessage;
+	CString				errorCaption;
+	int					res;
+	OSStatus			err = kNoErr;
+
+	HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
+
+	//
+	// initialize the debugging framework
+	//
+	debug_initialize( kDebugOutputTypeWindowsDebugger, "ControlPanel", NULL );
+	debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelTrace );
+
+	// Before we load the resources, let's load the error string
+
+	errorMessage.LoadString( IDS_REINSTALL );
+	errorCaption.LoadString( IDS_REINSTALL_CAPTION );
+
+	res = PathForResource( NULL, L"ControlPanelResources.dll", resource, MAX_PATH );
+	err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
+	require_noerr( err, exit );
+
+	g_nonLocalizedResources = LoadLibrary( resource );
+	translate_errno( g_nonLocalizedResources, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	res = PathForResource( NULL, L"ControlPanelLocalized.dll", resource, MAX_PATH );
+	err = translate_errno( res != 0, kUnknownErr, kUnknownErr );
+	require_noerr( err, exit );
+
+	g_localizedResources = LoadLibrary( resource );
+	translate_errno( g_localizedResources, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	AfxSetResourceHandle( g_localizedResources );
+
+	// InitCommonControls() is required on Windows XP if an application
+	// manifest specifies use of ComCtl32.dll version 6 or later to enable
+	// visual styles.  Otherwise, any window creation will fail.
+
+	InitCommonControls();
+
+	CWinApp::InitInstance();
+
+	AfxEnableControlContainer();
+
+	ParseCommandLine( commandLine );
+
+	if ( commandLine.m_nShellCommand == CCommandLineInfo::AppRegister )
+	{
+		CString		localizedName;
+		CString		toolTip;
+		TCHAR		iconPath[ MAX_PATH + 12 ]	= TEXT( "" );
+		TCHAR		exePath[ MAX_PATH ]			= TEXT( "" );
+		DWORD		nChars;
+		OSStatus	err;
+
+		nChars = GetModuleFileName( NULL, exePath, sizeof_array( exePath ) );
+
+		err = translate_errno( nChars > 0, (OSStatus) GetLastError(), kUnknownErr );
+
+		require_noerr( err, exit );
+
+		wsprintf( iconPath, L"%s,-%d", exePath, IDR_APPLET );
+
+		localizedName.LoadString( IDS_APPLET_NAME );
+		toolTip.LoadString( IDS_APPLET_TOOLTIP );
+
+		Register( g_controlPanelGUID, g_controlPanelName, g_controlPanelCanonicalName, g_controlPanelCategory, localizedName, toolTip, iconPath, exePath );
+	}
+	else if ( commandLine.m_nShellCommand == CCommandLineInfo::AppUnregister )
+	{
+		Unregister( g_controlPanelGUID );
+	}
+	else
+	{
+		CString					name;
+		CConfigPropertySheet	dlg;
+		
+		name.LoadString( IDR_APPLET );
+		dlg.Construct( name, NULL, 0 );
+
+		m_pMainWnd = &dlg;
+
+		try
+		{
+			INT_PTR nResponse = dlg.DoModal();
+		
+			if (nResponse == IDOK)
+			{
+				// TODO: Place code here to handle when the dialog is
+				//  dismissed with OK
+			}
+			else if (nResponse == IDCANCEL)
+			{
+				// TODO: Place code here to handle when the dialog is
+				//  dismissed with Cancel
+			}
+		}
+		catch (...)
+		{
+			MessageBox(NULL, L"", L"", MB_OK|MB_ICONEXCLAMATION);
+		}
+	}
+
+	if ( err )
+	{
+		MessageBox( NULL, L"", L"", MB_ICONERROR | MB_OK );
+	}
+
+exit:
+
+	if ( err )
+	{
+		MessageBox( NULL, errorMessage, errorCaption, MB_ICONERROR | MB_OK );
+	}
+
+	// Since the dialog has been closed, return FALSE so that we exit the
+	//  application, rather than start the application's message pump.
+	return FALSE;
+}
diff --git a/mDNSWindows/ControlPanel/ControlPanelExe.h b/mDNSWindows/ControlPanel/ControlPanelExe.h
new file mode 100644
index 0000000..079422b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelExe.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2007 Apple Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+    
+#pragma once
+
+#include "stdafx.h"

+
+extern HINSTANCE	GetNonLocalizedResources();
+extern HINSTANCE	GetLocalizedResources();
+
+//-------------------------------------------------
+//	CCPApp
+//-------------------------------------------------
+
+class CCPApp : public CWinApp
+{
+public:
+
+	CCPApp();
+	virtual ~CCPApp();
+
+protected:
+
+	virtual BOOL    InitInstance();
+
+	void
+	Register( LPCTSTR inClsidString, LPCTSTR inName, LPCTSTR inCanonicalName, LPCTSTR inCategory, LPCTSTR inLocalizedName, LPCTSTR inInfoTip, LPCTSTR inIconPath, LPCTSTR inExePath );
+
+	void
+	Unregister( LPCTSTR clsidString );
+
+	DECLARE_DYNAMIC(CCPApp);
+};
diff --git a/mDNSWindows/ControlPanel/ControlPanelExe.rc b/mDNSWindows/ControlPanel/ControlPanelExe.rc
new file mode 100644
index 0000000..4ea5f95
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelExe.rc
@@ -0,0 +1,123 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+#include "WinVersRes.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

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x1L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904e4"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "Bonjour Configuration Applet"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "InternalName", "ControlPanel.exe"

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "OriginalFilename", "ControlPanel.exe"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1252

+    END

+END

+

+

+#ifdef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// TEXTINCLUDE

+//

+

+1 TEXTINCLUDE 

+BEGIN

+    "resource.h\0"

+END

+

+2 TEXTINCLUDE 

+BEGIN

+    "#include ""afxres.h""\r\n"

+    "#include ""WinVersRes.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"

+    "LANGUAGE 9, 1\r\n"

+    "#pragma code_page(1252)\r\n"

+    "#include ""afxres.rc""         // Standard components\r\n"

+    "#include ""ControlPanel.rc""\r\n"

+    "#endif\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+#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)

+LANGUAGE 9, 1

+#pragma code_page(1252)

+#include "afxres.rc"         // Standard components

+#include "ControlPanel.rc"

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

diff --git a/mDNSWindows/ControlPanel/ControlPanelExe.vcproj b/mDNSWindows/ControlPanel/ControlPanelExe.vcproj
new file mode 100755
index 0000000..8bc0b29
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelExe.vcproj
@@ -0,0 +1,764 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="ControlPanel (Vista)"

+	ProjectGUID="{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}"

+	Keyword="MFCProj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="false"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderThrough=""

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="0"

+				DisableSpecificWarnings="4311;4312"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="2"

+				SuppressStartupBanner="true"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;_DEBUG;DEBUG=1;UNICODE;_UNICODE;_WINDOWS;WINVER=0x0501;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderThrough=""

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="0"

+				DisableSpecificWarnings="4311;4312"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="2"

+				SuppressStartupBanner="true"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel64.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="false"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="false"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="true"

+				TreatWChar_tAsBuiltInType="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				DisableSpecificWarnings="4702"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="ExeBuild\$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="1"

+				AdditionalIncludeDirectories="..;../../mDNSCore;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0501;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="false"

+				RuntimeLibrary="0"

+				EnableFunctionLevelLinking="true"

+				TreatWChar_tAsBuiltInType="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ObjectFile="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\vc80.pdb"

+				WarningLevel="4"

+				SuppressStartupBanner="true"

+				DisableSpecificWarnings="4702"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)/ControlPanel.exe"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				ProgramDatabaseFile="$(OutDir)\ControlPanel.pdb"

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				EntryPointSymbol="wWinMainCRTStartup"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\ControlPanel64.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+			>

+			<File

+				RelativePath="ConfigDialog.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="ConfigPropertySheet.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath=".\ControlPanelExe.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\FifthPage.cpp"

+				>

+			</File>

+			<File

+				RelativePath="FirstPage.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath=".\FourthPage.cpp"

+				>

+			</File>

+			<File

+				RelativePath="SecondPage.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="SharedSecret.cpp"

+				>

+			</File>

+			<File

+				RelativePath="stdafx.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="0"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="2"

+						PreprocessorDefinitions=""

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="ThirdPage.cpp"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl"

+			>

+			<File

+				RelativePath="ConfigDialog.h"

+				>

+			</File>

+			<File

+				RelativePath="ConfigPropertySheet.h"

+				>

+			</File>

+			<File

+				RelativePath=".\ControlPanelExe.h"

+				>

+			</File>

+			<File

+				RelativePath=".\FifthPage.h"

+				>

+			</File>

+			<File

+				RelativePath="FirstPage.h"

+				>

+			</File>

+			<File

+				RelativePath=".\FourthPage.h"

+				>

+			</File>

+			<File

+				RelativePath="Resource.h"

+				>

+			</File>

+			<File

+				RelativePath="SecondPage.h"

+				>

+			</File>

+			<File

+				RelativePath="SharedSecret.h"

+				>

+			</File>

+			<File

+				RelativePath="stdafx.h"

+				>

+			</File>

+			<File

+				RelativePath="ThirdPage.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"

+			>

+			<File

+				RelativePath="res\configurator.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\controlpanel.ico"

+				>

+			</File>

+			<File

+				RelativePath=".\res\ControlPanel.rc2"

+				>

+			</File>

+			<File

+				RelativePath=".\ControlPanelExe.rc"

+				>

+			</File>

+			<File

+				RelativePath="res\failure.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\success.ico"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Support"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dns_sd.h"

+				>

+			</File>

+			<File

+				RelativePath="..\Secret.c"

+				>

+			</File>

+			<File

+				RelativePath="..\Secret.h"

+				>

+			</File>

+			<File

+				RelativePath="..\WinServices.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\WinServices.h"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/ControlPanel/ControlPanelLocRes.rc b/mDNSWindows/ControlPanel/ControlPanelLocRes.rc
new file mode 100755
index 0000000..4ba22b4
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelLocRes.rc
@@ -0,0 +1,270 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+#include "WinVersRes.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"

+    "#include ""WinVersRes.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"

+    "LANGUAGE 9, 1\r\n"

+    "#pragma code_page(1252)\r\n"

+    "#include ""afxres.rc""     // Standard components\r\n"

+    "#endif\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x2L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "Bonjour Resource Module"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "InternalName", "ControlPanelLocalized.dll"

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "OriginalFilename", "ControlPanelLocalized.dll"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Dialog

+//

+

+IDR_APPLET_PAGE1 DIALOGEX 0, 0, 262, 140

+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION

+CAPTION "Registration"

+FONT 8, "MS Sans Serif", 0, 0, 0x0

+BEGIN

+    LTEXT           "Hostname:",IDC_STATIC,13,22,35,8

+    EDITTEXT        IDC_HOSTNAME,55,20,184,12,ES_AUTOHSCROLL

+    LTEXT           "User:",IDC_STATIC,13,38,35,8

+    EDITTEXT        IDC_USERNAME,55,36,184,12,ES_AUTOHSCROLL

+    LTEXT           "Password:",IDC_STATIC,13,54,35,8

+    EDITTEXT        IDC_PASSWORD,55,52,184,12,ES_PASSWORD | ES_AUTOHSCROLL

+    CONTROL         "Advertise services in this domain using Bonjour",IDC_ADVERTISE_SERVICES,

+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,55,80,199,8

+END

+

+IDR_APPLET_PAGE3 DIALOGEX 0, 0, 262, 140

+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION

+CAPTION "Browsing"

+FONT 8, "MS Sans Serif", 0, 0, 0x0

+BEGIN

+    LTEXT           "Choose which domains to browse using wide-area Bonjour",

+                    -1,7,16,248,12

+    CONTROL         "",IDC_BROWSE_LIST,"SysListView32",LVS_REPORT | 

+                    LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | 

+                    WS_TABSTOP,7,37,248,57

+    PUSHBUTTON      "Add",IDC_ADD_BROWSE_DOMAIN,152,100,50,14

+    PUSHBUTTON      "Remove",IDC_REMOVE_BROWSE_DOMAIN,205,100,50,14

+END

+

+IDR_APPLET_PAGE5 DIALOGEX 0, 0, 262, 140

+STYLE DS_SETFONT | WS_CHILD | WS_CAPTION

+CAPTION "Services"

+FONT 8, "MS Sans Serif", 0, 0, 0x0

+BEGIN

+    CONTROL         "Advertise shared folders using Bonjour",IDC_ADVERTISE_SMB,

+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,19,199,8

+    CONTROL         "Enable Wake on Demand",IDC_POWER_MANAGEMENT,

+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,34,199,8

+END

+

+IDR_POWER_MANAGEMENT_WARNING DIALOGEX 0, 0, 230, 95

+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 

+    WS_SYSMENU

+CAPTION "Power Management"

+FONT 8, "MS Shell Dlg", 400, 0, 0x1

+BEGIN

+    DEFPUSHBUTTON   "OK",IDOK,173,74,50,14

+    LTEXT           "When 'Wake On Demand' is enabled, you may hear your computer wake up occasionally.",

+					IDC_STATIC,50,12,175,26

+    LTEXT           "This informs other devices that your computer is still available on the network.",

+                    IDC_STATIC,50,38,175,26

+    ICON            IDI_ENERGY_SAVER,IDC_ENERGY_SAVER,2,10,64,64,SS_REALSIZEIMAGE

+END

+

+IDR_ADD_BROWSE_DOMAIN DIALOGEX 0, 0, 230, 95

+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 

+    WS_SYSMENU

+CAPTION "Add Browse Domain"

+FONT 8, "MS Shell Dlg", 400, 0, 0x1

+BEGIN

+    DEFPUSHBUTTON   "OK",IDOK,117,74,50,14

+    PUSHBUTTON      "Cancel",IDCANCEL,173,74,50,14

+    COMBOBOX        IDC_COMBO1,35,42,188,100,CBS_DROPDOWN | CBS_SORT | 

+                    WS_VSCROLL | WS_TABSTOP

+    LTEXT           "Domain:",IDC_STATIC,7,43,27,8

+    LTEXT           "The following domain will be added to your list of Bonjour browse domains.",

+                    IDC_STATIC,7,15,216,16

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// DESIGNINFO

+//

+

+#ifdef APSTUDIO_INVOKED

+GUIDELINES DESIGNINFO 

+BEGIN

+    IDR_APPLET_PAGE1, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 255

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 133

+    END

+

+    IDR_APPLET_PAGE2, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 255

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 133

+    END

+

+    IDR_SECRET, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 244

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 83

+    END

+

+    IDR_APPLET_PAGE3, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 255

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 133

+    END

+

+	IDR_POWER_MANAGEMENT_WARNING, DIALOG

+	BEGIN

+		LEFTMARGIN, 7

+		RIGHTMARGIN, 223

+		TOPMARGIN, 7,

+		BOTTOMMARGIN, 88

+	END

+

+    IDR_ADD_BROWSE_DOMAIN, DIALOG

+    BEGIN

+        LEFTMARGIN, 7

+        RIGHTMARGIN, 223

+        TOPMARGIN, 7

+        BOTTOMMARGIN, 88

+    END

+END

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// String Table

+//

+

+STRINGTABLE 

+BEGIN

+    IDR_APPLET              "Bonjour"

+	IDS_APPLET_NAME			"Bonjour"

+    IDS_APPLET_DESCRIPTION  "Bonjour"

+	IDS_APPLET_TOOLTIP		"Change Bonjour settings for this computer."

+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)

+LANGUAGE 9, 1

+#pragma code_page(1252)

+#include "afxres.rc"     // Standard components

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj b/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj
new file mode 100755
index 0000000..cdcee9b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj
@@ -0,0 +1,487 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="ControlPanelLocRes"

+	ProjectGUID="{4490229E-025A-478F-A2CF-51154DA83E39}"

+	RootNamespace="ControlPanelLocRes"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="1"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"

+				StringPooling="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Debug/"

+				ObjectFile=".\Debug/"

+				ProgramDataBaseFileName=".\Debug/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;if not exist $(OutDir)\ControlPanel.Resources\en.lproj mkdir $(OutDir)\ControlPanel.Resources\en.lproj&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				AdditionalDependencies=""

+				OutputFile="$(OutDir)\ControlPanel.Resources\en.lproj\ControlPanelLocalized.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"

+				SubSystem="2"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(OutDir)/$(ProjectName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="3"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"

+				StringPooling="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Debug/"

+				ObjectFile=".\Debug/"

+				ProgramDataBaseFileName=".\Debug/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;if not exist $(OutDir)\ControlPanel.Resources\en.lproj mkdir $(OutDir)\ControlPanel.Resources\en.lproj&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				AdditionalDependencies=""

+				OutputFile="$(OutDir)\ControlPanel.Resources\en.lproj\ControlPanelLocalized.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"

+				SubSystem="2"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(OutDir)/$(ProjectName).lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="1"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="2"

+				FavorSizeOrSpeed="2"

+				OmitFramePointers="true"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"

+				StringPooling="true"

+				RuntimeLibrary="0"

+				BufferSecurityCheck="false"

+				EnableFunctionLevelLinking="false"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Release/"

+				ObjectFile=".\Release/"

+				ProgramDataBaseFileName=".\Release/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;if not exist $(OutDir)\ControlPanel.Resources\en.lproj mkdir $(OutDir)\ControlPanel.Resources\en.lproj&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				AdditionalDependencies=""

+				OutputFile="$(OutDir)\ControlPanel.Resources\en.lproj\ControlPanelLocalized.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				ProgramDatabaseFile=""

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(IntDir)/$(ProjectName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources\en.lproj&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources\en.lproj&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                                                                          &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources\en.lproj&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="3"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="2"

+				FavorSizeOrSpeed="2"

+				OmitFramePointers="true"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"

+				StringPooling="true"

+				RuntimeLibrary="0"

+				BufferSecurityCheck="false"

+				EnableFunctionLevelLinking="false"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Release/"

+				ObjectFile=".\Release/"

+				ProgramDataBaseFileName=".\Release/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;if not exist $(OutDir)\ControlPanel.Resources\en.lproj mkdir $(OutDir)\ControlPanel.Resources\en.lproj&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				AdditionalDependencies=""

+				OutputFile="$(OutDir)\ControlPanel.Resources\en.lproj\ControlPanelLocalized.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				ProgramDatabaseFile=""

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(IntDir)/$(ProjectName).lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources\en.lproj&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources\en.lproj&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                                                                          &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources\en.lproj&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc"

+			>

+			<File

+				RelativePath="resource_loc_res.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"

+			>

+			<File

+				RelativePath="ControlPanelLocRes.rc"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+		<Global

+			Name="RESOURCE_FILE"

+			Value="ControlPanelLocRes.rc"

+		/>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/ControlPanel/ControlPanelRes.rc b/mDNSWindows/ControlPanel/ControlPanelRes.rc
new file mode 100755
index 0000000..b74c59b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelRes.rc
@@ -0,0 +1,134 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+#include "WinVersRes.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"

+    "#include ""WinVersRes.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"

+    "LANGUAGE 9, 1\r\n"

+    "#pragma code_page(1252)\r\n"

+    "#include ""afxres.rc""     // Standard components\r\n"

+    "#endif\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x2L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "Bonjour Resource Module"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "InternalName", "ControlPanelResources.dll"

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "OriginalFilename", "ControlPanelResources.dll"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Icon

+//

+

+// Icon with lowest ID value placed first to ensure application icon

+// remains consistent on all systems.

+IDR_APPLET              ICON                    "res\\controlpanel.ico"

+IDI_FAILURE             ICON                    "res\\failure.ico"

+IDI_SUCCESS             ICON                    "res\\success.ico"

+IDI_ENERGY_SAVER	ICON			"res\\EnergySaver.ico"

+#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)

+LANGUAGE 9, 1

+#pragma code_page(1252)

+#include "afxres.rc"     // Standard components

+#endif

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/mDNSWindows/ControlPanel/ControlPanelRes.vcproj b/mDNSWindows/ControlPanel/ControlPanelRes.vcproj
new file mode 100755
index 0000000..3e36161
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ControlPanelRes.vcproj
@@ -0,0 +1,518 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="ControlPanelRes"

+	ProjectGUID="{5254AA9C-3D2E-4539-86D9-5EB0F4151215}"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="1"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"

+				StringPooling="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Debug/"

+				ObjectFile=".\Debug/"

+				ProgramDataBaseFileName=".\Debug/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				OutputFile="$(OutDir)\ControlPanel.Resources\ControlPanelResources.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"

+				SubSystem="2"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(OutDir)/$(ProjectName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="3"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".."

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1;ENABLE_DOT_LOCAL_NAMES;WINVER=0x0400"

+				StringPooling="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Debug/"

+				ObjectFile=".\Debug/"

+				ProgramDataBaseFileName=".\Debug/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				OutputFile="$(OutDir)\ControlPanel.Resources\ControlPanelResources.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"

+				SubSystem="2"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(OutDir)/$(ProjectName).lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="1"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="2"

+				FavorSizeOrSpeed="2"

+				OmitFramePointers="true"

+				AdditionalIncludeDirectories="..\..\mDNSShared;.."

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"

+				StringPooling="true"

+				RuntimeLibrary="0"

+				BufferSecurityCheck="false"

+				EnableFunctionLevelLinking="false"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Release/"

+				ObjectFile=".\Release/"

+				ProgramDataBaseFileName=".\Release/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				OutputFile="$(OutDir)\ControlPanel.Resources\ControlPanelResources.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				ProgramDatabaseFile=""

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(IntDir)/$(ProjectName).lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                                                            &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			UseOfMFC="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="true"

+				SuppressStartupBanner="true"

+				TargetEnvironment="3"

+				TypeLibraryName="$(OutDir)/$(ProjectName).tlb"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				InlineFunctionExpansion="2"

+				FavorSizeOrSpeed="2"

+				OmitFramePointers="true"

+				AdditionalIncludeDirectories="..\..\mDNSShared;.."

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WINVER=0x0400"

+				StringPooling="true"

+				RuntimeLibrary="0"

+				BufferSecurityCheck="false"

+				EnableFunctionLevelLinking="false"

+				ForceConformanceInForLoopScope="true"

+				UsePrecompiledHeader="0"

+				PrecompiledHeaderFile=""

+				AssemblerListingLocation=".\Release/"

+				ObjectFile=".\Release/"

+				ProgramDataBaseFileName=".\Release/"

+				BrowseInformation="1"

+				WarningLevel="4"

+				WarnAsError="false"

+				SuppressStartupBanner="true"

+				Detect64BitPortabilityProblems="true"

+				CompileAs="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories=".."

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+				Description="Building Output Directories"

+				CommandLine="if not exist $(OutDir)\ControlPanel.Resources mkdir $(OutDir)\ControlPanel.Resources&#x0D;&#x0A;"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089 "

+				OutputFile="$(OutDir)\ControlPanel.Resources\ControlPanelResources.dll"

+				LinkIncremental="1"

+				SuppressStartupBanner="true"

+				IgnoreDefaultLibraryNames=""

+				ModuleDefinitionFile=""

+				ProgramDatabaseFile=""

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				ResourceOnlyDLL="true"

+				ImportLibrary="$(IntDir)/$(ProjectName).lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                                                            &quot;$(DSTROOT)\Program Files\Bonjour SDK\bin\$(PlatformName)\ControlPanel.Resources&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc"

+			>

+			<File

+				RelativePath="resource_res.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"

+			>

+			<File

+				RelativePath="res\about.bmp"

+				>

+			</File>

+			<File

+				RelativePath=".\about.bmp"

+				>

+			</File>

+			<File

+				RelativePath="res\button-2k.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\button-xp.ico"

+				>

+			</File>

+			<File

+				RelativePath=".\res\cold.ico"

+				>

+			</File>

+			<File

+				RelativePath="ControlPanelRes.rc"

+				>

+			</File>

+			<File

+				RelativePath=".\hot.ico"

+				>

+			</File>

+			<File

+				RelativePath="res\logo.bmp"

+				>

+			</File>

+			<File

+				RelativePath=".\logo.bmp"

+				>

+			</File>

+			<File

+				RelativePath="Web.ico"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+		<Global

+			Name="RESOURCE_FILE"

+			Value="ControlPanelRes.rc"

+		/>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/ControlPanel/FourthPage.cpp b/mDNSWindows/ControlPanel/FourthPage.cpp
new file mode 100755
index 0000000..f748efd
--- /dev/null
+++ b/mDNSWindows/ControlPanel/FourthPage.cpp
@@ -0,0 +1,197 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "FourthPage.h"
+#include "resource.h"
+
+#include "ConfigPropertySheet.h"
+#include "SharedSecret.h"
+
+#include <WinServices.h>
+    
+#define MAX_KEY_LENGTH 255
+
+
+IMPLEMENT_DYNCREATE(CFourthPage, CPropertyPage)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::CFourthPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CFourthPage::CFourthPage()
+:
+	CPropertyPage(CFourthPage::IDD)
+{
+	//{{AFX_DATA_INIT(CFourthPage)
+	//}}AFX_DATA_INIT
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::~CFourthPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CFourthPage::~CFourthPage()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CFourthPage::DoDataExchange(CDataExchange* pDX)
+{
+	CPropertyPage::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CFourthPage)
+	//}}AFX_DATA_MAP
+	DDX_Control(pDX, IDC_POWER_MANAGEMENT, m_checkBox);
+}
+
+BEGIN_MESSAGE_MAP(CFourthPage, CPropertyPage)
+	//{{AFX_MSG_MAP(CFourthPage)
+	//}}AFX_MSG_MAP
+
+	ON_BN_CLICKED(IDC_POWER_MANAGEMENT, &CFourthPage::OnBnClickedPowerManagement)
+
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::SetModified
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CFourthPage::SetModified( BOOL bChanged )
+{
+	m_modified = bChanged;
+
+	CPropertyPage::SetModified( bChanged );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::OnSetActive
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CFourthPage::OnSetActive()
+{
+	CConfigPropertySheet	*	psheet;
+	HKEY						key = NULL;
+	DWORD						dwSize;
+	DWORD						enabled;
+	DWORD						err;
+	BOOL						b = CPropertyPage::OnSetActive();
+
+	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
+	require_quiet( psheet, exit );
+
+	m_checkBox.SetCheck( 0 );
+
+	// Now populate the browse domain box
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	dwSize = sizeof( DWORD );
+	err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+	require_noerr( err, exit );
+
+	m_checkBox.SetCheck( enabled );
+ 
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return b;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::OnOK
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CFourthPage::OnOK()
+{
+	if ( m_modified )
+	{
+		Commit();
+	}
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CFourthPage::Commit()
+{
+	HKEY		key		= NULL;
+	DWORD		enabled;
+	DWORD		err;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	enabled = m_checkBox.GetCheck();
+	err = RegSetValueEx( key, L"Enabled", NULL, REG_DWORD, (LPBYTE) &enabled, sizeof( enabled ) );
+	require_noerr( err, exit );
+	
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage::OnBnClickedRemoveBrowseDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+
+
+void CFourthPage::OnBnClickedPowerManagement()
+
+{
+
+	char buf[ 256 ];
+
+
+
+	sprintf( buf, "check box: %d", m_checkBox.GetCheck() );
+
+	OutputDebugStringA( buf );
+
+	// TODO: Add your control notification handler code here
+
+
+
+	SetModified( TRUE );
+
+}
+
diff --git a/mDNSWindows/ControlPanel/FourthPage.h b/mDNSWindows/ControlPanel/FourthPage.h
new file mode 100755
index 0000000..d595291
--- /dev/null
+++ b/mDNSWindows/ControlPanel/FourthPage.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+#include <list>
+#include "afxcmn.h"
+
+#include "afxwin.h"
+
+
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CFourthPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CFourthPage : public CPropertyPage
+{
+public:
+	CFourthPage();
+	~CFourthPage();
+
+protected:
+
+	//{{AFX_DATA(CFourthPage)
+	enum { IDD = IDR_APPLET_PAGE4 };
+	//}}AFX_DATA
+
+	//{{AFX_VIRTUAL(CFourthPage)
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+	//}}AFX_VIRTUAL
+
+	DECLARE_DYNCREATE(CFourthPage)
+
+	//{{AFX_MSG(CFourthPage)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+	
+private:
+	
+	typedef std::list<CString> StringList;
+
+	afx_msg BOOL
+	OnSetActive();
+	
+	afx_msg void
+	OnOK();
+	
+	void
+	SetModified( BOOL bChanged = TRUE );
+	
+	void
+	Commit();
+
+	BOOL			m_modified;
+
+public:
+private:
+
+	CButton m_checkBox;
+
+public:
+
+
+	afx_msg void OnBnClickedPowerManagement();
+
+};
diff --git a/mDNSWindows/ControlPanel/RegistrationPage.cpp b/mDNSWindows/ControlPanel/RegistrationPage.cpp
new file mode 100755
index 0000000..9328a75
--- /dev/null
+++ b/mDNSWindows/ControlPanel/RegistrationPage.cpp
@@ -0,0 +1,387 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Secret.h>
+#include "RegistrationPage.h"
+#include "resource.h"
+
+#include "ConfigPropertySheet.h"
+extern "C"
+{
+#include <ClientCommon.h>
+}
+#include <WinServices.h>
+
+#define MAX_KEY_LENGTH 255
+
+
+IMPLEMENT_DYNCREATE(CRegistrationPage, CPropertyPage)
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::CRegistrationPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CRegistrationPage::CRegistrationPage()
+:
+	CPropertyPage(CRegistrationPage::IDD),
+	m_ignoreChanges( false ),
+	m_hostnameSetupKey( NULL ),
+	m_registrationSetupKey( NULL ),
+	m_statusKey( NULL )
+{
+	//{{AFX_DATA_INIT(CRegistrationPage)
+	//}}AFX_DATA_INIT
+
+	OSStatus err;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\Hostnames", 0,
+	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_hostnameSetupKey, NULL );
+	check_noerr( err );
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, 0,
+	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_registrationSetupKey, NULL );
+	check_noerr( err );
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\State\\Hostnames", 0,
+	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_statusKey, NULL );
+	check_noerr( err );
+
+	
+}
+
+CRegistrationPage::~CRegistrationPage()
+{
+	if ( m_hostnameSetupKey )
+	{
+		RegCloseKey( m_hostnameSetupKey );
+		m_hostnameSetupKey = NULL;
+	}
+
+	if ( m_registrationSetupKey )
+	{
+		RegCloseKey( m_registrationSetupKey );
+		m_registrationSetupKey = NULL;
+	}
+
+	if ( m_statusKey )
+	{
+		RegCloseKey( m_statusKey );
+		m_statusKey = NULL;
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CRegistrationPage::DoDataExchange(CDataExchange* pDX)
+{
+	CPropertyPage::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CRegistrationPage)
+	//}}AFX_DATA_MAP
+	DDX_Control(pDX, IDC_HOSTNAME, m_hostnameControl);
+	DDX_Control(pDX, IDC_USERNAME, m_usernameControl);
+	DDX_Control(pDX, IDC_PASSWORD, m_passwordControl);
+	DDX_Control(pDX, IDC_ADVERTISE_SERVICES, m_advertiseServices);
+}
+
+BEGIN_MESSAGE_MAP(CRegistrationPage, CPropertyPage)
+	//{{AFX_MSG_MAP(CRegistrationPage)
+	//}}AFX_MSG_MAP
+	ON_EN_CHANGE(IDC_HOSTNAME, OnEnChangeHostname)
+	ON_EN_CHANGE(IDC_USERNAME, OnEnChangeUsername)
+	ON_EN_CHANGE(IDC_PASSWORD, OnEnChangePassword)
+	ON_BN_CLICKED(IDC_ADVERTISE_SERVICES, OnBnClickedAdvertiseServices)
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::OnEnChangedHostname
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CRegistrationPage::OnEnChangeHostname()
+{
+	if ( !m_ignoreChanges )
+	{
+		SetModified( TRUE );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::OnEnChangedUsername
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CRegistrationPage::OnEnChangeUsername()
+{
+	if ( !m_ignoreChanges )
+	{
+		SetModified( TRUE );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::OnEnChangedPassword
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CRegistrationPage::OnEnChangePassword()
+{
+	if ( !m_ignoreChanges )
+	{
+		SetModified( TRUE );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::OnBnClickedAdvertiseServices
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CRegistrationPage::OnBnClickedAdvertiseServices()
+{
+	if ( !m_ignoreChanges )
+	{
+		SetModified( TRUE );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::SetModified
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CRegistrationPage::SetModified( BOOL bChanged )
+{
+	m_modified = bChanged ? true : false;
+
+	CPropertyPage::SetModified( bChanged );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::OnSetActive
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CRegistrationPage::OnSetActive()
+{
+	TCHAR	name[kDNSServiceMaxDomainName + 1];
+	DWORD	nameLen = ( kDNSServiceMaxDomainName + 1 ) * sizeof( TCHAR );
+	DWORD	err;
+
+	BOOL b = CPropertyPage::OnSetActive();
+
+	m_ignoreChanges = true;
+	m_modified = FALSE;
+	
+	if ( m_hostnameSetupKey )
+	{
+		err = RegQueryValueEx( m_hostnameSetupKey, L"", NULL, NULL, (LPBYTE) name, &nameLen );
+
+		if ( !err )
+		{
+			char	hostnameUTF8[ 256 ];
+			char	outDomain[ 256 ];
+			char	outUsername[ 256 ];
+			char	outPassword[ 256 ];
+			CString hostname = name;
+			CString username;
+			CString password;
+
+			m_hostnameControl.SetWindowText( hostname );
+
+			StringObjectToUTF8String( hostname, hostnameUTF8, sizeof( hostnameUTF8 ) );
+
+			if ( LsaGetSecret( hostnameUTF8, outDomain, sizeof( outDomain ) / sizeof( TCHAR ), outUsername, sizeof( outUsername ) / sizeof( TCHAR ), outPassword, sizeof( outPassword ) / sizeof( TCHAR ) ) )
+			{
+				username = outUsername;
+				m_usernameControl.SetWindowText( username );
+
+				password = outPassword;
+				m_passwordControl.SetWindowText( password );
+			}
+		}
+	}
+
+	m_advertiseServices.SetCheck( 0 );
+
+	if ( m_registrationSetupKey )
+	{
+		HKEY		subKey = NULL;
+		DWORD		dwSize;
+		DWORD		enabled = 0;
+		TCHAR		subKeyName[MAX_KEY_LENGTH];
+		DWORD		cSubKeys = 0;
+		DWORD		cbMaxSubKey;
+		DWORD		cchMaxClass;
+		OSStatus	err;
+
+		err = RegQueryInfoKey( m_registrationSetupKey, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+		if ( !err )
+		{
+			if ( cSubKeys > 0 )
+			{	
+				dwSize = MAX_KEY_LENGTH;
+	            
+				err = RegEnumKeyEx( m_registrationSetupKey, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+				if ( !err )
+				{
+					err = RegOpenKey( m_registrationSetupKey, subKeyName, &subKey );
+					if ( !err )
+					{
+						dwSize = sizeof( DWORD );
+						err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+						if ( !err && enabled )
+						{
+							m_advertiseServices.SetCheck( enabled );
+						}
+
+						RegCloseKey( subKey );
+						subKey = NULL;
+					}
+				}
+			}
+		}
+	}
+
+	m_ignoreChanges = false;
+
+	return b;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::OnOK
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CRegistrationPage::OnOK()
+{
+	if ( m_modified )
+	{
+		Commit();
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CRegistrationPage::Commit()
+{
+	CString	hostname;
+	char	hostnameUTF8[ 256 ];
+	CString username;
+	char	usernameUTF8[ 256 ];
+	CString password;
+	char	passwordUTF8[ 256 ];
+	DWORD	enabled = 1;
+	BOOL	secret = FALSE;
+	DWORD	err;
+
+	m_hostnameControl.GetWindowText( hostname );
+	hostname.MakeLower();
+	hostname.TrimRight( '.' );
+	StringObjectToUTF8String( hostname, hostnameUTF8, sizeof( hostnameUTF8 ) );
+	
+	m_usernameControl.GetWindowText( username );
+	m_passwordControl.GetWindowText( password );
+	
+	if ( username.GetLength() && password.GetLength() )
+	{
+		StringObjectToUTF8String( username, usernameUTF8, sizeof( usernameUTF8 ) );	
+		StringObjectToUTF8String( password, passwordUTF8, sizeof( passwordUTF8 ) );
+		secret = TRUE;
+	}
+
+	if ( m_hostnameSetupKey != NULL )
+	{
+		err = RegSetValueEx( m_hostnameSetupKey, L"", 0, REG_SZ, (LPBYTE) (LPCTSTR) hostname, ( hostname.GetLength() + 1 ) * sizeof( TCHAR ) );
+		require_noerr( err, exit );
+		
+		err = RegSetValueEx( m_hostnameSetupKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
+		require_noerr( err, exit );
+
+		if ( secret )
+		{
+			LsaSetSecret( hostnameUTF8, usernameUTF8, passwordUTF8 );
+		}
+	}
+
+	if ( m_registrationSetupKey != NULL )
+	{
+		TCHAR		subKeyName[MAX_KEY_LENGTH];
+		DWORD		cSubKeys = 0;
+		DWORD		cbMaxSubKey;
+		DWORD		cchMaxClass;
+		DWORD		dwSize;
+		int			i;
+		OSStatus	err = kNoErr;
+
+		// First, remove all the entries that are there
+
+		err = RegQueryInfoKey( m_registrationSetupKey, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+		if ( !err )
+		{
+			for ( i = 0; i < (int) cSubKeys; i++ )
+			{	
+				dwSize = MAX_KEY_LENGTH;
+		            
+				err = RegEnumKeyEx( m_registrationSetupKey, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+				require_noerr( err, exit );
+					
+				err = RegDeleteKey( m_registrationSetupKey, subKeyName );
+				require_noerr( err, exit );
+			}
+		}
+
+		if ( m_advertiseServices.GetCheck() )
+		{
+			const char	* domainUTF8;
+			CString		  domain;
+			char		  label[ 64 ];
+			HKEY		  subKey = NULL;
+
+			domainUTF8	= GetNextLabel( hostnameUTF8, label );
+			domain		= domainUTF8;
+
+			err = RegCreateKeyEx( m_registrationSetupKey, domain, 0,
+									 NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &subKey, NULL );
+			if ( !err )
+			{
+				err = RegSetValueEx( subKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
+				check_noerr( err );
+
+				RegCloseKey( subKey );
+				subKey = NULL;
+			}
+
+			if ( secret )
+			{
+				LsaSetSecret( domainUTF8, usernameUTF8, passwordUTF8 );
+			}
+		}
+	}
+
+exit:
+
+	return;
+}
diff --git a/mDNSWindows/ControlPanel/RegistrationPage.h b/mDNSWindows/ControlPanel/RegistrationPage.h
new file mode 100755
index 0000000..935a418
--- /dev/null
+++ b/mDNSWindows/ControlPanel/RegistrationPage.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+#include <DebugServices.h>
+#include "afxwin.h"
+
+    
+//---------------------------------------------------------------------------------------------------------------------------
+//	CRegistrationPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CRegistrationPage : public CPropertyPage
+{
+public:
+	CRegistrationPage();
+	~CRegistrationPage();
+
+protected:
+	//{{AFX_DATA(CRegistrationPage)
+	enum { IDD = IDR_APPLET_PAGE1 };
+	//}}AFX_DATA
+
+	//{{AFX_VIRTUAL(CRegistrationPage)
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+	//}}AFX_VIRTUAL
+
+	DECLARE_DYNCREATE(CRegistrationPage)
+
+	//{{AFX_MSG(CRegistrationPage)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+
+private:
+
+	afx_msg BOOL	OnSetActive();
+	afx_msg void	OnOK();
+
+	void			SetModified( BOOL bChanged = TRUE );
+	void			Commit();
+
+	CEdit			m_hostnameControl;
+	CEdit			m_usernameControl;
+	CEdit			m_passwordControl;
+	CButton			m_advertiseServices;
+	bool			m_ignoreChanges;
+	bool			m_modified;
+	HKEY			m_hostnameSetupKey;
+	HKEY			m_registrationSetupKey;
+	HKEY			m_statusKey;
+	
+public:
+	
+	afx_msg void OnEnChangeHostname();
+	afx_msg void OnEnChangeUsername();
+	afx_msg void OnEnChangePassword();
+	afx_msg void OnBnClickedAdvertiseServices();
+};
diff --git a/mDNSWindows/ControlPanel/SecondPage.cpp b/mDNSWindows/ControlPanel/SecondPage.cpp
new file mode 100755
index 0000000..d3bc133
--- /dev/null
+++ b/mDNSWindows/ControlPanel/SecondPage.cpp
@@ -0,0 +1,544 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SecondPage.h"
+#include "resource.h"
+
+#include "ConfigPropertySheet.h"
+#include "SharedSecret.h"
+
+#include <WinServices.h>
+    
+#define MAX_KEY_LENGTH 255
+
+IMPLEMENT_DYNCREATE(CSecondPage, CPropertyPage)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::CSecondPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CSecondPage::CSecondPage()
+:
+	CPropertyPage(CSecondPage::IDD),
+	m_setupKey( NULL )
+{
+	//{{AFX_DATA_INIT(CSecondPage)
+	//}}AFX_DATA_INIT
+
+	OSStatus err;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\DynDNS\\Setup\\" kServiceDynDNSRegistrationDomains, 0,
+	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &m_setupKey, NULL );
+	check_noerr( err );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::~CSecondPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CSecondPage::~CSecondPage()
+{
+	if ( m_setupKey )
+	{
+		RegCloseKey( m_setupKey );
+		m_setupKey = NULL;
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSecondPage::DoDataExchange(CDataExchange* pDX)
+{
+	CPropertyPage::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CSecondPage)
+	//}}AFX_DATA_MAP
+	DDX_Control(pDX, IDC_CHECK1, m_advertiseServicesButton);
+	DDX_Control(pDX, IDC_BUTTON1, m_sharedSecretButton);
+	DDX_Control(pDX, IDC_COMBO2, m_regDomainsBox);
+}
+
+BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
+	//{{AFX_MSG_MAP(CSecondPage)
+	//}}AFX_MSG_MAP
+	ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedSharedSecret)
+	ON_BN_CLICKED(IDC_CHECK1, OnBnClickedAdvertise)
+	ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelChange)
+	ON_CBN_EDITCHANGE(IDC_COMBO1, OnCbnEditChange)
+	ON_CBN_EDITCHANGE(IDC_COMBO2, OnCbnEditChange)
+	ON_CBN_SELCHANGE(IDC_COMBO2, OnCbnSelChange)
+	
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::SetModified
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSecondPage::SetModified( BOOL bChanged )
+{
+	m_modified = bChanged;
+
+	CPropertyPage::SetModified( bChanged );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnSetActive
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CSecondPage::OnSetActive()
+{
+	CConfigPropertySheet	*	psheet;
+	DWORD						err;
+	BOOL						b = CPropertyPage::OnSetActive();
+
+	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
+	require_quiet( psheet, exit );
+	
+	m_modified = FALSE;
+
+	// Clear out what's there
+
+	EmptyComboBox( m_regDomainsBox );
+
+	// Now populate the registration domain box
+
+	err = Populate( m_regDomainsBox, m_setupKey, psheet->m_regDomains );
+	check_noerr( err );
+
+exit:
+
+	return b;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnOK
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSecondPage::OnOK()
+{
+	if ( m_modified )
+	{
+		Commit();
+	}
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSecondPage::Commit()
+{
+	DWORD err;
+
+	if ( m_setupKey != NULL )
+	{
+		err = Commit( m_regDomainsBox, m_setupKey, m_advertiseServicesButton.GetCheck() == BST_CHECKED );
+		check_noerr( err );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CSecondPage::Commit( CComboBox & box, HKEY key, DWORD enabled )
+{
+	CString		selected;
+	HKEY		subKey	= NULL;
+	TCHAR		subKeyName[MAX_KEY_LENGTH];
+	DWORD		cSubKeys = 0;
+	DWORD		cbMaxSubKey;
+	DWORD		cchMaxClass;
+	DWORD		dwSize;
+	int			i;
+	OSStatus	err = kNoErr;
+
+	// First, remove all the entries that are there
+
+    err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+	require_noerr( err, exit );
+
+	for ( i = 0; i < (int) cSubKeys; i++ )
+	{	
+		dwSize = MAX_KEY_LENGTH;
+            
+		err = RegEnumKeyEx( key, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+		require_noerr( err, exit );
+			
+		err = RegDeleteKey( key, subKeyName );
+		require_noerr( err, exit );
+	}
+
+	// Get selected text
+	
+	box.GetWindowText( selected );
+	
+	// If we haven't seen this string before, add the string to the box and
+	// the registry
+	
+	if ( ( selected.GetLength() > 0 ) && ( box.FindStringExact( -1, selected ) == CB_ERR ) )
+	{
+		CString string;
+
+		box.AddString( selected );
+
+		err = RegQueryString( key, L"UserDefined", string );
+		check_noerr( err );
+
+		if ( string.GetLength() )
+		{
+			string += L"," + selected;
+		}
+		else
+		{
+			string = selected;
+		}
+
+		err = RegSetValueEx( key, L"UserDefined", 0, REG_SZ, (LPBYTE) (LPCTSTR) string, ( string.GetLength() + 1) * sizeof( TCHAR ) );
+		check_noerr ( err );
+	}
+
+	// Save selected text in registry.  This will trigger mDNSResponder to setup
+	// DynDNS config again
+
+	err = RegCreateKeyEx( key, selected, 0,
+	                      NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &subKey, NULL );
+	require_noerr( err, exit );
+
+	err = RegSetValueEx( subKey, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
+	check_noerr( err );
+
+exit:
+
+	if ( subKey )
+	{
+		RegCloseKey( subKey );
+		subKey = NULL;
+	}
+
+	return err;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnBnClickedSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSecondPage::OnBnClickedSharedSecret()
+{
+	CString name;
+
+	m_regDomainsBox.GetWindowText( name );
+
+	CSharedSecret dlg;
+
+	dlg.Load( name );
+
+	if ( dlg.DoModal() == IDOK )
+	{
+		DWORD		wakeup = 0;
+		DWORD		dwSize = sizeof( DWORD );
+		OSStatus	err;
+
+		dlg.Commit( name );
+
+		// We have now updated the secret, however the system service
+		// doesn't know about it yet.  So we're going to update the
+		// registry with a dummy value which will cause the system
+		// service to re-initialize it's DynDNS setup
+		//
+
+		RegQueryValueEx( m_setupKey, L"Wakeup", NULL, NULL, (LPBYTE) &wakeup, &dwSize );      
+
+		wakeup++;
+		
+		err = RegSetValueEx( m_setupKey, L"Wakeup", 0, REG_DWORD, (LPBYTE) &wakeup, sizeof( DWORD ) );
+		require_noerr( err, exit );
+	}
+
+exit:
+
+	return;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnBnClickedAdvertise
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSecondPage::OnBnClickedAdvertise()
+{
+	int state;
+
+	state = m_advertiseServicesButton.GetCheck();
+
+	m_regDomainsBox.EnableWindow( state );
+	m_sharedSecretButton.EnableWindow( state );
+
+	SetModified( TRUE );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnCbnSelChange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSecondPage::OnCbnSelChange()
+{
+	SetModified( TRUE );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnCbnEditChange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSecondPage::OnCbnEditChange()
+{
+	SetModified( TRUE );
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnAddRegistrationDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSecondPage::OnAddRegistrationDomain( CString & domain )
+{
+	int index = m_regDomainsBox.FindStringExact( -1, domain );
+
+	if ( index == CB_ERR )
+	{
+		m_regDomainsBox.AddString( domain );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::OnRemoveRegistrationDomain
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSecondPage::OnRemoveRegistrationDomain( CString & domain )
+{
+	int index = m_regDomainsBox.FindStringExact( -1, domain );
+
+	if ( index != CB_ERR )
+	{
+		m_regDomainsBox.DeleteString( index );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::EmptyComboBox
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSecondPage::EmptyComboBox( CComboBox & box )
+{
+	while ( box.GetCount() > 0 )
+	{
+		box.DeleteString( 0 );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::Populate
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CSecondPage::Populate( CComboBox & box, HKEY key, StringList & l )
+{
+	CString		string;
+	HKEY		subKey = NULL;
+	DWORD		dwSize;
+	DWORD		enabled = 0;
+	TCHAR		subKeyName[MAX_KEY_LENGTH];
+	DWORD		cSubKeys = 0;
+	DWORD		cbMaxSubKey;
+	DWORD		cchMaxClass;
+	OSStatus	err;
+
+	err = RegQueryString( key, L"UserDefined", string );
+
+	if ( !err && string.GetLength() )
+	{
+		bool done = false;
+
+		while ( !done )
+		{
+			CString tok;
+
+			tok = string.SpanExcluding( L"," );
+
+			box.AddString( tok );
+
+			if ( tok != string )
+			{
+				// Get rid of that string and comma
+
+				string = string.Right( string.GetLength() - tok.GetLength() - 1 );
+			}
+			else
+			{
+				done = true;
+			}
+		}
+	}
+
+	StringList::iterator it;
+
+	for ( it = l.begin(); it != l.end(); it++ )
+	{
+		if ( box.FindStringExact( -1, *it ) == CB_ERR )
+		{
+			box.AddString( *it );
+		}
+	}
+
+	err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+	require_noerr( err, exit );
+
+	if ( cSubKeys > 0 )
+	{	
+		dwSize = MAX_KEY_LENGTH;
+            
+		err = RegEnumKeyEx( key, 0, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+		require_noerr( err, exit );
+
+		err = RegOpenKey( key, subKeyName, &subKey );
+		require_noerr( err, exit );
+
+		dwSize = sizeof( DWORD );
+		err = RegQueryValueEx( subKey, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+		require_noerr( err, exit );
+
+		// See if it's there
+
+		if ( box.SelectString( -1, subKeyName ) == CB_ERR )
+		{
+			// If not, add it
+
+			box.AddString( subKeyName );
+		}
+
+		box.SelectString( -1, subKeyName );
+
+		RegCloseKey( subKey );
+		subKey = NULL;
+	}
+
+exit:
+
+	m_advertiseServicesButton.SetCheck( ( !err && enabled ) ? BST_CHECKED : BST_UNCHECKED );
+	m_regDomainsBox.EnableWindow( ( !err && enabled ) );
+	m_sharedSecretButton.EnableWindow( (!err && enabled ) );
+
+	return err;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::CreateKey
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CSecondPage::CreateKey( CString & name, DWORD enabled )
+{
+	HKEY		key = NULL;
+	OSStatus	err;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, (LPCTSTR) name, 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	err = RegSetValueEx( key, L"Enabled", 0, REG_DWORD, (LPBYTE) &enabled, sizeof( DWORD ) );
+	check_noerr( err );
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return err;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage::RegQueryString
+//---------------------------------------------------------------------------------------------------------------------------
+
+OSStatus
+CSecondPage::RegQueryString( HKEY key, CString valueName, CString & value )
+{
+	TCHAR	*	string;
+	DWORD		stringLen;
+	int			i;
+	OSStatus	err;
+
+	stringLen	= 1024;
+	string		= NULL;
+	i			= 0;
+
+	do
+	{
+		if ( string )
+		{
+			free( string );
+		}
+
+		string = (TCHAR*) malloc( stringLen );
+		require_action( string, exit, err = kUnknownErr );
+		*string = '\0';
+
+		err = RegQueryValueEx( key, valueName, 0, NULL, (LPBYTE) string, &stringLen );
+
+		i++;
+	}
+	while ( ( err == ERROR_MORE_DATA ) && ( i < 100 ) );
+
+	value = string;
+
+exit:
+
+	if ( string )
+	{
+		free( string );
+	}
+
+	return err;
+}
diff --git a/mDNSWindows/ControlPanel/SecondPage.h b/mDNSWindows/ControlPanel/SecondPage.h
new file mode 100755
index 0000000..3bd9e74
--- /dev/null
+++ b/mDNSWindows/ControlPanel/SecondPage.h
@@ -0,0 +1,107 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+#include <list>
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSecondPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CSecondPage : public CPropertyPage
+{
+public:
+	CSecondPage();
+	~CSecondPage();
+
+protected:
+
+	//{{AFX_DATA(CSecondPage)
+	enum { IDD = IDR_APPLET_PAGE2 };
+	//}}AFX_DATA
+
+	//{{AFX_VIRTUAL(CSecondPage)
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+	//}}AFX_VIRTUAL
+
+	DECLARE_DYNCREATE(CSecondPage)
+
+	//{{AFX_MSG(CSecondPage)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+public:
+	
+	afx_msg void	OnBnClickedSharedSecret();
+	afx_msg void	OnBnClickedAdvertise();
+
+	void			OnAddRegistrationDomain( CString & domain );
+	void			OnRemoveRegistrationDomain( CString & domain );
+	
+private:
+	
+	typedef std::list<CString> StringList;
+
+	afx_msg BOOL
+	OnSetActive();
+	
+	afx_msg void
+	OnOK();
+
+	void
+	EmptyComboBox
+			(
+			CComboBox	&	box
+			);
+
+	OSStatus
+	Populate(
+			CComboBox	&	box,
+			HKEY			key,
+			StringList	&	l
+			);
+	
+	void
+	SetModified( BOOL bChanged = TRUE );
+	
+	void
+	Commit();
+
+	OSStatus
+	Commit( CComboBox & box, HKEY key, DWORD enabled );
+
+	OSStatus
+	CreateKey( CString & name, DWORD enabled );
+
+	OSStatus
+	RegQueryString( HKEY key, CString valueName, CString & value );
+
+	CComboBox		m_regDomainsBox;
+	CButton			m_advertiseServicesButton;
+	CButton			m_sharedSecretButton;
+	BOOL			m_modified;
+	HKEY			m_setupKey;
+
+public:
+	afx_msg void OnCbnSelChange();
+	afx_msg void OnCbnEditChange();
+}; 
diff --git a/mDNSWindows/ControlPanel/ServicesPage.cpp b/mDNSWindows/ControlPanel/ServicesPage.cpp
new file mode 100755
index 0000000..e087157
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ServicesPage.cpp
@@ -0,0 +1,273 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ServicesPage.h"
+#include "resource.h"
+
+#include "ControlPanelExe.h"
+#include "ConfigPropertySheet.h"
+
+#include <WinServices.h>
+    
+#define MAX_KEY_LENGTH 255
+
+
+IMPLEMENT_DYNCREATE(CServicesPage, CPropertyPage)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::CServicesPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CServicesPage::CServicesPage()
+:
+	CPropertyPage(CServicesPage::IDD)
+{
+	//{{AFX_DATA_INIT(CServicesPage)
+	//}}AFX_DATA_INIT
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::~CServicesPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+CServicesPage::~CServicesPage()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CServicesPage::DoDataExchange(CDataExchange* pDX)
+{
+	CPropertyPage::DoDataExchange(pDX);
+	//{{AFX_DATA_MAP(CServicesPage)
+	//}}AFX_DATA_MAP
+	DDX_Control(pDX, IDC_ADVERTISE_SMB, m_SMBCheckBox);
+	DDX_Control(pDX, IDC_POWER_MANAGEMENT, m_powerManagementCheckBox);
+}
+
+BEGIN_MESSAGE_MAP(CServicesPage, CPropertyPage)
+	//{{AFX_MSG_MAP(CServicesPage)
+	//}}AFX_MSG_MAP
+
+	ON_BN_CLICKED(IDC_ADVERTISE_SMB, &CServicesPage::OnBnClickedAdvertiseSMB)
+	ON_BN_CLICKED(IDC_POWER_MANAGEMENT, &CServicesPage::OnBnClickedPowerManagement)
+
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::SetModified
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CServicesPage::SetModified( BOOL bChanged )
+{
+	m_modified = bChanged;
+
+	CPropertyPage::SetModified( bChanged );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::OnSetActive
+//---------------------------------------------------------------------------------------------------------------------------
+
+BOOL
+CServicesPage::OnSetActive()
+{
+	CConfigPropertySheet	*	psheet;
+	HKEY						key = NULL;
+	DWORD						dwSize;
+	DWORD						enabled;
+	DWORD						err;
+	BOOL						b = CPropertyPage::OnSetActive();
+
+	psheet = reinterpret_cast<CConfigPropertySheet*>(GetParent());
+	require_quiet( psheet, exit );
+
+	m_SMBCheckBox.SetCheck( 0 );
+
+	// Now populate the browse domain box
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Services\\SMB", 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	dwSize = sizeof( DWORD );
+	err = RegQueryValueEx( key, L"Advertise", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+	require_noerr( err, exit );
+
+	m_SMBCheckBox.SetCheck( enabled );
+
+	RegCloseKey( key );
+	key = NULL;
+
+	m_powerManagementCheckBox.SetCheck( 0 );
+
+	// Now populate the browse domain box
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	dwSize = sizeof( DWORD );
+	err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+	require_noerr( err, exit );
+
+	m_powerManagementCheckBox.SetCheck( enabled );
+ 
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return b;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::OnOK
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CServicesPage::OnOK()
+{
+	if ( m_modified )
+	{
+		Commit();
+	}
+}
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CServicesPage::Commit()
+{
+	HKEY		key		= NULL;
+	DWORD		enabled;
+	DWORD		err;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Services\\SMB", 0,
+	                   	NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	enabled = m_SMBCheckBox.GetCheck();
+	err = RegSetValueEx( key, L"Advertise", NULL, REG_DWORD, (LPBYTE) &enabled, sizeof( enabled ) );
+	require_noerr( err, exit );
+
+	RegCloseKey( key );
+	key = NULL;
+
+	err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", 0,
+		                  NULL, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE|KEY_WOW64_32KEY, NULL, &key, NULL );
+	require_noerr( err, exit );
+
+	enabled = m_powerManagementCheckBox.GetCheck();
+	err = RegSetValueEx( key, L"Enabled", NULL, REG_DWORD, (LPBYTE) &enabled, sizeof( enabled ) );
+	require_noerr( err, exit );
+	
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::OnBnClickedAdvertiseSMB
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CServicesPage::OnBnClickedAdvertiseSMB()
+{
+	SetModified( TRUE );
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage::OnBnClickedPowerManagement
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CServicesPage::OnBnClickedPowerManagement()
+{
+	SetModified( TRUE );
+
+	if ( m_powerManagementCheckBox.GetCheck() )
+	{
+		CPowerManagementWarning dlg( GetParent() );
+
+		dlg.DoModal();
+	}
+}
+
+
+// CPowerManagementWarning dialog
+
+IMPLEMENT_DYNAMIC(CPowerManagementWarning, CDialog)
+CPowerManagementWarning::CPowerManagementWarning(CWnd* pParent /*=NULL*/)
+	: CDialog(CPowerManagementWarning::IDD, pParent)
+{
+}
+
+CPowerManagementWarning::~CPowerManagementWarning()
+{
+}
+
+void CPowerManagementWarning::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_ENERGY_SAVER, m_energySaverIcon);
+}
+
+
+BOOL
+CPowerManagementWarning::OnInitDialog()
+{	
+	BOOL b = CDialog::OnInitDialog();
+
+	const HICON hIcon = ( HICON ) ::LoadImage( GetNonLocalizedResources(), MAKEINTRESOURCE( IDI_ENERGY_SAVER ), IMAGE_ICON, 0, 0, 0);
+	
+	if ( hIcon )
+	{
+		m_energySaverIcon.SetIcon( hIcon );
+	}
+
+	return b;
+}
+
+
+void
+CPowerManagementWarning::OnOK()
+{
+	CDialog::OnOK();
+}
+
+
+BEGIN_MESSAGE_MAP(CPowerManagementWarning, CDialog)
+END_MESSAGE_MAP()
+
diff --git a/mDNSWindows/ControlPanel/ServicesPage.h b/mDNSWindows/ControlPanel/ServicesPage.h
new file mode 100755
index 0000000..d593a72
--- /dev/null
+++ b/mDNSWindows/ControlPanel/ServicesPage.h
@@ -0,0 +1,123 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "stdafx.h"
+#include "resource.h"
+
+#include <DebugServices.h>
+#include <list>
+#include "afxcmn.h"
+
+#include "afxwin.h"
+
+
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CServicesPage
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CServicesPage : public CPropertyPage
+{
+public:
+	CServicesPage();
+	~CServicesPage();
+
+protected:
+
+	//{{AFX_DATA(CServicesPage)
+	enum { IDD = IDR_APPLET_PAGE5 };
+	//}}AFX_DATA
+
+	//{{AFX_VIRTUAL(CServicesPage)
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+	//}}AFX_VIRTUAL
+
+	DECLARE_DYNCREATE(CServicesPage)
+
+	//{{AFX_MSG(CServicesPage)
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+	
+private:
+	
+	typedef std::list<CString> StringList;
+
+	afx_msg BOOL
+	OnSetActive();
+	
+	afx_msg void
+	OnOK();
+	
+	void
+	SetModified( BOOL bChanged = TRUE );
+	
+	void
+	Commit();
+
+	BOOL			m_modified;
+
+public:
+private:
+
+	CButton m_SMBCheckBox;
+	CButton m_powerManagementCheckBox;
+
+public:
+
+
+	afx_msg void OnBnClickedAdvertiseSMB();
+	afx_msg void OnBnClickedPowerManagement();
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CPowerManagementWarning
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CPowerManagementWarning : public CDialog
+{
+	DECLARE_DYNAMIC(CPowerManagementWarning)
+
+public:
+
+	CPowerManagementWarning(CWnd* pParent = NULL);   // standard constructor
+
+	virtual ~CPowerManagementWarning();
+
+// Dialog Data
+
+	enum { IDD = IDR_POWER_MANAGEMENT_WARNING };
+
+protected:
+
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+	virtual BOOL OnInitDialog();
+
+	virtual void OnOK();
+
+	DECLARE_MESSAGE_MAP()
+
+public:
+
+	CStatic m_energySaverIcon;
+};
+
diff --git a/mDNSWindows/ControlPanel/SharedSecret.cpp b/mDNSWindows/ControlPanel/SharedSecret.cpp
new file mode 100644
index 0000000..3d19295
--- /dev/null
+++ b/mDNSWindows/ControlPanel/SharedSecret.cpp
@@ -0,0 +1,115 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+    
+// SharedSecret.cpp : implementation file
+//
+
+
+#include <Secret.h>
+#include "stdafx.h"
+#include "SharedSecret.h"
+#include <WinServices.h>
+
+#include <DebugServices.h>
+
+
+// SharedSecret dialog
+
+IMPLEMENT_DYNAMIC(CSharedSecret, CDialog)
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSharedSecret::CSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+CSharedSecret::CSharedSecret(CWnd* pParent /*=NULL*/)
+	: CDialog(CSharedSecret::IDD, pParent)
+	, m_key(_T(""))
+	, m_secret(_T(""))
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSharedSecret::~CSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+CSharedSecret::~CSharedSecret()
+{
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSharedSecret::DoDataExchange
+//---------------------------------------------------------------------------------------------------------------------------
+
+void CSharedSecret::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	DDX_Text(pDX, IDC_KEY, m_key );
+	DDX_Text(pDX, IDC_SECRET, m_secret );
+}
+
+
+BEGIN_MESSAGE_MAP(CSharedSecret, CDialog)
+END_MESSAGE_MAP()
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSharedSecret::Load
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSharedSecret::Load( CString zone )
+{
+	char	zoneUTF8[ 256 ];
+	char	outDomain[ 256 ];
+	char	outKey[ 256 ];
+	char	outSecret[ 256 ];
+
+	StringObjectToUTF8String( zone, zoneUTF8, sizeof( zoneUTF8 ) );
+
+	if ( LsaGetSecret( zoneUTF8, outDomain, sizeof( outDomain ) / sizeof( TCHAR ), outKey, sizeof( outKey ) / sizeof( TCHAR ), outSecret, sizeof( outSecret ) / sizeof( TCHAR ) ) )
+	{
+		m_key		= outKey;
+		m_secret	= outSecret;
+	}
+	else
+	{
+		m_key = zone;
+	}
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSharedSecret::Commit
+//---------------------------------------------------------------------------------------------------------------------------
+
+void
+CSharedSecret::Commit( CString zone )
+{
+	char	zoneUTF8[ 256 ];
+	char	keyUTF8[ 256 ];
+	char	secretUTF8[ 256 ];
+
+	StringObjectToUTF8String( zone, zoneUTF8, sizeof( zoneUTF8 ) );
+	StringObjectToUTF8String( m_key, keyUTF8, sizeof( keyUTF8 ) );
+	StringObjectToUTF8String( m_secret, secretUTF8, sizeof( secretUTF8 ) );
+
+	LsaSetSecret( zoneUTF8, keyUTF8, secretUTF8 );
+}
diff --git a/mDNSWindows/ControlPanel/SharedSecret.h b/mDNSWindows/ControlPanel/SharedSecret.h
new file mode 100644
index 0000000..be82d8b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/SharedSecret.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+    
+#pragma once
+
+#include "resource.h"
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+//	CSharedSecret
+//---------------------------------------------------------------------------------------------------------------------------
+
+class CSharedSecret : public CDialog
+{
+	DECLARE_DYNAMIC(CSharedSecret)
+
+public:
+	CSharedSecret(CWnd* pParent = NULL);   // standard constructor
+	virtual ~CSharedSecret();
+
+// Dialog Data
+	enum { IDD = IDR_SECRET };
+
+	void
+	Load( CString zone );
+
+	void
+	Commit( CString zone );
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+
+	DECLARE_MESSAGE_MAP()
+
+public:
+
+	CString m_key;
+	CString m_secret;
+};
diff --git a/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest b/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest
new file mode 100644
index 0000000..903b02b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+	<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+	<description>Control Panel applet for configuring Wide-Area Bonjour.</description>
+	<dependency>
+		<dependentAssembly>
+			<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
+		</dependentAssembly>
+	</dependency>
+</assembly>
diff --git a/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest b/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest
new file mode 100644
index 0000000..4879215
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+	<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+	<description>Control Panel applet for configuring Wide-Area Bonjour.</description>
+	<dependency>
+		<dependentAssembly>
+			<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
+		</dependentAssembly>
+	</dependency>
+	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+		<security>
+			<requestedPrivileges>
+				<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+			</requestedPrivileges>
+		</security>
+	</trustInfo>
+</assembly>
diff --git a/mDNSWindows/ControlPanel/res/ControlPanel.manifest b/mDNSWindows/ControlPanel/res/ControlPanel.manifest
new file mode 100644
index 0000000..4879215
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/ControlPanel.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+	<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+	<description>Control Panel applet for configuring Wide-Area Bonjour.</description>
+	<dependency>
+		<dependentAssembly>
+			<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" />
+		</dependentAssembly>
+	</dependency>
+	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+		<security>
+			<requestedPrivileges>
+				<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+			</requestedPrivileges>
+		</security>
+	</trustInfo>
+</assembly>
diff --git a/mDNSWindows/ControlPanel/res/ControlPanel.rc2 b/mDNSWindows/ControlPanel/res/ControlPanel.rc2
new file mode 100755
index 0000000..e3f7422
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/ControlPanel.rc2
@@ -0,0 +1,13 @@
+//

+// CPL_PP.RC2 - resources Microsoft Visual C++ does not edit directly

+//

+

+#ifdef APSTUDIO_INVOKED

+	#error this file is not editable by Microsoft Visual C++

+#endif //APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+// Add manually edited resources here...

+

+/////////////////////////////////////////////////////////////////////////////

diff --git a/mDNSWindows/ControlPanel/res/ControlPanel64.manifest b/mDNSWindows/ControlPanel/res/ControlPanel64.manifest
new file mode 100644
index 0000000..a47a4e2
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/ControlPanel64.manifest
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+	<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+	<description>Control Panel applet for configuring Wide-Area Bonjour.</description>
+	<dependency>
+		<dependentAssembly>
+			<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*" />
+		</dependentAssembly>
+	</dependency>
+	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+		<security>
+			<requestedPrivileges>
+				<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+			</requestedPrivileges>
+		</security>
+	</trustInfo>
+</assembly>
diff --git a/mDNSWindows/ControlPanel/res/EnergySaver.ico b/mDNSWindows/ControlPanel/res/EnergySaver.ico
new file mode 100755
index 0000000..c2b935b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/EnergySaver.ico
Binary files differ
diff --git a/mDNSWindows/ControlPanel/res/controlpanel.ico b/mDNSWindows/ControlPanel/res/controlpanel.ico
new file mode 100755
index 0000000..7ef6ebb
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/controlpanel.ico
Binary files differ
diff --git a/mDNSWindows/ControlPanel/res/failure.ico b/mDNSWindows/ControlPanel/res/failure.ico
new file mode 100755
index 0000000..f0b8f2b
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/failure.ico
Binary files differ
diff --git a/mDNSWindows/ControlPanel/res/success.ico b/mDNSWindows/ControlPanel/res/success.ico
new file mode 100755
index 0000000..9b97584
--- /dev/null
+++ b/mDNSWindows/ControlPanel/res/success.ico
Binary files differ
diff --git a/mDNSWindows/ControlPanel/resource.h b/mDNSWindows/ControlPanel/resource.h
new file mode 100644
index 0000000..fec673f
--- /dev/null
+++ b/mDNSWindows/ControlPanel/resource.h
@@ -0,0 +1,56 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ControlPanel.rc
+//
+#define IDR_APPLET                      131
+#define IDR_APPLET_PAGE1                131
+#define IDS_APPLET_DESCRIPTION          132
+#define IDR_APPLET_PAGE2                132
+#define IDR_SECRET                      133
+#define IDR_APPLET_PAGE3                134
+#define IDR_APPLET_PAGE4                135
+#define IDR_APPLET_PAGE5                136
+#define IDI_FAILURE                     140
+#define IDI_SUCCESS                     141
+#define IDI_ENERGY_SAVER				142
+#define IDR_ADD_BROWSE_DOMAIN           143
+#define IDR_POWER_MANAGEMENT_WARNING	144
+#define IDS_REINSTALL					145
+#define IDS_REINSTALL_CAPTION			146
+#define IDS_APPLET_NAME					147
+#define IDS_APPLET_TOOLTIP				148
+#define IDC_HOSTNAME                    1000
+#define IDC_USERNAME					1001
+#define IDC_PASSWORD					1002
+#define IDC_ADVERTISE_SERVICES			1003
+#define IDC_BUTTON1                     1004
+#define IDC_COMBO1                      1005
+#define IDC_CHECK1                      1006
+#define IDC_COMBO2                      1007
+#define IDC_EDIT2                       1008
+#define IDC_SECRET                      1009
+#define IDC_COMBO3                      1010
+#define IDC_FAILURE                     1011
+#define IDC_SUCCESS                     1012
+#define IDC_SECRET_NAME                 1013
+#define IDC_NAME                        1014
+#define IDC_KEY                         1015
+#define IDC_LIST1                       1016
+#define IDC_BROWSE_LIST                 1017
+#define IDC_BUTTON2                     1018
+#define IDC_REMOVE_BROWSE_DOMAIN        1019
+#define IDC_ADD_BROWSE_DOMAIN           1020
+#define IDC_POWER_MANAGEMENT            1021
+#define IDC_ADVERTISE_SMB	            1022
+#define IDC_ENERGY_SAVER				1023
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        149
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1024
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/mDNSWindows/ControlPanel/stdafx.cpp b/mDNSWindows/ControlPanel/stdafx.cpp
new file mode 100755
index 0000000..e05ec3d
--- /dev/null
+++ b/mDNSWindows/ControlPanel/stdafx.cpp
@@ -0,0 +1,20 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdafx.h"
+
+
diff --git a/mDNSWindows/ControlPanel/stdafx.h b/mDNSWindows/ControlPanel/stdafx.h
new file mode 100755
index 0000000..246752e
--- /dev/null
+++ b/mDNSWindows/ControlPanel/stdafx.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+#endif
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER				// Allow use of features specific to Windows 95 and Windows NT 4 or later.
+#define WINVER 0x0400		// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#ifndef _WIN32_WINNT		// Allow use of features specific to Windows NT 4 or later.
+#define _WIN32_WINNT 0x0400	// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif						
+
+#ifndef _WIN32_WINDOWS		// Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+// Step 3: We want to see one image, but not a tile
+#ifndef _WIN32_IE			// Allow use of features specific to IE 4.0 or later.
+#define _WIN32_IE 0x0500	// Change this to the appropriate value to target IE 5.0 or later.
+#endif
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// some CString constructors will be explicit
+
+// turns off MFC's hiding of some common and often safely ignored warning messages
+#define _AFX_ALL_WARNINGS
+
+#if !defined(_WSPIAPI_COUNTOF)
+#	define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+#endif
+
+#include <afxwin.h>         // MFC core and standard components
+#include <afxext.h>         // MFC extensions
+#include <afxdisp.h>        // MFC Automation classes
+
+#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 <afxdlgs.h>
+
+#include <cpl.h>            // Control Panel Applet functions and defines
+
+#include <afxtempl.h>       // MFC Template support
diff --git a/mDNSWindows/DLL.NET/AssemblyInfo.cpp b/mDNSWindows/DLL.NET/AssemblyInfo.cpp
new file mode 100755
index 0000000..40f0b5d
--- /dev/null
+++ b/mDNSWindows/DLL.NET/AssemblyInfo.cpp
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+#include "stdafx.h"
+#include "WinVersRes.h"
+
+using namespace System;
+using namespace System::Reflection;
+using namespace System::Runtime::CompilerServices;
+using namespace System::Runtime::InteropServices;
+using namespace System::Security::Permissions;
+
+//
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly:AssemblyTitleAttribute("dnssd.NET")];
+[assembly:AssemblyDescriptionAttribute(".NET wrapper for DNS-SD services")];
+[assembly:AssemblyConfigurationAttribute("")];
+[assembly:AssemblyCompanyAttribute("Apple Inc.")];
+[assembly:AssemblyProductAttribute("")];
+[assembly:AssemblyCopyrightAttribute("Apple Inc.")];
+[assembly:AssemblyTrademarkAttribute("")];
+[assembly:AssemblyCultureAttribute("")];		
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the value or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+
+[assembly:AssemblyVersionAttribute(MASTER_PROD_VERS_STR2)];
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly
+// signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name)
+//       utility
+//        When specifying the KeyFile, the location of the KeyFile should be
+//        relative to the project directory.
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly:AssemblyDelaySignAttribute(false)];
+[assembly:AssemblyKeyFileAttribute("dnssd_NET.snk")];
+[assembly:AssemblyKeyNameAttribute("")];
+
+[assembly:ComVisible(false)];
+[assembly:CLSCompliantAttribute(true)];
+[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
diff --git a/mDNSWindows/DLL.NET/PString.h b/mDNSWindows/DLL.NET/PString.h
new file mode 100755
index 0000000..0249c05
--- /dev/null
+++ b/mDNSWindows/DLL.NET/PString.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+#pragma once
+
+using namespace System;
+using namespace System::Text;
+
+namespace Apple
+{
+	__gc class PString
+	{
+	public:
+
+		PString(String* string)
+		{
+			if (string != NULL)
+			{
+				Byte unicodeBytes[] = Encoding::Unicode->GetBytes(string);
+				Byte utf8Bytes[] = Encoding::Convert(Encoding::Unicode, Encoding::UTF8, unicodeBytes);
+				m_p = Marshal::AllocHGlobal(utf8Bytes->Length + 1);
+
+				Byte __pin * p = &utf8Bytes[0];
+				char * hBytes = static_cast<char*>(m_p.ToPointer());
+				memcpy(hBytes, p, utf8Bytes->Length);
+				hBytes[utf8Bytes->Length] = '\0';
+			}
+			else
+			{
+				m_p = NULL;
+			}
+		}
+
+		~PString()
+		{
+			Marshal::FreeHGlobal(m_p);
+		}
+
+		const char*
+		c_str()
+		{
+			if (m_p != NULL)
+			{
+				return static_cast<const char*>(m_p.ToPointer());
+			}
+			else
+			{
+				return NULL;
+			}
+		}
+		
+	protected:
+
+		IntPtr m_p;
+	};
+}
diff --git a/mDNSWindows/DLL.NET/Stdafx.cpp b/mDNSWindows/DLL.NET/Stdafx.cpp
new file mode 100755
index 0000000..ef03e21
--- /dev/null
+++ b/mDNSWindows/DLL.NET/Stdafx.cpp
@@ -0,0 +1,22 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+// stdafx.cpp : source file that includes just the standard includes
+// dotNET.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
diff --git a/mDNSWindows/DLL.NET/Stdafx.h b/mDNSWindows/DLL.NET/Stdafx.h
new file mode 100755
index 0000000..d2e5c1a
--- /dev/null
+++ b/mDNSWindows/DLL.NET/Stdafx.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently,
+// but are changed infrequently
+
+#pragma once
+
+#if !defined(_WSPIAPI_COUNTOF)
+#	define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+#endif
+
+#using <mscorlib.dll>
+#using <System.dll>
+
+struct _DNSServiceRef_t {};
+struct _DNSRecordRef_t {};
+
diff --git a/mDNSWindows/DLL.NET/dnssd_NET.cpp b/mDNSWindows/DLL.NET/dnssd_NET.cpp
new file mode 100755
index 0000000..3e22146
--- /dev/null
+++ b/mDNSWindows/DLL.NET/dnssd_NET.cpp
@@ -0,0 +1,1234 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+// This is the main DLL file.
+
+#include "stdafx.h"
+
+#include "dnssd_NET.h"
+#include "DebugServices.h"
+#include "PString.h"
+
+
+using namespace System::Net::Sockets;
+using namespace System::Diagnostics;
+using namespace Apple;
+using namespace Apple::DNSSD;
+
+
+//===========================================================================================================================
+//	Constants
+//===========================================================================================================================
+
+#define	DEBUG_NAME	"[dnssd.NET] "
+
+//
+// ConvertToString
+//
+static String*
+ConvertToString(const char * utf8String)
+{
+	return __gc new String(utf8String, 0, strlen(utf8String), __gc new UTF8Encoding(true, true));
+}
+
+
+//
+// class ServiceRef
+//
+// ServiceRef serves as the base class for all DNSService operations.
+//
+// It manages the DNSServiceRef, and implements processing the
+// result
+//
+ServiceRef::ServiceRef(Object * callback)
+:
+	m_bDisposed(false),
+	m_callback(callback),
+	m_thread(NULL)
+{
+	m_impl = new ServiceRefImpl(this);
+}
+
+
+ServiceRef::~ServiceRef()
+{
+}
+
+
+//
+// StartThread
+//
+// Starts the main processing thread
+//
+void
+ServiceRef::StartThread()
+{
+	check( m_impl != NULL );
+
+	m_impl->SetupEvents();
+
+	m_thread		=	new Thread(new ThreadStart(this, &Apple::DNSSD::ServiceRef::ProcessingThread));
+	m_thread->Name	=	S"DNSService Thread";
+	m_thread->IsBackground = true;
+	
+	m_thread->Start();
+}
+
+
+//
+// ProcessingThread
+//
+// The Thread class can only invoke methods in MC++ types.  So we
+// make a ProcessingThread method that forwards to the impl
+//
+void
+ServiceRef::ProcessingThread()
+{
+	m_impl->ProcessingThread();
+}
+
+
+//
+// Dispose
+//
+// Calls impl-Dispose().  This ultimately will call DNSServiceRefDeallocate()
+//
+void
+ServiceRef::Dispose()
+{
+	check(m_impl != NULL);
+	check(m_bDisposed == false);
+
+	if (!m_bDisposed)
+	{
+		m_bDisposed = true;
+
+		//
+		// Call Dispose.  This won't call DNSServiceRefDeallocate()
+		// necessarily. It depends on what thread this is being
+		// called in.
+		//
+		m_impl->Dispose();
+		m_impl = NULL;
+
+		m_thread = NULL;
+
+		GC::SuppressFinalize(this);  
+	}
+}
+
+
+//
+// EnumerateDomainsDispatch
+//
+// Dispatch a reply to the delegate.
+//
+void
+ServiceRef::EnumerateDomainsDispatch
+						(
+						ServiceFlags	flags,
+						int				interfaceIndex,
+						ErrorCode		errorCode,
+						String		*	replyDomain
+						)
+{
+	if ((m_callback != NULL) && (m_impl != NULL))
+	{
+		DNSService::EnumerateDomainsReply * OnEnumerateDomainsReply = static_cast<DNSService::EnumerateDomainsReply*>(m_callback);
+		OnEnumerateDomainsReply(this, flags, interfaceIndex, errorCode, replyDomain);
+	}
+}
+
+
+//
+// RegisterDispatch
+//
+// Dispatch a reply to the delegate.
+//
+void
+ServiceRef::RegisterDispatch
+				(
+				ServiceFlags	flags,
+				ErrorCode		errorCode,
+ 				String		*	name,
+				String		*	regtype,
+				String		*	domain
+				)
+{
+	if ((m_callback != NULL) && (m_impl != NULL))
+	{
+		DNSService::RegisterReply * OnRegisterReply = static_cast<DNSService::RegisterReply*>(m_callback);
+		OnRegisterReply(this, flags, errorCode, name, regtype, domain);
+	}
+}
+
+
+//
+// BrowseDispatch
+//
+// Dispatch a reply to the delegate.
+//
+void
+ServiceRef::BrowseDispatch
+			(
+			ServiceFlags	flags,
+			int				interfaceIndex,
+			ErrorCode		errorCode,
+			String		*	serviceName,
+			String		*	regtype,
+			String		*	replyDomain
+			)
+{
+	if ((m_callback != NULL) && (m_impl != NULL))
+	{
+		DNSService::BrowseReply * OnBrowseReply = static_cast<DNSService::BrowseReply*>(m_callback);
+		OnBrowseReply(this, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain);
+	}
+}
+
+
+//
+// ResolveDispatch
+//
+// Dispatch a reply to the delegate.
+//
+void
+ServiceRef::ResolveDispatch
+			(
+			ServiceFlags	flags,
+			int				interfaceIndex,
+			ErrorCode		errorCode,
+			String		*	fullname,
+			String		*	hosttarget,
+			int				port,
+			Byte			txtRecord[]
+			)
+{
+	if ((m_callback != NULL) && (m_impl != NULL))
+	{
+		DNSService::ResolveReply * OnResolveReply = static_cast<DNSService::ResolveReply*>(m_callback);
+		OnResolveReply(this, flags, interfaceIndex, errorCode, fullname, hosttarget, port, txtRecord);
+	}
+}
+
+
+//
+// RegisterRecordDispatch
+//
+// Dispatch a reply to the delegate.
+//
+void
+ServiceRef::RegisterRecordDispatch
+				(
+				ServiceFlags	flags,
+				ErrorCode		errorCode,
+				RecordRef	*	record
+				)
+{
+	if ((m_callback != NULL) && (m_impl != NULL))
+	{
+		DNSService::RegisterRecordReply * OnRegisterRecordReply = static_cast<DNSService::RegisterRecordReply*>(m_callback);
+		OnRegisterRecordReply(this, flags, errorCode, record);
+	}
+}
+
+
+//
+// QueryRecordDispatch
+//
+// Dispatch a reply to the delegate.
+//
+void
+ServiceRef::QueryRecordDispatch
+					(
+					ServiceFlags	flags,
+					int				interfaceIndex,
+					ErrorCode		errorCode,
+					String		*	fullname,
+					int				rrtype,
+					int				rrclass,
+					Byte			rdata[],
+					int				ttl
+					)
+{
+	if ((m_callback != NULL) && (m_impl != NULL))
+	{
+		DNSService::QueryRecordReply * OnQueryRecordReply = static_cast<DNSService::QueryRecordReply*>(m_callback);
+		OnQueryRecordReply(this, flags, interfaceIndex, errorCode, fullname, rrtype, rrclass, rdata, ttl);
+	}
+}
+
+
+//
+// ServiceRefImpl::ServiceRefImpl()
+//
+// Constructs a new ServiceRefImpl.  We save the pointer to our enclosing
+// class in a gcroot handle.  This satisfies the garbage collector as
+// the outer class is a managed type
+//
+ServiceRef::ServiceRefImpl::ServiceRefImpl(ServiceRef * outer)
+:
+	m_socketEvent(NULL),
+	m_stopEvent(NULL),
+	m_disposed(false),
+	m_outer(outer),
+	m_ref(NULL)
+{
+	m_threadId = GetCurrentThreadId();
+}
+
+
+//
+// ServiceRefImpl::~ServiceRefImpl()
+//
+// Deallocate all resources associated with the ServiceRefImpl
+//
+ServiceRef::ServiceRefImpl::~ServiceRefImpl()
+{
+	if (m_socketEvent != NULL)
+	{
+		CloseHandle(m_socketEvent);
+		m_socketEvent = NULL;
+	}
+
+	if (m_stopEvent != NULL)
+	{
+		CloseHandle(m_stopEvent);
+		m_stopEvent = NULL;
+	}
+
+	if (m_ref != NULL)
+	{
+		DNSServiceRefDeallocate(m_ref);
+		m_ref = NULL;
+	}
+}
+
+
+//
+// ServiceRefImpl::SetupEvents()
+//
+// Setup the events necessary to manage multi-threaded dispatch
+// of DNSService Events
+//
+void
+ServiceRef::ServiceRefImpl::SetupEvents()
+{
+	check(m_ref != NULL);
+
+	m_socket		=	(SOCKET) DNSServiceRefSockFD(m_ref);
+	check(m_socket != INVALID_SOCKET);
+
+	m_socketEvent	=	CreateEvent(NULL, 0, 0, NULL);
+
+	if (m_socketEvent == NULL)
+	{
+		throw new DNSServiceException(Unknown);
+	}
+
+	int err = WSAEventSelect(m_socket, m_socketEvent, FD_READ|FD_CLOSE);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(Unknown);
+	}
+
+	m_stopEvent = CreateEvent(NULL, 0, 0, NULL);
+
+	if (m_stopEvent == NULL)
+	{
+		throw new DNSServiceException(Unknown);
+	}
+}
+
+
+//
+// ServiceRefImpl::ProcessingThread()
+//
+// Wait for socket events on the DNSServiceRefSockFD().  Also wait
+// for stop events
+//
+void
+ServiceRef::ServiceRefImpl::ProcessingThread()
+{
+	check( m_socketEvent != NULL );
+	check( m_stopEvent != NULL );
+	check( m_ref != NULL );
+	
+	HANDLE handles[2];
+
+	handles[0] = m_socketEvent;
+	handles[1] = m_stopEvent;
+
+	while (m_disposed == false)
+	{
+		int ret = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+
+		//
+		// it's a socket event
+		//
+		if (ret == WAIT_OBJECT_0)
+		{
+			DNSServiceProcessResult(m_ref);
+		}
+		//
+		// else it's a stop event
+		//
+		else if (ret == WAIT_OBJECT_0 + 1)
+		{
+			break;
+		}
+		else
+		{
+			//
+			// unexpected wait result
+			//
+			dlog( kDebugLevelWarning, DEBUG_NAME "%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__, ret );
+		}
+	}
+
+	delete this;
+}
+
+
+//
+// ServiceRefImpl::Dispose()
+//
+// Calls DNSServiceRefDeallocate()
+//
+void
+ServiceRef::ServiceRefImpl::Dispose()
+{
+	OSStatus	err;
+	BOOL		ok;
+
+	check(m_disposed == false);
+
+	m_disposed = true;
+
+	ok = SetEvent(m_stopEvent);
+	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+exit:
+
+	return;
+}
+
+
+//
+// ServiceRefImpl::EnumerateDomainsCallback()
+//
+// This is the callback from dnssd.dll.  We pass this up to our outer, managed type
+//
+void DNSSD_API
+ServiceRef::ServiceRefImpl::EnumerateDomainsCallback
+											(
+											DNSServiceRef			sdRef,
+											DNSServiceFlags			flags,
+											uint32_t				interfaceIndex,
+											DNSServiceErrorType		errorCode,
+											const char			*	replyDomain,
+											void				*	context
+											)
+{
+	ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
+
+	check( self != NULL );
+	check( self->m_outer != NULL );
+
+	if (self->m_disposed == false)
+	{
+		self->m_outer->EnumerateDomainsDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(replyDomain));
+	}
+}
+
+
+//
+// ServiceRefImpl::RegisterCallback()
+//
+// This is the callback from dnssd.dll.  We pass this up to our outer, managed type
+//
+void DNSSD_API
+ServiceRef::ServiceRefImpl::RegisterCallback
+							(
+							DNSServiceRef			sdRef,
+							DNSServiceFlags			flags,
+							DNSServiceErrorType		errorCode,
+							const char			*	name,
+							const char			*	regtype,
+							const char			*	domain,
+							void				*	context
+							)
+{
+	ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
+
+	check( self != NULL );
+	check( self->m_outer != NULL );
+	
+	if (self->m_disposed == false)
+	{
+		self->m_outer->RegisterDispatch((ServiceFlags) flags, (ErrorCode) errorCode, ConvertToString(name), ConvertToString(regtype), ConvertToString(domain));
+	}
+}
+
+
+//
+// ServiceRefImpl::BrowseCallback()
+//
+// This is the callback from dnssd.dll.  We pass this up to our outer, managed type
+//
+void DNSSD_API
+ServiceRef::ServiceRefImpl::BrowseCallback
+							(
+							DNSServiceRef			sdRef,
+   							DNSServiceFlags			flags,
+							uint32_t				interfaceIndex,
+							DNSServiceErrorType		errorCode,
+							const char			*	serviceName,
+							const char			*	regtype,
+							const char			*	replyDomain,
+							void				*	context
+							)
+{
+	ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
+
+	check( self != NULL );
+	check( self->m_outer != NULL );
+	
+	if (self->m_disposed == false)
+	{
+		self->m_outer->BrowseDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(serviceName), ConvertToString(regtype), ConvertToString(replyDomain));
+	}
+}
+
+
+//
+// ServiceRefImpl::ResolveCallback()
+//
+// This is the callback from dnssd.dll.  We pass this up to our outer, managed type
+//
+void DNSSD_API
+ServiceRef::ServiceRefImpl::ResolveCallback
+							(
+							DNSServiceRef			sdRef,
+							DNSServiceFlags			flags,
+							uint32_t				interfaceIndex,
+							DNSServiceErrorType		errorCode,
+							const char			*	fullname,
+							const char			*	hosttarget,
+							uint16_t				notAnIntPort,
+							uint16_t				txtLen,
+							const char			*	txtRecord,
+							void				*	context
+							)
+{
+	ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
+
+	check( self != NULL );
+	check( self->m_outer != NULL );
+	
+	if (self->m_disposed == false)
+	{
+		Byte txtRecordBytes[];
+
+		txtRecordBytes = NULL;
+
+		if (txtLen > 0)
+		{
+			//
+			// copy raw memory into managed byte array
+			//
+			txtRecordBytes		=	new Byte[txtLen];
+			Byte __pin	*	p	=	&txtRecordBytes[0];
+			memcpy(p, txtRecord, txtLen);
+		}
+
+		self->m_outer->ResolveDispatch((ServiceFlags) flags, interfaceIndex, (ErrorCode) errorCode, ConvertToString(fullname), ConvertToString(hosttarget), ntohs(notAnIntPort), txtRecordBytes);
+	}	
+}
+
+
+//
+// ServiceRefImpl::RegisterRecordCallback()
+//
+// This is the callback from dnssd.dll.  We pass this up to our outer, managed type
+//
+void DNSSD_API
+ServiceRef::ServiceRefImpl::RegisterRecordCallback
+								(
+								DNSServiceRef		sdRef,
+								DNSRecordRef		rrRef,
+								DNSServiceFlags		flags,
+								DNSServiceErrorType	errorCode,
+								void			*	context
+								)
+{
+	ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
+
+	check( self != NULL );
+	check( self->m_outer != NULL );
+	
+	if (self->m_disposed == false)
+	{
+		RecordRef * record = NULL;
+
+		if (errorCode == 0)
+		{
+			record = new RecordRef;
+
+			record->m_impl->m_ref = rrRef;
+		}
+
+		self->m_outer->RegisterRecordDispatch((ServiceFlags) flags, (ErrorCode) errorCode, record);
+	}
+}
+
+
+//
+// ServiceRefImpl::QueryRecordCallback()
+//
+// This is the callback from dnssd.dll.  We pass this up to our outer, managed type
+//
+void DNSSD_API
+ServiceRef::ServiceRefImpl::QueryRecordCallback
+								(
+								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
+								)
+{
+	ServiceRef::ServiceRefImpl * self = static_cast<ServiceRef::ServiceRefImpl*>(context);
+
+	check( self != NULL );
+	check( self->m_outer != NULL );
+	
+	if (self->m_disposed == false)
+	{
+		Byte rdataBytes[];
+
+		if (rdlen)
+		{
+			rdataBytes			=	new Byte[rdlen];
+			Byte __pin * p		=	&rdataBytes[0];
+			memcpy(p, rdata, rdlen);
+		}
+
+		self->m_outer->QueryRecordDispatch((ServiceFlags) flags, (int) interfaceIndex, (ErrorCode) errorCode, ConvertToString(fullname), rrtype, rrclass, rdataBytes, ttl);
+	}
+}
+
+
+/*
+ * EnumerateDomains()
+ *
+ * This maps to DNSServiceEnumerateDomains().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+ServiceRef*
+DNSService::EnumerateDomains
+		(
+		int							flags,
+		int							interfaceIndex,
+		EnumerateDomainsReply	*	callback
+		)
+{
+	ServiceRef * sdRef = new ServiceRef(callback);
+	int			 err;
+
+	err = DNSServiceEnumerateDomains(&sdRef->m_impl->m_ref, flags, interfaceIndex, ServiceRef::ServiceRefImpl::EnumerateDomainsCallback, sdRef->m_impl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	sdRef->StartThread();
+
+	return sdRef;
+}
+
+
+/*
+ * Register()
+ *
+ * This maps to DNSServiceRegister().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+ServiceRef*
+DNSService::Register
+				(
+				int					flags,
+				int					interfaceIndex,
+				String			*	name,
+				String			*	regtype,
+				String			*	domain,
+				String			*	host,
+				int					port,
+				Byte				txtRecord[],
+				RegisterReply	*	callback
+				)
+{
+	ServiceRef	*	sdRef	=	new ServiceRef(callback);
+	PString		*	pName	=	new PString(name);
+	PString		*	pType	=	new PString(regtype);
+	PString		*	pDomain =	new PString(domain);
+	PString		*	pHost	=	new PString(host);
+	int				len		=	0;
+	Byte __pin	*	p		=	NULL;
+	void		*	v		=	NULL;
+
+	if ((txtRecord != NULL) && (txtRecord->Length > 0))
+	{
+		len		= txtRecord->Length;
+		p		= &txtRecord[0];
+		v		= (void*) p;
+	}
+
+	int err = DNSServiceRegister(&sdRef->m_impl->m_ref, flags, interfaceIndex, pName->c_str(), pType->c_str(), pDomain->c_str(), pHost->c_str(), htons(port), len, v, ServiceRef::ServiceRefImpl::RegisterCallback, sdRef->m_impl );
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	sdRef->StartThread();
+
+	return sdRef;
+}
+
+
+/*
+ * AddRecord()
+ *
+ * This maps to DNSServiceAddRecord().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+RecordRef*
+DNSService::AddRecord
+				(
+				ServiceRef	*	sdRef,
+				int				flags,
+				int				rrtype,
+				Byte			rdata[],
+				int				ttl
+				)
+{
+	int				len		=	0;
+	Byte __pin	*	p		=	NULL;
+	void		*	v		=	NULL;
+
+	if ((rdata != NULL) && (rdata->Length > 0))
+	{
+		len = rdata->Length;
+		p	= &rdata[0];
+		v	= (void*) p;
+	}
+
+	RecordRef * record = new RecordRef;
+
+	int err = DNSServiceAddRecord(sdRef->m_impl->m_ref, &record->m_impl->m_ref, flags, rrtype, len, v, ttl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	return record;
+}
+
+
+/*
+ * UpdateRecord()
+ *
+ * This maps to DNSServiceUpdateRecord().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+void
+DNSService::UpdateRecord
+				(
+				ServiceRef	*	sdRef,
+				RecordRef	*	record,
+				int				flags,
+				Byte			rdata[],
+				int				ttl
+				)
+{
+	int				len		=	0;
+	Byte __pin	*	p		=	NULL;
+	void		*	v		=	NULL;
+
+	if ((rdata != NULL) && (rdata->Length > 0))
+	{
+		len	= rdata->Length;
+		p	= &rdata[0];
+		v	= (void*) p;
+	}
+
+	int err = DNSServiceUpdateRecord(sdRef->m_impl->m_ref, record ? record->m_impl->m_ref : NULL, flags, len, v, ttl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+}
+
+
+/*
+ * RemoveRecord()
+ *
+ * This maps to DNSServiceRemoveRecord().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+void
+DNSService::RemoveRecord
+		(
+		ServiceRef	*	sdRef,
+		RecordRef	*	record,
+		int				flags
+		)
+{
+	int err = DNSServiceRemoveRecord(sdRef->m_impl->m_ref, record->m_impl->m_ref, flags);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+}	
+
+
+/*
+ * Browse()
+ *
+ * This maps to DNSServiceBrowse().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+ServiceRef*
+DNSService::Browse
+	(
+	int				flags,
+	int				interfaceIndex,
+	String		*	regtype,
+	String		*	domain,
+	BrowseReply	*	callback
+	)
+{
+	ServiceRef	*	sdRef	= new ServiceRef(callback);
+	PString		*	pType	= new PString(regtype);
+	PString		*	pDomain	= new PString(domain);
+
+	int err = DNSServiceBrowse(&sdRef->m_impl->m_ref, flags, interfaceIndex, pType->c_str(), pDomain->c_str(),(DNSServiceBrowseReply) ServiceRef::ServiceRefImpl::BrowseCallback, sdRef->m_impl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	sdRef->StartThread();
+
+	return sdRef;
+}
+
+
+/*
+ * Resolve()
+ *
+ * This maps to DNSServiceResolve().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+ServiceRef*
+DNSService::Resolve
+	(
+	int					flags,
+	int					interfaceIndex,
+	String			*	name,
+	String			*	regtype,
+	String			*	domain,
+	ResolveReply	*	callback	
+	)
+{
+	ServiceRef	*	sdRef	= new ServiceRef(callback);
+	PString		*	pName	= new PString(name);
+	PString		*	pType	= new PString(regtype);
+	PString		*	pDomain	= new PString(domain);
+
+	int err = DNSServiceResolve(&sdRef->m_impl->m_ref, flags, interfaceIndex, pName->c_str(), pType->c_str(), pDomain->c_str(),(DNSServiceResolveReply) ServiceRef::ServiceRefImpl::ResolveCallback, sdRef->m_impl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	sdRef->StartThread();
+
+	return sdRef;
+}
+
+
+/*
+ * CreateConnection()
+ *
+ * This maps to DNSServiceCreateConnection().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+ServiceRef*
+DNSService::CreateConnection
+			(
+			RegisterRecordReply * callback
+			)
+{
+	ServiceRef * sdRef = new ServiceRef(callback);
+
+	int err = DNSServiceCreateConnection(&sdRef->m_impl->m_ref);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	sdRef->StartThread();
+
+	return sdRef;
+}
+
+
+/*
+ * RegisterRecord()
+ *
+ * This maps to DNSServiceRegisterRecord().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+
+RecordRef*
+DNSService::RegisterRecord
+			(
+			ServiceRef			*	sdRef,
+			ServiceFlags			flags,
+			int						interfaceIndex,
+			String				*	fullname,
+			int						rrtype,
+			int						rrclass,
+			Byte					rdata[],
+			int						ttl
+			)
+{
+	RecordRef	*	record	= new RecordRef;
+	int				len		= 0;
+	Byte __pin	*	p		= NULL;
+	void		*	v		= NULL;
+
+	PString * pFullname = new PString(fullname);
+
+	if ((rdata != NULL) && (rdata->Length > 0))
+	{
+		len		= rdata->Length;
+		p		= &rdata[0];
+		v		= (void*) p;
+	}
+
+	int err = DNSServiceRegisterRecord(sdRef->m_impl->m_ref, &record->m_impl->m_ref, flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, len, v, ttl, (DNSServiceRegisterRecordReply) ServiceRef::ServiceRefImpl::RegisterRecordCallback, sdRef->m_impl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	return record;
+}
+
+/*
+ * QueryRecord()
+ *
+ * This maps to DNSServiceQueryRecord().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+ServiceRef*
+DNSService::QueryRecord
+		(
+		ServiceFlags			flags,
+		int						interfaceIndex,
+		String				*	fullname,
+		int						rrtype,
+		int						rrclass,
+		QueryRecordReply	*	callback
+		)
+{
+	ServiceRef	*	sdRef		= new ServiceRef(callback);
+	PString		*	pFullname	= new PString(fullname);
+
+	int err = DNSServiceQueryRecord(&sdRef->m_impl->m_ref, flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, (DNSServiceQueryRecordReply) ServiceRef::ServiceRefImpl::QueryRecordCallback, sdRef->m_impl);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	sdRef->StartThread();
+
+	return sdRef;
+}
+
+
+/*
+ * ReconfirmRecord()
+ *
+ * This maps to DNSServiceReconfirmRecord().  Returns an
+ * initialized ServiceRef on success, throws an exception
+ * on failure.
+ */
+void
+DNSService::ReconfirmRecord
+		(
+		ServiceFlags	flags,
+		int				interfaceIndex,
+		String		*	fullname,
+		int				rrtype,
+		int				rrclass,
+		Byte			rdata[]
+		)
+{
+	int				len	= 0;
+	Byte __pin	*	p	= NULL;
+	void		*	v	= NULL;
+
+	PString * pFullname = new PString(fullname);
+
+	if ((rdata != NULL) && (rdata->Length > 0))
+	{
+		len	= rdata->Length;
+		p	= &rdata[0];
+		v	= (void*) p;
+	}
+
+	DNSServiceReconfirmRecord(flags, interfaceIndex, pFullname->c_str(), rrtype, rrclass, len, v);
+}
+
+
+void
+TextRecord::SetValue
+		(
+		String	*	key,
+		Byte		value[]            /* may be NULL */
+		)
+{
+	PString			*	pKey = new PString(key);
+	int					len		=	0;
+	Byte __pin		*	p		=	NULL;
+	void			*	v		=	NULL;
+	DNSServiceErrorType	err;
+
+	if (value && (value->Length > 0))
+	{
+		len	=	value->Length;
+		p	=	&value[0];
+		v	=	(void*) p;
+	}
+
+	err = TXTRecordSetValue(&m_impl->m_ref, pKey->c_str(), len, v);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+}
+
+
+void
+TextRecord::RemoveValue
+		(
+		String	*	key
+		)
+{
+	PString			*	pKey = new PString(key);
+	DNSServiceErrorType	err;
+
+	err = TXTRecordRemoveValue(&m_impl->m_ref, pKey->c_str());
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+}
+
+
+int
+TextRecord::GetLength
+		(
+		)
+{
+	return TXTRecordGetLength(&m_impl->m_ref);
+}
+
+
+Byte
+TextRecord::GetBytes
+		(
+		) __gc[]
+{
+	const void	*	noGCBytes = NULL;
+	Byte			gcBytes[] = NULL;		
+
+	noGCBytes		=	TXTRecordGetBytesPtr(&m_impl->m_ref);
+	int			len	=	GetLength();
+
+	if (noGCBytes && len)
+	{
+		gcBytes				=	new Byte[len];
+		Byte __pin	*	p	=	&gcBytes[0];
+		memcpy(p, noGCBytes, len);
+	}
+
+	return gcBytes;
+}
+
+
+bool
+TextRecord::ContainsKey
+		(
+		Byte		txtRecord[],
+		String	*	key
+		)
+{
+	PString		*	pKey	= new PString(key);
+	Byte __pin	*	p		= &txtRecord[0];
+	
+	return (TXTRecordContainsKey(txtRecord->Length, p, pKey->c_str()) > 0) ? true : false;
+}
+
+
+Byte
+TextRecord::GetValueBytes
+		(
+		Byte		txtRecord[],
+		String	*	key
+		) __gc[]
+{
+	uint8_t			valueLen;
+	Byte			ret[]	= NULL;
+	PString		*	pKey	= new PString(key);
+	Byte __pin	*	p1		= &txtRecord[0];
+	const void	*	v;
+
+	v = TXTRecordGetValuePtr(txtRecord->Length, p1, pKey->c_str(), &valueLen);
+
+	if (v != NULL)
+	{
+		ret					= new Byte[valueLen];
+		Byte __pin	*	p2	= &ret[0];
+
+		memcpy(p2, v, valueLen);
+	}
+
+	return ret;
+}
+
+
+int
+TextRecord::GetCount
+		(
+		Byte txtRecord[]
+		)
+{
+	Byte __pin	*	p	= &txtRecord[0];
+
+	return TXTRecordGetCount(txtRecord->Length, p);
+}
+
+
+Byte
+TextRecord::GetItemAtIndex
+		(
+		Byte				txtRecord[],
+		int					index,
+		[Out] String	**	key
+		) __gc[]
+{
+	char				keyBuf[255];
+	uint8_t				keyBufLen = 255;
+	uint8_t				valueLen;
+	void			*	value;
+	Byte				ret[]	= NULL;
+	DNSServiceErrorType	err;
+	Byte __pin		*	p1		= &txtRecord[0];
+	
+
+	err = TXTRecordGetItemAtIndex(txtRecord->Length, p1, index, keyBufLen, keyBuf, &valueLen, (const void**) &value);
+
+	if (err != 0)
+	{
+		throw new DNSServiceException(err);
+	}
+
+	*key = ConvertToString(keyBuf);
+
+	if (valueLen)
+	{
+		ret					= new Byte[valueLen];
+		Byte __pin	*	p2	= &ret[0];
+
+		memcpy(p2, value, valueLen);
+	}
+
+	return ret;
+}
+
+
+//
+// DNSServiceException::DNSServiceException()
+//
+// Constructs an exception with an error code
+//
+DNSServiceException::DNSServiceException
+				(
+				int _err
+				)
+:
+	err(_err)
+{
+}
+
+
+//
+// This version of the constructor is useful for instances in which
+// an inner exception is thrown, caught, and then a new exception
+// is thrown in it's place
+//
+DNSServiceException::DNSServiceException
+				(	
+				String				*	message,
+				System::Exception	*	innerException
+				)
+{
+}
diff --git a/mDNSWindows/DLL.NET/dnssd_NET.h b/mDNSWindows/DLL.NET/dnssd_NET.h
new file mode 100755
index 0000000..3e0196d
--- /dev/null
+++ b/mDNSWindows/DLL.NET/dnssd_NET.h
@@ -0,0 +1,1392 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+ * 
+ * NOTE:
+ * 
+ * These .Net APIs are a work in progress, currently being discussed and refined.
+ * If you plan to build an application based on these APIs, you may wish to
+ * statically link this code into your application, or otherwise distribute
+ * the DLL so that it installs into the same folder as your application
+ * (not into any common system area where it might interfere with other
+ * applications using a future completed version of these APIs).
+ * If you plan to do this, please be sure to inform us by sending email
+ * to bonjour@apple.com to let us know.
+ * You may want to discuss what you're doing on the Bonjour mailing
+ * list to see if others in similar positions have any suggestions for you:
+ * 
+ * <http://lists.apple.com/bonjour-dev/>
+ * 
+ */
+    
+#pragma once
+
+#include <dns_sd.h>
+#include <vcclr.h>
+#include <memory>
+#include <winsock2.h>
+
+using namespace System;
+using namespace System::Net;
+using namespace System::Runtime::InteropServices;
+using namespace System::Threading;
+using namespace System::Collections;
+
+
+namespace Apple
+{
+	namespace DNSSD
+	{
+		public __gc class ServiceRef;
+
+		public __value enum ServiceFlags : int
+		{
+			MoreComing			=	1,
+			/* 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.
+				*/
+
+			Add					=	2,
+			Default				=	4,
+			/* Flags for domain enumeration and browse/query reply callbacks.
+				* "Default" applies only to enumeration and is only valid in
+				* conjuction with "Add".  An enumeration callback with the "Add"
+				* flag NOT set indicates a "Remove", i.e. the domain is no longer
+				* valid.
+				*/
+
+			NoAutoRename		=	8,
+			/* Flag for specifying renaming behavior on name conflict when registering
+				* 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.)
+				*/
+
+			Shared				=	16,
+			Unique				=	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).
+				*/
+
+			BrowseDomains		=	64,
+			RegistrationDomains	=	128,
+			/* Flags for specifying domain enumeration type in DNSServiceEnumerateDomain
+	s.
+				* BrowseDomains enumerates domains recommended for browsing, RegistrationDo
+	mains
+				* enumerates domains recommended for registration.
+				*/
+		};
+
+
+		public __value enum ErrorCode : int
+		{
+			NoError				=	0,
+			Unknown				=	-65537,
+			NoSuchName			=	-65538,
+			NoMemory			=	-65539,
+			BadParam			=	-65540,
+			BadReference		=	-65541,
+			BadState			=	-65542,
+			BadFlags			=	-65543,
+			Unsupported			=	-65544,
+			AlreadyRegistered	=	-65547,
+			NameConflict		=	-65548,
+			Invalid				=	-65549,
+			Incompatible		=	-65551,
+			BadinterfaceIndex	=	-65552
+
+			/*
+				* mDNS Error codes are in the range
+				* FFFE FF00 (-65792) to FFFE FFFF (-65537)
+				*/
+		};
+
+		public __gc class DNSServiceException
+		:
+			public Exception
+		{
+		public:
+
+			DNSServiceException
+				(
+				int err
+				);
+
+			DNSServiceException
+				(	
+				String				*	message,
+				System::Exception	*	innerException
+				);
+
+			int err;
+		};
+
+
+		/*
+		* class RecordRef
+		*
+		* This is a thin MC++ class facade on top of a DNSRecordRef
+		*/
+		public __gc class RecordRef
+		{
+		public:
+
+			RecordRef()
+			{
+				m_impl = new RecordRefImpl;
+				m_impl->m_ref = NULL;
+			}
+
+			~RecordRef()
+			{
+				delete m_impl;
+			}
+
+			__nogc class RecordRefImpl
+			{
+			public:
+
+				DNSRecordRef m_ref;
+			};
+
+			RecordRefImpl * m_impl;
+		};			
+
+
+		/*
+		* class ServiceRef
+		*
+		* This is a thin MC++ class facade on top of a DNSServiceRef
+		*/
+		public __gc class ServiceRef : public IDisposable
+		{
+		public:
+
+			ServiceRef(Object * callback);
+
+			~ServiceRef();
+
+			/*
+			* This does an underlying DNSServiceRefDeallocate().  After
+			* calling Dispose, the ServiceRef is no longer usable.
+			*/
+			void
+			Dispose();
+
+			/*
+			* Internal - Dispatch an EnumerateDomains callback
+			*/
+			void
+			EnumerateDomainsDispatch
+				(
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	replyDomain
+				);
+
+			/*
+			* Internal - Dispatch a Register callback
+			*/
+			void
+			RegisterDispatch
+				(
+				ServiceFlags	flags,
+				ErrorCode		errorCode,
+ 				String		*	name,
+				String		*	regtype,
+				String		*	domain
+				);
+
+			/*
+			* Internal - Dispatch a Browse callback
+			*/
+			void
+			BrowseDispatch
+				(
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	serviceName,
+				String		*	regtype,
+				String		*	replyDomain
+				);
+
+			/*
+			* Internal - Dispatch a Resolve callback
+			*/
+			void
+			ResolveDispatch
+				(
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	fullname,
+				String		*	hosttarget,
+				int				port,
+				Byte			txtRecord[]
+				);
+			
+			/*
+			* Internal - Dispatch a RegisterRecord callback
+			*/
+			void
+			RegisterRecordDispatch
+				(
+				ServiceFlags	flags,
+				ErrorCode		errorCode,
+				RecordRef	*	record
+				);
+
+			/*
+			* Internal - Dispatch a QueryRecord callback
+			*/
+			void
+			QueryRecordDispatch
+				(
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	fullname,
+				int				rrtype,
+				int				rrclass,
+				Byte			rdata[],
+				int				ttl
+				);
+
+			/*
+			* Internal - A non managed class to wrap a DNSServiceRef
+			*/
+			__nogc class ServiceRefImpl
+			{
+			public:
+
+				ServiceRefImpl
+					(
+					ServiceRef * outer
+					);
+
+				~ServiceRefImpl();
+
+				/*
+				* Sets up events for threaded operation
+				*/
+				void
+				SetupEvents();
+
+				/*
+				* Main processing thread
+				*/
+				void
+				ProcessingThread();
+
+				/*
+				* Calls DNSServiceRefDeallocate()
+				*/
+				void
+				Dispose();
+
+				/*
+				* Called from dnssd.dll
+				*/
+				static void DNSSD_API
+				EnumerateDomainsCallback
+					(
+					DNSServiceRef			sdRef,
+					DNSServiceFlags			flags,
+					uint32_t				interfaceIndex,
+					DNSServiceErrorType		errorCode,
+					const char			*	replyDomain,
+					void				*	context
+					);
+
+				static void DNSSD_API
+				RegisterCallback
+					(
+					DNSServiceRef			ref,
+					DNSServiceFlags			flags,
+					DNSServiceErrorType		errorCode,
+ 					const char			*	name,
+					const char			*	regtype,
+					const char			*	domain,
+					void				*	context
+					);
+
+				static void DNSSD_API
+				BrowseCallback
+					(
+					DNSServiceRef			sdRef,
+   					DNSServiceFlags			flags,
+					uint32_t				interfaceIndex,
+					DNSServiceErrorType		errorCode,
+					const char			*	serviceName,
+					const char			*	regtype,
+					const char			*	replyDomain,
+					void				*	context
+					);
+
+				static void DNSSD_API
+				ResolveCallback
+					(
+					DNSServiceRef			sdRef,
+					DNSServiceFlags			flags,
+					uint32_t				interfaceIndex,
+					DNSServiceErrorType		errorCode,
+					const char			*	fullname,
+					const char			*	hosttarget,
+					uint16_t				notAnIntPort,
+					uint16_t				txtLen,
+					const char			*	txtRecord,
+					void				*	context
+					);
+
+				static void DNSSD_API
+				RegisterRecordCallback
+					( 
+					DNSServiceRef		sdRef,
+					DNSRecordRef		RecordRef,
+					DNSServiceFlags		flags,
+					DNSServiceErrorType	errorCode,
+					void			*	context
+					);
+
+				static void DNSSD_API
+				QueryRecordCallback
+					(
+					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
+					);
+
+				SOCKET				m_socket;
+				HANDLE				m_socketEvent;
+				HANDLE				m_stopEvent;
+				DWORD				m_threadId;
+				bool				m_disposed;
+				DNSServiceRef		m_ref;
+				gcroot<ServiceRef*> m_outer;
+			};
+
+			void
+			StartThread();
+
+			void
+			ProcessingThread();
+
+			bool				m_bDisposed;
+			Object			*	m_callback;
+			Thread			*	m_thread;
+			ServiceRefImpl	*	m_impl;
+		};
+			
+		/*********************************************************************************************
+		*
+		*   TXT Record Construction Functions
+		*
+		*********************************************************************************************/
+
+		/*
+		* A typical calling sequence for TXT record construction is something like:
+		*
+		* DNSService.TextRecord tr = new DNSService.TextRecord(1024);
+		* tr.SetValue();
+		* tr.SetValue();
+		* tr.SetValue();
+		* ...
+		* DNSServiceRegister( ... tr.GetLength(), tr.GetBytes() ... );
+		*/
+
+
+		/* TextRecord
+		*
+		* Opaque internal data type.
+		* Note: Represents a DNS-SD TXT record.
+		*/
+
+
+		/* TextRecord::TextRecord()
+		*
+		* Creates a new empty TextRecord .
+		*
+		*/
+
+		public __gc class TextRecord
+		{
+		public:
+
+			TextRecord()
+			{
+				m_impl = new TextRecordImpl();
+				TXTRecordCreate(&m_impl->m_ref, 0, NULL);
+			}
+
+			~TextRecord()
+			{
+				TXTRecordDeallocate(&m_impl->m_ref);
+				delete m_impl;
+			}
+
+			__nogc class TextRecordImpl
+			{
+			public:
+
+				TXTRecordRef m_ref;
+			};
+
+			TextRecordImpl * m_impl;
+
+
+			/* SetValue()
+			*
+			* Adds a key (optionally with value) to a TextRecord. If the "key" already
+			* exists in the TextRecord, 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>
+			*
+			* key:             A null-terminated string which only contains printable ASCII
+			*                  values (0x20-0x7E), excluding '=' (0x3D). Keys should be
+			*                  14 characters or less (not counting the terminating null).
+			*
+			* 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.
+			*
+			* exceptions:      Throws kDNSServiceErr_Invalid if the "key" string contains
+			*                  illegal characters.
+			*                  Throws kDNSServiceErr_NoMemory if adding this key would
+			*                  exceed the available storage.
+			*/
+
+			void
+			SetValue
+				(
+				String	*	key,
+				Byte		value[]  /* may be NULL */
+				);
+
+
+			/* RemoveValue()
+			*
+			* Removes a key from a TextRecord.  The "key" must be an
+			* ASCII string which exists in the TextRecord.
+			*
+			* key:             A key name which exists in the TextRecord.
+			*
+			* exceptions:      Throws kDNSServiceErr_NoSuchKey if the "key" does not
+			*                  exist in the TextRecord.
+			*
+			*/
+
+			void
+			RemoveValue
+				(
+				String	*	key
+				);
+
+
+			/* GetLength()
+			*
+			* Allows you to determine the length of the raw bytes within a TextRecord.
+			*
+			* return value :     Returns the size of the raw bytes inside a TextRecord
+			*                  which you can pass directly to DNSServiceRegister() or
+			*                  to DNSServiceUpdateRecord().
+			*                  Returns 0 if the TextRecord is empty.
+			*
+			*/
+
+			int
+			GetLength
+				(
+				);
+
+
+			/* GetBytes()
+			*
+			* Allows you to retrieve a pointer to the raw bytes within a TextRecord.
+			*
+			* return value:    Returns a pointer to the bytes inside the TextRecord
+			*                  which you can pass directly to DNSServiceRegister() or
+			*                  to DNSServiceUpdateRecord().
+			*
+			*/
+
+			Byte
+			GetBytes
+				(
+				) __gc[];
+
+
+			/*********************************************************************************************
+			*
+			*   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 = DNSService.TextService.GetValue(txtRecord, "key1", &len1);
+			* val2ptr = DNSService.TextService.GetValue(txtRecord, "key2", &len2);
+			* ...
+			* return;
+			*
+			*/
+
+			/* ContainsKey()
+			*
+			* Allows you to determine if a given TXT Record contains a specified key.
+			*
+			* 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.
+			*
+			*/
+
+			static public bool
+			ContainsKey
+				(
+				Byte		txtRecord[],
+				String	*	key
+				);
+
+
+			/* GetValueBytes()
+			*
+			* Allows you to retrieve the value for a given key from a TXT Record.
+			*
+			* txtRecord:       Pointer to the received TXT Record bytes.
+			*
+			* key:             A null-terminated ASCII string containing the key name.
+			*
+			* 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 ContainsKey()).
+			*                  Returns byte array 
+			*                  if the key exists with empty or non-empty value.
+			*                  For empty value, length of byte array will be zero.
+			*                  For non-empty value, it will be the length of value data.
+			*/
+
+			static public Byte
+			GetValueBytes
+				(
+				Byte		txtRecord[],
+				String	*	key
+				) __gc[];
+
+
+			/* GetCount()
+			*
+			* Returns the number of keys stored in the TXT Record.  The count
+			* can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
+			*
+			* txtRecord:       Pointer to the received TXT Record bytes.
+			*
+			* return value:    Returns the total number of keys in the TXT Record.
+			*
+			*/
+
+			static public int
+			GetCount
+				(
+				Byte	txtRecord[]
+				);
+
+
+			/* GetItemAtIndex()
+			*
+			* 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.
+			*
+			* txtRecord:       Pointer to the received TXT Record bytes.
+			*
+			* index:           An index into the TXT Record.
+			*
+			* key:             A string buffer used to store the key name.
+			*                  On return, the buffer contains a string
+			*                  giving the key name. DNS-SD TXT keys are usually
+			*                  14 characters or less. 
+			*
+			* return value:    Record bytes that holds the value data.
+			*
+			* exceptions:      Throws kDNSServiceErr_Invalid if index is greater than
+			*                  GetCount()-1.
+			*/
+
+			static public Byte
+			GetItemAtIndex
+				(
+				Byte				txtRecord[],
+				int					index,
+				[Out] String	**	key
+				) __gc[];
+		};
+
+
+		public __abstract __gc class DNSService
+		{
+		public:
+
+			/*********************************************************************************************
+			*
+			* 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.
+			*
+			*
+			* EnumerateDomainsReply Delegate
+			*
+			* This Delegate is invoked upon a reply from an EnumerateDomains call.
+			*
+			* sdRef:           The DNSServiceRef initialized by DNSServiceEnumerateDomains().
+			*
+			* flags:           Possible values are:
+			*                  MoreComing
+			*                  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 NoError (0) on success, otherwise indicates
+			*                  the failure that occurred (other parameters are undefined if errorCode is nonzero).
+			*
+			* replyDomain:     The name of the domain.
+			*
+			*/
+
+			__delegate void
+			EnumerateDomainsReply
+				(
+				ServiceRef	*	sdRef,
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	replyDomain
+				);
+
+			/* DNSServiceEnumerateDomains() Parameters:
+			*
+			*
+			* flags:           Possible values are:
+			*                  BrowseDomains to enumerate domains recommended for browsing.
+			*                  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 delegate to be called when a domain is found or the call asynchronously
+			*                  fails.
+			*
+			*
+			* return value:    Returns initialize ServiceRef on succeses (any subsequent, asynchronous
+			*                  errors are delivered to the delegate), otherwise throws an exception indicating
+			*                  the error that occurred (the callback is not invoked and the ServiceRef
+			*                  is not initialized.)
+			*/
+
+			static public ServiceRef*
+			EnumerateDomains
+				(
+				int							flags,
+				int							interfaceIndex,
+				EnumerateDomainsReply	*	callback
+				);
+
+			/*********************************************************************************************
+			*
+			*  Service Registration
+			*
+			*********************************************************************************************/
+
+			/* Register a service that is discovered via Browse() and Resolve() calls.
+			* 
+			* RegisterReply() Callback Parameters:
+			*
+			* sdRef:           The ServiceRef initialized by Register().
+			*
+			* flags:           Currently unused, reserved for future use.
+			*
+			* errorCode:       Will be NoError on success, otherwise will
+			*                  indicate the failure that occurred (including name conflicts, if the
+			*                  NoAutoRename 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 Register(), this indicates the default domain
+			*                  on which the service was registered).
+			*
+			*/
+
+			__delegate void
+			RegisterReply
+				(
+				ServiceRef	*	sdRef,
+				ServiceFlags	flags,
+				ErrorCode		errorCode,
+				String		*	name,
+				String		*	regtype,
+				String		*	domain
+				);
+
+			/* Register()  Parameters:
+			*
+			* flags:           Indicates the renaming behavior on name conflict (most applications
+			*                  will pass 0).  See flag definitions above for details.
+			*
+			* 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.)
+			*
+			* 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".
+			*                  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
+			*                  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, in host 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.
+			*
+			* 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 delegate 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().
+			*
+			* return value:    Returns initialize ServiceRef (any subsequent, asynchronous
+			*                  errors are delivered to the callback), otherwise throws an exception indicating
+			*                  the error that occurred (the callback is never invoked and the DNSServiceRef
+			*                  is not initialized.)
+			*
+			*/
+			static public ServiceRef*
+			Register
+				(
+				int					flags,
+				int					interfaceIndex,
+				String			*	name,
+				String			*	regtype,
+				String			*	domain,
+				String			*	host,
+				int					port,
+				Byte				txtRecord[],
+				RegisterReply	*	callback
+				);
+
+			/* AddRecord()
+			*
+			* 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 UpdateRecord() or RemoveRecord().
+			*
+			*
+			* Parameters;
+			*
+			* sdRef:           A ServiceRef initialized by Register().
+			*
+			* RecordRef:       A pointer to an uninitialized RecordRef.  Upon succesfull completion of this
+			*                  call, this ref may be passed to UpdateRecord() or RemoveRecord().
+			*                  If the above ServiceRef is disposed, 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.
+			*
+			* 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 initialized RecordRef, otherwise throws
+			*                  an exception indicating the error that occurred (the RecordRef is not initialized).
+			*/
+
+			static public RecordRef*
+			AddRecord
+				(
+				ServiceRef	*	sref,
+				int				flags,
+				int				rrtype,
+				Byte			rdata[],
+				int				ttl
+				);
+
+			/* UpdateRecord
+			*
+			* Update a registered resource record.  The record must either be:
+			*   - The primary txt record of a service registered via Register()
+			*   - A record added to a registered service via AddRecord()
+			*   - An individual record registered by RegisterRecord()
+			*
+			*
+			* Parameters:
+			*
+			* sdRef:           A ServiceRef that was initialized by Register()
+			*                  or CreateConnection().
+			*
+			* RecordRef:       A RecordRef initialized by AddRecord, or NULL to update the
+			*                  service's primary txt record.
+			*
+			* flags:           Currently ignored, reserved for future use.
+			*
+			* 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:    No return value on success, otherwise throws an exception
+			*                  indicating the error that occurred.
+			*/
+			static public void
+			UpdateRecord
+				(
+				ServiceRef	*	sref,
+				RecordRef	*	record,
+				int				flags,
+				Byte			rdata[],
+				int				ttl
+				);
+
+			/* RemoveRecord
+			*
+			* Remove a record previously added to a service record set via AddRecord(), or deregister
+			* an record registered individually via RegisterRecord().
+			*
+			* Parameters:
+			*
+			* sdRef:           A ServiceRef initialized by Register() (if the
+			*                  record being removed was registered via AddRecord()) or by
+			*                  CreateConnection() (if the record being removed was registered via
+			*                  RegisterRecord()).
+			*
+			* recordRef:       A RecordRef initialized by a successful call to AddRecord()
+			*                  or RegisterRecord().
+			*
+			* flags:           Currently ignored, reserved for future use.
+			*
+			* return value:    Nothing on success, otherwise throws an
+			*                  exception indicating the error that occurred.
+			*/
+
+			static public void
+			RemoveRecord
+							(
+							ServiceRef	*	sref,
+							RecordRef	*	record,	
+							int				flags
+							);
+
+			/*********************************************************************************************
+			*
+			*  Service Discovery
+			*
+			*********************************************************************************************/
+
+			/* Browse for instances of a service.
+			*
+			*
+			* BrowseReply() Parameters:
+			*
+			* sdRef:           The DNSServiceRef initialized by Browse().
+			*
+			* flags:           Possible values are MoreComing and Add.
+			*                  See flag definitions for details.
+			*
+			* interfaceIndex:  The interface on which the service is advertised.  This index should
+			*                  be passed to Resolve() when resolving the service.
+			*
+			* errorCode:       Will be 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 Browse().
+			* 
+			* domain:          The domain on which the service was discovered (if the application did not
+			*                  specify a domain in Browse(), this indicates the domain on which the
+			*                  service was discovered.)
+			*
+			*/
+
+			__delegate void
+			BrowseReply
+				(
+				ServiceRef	*	sdRef,
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	name,
+				String		*	type,
+				String		*	domain
+				);
+
+			/* DNSServiceBrowse() Parameters:
+			*
+			* sdRef:           A pointer to an uninitialized ServiceRef.  Call ServiceRef.Dispose()
+			*                  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 delegate to be called when an instance of the service being browsed for
+			*                  is found, or if the call asynchronously fails.
+			*
+			* return value:    Returns initialized ServiceRef on succeses (any subsequent, asynchronous
+			*                  errors are delivered to the callback), otherwise throws an exception indicating
+			*                  the error that occurred (the callback is not invoked and the ServiceRef
+			*                  is not initialized.)
+			*/
+
+			static public ServiceRef*
+			Browse
+				(
+				int				flags,
+				int				interfaceIndex,
+				String		*	regtype,
+				String		*	domain,
+				BrowseReply	*	callback
+				);
+
+			/* ResolveReply() Parameters:
+			*
+			* Resolve a service name discovered via Browse() to a target host name, port number, and
+			* txt record.
+			*
+			* Note: Applications should NOT use Resolve() solely for txt record monitoring - use
+			* QueryRecord() 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
+			* ServiceRef.Dispose().
+			*
+			* 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, QueryRecord() should be used.
+			*
+			* ResolveReply Callback Parameters:
+			*
+			* sdRef:           The DNSServiceRef initialized by Resolve().
+			*
+			* flags:           Currently unused, reserved for future use.
+			*
+			* interfaceIndex:  The interface on which the service was resolved.
+			*
+			* errorCode:       Will be 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, in host byte order, on which connections are accepted for this service.
+			*
+			* txtRecord:       The service's primary txt record, in standard txt record format.
+			*
+			*/
+
+			__delegate void
+			ResolveReply
+				(	
+				ServiceRef	*	sdRef,  
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,
+				String		*	fullName,
+				String		*	hostName,
+				int				port,
+				Byte			txtRecord[]
+				);
+
+			/* Resolve() Parameters
+			*
+			* 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 delegate to be called when a result is found, or if the call
+			*                  asynchronously fails.
+			*
+			*
+			* return value:    Returns initialized ServiceRef on succeses (any subsequent, asynchronous
+			*                  errors are delivered to the callback), otherwise throws an exception indicating
+			*                  the error that occurred (the callback is never invoked and the DNSServiceRef
+			*                  is not initialized.)
+			*/
+
+			static public ServiceRef*
+			Resolve
+				(
+				int					flags,
+				int					interfaceIndex,
+				String			*	name,
+				String			*	regtype,
+				String			*	domain,
+				ResolveReply	*	callback
+				);
+
+			/*********************************************************************************************
+			*
+			*  Special Purpose Calls (most applications will not use these)
+			*
+			*********************************************************************************************/
+
+			/* CreateConnection/RegisterRecord
+			*
+			* Register an individual resource record on a connected ServiceRef.
+			*
+			* Note that name conflicts occurring for records registered via this call must be handled
+			* by the client in the callback.
+			*
+			*
+			* RecordReply() parameters:
+			*
+			* sdRef:           The connected ServiceRef initialized by
+			*                  CreateConnection().
+			*
+			* RecordRef:       The RecordRef initialized by RegisterRecord().  If the above
+			*                  ServiceRef.Dispose is called, this RecordRef is
+			*                  invalidated, and may not be used further.
+			*
+			* flags:           Currently unused, reserved for future use.
+			*
+			* errorCode:       Will be NoError on success, otherwise will
+			*                  indicate the failure that occurred (including name conflicts.)
+			*                  Other parameters are undefined if errorCode is nonzero.
+			*
+			*/
+
+			__delegate void
+			RegisterRecordReply
+				(
+				ServiceRef	*	sdRef,
+				ServiceFlags	flags,
+				ErrorCode		errorCode,
+				RecordRef	*	record
+				);
+
+			/* CreateConnection()
+			*
+			* Create a connection to the daemon allowing efficient registration of
+			* multiple individual records.
+			*
+			*
+			* Parameters:
+			*
+			* callback:        The delegate to be called when a result is found, or if the call
+			*                  asynchronously fails (e.g. because of a name conflict.)
+			*
+			* return value:    Returns initialize ServiceRef on success, otherwise throws
+			*                  an exception indicating the specific failure that occurred (in which
+			*                  case the ServiceRef is not initialized).
+			*/
+
+			static public ServiceRef*
+			CreateConnection
+				(
+				RegisterRecordReply * callback
+				);
+
+
+			/* RegisterRecord() Parameters:
+			*
+			* sdRef:           A ServiceRef initialized by CreateConnection().
+			*
+			* RecordRef:       A pointer to an uninitialized RecordRef.  Upon succesfull completion of this
+			*                  call, this ref may be passed to UpdateRecord() or RemoveRecord().
+			*                  (To deregister ALL records registered on a single connected ServiceRef
+			*                  and deallocate each of their corresponding RecordRefs, call
+			*                  ServiceRef.Dispose()).
+			*
+			* flags:           Possible values are Shared or 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).
+			*
+			* 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.
+			*
+			*
+			* return value:    Returns initialize RecordRef on succeses (any subsequent, asynchronous
+			*                  errors are delivered to the callback), otherwise throws an exception indicating
+			*                  the error that occurred (the callback is never invoked and the RecordRef is
+			*                  not initialized.)
+			*/
+			static public RecordRef*
+			RegisterRecord
+				(
+				ServiceRef			*	sdRef,
+				ServiceFlags			flags,
+				int						interfaceIndex,
+				String				*	fullname,
+				int						rrtype,
+				int						rrclass,
+				Byte					rdata[],
+				int						ttl
+				);
+
+
+			/* DNSServiceQueryRecord
+			*
+			* Query for an arbitrary DNS record.
+			*
+			*
+			* QueryRecordReply() Delegate Parameters:
+			*
+			* sdRef:           The ServiceRef initialized by QueryRecord().
+			*
+			* flags:           Possible values are MoreComing and
+			*                  Add.  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).
+			*
+			* 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).
+			*
+			* rdata:           The raw rdata of the resource record.
+			*
+			* ttl:             The resource record's time to live, in seconds.
+			*
+			*/
+
+			__delegate void
+			QueryRecordReply
+				(
+				ServiceRef	*	sdRef,
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				ErrorCode		errorCode,	
+				String		*	fullName,
+				int				rrtype,
+				int				rrclass,
+				Byte			rdata[],
+				int				ttl
+				);
+
+			/* QueryRecord() Parameters:
+			*
+			* flags:           Pass LongLivedQuery 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.
+			*
+			* 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 delegate to be called when a result is found, or if the call
+			*                  asynchronously fails.
+			*
+			*
+			* return value:    Returns initialized ServiceRef on succeses (any subsequent, asynchronous
+			*                  errors are delivered to the callback), otherwise throws an exception indicating
+			*                  the error that occurred (the callback is never invoked and the ServiceRef
+			*                  is not initialized.)
+			*/
+
+			static public ServiceRef*
+			QueryRecord
+				(
+				ServiceFlags			flags,
+				int						interfaceIndex,
+				String				*	fullname,
+				int						rrtype,
+				int						rrclass,
+				QueryRecordReply	*	callback
+				);
+
+			/* ReconfirmRecord
+			*
+			* 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).
+			*
+			* rdata:           The raw rdata of the resource record.
+			*
+			*/
+			static public void
+			ReconfirmRecord
+				(
+				ServiceFlags	flags,
+				int				interfaceIndex,
+				String		*	fullname,
+				int				rrtype,
+				int				rrclass,
+				Byte			rdata[]
+				);
+		};
+	}
+}
diff --git a/mDNSWindows/DLL.NET/dnssd_NET.ico b/mDNSWindows/DLL.NET/dnssd_NET.ico
new file mode 100755
index 0000000..3a5525f
--- /dev/null
+++ b/mDNSWindows/DLL.NET/dnssd_NET.ico
Binary files differ
diff --git a/mDNSWindows/DLL.NET/dnssd_NET.rc b/mDNSWindows/DLL.NET/dnssd_NET.rc
new file mode 100755
index 0000000..95df1cf
--- /dev/null
+++ b/mDNSWindows/DLL.NET/dnssd_NET.rc
@@ -0,0 +1,113 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "WinVersRes.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
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+1                       ICON                    "dnssd_NET.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+    "\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MASTER_PROD_VERS
+ PRODUCTVERSION MASTER_PROD_VERS
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", MASTER_COMPANY_NAME
+            VALUE "FileDescription", "Bonjour.NET Client Library"
+            VALUE "FileVersion", MASTER_PROD_VERS_STR
+            VALUE "InternalName", "dnssd.NET.dll"
+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "dnssd.NET.dll"
+            VALUE "ProductName", MASTER_PROD_NAME
+            VALUE "ProductVersion", MASTER_PROD_VERS_STR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/mDNSWindows/DLL.NET/dnssd_NET.vcproj b/mDNSWindows/DLL.NET/dnssd_NET.vcproj
new file mode 100755
index 0000000..98cc63b
--- /dev/null
+++ b/mDNSWindows/DLL.NET/dnssd_NET.vcproj
@@ -0,0 +1,446 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="DLL.NET"

+	ProjectGUID="{2A2FFA97-AF60-494F-9384-BBAA283AA3F2}"

+	RootNamespace="DLL2NET"

+	Keyword="ManagedCProj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			CharacterSet="1"

+			ManagedExtensions="4"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+				Description="Generating keypair..."

+				CommandLine="sn -k dnssd_NET.snk"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;_DEBUG;WIN32_LEAN_AND_MEAN"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="2"

+				WarningLevel="3"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)\dnssd.NET.dll"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				AssemblyDebug="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="false"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			CharacterSet="1"

+			ManagedExtensions="4"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+				Description="Generating keypair..."

+				CommandLine="sn -k dnssd_NET.snk"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;_DEBUG;WIN32_LEAN_AND_MEAN"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="2"

+				WarningLevel="3"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)\dnssd.NET.dll"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				AssemblyDebug="1"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="false"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			CharacterSet="1"

+			ManagedExtensions="4"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+				Description="Generating keypair..."

+				CommandLine="sn -k dnssd_NET.snk"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;NDEBUG;WIN32_LEAN_AND_MEAN"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)\dnssd.NET.dll"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="false"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			CharacterSet="1"

+			ManagedExtensions="4"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+				Description="Generating keypair..."

+				CommandLine="sn -k dnssd_NET.snk"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;NDEBUG;WIN32_LEAN_AND_MEAN"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="../DLL/$(OutDir)/dnssd.lib ws2_32.lib"

+				OutputFile="$(OutDir)\dnssd.NET.dll"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				EmbedManifest="false"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<AssemblyReference

+			RelativePath="System.dll"

+			AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"

+		/>

+		<AssemblyReference

+			RelativePath="System.Data.dll"

+			AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"

+		/>

+		<AssemblyReference

+			RelativePath="System.XML.dll"

+			AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"

+		/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\AssemblyInfo.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\dnssd_NET.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\Stdafx.cpp"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="1"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="1"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="1"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="1"

+					/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath=".\dnssd_NET.h"

+				>

+			</File>

+			<File

+				RelativePath=".\resource.h"

+				>

+			</File>

+			<File

+				RelativePath=".\Stdafx.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath=".\dnssd_NET.ico"

+				>

+			</File>

+			<File

+				RelativePath=".\dnssd_NET.rc"

+				>

+			</File>

+		</Filter>

+		<File

+			RelativePath=".\ReadMe.txt"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/DLL.NET/resource.h b/mDNSWindows/DLL.NET/resource.h
new file mode 100755
index 0000000..29338aa
--- /dev/null
+++ b/mDNSWindows/DLL.NET/resource.h
@@ -0,0 +1,3 @@
+//{{NO_DEPENDENCIES}}

+// Microsoft Visual C++ generated include file.

+// Used by dnssd_NET.rc

diff --git a/mDNSWindows/DLL/dll.aps b/mDNSWindows/DLL/dll.aps
new file mode 100644
index 0000000..31b4787
--- /dev/null
+++ b/mDNSWindows/DLL/dll.aps
Binary files differ
diff --git a/mDNSWindows/DLL/dll.rc b/mDNSWindows/DLL/dll.rc
new file mode 100644
index 0000000..e76fb30
--- /dev/null
+++ b/mDNSWindows/DLL/dll.rc
@@ -0,0 +1,102 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "WinVersRes.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"
+    "#include ""WinVersRes.h""\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MASTER_PROD_VERS
+ PRODUCTVERSION MASTER_PROD_VERS
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", MASTER_COMPANY_NAME
+            VALUE "FileDescription", "Bonjour Client Library"
+            VALUE "FileVersion", MASTER_PROD_VERS_STR
+            VALUE "InternalName", "dnssd.dll"
+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "dnssd.dll"
+            VALUE "ProductName", MASTER_PROD_NAME
+            VALUE "ProductVersion", MASTER_PROD_VERS_STR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/mDNSWindows/DLL/dllmain.c b/mDNSWindows/DLL/dllmain.c
new file mode 100644
index 0000000..79f3bb7
--- /dev/null
+++ b/mDNSWindows/DLL/dllmain.c
@@ -0,0 +1,112 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <windows.h>
+#include <DebugServices.h>
+
+BOOL APIENTRY	DllMain( HANDLE inModule, DWORD inReason, LPVOID inReserved )
+{
+	(void) inModule;
+	(void) inReserved;
+	
+	switch( inReason )
+	{
+		case DLL_PROCESS_ATTACH:
+		case DLL_THREAD_ATTACH:
+		case DLL_THREAD_DETACH:
+		case DLL_PROCESS_DETACH:
+			break;
+	}
+    return( TRUE );
+}
+
+
+BOOL
+IsSystemServiceDisabled()
+{
+	ENUM_SERVICE_STATUS	*	lpService = NULL;
+	SC_HANDLE					sc;
+	BOOL							ret = FALSE;
+	BOOL							ok;
+	DWORD							bytesNeeded = 0;
+	DWORD							srvCount;
+	DWORD							resumeHandle = 0;
+	DWORD							srvType;
+	DWORD							srvState;
+	DWORD							dwBytes = 0;
+	DWORD							i;
+	OSStatus						err;
+
+	sc = OpenSCManager( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE );
+	err = translate_errno( sc, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	srvType		=	SERVICE_WIN32;
+	srvState		=	SERVICE_STATE_ALL;
+
+	for ( ;; )
+	{
+		// Call EnumServicesStatus using the handle returned by OpenSCManager
+
+		ok = EnumServicesStatus ( sc, srvType, srvState, lpService, dwBytes, &bytesNeeded, &srvCount, &resumeHandle );
+
+		if ( ok || ( GetLastError() != ERROR_MORE_DATA ) )
+		{
+			break;
+		}
+
+		if ( lpService )
+		{
+			free( lpService );
+		}
+
+		dwBytes = bytesNeeded;
+
+		lpService = ( ENUM_SERVICE_STATUS* ) malloc( dwBytes );
+		require_action( lpService, exit, ret = FALSE );
+	}
+
+	err = translate_errno( ok, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	for ( i = 0; i < srvCount; i++ )
+	{
+		if ( strcmp( lpService[i].lpServiceName, "Bonjour Service" ) == 0 )
+		{
+			if ( ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_PAUSED ) || ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_STOPPED ) )
+			{
+				ret = TRUE;
+			}
+
+			break;
+		}
+	}
+
+exit:
+
+	if ( lpService )
+	{
+		free( lpService );
+	}
+
+	if ( sc )
+	{
+		CloseServiceHandle ( sc );
+	}
+
+	return ret;
+}
diff --git a/mDNSWindows/DLL/dnssd.def b/mDNSWindows/DLL/dnssd.def
new file mode 100644
index 0000000..160510b
--- /dev/null
+++ b/mDNSWindows/DLL/dnssd.def
@@ -0,0 +1,48 @@
+; -*- tab-width: 4 -*-
+;
+; Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+; 
+;     http://www.apache.org/licenses/LICENSE-2.0
+; 
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+;
+
+LIBRARY		dnssd
+
+EXPORTS
+	DNSServiceRefSockFD
+	DNSServiceProcessResult
+	DNSServiceRefDeallocate
+	DNSServiceEnumerateDomains
+	DNSServiceRegister
+	DNSServiceAddRecord
+	DNSServiceUpdateRecord
+	DNSServiceRemoveRecord
+	DNSServiceBrowse
+	DNSServiceResolve
+	DNSServiceConstructFullName
+	DNSServiceCreateConnection
+	DNSServiceRegisterRecord
+	DNSServiceQueryRecord
+	DNSServiceReconfirmRecord
+	DNSServiceNATPortMappingCreate
+	DNSServiceGetAddrInfo
+	DNSServiceGetProperty
+	TXTRecordCreate
+	TXTRecordDeallocate
+	TXTRecordSetValue
+	TXTRecordRemoveValue
+	TXTRecordContainsKey
+	TXTRecordGetCount
+	TXTRecordGetLength
+	TXTRecordGetBytesPtr
+	TXTRecordGetValuePtr
+	TXTRecordGetItemAtIndex
diff --git a/mDNSWindows/DLL/dnssd.vcproj b/mDNSWindows/DLL/dnssd.vcproj
new file mode 100644
index 0000000..814a322
--- /dev/null
+++ b/mDNSWindows/DLL/dnssd.vcproj
@@ -0,0 +1,472 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="DLL"

+	ProjectGUID="{AB581101-18F0-46F6-B56A-83A6B1EA657E}"

+	RootNamespace="DLL"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DEBUG=1;NOT_HAVE_SA_LEN;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.dll.pdb"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+				DisableSpecificWarnings="4127;4204"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/dnssd.dll"

+				LinkIncremental="2"

+				ModuleDefinitionFile="dnssd.def"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\dnssd.dll.pdb"

+				SubSystem="2"

+				BaseAddress="0x16000000"

+				ImportLibrary="$(OutDir)\dnssd.lib"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DEBUG=1;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;NOT_HAVE_SA_LEN"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.dll.pdb"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+				DisableSpecificWarnings="4127;4204"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/dnssd.dll"

+				LinkIncremental="2"

+				ModuleDefinitionFile="dnssd.def"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\dnssd.dll.pdb"

+				SubSystem="2"

+				BaseAddress="0x16000000"

+				ImportLibrary="$(OutDir)\dnssd.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;NOT_HAVE_SA_LEN"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.dll.pdb"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+				DisableSpecificWarnings="4127;4204"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/dnssd.dll"

+				LinkIncremental="1"

+				ModuleDefinitionFile="dnssd.def"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\dnssd.dll.pdb"

+				SubSystem="2"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				BaseAddress="0x16000000"

+				ImportLibrary="$(OutDir)\dnssd.lib"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;                     mkdir &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib&quot;                                     mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;     mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\include&quot;                            mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\include&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal&quot;                                                                   mkdir &quot;$(DSTROOT)\AppleInternal&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal\bin&quot;                                                           mkdir &quot;$(DSTROOT)\AppleInternal\bin&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal\bin\$(PlatformName)&quot;                           mkdir &quot;$(DSTROOT)\AppleInternal\bin\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                                           &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(OutDir)\dnssd.dll.pdb&quot;                                                                          &quot;$(DSTROOT)\AppleInternal\bin\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(ProjectDir)..\..\mDNSShared\dns_sd.h&quot;                                             &quot;$(DSTROOT)\Program Files\Bonjour SDK\include&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../mDNSCore;../../mDNSShared;../"

+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MDNS_DEBUGMSGS=0;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;NOT_HAVE_SA_LEN"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.dll.pdb"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				CompileAs="0"

+				DisableSpecificWarnings="4127;4204"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/dnssd.dll"

+				LinkIncremental="1"

+				ModuleDefinitionFile="dnssd.def"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)\dnssd.dll.pdb"

+				SubSystem="2"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				BaseAddress="0x16000000"

+				ImportLibrary="$(OutDir)\dnssd.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;                     mkdir &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib&quot;                                     mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;     mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\include&quot;                            mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\include&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal&quot;                                                                   mkdir &quot;$(DSTROOT)\AppleInternal&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal\bin&quot;                                                           mkdir &quot;$(DSTROOT)\AppleInternal\bin&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal\bin\$(PlatformName)&quot;                           mkdir &quot;$(DSTROOT)\AppleInternal\bin\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                                           &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(OutDir)\dnssd.dll.pdb&quot;                                                                         &quot;$(DSTROOT)\AppleInternal\bin\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath=".\dllmain.c"

+				>

+			</File>

+			<File

+				RelativePath=".\dnssd.def"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dnssd_clientlib.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dnssd_clientstub.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dnssd_ipc.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\GenLinkedList.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dns_sd.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dnssd_ipc.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\GenLinkedList.h"

+				>

+			</File>

+			<File

+				RelativePath=".\resource.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath=".\dll.rc"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/DLL/resource.h b/mDNSWindows/DLL/resource.h
new file mode 100644
index 0000000..bdea251
--- /dev/null
+++ b/mDNSWindows/DLL/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by dll.rc
+//
+#define IDS_PROJNAME                    100
+#define IDR_WMDMLOGGER                  101
+#define IDS_LOG_SEV_INFO                201
+#define IDS_LOG_SEV_WARN                202
+#define IDS_LOG_SEV_ERROR               203
+#define IDS_LOG_DATETIME                204
+#define IDS_LOG_SRCNAME                 205
+#define IDS_DEF_LOGFILE                 301
+#define IDS_DEF_MAXSIZE                 302
+#define IDS_DEF_SHRINKTOSIZE            303
+#define IDS_DEF_LOGENABLED              304
+#define IDS_MUTEX_TIMEOUT               401
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        201
+#define _APS_NEXT_COMMAND_VALUE         32768
+#define _APS_NEXT_CONTROL_VALUE         201
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/mDNSWindows/DLLStub/DLLStub.cpp b/mDNSWindows/DLLStub/DLLStub.cpp
new file mode 100755
index 0000000..c39a747
--- /dev/null
+++ b/mDNSWindows/DLLStub/DLLStub.cpp
@@ -0,0 +1,693 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009, 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.
+ */
+
+#include "DLLStub.h"
+
+static int		g_defaultErrorCode = kDNSServiceErr_Unknown;
+static DLLStub	g_glueLayer;
+
+
+// ------------------------------------------
+// DLLStub implementation
+// ------------------------------------------
+DLLStub * DLLStub::m_instance;
+
+DLLStub::DLLStub()
+:
+	m_library( LoadLibrary( TEXT( "dnssd.dll" ) ) )
+{
+	m_instance = this;
+}
+
+
+DLLStub::~DLLStub()
+{
+	if ( m_library != NULL )
+	{
+		FreeLibrary( m_library );
+		m_library = NULL;
+	}
+
+	m_instance = NULL;
+}
+
+
+bool
+DLLStub::GetProcAddress( FARPROC * func, LPCSTR lpProcName )
+{ 
+	if ( m_instance && m_instance->m_library )
+	{
+		// Only call ::GetProcAddress if *func is NULL. This allows
+		// the calling code to cache the funcptr value, and we get
+		// some performance benefit.
+
+		if ( *func == NULL )
+		{
+			*func = ::GetProcAddress( m_instance->m_library, lpProcName );
+		}
+	}
+	else
+	{
+		*func = NULL;
+	}
+
+	return ( *func != NULL );
+}
+
+
+int DNSSD_API
+DNSServiceRefSockFD(DNSServiceRef sdRef)
+{
+	typedef int (DNSSD_API * Func)(DNSServiceRef sdRef);
+	static Func func = NULL;
+	int ret = -1;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceProcessResult(DNSServiceRef sdRef)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef sdRef);
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef );
+	}
+	
+	return ret;
+}
+
+
+void DNSSD_API
+DNSServiceRefDeallocate(DNSServiceRef sdRef)
+{
+	typedef void (DNSSD_API * Func)(DNSServiceRef sdRef);
+	static Func func = NULL;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		func( sdRef );
+	}
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceEnumerateDomains
+		(
+		DNSServiceRef                       *sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		DNSServiceDomainEnumReply           callBack,
+		void                                *context
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceDomainEnumReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceRegister
+		(
+		DNSServiceRef                       *sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		const char                          *name,
+		const char                          *regtype,
+		const char                          *domain,
+		const char                          *host,
+		uint16_t                            port,
+		uint16_t                            txtLen,
+		const void                          *txtRecord,
+		DNSServiceRegisterReply             callBack,
+		void                                *context
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, const char*, const char*, uint16_t, uint16_t, const void*, DNSServiceRegisterReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, name, regtype, domain, host, port, txtLen, txtRecord, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceAddRecord
+		(
+		DNSServiceRef                       sdRef,
+		DNSRecordRef                        *RecordRef,
+		DNSServiceFlags                     flags,
+		uint16_t                            rrtype,
+		uint16_t                            rdlen,
+		const void                          *rdata,
+		uint32_t                            ttl
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef*, DNSServiceFlags, uint16_t, uint16_t, const void*, uint32_t );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, RecordRef, flags, rrtype, rdlen, rdata, ttl );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceUpdateRecord
+		(
+		DNSServiceRef                       sdRef,
+		DNSRecordRef                        RecordRef,     /* may be NULL */
+		DNSServiceFlags                     flags,
+		uint16_t                            rdlen,
+		const void                          *rdata,
+		uint32_t                            ttl
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef, DNSServiceFlags, uint16_t, const void*, uint32_t );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, RecordRef, flags, rdlen, rdata, ttl );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceRemoveRecord
+		(
+		DNSServiceRef                 sdRef,
+		DNSRecordRef                  RecordRef,
+		DNSServiceFlags               flags
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef, DNSServiceFlags );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, RecordRef, flags );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceBrowse
+		(
+		DNSServiceRef                       *sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		const char                          *regtype,
+		const char                          *domain,    /* may be NULL */
+		DNSServiceBrowseReply               callBack,
+		void                                *context    /* may be NULL */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, DNSServiceBrowseReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, regtype, domain, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceResolve
+		(
+		DNSServiceRef                       *sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		const char                          *name,
+		const char                          *regtype,
+		const char                          *domain,
+		DNSServiceResolveReply              callBack,
+		void                                *context  /* may be NULL */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, const char*, const char*, DNSServiceResolveReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceConstructFullName
+		(
+		char                            *fullName,
+		const char                      *service,      /* may be NULL */
+		const char                      *regtype,
+		const char                      *domain
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( char*, const char*, const char*, const char* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( fullName, service, regtype, domain );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceCreateConnection(DNSServiceRef *sdRef)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( DNSServiceRef* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+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 */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef, DNSRecordRef*, DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, uint16_t, const void*, uint16_t, DNSServiceRegisterRecordReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, RecordRef, flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata, ttl, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceQueryRecord
+		(
+		DNSServiceRef                       *sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		const char                          *fullname,
+		uint16_t                            rrtype,
+		uint16_t                            rrclass,
+		DNSServiceQueryRecordReply          callBack,
+		void                                *context  /* may be NULL */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, DNSServiceQueryRecordReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, fullname, rrtype, rrclass, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceReconfirmRecord
+		(
+		DNSServiceFlags                    flags,
+		uint32_t                           interfaceIndex,
+		const char                         *fullname,
+		uint16_t                           rrtype,
+		uint16_t                           rrclass,
+		uint16_t                           rdlen,
+		const void                         *rdata
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( DNSServiceFlags, uint32_t, const char*, uint16_t, uint16_t, uint16_t, const void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( flags, interfaceIndex, fullname, rrtype, rrclass, rdlen, rdata );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceNATPortMappingCreate
+		(
+		DNSServiceRef                    *sdRef,
+		DNSServiceFlags                  flags,
+		uint32_t                         interfaceIndex,
+		DNSServiceProtocol               protocol,          /* TCP and/or UDP          */
+		uint16_t                         internalPort,      /* network byte order      */
+		uint16_t                         externalPort,      /* network byte order      */
+		uint32_t                         ttl,               /* time to live in seconds */
+		DNSServiceNATPortMappingReply    callBack,
+		void                             *context           /* may be NULL             */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceProtocol, uint16_t, uint16_t, uint16_t, DNSServiceNATPortMappingReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, protocol, internalPort, externalPort, ttl, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceGetAddrInfo
+		(
+		DNSServiceRef                    *sdRef,
+		DNSServiceFlags                  flags,
+		uint32_t                         interfaceIndex,
+		DNSServiceProtocol               protocol,
+		const char                       *hostname,
+		DNSServiceGetAddrInfoReply       callBack,
+		void                             *context          /* may be NULL */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)(DNSServiceRef*, DNSServiceFlags, uint32_t, DNSServiceProtocol, const char*, DNSServiceGetAddrInfoReply, void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( sdRef, flags, interfaceIndex, protocol, hostname, callBack, context );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+DNSServiceGetProperty
+		(
+		const char *property,  /* Requested property (i.e. kDNSServiceProperty_DaemonVersion) */
+		void       *result,    /* Pointer to place to store result */
+		uint32_t   *size       /* size of result location */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( const char*, void*, uint32_t* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( property, result, size );
+	}
+	
+	return ret;
+}
+
+
+void DNSSD_API
+TXTRecordCreate
+		(
+		TXTRecordRef     *txtRecord,
+		uint16_t         bufferLen,
+		void             *buffer
+		)
+{
+	typedef void (DNSSD_API * Func)( TXTRecordRef*, uint16_t, void* );
+	static Func func = NULL;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		func( txtRecord, bufferLen, buffer );
+	}
+}
+
+
+void DNSSD_API
+TXTRecordDeallocate
+		(
+		TXTRecordRef     *txtRecord
+		)
+{
+	typedef void (DNSSD_API * Func)( TXTRecordRef* );
+	static Func func = NULL;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		func( txtRecord );
+	}
+}
+
+
+DNSServiceErrorType DNSSD_API
+TXTRecordSetValue
+		(
+		TXTRecordRef     *txtRecord,
+		const char       *key,
+		uint8_t          valueSize,        /* may be zero */
+		const void       *value            /* may be NULL */
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( TXTRecordRef*, const char*, uint8_t, const void* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtRecord, key, valueSize, value );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+TXTRecordRemoveValue
+		(
+		TXTRecordRef     *txtRecord,
+		const char       *key
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( TXTRecordRef*, const char* );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtRecord, key );
+	}
+	
+	return ret;
+}
+
+
+int DNSSD_API
+TXTRecordContainsKey
+		(
+		uint16_t         txtLen,
+		const void       *txtRecord,
+		const char       *key
+		)
+{
+	typedef int (DNSSD_API * Func)( uint16_t, const void*, const char* );
+	static Func func = NULL;
+	int ret = 0;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtLen, txtRecord, key );
+	}
+	
+	return ret;
+}
+
+
+uint16_t DNSSD_API
+TXTRecordGetCount
+		(
+		uint16_t         txtLen,
+		const void       *txtRecord
+		)
+{
+	typedef uint16_t (DNSSD_API * Func)( uint16_t, const void* );
+	static Func func = NULL;
+	uint16_t ret = 0;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtLen, txtRecord );
+	}
+	
+	return ret;
+}
+
+
+uint16_t DNSSD_API
+TXTRecordGetLength
+		(
+		const TXTRecordRef *txtRecord
+		)
+{
+	typedef uint16_t (DNSSD_API * Func)( const TXTRecordRef* );
+	static Func func = NULL;
+	uint16_t ret = 0;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtRecord );
+	}
+	
+	return ret;
+}
+
+
+const void * DNSSD_API
+TXTRecordGetBytesPtr
+		(
+		const TXTRecordRef *txtRecord
+		)
+{
+	typedef const void* (DNSSD_API * Func)( const TXTRecordRef* );
+	static Func func = NULL;
+	const void* ret = NULL;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtRecord );
+	}
+	
+	return ret;
+}
+
+
+const void * DNSSD_API
+TXTRecordGetValuePtr
+		(
+		uint16_t         txtLen,
+		const void       *txtRecord,
+		const char       *key,
+		uint8_t          *valueLen
+		)
+{
+	typedef const void* (DNSSD_API * Func)( uint16_t, const void*, const char*, uint8_t* );
+	static Func func = NULL;
+	const void* ret = NULL;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtLen, txtRecord, key, valueLen );
+	}
+	
+	return ret;
+}
+
+
+DNSServiceErrorType DNSSD_API
+TXTRecordGetItemAtIndex
+		(
+		uint16_t         txtLen,
+		const void       *txtRecord,
+		uint16_t         itemIndex,
+		uint16_t         keyBufLen,
+		char             *key,
+		uint8_t          *valueLen,
+		const void       **value
+		)
+{
+	typedef DNSServiceErrorType (DNSSD_API * Func)( uint16_t, const void*, uint16_t, uint16_t, char*, uint8_t*, const void** );
+	static Func func = NULL;
+	DNSServiceErrorType ret = g_defaultErrorCode;
+
+	if ( DLLStub::GetProcAddress( ( FARPROC* ) &func, __FUNCTION__ ) )
+	{
+		ret = func( txtLen, txtRecord, itemIndex, keyBufLen, key, valueLen, value );
+	}
+	
+	return ret;
+}
\ No newline at end of file
diff --git a/mDNSWindows/DLLStub/DLLStub.h b/mDNSWindows/DLLStub/DLLStub.h
new file mode 100755
index 0000000..44f57d1
--- /dev/null
+++ b/mDNSWindows/DLLStub/DLLStub.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009, 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 _DLLStub_h
+#define _DLLStub_h
+
+#include <windows.h>
+#include <dns_sd.h>
+
+class DLLStub
+{
+public:
+
+	DLLStub();
+	~DLLStub();
+
+	static bool
+	GetProcAddress( FARPROC * func, LPCSTR lpProcName );
+
+private:
+
+	static DLLStub	*	m_instance;
+	HMODULE				m_library;
+};
+
+
+#endif
\ No newline at end of file
diff --git a/mDNSWindows/DLLStub/DLLStub.vcproj b/mDNSWindows/DLLStub/DLLStub.vcproj
new file mode 100755
index 0000000..dc68289
--- /dev/null
+++ b/mDNSWindows/DLLStub/DLLStub.vcproj
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="DLLStub"

+	ProjectGUID="{3A2B6325-3053-4236-84BD-AA9BE2E323E5}"

+	RootNamespace="DLLStub"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="4"

+			UseOfATL="0"

+			CharacterSet="1"

+			WholeProgramOptimization="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				MinimalRebuild="false"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.pdb"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)\dnssdStatic.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="4"

+			UseOfATL="0"

+			CharacterSet="1"

+			WholeProgramOptimization="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				MinimalRebuild="false"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.pdb"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)\dnssdStatic.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="4"

+			UseOfATL="0"

+			CharacterSet="1"

+			WholeProgramOptimization="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.lib.pdb"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)\dnssdStatic.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot; mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;&#x0D;&#x0A;echo F | xcopy /Y &quot;$(OutDir)\dnssdStatic.lib&quot;                                                        &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)\dnssd.lib&quot;&#x0D;&#x0A;xcopy /Y &quot;$(OutDir)\dnssd.lib.pdb&quot;                                                                         &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="4"

+			UseOfATL="0"

+			CharacterSet="1"

+			WholeProgramOptimization="0"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				ProgramDataBaseFileName="$(IntDir)\dnssd.lib.pdb"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)\dnssdStatic.lib"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot; mkdir &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;&#x0D;&#x0A;echo F | xcopy /I/Y &quot;$(OutDir)\dnssdStatic.lib&quot;                                                     &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)\dnssd.lib&quot;&#x0D;&#x0A;xcopy /Y &quot;$(OutDir)\dnssd.lib.pdb&quot;                                                                         &quot;$(DSTROOT)\Program Files\Bonjour SDK\lib\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\DLLStub.cpp"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath=".\DLLStub.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+		</Filter>

+		<File

+			RelativePath=".\ReadMe.txt"

+			>

+		</File>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/DLLX/DLLX.cpp b/mDNSWindows/DLLX/DLLX.cpp
new file mode 100755
index 0000000..77883cc
--- /dev/null
+++ b/mDNSWindows/DLLX/DLLX.cpp
@@ -0,0 +1,208 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+
+
+#include "stdafx.h"
+
+#include "resource.h"
+
+#include "DLLX.h"
+
+#include "dlldatax.h"
+
+#include <DebugServices.h>
+
+
+
+
+
+class CDLLComponentModule : public CAtlDllModuleT< CDLLComponentModule >
+
+{
+
+public :
+
+	DECLARE_LIBID(LIBID_Bonjour)
+
+	DECLARE_REGISTRY_APPID_RESOURCEID(IDR_DLLX, "{56608F9C-223B-4CB6-813D-85EDCCADFB4B}")
+
+};
+
+
+
+CDLLComponentModule _AtlModule;
+
+
+
+
+
+#ifdef _MANAGED
+
+#pragma managed(push, off)
+
+#endif
+
+
+
+// DLL Entry Point
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+
+{
+
+	debug_initialize( kDebugOutputTypeWindowsDebugger );
+	debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
+
+
+
+#ifdef _MERGE_PROXYSTUB
+
+    if (!PrxDllMain(hInstance, dwReason, lpReserved))
+
+        return FALSE;
+
+#endif
+
+	hInstance;
+
+    return _AtlModule.DllMain(dwReason, lpReserved); 
+
+}
+
+
+
+#ifdef _MANAGED
+
+#pragma managed(pop)
+
+#endif
+
+
+
+
+
+
+
+
+
+// Used to determine whether the DLL can be unloaded by OLE
+
+STDAPI DllCanUnloadNow(void)
+
+{
+
+#ifdef _MERGE_PROXYSTUB
+
+    HRESULT hr = PrxDllCanUnloadNow();
+
+    if (hr != S_OK)
+
+        return hr;
+
+#endif
+
+    return _AtlModule.DllCanUnloadNow();
+
+}
+
+
+
+
+
+// Returns a class factory to create an object of the requested type
+
+STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
+
+{
+
+#ifdef _MERGE_PROXYSTUB
+
+    if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
+
+        return S_OK;
+
+#endif
+
+    return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
+
+}
+
+
+
+
+
+// DllRegisterServer - Adds entries to the system registry
+
+STDAPI DllRegisterServer(void)
+
+{
+
+    // registers object, typelib and all interfaces in typelib
+
+    HRESULT hr = _AtlModule.DllRegisterServer();
+
+#ifdef _MERGE_PROXYSTUB
+
+    if (FAILED(hr))
+
+        return hr;
+
+    hr = PrxDllRegisterServer();
+
+#endif
+
+	return hr;
+
+}
+
+
+
+
+
+// DllUnregisterServer - Removes entries from the system registry
+
+STDAPI DllUnregisterServer(void)
+
+{
+
+	HRESULT hr = _AtlModule.DllUnregisterServer();
+
+#ifdef _MERGE_PROXYSTUB
+
+    if (FAILED(hr))
+
+        return hr;
+
+    hr = PrxDllRegisterServer();
+
+    if (FAILED(hr))
+
+        return hr;
+
+    hr = PrxDllUnregisterServer();
+
+#endif
+
+	return hr;
+
+}
+
+
+
diff --git a/mDNSWindows/DLLX/DLLX.def b/mDNSWindows/DLLX/DLLX.def
new file mode 100755
index 0000000..698b172
--- /dev/null
+++ b/mDNSWindows/DLLX/DLLX.def
@@ -0,0 +1,35 @@
+; -*- Mode: C; tab-width: 4 -*-
+;
+; Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+; 
+;     http://www.apache.org/licenses/LICENSE-2.0
+; 
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+;
+
+
+
+
+
+LIBRARY      "dnssdX.DLL"
+
+
+
+EXPORTS
+
+	DllCanUnloadNow		PRIVATE
+
+	DllGetClassObject	PRIVATE
+
+	DllRegisterServer	PRIVATE
+
+	DllUnregisterServer	PRIVATE
+
diff --git a/mDNSWindows/DLLX/DLLX.idl b/mDNSWindows/DLLX/DLLX.idl
new file mode 100755
index 0000000..475558e
--- /dev/null
+++ b/mDNSWindows/DLLX/DLLX.idl
@@ -0,0 +1,491 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+// This file will be processed by the MIDL tool to
+
+// produce the type library (DLLComponent.tlb) and marshalling code.
+
+
+
+typedef [ uuid(4085DD59-D0E1-4efe-B6EE-DDBF7631B9C0) ]
+
+enum DNSSDFlags
+
+{
+
+	kDNSSDFlagsMoreComing			= 0x0001,
+
+	kDNSSDFlagsDefault				= 0x0004,
+
+	kDNSSDFlagsNoAutoRename			= 0x0008,
+
+	kDNSSDFlagsShared				= 0x0010,
+
+	kDNSSDFlagsUnique				= 0x0020,
+
+	kDNSSDFlagsBrowseDomains		= 0x0040,
+
+	kDNSSDFlagsRegistrationDomains	= 0x0080,
+
+	kDNSSDFlagsLongLivedQuery		= 0x0100,
+
+	kDNSSDFlagsAllowRemoteQuery		= 0x0200,
+
+	kDNSSDFlagsForceMulticast		= 0x0400,
+
+	kDNSSDFlagsForce				= 0x0800,
+
+	kDNSSDFlagsReturnIntermediates	= 0x1000,
+
+	kDNSSDFlagsNonBrowsable			= 0x2000
+
+} DNSSDFlags;
+
+
+
+
+
+typedef [ uuid(30CDF335-CA52-4b17-AFF2-E83C64C450D4) ]
+
+enum DNSSDAddressFamily
+
+{
+
+	kDNSSDAddressFamily_IPv4 = 0x1,
+
+	kDNSSDAddressFamily_IPv6 = 0x2
+
+} DNSSDAddressFamily;
+
+
+
+
+
+typedef [ uuid(98FB4702-7374-4b16-A8DB-AD35BFB8364D) ]
+
+enum DNSSDProtocol
+
+{
+
+	kDNSSDProtocol_UDP	= 0x10,
+
+	kDNSSDProtocol_TCP	= 0x20
+
+} DNSSDProtocol;
+
+
+
+
+
+typedef [ uuid(72BF3EC3-19BC-47e5-8D95-3B73FF37D893) ]
+
+enum DNSSDRRClass
+
+{
+
+	kDNSSDClass_IN = 1
+
+} DNSSDRRClass;
+
+
+
+
+
+typedef [ uuid(08E362DF-5468-4c9a-AC66-FD4747B917BD) ]
+
+enum DNSSDRRType
+
+{
+
+	kDNSSDType_A         = 1,
+    kDNSSDType_NS        = 2,
+    kDNSSDType_MD        = 3,
+    kDNSSDType_MF        = 4,
+    kDNSSDType_CNAME     = 5,
+    kDNSSDType_SOA       = 6,
+    kDNSSDType_MB        = 7,
+    kDNSSDType_MG        = 8,
+    kDNSSDType_MR        = 9,
+    kDNSSDType_NULL      = 10,
+    kDNSSDType_WKS       = 11,
+    kDNSSDType_PTR       = 12,
+    kDNSSDType_HINFO     = 13,
+    kDNSSDType_MINFO     = 14,
+    kDNSSDType_MX        = 15,
+    kDNSSDType_TXT       = 16,
+    kDNSSDType_RP        = 17,
+    kDNSSDType_AFSDB     = 18,
+    kDNSSDType_X25       = 19,
+    kDNSSDType_ISDN      = 20,
+    kDNSSDType_RT        = 21,
+    kDNSSDType_NSAP      = 22,
+    kDNSSDType_NSAP_PTR  = 23,
+    kDNSSDType_SIG       = 24,
+    kDNSSDType_KEY       = 25,
+    kDNSSDType_PX        = 26,
+    kDNSSDType_GPOS      = 27,
+    kDNSSDType_AAAA      = 28,
+    kDNSSDType_LOC       = 29,
+    kDNSSDType_NXT       = 30,
+    kDNSSDType_EID       = 31,
+    kDNSSDType_NIMLOC    = 32,
+    kDNSSDType_SRV       = 33,
+    kDNSSDType_ATMA      = 34,
+    kDNSSDType_NAPTR     = 35,
+    kDNSSDType_KX        = 36,
+    kDNSSDType_CERT      = 37,
+    kDNSSDType_A6        = 38,
+    kDNSSDType_DNAME     = 39,
+    kDNSSDType_SINK      = 40,
+    kDNSSDType_OPT       = 41,
+    kDNSSDType_APL       = 42,
+    kDNSSDType_DS        = 43,
+    kDNSSDType_SSHFP     = 44,
+    kDNSSDType_IPSECKEY  = 45,
+    kDNSSDType_RRSIG     = 46,
+    kDNSSDType_NSEC      = 47,
+    kDNSSDType_DNSKEY    = 48,
+    kDNSSDType_DHCID     = 49,
+    kDNSSDType_NSEC3     = 50,
+    kDNSSDType_NSEC3PARAM= 51,
+    kDNSSDType_HIP       = 55,
+    kDNSSDType_SPF       = 99,
+    kDNSSDType_UINFO     = 100,
+    kDNSSDType_UID       = 101,
+    kDNSSDType_GID       = 102,
+    kDNSSDType_UNSPEC    = 103,
+    kDNSSDType_TKEY      = 249,
+    kDNSSDType_TSIG      = 250,
+    kDNSSDType_IXFR      = 251,
+    kDNSSDType_AXFR      = 252,
+    kDNSSDType_MAILB     = 253,
+    kDNSSDType_MAILA     = 254,
+    kDNSSDType_ANY       = 255
+
+} DNSSDRRType;
+
+
+
+
+
+typedef [ uuid(3B0059E7-5297-4301-9AAB-1522F31EC8A7) ]
+
+enum DNSSDError
+{
+	kDNSSDError_NoError                   = 0,
+	kDNSSDError_Unknown                   = -65537,
+	kDNSSDError_NoSuchName                = -65538,
+    kDNSSDError_NoMemory                  = -65539,
+    kDNSSDError_BadParam                  = -65540,
+    kDNSSDError_BadReference              = -65541,
+    kDNSSDError_BadState                  = -65542,
+    kDNSSDError_BadFlags                  = -65543,
+    kDNSSDError_Unsupported               = -65544,
+    kDNSSDError_NotInitialized            = -65545,
+    kDNSSDError_AlreadyRegistered         = -65547,
+    kDNSSDError_NameConflict              = -65548,
+    kDNSSDError_Invalid                   = -65549,
+    kDNSSDError_Firewall                  = -65550,
+    kDNSSDError_Incompatible              = -65551,
+    kDNSSDError_BadInterfaceIndex         = -65552,
+    kDNSSDError_Refused                   = -65553,
+    kDNSSDError_NoSuchRecord              = -65554,
+    kDNSSDError_NoAuth                    = -65555,
+    kDNSSDError_NoSuchKey                 = -65556,
+    kDNSSDError_NATTraversal              = -65557,
+    kDNSSDError_DoubleNAT                 = -65558,
+    kDNSSDError_BadTime                   = -65559,
+    kDNSSDError_BadSig                    = -65560,
+    kDNSSDError_BadKey                    = -65561,
+    kDNSSDError_Transient                 = -65562,
+    kDNSSDError_ServiceNotRunning         = -65563,  /* Background daemon not running */
+    kDNSSDError_NATPortMappingUnsupported = -65564,  /* NAT doesn't support NAT-PMP or UPnP */
+    kDNSSDError_NATPortMappingDisabled    = -65565,  /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
+    kDNSSDError_NoRouter                  = -65566,  /* No router currently configured (probably no network connectivity) */
+    kDNSSDError_PollingMode               = -65567
+} DNSSDError;
+
+
+
+import "oaidl.idl";
+
+import "ocidl.idl";
+
+
+
+
+
+[
+
+	object,
+
+	uuid(8FA0889C-5973-4FC9-970B-EC15C925D0CE),
+
+	dual,
+
+	nonextensible,
+
+	helpstring("ITXTRecord Interface"),
+
+	pointer_default(unique)
+
+]
+
+interface ITXTRecord : IDispatch{
+
+	[id(1), helpstring("method SetValue")] HRESULT SetValue([in] BSTR key, [in] VARIANT value);
+
+	[id(2), helpstring("method RemoveValue")] HRESULT RemoveValue([in] BSTR key);
+
+	[id(3), helpstring("method ContainsKey")] HRESULT ContainsKey([in] BSTR key, [out,retval] VARIANT_BOOL* retval);
+
+	[id(4), helpstring("method GetValueForKey")] HRESULT GetValueForKey([in] BSTR key, [out,retval] VARIANT* value);
+
+	[id(5), helpstring("method GetCount")] HRESULT GetCount([out,retval] ULONG* count);
+
+	[id(6), helpstring("method GetKeyAtIndex")] HRESULT GetKeyAtIndex([in] ULONG index, [out,retval] BSTR* retval);
+
+	[id(7), helpstring("method GetValueAtIndex")] HRESULT GetValueAtIndex([in] ULONG index, [out,retval] VARIANT* retval);
+
+};
+
+[
+
+	object,
+
+	uuid(9CE603A0-3365-4DA0-86D1-3F780ECBA110),
+
+	dual,
+
+	nonextensible,
+
+	helpstring("IDNSSDRecord Interface"),
+
+	pointer_default(unique)
+
+]
+
+interface IDNSSDRecord : IDispatch{
+
+	[id(1), helpstring("method Update")] HRESULT Update([in] DNSSDFlags flags, [in] VARIANT rdata, [in] ULONG ttl);
+
+	[id(2), helpstring("method Remove")] HRESULT Remove([in] DNSSDFlags flags);
+
+};
+
+[
+
+	object,
+
+	uuid(7FD72324-63E1-45AD-B337-4D525BD98DAD),
+
+	dual,
+
+	nonextensible,
+
+	helpstring("IDNSSDEventManager Interface"),
+
+	pointer_default(unique)
+
+]
+
+interface IDNSSDEventManager : IDispatch{
+
+};
+
+[
+
+	object,
+
+	uuid(29DE265F-8402-474F-833A-D4653B23458F),
+
+	dual,
+
+	nonextensible,
+
+	helpstring("IDNSSDService Interface"),
+
+	pointer_default(unique)
+
+]
+
+interface IDNSSDService : IDispatch{
+
+	[id(1), helpstring("method EnumerateDomains")] HRESULT EnumerateDomains([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);
+
+	[id(2), helpstring("method Browse"), local] HRESULT Browse([in] DNSSDFlags flags, [in] ULONG interfaceIndex, [in] BSTR regtype, [in] BSTR domain, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** sdref);
+
+	[id(3), helpstring("method Resolve")] HRESULT Resolve([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR serviceName, [in] BSTR regType, [in] BSTR domain, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);
+
+	[id(4), helpstring("method Register")] HRESULT Register([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR name, [in] BSTR regType, [in] BSTR domain, [in] BSTR host, [in] USHORT port, [in] ITXTRecord* record, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);
+
+	[id(5), helpstring("method QueryRecord")] HRESULT QueryRecord([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullname, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);
+
+	[id(6), helpstring("method RegisterRecord")] HRESULT RegisterRecord([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullname, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] VARIANT rdata, [in] ULONG ttl, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDRecord** record);
+
+	[id(7), helpstring("method AddRecord")] HRESULT AddRecord([in] DNSSDFlags flags, [in] DNSSDRRType rrtype, [in] VARIANT rdata, [in] ULONG ttl, [out,retval] IDNSSDRecord** record);
+
+	[id(8), helpstring("method ReconfirmRecord")] HRESULT ReconfirmRecord([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullname, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] VARIANT rdata);
+
+	[id(9), helpstring("method GetProperty")] HRESULT GetProperty([in] BSTR prop, [in,out] VARIANT * value );	
+
+	[id(10), helpstring("method GetAddrInfo")] HRESULT GetAddrInfo([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] DNSSDAddressFamily addressFamily, [in] BSTR hostname, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);
+
+	[id(11), helpstring("method NATPortMappingCreate")] HRESULT NATPortMappingCreate([in] DNSSDFlags flags, [in] ULONG ifIndex, [in] DNSSDAddressFamily addressFamily, [in] DNSSDProtocol protocol, [in] USHORT internalPort, [in] USHORT externalPort, [in] ULONG ttl, [in] IDNSSDEventManager* eventManager, [out,retval] IDNSSDService** service);
+
+	[id(12), helpstring("method Stop"), local] HRESULT Stop(void);
+
+};
+
+[
+
+	uuid(18FBED6D-F2B7-4EC8-A4A4-46282E635308),
+
+	version(1.0),
+
+	helpstring("Apple Bonjour Library 1.0")
+
+]
+
+library Bonjour
+
+{
+
+	importlib("stdole2.tlb");
+
+	[
+
+		uuid(21AE8D7F-D5FE-45cf-B632-CFA2C2C6B498),
+
+		helpstring("_IDNSSDEvents Interface")
+
+	]
+
+	dispinterface _IDNSSDEvents
+
+	{
+
+		properties:
+
+		methods:
+
+		[id(1), helpstring("method DomainFound")] void DomainFound([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR domain);
+
+		[id(2), helpstring("method DomainLost")] void DomainLost([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR domain);
+
+		[id(3), helpstring("method ServiceFound")] void ServiceFound([in] IDNSSDService* browser, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR serviceName, [in] BSTR regType, [in] BSTR domain);
+
+		[id(4), helpstring("method ServiceLost")] void ServiceLost([in] IDNSSDService* browser, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR serviceName, [in] BSTR regType, [in] BSTR domain);
+
+		[id(5), helpstring("method ServiceResolved")] void ServiceResolved([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullName, [in] BSTR hostName, [in] USHORT port, [in] ITXTRecord* record);
+
+		[id(6), helpstring("method ServiceRegistered")] void ServiceRegistered([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] BSTR name, [in] BSTR regType, [in] BSTR domain);
+
+		[id(7), helpstring("method QueryRecordAnswered")] void QueryRecordAnswered([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR fullName, [in] DNSSDRRType rrtype, [in] DNSSDRRClass rrclass, [in] VARIANT rdata, [in] ULONG ttl);
+
+		[id(8), helpstring("method RecordRegistered")] void RecordRegistered([in] IDNSSDRecord* record, [in] DNSSDFlags flags);
+
+		[id(9), helpstring("method AddressFound")] void AddressFound([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] BSTR hostname, [in] DNSSDAddressFamily addressFamily, [in] BSTR address, [in] ULONG ttl);
+
+		[id(10), helpstring("method MappingCreated")] void MappingCreated([in] IDNSSDService* service, [in] DNSSDFlags flags, [in] ULONG ifIndex, [in] ULONG externalAddress, [in] DNSSDAddressFamily addressFamily, [in] DNSSDProtocol protocol, [in] USHORT internalPort, [in] USHORT externalPort, [in] ULONG ttl);
+
+		[id(11), helpstring("method OperationFailed")] void OperationFailed([in] IDNSSDService* service, [in] DNSSDError error);
+
+	};
+
+	[
+
+		uuid(24CD4DE9-FF84-4701-9DC1-9B69E0D1090A),
+
+		helpstring("DNSSDService Class")
+
+	]
+
+	coclass DNSSDService
+
+	{
+
+		[default] interface IDNSSDService;
+
+	};
+
+	[
+
+		uuid(AFEE063C-05BA-4248-A26E-168477F49734),
+
+		helpstring("TXTRecord Class")
+
+	]
+
+	coclass TXTRecord
+
+	{
+
+		[default] interface ITXTRecord;
+
+	};
+
+	[
+
+		uuid(5E93C5A9-7516-4259-A67B-41A656F6E01C),
+
+		helpstring("DNSSDRecord Class")
+
+	]
+
+	coclass DNSSDRecord
+
+	{
+
+		[default] interface IDNSSDRecord;
+
+	};
+
+	[
+
+		uuid(BEEB932A-8D4A-4619-AEFE-A836F988B221),
+
+		helpstring("DNSSDEventManager Class")
+
+	]
+
+	coclass DNSSDEventManager
+
+	{
+
+		[default] interface IDNSSDEventManager;
+
+		[default, source] dispinterface _IDNSSDEvents;
+
+	};
+
+	enum DNSSDFlags;
+
+	enum DNSSDAddressFamily;
+
+	enum DNSSDProtocol;
+
+	enum DNSSDRRClass;
+
+	enum DNSSDRRType;
+
+	enum DNSSDError;
+
+};
+
diff --git a/mDNSWindows/DLLX/DLLX.rc b/mDNSWindows/DLLX/DLLX.rc
new file mode 100755
index 0000000..4299b5a
--- /dev/null
+++ b/mDNSWindows/DLLX/DLLX.rc
@@ -0,0 +1,126 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "winres.h"

+#include "WinVersRes.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 ""winres.h""\r\n"

+    "#include ""WinVersRes.h""\r\n"

+    "\0"

+END

+

+3 TEXTINCLUDE 

+BEGIN

+    "1 TYPELIB ""BonjourLib.tlb""\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x3fL

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x2L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904e4"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "Bonjour COM Component Library"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "InternalName", "dnssdX.dll"

+            VALUE "OriginalFilename", "dnssdX.dll"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1252

+    END

+END

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// REGISTRY

+//

+

+IDR_DLLX		        REGISTRY                "DLLX.rgs"

+IDR_DNSSDSERVICE        REGISTRY                "DNSSDService.rgs"

+IDR_TXTRECORD           REGISTRY                "TXTRecord.rgs"

+IDR_DNSSDRECORD         REGISTRY                "DNSSDRecord.rgs"

+IDR_DNSSDEVENTMANAGER   REGISTRY                "DNSSDEventManager.rgs"

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// String Table

+//

+

+STRINGTABLE 

+BEGIN

+    IDS_PROJNAME            "BonjourLib"

+END

+

+#endif    // English (U.S.) resources

+/////////////////////////////////////////////////////////////////////////////

+

+

+

+#ifndef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 3 resource.

+//

+1 TYPELIB "dnssdX.tlb"

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/mDNSWindows/DLLX/DLLX.rgs b/mDNSWindows/DLLX/DLLX.rgs
new file mode 100755
index 0000000..c55ee8d
--- /dev/null
+++ b/mDNSWindows/DLLX/DLLX.rgs
@@ -0,0 +1,11 @@
+HKCR

+{

+	NoRemove AppID

+	{

+		'%APPID%' = s 'Bonjour'

+		'Bonjour.DLL'

+		{

+			val AppID = s '%APPID%'

+		}

+	}

+}

diff --git a/mDNSWindows/DLLX/DLLX.vcproj b/mDNSWindows/DLLX/DLLX.vcproj
new file mode 100755
index 0000000..7c58b0a
--- /dev/null
+++ b/mDNSWindows/DLLX/DLLX.vcproj
@@ -0,0 +1,625 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="DLLX"

+	ProjectGUID="{78FBFCC5-2873-4AE2-9114-A08082F71124}"

+	RootNamespace="DLLX"

+	Keyword="AtlProj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			UseOfMFC="0"

+			UseOfATL="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="1"

+				GenerateStublessProxies="true"

+				TypeLibraryName="$(IntDir)/dnssdX.tlb"

+				HeaderFileName="DLLX.h"

+				DLLDataFileName=""

+				InterfaceIdentifierFileName="DLLX_i.c"

+				ProxyFileName="DLLX_p.c"

+				ValidateParameters="false"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;DEBUG=1;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="..;&quot;$(IntDir)&quot;"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				RegisterOutput="true"

+				IgnoreImportLibrary="true"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"

+				OutputFile="$(OutDir)\dnssdX.dll"

+				LinkIncremental="2"

+				ModuleDefinitionFile=".\DLLX.def"

+				GenerateDebugInformation="true"

+				SubSystem="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			UseOfMFC="0"

+			UseOfATL="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="_DEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="3"

+				GenerateStublessProxies="true"

+				TypeLibraryName="$(IntDir)/dnssdX.tlb"

+				HeaderFileName="DLLX.h"

+				DLLDataFileName=""

+				InterfaceIdentifierFileName="DLLX_i.c"

+				ProxyFileName="DLLX_p.c"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL;_MERGE_PROXYSTUB;DEBUG=1;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="_DEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="..;&quot;$(IntDir)&quot;"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				RegisterOutput="true"

+				IgnoreImportLibrary="true"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"

+				OutputFile="$(OutDir)\dnssdX.dll"

+				LinkIncremental="2"

+				ModuleDefinitionFile=".\DLLX.def"

+				GenerateDebugInformation="true"

+				SubSystem="2"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			UseOfATL="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="1"

+				GenerateStublessProxies="true"

+				TypeLibraryName="$(IntDir)/dnssdX.tlb"

+				HeaderFileName="DLLX.h"

+				DLLDataFileName=""

+				InterfaceIdentifierFileName="DLLX_i.c"

+				ProxyFileName="DLLX_p.c"

+				ValidateParameters="false"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL;_MERGE_PROXYSTUB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="..;&quot;$(IntDir)&quot;"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				RegisterOutput="false"

+				IgnoreImportLibrary="true"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"

+				OutputFile="$(OutDir)\dnssdX.dll"

+				LinkIncremental="1"

+				ModuleDefinitionFile=".\DLLX.def"

+				GenerateDebugInformation="true"

+				SubSystem="2"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;             mkdir &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                            &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			UseOfATL="1"

+			ATLMinimizesCRunTimeLibraryUsage="false"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				PreprocessorDefinitions="NDEBUG"

+				MkTypLibCompatible="false"

+				TargetEnvironment="3"

+				GenerateStublessProxies="true"

+				TypeLibraryName="$(IntDir)/dnssdX.tlb"

+				HeaderFileName="DLLX.h"

+				DLLDataFileName=""

+				InterfaceIdentifierFileName="DLLX_i.c"

+				ProxyFileName="DLLX_p.c"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="2"

+				AdditionalIncludeDirectories="..\..\mDNSShared;..\..\mDNSWindows"

+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL;_MERGE_PROXYSTUB;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				PreprocessorDefinitions="NDEBUG"

+				Culture="1033"

+				AdditionalIncludeDirectories="..;&quot;$(IntDir)&quot;"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				RegisterOutput="false"

+				IgnoreImportLibrary="true"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="ws2_32.lib ../../mDNSWindows/DLLStub/$(PlatformName)/$(ConfigurationName)/dnssdStatic.lib"

+				OutputFile="$(OutDir)\dnssdX.dll"

+				LinkIncremental="1"

+				ModuleDefinitionFile=".\DLLX.def"

+				GenerateDebugInformation="true"

+				SubSystem="2"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;             mkdir &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                            &quot;$(DSTROOT)\WINDOWS\system32\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\dlldatax.c"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath=".\DLLX.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\DLLX.def"

+				>

+			</File>

+			<File

+				RelativePath=".\DLLX.idl"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDEventManager.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDRecord.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDService.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\TXTRecord.cpp"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath=".\_IDNSSDEvents_CP.H"

+				>

+			</File>

+			<File

+				RelativePath=".\dlldatax.h"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDEventManager.h"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDRecord.h"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDService.h"

+				>

+			</File>

+			<File

+				RelativePath=".\Resource.h"

+				>

+			</File>

+			<File

+				RelativePath=".\stdafx.h"

+				>

+			</File>

+			<File

+				RelativePath=".\TXTRecord.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath=".\DLLX.rc"

+				>

+			</File>

+			<File

+				RelativePath=".\DLLX.rgs"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDEventManager.rgs"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDRecord.rgs"

+				>

+			</File>

+			<File

+				RelativePath=".\DNSSDService.rgs"

+				>

+			</File>

+			<File

+				RelativePath=".\TXTRecord.rgs"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Generated Files"

+			SourceControlFiles="false"

+			>

+			<File

+				RelativePath=".\DLLX.h"

+				>

+			</File>

+			<File

+				RelativePath=".\DLLX_i.c"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCLCompilerTool"

+						UsePrecompiledHeader="0"

+					/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Support Files"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath=".\StringServices.cpp"

+				>

+			</File>

+			<File

+				RelativePath=".\StringServices.h"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/DLLX/DNSSD.cpp b/mDNSWindows/DLLX/DNSSD.cpp
new file mode 100755
index 0000000..84a8206
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSD.cpp
@@ -0,0 +1,892 @@
+// DNSSD.cpp : Implementation of CDNSSD

+

+#include "stdafx.h"

+#include "DNSSD.h"

+#include "DNSSDService.h"

+#include "TXTRecord.h"

+#include <dns_sd.h>

+#include <CommonServices.h>

+#include <DebugServices.h>

+#include "StringServices.h"

+

+

+// CDNSSD

+

+STDMETHODIMP CDNSSD::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IBrowseListener* listener, IDNSSDService** browser )

+{

+	CComObject<CDNSSDService>	*	object		= NULL;

+	std::string						regtypeUTF8;

+	std::string						domainUTF8;

+	DNSServiceRef					sref		= NULL;

+	DNSServiceErrorType				err			= 0;

+	HRESULT							hr			= 0;

+	BOOL							ok;

+

+	// Initialize

+	*browser = NULL;

+

+	// Convert BSTR params to utf8

+	ok = BSTRToUTF8( regtype, regtypeUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+	ok = BSTRToUTF8( domain, domainUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	err = DNSServiceBrowse( &sref, flags, ifIndex, regtypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceBrowseReply ) &BrowseReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*browser = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IResolveListener* listener, IDNSSDService** service)

+{

+	CComObject<CDNSSDService>	*	object			= NULL;

+	std::string						serviceNameUTF8;

+	std::string						regTypeUTF8;

+	std::string						domainUTF8;

+	DNSServiceRef					sref			= NULL;

+	DNSServiceErrorType				err				= 0;

+	HRESULT							hr				= 0;

+	BOOL							ok;

+

+	// Initialize

+	*service = NULL;

+

+	// Convert BSTR params to utf8

+	ok = BSTRToUTF8( serviceName, serviceNameUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+	ok = BSTRToUTF8( regType, regTypeUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+	ok = BSTRToUTF8( domain, domainUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	err = DNSServiceResolve( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDomainListener *listener, IDNSSDService **service)

+{

+	CComObject<CDNSSDService>	*	object			= NULL;

+	DNSServiceRef					sref			= NULL;

+	DNSServiceErrorType				err				= 0;

+	HRESULT							hr				= 0;

+

+	// Initialize

+	*service = NULL;

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	err = DNSServiceEnumerateDomains( &sref, flags, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IRegisterListener *listener, IDNSSDService **service)

+{

+	CComObject<CDNSSDService>	*	object			= NULL;

+	std::string						serviceNameUTF8;

+	std::string						regTypeUTF8;

+	std::string						domainUTF8;

+	std::string						hostUTF8;

+	const void					*	txtRecord		= NULL;

+	uint16_t						txtLen			= 0;

+	DNSServiceRef					sref			= NULL;

+	DNSServiceErrorType				err				= 0;

+	HRESULT							hr				= 0;

+	BOOL							ok;

+

+	// Initialize

+	*service = NULL;

+

+	// Convert BSTR params to utf8

+	ok = BSTRToUTF8( serviceName, serviceNameUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+	ok = BSTRToUTF8( regType, regTypeUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+	ok = BSTRToUTF8( domain, domainUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+	ok = BSTRToUTF8( host, hostUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	if ( record )

+	{

+		CComObject< CTXTRecord > * realTXTRecord;

+

+		realTXTRecord = ( CComObject< CTXTRecord >* ) record;

+

+		txtRecord	= realTXTRecord->GetBytes();

+		txtLen		= realTXTRecord->GetLen();

+	}

+

+	err = DNSServiceRegister( &sref, flags, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), hostUTF8.c_str(), port, txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IQueryRecordListener *listener, IDNSSDService **service)

+{

+	CComObject<CDNSSDService>	*	object			= NULL;

+	DNSServiceRef					sref			= NULL;

+	std::string						fullNameUTF8;

+	DNSServiceErrorType				err				= 0;

+	HRESULT							hr				= 0;

+	BOOL							ok;

+

+	// Initialize

+	*service = NULL;

+

+	// Convert BSTR params to utf8

+	ok = BSTRToUTF8( fullname, fullNameUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	err = DNSServiceQueryRecord( &sref, flags, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IGetAddrInfoListener *listener, IDNSSDService **service)

+{

+	CComObject<CDNSSDService>	*	object			= NULL;

+	DNSServiceRef					sref			= NULL;

+	std::string						hostNameUTF8;

+	DNSServiceErrorType				err				= 0;

+	HRESULT							hr				= 0;

+	BOOL							ok;

+

+	// Initialize

+	*service = NULL;

+

+	// Convert BSTR params to utf8

+	ok = BSTRToUTF8( hostName, hostNameUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	err = DNSServiceGetAddrInfo( &sref, flags, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::CreateConnection(IDNSSDService **service)

+{

+	CComObject<CDNSSDService>	*	object	= NULL;

+	DNSServiceRef					sref	= NULL;

+	DNSServiceErrorType				err		= 0;

+	HRESULT							hr		= 0;

+

+	// Initialize

+	*service = NULL;

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	err = DNSServiceCreateConnection( &sref );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, INATPortMappingListener *listener, IDNSSDService **service)

+{

+	CComObject<CDNSSDService>	*	object			= NULL;

+	DNSServiceRef					sref			= NULL;

+	DNSServiceProtocol				prot			= 0;

+	DNSServiceErrorType				err				= 0;

+	HRESULT							hr				= 0;

+

+	// Initialize

+	*service = NULL;

+

+	try

+	{

+		object = new CComObject<CDNSSDService>();

+	}

+	catch ( ... )

+	{

+		object = NULL;

+	}

+

+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );

+	hr = object->FinalConstruct();

+	require_action( hr == S_OK, exit, err = kDNSServiceErr_Unknown );

+	object->AddRef();

+

+	prot = ( addressFamily | protocol );

+

+	err = DNSServiceNATPortMappingCreate( &sref, flags, ifIndex, prot, internalPort, externalPort, ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );

+	require_noerr( err, exit );

+

+	object->SetServiceRef( sref );

+	object->SetListener( listener );

+

+	err = object->Run();

+	require_noerr( err, exit );

+

+	*service = object;

+

+exit:

+

+	if ( err && object )

+	{

+		object->Release();

+	}

+

+	return err;

+}

+

+

+STDMETHODIMP CDNSSD::GetProperty(BSTR prop, VARIANT * value )

+{

+	std::string			propUTF8;

+	std::vector< BYTE >	byteArray;

+	SAFEARRAY		*	psa			= NULL;

+	BYTE			*	pData		= NULL;

+	uint32_t			elems		= 0;

+	DNSServiceErrorType	err			= 0;

+	BOOL				ok = TRUE;

+

+	// Convert BSTR params to utf8

+	ok = BSTRToUTF8( prop, propUTF8 );

+	require_action( ok, exit, err = kDNSServiceErr_BadParam );

+

+	// Setup the byte array

+	require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );

+	psa = V_ARRAY( value );

+	require_action( psa, exit, err = kDNSServiceErr_Unknown );

+	require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );

+	byteArray.reserve( psa->rgsabound[0].cElements );

+	byteArray.assign( byteArray.capacity(), 0 );

+	elems = ( uint32_t ) byteArray.capacity();

+

+	// Call the function and package the return value in the Variant

+	err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );

+	require_noerr( err, exit );

+	ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );

+	require_action( ok, exit, err = kDNSSDError_Unknown );

+

+exit:

+

+	if ( psa )

+	{

+		SafeArrayUnaccessData( psa );

+		psa = NULL;

+	}

+

+	return err;

+}

+

+

+void DNSSD_API
+CDNSSD::DomainEnumReply
+    (
+    DNSServiceRef                       sdRef,
+    DNSServiceFlags                     flags,
+    uint32_t                            ifIndex,
+    DNSServiceErrorType                 errorCode,
+    const char                          *replyDomainUTF8,
+    void                                *context
+    )

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		IDomainListener	* listener;

+

+		listener = ( IDomainListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			CComBSTR replyDomain;

+		

+			UTF8ToBSTR( replyDomainUTF8, replyDomain );

+

+			if ( flags & kDNSServiceFlagsAdd )

+			{

+				listener->DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );

+			}

+			else

+			{

+				listener->DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );

+			}

+		}

+		else

+		{

+			listener->EnumDomainsFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

+

+void DNSSD_API
+CDNSSD::BrowseReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *serviceNameUTF8,
+		const char                          *regTypeUTF8,
+		const char                          *replyDomainUTF8,
+		void                                *context
+		)

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		IBrowseListener	* listener;

+

+		listener = ( IBrowseListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			CComBSTR	serviceName;

+			CComBSTR	regType;

+			CComBSTR	replyDomain;

+		

+			UTF8ToBSTR( serviceNameUTF8, serviceName );

+			UTF8ToBSTR( regTypeUTF8, regType );

+			UTF8ToBSTR( replyDomainUTF8, replyDomain );

+

+			if ( flags & kDNSServiceFlagsAdd )

+			{

+				listener->ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );

+			}

+			else

+			{

+				listener->ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );

+			}

+		}

+		else

+		{

+			listener->BrowseFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

+

+void DNSSD_API

+CDNSSD::ResolveReply

+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *fullNameUTF8,
+		const char                          *hostNameUTF8,
+		uint16_t                            port,
+		uint16_t                            txtLen,
+		const unsigned char                 *txtRecord,
+		void                                *context

+		)

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		IResolveListener * listener;

+

+		listener = ( IResolveListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			CComBSTR					fullName;

+			CComBSTR					hostName;

+			CComBSTR					regType;

+			CComBSTR					replyDomain;

+			CComObject< CTXTRecord >*	record;

+			BOOL						ok;

+

+			ok = UTF8ToBSTR( fullNameUTF8, fullName );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+			ok = UTF8ToBSTR( hostNameUTF8, hostName );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+

+			try

+			{

+				record = new CComObject<CTXTRecord>();

+			}

+			catch ( ... )

+			{

+				record = NULL;

+			}

+

+			require_action( record, exit, err = kDNSServiceErr_NoMemory );

+			record->AddRef();

+

+			char buf[ 64 ];

+			sprintf( buf, "txtLen = %d", txtLen );

+			OutputDebugStringA( buf );

+

+			if ( txtLen > 0 )

+			{

+				record->SetBytes( txtRecord, txtLen );

+			}

+

+			listener->ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, port, record );

+		}

+		else

+		{

+			listener->ResolveFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

+

+void DNSSD_API
+CDNSSD::RegisterReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		DNSServiceErrorType                 errorCode,
+		const char                          *serviceNameUTF8,
+		const char                          *regTypeUTF8,
+		const char                          *domainUTF8,
+		void                                *context
+		)

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		IRegisterListener * listener;

+

+		listener = ( IRegisterListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			CComBSTR					serviceName;

+			CComBSTR					regType;

+			CComBSTR					domain;

+			BOOL						ok;

+

+			ok = UTF8ToBSTR( serviceNameUTF8, serviceName );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+			ok = UTF8ToBSTR( regTypeUTF8, regType );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+			ok = UTF8ToBSTR( domainUTF8, domain );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+

+			listener->ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );

+		}

+		else

+		{

+			listener->ServiceRegisterFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

+

+void DNSSD_API
+CDNSSD::QueryRecordReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *fullNameUTF8,
+		uint16_t                            rrtype,
+		uint16_t                            rrclass,
+		uint16_t                            rdlen,
+		const void                          *rdata,
+		uint32_t                            ttl,
+		void                                *context
+		)

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		IQueryRecordListener * listener;

+

+		listener = ( IQueryRecordListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			CComBSTR	fullName;

+			VARIANT		var;

+			BOOL		ok;

+

+			ok = UTF8ToBSTR( fullNameUTF8, fullName );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+			ok = ByteArrayToVariant( rdata, rdlen, &var );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+

+			listener->QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );

+		}

+		else

+		{

+			listener->QueryRecordFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

+

+void DNSSD_API
+CDNSSD::GetAddrInfoReply
+		(
+		DNSServiceRef                    sdRef,
+		DNSServiceFlags                  flags,
+		uint32_t                         ifIndex,
+		DNSServiceErrorType              errorCode,
+		const char                       *hostNameUTF8,
+		const struct sockaddr            *rawAddress,
+		uint32_t                         ttl,
+		void                             *context
+		)

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		IGetAddrInfoListener * listener;

+

+		listener = ( IGetAddrInfoListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			CComBSTR			hostName;

+			DWORD				sockaddrLen;

+			DNSSDAddressFamily	addressFamily;

+			char				addressUTF8[INET6_ADDRSTRLEN];

+			DWORD				addressLen = sizeof( addressUTF8 );

+			CComBSTR			address;

+			BOOL				ok;

+

+			ok = UTF8ToBSTR( hostNameUTF8, hostName );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+

+			switch ( rawAddress->sa_family )

+			{

+				case AF_INET:

+				{

+					addressFamily	= kDNSSDAddressFamily_IPv4;

+					sockaddrLen		= sizeof( sockaddr_in );

+				}

+				break;

+

+				case AF_INET6:

+				{

+					addressFamily	= kDNSSDAddressFamily_IPv6;

+					sockaddrLen		= sizeof( sockaddr_in6 );

+				}

+				break;

+			}

+

+			err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );

+			require_noerr( err, exit );

+			ok = UTF8ToBSTR( addressUTF8, address );

+			require_action( ok, exit, err = kDNSServiceErr_Unknown );

+

+			listener->GetAddrInfoReply( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );

+		}

+		else

+		{

+			listener->GetAddrInfoFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

+

+void DNSSD_API
+CDNSSD::NATPortMappingReply
+    (
+    DNSServiceRef                    sdRef,
+    DNSServiceFlags                  flags,
+    uint32_t                         ifIndex,
+    DNSServiceErrorType              errorCode,
+    uint32_t                         externalAddress,   /* four byte IPv4 address in network byte order */
+    DNSServiceProtocol               protocol,
+    uint16_t                         internalPort,
+    uint16_t                         externalPort,      /* may be different than the requested port     */
+    uint32_t                         ttl,               /* may be different than the requested ttl      */
+    void                             *context
+    )

+{

+	CComObject<CDNSSDService> * service;

+	int err;

+	

+	service = ( CComObject< CDNSSDService>* ) context;

+	require_action( service, exit, err = kDNSServiceErr_Unknown );

+

+	if ( !service->Stopped() )

+	{

+		INATPortMappingListener * listener;

+

+		listener = ( INATPortMappingListener* ) service->GetListener();

+		require_action( listener, exit, err = kDNSServiceErr_Unknown );

+

+		if ( !errorCode )

+		{

+			listener->MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), internalPort, externalPort, ttl  );

+		}

+		else

+		{

+			listener->MappingFailed( service, ( DNSSDError ) errorCode );

+		}

+	}

+

+exit:

+

+	return;

+}

+

diff --git a/mDNSWindows/DLLX/DNSSDEventManager.cpp b/mDNSWindows/DLLX/DNSSDEventManager.cpp
new file mode 100755
index 0000000..310ced0
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDEventManager.cpp
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#include "stdafx.h"
+
+#include "DNSSDEventManager.h"
+
+
+
+
+
+// CDNSSDEventManager
+
+
+
diff --git a/mDNSWindows/DLLX/DNSSDEventManager.h b/mDNSWindows/DLLX/DNSSDEventManager.h
new file mode 100755
index 0000000..70aedfc
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDEventManager.h
@@ -0,0 +1,133 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma once
+
+#include "resource.h"       // main symbols
+
+
+
+#include "DLLX.h"
+
+#include "_IDNSSDEvents_CP.H"
+
+
+
+
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
+
+#endif
+
+
+
+
+
+
+
+// CDNSSDEventManager
+
+
+
+class ATL_NO_VTABLE CDNSSDEventManager :
+
+	public CComObjectRootEx<CComSingleThreadModel>,
+
+	public CComCoClass<CDNSSDEventManager, &CLSID_DNSSDEventManager>,
+
+	public IConnectionPointContainerImpl<CDNSSDEventManager>,
+
+	public CProxy_IDNSSDEvents<CDNSSDEventManager>,
+
+	public IDispatchImpl<IDNSSDEventManager, &IID_IDNSSDEventManager, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>
+
+{
+
+public:
+
+	CDNSSDEventManager()
+
+	{
+
+	}
+
+
+
+DECLARE_REGISTRY_RESOURCEID(IDR_DNSSDEVENTMANAGER)
+
+
+
+
+
+BEGIN_COM_MAP(CDNSSDEventManager)
+
+	COM_INTERFACE_ENTRY(IDNSSDEventManager)
+
+	COM_INTERFACE_ENTRY(IDispatch)
+
+	COM_INTERFACE_ENTRY(IConnectionPointContainer)
+
+END_COM_MAP()
+
+
+
+BEGIN_CONNECTION_POINT_MAP(CDNSSDEventManager)
+
+	CONNECTION_POINT_ENTRY(__uuidof(_IDNSSDEvents))
+
+END_CONNECTION_POINT_MAP()
+
+
+
+
+
+	DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+
+
+	HRESULT FinalConstruct()
+
+	{
+
+		return S_OK;
+
+	}
+
+
+
+	void FinalRelease()
+
+	{
+
+	}
+
+
+
+public:
+
+
+
+};
+
+
+
+OBJECT_ENTRY_AUTO(__uuidof(DNSSDEventManager), CDNSSDEventManager)
+
diff --git a/mDNSWindows/DLLX/DNSSDEventManager.rgs b/mDNSWindows/DLLX/DNSSDEventManager.rgs
new file mode 100755
index 0000000..9103512
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDEventManager.rgs
@@ -0,0 +1,27 @@
+HKCR

+{

+	Bonjour.DNSSDEventManager.1 = s 'DNSSDEventManager Class'

+	{

+		CLSID = s '{BEEB932A-8D4A-4619-AEFE-A836F988B221}'

+	}

+	Bonjour.DNSSDEventManager = s 'DNSSDEventManager Class'

+	{

+		CLSID = s '{BEEB932A-8D4A-4619-AEFE-A836F988B221}'

+		CurVer = s 'Bonjour.DNSSDEventManager.1'

+	}

+	NoRemove CLSID

+	{

+		ForceRemove {BEEB932A-8D4A-4619-AEFE-A836F988B221} = s 'DNSSDEventManager Class'

+		{

+			ProgID = s 'Bonjour.DNSSDEventManager.1'

+			VersionIndependentProgID = s 'Bonjour.DNSSDEventManager'

+			ForceRemove 'Programmable'

+			InprocServer32 = s '%MODULE%'

+			{

+				val ThreadingModel = s 'Apartment'

+			}

+			val AppID = s '%APPID%'

+			'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'

+		}

+	}

+}

diff --git a/mDNSWindows/DLLX/DNSSDRecord.cpp b/mDNSWindows/DLLX/DNSSDRecord.cpp
new file mode 100755
index 0000000..a272720
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDRecord.cpp
@@ -0,0 +1,101 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#include "stdafx.h"
+
+#include "DNSSDRecord.h"
+
+#include "StringServices.h"
+
+#include <DebugServices.h>
+
+
+
+
+
+// CDNSSDRecord
+
+
+
+STDMETHODIMP CDNSSDRecord::Update(DNSSDFlags flags, VARIANT rdata, ULONG ttl)
+
+{
+
+	std::vector< BYTE >	byteArray;
+
+	const void		*	byteArrayPtr	= NULL;
+
+	DNSServiceErrorType	err				= 0;
+
+	HRESULT				hr				= 0;
+
+	BOOL				ok;
+
+
+
+	// Convert the VARIANT
+
+	ok = VariantToByteArray( &rdata, byteArray );
+
+	require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	err = DNSServiceUpdateRecord( m_serviceObject->GetSubordRef(), m_rref, flags, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl );
+
+	require_noerr( err, exit );
+
+
+
+exit:
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDRecord::Remove(DNSSDFlags flags)
+
+{
+
+	DNSServiceErrorType	err = 0;
+
+
+
+	err = DNSServiceRemoveRecord( m_serviceObject->GetSubordRef(), m_rref, flags );
+
+	require_noerr( err, exit );
+
+
+
+exit:
+
+
+
+	return err;
+
+}
+
+
+
diff --git a/mDNSWindows/DLLX/DNSSDRecord.h b/mDNSWindows/DLLX/DNSSDRecord.h
new file mode 100755
index 0000000..bdedda5
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDRecord.h
@@ -0,0 +1,185 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma once
+
+#include "resource.h"       // main symbols
+
+
+
+#include "DLLX.h"
+
+#include "DNSSDService.h"
+
+#include <dns_sd.h>
+
+
+
+
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
+
+#endif
+
+
+
+
+
+
+
+// CDNSSDRecord
+
+
+
+class ATL_NO_VTABLE CDNSSDRecord :
+
+	public CComObjectRootEx<CComSingleThreadModel>,
+
+	public CComCoClass<CDNSSDRecord, &CLSID_DNSSDRecord>,
+
+	public IDispatchImpl<IDNSSDRecord, &IID_IDNSSDRecord, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>
+
+{
+
+public:
+
+	CDNSSDRecord()
+
+	{
+
+	}
+
+
+
+DECLARE_REGISTRY_RESOURCEID(IDR_DNSSDRECORD)
+
+
+
+
+
+BEGIN_COM_MAP(CDNSSDRecord)
+
+	COM_INTERFACE_ENTRY(IDNSSDRecord)
+
+	COM_INTERFACE_ENTRY(IDispatch)
+
+END_COM_MAP()
+
+
+
+
+
+
+
+	DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+
+
+	HRESULT FinalConstruct()
+
+	{
+
+		return S_OK;
+
+	}
+
+
+
+	void FinalRelease()
+
+	{
+
+	}
+
+
+
+	inline CDNSSDService*
+
+	GetServiceObject()
+
+	{
+
+		return m_serviceObject;
+
+	}
+
+
+
+	inline void
+
+	SetServiceObject( CDNSSDService * serviceObject )
+
+	{
+
+		m_serviceObject = serviceObject;
+
+	}
+
+
+
+	inline DNSRecordRef
+
+	GetRecordRef()
+
+	{
+
+		return m_rref;
+
+	}
+
+
+
+	inline void
+
+	SetRecordRef( DNSRecordRef rref )
+
+	{
+
+		m_rref = rref;
+
+	}
+
+
+
+public:
+
+
+
+	STDMETHOD(Update)(DNSSDFlags flags, VARIANT rdata, ULONG ttl);
+
+	STDMETHOD(Remove)(DNSSDFlags flags);
+
+
+
+private:
+
+
+
+	CDNSSDService *	m_serviceObject;
+
+	DNSRecordRef	m_rref;
+
+};
+
+
+
+OBJECT_ENTRY_AUTO(__uuidof(DNSSDRecord), CDNSSDRecord)
+
diff --git a/mDNSWindows/DLLX/DNSSDRecord.rgs b/mDNSWindows/DLLX/DNSSDRecord.rgs
new file mode 100755
index 0000000..ee0a5a2
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDRecord.rgs
@@ -0,0 +1,27 @@
+HKCR

+{

+	Bonjour.DNSSDRecord.1 = s 'DNSSDRecord Class'

+	{

+		CLSID = s '{5E93C5A9-7516-4259-A67B-41A656F6E01C}'

+	}

+	Bonjour.DNSSDRecord = s 'DNSSDRecord Class'

+	{

+		CLSID = s '{5E93C5A9-7516-4259-A67B-41A656F6E01C}'

+		CurVer = s 'Bonjour.DNSSDRecord.1'

+	}

+	NoRemove CLSID

+	{

+		ForceRemove {5E93C5A9-7516-4259-A67B-41A656F6E01C} = s 'DNSSDRecord Class'

+		{

+			ProgID = s 'Bonjour.DNSSDRecord.1'

+			VersionIndependentProgID = s 'Bonjour.DNSSDRecord'

+			ForceRemove 'Programmable'

+			InprocServer32 = s '%MODULE%'

+			{

+				val ThreadingModel = s 'Apartment'

+			}

+			val AppID = s '%APPID%'

+			'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'

+		}

+	}

+}

diff --git a/mDNSWindows/DLLX/DNSSDService.cpp b/mDNSWindows/DLLX/DNSSDService.cpp
new file mode 100755
index 0000000..b8ce49b
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDService.cpp
@@ -0,0 +1,2095 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma warning(disable:4995)
+
+
+
+#include "stdafx.h"
+
+#include <strsafe.h>
+
+#include "DNSSDService.h"
+
+#include "DNSSDEventManager.h"
+
+#include "DNSSDRecord.h"
+
+#include "TXTRecord.h"
+
+#include "StringServices.h"
+
+#include <DebugServices.h>
+
+
+
+
+
+#define WM_SOCKET (WM_APP + 100)
+
+
+
+
+
+// CDNSSDService
+
+
+
+BOOL						CDNSSDService::m_registeredWindowClass	= FALSE;
+
+HWND						CDNSSDService::m_hiddenWindow			= NULL;
+
+CDNSSDService::SocketMap	CDNSSDService::m_socketMap;
+
+
+
+
+
+HRESULT CDNSSDService::FinalConstruct()
+
+{
+
+	DNSServiceErrorType	err	= 0;
+
+	HRESULT				hr	= S_OK;
+
+
+
+	m_isPrimary = TRUE;
+
+	err = DNSServiceCreateConnection( &m_primary );
+
+	require_action( !err, exit, hr = E_FAIL );
+
+
+
+	if ( !m_hiddenWindow )
+
+	{
+
+		TCHAR windowClassName[ 256 ];
+
+
+
+		StringCchPrintf( windowClassName, sizeof( windowClassName ) / sizeof( TCHAR ), TEXT( "Bonjour Hidden Window %d" ), GetProcessId( NULL ) );
+
+
+
+		if ( !m_registeredWindowClass )
+
+		{
+
+			WNDCLASS	wc;
+
+			ATOM		atom;
+
+
+
+			wc.style			= 0;
+
+			wc.lpfnWndProc		= WndProc;
+
+			wc.cbClsExtra		= 0;
+
+			wc.cbWndExtra		= 0;
+
+			wc.hInstance		= NULL;
+
+			wc.hIcon			= NULL;
+
+			wc.hCursor			= NULL;
+
+			wc.hbrBackground	= NULL;
+
+			wc.lpszMenuName		= NULL;
+
+			wc.lpszClassName	= windowClassName;
+
+
+
+			atom = RegisterClass(&wc);
+
+			require_action( atom != NULL, exit, hr = E_FAIL );
+
+
+
+			m_registeredWindowClass = TRUE;
+
+		}
+
+
+
+		m_hiddenWindow = CreateWindow( windowClassName, windowClassName, WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL, GetModuleHandle( NULL ), NULL );
+
+		require_action( m_hiddenWindow != NULL, exit, hr = E_FAIL );
+
+	}
+
+
+
+	err = WSAAsyncSelect( DNSServiceRefSockFD( m_primary ), m_hiddenWindow, WM_SOCKET, FD_READ );
+
+	require_action( !err, exit, hr = E_FAIL );
+
+
+
+	m_socketMap[ DNSServiceRefSockFD( m_primary ) ] = this;
+
+
+
+exit:
+
+
+
+	return hr;
+
+}
+
+
+
+
+
+void CDNSSDService::FinalRelease()
+
+{
+
+	dlog( kDebugLevelTrace, "FinalRelease()\n" ); 
+
+	Stop();
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::EnumerateDomains(DNSSDFlags flags, ULONG ifIndex, IDNSSDEventManager *eventManager, IDNSSDService **service)
+
+{
+
+	CComObject<CDNSSDService>	*	object	= NULL;
+
+	DNSServiceRef					subord	= NULL;
+
+	DNSServiceErrorType				err		= 0;
+
+	HRESULT							hr		= 0;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceEnumerateDomains( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, ( DNSServiceDomainEnumReply ) &DomainEnumReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::Browse(DNSSDFlags flags, ULONG ifIndex, BSTR regtype, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service )
+
+{
+
+	CComObject<CDNSSDService>	*	object		= NULL;
+
+	std::string						regtypeUTF8;
+
+	std::string						domainUTF8;
+
+	DNSServiceRef					subord		= NULL;
+
+	DNSServiceErrorType				err			= 0;
+
+	HRESULT							hr			= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( regtype, regtypeUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+	ok = BSTRToUTF8( domain, domainUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceBrowse( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, regtypeUTF8.c_str(), ( domainUTF8.size() > 0 ) ? domainUTF8.c_str() : NULL, ( DNSServiceBrowseReply ) &BrowseReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::Resolve(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service)
+
+{
+
+	CComObject<CDNSSDService>	*	object			= NULL;
+
+	std::string						serviceNameUTF8;
+
+	std::string						regTypeUTF8;
+
+	std::string						domainUTF8;
+
+	DNSServiceRef					subord			= NULL;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( serviceName, serviceNameUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+	ok = BSTRToUTF8( regType, regTypeUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+	ok = BSTRToUTF8( domain, domainUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceResolve( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), domainUTF8.c_str(), ( DNSServiceResolveReply ) &ResolveReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::Register(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IDNSSDEventManager *eventManager, IDNSSDService **service)
+
+{
+
+	CComObject<CDNSSDService>	*	object			= NULL;
+
+	std::string						serviceNameUTF8;
+
+	std::string						regTypeUTF8;
+
+	std::string						domainUTF8;
+
+	std::string						hostUTF8;
+
+	const void					*	txtRecord		= NULL;
+
+	uint16_t						txtLen			= 0;
+
+	DNSServiceRef					subord			= NULL;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( serviceName, serviceNameUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+	ok = BSTRToUTF8( regType, regTypeUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+	ok = BSTRToUTF8( domain, domainUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+	ok = BSTRToUTF8( host, hostUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	if ( record )
+
+	{
+
+		CComObject< CTXTRecord > * realTXTRecord;
+
+
+
+		realTXTRecord = ( CComObject< CTXTRecord >* ) record;
+
+
+
+		txtRecord	= realTXTRecord->GetBytes();
+
+		txtLen		= realTXTRecord->GetLen();
+
+	}
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceRegister( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, serviceNameUTF8.c_str(), regTypeUTF8.c_str(), ( domainUTF8.size() > 0 ) ? domainUTF8.c_str() : NULL, hostUTF8.c_str(), htons( port ), txtLen, txtRecord, ( DNSServiceRegisterReply ) &RegisterReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::QueryRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IDNSSDEventManager *eventManager, IDNSSDService **service)
+
+{
+
+	CComObject<CDNSSDService>	*	object			= NULL;
+
+	DNSServiceRef					subord			= NULL;
+
+	std::string						fullNameUTF8;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( fullname, fullNameUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceQueryRecord( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, fullNameUTF8.c_str(), ( uint16_t ) rrtype, ( uint16_t ) rrclass, ( DNSServiceQueryRecordReply ) &QueryRecordReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::RegisterRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata, ULONG ttl, IDNSSDEventManager* eventManager, IDNSSDRecord** record)
+
+{
+
+	CComObject<CDNSSDRecord>	*	object			= NULL;
+
+	DNSRecordRef					rref			= NULL;
+
+	std::string						fullNameUTF8;
+
+	std::vector< BYTE >				byteArray;
+
+	const void					*	byteArrayPtr	= NULL;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*object = NULL;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( fullName, fullNameUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	// Convert the VARIANT
+
+	ok = VariantToByteArray( &rdata, byteArray );
+
+	require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDRecord>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	err = DNSServiceRegisterRecord( m_primary, &rref, flags, ifIndex, fullNameUTF8.c_str(), rrtype, rrclass, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl, &RegisterRecordReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetServiceObject( this );
+
+	object->SetRecordRef( rref );
+
+	this->SetEventManager( eventManager );
+
+
+
+	*record = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::AddRecord(DNSSDFlags flags, DNSSDRRType rrtype, VARIANT rdata, ULONG ttl, IDNSSDRecord ** record)
+
+{
+
+	CComObject<CDNSSDRecord>	*	object			= NULL;
+
+	DNSRecordRef					rref			= NULL;
+
+	std::vector< BYTE >				byteArray;
+
+	const void					*	byteArrayPtr	= NULL;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*object = NULL;
+
+
+
+	// Convert the VARIANT
+
+	ok = VariantToByteArray( &rdata, byteArray );
+
+	require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDRecord>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	err = DNSServiceAddRecord( m_primary, &rref, flags, rrtype, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL, ttl );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetServiceObject( this );
+
+	object->SetRecordRef( rref );
+
+
+
+	*record = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+STDMETHODIMP CDNSSDService::ReconfirmRecord(DNSSDFlags flags, ULONG ifIndex, BSTR fullName, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata)
+
+{
+
+	std::string						fullNameUTF8;
+
+	std::vector< BYTE >				byteArray;
+
+	const void					*	byteArrayPtr	= NULL;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( fullName, fullNameUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	// Convert the VARIANT
+
+	ok = VariantToByteArray( &rdata, byteArray );
+
+	require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	err = DNSServiceReconfirmRecord( flags, ifIndex, fullNameUTF8.c_str(), rrtype, rrclass, ( uint16_t ) byteArray.size(), byteArray.size() > 0 ? &byteArray[ 0 ] : NULL );
+
+	require_noerr( err, exit );
+
+
+
+exit:
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::GetProperty(BSTR prop, VARIANT * value )
+
+{
+
+	std::string			propUTF8;
+
+	std::vector< BYTE >	byteArray;
+
+	SAFEARRAY		*	psa			= NULL;
+
+	BYTE			*	pData		= NULL;
+
+	uint32_t			elems		= 0;
+
+	DNSServiceErrorType	err			= 0;
+
+	BOOL				ok = TRUE;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( prop, propUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	// Setup the byte array
+
+	require_action( V_VT( value ) == ( VT_ARRAY|VT_UI1 ), exit, err = kDNSServiceErr_Unknown );
+
+	psa = V_ARRAY( value );
+
+	require_action( psa, exit, err = kDNSServiceErr_Unknown );
+
+	require_action( SafeArrayGetDim( psa ) == 1, exit, err = kDNSServiceErr_Unknown );
+
+	byteArray.reserve( psa->rgsabound[0].cElements );
+
+	byteArray.assign( byteArray.capacity(), 0 );
+
+	elems = ( uint32_t ) byteArray.capacity();
+
+
+
+	// Call the function and package the return value in the Variant
+
+	err = DNSServiceGetProperty( propUTF8.c_str(), &byteArray[ 0 ], &elems );
+
+	require_noerr( err, exit );
+
+	ok = ByteArrayToVariant( &byteArray[ 0 ], elems, value );
+
+	require_action( ok, exit, err = kDNSSDError_Unknown );
+
+
+
+exit:
+
+
+
+	if ( psa )
+
+	{
+
+		SafeArrayUnaccessData( psa );
+
+		psa = NULL;
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+STDMETHODIMP CDNSSDService::GetAddrInfo(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostName, IDNSSDEventManager *eventManager, IDNSSDService **service)
+
+{
+
+	CComObject<CDNSSDService>	*	object			= NULL;
+
+	DNSServiceRef					subord			= NULL;
+
+	std::string						hostNameUTF8;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+	BOOL							ok;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	// Convert BSTR params to utf8
+
+	ok = BSTRToUTF8( hostName, hostNameUTF8 );
+
+	require_action( ok, exit, err = kDNSServiceErr_BadParam );
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceGetAddrInfo( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, addressFamily, hostNameUTF8.c_str(), ( DNSServiceGetAddrInfoReply ) &GetAddrInfoReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::NATPortMappingCreate(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, IDNSSDEventManager *eventManager, IDNSSDService **service)
+
+{
+
+	CComObject<CDNSSDService>	*	object			= NULL;
+
+	DNSServiceRef					subord			= NULL;
+
+	DNSServiceProtocol				prot			= 0;
+
+	DNSServiceErrorType				err				= 0;
+
+	HRESULT							hr				= 0;
+
+
+
+	check( m_primary );
+
+
+
+	// Initialize
+
+	*service = NULL;
+
+
+
+	try
+
+	{
+
+		object = new CComObject<CDNSSDService>();
+
+	}
+
+	catch ( ... )
+
+	{
+
+		object = NULL;
+
+	}
+
+
+
+	require_action( object != NULL, exit, err = kDNSServiceErr_NoMemory );
+
+	object->AddRef();
+
+
+
+	prot = ( addressFamily | protocol );
+
+
+
+	subord = m_primary;
+
+	err = DNSServiceNATPortMappingCreate( &subord, flags | kDNSServiceFlagsShareConnection, ifIndex, prot, htons( internalPort ), htons( externalPort ), ttl, ( DNSServiceNATPortMappingReply ) &NATPortMappingReply, object );
+
+	require_noerr( err, exit );
+
+
+
+	object->SetPrimaryRef( m_primary );
+
+	object->SetSubordRef( subord );
+
+	object->SetEventManager( eventManager );
+
+
+
+	*service = object;
+
+
+
+exit:
+
+
+
+	if ( err && object )
+
+	{
+
+		object->Release();
+
+	}
+
+
+
+	return err;
+
+}
+
+
+
+
+
+STDMETHODIMP CDNSSDService::Stop(void)
+
+{
+
+	if ( !m_stopped )
+
+	{
+
+		m_stopped = TRUE;
+
+
+
+		dlog( kDebugLevelTrace, "Stop()\n" );
+
+
+
+		if ( m_isPrimary && m_primary )
+
+		{
+
+			SocketMap::iterator it;
+
+
+
+			if ( m_hiddenWindow )
+
+			{
+
+				WSAAsyncSelect( DNSServiceRefSockFD( m_primary ), m_hiddenWindow, 0, 0 );
+
+			}
+
+
+
+			it = m_socketMap.find( DNSServiceRefSockFD( m_primary ) );
+
+
+
+			if ( it != m_socketMap.end() )
+
+			{
+
+				m_socketMap.erase( it );
+
+			}
+
+
+
+			DNSServiceRefDeallocate( m_primary );
+
+			m_primary = NULL;
+
+		}
+
+		else if ( m_subord )
+
+		{
+
+			DNSServiceRefDeallocate( m_subord );
+
+			m_subord = NULL;
+
+		}
+
+
+
+		if ( m_eventManager != NULL )
+
+		{
+
+			m_eventManager->Release();
+
+			m_eventManager = NULL;
+
+		}
+
+	}
+
+
+
+	return S_OK;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::DomainEnumReply
+    (
+    DNSServiceRef                       sdRef,
+    DNSServiceFlags                     flags,
+    uint32_t                            ifIndex,
+    DNSServiceErrorType                 errorCode,
+    const char                          *replyDomainUTF8,
+    void                                *context
+    )
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		CComBSTR replyDomain;
+
+		BOOL ok;
+
+		
+
+		ok = UTF8ToBSTR( replyDomainUTF8, replyDomain );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+		if ( flags & kDNSServiceFlagsAdd )
+
+		{
+
+			eventManager->Fire_DomainFound( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );
+
+		}
+
+		else
+
+		{
+
+			eventManager->Fire_DomainLost( service, ( DNSSDFlags ) flags, ifIndex, replyDomain );
+
+		}
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::BrowseReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *serviceNameUTF8,
+		const char                          *regTypeUTF8,
+		const char                          *replyDomainUTF8,
+		void                                *context
+		)
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		CComBSTR	serviceName;
+
+		CComBSTR	regType;
+
+		CComBSTR	replyDomain;
+
+	
+
+		UTF8ToBSTR( serviceNameUTF8, serviceName );
+
+		UTF8ToBSTR( regTypeUTF8, regType );
+
+		UTF8ToBSTR( replyDomainUTF8, replyDomain );
+
+
+
+		if ( flags & kDNSServiceFlagsAdd )
+
+		{
+
+			eventManager->Fire_ServiceFound( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );
+
+		}
+
+		else
+
+		{
+
+			eventManager->Fire_ServiceLost( service, ( DNSSDFlags ) flags, ifIndex, serviceName, regType, replyDomain );
+
+		}
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+
+CDNSSDService::ResolveReply
+
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *fullNameUTF8,
+		const char                          *hostNameUTF8,
+		uint16_t                            port,
+		uint16_t                            txtLen,
+		const unsigned char                 *txtRecord,
+		void                                *context
+
+		)
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		CComBSTR					fullName;
+
+		CComBSTR					hostName;
+
+		CComBSTR					regType;
+
+		CComBSTR					replyDomain;
+
+		CComObject< CTXTRecord >*	record;
+
+		BOOL						ok;
+
+
+
+		ok = UTF8ToBSTR( fullNameUTF8, fullName );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+		ok = UTF8ToBSTR( hostNameUTF8, hostName );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+		try
+
+		{
+
+			record = new CComObject<CTXTRecord>();
+
+		}
+
+		catch ( ... )
+
+		{
+
+			record = NULL;
+
+		}
+
+
+
+		require_action( record, exit, err = kDNSServiceErr_NoMemory );
+
+		record->AddRef();
+
+
+
+		if ( txtLen > 0 )
+
+		{
+
+			record->SetBytes( txtRecord, txtLen );
+
+		}
+
+
+
+		eventManager->Fire_ServiceResolved( service, ( DNSSDFlags ) flags, ifIndex, fullName, hostName, ntohs( port ), record );
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::RegisterReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		DNSServiceErrorType                 errorCode,
+		const char                          *serviceNameUTF8,
+		const char                          *regTypeUTF8,
+		const char                          *domainUTF8,
+		void                                *context
+		)
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		CComBSTR					serviceName;
+
+		CComBSTR					regType;
+
+		CComBSTR					domain;
+
+		BOOL						ok;
+
+
+
+		ok = UTF8ToBSTR( serviceNameUTF8, serviceName );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+		ok = UTF8ToBSTR( regTypeUTF8, regType );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+		ok = UTF8ToBSTR( domainUTF8, domain );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+		eventManager->Fire_ServiceRegistered( service, ( DNSSDFlags ) flags, serviceName, regType, domain );
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::QueryRecordReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *fullNameUTF8,
+		uint16_t                            rrtype,
+		uint16_t                            rrclass,
+		uint16_t                            rdlen,
+		const void                          *rdata,
+		uint32_t                            ttl,
+		void                                *context
+		)
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		CComBSTR	fullName;
+
+		VARIANT		var;
+
+		BOOL		ok;
+
+
+
+		ok = UTF8ToBSTR( fullNameUTF8, fullName );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+		ok = ByteArrayToVariant( rdata, rdlen, &var );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+		eventManager->Fire_QueryRecordAnswered( service, ( DNSSDFlags ) flags, ifIndex, fullName, ( DNSSDRRType ) rrtype, ( DNSSDRRClass ) rrclass, var, ttl );
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::GetAddrInfoReply
+		(
+		DNSServiceRef                    sdRef,
+		DNSServiceFlags                  flags,
+		uint32_t                         ifIndex,
+		DNSServiceErrorType              errorCode,
+		const char                       *hostNameUTF8,
+		const struct sockaddr            *rawAddress,
+		uint32_t                         ttl,
+		void                             *context
+		)
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		CComBSTR			hostName;
+
+		DWORD				sockaddrLen;
+
+		DNSSDAddressFamily	addressFamily;
+
+		char				addressUTF8[INET6_ADDRSTRLEN];
+
+		DWORD				addressLen = sizeof( addressUTF8 );
+
+		CComBSTR			address;
+
+		BOOL				ok;
+
+
+
+		ok = UTF8ToBSTR( hostNameUTF8, hostName );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+		switch ( rawAddress->sa_family )
+
+		{
+
+			case AF_INET:
+
+			{
+
+				addressFamily	= kDNSSDAddressFamily_IPv4;
+
+				sockaddrLen		= sizeof( sockaddr_in );
+
+			}
+
+			break;
+
+
+
+			case AF_INET6:
+
+			{
+
+				addressFamily	= kDNSSDAddressFamily_IPv6;
+
+				sockaddrLen		= sizeof( sockaddr_in6 );
+
+			}
+
+			break;
+
+		}
+
+
+
+		err = WSAAddressToStringA( ( LPSOCKADDR ) rawAddress, sockaddrLen, NULL, addressUTF8, &addressLen );
+
+		require_noerr( err, exit );
+
+		ok = UTF8ToBSTR( addressUTF8, address );
+
+		require_action( ok, exit, err = kDNSServiceErr_Unknown );
+
+
+
+		eventManager->Fire_AddressFound( service, ( DNSSDFlags ) flags, ifIndex, hostName, addressFamily, address, ttl );
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::NATPortMappingReply
+    (
+    DNSServiceRef                    sdRef,
+    DNSServiceFlags                  flags,
+    uint32_t                         ifIndex,
+    DNSServiceErrorType              errorCode,
+    uint32_t                         externalAddress,   /* four byte IPv4 address in network byte order */
+    DNSServiceProtocol               protocol,
+    uint16_t                         internalPort,
+    uint16_t                         externalPort,      /* may be different than the requested port     */
+    uint32_t                         ttl,               /* may be different than the requested ttl      */
+    void                             *context
+    )
+
+{
+
+	CComObject<CDNSSDService>	* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	service = ( CComObject< CDNSSDService>* ) context;
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		eventManager->Fire_MappingCreated( service, ( DNSSDFlags ) flags, ifIndex, externalAddress, ( DNSSDAddressFamily ) ( protocol & 0x8 ), ( DNSSDProtocol ) ( protocol & 0x80 ), ntohs( internalPort ), ntohs( externalPort ), ttl  );
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+void DNSSD_API
+CDNSSDService::RegisterRecordReply
+		(
+		DNSServiceRef		sdRef,
+		DNSRecordRef		RecordRef,
+		DNSServiceFlags		flags,
+		DNSServiceErrorType	errorCode,
+		void				*context
+		)
+
+{
+
+	CComObject<CDNSSDRecord>	* record		= NULL;
+
+	CDNSSDService				* service		= NULL;
+
+	CDNSSDEventManager			* eventManager	= NULL;
+
+	int err = 0;
+
+	
+
+	record = ( CComObject< CDNSSDRecord >* ) context;
+
+	require_action( record, exit, err = kDNSServiceErr_Unknown );
+
+	service = record->GetServiceObject();
+
+	require_action( service, exit, err = kDNSServiceErr_Unknown );
+
+
+
+	if ( service->ShouldHandleReply( errorCode, eventManager ) )
+
+	{
+
+		eventManager->Fire_RecordRegistered( record, ( DNSSDFlags ) flags );
+
+	}
+
+
+
+exit:
+
+
+
+	return;
+
+}
+
+
+
+
+
+BOOL
+
+CDNSSDService::ShouldHandleReply( DNSServiceErrorType errorCode, CDNSSDEventManager *& eventManager )
+
+{
+
+	BOOL ok = FALSE;
+
+
+
+	if ( !this->Stopped() )
+
+	{
+
+		eventManager = this->GetEventManager();
+
+		require_action( eventManager, exit, ok = FALSE );
+
+
+
+		if ( !errorCode )
+
+		{
+
+			ok = TRUE;
+
+		}
+
+		else
+
+		{
+
+			eventManager->Fire_OperationFailed( this, ( DNSSDError ) errorCode );
+
+		}
+
+	}
+
+
+
+exit:
+
+
+
+	return ok;
+
+}
+
+
+
+
+
+LRESULT CALLBACK
+
+CDNSSDService::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
+
+{
+
+	if ( msg == WM_SOCKET )
+
+	{
+
+		SocketMap::iterator it;
+
+			
+
+		it = m_socketMap.find( ( SOCKET ) wParam );
+
+		check( it != m_socketMap.end() );
+
+
+
+		if ( it != m_socketMap.end() )
+
+		{
+
+			DNSServiceProcessResult( it->second->m_primary );
+
+		}
+
+	}
+
+
+
+	return DefWindowProc(hWnd, msg, wParam, lParam);;
+
+}
+
diff --git a/mDNSWindows/DLLX/DNSSDService.h b/mDNSWindows/DLLX/DNSSDService.h
new file mode 100755
index 0000000..5eb8dcb
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDService.h
@@ -0,0 +1,429 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma once
+
+#include "resource.h"       // main symbols
+
+
+
+#include "DLLX.h"
+
+#include "DNSSDEventManager.h"
+
+#include <CommonServices.h>
+
+#include <DebugServices.h>
+
+#include <dns_sd.h>
+
+#include <map>
+
+
+
+
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
+
+#endif
+
+
+
+
+
+
+
+// CDNSSDService
+
+
+
+class ATL_NO_VTABLE CDNSSDService :
+
+	public CComObjectRootEx<CComSingleThreadModel>,
+
+	public CComCoClass<CDNSSDService, &CLSID_DNSSDService>,
+
+	public IDispatchImpl<IDNSSDService, &IID_IDNSSDService, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>
+
+{
+
+public:
+
+
+
+	typedef CComObjectRootEx<CComSingleThreadModel> Super;
+
+
+
+	CDNSSDService()
+
+	:
+
+		m_isPrimary( FALSE ),
+
+		m_eventManager( NULL ),
+
+		m_stopped( FALSE ),
+
+		m_primary( NULL ),
+
+		m_subord( NULL )
+
+	{
+
+	}
+
+
+
+DECLARE_REGISTRY_RESOURCEID(IDR_DNSSDSERVICE)
+
+
+
+
+
+BEGIN_COM_MAP(CDNSSDService)
+
+	COM_INTERFACE_ENTRY(IDNSSDService)
+
+	COM_INTERFACE_ENTRY(IDispatch)
+
+END_COM_MAP()
+
+
+
+	DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+
+
+	HRESULT
+
+	FinalConstruct();
+
+
+
+	void 
+
+	FinalRelease();
+
+
+
+public:
+
+
+
+	inline DNSServiceRef
+
+	GetPrimaryRef()
+
+	{
+
+		return m_primary;
+
+	}
+
+
+
+	inline void
+
+	SetPrimaryRef( DNSServiceRef primary )
+
+	{
+
+		m_primary = primary;
+
+	}
+
+
+
+	inline DNSServiceRef
+
+	GetSubordRef()
+
+	{
+
+		return m_subord;
+
+	}
+
+
+
+	inline void
+
+	SetSubordRef( DNSServiceRef subord )
+
+	{
+
+		m_subord = subord;
+
+	}
+
+
+
+	inline CDNSSDEventManager*
+
+	GetEventManager()
+
+	{
+
+		return m_eventManager;
+
+	}
+
+
+
+	inline void
+
+	SetEventManager( IDNSSDEventManager * eventManager )
+
+	{
+
+		if ( m_eventManager )
+
+		{
+
+			m_eventManager->Release();
+
+			m_eventManager = NULL;
+
+		}
+
+
+
+		if ( eventManager )
+
+		{
+
+			m_eventManager = dynamic_cast< CDNSSDEventManager* >( eventManager );
+
+			check( m_eventManager );
+
+			m_eventManager->AddRef();
+
+		}
+
+	}
+
+
+
+	inline BOOL
+
+	Stopped()
+
+	{
+
+		return m_stopped;
+
+	}
+
+
+
+private:
+
+
+
+	static void DNSSD_API
+	DomainEnumReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            ifIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *replyDomain,
+		void                                *context
+		);
+
+
+
+	static void DNSSD_API
+	BrowseReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *serviceName,
+		const char                          *regtype,
+		const char                          *replyDomain,
+		void                                *context
+		);
+
+
+
+	static void DNSSD_API
+
+	ResolveReply
+
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		uint32_t                            interfaceIndex,
+		DNSServiceErrorType                 errorCode,
+		const char                          *fullname,
+		const char                          *hosttarget,
+		uint16_t                            port,
+		uint16_t                            txtLen,
+		const unsigned char                 *txtRecord,
+		void                                *context
+
+		);
+
+
+
+	static void DNSSD_API
+	RegisterReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSServiceFlags                     flags,
+		DNSServiceErrorType                 errorCode,
+		const char                          *name,
+		const char                          *regtype,
+		const char                          *domain,
+		void                                *context
+		);
+
+
+
+	static void DNSSD_API
+	QueryRecordReply
+		(
+		DNSServiceRef                       sdRef,
+		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
+		);
+
+
+
+	static void DNSSD_API
+    GetAddrInfoReply
+		(
+		DNSServiceRef                    sdRef,
+		DNSServiceFlags                  flags,
+		uint32_t                         interfaceIndex,
+		DNSServiceErrorType              errorCode,
+		const char                       *hostname,
+		const struct sockaddr            *address,
+		uint32_t                         ttl,
+		void                             *context
+		);
+
+
+
+	static void DNSSD_API
+	NATPortMappingReply
+		(
+		DNSServiceRef                    sdRef,
+		DNSServiceFlags                  flags,
+		uint32_t                         interfaceIndex,
+		DNSServiceErrorType              errorCode,
+		uint32_t                         externalAddress,   /* four byte IPv4 address in network byte order */
+		DNSServiceProtocol               protocol,
+		uint16_t                         internalPort,
+		uint16_t                         externalPort,      /* may be different than the requested port     */
+		uint32_t                         ttl,               /* may be different than the requested ttl      */
+		void                             *context
+		);
+
+
+
+	static void DNSSD_API
+	RegisterRecordReply
+		(
+		DNSServiceRef                       sdRef,
+		DNSRecordRef                        RecordRef,
+		DNSServiceFlags                     flags,
+		DNSServiceErrorType                 errorCode,
+		void                                *context
+		);
+
+
+
+	inline BOOL
+
+	ShouldHandleReply( DNSServiceErrorType errorCode, CDNSSDEventManager *& eventManager );
+
+	
+
+	static LRESULT CALLBACK
+
+	WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
+
+
+
+	typedef std::map< SOCKET, CDNSSDService* > SocketMap;
+
+
+
+	static BOOL				m_registeredWindowClass;
+
+	static HWND				m_hiddenWindow;
+
+	static SocketMap		m_socketMap;
+
+	CDNSSDEventManager	*	m_eventManager;
+
+	BOOL					m_stopped;
+
+	BOOL					m_isPrimary;
+
+	DNSServiceRef			m_primary;
+
+	DNSServiceRef			m_subord;
+
+public:
+
+	STDMETHOD(EnumerateDomains)(DNSSDFlags flags, ULONG ifIndex, IDNSSDEventManager *eventManager, IDNSSDService **service);  
+
+	STDMETHOD(Browse)(DNSSDFlags flags, ULONG interfaceIndex, BSTR regtype, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** sdref);
+
+	STDMETHOD(Resolve)(DNSSDFlags flags, ULONG ifIndex, BSTR serviceName, BSTR regType, BSTR domain, IDNSSDEventManager* eventManager, IDNSSDService** service);
+
+	STDMETHOD(Register)(DNSSDFlags flags, ULONG ifIndex, BSTR name, BSTR regType, BSTR domain, BSTR host, USHORT port, ITXTRecord *record, IDNSSDEventManager *eventManager, IDNSSDService **service);
+
+	STDMETHOD(QueryRecord)(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, IDNSSDEventManager *eventManager, IDNSSDService **service);      
+
+	STDMETHOD(RegisterRecord)(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata, ULONG ttl, IDNSSDEventManager* eventManager, IDNSSDRecord** record);
+
+	STDMETHOD(AddRecord)(DNSSDFlags flags, DNSSDRRType rrtype, VARIANT rdata, ULONG ttl, IDNSSDRecord ** record);
+
+	STDMETHOD(ReconfirmRecord)(DNSSDFlags flags, ULONG ifIndex, BSTR fullname, DNSSDRRType rrtype, DNSSDRRClass rrclass, VARIANT rdata);
+
+	STDMETHOD(GetProperty)(BSTR prop, VARIANT * value);
+
+	STDMETHOD(GetAddrInfo)(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, BSTR hostname, IDNSSDEventManager *eventManager, IDNSSDService **service);      
+
+	STDMETHOD(NATPortMappingCreate)(DNSSDFlags flags, ULONG ifIndex, DNSSDAddressFamily addressFamily, DNSSDProtocol protocol, USHORT internalPort, USHORT externalPort, ULONG ttl, IDNSSDEventManager *eventManager, IDNSSDService **service);
+
+	STDMETHOD(Stop)(void);
+
+};
+
+
+
+OBJECT_ENTRY_AUTO(__uuidof(DNSSDService), CDNSSDService)
+
diff --git a/mDNSWindows/DLLX/DNSSDService.rgs b/mDNSWindows/DLLX/DNSSDService.rgs
new file mode 100755
index 0000000..8a84297
--- /dev/null
+++ b/mDNSWindows/DLLX/DNSSDService.rgs
@@ -0,0 +1,27 @@
+HKCR

+{

+	Bonjour.DNSSDService.1 = s 'DNSSDService Class'

+	{

+		CLSID = s '{24CD4DE9-FF84-4701-9DC1-9B69E0D1090A}'

+	}

+	Bonjour.DNSSDService = s 'DNSSDService Class'

+	{

+		CLSID = s '{24CD4DE9-FF84-4701-9DC1-9B69E0D1090A}'

+		CurVer = s 'Bonjour.DNSSDService.1'

+	}

+	NoRemove CLSID

+	{

+		ForceRemove {24CD4DE9-FF84-4701-9DC1-9B69E0D1090A} = s 'DNSSDService Class'

+		{

+			ProgID = s 'Bonjour.DNSSDService.1'

+			VersionIndependentProgID = s 'Bonjour.DNSSDService'

+			ForceRemove 'Programmable'

+			InprocServer32 = s '%MODULE%'

+			{

+				val ThreadingModel = s 'Apartment'

+			}

+			val AppID = s '%APPID%'

+			'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'

+		}

+	}

+}

diff --git a/mDNSWindows/DLLX/StringServices.cpp b/mDNSWindows/DLLX/StringServices.cpp
new file mode 100755
index 0000000..f00750d
--- /dev/null
+++ b/mDNSWindows/DLLX/StringServices.cpp
@@ -0,0 +1,344 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#include "StringServices.h"
+
+#include <DebugServices.h>
+
+
+
+
+
+extern BOOL
+
+BSTRToUTF8
+
+	(
+
+	BSTR			inString,
+
+	std::string	&	outString
+
+	)
+
+{
+
+	USES_CONVERSION;
+
+	
+
+	char	*	utf8String	= NULL;
+
+	OSStatus    err			= kNoErr;
+
+
+
+	outString = "";
+
+	if ( inString )
+
+	{
+		TCHAR	*	utf16String	= NULL;
+		size_t      size		= 0;
+
+
+		utf16String = OLE2T( inString );
+
+		require_action( utf16String != NULL, exit, err = kUnknownErr );
+
+
+
+		if ( wcslen( utf16String ) > 0 )
+
+		{
+
+			size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), NULL, 0, NULL, NULL );
+
+			err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+
+			require_noerr( err, exit );
+
+
+
+			try
+
+			{
+
+				utf8String = new char[ size + 1 ];
+
+			}
+
+			catch ( ... )
+
+			{
+
+				utf8String = NULL;
+
+			}
+
+
+
+			require_action( utf8String != NULL, exit, err = kNoMemoryErr );
+
+			size = (size_t) WideCharToMultiByte( CP_UTF8, 0, utf16String, ( int ) wcslen( utf16String ), utf8String, (int) size, NULL, NULL);
+
+			err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+
+			require_noerr( err, exit );
+
+
+
+			// have to add the trailing 0 because WideCharToMultiByte doesn't do it,
+
+			// although it does return the correct size
+
+
+
+			utf8String[size] = '\0';
+
+			outString = utf8String;
+
+		}
+	}
+
+
+
+exit:
+
+
+
+	if ( utf8String != NULL )
+
+	{
+
+		delete [] utf8String;
+
+	}
+
+
+
+	return ( !err ) ? TRUE : FALSE;
+
+}
+
+
+
+
+
+extern BOOL
+
+UTF8ToBSTR
+
+	(
+
+	const char	*	inString,
+
+	CComBSTR	&	outString
+
+	)
+
+{
+
+	wchar_t	*	unicode	= NULL;
+
+	OSStatus	err		= 0;
+
+
+
+	if ( inString )
+
+	{
+		int n;
+
+		n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, NULL, 0 );
+
+	    
+
+		if ( n > 0 )
+
+		{
+
+			try
+
+			{
+
+				unicode = new wchar_t[ n ];
+
+			}
+
+			catch ( ... )
+
+			{
+
+				unicode = NULL;
+
+			}
+
+
+
+			require_action( unicode, exit, err = ERROR_INSUFFICIENT_BUFFER );
+
+
+
+			n = MultiByteToWideChar( CP_UTF8, 0, inString, -1, unicode, n );
+
+		}
+
+
+
+		outString = unicode;
+
+	}
+
+
+exit:
+
+
+
+    if ( unicode != NULL )
+
+    {
+
+        delete [] unicode;
+
+	}
+
+
+
+	return ( !err ) ? TRUE : FALSE;
+
+}
+
+
+
+
+
+BOOL
+
+ByteArrayToVariant
+
+	(
+
+	const void	*	inArray,
+
+	size_t			inArrayLen,
+
+	VARIANT		*	outVariant
+
+	)
+
+{
+
+	LPBYTE			buf	= NULL;
+
+	HRESULT			hr	= 0;
+
+	BOOL			ok	= TRUE;
+
+
+
+	VariantClear( outVariant );
+
+	outVariant->vt		= VT_ARRAY|VT_UI1;
+
+	outVariant->parray	= SafeArrayCreateVector( VT_UI1, 0, ( ULONG ) inArrayLen );
+
+	require_action( outVariant->parray, exit, ok = FALSE );
+
+	hr = SafeArrayAccessData( outVariant->parray, (LPVOID *)&buf );
+
+	require_action( hr == S_OK, exit, ok = FALSE );
+
+	memcpy( buf, inArray, inArrayLen );
+
+	hr = SafeArrayUnaccessData( outVariant->parray );
+
+	require_action( hr == S_OK, exit, ok = FALSE );
+
+
+
+exit:
+
+
+
+	return ok;
+
+}
+
+
+
+
+
+extern BOOL
+
+VariantToByteArray
+
+	(
+
+	VARIANT				*	inVariant,
+
+	std::vector< BYTE >	&	outArray
+
+	)
+
+{
+
+	SAFEARRAY	*	psa			= NULL;
+
+	BYTE		*	pData		= NULL;
+
+	ULONG			cElements	= 0;
+
+	HRESULT			hr;
+
+	BOOL			ok = TRUE;
+
+
+
+	require_action( V_VT( inVariant ) == ( VT_ARRAY|VT_UI1 ), exit, ok = FALSE );
+
+	psa = V_ARRAY( inVariant );
+
+	require_action( psa, exit, ok = FALSE );
+
+	require_action( SafeArrayGetDim( psa ) == 1, exit, ok = FALSE );
+
+	hr = SafeArrayAccessData( psa, ( LPVOID* )&pData );
+
+	require_action( hr == S_OK, exit, ok = FALSE );
+
+	cElements = psa->rgsabound[0].cElements;
+
+	outArray.reserve( cElements );
+
+	outArray.assign( cElements, 0 );
+
+	memcpy( &outArray[ 0 ], pData, cElements );
+
+	SafeArrayUnaccessData( psa );
+
+
+
+exit:
+
+
+
+	return ok;
+
+}
\ No newline at end of file
diff --git a/mDNSWindows/DLLX/StringServices.h b/mDNSWindows/DLLX/StringServices.h
new file mode 100755
index 0000000..12aa996
--- /dev/null
+++ b/mDNSWindows/DLLX/StringServices.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#ifndef _StringServices_h
+
+#define _StringServices_h
+
+
+
+#include <atlbase.h>
+
+#include <vector>
+
+#include <string>
+
+
+
+
+
+extern BOOL
+
+BSTRToUTF8
+
+	(
+
+	BSTR			inString,
+
+	std::string	&	outString
+
+	);
+
+
+
+
+
+extern BOOL
+
+UTF8ToBSTR
+
+	(
+
+	const char	*	inString,
+
+	CComBSTR	&	outString
+
+	);
+
+
+
+
+
+extern BOOL
+
+ByteArrayToVariant
+
+	(
+
+	const void	*	inArray,
+
+	size_t			inArrayLen,
+
+	VARIANT		*	outVariant
+
+	);
+
+
+
+
+
+extern BOOL
+
+VariantToByteArray
+
+	(
+
+	VARIANT				*	inVariant,
+
+	std::vector< BYTE >	&	outArray
+
+	);
+
+
+
+
+
+#endif
\ No newline at end of file
diff --git a/mDNSWindows/DLLX/TXTRecord.cpp b/mDNSWindows/DLLX/TXTRecord.cpp
new file mode 100755
index 0000000..e5345f8
--- /dev/null
+++ b/mDNSWindows/DLLX/TXTRecord.cpp
@@ -0,0 +1,381 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#include "stdafx.h"
+
+#include "TXTRecord.h"
+
+#include "StringServices.h"
+
+#include <DebugServices.h>
+
+
+
+
+
+// CTXTRecord
+
+
+
+
+
+STDMETHODIMP CTXTRecord::SetValue(BSTR key, VARIANT value)
+
+{
+
+	std::string			keyUTF8;
+
+	ByteArray			valueArray;
+
+	BOOL				ok;
+
+	DNSServiceErrorType	err;
+
+	HRESULT				hr = S_OK;
+
+
+
+	if ( !m_allocated )
+
+	{
+
+		TXTRecordCreate( &m_tref, 0, NULL );
+
+		m_allocated = TRUE;
+
+	}
+
+
+
+	ok = BSTRToUTF8( key, keyUTF8 );
+
+	require_action( ok, exit, hr = S_FALSE );
+
+
+
+	ok = VariantToByteArray( &value, valueArray );
+
+	require_action( ok, exit, hr = S_FALSE );
+
+
+
+	err = TXTRecordSetValue( &m_tref, keyUTF8.c_str(), ( uint8_t ) valueArray.size(), &valueArray[ 0 ] );
+
+	require_action( !err, exit, hr = S_FALSE );
+
+
+
+exit:
+
+
+
+	return hr;
+
+}
+
+
+
+STDMETHODIMP CTXTRecord::RemoveValue(BSTR key)
+
+{
+
+	HRESULT hr = S_OK;
+
+
+
+	if ( m_allocated )
+
+	{
+
+		std::string			keyUTF8;
+
+		BOOL				ok;
+
+		DNSServiceErrorType	err;
+
+
+
+		ok = BSTRToUTF8( key, keyUTF8 );
+
+		require_action( ok, exit, hr = S_FALSE );
+
+
+
+		err = TXTRecordRemoveValue( &m_tref, keyUTF8.c_str() );
+
+		require_action( !err, exit, hr = S_FALSE );
+
+	}
+
+
+
+exit:
+
+
+
+	return hr;
+
+}
+
+
+
+STDMETHODIMP CTXTRecord::ContainsKey(BSTR key, VARIANT_BOOL* retval)
+
+{
+
+	std::string keyUTF8;
+
+	int			ret	= 0;
+
+	HRESULT		err	= S_OK;
+
+
+
+	if ( m_byteArray.size() > 0 )
+
+	{
+
+		BOOL ok;
+
+
+
+		ok = BSTRToUTF8( key, keyUTF8 );
+
+		require_action( ok, exit, err = S_FALSE );
+
+
+
+		ret = TXTRecordContainsKey( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str() );
+
+	}
+
+
+
+	*retval = ( ret ) ? VARIANT_TRUE : VARIANT_FALSE;
+
+
+
+exit:
+
+
+
+	return err;
+
+}
+
+
+
+STDMETHODIMP CTXTRecord::GetValueForKey(BSTR key, VARIANT* value)
+
+{
+
+	std::string		keyUTF8;
+
+	const void	*	rawValue;
+
+	uint8_t			rawValueLen;
+
+	BOOL			ok	= TRUE;
+
+	HRESULT			hr	= S_OK;
+
+
+
+	VariantClear( value );
+
+
+
+	if ( m_byteArray.size() > 0 )
+
+	{
+
+		ok = BSTRToUTF8( key, keyUTF8 );
+
+		require_action( ok, exit, hr = S_FALSE );
+
+
+
+		rawValue = TXTRecordGetValuePtr( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], keyUTF8.c_str(), &rawValueLen );
+
+
+
+		if ( rawValue )
+
+		{
+
+			ok = ByteArrayToVariant( rawValue, rawValueLen, value );
+
+			require_action( ok, exit, hr = S_FALSE );
+
+		}
+
+	}
+
+
+
+exit:
+
+
+
+	return hr;
+
+}
+
+
+
+STDMETHODIMP CTXTRecord::GetCount(ULONG* count)
+
+{
+
+	*count = 0;
+
+
+
+	if ( m_byteArray.size() > 0 )
+
+	{
+
+		*count = TXTRecordGetCount( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ] );
+
+	}
+
+
+
+	return S_OK;
+
+}
+
+
+
+STDMETHODIMP CTXTRecord::GetKeyAtIndex(ULONG index, BSTR* retval)
+
+{
+
+	char				keyBuf[ 64 ];
+
+	uint8_t				rawValueLen;
+
+	const void		*	rawValue;
+
+	CComBSTR			temp;
+
+	DNSServiceErrorType	err;
+
+	BOOL				ok;
+
+	HRESULT				hr = S_OK;
+
+
+
+	err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue );
+
+	require_action( !err, exit, hr = S_FALSE );
+
+
+
+	ok = UTF8ToBSTR( keyBuf, temp );
+
+	require_action( ok, exit, hr = S_FALSE );
+
+
+
+	*retval = temp;
+
+
+
+exit:
+
+
+
+	return hr;
+
+}
+
+
+
+STDMETHODIMP CTXTRecord::GetValueAtIndex(ULONG index, VARIANT* retval)
+
+{
+
+	char				keyBuf[ 64 ];
+
+	uint8_t				rawValueLen;
+
+	const void		*	rawValue;
+
+	CComBSTR			temp;
+
+	DNSServiceErrorType	err;
+
+	BOOL				ok;
+
+	HRESULT				hr = S_OK;
+
+
+
+	err = TXTRecordGetItemAtIndex( ( uint16_t ) m_byteArray.size(), &m_byteArray[ 0 ], ( uint16_t ) index, sizeof( keyBuf ), keyBuf, &rawValueLen, &rawValue );
+
+	require_action( !err, exit, hr = S_FALSE );
+
+
+
+	ok = ByteArrayToVariant( rawValue, rawValueLen, retval );
+
+	require_action( ok, exit, hr = S_FALSE );
+
+
+
+exit:
+
+
+
+	return hr;
+
+}
+
+
+
+
+
+void
+
+CTXTRecord::SetBytes
+
+	(
+
+	const unsigned char	*	bytes,
+
+	uint16_t				len
+
+	)
+
+{
+
+	check ( bytes != NULL );
+
+	check( len );
+
+
+
+	m_byteArray.reserve( len );
+
+	m_byteArray.assign( bytes, bytes + len );
+
+}
+
diff --git a/mDNSWindows/DLLX/TXTRecord.h b/mDNSWindows/DLLX/TXTRecord.h
new file mode 100755
index 0000000..67f3bdc
--- /dev/null
+++ b/mDNSWindows/DLLX/TXTRecord.h
@@ -0,0 +1,203 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma once
+
+#include "resource.h"       // main symbols
+
+#include "DLLX.h"
+
+#include <vector>
+
+#include <dns_sd.h>
+
+
+
+
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
+
+#endif
+
+
+
+
+
+
+
+// CTXTRecord
+
+
+
+class ATL_NO_VTABLE CTXTRecord :
+
+	public CComObjectRootEx<CComSingleThreadModel>,
+
+	public CComCoClass<CTXTRecord, &CLSID_TXTRecord>,
+
+	public IDispatchImpl<ITXTRecord, &IID_ITXTRecord, &LIBID_Bonjour, /*wMajor =*/ 1, /*wMinor =*/ 0>
+
+{
+
+public:
+
+	CTXTRecord()
+
+	:
+
+		m_allocated( FALSE )
+
+	{
+
+	}
+
+
+
+DECLARE_REGISTRY_RESOURCEID(IDR_TXTRECORD)
+
+
+
+
+
+BEGIN_COM_MAP(CTXTRecord)
+
+	COM_INTERFACE_ENTRY(ITXTRecord)
+
+	COM_INTERFACE_ENTRY(IDispatch)
+
+END_COM_MAP()
+
+
+
+
+
+
+
+	DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+
+
+	HRESULT FinalConstruct()
+
+	{
+
+		return S_OK;
+
+	}
+
+
+
+	void FinalRelease()
+
+	{
+
+		if ( m_allocated )
+
+		{
+
+			TXTRecordDeallocate( &m_tref );
+
+		}
+
+	}
+
+
+
+public:
+
+
+
+	STDMETHOD(SetValue)(BSTR key, VARIANT value);
+
+	STDMETHOD(RemoveValue)(BSTR key);
+
+	STDMETHOD(ContainsKey)(BSTR key, VARIANT_BOOL* retval);
+
+	STDMETHOD(GetValueForKey)(BSTR key, VARIANT* value);
+
+	STDMETHOD(GetCount)(ULONG* count);
+
+	STDMETHOD(GetKeyAtIndex)(ULONG index, BSTR* retval);
+
+	STDMETHOD(GetValueAtIndex)(ULONG index, VARIANT* retval);
+
+
+
+private:
+
+
+
+	typedef std::vector< BYTE > ByteArray;
+
+	ByteArray		m_byteArray;
+
+	BOOL			m_allocated;
+
+	TXTRecordRef	m_tref;
+
+
+
+public:
+
+
+
+	uint16_t
+
+	GetLen()
+
+	{
+
+		return TXTRecordGetLength( &m_tref );
+
+	}
+
+
+
+	const void*
+
+	GetBytes()
+
+	{
+
+		return TXTRecordGetBytesPtr( &m_tref );
+
+	}
+
+
+
+	void
+
+	SetBytes
+
+		(
+
+		const unsigned char	*	bytes,
+
+		uint16_t				len
+
+		);
+
+};
+
+
+
+OBJECT_ENTRY_AUTO(__uuidof(TXTRecord), CTXTRecord)
+
diff --git a/mDNSWindows/DLLX/TXTRecord.rgs b/mDNSWindows/DLLX/TXTRecord.rgs
new file mode 100755
index 0000000..ce2fe1e
--- /dev/null
+++ b/mDNSWindows/DLLX/TXTRecord.rgs
@@ -0,0 +1,27 @@
+HKCR

+{

+	Bonjour.TXTRecord.1 = s 'TXTRecord Class'

+	{

+		CLSID = s '{AFEE063C-05BA-4248-A26E-168477F49734}'

+	}

+	Bonjour.TXTRecord = s 'TXTRecord Class'

+	{

+		CLSID = s '{AFEE063C-05BA-4248-A26E-168477F49734}'

+		CurVer = s 'Bonjour.TXTRecord.1'

+	}

+	NoRemove CLSID

+	{

+		ForceRemove {AFEE063C-05BA-4248-A26E-168477F49734} = s 'TXTRecord Class'

+		{

+			ProgID = s 'Bonjour.TXTRecord.1'

+			VersionIndependentProgID = s 'Bonjour.TXTRecord'

+			ForceRemove 'Programmable'

+			InprocServer32 = s '%MODULE%'

+			{

+				val ThreadingModel = s 'Apartment'

+			}

+			val AppID = s '%APPID%'

+			'TypeLib' = s '{18FBED6D-F2B7-4EC8-A4A4-46282E635308}'

+		}

+	}

+}

diff --git a/mDNSWindows/DLLX/_IDNSSDEvents_CP.h b/mDNSWindows/DLLX/_IDNSSDEvents_CP.h
new file mode 100755
index 0000000..5c48397
--- /dev/null
+++ b/mDNSWindows/DLLX/_IDNSSDEvents_CP.h
@@ -0,0 +1,358 @@
+

+// Wizard-generated connection point proxy class

+// WARNING: This file may be regenerated by the wizard

+

+

+#pragma once

+

+template<class T>

+class CProxy_IDNSSDEvents :

+	public IConnectionPointImpl<T, &__uuidof(_IDNSSDEvents)>

+{

+public:

+	HRESULT Fire_DomainFound( IDNSSDService * service,  DNSSDFlags flags,  ULONG ifIndex,  BSTR domain)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[4];

+				avarParams[3] = service;

+				avarParams[2] = flags;

+				avarParams[1] = ifIndex;

+				avarParams[1].vt = VT_UI4;

+				avarParams[0] = domain;

+				avarParams[0].vt = VT_BSTR;

+				DISPPARAMS params = { avarParams, NULL, 4, 0 };

+				hr = pConnection->Invoke(1, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_DomainLost( IDNSSDService * service,  DNSSDFlags flags,  ULONG ifIndex,  BSTR domain)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[4];

+				avarParams[3] = service;

+				avarParams[2] = flags;

+				avarParams[1] = ifIndex;

+				avarParams[1].vt = VT_UI4;

+				avarParams[0] = domain;

+				avarParams[0].vt = VT_BSTR;

+				DISPPARAMS params = { avarParams, NULL, 4, 0 };

+				hr = pConnection->Invoke(2, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_ServiceFound( IDNSSDService * browser,  DNSSDFlags flags,  ULONG ifIndex,  BSTR serviceName,  BSTR regType,  BSTR domain)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[6];

+				avarParams[5] = browser;

+				avarParams[4] = flags;

+				avarParams[3] = ifIndex;

+				avarParams[3].vt = VT_UI4;

+				avarParams[2] = serviceName;

+				avarParams[2].vt = VT_BSTR;

+				avarParams[1] = regType;

+				avarParams[1].vt = VT_BSTR;

+				avarParams[0] = domain;

+				avarParams[0].vt = VT_BSTR;

+				DISPPARAMS params = { avarParams, NULL, 6, 0 };

+				hr = pConnection->Invoke(3, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_ServiceLost( IDNSSDService * browser,  DNSSDFlags flags,  ULONG ifIndex,  BSTR serviceName,  BSTR regType,  BSTR domain)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[6];

+				avarParams[5] = browser;

+				avarParams[4] = flags;

+				avarParams[3] = ifIndex;

+				avarParams[3].vt = VT_UI4;

+				avarParams[2] = serviceName;

+				avarParams[2].vt = VT_BSTR;

+				avarParams[1] = regType;

+				avarParams[1].vt = VT_BSTR;

+				avarParams[0] = domain;

+				avarParams[0].vt = VT_BSTR;

+				DISPPARAMS params = { avarParams, NULL, 6, 0 };

+				hr = pConnection->Invoke(4, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_ServiceResolved( IDNSSDService * service,  DNSSDFlags flags,  ULONG ifIndex,  BSTR fullName,  BSTR hostName,  USHORT port,  ITXTRecord * record)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[7];

+				avarParams[6] = service;

+				avarParams[5] = flags;

+				avarParams[4] = ifIndex;

+				avarParams[4].vt = VT_UI4;

+				avarParams[3] = fullName;

+				avarParams[3].vt = VT_BSTR;

+				avarParams[2] = hostName;

+				avarParams[2].vt = VT_BSTR;

+				avarParams[1] = port;

+				avarParams[1].vt = VT_UI2;

+				avarParams[0] = record;

+				DISPPARAMS params = { avarParams, NULL, 7, 0 };

+				hr = pConnection->Invoke(5, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_ServiceRegistered( IDNSSDService * service,  DNSSDFlags flags,  BSTR name,  BSTR regType,  BSTR domain)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[5];

+				avarParams[4] = service;

+				avarParams[3] = flags;

+				avarParams[2] = name;

+				avarParams[2].vt = VT_BSTR;

+				avarParams[1] = regType;

+				avarParams[1].vt = VT_BSTR;

+				avarParams[0] = domain;

+				avarParams[0].vt = VT_BSTR;

+				DISPPARAMS params = { avarParams, NULL, 5, 0 };

+				hr = pConnection->Invoke(6, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_QueryRecordAnswered( IDNSSDService * service,  DNSSDFlags flags,  ULONG ifIndex,  BSTR fullName,  DNSSDRRType rrtype,  DNSSDRRClass rrclass,  VARIANT rdata,  ULONG ttl)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[8];

+				avarParams[7] = service;

+				avarParams[6] = flags;

+				avarParams[5] = ifIndex;

+				avarParams[5].vt = VT_UI4;

+				avarParams[4] = fullName;

+				avarParams[4].vt = VT_BSTR;

+				avarParams[3] = rrtype;

+				avarParams[2] = rrclass;

+				avarParams[1] = rdata;

+				avarParams[0] = ttl;

+				avarParams[0].vt = VT_UI4;

+				DISPPARAMS params = { avarParams, NULL, 8, 0 };

+				hr = pConnection->Invoke(7, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_RecordRegistered( IDNSSDRecord * record,  DNSSDFlags flags)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[2];

+				avarParams[1] = record;

+				avarParams[0] = flags;

+				DISPPARAMS params = { avarParams, NULL, 2, 0 };

+				hr = pConnection->Invoke(8, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_AddressFound( IDNSSDService * service,  DNSSDFlags flags,  ULONG ifIndex,  BSTR hostname,  DNSSDAddressFamily addressFamily,  BSTR address,  ULONG ttl)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[7];

+				avarParams[6] = service;

+				avarParams[5] = flags;

+				avarParams[4] = ifIndex;

+				avarParams[4].vt = VT_UI4;

+				avarParams[3] = hostname;

+				avarParams[3].vt = VT_BSTR;

+				avarParams[2] = addressFamily;

+				avarParams[1] = address;

+				avarParams[1].vt = VT_BSTR;

+				avarParams[0] = ttl;

+				avarParams[0].vt = VT_UI4;

+				DISPPARAMS params = { avarParams, NULL, 7, 0 };

+				hr = pConnection->Invoke(9, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_MappingCreated( IDNSSDService * service,  DNSSDFlags flags,  ULONG ifIndex,  ULONG externalAddress,  DNSSDAddressFamily addressFamily,  DNSSDProtocol protocol,  USHORT internalPort,  USHORT externalPort,  ULONG ttl)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[9];

+				avarParams[8] = service;

+				avarParams[7] = flags;

+				avarParams[6] = ifIndex;

+				avarParams[6].vt = VT_UI4;

+				avarParams[5] = externalAddress;

+				avarParams[5].vt = VT_UI4;

+				avarParams[4] = addressFamily;

+				avarParams[3] = protocol;

+				avarParams[2] = internalPort;

+				avarParams[2].vt = VT_UI2;

+				avarParams[1] = externalPort;

+				avarParams[1].vt = VT_UI2;

+				avarParams[0] = ttl;

+				avarParams[0].vt = VT_UI4;

+				DISPPARAMS params = { avarParams, NULL, 9, 0 };

+				hr = pConnection->Invoke(10, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+	HRESULT Fire_OperationFailed( IDNSSDService * service,  DNSSDError error)

+	{

+		HRESULT hr = S_OK;

+		T * pThis = static_cast<T *>(this);

+		int cConnections = m_vec.GetSize();

+

+		for (int iConnection = 0; iConnection < cConnections; iConnection++)

+		{

+			pThis->Lock();

+			CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);

+			pThis->Unlock();

+

+			IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);

+

+			if (pConnection)

+			{

+				CComVariant avarParams[2];

+				avarParams[1] = service;

+				avarParams[0] = error;

+				DISPPARAMS params = { avarParams, NULL, 2, 0 };

+				hr = pConnection->Invoke(11, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);

+			}

+		}

+		return hr;

+	}

+};

+

diff --git a/mDNSWindows/DLLX/dlldatax.c b/mDNSWindows/DLLX/dlldatax.c
new file mode 100755
index 0000000..a581532
--- /dev/null
+++ b/mDNSWindows/DLLX/dlldatax.c
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#ifdef _MERGE_PROXYSTUB // merge proxy stub DLL
+
+
+
+#define REGISTER_PROXY_DLL //DllRegisterServer, etc.
+
+
+
+#define _WIN32_WINNT 0x0500	//for WinNT 4.0 or Win95 with DCOM
+
+#define USE_STUBLESS_PROXY	//defined only with MIDL switch /Oicf
+
+
+
+#pragma comment(lib, "rpcns4.lib")
+
+#pragma comment(lib, "rpcrt4.lib")
+
+
+
+#define ENTRY_PREFIX	Prx
+
+
+
+#include "dlldata.c"
+
+#include "DLLX_p.c"
+
+
+
+#endif //_MERGE_PROXYSTUB
+
diff --git a/mDNSWindows/DLLX/dlldatax.h b/mDNSWindows/DLLX/dlldatax.h
new file mode 100755
index 0000000..f8816a3
--- /dev/null
+++ b/mDNSWindows/DLLX/dlldatax.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma once
+
+
+
+#ifdef _MERGE_PROXYSTUB
+
+
+
+extern "C" 
+
+{
+
+BOOL WINAPI PrxDllMain(HINSTANCE hInstance, DWORD dwReason, 
+
+	LPVOID lpReserved);
+
+STDAPI PrxDllCanUnloadNow(void);
+
+STDAPI PrxDllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv);
+
+STDAPI PrxDllRegisterServer(void);
+
+STDAPI PrxDllUnregisterServer(void);
+
+}
+
+
+
+#endif
+
diff --git a/mDNSWindows/DLLX/resource.h b/mDNSWindows/DLLX/resource.h
new file mode 100755
index 0000000..5613187
--- /dev/null
+++ b/mDNSWindows/DLLX/resource.h
@@ -0,0 +1,30 @@
+//{{NO_DEPENDENCIES}}

+// Microsoft Visual C++ generated include file.

+// Used by DLLX.rc

+//

+#define IDS_PROJNAME                    100

+#define IDR_DLLX		                101

+#define IDR_DNSSD                       102

+#define IDR_DNSSDSERVICE                103

+#define IDR_BROWSELISTENER              104

+#define IDR_RESOLVELISTENER             105

+#define IDR_TXTRECORD                   106

+#define IDR_ENUMERATEDOMAINSLISTENER    107

+#define IDR_REGISTERLISTENER            108

+#define IDR_QUERYRECORDLISTENER         109

+#define IDR_GETADDRINFOLISTENER         110

+#define IDR_DNSSDRECORD                 111

+#define IDR_REGISTERRECORDLISTENER      112

+#define IDR_NATPORTMAPPINGLISTENER      113

+#define IDR_DNSSDEVENTMANAGER           114

+

+// Next default values for new objects

+// 

+#ifdef APSTUDIO_INVOKED

+#ifndef APSTUDIO_READONLY_SYMBOLS

+#define _APS_NEXT_RESOURCE_VALUE        201

+#define _APS_NEXT_COMMAND_VALUE         32768

+#define _APS_NEXT_CONTROL_VALUE         201

+#define _APS_NEXT_SYMED_VALUE           115

+#endif

+#endif

diff --git a/mDNSWindows/DLLX/stdafx.h b/mDNSWindows/DLLX/stdafx.h
new file mode 100755
index 0000000..66fb37b
--- /dev/null
+++ b/mDNSWindows/DLLX/stdafx.h
@@ -0,0 +1,88 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2009 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#pragma once
+
+
+
+#ifndef STRICT
+
+#define STRICT
+
+#endif
+
+
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+
+#ifndef WINVER				// Allow use of features specific to Windows XP or later.
+
+#define WINVER 0x0501		// Change this to the appropriate value to target other versions of Windows.
+
+#endif
+
+
+
+#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
+
+#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
+
+#endif						
+
+
+
+#ifndef _WIN32_WINDOWS		// Allow use of features specific to Windows 98 or later.
+
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+
+#endif
+
+
+
+#ifndef _WIN32_IE			// Allow use of features specific to IE 6.0 or later.
+
+#define _WIN32_IE 0x0600	// Change this to the appropriate value to target other versions of IE.
+
+#endif
+
+
+
+#define _ATL_APARTMENT_THREADED
+
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+
+
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// some CString constructors will be explicit
+
+
+
+
+
+#include "resource.h"
+
+#include <atlbase.h>
+
+#include <atlcom.h>
+
+
+
+using namespace ATL;
\ No newline at end of file
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln
new file mode 100644
index 0000000..5ce1a0a
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln
@@ -0,0 +1,21 @@
+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 = Debug
+		ConfigName.1 = Release
+	EndGlobalSection
+	GlobalSection(ProjectDependencies) = postSolution
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{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
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj
new file mode 100644
index 0000000..c1a2424
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj
@@ -0,0 +1,253 @@
+<?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="1">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=".\Resources;..\;..\..\..\;..\..\..\..\mDNSCore;..\..\..\DNSServices"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1"
+				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="2"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="DNSServiceBrowser Debug.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="wsock32.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="1"
+			WholeProgramOptimization="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				GlobalOptimizations="TRUE"
+				InlineFunctionExpansion="0"
+				FavorSizeOrSpeed="2"
+				OmitFramePointers="TRUE"
+				OptimizeForWindowsApplication="FALSE"
+				AdditionalIncludeDirectories=".\Resources;..\;..\..\..\;..\..\..\..\mDNSCore;..\..\..\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="2"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386 /IGNORE:4089"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="DNSServiceBrowser.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="wsock32.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>
+	</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\LoginDialog.cpp">
+			</File>
+			<File
+				RelativePath="Sources\LoginDialog.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="Support"
+			Filter="">
+			<File
+				RelativePath="..\..\..\CommonServices.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\DNSCommon.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\DNSCommon.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\DNSDigest.c">
+			</File>
+			<File
+				RelativePath="..\..\..\DNSServices\DNSServices.c">
+			</File>
+			<File
+				RelativePath="..\..\..\DebugServices.c">
+			</File>
+			<File
+				RelativePath="..\..\..\DebugServices.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\mDNS.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\mDNSClientAPI.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\mDNSDebug.h">
+			</File>
+			<File
+				RelativePath="..\..\..\mDNSWin32.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\uDNS.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\uDNS.h">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln
new file mode 100644
index 0000000..bdaaa3b
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln
@@ -0,0 +1,21 @@
+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
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{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
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj
new file mode 100644
index 0000000..3c8cb1c
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj
@@ -0,0 +1,267 @@
+<?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="1">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories=".\Resources;..\;..\..\..\;..\..\..\..\mDNSCore;..\..\..\DNSServices"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;DEBUG=1"
+				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 /IGNORE:4089"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="DNSServiceBrowser Debug.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="wsock32.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="1"
+			WholeProgramOptimization="FALSE">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				GlobalOptimizations="TRUE"
+				InlineFunctionExpansion="0"
+				FavorSizeOrSpeed="2"
+				OmitFramePointers="TRUE"
+				OptimizeForWindowsApplication="FALSE"
+				AdditionalIncludeDirectories=".\Resources;..\;..\..\..\;..\..\..\..\mDNSCore;..\..\..\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 /IGNORE:4089"
+				AdditionalDependencies="ws2_32.lib"
+				OutputFile="DNSServiceBrowser.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				IgnoreDefaultLibraryNames="wsock32.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>
+	</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\LoginDialog.cpp">
+			</File>
+			<File
+				RelativePath="Sources\LoginDialog.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="Support"
+			Filter="">
+			<File
+				RelativePath="..\..\..\CommonServices.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\DNSCommon.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\DNSCommon.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\DNSDigest.c">
+			</File>
+			<File
+				RelativePath="..\..\..\DNSServices\DNSServices.c">
+			</File>
+			<File
+				RelativePath="..\..\..\DebugServices.c">
+			</File>
+			<File
+				RelativePath="..\..\..\DebugServices.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\mDNS.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\mDNSClientAPI.h">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\mDNSDebug.h">
+			</File>
+			<File
+				RelativePath="..\..\..\mDNSWin32.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\uDNS.c">
+			</File>
+			<File
+				RelativePath="..\..\..\..\mDNSCore\uDNS.h">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico
new file mode 100644
index 0000000..b0a8639
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico
Binary files differ
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc
new file mode 100644
index 0000000..3943139
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc
@@ -0,0 +1,323 @@
+// 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, 512, 316
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | 
+    WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "DNSServiceBrowser"
+MENU IDR_CHOOSER_DIALOG_MENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+    CONTROL         "",IDC_SERVICE_LIST,"SysListView32",LVS_REPORT | 
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | 
+                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,8,268,256
+    CONTROL         "",IDC_CHOOSER_LIST,"SysListView32",LVS_REPORT | 
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | 
+                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,282,8,224,170
+    CONTROL         "",IDC_DOMAIN_LIST,"SysListView32",LVS_REPORT | 
+                    LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | 
+                    LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,8,272,268,38
+    GROUPBOX        "Information",IDC_STATIC,282,182,224,128
+    RTEXT           "Name:",IDC_STATIC,288,195,38,8
+    EDITTEXT        IDC_INFO_NAME_TEXT,330,195,168,10,ES_AUTOHSCROLL | 
+                    ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE
+    RTEXT           "IP address:",IDC_STATIC,288,208,38,8
+    EDITTEXT        IDC_INFO_IP_TEXT,330,208,168,10,ES_AUTOHSCROLL | 
+                    ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE
+    RTEXT           "Interface:",IDC_STATIC,288,221,38,8
+    EDITTEXT        IDC_INFO_INTERFACE_TEXT,330,221,168,10,ES_AUTOHSCROLL | 
+                    ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE
+    RTEXT           "Host Name:",IDC_STATIC,287,234,38,8
+    EDITTEXT        IDC_INFO_HOST_NAME_TEXT,330,234,168,10,ES_AUTOHSCROLL | 
+                    ES_READONLY | NOT WS_BORDER,WS_EX_STATICEDGE
+    RTEXT           "Text:",IDC_STATIC,288,247,38,8
+    EDITTEXT        IDC_INFO_TEXT_TEXT,330,247,168,57,ES_MULTILINE | 
+                    ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | NOT 
+                    WS_BORDER,WS_EX_STATICEDGE
+END
+
+IDD_ABOUT_DIALOG DIALOGEX 0, 0, 244, 73
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION
+CAPTION "About DNSServiceBrowser"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+    ICON            IDR_MAIN_ICON,IDC_ABOUT_APP_ICON,12,12,20,20
+    LTEXT           "DNSServiceBrowser",IDC_ABOUT_APP_NAME_TEXT,44,11,192,
+                    12
+    LTEXT           "Version 1.2d1",IDC_ABOUT_APP_VERSION_TEXT,44,25,192,8
+    LTEXT           "Copyright (C) 2002-2004 Apple Computer, Inc.",
+                    IDC_ABOUT_COPYRIGHT_TEXT,4,60,156,8
+    DEFPUSHBUTTON   "OK",IDOK,192,52,44,14
+END
+
+IDD_LOGIN DIALOGEX 0, 0, 180, 89
+STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION
+CAPTION "Login"
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+    LTEXT           "Enter a username and password. Leave blank to use the default username and/or password.",
+                    IDC_STATIC,8,8,156,16,NOT WS_GROUP
+    RTEXT           "Username:",IDC_STATIC,10,34,36,8,NOT WS_GROUP
+    EDITTEXT        IDC_LOGIN_USERNAME_TEXT,50,32,118,12,ES_AUTOHSCROLL
+    RTEXT           "Password:",IDC_STATIC,10,50,36,8,NOT WS_GROUP
+    EDITTEXT        IDC_LOGIN_PASSWORD_TEXT,50,48,118,12,ES_PASSWORD | 
+                    ES_AUTOHSCROLL
+    DEFPUSHBUTTON   "OK",IDOK,129,70,44,14
+    PUSHBUTTON      "Cancel",IDCANCEL,77,70,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 "CompanyName", "Apple Computer, Inc."
+            VALUE "FileDescription", "DNSServiceBrowser for Windows"
+            VALUE "FileVersion", "1, 0, 0, 1"
+            VALUE "InternalName", "DNSServiceBrowser for Windows"
+            VALUE "LegalCopyright", "Copyright (C) 2002-2004 Apple Computer, Inc."
+            VALUE "OriginalFilename", "DNSServiceBrowser.exe"
+            VALUE "ProductName", "DNSServiceBrowser 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 DNSServiceBrowser...", 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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_CHOOSER_DIALOG, DIALOG
+    BEGIN
+        RIGHTMARGIN, 468
+    END
+
+    IDD_LOGIN, DIALOG
+    BEGIN
+        BOTTOMMARGIN, 62
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_ABOUTBOX            "&About DNSServiceBrowser"
+    IDS_CHOOSER_DOMAIN_COLUMN_NAME "Domains"
+    IDP_SOCKETS_INIT_FAILED "Windows sockets initialization failed."
+    IDS_CHOOSER_SERVICE_COLUMN_TYPE "Services"
+    IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME "Name"
+    IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME "IP Address"
+    IDS_CHOOSER_SERVICE_COLUMN_DESC "Description"
+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
+
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2 b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2
new file mode 100644
index 0000000..ec5e69f
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2
@@ -0,0 +1,20 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef APSTUDIO_INVOKED
+	#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h
new file mode 100644
index 0000000..62602a4
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h
@@ -0,0 +1,53 @@
+//{{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_SERVICE_COLUMN_TYPE 104
+#define IDS_CHOOSER_CHOOSER_NAME_COLUMN_NAME 105
+#define IDS_CHOOSER_CHOOSER_IP_COLUMN_NAME 106
+#define IDS_CHOOSER_SERVICE_COLUMN_DESC 107
+#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 IDC_INFO_INTERFACE_TEXT2        128
+#define IDC_INFO_HOST_NAME_TEXT         128
+#define IDR_CHOOSER_DIALOG_MENU         136
+#define IDD_CHOOSER_DIALOG              143
+#define IDD_ABOUT_DIALOG                144
+#define IDD_LOGIN                       145
+#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 IDC_LOGIN_USERNAME_TEXT         1182
+#define IDC_EDIT2                       1183
+#define IDC_LOGIN_PASSWORD_TEXT         1183
+#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         1185
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp b/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp
new file mode 100644
index 0000000..8dd6b09
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	<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
+}
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h b/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h
new file mode 100644
index 0000000..cdd257c
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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_)
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp b/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp
new file mode 100644
index 0000000..f7f4b03
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp
@@ -0,0 +1,111 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	<assert.h>
+
+#include	"StdAfx.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;
+	
+	// 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 );
+}
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h b/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h
new file mode 100644
index 0000000..8368a49
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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_)
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp b/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp
new file mode 100644
index 0000000..9e4db65
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp
@@ -0,0 +1,1426 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	<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	"LoginDialog.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 kDomainListDefaultDomainColumnWidth		 		164 
+	
+// Service List
+
+#define kServiceListDefaultServiceColumnTypeWidth		146
+#define kServiceListDefaultServiceColumnDescWidth		230
+	
+// Chooser List
+	
+#define kChooserListDefaultNameColumnWidth				190
+#define kChooserListDefaultIPColumnWidth				120
+
+// 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[] =
+{
+	{ "_accountedge._tcp.",	 		"MYOB AccountEdge", 										"", 			false },
+	{ "_aecoretech._tcp.", 			"Apple Application Engineering Services",					"", 			false },
+	{ "_afpovertcp._tcp.", 			"Apple File Sharing (AFP)", 								"afp://", 		false },
+	{ "_airport._tcp.", 			"AirPort Base Station",										"", 			false }, 
+	{ "_apple-sasl._tcp.", 			"Apple Password Server", 									"", 			false },
+	{ "_aquamon._tcp.", 			"AquaMon", 													"", 			false },
+	{ "_async._tcp", 				"address-o-sync", 											"", 			false },
+	{ "_auth._tcp.", 				"Authentication Service",									"", 			false },
+	{ "_bootps._tcp.", 				"Bootstrap Protocol Server",								"", 			false },
+	{ "_bousg._tcp.", 				"Bag Of Unusual Strategy Games",							"", 			false },
+	{ "_browse._udp.", 				"DNS Service Discovery",									"", 			false },
+	{ "_cheat._tcp.", 				"The Cheat",												"", 			false },
+	{ "_chess._tcp", 				"Project Gridlock", 										"", 			false },
+	{ "_chfts._tcp", 				"Fluid Theme Server", 										"", 			false },
+	{ "_clipboard._tcp", 			"Clipboard Sharing", 										"", 			false },
+	{ "_contactserver._tcp.", 		"Now Up-to-Date & Contact",									"", 			false },
+	{ "_cvspserver._tcp", 			"CVS PServer", 												"", 			false },
+	{ "_cytv._tcp.", 				"CyTV Network streaming for Elgato EyeTV",					"", 			false },
+	{ "_daap._tcp.", 				"Digital Audio Access Protocol (iTunes)",					"daap://",		false }, 
+	{ "_distcc._tcp", 				"Distributed Compiler", 									"", 			false },
+	{ "_dns-sd._udp", 				"DNS Service Discovery", 									"", 			false },
+	{ "_dpap._tcp.", 				"Digital Picture Access Protocol (iPhoto)",					"", 			false },
+	{ "_earphoria._tcp.", 			"Earphoria",												"", 			false },
+	{ "_ecbyesfsgksc._tcp.", 		"Net Monitor Anti-Piracy Service",							"",				false },
+	{ "_eheap._tcp.", 				"Interactive Room Software",								"",				false },
+	{ "_embrace._tcp.", 			"DataEnvoy",												"",				false },
+	{ "_eppc._tcp.", 				"Remote AppleEvents", 										"eppc://", 		false }, 
+	{ "_exec._tcp.", 				"Remote Process Execution",									"",				false },
+	{ "_facespan._tcp.", 			"FaceSpan",													"",				false },
+	{ "_fjork._tcp.", 				"Fjork",													"",				false },
+	{ "_ftp._tcp.", 				"File Transfer (FTP)", 										"ftp://", 		false }, 
+	{ "_ftpcroco._tcp.", 			"Crocodile FTP Server",										"",				false },
+	{ "_gbs-smp._tcp.", 			"SnapMail",													"",				false },
+	{ "_gbs-stp._tcp.", 			"SnapTalk",													"",				false },
+	{ "_grillezvous._tcp.", 		"Roxio ToastAnywhere(tm) Recorder Sharing",					"",				false },
+	{ "_h323._tcp.", 				"H.323",													"",				false },
+	{ "_hotwayd._tcp", 				"Hotwayd", 													"", 			false },
+	{ "_http._tcp.", 				"Web Server (HTTP)", 										"http://", 		true  }, 
+	{ "_hydra._tcp", 				"SubEthaEdit", 												"", 			false },
+	{ "_ica-networking._tcp.", 		"Image Capture Networking",									"", 			false }, 
+	{ "_ichalkboard._tcp.", 		"iChalk",													"", 			false }, 
+	{ "_ichat._tcp.", 				"iChat",				 									"ichat://",		false }, 
+	{ "_iconquer._tcp.",	 		"iConquer",													"", 			false }, 
+	{ "_imap._tcp.", 				"Internet Message Access Protocol",							"",				false },
+	{ "_imidi._tcp.", 				"iMidi",													"",				false },
+	{ "_ipp._tcp.", 				"Printer (IPP)", 											"ipp://", 		false },
+	{ "_ishare._tcp.", 				"iShare",													"",				false },
+	{ "_isparx._tcp.", 				"iSparx",													"",				false },
+	{ "_istorm._tcp", 				"iStorm", 													"", 			false },
+	{ "_iwork._tcp.", 				"iWork Server",												"",				false },
+	{ "_liaison._tcp.", 			"Liaison",													"",				false },
+	{ "_login._tcp.", 				"Remote Login a la Telnet",									"",				false },
+	{ "_lontalk._tcp.", 			"LonTalk over IP (ANSI 852)",								"",				false },
+	{ "_lonworks._tcp.", 			"Echelon LNS Remote Client",								"",				false },
+	{ "_macfoh-remote._tcp.", 		"MacFOH Remote",											"",				false },
+	{ "_moneyworks._tcp.", 			"MoneyWorks",												"",				false },
+	{ "_mp3sushi._tcp", 			"MP3 Sushi", 												"", 			false },
+	{ "_mttp._tcp.", 				"MenuTunes Sharing",										"",				false },
+	{ "_ncbroadcast._tcp.", 		"Network Clipboard Broadcasts",								"",				false },
+	{ "_ncdirect._tcp.", 			"Network Clipboard Direct Transfers",						"",				false },
+	{ "_ncsyncserver._tcp.", 		"Network Clipboard Sync Server",							"",				false },
+	{ "_newton-dock._tcp.", 		"Escale",													"",				false },
+	{ "_nfs._tcp", 					"NFS", 														"", 			false },
+	{ "_nssocketport._tcp.", 		"DO over NSSocketPort",										"",				false },
+	{ "_omni-bookmark._tcp.", 		"OmniWeb",													"",				false },
+	{ "_openbase._tcp.", 			"OpenBase SQL",												"",				false },
+	{ "_p2pchat._tcp.", 			"Peer-to-Peer Chat",										"",				false },
+	{ "_pdl-datastream._tcp.", 		"Printer (PDL)", 											"pdl://", 		false }, 
+	{ "_poch._tcp.", 				"Parallel OperatiOn and Control Heuristic",					"",				false },
+	{ "_pop_2_ambrosia._tcp.",		"Pop-Pop",													"",				false },
+	{ "_pop3._tcp", 				"POP3 Server", 												"", 			false },
+	{ "_postgresql._tcp", 			"PostgreSQL Server", 										"", 			false },
+	{ "_presence._tcp", 			"iChat AV", 												"", 			false },
+	{ "_printer._tcp.", 			"Printer (LPR)", 											"lpr://", 		false }, 
+	{ "_ptp._tcp.", 				"Picture Transfer (PTP)", 									"ptp://", 		false },
+	{ "_register._tcp", 			"DNS Service Discovery", 									"", 			false },
+	{ "_rfb._tcp.", 				"Remote Frame Buffer",										"",				false },
+	{ "_riousbprint._tcp.", 		"Remote I/O USB Printer Protocol",							"",				false },
+	{ "_rtsp._tcp.", 				"Real Time Stream Control Protocol",						"",				false },
+	{ "_safarimenu._tcp", 			"Safari Menu", 												"", 			false },
+	{ "_scone._tcp", 				"Scone", 													"", 			false },
+	{ "_sdsharing._tcp.", 			"Speed Download",											"",				false },
+	{ "_seeCard._tcp.", 			"seeCard",													"",				false },
+	{ "_services._udp.", 			"DNS Service Discovery",									"",				false },
+	{ "_shell._tcp.", 				"like exec, but automatic authentication",					"",				false },
+	{ "_shout._tcp.", 				"Shout",													"",				false },
+	{ "_shoutcast._tcp", 			"Nicecast", 												"", 			false },
+	{ "_smb._tcp.", 				"Windows File Sharing (SMB)", 								"smb://", 		false }, 
+	{ "_soap._tcp.", 				"Simple Object Access Protocol", 							"", 			false }, 
+	{ "_spincrisis._tcp.", 			"Spin Crisis",												"",				false },
+	{ "_spl-itunes._tcp.", 			"launchTunes",												"",				false },
+	{ "_spr-itunes._tcp.", 			"netTunes",													"",				false },
+	{ "_ssh._tcp.", 				"Secure Shell (SSH)", 										"ssh://", 		false }, 
+	{ "_ssscreenshare._tcp", 		"Screen Sharing", 											"", 			false },
+	{ "_sge-exec._tcp", 			"Sun Grid Engine (Execution Host)", 						"", 			false },
+	{ "_sge-qmaster._tcp", 			"Sun Grid Engine (Master)", 								"", 			false },
+	{ "_stickynotes._tcp", 			"Sticky Notes", 											"", 			false },
+	{ "_strateges._tcp", 			"Strateges", 												"", 			false },
+	{ "_sxqdea._tcp", 				"Synchronize! Pro X", 										"", 			false },
+	{ "_sybase-tds._tcp", 			"Sybase Server", 											"", 			false },
+	{ "_tce._tcp", 					"Power Card", 												"", 			false },
+	{ "_teamlist._tcp", 			"ARTIS Team Task",											"", 			false },
+	{ "_teleport._tcp", 			"teleport",													"", 			false },
+	{ "_telnet._tcp.", 				"Telnet", 													"telnet://", 	false }, 
+	{ "_tftp._tcp.", 				"Trivial File Transfer (TFTP)", 							"tftp://", 		false }, 
+	{ "_tinavigator._tcp.", 		"TI Navigator", 											"", 			false }, 
+	{ "_tivo_servemedia._tcp", 		"TiVo",														"", 			false },
+	{ "_upnp._tcp.", 				"Universal Plug and Play", 									"", 			false }, 
+	{ "_utest._tcp.", 				"uTest", 													"", 			false }, 
+	{ "_vue4rendercow._tcp",		"VueProRenderCow",											"", 			false },
+	{ "_webdav._tcp.", 				"WebDAV", 													"webdav://",	false }, 
+	{ "_whamb._tcp.", 				"Whamb", 													"",				false }, 
+	{ "_workstation._tcp", 			"Macintosh Manager",										"", 			false },
+	{ "_ws._tcp", 					"Web Services",												"", 			false },
+	{ "_xserveraid._tcp.", 			"Xserve RAID",												"xsr://", 		false }, 
+	{ "_xsync._tcp.",	 			"Xserve RAID Synchronization",								"",		 		false }, 
+	
+	{ "",	 						"",															"",		 		false }, 
+	
+	// Unofficial and invalid service types that will be phased out:
+	
+	{ "_clipboardsharing._tcp.",			"ClipboardSharing",									"",		 		false }, 
+	{ "_MacOSXDupSuppress._tcp.",			"Mac OS X Duplicate Suppression",					"",		 		false }, 
+	{ "_netmonitorserver._tcp.",			"Net Monitor Server",								"",		 		false }, 
+	{ "_networkclipboard._tcp.",			"Network Clipboard",								"",		 		false }, 
+	{ "_slimdevices_slimp3_cli._tcp.",		"SliMP3 Server Command-Line Interface",				"",		 		false }, 
+	{ "_slimdevices_slimp3_http._tcp.",		"SliMP3 Server Web Interface",						"",		 		false }, 
+	{ "_tieducationalhandhelddevice._tcp.",	"TI Connect Manager",								"",		 		false }, 
+	{ "_tivo_servemedia._tcp.",				"TiVo",												"",		 		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 );
+static DWORD	StringObjectToUTF8String( CString &inObject, std::string &outUTF8 );
+
+#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 )
+{
+	HICON			icon;
+	BOOL			result;
+	CString			tempString;
+	DNSStatus		err;
+	
+	// Initialize our parent.
+
+	CDialog::OnInitDialog();
+	
+	// Set up the window icon.
+	
+	icon = AfxGetApp()->LoadIcon( IDR_MAIN_ICON );
+	assert( icon );
+	if( icon )
+	{
+		SetIcon( icon, TRUE );		// Set big icon
+		SetIcon( icon, FALSE );		// Set small icon
+	}
+	
+	// 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_TYPE );
+	assert( result );
+	mServiceList.InsertColumn( 0, tempString, LVCFMT_LEFT, kServiceListDefaultServiceColumnTypeWidth );
+	
+	result = tempString.LoadString( IDS_CHOOSER_SERVICE_COLUMN_DESC );
+	assert( result );
+	mServiceList.InsertColumn( 1, tempString, LVCFMT_LEFT, kServiceListDefaultServiceColumnDescWidth );
+	
+	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() 
+{
+	OnClose();
+}
+
+//===========================================================================================================================
+//	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				s;
+		std::string			utf8;
+		const char *		type;
+		
+		s = mDomainList.GetItemText( selectedDomain, 0 );
+		StringObjectToUTF8String( s, utf8 );
+		type = mServiceTypes[ selectedType ].serviceType.c_str();
+		if( *type != '\0' )
+		{
+			StartBrowsing( type, utf8.c_str() );
+		}
+	}
+	
+	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 )
+		{
+			const char *		text;
+			
+			// Create a URL representing the service instance.
+			
+			if( strcmp( service->serviceType, "_smb._tcp." ) == 0 )
+			{
+				// Special case for SMB (no port number).
+				
+				url.Format( TEXT( "%s%s/" ), service->urlScheme, (const char *) p->ip.c_str() ); 
+			}
+			else if( strcmp( service->serviceType, "_ftp._tcp." ) == 0 )
+			{
+				// Special case for FTP to get login info.
+
+				LoginDialog		dialog;
+				CString			username;
+				CString			password;
+				
+				if( !dialog.GetLogin( username, password ) )
+				{
+					goto exit;
+				}
+				
+				// Build URL in the following format:
+				//
+				// ftp://[username[:password]@]<ip>
+				
+				url += service->urlScheme;
+				if( username.GetLength() > 0 )
+				{
+					url += username;
+					if( password.GetLength() > 0 )
+					{
+						url += ':';
+						url += password;
+					}
+					url += '@';
+				}
+				url += p->ip.c_str();
+			}
+			else if( strcmp( service->serviceType, "_http._tcp." ) == 0 )
+			{
+				// Special case for HTTP to exclude "path=" if present.
+				
+				text = service->useText ? p->text.c_str() : "";
+				if( strncmp( text, "path=", 5 ) == 0 )
+				{
+					text += 5;
+				}
+				if( *text != '/' )
+				{
+					url.Format( TEXT( "%s%s/%s" ), service->urlScheme, (const char *) p->ip.c_str(), text );
+				}
+				else
+				{
+					url.Format( TEXT( "%s%s%s" ), service->urlScheme, (const char *) p->ip.c_str(), text );
+				}
+			}
+			else
+			{
+				text = service->useText ? p->text.c_str() : "";
+				url.Format( TEXT( "%s%s/%s" ), service->urlScheme, (const char *) p->ip.c_str(), text ); 
+			}
+			
+			// Let the system open the URL in the correct app.
+			
+			{
+				CWaitCursor		waitCursor;
+				
+				ShellExecute( NULL, TEXT( "open" ), url, TEXT( "" ), TEXT( "c:\\" ), SW_SHOWNORMAL );
+			}
+		}
+	}
+
+exit:
+	*pResult = 0;
+}
+
+//===========================================================================================================================
+//	OnCancel
+//===========================================================================================================================
+
+void ChooserDialog::OnCancel() 
+{
+	// Do nothing.
+}
+
+//===========================================================================================================================
+//	PopulateServicesList
+//===========================================================================================================================
+
+void	ChooserDialog::PopulateServicesList( void )
+{
+	ServiceTypeVector::iterator		i;
+	CString							type;
+	CString							desc;
+	std::string						tmp;
+	
+	// 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 )
+	{
+		const char *		p;
+		const char *		q;
+		
+		p  = ( *i ).serviceType.c_str();
+		if( *p == '_' ) ++p;							// Skip leading '_'.
+		q  = strchr( p, '.' );							// Find first '.'.
+		if( q )	tmp.assign( p, (size_t)( q - p ) );		// Use only up to the first '.'.
+		else	tmp.assign( p );						// No '.' so use the entire string.
+		UTF8StringToStringObject( tmp.c_str(), type );
+		UTF8StringToStringObject( ( *i ).description.c_str(), desc );
+		
+		int		n;
+		
+		n = mServiceList.GetItemCount();
+		mServiceList.InsertItem( n, type );
+		mServiceList.SetItemText( n, 1, desc );
+	}
+	
+	// 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;
+	std::string					textNewLines;
+	std::string					hostName;
+	CWnd *						item;
+	std::string::iterator		i;
+	
+	// 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;
+		hostName	= p->hostName;
+
+		// Sync up the list items with the actual data (IP address may change).
+		
+		UTF8StringToStringObject( ip.c_str(), s );
+		mChooserList.SetItemText( selectedItem, 1, s );
+	}
+	
+	// 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 );
+	UTF8StringToStringObject( ip.c_str(), s );
+	item->SetWindowText( s );
+	
+	// Interface
+	
+	item = (CWnd *) this->GetDlgItem( IDC_INFO_INTERFACE_TEXT );
+	assert( item );
+	UTF8StringToStringObject( ifIP.c_str(), s );
+	item->SetWindowText( s );
+	
+
+	item = (CWnd *) this->GetDlgItem( IDC_INFO_HOST_NAME_TEXT );
+	assert( item );
+	UTF8StringToStringObject( hostName.c_str(), s );
+	item->SetWindowText( s );
+
+	// Text
+	
+	item = (CWnd *) this->GetDlgItem( IDC_INFO_TEXT_TEXT );
+	assert( item );
+	for( i = text.begin(); i != text.end(); ++i )
+	{
+		if( *i == '\1' )
+		{
+			textNewLines += "\r\n";
+		}
+		else
+		{
+			textNewLines += *i;
+		}
+	}
+	UTF8StringToStringObject( textNewLines.c_str(), s );
+	item->SetWindowText( s );
+}
+
+#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 );
+		
+		UTF8StringToStringObject( p->ip.c_str(), s );
+		mChooserList.SetItemText( n, 1, s );
+		
+		// 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:
+				if( inEvent->data.resolved->address.addressType == kDNSNetworkAddressTypeIPv4  )
+				{
+					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;
+					serviceInstance->hostName	= inEvent->data.resolved->hostName;
+
+					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 );
+}
+
+//===========================================================================================================================
+//	StringObjectToUTF8String
+//===========================================================================================================================
+
+static DWORD	StringObjectToUTF8String( CString &inObject, std::string &outUTF8 )
+{
+	DWORD		err;
+	BSTR		unicode;
+	int			nUnicode;
+	int			n;
+	char *		utf8;
+	
+	unicode = NULL;
+	utf8	= NULL;
+	
+	nUnicode = inObject.GetLength();
+	if( nUnicode > 0 )
+	{
+		unicode = inObject.AllocSysString();
+		n = WideCharToMultiByte( CP_UTF8, 0, unicode, nUnicode, NULL, 0, NULL, NULL );
+		assert( n > 0 );
+		
+		utf8 = (char *) malloc( (size_t) n );
+		assert( utf8 );
+		if( !utf8 ) { err = ERROR_INSUFFICIENT_BUFFER; goto exit; }
+		
+		n = WideCharToMultiByte( CP_UTF8, 0, unicode, nUnicode, utf8, n, NULL, NULL );
+		assert( n > 0 );
+		
+		try
+		{
+			outUTF8.assign( utf8, n );
+		}
+		catch( ... )
+		{
+			err = ERROR_NO_UNICODE_TRANSLATION;
+			goto exit;
+		}
+	}
+	else
+	{
+		outUTF8.clear();
+	}
+	err = 0;
+	
+exit:
+	if( unicode )
+	{
+		SysFreeString( unicode );
+	}
+	if( utf8 )
+	{
+		free( utf8 );
+	}
+	return( err );
+}
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h b/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h
new file mode 100644
index 0000000..41fd827
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h
@@ -0,0 +1,131 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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;
+	std::string		hostName;
+};
+
+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_)
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp b/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp
new file mode 100644
index 0000000..b9a9ec9
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp
@@ -0,0 +1,109 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	<assert.h>
+#include	<stdlib.h>
+
+#include	"stdafx.h"
+
+#include	"LoginDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//===========================================================================================================================
+//	Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP( LoginDialog, CDialog )
+END_MESSAGE_MAP()
+
+//===========================================================================================================================
+//	LoginDialog
+//===========================================================================================================================
+
+LoginDialog::LoginDialog( CWnd *inParent )
+	: CDialog( LoginDialog::IDD, inParent )
+{
+	//
+}
+
+//===========================================================================================================================
+//	OnInitDialog
+//===========================================================================================================================
+
+BOOL	LoginDialog::OnInitDialog( void )
+{
+	CDialog::OnInitDialog();
+	return( TRUE );
+}
+
+//===========================================================================================================================
+//	DoDataExchange
+//===========================================================================================================================
+
+void	LoginDialog::DoDataExchange( CDataExchange *inDX )
+{
+	CDialog::DoDataExchange( inDX );
+}
+
+//===========================================================================================================================
+//	OnOK
+//===========================================================================================================================
+
+void	LoginDialog::OnOK( void )
+{
+	const CWnd *		control;
+		
+	// Username
+	
+	control = GetDlgItem( IDC_LOGIN_USERNAME_TEXT );
+	assert( control );
+	if( control )
+	{
+		control->GetWindowText( mUsername );
+	}
+	
+	// Password
+	
+	control = GetDlgItem( IDC_LOGIN_PASSWORD_TEXT );
+	assert( control );
+	if( control )
+	{
+		control->GetWindowText( mPassword );
+	}
+	
+	CDialog::OnOK();
+}
+
+//===========================================================================================================================
+//	GetLogin
+//===========================================================================================================================
+
+BOOL	LoginDialog::GetLogin( CString &outUsername, CString &outPassword )
+{
+	if( DoModal() == IDOK )
+	{
+		outUsername = mUsername;
+		outPassword = mPassword;
+		return( TRUE );
+	}
+	return( FALSE );
+}
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h b/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h
new file mode 100644
index 0000000..e53beb6
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef	__LOGIN_DIALOG__
+#define	__LOGIN_DIALOG__
+
+#pragma once
+
+#include	"Resource.h"
+
+//===========================================================================================================================
+//	LoginDialog
+//===========================================================================================================================
+
+class	LoginDialog : public CDialog
+{
+	protected:
+	
+		CString		mUsername;
+		CString		mPassword;
+		
+	public:
+		
+		enum { IDD = IDD_LOGIN };
+		
+		LoginDialog( CWnd *inParent = NULL );
+		
+		virtual BOOL	GetLogin( CString &outUsername, CString &outPassword );
+	
+	protected:
+
+		virtual BOOL	OnInitDialog( void );
+		virtual void	DoDataExchange( CDataExchange *inDX );
+		virtual void	OnOK( void );
+		
+		DECLARE_MESSAGE_MAP()
+};
+
+#endif	// __LOGIN_DIALOG__
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp b/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp
new file mode 100644
index 0000000..ae2ca2e
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp
@@ -0,0 +1,18 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	"stdafx.h"
diff --git a/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h b/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h
new file mode 100644
index 0000000..c62bd3e
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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
+
+#ifndef WINVER				// Allow use of features specific to Windows 95 and Windows NT 4 or later.
+	#define WINVER 0x0400	// Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
+#endif
+
+#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	<winsock2.h>
+
+#include	<stdlib.h>
+
+#include	"DNSServices.h"
+
+#include	"Application.h"
+
+#include	"ChooserDialog.h"
+
+#endif // !defined(AFX_STDAFX_H__424305D2_0A97_4AA0_B9B1_A7D90D18EBA0__INCLUDED_)
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc b/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc
new file mode 100644
index 0000000..22f443d
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc
@@ -0,0 +1,37 @@
+; 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
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp b/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp
new file mode 100644
index 0000000..9c73567
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp
@@ -0,0 +1,868 @@
+# 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 /WX /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "_i386_" /D "_X86_" /D "x86" /D "NDEBUG" /D "_WIN32_WCE_CEPC" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /D DNS_SD_CLIENT_ENABLED=0 /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 "_X86_" /D "x86" /D "_WIN32_WCE_CEPC" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /D DNS_SD_CLIENT_ENABLED=0 /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 /WX /I "Resources" /I "Sources" /I "..\..\..\DNSServices" /I "..\..\..\..\mDNSCore" /I "..\..\..\..\mDNSCore\PlatformSupport" /D "ARM" /D "_ARM_" /D "ARMV4" /D "NDEBUG" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /D DNS_SD_CLIENT_ENABLED=0 /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 /WX /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" /D DNS_SD_CLIENT_ENABLED=0 /FR /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=\
+	"..\..\..\DNSServices\DNSServices.h"\
+	".\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=\
+	"..\..\..\DNSServices\DNSServices.h"\
+	".\Sources\Application.h"\
+	".\Sources\BrowserDialog.h"\
+	".\Sources\StdAfx.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_BROWS=\
+	"..\..\..\DNSServices\DNSServices.h"\
+	".\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 "Support"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\..\CommonServices.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DebugServices.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DEBUG=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	
+NODEP_CPP_DEBUG=\
+	"..\..\..\intLib.h"\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DEBUG=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	
+NODEP_CPP_DEBUG=\
+	"..\..\..\intLib.h"\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DEBUG=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	
+NODEP_CPP_DEBUG=\
+	"..\..\..\intLib.h"\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DEBUG=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	
+NODEP_CPP_DEBUG=\
+	"..\..\..\intLib.h"\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DebugServices.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\DNSCommon.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DNSCO=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DNSCO=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DNSCO=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DNSCO=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\DNSCommon.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\DNSDigest.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DNSDI=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DNSDI=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DNSDI=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DNSDI=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DNSSD.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DNSSD=\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	"..\..\..\RMxClient.h"\
+	
+NODEP_CPP_DNSSD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DNSSD=\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	"..\..\..\RMxClient.h"\
+	
+NODEP_CPP_DNSSD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DNSSD=\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	"..\..\..\RMxClient.h"\
+	
+NODEP_CPP_DNSSD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DNSSD=\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	"..\..\..\RMxClient.h"\
+	
+NODEP_CPP_DNSSD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DNSSD.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DNSSDDirect.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DNSSDD=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	
+NODEP_CPP_DNSSDD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DNSSDD=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	
+NODEP_CPP_DNSSDD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DNSSDD=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	
+NODEP_CPP_DNSSDD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DNSSDD=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\DNSSD.h"\
+	"..\..\..\DNSSDDirect.h"\
+	
+NODEP_CPP_DNSSDD=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DNSSDDirect.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\DNSServices\DNSServices.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_DNSSE=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\DNSServices\DNSServices.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_DNSSE=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\DNSServices\DNSServices.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_DNSSE=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\DNSServices\DNSServices.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_DNSSE=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\DNSServices\DNSServices.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\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_MDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_MDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_MDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.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=..\..\..\mDNSWin32.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_MDNSW=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\mDNSWin32.h"\
+	{$(INCLUDE)}"ipexport.h"\
+	{$(INCLUDE)}"Iphlpapi.h"\
+	{$(INCLUDE)}"iptypes.h"\
+	
+NODEP_CPP_MDNSW=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_MDNSW=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\mDNSWin32.h"\
+	{$(INCLUDE)}"ipexport.h"\
+	{$(INCLUDE)}"Iphlpapi.h"\
+	{$(INCLUDE)}"iptypes.h"\
+	
+NODEP_CPP_MDNSW=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+# ADD CPP /W3
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_MDNSW=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\mDNSWin32.h"\
+	{$(INCLUDE)}"ipexport.h"\
+	{$(INCLUDE)}"Iphlpapi.h"\
+	{$(INCLUDE)}"iptypes.h"\
+	
+NODEP_CPP_MDNSW=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_MDNSW=\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\CommonServices.h"\
+	"..\..\..\DebugServices.h"\
+	"..\..\..\mDNSWin32.h"\
+	{$(INCLUDE)}"ipexport.h"\
+	{$(INCLUDE)}"Iphlpapi.h"\
+	{$(INCLUDE)}"iptypes.h"\
+	
+NODEP_CPP_MDNSW=\
+	"..\..\..\logLib.h"\
+	"..\..\..\vxWorks.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\mDNSWin32.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\uDNS.c
+
+!IF  "$(CFG)" == "Application - Win32 (WCE emulator) Release"
+
+DEP_CPP_UDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE emulator) Debug"
+
+DEP_CPP_UDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Release"
+
+DEP_CPP_UDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ELSEIF  "$(CFG)" == "Application - Win32 (WCE ARMV4) Debug"
+
+DEP_CPP_UDNS_=\
+	"..\..\..\..\mDNSCore\DNSCommon.h"\
+	"..\..\..\..\mDNSCore\mDNSClientAPI.h"\
+	"..\..\..\..\mDNSCore\mDNSDebug.h"\
+	"..\..\..\..\mDNSCore\uDNS.h"\
+	
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\mDNSCore\uDNS.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw b/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw
new file mode 100644
index 0000000..11ef513
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw
@@ -0,0 +1,29 @@
+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>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico
new file mode 100644
index 0000000..50fb08f
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico
Binary files differ
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc
new file mode 100644
index 0000000..c153326
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc
@@ -0,0 +1,194 @@
+//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 "DNSServiceBrowser"
+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", "DNSServiceBrowser for Windows CE\0"
+            VALUE "FileVersion", "1, 0, 0, 1\0"
+            VALUE "InternalName", "Application\0"
+            VALUE "LegalCopyright", "Copyright (C) 2003-2004 Apple Computer, Inc.\0"
+            VALUE "LegalTrademarks", "\0"
+            VALUE "OriginalFilename", "Application.exe\0"
+            VALUE "PrivateBuild", "\0"
+            VALUE "ProductName", "DNSServiceBrowser 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
+
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2 b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2
new file mode 100644
index 0000000..29c9fe7
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2
@@ -0,0 +1,13 @@
+//
+// 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...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h
new file mode 100644
index 0000000..31c3a43
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h
@@ -0,0 +1,28 @@
+#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__
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h
new file mode 100644
index 0000000..0337c56
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h
@@ -0,0 +1,22 @@
+//{{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
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp
new file mode 100644
index 0000000..931cd95
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp
@@ -0,0 +1,92 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	"stdafx.h"
+
+#include	"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;
+	
+	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 );
+}
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h
new file mode 100644
index 0000000..cfd5429
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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_)
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp
new file mode 100644
index 0000000..92cdeb3
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp
@@ -0,0 +1,394 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	"stdafx.h"
+
+#include	"Application.h"
+
+#include	"DNSServices.h"
+
+#include	"BrowserDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+//===========================================================================================================================
+//	Constants
+//===========================================================================================================================
+
+#define	WM_USER_SERVICE_ADD			( WM_USER + 0x100 )
+#define	WM_USER_SERVICE_REMOVE		( WM_USER + 0x101 )
+
+//===========================================================================================================================
+//	Message Map
+//===========================================================================================================================
+
+BEGIN_MESSAGE_MAP(BrowserDialog, CDialog)
+	//{{AFX_MSG_MAP(BrowserDialog)
+	ON_NOTIFY(NM_CLICK, IDC_BROWSE_LIST, OnBrowserListDoubleClick)
+	ON_MESSAGE( WM_USER_SERVICE_ADD, OnServiceAdd )
+	ON_MESSAGE( WM_USER_SERVICE_REMOVE, OnServiceRemove )
+	//}}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 );
+	ASSERT( mIcon );
+}
+
+//===========================================================================================================================
+//	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, OnBrowserCallBack, this, &mBrowser );
+	if( err )
+	{
+		AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+		goto exit;
+	}
+	
+	err = DNSBrowserStartServiceSearch( mBrowser, kDNSBrowserFlagAutoResolve, "_http._tcp", NULL );
+	if( err )
+	{
+		AfxMessageBox( IDP_SOCKETS_INIT_FAILED );
+		goto exit;
+	}
+	
+exit:
+	return( TRUE );
+}
+
+
+//===========================================================================================================================
+//	OnBrowserListDoubleClick
+//===========================================================================================================================
+
+void	BrowserDialog::OnBrowserListDoubleClick( NMHDR *pNMHDR, LRESULT *pResult ) 
+{
+	int		selectedItem;
+
+	(void) pNMHDR;	// Unused
+
+	selectedItem = mBrowserList.GetNextItem( -1, LVNI_SELECTED );
+	if( selectedItem >= 0 )
+	{
+		BrowserEntry *		entry;
+		CString				temp;
+		CString				url;
+		
+		// Build the URL from the IP and optional TXT record.
+
+		entry = &mBrowserEntries[ selectedItem ];
+		url += "http://" + entry->ip;
+		temp = entry->text;
+		if( temp.Find( TEXT( "path=" ) ) == 0 )
+		{
+			temp.Delete( 0, 5 );
+		}
+		if( temp.Find( '/' ) != 0 )
+		{
+			url += '/';
+		}
+		url += temp;
+
+		// Let the system open the URL in the correct app.
+		
+		SHELLEXECUTEINFO		info;
+
+		info.cbSize			= sizeof( info );
+		info.fMask 			= 0;
+		info.hwnd 			= NULL;
+		info.lpVerb 		= NULL;
+		info.lpFile 		= url;
+		info.lpParameters 	= NULL;
+		info.lpDirectory 	= NULL;
+		info.nShow 			= SW_SHOWNORMAL;
+		info.hInstApp 		= NULL;
+
+		ShellExecuteEx( &info );
+	}
+	*pResult = 0;
+}
+
+//===========================================================================================================================
+//	OnBrowserCallBack [static]
+//===========================================================================================================================
+
+void
+	BrowserDialog::OnBrowserCallBack( 
+		void *					inContext, 
+		DNSBrowserRef			inRef, 
+		DNSStatus				inStatusCode,
+		const DNSBrowserEvent *	inEvent )
+{
+	BrowserDialog *		dialog;
+	BrowserEntry *		entry;
+	BOOL				posted;
+	
+	DNS_UNUSED( inStatusCode );
+	dialog = reinterpret_cast < BrowserDialog * > ( inContext );
+	ASSERT( dialog );
+	
+	switch( inEvent->type )
+	{
+		case kDNSBrowserEventTypeResolved:
+			if( inEvent->data.resolved->address.addressType == kDNSNetworkAddressTypeIPv4  )
+			{
+				char		ip[ 64 ];
+
+				sprintf( ip, "%u.%u.%u.%u:%u", 
+					inEvent->data.resolved->address.u.ipv4.addr.v8[ 0 ], 
+					inEvent->data.resolved->address.u.ipv4.addr.v8[ 1 ], 
+					inEvent->data.resolved->address.u.ipv4.addr.v8[ 2 ], 
+					inEvent->data.resolved->address.u.ipv4.addr.v8[ 3 ], 
+					( inEvent->data.resolved->address.u.ipv4.port.v8[ 0 ] << 8 ) | 
+					  inEvent->data.resolved->address.u.ipv4.port.v8[ 1 ] );
+				
+				entry = new BrowserEntry;
+				ASSERT( entry );
+				if( entry )
+				{
+					UTF8StringToStringObject( inEvent->data.resolved->name, entry->name );
+					UTF8StringToStringObject( ip, entry->ip );
+					UTF8StringToStringObject( inEvent->data.resolved->textRecord, entry->text );
+					
+					posted = ::PostMessage( dialog->GetSafeHwnd(), WM_USER_SERVICE_ADD, 0, (LPARAM) entry );
+					ASSERT( posted );
+					if( !posted )
+					{
+						delete entry;
+					}
+				}
+			}
+			break;
+
+		case kDNSBrowserEventTypeRemoveService:
+			entry = new BrowserEntry;
+			ASSERT( entry );
+			if( entry )
+			{
+				UTF8StringToStringObject( inEvent->data.removeService.name, entry->name );
+				
+				posted = ::PostMessage( dialog->GetSafeHwnd(), WM_USER_SERVICE_REMOVE, 0, (LPARAM) entry );
+				ASSERT( posted );
+				if( !posted )
+				{
+					delete entry;
+				}
+			}
+			break;
+		
+		default:
+			break;
+	}
+}
+
+//===========================================================================================================================
+//	BrowserAddService
+//===========================================================================================================================
+
+LONG	BrowserDialog::OnServiceAdd( WPARAM inWParam, LPARAM inLParam )
+{
+	BrowserEntry *		entry;
+	INT_PTR				lo;
+	INT_PTR				hi;
+	INT_PTR				mid;
+	int					result;
+	
+	(void) inWParam;	// Unused
+	
+	entry = reinterpret_cast < BrowserEntry * > ( inLParam );
+	ASSERT( entry );
+	
+	result 	= -1;
+	mid		= 0;
+	lo 		= 0;
+	hi 		= mBrowserEntries.GetSize() - 1;
+	while( lo <= hi )
+	{
+		mid = ( lo + hi ) / 2;
+		result = entry->name.CompareNoCase( mBrowserEntries[ mid ].name );
+		if( result == 0 )
+		{
+			break;
+		}
+		else if( result < 0 )
+		{
+			hi = mid - 1;
+		}
+		else
+		{
+			lo = mid + 1;
+		}
+	}
+	if( result == 0 )
+	{
+		mBrowserEntries[ mid ].ip	= entry->ip;
+		mBrowserEntries[ mid ].text	= entry->text;
+	}
+	else
+	{
+		if( result > 0 )
+		{
+			mid += 1;
+		}
+		mBrowserEntries.InsertAt( mid, *entry );
+		mBrowserList.InsertItem( mid, entry->name );
+	}
+	delete entry;
+	return( 0 );
+}
+
+//===========================================================================================================================
+//	OnServiceRemove
+//===========================================================================================================================
+
+LONG	BrowserDialog::OnServiceRemove( WPARAM inWParam, LPARAM inLParam )
+{
+	BrowserEntry *		entry;
+	INT_PTR				hi;
+	INT_PTR				lo;
+	INT_PTR				mid;
+	int					result;
+
+	(void) inWParam;	// Unused
+	
+	entry = reinterpret_cast < BrowserEntry * > ( inLParam );
+	ASSERT( entry );
+	
+	result 	= -1;
+	mid		= 0;
+	lo 		= 0;
+	hi 		= mBrowserEntries.GetSize() - 1;
+	while( lo <= hi )
+	{
+		mid = ( lo + hi ) / 2;
+		result = entry->name.CompareNoCase( mBrowserEntries[ mid ].name );
+		if( result == 0 )
+		{
+			break;
+		}
+		else if( result < 0 )
+		{
+			hi = mid - 1;
+		}
+		else
+		{
+			lo = mid + 1;
+		}
+	}
+	if( result == 0 )
+	{
+		mBrowserList.DeleteItem( mid );
+		mBrowserEntries.RemoveAt( mid );
+	}
+	delete entry;
+	return( 0 );
+}
+
+#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 );
+}
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h
new file mode 100644
index 0000000..a27df91
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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
+			OnBrowserCallBack( 
+				void *					inContext, 
+				DNSBrowserRef			inRef, 
+				DNSStatus				inStatusCode,  
+				const DNSBrowserEvent *	inEvent );
+		
+	protected:
+		
+		struct	BrowserEntry
+		{
+			CString		name;
+			CString		ip;
+			CString		text;
+		};
+		
+		HICON										mIcon;
+		DNSBrowserRef								mBrowser;
+		CArray < BrowserEntry, BrowserEntry >		mBrowserEntries;
+		
+		// Generated message map functions
+		//{{AFX_MSG(BrowserDialog)
+		virtual BOOL OnInitDialog();
+		afx_msg void OnBrowserListDoubleClick(NMHDR* pNMHDR, LRESULT* pResult);
+		afx_msg LONG OnServiceAdd( WPARAM inWParam, LPARAM inLParam );
+		afx_msg LONG OnServiceRemove( WPARAM inWParam, LPARAM inLParam );
+		//}}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_)
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp
new file mode 100644
index 0000000..ae2ca2e
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp
@@ -0,0 +1,18 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	"stdafx.h"
diff --git a/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h
new file mode 100644
index 0000000..4b14a0b
--- /dev/null
+++ b/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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 <winsock2.h>
+//#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_)
diff --git a/mDNSWindows/Java/Java.vcproj b/mDNSWindows/Java/Java.vcproj
new file mode 100755
index 0000000..1707ac5
--- /dev/null
+++ b/mDNSWindows/Java/Java.vcproj
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="Java"

+	ProjectGUID="{9CE2568A-3170-41C6-9F20-A0188A9EC114}"

+	Keyword="MakeFileProj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="Debug"

+			IntermediateDirectory="Debug"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /f makefile DEBUG=1"

+				ReBuildCommandLine="nmake /f makefile DEBUG=1"

+				CleanCommandLine="nmake /f makefile DEBUG=1 clean"

+				Output=""

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /f makefile64 DEBUG=1"

+				ReBuildCommandLine="nmake /f makefile64 DEBUG=1"

+				CleanCommandLine="nmake /f makefile64 DEBUG=1 clean"

+				Output=""

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="Release"

+			IntermediateDirectory="Release"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /f makefile"

+				ReBuildCommandLine="nmake /f makefile"

+				CleanCommandLine="nmake /f makefile clean"

+				Output=""

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="0"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			>

+			<Tool

+				Name="VCNMakeTool"

+				BuildCommandLine="nmake /f makefile64"

+				ReBuildCommandLine="nmake /f makefile64"

+				CleanCommandLine="nmake /f makefile64 clean"

+				Output=""

+				PreprocessorDefinitions=""

+				IncludeSearchPath=""

+				ForcedIncludes=""

+				AssemblySearchPath=""

+				ForcedUsingAssemblies=""

+				CompileAsManaged=""

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/Java/jdns_sd.rc b/mDNSWindows/Java/jdns_sd.rc
new file mode 100644
index 0000000..79fdf14
--- /dev/null
+++ b/mDNSWindows/Java/jdns_sd.rc
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef JDNS_SD_RC
+#define JDNS_SD_RC
+
+#include "afxres.h"
+#include "../WinVersRes.h"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MASTER_PROD_VERS
+ PRODUCTVERSION MASTER_PROD_VERS
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", MASTER_COMPANY_NAME
+            VALUE "FileDescription", MASTER_PROD_NAME " support for Java"
+            VALUE "FileVersion", MASTER_PROD_VERS_STR
+            VALUE "InternalName", "jdns_sd"
+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "jdns_sd.dll"
+            VALUE "ProductName", MASTER_PROD_NAME
+            VALUE "ProductVersion", MASTER_PROD_VERS_STR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif // JDNS_SD_RC
diff --git a/mDNSWindows/Java/makefile b/mDNSWindows/Java/makefile
new file mode 100644
index 0000000..2e4b6bd
--- /dev/null
+++ b/mDNSWindows/Java/makefile
@@ -0,0 +1,143 @@
+# -*- tab-width: 4 -*-
+#
+# Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This Makefile builds a .jar file and accompanying JNI support library
+# containing the DNSSD implementation for Java and support classes.
+#
+# Prior to building Java support, you must build DNSSD.dll.
+#
+# nmake with no arguments builds all production targets.
+# 'nmake DEBUG=1' to build debugging targets.
+# 'nmake clean' or 'nmake clean DEBUG=1' to delete prod/debug objects & targets
+#
+# To run nmake, you may need to set up your PATH correctly, using a script 
+# such as: "\Program Files\Microsoft Visual Studio .NET\Vc7\bin\vcvars32.bat"
+# 
+# The default location of the JDK is \javasdk. You can override this on the
+# command line (e.g. 'nmake JDK=\j2dk1.4.2_03').
+
+############################################################################
+
+COREDIR = ..\..\mDNSCore
+SHAREDDIR = ..\..\mDNSShared
+
+JDK = $(JAVA_HOME)
+
+CC = cl
+RC = rc
+LD = ld
+CP = copy
+RM = del /Q
+RMDIR = rmdir /S /Q
+JAVAC = $(JDK)\bin\javac
+JAVAH = $(JDK)\bin\javah
+JAR = $(JDK)\bin\jar
+CFLAGS_COMMON = -LD -DAUTO_CALLBACKS=0 -I. -I..\.. \
+	-I$(COREDIR) -I$(SHAREDDIR) -I$(JDK)\include -I$(JDK)\include\win32
+
+# Set up diverging paths for debug vs. prod builds
+DEBUG=0
+!if $(DEBUG) == 1
+CFLAGS_DEBUG = -Zi -DMDNS_DEBUGMSGS=2 
+OBJDIR = objects\debug
+BUILDDIR = build\debug
+INSTALLDIR = root\"Program Files"\Bonjour
+LIBDIR = ..\DLL\Win32\Debug
+!else
+CFLAGS_DEBUG = -Os -DMDNS_DEBUGMSGS=0 
+OBJDIR = objects\prod
+BUILDDIR = build\prod
+INSTALLDIR = root\"Program Files"\Bonjour
+LIBDIR = ..\DLL\Win32\Release
+!endif
+
+CFLAGS = $(CFLAGS_COMMON) $(CFLAGS_DEBUG)
+JAVACFLAGS = $(CFLAGS) $(JAVACFLAGS_OS)
+
+#############################################################################
+
+all: setup Java postbuild
+
+# 'setup' sets up the build directory structure the way we want
+setup:
+	@if not exist objects		mkdir objects
+	@if not exist build			mkdir build
+	@if not exist $(OBJDIR)		mkdir $(OBJDIR)
+	@if not exist $(BUILDDIR)	mkdir $(BUILDDIR)
+
+postbuild:
+	@if not "%RC_XBS%"=="YES" GOTO CONT
+	@if not exist "$(DSTROOT)\WINDOWS\system32\Win32"	mkdir "$(DSTROOT)\WINDOWS\system32\Win32"
+	@if not exist "$(DSTROOT)\Program Files\Bonjour\Win32"	mkdir "$(DSTROOT)\Program Files\Bonjour\Win32"
+	@copy $(BUILDDIR)\jdns_sd.dll "$(DSTROOT)\WINDOWS\system32\Win32"
+	@copy $(BUILDDIR)\dns_sd.jar  "$(DSTROOT)\Program Files\Bonjour\Win32"
+	@:CONT
+	@if not exist root					mkdir root
+	@if not exist root\"Program Files"	mkdir root\"Program Files"
+	@if not exist $(INSTALLDIR)			mkdir $(INSTALLDIR)
+	copy $(BUILDDIR)\dns_sd.jar $(INSTALLDIR)
+	copy $(BUILDDIR)\jdns_sd.dll $(INSTALLDIR)
+
+# clean removes targets and objects
+clean:
+	@if exist $(OBJDIR)		$(RMDIR) $(OBJDIR)
+	@if exist $(BUILDDIR)	$(RMDIR) $(BUILDDIR)
+
+#############################################################################
+
+# The following targets build Java wrappers for the dns-sd.h API.
+
+Java: setup $(BUILDDIR)\dns_sd.jar $(BUILDDIR)\jdns_sd.dll postbuild
+	@echo "Java wrappers done"
+
+JAVASRC	= $(SHAREDDIR)\Java
+JARCONTENTS =	$(OBJDIR)\com\apple\dnssd\DNSSDService.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSDException.class \
+				$(OBJDIR)\com\apple\dnssd\DNSRecord.class \
+				$(OBJDIR)\com\apple\dnssd\TXTRecord.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSDRegistration.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSDRecordRegistrar.class \
+				$(OBJDIR)\com\apple\dnssd\BaseListener.class \
+				$(OBJDIR)\com\apple\dnssd\BrowseListener.class \
+				$(OBJDIR)\com\apple\dnssd\ResolveListener.class \
+				$(OBJDIR)\com\apple\dnssd\RegisterListener.class \
+				$(OBJDIR)\com\apple\dnssd\RegisterRecordListener.class \
+				$(OBJDIR)\com\apple\dnssd\QueryListener.class \
+				$(OBJDIR)\com\apple\dnssd\DomainListener.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSD.class
+
+$(BUILDDIR)\dns_sd.jar: $(JARCONTENTS)
+	$(JAR) -cf $@ -C $(OBJDIR) com
+
+$(BUILDDIR)\jdns_sd.dll: $(JAVASRC)\JNISupport.c $(OBJDIR)\DNSSD.java.h $(OBJDIR)\jdns_sd.RES
+	$(CC) -Fe$@ $(JAVASRC)\JNISupport.c $(CFLAGS) -I$(OBJDIR) \
+	$(LIBDIR)\DNSSD.lib $(JDK)\lib\jvm.lib ws2_32.lib iphlpapi.lib $(OBJDIR)\jdns_sd.RES /link /NXCOMPAT /DYNAMICBASE /SAFESEH
+
+.SUFFIXES : .java
+{$(JAVASRC)}.java{$(OBJDIR)\com\apple\dnssd}.class:	
+	$(JAVAC) -d $(OBJDIR) -classpath $(OBJDIR) $<
+
+$(OBJDIR)\DNSSD.java.h: $(OBJDIR)\com\apple\dnssd\DNSSD.class
+	$(JAVAH) -classpath $(OBJDIR) -o $@ \
+		com.apple.dnssd.AppleBrowser \
+		com.apple.dnssd.AppleResolver \
+		com.apple.dnssd.AppleRegistration \
+		com.apple.dnssd.AppleQuery \
+		com.apple.dnssd.AppleService 
+
+$(OBJDIR)\jdns_sd.RES: jdns_sd.rc
+	$(RC) /fo $@ $?
+
diff --git a/mDNSWindows/Java/makefile64 b/mDNSWindows/Java/makefile64
new file mode 100644
index 0000000..fb0ff9c
--- /dev/null
+++ b/mDNSWindows/Java/makefile64
@@ -0,0 +1,143 @@
+# -*- tab-width: 4 -*-
+#
+# Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# This Makefile builds a .jar file and accompanying JNI support library
+# containing the DNSSD implementation for Java and support classes.
+#
+# Prior to building Java support, you must build DNSSD.dll.
+#
+# nmake with no arguments builds all production targets.
+# 'nmake DEBUG=1' to build debugging targets.
+# 'nmake clean' or 'nmake clean DEBUG=1' to delete prod/debug objects & targets
+#
+# To run nmake, you may need to set up your PATH correctly, using a script 
+# such as: "\Program Files\Microsoft Visual Studio .NET\Vc7\bin\vcvars32.bat"
+# 
+# The default location of the JDK is \javasdk. You can override this on the
+# command line (e.g. 'nmake JDK=\j2dk1.4.2_03').
+
+############################################################################
+
+COREDIR = ..\..\mDNSCore
+SHAREDDIR = ..\..\mDNSShared
+
+JDK = $(JAVA_HOME)
+
+CC = cl
+RC = rc
+LD = ld
+CP = copy
+RM = del /Q
+RMDIR = rmdir /S /Q
+JAVAC = $(JDK)\bin\javac
+JAVAH = $(JDK)\bin\javah
+JAR = $(JDK)\bin\jar
+CFLAGS_COMMON = -LD -DAUTO_CALLBACKS=0 -I. -I..\.. \
+	-I$(COREDIR) -I$(SHAREDDIR) -I$(JDK)\include -I$(JDK)\include\win32
+
+# Set up diverging paths for debug vs. prod builds
+DEBUG=0
+!if $(DEBUG) == 1
+CFLAGS_DEBUG = -Zi -DMDNS_DEBUGMSGS=2 
+OBJDIR = objects\debug\x64
+BUILDDIR = build\debug\x64
+INSTALLDIR = root\"Program Files"\Bonjour
+LIBDIR = ..\DLL\x64\Debug
+!else
+CFLAGS_DEBUG = -Os -DMDNS_DEBUGMSGS=0 
+OBJDIR = objects\prod\x64
+BUILDDIR = build\prod\x64
+INSTALLDIR = root\"Program Files"\Bonjour
+LIBDIR = ..\DLL\x64\Release
+!endif
+
+CFLAGS = $(CFLAGS_COMMON) $(CFLAGS_DEBUG)
+JAVACFLAGS = $(CFLAGS) $(JAVACFLAGS_OS)
+
+#############################################################################
+
+all: setup Java postbuild
+
+# 'setup' sets up the build directory structure the way we want
+setup:
+	@if not exist objects		mkdir objects
+	@if not exist build			mkdir build
+	@if not exist $(OBJDIR)		mkdir $(OBJDIR)
+	@if not exist $(BUILDDIR)	mkdir $(BUILDDIR)
+
+postbuild:
+	@if not "%RC_XBS%"=="YES" GOTO CONT
+	@if not exist "$(DSTROOT)\WINDOWS\system32\x64"	mkdir "$(DSTROOT)\WINDOWS\system32\x64"
+	@if not exist "$(DSTROOT)\Program Files\Bonjour\x64"	mkdir "$(DSTROOT)\Program Files\Bonjour\x64"
+	@copy $(BUILDDIR)\jdns_sd.dll "$(DSTROOT)\WINDOWS\system32\x64"
+	@copy $(BUILDDIR)\dns_sd.jar  "$(DSTROOT)\Program Files\Bonjour\x64"
+	@:CONT
+	@if not exist root					mkdir root
+	@if not exist root\"Program Files"	mkdir root\"Program Files"
+	@if not exist $(INSTALLDIR)			mkdir $(INSTALLDIR)
+	copy $(BUILDDIR)\dns_sd.jar $(INSTALLDIR)
+	copy $(BUILDDIR)\jdns_sd.dll $(INSTALLDIR)
+
+# clean removes targets and objects
+clean:
+	@if exist $(OBJDIR)		$(RMDIR) $(OBJDIR)
+	@if exist $(BUILDDIR)	$(RMDIR) $(BUILDDIR)
+
+#############################################################################
+
+# The following targets build Java wrappers for the dns-sd.h API.
+
+Java: setup $(BUILDDIR)\dns_sd.jar $(BUILDDIR)\jdns_sd.dll postbuild
+	@echo "Java wrappers done"
+
+JAVASRC	= $(SHAREDDIR)\Java
+JARCONTENTS =	$(OBJDIR)\com\apple\dnssd\DNSSDService.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSDException.class \
+				$(OBJDIR)\com\apple\dnssd\DNSRecord.class \
+				$(OBJDIR)\com\apple\dnssd\TXTRecord.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSDRegistration.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSDRecordRegistrar.class \
+				$(OBJDIR)\com\apple\dnssd\BaseListener.class \
+				$(OBJDIR)\com\apple\dnssd\BrowseListener.class \
+				$(OBJDIR)\com\apple\dnssd\ResolveListener.class \
+				$(OBJDIR)\com\apple\dnssd\RegisterListener.class \
+				$(OBJDIR)\com\apple\dnssd\RegisterRecordListener.class \
+				$(OBJDIR)\com\apple\dnssd\QueryListener.class \
+				$(OBJDIR)\com\apple\dnssd\DomainListener.class \
+				$(OBJDIR)\com\apple\dnssd\DNSSD.class
+
+$(BUILDDIR)\dns_sd.jar: $(JARCONTENTS)
+	$(JAR) -cf $@ -C $(OBJDIR) com
+
+$(BUILDDIR)\jdns_sd.dll: $(JAVASRC)\JNISupport.c $(OBJDIR)\DNSSD.java.h $(OBJDIR)\jdns_sd.RES
+	$(CC) -Fe$@ $(JAVASRC)\JNISupport.c $(CFLAGS) -I$(OBJDIR) \
+	$(LIBDIR)\DNSSD.lib $(JDK)\lib\jvm.lib ws2_32.lib iphlpapi.lib $(OBJDIR)\jdns_sd.RES /link /NXCOMPAT /DYNAMICBASE
+
+.SUFFIXES : .java
+{$(JAVASRC)}.java{$(OBJDIR)\com\apple\dnssd}.class:	
+	$(JAVAC) -d $(OBJDIR) -classpath $(OBJDIR) $<
+
+$(OBJDIR)\DNSSD.java.h: $(OBJDIR)\com\apple\dnssd\DNSSD.class
+	$(JAVAH) -classpath $(OBJDIR) -o $@ \
+		com.apple.dnssd.AppleBrowser \
+		com.apple.dnssd.AppleResolver \
+		com.apple.dnssd.AppleRegistration \
+		com.apple.dnssd.AppleQuery \
+		com.apple.dnssd.AppleService 
+
+$(OBJDIR)\jdns_sd.RES: jdns_sd.rc
+	$(RC) /fo $@ $?
+
diff --git a/mDNSWindows/NSPTool/NSPTool.aps b/mDNSWindows/NSPTool/NSPTool.aps
new file mode 100644
index 0000000..313f306
--- /dev/null
+++ b/mDNSWindows/NSPTool/NSPTool.aps
Binary files differ
diff --git a/mDNSWindows/NSPTool/NSPTool.c b/mDNSWindows/NSPTool/NSPTool.c
new file mode 100644
index 0000000..f3052d1
--- /dev/null
+++ b/mDNSWindows/NSPTool/NSPTool.c
@@ -0,0 +1,581 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	<stdio.h>
+#include	<stdlib.h>
+
+#include	"CommonServices.h"
+#include	"DebugServices.h"
+
+#include	<guiddef.h>
+#include	<ws2spi.h>
+
+//===========================================================================================================================
+//	Prototypes
+//===========================================================================================================================
+
+int  					main( int argc, char *argv[] );
+DEBUG_LOCAL void		Usage( void );
+DEBUG_LOCAL int			ProcessArgs( int argc, char *argv[] );
+DEBUG_LOCAL OSStatus	InstallNSP( const char *inName, const char *inGUID, const char *inPath );
+DEBUG_LOCAL OSStatus	RemoveNSP( const char *inGUID );
+DEBUG_LOCAL OSStatus	EnableNSP( const char *inGUID, BOOL inEnable );
+DEBUG_LOCAL OSStatus	ListNameSpaces( void );
+DEBUG_LOCAL OSStatus	ReorderNameSpaces( void );
+
+DEBUG_LOCAL WCHAR *		CharToWCharString( const char *inCharString, WCHAR *outWCharString );
+DEBUG_LOCAL char *		GUIDtoString( const GUID *inGUID, char *outString );
+DEBUG_LOCAL OSStatus	StringToGUID( const char *inCharString, GUID *outGUID );
+
+DEBUG_LOCAL BOOL gToolQuietMode = FALSE;
+
+//===========================================================================================================================
+//	main
+//===========================================================================================================================
+
+int main( int argc, char *argv[] )
+{
+	OSStatus		err;
+	
+	debug_initialize( kDebugOutputTypeMetaConsole );
+	debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
+	
+	err = ProcessArgs( argc, argv );
+	return( (int) err );
+}
+
+//===========================================================================================================================
+//	Usage
+//===========================================================================================================================
+
+DEBUG_LOCAL void	Usage( void )
+{
+	fprintf( stderr, "\n" );
+	fprintf( stderr, "NSP Tool 1.0d1\n" );
+	fprintf( stderr, "  Name Space Provider Tool\n" );
+	fprintf( stderr, "\n" );
+	
+	fprintf( stderr, "  -install <name> <guid> <path>   - Installs a Name Space Provider\n" );
+	fprintf( stderr, "\n" );
+	fprintf( stderr, "      <name> Name of the NSP\n" );
+	fprintf( stderr, "      <guid> GUID of the NSP\n" );
+	fprintf( stderr, "      <path> Path to the NSP file\n" );
+	fprintf( stderr, "\n" );
+	
+	fprintf( stderr, "  -remove <guid>                  - Removes a Name Space Provider\n" );
+	fprintf( stderr, "\n" );
+	fprintf( stderr, "      <guid> GUID of the NSP\n" );
+	fprintf( stderr, "\n" );
+	
+	fprintf( stderr, "  -enable/-disable <guid>         - Enables or Disables a Name Space Provider\n" );
+	fprintf( stderr, "\n" );
+	fprintf( stderr, "      <guid> GUID of the NSP\n" );
+	fprintf( stderr, "\n" );
+	
+	fprintf( stderr, "  -list                           - Lists Name Space Providers\n" );	
+	fprintf( stderr, "  -reorder                        - Reorders Name Space Providers\n" );
+	fprintf( stderr, "  -q                              - Enable quiet mode\n" );
+	fprintf( stderr, "  -h[elp]                         - Help\n" );
+	fprintf( stderr, "\n" );
+}
+
+//===========================================================================================================================
+//	ProcessArgs
+//===========================================================================================================================
+
+DEBUG_LOCAL int ProcessArgs( int argc, char* argv[] )
+{	
+	OSStatus			err;
+	int					i;
+	const char *		name;
+	const char *		guid;
+	const char *		path;
+			
+	if( argc <= 1 )
+	{
+		Usage();
+		err = 0;
+		goto exit;
+	}
+	for( i = 1; i < argc; ++i )
+	{
+		if( strcmp( argv[ i ], "-install" ) == 0 )
+		{
+			// Install
+			
+			if( argc <= ( i + 3 ) )
+			{
+				fprintf( stderr, "\n### ERROR: missing arguments for %s\n\n", argv[ i ] );
+				Usage();
+				err = kParamErr;
+				goto exit;
+			}
+			name = argv[ ++i ];
+			guid = argv[ ++i ];
+			path = argv[ ++i ];
+			
+			if( *name == '\0' )
+			{
+				name = "DotLocalNSP";
+			}
+			if( *guid == '\0' )
+			{
+				guid = "B600E6E9-553B-4a19-8696-335E5C896153";
+			}
+			
+			err = InstallNSP( name, guid, path );
+			require_noerr( err, exit );
+		}
+		else if( strcmp( argv[ i ], "-remove" ) == 0 )
+		{
+			// Remove
+			
+			if( argc <= ( i + 1 ) )
+			{
+				fprintf( stderr, "\n### ERROR: missing arguments for %s\n\n", argv[ i ] );
+				Usage();
+				err = kParamErr;
+				goto exit;
+			}
+			guid = argv[ ++i ];
+			if( *guid == '\0' )
+			{
+				guid = "B600E6E9-553B-4a19-8696-335E5C896153";
+			}
+			
+			err = RemoveNSP( guid );
+			require_noerr( err, exit );
+		}
+		else if( ( strcmp( argv[ i ], "-enable" )  == 0 ) || 
+				 ( strcmp( argv[ i ], "-disable" ) == 0 ) )
+		{
+			BOOL		enable;
+			
+			// Enable/Disable
+			
+			enable = ( strcmp( argv[ i ], "-enable" ) == 0 );
+			if( argc <= ( i + 1 ) )
+			{
+				fprintf( stderr, "\n### ERROR: missing arguments for %s\n\n", argv[ i ] );
+				Usage();
+				err = kParamErr;
+				goto exit;
+			}
+			guid = argv[ ++i ];
+			
+			err = EnableNSP( guid, enable );
+			require_noerr( err, exit );
+		}
+		else if( strcmp( argv[ i ], "-list" ) == 0 )
+		{
+			// List
+						
+			err = ListNameSpaces();
+			require_noerr( err, exit );
+		}
+		else if( strcmp( argv[ i ], "-reorder" ) == 0 )
+		{
+			// Reorder
+			
+			err = ReorderNameSpaces();
+			require_noerr( err, exit );
+		}
+		else if( strcmp( argv[ i ], "-q" ) == 0 )
+		{
+			gToolQuietMode = TRUE;
+		}
+		else if( ( strcmp( argv[ i ], "-help" ) == 0 ) || 
+				 ( strcmp( argv[ i ], "-h" ) == 0 ) )
+		{
+			// Help
+			
+			Usage();
+			err = 0;
+			goto exit;
+		}
+		else
+		{
+			fprintf( stderr, "\n### ERROR: unknown argment: \"%s\"\n\n", argv[ i ] );
+			Usage();
+			err = kParamErr;
+			goto exit;
+		}
+	}
+	err = kNoErr;
+	
+exit:
+	return( err );
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	InstallNSP
+//===========================================================================================================================
+
+OSStatus	InstallNSP( const char *inName, const char *inGUID, const char *inPath )
+{
+	OSStatus		err;
+	size_t			size;
+	WSADATA			wsd;
+	WCHAR			name[ 256 ];
+	GUID			guid;
+	WCHAR			path[ MAX_PATH ];
+	
+	require_action( inName && ( *inName != '\0' ), exit, err = kParamErr );
+	require_action( inGUID && ( *inGUID != '\0' ), exit, err = kParamErr );
+	require_action( inPath && ( *inPath != '\0' ), exit, err = kParamErr );
+	
+	size = strlen( inName );
+	require_action( size < sizeof_array( name ), exit, err = kSizeErr );
+	CharToWCharString( inName, name );
+	
+	err = StringToGUID( inGUID, &guid );
+	require_noerr( err, exit );
+	
+	size = strlen( inPath );
+	require_action( size < sizeof_array( path ), exit, err = kSizeErr );
+	CharToWCharString( inPath, path );
+	
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+	err = WSCInstallNameSpace( name, path, NS_DNS, 1, &guid );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	WSACleanup();
+	require_noerr( err, exit );
+	
+	if (!gToolQuietMode)
+	{
+		fprintf( stderr, "Installed NSP \"%s\" (%s) at %s\n", inName, inGUID, inPath );
+	}
+	
+exit:
+	if( err != kNoErr )
+	{
+		fprintf( stderr, "### FAILED (%d) to install \"%s\" (%s) Name Space Provider at %s\n", err, inName, inGUID, inPath );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	RemoveNSP
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	RemoveNSP( const char *inGUID )
+{
+	OSStatus		err;
+	WSADATA			wsd;
+	GUID			guid;
+	
+	require_action( inGUID && ( *inGUID != '\0' ), exit, err = kParamErr );
+	
+	err = StringToGUID( inGUID, &guid );
+	require_noerr( err, exit );
+	
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+	err = WSCUnInstallNameSpace( &guid );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	WSACleanup();
+	require_noerr( err, exit );
+	
+	if (!gToolQuietMode)
+	{
+		fprintf( stderr, "Removed NSP %s\n", inGUID );
+	}
+		
+exit:
+	if( err != kNoErr )
+	{
+		fprintf( stderr, "### FAILED (%d) to remove %s Name Space Provider\n", err, inGUID );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	EnableNSP
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	EnableNSP( const char *inGUID, BOOL inEnable )
+{
+	OSStatus		err;
+	WSADATA			wsd;
+	GUID			guid;
+	
+	require_action( inGUID && ( *inGUID != '\0' ), exit, err = kParamErr );
+	
+	err = StringToGUID( inGUID, &guid );
+	require_noerr( err, exit );
+	
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+	err = WSCEnableNSProvider( &guid, inEnable );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	WSACleanup();
+	require_noerr( err, exit );
+	
+	if (!gToolQuietMode)
+	{
+		fprintf( stderr, "Removed NSP %s\n", inGUID );
+	}
+		
+exit:
+	if( err != kNoErr )
+	{
+		fprintf( stderr, "### FAILED (%d) to remove %s Name Space Provider\n", err, inGUID );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	ListNameSpaces
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	ListNameSpaces( void )
+{
+	OSStatus				err;
+	WSADATA					wsd;
+	bool					started;
+	int						n;
+	int						i;
+	DWORD					size;
+	WSANAMESPACE_INFO *		array;
+	char					s[ 256 ];
+	
+	array 	= NULL;
+	started	= false;
+	
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	started = true;
+	
+	// Build an array of all the NSPs. Call it first with NULL to get the size, allocate a buffer, then get them into it.
+	
+	size = 0;
+	n = WSAEnumNameSpaceProviders( &size, NULL );
+	err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
+	require_action( err == WSAEFAULT, exit, err = kUnknownErr );
+	
+	array = (WSANAMESPACE_INFO *) malloc( size );
+	require_action( array, exit, err = kNoMemoryErr );
+	
+	n = WSAEnumNameSpaceProviders( &size, array );
+	err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	fprintf( stdout, "\n" );
+	for( i = 0; i < n; ++i )
+	{
+		fprintf( stdout, "Name Space %d\n", i + 1 );
+		fprintf( stdout, "    NSProviderId:   %s\n", GUIDtoString( &array[ i ].NSProviderId, s ) );
+		fprintf( stdout, "    dwNameSpace:    %d\n", array[ i ].dwNameSpace );
+		fprintf( stdout, "    fActive:        %s\n", array[ i ].fActive ? "YES" : "NO" );
+		fprintf( stdout, "    dwVersion:      %d\n", array[ i ].dwVersion );
+		fprintf( stdout, "    lpszIdentifier: \"%s\"\n", array[ i ].lpszIdentifier );
+		fprintf( stdout, "\n" );
+	}
+	err = kNoErr;
+	
+exit:
+	if( array )
+	{
+		free( array );
+	}
+	if( started )
+	{
+		WSACleanup();
+	}
+	if( err != kNoErr )
+	{
+		fprintf( stderr, "### FAILED (%d) to list Name Space Providers\n", err );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	ReorderNameSpaces
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	ReorderNameSpaces( void )
+{
+	OSStatus				err;
+	WSADATA					wsd;
+	bool					started;
+	int						n;
+	int						i;
+	DWORD					size;
+	WSANAMESPACE_INFO *		array;
+	WCHAR					name[ 256 ];
+	WCHAR					path[ MAX_PATH ];
+	
+	array 	= NULL;
+	started	= false;
+		
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	started = true;
+	
+	// Build an array of all the NSPs. Call it first with NULL to get the size, allocate a buffer, then get them into it.
+	
+	size = 0;
+	n = WSAEnumNameSpaceProviders( &size, NULL );
+	err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
+	require_action( err == WSAEFAULT, exit, err = kUnknownErr );
+	
+	array = (WSANAMESPACE_INFO *) malloc( size );
+	require_action( array, exit, err = kNoMemoryErr );
+	
+	n = WSAEnumNameSpaceProviders( &size, array );
+	err = translate_errno( n != SOCKET_ERROR, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	// Find the "Tcpip" NSP.
+	
+	for( i = 0; i < n; ++i )
+	{
+		if( strcmp( array[ i ].lpszIdentifier, "Tcpip" ) == 0 )
+		{
+			break;
+		}
+	}
+	require_action( i < n, exit, err = kNotFoundErr );
+	
+	// Uninstall it then re-install it to move it to the end.
+	
+	size = (DWORD) strlen( array[ i ].lpszIdentifier );
+	require_action( size < sizeof_array( name ), exit, err = kSizeErr );
+	CharToWCharString( array[ i ].lpszIdentifier, name );
+	
+	size = (DWORD) strlen( "%SystemRoot%\\System32\\mswsock.dll" );
+	require_action( size < sizeof_array( path ), exit, err = kSizeErr );
+	CharToWCharString( "%SystemRoot%\\System32\\mswsock.dll", path );
+	
+	err = WSCUnInstallNameSpace( &array[ i ].NSProviderId );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+	err = WSCInstallNameSpace( name, path, NS_DNS, array[ i ].dwVersion, &array[ i ].NSProviderId );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+		
+	// Success!
+	
+	fprintf( stderr, "Reordered \"Tcpip\" NSP to to the bottom of the NSP chain\n" );	
+	err = kNoErr;
+	
+exit:
+	if( array )
+	{
+		free( array );
+	}
+	if( started )
+	{
+		WSACleanup();
+	}
+	if( err != kNoErr )
+	{
+		fprintf( stderr, "### FAILED (%d) to reorder Name Space Providers\n", err );
+	}
+	return( err );
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	CharToWCharString
+//===========================================================================================================================
+
+DEBUG_LOCAL WCHAR *	CharToWCharString( const char *inCharString, WCHAR *outWCharString )
+{
+	const char *		src;
+	WCHAR *				dst;
+	char				c;
+	
+	check( inCharString );
+	check( outWCharString );
+	
+	src = inCharString;
+	dst = outWCharString;
+	do
+	{
+		c = *src++;
+		*dst++ = (WCHAR) c;
+	
+	}	while( c != '\0' );
+	
+	return( outWCharString );
+}
+
+//===========================================================================================================================
+//	GUIDtoString
+//===========================================================================================================================
+
+DEBUG_LOCAL char *	GUIDtoString( const GUID *inGUID, char *outString )
+{
+	check( inGUID );
+	check( outString );
+	
+	sprintf( outString, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 
+		inGUID->Data1, inGUID->Data2, inGUID->Data3, 
+		inGUID->Data4[ 0 ], inGUID->Data4[ 1 ], inGUID->Data4[ 2 ], inGUID->Data4[ 3 ], 
+		inGUID->Data4[ 4 ], inGUID->Data4[ 5 ], inGUID->Data4[ 6 ], inGUID->Data4[ 7 ] );
+	return( outString );
+}
+
+//===========================================================================================================================
+//	StringToGUID
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	StringToGUID( const char *inCharString, GUID *outGUID )
+{
+	OSStatus			err;
+	int					n;
+	unsigned int		v[ 8 ];
+	
+	check( inCharString );
+	check( outGUID );
+	
+	n = sscanf( inCharString, "%lX-%hX-%hX-%02X%02X-%02X%02X%02X%02X%02X%02X", 
+		&outGUID->Data1, &outGUID->Data2, &outGUID->Data3, 
+		&v[ 0 ], &v[ 1 ], &v[ 2 ], &v[ 3 ], &v[ 4 ], &v[ 5 ], &v[ 6 ], &v[ 7 ] );
+	require_action( n == 11, exit, err = kFormatErr );
+	
+	outGUID->Data4[ 0 ] = (unsigned char) v[ 0 ];
+	outGUID->Data4[ 1 ] = (unsigned char) v[ 1 ];
+	outGUID->Data4[ 2 ] = (unsigned char) v[ 2 ];
+	outGUID->Data4[ 3 ] = (unsigned char) v[ 3 ];
+	outGUID->Data4[ 4 ] = (unsigned char) v[ 4 ];
+	outGUID->Data4[ 5 ] = (unsigned char) v[ 5 ];
+	outGUID->Data4[ 6 ] = (unsigned char) v[ 6 ];
+	outGUID->Data4[ 7 ] = (unsigned char) v[ 7 ];
+	err = kNoErr;
+
+exit:
+	return( err );
+}
diff --git a/mDNSWindows/NSPTool/NSPTool.rc b/mDNSWindows/NSPTool/NSPTool.rc
new file mode 100644
index 0000000..72a6b36
--- /dev/null
+++ b/mDNSWindows/NSPTool/NSPTool.rc
@@ -0,0 +1,103 @@
+// Microsoft Visual C++ generated resource script.

+//

+#include "resource.h"

+

+#define APSTUDIO_READONLY_SYMBOLS

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 2 resource.

+//

+#include "afxres.h"

+#include "WinVersRes.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

+    "\r\n"

+    "\0"

+END

+

+#endif    // APSTUDIO_INVOKED

+

+

+/////////////////////////////////////////////////////////////////////////////

+//

+// Version

+//

+

+VS_VERSION_INFO VERSIONINFO

+ FILEVERSION MASTER_PROD_VERS

+ PRODUCTVERSION MASTER_PROD_VERS

+ FILEFLAGSMASK 0x17L

+#ifdef _DEBUG

+ FILEFLAGS 0x1L

+#else

+ FILEFLAGS 0x0L

+#endif

+ FILEOS 0x4L

+ FILETYPE 0x1L

+ FILESUBTYPE 0x0L

+BEGIN

+    BLOCK "StringFileInfo"

+    BEGIN

+        BLOCK "040904b0"

+        BEGIN

+            VALUE "CompanyName", MASTER_COMPANY_NAME

+            VALUE "FileDescription", "NSPTool Application"

+            VALUE "FileVersion", MASTER_PROD_VERS_STR

+            VALUE "InternalName", "NSPTool"

+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT

+            VALUE "OriginalFilename", "NSPTool.exe"

+            VALUE "ProductName", MASTER_PROD_NAME

+            VALUE "ProductVersion", MASTER_PROD_VERS_STR

+        END

+    END

+    BLOCK "VarFileInfo"

+    BEGIN

+        VALUE "Translation", 0x409, 1200

+    END

+END

+

+#endif    // English (U.S.) resources

+/////////////////////////////////////////////////////////////////////////////

+

+

+

+#ifndef APSTUDIO_INVOKED

+/////////////////////////////////////////////////////////////////////////////

+//

+// Generated from the TEXTINCLUDE 3 resource.

+//

+

+

+/////////////////////////////////////////////////////////////////////////////

+#endif    // not APSTUDIO_INVOKED

+

diff --git a/mDNSWindows/NSPTool/NSPTool.vcproj b/mDNSWindows/NSPTool/NSPTool.vcproj
new file mode 100644
index 0000000..bed3203
--- /dev/null
+++ b/mDNSWindows/NSPTool/NSPTool.vcproj
@@ -0,0 +1,409 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="NSPTool"

+	ProjectGUID="{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".;..;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				EnableFunctionLevelLinking="false"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+				CallingConvention="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="..\"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/NSPTool.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/NSPTool.pdb"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".;..;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				EnableFunctionLevelLinking="false"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="0"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="..\"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/NSPTool.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/NSPTool.pdb"

+				SubSystem="1"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".;..;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="..\"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/NSPTool.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".;..;../../mDNSShared"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="..\"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib"

+				OutputFile="$(OutDir)/NSPTool.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath=".\NSPTool.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath=".\resource.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath=".\NSPTool.rc"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/NSPTool/Prefix.h b/mDNSWindows/NSPTool/Prefix.h
new file mode 100644
index 0000000..3aa1cee
--- /dev/null
+++ b/mDNSWindows/NSPTool/Prefix.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PREFIX__
+#define __PREFIX__
+
+#if( defined( _DEBUG ) )
+	#define	DEBUG				1
+	#define	MDNS_DEBUGMSGS		1
+#else
+	#define	DEBUG				0
+#endif
+
+#endif	// __PREFIX__
diff --git a/mDNSWindows/NSPTool/resource.h b/mDNSWindows/NSPTool/resource.h
new file mode 100644
index 0000000..78c1d91
--- /dev/null
+++ b/mDNSWindows/NSPTool/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by NSPTool.rc
+//
+#define IDS_PROJNAME                    100
+#define IDR_WMDMLOGGER                  101
+#define IDS_LOG_SEV_INFO                201
+#define IDS_LOG_SEV_WARN                202
+#define IDS_LOG_SEV_ERROR               203
+#define IDS_LOG_DATETIME                204
+#define IDS_LOG_SRCNAME                 205
+#define IDS_DEF_LOGFILE                 301
+#define IDS_DEF_MAXSIZE                 302
+#define IDS_DEF_SHRINKTOSIZE            303
+#define IDS_DEF_LOGENABLED              304
+#define IDS_MUTEX_TIMEOUT               401
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        201
+#define _APS_NEXT_COMMAND_VALUE         32768
+#define _APS_NEXT_CONTROL_VALUE         201
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/mDNSWindows/PosixCompat.c b/mDNSWindows/PosixCompat.c
new file mode 100755
index 0000000..506c82b
--- /dev/null
+++ b/mDNSWindows/PosixCompat.c
@@ -0,0 +1,128 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "PosixCompat.h"
+#include <DebugServices.h>
+
+
+typedef PCHAR (WINAPI * if_indextoname_funcptr_t)(ULONG index, PCHAR name);
+typedef ULONG (WINAPI * if_nametoindex_funcptr_t)(PCSTR name);
+
+
+unsigned
+if_nametoindex( const char * ifname )
+{
+	HMODULE library;
+	unsigned index = 0;
+
+	check( ifname );
+
+	// Try and load the IP helper library dll
+	if ((library = LoadLibrary(TEXT("Iphlpapi")) ) != NULL )
+	{
+		if_nametoindex_funcptr_t if_nametoindex_funcptr;
+
+		// On Vista and above there is a Posix like implementation of if_nametoindex
+		if ((if_nametoindex_funcptr = (if_nametoindex_funcptr_t) GetProcAddress(library, "if_nametoindex")) != NULL )
+		{
+			index = if_nametoindex_funcptr(ifname);
+		}
+
+		FreeLibrary(library);
+	}
+
+	return index;
+}
+
+
+char*
+if_indextoname( unsigned ifindex, char * ifname )
+{
+	HMODULE library;
+	char * name = NULL;
+
+	check( ifname );
+	*ifname = '\0';
+
+	// Try and load the IP helper library dll
+	if ((library = LoadLibrary(TEXT("Iphlpapi")) ) != NULL )
+	{
+		if_indextoname_funcptr_t if_indextoname_funcptr;
+
+		// On Vista and above there is a Posix like implementation of if_indextoname
+		if ((if_indextoname_funcptr = (if_indextoname_funcptr_t) GetProcAddress(library, "if_indextoname")) != NULL )
+		{
+			name = if_indextoname_funcptr(ifindex, ifname);
+		}
+
+		FreeLibrary(library);
+	}
+
+	return name;
+}
+
+
+int
+inet_pton( int family, const char * addr, void * dst )
+{
+	struct sockaddr_storage ss;
+	int sslen = sizeof( ss );
+
+	ZeroMemory( &ss, sizeof( ss ) );
+	ss.ss_family = family;
+
+	if ( WSAStringToAddressA( ( LPSTR ) addr, family, NULL, ( struct sockaddr* ) &ss, &sslen ) == 0 )
+	{
+		if ( family == AF_INET ) { memcpy( dst, &( ( struct sockaddr_in* ) &ss)->sin_addr, sizeof( IN_ADDR ) ); return 1; }
+		else if ( family == AF_INET6 ) { memcpy( dst, &( ( struct sockaddr_in6* ) &ss)->sin6_addr, sizeof( IN6_ADDR ) ); return 1; }
+		else return 0;
+	}
+    else return 0;
+}
+

+
+int
+gettimeofday( struct timeval * tv, struct timezone * tz )
+{

+#define EPOCHFILETIME (116444736000000000i64)

+

+	if ( tv != NULL )

+	{

+		FILETIME        ft;

+		LARGE_INTEGER   li;

+		__int64         t;

+

+		GetSystemTimeAsFileTime(&ft);

+		li.LowPart  = ft.dwLowDateTime;

+		li.HighPart = ft.dwHighDateTime;

+		t  = li.QuadPart;	/* In 100-nanosecond intervals */

+		t -= EPOCHFILETIME;	/* Offset to the Epoch time */

+		t /= 10;			/* In microseconds */

+		tv->tv_sec  = ( long )( t / 1000000 );

+		tv->tv_usec = ( long )( t % 1000000 );

+	}

+

+	return 0;
+}
+
+
+extern struct tm*
+localtime_r( const time_t * clock, struct tm * result )
+{
+	localtime_s( result, clock );
+	return result;
+}
diff --git a/mDNSWindows/PosixCompat.h b/mDNSWindows/PosixCompat.h
new file mode 100755
index 0000000..9f9d005
--- /dev/null
+++ b/mDNSWindows/PosixCompat.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "CommonServices.h"
+#include <winsock2.h>
+#include <time.h>
+
+
+/* 
+ * Posix process compatibility
+ */
+typedef int pid_t;
+#if !defined( getpid )
+#	define getpid _getpid
+#endif
+
+
+/* 
+ * Posix networking compatibility
+ */
+extern unsigned
+if_nametoindex( const char * ifname );
+
+
+extern char*
+if_indextoname( unsigned ifindex, char * ifname );
+
+
+extern int
+inet_pton( int family, const char * addr, void * dst );
+
+
+/* 
+ * Posix time compatibility
+ */
+extern int
+gettimeofday( struct timeval * tv, struct timezone * tz );
+
+
+extern struct tm*
+localtime_r( const time_t * clock, struct tm * result );
+
+
+/* 
+ * Posix string compatibility
+ */
+#if !defined( strcasecmp )
+#	define strcasecmp	_stricmp
+#endif
+
+#if !defined( snprintf )
+#	define snprint		_snprintf
+#endif
+
diff --git a/mDNSWindows/README.txt b/mDNSWindows/README.txt
new file mode 100644
index 0000000..8d8ab4b
--- /dev/null
+++ b/mDNSWindows/README.txt
@@ -0,0 +1,85 @@
+This directory contains support files for running mDNS on Microsoft Windows 
+and Windows CE/PocketPC. Building this code requires the Windows SDK 2003
+or later. The CodeWarrior builds require CodeWarrior 8 or later and if using
+CodeWarrior 8, the newer Windows headers from the Mac CodeWarrior 9 need to
+be used.
+
+mDNSWin32.c/.h
+	
+	Platform Support files that go below mDNS Core. These work on both Windows 
+	and Windows CE/PocketPC.
+
+DNSSD.c/.h
+
+	High-level implementation of the DNS-SD API. This supports both "direct"
+	(compiled-in mDNSCore) and "client" (IPC to service) usage. Conditionals
+	can exclude either "direct" or "client" to reduce code size.
+
+DNSSDDirect.c/.h
+
+	Portable implementation of the DNS-SD API. This interacts with mDNSCore
+	to perform all the real work of the DNS-SD API. This code does not rely
+	on any platform-specifics so it should run on any platform with an mDNS
+	platform plugin available. Software that cannot or does not want to use
+	the IPC mechanism (e.g. Windows CE, VxWorks, etc.) can use this code 
+	directly without any of the IPC pieces.
+
+RMxClient.c/.h
+	
+	Client-side implementation of the DNS-SD IPC API. This handles sending 
+	and receiving messages from the service to perform DNS-SD operations 
+	and get DNS-SD responses.
+
+RMxCommon.c/.h
+
+	Common code between the RMxClient and RMxServer. This handles establishing
+	and accepting connections, the underying message sending and receiving, 
+	portable data packing and unpacking, and shared utility routines.
+
+RMxServer.c/.h
+
+	Server-side implementation of the DNS-SD IPC API. This listens for 
+	and accepts connections from IPC clients, starts server sessions, and 
+	acts as a mediator between the "direct" (compiled-in mDNSCore) code
+	and the IPC client.
+
+DNSServices is an obsolete higher-level API for using mDNS. New code should 
+use the DNS-SD APIs.
+
+DNSServiceDiscovery is an obsolete emulation layer that sits on top of 
+DNSServices and provides the Mac OS X DNS Service Discovery API's on any 
+platform. New code should use the DNS-SD APIs.
+
+Tool.c is an example client that uses the services of mDNS Core.
+
+ToolWin32.mcp is a CodeWarrior project (CodeWarrior for Windows version 8). 
+ToolWin32.vcproj is a Visual Studio .NET 7 project. These projects build 
+Tool.c to make DNSServiceTest.exe, a small Windows command-line tool to do all 
+the standard DNS-SD stuff on Windows. It has the following features:
+
+- Browse for browsing and/or registration domains.
+- Browse for services.
+- Lookup Service Instances.
+- Register domains for browsing and/or registration.
+- Register services.
+
+For example, if you have a Windows machine running a Web server,
+then you can make it advertise that it is offering HTTP on port 80
+with the following command:
+
+DNSServiceTest -rs "Windows Web Server" "_http._tcp." "local." 80 ""
+
+To search for AFP servers, use this:
+
+DNSServiceTest -bs "_afpovertcp._tcp." "local."
+
+You can also do multiple things at once (e.g. register a service and
+browse for it so one instance of the app can be used for testing).
+Multiple instances can also be run on the same machine to discover each
+other. There is a -help command to show all the commands, their
+parameters, and some examples of using it.
+
+DNSServiceBrowser contains the source code for a graphical browser application 
+for Windows CE/PocketPC. The Windows CE/PocketPC version requires Microsoft 
+eMbedded C++ 4.0 with SP2 installed and the PocketPC 2003 SDK.
+
diff --git a/mDNSWindows/RegNames.h b/mDNSWindows/RegNames.h
new file mode 100644
index 0000000..bc885d6
--- /dev/null
+++ b/mDNSWindows/RegNames.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//----------------------------------------------------------------------------------------
+//	Registry Constants
+//----------------------------------------------------------------------------------------
+
+#if defined(UNICODE)
+
+#	define kServiceParametersSoftware			L"SOFTWARE"
+#	define kServiceParametersAppleComputer		L"Apple Computer, Inc."
+#	define kServiceParametersBonjour			L"Bonjour"
+#	define kServiceParametersNode				L"SOFTWARE\\Apple Inc.\\Bonjour"
+#	define kServiceName							L"Bonjour Service"
+#	define kServiceDynDNSBrowseDomains			L"BrowseDomains"
+#	define kServiceDynDNSHostNames				L"HostNames"
+#	define kServiceDynDNSRegistrationDomains	L"RegistrationDomains"
+#	define kServiceDynDNSDomains				L"Domains"	// value is comma separated list of domains
+#	define kServiceDynDNSEnabled				L"Enabled"
+#	define kServiceDynDNSStatus					L"Status"
+#	define kServiceManageLLRouting				L"ManageLLRouting"
+#	define kServiceCacheEntryCount				L"CacheEntryCount"
+#	define kServiceManageFirewall				L"ManageFirewall"
+#	define kServiceAdvertisedServices			L"Services"
+
+# else
+
+#	define kServiceParametersSoftware			"SOFTWARE"
+#	define kServiceParametersAppleComputer		"Apple Computer, Inc."
+#	define kServiceParametersBonjour			"Bonjour"
+#	define kServiceParametersNode				"SOFTWARE\\Apple Inc.\\Bonjour"
+#	define kServiceName							"Bonjour Service"
+#	define kServiceDynDNSBrowseDomains			"BrowseDomains"
+#	define kServiceDynDNSHostNames				"HostNames"
+#	define kServiceDynDNSRegistrationDomains	"RegistrationDomains"
+#	define kServiceDynDNSDomains				"Domains"	// value is comma separated list of domains
+#	define kServiceDynDNSEnabled				"Enabled"
+#	define kServiceDynDNSStatus					"Status"
+#	define kServiceManageLLRouting				"ManageLLRouting"
+#	define kServiceCacheEntryCount				"CacheEntryCount"
+#	define kServiceManageFirewall				"ManageFirewall"
+
+#endif
diff --git a/mDNSWindows/Secret.c b/mDNSWindows/Secret.c
new file mode 100644
index 0000000..5abd28b
--- /dev/null
+++ b/mDNSWindows/Secret.c
@@ -0,0 +1,338 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Secret.h"
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <process.h>
+#include <ntsecapi.h>
+#include <lm.h>
+#include "DebugServices.h"
+
+
+mDNSlocal OSStatus MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input );
+mDNSlocal OSStatus MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input );
+
+
+BOOL
+LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize )
+{
+	PLSA_UNICODE_STRING		domainLSA;
+	PLSA_UNICODE_STRING		keyLSA;
+	PLSA_UNICODE_STRING		secretLSA;
+	size_t					i;
+	size_t					dlen;
+	LSA_OBJECT_ATTRIBUTES	attrs;
+	LSA_HANDLE				handle = NULL;
+	NTSTATUS				res;
+	OSStatus				err;
+
+	check( inDomain );
+	check( outDomain );
+	check( outKey );
+	check( outSecret );
+
+	// Initialize
+
+	domainLSA	= NULL;
+	keyLSA		= NULL;
+	secretLSA	= NULL;
+
+	// Make sure we have enough space to add trailing dot
+
+	dlen = strlen( inDomain );
+	err = strcpy_s( outDomain, outDomainSize - 2, inDomain );
+	require_noerr( err, exit );
+
+	// If there isn't a trailing dot, add one because the mDNSResponder
+	// presents names with the trailing dot.
+
+	if ( outDomain[ dlen - 1 ] != '.' )
+	{
+		outDomain[ dlen++ ] = '.';
+		outDomain[ dlen ] = '\0';
+	}
+
+	// Canonicalize name by converting to lower case (keychain and some name servers are case sensitive)
+
+	for ( i = 0; i < dlen; i++ )
+	{
+		outDomain[i] = (char) tolower( outDomain[i] );  // canonicalize -> lower case
+	}
+
+	// attrs are reserved, so initialize to zeroes.
+
+	ZeroMemory( &attrs, sizeof( attrs ) );
+
+	// Get a handle to the Policy object on the local system
+
+	res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle );
+	err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+	require_noerr( err, exit );
+
+	// Get the encrypted data
+
+	domainLSA = ( PLSA_UNICODE_STRING ) malloc( sizeof( LSA_UNICODE_STRING ) );
+	require_action( domainLSA != NULL, exit, err = mStatus_NoMemoryErr );
+	err = MakeLsaStringFromUTF8String( domainLSA, outDomain );
+	require_noerr( err, exit );
+
+	// Retrieve the key
+
+	res = LsaRetrievePrivateData( handle, domainLSA, &keyLSA );
+	err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+	require_noerr_quiet( err, exit );
+
+	// <rdar://problem/4192119> Lsa secrets use a flat naming space.  Therefore, we will prepend "$" to the keyname to
+	// make sure it doesn't conflict with a zone name.	
+	// Strip off the "$" prefix.
+
+	err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA );
+	require_noerr( err, exit );
+	require_action( outKey[0] == '$', exit, err = kUnknownErr );
+	memcpy( outKey, outKey + 1, strlen( outKey ) );
+
+	// Retrieve the secret
+
+	res = LsaRetrievePrivateData( handle, keyLSA, &secretLSA );
+	err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+	require_noerr_quiet( err, exit );
+
+	// Convert the secret to UTF8 string
+
+	err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA );
+	require_noerr( err, exit );
+
+exit:
+
+	if ( domainLSA != NULL )
+	{
+		if ( domainLSA->Buffer != NULL )
+		{
+			free( domainLSA->Buffer );
+		}
+
+		free( domainLSA );
+	}
+
+	if ( keyLSA != NULL )
+	{
+		LsaFreeMemory( keyLSA );
+	}
+
+	if ( secretLSA != NULL )
+	{
+		LsaFreeMemory( secretLSA );
+	}
+
+	if ( handle )
+	{
+		LsaClose( handle );
+		handle = NULL;
+	}
+
+	return ( !err ) ? TRUE : FALSE;
+}
+
+
+mDNSBool
+LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret )
+{
+	size_t					inDomainLength;
+	size_t					inKeyLength;
+	char					domain[ 1024 ];
+	char					key[ 1024 ];
+	LSA_OBJECT_ATTRIBUTES	attrs;
+	LSA_HANDLE				handle = NULL;
+	NTSTATUS				res;
+	LSA_UNICODE_STRING		lucZoneName;
+	LSA_UNICODE_STRING		lucKeyName;
+	LSA_UNICODE_STRING		lucSecretName;
+	BOOL					ok = TRUE;
+	OSStatus				err;
+
+	require_action( inDomain != NULL, exit, ok = FALSE );
+	require_action( inKey != NULL, exit, ok = FALSE );
+	require_action( inSecret != NULL, exit, ok = FALSE );
+
+	// If there isn't a trailing dot, add one because the mDNSResponder
+	// presents names with the trailing dot.
+
+	ZeroMemory( domain, sizeof( domain ) );
+	inDomainLength = strlen( inDomain );
+	require_action( inDomainLength > 0, exit, ok = FALSE );
+	err = strcpy_s( domain, sizeof( domain ) - 2, inDomain );
+	require_action( !err, exit, ok = FALSE );
+
+	if ( domain[ inDomainLength - 1 ] != '.' )
+	{
+		domain[ inDomainLength++ ] = '.';
+		domain[ inDomainLength ] = '\0';
+	}
+
+	// <rdar://problem/4192119>
+	//
+	// Prepend "$" to the key name, so that there will
+	// be no conflict between the zone name and the key
+	// name
+
+	ZeroMemory( key, sizeof( key ) );
+	inKeyLength = strlen( inKey );
+	require_action( inKeyLength > 0 , exit, ok = FALSE );
+	key[ 0 ] = '$';
+	err = strcpy_s( key + 1, sizeof( key ) - 3, inKey );
+	require_action( !err, exit, ok = FALSE );
+	inKeyLength++;
+
+	if ( key[ inKeyLength - 1 ] != '.' )
+	{
+		key[ inKeyLength++ ] = '.';
+		key[ inKeyLength ] = '\0';
+	}
+
+	// attrs are reserved, so initialize to zeroes.
+
+	ZeroMemory( &attrs, sizeof( attrs ) );
+
+	// Get a handle to the Policy object on the local system
+
+	res = LsaOpenPolicy( NULL, &attrs, POLICY_ALL_ACCESS, &handle );
+	err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+	require_noerr( err, exit );
+
+	// Intializing PLSA_UNICODE_STRING structures
+
+	err = MakeLsaStringFromUTF8String( &lucZoneName, domain );
+	require_noerr( err, exit );
+
+	err = MakeLsaStringFromUTF8String( &lucKeyName, key );
+	require_noerr( err, exit );
+
+	err = MakeLsaStringFromUTF8String( &lucSecretName, inSecret );
+	require_noerr( err, exit );
+
+	// Store the private data.
+
+	res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName );
+	err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+	require_noerr( err, exit );
+
+	res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName );
+	err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr );
+	require_noerr( err, exit );
+
+exit:
+
+	if ( handle )
+	{
+		LsaClose( handle );
+		handle = NULL;
+	}
+
+	return ok;
+}
+
+
+//===========================================================================================================================
+//	MakeLsaStringFromUTF8String
+//===========================================================================================================================
+
+mDNSlocal OSStatus
+MakeLsaStringFromUTF8String( PLSA_UNICODE_STRING output, const char * input )
+{
+	int			size;
+	OSStatus	err;
+	
+	check( input );
+	check( output );
+
+	output->Buffer = NULL;
+
+	size = MultiByteToWideChar( CP_UTF8, 0, input, -1, NULL, 0 );
+	err = translate_errno( size > 0, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	output->Length = (USHORT)( size * sizeof( wchar_t ) );
+	output->Buffer = (PWCHAR) malloc( output->Length );
+	require_action( output->Buffer, exit, err = mStatus_NoMemoryErr );
+	size = MultiByteToWideChar( CP_UTF8, 0, input, -1, output->Buffer, size );
+	err = translate_errno( size > 0, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	// We're going to subtrace one wchar_t from the size, because we didn't
+	// include it when we encoded the string
+
+	output->MaximumLength = output->Length;
+	output->Length		-= sizeof( wchar_t );
+	
+exit:
+
+	if ( err && output->Buffer )
+	{
+		free( output->Buffer );
+		output->Buffer = NULL;
+	}
+
+	return( err );
+}
+
+
+
+//===========================================================================================================================
+//	MakeUTF8StringFromLsaString
+//===========================================================================================================================
+
+mDNSlocal OSStatus
+MakeUTF8StringFromLsaString( char * output, size_t len, PLSA_UNICODE_STRING input )
+{
+	size_t		size;
+	OSStatus	err = kNoErr;
+
+	// The Length field of this structure holds the number of bytes,
+	// but WideCharToMultiByte expects the number of wchar_t's. So
+	// we divide by sizeof(wchar_t) to get the correct number.
+
+	size = (size_t) WideCharToMultiByte(CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), NULL, 0, NULL, NULL);
+	err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	// Ensure that we have enough space (Add one for trailing '\0')
+
+	require_action( ( size + 1 ) <= len, exit, err = mStatus_NoMemoryErr );
+
+	// Convert the string
+
+	size = (size_t) WideCharToMultiByte( CP_UTF8, 0, input->Buffer, ( input->Length / sizeof( wchar_t ) ), output, (int) size, NULL, NULL);	
+	err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	// have to add the trailing 0 because WideCharToMultiByte doesn't do it,
+	// although it does return the correct size
+
+	output[size] = '\0';
+
+exit:
+
+	return err;
+}
+
diff --git a/mDNSWindows/Secret.h b/mDNSWindows/Secret.h
new file mode 100644
index 0000000..79643d6
--- /dev/null
+++ b/mDNSWindows/Secret.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _Secret_h
+#define _Secret_h
+
+#include "mDNSEmbeddedAPI.h"
+
+
+#if defined(__cplusplus )
+extern "C" {
+#endif
+
+
+extern mDNSBool
+LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, char * outKey, unsigned outKeyLength, char * outSecret, unsigned outSecretLength );
+
+
+extern mDNSBool
+LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret );
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif
\ No newline at end of file
diff --git a/mDNSWindows/SystemService/EventLog.mc b/mDNSWindows/SystemService/EventLog.mc
new file mode 100644
index 0000000..248e6c1
--- /dev/null
+++ b/mDNSWindows/SystemService/EventLog.mc
@@ -0,0 +1,11 @@
+MessageIdTypedef=WORD
+LanguageNames=(English=0x409:MSG00409)
+
+MessageId=100
+SymbolicName=MDNSRESPONDER_LOG
+Severity=Success
+Facility=Application
+Language=English
+%1
+.
+
diff --git a/mDNSWindows/SystemService/EventLogMessages.bin b/mDNSWindows/SystemService/EventLogMessages.bin
new file mode 100644
index 0000000..e74c67e
--- /dev/null
+++ b/mDNSWindows/SystemService/EventLogMessages.bin
Binary files differ
diff --git a/mDNSWindows/SystemService/Firewall.cpp b/mDNSWindows/SystemService/Firewall.cpp
new file mode 100755
index 0000000..c7c96d0
--- /dev/null
+++ b/mDNSWindows/SystemService/Firewall.cpp
@@ -0,0 +1,484 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// <rdar://problem/4278931> Doesn't compile correctly with latest Platform SDK
+
+#if !defined(_WIN32_DCOM)
+#	define _WIN32_DCOM 
+#endif
+
+
+#include "Firewall.h"
+#include <windows.h>
+#include <crtdbg.h>
+#include <netfw.h>
+#include <objbase.h>
+#include <oleauto.h>
+
+
+static const int kMaxTries			= 30;
+static const int kRetrySleepPeriod	= 1 * 1000; // 1 second
+
+
+static OSStatus
+mDNSFirewallInitialize(OUT INetFwProfile ** fwProfile)
+{
+	INetFwMgr		*	fwMgr		= NULL;
+	INetFwPolicy	*	fwPolicy	= NULL;
+	int					numRetries	= 0;
+	HRESULT				err			= kNoErr;
+    
+	_ASSERT(fwProfile != NULL);
+
+    *fwProfile = NULL;
+
+	// Use COM to get a reference to the firewall settings manager.  This
+	// call will fail on anything other than XP SP2
+
+	err = CoCreateInstance( __uuidof(NetFwMgr), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwMgr), (void**)&fwMgr );
+	require(SUCCEEDED(err) && ( fwMgr != NULL ), exit);
+
+	// Use the reference to get the local firewall policy
+
+	err = fwMgr->get_LocalPolicy(&fwPolicy);
+	require(SUCCEEDED(err) && ( fwPolicy != NULL ), exit);
+
+	// Use the reference to get the extant profile. Empirical evidence
+	// suggests that there is the potential for a race condition when a system
+	// service whose startup type is automatic calls this method.
+	// This is true even when the service declares itself to be dependent
+	// on the firewall service. Re-trying the method will succeed within
+	// a few seconds.
+
+	do
+	{
+    	err = fwPolicy->get_CurrentProfile(fwProfile);
+
+		if (err)
+		{
+			Sleep(kRetrySleepPeriod);
+		}
+	}
+	while (err && (numRetries++ < kMaxTries));
+
+	require(SUCCEEDED(err), exit);
+
+	err = kNoErr;
+
+exit:
+
+	// Release temporary COM objects
+
+    if (fwPolicy != NULL)
+    {
+        fwPolicy->Release();
+    }
+
+    if (fwMgr != NULL)
+    {
+        fwMgr->Release();
+    }
+
+    return err;
+}
+
+
+static void
+mDNSFirewallCleanup
+			(
+			IN INetFwProfile	*	fwProfile
+			)
+{
+	// Call Release on the COM reference.
+
+    if (fwProfile != NULL)
+    {
+        fwProfile->Release();
+    }
+}
+
+
+static OSStatus
+mDNSFirewallAppIsEnabled
+			(
+			IN INetFwProfile	*	fwProfile,
+			IN const wchar_t	*	fwProcessImageFileName,
+			OUT BOOL			*	fwAppEnabled    
+			)
+{
+	BSTR							fwBstrProcessImageFileName = NULL;
+	VARIANT_BOOL					fwEnabled;
+	INetFwAuthorizedApplication	*	fwApp	= NULL;
+	INetFwAuthorizedApplications*	fwApps	= NULL;
+	OSStatus						err		= kNoErr;
+    
+	_ASSERT(fwProfile != NULL);
+	_ASSERT(fwProcessImageFileName != NULL);
+	_ASSERT(fwAppEnabled != NULL);
+
+    *fwAppEnabled = FALSE;
+
+	// Get the list of authorized applications
+
+	err = fwProfile->get_AuthorizedApplications(&fwApps);
+	require(SUCCEEDED(err) && ( fwApps != NULL ), exit);
+
+    fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName);
+	require_action( ( fwProcessImageFileName != NULL ) && ( SysStringLen(fwBstrProcessImageFileName) > 0 ), exit, err = kNoMemoryErr);
+
+	// Look for us
+
+    err = fwApps->Item(fwBstrProcessImageFileName, &fwApp);
+	
+    if (SUCCEEDED(err) && ( fwApp != NULL ) )
+    {
+        // It's listed, but is it enabled?
+
+		err = fwApp->get_Enabled(&fwEnabled);
+		require(SUCCEEDED(err), exit);
+
+        if (fwEnabled != VARIANT_FALSE)
+        {
+			// Yes, it's enabled
+
+            *fwAppEnabled = TRUE;
+		}
+	}
+
+	err = kNoErr;
+
+exit:
+
+	// Deallocate the BSTR
+
+	if ( fwBstrProcessImageFileName != NULL )
+	{
+		SysFreeString(fwBstrProcessImageFileName);
+	}
+
+	// Release the COM objects
+
+    if (fwApp != NULL)
+    {
+        fwApp->Release();
+    }
+
+    if (fwApps != NULL)
+    {
+        fwApps->Release();
+    }
+
+    return err;
+}
+
+
+static OSStatus
+mDNSFirewallAddApp
+			(
+            IN INetFwProfile	*	fwProfile,
+            IN const wchar_t	*	fwProcessImageFileName,
+            IN const wchar_t	*	fwName
+            )
+{
+	BOOL							fwAppEnabled;
+	BSTR							fwBstrName = NULL;
+	BSTR							fwBstrProcessImageFileName = NULL;
+	INetFwAuthorizedApplication	*	fwApp = NULL;
+	INetFwAuthorizedApplications*	fwApps = NULL;
+	OSStatus						err = S_OK;
+    
+	_ASSERT(fwProfile != NULL);
+    _ASSERT(fwProcessImageFileName != NULL);
+    _ASSERT(fwName != NULL);
+
+    // First check to see if the application is already authorized.
+	err = mDNSFirewallAppIsEnabled( fwProfile, fwProcessImageFileName, &fwAppEnabled );
+	require_noerr(err, exit);
+
+	// Only add the application if it isn't enabled
+
+	if (!fwAppEnabled)
+	{
+		// Get the list of authorized applications
+
+        err = fwProfile->get_AuthorizedApplications(&fwApps);
+		require(SUCCEEDED(err) && ( fwApps != NULL ), exit);
+
+        // Create an instance of an authorized application.
+
+		err = CoCreateInstance( __uuidof(NetFwAuthorizedApplication), NULL, CLSCTX_INPROC_SERVER, __uuidof(INetFwAuthorizedApplication), (void**)&fwApp );
+		require(SUCCEEDED(err) && ( fwApp != NULL ), exit);
+
+        fwBstrProcessImageFileName = SysAllocString(fwProcessImageFileName);
+		require_action(( fwProcessImageFileName != NULL ) && ( SysStringLen(fwBstrProcessImageFileName) > 0 ), exit, err = kNoMemoryErr);
+
+		// Set the executable file name
+
+		err = fwApp->put_ProcessImageFileName(fwBstrProcessImageFileName);
+		require(SUCCEEDED(err), exit);
+
+		fwBstrName = SysAllocString(fwName);
+		require_action( ( fwBstrName != NULL ) && ( SysStringLen(fwBstrName) > 0 ), exit, err = kNoMemoryErr);
+
+		// Set the friendly name
+
+        err = fwApp->put_Name(fwBstrName);
+		require(SUCCEEDED(err), exit);
+
+		// Now add the application
+
+        err = fwApps->Add(fwApp);
+		require(SUCCEEDED(err), exit);
+	}
+
+	err = kNoErr;
+
+exit:
+
+	// Deallocate the BSTR objects
+
+	if ( fwBstrName != NULL )
+	{
+		SysFreeString(fwBstrName);
+	}
+
+	if ( fwBstrProcessImageFileName != NULL )
+	{
+		SysFreeString(fwBstrProcessImageFileName);
+	}
+
+    // Release the COM objects
+
+    if (fwApp != NULL)
+    {
+        fwApp->Release();
+    }
+
+    if (fwApps != NULL)
+    {
+        fwApps->Release();
+    }
+
+    return err;
+}
+
+
+
+
+
+static OSStatus
+
+mDNSFirewallIsFileAndPrintSharingEnabled
+
+	(
+
+	IN INetFwProfile	* fwProfile,
+
+	OUT BOOL			* fwServiceEnabled
+
+	)
+
+{
+
+    VARIANT_BOOL fwEnabled;
+
+    INetFwService* fwService = NULL;
+
+    INetFwServices* fwServices = NULL;
+
+	OSStatus err = S_OK;
+
+
+
+    _ASSERT(fwProfile != NULL);
+
+    _ASSERT(fwServiceEnabled != NULL);
+
+
+
+    *fwServiceEnabled = FALSE;
+
+
+
+    // Retrieve the globally open ports collection.
+
+    err = fwProfile->get_Services(&fwServices);
+
+	require( SUCCEEDED( err ), exit );
+
+
+
+    // Attempt to retrieve the globally open port.
+
+    err = fwServices->Item(NET_FW_SERVICE_FILE_AND_PRINT, &fwService);
+
+	require( SUCCEEDED( err ), exit );
+
+	
+
+	// Find out if the globally open port is enabled.
+
+    err = fwService->get_Enabled(&fwEnabled);
+
+	require( SUCCEEDED( err ), exit );
+
+	if (fwEnabled != VARIANT_FALSE)
+
+	{
+
+		*fwServiceEnabled = TRUE;
+
+	}
+
+
+
+exit:
+
+
+
+    // Release the globally open port.
+
+    if (fwService != NULL)
+
+    {
+
+        fwService->Release();
+
+    }
+
+
+
+    // Release the globally open ports collection.
+
+    if (fwServices != NULL)
+
+    {
+
+        fwServices->Release();
+
+    }
+
+
+
+    return err;
+
+}
+
+
+OSStatus
+mDNSAddToFirewall
+		(
+		LPWSTR	executable,
+		LPWSTR	name
+		)
+{
+	INetFwProfile	*	fwProfile	= NULL;
+	HRESULT				comInit		= E_FAIL;
+	OSStatus			err			= kNoErr;
+
+	// Initialize COM.
+
+	comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE );
+
+	// Ignore this case. RPC_E_CHANGED_MODE means that COM has already been
+	// initialized with a different mode.
+
+	if (comInit != RPC_E_CHANGED_MODE)
+	{
+		err = comInit;
+		require(SUCCEEDED(err), exit);
+	}
+
+	// Connect to the firewall
+
+	err = mDNSFirewallInitialize(&fwProfile);
+	require( SUCCEEDED( err ) && ( fwProfile != NULL ), exit);
+
+	// Add us to the list of exempt programs
+
+	err = mDNSFirewallAddApp( fwProfile, executable, name );
+	require_noerr(err, exit);
+
+exit:
+
+	// Disconnect from the firewall
+
+	if ( fwProfile != NULL )
+	{
+		mDNSFirewallCleanup(fwProfile);
+	}
+
+	// De-initialize COM
+
+	if (SUCCEEDED(comInit))
+    {
+        CoUninitialize();
+    }
+
+	return err;
+}
+
+
+BOOL
+mDNSIsFileAndPrintSharingEnabled( BOOL * retry )
+{
+	INetFwProfile	*	fwProfile					= NULL;
+	HRESULT				comInit						= E_FAIL;
+	BOOL				enabled						= FALSE;
+	OSStatus			err							= kNoErr;
+
+	// Initialize COM.
+
+	*retry = FALSE;
+	comInit = CoInitializeEx( 0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE );
+
+	// Ignore this case. RPC_E_CHANGED_MODE means that COM has already been
+	// initialized with a different mode.
+
+	if (comInit != RPC_E_CHANGED_MODE)
+	{
+		*retry = TRUE;
+		err = comInit;
+		require(SUCCEEDED(err), exit);
+	}
+
+	// Connect to the firewall
+
+	err = mDNSFirewallInitialize(&fwProfile);
+	require( SUCCEEDED( err ) && ( fwProfile != NULL ), exit);
+
+	err = mDNSFirewallIsFileAndPrintSharingEnabled( fwProfile, &enabled );
+	require_noerr( err, exit );
+
+exit:
+
+	// Disconnect from the firewall
+
+	if ( fwProfile != NULL )
+	{
+		mDNSFirewallCleanup(fwProfile);
+	}
+
+	// De-initialize COM
+
+	if (SUCCEEDED(comInit))
+    {
+        CoUninitialize();
+    }
+
+	return enabled;
+}
diff --git a/mDNSWindows/SystemService/Firewall.h b/mDNSWindows/SystemService/Firewall.h
new file mode 100755
index 0000000..3d7d532
--- /dev/null
+++ b/mDNSWindows/SystemService/Firewall.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+#ifndef _Firewall_h
+
+#define _Firewall_h
+
+
+
+
+
+#include "CommonServices.h"
+
+#include "DebugServices.h"
+
+
+
+
+
+#if defined(__cplusplus)
+
+extern "C"
+
+{
+
+#endif
+
+
+
+
+
+OSStatus
+
+mDNSAddToFirewall
+
+		(
+
+		LPWSTR	executable,
+
+		LPWSTR	name
+
+		);
+
+
+BOOL
+mDNSIsFileAndPrintSharingEnabled( BOOL * retry );
+
+
+
+
+
+#if defined(__cplusplus)
+
+}
+
+#endif
+
+
+
+
+
+#endif
+
diff --git a/mDNSWindows/SystemService/Prefix.h b/mDNSWindows/SystemService/Prefix.h
new file mode 100644
index 0000000..61381d0
--- /dev/null
+++ b/mDNSWindows/SystemService/Prefix.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PREFIX__
+#define __PREFIX__
+
+#if( defined( _DEBUG ) )
+	#define	DEBUG					1
+	#define	MDNS_DEBUGMSGS			1
+#else
+	#define	DEBUG					0
+#endif
+
+#define	DNS_SD_CLIENT_ENABLED		0
+
+#endif	// __PREFIX__
diff --git a/mDNSWindows/SystemService/Service.aps b/mDNSWindows/SystemService/Service.aps
new file mode 100644
index 0000000..41f2556
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.aps
Binary files differ
diff --git a/mDNSWindows/SystemService/Service.c b/mDNSWindows/SystemService/Service.c
new file mode 100644
index 0000000..8b4c2c6
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.c
@@ -0,0 +1,2669 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include	<stdio.h>
+#include	<stdlib.h>
+#include	<crtdbg.h>
+#include	<stdarg.h>
+#include	<stddef.h>
+
+
+#include	"CommonServices.h"
+#include	"DebugServices.h"
+#include	"RegNames.h"
+
+#include	"uds_daemon.h"
+#include	"GenLinkedList.h"
+#include	"Service.h"
+#include	"EventLog.h"
+
+#include	"Resource.h"
+
+#include	"mDNSEmbeddedAPI.h"
+#include	"uDNS.h"
+#include	"mDNSWin32.h"
+
+#include	"Firewall.h"
+
+#if( !TARGET_OS_WINDOWS_CE )
+	#include	<mswsock.h>
+	#include	<process.h>
+	#include	<ipExport.h>
+	#include	<ws2def.h>
+	#include	<ws2ipdef.h>
+	#include	<iphlpapi.h>
+	#include	<netioapi.h>
+	#include	<iptypes.h>
+	#include	<powrprof.h>
+#endif
+
+#ifndef HeapEnableTerminationOnCorruption
+#	define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1
+#endif
+
+#if 0
+#pragma mark == Constants ==
+#endif
+
+//===========================================================================================================================
+//	Constants
+//===========================================================================================================================
+
+#define	DEBUG_NAME							"[mDNSWin32] "
+#define kServiceFirewallName				L"Bonjour"
+#define	kServiceDependencies				TEXT("Tcpip\0\0")
+#define	kDNSServiceCacheEntryCountDefault	512
+#define kRetryFirewallPeriod				30 * 1000
+#define kDefValueSize						MAX_PATH + 1
+#define kZeroIndex							0
+#define kDefaultRouteMetric					399
+#define kSecondsTo100NSUnits				( 10 * 1000 * 1000 )
+#define kSPSMaintenanceWakePeriod			-30
+
+#define RR_CACHE_SIZE 500
+static CacheEntity gRRCache[RR_CACHE_SIZE];
+#if 0
+#pragma mark == Structures ==
+#endif
+
+//===========================================================================================================================
+//	Structures
+//===========================================================================================================================
+
+typedef struct EventSource
+{
+	HANDLE							event;
+	void						*	context;
+	RegisterWaitableEventHandler	handler;
+	struct EventSource			*	next;
+} EventSource;
+
+static BOOL											gEventSourceListChanged = FALSE;
+static EventSource								*	gEventSourceList = NULL;
+static EventSource								*	gCurrentSource = NULL;
+static int											gEventSources = 0;
+
+#define	kWaitListStopEvent							( WAIT_OBJECT_0 + 0 )
+#define	kWaitListInterfaceListChangedEvent			( WAIT_OBJECT_0 + 1 )
+#define kWaitListComputerDescriptionEvent			( WAIT_OBJECT_0 + 2 )
+#define kWaitListTCPIPEvent							( WAIT_OBJECT_0 + 3 )
+#define kWaitListDynDNSEvent						( WAIT_OBJECT_0 + 4 )
+#define kWaitListFileShareEvent						( WAIT_OBJECT_0 + 5 )
+#define kWaitListFirewallEvent						( WAIT_OBJECT_0 + 6 )
+#define kWaitListAdvertisedServicesEvent			( WAIT_OBJECT_0 + 7 )
+#define kWaitListSPSWakeupEvent						( WAIT_OBJECT_0 + 8 )
+#define kWaitListSPSSleepEvent						( WAIT_OBJECT_0 + 9 )
+#define	kWaitListFixedItemCount						10
+
+
+#if 0
+#pragma mark == Prototypes ==
+#endif
+
+//===========================================================================================================================
+//	Prototypes
+//===========================================================================================================================
+static void			Usage( void );
+static BOOL WINAPI	ConsoleControlHandler( DWORD inControlEvent );
+static OSStatus		InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath );
+static OSStatus		RemoveService( LPCTSTR inName );
+static OSStatus		SetServiceParameters();
+static OSStatus		GetServiceParameters();
+static OSStatus		CheckFirewall();
+static OSStatus		SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription );
+static void			ReportStatus( int inType, const char *inFormat, ... );
+
+static void WINAPI	ServiceMain( DWORD argc, LPTSTR argv[] );
+static OSStatus		ServiceSetupEventLogging( void );
+static DWORD WINAPI	ServiceControlHandler( DWORD inControl, DWORD inEventType, LPVOID inEventData, LPVOID inContext );
+
+static OSStatus		ServiceRun( int argc, LPTSTR argv[] );
+static void			ServiceStop( void );
+
+static OSStatus		ServiceSpecificInitialize( int argc, LPTSTR  argv[] );
+static OSStatus		ServiceSpecificRun( int argc, LPTSTR argv[] );
+static OSStatus		ServiceSpecificStop( void );
+static void			ServiceSpecificFinalize( int argc, LPTSTR argv[] );
+static mStatus		SetupNotifications();
+static mStatus		TearDownNotifications();
+static mStatus		RegisterWaitableEvent( mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler );
+static void			UnregisterWaitableEvent( mDNS * const inMDNS, HANDLE event );
+static mStatus		SetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount );
+static void			UDSCanAccept( mDNS * const inMDNS, HANDLE event, void * context );
+static void			UDSCanRead( TCPSocket * sock );
+static void			HandlePowerSuspend( void * v );
+static void			HandlePowerResumeSuspend( void * v );
+static void			CoreCallback(mDNS * const inMDNS, mStatus result);
+static mDNSu8		SystemWakeForNetworkAccess( LARGE_INTEGER * timeout );
+static OSStatus		GetRouteDestination(DWORD * ifIndex, DWORD * address);
+static OSStatus		SetLLRoute( mDNS * const inMDNS );
+static bool			HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric );
+static bool			IsValidAddress( const char * addr );
+static bool			IsNortelVPN( IP_ADAPTER_INFO * pAdapter );
+static bool			IsJuniperVPN( IP_ADAPTER_INFO * pAdapter );
+static bool			IsCiscoVPN( IP_ADAPTER_INFO * pAdapter );
+static const char * strnistr( const char * string, const char * subString, size_t max );
+
+#if defined(UNICODE)
+#	define StrLen(X)	wcslen(X)
+#	define StrCmp(X,Y)	wcscmp(X,Y)
+#else
+#	define StrLen(X)	strlen(X)
+#	define StrCmp(X,Y)	strcmp(X,Y)
+#endif
+
+
+#define kLLNetworkAddr      "169.254.0.0"
+#define kLLNetworkAddrMask  "255.255.0.0"
+
+
+#include	"mDNSEmbeddedAPI.h"
+
+#if 0
+#pragma mark == Globals ==
+#endif
+
+//===========================================================================================================================
+//	Globals
+//===========================================================================================================================
+#define gMDNSRecord mDNSStorage
+DEBUG_LOCAL	mDNS_PlatformSupport		gPlatformStorage;
+DEBUG_LOCAL BOOL						gServiceQuietMode		= FALSE;
+DEBUG_LOCAL SERVICE_TABLE_ENTRY			gServiceDispatchTable[] = 
+{
+	{ kServiceName,	ServiceMain }, 
+	{ NULL, 		NULL }
+};
+DEBUG_LOCAL SOCKET						gInterfaceListChangedSocket	= INVALID_SOCKET;
+DEBUG_LOCAL HANDLE						gInterfaceListChangedEvent	= NULL;
+DEBUG_LOCAL HKEY						gDescKey					= NULL;
+DEBUG_LOCAL HANDLE						gDescChangedEvent			= NULL;	// Computer description changed event
+DEBUG_LOCAL HKEY						gTcpipKey					= NULL;
+DEBUG_LOCAL HANDLE						gTcpipChangedEvent			= NULL;	// TCP/IP config changed
+DEBUG_LOCAL HKEY						gDdnsKey					= NULL;
+DEBUG_LOCAL HANDLE						gDdnsChangedEvent			= NULL;	// DynDNS config changed
+DEBUG_LOCAL HKEY						gFileSharingKey				= NULL;
+DEBUG_LOCAL HANDLE						gFileSharingChangedEvent	= NULL;	// File Sharing changed
+DEBUG_LOCAL HKEY						gFirewallKey				= NULL;
+DEBUG_LOCAL HANDLE						gFirewallChangedEvent		= NULL;	// Firewall changed
+DEBUG_LOCAL HKEY						gAdvertisedServicesKey		= NULL;
+DEBUG_LOCAL HANDLE						gAdvertisedServicesChangedEvent	= NULL; // Advertised services changed
+DEBUG_LOCAL SERVICE_STATUS				gServiceStatus;
+DEBUG_LOCAL SERVICE_STATUS_HANDLE		gServiceStatusHandle 	= NULL;
+DEBUG_LOCAL HANDLE						gServiceEventSource		= NULL;
+DEBUG_LOCAL bool						gServiceAllowRemote		= false;
+DEBUG_LOCAL int							gServiceCacheEntryCount	= 0;	// 0 means to use the DNS-SD default.
+DEBUG_LOCAL bool						gServiceManageLLRouting = true;
+DEBUG_LOCAL int							gWaitCount				= 0;
+DEBUG_LOCAL HANDLE					*	gWaitList				= NULL;
+DEBUG_LOCAL HANDLE						gStopEvent				= NULL;
+DEBUG_LOCAL HANDLE						gSPSWakeupEvent			= NULL;
+DEBUG_LOCAL HANDLE						gSPSSleepEvent			= NULL;
+DEBUG_LOCAL HANDLE						gUDSEvent				= NULL;
+DEBUG_LOCAL SocketRef					gUDSSocket				= 0;
+DEBUG_LOCAL udsEventCallback			gUDSCallback			= NULL;
+DEBUG_LOCAL BOOL						gRetryFirewall			= FALSE;
+DEBUG_LOCAL DWORD						gOSMajorVersion;
+DEBUG_LOCAL DWORD						gOSMinorVersion;
+
+typedef DWORD ( WINAPI * GetIpInterfaceEntryFunctionPtr )( PMIB_IPINTERFACE_ROW );
+mDNSlocal HMODULE								gIPHelperLibraryInstance		= NULL;
+mDNSlocal GetIpInterfaceEntryFunctionPtr		gGetIpInterfaceEntryFunctionPtr	= NULL;
+
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	Main
+//===========================================================================================================================
+int	Main( int argc, LPTSTR argv[] )
+{
+	OSStatus		err;
+	BOOL			ok;
+	BOOL			start;
+	int				i;
+
+	HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
+
+	debug_initialize( kDebugOutputTypeMetaConsole );
+	debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
+
+	// Default to automatically starting the service dispatcher if no extra arguments are specified.
+	
+	start = ( argc <= 1 );
+	
+	// Parse arguments.
+	
+	for( i = 1; i < argc; ++i )
+	{
+		if( StrCmp( argv[ i ], TEXT("-install") ) == 0 )			// Install
+		{
+			TCHAR desc[ 256 ];
+			
+			desc[ 0 ] = 0;
+			LoadString( GetModuleHandle( NULL ), IDS_SERVICE_DESCRIPTION, desc, sizeof( desc ) );
+			err = InstallService( kServiceName, kServiceName, desc, argv[0] );
+			if( err )
+			{
+				ReportStatus( EVENTLOG_ERROR_TYPE, "install service failed (%d)\n", err );
+				goto exit;
+			}
+		}
+		else if( StrCmp( argv[ i ], TEXT("-remove") ) == 0 )		// Remove
+		{
+			err = RemoveService( kServiceName );
+			if( err )
+			{
+				ReportStatus( EVENTLOG_ERROR_TYPE, "remove service failed (%d)\n", err );
+				goto exit;
+			}
+		}
+		else if( StrCmp( argv[ i ], TEXT("-start") ) == 0 )		// Start
+		{
+			start = TRUE;
+		}
+		else if( StrCmp( argv[ i ], TEXT("-server") ) == 0 )		// Server
+		{
+			err = RunDirect( argc, argv );
+			if( err )
+			{
+				ReportStatus( EVENTLOG_ERROR_TYPE, "run service directly failed (%d)\n", err );
+			}
+			goto exit;
+		}
+		else if( StrCmp( argv[ i ], TEXT("-q") ) == 0 )			// Quiet Mode (toggle)
+		{
+			gServiceQuietMode = !gServiceQuietMode;
+		}
+		else if( ( StrCmp( argv[ i ], TEXT("-help") ) == 0 ) || 	// Help
+				 ( StrCmp( argv[ i ], TEXT("-h") ) == 0 ) )
+		{
+			Usage();
+			err = 0;
+			break;
+		}
+		else
+		{
+			Usage();
+			err = kParamErr;
+			break;
+		}
+	}
+	
+	// Start the service dispatcher if requested. This does not return until all services have terminated. If any 
+	// global initialization is needed, it should be done before starting the service dispatcher, but only if it 
+	// will take less than 30 seconds. Otherwise, use a separate thread for it and start the dispatcher immediately.
+	
+	if( start )
+	{
+		ok = StartServiceCtrlDispatcher( gServiceDispatchTable );
+		err = translate_errno( ok, (OSStatus) GetLastError(), kInUseErr );
+		if( err != kNoErr )
+		{
+			ReportStatus( EVENTLOG_ERROR_TYPE, "start service dispatcher failed (%d)\n", err );
+			goto exit;
+		}
+	}
+	err = 0;
+	
+exit:
+	dlog( kDebugLevelTrace, DEBUG_NAME "exited (%d %m)\n", err, err );
+	_CrtDumpMemoryLeaks();
+	return( (int) err );
+}
+
+//===========================================================================================================================
+//	Usage
+//===========================================================================================================================
+
+static void	Usage( void )
+{
+	fprintf( stderr, "\n" );
+	fprintf( stderr, "mDNSResponder 1.0d1\n" );
+	fprintf( stderr, "\n" );
+	fprintf( stderr, "    <no args>    Runs the service normally\n" );
+	fprintf( stderr, "    -install     Creates the service and starts it\n" );
+	fprintf( stderr, "    -remove      Stops the service and deletes it\n" );
+	fprintf( stderr, "    -start       Starts the service dispatcher after processing all other arguments\n" );
+	fprintf( stderr, "    -server      Runs the service directly as a server (for debugging)\n" );
+	fprintf( stderr, "    -q           Toggles Quiet Mode (no events or output)\n" );
+	fprintf( stderr, "    -remote      Allow remote connections\n" );
+	fprintf( stderr, "    -cache n     Number of mDNS cache entries (defaults to %d)\n", kDNSServiceCacheEntryCountDefault );
+	fprintf( stderr, "    -h[elp]      Display Help/Usage\n" );
+	fprintf( stderr, "\n" );
+}
+
+//===========================================================================================================================
+//	ConsoleControlHandler
+//===========================================================================================================================
+
+static BOOL WINAPI	ConsoleControlHandler( DWORD inControlEvent )
+{
+	BOOL			handled;
+	OSStatus		err;
+	
+	handled = FALSE;
+	switch( inControlEvent )
+	{
+		case CTRL_C_EVENT:
+		case CTRL_BREAK_EVENT:
+		case CTRL_CLOSE_EVENT:
+		case CTRL_LOGOFF_EVENT:
+		case CTRL_SHUTDOWN_EVENT:
+			err = ServiceSpecificStop();
+			require_noerr( err, exit );
+			
+			handled = TRUE;
+			break;
+		
+		default:
+			break;
+	}
+	
+exit:
+	return( handled );
+}
+
+//===========================================================================================================================
+//	InstallService
+//===========================================================================================================================
+
+static OSStatus	InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath )
+{
+	OSStatus		err;
+	SC_HANDLE		scm;
+	SC_HANDLE		service;
+	BOOL			ok;
+	TCHAR			fullPath[ MAX_PATH ];
+	TCHAR *			namePtr;
+	DWORD			size;
+	
+	scm		= NULL;
+	service = NULL;
+	
+	// Get a full path to the executable since a relative path may have been specified.
+	
+	size = GetFullPathName( inPath, MAX_PATH, fullPath, &namePtr );
+	err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
+	require_noerr( err, exit );
+	
+	// Create the service and start it.
+	
+	scm = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+	err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
+	require_noerr( err, exit );
+	
+	service = CreateService( scm, inName, inDisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS, 
+							 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fullPath, NULL, NULL, kServiceDependencies, 
+							 NULL, NULL );
+	err = translate_errno( service, (OSStatus) GetLastError(), kDuplicateErr );
+	require_noerr( err, exit );
+
+	err = SetServiceParameters();
+	check_noerr( err );
+	
+	if( inDescription )
+	{
+		err = SetServiceInfo( scm, inName, inDescription );
+		check_noerr( err );
+	}
+
+	ok = StartService( service, 0, NULL );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kInUseErr );
+	require_noerr( err, exit );
+	
+	ReportStatus( EVENTLOG_SUCCESS, "installed service\n" );
+	err = kNoErr;
+	
+exit:
+	if( service )
+	{
+		CloseServiceHandle( service );
+	}
+	if( scm )
+	{
+		CloseServiceHandle( scm );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	RemoveService
+//===========================================================================================================================
+
+static OSStatus	RemoveService( LPCTSTR inName )
+{
+	OSStatus			err;
+	SC_HANDLE			scm;
+	SC_HANDLE			service;
+	BOOL				ok;
+	SERVICE_STATUS		status;
+	
+	scm		= NULL;
+	service = NULL;
+	
+	// Open a connection to the service.
+	
+	scm = OpenSCManager( 0, 0, SC_MANAGER_ALL_ACCESS );
+	err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
+	require_noerr( err, exit );
+	
+	service = OpenService( scm, inName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE );
+	err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
+	require_noerr( err, exit );
+	
+	// Stop the service, if it is not already stopped, then delete it.
+	
+	ok = QueryServiceStatus( service, &status );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
+	require_noerr( err, exit );
+	
+	if( status.dwCurrentState != SERVICE_STOPPED )
+	{
+		ok = ControlService( service, SERVICE_CONTROL_STOP, &status );
+		check_translated_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
+	}
+	
+	ok = DeleteService( service );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kDeletedErr );
+	require_noerr( err, exit );
+		
+	ReportStatus( EVENTLOG_SUCCESS, "Removed service\n" );
+	err = ERROR_SUCCESS;
+	
+exit:
+	if( service )
+	{
+		CloseServiceHandle( service );
+	}
+	if( scm )
+	{
+		CloseServiceHandle( scm );
+	}
+	return( err );
+}
+
+
+
+//===========================================================================================================================
+//	SetServiceParameters
+//===========================================================================================================================
+
+static OSStatus SetServiceParameters()
+{
+	DWORD 			value;
+	DWORD			valueLen = sizeof(DWORD);
+	DWORD			type;
+	OSStatus		err;
+	HKEY			key;
+
+	key = NULL;
+
+	//
+	// Add/Open Parameters section under service entry in registry
+	//
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
+	require_noerr( err, exit );
+	
+	//
+	// If the value isn't already there, then we create it
+	//
+	err = RegQueryValueEx(key, kServiceManageLLRouting, 0, &type, (LPBYTE) &value, &valueLen);
+
+	if (err != ERROR_SUCCESS)
+	{
+		value = 1;
+
+		err = RegSetValueEx( key, kServiceManageLLRouting, 0, REG_DWORD, (const LPBYTE) &value, sizeof(DWORD) );
+		require_noerr( err, exit );
+	}
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return( err );
+}
+
+
+
+//===========================================================================================================================
+//	GetServiceParameters
+//===========================================================================================================================
+
+static OSStatus GetServiceParameters()
+{
+	DWORD 			value;
+	DWORD			valueLen;
+	DWORD			type;
+	OSStatus		err;
+	HKEY			key;
+
+	key = NULL;
+
+	//
+	// Add/Open Parameters section under service entry in registry
+	//
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
+	require_noerr( err, exit );
+	
+	valueLen = sizeof(DWORD);
+	err = RegQueryValueEx(key, kServiceManageLLRouting, 0, &type, (LPBYTE) &value, &valueLen);
+	if (err == ERROR_SUCCESS)
+	{
+		gServiceManageLLRouting = (value) ? true : false;
+	}
+
+	valueLen = sizeof(DWORD);
+	err = RegQueryValueEx(key, kServiceCacheEntryCount, 0, &type, (LPBYTE) &value, &valueLen);
+	if (err == ERROR_SUCCESS)
+	{
+		gServiceCacheEntryCount = value;
+	}
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return( err );
+}
+
+
+//===========================================================================================================================
+//	CheckFirewall
+//===========================================================================================================================
+
+static OSStatus CheckFirewall()
+{
+	DWORD 					value;
+	DWORD					valueLen;
+	DWORD					type;
+	ENUM_SERVICE_STATUS	*	lpService = NULL;
+	SC_HANDLE				sc = NULL;
+	HKEY					key = NULL;
+	BOOL					ok;
+	DWORD					bytesNeeded = 0;
+	DWORD					srvCount;
+	DWORD					resumeHandle = 0;
+	DWORD					srvType;
+	DWORD					srvState;
+	DWORD					dwBytes = 0;
+	DWORD					i;
+	BOOL					isRunning = FALSE;
+	OSStatus				err = kUnknownErr;
+	
+	// Check to see if the firewall service is running.  If it isn't, then
+	// we want to return immediately
+
+	sc = OpenSCManager( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE );
+	err = translate_errno( sc, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	srvType		=	SERVICE_WIN32;
+	srvState	=	SERVICE_STATE_ALL;
+
+	for ( ;; )
+	{
+		// Call EnumServicesStatus using the handle returned by OpenSCManager
+
+		ok = EnumServicesStatus ( sc, srvType, srvState, lpService, dwBytes, &bytesNeeded, &srvCount, &resumeHandle );
+
+		if ( ok || ( GetLastError() != ERROR_MORE_DATA ) )
+		{
+			break;
+		}
+
+		if ( lpService )
+		{
+			free( lpService );
+		}
+
+		dwBytes = bytesNeeded;
+
+		lpService = ( ENUM_SERVICE_STATUS* ) malloc( dwBytes );
+		require_action( lpService, exit, err = mStatus_NoMemoryErr );
+	}
+
+	err = translate_errno( ok, GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	for ( i = 0; i < srvCount; i++ )
+	{
+		if ( wcscmp( lpService[i].lpServiceName, L"SharedAccess" ) == 0 )
+		{
+			if ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_RUNNING )
+			{
+				isRunning = TRUE;
+			}
+
+			break;
+		}
+	}
+
+	require_action( isRunning, exit, err = kUnknownErr );
+
+	// Check to see if we've managed the firewall.
+	// This package might have been installed, then
+	// the OS was upgraded to SP2 or above.  If that's
+	// the case, then we need to manipulate the firewall
+	// so networking works correctly.
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
+	require_noerr( err, exit );
+
+	valueLen = sizeof(DWORD);
+	err = RegQueryValueEx(key, kServiceManageFirewall, 0, &type, (LPBYTE) &value, &valueLen);
+	
+	if ((err != ERROR_SUCCESS) || (value == 0))
+	{
+		wchar_t	fullPath[ MAX_PATH ];
+		DWORD	size;
+
+		// Get a full path to the executable
+
+		size = GetModuleFileNameW( NULL, fullPath, MAX_PATH );
+		err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
+		require_noerr( err, exit );
+
+		err = mDNSAddToFirewall(fullPath, kServiceFirewallName);
+		require_noerr( err, exit );
+
+		value = 1;
+		err = RegSetValueEx( key, kServiceManageFirewall, 0, REG_DWORD, (const LPBYTE) &value, sizeof( DWORD ) );
+		require_noerr( err, exit );
+	}
+	
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+	
+	if ( lpService )
+	{
+		free( lpService );
+	}
+
+	if ( sc )
+	{
+		CloseServiceHandle ( sc );
+	}
+
+	return( err );
+}
+
+
+
+//===========================================================================================================================
+//	SetServiceInfo
+//===========================================================================================================================
+
+static OSStatus	SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription )
+{
+	OSStatus				err;
+	SC_LOCK					lock;
+	SC_HANDLE				service;
+	SERVICE_DESCRIPTION		description;
+	SERVICE_FAILURE_ACTIONS	actions;
+	SC_ACTION				action;
+	BOOL					ok;
+	
+	check( inServiceName );
+	check( inDescription );
+	
+	lock 	= NULL;
+	service	= NULL;
+	
+	// Open the database (if not provided) and lock it to prevent other access while re-configuring.
+	
+	if( !inSCM )
+	{
+		inSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
+		err = translate_errno( inSCM, (OSStatus) GetLastError(), kOpenErr );
+		require_noerr( err, exit );
+	}
+	
+	lock = LockServiceDatabase( inSCM );
+	err = translate_errno( lock, (OSStatus) GetLastError(), kInUseErr );
+	require_noerr( err, exit );
+	
+	// Open a handle to the service. 
+
+	service = OpenService( inSCM, inServiceName, SERVICE_CHANGE_CONFIG|SERVICE_START );
+	err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
+	require_noerr( err, exit );
+	
+	// Change the description.
+	
+	description.lpDescription = (LPTSTR) inDescription;
+	ok = ChangeServiceConfig2( service, SERVICE_CONFIG_DESCRIPTION, &description );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kParamErr );
+	require_noerr( err, exit );
+	
+	actions.dwResetPeriod	=	INFINITE;
+	actions.lpRebootMsg		=	NULL;
+	actions.lpCommand		=	NULL;
+	actions.cActions		=	1;
+	actions.lpsaActions		=	&action;
+	action.Delay			=	500;
+	action.Type				=	SC_ACTION_RESTART;
+
+	ok = ChangeServiceConfig2( service, SERVICE_CONFIG_FAILURE_ACTIONS, &actions );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kParamErr );
+	require_noerr( err, exit );
+	
+	err = ERROR_SUCCESS;
+	
+exit:
+	// Close the service and release the lock.
+	
+	if( service )
+	{
+		CloseServiceHandle( service );
+	}
+	if( lock )
+	{
+		UnlockServiceDatabase( lock ); 
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	ReportStatus
+//===========================================================================================================================
+
+static void	ReportStatus( int inType, const char *inFormat, ... )
+{
+	if( !gServiceQuietMode )
+	{
+		va_list		args;
+		
+		va_start( args, inFormat );
+		if( gServiceEventSource )
+		{
+			char				s[ 1024 ];
+			BOOL				ok;
+			const char *		array[ 1 ];
+			
+			vsprintf( s, inFormat, args );
+			array[ 0 ] = s;
+			ok = ReportEventA( gServiceEventSource, (WORD) inType, 0, MDNSRESPONDER_LOG, NULL, 1, 0, array, NULL );
+			check_translated_errno( ok, GetLastError(), kUnknownErr );
+		}
+		else
+		{
+			int		n;
+			
+			n = vfprintf( stderr, inFormat, args );
+			check( n >= 0 );
+		}
+		va_end( args );
+	}
+}
+
+//===========================================================================================================================
+//	RunDirect
+//===========================================================================================================================
+
+int	RunDirect( int argc, LPTSTR argv[] )
+{
+	OSStatus		err;
+	BOOL			initialized;
+   BOOL        ok;
+	
+	initialized = FALSE;
+
+	// Install a Console Control Handler to handle things like control-c signals.
+	
+	ok = SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	err = ServiceSpecificInitialize( argc, argv );
+	require_noerr( err, exit );
+	initialized = TRUE;
+	
+	// Run the service. This does not return until the service quits or is stopped.
+	
+	ReportStatus( EVENTLOG_INFORMATION_TYPE, "Running service directly\n" );
+	
+	err = ServiceSpecificRun( argc, argv );
+	require_noerr( err, exit );
+	
+	// Clean up.
+	
+exit:
+	if( initialized )
+	{
+		ServiceSpecificFinalize( argc, argv );
+	}
+	return( err );
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	ServiceMain
+//===========================================================================================================================
+
+static void WINAPI ServiceMain( DWORD argc, LPTSTR argv[] )
+{
+	OSStatus		err;
+	BOOL			ok;
+	
+	err = ServiceSetupEventLogging();
+	check_noerr( err );
+
+	err = GetServiceParameters();
+	check_noerr( err );
+	
+	// Initialize the service status and register the service control handler with the name of the service.
+	
+	gServiceStatus.dwServiceType 				= SERVICE_WIN32_SHARE_PROCESS;
+	gServiceStatus.dwCurrentState 				= 0;
+	gServiceStatus.dwControlsAccepted 			= SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_POWEREVENT;
+	gServiceStatus.dwWin32ExitCode 				= NO_ERROR;
+	gServiceStatus.dwServiceSpecificExitCode 	= NO_ERROR;
+	gServiceStatus.dwCheckPoint 				= 0;
+	gServiceStatus.dwWaitHint 					= 0;
+	
+	gServiceStatusHandle = RegisterServiceCtrlHandlerEx( argv[ 0 ], ServiceControlHandler, NULL );
+	err = translate_errno( gServiceStatusHandle, (OSStatus) GetLastError(), kInUseErr );
+	require_noerr( err, exit );
+	
+	// Mark the service as starting.
+
+	gServiceStatus.dwCurrentState 	= SERVICE_START_PENDING;
+	gServiceStatus.dwCheckPoint	 	= 0;
+	gServiceStatus.dwWaitHint 		= 5000;	// 5 seconds
+	ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
+	check_translated_errno( ok, GetLastError(), kParamErr );
+	
+	// Run the service. This does not return until the service quits or is stopped.
+	
+	err = ServiceRun( (int) argc, argv );
+	if( err != kNoErr )
+	{
+		gServiceStatus.dwWin32ExitCode				= ERROR_SERVICE_SPECIFIC_ERROR;
+		gServiceStatus.dwServiceSpecificExitCode 	= (DWORD) err;
+	}
+	
+	// Service-specific work is done so mark the service as stopped.
+	
+	gServiceStatus.dwCurrentState = SERVICE_STOPPED;
+	ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
+	check_translated_errno( ok, GetLastError(), kParamErr );
+	
+	// Note: The service status handle should not be closed according to Microsoft documentation.
+	
+exit:
+	if( gServiceEventSource )
+	{
+		ok = DeregisterEventSource( gServiceEventSource );
+		check_translated_errno( ok, GetLastError(), kUnknownErr );
+		gServiceEventSource = NULL;
+	}
+}
+
+//===========================================================================================================================
+//	ServiceSetupEventLogging
+//===========================================================================================================================
+
+static OSStatus	ServiceSetupEventLogging( void )
+{
+	OSStatus			err;
+	HKEY				key;
+	LPCTSTR				s;
+	DWORD				typesSupported;
+	TCHAR				path[ MAX_PATH ];
+	DWORD 				n;
+	
+	key = NULL;
+	
+	// Add/Open source name as a sub-key under the Application key in the EventLog registry key.
+
+	s = TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\") kServiceName;
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, s, &key );
+	require_noerr( err, exit );
+	
+	// Add the name to the EventMessageFile subkey.
+
+	path[ 0 ] = '\0';
+	GetModuleFileName( NULL, path, MAX_PATH );
+	n = (DWORD) ( ( StrLen( path ) + 1 ) * sizeof( TCHAR ) );
+	err = RegSetValueEx( key, TEXT("EventMessageFile"), 0, REG_EXPAND_SZ, (const LPBYTE) path, n );
+	require_noerr( err, exit );
+	
+	// Set the supported event types in the TypesSupported subkey.
+	
+	typesSupported = 0 
+					 | EVENTLOG_SUCCESS
+					 | EVENTLOG_ERROR_TYPE
+					 | EVENTLOG_WARNING_TYPE
+					 | EVENTLOG_INFORMATION_TYPE
+					 | EVENTLOG_AUDIT_SUCCESS
+					 | EVENTLOG_AUDIT_FAILURE; 
+	err = RegSetValueEx( key, TEXT("TypesSupported"), 0, REG_DWORD, (const LPBYTE) &typesSupported, sizeof( DWORD ) );
+	require_noerr( err, exit );
+	
+	// Set up the event source.
+	
+	gServiceEventSource = RegisterEventSource( NULL, kServiceName );
+	err = translate_errno( gServiceEventSource, (OSStatus) GetLastError(), kParamErr );
+	require_noerr( err, exit );
+		
+exit:
+	if( key )
+	{
+		RegCloseKey( key );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	HandlePowerSuspend
+//===========================================================================================================================
+
+static void HandlePowerSuspend( void * v )
+{
+	LARGE_INTEGER	timeout;
+	BOOL			ok;
+
+	( void ) v;
+
+	dlog( kDebugLevelInfo, DEBUG_NAME "HandlePowerSuspend\n" );
+
+	gMDNSRecord.SystemWakeOnLANEnabled = SystemWakeForNetworkAccess( &timeout );
+				
+	if ( gMDNSRecord.SystemWakeOnLANEnabled )
+	{
+		ok = SetWaitableTimer( gSPSWakeupEvent, &timeout, 0, NULL, NULL, TRUE );
+		check( ok );
+	}
+
+	mDNSCoreMachineSleep(&gMDNSRecord, TRUE);
+}
+
+
+//===========================================================================================================================
+//	HandlePowerResumeSuspend
+//===========================================================================================================================
+
+static void HandlePowerResumeSuspend( void * v )
+{
+	( void ) v;
+
+	dlog( kDebugLevelInfo, DEBUG_NAME "HandlePowerResumeSuspend\n" );
+
+	if ( gSPSWakeupEvent )
+	{
+		CancelWaitableTimer( gSPSWakeupEvent );
+	}
+
+	if ( gSPSSleepEvent )
+	{
+		CancelWaitableTimer( gSPSSleepEvent );
+	}
+
+	mDNSCoreMachineSleep(&gMDNSRecord, FALSE);
+}
+
+
+//===========================================================================================================================
+//	ServiceControlHandler
+//===========================================================================================================================
+
+static DWORD WINAPI	ServiceControlHandler( DWORD inControl, DWORD inEventType, LPVOID inEventData, LPVOID inContext )
+{
+	BOOL		setStatus;
+	BOOL		ok;
+
+	DEBUG_UNUSED( inEventData );
+	DEBUG_UNUSED( inContext );
+	
+	setStatus = TRUE;
+	switch( inControl )
+	{
+		case SERVICE_CONTROL_STOP:
+		case SERVICE_CONTROL_SHUTDOWN:
+			dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP|SERVICE_CONTROL_SHUTDOWN\n" );
+			
+			ServiceStop();
+			setStatus = FALSE;
+			break;
+		
+		case SERVICE_CONTROL_POWEREVENT:
+
+			if (inEventType == PBT_APMSUSPEND)
+			{
+				dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMSUSPEND\n" );
+
+				QueueUserAPC( ( PAPCFUNC ) HandlePowerSuspend, gMDNSRecord.p->mainThread, ( ULONG_PTR ) NULL );
+			}
+			else if (inEventType == PBT_APMRESUMESUSPEND)
+			{
+				dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMRESUMESUSPEND\n" );
+
+				QueueUserAPC( ( PAPCFUNC ) HandlePowerResumeSuspend, gMDNSRecord.p->mainThread, ( ULONG_PTR ) NULL );
+			}
+		
+			break;
+
+		default:
+			dlog( kDebugLevelNotice, DEBUG_NAME "ServiceControlHandler: event (0x%08X)\n", inControl );
+			break;
+	}
+	
+	if( setStatus && gServiceStatusHandle )
+	{
+		ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
+		check_translated_errno( ok, GetLastError(), kUnknownErr );
+	}
+
+	return NO_ERROR;
+}
+
+//===========================================================================================================================
+//	ServiceRun
+//===========================================================================================================================
+
+static OSStatus	ServiceRun( int argc, LPTSTR argv[] )
+{
+	OSStatus		err;
+	BOOL			initialized;
+	BOOL			ok;
+	
+	DEBUG_UNUSED( argc );
+	DEBUG_UNUSED( argv );
+	
+	initialized = FALSE;
+	
+	// <rdar://problem/5727548> Make the service as running before we call ServiceSpecificInitialize. We've
+	// had reports that some machines with McAfee firewall installed cause a problem with iTunes installation.
+	// We think that the firewall product is interferring with code in ServiceSpecificInitialize. So as a
+	// simple workaround, we'll mark us as running *before* we call ServiceSpecificInitialize. This will unblock
+	// any installers that are waiting for our state to change.
+
+	gServiceStatus.dwCurrentState = SERVICE_RUNNING;
+	ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
+	check_translated_errno( ok, GetLastError(), kParamErr );
+
+	// Initialize the service-specific stuff
+	
+	err = ServiceSpecificInitialize( argc, argv );
+	require_noerr( err, exit );
+	initialized = TRUE;
+	
+	err = CheckFirewall();
+	check_noerr( err );
+
+	if ( err )
+	{
+		gRetryFirewall = TRUE;
+	}
+	
+	// Run the service-specific stuff. This does not return until the service quits or is stopped.
+	
+	ReportStatus( EVENTLOG_INFORMATION_TYPE, "Service started\n" );
+	err = ServiceSpecificRun( argc, argv );
+	ReportStatus( EVENTLOG_INFORMATION_TYPE, "Service stopped (%d)\n", err );
+	require_noerr( err, exit );
+	
+	// Service stopped. Clean up and we're done.
+	
+exit:
+	if( initialized )
+	{
+		ServiceSpecificFinalize( argc, argv );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	ServiceStop
+//===========================================================================================================================
+
+static void	ServiceStop( void )
+{
+	BOOL			ok;
+	OSStatus		err;
+	
+	// Signal the event to cause the service to exit.
+	
+	if( gServiceStatusHandle )
+	{
+		gServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+		ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
+		check_translated_errno( ok, GetLastError(), kParamErr );
+	}
+		
+	err = ServiceSpecificStop();
+	check_noerr( err );
+}
+
+#if 0
+#pragma mark -
+#pragma mark == Service Specific ==
+#endif
+
+//===========================================================================================================================
+//	ServiceSpecificInitialize
+//===========================================================================================================================
+
+static OSStatus	ServiceSpecificInitialize( int argc, LPTSTR argv[] )
+{
+	OSVERSIONINFO osInfo;
+	OSStatus err;
+	BOOL ok;
+	
+	DEBUG_UNUSED( argc );
+	DEBUG_UNUSED( argv );
+	
+	mDNSPlatformMemZero( &gMDNSRecord, sizeof gMDNSRecord);
+	mDNSPlatformMemZero( &gPlatformStorage, sizeof gPlatformStorage);
+
+	gPlatformStorage.registerWaitableEventFunc = RegisterWaitableEvent;
+	gPlatformStorage.unregisterWaitableEventFunc = UnregisterWaitableEvent;
+	gPlatformStorage.reportStatusFunc = ReportStatus;
+
+	err = mDNS_Init( &gMDNSRecord, &gPlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, CoreCallback, mDNS_Init_NoInitCallbackContext); 
+	require_noerr( err, exit);
+
+	err = SetupNotifications();
+	check_noerr( err );
+
+	err = udsserver_init(mDNSNULL, 0);
+	require_noerr( err, exit);
+
+	//
+	// Get the version of Windows that we're running on
+	//
+	osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+	ok = GetVersionEx( &osInfo );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+	gOSMajorVersion = osInfo.dwMajorVersion;
+	gOSMinorVersion = osInfo.dwMinorVersion;
+
+	SetLLRoute( &gMDNSRecord );
+
+exit:
+	if( err != kNoErr )
+	{
+		ServiceSpecificFinalize( argc, argv );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	ServiceSpecificRun
+//===========================================================================================================================
+
+static OSStatus	ServiceSpecificRun( int argc, LPTSTR argv[] )
+{
+	HANDLE	*	waitList;
+	int			waitListCount;
+	DWORD		timeout;
+	DWORD		result;
+	BOOL		done;
+	mStatus		err;
+	
+	DEBUG_UNUSED( argc );
+	DEBUG_UNUSED( argv );
+
+	timeout = ( gRetryFirewall ) ? kRetryFirewallPeriod : INFINITE;
+
+	err = SetupInterfaceList( &gMDNSRecord );
+	check( !err );
+
+	err = uDNS_SetupDNSConfig( &gMDNSRecord );
+	check( !err );
+
+	done = FALSE;
+
+	// Main event loop.
+
+	while( !done )
+	{
+		waitList		= NULL;
+		waitListCount	= 0;
+
+		err = SetupWaitList( &gMDNSRecord, &waitList, &waitListCount );
+		require_noerr( err, exit );
+
+		gEventSourceListChanged = FALSE;
+
+		while ( !gEventSourceListChanged )
+		{
+			static mDNSs32 RepeatedBusy = 0;	
+			mDNSs32 nextTimerEvent;
+
+			// Give the mDNS core a chance to do its work and determine next event time.
+
+			nextTimerEvent = udsserver_idle( mDNS_Execute( &gMDNSRecord ) - mDNS_TimeNow( &gMDNSRecord ) );
+
+			if      ( nextTimerEvent < 0)					nextTimerEvent = 0;
+			else if ( nextTimerEvent > (0x7FFFFFFF / 1000))	nextTimerEvent = 0x7FFFFFFF / mDNSPlatformOneSecond;
+			else											nextTimerEvent = ( nextTimerEvent * 1000) / mDNSPlatformOneSecond;
+
+			// Debugging sanity check, to guard against CPU spins
+			
+			if ( nextTimerEvent > 0 )
+			{
+				RepeatedBusy = 0;
+			}
+			else
+			{
+				nextTimerEvent = 1;
+
+				if ( ++RepeatedBusy >= mDNSPlatformOneSecond )
+				{
+					ShowTaskSchedulingError( &gMDNSRecord );
+					RepeatedBusy = 0;
+				}
+			}
+
+			if ( gMDNSRecord.ShutdownTime )
+			{
+				mDNSs32 now = mDNS_TimeNow( &gMDNSRecord );
+
+				if ( mDNS_ExitNow( &gMDNSRecord, now ) )
+				{
+					mDNS_FinalExit( &gMDNSRecord );
+					done = TRUE;
+					break;
+				}
+
+				if ( nextTimerEvent - gMDNSRecord.ShutdownTime >= 0 )
+				{
+					nextTimerEvent = gMDNSRecord.ShutdownTime;
+				}
+			}
+
+			// Wait until something occurs (e.g. cancel, incoming packet, or timeout).
+			//
+			// Note: There seems to be a bug in WinSock with respect to Alertable I/O. According
+			// to MSDN <http://msdn.microsoft.com/en-us/library/aa363772(VS.85).aspx>, Alertable I/O
+			// callbacks will only be invoked during the following calls (when the caller sets
+			// the appropriate flag):
+			//
+			// - SleepEx
+			// - WaitForSingleObjectEx
+			// - WaitForMultipleObjectsEx
+			// - SignalObjectAndWait
+			// - MsgWaitForMultipleObjectsEx
+			//
+			// However, we have seen callbacks be invoked during calls to bind() (and maybe others). If there
+			// weren't a bug, then socket events would only be queued during the call to WaitForMultipleObjects() and
+			// we'd only have to check them once afterwards. However since that doesn't seem to be the case, we'll
+			// check the queue both before we call WaitForMultipleObjects() and after.
+
+			DispatchSocketEvents( &gMDNSRecord );
+			result = WaitForMultipleObjectsEx( ( DWORD ) waitListCount, waitList, FALSE, (DWORD) nextTimerEvent, TRUE );
+			check( result != WAIT_FAILED );
+			DispatchSocketEvents( &gMDNSRecord );
+
+			if ( result != WAIT_FAILED )
+			{
+				if ( result == WAIT_TIMEOUT )
+				{
+					// Next task timeout occurred. Loop back up to give mDNS core a chance to work.
+					
+					dlog( kDebugLevelChatty - 1, DEBUG_NAME "timeout\n" );
+					continue;
+				}
+				else if ( result == WAIT_IO_COMPLETION )
+				{
+					dlog( kDebugLevelChatty - 1, DEBUG_NAME "i/o completion\n" );
+					continue;
+				}
+				else if ( result == kWaitListStopEvent )
+				{
+					// Stop event. Set the done flag and break to exit.
+					
+					dlog( kDebugLevelVerbose, DEBUG_NAME "stopping...\n" );
+					udsserver_exit();
+					mDNS_StartExit( &gMDNSRecord );
+					break;
+				}
+				else if( result == kWaitListInterfaceListChangedEvent )
+				{
+					int		inBuffer;
+					int		outBuffer;
+					DWORD	outSize;
+
+					// It would be nice to come up with a more elegant solution to this, but it seems that
+					// GetAdaptersAddresses doesn't always stay in sync after network changed events.  So as
+					// as a simple workaround, we'll pause for a couple of seconds before processing the change.
+
+					// We arrived at 2 secs by trial and error. We could reproduce the problem after sleeping
+					// for 500 msec and 750 msec, but couldn't after sleeping for 1 sec.  We added another
+					// second on top of that to account for machine load or some other exigency.
+
+					Sleep( 2000 );
+
+					// Interface list changed event. Break out of the inner loop to re-setup the wait list.
+					
+					InterfaceListDidChange( &gMDNSRecord );
+
+					// reset the event handler
+					inBuffer	= 0;
+					outBuffer	= 0;
+					err = WSAIoctl( gInterfaceListChangedSocket, SIO_ADDRESS_LIST_CHANGE, &inBuffer, 0, &outBuffer, 0, &outSize, NULL, NULL );
+					if( err < 0 )
+					{
+						check( errno_compat() == WSAEWOULDBLOCK );
+					}
+				}
+				else if ( result == kWaitListComputerDescriptionEvent )
+				{
+					// The computer description might have changed
+					
+					ComputerDescriptionDidChange( &gMDNSRecord );
+					udsserver_handle_configchange( &gMDNSRecord );
+
+					// and reset the event handler
+					if ( ( gDescKey != NULL ) && ( gDescChangedEvent != NULL ) )
+					{
+						err = RegNotifyChangeKeyValue( gDescKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, gDescChangedEvent, TRUE);
+						check_noerr( err );
+					}
+				}
+				else if ( result == kWaitListTCPIPEvent )
+				{	
+					// The TCP/IP might have changed
+
+					TCPIPConfigDidChange( &gMDNSRecord );
+					udsserver_handle_configchange( &gMDNSRecord );
+
+					// and reset the event handler
+
+					if ( ( gTcpipKey != NULL ) && ( gTcpipChangedEvent ) )
+					{
+						err = RegNotifyChangeKeyValue( gTcpipKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gTcpipChangedEvent, TRUE );
+						check_noerr( err );
+					}
+				}
+				else if ( result == kWaitListDynDNSEvent )
+				{
+					// The DynDNS config might have changed
+
+					DynDNSConfigDidChange( &gMDNSRecord );
+					udsserver_handle_configchange( &gMDNSRecord );
+
+					// and reset the event handler
+
+					if ((gDdnsKey != NULL) && (gDdnsChangedEvent))
+					{
+						err = RegNotifyChangeKeyValue(gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
+						check_noerr( err );
+					}
+				}
+				else if ( result == kWaitListFileShareEvent )
+				{
+					// File sharing changed
+
+					FileSharingDidChange( &gMDNSRecord );
+
+					// and reset the event handler
+
+					if ((gFileSharingKey != NULL) && (gFileSharingChangedEvent))
+					{
+						err = RegNotifyChangeKeyValue(gFileSharingKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFileSharingChangedEvent, TRUE);
+						check_noerr( err );
+					}
+				}
+				else if ( result == kWaitListFirewallEvent )
+				{
+					// Firewall configuration changed
+
+					FirewallDidChange( &gMDNSRecord );
+
+					// and reset the event handler
+
+					if ((gFirewallKey != NULL) && (gFirewallChangedEvent))
+					{
+						err = RegNotifyChangeKeyValue(gFirewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFirewallChangedEvent, TRUE);
+						check_noerr( err );
+					}
+				}
+				else if ( result == kWaitListAdvertisedServicesEvent )
+				{
+					// Ultimately we'll want to manage multiple services, but right now the only service
+					// we'll be managing is SMB.
+
+					FileSharingDidChange( &gMDNSRecord );
+
+					// and reset the event handler
+
+					if ( ( gAdvertisedServicesKey != NULL ) && ( gAdvertisedServicesChangedEvent ) )
+					{
+						err = RegNotifyChangeKeyValue(gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
+						check_noerr( err );
+					}
+				}
+				else if ( result == kWaitListSPSWakeupEvent )
+				{
+					LARGE_INTEGER timeout;
+
+					ReportStatus( EVENTLOG_INFORMATION_TYPE, "Maintenance wake" );
+
+					timeout.QuadPart  = kSPSMaintenanceWakePeriod;
+					timeout.QuadPart *= kSecondsTo100NSUnits;
+
+					SetWaitableTimer( gSPSSleepEvent, &timeout, 0, NULL, NULL, TRUE );
+				}
+				else if ( result == kWaitListSPSSleepEvent )
+				{
+					ReportStatus( EVENTLOG_INFORMATION_TYPE, "Returning to sleep after maintenance wake" );
+
+					// Calling SetSuspendState() doesn't invoke our sleep handlers, so we'll
+					// call HandlePowerSuspend() explicity.  This will reset the 
+					// maintenance wake timers.
+
+					HandlePowerSuspend( NULL );
+					SetSuspendState( FALSE, FALSE, FALSE );
+				}
+				else
+				{
+					int waitItemIndex;
+
+					waitItemIndex = (int)( ( (int) result ) - WAIT_OBJECT_0 );
+					dlog( kDebugLevelChatty, DEBUG_NAME "waitable event on %d\n", waitItemIndex );
+					check( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) );
+
+					if ( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) )
+					{
+						HANDLE	signaledEvent;
+						int		n = 0;
+						
+						signaledEvent = waitList[ waitItemIndex ];
+
+						// If gCurrentSource is not NULL, then this routine has been called
+						// re-entrantly which should never happen.
+
+						check( !gCurrentSource );
+
+						for ( gCurrentSource = gEventSourceList; gCurrentSource; )
+						{
+							EventSource * current = gCurrentSource;
+
+							if ( gCurrentSource->event == signaledEvent )
+							{
+								gCurrentSource->handler( &gMDNSRecord, gCurrentSource->event, gCurrentSource->context );
+								++n;
+								break;
+							}
+
+							// If the current node was removed as a result of calling
+							// the handler, then gCurrentSource was already incremented to
+							// the next node.  If it wasn't removed, then increment it
+							// ourselves
+
+							if ( gCurrentSource == current )
+							{
+								gCurrentSource = gCurrentSource->next;
+							}
+						}
+
+						gCurrentSource = NULL;
+
+						check( n > 0 );
+					}
+					else
+					{
+						dlog( kDebugLevelWarning, DEBUG_NAME "%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__, result );
+					}
+				}
+			}
+			else
+			{
+				Sleep( 3 * 1000 );
+				
+				err = SetupInterfaceList( &gMDNSRecord );
+				check( !err );
+
+				err = uDNS_SetupDNSConfig( &gMDNSRecord );
+				check( !err );
+				
+				break;
+			}
+		}
+
+		if ( waitList )
+		{
+			free( waitList );
+			waitList = NULL;
+			waitListCount = 0;
+		}
+	}
+
+exit:
+
+	return( 0 );
+}
+
+//===========================================================================================================================
+//	ServiceSpecificStop
+//===========================================================================================================================
+
+static OSStatus	ServiceSpecificStop( void )
+{
+	OSStatus	err;
+	BOOL	 	ok;
+
+	ok = SetEvent(gStopEvent);
+	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+exit:
+	return( err );
+}
+
+//===========================================================================================================================
+//	ServiceSpecificFinalize
+//===========================================================================================================================
+
+static void	ServiceSpecificFinalize( int argc, LPTSTR argv[] )
+{
+	DEBUG_UNUSED( argc );
+	DEBUG_UNUSED( argv );
+	
+	//
+	// clean up any open sessions
+	//
+	while ( gEventSourceList )
+	{
+		UnregisterWaitableEvent( &gMDNSRecord, gEventSourceList->event );
+	}
+
+	//
+	// clean up the notifications
+	//
+	TearDownNotifications();
+
+	//
+	// clean up loaded library
+	//
+
+	if( gIPHelperLibraryInstance )
+	{
+		gGetIpInterfaceEntryFunctionPtr = NULL;
+		
+		FreeLibrary( gIPHelperLibraryInstance );
+		gIPHelperLibraryInstance = NULL;
+	}
+}
+
+
+//===========================================================================================================================
+//	SetupNotifications
+//===========================================================================================================================
+
+mDNSlocal mStatus	SetupNotifications()
+{
+	mStatus				err;
+	SocketRef			sock;
+	unsigned long		param;
+	int					inBuffer;
+	int					outBuffer;
+	DWORD				outSize;
+	
+	gStopEvent	=	CreateEvent(NULL, FALSE, FALSE, NULL);
+	err = translate_errno( gStopEvent, errno_compat(), kNoResourcesErr );
+	require_noerr( err, exit );
+
+	// Register to listen for address list changes.
+	
+	gInterfaceListChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+	err = translate_errno( gInterfaceListChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+	gInterfaceListChangedSocket = sock;
+	
+	// Make the socket non-blocking so the WSAIoctl returns immediately with WSAEWOULDBLOCK. It will set the event 
+	// when a change to the interface list is detected.
+	
+	param = 1;
+	err = ioctlsocket( sock, FIONBIO, &param );
+	err = translate_errno( err == 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	inBuffer	= 0;
+	outBuffer	= 0;
+	err = WSAIoctl( sock, SIO_ADDRESS_LIST_CHANGE, &inBuffer, 0, &outBuffer, 0, &outSize, NULL, NULL );
+	if( err < 0 )
+	{
+		check( errno_compat() == WSAEWOULDBLOCK );
+	}
+	
+	err = WSAEventSelect( sock, gInterfaceListChangedEvent, FD_ADDRESS_LIST_CHANGE );
+	err = translate_errno( err == 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+
+	gDescChangedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+	err = translate_errno( gDescChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters"), 0, KEY_READ, &gDescKey);
+	check_translated_errno( err == 0, errno_compat(), kNameErr );
+
+	if ( gDescKey != NULL )
+	{
+		err = RegNotifyChangeKeyValue( gDescKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, gDescChangedEvent, TRUE);
+		require_noerr( err, exit );
+	}
+
+	// This will catch all changes to tcp/ip networking, including changes to the domain search list
+
+	gTcpipChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+	err = translate_errno( gTcpipChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &gTcpipKey );
+	require_noerr( err, exit );
+
+	err = RegNotifyChangeKeyValue( gTcpipKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gTcpipChangedEvent, TRUE);
+	require_noerr( err, exit );
+
+	// This will catch all changes to ddns configuration
+
+	gDdnsChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+	err = translate_errno( gDdnsChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup"), &gDdnsKey );
+	require_noerr( err, exit );
+
+	err = RegNotifyChangeKeyValue( gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
+	require_noerr( err, exit );
+
+	// This will catch all changes to file sharing
+
+	gFileSharingChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+	err = translate_errno( gFileSharingChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\Shares"), &gFileSharingKey );
+	
+	// Just to make sure that initialization doesn't fail on some old OS
+	// that doesn't have this key, we'll only add the notification if
+	// the key exists.
+
+	if ( !err )
+	{
+		err = RegNotifyChangeKeyValue( gFileSharingKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFileSharingChangedEvent, TRUE);
+		require_noerr( err, exit );
+	}
+	else
+	{
+		err = mStatus_NoError;
+	}
+
+	// This will catch changes to the Windows firewall
+
+	gFirewallChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+	err = translate_errno( gFirewallChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	// Just to make sure that initialization doesn't fail on some old OS
+	// that doesn't have this key, we'll only add the notification if
+	// the key exists.
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules"), &gFirewallKey );
+	
+	if ( !err )
+	{
+		err = RegNotifyChangeKeyValue( gFirewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFirewallChangedEvent, TRUE);
+		require_noerr( err, exit );
+	}
+	else
+	{
+		err = mStatus_NoError;
+	}
+
+	// This will catch all changes to advertised services configuration
+
+	gAdvertisedServicesChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+	err = translate_errno( gAdvertisedServicesChangedEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\Services"), &gAdvertisedServicesKey );
+	require_noerr( err, exit );
+
+	err = RegNotifyChangeKeyValue( gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
+	require_noerr( err, exit );
+
+	gSPSWakeupEvent = CreateWaitableTimer( NULL, FALSE, NULL );
+	err = translate_errno( gSPSWakeupEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	gSPSSleepEvent = CreateWaitableTimer( NULL, FALSE, NULL );
+	err = translate_errno( gSPSSleepEvent, (mStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	gUDSEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+	err = translate_errno( gUDSEvent, ( mStatus ) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+exit:
+	if( err )
+	{
+		TearDownNotifications();
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	TearDownNotifications
+//===========================================================================================================================
+
+mDNSlocal mStatus	TearDownNotifications()
+{
+	if ( gStopEvent )
+	{
+		CloseHandle( gStopEvent );
+		gStopEvent = NULL;
+	}
+
+	if( IsValidSocket( gInterfaceListChangedSocket ) )
+	{
+		close_compat( gInterfaceListChangedSocket );
+		gInterfaceListChangedSocket = kInvalidSocketRef;
+	}
+
+	if( gInterfaceListChangedEvent )
+	{
+		CloseHandle( gInterfaceListChangedEvent );
+		gInterfaceListChangedEvent = 0;
+	}
+
+	if ( gDescChangedEvent != NULL )
+	{
+		CloseHandle( gDescChangedEvent );
+		gDescChangedEvent = NULL;
+	}
+
+	if ( gDescKey != NULL )
+	{
+		RegCloseKey( gDescKey );
+		gDescKey = NULL;
+	}
+
+	if ( gTcpipChangedEvent != NULL )
+	{
+		CloseHandle( gTcpipChangedEvent );
+		gTcpipChangedEvent = NULL;
+	}
+
+	if ( gDdnsChangedEvent != NULL )
+	{
+		CloseHandle( gDdnsChangedEvent );
+		gDdnsChangedEvent = NULL;
+	}
+
+	if ( gDdnsKey != NULL )
+	{
+		RegCloseKey( gDdnsKey );
+		gDdnsKey = NULL;
+	}
+
+	if ( gFileSharingChangedEvent != NULL )
+	{
+		CloseHandle( gFileSharingChangedEvent );
+		gFileSharingChangedEvent = NULL;
+	}
+
+	if ( gFileSharingKey != NULL )
+	{
+		RegCloseKey( gFileSharingKey );
+		gFileSharingKey = NULL;
+	}
+
+	if ( gFirewallChangedEvent != NULL )
+	{
+		CloseHandle( gFirewallChangedEvent );
+		gFirewallChangedEvent = NULL;
+	}
+
+	if ( gFirewallKey != NULL )
+	{
+		RegCloseKey( gFirewallKey );
+		gFirewallKey = NULL;
+	}
+
+	if ( gAdvertisedServicesChangedEvent != NULL )
+	{
+		CloseHandle( gAdvertisedServicesChangedEvent );
+		gAdvertisedServicesChangedEvent = NULL;
+	}
+
+	if ( gAdvertisedServicesKey != NULL )
+	{
+		RegCloseKey( gAdvertisedServicesKey );
+		gAdvertisedServicesKey = NULL;
+	}
+
+	if ( gSPSWakeupEvent )
+	{
+		CloseHandle( gSPSWakeupEvent );
+		gSPSWakeupEvent = NULL;
+	}
+
+	if ( gSPSSleepEvent )
+	{
+		CloseHandle( gSPSSleepEvent );
+		gSPSSleepEvent = NULL;
+	}
+
+	return( mStatus_NoError );
+}
+
+
+//===========================================================================================================================
+//	RegisterWaitableEvent
+//===========================================================================================================================
+
+static mStatus RegisterWaitableEvent( mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler )
+{
+	EventSource * source;
+	mStatus err = mStatus_NoError;
+
+	( void ) inMDNS;
+	check( event );
+	check( handler );
+
+	source = ( EventSource* ) malloc( sizeof( EventSource ) );
+	require_action( source, exit, err = mStatus_NoMemoryErr );
+	mDNSPlatformMemZero( source, sizeof( EventSource ) );
+	source->event = event;
+	source->context = context;
+	source->handler = handler;
+
+	source->next			= gEventSourceList;
+	gEventSourceList		= source;
+	gEventSourceListChanged	= TRUE;
+	gEventSources++;
+
+exit:
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	UnregisterWaitableEvent
+//===========================================================================================================================
+
+static void UnregisterWaitableEvent( mDNS * const inMDNS, HANDLE event )
+{
+	EventSource	*	current	= gEventSourceList;
+	EventSource	*	last	= NULL;
+
+	( void ) inMDNS;
+	check( event );
+
+	while ( current )
+	{
+		if ( current->event == event )
+		{
+			if ( last == NULL )
+			{
+				gEventSourceList = current->next;
+			}
+			else
+			{
+				last->next = current->next;
+			}
+
+			gEventSourceListChanged = TRUE;
+
+			// Protect against removing the node that we happen
+			// to be looking at as we iterate through the event
+			// source list in ServiceSpecificRun()
+
+			if ( current == gCurrentSource )
+			{
+				gCurrentSource = current->next;
+			}
+
+			gEventSources--;
+			free( current );
+
+			break;
+		}
+
+		last	= current;
+		current	= current->next;
+	}
+}
+
+
+//===========================================================================================================================
+//	SetupWaitList
+//===========================================================================================================================
+
+mDNSlocal mStatus SetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount )
+{
+	int				waitListCount;
+	HANDLE		*	waitList;
+	HANDLE		*	waitItemPtr;
+	EventSource	*	source;
+	mStatus			err;
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up wait list\n" );
+	
+	( void ) inMDNS;
+	check( inMDNS->p );
+	check( outWaitList );
+	check( outWaitListCount );
+	
+	// Allocate an array to hold all the objects to wait on.
+	
+	waitListCount = kWaitListFixedItemCount + gEventSources;
+	waitList = ( HANDLE* ) malloc( waitListCount * sizeof( *waitList ) );
+	require_action( waitList, exit, err = mStatus_NoMemoryErr );
+	waitItemPtr = waitList;
+	
+	// Add the fixed wait items to the beginning of the list.
+	
+	*waitItemPtr++	=	gStopEvent;
+	*waitItemPtr++	=	gInterfaceListChangedEvent;
+	*waitItemPtr++	=	gDescChangedEvent;
+	*waitItemPtr++	=	gTcpipChangedEvent;
+	*waitItemPtr++	=	gDdnsChangedEvent;
+	*waitItemPtr++	=	gFileSharingChangedEvent;
+	*waitItemPtr++	=	gFirewallChangedEvent;
+	*waitItemPtr++	=	gAdvertisedServicesChangedEvent;
+	*waitItemPtr++	=	gSPSWakeupEvent;
+	*waitItemPtr++	=	gSPSSleepEvent;
+
+	for ( source = gEventSourceList; source; source = source->next )
+	{
+		*waitItemPtr++ = source->event;
+	}
+
+	check( ( int )( waitItemPtr - waitList ) == waitListCount );
+	
+	*outWaitList 		= waitList;
+	*outWaitListCount	= waitListCount;
+	waitList			= NULL;
+	err					= mStatus_NoError;
+	
+exit:
+
+	if( waitList )
+	{
+		free( waitList );
+	}
+
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up wait list done (err=%d %m)\n", err, err );
+	return( err );
+}
+
+
+//===========================================================================================================================
+//	CoreCallback
+//===========================================================================================================================
+
+static void
+CoreCallback(mDNS * const inMDNS, mStatus status)
+{
+	if (status == mStatus_ConfigChanged)
+	{
+		SetLLRoute( inMDNS );
+	}
+}
+
+
+//===========================================================================================================================
+//	UDSCanAccept
+//===========================================================================================================================
+
+mDNSlocal void UDSCanAccept( mDNS * const inMDNS, HANDLE event, void * context )
+{
+	( void ) inMDNS;
+	( void ) event;
+	
+	if ( gUDSCallback )
+	{
+		gUDSCallback( ( int ) gUDSSocket, 0, context );
+	}
+}
+
+
+//===========================================================================================================================
+//	UDSCanRead
+//===========================================================================================================================
+
+mDNSlocal void UDSCanRead( TCPSocket * sock )
+{
+	udsEventCallback callback = ( udsEventCallback ) sock->userCallback;
+
+	if ( callback )
+	{
+		callback( (int) sock->fd, 0, sock->userContext );
+	}
+}
+
+
+//===========================================================================================================================
+//	udsSupportAddFDToEventLoop
+//===========================================================================================================================
+
+
+mStatus
+udsSupportAddFDToEventLoop( SocketRef fd, udsEventCallback callback, void *context, void **platform_data)
+{
+	mStatus err = mStatus_NoError;
+
+	// We are using some knowledge of what is being passed to us here.  If the fd is a listen socket,
+	// then the "callback" parameter is NULL.  If it is an actual read/write socket, then the "callback"
+	// parameter is not null. This is important because we use waitable events for the listen socket
+	// and alertable I/O for the read/write sockets.
+
+	if ( context )
+	{
+		TCPSocket * sock;
+
+		sock = malloc( sizeof( TCPSocket ) );
+		require_action( sock, exit, err = mStatus_NoMemoryErr );
+		mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
+
+		sock->fd				= (SOCKET) fd;
+		sock->readEventHandler	= UDSCanRead;
+		sock->userCallback		= callback;
+		sock->userContext		= context;
+		sock->m					= &gMDNSRecord;
+
+		err = TCPAddSocket( sock->m, sock );
+		require_noerr( err, exit );
+
+		*platform_data = sock;
+	}
+	else
+	{
+		gUDSSocket		= fd;
+		gUDSCallback	= callback;
+		gUDSEvent		= CreateEvent( NULL, FALSE, FALSE, NULL );
+		err = translate_errno( gUDSEvent, (mStatus) GetLastError(), kUnknownErr );
+		require_noerr( err, exit ); 
+		err = WSAEventSelect( fd, gUDSEvent, FD_ACCEPT | FD_CLOSE );
+		err = translate_errno( err == 0, WSAGetLastError(), kNoResourcesErr );
+		require_noerr( err, exit );
+		err = RegisterWaitableEvent( &gMDNSRecord, gUDSEvent, context, UDSCanAccept );
+		require_noerr( err, exit );
+	}
+
+exit:
+
+	return err;
+}
+
+
+int
+udsSupportReadFD( SocketRef fd, char *buf, int len, int flags, void *platform_data )
+{
+	TCPSocket	*	sock;
+	mDNSBool		closed;
+	int				ret;
+
+	( void ) flags;
+
+	sock = ( TCPSocket* ) platform_data;
+	require_action( sock, exit, ret = -1 );
+	require_action( sock->fd == fd, exit, ret = -1 );
+
+	ret = mDNSPlatformReadTCP( sock, buf, len, &closed );
+
+	if ( closed )
+	{
+		ret = 0;
+	}
+
+exit:
+
+	return ret;
+}
+
+
+mStatus
+udsSupportRemoveFDFromEventLoop( SocketRef fd, void *platform_data)		// Note: This also CLOSES the socket
+{
+	mStatus err = kNoErr;
+
+	if ( platform_data != NULL )
+	{
+		TCPSocket * sock;
+
+		dlog( kDebugLevelInfo, DEBUG_NAME "session closed\n" );
+		sock = ( TCPSocket* ) platform_data;
+		check( sock->fd == fd );
+		mDNSPlatformTCPCloseConnection( sock );
+	}
+	else if ( gUDSEvent != NULL )
+	{
+		UnregisterWaitableEvent( &gMDNSRecord, gUDSEvent );
+		WSAEventSelect( fd, gUDSEvent, 0 );
+		CloseHandle( gUDSEvent );
+		gUDSEvent = NULL;
+	}
+
+	return err;
+}
+
+
+mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
+	{
+	(void)m;
+	(void)delay;
+	// No-op, for now
+	}
+
+
+//===========================================================================================================================
+//	SystemWakeForNetworkAccess
+//===========================================================================================================================
+
+mDNSu8
+SystemWakeForNetworkAccess( LARGE_INTEGER * timeout )
+{
+	HKEY					key = NULL;
+	DWORD					dwSize;
+	DWORD					enabled;
+	mDNSu8					ok;
+	SYSTEM_POWER_STATUS		powerStatus;
+	time_t					startTime;
+	time_t					nextWakeupTime;
+	int						delta;
+	DWORD					err;
+
+	dlog( kDebugLevelInfo, DEBUG_NAME "SystemWakeForNetworkAccess\n" );
+
+	// Make sure we have a timer
+
+	require_action( gSPSWakeupEvent != NULL, exit, ok = FALSE );
+	require_action( gSPSSleepEvent != NULL, exit, ok = FALSE );
+
+	// Make sure the user enabled bonjour sleep proxy client 
+	
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key );
+	require_action( !err, exit, ok = FALSE );
+	dwSize = sizeof( DWORD );
+	err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+	require_action( !err, exit, ok = FALSE );
+	require_action( enabled, exit, ok = FALSE );
+	
+	// Make sure machine is on AC power
+	
+	ok = ( mDNSu8 ) GetSystemPowerStatus( &powerStatus );
+	require_action( ok, exit, ok = FALSE );
+	require_action( powerStatus.ACLineStatus == AC_LINE_ONLINE, exit, ok = FALSE );
+
+	// Now make sure we have a network interface that does wake-on-lan
+
+	ok = ( mDNSu8 ) IsWOMPEnabled( &gMDNSRecord );
+	require_action( ok, exit, ok = FALSE );
+
+	// Now make sure we have advertised services. Doesn't make sense to
+	// enable sleep proxy if we have no multicast services that could
+	// potentially wake us up.
+
+	ok = ( mDNSu8 ) mDNSCoreHaveAdvertisedMulticastServices( &gMDNSRecord );
+	require_action( ok, exit, ok = FALSE );
+
+	// Calculate next wake up time
+
+	startTime		= time( NULL );					// Seconds since midnight January 1, 1970
+	nextWakeupTime	= startTime + ( 120 * 60 );		// 2 hours later
+	
+	if ( gMDNSRecord.p->nextDHCPLeaseExpires < nextWakeupTime )
+	{
+		nextWakeupTime = gMDNSRecord.p->nextDHCPLeaseExpires;
+	}
+
+	// Finally calculate the next relative wakeup time
+
+	delta = ( int )( ( ( double )( nextWakeupTime - startTime ) ) * 0.9 );
+	ReportStatus( EVENTLOG_INFORMATION_TYPE, "enabling sleep proxy client with next maintenance wake in %d seconds", delta );
+
+	// Convert seconds to 100 nanosecond units expected by SetWaitableTimer
+
+	timeout->QuadPart  = -delta;
+	timeout->QuadPart *= kSecondsTo100NSUnits;
+
+	ok = TRUE;
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return ok;
+}
+
+
+//===========================================================================================================================
+//	HaveRoute
+//===========================================================================================================================
+
+static bool
+HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric )
+{
+	PMIB_IPFORWARDTABLE	pIpForwardTable	= NULL;
+	DWORD				dwSize			= 0;
+	BOOL				bOrder			= FALSE;
+	OSStatus			err;
+	bool				found			= false;
+	unsigned long int	i;
+
+	//
+	// Find out how big our buffer needs to be.
+	//
+	err = GetIpForwardTable(NULL, &dwSize, bOrder);
+	require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
+
+	//
+	// Allocate the memory for the table
+	//
+	pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
+	require_action( pIpForwardTable, exit, err = kNoMemoryErr );
+  
+	//
+	// Now get the table.
+	//
+	err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
+	require_noerr( err, exit );
+
+	//
+	// Search for the row in the table we want.
+	//
+	for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
+	{
+		if ( ( pIpForwardTable->table[i].dwForwardDest == addr ) && ( !metric || ( pIpForwardTable->table[i].dwForwardMetric1 == metric ) ) )
+		{
+			memcpy( rowExtant, &(pIpForwardTable->table[i]), sizeof(*rowExtant) );
+			found = true;
+			break;
+		}
+	}
+
+exit:
+
+	if ( pIpForwardTable != NULL ) 
+	{
+		free(pIpForwardTable);
+	}
+    
+	return found;
+}
+
+
+//===========================================================================================================================
+//	IsValidAddress
+//===========================================================================================================================
+
+static bool
+IsValidAddress( const char * addr )
+{
+	return ( addr && ( strcmp( addr, "0.0.0.0" ) != 0 ) ) ? true : false;
+}	
+
+
+//===========================================================================================================================
+//	GetAdditionalMetric
+//===========================================================================================================================
+
+static ULONG
+GetAdditionalMetric( DWORD ifIndex )
+{
+	ULONG metric = 0;
+
+	if( !gIPHelperLibraryInstance )
+	{
+		gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
+
+		gGetIpInterfaceEntryFunctionPtr = 
+				(GetIpInterfaceEntryFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetIpInterfaceEntry" );
+
+		if( !gGetIpInterfaceEntryFunctionPtr )
+		{		
+			BOOL ok;
+				
+			ok = FreeLibrary( gIPHelperLibraryInstance );
+			check_translated_errno( ok, GetLastError(), kUnknownErr );
+			gIPHelperLibraryInstance = NULL;
+		}
+	}
+
+	if ( gGetIpInterfaceEntryFunctionPtr )
+	{
+		MIB_IPINTERFACE_ROW row;
+		DWORD err;
+
+		ZeroMemory( &row, sizeof( MIB_IPINTERFACE_ROW ) );
+		row.Family = AF_INET;
+		row.InterfaceIndex = ifIndex;
+		err = gGetIpInterfaceEntryFunctionPtr( &row );
+		require_noerr( err, exit );
+		metric = row.Metric + 256;
+	}
+
+exit:
+
+	return metric;
+}
+
+
+//===========================================================================================================================
+//	SetLLRoute
+//===========================================================================================================================
+
+static OSStatus
+SetLLRoute( mDNS * const inMDNS )
+{
+	OSStatus err = kNoErr;
+
+	DEBUG_UNUSED( inMDNS );
+
+	//
+	// <rdar://problem/4096464> Don't call SetLLRoute on loopback
+	// <rdar://problem/6885843> Default route on Windows 7 breaks network connectivity
+	// 
+	// Don't mess w/ the routing table on Vista and later OSes, as 
+	// they have a permanent route to link-local addresses. Otherwise,
+	// set a route to link local addresses (169.254.0.0)
+	//
+	if ( ( gOSMajorVersion < 6 ) && gServiceManageLLRouting && !gPlatformStorage.registeredLoopback4 )
+	{
+		DWORD				ifIndex;
+		MIB_IPFORWARDROW	rowExtant;
+		bool				addRoute;
+		MIB_IPFORWARDROW	row;
+
+		ZeroMemory(&row, sizeof(row));
+
+		err = GetRouteDestination(&ifIndex, &row.dwForwardNextHop);
+		require_noerr( err, exit );
+		row.dwForwardDest		= inet_addr(kLLNetworkAddr);
+		row.dwForwardIfIndex	= ifIndex;
+		row.dwForwardMask		= inet_addr(kLLNetworkAddrMask);
+		row.dwForwardType		= 3;
+		row.dwForwardProto		= MIB_IPPROTO_NETMGMT;
+		row.dwForwardAge		= 0;
+		row.dwForwardPolicy		= 0;
+		row.dwForwardMetric1	= 20 + GetAdditionalMetric( ifIndex );
+		row.dwForwardMetric2	= (DWORD) - 1;
+		row.dwForwardMetric3	= (DWORD) - 1;
+		row.dwForwardMetric4	= (DWORD) - 1;
+		row.dwForwardMetric5	= (DWORD) - 1;
+
+		addRoute = true;
+
+		//
+		// check to make sure we don't already have a route
+		//
+		if ( HaveRoute( &rowExtant, inet_addr( kLLNetworkAddr ), 0 ) )
+		{
+			//
+			// set the age to 0 so that we can do a memcmp.
+			//
+			rowExtant.dwForwardAge = 0;
+
+			//
+			// check to see if this route is the same as our route
+			//
+			if (memcmp(&row, &rowExtant, sizeof(row)) != 0)
+			{
+				//
+				// if it isn't then delete this entry
+				//
+				DeleteIpForwardEntry(&rowExtant);
+			}
+			else
+			{
+				//
+				// else it is, so we don't want to create another route
+				//
+				addRoute = false;
+			}
+		}
+
+		if (addRoute && row.dwForwardNextHop)
+		{
+			err = CreateIpForwardEntry(&row);
+			check_noerr( err );
+		}
+	}
+
+exit:
+
+	return ( err );
+}
+
+
+//===========================================================================================================================
+//	GetRouteDestination
+//===========================================================================================================================
+
+static OSStatus
+GetRouteDestination(DWORD * ifIndex, DWORD * address)
+{
+	struct in_addr		ia;
+	IP_ADAPTER_INFO	*	pAdapterInfo	=	NULL;
+	IP_ADAPTER_INFO	*	pAdapter		=	NULL;
+	ULONG				bufLen;
+	mDNSBool			done			=	mDNSfalse;
+	OSStatus			err;
+
+	//
+	// GetBestInterface will fail if there is no default gateway
+	// configured.  If that happens, we will just take the first
+	// interface in the list. MSDN support says there is no surefire
+	// way to manually determine what the best interface might
+	// be for a particular network address.
+	//
+	ia.s_addr	=	inet_addr(kLLNetworkAddr);
+	err			=	GetBestInterface(*(IPAddr*) &ia, ifIndex);
+
+	if (err)
+	{
+		*ifIndex = 0;
+	}
+
+	//
+	// Make an initial call to GetAdaptersInfo to get
+	// the necessary size into the bufLen variable
+	//
+	err = GetAdaptersInfo( NULL, &bufLen);
+	require_action( err == ERROR_BUFFER_OVERFLOW, exit, err = kUnknownErr );
+
+	pAdapterInfo = (IP_ADAPTER_INFO*) malloc( bufLen );
+	require_action( pAdapterInfo, exit, err = kNoMemoryErr );
+	
+	err = GetAdaptersInfo( pAdapterInfo, &bufLen);
+	require_noerr( err, exit );
+	
+	pAdapter	=	pAdapterInfo;
+	err			=	kUnknownErr;
+			
+	// <rdar://problem/3718122>
+	// <rdar://problem/5652098>
+	//
+	// Look for the Nortel VPN virtual interface, along with Juniper virtual interface.
+	//
+	// If these interfaces are active (i.e., has a non-zero IP Address),
+	// then we want to disable routing table modifications.
+
+	while (pAdapter)
+	{
+		if ( ( IsNortelVPN( pAdapter ) || IsJuniperVPN( pAdapter ) || IsCiscoVPN( pAdapter ) ) &&
+			 ( inet_addr( pAdapter->IpAddressList.IpAddress.String ) != 0 ) )
+		{
+			dlog( kDebugLevelTrace, DEBUG_NAME "disabling routing table management due to VPN incompatibility" );
+			goto exit;
+		}
+
+		pAdapter = pAdapter->Next;
+	}
+
+	while ( !done )
+	{
+		pAdapter	=	pAdapterInfo;
+		err			=	kUnknownErr;
+
+		while (pAdapter)
+		{
+			// If we don't have an interface selected, choose the first one that is of type ethernet and
+			// has a valid IP Address
+
+			if ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) && ( IsValidAddress( pAdapter->IpAddressList.IpAddress.String ) ) && (!(*ifIndex) || (pAdapter->Index == (*ifIndex))))
+			{
+				*address =	inet_addr( pAdapter->IpAddressList.IpAddress.String );
+				*ifIndex =  pAdapter->Index;
+				err		 =	kNoErr;
+				break;
+			}
+		
+			pAdapter = pAdapter->Next;
+		}
+
+		// If we found the right interface, or we weren't trying to find a specific interface then we're done
+
+		if ( !err || !( *ifIndex) )
+		{
+			done = mDNStrue;
+		}
+
+		// Otherwise, try again by wildcarding the interface
+
+		else
+		{
+			*ifIndex = 0;
+		}
+	} 
+
+exit:
+
+	if ( pAdapterInfo != NULL )
+	{
+		free( pAdapterInfo );
+	}
+
+	return( err );
+}
+
+
+static bool
+IsNortelVPN( IP_ADAPTER_INFO * pAdapter )
+{
+	return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
+		    (pAdapter->AddressLength == 6) &&
+		    (pAdapter->Address[0] == 0x44) &&
+		    (pAdapter->Address[1] == 0x45) &&
+		    (pAdapter->Address[2] == 0x53) &&
+		    (pAdapter->Address[3] == 0x54) &&
+		    (pAdapter->Address[4] == 0x42) &&
+			(pAdapter->Address[5] == 0x00)) ? true : false;
+}
+
+
+static bool
+IsJuniperVPN( IP_ADAPTER_INFO * pAdapter )
+{	
+	return ( strnistr( pAdapter->Description, "Juniper", sizeof( pAdapter->Description  ) ) != NULL ) ? true : false;
+}
+
+
+static bool
+IsCiscoVPN( IP_ADAPTER_INFO * pAdapter )
+{
+	return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
+		    (pAdapter->AddressLength == 6) &&
+		    (pAdapter->Address[0] == 0x00) &&
+		    (pAdapter->Address[1] == 0x05) &&
+		    (pAdapter->Address[2] == 0x9a) &&
+		    (pAdapter->Address[3] == 0x3c) &&
+		    (pAdapter->Address[4] == 0x7a) &&
+			(pAdapter->Address[5] == 0x00)) ? true : false;
+}
+
+
+static const char *
+strnistr( const char * string, const char * subString, size_t max )
+{
+	size_t       subStringLen;
+	size_t       offset;
+	size_t       maxOffset;
+	size_t       stringLen;
+	const char * pPos;
+
+	if ( ( string == NULL ) || ( subString == NULL ) )
+	{
+		return string;
+	}
+
+	stringLen = ( max > strlen( string ) ) ? strlen( string ) : max;
+
+	if ( stringLen == 0 )
+	{
+		return NULL;
+	}
+	
+	subStringLen = strlen( subString );
+
+	if ( subStringLen == 0 )
+	{
+		return string;
+	}
+
+	if ( subStringLen > stringLen )
+	{
+		return NULL;
+	}
+
+	maxOffset = stringLen - subStringLen;
+	pPos      = string;
+
+	for ( offset = 0; offset <= maxOffset; offset++ )
+	{
+		if ( _strnicmp( pPos, subString, subStringLen ) == 0 )
+		{
+			return pPos;
+		}
+
+		pPos++;
+	}
+
+	return NULL;
+}
+
diff --git a/mDNSWindows/SystemService/Service.h b/mDNSWindows/SystemService/Service.h
new file mode 100755
index 0000000..0b806f0
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef	__MDNS_SERVICE_H__
+#define	__MDNS_SERVICE_H__
+
+
+#include <windows.h>
+
+
+extern int	RunDirect( int argc, LPTSTR argv[] );
+extern int	Main( int argc, LPTSTR argv[] );
+
+
+#endif
+
diff --git a/mDNSWindows/SystemService/Service.mcp b/mDNSWindows/SystemService/Service.mcp
new file mode 100644
index 0000000..ca15566
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.mcp
Binary files differ
diff --git a/mDNSWindows/SystemService/Service.rc b/mDNSWindows/SystemService/Service.rc
new file mode 100644
index 0000000..60ad484
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.rc
@@ -0,0 +1,114 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+#include "WinVersRes.h"
+#include "EventLog.rc"
+/////////////////////////////////////////////////////////////////////////////
+#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
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MASTER_PROD_VERS
+ PRODUCTVERSION MASTER_PROD_VERS
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", MASTER_COMPANY_NAME
+            VALUE "FileDescription", "Bonjour Service"
+            VALUE "FileVersion", MASTER_PROD_VERS_STR
+            VALUE "InternalName", "mDNSResponder.exe"
+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "mDNSResponder.exe"
+            VALUE "ProductName", MASTER_PROD_NAME
+            VALUE "ProductVersion", MASTER_PROD_VERS_STR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#include ""winres.h""\r\n"
+    "#include ""WinVersRes.h""\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_SERVICE_DESCRIPTION "Enables hardware devices and software services to automatically configure themselves on the network and advertise their presence, so that users can discover and use those services without any unnecessary manual setup or administration."
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/mDNSWindows/SystemService/Service.vcproj b/mDNSWindows/SystemService/Service.vcproj
new file mode 100644
index 0000000..720f00a
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.vcproj
@@ -0,0 +1,562 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="mDNSResponder"

+	ProjectGUID="{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}"

+	RootNamespace="mDNSResponder"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;&quot;$(VCInstallDir)include&quot;;&quot;$(VCInstallDir)atlmfc\include&quot;;&quot;C:/Program Files/Microsoft SDKs/Windows/v6.1/Include&quot;"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;DEBUG=1;MDNS_DEBUGMSGS=0;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE=&quot;&quot;&quot;&quot;;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;_LEGACY_NAT_TRAVERSAL_;_USE_32BIT_TIME_T"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				DisableSpecificWarnings="4127;4201"

+				ShowIncludes="false"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib netapi32.lib powrprof.lib"

+				OutputFile="$(OutDir)/mDNSResponder.exe"

+				LinkIncremental="2"

+				IgnoreAllDefaultLibraries="false"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/mDNSResponder.pdb"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\mDNSResponder.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;&quot;$(VCInstallDir)include&quot;;&quot;$(VCInstallDir)atlmfc\include&quot;;&quot;C:/Program Files/Microsoft SDKs/Windows/v6.1/Include&quot;"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;DEBUG=1;MDNS_DEBUGMSGS=0;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE=&quot;&quot;&quot;&quot;;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;_LEGACY_NAT_TRAVERSAL_"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				DisableSpecificWarnings="4127;4201"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib netapi32.lib powrprof.lib"

+				OutputFile="$(OutDir)/mDNSResponder.exe"

+				LinkIncremental="2"

+				IgnoreAllDefaultLibraries="false"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/mDNSResponder.pdb"

+				SubSystem="1"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\mDNSResponder64.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;&quot;$(VCInstallDir)include&quot;;&quot;$(VCInstallDir)atlmfc\include&quot;;&quot;C:/Program Files/Microsoft SDKs/Windows/v6.1/Include&quot;"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE=&quot;&quot;&quot;&quot;;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;_LEGACY_NAT_TRAVERSAL_;_USE_32BIT_TIME_T"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+				DisableSpecificWarnings="4127;4201"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib netapi32.lib powrprof.lib"

+				OutputFile="$(OutDir)/mDNSResponder.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\mDNSResponder.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal&quot;                                                   mkdir &quot;$(DSTROOT)\AppleInternal&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal\bin&quot;                                            mkdir &quot;$(DSTROOT)\AppleInternal\bin&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                           &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetDir)$(TargetName).pdb&quot;                                          &quot;$(DSTROOT)\AppleInternal\bin&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="1"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;&quot;$(VCInstallDir)include&quot;;&quot;$(VCInstallDir)atlmfc\include&quot;;&quot;C:/Program Files/Microsoft SDKs/Windows/v6.1/Include&quot;"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;TARGET_OS_WIN32;WIN32_LEAN_AND_MEAN;USE_TCP_LOOPBACK;PLATFORM_NO_STRSEP;PLATFORM_NO_EPIPE;PLATFORM_NO_RLIMIT;PID_FILE=&quot;&quot;&quot;&quot;;UNICODE;_UNICODE;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1;_LEGACY_NAT_TRAVERSAL_"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				DisableSpecificWarnings="4127;4201"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="ws2_32.lib iphlpapi.lib netapi32.lib powrprof.lib"

+				OutputFile="$(OutDir)/mDNSResponder.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="res\mDNSResponder64.manifest"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal&quot;                                                   mkdir &quot;$(DSTROOT)\AppleInternal&quot;&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\AppleInternal\bin&quot;                                            mkdir &quot;$(DSTROOT)\AppleInternal\bin&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                           &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetDir)$(TargetName).pdb&quot;                                          &quot;$(DSTROOT)\AppleInternal\bin&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\DNSCommon.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\DNSDigest.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dnssd_ipc.c"

+				>

+			</File>

+			<File

+				RelativePath=".\EventLog.mc"

+				>

+				<FileConfiguration

+					Name="Debug|Win32"

+					>

+					<Tool

+						Name="VCCustomBuildTool"

+						Description="Compiling Message Resource"

+						CommandLine="mc.exe EventLog.mc"

+						Outputs="EventLog.rc EventLog.h"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Debug|x64"

+					>

+					<Tool

+						Name="VCCustomBuildTool"

+						Description="Compiling Message Resource"

+						CommandLine="mc.exe EventLog.mc"

+						Outputs="EventLog.rc EventLog.h"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32"

+					>

+					<Tool

+						Name="VCCustomBuildTool"

+						Description="Compiling Message Resource"

+						CommandLine="mc.exe EventLog.mc"

+						Outputs="EventLog.rc EventLog.h"

+					/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|x64"

+					>

+					<Tool

+						Name="VCCustomBuildTool"

+						Description="Compiling Message Resource"

+						CommandLine="mc.exe EventLog.mc"

+						Outputs="EventLog.rc EventLog.h"

+					/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="Firewall.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\GenLinkedList.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSMacOSX\LegacyNATTraversal.c"

+				>

+			</File>

+			<File

+				RelativePath=".\main.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\mDNS.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\mDNSDebug.c"

+				>

+			</File>

+			<File

+				RelativePath="..\mDNSWin32.c"

+				>

+			</File>

+			<File

+				RelativePath="..\Secret.c"

+				>

+			</File>

+			<File

+				RelativePath=".\Service.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\uDNS.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\uds_daemon.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\DNSCommon.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\dnssd_ipc.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\GenLinkedList.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\mDNSDebug.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\mDNSEmbeddedAPI.h"

+				>

+			</File>

+			<File

+				RelativePath="..\mDNSWin32.h"

+				>

+			</File>

+			<File

+				RelativePath=".\Resource.h"

+				>

+			</File>

+			<File

+				RelativePath="..\Secret.h"

+				>

+			</File>

+			<File

+				RelativePath=".\Service.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\uDNS.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\uds_daemon.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath=".\Service.rc"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/SystemService/main.c b/mDNSWindows/SystemService/main.c
new file mode 100755
index 0000000..33cce9e
--- /dev/null
+++ b/mDNSWindows/SystemService/main.c
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Service.h"
+
+
+//===========================================================================================================================
+//	main
+//===========================================================================================================================
+#if defined(UNICODE)
+int __cdecl wmain( int argc, wchar_t * argv[] )
+#else
+int	__cdecl main( int argc, char *argv[] )
+#endif
+{
+	return Main( argc, argv );
+}
+
diff --git a/mDNSWindows/SystemService/res/mDNSResponder.manifest b/mDNSWindows/SystemService/res/mDNSResponder.manifest
new file mode 100644
index 0000000..7275854
--- /dev/null
+++ b/mDNSWindows/SystemService/res/mDNSResponder.manifest
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+	<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.mDNSResponder" type="win32"/>
+	<description>Enables hardware devices and software services to automatically configure themselves and advertise their presence on the network.</description>
+	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+		<security>
+			<requestedPrivileges>
+				<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+			</requestedPrivileges>
+		</security>
+	</trustInfo>
+</assembly>
diff --git a/mDNSWindows/SystemService/res/mDNSResponder64.manifest b/mDNSWindows/SystemService/res/mDNSResponder64.manifest
new file mode 100644
index 0000000..13b3998
--- /dev/null
+++ b/mDNSWindows/SystemService/res/mDNSResponder64.manifest
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+	<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="Apple.Bonjour.ControlPanel" type="win32"/>
+	<description>Enables hardware devices and software services to automatically configure themselves and advertise their presence on the network.</description>
+	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+		<security>
+			<requestedPrivileges>
+				<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+			</requestedPrivileges>
+		</security>
+	</trustInfo>
+</assembly>
diff --git a/mDNSWindows/SystemService/resource.h b/mDNSWindows/SystemService/resource.h
new file mode 100644
index 0000000..d968af9
--- /dev/null
+++ b/mDNSWindows/SystemService/resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Service.rc
+//
+
+#define IDS_SERVICE_DESCRIPTION        100
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/mDNSWindows/SystemService/resrc1.h b/mDNSWindows/SystemService/resrc1.h
new file mode 100644
index 0000000..54a6524
--- /dev/null
+++ b/mDNSWindows/SystemService/resrc1.h
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Service.rc
+//
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
diff --git a/mDNSWindows/VPCDetect.cpp b/mDNSWindows/VPCDetect.cpp
new file mode 100755
index 0000000..3df7c14
--- /dev/null
+++ b/mDNSWindows/VPCDetect.cpp
@@ -0,0 +1,165 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _WIN32_DCOM
+#include "VPCDetect.h"
+#include "DebugServices.h"
+#include <comdef.h>
+#include <Wbemidl.h>
+
+# pragma comment(lib, "wbemuuid.lib")
+
+static BOOL g_doneCheck = FALSE;
+static BOOL g_isVPC		= FALSE;
+
+
+mStatus
+IsVPCRunning( BOOL * inVirtualPC )
+{
+	IWbemLocator			*	pLoc 		= 0;
+	IWbemServices			*	pSvc 		= 0;
+    IEnumWbemClassObject	*	pEnumerator = NULL;
+	bool						coInit 		= false;
+	HRESULT						hres;
+	SC_HANDLE					scm			= NULL;
+	SC_HANDLE					service		= NULL;
+	SERVICE_STATUS				status;
+	mStatus						err;
+	BOOL						ok          = TRUE;
+
+	// Initialize flag
+
+	*inVirtualPC = FALSE;
+
+	// Find out if WMI is running
+
+	scm = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
+	err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
+	require_noerr( err, exit );
+
+	service = OpenService( scm, TEXT( "winmgmt" ), SERVICE_QUERY_STATUS );
+	err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
+	require_noerr( err, exit );
+	
+	ok = QueryServiceStatus( service, &status );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
+	require_noerr( err, exit );
+	require_action( status.dwCurrentState == SERVICE_RUNNING, exit, err = kUnknownErr );
+	
+    // Initialize COM.
+
+	hres = CoInitializeEx(0, COINIT_MULTITHREADED);
+	require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
+	coInit = true;
+
+	// Initialize Security
+
+	hres =  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
+	require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
+
+                      
+    // Obtain the initial locator to Windows Management on a particular host computer.
+
+    hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc );
+	require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
+ 
+    // Connect to the root\cimv2 namespace with the
+    // current user and obtain pointer pSvc
+    // to make IWbemServices calls.
+
+	hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, WBEM_FLAG_CONNECT_USE_MAX_WAIT, 0, 0, &pSvc );
+	require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
+    
+    // Set the IWbemServices proxy so that impersonation
+    // of the user (client) occurs.
+
+	hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
+	require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
+
+    // Use the IWbemServices pointer to make requests of WMI. 
+    // Make requests here:
+
+	hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * from Win32_BaseBoard"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
+    
+	require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
+
+	do
+	{
+		IWbemClassObject* pInstance = NULL;
+		ULONG dwCount = NULL;
+
+		hres = pEnumerator->Next( WBEM_INFINITE, 1, &pInstance, &dwCount);
+
+		if ( pInstance )
+		{
+			VARIANT v;
+			BSTR strClassProp = SysAllocString(L"Manufacturer");
+			HRESULT hr;
+
+			hr = pInstance->Get(strClassProp, 0, &v, 0, 0);
+			SysFreeString(strClassProp);
+
+			// check the HRESULT to see if the action succeeded.
+
+			if (SUCCEEDED(hr) && (V_VT(&v) == VT_BSTR))
+			{
+				wchar_t * wstring = wcslwr( V_BSTR( &v ) );
+
+				if (wcscmp( wstring, L"microsoft corporation" ) == 0 )
+				{
+					*inVirtualPC = TRUE;
+				}
+			}
+		
+			VariantClear(&v);
+		}
+	} while (hres == WBEM_S_NO_ERROR);
+         
+exit:
+ 
+	if ( pSvc != NULL )
+	{
+    	pSvc->Release();
+	}
+
+	if ( pLoc != NULL )
+	{
+    	pLoc->Release();     
+	}
+
+	if ( coInit )
+	{
+    	CoUninitialize();
+	}
+
+	if ( service )
+	{
+		CloseServiceHandle( service );
+	}
+
+	if ( scm )
+	{
+		CloseServiceHandle( scm );
+	}
+
+	if ( *inVirtualPC )
+	{
+		dlog( kDebugLevelTrace, "Virtual PC detected" );
+	}
+
+	return err;
+}
diff --git a/mDNSWindows/VPCDetect.h b/mDNSWindows/VPCDetect.h
new file mode 100644
index 0000000..9f34bee
--- /dev/null
+++ b/mDNSWindows/VPCDetect.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <windows.h>
+#include <mDNSEmbeddedAPI.h>
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+extern mStatus
+IsVPCRunning( BOOL * inVirtualPC );
+
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/mDNSWindows/WinServices.cpp b/mDNSWindows/WinServices.cpp
new file mode 100644
index 0000000..e47c468
--- /dev/null
+++ b/mDNSWindows/WinServices.cpp
@@ -0,0 +1,93 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "WinServices.h"
+#include <DebugServices.h>
+
+
+//===========================================================================================================================
+//	UTF8StringToStringObject
+//===========================================================================================================================
+
+OSStatus	UTF8StringToStringObject( const char *inUTF8, CString &inObject )
+{
+	OSStatus		err;
+	int				n;
+	BSTR			unicode;
+	
+	unicode = NULL;
+	
+	n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, NULL, 0 );
+	if( n > 0 )
+	{
+		unicode = (BSTR) malloc( (size_t)( n * sizeof( wchar_t ) ) );
+		if( !unicode )
+		{
+			err = ERROR_INSUFFICIENT_BUFFER;
+			goto exit;
+		}
+
+		n = MultiByteToWideChar( CP_UTF8, 0, inUTF8, -1, unicode, n );
+		try
+		{
+			inObject = unicode;
+		}
+		catch( ... )
+		{
+			err = ERROR_NO_UNICODE_TRANSLATION;
+			goto exit;
+		}
+	}
+	else
+	{
+		inObject = "";
+	}
+	err = ERROR_SUCCESS;
+	
+exit:
+	if( unicode )
+	{
+		free( unicode );
+	}
+	return( err );
+}
+
+
+//===========================================================================================================================
+//	UTF8StringToStringObject
+//===========================================================================================================================
+
+OSStatus
+StringObjectToUTF8String( CString &inObject, char* outUTF8, size_t outUTF8Len )
+{
+    OSStatus err = kNoErr;
+
+	memset( outUTF8, 0, outUTF8Len );
+
+	if ( inObject.GetLength() > 0 )
+    {
+		size_t size;
+
+		size = (size_t) WideCharToMultiByte( CP_UTF8, 0, inObject.GetBuffer(), inObject.GetLength(), outUTF8, (int) outUTF8Len, NULL, NULL);
+        err = translate_errno( size != 0, GetLastError(), kUnknownErr );
+        require_noerr( err, exit );
+    }
+
+exit:
+
+	return err;
+}
diff --git a/mDNSWindows/WinServices.h b/mDNSWindows/WinServices.h
new file mode 100644
index 0000000..f650d1d
--- /dev/null
+++ b/mDNSWindows/WinServices.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#pragma once
+
+#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
+
+#include <winsock2.h>
+#include <afxsock.h>		// MFC socket extensions
+#include "CommonServices.h"
+
+
+OSStatus	UTF8StringToStringObject( const char *inUTF8, CString &outObject );
+OSStatus	StringObjectToUTF8String( CString &inObject, char* outUTF8, size_t outUTF8Len );
diff --git a/mDNSWindows/WinVersRes.h b/mDNSWindows/WinVersRes.h
new file mode 100644
index 0000000..c395aa4
--- /dev/null
+++ b/mDNSWindows/WinVersRes.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WINRESVERS_H
+#define WINRESVERS_H
+
+#define MASTER_PROD_NAME	"Bonjour"
+
+// Define the company name for mDNSResponder on Windows
+#define MASTER_COMPANY_NAME   "Apple Inc."
+
+// Define the product version for mDNSResponder on Windows
+#define MASTER_PROD_VERS		2,0,0,19
+#define MASTER_PROD_VERS_STR	"2,0,0,19"
+#define MASTER_PROD_VERS_STR2	"2.0.0.19"
+#define MASTER_PROD_VERS_STR3 "Explorer Plugin 2.0.0.19"
+
+// Define the legal copyright
+#define MASTER_LEGAL_COPYRIGHT "Copyright (C) 2003-2010 Apple Inc."
+
+#endif // WINRESVERS_H
diff --git a/mDNSWindows/isocode.h b/mDNSWindows/isocode.h
new file mode 100755
index 0000000..fe04f31
--- /dev/null
+++ b/mDNSWindows/isocode.h
@@ -0,0 +1,135 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* isocode.h                                                             */
+/* ----------------------------------------------------------------------*/
+/* THIS FILE HAS BEEN AUTO-GENERATED.  DO NOT EDIT DIRECTLY              */
+/* If a language needs to be added, edit isocode.txt, and run isocode.pl */
+/* to generate a new version of this file                                */
+/* ----------------------------------------------------------------------*/
+/* ----------------------------------------------------------------------*/
+
+
+unsigned char ISOCODES[] = {
+12, 9, 'e','n', 0 , 0 , 0 , 0 ,
+40, 9, 'e','n', 0 , 0 , 0 , 0 ,
+16, 9, 'e','n', 0 , 0 , 0 , 0 ,
+36, 9, 'e','n', 0 , 0 , 0 , 0 ,
+24, 9, 'e','n', 0 , 0 , 0 , 0 ,
+32, 9, 'e','n', 0 , 0 , 0 , 0 ,
+20, 9, 'e','n', 0 , 0 , 0 , 0 ,
+52, 9, 'e','n', 0 , 0 , 0 , 0 ,
+28, 9, 'e','n', 0 , 0 , 0 , 0 ,
+44, 9, 'e','n', 0 , 0 , 0 , 0 ,
+8, 9, 'e','n', 0 , 0 , 0 , 0 ,
+4, 9, 'e','n', 0 , 0 , 0 , 0 ,
+48, 9, 'e','n', 0 , 0 , 0 , 0 ,
+8, 12, 'f','r', 0 , 0 , 0 , 0 ,
+44, 12, 'f','r', 0 , 0 , 0 , 0 ,
+12, 12, 'f','r', 0 , 0 , 0 , 0 ,
+36, 12, 'f','r', 0 , 0 , 0 , 0 ,
+48, 12, 'f','r', 0 , 0 , 0 , 0 ,
+4, 12, 'f','r', 0 , 0 , 0 , 0 ,
+20, 12, 'f','r', 0 , 0 , 0 , 0 ,
+52, 12, 'f','r', 0 , 0 , 0 , 0 ,
+24, 12, 'f','r', 0 , 0 , 0 , 0 ,
+40, 12, 'f','r', 0 , 0 , 0 , 0 ,
+16, 12, 'f','r', 0 , 0 , 0 , 0 ,
+28, 12, 'f','r', 0 , 0 , 0 , 0 ,
+4, 98, 'f','r', 0 , 0 , 0 , 0 ,
+12, 7, 'd','e', 0 , 0 , 0 , 0 ,
+4, 7, 'd','e', 0 , 0 , 0 , 0 ,
+20, 7, 'd','e', 0 , 0 , 0 , 0 ,
+16, 7, 'd','e', 0 , 0 , 0 , 0 ,
+8, 7, 'd','e', 0 , 0 , 0 , 0 ,
+4, 17, 'j','a', 0 , 0 , 0 , 0 ,
+8, 19, 'n','l', 0 , 0 , 0 , 0 ,
+4, 19, 'n','l', 0 , 0 , 0 , 0 ,
+4, 16, 'i','t', 0 , 0 , 0 , 0 ,
+8, 16, 'i','t', 0 , 0 , 0 , 0 ,
+44, 10, 'e','s', 0 , 0 , 0 , 0 ,
+64, 10, 'e','s', 0 , 0 , 0 , 0 ,
+52, 10, 'e','s', 0 , 0 , 0 , 0 ,
+36, 10, 'e','s', 0 , 0 , 0 , 0 ,
+20, 10, 'e','s', 0 , 0 , 0 , 0 ,
+28, 10, 'e','s', 0 , 0 , 0 , 0 ,
+48, 10, 'e','s', 0 , 0 , 0 , 0 ,
+68, 10, 'e','s', 0 , 0 , 0 , 0 ,
+16, 10, 'e','s', 0 , 0 , 0 , 0 ,
+72, 10, 'e','s', 0 , 0 , 0 , 0 ,
+12, 10, 'e','s', 0 , 0 , 0 , 0 ,
+8, 10, 'e','s', 0 , 0 , 0 , 0 ,
+76, 10, 'e','s', 0 , 0 , 0 , 0 ,
+24, 10, 'e','s', 0 , 0 , 0 , 0 ,
+60, 10, 'e','s', 0 , 0 , 0 , 0 ,
+40, 10, 'e','s', 0 , 0 , 0 , 0 ,
+80, 10, 'e','s', 0 , 0 , 0 , 0 ,
+4, 10, 'e','s', 0 , 0 , 0 , 0 ,
+56, 10, 'e','s', 0 , 0 , 0 , 0 ,
+32, 10, 'e','s', 0 , 0 , 0 , 0 ,
+8, 4, 'z','h','_','C','N', 0 ,
+16, 4, 'z','h','_','C','N', 0 ,
+12, 4, 'z','h','_','T','W', 0 ,
+20, 4, 'z','h','_','T','W', 0 ,
+4, 4, 'z','h','_','T','W', 0 ,
+4, 6, 'd','a', 0 , 0 , 0 , 0 ,
+4, 11, 'f','i', 0 , 0 , 0 , 0 ,
+4, 18, 'k','o', 0 , 0 , 0 , 0 ,
+4, 20, 'n','b', 0 , 0 , 0 , 0 ,
+8, 20, 'n','b', 0 , 0 , 0 , 0 ,
+4, 22, 'p','t', 0 , 0 , 0 , 0 ,
+4, 29, 's','v', 0 , 0 , 0 , 0 ,
+8, 29, 's','v', 0 , 0 , 0 , 0 ,
+20, 1, 'a','r', 0 , 0 , 0 , 0 ,
+60, 1, 'a','r', 0 , 0 , 0 , 0 ,
+12, 1, 'a','r', 0 , 0 , 0 , 0 ,
+8, 1, 'a','r', 0 , 0 , 0 , 0 ,
+44, 1, 'a','r', 0 , 0 , 0 , 0 ,
+52, 1, 'a','r', 0 , 0 , 0 , 0 ,
+48, 1, 'a','r', 0 , 0 , 0 , 0 ,
+16, 1, 'a','r', 0 , 0 , 0 , 0 ,
+24, 1, 'a','r', 0 , 0 , 0 , 0 ,
+32, 1, 'a','r', 0 , 0 , 0 , 0 ,
+64, 1, 'a','r', 0 , 0 , 0 , 0 ,
+4, 1, 'a','r', 0 , 0 , 0 , 0 ,
+40, 1, 'a','r', 0 , 0 , 0 , 0 ,
+28, 1, 'a','r', 0 , 0 , 0 , 0 ,
+56, 1, 'a','r', 0 , 0 , 0 , 0 ,
+36, 1, 'a','r', 0 , 0 , 0 , 0 ,
+4, 2, 'b','g', 0 , 0 , 0 , 0 ,
+4, 26, 'h','r', 0 , 0 , 0 , 0 ,
+4, 5, 'c','s', 0 , 0 , 0 , 0 ,
+4, 8, 'e','l', 0 , 0 , 0 , 0 ,
+4, 13, 'i','w', 0 , 0 , 0 , 0 ,
+4, 14, 'h','u', 0 , 0 , 0 , 0 ,
+4, 15, 'i','s', 0 , 0 , 0 , 0 ,
+4, 21, 'p','l', 0 , 0 , 0 , 0 ,
+8, 22, 'p','t','_','P','T', 0 ,
+4, 24, 'r','o', 0 , 0 , 0 , 0 ,
+8, 24, 'r','o', 0 , 0 , 0 , 0 ,
+4, 25, 'r','u', 0 , 0 , 0 , 0 ,
+8, 25, 'r','u', 0 , 0 , 0 , 0 ,
+4, 30, 't','h', 0 , 0 , 0 , 0 ,
+4, 31, 't','r', 0 , 0 , 0 , 0 ,
+4, 34, 'u','k', 0 , 0 , 0 , 0 ,
+};
+
+#define NUM_ISOCODES      101
+#define LANG_CODE_LEN     5
+#define MODULO_ISOCODES   8
+
+
diff --git a/mDNSWindows/loclibrary.c b/mDNSWindows/loclibrary.c
new file mode 100755
index 0000000..9744120
--- /dev/null
+++ b/mDNSWindows/loclibrary.c
@@ -0,0 +1,268 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+/* loclibrary.c                                                          
+ * ----------------------------------------------------------------------
+ * Source for localization library                                       
+ * Originally created by jsantamaria: 3 may 2004                         
+ * ----------------------------------------------------------------------
+ */
+ 
+#include "DebugServices.h"
+#include <windows.h>
+#include <stdio.h>
+#include "isocode.h"
+#include "loclibrary.h"
+#include "Shlwapi.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <wchar.h>
+
+
+#ifdef __cplusplus
+extern "c" {
+#endif
+
+#ifdef _MSC_VER
+#define swprintf _snwprintf
+#define snprintf _snprintf
+#endif
+
+
+
+#define DEFAULT_LANG_CODE "en"
+
+// gets the user language
+static LANGID _getUserLanguage( void ) {
+	
+	return GetUserDefaultUILanguage();
+
+}
+
+
+// gets the ISO mapping
+static int _getISOCode(LANGID wLangID, char *isoLangCode, int codeLen) {
+	int i;
+	unsigned short langCode;
+
+	for (i = 0; i < NUM_ISOCODES; i++) {
+		int startIndex = i * MODULO_ISOCODES;
+		
+		langCode = (ISOCODES[startIndex] << 8);
+		langCode = langCode + ( (unsigned short) (ISOCODES[startIndex + 1]) );
+
+		if (langCode == wLangID) {
+			char *langStr = (char *)&(ISOCODES[startIndex+2]);
+			strncpy(isoLangCode, langStr, codeLen);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static char isoLangCode[LANG_CODE_LEN + 1] = "";
+static LANGID wLangID = (LANGID) -1;
+
+static void _setLanguageIfNeeded(void) {
+	
+	// get the language code if we don't have it cached
+	if (!strncmp(isoLangCode,"",LANG_CODE_LEN + 1)) {
+		
+		// if we haven't cached the language id, do the lookup
+		if (wLangID == (LANGID) -1) {
+			wLangID = _getUserLanguage();
+		}
+		
+		// if no ISOCode, set it to DEFAULT_LANG_CODE
+		if (_getISOCode(wLangID, isoLangCode, LANG_CODE_LEN + 1)) {
+			strncpy(isoLangCode, DEFAULT_LANG_CODE, LANG_CODE_LEN+1);
+		}
+	}
+
+}
+
+//// PathForResource
+
+// Gets the PathForResource for handle 0 for the current process
+
+
+static char appPathNameA[MAX_PATH] = "";
+
+int PathForResourceA ( HMODULE module, const char *name, char *locFile, int locFileLen)
+{
+	int ret = 0;
+
+	if ( !strcmp( appPathNameA, "" ) )
+	{
+		char   folder[MAX_PATH];
+		char * ext;
+		char * app;
+
+		GetModuleFileNameA( module, folder, MAX_PATH );
+
+		// Get folder string
+		
+		app = strrchr( folder, '\\' );
+		require_action( app, exit, ret = 0 );
+		*app++ = '\0';
+
+		// Strip the extension
+
+		if ( ( ( ext = strstr( app, ".exe" ) ) != NULL ) || ( ( ext = strstr( app, ".dll" ) ) != NULL ) )
+		{
+			*ext = '\0';
+		}
+
+		snprintf( appPathNameA, MAX_PATH, "%s\\%s", folder, app );
+	}
+
+	ret = PathForResourceWithPathA (appPathNameA, name, locFile, locFileLen);
+
+exit:
+
+	return ret;
+}
+
+static wchar_t appPathNameW[MAX_PATH] = L"";
+
+int PathForResourceW ( HMODULE module, const wchar_t *name, wchar_t *locFile, int locFileLen)
+{
+	int ret = 0;
+
+	if ( !wcscmp( appPathNameW, L"" ) )
+	{
+		wchar_t   folder[MAX_PATH];
+		wchar_t * app;
+		wchar_t * ext;
+
+		GetModuleFileNameW( module, folder, MAX_PATH);
+
+		// Get folder string
+		
+		app = wcsrchr( folder, '\\' );
+		require_action( app, exit, ret = 0 );
+		*app++ = '\0';
+
+		// Strip the extension
+
+		if ( ( ( ext = wcsstr( app, L".exe" ) ) != NULL ) || ( ( ext = wcsstr( app, L".dll" ) ) != NULL ) )
+		{
+			*ext = '\0';
+		}
+
+		swprintf( appPathNameW, MAX_PATH, L"%ls\\%ls", folder, app );
+	}
+
+	ret = PathForResourceWithPathW (appPathNameW, name, locFile, locFileLen);
+
+exit:
+
+	return ret;
+}
+
+
+//// PathForResourceWithPath
+
+#define TMP_BUF_SIZE MAX_PATH
+
+int PathForResourceWithPathA (const char *path, const char *nm, 
+									char *locFile, int locFileLen) {
+	char tmpBuffer[TMP_BUF_SIZE];
+
+	// build the path to the executable in the generic 
+	// resources folder, check there first
+	snprintf(tmpBuffer, MAX_PATH, "%s.Resources\\%s", path, nm);
+
+	if (!PathFileExistsA(tmpBuffer)) {
+
+		// didn't hit generic resource folder, so need to get language codes
+		_setLanguageIfNeeded();
+
+		// test to see if localized directory exists, 
+		// if so, we don't fall back if we don't find the file.
+		snprintf(tmpBuffer, TMP_BUF_SIZE, 
+				 "%s.Resources\\%s.lproj", path, isoLangCode);
+
+		if (PathFileExistsA(tmpBuffer)) {
+			snprintf(tmpBuffer, TMP_BUF_SIZE, "%s\\%s", tmpBuffer, nm);
+
+			if (!PathFileExistsA(tmpBuffer)) return 0;
+
+			strncpy(locFile, tmpBuffer, locFileLen);
+			return (int) strlen(locFile);
+		}
+
+		// fall back on DEFAULT_LANG_CODE if still no good
+		snprintf(tmpBuffer, TMP_BUF_SIZE, "%s.Resources\\%s.lproj\\%s", 
+				path, DEFAULT_LANG_CODE, nm);
+				
+		// we can't find the resource, so return 0
+		if (!PathFileExistsA(tmpBuffer)) return 0;
+	}
+	
+	strncpy(locFile, tmpBuffer, locFileLen);
+	return (int) strlen(locFile);
+
+}
+
+
+int PathForResourceWithPathW (const wchar_t *path, const wchar_t *nm, 
+								wchar_t *locFile, int locFileLen) {
+
+	wchar_t tmpBuffer[TMP_BUF_SIZE];
+
+	// build the path to the executable in the generic
+	// resources folder, check there first
+	swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%ls", path, nm);
+
+	if (!PathFileExistsW(tmpBuffer)) {
+		// didn't hit generic resource folder, so need to get language codes
+		_setLanguageIfNeeded();
+
+		// test to see if localized directory exists, 
+		// if so, we don't fall back if we don't find the file.
+		swprintf(tmpBuffer, TMP_BUF_SIZE, 
+				  L"%ls.Resources\\%S.lproj", path, isoLangCode);
+
+		if (PathFileExistsW(tmpBuffer)) {
+			swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls\\%ls", tmpBuffer, nm);
+
+			if (!PathFileExistsW(tmpBuffer)) return 0;
+
+			wcsncpy(locFile, tmpBuffer, locFileLen);
+			return (int) wcslen(locFile);
+		}
+
+		// fall back on DEFAULT_LANG_CODE if still no good
+		swprintf(tmpBuffer, TMP_BUF_SIZE, L"%ls.Resources\\%S.lproj\\%ls", 
+			path, DEFAULT_LANG_CODE, nm);
+
+		// we can't find the resource, so return 0
+		if (!PathFileExistsW(tmpBuffer)) return 0;
+	}
+	
+	wcsncpy(locFile, tmpBuffer, locFileLen);
+	return (int) wcslen(locFile);
+
+
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/mDNSWindows/loclibrary.h b/mDNSWindows/loclibrary.h
new file mode 100755
index 0000000..0a9b7ce
--- /dev/null
+++ b/mDNSWindows/loclibrary.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+    
+/* loclibrary.h                                                      
+ * ----------------------------------------------------------------------
+ * Header file for localization library                                       
+ * Originally created by jsantamaria: 3 may 2004                         
+ * ----------------------------------------------------------------------
+ */
+ 
+#ifndef _loclibrary_h_
+#define _loclibrary_h_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+int PathForResourceW ( HMODULE module, const wchar_t *name, wchar_t *locFile, int locFileLen);
+int PathForResourceWithPathW ( const wchar_t *path, const wchar_t *name, wchar_t *locFile, int locFileLen);
+
+int PathForResourceA ( HMODULE module, const char *name, char *locFile, int locFileLen);
+int PathForResourceWithPathA ( const char *path, const char *name, char *locFile, int locFileLen);
+
+
+#ifdef UNICODE
+#define PathForResource PathForResourceW
+#define PathForResourceWithPath PathForResourceWithPathW
+#else
+#define PathForResource PathForResourceA
+#define PathForResourceWithPath PathForResourceWithPathA
+#endif // UNICODE
+
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+
+#endif // _loclibrary_h_
diff --git a/mDNSWindows/mDNSWin32.c b/mDNSWindows/mDNSWin32.c
new file mode 100755
index 0000000..0dcc121
--- /dev/null
+++ b/mDNSWindows/mDNSWin32.c
@@ -0,0 +1,5200 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+
+	To Do:
+	
+	- Get unicode name of machine for nice name instead of just the host name.
+	- Use the IPv6 Internet Connection Firewall API to allow IPv6 mDNS without manually changing the firewall.
+	- Get DNS server address(es) from Windows and provide them to the uDNS layer.
+	- Implement TCP support for truncated packets (only stubs now).	
+
+*/
+
+#include	<stdarg.h>
+#include	<stddef.h>
+#include	<stdio.h>
+#include	<stdlib.h>
+#include	<crtdbg.h>
+#include	<string.h>
+
+#include	"CommonServices.h"
+#include	"DebugServices.h"
+#include	"Firewall.h"
+#include	"RegNames.h"
+#include	"Secret.h"
+#include	<dns_sd.h>
+
+#include	<Iphlpapi.h>
+#include	<mswsock.h>
+#include	<process.h>
+#include	<ntsecapi.h>
+#include	<lm.h>
+#include	<winioctl.h>
+#include	<ntddndis.h>        // This defines the IOCTL constants.
+
+#include	"mDNSEmbeddedAPI.h"
+#include	"GenLinkedList.h"
+#include	"DNSCommon.h"
+#include	"mDNSWin32.h"
+
+#if 0
+#pragma mark == Constants ==
+#endif
+
+//===========================================================================================================================
+//	Constants
+//===========================================================================================================================
+
+#define	DEBUG_NAME									"[mDNSWin32] "
+
+#define	MDNS_WINDOWS_USE_IPV6_IF_ADDRS				1
+#define	MDNS_WINDOWS_ENABLE_IPV4					1
+#define	MDNS_WINDOWS_ENABLE_IPV6					1
+#define	MDNS_FIX_IPHLPAPI_PREFIX_BUG				1
+#define MDNS_SET_HINFO_STRINGS						0
+
+#define	kMDNSDefaultName							"My Computer"
+
+#define	kWinSockMajorMin							2
+#define	kWinSockMinorMin							2
+
+#define kRegistryMaxKeyLength						255
+#define kRegistryMaxValueName						16383
+
+static GUID											kWSARecvMsgGUID = WSAID_WSARECVMSG;
+
+#define kIPv6IfIndexBase							(10000000L)
+#define SMBPortAsNumber								445
+#define DEVICE_PREFIX								"\\\\.\\"
+
+#if 0
+#pragma mark == Prototypes ==
+#endif
+
+//===========================================================================================================================
+//	Prototypes
+//===========================================================================================================================
+
+mDNSlocal mStatus			SetupNiceName( mDNS * const inMDNS );
+mDNSlocal mStatus			SetupHostName( mDNS * const inMDNS );
+mDNSlocal mStatus			SetupName( mDNS * const inMDNS );
+mDNSlocal mStatus			SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inIFA, mDNSInterfaceData **outIFD );
+mDNSlocal mStatus			TearDownInterface( mDNS * const inMDNS, mDNSInterfaceData *inIFD );
+mDNSlocal void CALLBACK		FreeInterface( mDNSInterfaceData *inIFD );
+mDNSlocal mStatus			SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAddr, mDNSIPPort port, SocketRef *outSocketRef  );
+mDNSlocal mStatus			SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort );
+mDNSlocal OSStatus			GetWindowsVersionString( char *inBuffer, size_t inBufferSize );
+mDNSlocal int				getifaddrs( struct ifaddrs **outAddrs );
+mDNSlocal void				freeifaddrs( struct ifaddrs *inAddrs );
+
+
+
+// Platform Accessors
+
+#ifdef	__cplusplus
+	extern "C" {
+#endif
+
+typedef struct mDNSPlatformInterfaceInfo	mDNSPlatformInterfaceInfo;
+struct	mDNSPlatformInterfaceInfo
+{
+	const char *		name;
+	mDNSAddr			ip;
+};
+
+
+mDNSexport mStatus	mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID );
+mDNSexport mStatus	mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo );
+
+// Utilities
+
+#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
+	mDNSlocal int	getifaddrs_ipv6( struct ifaddrs **outAddrs );
+#endif
+
+mDNSlocal int getifaddrs_ipv4( struct ifaddrs **outAddrs );
+
+
+mDNSlocal DWORD				GetPrimaryInterface();
+mDNSlocal mStatus			AddressToIndexAndMask( struct sockaddr * address, uint32_t * index, struct sockaddr * mask );
+mDNSlocal mDNSBool			CanReceiveUnicast( void );
+mDNSlocal mDNSBool			IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr );
+
+mDNSlocal mStatus			StringToAddress( mDNSAddr * ip, LPSTR string );
+mDNSlocal mStatus			RegQueryString( HKEY key, LPCSTR param, LPSTR * string, DWORD * stringLen, DWORD * enabled );
+mDNSlocal struct ifaddrs*	myGetIfAddrs(int refresh);
+mDNSlocal OSStatus			TCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize );
+mDNSlocal OSStatus			WindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize );
+mDNSlocal void				TCPDidConnect( mDNS * const inMDNS, HANDLE event, void * context );
+mDNSlocal void				TCPCanRead( TCPSocket * sock );
+mDNSlocal mStatus			TCPBeginRecv( TCPSocket * sock );
+mDNSlocal void CALLBACK		TCPEndRecv( DWORD error, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags );
+mDNSlocal void				TCPCloseSocket( TCPSocket * socket );
+mDNSlocal void CALLBACK		TCPFreeSocket( TCPSocket *sock );
+mDNSlocal OSStatus			UDPBeginRecv( UDPSocket * socket );
+mDNSlocal void CALLBACK		UDPEndRecv( DWORD err, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags );
+mDNSlocal void				UDPCloseSocket( UDPSocket * sock );
+mDNSlocal void CALLBACK		UDPFreeSocket( UDPSocket * sock );
+mDNSlocal mStatus           SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa);
+mDNSlocal void				GetDDNSFQDN( domainname *const fqdn );
+#ifdef UNICODE
+mDNSlocal void				GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey );
+#else
+mDNSlocal void				GetDDNSDomains( DNameListElem ** domains, LPCSTR lpSubKey );
+#endif
+mDNSlocal void				SetDomainSecrets( mDNS * const inMDNS );
+mDNSlocal void				SetDomainSecret( mDNS * const m, const domainname * inDomain );
+mDNSlocal VOID CALLBACK		CheckFileSharesProc( LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue );
+mDNSlocal void				CheckFileShares( mDNS * const inMDNS );
+mDNSlocal void				SMBCallback(mDNS *const m, ServiceRecordSet *const srs, mStatus result);
+mDNSlocal mDNSu8			IsWOMPEnabledForAdapter( const char * adapterName );
+mDNSlocal void				DispatchUDPEvent( mDNS * const m, UDPSocket * sock );
+mDNSlocal void				DispatchTCPEvent( mDNS * const m, TCPSocket * sock );
+
+#ifdef	__cplusplus
+	}
+#endif
+
+#if 0
+#pragma mark == Globals ==
+#endif
+
+//===========================================================================================================================
+//	Globals
+//===========================================================================================================================
+
+mDNSlocal mDNS_PlatformSupport	gMDNSPlatformSupport;
+mDNSs32							mDNSPlatformOneSecond	= 0;
+mDNSlocal UDPSocket		*		gUDPSockets				= NULL;
+mDNSlocal int					gUDPNumSockets			= 0;
+mDNSlocal GenLinkedList			gUDPDispatchableSockets;
+mDNSlocal GenLinkedList			gTCPDispatchableSockets;
+
+#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
+
+	typedef DWORD
+		( WINAPI * GetAdaptersAddressesFunctionPtr )( 
+			ULONG 					inFamily, 
+			DWORD 					inFlags, 
+			PVOID 					inReserved, 
+			PIP_ADAPTER_ADDRESSES 	inAdapter, 
+			PULONG					outBufferSize );
+
+	mDNSlocal HMODULE								gIPHelperLibraryInstance			= NULL;
+	mDNSlocal GetAdaptersAddressesFunctionPtr		gGetAdaptersAddressesFunctionPtr	= NULL;
+
+#endif
+
+
+#ifndef HCRYPTPROV
+   typedef ULONG_PTR HCRYPTPROV;    // WinCrypt.h, line 249
+#endif
+
+
+#ifndef CRYPT_MACHINE_KEYSET
+#	define CRYPT_MACHINE_KEYSET    0x00000020
+#endif
+
+#ifndef CRYPT_NEWKEYSET
+#	define CRYPT_NEWKEYSET         0x00000008
+#endif
+
+#ifndef PROV_RSA_FULL
+#  define PROV_RSA_FULL 1
+#endif
+
+typedef BOOL (__stdcall *fnCryptGenRandom)( HCRYPTPROV, DWORD, BYTE* ); 
+typedef BOOL (__stdcall *fnCryptAcquireContext)( HCRYPTPROV*, LPCTSTR, LPCTSTR, DWORD, DWORD);
+typedef BOOL (__stdcall *fnCryptReleaseContext)(HCRYPTPROV, DWORD);
+
+static fnCryptAcquireContext g_lpCryptAcquireContext 	= NULL;
+static fnCryptReleaseContext g_lpCryptReleaseContext 	= NULL;
+static fnCryptGenRandom		 g_lpCryptGenRandom 		= NULL;
+static HINSTANCE			 g_hAAPI32 					= NULL;
+static HCRYPTPROV			 g_hProvider 				= ( ULONG_PTR ) NULL;
+
+
+typedef DNSServiceErrorType ( DNSSD_API *DNSServiceRegisterFunc )
+    (
+    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 */
+    );
+
+
+typedef void ( DNSSD_API *DNSServiceRefDeallocateFunc )( DNSServiceRef sdRef );
+
+mDNSlocal HMODULE					gDNSSDLibrary				= NULL;
+mDNSlocal DNSServiceRegisterFunc	gDNSServiceRegister			= NULL;
+mDNSlocal DNSServiceRefDeallocateFunc gDNSServiceRefDeallocate	= NULL;
+mDNSlocal HANDLE					gSMBThread					= NULL;
+mDNSlocal HANDLE					gSMBThreadRegisterEvent		= NULL;
+mDNSlocal HANDLE					gSMBThreadDeregisterEvent	= NULL;
+mDNSlocal HANDLE					gSMBThreadStopEvent			= NULL;
+mDNSlocal HANDLE					gSMBThreadQuitEvent			= NULL;
+
+#define	kSMBStopEvent				( WAIT_OBJECT_0 + 0 )
+#define	kSMBRegisterEvent			( WAIT_OBJECT_0 + 1 )
+#define kSMBDeregisterEvent			( WAIT_OBJECT_0 + 2 )
+
+
+#if 0
+#pragma mark -
+#pragma mark == Platform Support ==
+#endif
+
+//===========================================================================================================================
+//	mDNSPlatformInit
+//===========================================================================================================================
+
+mDNSexport mStatus	mDNSPlatformInit( mDNS * const inMDNS )
+{
+	mStatus		err;
+	WSADATA		wsaData;
+	int			supported;
+	struct sockaddr_in	sa4;
+	struct sockaddr_in6 sa6;
+	int					sa4len;
+	int					sa6len;
+	DWORD				size;
+	DWORD				val;
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "platform init\n" );
+	
+	// Initialize variables. If the PlatformSupport pointer is not null then just assume that a non-Apple client is 
+	// calling mDNS_Init and wants to provide its own storage for the platform-specific data so do not overwrite it.
+	
+	mDNSPlatformMemZero( &gMDNSPlatformSupport, sizeof( gMDNSPlatformSupport ) );
+	if( !inMDNS->p ) inMDNS->p				= &gMDNSPlatformSupport;
+	inMDNS->p->mainThread					= OpenThread( THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId() );
+	require_action( inMDNS->p->mainThread, exit, err = mStatus_UnknownErr );
+	inMDNS->p->checkFileSharesTimer = CreateWaitableTimer( NULL, FALSE, NULL );
+	require_action( inMDNS->p->checkFileSharesTimer, exit, err = mStatus_UnknownErr );
+	inMDNS->p->checkFileSharesTimeout		= 10;		// Retry time for CheckFileShares() in seconds
+	mDNSPlatformOneSecond 					= 1000;		// Use milliseconds as the quantum of time
+	InitLinkedList( &gTCPDispatchableSockets, offsetof( TCPSocket, nextDispatchable ) );
+	InitLinkedList( &gUDPDispatchableSockets, offsetof( UDPSocket, nextDispatchable ) );
+	
+	// Startup WinSock 2.2 or later.
+	
+	err = WSAStartup( MAKEWORD( kWinSockMajorMin, kWinSockMinorMin ), &wsaData );
+	require_noerr( err, exit );
+	
+	supported = ( ( LOBYTE( wsaData.wVersion ) == kWinSockMajorMin ) && ( HIBYTE( wsaData.wVersion ) == kWinSockMinorMin ) );
+	require_action( supported, exit, err = mStatus_UnsupportedErr );
+	
+	inMDNS->CanReceiveUnicastOn5353 = CanReceiveUnicast();
+	
+	// Setup the HINFO HW strings.
+	//<rdar://problem/7245119> device-info should have model=Windows
+
+	strcpy_s( ( char* ) &inMDNS->HIHardware.c[ 1 ], sizeof( inMDNS->HIHardware.c ) - 2, "Windows" );
+	inMDNS->HIHardware.c[ 0 ] = ( mDNSu8 ) mDNSPlatformStrLen( &inMDNS->HIHardware.c[ 1 ] );
+	dlog( kDebugLevelInfo, DEBUG_NAME "HIHardware: %#s\n", inMDNS->HIHardware.c );
+
+	// Setup the HINFO SW strings.
+#if ( MDNS_SET_HINFO_STRINGS )
+	mDNS_snprintf( (char *) &inMDNS->HISoftware.c[ 1 ], sizeof( inMDNS->HISoftware.c ) - 2, 
+		"mDNSResponder (%s %s)", __DATE__, __TIME__ );
+	inMDNS->HISoftware.c[ 0 ] = (mDNSu8) mDNSPlatformStrLen( &inMDNS->HISoftware.c[ 1 ] );
+	dlog( kDebugLevelInfo, DEBUG_NAME "HISoftware: %#s\n", inMDNS->HISoftware.c );
+#endif
+
+	// Set the thread global overlapped flag
+
+	val = 0;
+	err = setsockopt( INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, ( char* ) &val, sizeof( val ) );
+	err = translate_errno( err != SOCKET_ERROR, WSAGetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	// Set up the IPv4 unicast socket
+
+	inMDNS->p->unicastSock4.fd			= INVALID_SOCKET;
+	inMDNS->p->unicastSock4.recvMsgPtr	= NULL;
+	inMDNS->p->unicastSock4.ifd			= NULL;
+	inMDNS->p->unicastSock4.overlapped.pending = FALSE;
+	inMDNS->p->unicastSock4.next		= NULL;
+	inMDNS->p->unicastSock4.m			= inMDNS;
+
+#if ( MDNS_WINDOWS_ENABLE_IPV4 )
+
+	sa4.sin_family		= AF_INET;
+	sa4.sin_addr.s_addr = INADDR_ANY;
+	err = SetupSocket( inMDNS, (const struct sockaddr*) &sa4, zeroIPPort, &inMDNS->p->unicastSock4.fd );
+	check_noerr( err );
+	sa4len = sizeof( sa4 );
+	err = getsockname( inMDNS->p->unicastSock4.fd, (struct sockaddr*) &sa4, &sa4len );
+	require_noerr( err, exit );
+	inMDNS->p->unicastSock4.port.NotAnInteger = sa4.sin_port;
+	inMDNS->UnicastPort4 = inMDNS->p->unicastSock4.port;
+	err = WSAIoctl( inMDNS->p->unicastSock4.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &inMDNS->p->unicastSock4.recvMsgPtr, sizeof( inMDNS->p->unicastSock4.recvMsgPtr ), &size, NULL, NULL );
+		
+	if ( err )
+	{
+		inMDNS->p->unicastSock4.recvMsgPtr = NULL;
+	}
+
+	err = UDPBeginRecv( &inMDNS->p->unicastSock4 );
+	require_noerr( err, exit ); 
+
+#endif
+
+	// Set up the IPv6 unicast socket
+
+	inMDNS->p->unicastSock6.fd			= INVALID_SOCKET;
+	inMDNS->p->unicastSock6.recvMsgPtr	= NULL;
+	inMDNS->p->unicastSock6.ifd			= NULL;
+	inMDNS->p->unicastSock6.overlapped.pending = FALSE;
+	inMDNS->p->unicastSock6.next		= NULL;
+	inMDNS->p->unicastSock6.m			= inMDNS;
+
+#if ( MDNS_WINDOWS_ENABLE_IPV6 )
+
+	sa6.sin6_family		= AF_INET6;
+	sa6.sin6_addr		= in6addr_any;
+	sa6.sin6_scope_id	= 0;
+
+	// This call will fail if the machine hasn't installed IPv6.  In that case,
+	// the error will be WSAEAFNOSUPPORT.
+
+	err = SetupSocket( inMDNS, (const struct sockaddr*) &sa6, zeroIPPort, &inMDNS->p->unicastSock6.fd );
+	require_action( !err || ( err == WSAEAFNOSUPPORT ), exit, err = (mStatus) WSAGetLastError() );
+	err = kNoErr;
+	
+	// If we weren't able to create the socket (because IPv6 hasn't been installed) don't do this
+
+	if ( inMDNS->p->unicastSock6.fd != INVALID_SOCKET )
+	{
+		sa6len = sizeof( sa6 );
+		err = getsockname( inMDNS->p->unicastSock6.fd, (struct sockaddr*) &sa6, &sa6len );
+		require_noerr( err, exit );
+		inMDNS->p->unicastSock6.port.NotAnInteger = sa6.sin6_port;
+		inMDNS->UnicastPort6 = inMDNS->p->unicastSock6.port;
+
+		err = WSAIoctl( inMDNS->p->unicastSock6.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &inMDNS->p->unicastSock6.recvMsgPtr, sizeof( inMDNS->p->unicastSock6.recvMsgPtr ), &size, NULL, NULL );
+		
+		if ( err != 0 )
+		{
+			inMDNS->p->unicastSock6.recvMsgPtr = NULL;
+		}
+
+		err = UDPBeginRecv( &inMDNS->p->unicastSock6 );
+		require_noerr( err, exit );
+	} 
+
+#endif
+
+	// Notify core of domain secret keys
+
+	SetDomainSecrets( inMDNS );
+	
+	// Success!
+
+	mDNSCoreInitComplete( inMDNS, err );
+
+	
+exit:
+
+	if ( err )
+	{
+		mDNSPlatformClose( inMDNS );
+	}
+
+	dlog( kDebugLevelTrace, DEBUG_NAME "platform init done (err=%d %m)\n", err, err );
+	return( err );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformClose
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformClose( mDNS * const inMDNS )
+{
+	mStatus		err;
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "platform close\n" );
+	check( inMDNS );
+
+	if ( gSMBThread != NULL )
+	{
+		dlog( kDebugLevelTrace, DEBUG_NAME "tearing down smb registration thread\n" );
+		SetEvent( gSMBThreadStopEvent );
+		
+		if ( WaitForSingleObject( gSMBThreadQuitEvent, 5 * 1000 ) == WAIT_OBJECT_0 )
+		{
+			if ( gSMBThreadQuitEvent )
+			{
+				CloseHandle( gSMBThreadQuitEvent );
+				gSMBThreadQuitEvent = NULL;
+			}
+
+			if ( gSMBThreadStopEvent )
+			{
+				CloseHandle( gSMBThreadStopEvent );
+				gSMBThreadStopEvent = NULL;
+			}
+
+			if ( gSMBThreadDeregisterEvent )
+			{
+				CloseHandle( gSMBThreadDeregisterEvent );
+				gSMBThreadDeregisterEvent = NULL;
+			}
+
+			if ( gSMBThreadRegisterEvent )
+			{
+				CloseHandle( gSMBThreadRegisterEvent );
+				gSMBThreadRegisterEvent = NULL;
+			}
+
+			if ( gDNSSDLibrary )
+			{
+				FreeLibrary( gDNSSDLibrary );
+				gDNSSDLibrary = NULL;
+			}	
+		}
+		else
+		{
+			LogMsg( "Unable to stop SMBThread" );
+		}
+
+		inMDNS->p->smbFileSharing = mDNSfalse;
+		inMDNS->p->smbPrintSharing = mDNSfalse;
+	}
+
+	// Tear everything down in reverse order to how it was set up.
+	
+	err = TearDownInterfaceList( inMDNS );
+	check_noerr( err );
+	check( !inMDNS->p->inactiveInterfaceList );
+
+#if ( MDNS_WINDOWS_ENABLE_IPV4 )
+
+	UDPCloseSocket( &inMDNS->p->unicastSock4 );
+
+#endif
+	
+#if ( MDNS_WINDOWS_ENABLE_IPV6 )
+
+	UDPCloseSocket( &inMDNS->p->unicastSock6 );
+
+#endif
+
+	// Free the DLL needed for IPv6 support.
+	
+#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
+	if( gIPHelperLibraryInstance )
+	{
+		gGetAdaptersAddressesFunctionPtr = NULL;
+		
+		FreeLibrary( gIPHelperLibraryInstance );
+		gIPHelperLibraryInstance = NULL;
+	}
+#endif
+
+	if ( g_hAAPI32 )
+	{
+		// Release any resources
+
+		if ( g_hProvider && g_lpCryptReleaseContext )
+		{
+			( g_lpCryptReleaseContext )( g_hProvider, 0 );
+		}
+
+		// Free the AdvApi32.dll
+
+		FreeLibrary( g_hAAPI32 );
+
+		// And reset all the data
+
+		g_lpCryptAcquireContext = NULL;
+		g_lpCryptReleaseContext = NULL;
+		g_lpCryptGenRandom 		= NULL;
+		g_hProvider 			= ( ULONG_PTR ) NULL;
+		g_hAAPI32				= NULL;
+	}
+
+	// Clear out the APC queue
+
+	while ( SleepEx( 0, TRUE ) == WAIT_IO_COMPLETION )
+	{
+		DispatchSocketEvents( inMDNS );
+	}
+
+	WSACleanup();
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "platform close done\n" );
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformLock
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformLock( const mDNS * const inMDNS )
+{
+	( void ) inMDNS;
+}
+
+//===========================================================================================================================
+//	mDNSPlatformUnlock
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformUnlock( const mDNS * const inMDNS )
+{
+	( void ) inMDNS;
+}
+
+//===========================================================================================================================
+//	mDNSPlatformStrCopy
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformStrCopy( void *inDst, const void *inSrc )
+{
+	check( inSrc );
+	check( inDst );
+	
+	strcpy( (char *) inDst, (const char*) inSrc );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformStrLCopy
+//===========================================================================================================================
+
+mDNSexport mDNSu32 mDNSPlatformStrLCopy(void *inDst, const void *inSrc, mDNSu32 inSize)
+{
+	const char *		src = (const char *) inSrc;
+	
+	if( inSize > 0 )
+	{
+		size_t		n;
+		char *		dst = (char *) inDst;
+		
+		for( n = inSize - 1; n > 0; --n )
+		{
+			if( ( *dst++ = *src++ ) == '\0' )
+			{
+				// Null terminator encountered, so exit.
+				goto exit;
+			}
+		}
+		*dst = '\0';
+	}
+	
+	while( *src++ != '\0' )
+	{
+		// Stop at null terminator.
+	}
+	
+exit:
+	return( (mDNSu32)( src - (const char *) inSrc ) - 1 );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformStrLen
+//===========================================================================================================================
+
+mDNSexport mDNSu32	mDNSPlatformStrLen( const void *inSrc )
+{
+	check( inSrc );
+	
+	return( (mDNSu32) strlen( (const char *) inSrc ) );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformMemCopy
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformMemCopy( void *inDst, const void *inSrc, mDNSu32 inSize )
+{
+	check( inSrc );
+	check( inDst );
+	
+	memcpy( inDst, inSrc, inSize );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformMemSame
+//===========================================================================================================================
+
+mDNSexport mDNSBool	mDNSPlatformMemSame( const void *inDst, const void *inSrc, mDNSu32 inSize )
+{
+	check( inSrc );
+	check( inDst );
+	
+	return( (mDNSBool)( memcmp( inSrc, inDst, inSize ) == 0 ) );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformMemZero
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformMemZero( void *inDst, mDNSu32 inSize )
+{
+	check( inDst );
+	
+	memset( inDst, 0, inSize );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformMemAllocate
+//===========================================================================================================================
+
+mDNSexport void *	mDNSPlatformMemAllocate( mDNSu32 inSize )
+{
+	void *		mem;
+	
+	check( inSize > 0 );
+	
+	mem = malloc( inSize );
+	check( mem );
+	
+	return( mem );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformMemFree
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformMemFree( void *inMem )
+{
+	check( inMem );
+	
+	free( inMem );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformRandomNumber
+//===========================================================================================================================
+
+mDNSexport mDNSu32 mDNSPlatformRandomNumber(void)
+{
+	mDNSu32		randomNumber = 0;
+	BOOL		bResult;
+	OSStatus	err = 0;
+
+	if ( !g_hAAPI32 )
+	{
+		g_hAAPI32 = LoadLibrary( TEXT("AdvAPI32.dll") );
+		err = translate_errno( g_hAAPI32 != NULL, GetLastError(), mStatus_UnknownErr );
+		require_noerr( err, exit );
+	}
+
+	// Function Pointer: CryptAcquireContext
+
+	if ( !g_lpCryptAcquireContext )
+	{
+		g_lpCryptAcquireContext = ( fnCryptAcquireContext )
+#ifdef UNICODE
+			( GetProcAddress( g_hAAPI32, "CryptAcquireContextW" ) );
+#else
+			( GetProcAddress( g_hAAPI32, "CryptAcquireContextA" ) );
+#endif
+		err = translate_errno( g_lpCryptAcquireContext != NULL, GetLastError(), mStatus_UnknownErr );
+		require_noerr( err, exit );
+	}
+
+	// Function Pointer: CryptReleaseContext
+
+	if ( !g_lpCryptReleaseContext )
+	{
+		g_lpCryptReleaseContext = ( fnCryptReleaseContext )
+         ( GetProcAddress( g_hAAPI32, "CryptReleaseContext" ) );
+		err = translate_errno( g_lpCryptReleaseContext != NULL, GetLastError(), mStatus_UnknownErr );
+		require_noerr( err, exit );
+	}
+      
+	// Function Pointer: CryptGenRandom
+
+	if ( !g_lpCryptGenRandom )
+	{
+		g_lpCryptGenRandom = ( fnCryptGenRandom )
+          ( GetProcAddress( g_hAAPI32, "CryptGenRandom" ) );
+		err = translate_errno( g_lpCryptGenRandom != NULL, GetLastError(), mStatus_UnknownErr );
+		require_noerr( err, exit );
+	}
+
+	// Setup
+
+	if ( !g_hProvider )
+	{
+		bResult = (*g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET );
+
+		if ( !bResult )
+		{
+			bResult =  ( *g_lpCryptAcquireContext)( &g_hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET );
+			err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
+			require_noerr( err, exit );
+		}
+	}
+
+	bResult = (*g_lpCryptGenRandom)( g_hProvider, sizeof( randomNumber ), ( BYTE* ) &randomNumber );
+	err = translate_errno( bResult, GetLastError(), mStatus_UnknownErr );
+	require_noerr( err, exit );
+
+exit:
+
+	if ( err )
+	{
+		randomNumber = rand();
+	}
+
+	return randomNumber;
+}
+
+//===========================================================================================================================
+//	mDNSPlatformTimeInit
+//===========================================================================================================================
+
+mDNSexport mStatus	mDNSPlatformTimeInit( void )
+{
+	// No special setup is required on Windows -- we just use GetTickCount().
+	return( mStatus_NoError );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformRawTime
+//===========================================================================================================================
+
+mDNSexport mDNSs32	mDNSPlatformRawTime( void )
+{
+	return( (mDNSs32) GetTickCount() );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformUTC
+//===========================================================================================================================
+
+mDNSexport mDNSs32	mDNSPlatformUTC( void )
+{
+	return ( mDNSs32 ) time( NULL );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformInterfaceNameToID
+//===========================================================================================================================
+
+mDNSexport mStatus	mDNSPlatformInterfaceNameToID( mDNS * const inMDNS, const char *inName, mDNSInterfaceID *outID )
+{
+	mStatus					err;
+	mDNSInterfaceData *		ifd;
+	
+	check( inMDNS );
+	check( inMDNS->p );
+	check( inName );
+	
+	// Search for an interface with the specified name,
+	
+	for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
+	{
+		if( strcmp( ifd->name, inName ) == 0 )
+		{
+			break;
+		}
+	}
+	require_action_quiet( ifd, exit, err = mStatus_NoSuchNameErr );
+	
+	// Success!
+	
+	if( outID )
+	{
+		*outID = (mDNSInterfaceID) ifd;
+	}
+	err = mStatus_NoError;
+	
+exit:
+	return( err );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformInterfaceIDToInfo
+//===========================================================================================================================
+
+mDNSexport mStatus	mDNSPlatformInterfaceIDToInfo( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSPlatformInterfaceInfo *outInfo )
+{
+	mStatus					err;
+	mDNSInterfaceData *		ifd;
+	
+	check( inMDNS );
+	check( inID );
+	check( outInfo );
+	
+	// Search for an interface with the specified ID,
+	
+	for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
+	{
+		if( ifd == (mDNSInterfaceData *) inID )
+		{
+			break;
+		}
+	}
+	require_action_quiet( ifd, exit, err = mStatus_NoSuchNameErr );
+	
+	// Success!
+	
+	outInfo->name 	= ifd->name;
+	outInfo->ip 	= ifd->interfaceInfo.ip;
+	err 			= mStatus_NoError;
+	
+exit:
+	return( err );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformInterfaceIDfromInterfaceIndex
+//===========================================================================================================================
+
+mDNSexport mDNSInterfaceID	mDNSPlatformInterfaceIDfromInterfaceIndex( mDNS * const inMDNS, mDNSu32 inIndex )
+{
+	mDNSInterfaceID		id;
+	
+	id = mDNSNULL;
+	if( inIndex == kDNSServiceInterfaceIndexLocalOnly )
+	{
+		id = mDNSInterface_LocalOnly;
+	}
+	/* uncomment if Windows ever supports P2P
+	else if( inIndex == kDNSServiceInterfaceIndexP2P )
+	{
+		id = mDNSInterface_P2P;
+	}
+	*/
+	else if( inIndex != 0 )
+	{
+		mDNSInterfaceData *		ifd;
+		
+		for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
+		{
+			if( ( ifd->scopeID == inIndex ) && ifd->interfaceInfo.InterfaceActive )
+			{
+				id = ifd->interfaceInfo.InterfaceID;
+				break;
+			}
+		}
+		check( ifd );
+	}
+	return( id );
+}
+
+//===========================================================================================================================
+//	mDNSPlatformInterfaceIndexfromInterfaceID
+//===========================================================================================================================
+	
+mDNSexport mDNSu32	mDNSPlatformInterfaceIndexfromInterfaceID( mDNS * const inMDNS, mDNSInterfaceID inID, mDNSBool suppressNetworkChange )
+{
+	mDNSu32		index;
+	(void) suppressNetworkChange; // Unused
+	
+	index = 0;
+	if( inID == mDNSInterface_LocalOnly )
+	{
+		index = (mDNSu32) kDNSServiceInterfaceIndexLocalOnly;
+	}
+	/* uncomment if Windows ever supports P2P
+	else if( inID == mDNSInterface_P2P )
+	{
+		index = (mDNSu32) kDNSServiceInterfaceIndexP2P;
+	}
+	*/
+	else if( inID )
+	{
+		mDNSInterfaceData *		ifd;
+		
+		// Search active interfaces.
+		for( ifd = inMDNS->p->interfaceList; ifd; ifd = ifd->next )
+		{
+			if( (mDNSInterfaceID) ifd == inID )
+			{
+				index = ifd->scopeID;
+				break;
+			}
+		}
+		
+		// Search inactive interfaces too so remove events for inactive interfaces report the old interface index.
+		
+		if( !ifd )
+		{
+			for( ifd = inMDNS->p->inactiveInterfaceList; ifd; ifd = ifd->next )
+			{
+				if( (mDNSInterfaceID) ifd == inID )
+				{
+					index = ifd->scopeID;
+					break;
+				}
+			}
+		}
+		check( ifd );
+	}
+	return( index );
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformTCPSocket
+//===========================================================================================================================
+
+TCPSocket *
+mDNSPlatformTCPSocket
+	(
+	mDNS			* const m,
+	TCPSocketFlags		flags,
+	mDNSIPPort			*	port 
+	)
+{
+	TCPSocket *		sock    = NULL;
+	u_long				on		= 1;  // "on" for setsockopt
+	struct sockaddr_in	saddr;
+	int					len;
+	mStatus				err		= mStatus_NoError;
+
+	DEBUG_UNUSED( m );
+
+	require_action( flags == 0, exit, err = mStatus_UnsupportedErr );
+
+	// Setup connection data object
+
+	sock = (TCPSocket *) malloc( sizeof( TCPSocket ) );
+	require_action( sock, exit, err = mStatus_NoMemoryErr );
+	mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
+	sock->fd		= INVALID_SOCKET;
+	sock->flags		= flags;
+	sock->m			= m;
+
+	mDNSPlatformMemZero(&saddr, sizeof(saddr));
+	saddr.sin_family		= AF_INET;
+	saddr.sin_addr.s_addr	= htonl( INADDR_ANY );
+	saddr.sin_port			= port->NotAnInteger;
+	
+	// Create the socket
+
+	sock->fd = socket(AF_INET, SOCK_STREAM, 0);
+	err = translate_errno( sock->fd != INVALID_SOCKET, WSAGetLastError(), mStatus_UnknownErr );
+	require_noerr( err, exit );
+
+	// bind
+
+	err = bind( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr )  );
+	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
+	require_noerr( err, exit );
+
+	// Set it to be non-blocking
+
+	err = ioctlsocket( sock->fd, FIONBIO, &on );
+	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
+	require_noerr( err, exit );
+
+	// Get port number
+
+	mDNSPlatformMemZero( &saddr, sizeof( saddr ) );
+	len = sizeof( saddr );
+
+	err = getsockname( sock->fd, ( struct sockaddr* ) &saddr, &len );
+	err = translate_errno( err == 0, WSAGetLastError(), mStatus_UnknownErr );
+	require_noerr( err, exit );
+
+	port->NotAnInteger = saddr.sin_port;
+
+exit:
+
+	if ( err && sock )
+	{
+		TCPFreeSocket( sock );
+		sock = mDNSNULL;
+	}
+
+	return sock;
+} 
+
+//===========================================================================================================================
+//	mDNSPlatformTCPConnect
+//===========================================================================================================================
+
+mStatus
+mDNSPlatformTCPConnect
+	(
+	TCPSocket			*	sock,
+	const mDNSAddr		*	inDstIP, 
+	mDNSOpaque16 			inDstPort, 
+	domainname          *   hostname,
+	mDNSInterfaceID			inInterfaceID,
+	TCPConnectionCallback	inCallback, 
+	void *					inContext
+	)
+{
+	struct sockaddr_in	saddr;
+	mStatus				err		= mStatus_NoError;
+
+	DEBUG_UNUSED( inInterfaceID );
+	( void ) hostname;
+
+	if ( inDstIP->type != mDNSAddrType_IPv4 )
+	{
+		LogMsg("ERROR: mDNSPlatformTCPConnect - attempt to connect to an IPv6 address: operation not supported");
+		return mStatus_UnknownErr;
+	}
+
+	// Setup connection data object
+
+	sock->readEventHandler	= TCPCanRead;
+	sock->userCallback		= inCallback;
+	sock->userContext		= inContext;
+
+	mDNSPlatformMemZero(&saddr, sizeof(saddr));
+	saddr.sin_family	= AF_INET;
+	saddr.sin_port		= inDstPort.NotAnInteger;
+	memcpy(&saddr.sin_addr, &inDstIP->ip.v4.NotAnInteger, sizeof(saddr.sin_addr));
+
+	// Try and do connect
+
+	err = connect( sock->fd, ( struct sockaddr* ) &saddr, sizeof( saddr ) );
+	require_action( !err || ( WSAGetLastError() == WSAEWOULDBLOCK ), exit, err = mStatus_ConnFailed );
+	sock->connected	= !err ? TRUE : FALSE;
+
+	if ( sock->connected )
+	{
+		err = TCPAddSocket( sock->m, sock );
+		require_noerr( err, exit );
+	}
+	else
+	{
+		require_action( sock->m->p->registerWaitableEventFunc != NULL, exit, err = mStatus_ConnFailed );
+
+		sock->connectEvent	= CreateEvent( NULL, FALSE, FALSE, NULL );
+		err = translate_errno( sock->connectEvent, GetLastError(), mStatus_UnknownErr );
+		require_noerr( err, exit );
+
+		err = WSAEventSelect( sock->fd, sock->connectEvent, FD_CONNECT );
+		require_noerr( err, exit );
+
+		err = sock->m->p->registerWaitableEventFunc( sock->m, sock->connectEvent, sock, TCPDidConnect );
+		require_noerr( err, exit );
+	}
+
+exit:
+
+	if ( !err )
+	{
+		err = sock->connected ? mStatus_ConnEstablished : mStatus_ConnPending;
+	}
+
+	return err;
+}
+
+//===========================================================================================================================
+//	mDNSPlatformTCPAccept
+//===========================================================================================================================
+
+mDNSexport 
+mDNSexport TCPSocket *mDNSPlatformTCPAccept( TCPSocketFlags flags, int fd )
+	{
+	TCPSocket	*	sock = NULL;
+	mStatus							err = mStatus_NoError;
+
+	require_action( !flags, exit, err = mStatus_UnsupportedErr );
+
+	sock = malloc( sizeof( TCPSocket ) );
+	require_action( sock, exit, err = mStatus_NoMemoryErr );
+	
+	mDNSPlatformMemZero( sock, sizeof( *sock ) );
+
+	sock->fd	= fd;
+	sock->flags = flags;
+
+exit:
+
+	if ( err && sock )
+	{
+		free( sock );
+		sock = NULL;
+	}
+
+	return sock;
+	}
+
+
+//===========================================================================================================================
+//	mDNSPlatformTCPCloseConnection
+//===========================================================================================================================
+
+mDNSexport void	mDNSPlatformTCPCloseConnection( TCPSocket *sock )
+{
+	check( sock );
+
+	if ( sock->connectEvent && sock->m->p->unregisterWaitableEventFunc )
+	{
+		sock->m->p->unregisterWaitableEventFunc( sock->m, sock->connectEvent );
+	}
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		TCPCloseSocket( sock );
+
+		QueueUserAPC( ( PAPCFUNC ) TCPFreeSocket, sock->m->p->mainThread, ( ULONG_PTR ) sock );
+	}
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformReadTCP
+//===========================================================================================================================
+
+mDNSexport long	mDNSPlatformReadTCP( TCPSocket *sock, void *inBuffer, unsigned long inBufferSize, mDNSBool * closed )
+{
+	unsigned long	bytesLeft;
+	int				wsaError;
+	long			ret;
+
+	*closed = sock->closed;
+	wsaError = sock->lastError;
+	ret = -1;
+
+	if ( *closed )
+	{
+		ret = 0;
+	}
+	else if ( sock->lastError == 0 )
+	{
+		// First check to see if we have any data left in our buffer
+
+		bytesLeft = ( DWORD ) ( sock->eptr - sock->bptr );
+
+		if ( bytesLeft )
+		{
+			unsigned long bytesToCopy = ( bytesLeft < inBufferSize ) ? bytesLeft : inBufferSize;
+
+			memcpy( inBuffer, sock->bptr, bytesToCopy );
+			sock->bptr += bytesToCopy;
+
+			if ( !sock->overlapped.pending && ( sock->bptr == sock->eptr ) )
+			{
+				sock->bptr = sock->bbuf;
+				sock->eptr = sock->bbuf;
+			}
+
+			ret = bytesToCopy;
+		}
+		else
+		{
+			wsaError = WSAEWOULDBLOCK;
+		}
+	}
+
+	// Always set the last winsock error, so that we don't inadvertently use a previous one		
+	
+	WSASetLastError( wsaError );
+
+	return ret;
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformWriteTCP
+//===========================================================================================================================
+
+mDNSexport long	mDNSPlatformWriteTCP( TCPSocket *sock, const char *inMsg, unsigned long inMsgSize )
+{
+	int			nsent;
+	OSStatus	err;
+
+	nsent = send( sock->fd, inMsg, inMsgSize, 0 );
+
+	err = translate_errno( ( nsent >= 0 ) || ( WSAGetLastError() == WSAEWOULDBLOCK ), WSAGetLastError(), mStatus_UnknownErr );
+	require_noerr( err, exit );
+
+	if ( nsent < 0)
+	{
+		nsent = 0;
+	}
+		
+exit:
+
+	return nsent;
+}
+
+//===========================================================================================================================
+//	mDNSPlatformTCPGetFD
+//===========================================================================================================================
+
+mDNSexport int mDNSPlatformTCPGetFD(TCPSocket *sock )
+{
+	return ( int ) sock->fd;
+}
+
+
+//===========================================================================================================================
+//	TCPAddConnection
+//===========================================================================================================================
+
+mStatus TCPAddSocket( mDNS * const inMDNS, TCPSocket *sock )
+{
+	mStatus err;
+
+	( void ) inMDNS;
+
+	sock->bptr	= sock->bbuf;
+	sock->eptr	= sock->bbuf;
+	sock->ebuf	= sock->bbuf + sizeof( sock->bbuf );
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "adding TCPSocket 0x%x:%d\n", sock, sock->fd );
+	err = TCPBeginRecv( sock );
+	require_noerr( err, exit );
+
+exit:
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	TCPDidConnect
+//===========================================================================================================================
+
+mDNSlocal void TCPDidConnect( mDNS * const inMDNS, HANDLE event, void * context )
+{
+	TCPSocket * sock = ( TCPSocket* ) context;
+	TCPConnectionCallback callback = NULL;
+	WSANETWORKEVENTS sockEvent;
+	int err = kNoErr;
+
+	if ( inMDNS->p->unregisterWaitableEventFunc )
+	{
+		inMDNS->p->unregisterWaitableEventFunc( inMDNS, event );
+	}
+
+	if ( sock )
+	{
+		callback = ( TCPConnectionCallback ) sock->userCallback;
+		err = WSAEnumNetworkEvents( sock->fd, sock->connectEvent, &sockEvent );
+		require_noerr( err, exit );
+		require_action( sockEvent.lNetworkEvents & FD_CONNECT, exit, err = mStatus_UnknownErr );
+		require_action( sockEvent.iErrorCode[ FD_CONNECT_BIT ] == 0, exit, err = sockEvent.iErrorCode[ FD_CONNECT_BIT ] );
+
+		sock->connected	= mDNStrue;
+
+		if ( sock->fd != INVALID_SOCKET )
+		{
+			err = TCPAddSocket( sock->m, sock );
+			require_noerr( err, exit );
+		}
+
+		if ( callback )
+		{
+			callback( sock, sock->userContext, TRUE, 0 );
+		}
+	}
+
+exit:
+
+	if ( err && callback )
+	{
+		callback( sock, sock->userContext, TRUE, err );
+	}
+}
+
+
+
+//===========================================================================================================================
+//	TCPCanRead
+//===========================================================================================================================
+
+mDNSlocal void TCPCanRead( TCPSocket * sock )
+{
+	TCPConnectionCallback callback = ( TCPConnectionCallback ) sock->userCallback;
+
+	if ( callback )
+	{
+		callback( sock, sock->userContext, mDNSfalse, sock->lastError );
+	}
+}
+
+
+//===========================================================================================================================
+//	TCPBeginRecv
+//===========================================================================================================================
+
+mDNSlocal mStatus TCPBeginRecv( TCPSocket * sock )
+{
+	DWORD	bytesReceived	= 0;
+	DWORD	flags			= 0;
+	mStatus err;
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
+
+	check( !sock->overlapped.pending );
+
+	ZeroMemory( &sock->overlapped.data, sizeof( sock->overlapped.data ) );
+	sock->overlapped.data.hEvent = sock;
+
+	sock->overlapped.wbuf.buf = ( char* ) sock->eptr;
+	sock->overlapped.wbuf.len = ( ULONG) ( sock->ebuf - sock->eptr );
+	
+	err = WSARecv( sock->fd, &sock->overlapped.wbuf, 1, &bytesReceived, &flags, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) TCPEndRecv );
+	err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), WSAGetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+
+	sock->overlapped.pending = TRUE;
+
+exit:
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	TCPEndRecv
+//===========================================================================================================================
+
+mDNSlocal void CALLBACK TCPEndRecv( DWORD error, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags )
+{
+	TCPSocket * sock;
+
+	( void ) flags;
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "%s: error = %d, bytesTransferred = %d\n", __ROUTINE__, error, bytesTransferred );
+	sock = ( overlapped != NULL ) ? overlapped->hEvent : NULL;
+	require_action( sock, exit, error = ( DWORD ) mStatus_BadStateErr );
+	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
+	sock->overlapped.error				= error;
+	sock->overlapped.bytesTransferred	= bytesTransferred;
+	check( sock->overlapped.pending );
+	sock->overlapped.pending			= FALSE;
+
+	// Queue this socket
+
+	AddToTail( &gTCPDispatchableSockets, sock );
+
+exit:
+
+	return;
+}
+
+
+	
+//===========================================================================================================================
+//	mDNSPlatformUDPSocket
+//===========================================================================================================================
+
+mDNSexport UDPSocket* mDNSPlatformUDPSocket(mDNS *const m, const mDNSIPPort requestedport)
+{
+	UDPSocket*	sock	= NULL;
+	mDNSIPPort	port	= requestedport;
+	mStatus		err		= mStatus_NoError;
+	unsigned	i;
+
+	// Setup connection data object
+
+	sock = ( UDPSocket* ) malloc(sizeof( UDPSocket ) );
+	require_action( sock, exit, err = mStatus_NoMemoryErr );
+	memset( sock, 0, sizeof( UDPSocket ) );
+
+	// Create the socket
+
+	sock->fd					= INVALID_SOCKET;
+	sock->recvMsgPtr			= m->p->unicastSock4.recvMsgPtr;
+	sock->addr					= m->p->unicastSock4.addr;
+	sock->ifd					= NULL;
+	sock->overlapped.pending	= FALSE;
+	sock->m						= m;
+
+	// Try at most 10000 times to get a unique random port
+
+	for (i=0; i<10000; i++)
+	{
+		struct sockaddr_in saddr;
+
+		saddr.sin_family		= AF_INET;
+		saddr.sin_addr.s_addr	= 0;
+
+		// The kernel doesn't do cryptographically strong random port
+		// allocation, so we do it ourselves here
+
+        if (mDNSIPPortIsZero(requestedport))
+		{
+			port = mDNSOpaque16fromIntVal( ( mDNSu16 ) ( 0xC000 + mDNSRandom(0x3FFF) ) );
+		}
+
+		saddr.sin_port = port.NotAnInteger;
+
+        err = SetupSocket(m, ( struct sockaddr* ) &saddr, port, &sock->fd );
+        if (!err) break;
+	}
+
+	require_noerr( err, exit );
+
+	// Set the port
+
+	sock->port = port;
+
+	// Arm the completion routine
+
+	err = UDPBeginRecv( sock );
+	require_noerr( err, exit ); 
+
+	// Bookkeeping
+
+	sock->next		= gUDPSockets;
+	gUDPSockets		= sock;
+	gUDPNumSockets++;
+
+exit:
+
+	if ( err && sock )
+	{
+		UDPFreeSocket( sock );
+		sock = NULL;
+	}
+
+	return sock;
+}
+	
+//===========================================================================================================================
+//	mDNSPlatformUDPClose
+//===========================================================================================================================
+	
+mDNSexport void mDNSPlatformUDPClose( UDPSocket *sock )
+{
+	UDPSocket	*	current  = gUDPSockets;
+	UDPSocket	*	last = NULL;
+
+	while ( current )
+	{
+		if ( current == sock )
+		{
+			if ( last == NULL )
+			{
+				gUDPSockets = sock->next;
+			}
+			else
+			{
+				last->next = sock->next;
+			}
+
+			// Alertable I/O is great, except not so much when it comes to closing
+			// the socket.  Anything that has been previously queued for this socket
+			// will stay in the queue after you close the socket.  This is problematic
+			// for obvious reasons. So we'll attempt to workaround this by closing
+			// the socket which will prevent any further queued packets and then not calling
+			// UDPFreeSocket directly, but by queueing it using QueueUserAPC.  The queues
+			// are FIFO, so that will execute *after* any other previous items in the queue
+			//
+			// UDPEndRecv will check if the socket is valid, and if not, it will ignore
+			// the packet
+
+			UDPCloseSocket( sock );
+
+			QueueUserAPC( ( PAPCFUNC ) UDPFreeSocket, sock->m->p->mainThread, ( ULONG_PTR ) sock );
+
+			gUDPNumSockets--;
+
+			break;
+		}
+
+		last	= current;
+		current	= current->next;
+	}
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformSendUDP
+//===========================================================================================================================
+
+mDNSexport mStatus
+	mDNSPlatformSendUDP( 
+		const mDNS * const			inMDNS, 
+		const void * const	        inMsg, 
+		const mDNSu8 * const		inMsgEnd, 
+		mDNSInterfaceID 			inInterfaceID, 
+		UDPSocket *					inSrcSocket,
+		const mDNSAddr *			inDstIP, 
+		mDNSIPPort 					inDstPort )
+{
+	SOCKET						sendingsocket = INVALID_SOCKET;
+	mStatus						err = mStatus_NoError;
+	mDNSInterfaceData *			ifd = (mDNSInterfaceData*) inInterfaceID;
+	struct sockaddr_storage		addr;
+	int							n;
+	
+	DEBUG_USE_ONLY( inMDNS );
+	
+	n = (int)( inMsgEnd - ( (const mDNSu8 * const) inMsg ) );
+	check( inMDNS );
+	check( inMsg );
+	check( inMsgEnd );
+	check( inDstIP );
+	
+	dlog( kDebugLevelChatty, DEBUG_NAME "platform send %d bytes to %#a:%u\n", n, inDstIP, ntohs( inDstPort.NotAnInteger ) );
+	
+	if( inDstIP->type == mDNSAddrType_IPv4 )
+	{
+		struct sockaddr_in *		sa4;
+		
+		sa4						= (struct sockaddr_in *) &addr;
+		sa4->sin_family			= AF_INET;
+		sa4->sin_port			= inDstPort.NotAnInteger;
+		sa4->sin_addr.s_addr	= inDstIP->ip.v4.NotAnInteger;
+		sendingsocket           = ifd ? ifd->sock.fd : inMDNS->p->unicastSock4.fd;
+
+		if (inSrcSocket) { sendingsocket = inSrcSocket->fd; debugf("mDNSPlatformSendUDP using port %d, static port %d, sock %d", mDNSVal16(inSrcSocket->port), inMDNS->p->unicastSock4.fd, sendingsocket); }
+	}
+	else if( inDstIP->type == mDNSAddrType_IPv6 )
+	{
+		struct sockaddr_in6 *		sa6;
+		
+		sa6					= (struct sockaddr_in6 *) &addr;
+		sa6->sin6_family	= AF_INET6;
+		sa6->sin6_port		= inDstPort.NotAnInteger;
+		sa6->sin6_flowinfo	= 0;
+		sa6->sin6_addr		= *( (struct in6_addr *) &inDstIP->ip.v6 );
+		sa6->sin6_scope_id	= 0;	// Windows requires the scope ID to be zero. IPV6_MULTICAST_IF specifies interface.
+		sendingsocket		= ifd ? ifd->sock.fd : inMDNS->p->unicastSock6.fd;
+	}
+	else
+	{
+		dlog( kDebugLevelError, DEBUG_NAME "%s: dst is not an IPv4 or IPv6 address (type=%d)\n", __ROUTINE__, inDstIP->type );
+		err = mStatus_BadParamErr;
+		goto exit;
+	}
+	
+	if (IsValidSocket(sendingsocket))
+	{
+		n = sendto( sendingsocket, (char *) inMsg, n, 0, (struct sockaddr *) &addr, sizeof( addr ) );
+		err = translate_errno( n > 0, errno_compat(), kWriteErr );
+
+		if ( err )
+		{
+			// Don't report EHOSTDOWN (i.e. ARP failure), ENETDOWN, or no route to host for unicast destinations
+
+			if ( !mDNSAddressIsAllDNSLinkGroup( inDstIP ) && ( WSAGetLastError() == WSAEHOSTDOWN || WSAGetLastError() == WSAENETDOWN || WSAGetLastError() == WSAEHOSTUNREACH || WSAGetLastError() == WSAENETUNREACH ) )
+			{
+				err = mStatus_TransientErr;
+			}
+			else
+			{
+				require_noerr( err, exit );
+			}
+		}
+	}
+	
+exit:
+	return( err );
+}
+
+
+mDNSexport void mDNSPlatformUpdateProxyList(mDNS *const m, const mDNSInterfaceID InterfaceID)
+	{
+	DEBUG_UNUSED( m );
+	DEBUG_UNUSED( InterfaceID );
+	}
+
+//===========================================================================================================================
+//	mDNSPlatformSendRawPacket
+//===========================================================================================================================
+	
+mDNSexport void mDNSPlatformSetAllowSleep(mDNS *const m, mDNSBool allowSleep, const char *reason)

+    {

+    DEBUG_UNUSED( m );

+	DEBUG_UNUSED( allowSleep );

+	DEBUG_UNUSED( reason );

+    }

+
+mDNSexport void mDNSPlatformSendRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
+	{
+	DEBUG_UNUSED( msg );
+	DEBUG_UNUSED( end );
+	DEBUG_UNUSED( InterfaceID );
+	}
+
+mDNSexport void mDNSPlatformReceiveRawPacket(const void *const msg, const mDNSu8 *const end, mDNSInterfaceID InterfaceID)
+	{
+	DEBUG_UNUSED( msg );
+	DEBUG_UNUSED( end );
+	DEBUG_UNUSED( InterfaceID );
+	}
+
+mDNSexport void mDNSPlatformSetLocalAddressCacheEntry(mDNS *const m, const mDNSAddr *const tpa, const mDNSEthAddr *const tha, mDNSInterfaceID InterfaceID)
+	{
+	DEBUG_UNUSED( m );
+	DEBUG_UNUSED( tpa );
+	DEBUG_UNUSED( tha );
+	DEBUG_UNUSED( InterfaceID );
+	}
+
+mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
+	{
+	dlog( kDebugLevelInfo, "%s\n", msg );
+	}
+
+mDNSexport void mDNSPlatformWriteLogMsg( const char * ident, const char * msg, mDNSLogLevel_t loglevel )
+	{
+	extern mDNS mDNSStorage;
+	int type;
+	
+	DEBUG_UNUSED( ident );
+
+	type = EVENTLOG_ERROR_TYPE;
+
+	switch (loglevel) 
+	{
+		case MDNS_LOG_MSG:       type = EVENTLOG_ERROR_TYPE;		break;
+		case MDNS_LOG_OPERATION: type = EVENTLOG_WARNING_TYPE;		break;
+		case MDNS_LOG_SPS:       type = EVENTLOG_INFORMATION_TYPE;  break;
+		case MDNS_LOG_INFO:      type = EVENTLOG_INFORMATION_TYPE;	break;
+		case MDNS_LOG_DEBUG:     type = EVENTLOG_INFORMATION_TYPE;	break;
+		default:
+			fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel);
+			fflush(stderr);
+			}
+
+	mDNSStorage.p->reportStatusFunc( type, msg );
+	dlog( kDebugLevelInfo, "%s\n", msg );
+	}
+
+mDNSexport void mDNSPlatformSourceAddrForDest( mDNSAddr * const src, const mDNSAddr * const dst )
+	{
+	DEBUG_UNUSED( src );
+	DEBUG_UNUSED( dst );
+	}
+
+//===========================================================================================================================
+//	mDNSPlatformTLSSetupCerts
+//===========================================================================================================================
+
+mDNSexport mStatus
+mDNSPlatformTLSSetupCerts(void)
+{
+	return mStatus_UnsupportedErr;
+}
+
+//===========================================================================================================================
+//	mDNSPlatformTLSTearDownCerts
+//===========================================================================================================================
+
+mDNSexport void
+mDNSPlatformTLSTearDownCerts(void)
+{
+}
+
+//===========================================================================================================================
+//	mDNSPlatformSetDNSConfig
+//===========================================================================================================================
+
+mDNSlocal void SetDNSServers( mDNS *const m );
+mDNSlocal void SetSearchDomainList( void );
+
+mDNSexport void mDNSPlatformSetDNSConfig(mDNS *const m, mDNSBool setservers, mDNSBool setsearch, domainname *const fqdn, DNameListElem **regDomains, DNameListElem **browseDomains)
+{
+	if (setservers) SetDNSServers(m);
+	if (setsearch) SetSearchDomainList();
+	
+	if ( fqdn )
+	{
+		GetDDNSFQDN( fqdn );
+	}
+
+	if ( browseDomains )
+	{
+		GetDDNSDomains( browseDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSBrowseDomains );
+	}
+
+	if ( regDomains )
+	{
+		GetDDNSDomains( regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
+	}
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformDynDNSHostNameStatusChanged
+//===========================================================================================================================
+
+mDNSexport void
+mDNSPlatformDynDNSHostNameStatusChanged(const domainname *const dname, const mStatus status)
+{
+	char		uname[MAX_ESCAPED_DOMAIN_NAME];
+	BYTE		bStatus;
+	LPCTSTR		name;
+	HKEY		key = NULL;
+	mStatus		err;
+	char	*	p;
+	
+	ConvertDomainNameToCString(dname, uname);
+	
+	p = uname;
+
+	while (*p)
+	{
+		*p = (char) tolower(*p);
+		if (!(*(p+1)) && *p == '.') *p = 0; // if last character, strip trailing dot
+		p++;
+	}
+
+	check( strlen( p ) <= MAX_ESCAPED_DOMAIN_NAME );
+	name = kServiceParametersNode TEXT("\\DynDNS\\State\\HostNames");
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, name, &key );
+	require_noerr( err, exit );
+
+	bStatus = ( status ) ? 0 : 1;
+	err = RegSetValueEx( key, kServiceDynDNSStatus, 0, REG_DWORD, (const LPBYTE) &bStatus, sizeof(DWORD) );
+	require_noerr( err, exit );
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return;
+}
+
+
+mDNSexport void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result)
+    {
+    (void)m;  // unused
+    (void)rr;
+    (void)result;
+    }
+
+
+
+//===========================================================================================================================
+//	SetDomainSecrets
+//===========================================================================================================================
+
+// This routine needs to be called whenever the system secrets database changes.
+// We call it from DynDNSConfigDidChange and mDNSPlatformInit
+
+void
+SetDomainSecrets( mDNS * const m )
+{
+	DomainAuthInfo *ptr;
+	domainname		fqdn;
+	DNameListElem * regDomains = NULL;
+
+	// Rather than immediately deleting all keys now, we mark them for deletion in ten seconds.
+	// In the case where the user simultaneously removes their DDNS host name and the key
+	// for it, this gives mDNSResponder ten seconds to gracefully delete the name from the
+	// server before it loses access to the necessary key. Otherwise, we'd leave orphaned
+	// address records behind that we no longer have permission to delete.
+	
+	for (ptr = m->AuthInfoList; ptr; ptr = ptr->next)
+		ptr->deltime = NonZeroTime(m->timenow + mDNSPlatformOneSecond*10);
+
+	GetDDNSFQDN( &fqdn );
+
+	if ( fqdn.c[ 0 ] )
+	{
+		SetDomainSecret( m, &fqdn );
+	}
+
+	GetDDNSDomains( &regDomains, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSRegistrationDomains );
+
+	while ( regDomains )
+	{
+		DNameListElem * current = regDomains;
+		SetDomainSecret( m, &current->name );
+		regDomains = regDomains->next;
+		free( current );
+	}
+}
+
+
+//===========================================================================================================================
+//	SetSearchDomainList
+//===========================================================================================================================
+
+mDNSlocal void SetDomainFromDHCP( void );
+mDNSlocal void SetReverseMapSearchDomainList( void );
+
+mDNSlocal void
+SetSearchDomainList( void )
+{
+	char			*	searchList	= NULL;
+	DWORD				searchListLen;
+	//DNameListElem	*	head = NULL;
+	//DNameListElem	*	current = NULL;
+	char			*	tok;
+	HKEY				key;
+	mStatus				err;
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &key );
+	require_noerr( err, exit );
+
+	err = RegQueryString( key, "SearchList", &searchList, &searchListLen, NULL );
+	require_noerr( err, exit );
+
+	// Windows separates the search domains with ','
+
+	tok = strtok( searchList, "," );
+	while ( tok )
+	{
+		if ( ( strcmp( tok, "" ) != 0 ) && ( strcmp( tok, "." ) != 0 ) )
+			mDNS_AddSearchDomain_CString(tok, mDNSNULL);
+		tok = strtok( NULL, "," );
+	}
+
+exit:
+
+	if ( searchList ) 
+	{
+		free( searchList );
+	}
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	SetDomainFromDHCP();
+	SetReverseMapSearchDomainList();
+}
+
+
+//===========================================================================================================================
+//	SetReverseMapSearchDomainList
+//===========================================================================================================================
+
+mDNSlocal void
+SetReverseMapSearchDomainList( void )
+{
+	struct ifaddrs	*	ifa;
+
+	ifa = myGetIfAddrs( 1 );
+	while (ifa)
+	{
+		mDNSAddr addr;
+		
+		if (ifa->ifa_addr->sa_family == AF_INET && !SetupAddr(&addr, ifa->ifa_addr) && !(ifa->ifa_flags & IFF_LOOPBACK) && ifa->ifa_netmask)
+		{
+			mDNSAddr	netmask;
+			char		buffer[256];
+			
+			if (!SetupAddr(&netmask, ifa->ifa_netmask))
+			{
+				sprintf(buffer, "%d.%d.%d.%d.in-addr.arpa.", addr.ip.v4.b[3] & netmask.ip.v4.b[3],
+                                                             addr.ip.v4.b[2] & netmask.ip.v4.b[2],
+                                                             addr.ip.v4.b[1] & netmask.ip.v4.b[1],
+                                                             addr.ip.v4.b[0] & netmask.ip.v4.b[0]);
+				mDNS_AddSearchDomain_CString(buffer, mDNSNULL);
+			}
+		}
+	
+		ifa = ifa->ifa_next;
+	}
+
+	return;
+}
+
+
+//===========================================================================================================================
+//	SetDNSServers
+//===========================================================================================================================
+
+mDNSlocal void
+SetDNSServers( mDNS *const m )
+{
+	PIP_PER_ADAPTER_INFO	pAdapterInfo	=	NULL;
+	FIXED_INFO			*	fixedInfo	= NULL;
+	ULONG					bufLen		= 0;	
+	IP_ADDR_STRING		*	dnsServerList;
+	IP_ADDR_STRING		*	ipAddr;
+	DWORD					index;
+	int						i			= 0;
+	mStatus					err			= kUnknownErr;
+
+	// Get the primary interface.
+
+	index = GetPrimaryInterface();
+
+	// This should have the interface index of the primary index.  Fall back in cases where
+	// it can't be determined.
+
+	if ( index )
+	{
+		bufLen = 0;
+
+		for ( i = 0; i < 100; i++ )
+		{
+			err = GetPerAdapterInfo( index, pAdapterInfo, &bufLen );
+
+			if ( err != ERROR_BUFFER_OVERFLOW )
+			{
+				break;
+			}
+
+			pAdapterInfo = (PIP_PER_ADAPTER_INFO) realloc( pAdapterInfo, bufLen );
+			require_action( pAdapterInfo, exit, err = mStatus_NoMemoryErr );
+		}
+
+		require_noerr( err, exit );
+
+		dnsServerList = &pAdapterInfo->DnsServerList;
+	}
+	else
+	{
+		bufLen = sizeof( FIXED_INFO );
+
+		for ( i = 0; i < 100; i++ )
+		{
+			if ( fixedInfo )
+			{
+				GlobalFree( fixedInfo );
+				fixedInfo = NULL;
+			}
+
+			fixedInfo = (FIXED_INFO*) GlobalAlloc( GPTR, bufLen );
+			require_action( fixedInfo, exit, err = mStatus_NoMemoryErr );
+	   
+			err = GetNetworkParams( fixedInfo, &bufLen );
+
+			if ( err != ERROR_BUFFER_OVERFLOW )
+			{
+				break;
+			}
+		}
+
+		require_noerr( err, exit );
+
+		dnsServerList = &fixedInfo->DnsServerList;
+	}
+
+	for ( ipAddr = dnsServerList; ipAddr; ipAddr = ipAddr->Next )
+	{
+		mDNSAddr addr;
+		err = StringToAddress( &addr, ipAddr->IpAddress.String );
+		if ( !err ) mDNS_AddDNSServer(m, mDNSNULL, mDNSInterface_Any, &addr, UnicastDNSPort, mDNSfalse, 0);
+	}
+
+exit:
+
+	if ( pAdapterInfo )
+	{
+		free( pAdapterInfo );
+	}
+
+	if ( fixedInfo )
+	{
+		GlobalFree( fixedInfo );
+	}
+}
+
+
+//===========================================================================================================================
+//	SetDomainFromDHCP
+//===========================================================================================================================
+
+mDNSlocal void
+SetDomainFromDHCP( void )
+{
+	int					i			= 0;
+	IP_ADAPTER_INFO *	pAdapterInfo;
+	IP_ADAPTER_INFO *	pAdapter;
+	DWORD				bufLen;
+	DWORD				index;
+	HKEY				key = NULL;
+	LPSTR				domain = NULL;
+	DWORD				dwSize;
+	mStatus				err = mStatus_NoError;
+
+	pAdapterInfo	= NULL;
+	
+	for ( i = 0; i < 100; i++ )
+	{
+		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
+
+		if ( err != ERROR_BUFFER_OVERFLOW )
+		{
+			break;
+		}
+
+		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
+		require_action( pAdapterInfo, exit, err = kNoMemoryErr );
+	}
+
+	require_noerr( err, exit );
+
+	index = GetPrimaryInterface();
+
+	for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
+	{
+		if ( pAdapter->IpAddressList.IpAddress.String &&
+		     pAdapter->IpAddressList.IpAddress.String[0] &&
+		     pAdapter->GatewayList.IpAddress.String &&
+		     pAdapter->GatewayList.IpAddress.String[0] &&
+		     ( !index || ( pAdapter->Index == index ) ) )
+		{
+			// Found one that will work
+
+			char keyName[1024];
+
+			_snprintf( keyName, 1024, "%s%s", "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\", pAdapter->AdapterName );
+
+			err = RegCreateKeyA( HKEY_LOCAL_MACHINE, keyName, &key );
+			require_noerr( err, exit );
+
+			err = RegQueryString( key, "Domain", &domain, &dwSize, NULL );
+			check_noerr( err );
+
+			if ( !domain || !domain[0] )
+			{
+				if ( domain )
+				{
+					free( domain );
+					domain = NULL;
+				}
+
+				err = RegQueryString( key, "DhcpDomain", &domain, &dwSize, NULL );
+				check_noerr( err );
+			}
+
+			if ( domain && domain[0] ) mDNS_AddSearchDomain_CString(domain, mDNSNULL);
+
+			break;
+		}
+	}
+
+exit:
+
+	if ( pAdapterInfo )
+	{
+		free( pAdapterInfo );
+	}
+
+	if ( domain )
+	{
+		free( domain );
+	}
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+}
+
+
+//===========================================================================================================================
+//	mDNSPlatformGetPrimaryInterface
+//===========================================================================================================================
+
+mDNSexport mStatus
+mDNSPlatformGetPrimaryInterface( mDNS * const m, mDNSAddr * v4, mDNSAddr * v6, mDNSAddr * router )
+{
+	IP_ADAPTER_INFO *	pAdapterInfo;
+	IP_ADAPTER_INFO *	pAdapter;
+	DWORD				bufLen;
+	int					i;
+	BOOL				found;
+	DWORD				index;
+	mStatus				err = mStatus_NoError;
+
+	DEBUG_UNUSED( m );
+
+	*v6 = zeroAddr;
+
+	pAdapterInfo	= NULL;
+	bufLen			= 0;
+	found			= FALSE;
+
+	for ( i = 0; i < 100; i++ )
+	{
+		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
+
+		if ( err != ERROR_BUFFER_OVERFLOW )
+		{
+			break;
+		}
+
+		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
+		require_action( pAdapterInfo, exit, err = kNoMemoryErr );
+	}
+
+	require_noerr( err, exit );
+
+	index = GetPrimaryInterface();
+
+	for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
+	{
+		if ( pAdapter->IpAddressList.IpAddress.String &&
+		     pAdapter->IpAddressList.IpAddress.String[0] &&
+		     pAdapter->GatewayList.IpAddress.String &&
+		     pAdapter->GatewayList.IpAddress.String[0] &&
+		     ( StringToAddress( v4, pAdapter->IpAddressList.IpAddress.String ) == mStatus_NoError ) &&
+		     ( StringToAddress( router, pAdapter->GatewayList.IpAddress.String ) == mStatus_NoError ) &&
+		     ( !index || ( pAdapter->Index == index ) ) )
+		{
+			// Found one that will work
+
+			if ( pAdapter->AddressLength == sizeof( m->PrimaryMAC ) )
+			{
+				memcpy( &m->PrimaryMAC, pAdapter->Address, pAdapter->AddressLength );
+			}
+
+			found = TRUE;
+			break;
+		}
+	}
+
+exit:
+
+	if ( pAdapterInfo )
+	{
+		free( pAdapterInfo );
+	}
+
+	return err;
+}
+
+mDNSexport void mDNSPlatformSendWakeupPacket(mDNS *const m, mDNSInterfaceID InterfaceID, char *EthAddr, char *IPAddr, int iteration)
+	{
+	(void) m;
+	(void) InterfaceID;
+	(void) EthAddr;
+	(void) IPAddr;
+	(void) iteration;
+	}
+
+mDNSexport mDNSBool mDNSPlatformValidRecordForInterface(AuthRecord *rr, const NetworkInterfaceInfo *intf)
+	{
+	(void) rr;
+	(void) intf;
+
+	return 1;
+	}
+
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	debugf_
+//===========================================================================================================================
+#if( MDNS_DEBUGMSGS )
+mDNSexport void	debugf_( const char *inFormat, ... )
+{
+	char		buffer[ 512 ];
+    va_list		args;
+    mDNSu32		length;
+	
+	va_start( args, inFormat );
+	length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
+	va_end( args );
+	
+	dlog( kDebugLevelInfo, "%s\n", buffer );
+}
+#endif
+
+//===========================================================================================================================
+//	verbosedebugf_
+//===========================================================================================================================
+
+#if( MDNS_DEBUGMSGS > 1 )
+mDNSexport void	verbosedebugf_( const char *inFormat, ... )
+{
+	char		buffer[ 512 ];
+    va_list		args;
+    mDNSu32		length;
+	
+	va_start( args, inFormat );
+	length = mDNS_vsnprintf( buffer, sizeof( buffer ), inFormat, args );
+	va_end( args );
+	
+	dlog( kDebugLevelVerbose, "%s\n", buffer );
+}
+#endif
+
+
+#if 0
+#pragma mark -
+#pragma mark == Platform Internals  ==
+#endif
+
+
+//===========================================================================================================================
+//	SetupNiceName
+//===========================================================================================================================
+
+mStatus	SetupNiceName( mDNS * const inMDNS )
+{
+	HKEY		descKey = NULL;
+	char		utf8[ 256 ];
+	LPCTSTR		s;
+	LPWSTR		joinName;
+	NETSETUP_JOIN_STATUS joinStatus;
+	mStatus		err = 0;
+	DWORD		namelen;
+	BOOL		ok;
+	
+	check( inMDNS );
+	
+	// Set up the nice name.
+	utf8[0] = '\0';
+
+	// First try and open the registry key that contains the computer description value
+	s = TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters");
+	err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, s, 0, KEY_READ, &descKey);
+	check_translated_errno( err == 0, errno_compat(), kNameErr );
+
+	if ( !err )
+	{
+		TCHAR	desc[256];
+		DWORD	descSize = sizeof( desc );
+
+		// look for the computer description
+		err = RegQueryValueEx( descKey, TEXT("srvcomment"), 0, NULL, (LPBYTE) &desc, &descSize);
+		
+		if ( !err )
+		{
+			err = TCHARtoUTF8( desc, utf8, sizeof( utf8 ) );
+		}
+
+		if ( err )
+		{
+			utf8[ 0 ] = '\0';
+		}
+	}
+
+	// if we can't find it in the registry, then use the hostname of the machine
+	if ( err || ( utf8[ 0 ] == '\0' ) )
+	{
+		TCHAR hostname[256];
+		
+		namelen = sizeof( hostname ) / sizeof( TCHAR );
+
+		ok = GetComputerNameExW( ComputerNamePhysicalDnsHostname, hostname, &namelen );
+		err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
+		check_noerr( err );
+		
+		if( !err )
+		{
+			err = TCHARtoUTF8( hostname, utf8, sizeof( utf8 ) );
+		}
+
+		if ( err )
+		{
+			utf8[ 0 ] = '\0';
+		}
+	}
+
+	// if we can't get the hostname
+	if ( err || ( utf8[ 0 ] == '\0' ) )
+	{
+		// Invalidate name so fall back to a default name.
+		
+		strcpy( utf8, kMDNSDefaultName );
+	}
+
+	utf8[ sizeof( utf8 ) - 1 ]	= '\0';	
+	inMDNS->nicelabel.c[ 0 ]	= (mDNSu8) (strlen( utf8 ) < MAX_DOMAIN_LABEL ? strlen( utf8 ) : MAX_DOMAIN_LABEL);
+	memcpy( &inMDNS->nicelabel.c[ 1 ], utf8, inMDNS->nicelabel.c[ 0 ] );
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "nice name \"%.*s\"\n", inMDNS->nicelabel.c[ 0 ], &inMDNS->nicelabel.c[ 1 ] );
+	
+	if ( descKey )
+	{
+		RegCloseKey( descKey );
+	}
+
+	ZeroMemory( inMDNS->p->nbname, sizeof( inMDNS->p->nbname ) );
+	ZeroMemory( inMDNS->p->nbdomain, sizeof( inMDNS->p->nbdomain ) );
+
+	namelen = sizeof( inMDNS->p->nbname );
+	ok = GetComputerNameExA( ComputerNamePhysicalNetBIOS, inMDNS->p->nbname, &namelen );
+	check( ok );
+	if ( ok ) dlog( kDebugLevelInfo, DEBUG_NAME "netbios name \"%s\"\n", inMDNS->p->nbname );
+
+	err = NetGetJoinInformation( NULL, &joinName, &joinStatus );
+	check ( err == NERR_Success );
+	if ( err == NERR_Success )
+	{
+		if ( ( joinStatus == NetSetupWorkgroupName ) || ( joinStatus == NetSetupDomainName ) )
+		{
+			err = TCHARtoUTF8( joinName, inMDNS->p->nbdomain, sizeof( inMDNS->p->nbdomain ) );
+			check( !err );
+			if ( !err ) dlog( kDebugLevelInfo, DEBUG_NAME "netbios domain/workgroup \"%s\"\n", inMDNS->p->nbdomain );
+		}
+
+		NetApiBufferFree( joinName );
+		joinName = NULL;
+	}
+
+	err = 0;
+
+	return( err );
+}
+
+//===========================================================================================================================
+//	SetupHostName
+//===========================================================================================================================
+
+mDNSlocal mStatus	SetupHostName( mDNS * const inMDNS )
+{
+	mStatus		err = 0;
+	char		tempString[ 256 ];
+	DWORD		tempStringLen;
+	domainlabel tempLabel;
+	BOOL		ok;
+	
+	check( inMDNS );
+
+	// Set up the nice name.
+	tempString[ 0 ] = '\0';
+
+	// use the hostname of the machine
+	tempStringLen = sizeof( tempString );
+	ok = GetComputerNameExA( ComputerNamePhysicalDnsHostname, tempString, &tempStringLen );
+	err = translate_errno( ok, (mStatus) GetLastError(), kNameErr );
+	check_noerr( err );
+
+	// if we can't get the hostname
+	if( err || ( tempString[ 0 ] == '\0' ) )
+	{
+		// Invalidate name so fall back to a default name.
+		
+		strcpy( tempString, kMDNSDefaultName );
+	}
+
+	tempString[ sizeof( tempString ) - 1 ] = '\0';
+	tempLabel.c[ 0 ] = (mDNSu8) (strlen( tempString ) < MAX_DOMAIN_LABEL ? strlen( tempString ) : MAX_DOMAIN_LABEL );
+	memcpy( &tempLabel.c[ 1 ], tempString, tempLabel.c[ 0 ] );
+	
+	// Set up the host name.
+	
+	ConvertUTF8PstringToRFC1034HostLabel( tempLabel.c, &inMDNS->hostlabel );
+	if( inMDNS->hostlabel.c[ 0 ] == 0 )
+	{
+		// Nice name has no characters that are representable as an RFC1034 name (e.g. Japanese) so use the default.
+		
+		MakeDomainLabelFromLiteralString( &inMDNS->hostlabel, kMDNSDefaultName );
+	}
+
+	check( inMDNS->hostlabel.c[ 0 ] != 0 );
+	
+	mDNS_SetFQDN( inMDNS );
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "host name \"%.*s\"\n", inMDNS->hostlabel.c[ 0 ], &inMDNS->hostlabel.c[ 1 ] );
+	
+	return( err );
+}
+
+//===========================================================================================================================
+//	SetupName
+//===========================================================================================================================
+
+mDNSlocal mStatus	SetupName( mDNS * const inMDNS )
+{
+	mStatus		err = 0;
+	
+	check( inMDNS );
+	
+	err = SetupNiceName( inMDNS );
+	check_noerr( err );
+
+	err = SetupHostName( inMDNS );
+	check_noerr( err );
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	SetupInterfaceList
+//===========================================================================================================================
+
+mStatus	SetupInterfaceList( mDNS * const inMDNS )
+{
+	mStatus						err;
+	mDNSInterfaceData **		next;
+	mDNSInterfaceData *			ifd;
+	struct ifaddrs *			addrs;
+	struct ifaddrs *			p;
+	struct ifaddrs *			loopbackv4;
+	struct ifaddrs *			loopbackv6;
+	u_int						flagMask;
+	u_int						flagTest;
+	mDNSBool					foundv4;
+	mDNSBool					foundv6;
+	mDNSBool					foundUnicastSock4DestAddr;
+	mDNSBool					foundUnicastSock6DestAddr;
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list\n" );
+	check( inMDNS );
+	check( inMDNS->p );
+	
+	inMDNS->p->registeredLoopback4	= mDNSfalse;
+	inMDNS->p->nextDHCPLeaseExpires = 0x7FFFFFFF;
+	addrs							= NULL;
+	foundv4							= mDNSfalse;
+	foundv6							= mDNSfalse;
+	foundUnicastSock4DestAddr		= mDNSfalse;
+	foundUnicastSock6DestAddr		= mDNSfalse;
+	
+	// Tear down any existing interfaces that may be set up.
+	
+	TearDownInterfaceList( inMDNS );
+
+	// Set up the name of this machine.
+	
+	err = SetupName( inMDNS );
+	check_noerr( err );
+
+	// Set up IPv4 interface(s). We have to set up IPv4 first so any IPv6 interface with an IPv4-routable address
+	// can refer to the IPv4 interface when it registers to allow DNS AAAA records over the IPv4 interface.
+	
+	err = getifaddrs( &addrs );
+	require_noerr( err, exit );
+	
+	loopbackv4	= NULL;
+	loopbackv6	= NULL;
+	next		= &inMDNS->p->interfaceList;
+
+	flagMask = IFF_UP | IFF_MULTICAST;
+	flagTest = IFF_UP | IFF_MULTICAST;
+	
+#if( MDNS_WINDOWS_ENABLE_IPV4 )
+	for( p = addrs; p; p = p->ifa_next )
+	{
+		if( !p->ifa_addr || ( p->ifa_addr->sa_family != AF_INET ) || ( ( p->ifa_flags & flagMask ) != flagTest ) )
+		{
+			continue;
+		}
+		if( p->ifa_flags & IFF_LOOPBACK )
+		{
+			if( !loopbackv4 )
+			{
+				loopbackv4 = p;
+			}
+			continue;
+		}
+		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", 
+			p->ifa_name ? p->ifa_name : "<null>", p->ifa_extra.index, p->ifa_addr );
+		
+		err = SetupInterface( inMDNS, p, &ifd );
+		require_noerr( err, exit );
+
+		// If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
+		// register him, but we also want to note that we haven't found a v4 interface
+		// so that we register loopback so same host operations work
+ 		
+		if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
+		{
+			foundv4 = mDNStrue;
+		}
+
+		if ( p->ifa_dhcpEnabled && ( p->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
+		{
+			inMDNS->p->nextDHCPLeaseExpires = p->ifa_dhcpLeaseExpires;
+		}
+
+		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
+		// of determing the destination address of a packet that is sent to us.
+		// For multicast packets, that's easy to determine.  But for the unicast
+		// sockets, we'll fake it by taking the address of the first interface
+		// that is successfully setup.
+
+		if ( !foundUnicastSock4DestAddr )
+		{
+			inMDNS->p->unicastSock4.addr = ifd->interfaceInfo.ip;
+			foundUnicastSock4DestAddr = TRUE;
+		}
+			
+		*next = ifd;
+		next  = &ifd->next;
+		++inMDNS->p->interfaceCount;
+	}
+#endif
+	
+	// Set up IPv6 interface(s) after IPv4 is set up (see IPv4 notes above for reasoning).
+	
+#if( MDNS_WINDOWS_ENABLE_IPV6 )
+	for( p = addrs; p; p = p->ifa_next )
+	{
+		if( !p->ifa_addr || ( p->ifa_addr->sa_family != AF_INET6 ) || ( ( p->ifa_flags & flagMask ) != flagTest ) )
+		{
+			continue;
+		}
+		if( p->ifa_flags & IFF_LOOPBACK )
+		{
+			if( !loopbackv6 )
+			{
+				loopbackv6 = p;
+			}
+			continue;
+		}
+		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", 
+			p->ifa_name ? p->ifa_name : "<null>", p->ifa_extra.index, p->ifa_addr );
+		
+		err = SetupInterface( inMDNS, p, &ifd );
+		require_noerr( err, exit );
+				
+		// If this guy is point-to-point (ifd->interfaceInfo.McastTxRx == 0 ) we still want to
+		// register him, but we also want to note that we haven't found a v4 interface
+		// so that we register loopback so same host operations work
+ 		
+		if ( ifd->interfaceInfo.McastTxRx == mDNStrue )
+		{
+			foundv6 = mDNStrue;
+		}
+
+		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
+		// of determing the destination address of a packet that is sent to us.
+		// For multicast packets, that's easy to determine.  But for the unicast
+		// sockets, we'll fake it by taking the address of the first interface
+		// that is successfully setup.
+
+		if ( !foundUnicastSock6DestAddr )
+		{
+			inMDNS->p->unicastSock6.addr = ifd->interfaceInfo.ip;
+			foundUnicastSock6DestAddr = TRUE;
+		}
+
+		*next = ifd;
+		next  = &ifd->next;
+		++inMDNS->p->interfaceCount;
+	}
+#endif
+
+	// If there are no real interfaces, but there is a loopback interface, use that so same-machine operations work.
+
+#if( !MDNS_WINDOWS_ENABLE_IPV4 && !MDNS_WINDOWS_ENABLE_IPV6 )
+	
+	flagMask |= IFF_LOOPBACK;
+	flagTest |= IFF_LOOPBACK;
+	
+	for( p = addrs; p; p = p->ifa_next )
+	{
+		if( !p->ifa_addr || ( ( p->ifa_flags & flagMask ) != flagTest ) )
+		{
+			continue;
+		}
+		if( ( p->ifa_addr->sa_family != AF_INET ) && ( p->ifa_addr->sa_family != AF_INET6 ) )
+		{
+			continue;
+		}
+		
+		v4loopback = p;
+		break;
+	}
+	
+#endif
+	
+	if ( !foundv4 && loopbackv4 )
+	{
+		dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", 
+			loopbackv4->ifa_name ? loopbackv4->ifa_name : "<null>", loopbackv4->ifa_extra.index, loopbackv4->ifa_addr );
+		
+		err = SetupInterface( inMDNS, loopbackv4, &ifd );
+		require_noerr( err, exit );
+
+		inMDNS->p->registeredLoopback4 = mDNStrue;
+		
+#if( MDNS_WINDOWS_ENABLE_IPV4 )
+
+		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
+		// of determing the destination address of a packet that is sent to us.
+		// For multicast packets, that's easy to determine.  But for the unicast
+		// sockets, we'll fake it by taking the address of the first interface
+		// that is successfully setup.
+
+		if ( !foundUnicastSock4DestAddr )
+		{
+			inMDNS->p->unicastSock4.addr = ifd->sock.addr;
+			foundUnicastSock4DestAddr = TRUE;
+		}
+#endif
+
+		*next = ifd;
+		next  = &ifd->next;
+		++inMDNS->p->interfaceCount;
+	}
+
+	if ( !foundv6 && loopbackv6 )
+	{
+		dlog( kDebugLevelInfo, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", 
+			loopbackv6->ifa_name ? loopbackv6->ifa_name : "<null>", loopbackv6->ifa_extra.index, loopbackv6->ifa_addr );
+		
+		err = SetupInterface( inMDNS, loopbackv6, &ifd );
+		require_noerr( err, exit );
+		
+#if( MDNS_WINDOWS_ENABLE_IPV6 )
+
+		// If we're on a platform that doesn't have WSARecvMsg(), there's no way
+		// of determing the destination address of a packet that is sent to us.
+		// For multicast packets, that's easy to determine.  But for the unicast
+		// sockets, we'll fake it by taking the address of the first interface
+		// that is successfully setup.
+
+		if ( !foundUnicastSock6DestAddr )
+		{
+			inMDNS->p->unicastSock6.addr = ifd->sock.addr;
+			foundUnicastSock6DestAddr = TRUE;
+		}
+#endif
+
+		*next = ifd;
+		next  = &ifd->next;
+		++inMDNS->p->interfaceCount;
+	}
+
+	CheckFileShares( inMDNS );
+
+exit:
+	if( err )
+	{
+		TearDownInterfaceList( inMDNS );
+	}
+	if( addrs )
+	{
+		freeifaddrs( addrs );
+	}
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface list done (err=%d %m)\n", err, err );
+	return( err );
+}
+
+//===========================================================================================================================
+//	TearDownInterfaceList
+//===========================================================================================================================
+
+mStatus	TearDownInterfaceList( mDNS * const inMDNS )
+{
+	mDNSInterfaceData **		p;
+	mDNSInterfaceData *		ifd;
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "tearing down interface list\n" );
+	check( inMDNS );
+	check( inMDNS->p );
+
+	// Free any interfaces that were previously marked inactive and are no longer referenced by the mDNS cache.
+	// Interfaces are marked inactive, but not deleted immediately if they were still referenced by the mDNS cache
+	// so that remove events that occur after an interface goes away can still report the correct interface.
+
+	p = &inMDNS->p->inactiveInterfaceList;
+	while( *p )
+	{
+		ifd = *p;
+		if( NumCacheRecordsForInterfaceID( inMDNS, (mDNSInterfaceID) ifd ) > 0 )
+		{
+			p = &ifd->next;
+			continue;
+		}
+		
+		dlog( kDebugLevelInfo, DEBUG_NAME "freeing unreferenced, inactive interface %#p %#a\n", ifd, &ifd->interfaceInfo.ip );
+		*p = ifd->next;
+
+		QueueUserAPC( ( PAPCFUNC ) FreeInterface, inMDNS->p->mainThread, ( ULONG_PTR ) ifd );
+	}
+
+	// Tear down all the interfaces.
+	
+	while( inMDNS->p->interfaceList )
+	{
+		ifd = inMDNS->p->interfaceList;
+		inMDNS->p->interfaceList = ifd->next;
+		
+		TearDownInterface( inMDNS, ifd );
+	}
+	inMDNS->p->interfaceCount = 0;
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "tearing down interface list done\n" );
+	return( mStatus_NoError );
+}
+
+//===========================================================================================================================
+//	SetupInterface
+//===========================================================================================================================
+
+mDNSlocal mStatus	SetupInterface( mDNS * const inMDNS, const struct ifaddrs *inIFA, mDNSInterfaceData **outIFD )
+{
+	mDNSInterfaceData	*	ifd;
+	mDNSInterfaceData	*	p;
+	mStatus					err;
+	
+	ifd = NULL;
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface\n" );
+	check( inMDNS );
+	check( inMDNS->p );
+	check( inIFA );
+	check( inIFA->ifa_addr );
+	check( outIFD );
+	
+	// Allocate memory for the interface and initialize it.
+	
+	ifd = (mDNSInterfaceData *) calloc( 1, sizeof( *ifd ) );
+	require_action( ifd, exit, err = mStatus_NoMemoryErr );
+	ifd->sock.fd		= kInvalidSocketRef;
+	ifd->sock.overlapped.pending = FALSE;
+	ifd->sock.ifd		= ifd;
+	ifd->sock.next		= NULL;
+	ifd->sock.m			= inMDNS;
+	ifd->index			= inIFA->ifa_extra.index;
+	ifd->scopeID		= inIFA->ifa_extra.index;
+	check( strlen( inIFA->ifa_name ) < sizeof( ifd->name ) );
+	strncpy( ifd->name, inIFA->ifa_name, sizeof( ifd->name ) - 1 );
+	ifd->name[ sizeof( ifd->name ) - 1 ] = '\0';
+	
+	strncpy(ifd->interfaceInfo.ifname, inIFA->ifa_name, sizeof(ifd->interfaceInfo.ifname));
+	ifd->interfaceInfo.ifname[sizeof(ifd->interfaceInfo.ifname)-1] = 0;
+	
+	// We always send and receive using IPv4, but 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.
+	
+	ifd->interfaceInfo.McastTxRx   = ( ( inIFA->ifa_flags & IFF_MULTICAST ) && !( inIFA->ifa_flags & IFF_POINTTOPOINT ) ) ? mDNStrue : mDNSfalse;
+	ifd->interfaceInfo.InterfaceID = NULL;
+
+	for( p = inMDNS->p->interfaceList; p; p = p->next )
+	{
+		if ( strcmp( p->name, ifd->name ) == 0 )
+		{
+			if (!ifd->interfaceInfo.InterfaceID)
+			{
+				ifd->interfaceInfo.InterfaceID	= (mDNSInterfaceID) p;
+			}
+
+			if ( ( inIFA->ifa_addr->sa_family != AF_INET ) &&
+			     ( p->interfaceInfo.ip.type == mDNSAddrType_IPv4 ) &&
+			     ( p->interfaceInfo.ip.ip.v4.b[ 0 ] != 169 || p->interfaceInfo.ip.ip.v4.b[ 1 ] != 254 ) )
+			{
+				ifd->interfaceInfo.McastTxRx = mDNSfalse;
+			}
+
+			break;
+		}
+	}
+
+	if ( !ifd->interfaceInfo.InterfaceID )
+	{
+		ifd->interfaceInfo.InterfaceID = (mDNSInterfaceID) ifd;
+	}
+
+	// Set up a socket for this interface (if needed).
+	
+	if( ifd->interfaceInfo.McastTxRx )
+	{
+		DWORD size;
+			
+		err = SetupSocket( inMDNS, inIFA->ifa_addr, MulticastDNSPort, &ifd->sock.fd );
+		require_noerr( err, exit );
+		ifd->sock.addr = ( inIFA->ifa_addr->sa_family == AF_INET6 ) ? AllDNSLinkGroup_v6 : AllDNSLinkGroup_v4;
+		ifd->sock.port = MulticastDNSPort;
+		
+		// Get a ptr to the WSARecvMsg function, if supported. Otherwise, we'll fallback to recvfrom.
+
+		err = WSAIoctl( ifd->sock.fd, SIO_GET_EXTENSION_FUNCTION_POINTER, &kWSARecvMsgGUID, sizeof( kWSARecvMsgGUID ), &ifd->sock.recvMsgPtr, sizeof( ifd->sock.recvMsgPtr ), &size, NULL, NULL );
+
+		if ( err )
+		{
+			ifd->sock.recvMsgPtr = NULL;
+		}
+	}
+
+	if ( inIFA->ifa_dhcpEnabled && ( inIFA->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
+	{
+		inMDNS->p->nextDHCPLeaseExpires = inIFA->ifa_dhcpLeaseExpires;
+	}
+
+	ifd->interfaceInfo.NetWake = inIFA->ifa_womp;
+
+	// Register this interface with mDNS.
+	
+	err = SockAddrToMDNSAddr( inIFA->ifa_addr, &ifd->interfaceInfo.ip, NULL );
+	require_noerr( err, exit );
+	
+	err = SockAddrToMDNSAddr( inIFA->ifa_netmask, &ifd->interfaceInfo.mask, NULL );
+	require_noerr( err, exit );
+
+	memcpy( ifd->interfaceInfo.MAC.b, inIFA->ifa_physaddr, sizeof( ifd->interfaceInfo.MAC.b ) );
+	
+	ifd->interfaceInfo.Advertise = ( mDNSu8 ) inMDNS->AdvertiseLocalAddresses;
+
+	if ( ifd->sock.fd != kInvalidSocketRef )
+	{
+		err = UDPBeginRecv( &ifd->sock );
+		require_noerr( err, exit );
+	}
+
+	err = mDNS_RegisterInterface( inMDNS, &ifd->interfaceInfo, mDNSfalse );
+	require_noerr( err, exit );
+	ifd->hostRegistered = mDNStrue;
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "Registered interface %##a with mDNS\n", inIFA->ifa_addr );
+	
+	// Success!
+	
+	*outIFD = ifd;
+	ifd = NULL;
+	
+exit:
+
+	if( ifd )
+	{
+		TearDownInterface( inMDNS, ifd );
+	}
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up interface done (err=%d %m)\n", err, err );
+	return( err );
+}
+
+//===========================================================================================================================
+//	TearDownInterface
+//===========================================================================================================================
+
+mDNSlocal mStatus	TearDownInterface( mDNS * const inMDNS, mDNSInterfaceData *inIFD )
+{	
+	check( inMDNS );
+	check( inIFD );
+	
+	// Deregister this interface with mDNS.
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "Deregistering interface %#a with mDNS\n", &inIFD->interfaceInfo.ip );
+	
+	if( inIFD->hostRegistered )
+	{
+		inIFD->hostRegistered = mDNSfalse;
+		mDNS_DeregisterInterface( inMDNS, &inIFD->interfaceInfo, mDNSfalse );
+	}
+	
+	// Tear down the multicast socket.
+	
+	UDPCloseSocket( &inIFD->sock );
+
+	// If the interface is still referenced by items in the mDNS cache then put it on the inactive list. This keeps 
+	// the InterfaceID valid so remove events report the correct interface. If it is no longer referenced, free it.
+
+	if( NumCacheRecordsForInterfaceID( inMDNS, (mDNSInterfaceID) inIFD ) > 0 )
+	{
+		inIFD->next = inMDNS->p->inactiveInterfaceList;
+		inMDNS->p->inactiveInterfaceList = inIFD;
+		dlog( kDebugLevelInfo, DEBUG_NAME "deferring free of interface %#p %#a\n", inIFD, &inIFD->interfaceInfo.ip );
+	}
+	else
+	{
+		dlog( kDebugLevelInfo, DEBUG_NAME "freeing interface %#p %#a immediately\n", inIFD, &inIFD->interfaceInfo.ip );
+		QueueUserAPC( ( PAPCFUNC ) FreeInterface, inMDNS->p->mainThread, ( ULONG_PTR ) inIFD );
+	}
+
+	return( mStatus_NoError );
+}
+
+mDNSlocal void CALLBACK FreeInterface( mDNSInterfaceData *inIFD )
+{
+	free( inIFD );
+}
+
+//===========================================================================================================================
+//	SetupSocket
+//===========================================================================================================================
+
+mDNSlocal mStatus	SetupSocket( mDNS * const inMDNS, const struct sockaddr *inAddr, mDNSIPPort port, SocketRef *outSocketRef  )
+{
+	mStatus			err;
+	SocketRef		sock;
+	int				option;
+	DWORD			bytesReturned = 0;
+	BOOL			behavior = FALSE;
+	
+	DEBUG_UNUSED( inMDNS );
+	
+	dlog( kDebugLevelTrace, DEBUG_NAME "setting up socket %##a\n", inAddr );
+	check( inMDNS );
+	check( outSocketRef );
+	
+	// Set up an IPv4 or IPv6 UDP socket.
+	
+	sock = socket( inAddr->sa_family, SOCK_DGRAM, IPPROTO_UDP );
+	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+		
+	// Turn on reuse address option so multiple servers can listen for Multicast DNS packets,
+	// if we're creating a multicast socket
+	
+	if ( port.NotAnInteger )
+	{
+		option = 1;
+		err = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+	}
+
+	// <rdar://problem/7894393> Bonjour for Windows broken on Windows XP
+	//
+	// Not sure why, but the default behavior for sockets is to behave incorrectly
+	// when using them in Overlapped I/O mode on XP. According to MSDN:
+	//
+	// SIO_UDP_CONNRESET (opcode setting: I, T==3)
+	//     Windows XP:  Controls whether UDP PORT_UNREACHABLE messages are reported. Set to TRUE to enable reporting.
+	//     Set to FALSE to disable reporting.
+	//
+	// Packet traces from misbehaving Bonjour installations showed that ICMP port unreachable
+	// messages were being sent to us after we sent out packets to a multicast address. This is clearly
+	// incorrect behavior, but should be harmless. However, after receiving a port unreachable error, WinSock
+	// will no longer receive any packets from that socket, which is not harmless. This behavior is only
+	// seen on XP.
+	//
+	// So we turn off port unreachable reporting to make sure our sockets that are reading
+	// multicast packets function correctly under all circumstances.
+
+	err = WSAIoctl( sock, SIO_UDP_CONNRESET, &behavior, sizeof(behavior), NULL, 0, &bytesReturned, NULL, NULL );
+	check_translated_errno( err == 0, errno_compat(), kOptionErr );
+
+	if( inAddr->sa_family == AF_INET )
+	{
+		mDNSv4Addr				ipv4;
+		struct sockaddr_in		sa4;
+		struct ip_mreq			mreqv4;
+		
+		// Bind the socket to the desired port
+		
+		ipv4.NotAnInteger 	= ( (const struct sockaddr_in *) inAddr )->sin_addr.s_addr;
+		mDNSPlatformMemZero( &sa4, sizeof( sa4 ) );
+		sa4.sin_family 		= AF_INET;
+		sa4.sin_port 		= port.NotAnInteger;
+		sa4.sin_addr.s_addr	= ipv4.NotAnInteger;
+		
+		err = bind( sock, (struct sockaddr *) &sa4, sizeof( sa4 ) );
+		check_translated_errno( err == 0, errno_compat(), kUnknownErr );
+		
+		// Turn on option to receive destination addresses and receiving interface.
+		
+		option = 1;
+		err = setsockopt( sock, IPPROTO_IP, IP_PKTINFO, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		
+		if (port.NotAnInteger)
+		{
+			// Join the all-DNS multicast group so we receive Multicast DNS packets
+
+			mreqv4.imr_multiaddr.s_addr = AllDNSLinkGroup_v4.ip.v4.NotAnInteger;
+			mreqv4.imr_interface.s_addr = ipv4.NotAnInteger;
+			err = setsockopt( sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &mreqv4, sizeof( mreqv4 ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		
+			// Specify the interface to send multicast packets on this socket.
+		
+			sa4.sin_addr.s_addr = ipv4.NotAnInteger;
+			err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_IF, (char *) &sa4.sin_addr, sizeof( sa4.sin_addr ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		
+			// Enable multicast loopback so we receive multicast packets we send (for same-machine operations).
+		
+			option = 1;
+			err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &option, sizeof( option ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		}
+
+		// Send unicast packets with TTL 255 (helps against spoofing).
+		
+		option = 255;
+		err = setsockopt( sock, IPPROTO_IP, IP_TTL, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+
+		// Send multicast packets with TTL 255 (helps against spoofing).
+		
+		option = 255;
+		err = setsockopt( sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+
+	}
+	else if( inAddr->sa_family == AF_INET6 )
+	{
+		struct sockaddr_in6 *		sa6p;
+		struct sockaddr_in6			sa6;
+		struct ipv6_mreq			mreqv6;
+		
+		sa6p = (struct sockaddr_in6 *) inAddr;
+		
+		// Bind the socket to the desired port
+		
+		mDNSPlatformMemZero( &sa6, sizeof( sa6 ) );
+		sa6.sin6_family		= AF_INET6;
+		sa6.sin6_port		= port.NotAnInteger;
+		sa6.sin6_flowinfo	= 0;
+		sa6.sin6_addr		= sa6p->sin6_addr;
+		sa6.sin6_scope_id	= sa6p->sin6_scope_id;
+		
+		err = bind( sock, (struct sockaddr *) &sa6, sizeof( sa6 ) );
+		check_translated_errno( err == 0, errno_compat(), kUnknownErr );
+		
+		// Turn on option to receive destination addresses and receiving interface.
+		
+		option = 1;
+		err = setsockopt( sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		
+		// We only want to receive IPv6 packets (not IPv4-mapped IPv6 addresses) because we have a separate socket 
+		// for IPv4, but the IPv6 stack in Windows currently doesn't support IPv4-mapped IPv6 addresses and doesn't
+		// support the IPV6_V6ONLY socket option so the following code would typically not be executed (or needed).
+		
+		#if( defined( IPV6_V6ONLY ) )
+			option = 1;
+			err = setsockopt( sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &option, sizeof( option ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );		
+		#endif
+		
+		if ( port.NotAnInteger )
+		{
+			// Join the all-DNS multicast group so we receive Multicast DNS packets.
+		
+			mreqv6.ipv6mr_multiaddr = *( (struct in6_addr *) &AllDNSLinkGroup_v6.ip.v6 );
+			mreqv6.ipv6mr_interface = sa6p->sin6_scope_id;
+			err = setsockopt( sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *) &mreqv6, sizeof( mreqv6 ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		
+			// Specify the interface to send multicast packets on this socket.
+		
+			option = (int) sa6p->sin6_scope_id;
+			err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &option, sizeof( option ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		
+			// Enable multicast loopback so we receive multicast packets we send (for same-machine operations).
+			
+			option = 1;
+			err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &option, sizeof( option ) );
+			check_translated_errno( err == 0, errno_compat(), kOptionErr );
+		}
+
+		// Send unicast packets with TTL 255 (helps against spoofing).
+		
+		option = 255;
+		err = setsockopt( sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+
+		// Send multicast packets with TTL 255 (helps against spoofing).
+			
+		option = 255;
+		err = setsockopt( sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &option, sizeof( option ) );
+		check_translated_errno( err == 0, errno_compat(), kOptionErr );
+	}
+	else
+	{
+		dlog( kDebugLevelError, DEBUG_NAME "%s: unsupport socket family (%d)\n", __ROUTINE__, inAddr->sa_family );
+		err = kUnsupportedErr;
+		goto exit;
+	}
+	
+	// Success!
+	
+	*outSocketRef = sock;
+	sock = kInvalidSocketRef;
+	err = mStatus_NoError;
+	
+exit:
+	if( IsValidSocket( sock ) )
+	{
+		close_compat( sock );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	SetupSocket
+//===========================================================================================================================
+
+mDNSlocal mStatus	SockAddrToMDNSAddr( const struct sockaddr * const inSA, mDNSAddr *outIP, mDNSIPPort *outPort )
+{
+	mStatus		err;
+	
+	check( inSA );
+	check( outIP );
+	
+	if( inSA->sa_family == AF_INET )
+	{
+		struct sockaddr_in *		sa4;
+		
+		sa4 						= (struct sockaddr_in *) inSA;
+		outIP->type 				= mDNSAddrType_IPv4;
+		outIP->ip.v4.NotAnInteger	= sa4->sin_addr.s_addr;
+		if( outPort )
+		{
+			outPort->NotAnInteger	= sa4->sin_port;
+		}
+		err = mStatus_NoError;
+	}
+	else if( inSA->sa_family == AF_INET6 )
+	{
+		struct sockaddr_in6 *		sa6;
+		
+		sa6 			= (struct sockaddr_in6 *) inSA;
+		outIP->type 	= mDNSAddrType_IPv6;
+		outIP->ip.v6 	= *( (mDNSv6Addr *) &sa6->sin6_addr );
+		if( IN6_IS_ADDR_LINKLOCAL( &sa6->sin6_addr ) )
+		{
+			outIP->ip.v6.w[ 1 ] = 0;
+		}
+		if( outPort )
+		{
+			outPort->NotAnInteger = sa6->sin6_port;
+		}
+		err = mStatus_NoError;
+	}
+	else
+	{
+		dlog( kDebugLevelError, DEBUG_NAME "%s: invalid sa_family %d", __ROUTINE__, inSA->sa_family );
+		err = mStatus_BadParamErr;
+	}
+	return( err );
+}
+
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	UDPBeginRecv
+//===========================================================================================================================
+
+mDNSlocal OSStatus UDPBeginRecv( UDPSocket * sock )
+{
+	DWORD	size;
+	DWORD	numTries;
+	mStatus	err;
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
+	
+	require_action( sock != NULL, exit, err = mStatus_BadStateErr );
+	check( !sock->overlapped.pending );
+	
+	// Initialize the buffer structure
+
+	sock->overlapped.wbuf.buf	= (char *) &sock->packet;
+	sock->overlapped.wbuf.len	= (u_long) sizeof( sock->packet );
+	sock->srcAddrLen			= sizeof( sock->srcAddr );
+
+	// Initialize the overlapped structure
+
+	ZeroMemory( &sock->overlapped.data, sizeof( OVERLAPPED ) );
+	sock->overlapped.data.hEvent = sock;
+
+	numTries = 0;
+
+	do
+	{
+		if ( sock->recvMsgPtr )
+		{
+			sock->wmsg.name				= ( LPSOCKADDR ) &sock->srcAddr;
+			sock->wmsg.namelen			= sock->srcAddrLen;
+			sock->wmsg.lpBuffers		= &sock->overlapped.wbuf;
+			sock->wmsg.dwBufferCount	= 1;
+			sock->wmsg.Control.buf		= ( CHAR* ) sock->controlBuffer;
+			sock->wmsg.Control.len		= sizeof( sock->controlBuffer );
+			sock->wmsg.dwFlags			= 0;
+
+			err = sock->recvMsgPtr( sock->fd, &sock->wmsg, &size, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) UDPEndRecv );
+			err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), (OSStatus) WSAGetLastError(), kUnknownErr ); 
+
+			// <rdar://problem/7824093> iTunes 9.1 fails to install with Bonjour service on Windows 7 Ultimate
+			//
+			// There seems to be a bug in some network device drivers that involves calling WSARecvMsg() in
+			// overlapped i/o mode. Although all the parameters to WSARecvMsg() are correct, it returns a
+			// WSAEFAULT error code when there is no actual error. We have found experientially that falling
+			// back to using WSARecvFrom() when this happens will work correctly.
+
+			if ( err == WSAEFAULT ) sock->recvMsgPtr = NULL;
+		}
+		else
+		{
+			DWORD flags = 0;
+
+			err = WSARecvFrom( sock->fd, &sock->overlapped.wbuf, 1, NULL, &flags, ( LPSOCKADDR ) &sock->srcAddr, &sock->srcAddrLen, &sock->overlapped.data, ( LPWSAOVERLAPPED_COMPLETION_ROUTINE ) UDPEndRecv );
+			err = translate_errno( ( err == 0 ) || ( WSAGetLastError() == WSA_IO_PENDING ), ( OSStatus ) WSAGetLastError(), kUnknownErr );
+		}
+
+		// According to MSDN <http://msdn.microsoft.com/en-us/library/ms741687(VS.85).aspx>:
+		//
+		// "WSAECONNRESET: For a UDP datagram socket, this error would indicate that a previous
+		//                 send operation resulted in an ICMP "Port Unreachable" message."
+		//
+		// Because this is the case, we want to ignore this error and try again.  Just in case
+		// this is some kind of pathological condition, we'll break out of the retry loop 
+		// after 100 iterations
+
+		require_action( !err || ( err == WSAECONNRESET ) || ( err == WSAEFAULT ), exit, err = WSAGetLastError() );
+	}
+	while ( ( ( err == WSAECONNRESET ) || ( err == WSAEFAULT ) ) && ( numTries++ < 100 ) );
+
+	sock->overlapped.pending = TRUE;
+
+exit:
+
+	if ( err )
+	{
+		LogMsg( "WSARecvMsg failed (%d)\n", err );
+	}
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	UDPEndRecv
+//===========================================================================================================================
+
+mDNSlocal void CALLBACK UDPEndRecv( DWORD err, DWORD bytesTransferred, LPWSAOVERLAPPED overlapped, DWORD flags )
+{
+	UDPSocket * sock = NULL;
+
+	( void ) flags;
+	
+	dlog( kDebugLevelChatty, DEBUG_NAME "%s: err = %d, bytesTransferred = %d\n", __ROUTINE__, err, bytesTransferred );
+	require_action_quiet( err != WSA_OPERATION_ABORTED, exit, err = ( DWORD ) kUnknownErr );
+	require_noerr( err, exit );
+	sock = ( overlapped != NULL ) ? overlapped->hEvent : NULL;
+	require_action( sock != NULL, exit, err = ( DWORD ) kUnknownErr );
+	dlog( kDebugLevelChatty, DEBUG_NAME "%s: sock = %d\n", __ROUTINE__, sock->fd );
+	sock->overlapped.error				= err;
+	sock->overlapped.bytesTransferred	= bytesTransferred;
+	check( sock->overlapped.pending );
+	sock->overlapped.pending			= FALSE;
+	
+	// Translate the source of this packet into mDNS data types
+
+	SockAddrToMDNSAddr( (struct sockaddr *) &sock->srcAddr, &sock->overlapped.srcAddr, &sock->overlapped.srcPort );
+	
+	// Initialize the destination of this packet. Just in case
+	// we can't determine this info because we couldn't call
+	// WSARecvMsg (recvMsgPtr)
+
+	sock->overlapped.dstAddr = sock->addr;
+	sock->overlapped.dstPort = sock->port;
+
+	if ( sock->recvMsgPtr )
+	{
+		LPWSACMSGHDR	header;
+		LPWSACMSGHDR	last = NULL;
+		int				count = 0;
+		
+		// Parse the control information. Reject packets received on the wrong interface.
+		
+		// <rdar://problem/7832196> INSTALL: Bonjour 2.0 on Windows can not start / stop
+		// 
+		// There seems to be an interaction between Bullguard and this next bit of code.
+		// When a user's machine is running Bullguard, the control information that is
+		// returned is corrupted, and the code would go into an infinite loop. We'll add
+		// two bits of defensive coding here. The first will check that each pointer to
+		// the LPWSACMSGHDR that is returned in the for loop is different than the last.
+		// This fixes the problem with Bullguard. The second will break out of this loop
+		// after 100 iterations, just in case the corruption isn't caught by the first
+		// check.
+
+		for ( header = WSA_CMSG_FIRSTHDR( &sock->wmsg ); header; header = WSA_CMSG_NXTHDR( &sock->wmsg, header ) )
+		{
+			if ( ( header != last ) && ( ++count < 100 ) )
+			{
+				last = header;
+					
+				if ( ( header->cmsg_level == IPPROTO_IP ) && ( header->cmsg_type == IP_PKTINFO ) )
+				{
+					IN_PKTINFO * ipv4PacketInfo;
+					
+					ipv4PacketInfo = (IN_PKTINFO *) WSA_CMSG_DATA( header );
+
+					if ( sock->ifd != NULL )
+					{
+						require_action( ipv4PacketInfo->ipi_ifindex == sock->ifd->index, exit, err = ( DWORD ) kMismatchErr );
+					}
+
+					sock->overlapped.dstAddr.type 				= mDNSAddrType_IPv4;
+					sock->overlapped.dstAddr.ip.v4.NotAnInteger	= ipv4PacketInfo->ipi_addr.s_addr;
+				}
+				else if( ( header->cmsg_level == IPPROTO_IPV6 ) && ( header->cmsg_type == IPV6_PKTINFO ) )
+				{
+					IN6_PKTINFO * ipv6PacketInfo;
+						
+					ipv6PacketInfo = (IN6_PKTINFO *) WSA_CMSG_DATA( header );
+		
+					if ( sock->ifd != NULL )
+					{
+						require_action( ipv6PacketInfo->ipi6_ifindex == ( sock->ifd->index - kIPv6IfIndexBase ), exit, err = ( DWORD ) kMismatchErr );
+					}
+
+					sock->overlapped.dstAddr.type	= mDNSAddrType_IPv6;
+					sock->overlapped.dstAddr.ip.v6	= *( (mDNSv6Addr *) &ipv6PacketInfo->ipi6_addr );
+				}
+			}
+			else
+			{
+				static BOOL loggedMessage = FALSE;
+
+				if ( !loggedMessage )
+				{
+					LogMsg( "UDPEndRecv: WSARecvMsg control information error." );
+					loggedMessage = TRUE;
+				}
+
+				break;
+			}
+		}
+	}
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "packet received\n" );
+	dlog( kDebugLevelChatty, DEBUG_NAME "    size      = %d\n", bytesTransferred );
+	dlog( kDebugLevelChatty, DEBUG_NAME "    src       = %#a:%u\n", &sock->overlapped.srcAddr, ntohs( sock->overlapped.srcPort.NotAnInteger ) );
+	dlog( kDebugLevelChatty, DEBUG_NAME "    dst       = %#a:%u\n", &sock->overlapped.dstAddr, ntohs( sock->overlapped.dstPort.NotAnInteger ) );
+	
+	if ( sock->ifd != NULL )
+	{
+		dlog( kDebugLevelChatty, DEBUG_NAME "    interface = %#a (index=0x%08X)\n", &sock->ifd->interfaceInfo.ip, sock->ifd->index );
+	}
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "\n" );
+
+	// Queue this socket
+	
+	AddToTail( &gUDPDispatchableSockets, sock );
+
+exit:
+
+	return;
+}
+
+
+//===========================================================================================================================
+//	InterfaceListDidChange
+//===========================================================================================================================
+void InterfaceListDidChange( mDNS * const inMDNS )
+{
+	mStatus err;
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "interface list changed\n" );
+	check( inMDNS );
+	
+	// Tear down the existing interfaces and set up new ones using the new IP info.
+	
+	err = TearDownInterfaceList( inMDNS );
+	check_noerr( err );
+	
+	err = SetupInterfaceList( inMDNS );
+	check_noerr( err );
+		
+	err = uDNS_SetupDNSConfig( inMDNS );
+	check_noerr( err );
+	
+	// Inform clients of the change.
+	
+	mDNS_ConfigChanged(inMDNS);
+	
+	// Force mDNS to update.
+	
+	mDNSCoreMachineSleep( inMDNS, mDNSfalse ); // What is this for? Mac OS X does not do this
+}
+
+
+//===========================================================================================================================
+//	ComputerDescriptionDidChange
+//===========================================================================================================================
+void ComputerDescriptionDidChange( mDNS * const inMDNS )
+{	
+	dlog( kDebugLevelInfo, DEBUG_NAME "computer description has changed\n" );
+	check( inMDNS );
+
+	// redo the names
+	SetupNiceName( inMDNS );
+}
+
+
+//===========================================================================================================================
+//	TCPIPConfigDidChange
+//===========================================================================================================================
+void TCPIPConfigDidChange( mDNS * const inMDNS )
+{
+	mStatus		err;
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "TCP/IP config has changed\n" );
+	check( inMDNS );
+
+	err = uDNS_SetupDNSConfig( inMDNS );
+	check_noerr( err );
+}
+
+
+//===========================================================================================================================
+//	DynDNSConfigDidChange
+//===========================================================================================================================
+void DynDNSConfigDidChange( mDNS * const inMDNS )
+{
+	mStatus		err;
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "DynDNS config has changed\n" );
+	check( inMDNS );
+
+	SetDomainSecrets( inMDNS );
+
+	err = uDNS_SetupDNSConfig( inMDNS );
+	check_noerr( err );
+}
+
+
+//===========================================================================================================================
+//	FileSharingDidChange
+//===========================================================================================================================
+void FileSharingDidChange( mDNS * const inMDNS )
+{	
+	dlog( kDebugLevelInfo, DEBUG_NAME "File shares has changed\n" );
+	check( inMDNS );
+
+	CheckFileShares( inMDNS );
+}
+
+
+//===========================================================================================================================
+//	FilewallDidChange
+//===========================================================================================================================
+void FirewallDidChange( mDNS * const inMDNS )
+{	
+	dlog( kDebugLevelInfo, DEBUG_NAME "Firewall has changed\n" );
+	check( inMDNS );
+
+	CheckFileShares( inMDNS );
+}
+
+
+#if 0
+#pragma mark -
+#pragma mark == Utilities ==
+#endif
+
+//===========================================================================================================================
+//	getifaddrs
+//===========================================================================================================================
+
+mDNSlocal int	getifaddrs( struct ifaddrs **outAddrs )
+{
+	int		err;
+	
+#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
+	
+	// Try to the load the GetAdaptersAddresses function from the IP Helpers DLL. This API is only available on Windows
+	// XP or later. Looking up the symbol at runtime allows the code to still work on older systems without that API.
+	
+	if( !gIPHelperLibraryInstance )
+	{
+		gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
+		if( gIPHelperLibraryInstance )
+		{
+			gGetAdaptersAddressesFunctionPtr = 
+				(GetAdaptersAddressesFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetAdaptersAddresses" );
+			if( !gGetAdaptersAddressesFunctionPtr )
+			{
+				BOOL		ok;
+				
+				ok = FreeLibrary( gIPHelperLibraryInstance );
+				check_translated_errno( ok, GetLastError(), kUnknownErr );
+				gIPHelperLibraryInstance = NULL;
+			}
+		}
+	}
+	
+	// Use the new IPv6-capable routine if supported. Otherwise, fall back to the old and compatible IPv4-only code.
+	// <rdar://problem/4278934>  Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 fails
+	// <rdar://problem/6145913>  Fall back to using getifaddrs_ipv4 if getifaddrs_ipv6 returns no addrs
+
+	if( !gGetAdaptersAddressesFunctionPtr || ( ( ( err = getifaddrs_ipv6( outAddrs ) ) != mStatus_NoError ) || ( ( outAddrs != NULL ) && ( *outAddrs == NULL ) ) ) )
+	{
+		err = getifaddrs_ipv4( outAddrs );
+		require_noerr( err, exit );
+	}
+	
+#else
+
+	err = getifaddrs_ipv4( outAddrs );
+	require_noerr( err, exit );
+
+#endif
+
+exit:
+	return( err );
+}
+
+#if( MDNS_WINDOWS_USE_IPV6_IF_ADDRS )
+//===========================================================================================================================
+//	getifaddrs_ipv6
+//===========================================================================================================================
+
+mDNSlocal int	getifaddrs_ipv6( struct ifaddrs **outAddrs )
+{
+	DWORD						err;
+	int							i;
+	DWORD						flags;
+	struct ifaddrs *			head;
+	struct ifaddrs **			next;
+	IP_ADAPTER_ADDRESSES *		iaaList;
+	ULONG						iaaListSize;
+	IP_ADAPTER_ADDRESSES *		iaa;
+	size_t						size;
+	struct ifaddrs *			ifa;
+	
+	check( gGetAdaptersAddressesFunctionPtr );
+	
+	head	= NULL;
+	next	= &head;
+	iaaList	= NULL;
+	
+	// Get the list of interfaces. The first call gets the size and the second call gets the actual data.
+	// This loops to handle the case where the interface changes in the window after getting the size, but before the
+	// second call completes. A limit of 100 retries is enforced to prevent infinite loops if something else is wrong.
+	
+	flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
+	i = 0;
+	for( ;; )
+	{
+		iaaListSize = 0;
+		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, NULL, &iaaListSize );
+		check( err == ERROR_BUFFER_OVERFLOW );
+		check( iaaListSize >= sizeof( IP_ADAPTER_ADDRESSES ) );
+		
+		iaaList = (IP_ADAPTER_ADDRESSES *) malloc( iaaListSize );
+		require_action( iaaList, exit, err = ERROR_NOT_ENOUGH_MEMORY );
+		
+		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, iaaList, &iaaListSize );
+		if( err == ERROR_SUCCESS ) break;
+		
+		free( iaaList );
+		iaaList = NULL;
+		++i;
+		require( i < 100, exit );
+		dlog( kDebugLevelWarning, "%s: retrying GetAdaptersAddresses after %d failure(s) (%d %m)\n", __ROUTINE__, i, err, err );
+	}
+	
+	for( iaa = iaaList; iaa; iaa = iaa->Next )
+	{
+		int								addrIndex;
+		IP_ADAPTER_UNICAST_ADDRESS	*	addr;
+		DWORD							ipv6IfIndex;
+		IP_ADAPTER_PREFIX			*	firstPrefix;
+
+		if( iaa->IfIndex > 0xFFFFFF )
+		{
+			dlog( kDebugLevelAlert, DEBUG_NAME "%s: IPv4 ifindex out-of-range (0x%08X)\n", __ROUTINE__, iaa->IfIndex );
+		}
+		if( iaa->Ipv6IfIndex > 0xFF )
+		{
+			dlog( kDebugLevelAlert, DEBUG_NAME "%s: IPv6 ifindex out-of-range (0x%08X)\n", __ROUTINE__, iaa->Ipv6IfIndex );
+		}
+
+		// For IPv4 interfaces, there seems to be a bug in iphlpapi.dll that causes the 
+		// following code to crash when iterating through the prefix list.  This seems
+		// to occur when iaa->Ipv6IfIndex != 0 when IPv6 is not installed on the host.
+		// This shouldn't happen according to Microsoft docs which states:
+		//
+		//     "Ipv6IfIndex contains 0 if IPv6 is not available on the interface."
+		//
+		// So the data structure seems to be corrupted when we return from
+		// GetAdaptersAddresses(). The bug seems to occur when iaa->Length <
+		// sizeof(IP_ADAPTER_ADDRESSES), so when that happens, we'll manually
+		// modify iaa to have the correct values.
+
+		if ( iaa->Length >= sizeof( IP_ADAPTER_ADDRESSES ) )
+		{
+			ipv6IfIndex = iaa->Ipv6IfIndex;
+			firstPrefix = iaa->FirstPrefix;
+		}
+		else
+		{
+			ipv6IfIndex	= 0;
+			firstPrefix = NULL;
+		}
+
+		// Skip pseudo and tunnel interfaces.
+		
+		if( ( ( ipv6IfIndex == 1 ) && ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
+		{
+			continue;
+		}
+		
+		// Add each address as a separate interface to emulate the way getifaddrs works.
+		
+		for( addrIndex = 0, addr = iaa->FirstUnicastAddress; addr; ++addrIndex, addr = addr->Next )
+		{			
+			int						family;
+			int						prefixIndex;
+			IP_ADAPTER_PREFIX *		prefix;
+			ULONG					prefixLength;
+			uint32_t				ipv4Index;
+			struct sockaddr_in		ipv4Netmask;
+
+			family = addr->Address.lpSockaddr->sa_family;
+			if( ( family != AF_INET ) && ( family != AF_INET6 ) ) continue;
+			
+			// <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
+			// Seems as if the problem here is a buggy implementation of some network interface
+			// driver. It is reporting that is has a link-local address when it is actually
+			// disconnected. This was causing a problem in AddressToIndexAndMask.
+			// The solution is to call AddressToIndexAndMask first, and if unable to lookup
+			// the address, to ignore that address.
+
+			ipv4Index = 0;
+			memset( &ipv4Netmask, 0, sizeof( ipv4Netmask ) );
+			
+			if ( family == AF_INET )
+			{
+				err = AddressToIndexAndMask( addr->Address.lpSockaddr, &ipv4Index, ( struct sockaddr* ) &ipv4Netmask );
+				
+				if ( err )
+				{
+					err = 0;
+					continue;
+				}
+			}
+
+			ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
+			require_action( ifa, exit, err = WSAENOBUFS );
+			
+			*next = ifa;
+			next  = &ifa->ifa_next;
+			
+			// Get the name.
+			
+			size = strlen( iaa->AdapterName ) + 1;
+			ifa->ifa_name = (char *) malloc( size );
+			require_action( ifa->ifa_name, exit, err = WSAENOBUFS );
+			memcpy( ifa->ifa_name, iaa->AdapterName, size );
+			
+			// Get interface flags.
+			
+			ifa->ifa_flags = 0;
+			if( iaa->OperStatus == IfOperStatusUp ) 		ifa->ifa_flags |= IFF_UP;
+			if( iaa->IfType == IF_TYPE_SOFTWARE_LOOPBACK )	ifa->ifa_flags |= IFF_LOOPBACK;
+			else if ( IsPointToPoint( addr ) )				ifa->ifa_flags |= IFF_POINTTOPOINT;
+			if( !( iaa->Flags & IP_ADAPTER_NO_MULTICAST ) )	ifa->ifa_flags |= IFF_MULTICAST;
+
+			
+			// <rdar://problem/4045657> Interface index being returned is 512
+			//
+			// Windows does not have a uniform scheme for IPv4 and IPv6 interface indexes.
+			// This code used to shift the IPv4 index up to ensure uniqueness between
+			// it and IPv6 indexes.  Although this worked, it was somewhat confusing to developers, who
+			// then see interface indexes passed back that don't correspond to anything
+			// that is seen in Win32 APIs or command line tools like "route".  As a relatively
+			// small percentage of developers are actively using IPv6, it seems to 
+			// make sense to make our use of IPv4 as confusion free as possible.
+			// So now, IPv6 interface indexes will be shifted up by a
+			// constant value which will serve to uniquely identify them, and we will
+			// leave IPv4 interface indexes unmodified.
+			
+			switch( family )
+			{
+				case AF_INET:  ifa->ifa_extra.index = iaa->IfIndex; break;
+				case AF_INET6: ifa->ifa_extra.index = ipv6IfIndex + kIPv6IfIndexBase;	 break;
+				default: break;
+			}
+
+			// Get lease lifetime
+
+			if ( ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) && ( addr->LeaseLifetime != 0 ) && ( addr->ValidLifetime != 0xFFFFFFFF ) )
+			{
+				ifa->ifa_dhcpEnabled		= TRUE;
+				ifa->ifa_dhcpLeaseExpires	= time( NULL ) + addr->ValidLifetime;
+			}
+			else
+			{
+				ifa->ifa_dhcpEnabled		= FALSE;
+				ifa->ifa_dhcpLeaseExpires	= 0;
+			}
+
+			if ( iaa->PhysicalAddressLength == sizeof( ifa->ifa_physaddr ) )
+			{
+				memcpy( ifa->ifa_physaddr, iaa->PhysicalAddress, iaa->PhysicalAddressLength );
+			}
+
+			// Because we don't get notified of womp changes, we're going to just assume
+			// that all wired interfaces have it enabled. Before we go to sleep, we'll check
+			// if the interface actually supports it, and update mDNS->SystemWakeOnLANEnabled
+			// accordingly
+
+			ifa->ifa_womp = ( iaa->IfType == IF_TYPE_ETHERNET_CSMACD ) ? mDNStrue : mDNSfalse;
+			
+			// Get address.
+			
+			switch( family )
+			{
+				case AF_INET:
+				case AF_INET6:
+					ifa->ifa_addr = (struct sockaddr *) calloc( 1, (size_t) addr->Address.iSockaddrLength );
+					require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
+					memcpy( ifa->ifa_addr, addr->Address.lpSockaddr, (size_t) addr->Address.iSockaddrLength );
+					break;
+				
+				default:
+					break;
+			}
+			check( ifa->ifa_addr );
+			
+			// Get subnet mask (IPv4)/link prefix (IPv6). It is specified as a bit length (e.g. 24 for 255.255.255.0).
+			
+			prefixLength = 0;
+			for( prefixIndex = 0, prefix = firstPrefix; prefix; ++prefixIndex, prefix = prefix->Next )
+			{
+				if( ( prefix->Address.lpSockaddr->sa_family == family ) && ( prefixIndex == addrIndex ) )
+				{
+					check_string( prefix->Address.lpSockaddr->sa_family == family, "addr family != netmask family" );
+					prefixLength = prefix->PrefixLength;
+					break;
+				}
+			}
+			switch( family )
+			{
+				case AF_INET:
+				{
+					struct sockaddr_in * sa4;
+					
+					sa4 = (struct sockaddr_in *) calloc( 1, sizeof( *sa4 ) );
+					require_action( sa4, exit, err = WSAENOBUFS );
+					sa4->sin_family = AF_INET;
+					sa4->sin_addr.s_addr = ipv4Netmask.sin_addr.s_addr;
+
+					dlog( kDebugLevelInfo, DEBUG_NAME "%s: IPv4 mask = %s\n", __ROUTINE__, inet_ntoa( sa4->sin_addr ) );
+					ifa->ifa_netmask = (struct sockaddr *) sa4;
+					break;
+				}
+				
+				case AF_INET6:
+				{
+					struct sockaddr_in6 *		sa6;
+					int							len;
+					int							maskIndex;
+					uint8_t						maskByte;
+					
+					require_action( prefixLength <= 128, exit, err = ERROR_INVALID_DATA );
+					
+					sa6 = (struct sockaddr_in6 *) calloc( 1, sizeof( *sa6 ) );
+					require_action( sa6, exit, err = WSAENOBUFS );
+					sa6->sin6_family = AF_INET6;
+					
+					if( prefixLength == 0 )
+					{
+						dlog( kDebugLevelWarning, DEBUG_NAME "%s: IPv6 link prefix 0, defaulting to /128\n", __ROUTINE__ );
+						prefixLength = 128;
+					}
+					maskIndex = 0;
+					for( len = (int) prefixLength; len > 0; len -= 8 )
+					{
+						if( len >= 8 ) maskByte = 0xFF;
+						else		   maskByte = (uint8_t)( ( 0xFFU << ( 8 - len ) ) & 0xFFU );
+						sa6->sin6_addr.s6_addr[ maskIndex++ ] = maskByte;
+					}
+					ifa->ifa_netmask = (struct sockaddr *) sa6;
+					break;
+				}
+				
+				default:
+					break;
+			}
+		}
+	}
+	
+	// Success!
+	
+	if( outAddrs )
+	{
+		*outAddrs = head;
+		head = NULL;
+	}
+	err = ERROR_SUCCESS;
+	
+exit:
+	if( head )
+	{
+		freeifaddrs( head );
+	}
+	if( iaaList )
+	{
+		free( iaaList );
+	}
+	return( (int) err );
+}
+
+#endif	// MDNS_WINDOWS_USE_IPV6_IF_ADDRS
+
+//===========================================================================================================================
+//	getifaddrs_ipv4
+//===========================================================================================================================
+
+mDNSlocal int	getifaddrs_ipv4( struct ifaddrs **outAddrs )
+{
+	int						err;
+	SOCKET					sock;
+	DWORD					size;
+	DWORD					actualSize;
+	INTERFACE_INFO *		buffer;
+	INTERFACE_INFO *		tempBuffer;
+	INTERFACE_INFO *		ifInfo;
+	int						n;
+	int						i;
+	struct ifaddrs *		head;
+	struct ifaddrs **		next;
+	struct ifaddrs *		ifa;
+	
+	sock	= INVALID_SOCKET;
+	buffer	= NULL;
+	head	= NULL;
+	next	= &head;
+	
+	// Get the interface list. WSAIoctl is called with SIO_GET_INTERFACE_LIST, but since this does not provide a 
+	// way to determine the size of the interface list beforehand, we have to start with an initial size guess and
+	// call WSAIoctl repeatedly with increasing buffer sizes until it succeeds. Limit this to 100 tries for safety.
+	
+	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+	err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+		
+	n = 0;
+	size = 16 * sizeof( INTERFACE_INFO );
+	for( ;; )
+	{
+		tempBuffer = (INTERFACE_INFO *) realloc( buffer, size );
+		require_action( tempBuffer, exit, err = WSAENOBUFS );
+		buffer = tempBuffer;
+		
+		err = WSAIoctl( sock, SIO_GET_INTERFACE_LIST, NULL, 0, buffer, size, &actualSize, NULL, NULL );
+		if( err == 0 )
+		{
+			break;
+		}
+		
+		++n;
+		require_action( n < 100, exit, err = WSAEADDRNOTAVAIL );
+		
+		size += ( 16 * sizeof( INTERFACE_INFO ) );
+	}
+	check( actualSize <= size );
+	check( ( actualSize % sizeof( INTERFACE_INFO ) ) == 0 );
+	n = (int)( actualSize / sizeof( INTERFACE_INFO ) );
+	
+	// Process the raw interface list and build a linked list of IPv4 interfaces.
+	
+	for( i = 0; i < n; ++i )
+	{
+		uint32_t ifIndex;
+		struct sockaddr_in netmask;
+		
+		ifInfo = &buffer[ i ];
+		if( ifInfo->iiAddress.Address.sa_family != AF_INET )
+		{
+			continue;
+		}
+		
+		// <rdar://problem/6220642> iTunes 8: Bonjour doesn't work after upgrading iTunes 8
+		// See comment in getifaddrs_ipv6
+
+		ifIndex = 0;
+		memset( &netmask, 0, sizeof( netmask ) );
+		err = AddressToIndexAndMask( ( struct sockaddr* ) &ifInfo->iiAddress.AddressIn, &ifIndex, ( struct sockaddr* ) &netmask );
+
+		if ( err )
+		{
+			continue;
+		}
+
+		ifa = (struct ifaddrs *) calloc( 1, sizeof( struct ifaddrs ) );
+		require_action( ifa, exit, err = WSAENOBUFS );
+		
+		*next = ifa;
+		next  = &ifa->ifa_next;
+		
+		// Get the name.
+		
+		ifa->ifa_name = (char *) malloc( 16 );
+		require_action( ifa->ifa_name, exit, err = WSAENOBUFS );
+		sprintf( ifa->ifa_name, "%d", i + 1 );
+		
+		// Get interface flags.
+		
+		ifa->ifa_flags = (u_int) ifInfo->iiFlags;
+		
+		// Get addresses.
+		
+		if ( ifInfo->iiAddress.Address.sa_family == AF_INET )
+		{
+			struct sockaddr_in *		sa4;
+			
+			sa4 = &ifInfo->iiAddress.AddressIn;
+			ifa->ifa_addr = (struct sockaddr *) calloc( 1, sizeof( *sa4 ) );
+			require_action( ifa->ifa_addr, exit, err = WSAENOBUFS );
+			memcpy( ifa->ifa_addr, sa4, sizeof( *sa4 ) );
+
+			ifa->ifa_netmask = (struct sockaddr*) calloc(1, sizeof( *sa4 ) );
+			require_action( ifa->ifa_netmask, exit, err = WSAENOBUFS );
+
+			// <rdar://problem/4076478> Service won't start on Win2K. The address
+			// family field was not being initialized.
+
+			ifa->ifa_netmask->sa_family = AF_INET;
+			( ( struct sockaddr_in* ) ifa->ifa_netmask )->sin_addr = netmask.sin_addr;
+			ifa->ifa_extra.index = ifIndex;
+		}
+		else
+		{
+			// Emulate an interface index.
+		
+			ifa->ifa_extra.index = (uint32_t)( i + 1 );
+		}
+	}
+	
+	// Success!
+	
+	if( outAddrs )
+	{
+		*outAddrs = head;
+		head = NULL;
+	}
+	err = 0;
+	
+exit:
+
+	if( head )
+	{
+		freeifaddrs( head );
+	}
+	if( buffer )
+	{
+		free( buffer );
+	}
+	if( sock != INVALID_SOCKET )
+	{
+		closesocket( sock );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	freeifaddrs
+//===========================================================================================================================
+
+mDNSlocal void	freeifaddrs( struct ifaddrs *inIFAs )
+{
+	struct ifaddrs *		p;
+	struct ifaddrs *		q;
+	
+	// Free each piece of the structure. Set to null after freeing to handle macro-aliased fields.
+	
+	for( p = inIFAs; p; p = q )
+	{
+		q = p->ifa_next;
+		
+		if( p->ifa_name )
+		{
+			free( p->ifa_name );
+			p->ifa_name = NULL;
+		}
+		if( p->ifa_addr )
+		{
+			free( p->ifa_addr );
+			p->ifa_addr = NULL;
+		}
+		if( p->ifa_netmask )
+		{
+			free( p->ifa_netmask );
+			p->ifa_netmask = NULL;
+		}
+		if( p->ifa_broadaddr )
+		{
+			free( p->ifa_broadaddr );
+			p->ifa_broadaddr = NULL;
+		}
+		if( p->ifa_dstaddr )
+		{
+			free( p->ifa_dstaddr );
+			p->ifa_dstaddr = NULL;
+		}
+		if( p->ifa_data )
+		{
+			free( p->ifa_data );
+			p->ifa_data = NULL;
+		}
+		free( p );
+	}
+}
+
+
+//===========================================================================================================================
+//	GetPrimaryInterface
+//===========================================================================================================================
+
+mDNSlocal DWORD
+GetPrimaryInterface()
+{
+	PMIB_IPFORWARDTABLE	pIpForwardTable	= NULL;
+	DWORD				dwSize			= 0;
+	BOOL				bOrder			= FALSE;
+	OSStatus			err;
+	DWORD				index			= 0;
+	DWORD				metric			= 0;
+	unsigned long int	i;
+
+	// Find out how big our buffer needs to be.
+
+	err = GetIpForwardTable(NULL, &dwSize, bOrder);
+	require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
+
+	// Allocate the memory for the table
+
+	pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
+	require_action( pIpForwardTable, exit, err = kNoMemoryErr );
+  
+	// Now get the table.
+
+	err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
+	require_noerr( err, exit );
+
+
+	// Search for the row in the table we want.
+
+	for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
+	{
+		// Look for a default route
+
+		if ( pIpForwardTable->table[i].dwForwardDest == 0 )
+		{
+			if ( index && ( pIpForwardTable->table[i].dwForwardMetric1 >= metric ) )
+			{
+				continue;
+			}
+
+			index	= pIpForwardTable->table[i].dwForwardIfIndex;
+			metric	= pIpForwardTable->table[i].dwForwardMetric1;
+		}
+	}
+
+exit:
+
+	if ( pIpForwardTable != NULL )
+	{
+		free( pIpForwardTable );
+	}
+
+	return index;
+}
+
+
+//===========================================================================================================================
+//	AddressToIndexAndMask
+//===========================================================================================================================
+
+mDNSlocal mStatus
+AddressToIndexAndMask( struct sockaddr * addr, uint32_t * ifIndex, struct sockaddr * mask  )
+{
+	// Before calling AddIPAddress we use GetIpAddrTable to get
+	// an adapter to which we can add the IP.
+	
+	PMIB_IPADDRTABLE	pIPAddrTable	= NULL;
+	DWORD				dwSize			= 0;
+	mStatus				err				= mStatus_UnknownErr;
+	DWORD				i;
+
+	// For now, this is only for IPv4 addresses.  That is why we can safely cast
+	// addr's to sockaddr_in.
+
+	require_action( addr->sa_family == AF_INET, exit, err = mStatus_UnknownErr );
+
+	// Make an initial call to GetIpAddrTable to get the
+	// necessary size into the dwSize variable
+
+	for ( i = 0; i < 100; i++ )
+	{
+		err = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
+
+		if ( err != ERROR_INSUFFICIENT_BUFFER )
+		{
+			break;
+		}
+
+		pIPAddrTable = (MIB_IPADDRTABLE *) realloc( pIPAddrTable, dwSize );
+		require_action( pIPAddrTable, exit, err = WSAENOBUFS );
+	}
+
+	require_noerr( err, exit );
+	err = mStatus_UnknownErr;
+
+	for ( i = 0; i < pIPAddrTable->dwNumEntries; i++ )
+	{
+		if ( ( ( struct sockaddr_in* ) addr )->sin_addr.s_addr == pIPAddrTable->table[i].dwAddr )
+		{
+			*ifIndex											= pIPAddrTable->table[i].dwIndex;
+			( ( struct sockaddr_in*) mask )->sin_addr.s_addr	= pIPAddrTable->table[i].dwMask;
+			err													= mStatus_NoError;
+			break;
+		}
+	}
+
+exit:
+
+	if ( pIPAddrTable )
+	{
+		free( pIPAddrTable );
+	}
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	CanReceiveUnicast
+//===========================================================================================================================
+
+mDNSlocal mDNSBool	CanReceiveUnicast( void )
+{
+	mDNSBool				ok;
+	SocketRef				sock;
+	struct sockaddr_in		addr;
+	
+	// Try to bind to the port without the SO_REUSEADDR option to test if someone else has already bound to it.
+	
+	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+	check_translated_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
+	ok = IsValidSocket( sock );
+	if( ok )
+	{
+		mDNSPlatformMemZero( &addr, sizeof( addr ) );
+		addr.sin_family			= AF_INET;
+		addr.sin_port			= MulticastDNSPort.NotAnInteger;
+		addr.sin_addr.s_addr	= htonl( INADDR_ANY );
+		
+		ok = ( bind( sock, (struct sockaddr *) &addr, sizeof( addr ) ) == 0 );
+		close_compat( sock );
+	}
+	
+	dlog( kDebugLevelInfo, DEBUG_NAME "Unicast UDP responses %s\n", ok ? "okay" : "*not allowed*" );
+	return( ok );
+}
+
+
+//===========================================================================================================================
+//	IsPointToPoint
+//===========================================================================================================================
+
+mDNSlocal mDNSBool IsPointToPoint( IP_ADAPTER_UNICAST_ADDRESS * addr )
+{
+	struct ifaddrs	*	addrs	=	NULL;
+	struct ifaddrs	*	p		=	NULL;
+	OSStatus			err;
+	mDNSBool			ret		=	mDNSfalse;
+
+	// For now, only works for IPv4 interfaces
+
+	if ( addr->Address.lpSockaddr->sa_family == AF_INET )
+	{
+		// The getifaddrs_ipv4 call will give us correct information regarding IFF_POINTTOPOINT flags.
+
+		err = getifaddrs_ipv4( &addrs );
+		require_noerr( err, exit );
+
+		for ( p = addrs; p; p = p->ifa_next )
+		{
+			if ( ( addr->Address.lpSockaddr->sa_family == p->ifa_addr->sa_family ) &&
+			     ( ( ( struct sockaddr_in* ) addr->Address.lpSockaddr )->sin_addr.s_addr == ( ( struct sockaddr_in* ) p->ifa_addr )->sin_addr.s_addr ) )
+			{
+				ret = ( p->ifa_flags & IFF_POINTTOPOINT ) ? mDNStrue : mDNSfalse;
+				break;
+			}
+		}
+	}
+
+exit:
+
+	if ( addrs )
+	{
+		freeifaddrs( addrs );
+	}
+
+	return ret;
+}
+
+
+//===========================================================================================================================
+//	GetWindowsVersionString
+//===========================================================================================================================
+
+mDNSlocal OSStatus	GetWindowsVersionString( char *inBuffer, size_t inBufferSize )
+{
+#if( !defined( VER_PLATFORM_WIN32_CE ) )
+	#define VER_PLATFORM_WIN32_CE		3
+#endif
+
+	OSStatus				err;
+	OSVERSIONINFO			osInfo;
+	BOOL					ok;
+	const char *			versionString;
+	DWORD					platformID;
+	DWORD					majorVersion;
+	DWORD					minorVersion;
+	DWORD					buildNumber;
+	
+	versionString = "unknown Windows version";
+	
+	osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+	ok = GetVersionEx( &osInfo );
+	err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	platformID		= osInfo.dwPlatformId;
+	majorVersion	= osInfo.dwMajorVersion;
+	minorVersion	= osInfo.dwMinorVersion;
+	buildNumber		= osInfo.dwBuildNumber & 0xFFFF;
+	
+	if( ( platformID == VER_PLATFORM_WIN32_WINDOWS ) && ( majorVersion == 4 ) )
+	{
+		if( ( minorVersion < 10 ) && ( buildNumber == 950 ) )
+		{
+			versionString	= "Windows 95";
+		}
+		else if( ( minorVersion < 10 ) && ( ( buildNumber > 950 ) && ( buildNumber <= 1080 ) ) )
+		{
+			versionString	= "Windows 95 SP1";
+		}
+		else if( ( minorVersion < 10 ) && ( buildNumber > 1080 ) )
+		{
+			versionString	= "Windows 95 OSR2";
+		}
+		else if( ( minorVersion == 10 ) && ( buildNumber == 1998 ) )
+		{
+			versionString	= "Windows 98";
+		}
+		else if( ( minorVersion == 10 ) && ( ( buildNumber > 1998 ) && ( buildNumber < 2183 ) ) )
+		{
+			versionString	= "Windows 98 SP1";
+		}
+		else if( ( minorVersion == 10 ) && ( buildNumber >= 2183 ) )
+		{
+			versionString	= "Windows 98 SE";
+		}
+		else if( minorVersion == 90 )
+		{
+			versionString	= "Windows ME";
+		}
+	}
+	else if( platformID == VER_PLATFORM_WIN32_NT )
+	{
+		if( ( majorVersion == 3 ) && ( minorVersion == 51 ) )
+		{
+			versionString	= "Windows NT 3.51";
+		}
+		else if( ( majorVersion == 4 ) && ( minorVersion == 0 ) )
+		{
+			versionString	= "Windows NT 4";
+		}
+		else if( ( majorVersion == 5 ) && ( minorVersion == 0 ) )
+		{
+			versionString	= "Windows 2000";
+		}
+		else if( ( majorVersion == 5 ) && ( minorVersion == 1 ) )
+		{
+			versionString	= "Windows XP";
+		}
+		else if( ( majorVersion == 5 ) && ( minorVersion == 2 ) )
+		{
+			versionString	= "Windows Server 2003";
+		}
+	}
+	else if( platformID == VER_PLATFORM_WIN32_CE )
+	{
+		versionString		= "Windows CE";
+	}
+	
+exit:
+	if( inBuffer && ( inBufferSize > 0 ) )
+	{
+		inBufferSize -= 1;
+		strncpy( inBuffer, versionString, inBufferSize );
+		inBuffer[ inBufferSize ] = '\0';
+	}
+	return( err );
+}
+
+
+//===========================================================================================================================
+//	RegQueryString
+//===========================================================================================================================
+
+mDNSlocal mStatus
+RegQueryString( HKEY key, LPCSTR valueName, LPSTR * string, DWORD * stringLen, DWORD * enabled )
+{
+	DWORD	type;
+	int		i;
+	mStatus err;
+
+	*stringLen	= MAX_ESCAPED_DOMAIN_NAME;
+	*string		= NULL;
+	i			= 0;
+
+	do
+	{
+		if ( *string )
+		{
+			free( *string );
+		}
+
+		*string = (char*) malloc( *stringLen );
+		require_action( *string, exit, err = mStatus_NoMemoryErr );
+
+		err = RegQueryValueExA( key, valueName, 0, &type, (LPBYTE) *string, stringLen );
+
+		i++;
+	}
+	while ( ( err == ERROR_MORE_DATA ) && ( i < 100 ) );
+
+	require_noerr_quiet( err, exit );
+
+	if ( enabled )
+	{
+		DWORD dwSize = sizeof( DWORD );
+
+		err = RegQueryValueEx( key, TEXT("Enabled"), NULL, NULL, (LPBYTE) enabled, &dwSize );
+		check_noerr( err );
+
+		err = kNoErr;
+	}
+
+exit:
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	StringToAddress
+//===========================================================================================================================
+
+mDNSlocal mStatus StringToAddress( mDNSAddr * ip, LPSTR string )
+{
+	struct sockaddr_in6 sa6;
+	struct sockaddr_in	sa4;
+	INT					dwSize;
+	mStatus				err;
+
+	sa6.sin6_family	= AF_INET6;
+	dwSize			= sizeof( sa6 );
+
+	err = WSAStringToAddressA( string, AF_INET6, NULL, (struct sockaddr*) &sa6, &dwSize );
+
+	if ( err == mStatus_NoError )
+	{
+		err = SetupAddr( ip, (struct sockaddr*) &sa6 );
+		require_noerr( err, exit );
+	}
+	else
+	{
+		sa4.sin_family = AF_INET;
+		dwSize = sizeof( sa4 );
+
+		err = WSAStringToAddressA( string, AF_INET, NULL, (struct sockaddr*) &sa4, &dwSize );
+		err = translate_errno( err == 0, WSAGetLastError(), kUnknownErr );
+		require_noerr( err, exit );
+			
+		err = SetupAddr( ip, (struct sockaddr*) &sa4 );
+		require_noerr( err, exit );
+	}
+
+exit:
+
+	return err;
+}
+
+
+//===========================================================================================================================
+//	myGetIfAddrs
+//===========================================================================================================================
+
+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;
+}
+
+
+//===========================================================================================================================
+//	TCHARtoUTF8
+//===========================================================================================================================
+
+mDNSlocal OSStatus
+TCHARtoUTF8( const TCHAR *inString, char *inBuffer, size_t inBufferSize )
+{
+#if( defined( UNICODE ) || defined( _UNICODE ) )
+	OSStatus		err;
+	int				len;
+	
+	len = WideCharToMultiByte( CP_UTF8, 0, inString, -1, inBuffer, (int) inBufferSize, NULL, NULL );
+	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+	
+exit:
+	return( err );
+#else
+	return( WindowsLatin1toUTF8( inString, inBuffer, inBufferSize ) );
+#endif
+}
+
+
+//===========================================================================================================================
+//	WindowsLatin1toUTF8
+//===========================================================================================================================
+
+mDNSlocal OSStatus
+WindowsLatin1toUTF8( const char *inString, char *inBuffer, size_t inBufferSize )
+{
+	OSStatus		err;
+	WCHAR *			utf16;
+	int				len;
+	
+	utf16 = NULL;
+	
+	// Windows doesn't support going directly from Latin-1 to UTF-8 so we have to go from Latin-1 to UTF-16 first.
+	
+	len = MultiByteToWideChar( CP_ACP, 0, inString, -1, NULL, 0 );
+	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	utf16 = (WCHAR *) malloc( len * sizeof( *utf16 ) );
+	require_action( utf16, exit, err = kNoMemoryErr );
+	
+	len = MultiByteToWideChar( CP_ACP, 0, inString, -1, utf16, len );
+	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+	
+	// Now convert the temporary UTF-16 to UTF-8.
+	
+	len = WideCharToMultiByte( CP_UTF8, 0, utf16, -1, inBuffer, (int) inBufferSize, NULL, NULL );
+	err = translate_errno( len > 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+
+exit:
+	if( utf16 ) free( utf16 );
+	return( err );
+}
+
+
+//===========================================================================================================================
+//	TCPCloseSocket
+//===========================================================================================================================
+
+mDNSlocal void
+TCPCloseSocket( TCPSocket * sock )
+{
+	dlog( kDebugLevelChatty, DEBUG_NAME "closing TCPSocket 0x%x:%d\n", sock, sock->fd );
+
+	RemoveFromList( &gTCPDispatchableSockets, sock );	
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		closesocket( sock->fd );
+		sock->fd = INVALID_SOCKET;
+	}
+}
+
+
+//===========================================================================================================================
+//	TCPFreeSocket
+//===========================================================================================================================
+
+mDNSlocal void CALLBACK
+TCPFreeSocket( TCPSocket *sock )
+{
+	check( sock );
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "freeing TCPSocket 0x%x:%d\n", sock, sock->fd );
+	
+	if ( sock->connectEvent )
+	{
+		CloseHandle( sock->connectEvent );
+		sock->connectEvent = NULL;
+	}
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		closesocket( sock->fd );
+		sock->fd = INVALID_SOCKET;
+	}
+
+	free( sock );
+}
+
+
+//===========================================================================================================================
+//  UDPCloseSocket
+//===========================================================================================================================
+
+mDNSlocal void
+UDPCloseSocket( UDPSocket * sock )
+{
+	dlog( kDebugLevelChatty, DEBUG_NAME "closing UDPSocket %d\n", sock->fd );
+
+	RemoveFromList( &gUDPDispatchableSockets, sock );
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		closesocket( sock->fd );
+		sock->fd = INVALID_SOCKET;
+	}
+}
+
+
+//===========================================================================================================================
+//  UDPFreeSocket
+//===========================================================================================================================
+
+mDNSlocal void CALLBACK
+UDPFreeSocket( UDPSocket * sock )
+{
+    check( sock );
+
+	dlog( kDebugLevelChatty, DEBUG_NAME "freeing UDPSocket %d\n", sock->fd );
+
+    if ( sock->fd != INVALID_SOCKET )
+    {		
+        closesocket( sock->fd );
+		sock->fd = INVALID_SOCKET;
+    }
+
+    free( sock );
+}
+
+//===========================================================================================================================
+//	SetupAddr
+//===========================================================================================================================
+
+mDNSlocal mStatus SetupAddr(mDNSAddr *ip, const struct sockaddr *const sa)
+	{
+	if (!sa) { LogMsg("SetupAddr ERROR: NULL sockaddr"); return(mStatus_Invalid); }
+
+	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(mStatus_NoError);
+		}
+
+	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.u.Word[1] = 0;
+		ip->ip.v6 = *(mDNSv6Addr*)&ifa_addr->sin6_addr;
+		return(mStatus_NoError);
+		}
+
+	LogMsg("SetupAddr invalid sa_family %d", sa->sa_family);
+	return(mStatus_Invalid);
+	}
+
+
+mDNSlocal void GetDDNSFQDN( domainname *const fqdn )
+{
+	LPSTR		name = NULL;
+	DWORD		dwSize;
+	DWORD		enabled;
+	HKEY		key = NULL;
+	OSStatus	err;
+
+	check( fqdn );
+
+	// Initialize
+
+	fqdn->c[0] = '\0';
+
+	// Get info from Bonjour registry key
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup\\") kServiceDynDNSHostNames, &key );
+	require_noerr( err, exit );
+
+	err = RegQueryString( key, "", &name, &dwSize, &enabled );
+	if ( !err && ( name[0] != '\0' ) && enabled )
+	{
+		if ( !MakeDomainNameFromDNSNameString( fqdn, name ) || !fqdn->c[0] )
+		{
+			dlog( kDebugLevelError, "bad DDNS host name in registry: %s", name[0] ? name : "(unknown)");
+		}
+	}
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+		key = NULL;
+	}
+
+	if ( name )
+	{
+		free( name );
+		name = NULL;
+	}
+}
+
+
+#ifdef UNICODE
+mDNSlocal void GetDDNSDomains( DNameListElem ** domains, LPCWSTR lpSubKey )
+#else
+mDNSlocal void GetDDNSConfig( DNameListElem ** domains, LPCSTR lpSubKey )
+#endif
+{
+	char		subKeyName[kRegistryMaxKeyLength + 1];
+	DWORD		cSubKeys = 0;
+	DWORD		cbMaxSubKey;
+	DWORD		cchMaxClass;
+	DWORD		dwSize;
+	HKEY		key = NULL;
+	HKEY		subKey = NULL;
+	domainname	dname;
+	DWORD		i;
+	OSStatus	err;
+
+	check( domains );
+
+	// Initialize
+
+	*domains = NULL;
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, lpSubKey, &key );
+	require_noerr( err, exit );
+
+	// Get information about this node
+
+	err = RegQueryInfoKey( key, NULL, NULL, NULL, &cSubKeys, &cbMaxSubKey, &cchMaxClass, NULL, NULL, NULL, NULL, NULL );       
+	require_noerr( err, exit );
+
+	for ( i = 0; i < cSubKeys; i++)
+	{
+		DWORD enabled;
+
+		dwSize = kRegistryMaxKeyLength;
+        
+		err = RegEnumKeyExA( key, i, subKeyName, &dwSize, NULL, NULL, NULL, NULL );
+
+		if ( !err )
+		{
+			err = RegOpenKeyExA( key, subKeyName, 0, KEY_READ, &subKey );
+			require_noerr( err, exit );
+
+			dwSize = sizeof( DWORD );
+			err = RegQueryValueExA( subKey, "Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
+
+			if ( !err && ( subKeyName[0] != '\0' ) && enabled )
+			{
+				if ( !MakeDomainNameFromDNSNameString( &dname, subKeyName ) || !dname.c[0] )
+				{
+					dlog( kDebugLevelError, "bad DDNS domain in registry: %s", subKeyName[0] ? subKeyName : "(unknown)");
+				}
+				else
+				{
+					DNameListElem * domain = (DNameListElem*) malloc( sizeof( DNameListElem ) );
+					require_action( domain, exit, err = mStatus_NoMemoryErr );
+					
+					AssignDomainName(&domain->name, &dname);
+					domain->next = *domains;
+
+					*domains = domain;
+				}
+			}
+
+			RegCloseKey( subKey );
+			subKey = NULL;
+		}
+	}
+
+exit:
+
+	if ( subKey )
+	{
+		RegCloseKey( subKey );
+	}
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+}
+
+
+mDNSlocal void SetDomainSecret( mDNS * const m, const domainname * inDomain )
+{
+	char					domainUTF8[ 256 ];
+	DomainAuthInfo			*foundInList;
+	DomainAuthInfo			*ptr;
+	char					outDomain[ 256 ];
+	char					outKey[ 256 ];
+	char					outSecret[ 256 ];
+	OSStatus				err;
+	
+	ConvertDomainNameToCString( inDomain, domainUTF8 );
+	
+	// If we're able to find a secret for this domain
+
+	if ( LsaGetSecret( domainUTF8, outDomain, sizeof( outDomain ), outKey, sizeof( outKey ), outSecret, sizeof( outSecret ) ) )
+	{
+		domainname domain;
+		domainname key;
+
+		// Tell the core about this secret
+
+		MakeDomainNameFromDNSNameString( &domain, outDomain );
+		MakeDomainNameFromDNSNameString( &key, outKey );
+
+		for (foundInList = m->AuthInfoList; foundInList; foundInList = foundInList->next)
+			if (SameDomainName(&foundInList->domain, &domain ) ) break;
+
+		ptr = foundInList;
+	
+		if (!ptr)
+		{
+			ptr = (DomainAuthInfo*)malloc(sizeof(DomainAuthInfo));
+			require_action( ptr, exit, err = mStatus_NoMemoryErr );
+		}
+
+		err = mDNS_SetSecretForDomain(m, ptr, &domain, &key, outSecret, NULL, 0, NULL );
+		require_action( err != mStatus_BadParamErr, exit, if (!foundInList ) mDNSPlatformMemFree( ptr ) );
+
+		debugf("Setting shared secret for zone %s with key %##s", outDomain, key.c);
+	}
+
+exit:
+
+	return;
+}
+
+
+mDNSlocal VOID CALLBACK
+CheckFileSharesProc( LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue )
+{
+	mDNS * const m = ( mDNS * const ) arg;
+
+	( void ) dwTimerLowValue;
+	( void ) dwTimerHighValue;
+
+	CheckFileShares( m );
+}
+
+
+mDNSlocal unsigned __stdcall 
+SMBRegistrationThread( void * arg )
+{
+	mDNS * const m = ( mDNS * const ) arg;
+	DNSServiceRef sref = NULL;
+	HANDLE		handles[ 3 ];
+	mDNSu8		txtBuf[ 256 ];
+	mDNSu8	*	txtPtr;
+	size_t		keyLen;
+	size_t		valLen;
+	mDNSIPPort	port = { { SMBPortAsNumber >> 8, SMBPortAsNumber & 0xFF } };
+	DNSServiceErrorType err;
+
+	DEBUG_UNUSED( arg );
+
+	handles[ 0 ] = gSMBThreadStopEvent;
+	handles[ 1 ] = gSMBThreadRegisterEvent;
+	handles[ 2 ] = gSMBThreadDeregisterEvent;
+
+	memset( txtBuf, 0, sizeof( txtBuf )  );
+	txtPtr = txtBuf;
+	keyLen = strlen( "netbios=" );
+	valLen = strlen( m->p->nbname );
+	require_action( valLen < 32, exit, err = kUnknownErr );	// This should never happen, but check to avoid further memory corruption
+	*txtPtr++ = ( mDNSu8 ) ( keyLen + valLen );
+	memcpy( txtPtr, "netbios=", keyLen );
+	txtPtr += keyLen;
+	if ( valLen ) { memcpy( txtPtr, m->p->nbname, valLen ); txtPtr += ( mDNSu8 ) valLen; }
+	keyLen = strlen( "domain=" );
+	valLen = strlen( m->p->nbdomain );
+	require_action( valLen < 32, exit, err = kUnknownErr );	// This should never happen, but check to avoid further memory corruption
+	*txtPtr++ = ( mDNSu8 )( keyLen + valLen );
+	memcpy( txtPtr, "domain=", keyLen );
+	txtPtr += keyLen;
+	if ( valLen ) { memcpy( txtPtr, m->p->nbdomain, valLen ); txtPtr += valLen; }
+	
+	for ( ;; )
+	{
+		DWORD ret;
+
+		ret = WaitForMultipleObjects( 3, handles, FALSE, INFINITE );
+
+		if ( ret != WAIT_FAILED )
+		{
+			if ( ret == kSMBStopEvent )
+			{
+				break;
+			}
+			else if ( ret == kSMBRegisterEvent )
+			{
+				err = gDNSServiceRegister( &sref, 0, 0, NULL, "_smb._tcp,_file", NULL, NULL, ( uint16_t ) port.NotAnInteger, ( mDNSu16 )( txtPtr - txtBuf ), txtBuf, NULL, NULL );
+
+				if ( err )
+				{
+					LogMsg( "SMBRegistrationThread: DNSServiceRegister returned %d\n", err );
+					sref = NULL;
+					break;
+				}
+			}
+			else if ( ret == kSMBDeregisterEvent )
+			{
+				if ( sref )
+				{
+					gDNSServiceRefDeallocate( sref );
+					sref = NULL;
+				}
+			}
+		}
+		else
+		{
+			LogMsg( "SMBRegistrationThread:  WaitForMultipleObjects returned %d\n", GetLastError() );
+			break;
+		}
+	}
+
+exit:
+
+	if ( sref != NULL )
+	{
+		gDNSServiceRefDeallocate( sref );
+		sref = NULL;
+	}
+
+	SetEvent( gSMBThreadQuitEvent );
+	_endthreadex( 0 );
+	return 0;
+}
+
+
+mDNSlocal void
+CheckFileShares( mDNS * const m )
+{
+	PSHARE_INFO_1	bufPtr = ( PSHARE_INFO_1 ) NULL;
+	DWORD			entriesRead = 0;
+	DWORD			totalEntries = 0;
+	DWORD			resume = 0;
+	mDNSBool		advertise = mDNSfalse;
+	mDNSBool		fileSharing = mDNSfalse;
+	mDNSBool		printSharing = mDNSfalse;
+	HKEY			key = NULL;
+	BOOL			retry = FALSE;
+	NET_API_STATUS  res;
+	mStatus			err;
+
+	check( m );
+
+	// Only do this if we're not shutting down
+
+	require_action_quiet( m->AdvertiseLocalAddresses && !m->ShutdownTime, exit, err = kNoErr );
+
+	err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Services\\SMB", &key );
+
+	if ( !err )
+	{
+		DWORD dwSize = sizeof( DWORD );
+		RegQueryValueEx( key, L"Advertise", NULL, NULL, (LPBYTE) &advertise, &dwSize );
+	}
+
+	if ( advertise && mDNSIsFileAndPrintSharingEnabled( &retry ) )
+	{
+		dlog( kDebugLevelTrace, DEBUG_NAME "Sharing is enabled\n" );
+
+		res = NetShareEnum( NULL, 1, ( LPBYTE* )&bufPtr, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resume );
+
+		if ( ( res == ERROR_SUCCESS ) || ( res == ERROR_MORE_DATA ) )
+		{
+			PSHARE_INFO_1 p = bufPtr;
+			DWORD i;
+
+			for( i = 0; i < entriesRead; i++ ) 
+			{
+				// We are only interested if the user is sharing anything other 
+				// than the built-in "print$" source
+
+				if ( ( p->shi1_type == STYPE_DISKTREE ) && ( wcscmp( p->shi1_netname, TEXT( "print$" ) ) != 0 ) )
+				{
+					fileSharing = mDNStrue;
+				}
+				else if ( p->shi1_type == STYPE_PRINTQ )
+				{
+					printSharing = mDNStrue;
+				}
+
+				p++;
+			}
+
+			NetApiBufferFree( bufPtr );
+			bufPtr = NULL;
+			retry = FALSE;
+		}
+		else if ( res == NERR_ServerNotStarted )
+		{
+			retry = TRUE;
+		}
+	}
+	
+	if ( retry )
+	{
+		__int64			qwTimeout;
+		LARGE_INTEGER   liTimeout;
+
+		qwTimeout = -m->p->checkFileSharesTimeout * 10000000;
+		liTimeout.LowPart  = ( DWORD )( qwTimeout & 0xFFFFFFFF );
+		liTimeout.HighPart = ( LONG )( qwTimeout >> 32 );
+
+		SetWaitableTimer( m->p->checkFileSharesTimer, &liTimeout, 0, CheckFileSharesProc, m, FALSE );
+	}
+
+	if ( !m->p->smbFileSharing && fileSharing )
+	{
+		if ( !gSMBThread )
+		{
+			if ( !gDNSSDLibrary )
+			{
+				gDNSSDLibrary = LoadLibrary( TEXT( "dnssd.dll" ) );
+				require_action( gDNSSDLibrary, exit, err = GetLastError() );
+			}
+
+			if ( !gDNSServiceRegister )
+			{
+				gDNSServiceRegister = ( DNSServiceRegisterFunc ) GetProcAddress( gDNSSDLibrary, "DNSServiceRegister" );
+				require_action( gDNSServiceRegister, exit, err = GetLastError() );
+			}
+
+			if ( !gDNSServiceRefDeallocate )
+			{
+				gDNSServiceRefDeallocate = ( DNSServiceRefDeallocateFunc ) GetProcAddress( gDNSSDLibrary, "DNSServiceRefDeallocate" );
+				require_action( gDNSServiceRefDeallocate, exit, err = GetLastError() );
+			}
+
+			if ( !gSMBThreadRegisterEvent )
+			{
+				gSMBThreadRegisterEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+				require_action( gSMBThreadRegisterEvent != NULL, exit, err = GetLastError() );
+			}
+
+			if ( !gSMBThreadDeregisterEvent )
+			{
+				gSMBThreadDeregisterEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+				require_action( gSMBThreadDeregisterEvent != NULL, exit, err = GetLastError() );
+			}
+
+			if ( !gSMBThreadStopEvent )
+			{
+				gSMBThreadStopEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+				require_action( gSMBThreadStopEvent != NULL, exit, err = GetLastError() );
+			}
+
+			if ( !gSMBThreadQuitEvent )
+			{
+				gSMBThreadQuitEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
+				require_action( gSMBThreadQuitEvent != NULL, exit, err = GetLastError() );
+			}
+
+			gSMBThread = ( HANDLE ) _beginthreadex( NULL, 0, SMBRegistrationThread, m, 0, NULL );
+			require_action( gSMBThread != NULL, exit, err = GetLastError() );
+		}
+
+		SetEvent( gSMBThreadRegisterEvent );
+
+		m->p->smbFileSharing = mDNStrue;
+	}
+	else if ( m->p->smbFileSharing && !fileSharing )
+	{
+		dlog( kDebugLevelTrace, DEBUG_NAME "deregistering smb type\n" );
+
+		if ( gSMBThreadDeregisterEvent != NULL )
+		{
+			SetEvent( gSMBThreadDeregisterEvent );
+		}
+
+		m->p->smbFileSharing = mDNSfalse;
+	}
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+}
+
+
+BOOL
+IsWOMPEnabled( mDNS * const m )
+{
+	BOOL enabled;
+
+	mDNSInterfaceData * ifd;
+
+	enabled = FALSE;
+
+	for( ifd = m->p->interfaceList; ifd; ifd = ifd->next )
+	{
+		if ( IsWOMPEnabledForAdapter( ifd->name ) )
+		{
+			enabled = TRUE;
+			break;
+		}
+	}
+
+	return enabled;
+}
+
+
+mDNSlocal mDNSu8
+IsWOMPEnabledForAdapter( const char * adapterName )
+{
+	char						fileName[80];
+	NDIS_OID					oid;
+    DWORD						count;
+    HANDLE						handle	= INVALID_HANDLE_VALUE;
+	NDIS_PNP_CAPABILITIES	*	pNPC	= NULL;
+	int							err;
+	mDNSu8						ok		= TRUE;
+
+	require_action( adapterName != NULL, exit, ok = FALSE );
+
+	dlog( kDebugLevelTrace, DEBUG_NAME "IsWOMPEnabledForAdapter: %s\n", adapterName );
+	
+    // Construct a device name to pass to CreateFile
+
+	strncpy_s( fileName, sizeof( fileName ), DEVICE_PREFIX, strlen( DEVICE_PREFIX ) );
+	strcat_s( fileName, sizeof( fileName ), adapterName );
+    handle = CreateFileA( fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, INVALID_HANDLE_VALUE );
+	require_action ( handle != INVALID_HANDLE_VALUE, exit, ok = FALSE );
+
+	// We successfully opened the driver, format the IOCTL to pass the driver.
+		
+	oid = OID_PNP_CAPABILITIES;
+	pNPC = ( NDIS_PNP_CAPABILITIES * ) malloc( sizeof( NDIS_PNP_CAPABILITIES ) );
+	require_action( pNPC != NULL, exit, ok = FALSE );
+	ok = ( mDNSu8 ) DeviceIoControl( handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &oid, sizeof( oid ), pNPC, sizeof( NDIS_PNP_CAPABILITIES ), &count, NULL );
+	err = translate_errno( ok, GetLastError(), kUnknownErr );
+	require_action( !err, exit, ok = FALSE );
+	ok = ( mDNSu8 ) ( ( count == sizeof( NDIS_PNP_CAPABILITIES ) ) && ( pNPC->Flags & NDIS_DEVICE_WAKE_ON_MAGIC_PACKET_ENABLE ) );
+       
+exit:
+
+	if ( pNPC != NULL )
+	{
+		free( pNPC );
+	}
+
+    if ( handle != INVALID_HANDLE_VALUE )
+    {
+		CloseHandle( handle );
+    }
+
+	dlog( kDebugLevelTrace, DEBUG_NAME "IsWOMPEnabledForAdapter returns %s\n", ok ? "true" : "false" );
+
+	return ( mDNSu8 ) ok;
+}
+
+
+void
+DispatchSocketEvents( mDNS * const inMDNS )
+{
+	UDPSocket * udpSock;
+	TCPSocket * tcpSock;
+
+	while ( ( udpSock = ( UDPSocket* ) gUDPDispatchableSockets.Head ) != NULL )
+	{
+		dlog( kDebugLevelChatty, DEBUG_NAME "%s: calling DispatchUDPEvent on socket %d, error = %d, bytesTransferred = %d\n",
+		                                     __ROUTINE__, udpSock->fd, udpSock->overlapped.error, udpSock->overlapped.bytesTransferred );
+		RemoveFromList( &gUDPDispatchableSockets, udpSock );
+		DispatchUDPEvent( inMDNS, udpSock );
+	}
+		
+	while ( ( tcpSock = ( TCPSocket* ) gTCPDispatchableSockets.Head ) != NULL )
+	{
+		dlog( kDebugLevelChatty, DEBUG_NAME "%s: calling DispatchTCPEvent on socket %d, error = %d, bytesTransferred = %d\n",
+		                                     __ROUTINE__, tcpSock->fd, tcpSock->overlapped.error, tcpSock->overlapped.bytesTransferred );
+		RemoveFromList( &gTCPDispatchableSockets, tcpSock );
+		DispatchTCPEvent( inMDNS, tcpSock );
+	}
+}
+
+
+mDNSlocal void
+DispatchUDPEvent( mDNS * const inMDNS, UDPSocket * sock )
+{
+	( void ) inMDNS;
+
+	// If we've closed the socket, then we want to ignore
+	// this read.  The packet might have been queued before
+	// the socket was closed.
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		const mDNSInterfaceID	iid = sock->ifd ? sock->ifd->interfaceInfo.InterfaceID : NULL;
+		mDNSu8				*	end = ( (mDNSu8 *) &sock->packet ) + sock->overlapped.bytesTransferred;
+
+		dlog( kDebugLevelChatty, DEBUG_NAME "calling mDNSCoreReceive on socket: %d\n", sock->fd );
+		mDNSCoreReceive( sock->m, &sock->packet, end, &sock->overlapped.srcAddr, sock->overlapped.srcPort, &sock->overlapped.dstAddr, sock->overlapped.dstPort, iid );
+	}
+
+	// If the socket is still good, then start up another asynchronous read
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		int err = UDPBeginRecv( sock );
+		check_noerr( err );
+	}
+}
+
+
+mDNSlocal void
+DispatchTCPEvent( mDNS * const inMDNS, TCPSocket * sock )
+{
+	( void ) inMDNS;
+
+	if ( sock->fd != INVALID_SOCKET )
+	{
+		sock->eptr += sock->overlapped.bytesTransferred;
+		sock->lastError = sock->overlapped.error;
+
+		if ( !sock->overlapped.error && !sock->overlapped.bytesTransferred )
+		{
+			sock->closed = TRUE;
+		}
+
+		if ( sock->readEventHandler != NULL )
+		{
+			dlog( kDebugLevelChatty, DEBUG_NAME "calling TCP read handler  on socket: %d\n", sock->fd );
+			sock->readEventHandler( sock );
+		}
+	}
+
+	// If the socket is still good, then start up another asynchronous read
+
+	if ( !sock->closed && ( sock->fd != INVALID_SOCKET ) )
+	{
+		int err = TCPBeginRecv( sock );
+		check_noerr( err );
+	}
+}
diff --git a/mDNSWindows/mDNSWin32.h b/mDNSWindows/mDNSWin32.h
new file mode 100755
index 0000000..e08c462
--- /dev/null
+++ b/mDNSWindows/mDNSWin32.h
@@ -0,0 +1,208 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef	__MDNS_WIN32__
+#define	__MDNS_WIN32__
+
+#include	"CommonServices.h"
+
+#if( !defined( _WIN32_WCE ) )
+	#include	<mswsock.h>
+#endif
+
+#include	"mDNSEmbeddedAPI.h"
+#include	"uDNS.h"
+
+#ifdef	__cplusplus
+	extern "C" {
+#endif
+
+
+typedef struct Overlapped
+{
+	BOOL		pending;
+	OVERLAPPED	data;
+	WSABUF		wbuf;
+	DWORD		error;
+	DWORD		bytesTransferred;
+	mDNSAddr	srcAddr;
+	mDNSIPPort	srcPort;
+	mDNSAddr	dstAddr;
+	mDNSIPPort	dstPort;
+} Overlapped;
+
+
+typedef void ( *TCPReadEventHandler )( TCPSocket * sock );
+typedef void ( *TCPUserCallback )();
+
+struct TCPSocket_struct
+{
+	TCPSocketFlags				flags;		// MUST BE FIRST FIELD -- mDNSCore expects every TCPSocket_struct to begin with TCPSocketFlags flags
+	SOCKET						fd;
+	TCPReadEventHandler			readEventHandler;
+	HANDLE						connectEvent;
+	BOOL						connected;
+	TCPUserCallback				userCallback;
+	void					*	userContext;
+	Overlapped					overlapped;
+	DWORD						lastError;
+	BOOL						closed;

+	uint8_t						bbuf[ 4192 ];
+	uint8_t					*	bptr;
+	uint8_t					*	eptr;
+	uint8_t					*	ebuf;
+	TCPSocket				*	nextDispatchable;
+	mDNS					*	m;
+};
+
+
+struct UDPSocket_struct
+{
+	mDNSIPPort						port; 			// MUST BE FIRST FIELD -- mDNSCoreReceive expects every UDPSocket_struct to begin with mDNSIPPort port
+	mDNSAddr						addr;			// This is initialized by our code. If we don't get the 
+													// dstAddr from WSARecvMsg we use this value instead.
+	SOCKET							fd;
+	LPFN_WSARECVMSG					recvMsgPtr;
+	Overlapped						overlapped;
+	WSAMSG							wmsg;
+	DNSMessage						packet;
+	uint8_t							controlBuffer[ 128 ];
+	struct sockaddr_storage			srcAddr;		// This is filled in by the WSARecv* function
+	INT								srcAddrLen;		// See above
+	struct mDNSInterfaceData	*	ifd;
+	UDPSocket					*	nextDispatchable;
+	UDPSocket					*	next;
+	mDNS						*	m;
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@struct		mDNSInterfaceData
+
+	@abstract	Structure containing interface-specific data.
+*/
+
+typedef struct	mDNSInterfaceData	mDNSInterfaceData;
+struct	mDNSInterfaceData
+{
+	char						name[ 128 ];
+	uint32_t					index;
+	uint32_t					scopeID;
+	struct UDPSocket_struct		sock;
+	NetworkInterfaceInfo		interfaceInfo;
+	mDNSBool					hostRegistered;
+	mDNSInterfaceData		*	next;
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@typedef	RegisterWaitableEventHandler
+*/
+typedef void		(*RegisterWaitableEventHandler)(mDNS * const inMDNS, HANDLE event, void * context );
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@typedef	RegisterWaitableEventFunc
+*/
+typedef mStatus		(*RegisterWaitableEventFunc)(mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler );
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@typedef	UnregisterWaitableEventHandler
+*/
+typedef void		(*UnregisterWaitableEventFunc)(mDNS * const inMDNS, HANDLE event );
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@typedef	ReportStatusFunc
+*/
+typedef void		(*ReportStatusFunc)(int inType, const char *inFormat, ...);
+
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@struct		mDNS_PlatformSupport_struct
+
+	@abstract	Structure containing platform-specific data.
+*/
+
+struct	mDNS_PlatformSupport_struct
+{
+	HANDLE						mainThread;
+	HANDLE						checkFileSharesTimer;
+	mDNSs32						checkFileSharesTimeout;
+	RegisterWaitableEventFunc	registerWaitableEventFunc;
+	UnregisterWaitableEventFunc	unregisterWaitableEventFunc;
+	ReportStatusFunc			reportStatusFunc;
+	time_t						nextDHCPLeaseExpires;
+	char						nbname[ 32 ];
+	char						nbdomain[ 32 ];
+	mDNSBool					smbFileSharing;
+	mDNSBool					smbPrintSharing;
+	ServiceRecordSet			smbSRS;
+	AuthRecord					smbSubTypes[ 2 ];
+	mDNSBool					registeredLoopback4;
+	int							interfaceCount;
+	mDNSInterfaceData *			interfaceList;
+	mDNSInterfaceData *			inactiveInterfaceList;
+	struct UDPSocket_struct		unicastSock4;
+	struct UDPSocket_struct		unicastSock6;
+};
+
+//---------------------------------------------------------------------------------------------------------------------------
+/*!	@struct		ifaddrs
+
+	@abstract	Interface information
+*/
+
+struct ifaddrs
+{
+	struct ifaddrs *	ifa_next;
+	char *				ifa_name;
+	u_int				ifa_flags;
+	struct sockaddr	*	ifa_addr;
+	struct sockaddr	*	ifa_netmask;
+	struct sockaddr	*	ifa_broadaddr;
+	struct sockaddr	*	ifa_dstaddr;
+	BYTE				ifa_physaddr[6];
+	BOOL				ifa_dhcpEnabled;
+	time_t				ifa_dhcpLeaseExpires;
+	mDNSu8				ifa_womp;
+	void *				ifa_data;
+	
+	struct
+	{
+		uint32_t		index;
+	
+	}	ifa_extra;
+};
+
+

+extern void		InterfaceListDidChange( mDNS * const inMDNS );
+extern void		ComputerDescriptionDidChange( mDNS * const inMDNS );
+extern void		TCPIPConfigDidChange( mDNS * const inMDNS );
+extern void		DynDNSConfigDidChange( mDNS * const inMDNS );
+extern void		FileSharingDidChange( mDNS * const inMDNS );
+extern void		FirewallDidChange( mDNS * const inMDNS );
+extern mStatus  TCPAddSocket( mDNS * const inMDNS, TCPSocket *sock );
+extern mStatus	SetupInterfaceList( mDNS * const inMDNS );
+extern mStatus	TearDownInterfaceList( mDNS * const inMDNS );
+extern BOOL		IsWOMPEnabled();
+extern void     DispatchSocketEvents( mDNS * const inMDNS );
+
+
+#ifdef	__cplusplus
+	}
+#endif
+
+#endif	// __MDNS_WIN32__
diff --git a/mDNSWindows/mdnsNSP/ReadMe.txt b/mDNSWindows/mdnsNSP/ReadMe.txt
new file mode 100644
index 0000000..7a6e2cc
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/ReadMe.txt
@@ -0,0 +1,15 @@
+The mdnsNSP is a NameSpace Provider. It hooks into the Windows name resolution infrastructure to allow any software using the standard Windows APIs for resolving names to work with DNS-SD. For example, when the mdnsNSP is installed, you can type "http://computer.local./" in Internet Explorer and it will resolve "computer.local." using DNS-SD and go to the web site (assuming you have a computer named "computer" on the local network and advertised via DNS-SD).
+
+NSP's are implemented DLLs and must be installed to work. NSP DLLs export an NSPStartup function, which is called when the NSP is used, and NSPStartup provides information about itself (e.g. version number, compatibility information, and a list of function pointers for each of the supported NSP routines).
+
+If you need to register the mdnsNSP, you can use the NSPTool (sources for it are provided along with the mdnsNSP) with the following line from the DOS command line prompt ("<path>" is the actual parent path of the DLL):
+
+NSPTool -install "mdnsNSP" "B600E6E9-553B-4a19-8696-335E5C896153" "<path>"
+
+You can remove remove the mdnsNSP with the following line:
+
+NSPTool -remove "B600E6E9-553B-4a19-8696-335E5C896153"
+
+For more information, check out the following URL:
+
+<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/name_space_service_providers_2.asp>
diff --git a/mDNSWindows/mdnsNSP/mdnsNSP.aps b/mDNSWindows/mdnsNSP/mdnsNSP.aps
new file mode 100644
index 0000000..2e3b63a
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/mdnsNSP.aps
Binary files differ
diff --git a/mDNSWindows/mdnsNSP/mdnsNSP.c b/mDNSWindows/mdnsNSP/mdnsNSP.c
new file mode 100644
index 0000000..2cd01ef
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/mdnsNSP.c
@@ -0,0 +1,2430 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include	<stdio.h>
+#include	<stdlib.h>
+#include	<string.h>
+
+#include	"ClientCommon.h"
+#include	"CommonServices.h"
+#include	"DebugServices.h"
+
+#include	<iphlpapi.h>
+#include	<guiddef.h>
+#include	<ws2spi.h>
+#include	<shlwapi.h>
+
+
+
+#include	"dns_sd.h"
+
+#pragma comment(lib, "DelayImp.lib")
+
+#ifdef _MSC_VER
+#define swprintf _snwprintf
+#define snprintf _snprintf
+#endif
+
+#define MAX_LABELS 128
+
+#if 0
+#pragma mark == Structures ==
+#endif
+
+//===========================================================================================================================
+//	Structures
+//===========================================================================================================================
+
+typedef struct	Query *		QueryRef;
+typedef struct	Query		Query;
+struct	Query
+{
+	QueryRef			next;
+	int					refCount;
+	DWORD				querySetFlags;
+	WSAQUERYSETW *		querySet;
+	size_t				querySetSize;
+	HANDLE				data4Event;
+	HANDLE				data6Event;
+	HANDLE				cancelEvent;
+	HANDLE				waitHandles[ 3 ];
+	DWORD				waitCount;
+	DNSServiceRef		resolver4;
+	DNSServiceRef		resolver6;
+	char				name[ kDNSServiceMaxDomainName ];
+	size_t				nameSize;
+	uint8_t				numValidAddrs;
+	uint32_t			addr4;
+	bool				addr4Valid;
+	uint8_t				addr6[16];
+	u_long				addr6ScopeId;
+	bool				addr6Valid;
+};
+
+#define BUFFER_INITIAL_SIZE		4192
+#define ALIASES_INITIAL_SIZE	5
+
+typedef struct HostsFile
+{
+	int			m_bufferSize;
+	char	*	m_buffer;
+	FILE	*	m_fp;
+} HostsFile;
+
+
+typedef struct HostsFileInfo
+{
+	struct hostent		m_host;
+	struct HostsFileInfo	*	m_next;
+} HostsFileInfo;
+
+
+#if 0
+#pragma mark == Prototypes ==
+#endif
+
+//===========================================================================================================================
+//	Prototypes
+//===========================================================================================================================
+
+// DLL Exports
+
+BOOL WINAPI		DllMain( HINSTANCE inInstance, DWORD inReason, LPVOID inReserved );
+STDAPI			DllRegisterServer( void );
+STDAPI			DllRegisterServer( void );
+
+	
+// NSP SPIs
+
+int	WSPAPI	NSPCleanup( LPGUID inProviderID );
+
+DEBUG_LOCAL int WSPAPI
+	NSPLookupServiceBegin(
+		LPGUID					inProviderID,
+		LPWSAQUERYSETW			inQuerySet,
+		LPWSASERVICECLASSINFOW	inServiceClassInfo,
+		DWORD					inFlags,   
+		LPHANDLE				outLookup );
+
+DEBUG_LOCAL int WSPAPI
+	NSPLookupServiceNext(  
+		HANDLE			inLookup,
+		DWORD			inFlags,
+		LPDWORD			ioBufferLength,
+		LPWSAQUERYSETW	outResults );
+
+DEBUG_LOCAL int WSPAPI	NSPLookupServiceEnd( HANDLE inLookup );
+
+DEBUG_LOCAL int WSPAPI
+	NSPSetService(
+		LPGUID					inProviderID,						
+		LPWSASERVICECLASSINFOW	inServiceClassInfo,   
+		LPWSAQUERYSETW			inRegInfo,				  
+		WSAESETSERVICEOP		inOperation,			   
+		DWORD					inFlags );
+
+DEBUG_LOCAL int WSPAPI	NSPInstallServiceClass( LPGUID inProviderID, LPWSASERVICECLASSINFOW inServiceClassInfo );
+DEBUG_LOCAL int WSPAPI	NSPRemoveServiceClass( LPGUID inProviderID, LPGUID inServiceClassID );
+DEBUG_LOCAL int WSPAPI	NSPGetServiceClassInfo(	LPGUID inProviderID, LPDWORD ioBufSize, LPWSASERVICECLASSINFOW ioServiceClassInfo );
+
+// Private
+
+#define	NSPLock()		EnterCriticalSection( &gLock );
+#define	NSPUnlock()		LeaveCriticalSection( &gLock );
+
+DEBUG_LOCAL OSStatus	QueryCreate( const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags, QueryRef *outRef );
+DEBUG_LOCAL OSStatus	QueryRetain( QueryRef inRef );
+DEBUG_LOCAL OSStatus	QueryRelease( QueryRef inRef );
+
+DEBUG_LOCAL void CALLBACK_COMPAT
+	QueryRecordCallback4(
+		DNSServiceRef		inRef,
+		DNSServiceFlags		inFlags,
+		uint32_t			inInterfaceIndex,
+		DNSServiceErrorType	inErrorCode,
+		const char *		inName,    
+		uint16_t			inRRType,
+		uint16_t			inRRClass,
+		uint16_t			inRDataSize,
+		const void *		inRData,
+		uint32_t			inTTL,
+		void *				inContext );
+
+DEBUG_LOCAL void CALLBACK_COMPAT
+	QueryRecordCallback6(
+		DNSServiceRef		inRef,
+		DNSServiceFlags		inFlags,
+		uint32_t			inInterfaceIndex,
+		DNSServiceErrorType	inErrorCode,
+		const char *		inName,    
+		uint16_t			inRRType,
+		uint16_t			inRRClass,
+		uint16_t			inRDataSize,
+		const void *		inRData,
+		uint32_t			inTTL,
+		void *				inContext );
+
+DEBUG_LOCAL OSStatus
+	QueryCopyQuerySet( 
+		QueryRef 				inRef, 
+		const WSAQUERYSETW *	inQuerySet, 
+		DWORD 					inQuerySetFlags, 
+		WSAQUERYSETW **			outQuerySet, 
+		size_t *				outSize );
+
+DEBUG_LOCAL void
+	QueryCopyQuerySetTo( 
+		QueryRef 				inRef, 
+		const WSAQUERYSETW *	inQuerySet, 
+		DWORD 					inQuerySetFlags, 
+		WSAQUERYSETW *			outQuerySet );
+
+DEBUG_LOCAL size_t	QueryCopyQuerySetSize( QueryRef inRef, const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags );
+
+#if( DEBUG )
+	void	DebugDumpQuerySet( DebugLevel inLevel, const WSAQUERYSETW *inQuerySet );
+	
+	#define	dlog_query_set( LEVEL, SET )		DebugDumpQuerySet( LEVEL, SET )
+#else
+	#define	dlog_query_set( LEVEL, SET )
+#endif
+
+DEBUG_LOCAL BOOL		InHostsTable( const char * name );
+DEBUG_LOCAL BOOL		IsLocalName( HostsFileInfo * node );
+DEBUG_LOCAL BOOL		IsSameName( HostsFileInfo * node, const char * name );
+DEBUG_LOCAL OSStatus	HostsFileOpen( HostsFile ** self, const char * fname );
+DEBUG_LOCAL OSStatus	HostsFileClose( HostsFile * self );
+DEBUG_LOCAL void		HostsFileInfoFree( HostsFileInfo * info );
+DEBUG_LOCAL OSStatus	HostsFileNext( HostsFile * self, HostsFileInfo ** hInfo );
+DEBUG_LOCAL DWORD		GetScopeId( DWORD ifIndex );
+
+#ifdef ENABLE_REVERSE_LOOKUP
+DEBUG_LOCAL OSStatus	IsReverseLookup( LPCWSTR name, size_t size );
+#endif
+
+
+#if 0
+#pragma mark == Globals ==
+#endif
+
+//===========================================================================================================================
+//	Globals
+//===========================================================================================================================
+
+// {B600E6E9-553B-4a19-8696-335E5C896153}
+DEBUG_LOCAL HINSTANCE				gInstance			= NULL;
+DEBUG_LOCAL wchar_t				*	gNSPName			= L"mdnsNSP";
+DEBUG_LOCAL GUID					gNSPGUID			= { 0xb600e6e9, 0x553b, 0x4a19, { 0x86, 0x96, 0x33, 0x5e, 0x5c, 0x89, 0x61, 0x53 } };
+DEBUG_LOCAL LONG					gRefCount			= 0;
+DEBUG_LOCAL CRITICAL_SECTION		gLock;
+DEBUG_LOCAL bool					gLockInitialized 	= false;
+DEBUG_LOCAL QueryRef				gQueryList	 		= NULL;
+DEBUG_LOCAL HostsFileInfo		*	gHostsFileInfo		= NULL;
+typedef DWORD
+	( WINAPI * GetAdaptersAddressesFunctionPtr )( 
+			ULONG 					inFamily, 
+			DWORD 					inFlags, 
+			PVOID 					inReserved, 
+			PIP_ADAPTER_ADDRESSES 	inAdapter, 
+			PULONG					outBufferSize );
+
+DEBUG_LOCAL HMODULE								gIPHelperLibraryInstance			= NULL;
+DEBUG_LOCAL GetAdaptersAddressesFunctionPtr		gGetAdaptersAddressesFunctionPtr	= NULL;
+
+
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	DllMain
+//===========================================================================================================================
+
+BOOL APIENTRY	DllMain( HINSTANCE inInstance, DWORD inReason, LPVOID inReserved )
+{
+	DEBUG_USE_ONLY( inInstance );
+	DEBUG_UNUSED( inReserved );
+
+	switch( inReason )
+	{
+		case DLL_PROCESS_ATTACH:			
+			gInstance = inInstance;		
+			gHostsFileInfo	= NULL;
+			debug_initialize( kDebugOutputTypeWindowsEventLog, "mDNS NSP", inInstance );
+			debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelNotice );
+			dlog( kDebugLevelTrace, "\n" );
+			dlog( kDebugLevelVerbose, "%s: process attach\n", __ROUTINE__ );
+
+			break;
+		
+		case DLL_PROCESS_DETACH:
+			HostsFileInfoFree( gHostsFileInfo );
+			gHostsFileInfo = NULL;
+			dlog( kDebugLevelVerbose, "%s: process detach\n", __ROUTINE__ );
+			break;
+		
+		case DLL_THREAD_ATTACH:
+			dlog( kDebugLevelVerbose, "%s: thread attach\n", __ROUTINE__ );
+			break;
+		
+		case DLL_THREAD_DETACH:
+			dlog( kDebugLevelVerbose, "%s: thread detach\n", __ROUTINE__ );
+			break;
+		
+		default:
+			dlog( kDebugLevelNotice, "%s: unknown reason code (%d)\n", __ROUTINE__, inReason );
+			break;
+	}
+
+	return( TRUE );
+}
+
+
+//===========================================================================================================================
+//	DllRegisterServer
+//===========================================================================================================================
+
+STDAPI	DllRegisterServer( void )
+{
+	WSADATA		wsd;
+	WCHAR		path[ MAX_PATH ];
+	HRESULT		err;
+	
+	dlog( kDebugLevelTrace, "DllRegisterServer\n" );
+
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+
+	// Unregister before registering to workaround an installer
+	// problem during upgrade installs.
+
+	WSCUnInstallNameSpace( &gNSPGUID );
+
+	err = GetModuleFileNameW( gInstance, path, MAX_PATH );
+	err = translate_errno( err != 0, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+
+	err = WSCInstallNameSpace( gNSPName, path, NS_DNS, 1, &gNSPGUID );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+exit:
+
+	WSACleanup();
+	return( err );
+}
+
+//===========================================================================================================================
+//	DllUnregisterServer
+//===========================================================================================================================
+
+STDAPI	DllUnregisterServer( void )
+{
+	WSADATA		wsd;
+	HRESULT err;
+	
+	dlog( kDebugLevelTrace, "DllUnregisterServer\n" );
+	
+	err = WSAStartup( MAKEWORD( 2, 2 ), &wsd );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+	err = WSCUnInstallNameSpace( &gNSPGUID );
+	err = translate_errno( err == 0, errno_compat(), WSAEINVAL );
+	require_noerr( err, exit );
+		
+exit:
+
+	WSACleanup();
+	return err;
+}
+
+
+//===========================================================================================================================
+//	NSPStartup
+//
+//	This function is called when our namespace DLL is loaded. It sets up the NSP functions we implement and initializes us.
+//===========================================================================================================================
+
+int WSPAPI	NSPStartup( LPGUID inProviderID, LPNSP_ROUTINE outRoutines )
+{
+	OSStatus		err;
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	dlog( kDebugLevelTrace, "%s (GUID=%U, refCount=%ld)\n", __ROUTINE__, inProviderID, gRefCount );
+	
+	// Only initialize if this is the first time NSPStartup is called. 
+	
+	if( InterlockedIncrement( &gRefCount ) != 1 )
+	{
+		err = NO_ERROR;
+		goto exit;
+	}
+	
+	// Initialize our internal state.
+	
+	InitializeCriticalSection( &gLock );
+	gLockInitialized = true;
+	
+	// Set the size to exclude NSPIoctl because we don't implement it.
+	
+	outRoutines->cbSize					= FIELD_OFFSET( NSP_ROUTINE, NSPIoctl );
+	outRoutines->dwMajorVersion			= 4;
+	outRoutines->dwMinorVersion			= 4;
+	outRoutines->NSPCleanup				= NSPCleanup;
+	outRoutines->NSPLookupServiceBegin	= NSPLookupServiceBegin;
+	outRoutines->NSPLookupServiceNext	= NSPLookupServiceNext;
+	outRoutines->NSPLookupServiceEnd	= NSPLookupServiceEnd;
+	outRoutines->NSPSetService			= NSPSetService;
+	outRoutines->NSPInstallServiceClass	= NSPInstallServiceClass;
+	outRoutines->NSPRemoveServiceClass	= NSPRemoveServiceClass;
+	outRoutines->NSPGetServiceClassInfo	= NSPGetServiceClassInfo;
+	
+	// See if we can get the address for the GetAdaptersAddresses() API.  This is only in XP, but we want our
+	// code to run on older versions of Windows
+
+	if ( !gIPHelperLibraryInstance )
+	{
+		gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
+		if( gIPHelperLibraryInstance )
+		{
+			gGetAdaptersAddressesFunctionPtr = (GetAdaptersAddressesFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetAdaptersAddresses" );
+		}
+	}
+
+	err = NO_ERROR;
+	
+exit:
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	if( err != NO_ERROR )
+	{
+		NSPCleanup( inProviderID );
+		SetLastError( (DWORD) err );
+		return( SOCKET_ERROR );
+	}
+	return( NO_ERROR );
+}
+
+//===========================================================================================================================
+//	NSPCleanup
+//
+//	This function is called when our namespace DLL is unloaded. It cleans up anything we set up in NSPStartup.
+//===========================================================================================================================
+
+int	WSPAPI	NSPCleanup( LPGUID inProviderID )
+{
+	DEBUG_USE_ONLY( inProviderID );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	dlog( kDebugLevelTrace, "%s (GUID=%U, refCount=%ld)\n", __ROUTINE__, inProviderID, gRefCount );
+	
+	// Only initialize if this is the first time NSPStartup is called.
+	
+	if( InterlockedDecrement( &gRefCount ) != 0 )
+	{
+		goto exit;
+	}
+	
+	// Stop any outstanding queries.
+	
+	if( gLockInitialized )
+	{
+		NSPLock();
+	}
+	while( gQueryList )
+	{
+		check_string( gQueryList->refCount == 1, "NSPCleanup with outstanding queries!" );
+		QueryRelease( gQueryList );
+	}
+	if( gLockInitialized )
+	{
+		NSPUnlock();
+	}
+	
+	if( gLockInitialized )
+	{
+		gLockInitialized = false;
+		DeleteCriticalSection( &gLock );
+	}
+
+	if( gIPHelperLibraryInstance )
+	{
+		BOOL ok;
+				
+		ok = FreeLibrary( gIPHelperLibraryInstance );
+		check_translated_errno( ok, GetLastError(), kUnknownErr );
+		gIPHelperLibraryInstance = NULL;
+	}
+	
+exit:
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	return( NO_ERROR );
+}
+
+//===========================================================================================================================
+//	NSPLookupServiceBegin
+//
+//	This function maps to the WinSock WSALookupServiceBegin function. It starts the lookup process and returns a HANDLE 
+//	that can be used in subsequent operations. Subsequent calls only need to refer to this query by the handle as 
+//	opposed to specifying the query parameters each time.
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI
+	NSPLookupServiceBegin(
+		LPGUID					inProviderID,
+		LPWSAQUERYSETW			inQuerySet,
+		LPWSASERVICECLASSINFOW	inServiceClassInfo,
+		DWORD					inFlags,   
+		LPHANDLE				outLookup )
+{
+	OSStatus		err;
+	QueryRef		obj;
+	LPCWSTR			name;
+	size_t			size;
+	LPCWSTR			p;
+	DWORD           type;
+	DWORD			n;
+	DWORD			i;
+	INT				family;
+	INT				protocol;
+	
+	DEBUG_UNUSED( inProviderID );
+	DEBUG_UNUSED( inServiceClassInfo );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	
+	obj = NULL;
+	require_action( inQuerySet, exit, err = WSAEINVAL );
+	name = inQuerySet->lpszServiceInstanceName;
+	require_action_quiet( name, exit, err = WSAEINVAL );
+	require_action( outLookup, exit, err = WSAEINVAL );
+	
+	dlog( kDebugLevelTrace, "%s (flags=0x%08X, name=\"%S\")\n", __ROUTINE__, inFlags, name );
+	dlog_query_set( kDebugLevelVerbose, inQuerySet );
+	
+	// Check if we can handle this type of request and if we support any of the protocols being requested.
+	// We only support the DNS namespace, TCP and UDP protocols, and IPv4. Only blob results are supported.
+	
+	require_action_quiet( inFlags & (LUP_RETURN_ADDR|LUP_RETURN_BLOB), exit, err = WSASERVICE_NOT_FOUND );
+	
+	type = inQuerySet->dwNameSpace;
+	require_action_quiet( ( type == NS_DNS ) || ( type == NS_ALL ), exit, err = WSASERVICE_NOT_FOUND );
+	
+	n = inQuerySet->dwNumberOfProtocols;
+	if( n > 0 )
+	{
+		require_action( inQuerySet->lpafpProtocols, exit, err = WSAEINVAL );
+		for( i = 0; i < n; ++i )
+		{
+			family = inQuerySet->lpafpProtocols[ i ].iAddressFamily;
+			protocol = inQuerySet->lpafpProtocols[ i ].iProtocol;
+			if( ( family == AF_INET ) && ( ( protocol == IPPROTO_UDP ) || ( protocol == IPPROTO_TCP ) ) )
+			{
+				break;
+			}
+		}
+		require_action_quiet( i < n, exit, err = WSASERVICE_NOT_FOUND );
+	}
+	
+	// Check if the name ends in ".local" and if not, exit with an error since we only resolve .local names.
+	// The name may or may not end with a "." (fully qualified) so handle both cases. DNS is also case 
+	// insensitive the check for .local has to be case insensitive (.LoCaL is equivalent to .local). This
+	// manually does the wchar_t strlen and stricmp to avoid needing any special wchar_t versions of the 
+	// libraries. It is probably faster to do the inline compare than invoke functions to do it anyway.
+	
+	for( p = name; *p; ++p ) {}		// Find end of string
+	size = (size_t)( p - name );
+	require_action_quiet( size > sizeof_string( ".local" ), exit, err = WSASERVICE_NOT_FOUND );
+	
+	p = name + ( size - 1 );
+	p = ( *p == '.' ) ? ( p - sizeof_string( ".local" ) ) : ( ( p - sizeof_string( ".local" ) ) + 1 );
+	if	( ( ( p[ 0 ] != '.' )						||
+		( ( p[ 1 ] != 'L' ) && ( p[ 1 ] != 'l' ) )	||
+		( ( p[ 2 ] != 'O' ) && ( p[ 2 ] != 'o' ) )	||
+		( ( p[ 3 ] != 'C' ) && ( p[ 3 ] != 'c' ) )	||
+		( ( p[ 4 ] != 'A' ) && ( p[ 4 ] != 'a' ) )	||
+		( ( p[ 5 ] != 'L' ) && ( p[ 5 ] != 'l' ) ) ) )
+	{
+#ifdef ENABLE_REVERSE_LOOKUP
+
+		err = IsReverseLookup( name, size );
+
+#else
+
+		err = WSASERVICE_NOT_FOUND;
+
+#endif
+
+		require_noerr( err, exit );
+	}
+	else
+	{
+		const char	*	replyDomain;
+		char			translated[ kDNSServiceMaxDomainName ];
+		int				n;
+		int				labels		= 0;
+		const char	*	label[MAX_LABELS];
+		char			text[64];
+
+		n = WideCharToMultiByte( CP_UTF8, 0, name, -1, translated, sizeof( translated ), NULL, NULL );
+		require_action( n > 0, exit, err = WSASERVICE_NOT_FOUND );
+
+		// <rdar://problem/4050633>
+
+		// Don't resolve multi-label name
+
+		// <rdar://problem/5914160> Eliminate use of GetNextLabel in mdnsNSP
+		// Add checks for GetNextLabel returning NULL, individual labels being greater than
+		// 64 bytes, and the number of labels being greater than MAX_LABELS
+		replyDomain = translated;
+
+		while (replyDomain && *replyDomain && labels < MAX_LABELS)
+		{
+			label[labels++]	= replyDomain;
+			replyDomain		= GetNextLabel(replyDomain, text);
+		}
+
+		require_action( labels == 2, exit, err = WSASERVICE_NOT_FOUND );
+
+		// <rdar://problem/3936771>
+		//
+		// Check to see if the name of this host is in the hosts table. If so,
+		// don't try and resolve it
+		
+		require_action( InHostsTable( translated ) == FALSE, exit, err = WSASERVICE_NOT_FOUND );
+	}
+
+	// The name ends in .local ( and isn't in the hosts table ), .0.8.e.f.ip6.arpa, or .254.169.in-addr.arpa so start the resolve operation. Lazy initialize DNS-SD if needed.
+		
+	NSPLock();
+	
+	err = QueryCreate( inQuerySet, inFlags, &obj );
+	NSPUnlock();
+	require_noerr( err, exit );
+	
+	*outLookup = (HANDLE) obj;
+	
+exit:
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	if( err != NO_ERROR )
+	{
+		SetLastError( (DWORD) err );
+		return( SOCKET_ERROR );
+	}
+	return( NO_ERROR );
+}
+
+//===========================================================================================================================
+//	NSPLookupServiceNext
+//
+//	This function maps to the Winsock call WSALookupServiceNext. This routine takes a handle to a previously defined 
+//	query and attempts to locate a service matching the criteria defined by the query. If so, that instance is returned 
+//	in the lpqsResults parameter.
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI
+	NSPLookupServiceNext(  
+		HANDLE			inLookup,
+		DWORD			inFlags,
+		LPDWORD			ioSize,
+		LPWSAQUERYSETW	outResults )
+{
+	BOOL			data4;
+	BOOL			data6;
+	OSStatus		err;
+	QueryRef		obj;
+	DWORD			waitResult;
+	size_t			size;
+	
+	DEBUG_USE_ONLY( inFlags );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	
+	data4 = FALSE;
+	data6 = FALSE;
+	obj = NULL;
+	NSPLock();
+	err = QueryRetain( (QueryRef) inLookup );
+	require_noerr( err, exit );
+	obj = (QueryRef) inLookup;
+	require_action( ioSize, exit, err = WSAEINVAL );
+	require_action( outResults, exit, err = WSAEINVAL );
+	
+	dlog( kDebugLevelTrace, "%s (lookup=%#p, flags=0x%08X, *ioSize=%d)\n", __ROUTINE__, inLookup, inFlags, *ioSize );
+	
+	// Wait for data or a cancel. Release the lock while waiting. This is safe because we've retained the query.
+
+	NSPUnlock();
+	waitResult = WaitForMultipleObjects( obj->waitCount, obj->waitHandles, FALSE, 2 * 1000 );
+	NSPLock();
+	require_action_quiet( waitResult != ( WAIT_OBJECT_0 ), exit, err = WSA_E_CANCELLED );
+	err = translate_errno( ( waitResult == WAIT_OBJECT_0 + 1 ) || ( waitResult == WAIT_OBJECT_0 + 2 ), (OSStatus) GetLastError(), WSASERVICE_NOT_FOUND );
+	require_noerr_quiet( err, exit );
+
+	// If we've received an IPv4 reply, then hang out briefly for an IPv6 reply
+
+	if ( waitResult == WAIT_OBJECT_0 + 1 )
+	{
+		data4 = TRUE;
+		data6 = WaitForSingleObject( obj->data6Event, 100 ) == WAIT_OBJECT_0 ? TRUE : FALSE;
+	}
+
+	// Else we've received an IPv6 reply, so hang out briefly for an IPv4 reply
+
+	else if ( waitResult == WAIT_OBJECT_0 + 2 )
+	{
+		data4 = WaitForSingleObject( obj->data4Event, 100 ) == WAIT_OBJECT_0 ? TRUE : FALSE;
+		data6 = TRUE;
+	}
+
+	if ( data4 )
+	{
+		__try
+		{
+			err = DNSServiceProcessResult(obj->resolver4);
+		}
+		__except( EXCEPTION_EXECUTE_HANDLER )
+		{
+			err = kUnknownErr;
+		}
+
+		require_noerr( err, exit );
+	}
+
+	if ( data6 )
+	{
+		__try
+		{
+			err = DNSServiceProcessResult( obj->resolver6 );
+		}
+		__except( EXCEPTION_EXECUTE_HANDLER )
+		{
+			err = kUnknownErr;
+		}
+
+		require_noerr( err, exit );
+	}
+
+	require_action_quiet( obj->addr4Valid || obj->addr6Valid, exit, err = WSA_E_NO_MORE );
+
+	// Copy the externalized query results to the callers buffer (if it fits).
+	
+	size = QueryCopyQuerySetSize( obj, obj->querySet, obj->querySetFlags );
+	require_action( size <= (size_t) *ioSize, exit, err = WSAEFAULT );
+	
+	QueryCopyQuerySetTo( obj, obj->querySet, obj->querySetFlags, outResults );
+	outResults->dwOutputFlags = RESULT_IS_ADDED;
+	obj->addr4Valid = false;
+	obj->addr6Valid = false;
+
+exit:
+	if( obj )
+	{
+		QueryRelease( obj );
+	}
+	NSPUnlock();
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	if( err != NO_ERROR )
+	{
+		SetLastError( (DWORD) err );
+		return( SOCKET_ERROR );
+	}
+	return( NO_ERROR );
+}
+
+//===========================================================================================================================
+//	NSPLookupServiceEnd
+//
+//	This function maps to the Winsock call WSALookupServiceEnd. Once the user process has finished is query (usually 
+//	indicated when WSALookupServiceNext returns the error WSA_E_NO_MORE) a call to this function is made to release any 
+//	allocated resources associated with the query.
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI	NSPLookupServiceEnd( HANDLE inLookup )
+{
+	OSStatus		err;
+
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	
+	dlog( kDebugLevelTrace, "%s (lookup=%#p)\n", __ROUTINE__, inLookup );
+	
+	NSPLock();
+	err = QueryRelease( (QueryRef) inLookup );
+	NSPUnlock();
+	require_noerr( err, exit );
+	
+exit:
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	if( err != NO_ERROR )
+	{
+		SetLastError( (DWORD) err );
+		return( SOCKET_ERROR );
+	}
+	return( NO_ERROR );
+}
+
+//===========================================================================================================================
+//	NSPSetService
+//
+//	This function maps to the Winsock call WSASetService. This routine is called when the user wants to register or 
+//	deregister an instance of a server with our service. For registration, the user needs to associate the server with a 
+//	service class. For deregistration the service class is required along with the servicename. The inRegInfo parameter 
+//	contains a WSAQUERYSET structure defining the server (such as protocol and address where it is).
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI
+	NSPSetService(
+		LPGUID					inProviderID,						
+		LPWSASERVICECLASSINFOW	inServiceClassInfo,   
+		LPWSAQUERYSETW			inRegInfo,				  
+		WSAESETSERVICEOP		inOperation,			   
+		DWORD					inFlags )
+{
+	DEBUG_UNUSED( inProviderID );
+	DEBUG_UNUSED( inServiceClassInfo );
+	DEBUG_UNUSED( inRegInfo );
+	DEBUG_UNUSED( inOperation );
+	DEBUG_UNUSED( inFlags );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
+	
+	// We don't allow services to be registered so always return an error.
+	
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	return( WSAEINVAL );
+}
+
+//===========================================================================================================================
+//	NSPInstallServiceClass
+//
+//	This function maps to the Winsock call WSAInstallServiceClass. This routine is used to install a service class which 
+//	is used to define certain characteristics for a group of services. After a service class is registered, an actual
+//	instance of a server may be registered.
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI	NSPInstallServiceClass( LPGUID inProviderID, LPWSASERVICECLASSINFOW inServiceClassInfo )
+{
+	DEBUG_UNUSED( inProviderID );
+	DEBUG_UNUSED( inServiceClassInfo );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
+	
+	// We don't allow service classes to be installed so always return an error.
+
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	return( WSA_INVALID_PARAMETER );
+}
+
+//===========================================================================================================================
+//	NSPRemoveServiceClass
+//
+//	This function maps to the Winsock call WSARemoveServiceClass. This routine removes a previously registered service 
+//	class. This is accomplished by connecting to the namespace service and writing the GUID which defines the given 
+//	service class.
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI	NSPRemoveServiceClass( LPGUID inProviderID, LPGUID inServiceClassID )
+{
+	DEBUG_UNUSED( inProviderID );
+	DEBUG_UNUSED( inServiceClassID );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
+	
+	// We don't allow service classes to be installed so always return an error.
+	
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	return( WSATYPE_NOT_FOUND );
+}
+
+//===========================================================================================================================
+//	NSPGetServiceClassInfo
+//
+//	This function maps to the Winsock call WSAGetServiceClassInfo. This routine returns the information associated with 
+//	a given service class.
+//===========================================================================================================================
+
+DEBUG_LOCAL int WSPAPI	NSPGetServiceClassInfo(	LPGUID inProviderID, LPDWORD ioSize, LPWSASERVICECLASSINFOW ioServiceClassInfo )
+{
+	DEBUG_UNUSED( inProviderID );
+	DEBUG_UNUSED( ioSize );
+	DEBUG_UNUSED( ioServiceClassInfo );
+	
+	dlog( kDebugLevelTrace, "%s begin (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	dlog( kDebugLevelTrace, "%s\n", __ROUTINE__ );
+	
+	// We don't allow service classes to be installed so always return an error.
+	
+	dlog( kDebugLevelTrace, "%s end   (ticks=%d)\n", __ROUTINE__, GetTickCount() );
+	return( WSATYPE_NOT_FOUND );
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//===========================================================================================================================
+//	QueryCreate
+//
+//	Warning: Assumes the NSP lock is held.
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	QueryCreate( const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags, QueryRef *outRef )
+{
+	OSStatus		err;
+	QueryRef		obj;
+	char			name[ kDNSServiceMaxDomainName ];
+	int				n;
+	QueryRef *		p;
+	SOCKET			s4;
+	SOCKET			s6;
+
+	obj = NULL;
+	check( inQuerySet );
+	check( inQuerySet->lpszServiceInstanceName );
+	check( outRef );
+	
+	// Convert the wchar_t name to UTF-8.
+	
+	n = WideCharToMultiByte( CP_UTF8, 0, inQuerySet->lpszServiceInstanceName, -1, name, sizeof( name ), NULL, NULL );
+	err = translate_errno( n > 0, (OSStatus) GetLastError(), WSAEINVAL );
+	require_noerr( err, exit );
+	
+	// Allocate the object and append it to the list. Append immediately so releases of partial objects work.
+	
+	obj = (QueryRef) calloc( 1, sizeof( *obj ) );
+	require_action( obj, exit, err = WSA_NOT_ENOUGH_MEMORY );
+	
+	obj->refCount = 1;
+	
+	for( p = &gQueryList; *p; p = &( *p )->next ) {}	// Find the end of the list.
+	*p = obj;
+	
+	// Set up cancel event
+
+	obj->cancelEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
+	require_action( obj->cancelEvent, exit, err = WSA_NOT_ENOUGH_MEMORY );
+
+	// Set up events to signal when A record data is ready
+	
+	obj->data4Event = CreateEvent( NULL, TRUE, FALSE, NULL );
+	require_action( obj->data4Event, exit, err = WSA_NOT_ENOUGH_MEMORY );
+	
+	// Start the query.  Handle delay loaded DLL errors.
+
+	__try
+	{
+		err = DNSServiceQueryRecord( &obj->resolver4, 0, 0, name, kDNSServiceType_A, kDNSServiceClass_IN, QueryRecordCallback4, obj );
+	}
+	__except( EXCEPTION_EXECUTE_HANDLER )
+	{
+		err = kUnknownErr;
+	}
+
+	require_noerr( err, exit );
+
+	// Attach the socket to the event
+
+	__try
+	{
+		s4 = DNSServiceRefSockFD(obj->resolver4);
+	}
+	__except( EXCEPTION_EXECUTE_HANDLER )
+	{
+		s4 = INVALID_SOCKET;
+	}
+
+	err = translate_errno( s4 != INVALID_SOCKET, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+
+	WSAEventSelect(s4, obj->data4Event, FD_READ|FD_CLOSE);
+	
+	// Set up events to signal when AAAA record data is ready
+	
+	obj->data6Event = CreateEvent( NULL, TRUE, FALSE, NULL );
+	require_action( obj->data6Event, exit, err = WSA_NOT_ENOUGH_MEMORY );
+	
+	// Start the query.  Handle delay loaded DLL errors.
+
+	__try
+	{
+		err = DNSServiceQueryRecord( &obj->resolver6, 0, 0, name, kDNSServiceType_AAAA, kDNSServiceClass_IN, QueryRecordCallback6, obj );
+	}
+	__except( EXCEPTION_EXECUTE_HANDLER )
+	{
+		err = kUnknownErr;
+	}
+
+	require_noerr( err, exit );
+
+	// Attach the socket to the event
+
+	__try
+	{
+		s6 = DNSServiceRefSockFD(obj->resolver6);
+	}
+	__except( EXCEPTION_EXECUTE_HANDLER )
+	{
+		s6 = INVALID_SOCKET;
+	}
+
+	err = translate_errno( s6 != INVALID_SOCKET, errno_compat(), kUnknownErr );
+	require_noerr( err, exit );
+
+	WSAEventSelect(s6, obj->data6Event, FD_READ|FD_CLOSE);
+
+	obj->waitCount = 0;
+	obj->waitHandles[ obj->waitCount++ ] = obj->cancelEvent;
+	obj->waitHandles[ obj->waitCount++ ] = obj->data4Event;
+	obj->waitHandles[ obj->waitCount++ ] = obj->data6Event;
+	
+	check( obj->waitCount == sizeof_array( obj->waitHandles ) );
+	
+	// Copy the QuerySet so it can be returned later.
+	
+	obj->querySetFlags = inQuerySetFlags;
+	inQuerySetFlags = ( inQuerySetFlags & ~( LUP_RETURN_ADDR | LUP_RETURN_BLOB ) ) | LUP_RETURN_NAME;
+	err = QueryCopyQuerySet( obj, inQuerySet, inQuerySetFlags, &obj->querySet, &obj->querySetSize );
+	require_noerr( err, exit );
+	
+	// Success!
+	
+	*outRef	= obj;
+	obj 	= NULL;
+	err 	= NO_ERROR;
+
+exit:
+	if( obj )
+	{
+		QueryRelease( obj );
+	}
+	return( err );
+}
+
+//===========================================================================================================================
+//	QueryRetain
+//
+//	Warning: Assumes the NSP lock is held.
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	QueryRetain( QueryRef inRef )
+{
+	OSStatus		err;
+	QueryRef		obj;
+	
+	for( obj = gQueryList; obj; obj = obj->next )
+	{
+		if( obj == inRef )
+		{
+			break;
+		}
+	}
+	require_action( obj, exit, err = WSA_INVALID_HANDLE );
+	
+	++inRef->refCount;
+	err = NO_ERROR;
+	
+exit:
+	return( err );
+}
+
+//===========================================================================================================================
+//	QueryRelease
+//
+//	Warning: Assumes the NSP lock is held.
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus	QueryRelease( QueryRef inRef )
+{
+	OSStatus		err;
+	QueryRef *		p;
+	BOOL			ok;
+		
+	// Find the item in the list.
+	
+	for( p = &gQueryList; *p; p = &( *p )->next )
+	{
+		if( *p == inRef )
+		{
+			break;
+		}
+	}
+	require_action( *p, exit, err = WSA_INVALID_HANDLE );
+	
+	// Signal a cancel to unblock any threads waiting for results.
+	
+	if( inRef->cancelEvent )
+	{
+		ok = SetEvent( inRef->cancelEvent );
+		check_translated_errno( ok, GetLastError(), WSAEINVAL );
+	}
+	
+	// Stop the query.
+	
+	if( inRef->resolver4 )
+	{
+		__try
+		{
+			DNSServiceRefDeallocate( inRef->resolver4 );
+		}
+		__except( EXCEPTION_EXECUTE_HANDLER )
+		{
+		}
+		
+		inRef->resolver4 = NULL;
+	}
+
+	if ( inRef->resolver6 )
+	{
+		__try
+		{
+			DNSServiceRefDeallocate( inRef->resolver6 );
+		}
+		__except( EXCEPTION_EXECUTE_HANDLER )
+		{
+		}
+
+		inRef->resolver6 = NULL;
+	}
+	
+	// Decrement the refCount. Fully release if it drops to 0. If still referenced, just exit.
+	
+	if( --inRef->refCount != 0 )
+	{
+		err = NO_ERROR;
+		goto exit;
+	}
+	*p = inRef->next;
+	
+	// Release resources.
+	
+	if( inRef->cancelEvent )
+	{
+		ok = CloseHandle( inRef->cancelEvent );
+		check_translated_errno( ok, GetLastError(), WSAEINVAL );
+	}
+	if( inRef->data4Event )
+	{
+		ok = CloseHandle( inRef->data4Event );
+		check_translated_errno( ok, GetLastError(), WSAEINVAL );
+	}
+	if( inRef->data6Event )
+	{
+		ok = CloseHandle( inRef->data6Event );
+		check_translated_errno( ok, GetLastError(), WSAEINVAL );
+	}
+	if( inRef->querySet )
+	{
+		free( inRef->querySet );
+	}
+	free( inRef );
+	err = NO_ERROR;
+	
+exit:
+	return( err );
+}
+
+//===========================================================================================================================
+//	QueryRecordCallback4
+//===========================================================================================================================
+
+DEBUG_LOCAL void CALLBACK_COMPAT
+	QueryRecordCallback4(
+		DNSServiceRef		inRef,
+		DNSServiceFlags		inFlags,
+		uint32_t			inInterfaceIndex,
+		DNSServiceErrorType	inErrorCode,
+		const char *		inName,    
+		uint16_t			inRRType,
+		uint16_t			inRRClass,
+		uint16_t			inRDataSize,
+		const void *		inRData,
+		uint32_t			inTTL,
+		void *				inContext )
+{
+	QueryRef			obj;
+	const char *		src;
+	char *				dst;
+	BOOL				ok;
+	
+	DEBUG_UNUSED( inFlags );
+	DEBUG_UNUSED( inInterfaceIndex );
+	DEBUG_UNUSED( inTTL );
+
+	NSPLock();
+	obj = (QueryRef) inContext;
+	check( obj );
+	require_noerr( inErrorCode, exit );
+	require_quiet( inFlags & kDNSServiceFlagsAdd, exit );
+	require( inRRClass   == kDNSServiceClass_IN, exit );
+	require( inRRType    == kDNSServiceType_A, exit );
+	require( inRDataSize == 4, exit );
+	
+	dlog( kDebugLevelTrace, "%s (flags=0x%08X, name=%s, rrType=%d, rDataSize=%d)\n", 
+		__ROUTINE__, inFlags, inName, inRRType, inRDataSize );
+		
+	// Copy the name if needed.
+	
+	if( obj->name[ 0 ] == '\0' )
+	{
+		src = inName;
+		dst = obj->name;
+		while( *src != '\0' )
+		{
+			*dst++ = *src++;
+		}
+		*dst = '\0';
+		obj->nameSize = (size_t)( dst - obj->name );
+		check( obj->nameSize < sizeof( obj->name ) );
+	}
+	
+	// Copy the data.
+	
+	memcpy( &obj->addr4, inRData, inRDataSize );
+	obj->addr4Valid = true;
+	obj->numValidAddrs++;
+	
+	// Signal that a result is ready.
+	
+	check( obj->data4Event );
+	ok = SetEvent( obj->data4Event );
+	check_translated_errno( ok, GetLastError(), WSAEINVAL );
+	
+	// Stop the resolver after the first response.
+	
+	__try
+	{
+		DNSServiceRefDeallocate( inRef );
+	}
+	__except( EXCEPTION_EXECUTE_HANDLER )
+	{
+	}
+
+	obj->resolver4 = NULL;
+
+exit:
+	NSPUnlock();
+}
+
+#if 0
+#pragma mark -
+#endif
+
+
+//===========================================================================================================================
+//	QueryRecordCallback6
+//===========================================================================================================================
+
+DEBUG_LOCAL void CALLBACK_COMPAT
+	QueryRecordCallback6(
+		DNSServiceRef		inRef,
+		DNSServiceFlags		inFlags,
+		uint32_t			inInterfaceIndex,
+		DNSServiceErrorType	inErrorCode,
+		const char *		inName,    
+		uint16_t			inRRType,
+		uint16_t			inRRClass,
+		uint16_t			inRDataSize,
+		const void *		inRData,
+		uint32_t			inTTL,
+		void *				inContext )
+{
+	QueryRef			obj;
+	const char *		src;
+	char *				dst;
+	BOOL				ok;
+	
+	DEBUG_UNUSED( inFlags );
+	DEBUG_UNUSED( inInterfaceIndex );
+	DEBUG_UNUSED( inTTL );
+
+	NSPLock();
+	obj = (QueryRef) inContext;
+	check( obj );
+	require_noerr( inErrorCode, exit );
+	require_quiet( inFlags & kDNSServiceFlagsAdd, exit );
+	require( inRRClass   == kDNSServiceClass_IN, exit );
+	require( inRRType    == kDNSServiceType_AAAA, exit );
+	require( inRDataSize == 16, exit );
+	
+	dlog( kDebugLevelTrace, "%s (flags=0x%08X, name=%s, rrType=%d, rDataSize=%d)\n", 
+		__ROUTINE__, inFlags, inName, inRRType, inRDataSize );
+
+	// Copy the name if needed.
+	
+	if( obj->name[ 0 ] == '\0' )
+	{
+		src = inName;
+		dst = obj->name;
+		while( *src != '\0' )
+		{
+			*dst++ = *src++;
+		}
+		*dst = '\0';
+		obj->nameSize = (size_t)( dst - obj->name );
+		check( obj->nameSize < sizeof( obj->name ) );
+	}
+	
+	// Copy the data.
+	
+	memcpy( &obj->addr6, inRData, inRDataSize );
+
+	obj->addr6ScopeId = GetScopeId( inInterfaceIndex );
+	require( obj->addr6ScopeId, exit );
+	obj->addr6Valid	  = true;
+	obj->numValidAddrs++;
+
+	// Signal that we're done
+	
+	check( obj->data6Event );
+	ok = SetEvent( obj->data6Event );
+	check_translated_errno( ok, GetLastError(), WSAEINVAL );
+
+	// Stop the resolver after the first response.
+	
+	__try
+	{
+		DNSServiceRefDeallocate( inRef );
+	}
+	__except( EXCEPTION_EXECUTE_HANDLER )
+	{
+	}
+
+	obj->resolver6 = NULL;
+
+exit:
+
+	
+	
+	NSPUnlock();
+}
+
+
+//===========================================================================================================================
+//	QueryCopyQuerySet
+//
+//	Warning: Assumes the NSP lock is held.
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus
+	QueryCopyQuerySet( 
+		QueryRef 				inRef, 
+		const WSAQUERYSETW *	inQuerySet, 
+		DWORD 					inQuerySetFlags, 
+		WSAQUERYSETW **			outQuerySet, 
+		size_t *				outSize )
+{
+	OSStatus			err;
+	size_t				size;
+	WSAQUERYSETW *		qs;
+	
+	check( inQuerySet );
+	check( outQuerySet );
+	
+	size  = QueryCopyQuerySetSize( inRef, inQuerySet, inQuerySetFlags );
+	qs = (WSAQUERYSETW *) calloc( 1, size );
+	require_action( qs, exit, err = WSA_NOT_ENOUGH_MEMORY  );
+	
+	QueryCopyQuerySetTo( inRef, inQuerySet, inQuerySetFlags, qs );
+	
+	*outQuerySet = qs;
+	if( outSize )
+	{
+		*outSize = size;
+	}
+	qs = NULL;
+	err = NO_ERROR;
+	
+exit:
+	if( qs )
+	{
+		free( qs );
+	}
+	return( err );	
+}
+
+
+
+//===========================================================================================================================
+//	QueryCopyQuerySetTo
+//
+//	Warning: Assumes the NSP lock is held.
+//===========================================================================================================================
+
+DEBUG_LOCAL void
+	QueryCopyQuerySetTo( 
+		QueryRef 				inRef, 
+		const WSAQUERYSETW *	inQuerySet, 
+		DWORD 					inQuerySetFlags, 
+		WSAQUERYSETW *			outQuerySet )
+{
+	uint8_t *		dst;
+	LPCWSTR			s;
+	LPWSTR			q;
+	DWORD			n;
+	DWORD			i;
+	
+#if( DEBUG )
+	size_t			debugSize;
+	
+	debugSize = QueryCopyQuerySetSize( inRef, inQuerySet, inQuerySetFlags );
+#endif
+
+	check( inQuerySet );
+	check( outQuerySet );
+
+	dst = (uint8_t *) outQuerySet;
+	
+	// Copy the static portion of the results.
+	
+	*outQuerySet = *inQuerySet;
+	dst += sizeof( *inQuerySet );
+	
+	if( inQuerySetFlags & LUP_RETURN_NAME )
+	{
+		s = inQuerySet->lpszServiceInstanceName;
+		if( s )
+		{
+			outQuerySet->lpszServiceInstanceName = (LPWSTR) dst;
+			q = (LPWSTR) dst;
+			while( ( *q++ = *s++ ) != 0 ) {}
+			dst = (uint8_t *) q;
+		}
+	}
+	else
+	{
+		outQuerySet->lpszServiceInstanceName = NULL;
+	}
+	
+	if( inQuerySet->lpServiceClassId )
+	{
+		outQuerySet->lpServiceClassId  = (LPGUID) dst;
+		*outQuerySet->lpServiceClassId = *inQuerySet->lpServiceClassId;
+		dst += sizeof( *inQuerySet->lpServiceClassId );
+	}
+	
+	if( inQuerySet->lpVersion )
+	{
+		outQuerySet->lpVersion  = (LPWSAVERSION) dst;
+		*outQuerySet->lpVersion = *inQuerySet->lpVersion;
+		dst += sizeof( *inQuerySet->lpVersion );
+	}
+	
+	s = inQuerySet->lpszComment;
+	if( s )
+	{
+		outQuerySet->lpszComment = (LPWSTR) dst;
+		q = (LPWSTR) dst;
+		while( ( *q++ = *s++ ) != 0 ) {}
+		dst = (uint8_t *) q;
+	}
+	
+	if( inQuerySet->lpNSProviderId )
+	{
+		outQuerySet->lpNSProviderId  = (LPGUID) dst;
+		*outQuerySet->lpNSProviderId = *inQuerySet->lpNSProviderId;
+		dst += sizeof( *inQuerySet->lpNSProviderId );
+	}
+	
+	s = inQuerySet->lpszContext;
+	if( s )
+	{
+		outQuerySet->lpszContext = (LPWSTR) dst;
+		q = (LPWSTR) dst;
+		while( ( *q++ = *s++ ) != 0 ) {}
+		dst = (uint8_t *) q;
+	}
+		
+	n = inQuerySet->dwNumberOfProtocols;
+
+	if( n > 0 )
+	{
+		check( inQuerySet->lpafpProtocols );
+		
+		outQuerySet->lpafpProtocols = (LPAFPROTOCOLS) dst;
+		for( i = 0; i < n; ++i )
+		{
+			outQuerySet->lpafpProtocols[ i ] = inQuerySet->lpafpProtocols[ i ];
+			dst += sizeof( *inQuerySet->lpafpProtocols );
+		}
+	}
+		
+	s = inQuerySet->lpszQueryString;
+	if( s )
+	{
+		outQuerySet->lpszQueryString = (LPWSTR) dst;
+		q = (LPWSTR) dst;
+		while( ( *q++ = *s++ ) != 0 ) {}
+		dst = (uint8_t *) q;
+	}
+	
+	// Copy the address(es).
+	
+	if( ( inQuerySetFlags & LUP_RETURN_ADDR ) && ( inRef->numValidAddrs > 0 ) )
+	{
+		struct sockaddr_in	*	addr4;
+		struct sockaddr_in6	*	addr6;
+		int						index;
+		
+		outQuerySet->dwNumberOfCsAddrs	= inRef->numValidAddrs;
+		outQuerySet->lpcsaBuffer 		= (LPCSADDR_INFO) dst;
+		dst 							+= ( sizeof( *outQuerySet->lpcsaBuffer ) ) * ( inRef->numValidAddrs ) ;
+		index							= 0;
+		
+		if ( inRef->addr4Valid )
+		{	
+			outQuerySet->lpcsaBuffer[ index ].LocalAddr.lpSockaddr 			= NULL;
+			outQuerySet->lpcsaBuffer[ index ].LocalAddr.iSockaddrLength		= 0;
+		
+			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.lpSockaddr 		= (LPSOCKADDR) dst;
+			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.iSockaddrLength	= sizeof( struct sockaddr_in );
+		
+			addr4 															= (struct sockaddr_in *) dst;
+			memset( addr4, 0, sizeof( *addr4 ) );
+			addr4->sin_family												= AF_INET;
+			memcpy( &addr4->sin_addr, &inRef->addr4, 4 );
+			dst 															+= sizeof( *addr4 );
+		
+			outQuerySet->lpcsaBuffer[ index ].iSocketType 					= AF_INET;		// Emulate Tcpip NSP
+			outQuerySet->lpcsaBuffer[ index ].iProtocol						= IPPROTO_UDP;	// Emulate Tcpip NSP
+
+			index++;
+		}
+
+		if ( inRef->addr6Valid )
+		{
+			outQuerySet->lpcsaBuffer[ index ].LocalAddr.lpSockaddr 			= NULL;
+			outQuerySet->lpcsaBuffer[ index ].LocalAddr.iSockaddrLength		= 0;
+		
+			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.lpSockaddr 		= (LPSOCKADDR) dst;
+			outQuerySet->lpcsaBuffer[ index ].RemoteAddr.iSockaddrLength	= sizeof( struct sockaddr_in6 );
+		
+			addr6 															= (struct sockaddr_in6 *) dst;
+			memset( addr6, 0, sizeof( *addr6 ) );
+			addr6->sin6_family												= AF_INET6;
+			addr6->sin6_scope_id											= inRef->addr6ScopeId;
+			memcpy( &addr6->sin6_addr, &inRef->addr6, 16 );
+			dst 															+= sizeof( *addr6 );
+		
+			outQuerySet->lpcsaBuffer[ index ].iSocketType 					= AF_INET6;		// Emulate Tcpip NSP
+			outQuerySet->lpcsaBuffer[ index ].iProtocol						= IPPROTO_UDP;	// Emulate Tcpip NSP
+		}
+	}
+	else
+	{
+		outQuerySet->dwNumberOfCsAddrs	= 0;
+		outQuerySet->lpcsaBuffer 		= NULL;
+	}
+	
+	// Copy the hostent blob.
+	
+	if( ( inQuerySetFlags & LUP_RETURN_BLOB ) && inRef->addr4Valid )
+	{
+		uint8_t *				base;
+		struct hostent *		he;
+		uintptr_t *				p;
+
+		outQuerySet->lpBlob	 = (LPBLOB) dst;
+		dst 				+= sizeof( *outQuerySet->lpBlob );
+		
+		base = dst;
+		he	 = (struct hostent *) dst;
+		dst += sizeof( *he );
+		
+		he->h_name = (char *)( dst - base );
+		memcpy( dst, inRef->name, inRef->nameSize + 1 );
+		dst += ( inRef->nameSize + 1 );
+		
+		he->h_aliases 	= (char **)( dst - base );
+		p	  			= (uintptr_t *) dst;
+		*p++  			= 0;
+		dst 		 	= (uint8_t *) p;
+		
+		he->h_addrtype 	= AF_INET;
+		he->h_length	= 4;
+		
+		he->h_addr_list	= (char **)( dst - base );
+		p	  			= (uintptr_t *) dst;
+		dst 		   += ( 2 * sizeof( *p ) );
+		*p++			= (uintptr_t)( dst - base );
+		*p++			= 0;
+		p	  			= (uintptr_t *) dst;
+		*p++			= (uintptr_t) inRef->addr4;
+		dst 		 	= (uint8_t *) p;
+		
+		outQuerySet->lpBlob->cbSize 	= (ULONG)( dst - base );
+		outQuerySet->lpBlob->pBlobData	= (BYTE *) base;
+	}
+	dlog_query_set( kDebugLevelVerbose, outQuerySet );
+
+	check( (size_t)( dst - ( (uint8_t *) outQuerySet ) ) == debugSize );
+}
+
+//===========================================================================================================================
+//	QueryCopyQuerySetSize
+//
+//	Warning: Assumes the NSP lock is held.
+//===========================================================================================================================
+
+DEBUG_LOCAL size_t	QueryCopyQuerySetSize( QueryRef inRef, const WSAQUERYSETW *inQuerySet, DWORD inQuerySetFlags )
+{
+	size_t		size;
+	LPCWSTR		s;
+	LPCWSTR		p;
+	
+	check( inRef );
+	check( inQuerySet );
+	
+	// Calculate the size of the static portion of the results.
+	
+	size = sizeof( *inQuerySet );
+	
+	if( inQuerySetFlags & LUP_RETURN_NAME )
+	{
+		s = inQuerySet->lpszServiceInstanceName;
+		if( s )
+		{
+			for( p = s; *p; ++p ) {}
+			size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
+		}
+	}
+	
+	if( inQuerySet->lpServiceClassId )
+	{
+		size += sizeof( *inQuerySet->lpServiceClassId );
+	}
+	
+	if( inQuerySet->lpVersion )
+	{
+		size += sizeof( *inQuerySet->lpVersion );
+	}
+	
+	s = inQuerySet->lpszComment;
+	if( s )
+	{
+		for( p = s; *p; ++p ) {}
+		size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
+	}
+	
+	if( inQuerySet->lpNSProviderId )
+	{
+		size += sizeof( *inQuerySet->lpNSProviderId );
+	}
+	
+	s = inQuerySet->lpszContext;
+	if( s )
+	{
+		for( p = s; *p; ++p ) {}
+		size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
+	}
+	
+	size += ( inQuerySet->dwNumberOfProtocols * sizeof( *inQuerySet->lpafpProtocols ) );
+	
+	s = inQuerySet->lpszQueryString;
+	if( s )
+	{
+		for( p = s; *p; ++p ) {}
+		size += (size_t)( ( ( p - s ) + 1 ) * sizeof( *p ) );
+	}
+	
+	// Calculate the size of the address(es).
+	
+	if( ( inQuerySetFlags & LUP_RETURN_ADDR ) && inRef->addr4Valid )
+	{
+		size += sizeof( *inQuerySet->lpcsaBuffer );
+		size += sizeof( struct sockaddr_in );
+	}
+
+	if( ( inQuerySetFlags & LUP_RETURN_ADDR ) && inRef->addr6Valid )
+	{
+		size += sizeof( *inQuerySet->lpcsaBuffer );
+		size += sizeof( struct sockaddr_in6 );
+	}
+	
+	// Calculate the size of the hostent blob.
+	
+	if( ( inQuerySetFlags & LUP_RETURN_BLOB ) && inRef->addr4Valid )
+	{
+		size += sizeof( *inQuerySet->lpBlob );	// Blob ptr/size structure
+		size += sizeof( struct hostent );		// Old-style hostent structure
+		size += ( inRef->nameSize + 1 );		// Name and null terminator
+		size += 4;								// Alias list terminator (0 offset)
+		size += 4;								// Offset to address.
+		size += 4;								// Address list terminator (0 offset)
+		size += 4;								// IPv4 address
+	}
+	return( size );
+}
+
+#if 0
+#pragma mark -
+#endif
+
+#if( DEBUG )
+//===========================================================================================================================
+//	DebugDumpQuerySet
+//===========================================================================================================================
+
+#define	DebugSocketFamilyToString( FAM )	( ( FAM ) == AF_INET )  ? "AF_INET"  : \
+											( ( FAM ) == AF_INET6 ) ? "AF_INET6" : ""
+
+#define	DebugSocketProtocolToString( PROTO )	( ( PROTO ) == IPPROTO_UDP ) ? "IPPROTO_UDP" : \
+												( ( PROTO ) == IPPROTO_TCP ) ? "IPPROTO_TCP" : ""
+
+#define	DebugNameSpaceToString( NS )			( ( NS ) == NS_DNS ) ? "NS_DNS" : ( ( NS ) == NS_ALL ) ? "NS_ALL" : ""
+
+void	DebugDumpQuerySet( DebugLevel inLevel, const WSAQUERYSETW *inQuerySet )
+{
+	DWORD		i;
+	
+	check( inQuerySet );
+
+	// Fixed portion of the QuerySet.
+		
+	dlog( inLevel, "QuerySet:\n" );
+	dlog( inLevel, "    dwSize:                  %d (expected %d)\n", inQuerySet->dwSize, sizeof( *inQuerySet ) );
+	if( inQuerySet->lpszServiceInstanceName )
+	{
+		dlog( inLevel, "    lpszServiceInstanceName: %S\n", inQuerySet->lpszServiceInstanceName );
+	}
+	else
+	{
+		dlog( inLevel, "    lpszServiceInstanceName: <null>\n" );
+	}
+	if( inQuerySet->lpServiceClassId )
+	{
+		dlog( inLevel, "    lpServiceClassId:        %U\n", inQuerySet->lpServiceClassId );
+	}
+	else
+	{
+		dlog( inLevel, "    lpServiceClassId:        <null>\n" );
+	}
+	if( inQuerySet->lpVersion )
+	{
+		dlog( inLevel, "    lpVersion:\n" );
+		dlog( inLevel, "        dwVersion:               %d\n", inQuerySet->lpVersion->dwVersion );
+		dlog( inLevel, "        dwVersion:               %d\n", inQuerySet->lpVersion->ecHow );
+	}
+	else
+	{
+		dlog( inLevel, "    lpVersion:               <null>\n" );
+	}
+	if( inQuerySet->lpszComment )
+	{
+		dlog( inLevel, "    lpszComment:             %S\n", inQuerySet->lpszComment );
+	}
+	else
+	{
+		dlog( inLevel, "    lpszComment:             <null>\n" );
+	}
+	dlog( inLevel, "    dwNameSpace:             %d %s\n", inQuerySet->dwNameSpace, 
+		DebugNameSpaceToString( inQuerySet->dwNameSpace ) );
+	if( inQuerySet->lpNSProviderId )
+	{
+		dlog( inLevel, "    lpNSProviderId:          %U\n", inQuerySet->lpNSProviderId );
+	}
+	else
+	{
+		dlog( inLevel, "    lpNSProviderId:          <null>\n" );
+	}
+	if( inQuerySet->lpszContext )
+	{
+		dlog( inLevel, "    lpszContext:             %S\n", inQuerySet->lpszContext );
+	}
+	else
+	{
+		dlog( inLevel, "    lpszContext:             <null>\n" );
+	}
+	dlog( inLevel, "    dwNumberOfProtocols:     %d\n", inQuerySet->dwNumberOfProtocols );
+	dlog( inLevel, "    lpafpProtocols:          %s\n", inQuerySet->lpafpProtocols ? "" : "<null>" );
+	for( i = 0; i < inQuerySet->dwNumberOfProtocols; ++i )
+	{
+		if( i != 0 )
+		{
+			dlog( inLevel, "\n" );
+		}
+		dlog( inLevel, "        iAddressFamily:          %d %s\n", inQuerySet->lpafpProtocols[ i ].iAddressFamily, 
+			DebugSocketFamilyToString( inQuerySet->lpafpProtocols[ i ].iAddressFamily ) );
+		dlog( inLevel, "        iProtocol:               %d %s\n", inQuerySet->lpafpProtocols[ i ].iProtocol, 
+			DebugSocketProtocolToString( inQuerySet->lpafpProtocols[ i ].iProtocol ) );
+	}
+	if( inQuerySet->lpszQueryString )
+	{
+		dlog( inLevel, "    lpszQueryString:         %S\n", inQuerySet->lpszQueryString );
+	}
+	else
+	{
+		dlog( inLevel, "    lpszQueryString:         <null>\n" );
+	}
+	dlog( inLevel, "    dwNumberOfCsAddrs:       %d\n", inQuerySet->dwNumberOfCsAddrs );
+	dlog( inLevel, "    lpcsaBuffer:             %s\n", inQuerySet->lpcsaBuffer ? "" : "<null>" );
+	for( i = 0; i < inQuerySet->dwNumberOfCsAddrs; ++i )
+	{
+		if( i != 0 )
+		{
+			dlog( inLevel, "\n" );
+		}
+		if( inQuerySet->lpcsaBuffer[ i ].LocalAddr.lpSockaddr && 
+			( inQuerySet->lpcsaBuffer[ i ].LocalAddr.iSockaddrLength > 0 ) )
+		{
+			dlog( inLevel, "        LocalAddr:               %##a\n", 
+				inQuerySet->lpcsaBuffer[ i ].LocalAddr.lpSockaddr );
+		}
+		else
+		{
+			dlog( inLevel, "        LocalAddr:               <null/empty>\n" );
+		}
+		if( inQuerySet->lpcsaBuffer[ i ].RemoteAddr.lpSockaddr && 
+			( inQuerySet->lpcsaBuffer[ i ].RemoteAddr.iSockaddrLength > 0 ) )
+		{
+			dlog( inLevel, "        RemoteAddr:              %##a\n", 
+				inQuerySet->lpcsaBuffer[ i ].RemoteAddr.lpSockaddr );
+		}
+		else
+		{
+			dlog( inLevel, "        RemoteAddr:              <null/empty>\n" );
+		}
+		dlog( inLevel, "        iSocketType:             %d\n", inQuerySet->lpcsaBuffer[ i ].iSocketType );
+		dlog( inLevel, "        iProtocol:               %d\n", inQuerySet->lpcsaBuffer[ i ].iProtocol );
+	}
+	dlog( inLevel, "    dwOutputFlags:           %d\n", inQuerySet->dwOutputFlags );
+	
+	// Blob portion of the QuerySet.
+	
+	if( inQuerySet->lpBlob )
+	{
+		dlog( inLevel, "    lpBlob:\n" );
+		dlog( inLevel, "        cbSize:                  %ld\n", inQuerySet->lpBlob->cbSize );
+		dlog( inLevel, "        pBlobData:               %#p\n", inQuerySet->lpBlob->pBlobData );
+		dloghex( inLevel, 12, NULL, 0, 0, NULL, 0, 
+			inQuerySet->lpBlob->pBlobData, inQuerySet->lpBlob->pBlobData, inQuerySet->lpBlob->cbSize, 
+			kDebugFlagsNone, NULL, 0 );
+	}
+	else
+	{
+		dlog( inLevel, "    lpBlob:                  <null>\n" );
+	}
+}
+#endif
+
+
+//===========================================================================================================================
+//	InHostsTable
+//===========================================================================================================================
+
+DEBUG_LOCAL BOOL
+InHostsTable( const char * name )
+{
+	HostsFileInfo	*	node;
+	BOOL				ret = FALSE;
+	OSStatus			err;
+	
+	check( name );
+
+	if ( gHostsFileInfo == NULL )
+	{
+		TCHAR				systemDirectory[MAX_PATH];
+		TCHAR				hFileName[MAX_PATH];
+		HostsFile		*	hFile;
+
+		GetSystemDirectory( systemDirectory, sizeof( systemDirectory ) );
+		sprintf( hFileName, "%s\\drivers\\etc\\hosts", systemDirectory );
+		err = HostsFileOpen( &hFile, hFileName );
+		require_noerr( err, exit );
+
+		while ( HostsFileNext( hFile, &node ) == 0 )
+		{
+			if ( IsLocalName( node ) )
+			{
+				node->m_next = gHostsFileInfo;
+				gHostsFileInfo = node;
+			}
+			else
+			{
+				HostsFileInfoFree( node );
+			}
+		}
+
+		HostsFileClose( hFile );
+	}
+
+	for ( node = gHostsFileInfo; node; node = node->m_next )
+	{
+		if ( IsSameName( node, name ) )
+		{
+			ret = TRUE;
+			break;
+		}
+	}
+
+exit:
+
+	return ret;
+}
+
+
+//===========================================================================================================================
+//	IsLocalName
+//===========================================================================================================================
+
+DEBUG_LOCAL BOOL
+IsLocalName( HostsFileInfo * node )
+{
+	BOOL ret = TRUE;
+
+	check( node );
+
+	if ( strstr( node->m_host.h_name, ".local" ) == NULL )
+	{
+		int i;
+
+		for ( i = 0; node->m_host.h_aliases[i]; i++ )
+		{
+			if ( strstr( node->m_host.h_aliases[i], ".local" ) )
+			{
+				goto exit;
+			}
+		}
+
+		ret = FALSE;
+	}
+
+exit:
+
+	return ret;
+}
+
+
+//===========================================================================================================================
+//	IsSameName
+//===========================================================================================================================
+
+DEBUG_LOCAL BOOL
+IsSameName( HostsFileInfo * node, const char * name )
+{
+	BOOL ret = TRUE;
+
+	check( node );
+	check( name );
+
+	if ( strcmp( node->m_host.h_name, name ) != 0 )
+	{
+		int i;
+
+		for ( i = 0; node->m_host.h_aliases[i]; i++ )
+		{
+			if ( strcmp( node->m_host.h_aliases[i], name ) == 0 )
+			{
+				goto exit;
+			}
+		}
+
+		ret = FALSE;
+	}
+
+exit:
+
+	return ret;
+}
+
+
+//===========================================================================================================================
+//	HostsFileOpen
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus
+HostsFileOpen( HostsFile ** self, const char * fname )
+{
+	OSStatus err = kNoErr;
+
+	*self = (HostsFile*) malloc( sizeof( HostsFile ) );
+	require_action( *self, exit, err = kNoMemoryErr );
+	memset( *self, 0, sizeof( HostsFile ) );
+
+	(*self)->m_bufferSize = BUFFER_INITIAL_SIZE;
+	(*self)->m_buffer = (char*) malloc( (*self)->m_bufferSize );
+	require_action( (*self)->m_buffer, exit, err = kNoMemoryErr );
+
+	// check malloc
+
+	(*self)->m_fp = fopen( fname, "r" );
+	require_action( (*self)->m_fp, exit, err = kUnknownErr );
+
+exit:
+
+	if ( err && *self )
+	{
+		HostsFileClose( *self );
+		*self = NULL;
+	}
+		
+	return err;
+}
+
+
+//===========================================================================================================================
+//	HostsFileClose
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus
+HostsFileClose( HostsFile * self )
+{
+	check( self );
+
+	if ( self->m_buffer )
+	{
+		free( self->m_buffer );
+		self->m_buffer = NULL;
+	}
+
+	if ( self->m_fp )
+	{
+		fclose( self->m_fp );
+		self->m_fp = NULL;
+	}
+
+	free( self );
+
+	return kNoErr;
+} 
+
+
+//===========================================================================================================================
+//	HostsFileInfoFree
+//===========================================================================================================================
+
+DEBUG_LOCAL void
+HostsFileInfoFree( HostsFileInfo * info )
+{
+	while ( info )
+	{
+		HostsFileInfo * next = info->m_next;
+
+		if ( info->m_host.h_addr_list )
+		{
+			if ( info->m_host.h_addr_list[0] )
+			{
+				free( info->m_host.h_addr_list[0] );
+				info->m_host.h_addr_list[0] = NULL;
+			}
+
+			free( info->m_host.h_addr_list );
+			info->m_host.h_addr_list = NULL;
+		}
+
+		if ( info->m_host.h_aliases )
+		{
+			int i;
+
+			for ( i = 0; info->m_host.h_aliases[i]; i++ )
+			{
+				free( info->m_host.h_aliases[i] );
+			}
+
+			free( info->m_host.h_aliases );
+		}
+
+		if ( info->m_host.h_name )
+		{
+			free( info->m_host.h_name );
+			info->m_host.h_name = NULL;
+		}
+			
+		free( info );
+
+		info = next;
+	}
+}
+
+
+//===========================================================================================================================
+//	HostsFileNext
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus
+HostsFileNext( HostsFile * self, HostsFileInfo ** hInfo )
+{
+	struct sockaddr_in6	addr_6;
+	struct sockaddr_in	addr_4;
+	int					numAliases = ALIASES_INITIAL_SIZE;
+	char			*	line;
+	char			*	tok;
+	int					dwSize;
+	int					idx;
+	int					i;
+	short				family;
+	OSStatus			err = kNoErr;
+
+	check( self );
+	check( self->m_fp );
+	check( hInfo );
+
+	idx	= 0;
+
+	*hInfo = (HostsFileInfo*) malloc( sizeof( HostsFileInfo ) );
+	require_action( *hInfo, exit, err = kNoMemoryErr );
+	memset( *hInfo, 0, sizeof( HostsFileInfo ) );
+
+	for ( ; ; )
+	{
+		line = fgets( self->m_buffer + idx, self->m_bufferSize - idx, self->m_fp );
+		
+		if ( line == NULL )
+		{
+			err = 1;
+			goto exit;
+		}
+
+		// If there's no eol and no eof, then we didn't get the whole line
+
+		if ( !strchr( line, '\n' ) && !feof( self->m_fp ) )
+		{
+			int			bufferSize;
+			char	*	buffer;
+
+			/* Try and allocate space for longer line */
+
+			bufferSize	= self->m_bufferSize * 2;
+			buffer		= (char*) realloc( self->m_buffer, bufferSize );
+			require_action( buffer, exit, err = kNoMemoryErr );
+			self->m_bufferSize	= bufferSize;
+			self->m_buffer		= buffer;
+			idx					= (int) strlen( self->m_buffer );
+
+			continue;
+		}
+
+		line	= self->m_buffer;
+		idx		= 0;
+
+		if (*line == '#')
+		{
+			continue;
+		}
+
+		// Get rid of either comments or eol characters
+
+		if (( tok = strpbrk(line, "#\n")) != NULL )
+		{
+			*tok = '\0';
+		}
+
+		// Make sure there is some whitespace on this line
+
+		if (( tok = strpbrk(line, " \t")) == NULL )
+		{
+			continue;
+		}
+
+		// Create two strings, where p == the IP Address and tok is the name list
+
+		*tok++ = '\0';
+
+		while ( *tok == ' ' || *tok == '\t')
+		{
+			tok++;
+		}
+
+		// Now we have the name
+
+		(*hInfo)->m_host.h_name = (char*) malloc( strlen( tok ) + 1 );
+		require_action( (*hInfo)->m_host.h_name, exit, err = kNoMemoryErr );
+		strcpy( (*hInfo)->m_host.h_name, tok );
+
+		// Now create the address (IPv6/IPv4)
+
+		addr_6.sin6_family	= family = AF_INET6;
+		dwSize				= sizeof( addr_6 );
+
+		if ( WSAStringToAddress( line, AF_INET6, NULL, ( struct sockaddr*) &addr_6, &dwSize ) != 0 )
+		{
+			addr_4.sin_family = family = AF_INET;
+			dwSize = sizeof( addr_4 );
+
+			if (WSAStringToAddress( line, AF_INET, NULL, ( struct sockaddr*) &addr_4, &dwSize ) != 0 )
+			{
+				continue;
+			}
+		}
+
+		(*hInfo)->m_host.h_addr_list = (char**) malloc( sizeof( char**) * 2 );
+		require_action( (*hInfo)->m_host.h_addr_list, exit, err = kNoMemoryErr );
+
+		if ( family == AF_INET6 )
+		{
+			(*hInfo)->m_host.h_length		= (short) sizeof( addr_6.sin6_addr );
+			(*hInfo)->m_host.h_addr_list[0] = (char*) malloc( (*hInfo)->m_host.h_length );
+			require_action( (*hInfo)->m_host.h_addr_list[0], exit, err = kNoMemoryErr );
+			memmove( (*hInfo)->m_host.h_addr_list[0], &addr_6.sin6_addr, sizeof( addr_6.sin6_addr ) );
+			
+		}
+		else
+		{
+			(*hInfo)->m_host.h_length		= (short) sizeof( addr_4.sin_addr );
+			(*hInfo)->m_host.h_addr_list[0] = (char*) malloc( (*hInfo)->m_host.h_length );
+			require_action( (*hInfo)->m_host.h_addr_list[0], exit, err = kNoMemoryErr );
+			memmove( (*hInfo)->m_host.h_addr_list[0], &addr_4.sin_addr, sizeof( addr_4.sin_addr ) );
+		}
+
+		(*hInfo)->m_host.h_addr_list[1] = NULL;
+		(*hInfo)->m_host.h_addrtype		= family;
+
+		// Now get the aliases
+
+		if ((tok = strpbrk(tok, " \t")) != NULL)
+		{
+			*tok++ = '\0';
+		}
+
+		i = 0;
+
+		(*hInfo)->m_host.h_aliases		= (char**) malloc( sizeof(char**) * numAliases );
+		require_action( (*hInfo)->m_host.h_aliases, exit, err = kNoMemoryErr );
+		(*hInfo)->m_host.h_aliases[0]	= NULL;
+
+		while ( tok && *tok )
+		{
+			// Skip over the whitespace, waiting for the start of the next alias name
+
+			if (*tok == ' ' || *tok == '\t')
+			{
+				tok++;
+				continue;
+			}
+
+			// Check to make sure we don't exhaust the alias buffer
+
+			if ( i >= ( numAliases - 1 ) )
+			{
+				numAliases = numAliases * 2;
+				(*hInfo)->m_host.h_aliases = (char**) realloc( (*hInfo)->m_host.h_aliases, numAliases * sizeof( char** ) );
+				require_action( (*hInfo)->m_host.h_aliases, exit, err = kNoMemoryErr );
+			}
+
+			(*hInfo)->m_host.h_aliases[i] = (char*) malloc( strlen( tok ) + 1 );
+			require_action( (*hInfo)->m_host.h_aliases[i], exit, err = kNoMemoryErr );
+
+			strcpy( (*hInfo)->m_host.h_aliases[i], tok );
+
+			if (( tok = strpbrk( tok, " \t")) != NULL )
+			{
+				*tok++ = '\0';
+			}
+
+			(*hInfo)->m_host.h_aliases[++i] = NULL;
+		}
+
+		break;
+	}
+
+exit:
+
+	if ( err && ( *hInfo ) )
+	{
+		HostsFileInfoFree( *hInfo );
+		*hInfo = NULL;
+	}
+
+	return err;
+}
+
+
+#ifdef ENABLE_REVERSE_LOOKUP
+//===========================================================================================================================
+//	IsReverseLookup
+//===========================================================================================================================
+
+DEBUG_LOCAL OSStatus
+IsReverseLookup( LPCWSTR name, size_t size )
+{
+	LPCWSTR		p;
+	OSStatus	err = kNoErr;
+
+	// IPv6LL Reverse-mapping domains are {8,9,A,B}.E.F.ip6.arpa
+	require_action_quiet( size > sizeof_string( ".0.8.e.f.ip6.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
+ 
+	p = name + ( size - 1 );
+	p = ( *p == '.' ) ? ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) : ( ( p - sizeof_string( ".0.8.e.f.ip6.arpa" ) ) + 1 );
+	
+	if	( ( ( p[ 0 ] != '.' )							||
+		( ( p[ 1 ] != '0' ) )							||
+		( ( p[ 2 ] != '.' ) )							||
+		( ( p[ 3 ] != '8' ) )							||
+		( ( p[ 4 ] != '.' ) )							||
+		( ( p[ 5 ] != 'E' ) && ( p[ 5 ] != 'e' ) )		||
+		( ( p[ 6 ] != '.' ) )							||
+		( ( p[ 7 ] != 'F' ) && ( p[ 7 ] != 'f' ) )		||
+		( ( p[ 8 ] != '.' ) )							||
+		( ( p[ 9 ] != 'I' ) && ( p[ 9 ] != 'i' ) )		||
+		( ( p[ 10 ] != 'P' ) && ( p[ 10 ] != 'p' ) )	||	
+		( ( p[ 11 ] != '6' ) )							||
+		( ( p[ 12 ] != '.' ) )							||
+		( ( p[ 13 ] != 'A' ) && ( p[ 13 ] != 'a' ) )	||
+		( ( p[ 14 ] != 'R' ) && ( p[ 14 ] != 'r' ) )	||
+		( ( p[ 15 ] != 'P' ) && ( p[ 15 ] != 'p' ) )	||
+		( ( p[ 16 ] != 'A' ) && ( p[ 16 ] != 'a' ) ) ) )
+	{
+		require_action_quiet( size > sizeof_string( ".254.169.in-addr.arpa" ), exit, err = WSASERVICE_NOT_FOUND );
+ 
+		p = name + ( size - 1 );
+		p = ( *p == '.' ) ? ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) : ( ( p - sizeof_string( ".254.169.in-addr.arpa" ) ) + 1 );
+	
+		require_action_quiet( ( ( p[ 0 ] == '.' )						 &&
+								( ( p[ 1 ] == '2' ) )							&&
+								( ( p[ 2 ] == '5' ) )							&&
+								( ( p[ 3 ] == '4' ) )							&&
+								( ( p[ 4 ] == '.' ) )							&&
+								( ( p[ 5 ] == '1' ) )							&&
+								( ( p[ 6 ] == '6' ) )							&&
+								( ( p[ 7 ] == '9' ) )							&&
+								( ( p[ 8 ] == '.' ) )							&&
+								( ( p[ 9 ] == 'I' ) || ( p[ 9 ] == 'i' ) )		&&
+								( ( p[ 10 ] == 'N' ) || ( p[ 10 ] == 'n' ) )	&&	
+								( ( p[ 11 ] == '-' ) )							&&
+								( ( p[ 12 ] == 'A' ) || ( p[ 12 ] == 'a' ) )	&&
+								( ( p[ 13 ] == 'D' ) || ( p[ 13 ] == 'd' ) )	&&
+								( ( p[ 14 ] == 'D' ) || ( p[ 14 ] == 'd' ) )	&&
+								( ( p[ 15 ] == 'R' ) || ( p[ 15 ] == 'r' ) )	&&
+								( ( p[ 16 ] == '.' ) )							&&
+								( ( p[ 17 ] == 'A' ) || ( p[ 17 ] == 'a' ) )	&&
+								( ( p[ 18 ] == 'R' ) || ( p[ 18 ] == 'r' ) )	&&
+								( ( p[ 19 ] == 'P' ) || ( p[ 19 ] == 'p' ) )	&&
+								( ( p[ 20 ] == 'A' ) || ( p[ 20 ] == 'a' ) ) ),
+								exit, err = WSASERVICE_NOT_FOUND );
+	}
+
+	// It's a reverse lookup
+
+	check( err == kNoErr );
+
+exit:
+
+	return err;
+}
+#endif
+
+//===========================================================================================================================
+//	GetScopeId
+//===========================================================================================================================
+
+DEBUG_LOCAL DWORD
+GetScopeId( DWORD ifIndex )
+{
+	DWORD						err;
+	int							i;
+	DWORD						flags;
+	struct ifaddrs *			head;
+	struct ifaddrs **			next;
+	IP_ADAPTER_ADDRESSES *		iaaList;
+	ULONG						iaaListSize;
+	IP_ADAPTER_ADDRESSES *		iaa;
+	DWORD						scopeId = 0;
+	
+	head	= NULL;
+	next	= &head;
+	iaaList	= NULL;
+	
+	require( gGetAdaptersAddressesFunctionPtr, exit );
+
+	// Get the list of interfaces. The first call gets the size and the second call gets the actual data.
+	// This loops to handle the case where the interface changes in the window after getting the size, but before the
+	// second call completes. A limit of 100 retries is enforced to prevent infinite loops if something else is wrong.
+	
+	flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
+	i = 0;
+	for( ;; )
+	{
+		iaaListSize = 0;
+		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, NULL, &iaaListSize );
+		check( err == ERROR_BUFFER_OVERFLOW );
+		check( iaaListSize >= sizeof( IP_ADAPTER_ADDRESSES ) );
+		
+		iaaList = (IP_ADAPTER_ADDRESSES *) malloc( iaaListSize );
+		require_action( iaaList, exit, err = ERROR_NOT_ENOUGH_MEMORY );
+		
+		err = gGetAdaptersAddressesFunctionPtr( AF_UNSPEC, flags, NULL, iaaList, &iaaListSize );
+		if( err == ERROR_SUCCESS ) break;
+		
+		free( iaaList );
+		iaaList = NULL;
+		++i;
+		require( i < 100, exit );
+		dlog( kDebugLevelWarning, "%s: retrying GetAdaptersAddresses after %d failure(s) (%d %m)\n", __ROUTINE__, i, err, err );
+	}
+	
+	for( iaa = iaaList; iaa; iaa = iaa->Next )
+	{
+		DWORD ipv6IfIndex;
+
+		if ( iaa->IfIndex > 0xFFFFFF )
+		{
+			continue;
+		}
+		if ( iaa->Ipv6IfIndex > 0xFF )
+		{
+			continue;
+		}
+
+		// For IPv4 interfaces, there seems to be a bug in iphlpapi.dll that causes the 
+		// following code to crash when iterating through the prefix list.  This seems
+		// to occur when iaa->Ipv6IfIndex != 0 when IPv6 is not installed on the host.
+		// This shouldn't happen according to Microsoft docs which states:
+		//
+		//     "Ipv6IfIndex contains 0 if IPv6 is not available on the interface."
+		//
+		// So the data structure seems to be corrupted when we return from
+		// GetAdaptersAddresses(). The bug seems to occur when iaa->Length <
+		// sizeof(IP_ADAPTER_ADDRESSES), so when that happens, we'll manually
+		// modify iaa to have the correct values.
+
+		if ( iaa->Length >= sizeof( IP_ADAPTER_ADDRESSES ) )
+		{
+			ipv6IfIndex = iaa->Ipv6IfIndex;
+		}
+		else
+		{
+			ipv6IfIndex	= 0;
+		}
+
+		// Skip psuedo and tunnel interfaces.
+		
+		if( ( ipv6IfIndex == 1 ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
+		{
+			continue;
+		}
+
+		if ( iaa->IfIndex == ifIndex )
+		{
+			scopeId = iaa->Ipv6IfIndex;
+			break;
+		}
+	} 
+
+exit:
+
+	if( iaaList )
+	{
+		free( iaaList );
+	}
+
+	return scopeId;
+}
diff --git a/mDNSWindows/mdnsNSP/mdnsNSP.def b/mDNSWindows/mdnsNSP/mdnsNSP.def
new file mode 100644
index 0000000..822213d
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/mdnsNSP.def
@@ -0,0 +1,24 @@
+; -*- tab-width: 4 -*-
+;
+; Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
+;
+; Licensed under the Apache License, Version 2.0 (the "License");
+; you may not use this file except in compliance with the License.
+; You may obtain a copy of the License at
+; 
+;     http://www.apache.org/licenses/LICENSE-2.0
+; 
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+;
+
+LIBRARY		mdnsNSP
+
+EXPORTS
+	NSPStartup
+	NSPCleanup
+	DllRegisterServer	PRIVATE
+	DllUnregisterServer	PRIVATE
diff --git a/mDNSWindows/mdnsNSP/mdnsNSP.rc b/mDNSWindows/mdnsNSP/mdnsNSP.rc
new file mode 100644
index 0000000..c090f0c
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/mdnsNSP.rc
@@ -0,0 +1,104 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include "WinVersRes.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"
+    "#include ""WinVersRes.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION MASTER_PROD_VERS
+ PRODUCTVERSION MASTER_PROD_VERS
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", MASTER_COMPANY_NAME
+            VALUE "FileDescription", "Bonjour Namespace Provider"
+            VALUE "FileVersion", MASTER_PROD_VERS_STR
+            VALUE "InternalName", "mdnsNSP.dll"
+            VALUE "LegalCopyright", MASTER_LEGAL_COPYRIGHT
+            VALUE "OriginalFilename", "mdnsNSP.dll"
+            VALUE "ProductName", MASTER_PROD_NAME
+            VALUE "ProductVersion", MASTER_PROD_VERS_STR
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/mDNSWindows/mdnsNSP/mdnsNSP.vcproj b/mDNSWindows/mdnsNSP/mdnsNSP.vcproj
new file mode 100644
index 0000000..1d6f563
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/mdnsNSP.vcproj
@@ -0,0 +1,457 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="mdnsNSP"

+	ProjectGUID="{F4F15529-F0EB-402F-8662-73C5797EE557}"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+		<Platform

+			Name="x64"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NSP_EXPORTS;DEBUG;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"

+				OutputFile="$(OutDir)/mdnsNSP.dll"

+				LinkIncremental="2"

+				ModuleDefinitionFile="mdnsNSP.def"

+				DelayLoadDLLs="dnssd.dll"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/mdnsNSP.pdb"

+				SubSystem="2"

+				BaseAddress="0x64000000"

+				ImportLibrary="$(OutDir)/mdnsNSP.lib"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Debug|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;NSP_EXPORTS;DEBUG;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="3"

+				SmallerTypeCheck="true"

+				RuntimeLibrary="1"

+				BufferSecurityCheck="true"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"

+				OutputFile="$(OutDir)/mdnsNSP.dll"

+				LinkIncremental="2"

+				ModuleDefinitionFile="mdnsNSP.def"

+				DelayLoadDLLs="dnssd.dll"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(OutDir)/mdnsNSP.pdb"

+				SubSystem="2"

+				BaseAddress="0x64000000"

+				ImportLibrary="$(OutDir)/mdnsNSP.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NSP_EXPORTS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="0"

+				SmallerTypeCheck="false"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"

+				OutputFile="$(OutDir)/mdnsNSP.dll"

+				LinkIncremental="1"

+				ModuleDefinitionFile="mdnsNSP.def"

+				DelayLoadDLLs="dnssd.dll"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				BaseAddress="0x64000000"

+				ImportLibrary="$(IntDir)/mdnsNSP.lib"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                  &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|x64"

+			OutputDirectory="$(PlatformName)\$(ConfigurationName)"

+			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"

+			ConfigurationType="2"

+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"

+			CharacterSet="2"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+				TargetEnvironment="3"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories=".;../;../../mDNSShared;../../Clients"

+				PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;NSP_EXPORTS;WIN32_LEAN_AND_MEAN;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1"

+				StringPooling="true"

+				MinimalRebuild="true"

+				ExceptionHandling="0"

+				BasicRuntimeChecks="0"

+				SmallerTypeCheck="false"

+				RuntimeLibrary="0"

+				UsePrecompiledHeader="0"

+				AssemblerListingLocation="$(IntDir)\"

+				WarningLevel="4"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				CallingConvention="2"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+				AdditionalIncludeDirectories="../"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

+				AdditionalDependencies="../DLL/$(PlatformName)/$(ConfigurationName)/dnssd.lib ws2_32.lib iphlpapi.lib shlwapi.lib"

+				OutputFile="$(OutDir)/mdnsNSP.dll"

+				LinkIncremental="1"

+				ModuleDefinitionFile="mdnsNSP.def"

+				DelayLoadDLLs="dnssd.dll"

+				GenerateDebugInformation="true"

+				ProgramDatabaseFile="$(IntDir)/$(ProjectName).pdb"

+				SubSystem="2"

+				OptimizeReferences="0"

+				EnableCOMDATFolding="0"

+				BaseAddress="0x64000000"

+				ImportLibrary="$(IntDir)/mdnsNSP.lib"

+				TargetMachine="17"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+				CommandLine="if not &quot;%RC_XBS%&quot; == &quot;YES&quot; goto END&#x0D;&#x0A;if not exist &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;   mkdir &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;xcopy /I/Y &quot;$(TargetPath)&quot;                                                                  &quot;$(DSTROOT)\Program Files\Bonjour\$(PlatformName)&quot;&#x0D;&#x0A;:END&#x0D;&#x0A;"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath="..\..\Clients\ClientCommon.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.c"

+				>

+			</File>

+			<File

+				RelativePath=".\mdnsNSP.c"

+				>

+			</File>

+			<File

+				RelativePath=".\mdnsNSP.def"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+			<File

+				RelativePath="..\..\Clients\ClientCommon.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\CommonServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSShared\DebugServices.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\..\mDNSShared\dns_sd.h"

+				>

+			</File>

+			<File

+				RelativePath=".\resource.h"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Resource Files"

+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

+			>

+			<File

+				RelativePath=".\mdnsNSP.rc"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/mDNSWindows/mdnsNSP/resource.h b/mDNSWindows/mdnsNSP/resource.h
new file mode 100644
index 0000000..818f083
--- /dev/null
+++ b/mDNSWindows/mdnsNSP/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by mdnsNSP.rc
+//
+#define IDS_PROJNAME                    100
+#define IDR_WMDMLOGGER                  101
+#define IDS_LOG_SEV_INFO                201
+#define IDS_LOG_SEV_WARN                202
+#define IDS_LOG_SEV_ERROR               203
+#define IDS_LOG_DATETIME                204
+#define IDS_LOG_SRCNAME                 205
+#define IDS_DEF_LOGFILE                 301
+#define IDS_DEF_MAXSIZE                 302
+#define IDS_DEF_SHRINKTOSIZE            303
+#define IDS_DEF_LOGENABLED              304
+#define IDS_MUTEX_TIMEOUT               401
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        201
+#define _APS_NEXT_COMMAND_VALUE         32768
+#define _APS_NEXT_CONTROL_VALUE         201
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif