version 214
diff --git a/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc b/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc
index d535344..a07023e 100755
--- a/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc
+++ b/Clients/PrinterSetupWizard/PrinterSetupWizardLocRes.rc
@@ -256,6 +256,8 @@
     IDS_INSTALL_ERROR_CAPTION "Error"

     IDS_INSTALL_ERROR_MESSAGE 

                             "You do not have sufficient access to your computer to connect to the selected printer."

+	IDS_NO_MATCH_INF_FILE	"The software that you chose does not match the selected printer."

+	IDS_NO_MATCH_INF_FILE_CAPTION "Select Device"

 	IDS_BAD_INF_FILE		"The specified location does not contain information about your printer"

 	IDS_BAD_INF_FILE_CAPTION "Select Device"

     IDS_MANUFACTURER_HEADING "Manufacturer"

diff --git a/Clients/PrinterSetupWizard/ThirdPage.cpp b/Clients/PrinterSetupWizard/ThirdPage.cpp
index f3d0432..8981bd4 100644
--- a/Clients/PrinterSetupWizard/ThirdPage.cpp
+++ b/Clients/PrinterSetupWizard/ThirdPage.cpp
@@ -17,6 +17,9 @@
     Change History (most recent first):
     
 $Log: ThirdPage.cpp,v $
+Revision 1.42  2009/07/07 22:04:55  herscher
+<rdar://problem/4176343> LOC Impact: Need custom text when selecting the wrong printer driver
+
 Revision 1.41  2009/06/18 18:05:50  herscher
 <rdar://problem/4694554> Eliminate the first screen of Printer Wizard and maybe combine others ("I'm Feeling Lucky")
 
@@ -1136,6 +1139,7 @@
 	if (found)
 	{
 		text.LoadString(IDS_PRINTER_MATCH_GOOD);
+		err = kNoErr;
 	}
 	else if ( MatchGeneric( manufacturers, printer, service, &genericManufacturer, &genericModel ) )
 	{
@@ -1157,6 +1161,8 @@
 			SelectMatch( manufacturers, printer, service, genericManufacturer, genericModel );
 			text.LoadString(IDS_PRINTER_MATCH_MAYBE);
 		}
+
+		err = kNoErr;
 	}
 	else
 	{
@@ -1193,6 +1199,8 @@
 				AutoScroll(m_manufacturerListCtrl, nIndex);
 			}
 		}
+
+		err = kUnknownErr;
 	}
 
 	m_printerSelectionText.SetWindowText(text);
@@ -1651,7 +1659,16 @@
 			{
 				PopulateUI( manufacturers );
 
-				MatchPrinter( manufacturers, printer, service, false );
+				if ( MatchPrinter( manufacturers, printer, service, false ) != kNoErr )
+				{
+					CString errorMessage;
+					CString errorCaption;
+					
+					errorMessage.LoadString( IDS_NO_MATCH_INF_FILE );
+					errorCaption.LoadString( IDS_NO_MATCH_INF_FILE_CAPTION );
+
+					MessageBox( errorMessage, errorCaption, MB_OK );
+				}
 
 				break;
 			}
diff --git a/Clients/PrinterSetupWizard/resource_exe.h b/Clients/PrinterSetupWizard/resource_exe.h
index 4a4f980..bb2faaf 100755
--- a/Clients/PrinterSetupWizard/resource_exe.h
+++ b/Clients/PrinterSetupWizard/resource_exe.h
@@ -51,6 +51,8 @@
 #define IDS_PRINTER_UNAVAILABLE         145

 #define IDS_BAD_INF_FILE				150

 #define IDS_BAD_INF_FILE_CAPTION		151

+#define IDS_NO_MATCH_INF_FILE			152

+#define IDS_NO_MATCH_INF_FILE_CAPTION	153

 #define IDC_BUTTON1                     1000

 #define IDC_LIST1                       1000

 #define IDC_BROWSE_LIST                 1000

diff --git a/Clients/PrinterSetupWizard/resource_loc_res.h b/Clients/PrinterSetupWizard/resource_loc_res.h
index 951c54d..3aac90d 100755
--- a/Clients/PrinterSetupWizard/resource_loc_res.h
+++ b/Clients/PrinterSetupWizard/resource_loc_res.h
@@ -52,6 +52,8 @@
 #define IDS_PRINTER_UNAVAILABLE         145

 #define IDS_BAD_INF_FILE				150

 #define IDS_BAD_INF_FILE_CAPTION		151

+#define IDS_NO_MATCH_INF_FILE			152

+#define IDS_NO_MATCH_INF_FILE_CAPTION	153

 #define IDC_BUTTON1                     1000

 #define IDC_LIST1                       1000

 #define IDC_BROWSE_LIST                 1000

diff --git a/Clients/PrinterSetupWizard/resource_res.h b/Clients/PrinterSetupWizard/resource_res.h
index 4a4f980..bb2faaf 100755
--- a/Clients/PrinterSetupWizard/resource_res.h
+++ b/Clients/PrinterSetupWizard/resource_res.h
@@ -51,6 +51,8 @@
 #define IDS_PRINTER_UNAVAILABLE         145

 #define IDS_BAD_INF_FILE				150

 #define IDS_BAD_INF_FILE_CAPTION		151

+#define IDS_NO_MATCH_INF_FILE			152

+#define IDS_NO_MATCH_INF_FILE_CAPTION	153

 #define IDC_BUTTON1                     1000

 #define IDC_LIST1                       1000

 #define IDC_BROWSE_LIST                 1000

diff --git a/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.manifest b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.manifest
new file mode 100755
index 0000000..554f590
--- /dev/null
+++ b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.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.mDNSNetMonitor" type="win32"/>
+	<description>mDNSNetMonitor command line utility.</description>
+	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+		<security>
+			<requestedPrivileges>
+				<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
+			</requestedPrivileges>
+		</security>
+	</trustInfo>
+</assembly>
diff --git a/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj
new file mode 100755
index 0000000..85ede41
--- /dev/null
+++ b/Clients/mDNSNetMonitor.VisualStudio/mDNSNetMonitor.vcproj
@@ -0,0 +1,292 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="mDNSNetMonitor"

+	ProjectGUID="{AF35C285-528D-46A1-8A0E-47B0733DC718}"

+	RootNamespace="mDNSNetMonitor"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

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

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

+			ConfigurationType="1"

+			CharacterSet="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="../../mDNSWindows/SystemService;../../mDNSWindows;../../mDNSShared;../../mDNSCore;&quot;C:/Program Files/Microsoft SDKs/Windows/v6.1/Include&quot;"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;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;_USE_32BIT_TIME_T"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

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

+				LinkIncremental="2"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="mDNSNetMonitor.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"

+			CharacterSet="1"

+			WholeProgramOptimization="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				AdditionalIncludeDirectories="../../mDNSWindows/SystemService;../../mDNSWindows;../../mDNSShared;../../mDNSCore;&quot;C:/Program Files/Microsoft SDKs/Windows/v6.1/Include&quot;"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;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;_USE_32BIT_TIME_T"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

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

+				LinkIncremental="1"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+				AdditionalManifestFiles="mDNSNetMonitor.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;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

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

+			>

+			<File

+				RelativePath="..\..\mDNSCore\DNSCommon.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\DNSDigest.c"

+				>

+			</File>

+			<File

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

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\SystemService\Firewall.cpp"

+				>

+			</File>

+			<File

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

+				>

+			</File>

+			<File

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

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\mDNSWin32.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSPosix\NetMonitor.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\PosixCompat.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\Secret.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\SystemService\Service.c"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\uDNS.c"

+				>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

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

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

+			>

+			<File

+				RelativePath="..\..\mDNSCore\DNSCommon.h"

+				>

+			</File>

+			<File

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

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\SystemService\Firewall.h"

+				>

+			</File>

+			<File

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

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\mDNSDebug.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\mDNSEmbeddedAPI.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\mDNSWin32.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\PosixCompat.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\RegNames.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSWindows\Secret.h"

+				>

+			</File>

+			<File

+				RelativePath="..\..\mDNSCore\uDNS.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>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/Makefile b/Makefile
index 1f62270..aaf7bc6 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@
 
 include /Developer/Makefiles/pb_makefiles/platform.make
 
-MVERS = "mDNSResponder-212.1"
+MVERS = "mDNSResponder-214"
 
 DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
 
diff --git a/mDNSCore/DNSCommon.c b/mDNSCore/DNSCommon.c
index b001a70..bf57929 100644
--- a/mDNSCore/DNSCommon.c
+++ b/mDNSCore/DNSCommon.c
@@ -606,6 +606,7 @@
 #define   SSHPortAsNumber                  22
 #define   UnicastDNSPortAsNumber           53
 #define   SSDPPortAsNumber               1900
+#define   IPSECPortAsNumber              4500
 #define   NSIPCPortAsNumber              5030		// Port used for dnsextd to talk to local nameserver bound to loopback
 #define   NATPMPAnnouncementPortAsNumber 5350
 #define   NATPMPPortAsNumber             5351
@@ -619,6 +620,7 @@
 mDNSexport const mDNSIPPort SSHPort                = { { SSHPortAsNumber                >> 8, SSHPortAsNumber                & 0xFF } };
 mDNSexport const mDNSIPPort UnicastDNSPort         = { { UnicastDNSPortAsNumber         >> 8, UnicastDNSPortAsNumber         & 0xFF } };
 mDNSexport const mDNSIPPort SSDPPort               = { { SSDPPortAsNumber               >> 8, SSDPPortAsNumber               & 0xFF } };
+mDNSexport const mDNSIPPort IPSECPort              = { { IPSECPortAsNumber              >> 8, IPSECPortAsNumber              & 0xFF } };
 mDNSexport const mDNSIPPort NSIPCPort              = { { NSIPCPortAsNumber              >> 8, NSIPCPortAsNumber              & 0xFF } };
 mDNSexport const mDNSIPPort NATPMPAnnouncementPort = { { NATPMPAnnouncementPortAsNumber >> 8, NATPMPAnnouncementPortAsNumber & 0xFF } };
 mDNSexport const mDNSIPPort NATPMPPort             = { { NATPMPPortAsNumber             >> 8, NATPMPPortAsNumber             & 0xFF } };
@@ -2833,7 +2835,7 @@
 		// embedded systems) putting a 9kB object on the stack isn't a big problem.
 		LargeCacheRecord largecr;
 		ptr = GetLargeResourceRecord(m, msg, ptr, end, mDNSInterface_Any, kDNSRecordTypePacketAns, &largecr);
-		if (ptr) LogMsg("%2d TTL%7d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
+		if (ptr) LogMsg("%2d TTL%8d %s", i, largecr.r.resrec.rroriginalttl, CRDisplayString(m, &largecr.r));
 		}
 	if (!ptr) LogMsg("ERROR: Premature end of packet data");
 	return(ptr);
@@ -3048,7 +3050,8 @@
 #endif
 	if (e - m->NextCacheCheck        > 0) e = m->NextCacheCheck;
 	if (e - m->NextScheduledSPS      > 0) e = m->NextScheduledSPS;
-	if (m->SleepLimit && e - m->NextScheduledSPRetry > 0) e = m->NextScheduledSPRetry;
+	// NextScheduledSPRetry only valid when DelaySleep not set
+	if (!m->DelaySleep && m->SleepLimit && e - m->NextScheduledSPRetry > 0) e = m->NextScheduledSPRetry;
 	if (m->DelaySleep && e - m->DelaySleep           > 0) e = m->DelaySleep;
 
 	if (m->SuppressSending)
@@ -3100,7 +3103,7 @@
 		LogMsg("Task Scheduling Error: m->NextScheduledNATOp %d",    m->timenow - m->NextScheduledNATOp);
 	if (m->timenow - m->NextScheduledSPS      >= 0)
 		LogMsg("Task Scheduling Error: m->NextScheduledSPS %d",      m->timenow - m->NextScheduledSPS);
-	if (m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0)
+	if (!m->DelaySleep && m->SleepLimit && m->timenow - m->NextScheduledSPRetry >= 0)
 		LogMsg("Task Scheduling Error: m->NextScheduledSPRetry %d",  m->timenow - m->NextScheduledSPRetry);
 	if (m->DelaySleep && m->timenow - m->DelaySleep >= 0)
 		LogMsg("Task Scheduling Error: m->DelaySleep %d",            m->timenow - m->DelaySleep);
diff --git a/mDNSCore/mDNS.c b/mDNSCore/mDNS.c
index c267896..8fe2a80 100755
--- a/mDNSCore/mDNS.c
+++ b/mDNSCore/mDNS.c
@@ -38,9 +38,13 @@
     Change History (most recent first):
 
 $Log: mDNS.c,v $
-Revision 1.969.2.1  2009/07/23 23:41:25  cheshire
+Revision 1.970.2.1  2009/07/23 23:36:04  cheshire
 <rdar://problem/7086623> Sleep Proxy: Ten-second maintenance wake not long enough to reliably get network connectivity
 
+Revision 1.970  2009/07/11 01:59:27  cheshire
+<rdar://problem/6613674> Sleep Proxy: Add support for using sleep proxy in local network interface hardware
+When going to sleep, try calling ActivateLocalProxy before registering with remote sleep proxy
+
 Revision 1.969  2009/06/30 21:18:19  cheshire
 <rdar://problem/7020041> Plugging and unplugging the power cable shouldn't cause a network change event
 Additional fixes:
@@ -3886,6 +3890,21 @@
 		// which we would subsequently cancel and retract if the CNAME referral record were removed.
 		// In reality this is such a corner case we'll ignore it until someone actually needs it.
 		LogInfo("AnswerCurrentQuestionWithResourceRecord: following CNAME referral for %s", CRDisplayString(m, rr));
+		
+		// If this query is a duplicate of another query, UpdateQuestionDuplicates called from
+		// mDNS_StopQuery_internal copies the value of CNAMEReferrals from this query to the other
+		// query on the Questions list. By setting the new value before calling mDNS_StopQuery_internal,
+		// we ensure that the duplicate question gets a hgigher value and eventually the check for 10 above
+		// would be true. Otherwise, the two queries would end up as active questions
+		// sending mDNSResponder in an infinite loop e.g., Two queries starting off unique but receives
+		// a CNAME response that refers to itself (test IN CNAME test) which makes it a duplicate of
+		// one another. This fix now will make sure that stop at the 10th iteration. 
+		//
+		// Though CNAME records that refer to itself are not added anymore in mDNSCoreReceiveResponse, this fix is
+		// still needed to catch the cases where the CNAME referral spans across multiple records with a potential
+		// cycle in it which in turn can make multiple queries duplicate of each other
+		
+		q->CNAMEReferrals = c;	
 		mDNS_StopQuery_internal(m, q);								// Stop old query
 		AssignDomainName(&q->qname, &rr->resrec.rdata->u.name);		// Update qname
 		q->qnamehash = DomainNameHashValue(&q->qname);				// and namehash
@@ -4130,7 +4149,7 @@
 		if (m->timenow - event >= 0)	// If expired, delete it
 			{
 			*rp = rr->next;				// Cut it from the list
-			verbosedebugf("CheckCacheExpiration: Deleting%7d %4d %p %s",
+			verbosedebugf("CheckCacheExpiration: Deleting%7d %7d %p %s",
 				m->timenow - rr->TimeRcvd, rr->resrec.rroriginalttl, rr->CRActiveQuestion, CRDisplayString(m, rr));
 			if (rr->CRActiveQuestion)	// If this record has one or more active questions, tell them it's going away
 				{
@@ -4877,6 +4896,8 @@
 	if (!AddRecord) return;												// Don't care about REMOVE events
 	if (answer->rrtype != question->qtype) return;						// Don't care about CNAMEs
 
+	// if (answer->rrtype == kDNSType_AAAA) return;	// To test failing to resolve sleep proxy's address
+
 	mDNS_StopQuery(m, question);
 	question->ThisQInterval = -1;
 
@@ -4920,9 +4941,27 @@
 	return mDNSfalse;
 	}
 
+mDNSlocal void SendSleepGoodbyes(mDNS *const m)
+	{
+	AuthRecord *rr;
+	m->SleepState = SleepState_Sleeping;
+
+#ifndef UNICAST_DISABLED
+	SleepServiceRegistrations(m);
+	SleepRecordRegistrations(m);	// If we have no SPS, need to deregister our uDNS records
+#endif
+
+	// Mark all the records we need to deregister and send them
+	for (rr = m->ResourceRecords; rr; rr=rr->next)
+		if (rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye)
+			rr->ImmedAnswer = mDNSInterfaceMark;
+	SendResponses(m);
+	}
+
 // BeginSleepProcessing is called, with the lock held, from either mDNS_Execute or mDNSCoreMachineSleep
 mDNSlocal void BeginSleepProcessing(mDNS *const m)
 	{
+	mDNSBool SendGoodbyes = mDNStrue;
 	const CacheRecord *sps[3] = { mDNSNULL };
 
 	m->NextScheduledSPRetry = m->timenow;
@@ -4935,6 +4974,16 @@
 		for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
 			{
 			if (!intf->NetWake) LogSPS("BeginSleepProcessing: %-6s not capable of magic packet wakeup", intf->ifname);
+#if APPLE_OSX_mDNSResponder
+			else if (ActivateLocalProxy(m, intf->ifname) == mStatus_NoError)
+				{
+				SendGoodbyes = mDNSfalse;
+				LogSPS("BeginSleepProcessing: %-6s using local proxy", intf->ifname);
+				// This will leave m->SleepState set to SleepState_Transferring,
+				// which is okay because with no outstanding resolves, or updates in flight,
+				// mDNSCoreReadyForSleep() will conclude correctly that all the updates have already completed
+				}
+#endif // APPLE_OSX_mDNSResponder
 			else
 				{
 				FindSPSInCache(m, &intf->NetWakeBrowse, sps);
@@ -4942,6 +4991,7 @@
 				else
 					{
 					int i;
+					SendGoodbyes = mDNSfalse;
 					intf->NextSPSAttempt = 0;
 					intf->NextSPSAttemptTime = m->timenow + mDNSPlatformOneSecond;
 					// Don't need to set m->NextScheduledSPRetry here because we already set "m->NextScheduledSPRetry = m->timenow" above
@@ -4969,22 +5019,10 @@
 			}
 		}
 
-	if (!sps[0])	// If we didn't find even one Sleep Proxy
+	if (SendGoodbyes)	// If we didn't find even one Sleep Proxy
 		{
-		AuthRecord *rr;
 		LogSPS("BeginSleepProcessing: Not registering with Sleep Proxy Server");
-		m->SleepState = SleepState_Sleeping;
-
-#ifndef UNICAST_DISABLED
-		SleepServiceRegistrations(m);
-		SleepRecordRegistrations(m);	// If we have no SPS, need to deregister our uDNS records
-#endif
-
-		// Mark all the records we need to deregister and send them
-		for (rr = m->ResourceRecords; rr; rr=rr->next)
-			if (rr->resrec.RecordType == kDNSRecordTypeShared && rr->RequireGoodbye)
-				rr->ImmedAnswer = mDNSInterfaceMark;
-		SendResponses(m);
+		SendSleepGoodbyes(m);
 		}
 	}
 
@@ -5103,7 +5141,7 @@
 	mDNS_Unlock(m);
 	}
 
-mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m)
+mDNSexport mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now)
 	{
 	DNSQuestion *q;
 	AuthRecord *rr;
@@ -5112,26 +5150,43 @@
 
 	mDNS_Lock(m);
 
-	if (m->NextScheduledSPRetry - m->timenow > 0) goto notready;
-
-	m->NextScheduledSPRetry = m->timenow + 0x40000000UL;
-
 	if (m->DelaySleep) goto notready;
 
+	// If we've not hit the sleep limit time, and it's not time for our next retry, we can skip these checks
+	if (m->SleepLimit - now > 0 && m->NextScheduledSPRetry - now > 0) goto notready;
+
+	m->NextScheduledSPRetry = now + 0x40000000UL;
+
 	// See if we might need to retransmit any lost Sleep Proxy Registrations
 	for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
 		if (intf->NextSPSAttempt >= 0)
 			{
-			if (m->timenow - intf->NextSPSAttemptTime >= 0)
+			if (now - intf->NextSPSAttemptTime >= 0)
 				{
 				LogSPS("ReadyForSleep retrying SPS %s %d", intf->ifname, intf->NextSPSAttempt);
 				SendSPSRegistration(m, intf, zeroID);
+				// Don't need to "goto notready" here, becase if we do still have record registrations
+				// that have not been acknowledged yet, we'll catch that in the record list scan below.
 				}
 			else
 				if (m->NextScheduledSPRetry - intf->NextSPSAttemptTime > 0)
 					m->NextScheduledSPRetry = intf->NextSPSAttemptTime;
 			}
 
+	// Scan list of interfaces, and see if we're still waiting for any sleep proxy resolves to complete
+	for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
+		if (intf->NetWakeResolve[0].ThisQInterval >= 0)
+			{
+			LogSPS("ReadyForSleep waiting for SPS Resolve %s %##s (%s)", intf->ifname, intf->NetWakeResolve[0].qname.c, DNSTypeName(intf->NetWakeResolve[0].qtype));
+			goto spsnotready;
+			}
+
+	// Scan list of registered records
+	for (rr = m->ResourceRecords; rr; rr = rr->next)
+		if (!AuthRecord_uDNS(rr))
+			if (!mDNSOpaque16IsZero(rr->updateid))
+				{ LogSPS("ReadyForSleep waiting for SPS Update ID %d %s", mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto spsnotready; }
+
 	// Scan list of private LLQs, and make sure they've all completed their handshake with the server
 	for (q = m->Questions; q; q = q->next)
 		if (!mDNSOpaque16IsZero(q->TargetQID) && q->LongLived && q->ReqLease == 0 && q->tcp)
@@ -5140,28 +5195,11 @@
 			goto notready;
 			}
 
-	// Scan list of interfaces
-	for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
-		if (intf->NetWakeResolve[0].ThisQInterval >= 0)
-			{
-			LogSPS("ReadyForSleep waiting for SPS Resolve %s %##s (%s)", intf->ifname, intf->NetWakeResolve[0].qname.c, DNSTypeName(intf->NetWakeResolve[0].qtype));
-			goto notready;
-			}
-
 	// Scan list of registered records
 	for (rr = m->ResourceRecords; rr; rr = rr->next)
-		{
 		if (AuthRecord_uDNS(rr))
-			{
 			if (rr->state == regState_Refresh && rr->tcp)
 				{ LogSPS("ReadyForSleep waiting for Record Update ID %d %s", mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto notready; }
-			}
-		else
-			{
-			if (!mDNSOpaque16IsZero(rr->updateid))
-				{ LogSPS("ReadyForSleep waiting for SPS Update ID %d %s", mDNSVal16(rr->updateid), ARDisplayString(m,rr)); goto notready; }
-			}
-		}
 
 	// Scan list of registered services
 	for (srs = m->ServiceRegistrations; srs; srs = srs->uDNS_next)
@@ -5170,6 +5208,40 @@
 	mDNS_Unlock(m);
 	return mDNStrue;
 
+spsnotready:
+
+	// If we failed to complete sleep proxy registration within ten seconds, we give up on that
+	// and allow up to ten seconds more to complete wide-area deregistration instead
+	if (now - m->SleepLimit >= 0)
+		{
+		LogMsg("Failed to register with SPS, now sending goodbyes");
+
+		for (intf = GetFirstActiveInterface(m->HostInterfaces); intf; intf = GetFirstActiveInterface(intf->next))
+			if (intf->NetWakeBrowse.ThisQInterval >= 0)
+				{
+				LogSPS("ReadyForSleep mDNS_DeactivateNetWake %s %##s (%s)", intf->ifname, intf->NetWakeResolve[0].qname.c, DNSTypeName(intf->NetWakeResolve[0].qtype));
+				mDNS_DeactivateNetWake_internal(m, intf);
+				}
+
+		for (rr = m->ResourceRecords; rr; rr = rr->next)
+			if (!AuthRecord_uDNS(rr))
+				if (!mDNSOpaque16IsZero(rr->updateid))
+					{
+					LogSPS("ReadyForSleep clearing updateid for %s", ARDisplayString(m, rr));
+					rr->updateid = zeroID;
+					}
+
+		// We'd really like to allow up to ten seconds more here,
+		// but if we don't respond to the sleep notification within 30 seconds
+		// we'll be put back to sleep forcibly without the chance to schedule the next maintenance wake.
+		// Right now we wait 16 sec after wake for all the interfaces to come up, then we wait up to 10 seconds
+		// more for SPS resolves and record registrations to complete, which puts us at 26 seconds.
+		// If we allow just one more second to send our goodbyes, that puts us at 27 seconds.
+		m->SleepLimit = now + mDNSPlatformOneSecond * 1;
+
+		SendSleepGoodbyes(m);
+		}
+
 notready:
 	mDNS_Unlock(m);
 	return mDNSfalse;
@@ -6177,8 +6249,8 @@
 	else	// else not LLQ (standard uDNS response)
 		{
 		// The TTL is already capped to a maximum value in GetLargeResourceRecord, but just to be extra safe we
-		// also do this check here to make sure we can't get integer overflow below
-		if (ttl > 0x8000000UL) ttl = 0x8000000UL;
+		// also do this check here to make sure we can't get overflow below when we add a quarter to the TTL
+		if (ttl > 0x60000000UL / mDNSPlatformOneSecond) ttl = 0x60000000UL / mDNSPlatformOneSecond;
 
 		// Adjustment factor to avoid race condition:
 		// Suppose real record as TTL of 3600, and our local caching server has held it for 3500 seconds, so it returns an aged TTL of 100.
@@ -6338,6 +6410,14 @@
 		// Don't want to cache OPT or TSIG pseudo-RRs
 		if (m->rec.r.resrec.rrtype == kDNSType_OPT || m->rec.r.resrec.rrtype == kDNSType_TSIG)
 			{ m->rec.r.resrec.RecordType = 0; continue; }
+			
+		// if a CNAME record points to itself, then don't add it to the cache
+		if ((m->rec.r.resrec.rrtype == kDNSType_CNAME) && SameDomainName(m->rec.r.resrec.name, &m->rec.r.resrec.rdata->u.name))
+			{ 
+			LogInfo("mDNSCoreReceiveResponse: CNAME loop domain name %##s", m->rec.r.resrec.name->c);
+			m->rec.r.resrec.RecordType = 0; 
+			continue; 
+			}
 		
 		// When we receive uDNS LLQ responses, we assume a long cache lifetime --
 		// In the case of active LLQs, we'll get remove events when the records actually do go away
@@ -8327,7 +8407,7 @@
 		
 		if (flapping)
 			{
-			LogMsg("Note: RegisterInterface: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect",
+			LogMsg("RegisterInterface: Frequent transitions for interface %s (%#a)",
 				set->ifname, &set->ip);
 			if (!m->SuppressProbes ||
 				m->SuppressProbes - (m->timenow + delay) < 0)
@@ -8438,7 +8518,7 @@
 				" marking questions etc. dormant", set->InterfaceID, set->ifname, &set->ip);
 
 			if (flapping)
-				LogMsg("Note: DeregisterInterface: Frequent transitions for interface %s (%#a); network traffic reduction measures in effect",
+				LogMsg("DeregisterInterface: Frequent transitions for interface %s (%#a)",
 					set->ifname, &set->ip);
 
 			// 1. Deactivate any questions specific to this interface, and tag appropriate questions
@@ -9165,11 +9245,11 @@
 					if (rr->resrec.InterfaceID == InterfaceID &&
 						rr->AddressProxy.type == mDNSAddrType_IPv4 && mDNSSameIPv4Address(rr->AddressProxy.ip.v4, v4->dst))
 						{
-						const mDNSu8 *const tp = (v4->protocol == 6) ? (mDNSu8 *)"\x4_tcp" : (mDNSu8 *)"\x4_udp";
+						const mDNSu8 *const tp = (v4->protocol == 6) ? (const mDNSu8 *)"\x4_tcp" : (const mDNSu8 *)"\x4_udp";
 						for (r2 = m->ResourceRecords; r2; r2=r2->next)
 							if (r2->resrec.InterfaceID == InterfaceID && mDNSSameEthAddress(&r2->WakeUp.HMAC, &rr->WakeUp.HMAC) &&
 								r2->resrec.rrtype == kDNSType_SRV && mDNSSameIPPort(r2->resrec.rdata->u.srv.port, port) &&
-								SameDomainLabel(SkipLeadingLabels(r2->resrec.name, 2)->c, tp))
+								SameDomainLabel(ThirdLabel(r2->resrec.name)->c, tp))
 								break;
 						if (!r2 && mDNSSameIPPort(port, IPSEC)) r2 = rr;	// So that we wake for BTMM IPSEC packets, even without a matching SRV record
 						if (r2)
diff --git a/mDNSCore/mDNSEmbeddedAPI.h b/mDNSCore/mDNSEmbeddedAPI.h
index c02cea4..00329ec 100755
--- a/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSCore/mDNSEmbeddedAPI.h
@@ -54,6 +54,13 @@
     Change History (most recent first):
 
 $Log: mDNSEmbeddedAPI.h,v $
+Revision 1.575  2009/07/11 01:57:00  cheshire
+<rdar://problem/6613674> Sleep Proxy: Add support for using sleep proxy in local network interface hardware
+Added declaration of ActivateLocalProxy
+
+Revision 1.574  2009/07/10 23:03:17  cheshire
+Made SecondLabel(X) more defensive, to guard against the case where the name doesn't have a second label
+
 Revision 1.573  2009/06/30 18:17:45  herscher
 Add to 64 bit macro check for 64 bit Windows OSes
 
@@ -1212,6 +1219,13 @@
 	mDNSAddrType_Unknown = ~0	// Special marker value used in known answer list recording
 	};
 
+enum
+	{
+	mDNSTransport_None = 0,
+	mDNSTransport_UDP  = 1,
+	mDNSTransport_TCP  = 2
+	};
+
 typedef struct
 	{
 	mDNSs32 type;
@@ -2562,7 +2576,8 @@
 	mDNSs32  DelaySleep;				// To inhibit re-sleeping too quickly right after wake
 	mDNSs32  SleepLimit;				// Time window to allow deregistrations, etc.,
 										// during which underying platform layer should inhibit system sleep
-	mDNSs32  NextScheduledSPRetry;		// Time next sleep proxy registration action is required. Only valid if SleepLimit is nonzero.
+	mDNSs32  NextScheduledSPRetry;		// Time next sleep proxy registration action is required.
+										// Only valid if SleepLimit is nonzero and DelaySleep is zero.
 
 	// These fields only required for mDNS Searcher...
 	DNSQuestion *Questions;				// List of all registered questions, active and inactive
@@ -2700,6 +2715,7 @@
 extern const mDNSIPPort   SSHPort;
 extern const mDNSIPPort   UnicastDNSPort;
 extern const mDNSIPPort   SSDPPort;
+extern const mDNSIPPort   IPSECPort;
 extern const mDNSIPPort   NSIPCPort;
 extern const mDNSIPPort   NATPMPAnnouncementPort;
 extern const mDNSIPPort   NATPMPPort;
@@ -2979,8 +2995,12 @@
 extern mDNSBool SameDomainNameCS(const domainname *const d1, const domainname *const d2);
 extern mDNSBool IsLocalDomain(const domainname *d);     // returns true for domains that by default should be looked up using link-local multicast
 
+#define StripFirstLabel(X) ((const domainname *)&(X)->c[(X)->c[0] ? 1 + (X)->c[0] : 0])
+
 #define FirstLabel(X)  ((const domainlabel *)(X))
-#define SecondLabel(X) ((const domainlabel *)&(X)->c[1 + (X)->c[0]])
+#define SecondLabel(X) ((const domainlabel *)StripFirstLabel(X))
+#define ThirdLabel(X)  ((const domainlabel *)StripFirstLabel(StripFirstLabel(X)))
+
 extern const mDNSu8 *LastLabel(const domainname *d);
 
 // Get total length of domain name, in native DNS format, including terminal root label
@@ -3377,7 +3397,7 @@
 extern void 	mDNSCoreRestartQueries(mDNS *const m);
 extern mDNSBool mDNSCoreHaveAdvertisedMulticastServices(mDNS *const m);
 extern void     mDNSCoreMachineSleep(mDNS *const m, mDNSBool wake);
-extern mDNSBool mDNSCoreReadyForSleep(mDNS *m);
+extern mDNSBool mDNSCoreReadyForSleep(mDNS *m, mDNSs32 now);
 extern mDNSs32  mDNSCoreIntervalToNextWake(mDNS *const m, mDNSs32 now);
 
 extern void     mDNSCoreBeSleepProxyServer(mDNS *const m, mDNSu8 sps, mDNSu8 port, mDNSu8 marginalpower, mDNSu8 totpower);
@@ -3406,6 +3426,7 @@
 extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
 extern void SetupLocalAutoTunnelInterface_internal(mDNS *const m);
 extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
+extern mStatus ActivateLocalProxy(mDNS *const m, char *ifname);
 #endif
 
 // ***************************************************************************
diff --git a/mDNSMacOSX/LegacyNATTraversal.c b/mDNSMacOSX/LegacyNATTraversal.c
index 5cf1ae1..1a05eb1 100644
--- a/mDNSMacOSX/LegacyNATTraversal.c
+++ b/mDNSMacOSX/LegacyNATTraversal.c
@@ -1002,7 +1002,7 @@
 	ptr = (char *)data;
 	while (ptr && ptr != end)
 		{
-		if (*ptr == 'L' && (strncasecmp(ptr, "Location:", 9) == 0)) break;			// find the first 'L'; is this Location? if not, keep looking
+		if ((*ptr & 0xDF) == 'L' && (strncasecmp(ptr, "Location:", 9) == 0)) break;			// find the first 'L'; is this Location? if not, keep looking
 		ptr++;
 		}
 	if (ptr == mDNSNULL || ptr == end) 
diff --git a/mDNSMacOSX/daemon.c b/mDNSMacOSX/daemon.c
index 50abe96..7e6db35 100644
--- a/mDNSMacOSX/daemon.c
+++ b/mDNSMacOSX/daemon.c
@@ -2663,7 +2663,7 @@
 
 mDNSlocal mDNSBool AllowSleepNow(mDNS *const m, mDNSs32 now)
 	{
-	mDNSBool ready = mDNSCoreReadyForSleep(m);
+	mDNSBool ready = mDNSCoreReadyForSleep(m, now);
 	if (m->SleepState && !ready && now - m->SleepLimit < 0) return(mDNSfalse);
 
 	m->p->WakeAtUTC = 0;
diff --git a/mDNSMacOSX/mDNSMacOSX.c b/mDNSMacOSX/mDNSMacOSX.c
index 7f66dd4..cb3b3c7 100644
--- a/mDNSMacOSX/mDNSMacOSX.c
+++ b/mDNSMacOSX/mDNSMacOSX.c
@@ -17,6 +17,21 @@
     Change History (most recent first):
 
 $Log: mDNSMacOSX.c,v $
+Revision 1.691  2009/07/30 20:28:15  mkrochma
+<rdar://problem/7100784> Sleep Proxy: Structure changes to data passed to userclient
+
+Revision 1.690  2009/07/15 22:34:25  cheshire
+<rdar://problem/6613674> Sleep Proxy: Add support for using sleep proxy in local network interface hardware
+Fixes to make the code still compile with old headers and libraries (pre 10.5) that don't include IOConnectCallStructMethod
+
+Revision 1.689  2009/07/15 22:09:19  cheshire
+<rdar://problem/6613674> Sleep Proxy: Add support for using sleep proxy in local network interface hardware
+Removed unnecessary sleep(1) and syslog message
+
+Revision 1.688  2009/07/11 01:58:17  cheshire
+<rdar://problem/6613674> Sleep Proxy: Add support for using sleep proxy in local network interface hardware
+Added ActivateLocalProxy routine for transferring mDNS records to local proxy
+
 Revision 1.687  2009/06/30 21:16:09  cheshire
 <rdar://problem/7020041> Plugging and unplugging the power cable shouldn't cause a network change event
 Additional fix: Only start and stop NetWake browses for active interfaces that are currently registered with mDNSCore
@@ -1515,7 +1530,7 @@
 	asl_set_filter(NULL, old_filter);
 	asl_free(asl_msg);
 	}
-#endif
+#endif // APPLE_OSX_mDNSResponder
 
 #if COMPILER_LIKES_PRAGMA_MARK
 #pragma mark -
@@ -5323,6 +5338,207 @@
 	return(mStatus_NoError);
 	}
 
+// The definitions below should eventually come from some externally-supplied header file.
+// However, since these definitions can't really be changed without breaking binary compatibility,
+// they should never change, so in practice it should not be a big problem to have them defined here.
+
+#define mDNS_IOREG_KEY               "mDNS_KEY"
+#define mDNS_IOREG_VALUE             "2009-07-30"
+#define mDNS_USER_CLIENT_CREATE_TYPE 'mDNS'
+
+enum
+	{							// commands from the daemon to the driver
+    cmd_mDNSOffloadRR = 21,		// give the mdns update buffer to the driver
+	};
+
+typedef union { void *ptr; mDNSOpaque64 sixtyfourbits; } FatPtr;
+
+typedef struct
+	{                                   // cmd_mDNSOffloadRR structure
+    uint32_t  command;                // set to OffloadRR
+    uint32_t  rrBufferSize;           // number of bytes of RR records
+    uint32_t  numUDPPorts;            // number of SRV UDP ports
+    uint32_t  numTCPPorts;            // number of SRV TCP ports 
+    uint32_t  numRRRecords;           // number of RR records
+    uint32_t  compression;            // rrRecords - compression is base for compressed strings
+    FatPtr    rrRecords;              // address of array of pointers to the rr records
+    FatPtr    udpPorts;               // address of udp port list (SRV)
+    FatPtr    tcpPorts;               // address of tcp port list (SRV)
+	} mDNSOffloadCmd;
+
+#include <IOKit/IOKitLib.h>
+#include <dns_util.h>
+
+mDNSlocal mDNSu16 GetPortArray(mDNS *const m, int trans, mDNSIPPort *portarray)
+	{
+	const domainlabel *const tp = (trans == mDNSTransport_UDP) ? (const domainlabel *)"\x4_udp" : (const domainlabel *)"\x4_tcp";
+	int count = 0;
+	AuthRecord *rr;
+	for (rr = m->ResourceRecords; rr; rr=rr->next)
+		if (rr->resrec.rrtype == kDNSType_SRV && SameDomainLabel(ThirdLabel(rr->resrec.name)->c, tp->c))
+			{
+			if (portarray) portarray[count] = rr->resrec.rdata->u.srv.port;
+			count++;
+			}
+
+	// If Back to My Mac is on, also wake for packets to the IPSEC UDP port (4500)
+	if (trans == mDNSTransport_UDP && TunnelServers(m))	
+		{
+		LogSPS("GetPortArray Back to My Mac at %d", count);
+		if (portarray) portarray[count] = IPSECPort;
+		count++;
+		}
+	return(count);
+	}
+
+#define TfrRecordToNIC(RR) \
+	(((RR)->resrec.InterfaceID && (RR)->resrec.InterfaceID != mDNSInterface_LocalOnly) || \
+	(!(RR)->resrec.InterfaceID && ((RR)->ForceMCast || IsLocalDomain((RR)->resrec.name))))
+
+mDNSlocal mDNSu32 CountProxyRecords(mDNS *const m, uint32_t *numbytes)
+	{
+	*numbytes = 0;
+	int count = 0;
+	AuthRecord *rr;
+	for (rr = m->ResourceRecords; rr; rr=rr->next)
+		if (rr->resrec.RecordType > kDNSRecordTypeDeregistering)
+			if (TfrRecordToNIC(rr))
+				{
+				*numbytes += DomainNameLength(rr->resrec.name) + 10 + rr->resrec.rdestimate;
+				LogSPS("CountProxyRecords: %3d %5d %5d %s", count, DomainNameLength(rr->resrec.name) + 10 + rr->resrec.rdestimate, *numbytes, ARDisplayString(m,rr));
+				count++;
+				}
+	return(count);
+	}
+
+mDNSlocal mDNSu16 GetProxyRecords(mDNS *const m, DNSMessage *msg, uint16_t numbytes, FatPtr *records)
+	{
+	mDNSu8 *p = msg->data;
+	const mDNSu8 *const limit = p + numbytes;
+	InitializeDNSMessage(&msg->h, zeroID, zeroID);
+
+	int count = 0;
+	AuthRecord *rr;
+	for (rr = m->ResourceRecords; rr; rr=rr->next)
+		if (rr->resrec.RecordType > kDNSRecordTypeDeregistering)
+			if (TfrRecordToNIC(rr))
+				{
+				records[count].sixtyfourbits = zeroOpaque64;
+				records[count].ptr = p;
+				if (rr->resrec.RecordType & kDNSRecordTypeUniqueMask)
+					rr->resrec.rrclass |= kDNSClass_UniqueRRSet;	// Temporarily set the 'unique' bit so PutResourceRecord will set it
+				p = PutResourceRecordTTLWithLimit(msg, p, &msg->h.mDNS_numUpdates, &rr->resrec, rr->resrec.rroriginalttl, limit);
+				rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet;		// Make sure to clear 'unique' bit back to normal state
+				LogSPS("GetProxyRecords: %3d %p %p %s", count, records[count].ptr, p, ARDisplayString(m,rr));
+				count++;
+				}
+	return(count);
+	}
+
+// If compiling with old headers and libraries (pre 10.5) that don't include IOConnectCallStructMethod
+// then we declare a dummy version here so that the code at least compiles
+#ifndef AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER
+static kern_return_t
+IOConnectCallStructMethod(
+	mach_port_t	 connection,		// In
+	uint32_t	 selector,		// In
+	const void	*inputStruct,		// In
+	size_t		 inputStructCnt,	// In
+	void		*outputStruct,		// Out
+	size_t		*outputStructCnt)	// In/Out
+	{
+	(void)connection;
+	(void)selector;
+	(void)inputStruct;
+	(void)inputStructCnt;
+	(void)outputStruct;
+	(void)outputStructCnt;
+	LogMsg("Compiled without IOConnectCallStructMethod");
+	return(KERN_FAILURE);
+	}
+#endif
+
+mDNSexport mStatus ActivateLocalProxy(mDNS *const m, char *ifname)
+	{
+	mStatus result = mStatus_UnknownErr;
+	io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, ifname));
+	if (!service) { LogMsg("ActivateLocalProxy: No service for interface %s", ifname); return(mStatus_UnknownErr); }
+
+	io_name_t n1, n2;
+	IOObjectGetClass(service, n1);
+	io_object_t parent;
+	kern_return_t kr = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent);
+	if (kr != KERN_SUCCESS) LogMsg("ActivateLocalProxy: IORegistryEntryGetParentEntry for %s/%s failed %d", ifname, n1, kr);
+	else
+		{
+		IOObjectGetClass(parent, n2);
+		LogSPS("ActivateLocalProxy: Interface %s service %s parent %s", ifname, n1, n2);
+		const CFTypeRef ref = IORegistryEntryCreateCFProperty(parent, CFSTR(mDNS_IOREG_KEY), kCFAllocatorDefault, mDNSNULL);
+		if (!ref) LogSPS("ActivateLocalProxy: No mDNS_IOREG_KEY for interface %s/%s/%s", ifname, n1, n2);
+		else
+			{
+			if (CFGetTypeID(ref) != CFStringGetTypeID() || !CFEqual(ref, CFSTR(mDNS_IOREG_VALUE)))
+				LogMsg("ActivateLocalProxy: mDNS_IOREG_KEY for interface %s/%s/%s value %s != %s",
+					ifname, n1, n2, CFStringGetCStringPtr(ref, mDNSNULL), mDNS_IOREG_VALUE);
+			else
+				{
+				io_connect_t conObj;
+				kr = IOServiceOpen(parent, mach_task_self(), mDNS_USER_CLIENT_CREATE_TYPE, &conObj);
+				if (kr != KERN_SUCCESS) LogMsg("ActivateLocalProxy: IOServiceOpen for %s/%s/%s failed %d", ifname, n1, n2, kr);
+				else
+					{
+					mDNSOffloadCmd cmd;
+					mDNSPlatformMemZero(&cmd, sizeof(cmd)); // When compiling 32-bit, make sure top 32 bits of 64-bit pointers get initialized to zero
+					cmd.command       = cmd_mDNSOffloadRR;
+					cmd.numUDPPorts   = GetPortArray(m, mDNSTransport_UDP, mDNSNULL);
+					cmd.numTCPPorts   = GetPortArray(m, mDNSTransport_TCP, mDNSNULL);
+					cmd.numRRRecords  = CountProxyRecords(m, &cmd.rrBufferSize);
+					cmd.compression   = sizeof(DNSMessageHeader);
+
+					DNSMessage *msg = (DNSMessage *)mallocL("mDNSOffloadCmd msg", sizeof(DNSMessageHeader) + cmd.rrBufferSize);
+					cmd.rrRecords.ptr = mallocL("mDNSOffloadCmd rrRecords", cmd.numRRRecords * sizeof(FatPtr));
+					cmd.udpPorts .ptr = mallocL("mDNSOffloadCmd udpPorts",  cmd.numUDPPorts  * sizeof(mDNSIPPort));
+					cmd.tcpPorts .ptr = mallocL("mDNSOffloadCmd tcpPorts",  cmd.numTCPPorts  * sizeof(mDNSIPPort));
+
+					LogSPS("ActivateLocalProxy: msg %p %d RR %p %d, UDP %p %d, TCP %p %d",
+						msg, cmd.rrBufferSize,
+						cmd.rrRecords.ptr, cmd.numRRRecords,
+						cmd.udpPorts .ptr, cmd.numUDPPorts,
+						cmd.tcpPorts .ptr, cmd.numTCPPorts);
+
+					if (!msg || !cmd.rrRecords.ptr || !cmd.udpPorts.ptr || !cmd.tcpPorts.ptr)
+						LogMsg("ActivateLocalProxy: Failed to allocate memory: msg %p %d RR %p %d, UDP %p %d, TCP %p %d",
+						msg, cmd.rrBufferSize,
+						cmd.rrRecords.ptr, cmd.numRRRecords,
+						cmd.udpPorts .ptr, cmd.numUDPPorts,
+						cmd.tcpPorts .ptr, cmd.numTCPPorts);
+					else
+						{
+						GetProxyRecords(m, msg, cmd.rrBufferSize, cmd.rrRecords.ptr);
+						GetPortArray(m, mDNSTransport_UDP, cmd.udpPorts.ptr);
+						GetPortArray(m, mDNSTransport_TCP, cmd.tcpPorts.ptr);
+						char outputData[2];
+						size_t outputDataSize = sizeof(outputData);
+						kr = IOConnectCallStructMethod(conObj, 0, &cmd, sizeof(cmd), outputData, &outputDataSize);
+						LogSPS("ActivateLocalProxy: IOConnectCallStructMethod for %s/%s/%s %d", ifname, n1, n2, kr);
+						if (kr == KERN_SUCCESS) result = mStatus_NoError;
+						}
+
+				 	if (cmd.tcpPorts. ptr) freeL("mDNSOffloadCmd udpPorts",  cmd.tcpPorts .ptr);
+					if (cmd.udpPorts. ptr) freeL("mDNSOffloadCmd tcpPorts",  cmd.udpPorts .ptr);
+					if (cmd.rrRecords.ptr) freeL("mDNSOffloadCmd rrRecords", cmd.rrRecords.ptr);
+					if (msg)               freeL("mDNSOffloadCmd msg",       msg);
+					IOServiceClose(conObj);
+					}
+				}
+			CFRelease(ref);
+			}
+		IOObjectRelease(parent);
+		}
+	IOObjectRelease(service);
+	return result;
+	}
+
 #endif // APPLE_OSX_mDNSResponder
 
 static io_service_t g_rootdomain = MACH_PORT_NULL;
diff --git a/mDNSPosix/NetMonitor.c b/mDNSPosix/NetMonitor.c
index f873ea3..ed8124f 100644
--- a/mDNSPosix/NetMonitor.c
+++ b/mDNSPosix/NetMonitor.c
@@ -30,6 +30,12 @@
     Change History (most recent first):
 
 $Log: NetMonitor.c,v $
+Revision 1.96  2009/07/16 00:08:57  cheshire
+Display any stray Update (Authority) records in query packets
+
+Revision 1.95  2009/07/09 22:24:52  herscher
+<rdar://problem/3775717> SDK: Port mDNSNetMonitor to Windows
+
 Revision 1.94  2009/04/24 00:31:56  cheshire
 <rdar://problem/3476350> Return negative answers when host knows authoritatively that no answer exists
 Added code to display NSEC records
@@ -115,13 +121,28 @@
 #include <string.h>			// For strrchr(), strcmp()
 #include <time.h>			// For "struct tm" etc.
 #include <signal.h>			// For SIGINT, SIGTERM
-#include <netdb.h>			// For gethostbyname()
-#include <sys/socket.h>		// For AF_INET, AF_INET6, etc.
-#include <net/if.h>			// For IF_NAMESIZE
-#include <netinet/in.h>		// For INADDR_NONE
-#include <arpa/inet.h>		// For inet_addr()
+#if defined(WIN32)
+#	include <mDNSEmbeddedAPI.h>
+#	include <mDNSWin32.h>
+#	include <uds_daemon.h>
+#	include <PosixCompat.h>
+#	include <Service.h>
+#	define IFNAMSIZ 256
 
-#include "mDNSPosix.h"      // Defines the specific types needed to run mDNS on this platform
+// Stub these functions out
+mDNSexport int udsserver_init(dnssd_sock_t skts[], mDNSu32 count) { return 0; }
+mDNSexport mDNSs32 udsserver_idle(mDNSs32 nextevent) { return 0; }
+mDNSexport void udsserver_handle_configchange(mDNS *const m) {}
+mDNSexport int udsserver_exit(void) { return 0; }
+void setlinebuf( FILE * fp ) {}
+#else
+#	include <netdb.h>			// For gethostbyname()
+#	include <sys/socket.h>		// For AF_INET, AF_INET6, etc.
+#	include <net/if.h>			// For IF_NAMESIZE
+#	include <netinet/in.h>		// For INADDR_NONE
+#	include <arpa/inet.h>		// For inet_addr()
+#	include "mDNSPosix.h"      // Defines the specific types needed to run mDNS on this platform
+#endif
 #include "ExampleClientApp.h"
 
 //*************************************************************************************************************
@@ -179,7 +200,7 @@
 //*************************************************************************************************************
 // Globals
 
-static mDNS mDNSStorage;						// mDNS core uses this to store its globals
+mDNS mDNSStorage;						// mDNS core uses this to store its globals
 static mDNS_PlatformSupport PlatformStorage;	// Stores this platform's globals
 mDNSexport const char ProgramName[] = "mDNSNetMonitor";
 
@@ -712,16 +733,19 @@
 	for (i=0; i<msg->h.numAuthorities; i++)
 		{
 		const mDNSu8 *ep = ptr;
-		ptr = skipResourceRecord(msg, ptr, end);
+		ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &pkt);
 		if (!ptr) { DisplayError(srcaddr, ep, end, "AUTHORITY"); return; }
+		// After we display an Update record with its matching question (above) we zero out its type and class
+		// If any remain that haven't been zero'd out, display them here
+		if (pkt.r.resrec.rrtype || pkt.r.resrec.rrclass) DisplayResourceRecord(srcaddr, "(AU)", &pkt.r.resrec);
 		}
 
 	for (i=0; i<msg->h.numAdditionals; i++)
 		{
 		const mDNSu8 *ep = ptr;
-		ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt);
+		ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt);
 		if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; }
-		DisplayResourceRecord(srcaddr, "    ", &pkt.r.resrec);
+		DisplayResourceRecord(srcaddr, pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : "(AD)", &pkt.r.resrec);
 		}
 
 	if (entry) AnalyseHost(m, entry, InterfaceID);
@@ -785,7 +809,9 @@
 		ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt);
 		if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; }
 		NumAdditionals++;
-		DisplayResourceRecord(srcaddr, (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AD)" : "(AD+)", &pkt.r.resrec);
+		DisplayResourceRecord(srcaddr,
+			pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AD)" : "(AD+)",
+			&pkt.r.resrec);
 		if (entry) RecordHostInfo(entry, &pkt.r.resrec);
 		}
 	
@@ -863,7 +889,9 @@
 	{
 	struct tm tm;
 	int h, m, s, mul, div, TotPkt;
+#if !defined(WIN32)
 	sigset_t signals;
+#endif
 	
 	mStatus status = mDNS_Init(&mDNSStorage, &PlatformStorage,
 		mDNS_Init_NoCache, mDNS_Init_ZeroCacheSize,
@@ -872,6 +900,10 @@
 	if (status) return(status);
 
 	gettimeofday(&tv_start, NULL);
+
+#if defined( WIN32 )
+	RunDirect( 0, NULL );
+#else
 	mDNSPosixListenForSignalInEventLoop(SIGINT);
 	mDNSPosixListenForSignalInEventLoop(SIGTERM);
 
@@ -882,6 +914,7 @@
 		mDNSPosixRunEventLoopOnce(&mDNSStorage, &timeout, &signals, &gotSomething);
 		}
 	while ( !( sigismember( &signals, SIGINT) || sigismember( &signals, SIGTERM)));
+#endif
 	
 	// Now display final summary
 	TotPkt = NumPktQ + NumPktL + NumPktR;
diff --git a/mDNSResponder.sln b/mDNSResponder.sln
index 1e0eca1..98423dc 100755
--- a/mDNSResponder.sln
+++ b/mDNSResponder.sln
@@ -65,138 +65,296 @@
 		{AB581101-18F0-46F6-B56A-83A6B1EA657E} = {AB581101-18F0-46F6-B56A-83A6B1EA657E}

 	EndProjectSection

 EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DLLX", "mDNSWindows\DLLX\DLLX.vcproj", "{78FBFCC5-2873-4AE2-9114-A08082F71124}"

+EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DNSServiceBrowser.NET", "Clients\DNSServiceBrowser.NET\DNSServiceBrowser.NET.csproj", "{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}"

+EndProject

+Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "DNSServiceBrowser.VB", "Clients\DNSServiceBrowser.VB\DNSServiceBrowser.VB.vbproj", "{FB79E297-5703-435C-A829-51AA51CD71C2}"

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mDNSNetMonitor", "Clients\mDNSNetMonitor.VisualStudio\mDNSNetMonitor.vcproj", "{AF35C285-528D-46A1-8A0E-47B0733DC718}"

+EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

+		Debug|Any CPU = Debug|Any CPU

+		Debug|Mixed Platforms = Debug|Mixed Platforms

 		Debug|Win32 = Debug|Win32

 		Debug|x64 = Debug|x64

+		Release|Any CPU = Release|Any CPU

+		Release|Mixed Platforms = Release|Mixed Platforms

 		Release|Win32 = Release|Win32

 		Release|x64 = Release|x64

 	EndGlobalSection

 	GlobalSection(ProjectConfigurationPlatforms) = postSolution

+		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Win32.ActiveCfg = Debug|Win32

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|Win32.Build.0 = Debug|Win32

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|x64.ActiveCfg = Debug|x64

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Debug|x64.Build.0 = Debug|x64

+		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Any CPU.ActiveCfg = Release|x64

+		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Mixed Platforms.Build.0 = Release|x64

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Win32.ActiveCfg = Release|Win32

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|Win32.Build.0 = Release|Win32

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|x64.ActiveCfg = Release|x64

 		{AB581101-18F0-46F6-B56A-83A6B1EA657E}.Release|x64.Build.0 = Release|x64

+		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Win32.ActiveCfg = Debug|Win32

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|Win32.Build.0 = Debug|Win32

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|x64.ActiveCfg = Debug|x64

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Debug|x64.Build.0 = Debug|x64

+		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Any CPU.ActiveCfg = Release|x64

+		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Mixed Platforms.Build.0 = Release|x64

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Win32.ActiveCfg = Release|Win32

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|Win32.Build.0 = Release|Win32

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|x64.ActiveCfg = Release|x64

 		{C1D98254-BA27-4427-A3BE-A68CA2CC5F69}.Release|x64.Build.0 = Release|x64

+		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Win32.ActiveCfg = Debug|Win32

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|Win32.Build.0 = Debug|Win32

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|x64.ActiveCfg = Debug|x64

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Debug|x64.Build.0 = Debug|x64

+		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Any CPU.ActiveCfg = Release|x64

+		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Mixed Platforms.Build.0 = Release|x64

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Win32.ActiveCfg = Release|Win32

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|Win32.Build.0 = Release|Win32

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|x64.ActiveCfg = Release|x64

 		{208B3A9F-1CA0-4D1D-9D6C-C61616F94705}.Release|x64.Build.0 = Release|x64

+		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Win32.ActiveCfg = Debug|Win32

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|Win32.Build.0 = Debug|Win32

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|x64.ActiveCfg = Debug|x64

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Debug|x64.Build.0 = Debug|x64

+		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Any CPU.ActiveCfg = Release|x64

+		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Mixed Platforms.Build.0 = Release|x64

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Win32.ActiveCfg = Release|Win32

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|Win32.Build.0 = Release|Win32

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|x64.ActiveCfg = Release|x64

 		{F4F15529-F0EB-402F-8662-73C5797EE557}.Release|x64.Build.0 = Release|x64

+		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Win32.ActiveCfg = Debug|Win32

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|Win32.Build.0 = Debug|Win32

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|x64.ActiveCfg = Debug|x64

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Debug|x64.Build.0 = Debug|x64

+		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Any CPU.ActiveCfg = Release|x64

+		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Mixed Platforms.Build.0 = Release|x64

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Win32.ActiveCfg = Release|Win32

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|Win32.Build.0 = Release|Win32

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|x64.ActiveCfg = Release|x64

 		{BB8AC1B5-6587-4163-BDC6-788B157705CA}.Release|x64.Build.0 = Release|x64

+		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Win32.ActiveCfg = Debug|Win32

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|Win32.Build.0 = Debug|Win32

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|x64.ActiveCfg = Debug|x64

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Debug|x64.Build.0 = Debug|x64

+		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Any CPU.ActiveCfg = Release|x64

+		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Mixed Platforms.Build.0 = Release|x64

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Win32.ActiveCfg = Release|Win32

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|Win32.Build.0 = Release|Win32

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|x64.ActiveCfg = Release|x64

 		{B1D2CDA2-CC8F-45D5-A694-2EE45B0308CF}.Release|x64.Build.0 = Release|x64

+		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Win32.ActiveCfg = Debug|Win32

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|Win32.Build.0 = Debug|Win32

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|x64.ActiveCfg = Debug|x64

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Debug|x64.Build.0 = Debug|x64

+		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Any CPU.ActiveCfg = Release|x64

+		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Mixed Platforms.Build.0 = Release|x64

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Win32.ActiveCfg = Release|Win32

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|Win32.Build.0 = Release|Win32

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|x64.ActiveCfg = Release|x64

 		{F5D703B6-5612-4381-8BE2-2B7AEBAE58FC}.Release|x64.Build.0 = Release|x64

+		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Win32.ActiveCfg = Debug|Win32

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|Win32.Build.0 = Debug|Win32

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|x64.ActiveCfg = Debug|x64

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Debug|x64.Build.0 = Debug|x64

+		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Any CPU.ActiveCfg = Release|x64

+		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Mixed Platforms.Build.0 = Release|x64

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Win32.ActiveCfg = Release|Win32

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|Win32.Build.0 = Release|Win32

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|x64.ActiveCfg = Release|x64

 		{967F5375-0176-43D3-ADA3-22EE25551C37}.Release|x64.Build.0 = Release|x64

+		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Win32.ActiveCfg = Debug|Win32

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|Win32.Build.0 = Debug|Win32

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|x64.ActiveCfg = Debug|x64

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Debug|x64.Build.0 = Debug|x64

+		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Any CPU.ActiveCfg = Release|x64

+		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Mixed Platforms.Build.0 = Release|x64

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Win32.ActiveCfg = Release|Win32

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|Win32.Build.0 = Release|Win32

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|x64.ActiveCfg = Release|x64

 		{CFCCB176-6CAA-472B-B0A2-90511C8E2E52}.Release|x64.Build.0 = Release|x64

+		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Win32.ActiveCfg = Debug|Win32

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|Win32.Build.0 = Debug|Win32

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|x64.ActiveCfg = Debug|x64

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Debug|x64.Build.0 = Debug|x64

+		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Any CPU.ActiveCfg = Release|x64

+		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Mixed Platforms.Build.0 = Release|x64

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Win32.ActiveCfg = Release|Win32

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|Win32.Build.0 = Release|Win32

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|x64.ActiveCfg = Release|x64

 		{1643427B-F226-4AD6-B413-97DA64D5C6B4}.Release|x64.Build.0 = Release|x64

+		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Win32.ActiveCfg = Debug|Win32

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|Win32.Build.0 = Debug|Win32

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|x64.ActiveCfg = Debug|x64

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Debug|x64.Build.0 = Debug|x64

+		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Any CPU.ActiveCfg = Release|x64

+		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Mixed Platforms.Build.0 = Release|x64

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Win32.ActiveCfg = Release|Win32

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|Win32.Build.0 = Release|Win32

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|x64.ActiveCfg = Release|x64

 		{871B1492-B4A4-4B57-9237-FA798484D7D7}.Release|x64.Build.0 = Release|x64

+		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Win32.ActiveCfg = Debug|Win32

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|Win32.Build.0 = Debug|Win32

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|x64.ActiveCfg = Debug|x64

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Debug|x64.Build.0 = Debug|x64

+		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Any CPU.ActiveCfg = Release|x64

+		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Mixed Platforms.Build.0 = Release|x64

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Win32.ActiveCfg = Release|Win32

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|Win32.Build.0 = Release|Win32

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|x64.ActiveCfg = Release|x64

 		{AA230639-E115-4A44-AA5A-44A61235BA50}.Release|x64.Build.0 = Release|x64

+		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Win32.ActiveCfg = Debug|Win32

 		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|Win32.Build.0 = Debug|Win32

 		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Debug|x64.ActiveCfg = Debug|x64

+		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Any CPU.ActiveCfg = Release|x64

+		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Mixed Platforms.Build.0 = Release|x64

 		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Win32.ActiveCfg = Release|Win32

 		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|Win32.Build.0 = Release|Win32

 		{9CE2568A-3170-41C6-9F20-A0188A9EC114}.Release|x64.ActiveCfg = Release|x64

+		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Win32.ActiveCfg = Debug|Win32

 		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|Win32.Build.0 = Debug|Win32

 		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Debug|x64.ActiveCfg = Debug|x64

+		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Any CPU.ActiveCfg = Release|x64

+		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Mixed Platforms.Build.0 = Release|x64

 		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Win32.ActiveCfg = Release|Win32

 		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|Win32.Build.0 = Release|Win32

 		{A987A0C1-344F-475C-869C-F082EB11EEBA}.Release|x64.ActiveCfg = Release|x64

+		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Win32.ActiveCfg = Debug|Win32

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|Win32.Build.0 = Debug|Win32

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|x64.ActiveCfg = Debug|x64

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Debug|x64.Build.0 = Debug|x64

+		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Any CPU.ActiveCfg = Release|x64

+		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Mixed Platforms.Build.0 = Release|x64

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Win32.ActiveCfg = Release|Win32

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|Win32.Build.0 = Release|Win32

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|x64.ActiveCfg = Release|x64

 		{0DF09484-B4C2-4AB4-9FC0-7B091ADEAFEB}.Release|x64.Build.0 = Release|x64

+		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Mixed Platforms.Build.0 = Debug|x64

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Win32.ActiveCfg = Debug|Win32

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|Win32.Build.0 = Debug|Win32

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|x64.ActiveCfg = Debug|x64

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Debug|x64.Build.0 = Debug|x64

+		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Any CPU.ActiveCfg = Release|x64

+		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Mixed Platforms.Build.0 = Release|x64

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Win32.ActiveCfg = Release|Win32

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|Win32.Build.0 = Release|Win32

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|x64.ActiveCfg = Release|x64

 		{3A2B6325-3053-4236-84BD-AA9BE2E323E5}.Release|x64.Build.0 = Release|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Any CPU.ActiveCfg = Debug|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Mixed Platforms.ActiveCfg = Debug|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Mixed Platforms.Build.0 = Debug|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Win32.ActiveCfg = Debug|Win32

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|Win32.Build.0 = Debug|Win32

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|x64.ActiveCfg = Debug|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Debug|x64.Build.0 = Debug|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Any CPU.ActiveCfg = Release|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Mixed Platforms.ActiveCfg = Release|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Mixed Platforms.Build.0 = Release|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Win32.ActiveCfg = Release|Win32

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|Win32.Build.0 = Release|Win32

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|x64.ActiveCfg = Release|x64

+		{78FBFCC5-2873-4AE2-9114-A08082F71124}.Release|x64.Build.0 = Release|x64

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|Win32.ActiveCfg = Debug|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Debug|x64.ActiveCfg = Debug|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Any CPU.Build.0 = Release|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Mixed Platforms.Build.0 = Release|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|Win32.ActiveCfg = Release|Any CPU

+		{DE8DB97E-37A3-43ED-9A5E-CCC5F6DE9CB4}.Release|x64.ActiveCfg = Release|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|Win32.ActiveCfg = Debug|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Debug|x64.ActiveCfg = Debug|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Any CPU.Build.0 = Release|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Mixed Platforms.Build.0 = Release|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Release|Win32.ActiveCfg = Release|Any CPU

+		{FB79E297-5703-435C-A829-51AA51CD71C2}.Release|x64.ActiveCfg = Release|Any CPU

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Any CPU.ActiveCfg = Debug|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Mixed Platforms.Build.0 = Debug|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Win32.ActiveCfg = Debug|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|Win32.Build.0 = Debug|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Debug|x64.ActiveCfg = Debug|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Any CPU.ActiveCfg = Release|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Mixed Platforms.ActiveCfg = Release|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Mixed Platforms.Build.0 = Release|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Win32.ActiveCfg = Release|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|Win32.Build.0 = Release|Win32

+		{AF35C285-528D-46A1-8A0E-47B0733DC718}.Release|x64.ActiveCfg = Release|Win32

 	EndGlobalSection

 	GlobalSection(SolutionProperties) = preSolution

 		HideSolutionNode = FALSE

diff --git a/mDNSShared/dns_sd.h b/mDNSShared/dns_sd.h
index 3169a5a..59891f7 100644
--- a/mDNSShared/dns_sd.h
+++ b/mDNSShared/dns_sd.h
@@ -77,7 +77,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 2120100
+#define _DNS_SD_H 2140000
 
 #ifdef  __cplusplus
     extern "C" {
diff --git a/mDNSShared/uds_daemon.c b/mDNSShared/uds_daemon.c
index dfae86e..9022f94 100644
--- a/mDNSShared/uds_daemon.c
+++ b/mDNSShared/uds_daemon.c
@@ -17,6 +17,14 @@
 	Change History (most recent first):
 
 $Log: uds_daemon.c,v $
+Revision 1.463  2009/07/10 22:25:47  cheshire
+Updated syslog messages for debugging unresponsive clients:
+Will now log a warning message about an unresponsive client every ten seconds,
+and then after 60 messagess (10 minutes) will terminate connection to that client.
+
+Revision 1.462  2009/07/09 22:43:31  cheshire
+Improved log messages for debugging unresponsive clients
+
 Revision 1.461  2009/06/19 23:15:07  cheshire
 <rdar://problem/6990066> Library: crash at handle_resolve_response + 183
 Made resolve_result_callback code more defensive and improved LogOperation messages
@@ -989,7 +997,8 @@
 
 	// reply, termination, error, and client context info
 	int no_reply;					// don't send asynchronous replies to client
-	int time_blocked;				// record time of a blocked client
+	mDNSs32 time_blocked;			// record time of a blocked client
+	int unresponsiveness_reports;
 	struct reply_state *replies;	// corresponding (active) reply list
 	req_termination_fn terminate;
 
@@ -1891,8 +1900,7 @@
 			if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_update_request - malloc");
 			mDNSPlatformMemCopy(request->u.servicereg.txtdata, rdata, rdlen);
 			}
-		else
-			request->u.servicereg.txtdata = NULL;
+		request->u.servicereg.txtlen = rdlen;
 		}
 
 	// update a record from a service record set
@@ -2231,7 +2239,6 @@
 		if (!request->u.servicereg.txtdata) FatalError("ERROR: handle_regservice_request - malloc");
 		mDNSPlatformMemCopy(request->u.servicereg.txtdata, get_rdata(&request->msgptr, request->msgend, request->u.servicereg.txtlen), request->u.servicereg.txtlen);
 		}
-	else request->u.servicereg.txtdata = NULL;
 
 	if (!request->msgptr) { LogMsg("%3d: DNSServiceRegister(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
 
@@ -4467,6 +4474,7 @@
 				r->replies = r->replies->next;
 				freeL("reply_state/udsserver_idle", fptr);
 				r->time_blocked = 0; // reset failure counter after successful send
+				r->unresponsiveness_reports = 0;
 				continue;
 				}
 			else if (result == t_terminated || result == t_error)
@@ -4480,15 +4488,24 @@
 
 		if (r->replies)		// If we failed to send everything, check our time_blocked timer
 			{
-			if (!r->time_blocked) r->time_blocked = NonZeroTime(now);
-			if (now - r->time_blocked >= 60 * mDNSPlatformOneSecond)
+			if (nextevent - now > mDNSPlatformOneSecond) nextevent = now + mDNSPlatformOneSecond;
+
+			if (mDNSStorage.SleepState != SleepState_Awake) r->time_blocked = 0;
+			else if (!r->time_blocked) r->time_blocked = NonZeroTime(now);
+			else if (now - r->time_blocked >= 10 * mDNSPlatformOneSecond * (r->unresponsiveness_reports+1))
 				{
-				LogMsg("%3d: Could not write data to client after %ld seconds - aborting connection", r->sd,
-					(now - r->time_blocked) / mDNSPlatformOneSecond);
-				LogClientInfo(&mDNSStorage, r);
-				abort_request(r);
+				int num = 0;
+				struct reply_state *x = r->replies;
+				while (x) { num++; x=x->next; }
+				LogMsg("%3d: Could not write data to client after %ld seconds, %d repl%s waiting",
+					r->sd, (now - r->time_blocked) / mDNSPlatformOneSecond, num, num == 1 ? "y" : "ies");
+				if (++r->unresponsiveness_reports >= 60)
+					{
+					LogMsg("%3d: Client unresponsive; aborting connection", r->sd);
+					LogClientInfo(&mDNSStorage, r);
+					abort_request(r);
+					}
 				}
-			else if (nextevent - now > mDNSPlatformOneSecond) nextevent = now + mDNSPlatformOneSecond;
 			}
 
 		if (!dnssd_SocketValid(r->sd)) // If this request is finished, unlink it from the list and free the memory
@@ -4508,7 +4525,7 @@
 	// Check our structures are reasonable sizes. Including overly-large buffers, or embedding
 	// other overly-large structures instead of having a pointer to them, can inadvertently
 	// cause structure sizes (and therefore memory usage) to balloon unreasonably.
-	char sizecheck_request_state          [(sizeof(request_state)           <= 1760) ? 1 : -1];
+	char sizecheck_request_state          [(sizeof(request_state)           <= 2000) ? 1 : -1];
 	char sizecheck_registered_record_entry[(sizeof(registered_record_entry) <=   40) ? 1 : -1];
 	char sizecheck_service_instance       [(sizeof(service_instance)        <= 6552) ? 1 : -1];
 	char sizecheck_browser_t              [(sizeof(browser_t)               <=  992) ? 1 : -1];
diff --git a/mDNSWindows/DLLX/DLLX.vcproj b/mDNSWindows/DLLX/DLLX.vcproj
index 04fe58b..7c58b0a 100755
--- a/mDNSWindows/DLLX/DLLX.vcproj
+++ b/mDNSWindows/DLLX/DLLX.vcproj
@@ -272,7 +272,7 @@
 			/>

 			<Tool

 				Name="VCLinkerTool"

-				RegisterOutput="true"

+				RegisterOutput="false"

 				IgnoreImportLibrary="true"

 				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

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

@@ -308,6 +308,7 @@
 			/>

 			<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

@@ -368,7 +369,7 @@
 			/>

 			<Tool

 				Name="VCLinkerTool"

-				RegisterOutput="true"

+				RegisterOutput="false"

 				IgnoreImportLibrary="true"

 				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

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

@@ -404,6 +405,7 @@
 			/>

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

diff --git a/mDNSWindows/PosixCompat.c b/mDNSWindows/PosixCompat.c
new file mode 100755
index 0000000..ec69f95
--- /dev/null
+++ b/mDNSWindows/PosixCompat.c
@@ -0,0 +1,141 @@
+/* -*- 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.
+
+    Change History (most recent first):
+    
+$Log: PosixCompat.c,v $
+Revision 1.1  2009/07/09 21:40:32  herscher
+<rdar://problem/3775717> SDK: Port mDNSNetMonitor to Windows. Add a small Posix compatibility layer to the mDNSWindows platform layer. This makes it possible to centralize the implementations to functions such as if_indextoname() and inet_pton() that are made in several projects in B4W.
+
+
+*/
+
+#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 )
+{
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+#	define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+#else
+#	define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+#endif
+ 
+	FILETIME ft;
+	unsigned __int64 tmpres = 0;
+ 
+	if ( tv != NULL )
+	{
+		GetSystemTimeAsFileTime(&ft);
+ 
+		tmpres |= ft.dwHighDateTime;
+		tmpres <<= 32;
+		tmpres |= ft.dwLowDateTime;
+ 
+		tmpres -= DELTA_EPOCH_IN_MICROSECS; 
+		tmpres /= 10;  /*convert into microseconds*/
+		tv->tv_sec = (long)(tmpres / 1000000UL);
+		tv->tv_usec = (long)(tmpres % 1000000UL);
+	}
+ 
+	return 0;
+}
+
+
+extern struct tm*
+localtime_r( const time_t * clock, struct tm * result )
+{
+	result = localtime( clock );
+	return result;
+}
diff --git a/mDNSWindows/PosixCompat.h b/mDNSWindows/PosixCompat.h
new file mode 100755
index 0000000..c7de0ea
--- /dev/null
+++ b/mDNSWindows/PosixCompat.h
@@ -0,0 +1,78 @@
+/* -*- 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.
+
+    Change History (most recent first):
+    
+$Log: PosixCompat.h,v $
+Revision 1.1  2009/07/09 21:40:32  herscher
+<rdar://problem/3775717> SDK: Port mDNSNetMonitor to Windows. Add a small Posix compatibility layer to the mDNSWindows platform layer. This makes it possible to centralize the implementations to functions such as if_indextoname() and inet_pton() that are made in several projects in B4W.
+
+
+*/
+
+#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/Secret.c b/mDNSWindows/Secret.c
index 4c12d15..2797655 100644
--- a/mDNSWindows/Secret.c
+++ b/mDNSWindows/Secret.c
@@ -17,6 +17,9 @@
     Change History (most recent first):
     
 $Log: Secret.c,v $
+Revision 1.3  2009/07/17 19:50:25  herscher
+<rdar://problem/5265747> ControlPanel doesn't display key and password in dialog box
+
 Revision 1.2  2009/06/25 21:11:52  herscher
 Fix compilation error when building Control Panel.
 
@@ -46,7 +49,7 @@
 
 
 BOOL
-LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainLength, char * outKey, unsigned outKeyLength, char * outSecret, unsigned outSecretLength )
+LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize )
 {
 	PLSA_UNICODE_STRING		domainLSA;
 	PLSA_UNICODE_STRING		keyLSA;
@@ -69,21 +72,23 @@
 	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.
 
-	strcpy_s( outDomain, outDomainLength, inDomain );
-	dlen = strlen( outDomain );
-	
 	if ( outDomain[ dlen - 1 ] != '.' )
 	{
-		outDomain[ dlen ] = '.';
-		outDomain[ dlen + 1 ] = '\0';
+		outDomain[ dlen++ ] = '.';
+		outDomain[ dlen ] = '\0';
 	}
 
 	// Canonicalize name by converting to lower case (keychain and some name servers are case sensitive)
 
-	dlen = strlen( outDomain );
 	for ( i = 0; i < dlen; i++ )
 	{
 		outDomain[i] = (char) tolower( outDomain[i] );  // canonicalize -> lower case
@@ -113,11 +118,10 @@
 	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.
-	
+	// make sure it doesn't conflict with a zone name.	
 	// Strip off the "$" prefix.
 
-	err = MakeUTF8StringFromLsaString( outKey, outKeyLength, keyLSA );
+	err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA );
 	require_noerr( err, exit );
 	require_action( outKey[0] == '$', exit, err = kUnknownErr );
 	memcpy( outKey, outKey + 1, strlen( outKey ) );
@@ -130,7 +134,7 @@
 
 	// Convert the secret to UTF8 string
 
-	err = MakeUTF8StringFromLsaString( outSecret, outSecretLength, secretLSA );
+	err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA );
 	require_noerr( err, exit );
 
 exit:
@@ -185,21 +189,19 @@
 	require_action( inKey != NULL, exit, ok = FALSE );
 	require_action( inSecret != NULL, exit, ok = FALSE );
 
-	inDomainLength = strlen( inDomain );
-	require_action( ( inDomainLength > 0 ) && ( inDomainLength < sizeof( domain ) ), exit, ok = FALSE );
-
-	inKeyLength = strlen( inKey );
-	require_action( ( inKeyLength > 0 ) && ( inKeyLength < ( sizeof( key ) - 1 ) ), 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 ) );
-	strcpy_s( domain, sizeof( domain ), inDomain );
+	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[ strlen( domain ) - 1 ] != '.' )
+	if ( domain[ inDomainLength - 1 ] != '.' )
 	{
-		domain[ strlen( domain ) - 1 ] = '.';
+		domain[ inDomainLength++ ] = '.';
+		domain[ inDomainLength ] = '\0';
 	}
 
 	// <rdar://problem/4192119>
@@ -209,12 +211,17 @@
 	// name
 
 	ZeroMemory( key, sizeof( key ) );
+	inKeyLength = strlen( inKey );
+	require_action( inKeyLength > 0 , exit, ok = FALSE );
 	key[ 0 ] = '$';
-	strcpy_s( key + 1, sizeof( key ) - 1, inKey );
+	err = strcpy_s( key + 1, sizeof( key ) - 3, inKey );
+	require_action( !err, exit, ok = FALSE );
+	inKeyLength++;
 
-	if ( key[ strlen( key ) - 1 ] != '.' )
+	if ( key[ inKeyLength - 1 ] != '.' )
 	{
-		key[ strlen( key ) - 1 ] = '.';
+		key[ inKeyLength++ ] = '.';
+		key[ inKeyLength ] = '\0';
 	}
 
 	// attrs are reserved, so initialize to zeroes.
@@ -229,16 +236,13 @@
 
 	// Intializing PLSA_UNICODE_STRING structures
 
-	ok = MakeLsaStringFromUTF8String( &lucZoneName, domain );
-	err = translate_errno( ok, errno_compat(), kUnknownErr );
-	require_noerr( err, exit );
- 
-	ok = MakeLsaStringFromUTF8String( &lucKeyName, key );
-	err = translate_errno( ok, errno_compat(), kUnknownErr );
+	err = MakeLsaStringFromUTF8String( &lucZoneName, domain );
 	require_noerr( err, exit );
 
-	ok = MakeLsaStringFromUTF8String( &lucSecretName, inSecret );
-	err = translate_errno( ok, errno_compat(), kUnknownErr );
+	err = MakeLsaStringFromUTF8String( &lucKeyName, key );
+	require_noerr( err, exit );
+
+	err = MakeLsaStringFromUTF8String( &lucSecretName, inSecret );
 	require_noerr( err, exit );
 
 	// Store the private data.
diff --git a/mDNSWindows/SystemService/Service.c b/mDNSWindows/SystemService/Service.c
index 8671e0b..2fb67bc 100644
--- a/mDNSWindows/SystemService/Service.c
+++ b/mDNSWindows/SystemService/Service.c
@@ -17,6 +17,15 @@
     Change History (most recent first):
     
 $Log: Service.c,v $
+Revision 1.49  2009/07/17 19:59:46  herscher
+<rdar://problem/7062660> Update the womp settings for each network adapter immediately preceding the call to mDNSCoreMachineSleep().
+
+Revision 1.48  2009/07/09 21:34:14  herscher
+<rdar://problem/3775717> SDK: Port mDNSNetMonitor to Windows. Refactor the system service slightly by removing the main() function from Service.c so that mDNSNetMonitor can link to functions defined in Service.c
+
+Revision 1.47  2009/07/07 21:35:06  herscher
+<rdar://problem/6713286> windows platform changes to support use as sleep proxy client
+
 Revision 1.46  2009/06/05 18:28:24  herscher
 <rdar://problem/6125087> mDNSResponder should be able to identify VPN adapters generically
 <rdar://problem/6885843> WIN7: Bonjour removes the default gateway entry and thereby breaks network connectivity
@@ -198,6 +207,7 @@
 
 #include	"uds_daemon.h"
 #include	"GenLinkedList.h"
+#include	"Service.h"
 
 #include	"Resource.h"
 
@@ -215,6 +225,7 @@
 	#include	<iphlpapi.h>
 	#include	<netioapi.h>
 	#include	<iptypes.h>
+	#include	<powrprof.h>
 #endif
 
 #ifndef HeapEnableTerminationOnCorruption
@@ -289,11 +300,6 @@
 //===========================================================================================================================
 //	Prototypes
 //===========================================================================================================================
-#if defined(UNICODE)
-int __cdecl			wmain( int argc, LPTSTR argv[] );
-#else
-int __cdecl 		main( int argc, char *argv[] );
-#endif
 static void			Usage( void );
 static BOOL WINAPI	ConsoleControlHandler( DWORD inControlEvent );
 static OSStatus		InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath );
@@ -303,7 +309,6 @@
 static OSStatus		CheckFirewall();
 static OSStatus		SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription );
 static void			ReportStatus( int inType, const char *inFormat, ... );
-static OSStatus		RunDirect( int argc, LPTSTR argv[] );
 
 static void WINAPI	ServiceMain( DWORD argc, LPTSTR argv[] );
 static OSStatus		ServiceSetupEventLogging( void );
@@ -322,6 +327,7 @@
 static mDNSs32		udsIdle(mDNS * const inMDNS, mDNSs32 interval);
 static void			CoreCallback(mDNS * const inMDNS, mStatus result);
 static void			HostDescriptionChanged(mDNS * const inMDNS);
+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 );
@@ -370,6 +376,8 @@
 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 CRITICAL_SECTION			gEventSourceLock;
 DEBUG_LOCAL GenLinkedList				gEventSources;
 DEBUG_LOCAL BOOL						gRetryFirewall			= FALSE;
@@ -386,13 +394,9 @@
 #endif
 
 //===========================================================================================================================
-//	main
+//	Main
 //===========================================================================================================================
-#if defined(UNICODE)
-int __cdecl wmain( int argc, wchar_t * argv[] )
-#else
-int	__cdecl main( int argc, char *argv[] )
-#endif
+int	Main( int argc, LPTSTR argv[] )
 {
 	OSStatus		err;
 	BOOL			ok;
@@ -987,7 +991,7 @@
 //	RunDirect
 //===========================================================================================================================
 
-static OSStatus	RunDirect( int argc, LPTSTR argv[] )
+int	RunDirect( int argc, LPTSTR argv[] )
 {
 	OSStatus		err;
 	BOOL			initialized;
@@ -1160,7 +1164,7 @@
 	switch( inControl )
 	{
 		case SERVICE_CONTROL_STOP:
-			dlog( kDebugLevelNotice, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP\n" );
+			dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP\n" );
 			
 			ServiceStop();
 			setStatus = FALSE;
@@ -1170,10 +1174,42 @@
 
 			if (inEventType == PBT_APMSUSPEND)
 			{
+				LARGE_INTEGER timeout;
+
+				dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMSUSPEND\n" );
+
+				mDNSPlatformLock( &gMDNSRecord );
+				
+				gMDNSRecord.SystemWakeOnLANEnabled = SystemWakeForNetworkAccess( &timeout );
+				
+				if ( gMDNSRecord.SystemWakeOnLANEnabled )
+				{
+					ok = SetWaitableTimer( gSPSWakeupEvent, &timeout, 0, NULL, NULL, TRUE );
+					check( ok );
+				}
+
+				mDNSPlatformUnlock( &gMDNSRecord );
+
 				mDNSCoreMachineSleep(&gMDNSRecord, TRUE);
 			}
 			else if (inEventType == PBT_APMRESUMESUSPEND)
 			{
+				dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMRESUMESUSPEND\n" );
+
+				mDNSPlatformLock( &gMDNSRecord );
+
+				if ( gSPSWakeupEvent )
+				{
+					CancelWaitableTimer( gSPSWakeupEvent );
+				}
+
+				if ( gSPSSleepEvent )
+				{
+					CancelWaitableTimer( gSPSSleepEvent );
+				}
+
+				mDNSPlatformUnlock( &gMDNSRecord );
+
 				mDNSCoreMachineSleep(&gMDNSRecord, FALSE);
 			}
 		
@@ -1301,6 +1337,14 @@
 	err = translate_errno( gStopEvent, errno_compat(), kNoResourcesErr );
 	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 );
+
 	err = mDNS_Init( &gMDNSRecord, &gPlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, CoreCallback, mDNS_Init_NoInitCallbackContext); 
 	require_noerr( err, exit);
 
@@ -1343,9 +1387,41 @@
 
 	timeout = ( gRetryFirewall ) ? kRetryFirewallPeriod : INFINITE;
 
-	while( (result = WaitForSingleObject( gStopEvent, timeout ) ) != WAIT_OBJECT_0 )
+	for ( ;; )
 	{
-		if ( result == WAIT_TIMEOUT )
+		HANDLE	waitList[ 3 ];
+
+		waitList[ 0 ] = gStopEvent;
+		waitList[ 1 ] = gSPSWakeupEvent;
+		waitList[ 2 ] = gSPSSleepEvent;
+
+		result = WaitForMultipleObjects( 3, waitList, FALSE, timeout );
+
+		if ( result == WAIT_OBJECT_0 )
+		{
+			break;
+		}
+		else if ( result == WAIT_OBJECT_0 + 1 )
+		{
+			__int64			temp;
+			LARGE_INTEGER	timeout;
+
+			dlog( kDebugLevelInfo, DEBUG_NAME "setting suspend event\n" );
+
+			// Stay awake for 60 seconds
+
+			temp				= -60 * 10000000;
+			timeout.LowPart		= (DWORD) ( temp & 0xFFFFFFFF );
+			timeout.HighPart	= (LONG)  ( temp >> 32 );
+
+			SetWaitableTimer( gSPSSleepEvent, &timeout, 0, NULL, NULL, TRUE );
+		}
+		else if ( result == WAIT_OBJECT_0 + 2 )
+		{
+			dlog( kDebugLevelInfo, DEBUG_NAME "suspending machine\n" );
+			SetSuspendState( FALSE, FALSE, FALSE );
+		}
+		else if ( result == WAIT_TIMEOUT )
 		{
 			OSStatus err;
 
@@ -1411,6 +1487,24 @@
 	//
 	DeleteCriticalSection(&gEventSourceLock);
 
+	if ( gSPSWakeupEvent )
+	{
+		CloseHandle( gSPSWakeupEvent );
+		gSPSWakeupEvent = NULL;
+	}
+
+	if ( gSPSSleepEvent )
+	{
+		CloseHandle( gSPSSleepEvent );
+		gSPSSleepEvent = NULL;
+	}
+
+	if ( gStopEvent )
+	{
+		CloseHandle( gStopEvent );
+		gStopEvent = NULL;
+	}
+
 	//
 	// clean up loaded library
 	//
@@ -1835,6 +1929,83 @@
 
 
 //===========================================================================================================================
+//	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;
+	time_t					delta;
+	__int64					delta64;
+	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
+
+	UpdateWOMPConfig( &gMDNSRecord );
+	require_action( gMDNSRecord.p->womp, exit, ok = FALSE );
+
+	// Calculate next wake up time
+
+	startTime		= time( NULL );
+	nextWakeupTime	= startTime + ( 120 * 60 );
+	
+	if ( gMDNSRecord.p->nextDHCPLeaseExpires < nextWakeupTime )
+	{
+		nextWakeupTime = gMDNSRecord.p->nextDHCPLeaseExpires;
+	}
+
+	// Finally calculate the next relative wakeup time
+
+	delta = ( time_t ) ( ( ( double )( nextWakeupTime - startTime ) ) * 0.9 );
+	delta64 = -delta * 10000000;
+	timeout->LowPart  = (DWORD) ( delta64 & 0xFFFFFFFF );
+	timeout->HighPart = (LONG)  ( delta64 >> 32 );
+
+	dlog( kDebugLevelInfo, DEBUG_NAME "enabling sleep proxy client with next wakeup time %d seconds from now\n", delta );
+
+	ok = TRUE;
+
+exit:
+
+	if ( key )
+	{
+		RegCloseKey( key );
+	}
+
+	return ok;
+}
+
+
+//===========================================================================================================================
 //	HaveRoute
 //===========================================================================================================================
 
diff --git a/mDNSWindows/SystemService/Service.h b/mDNSWindows/SystemService/Service.h
new file mode 100755
index 0000000..438c1c4
--- /dev/null
+++ b/mDNSWindows/SystemService/Service.h
@@ -0,0 +1,38 @@
+/* -*- 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.
+
+    Change History (most recent first):
+    
+$Log: Service.h,v $
+Revision 1.1  2009/07/09 21:34:15  herscher
+<rdar://problem/3775717> SDK: Port mDNSNetMonitor to Windows. Refactor the system service slightly by removing the main() function from Service.c so that mDNSNetMonitor can link to functions defined in Service.c
+
+
+ */
+
+#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.vcproj b/mDNSWindows/SystemService/Service.vcproj
index d16d017..c30cca8 100644
--- a/mDNSWindows/SystemService/Service.vcproj
+++ b/mDNSWindows/SystemService/Service.vcproj
@@ -44,7 +44,7 @@
 				Name="VCCLCompilerTool"

 				Optimization="0"

 				AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;&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_"

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

@@ -58,7 +58,7 @@
 				Detect64BitPortabilityProblems="true"

 				DebugInformationFormat="3"

 				CallingConvention="2"

-				DisableSpecificWarnings="4127"

+				DisableSpecificWarnings="4127;4201"

 				ShowIncludes="false"

 			/>

 			<Tool

@@ -74,7 +74,7 @@
 			<Tool

 				Name="VCLinkerTool"

 				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

-				AdditionalDependencies="ws2_32.lib iphlpapi.lib crypt32.lib netapi32.lib"

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

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

 				LinkIncremental="2"

 				IgnoreAllDefaultLibraries="false"

@@ -151,7 +151,7 @@
 				Detect64BitPortabilityProblems="true"

 				DebugInformationFormat="3"

 				CallingConvention="2"

-				DisableSpecificWarnings="4127"

+				DisableSpecificWarnings="4127;4201"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

@@ -227,14 +227,14 @@
 			<Tool

 				Name="VCCLCompilerTool"

 				AdditionalIncludeDirectories=".;../;../../mDNSCore;../../mDNSShared;&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_"

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

-				DisableSpecificWarnings="4127"

+				DisableSpecificWarnings="4127;4201"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

@@ -249,7 +249,7 @@
 			<Tool

 				Name="VCLinkerTool"

 				AdditionalOptions="/NXCOMPAT /DYNAMICBASE /SAFESEH"

-				AdditionalDependencies="ws2_32.lib iphlpapi.lib netapi32.lib"

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

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

 				LinkIncremental="1"

 				GenerateDebugInformation="true"

@@ -320,7 +320,7 @@
 				WarningLevel="4"

 				Detect64BitPortabilityProblems="true"

 				DebugInformationFormat="3"

-				DisableSpecificWarnings="4127"

+				DisableSpecificWarnings="4127;4201"

 			/>

 			<Tool

 				Name="VCManagedResourceCompilerTool"

@@ -335,7 +335,7 @@
 			<Tool

 				Name="VCLinkerTool"

 				AdditionalOptions="/NXCOMPAT /DYNAMICBASE"

-				AdditionalDependencies="ws2_32.lib iphlpapi.lib netapi32.lib"

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

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

 				LinkIncremental="1"

 				GenerateDebugInformation="true"

@@ -410,6 +410,10 @@
 				>

 			</File>

 			<File

+				RelativePath=".\main.c"

+				>

+			</File>

+			<File

 				RelativePath="..\..\mDNSCore\mDNS.c"

 				>

 			</File>

@@ -484,6 +488,10 @@
 				>

 			</File>

 			<File

+				RelativePath=".\Service.h"

+				>

+			</File>

+			<File

 				RelativePath="..\..\mDNSCore\uDNS.h"

 				>

 			</File>

diff --git a/mDNSWindows/SystemService/main.c b/mDNSWindows/SystemService/main.c
new file mode 100755
index 0000000..40c53b8
--- /dev/null
+++ b/mDNSWindows/SystemService/main.c
@@ -0,0 +1,40 @@
+/* -*- 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.
+
+    Change History (most recent first):
+    
+$Log: main.c,v $
+Revision 1.1  2009/07/09 21:34:15  herscher
+<rdar://problem/3775717> SDK: Port mDNSNetMonitor to Windows. Refactor the system service slightly by removing the main() function from Service.c so that mDNSNetMonitor can link to functions defined in Service.c
+
+
+ */
+
+#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/WinVersRes.h b/mDNSWindows/WinVersRes.h
index b155515..a46a002 100644
--- a/mDNSWindows/WinVersRes.h
+++ b/mDNSWindows/WinVersRes.h
@@ -17,6 +17,12 @@
     Change History (most recent first):
 
 $Log: WinVersRes.h,v $
+Revision 1.63  2009/07/21 05:10:55  herscher
+Bump version to 2.0.0.7
+
+Revision 1.62  2009/07/13 18:47:58  herscher
+Bump to version 2.0.0.6
+
 Revision 1.61  2009/06/30 17:37:32  herscher
 Bump to 2.0.0.5
 
@@ -211,10 +217,10 @@
 #define MASTER_COMPANY_NAME   "Apple Inc."
 
 // Define the product version for mDNSResponder on Windows
-#define MASTER_PROD_VERS		2,0,0,5
-#define MASTER_PROD_VERS_STR	"2,0,0,5"
-#define MASTER_PROD_VERS_STR2	"2.0.0.5"
-#define MASTER_PROD_VERS_STR3 "Explorer Plugin 2.0.0.5"
+#define MASTER_PROD_VERS		2,0,0,7
+#define MASTER_PROD_VERS_STR	"2,0,0,7"
+#define MASTER_PROD_VERS_STR2	"2.0.0.7"
+#define MASTER_PROD_VERS_STR3 "Explorer Plugin 2.0.0.7"
 
 // Define the legal copyright
 #define MASTER_LEGAL_COPYRIGHT "Copyright (C) 2003-2009 Apple Inc."
diff --git a/mDNSWindows/mDNSWin32.c b/mDNSWindows/mDNSWin32.c
index 8f1283f..05b9a56 100755
--- a/mDNSWindows/mDNSWin32.c
+++ b/mDNSWindows/mDNSWin32.c
@@ -17,6 +17,15 @@
     Change History (most recent first):
     
 $Log: mDNSWin32.c,v $
+Revision 1.145  2009/07/20 04:07:41  herscher
+<rdar://problem/6145339> Bonjour does not list IPv6 loopback address when all network adapters are disabled
+
+Revision 1.144  2009/07/17 19:59:46  herscher
+<rdar://problem/7062660> Update the womp settings for each network adapter immediately preceding the call to mDNSCoreMachineSleep().
+
+Revision 1.143  2009/07/07 21:34:58  herscher
+<rdar://problem/6713286> windows platform changes to support use as sleep proxy client
+
 Revision 1.142  2009/06/25 21:11:02  herscher
 <rdar://problem/7003607> Platform layer doesn't correctly initialize the port field of TCP and UDP socket structures.
 
@@ -169,6 +178,8 @@
 	#include	<process.h>
 	#include	<ntsecapi.h>
 	#include	<lm.h>
+	#include	<winioctl.h>
+	#include	<ntddndis.h>        // This defines the IOCTL constants.
 #endif
 
 #include	"mDNSEmbeddedAPI.h"
@@ -215,6 +226,7 @@
 
 #define kIPv6IfIndexBase							(10000000L)
 #define SMBPortAsNumber								445
+#define DEVICE_PREFIX								"\\\\.\\"
 
 
 #if 0
@@ -335,6 +347,7 @@
 mDNSlocal void				SetDomainSecrets( mDNS * const m );
 mDNSlocal void				SetDomainSecret( mDNS * const m, const domainname * inDomain );
 mDNSlocal void				CheckFileShares( mDNS * const m );
+mDNSlocal mDNSu8			IsWOMPEnabled( const char * adapterName );
 
 #ifdef	__cplusplus
 	}
@@ -1350,7 +1363,7 @@
 
         if (mDNSIPPortIsZero(requestedport))
 		{
-			port = mDNSOpaque16fromIntVal(0xC000 + mDNSRandom(0x3FFF));
+			port = mDNSOpaque16fromIntVal( ( mDNSu16 ) ( 0xC000 + mDNSRandom(0x3FFF) ) );
 		}
 
 		saddr.sin_port = port.NotAnInteger;
@@ -2362,6 +2375,8 @@
 	check( inMDNS->p );
 	
 	inMDNS->p->registeredLoopback4	= mDNSfalse;
+	inMDNS->p->nextDHCPLeaseExpires = 0xFFFFFFFF;
+	inMDNS->p->womp					= mDNSfalse;
 	addrs							= NULL;
 	foundv4							= mDNSfalse;
 	foundv6							= mDNSfalse;
@@ -2425,6 +2440,11 @@
 			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
@@ -2519,7 +2539,7 @@
 	
 	if ( !foundv4 && loopbackv4 )
 	{
-		dlog( kDebugLevelVerbose, DEBUG_NAME "Interface %40s (0x%08X) %##a\n", 
+		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 );
@@ -2547,6 +2567,34 @@
 		++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->unicastSock6DestAddr = ifd->defaultAddr;
+			foundUnicastSock6DestAddr = TRUE;
+		}
+#endif
+
+		*next = ifd;
+		next  = &ifd->next;
+		++inMDNS->p->interfaceCount;
+	}
+
 exit:
 	if( err )
 	{
@@ -2723,7 +2771,19 @@
 		err = translate_errno( ifd->readPendingEvent, (mStatus) GetLastError(), kUnknownErr );
 		require_noerr( err, exit );
 	}
-	
+
+	if ( inIFA->ifa_dhcpEnabled && ( inIFA->ifa_dhcpLeaseExpires < inMDNS->p->nextDHCPLeaseExpires ) )
+	{
+		inMDNS->p->nextDHCPLeaseExpires = inIFA->ifa_dhcpLeaseExpires;
+	}
+
+	ifd->interfaceInfo.NetWake = inIFA->ifa_womp;
+
+	if ( ifd->interfaceInfo.NetWake )
+	{
+		inMDNS->p->womp = TRUE;
+	}
+
 	// Register this interface with mDNS.
 	
 	err = SockAddrToMDNSAddr( inIFA->ifa_addr, &ifd->interfaceInfo.ip, NULL );
@@ -2746,6 +2806,7 @@
 	ifd = NULL;
 	
 exit:
+
 	if( ifd )
 	{
 		TearDownInterface( inMDNS, ifd );
@@ -4138,9 +4199,9 @@
 			firstPrefix = NULL;
 		}
 
-		// Skip psuedo and tunnel interfaces.
+		// Skip pseudo and tunnel interfaces.
 		
-		if( ( ipv6IfIndex == 1 ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
+		if( ( ( ipv6IfIndex == 1 ) && ( iaa->IfType != IF_TYPE_SOFTWARE_LOOPBACK ) ) || ( iaa->IfType == IF_TYPE_TUNNEL ) )
 		{
 			continue;
 		}
@@ -4155,7 +4216,7 @@
 			ULONG					prefixLength;
 			uint32_t				ipv4Index;
 			struct sockaddr_in		ipv4Netmask;
-			
+
 			family = addr->Address.lpSockaddr->sa_family;
 			if( ( family != AF_INET ) && ( family != AF_INET6 ) ) continue;
 			
@@ -4221,6 +4282,26 @@
 				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->LeaseLifetime != 0xFFFFFFFF ) )
+			{
+				ifa->ifa_dhcpEnabled		= TRUE;
+				ifa->ifa_dhcpLeaseExpires	= time( NULL ) + addr->LeaseLifetime;
+			}
+			else
+			{
+				ifa->ifa_dhcpEnabled		= FALSE;
+				ifa->ifa_dhcpLeaseExpires	= 0;
+			}
+
+			// Get WakeOnLAN settings
+
+			if ( iaa->IfType == IF_TYPE_ETHERNET_CSMACD )
+			{
+				ifa->ifa_womp = IsWOMPEnabled( iaa->AdapterName );
+			}
 			
 			// Get address.
 			
@@ -4338,6 +4419,9 @@
 	INTERFACE_INFO *		buffer;
 	INTERFACE_INFO *		tempBuffer;
 	INTERFACE_INFO *		ifInfo;
+	IP_ADAPTER_INFO *		pAdapterInfo;
+	IP_ADAPTER_INFO *		pAdapter;
+	ULONG					bufLen;
 	int						n;
 	int						i;
 	struct ifaddrs *		head;
@@ -4348,6 +4432,7 @@
 	buffer	= NULL;
 	head	= NULL;
 	next	= &head;
+	pAdapterInfo = NULL;
 	
 	// 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
@@ -4379,6 +4464,28 @@
 	check( actualSize <= size );
 	check( ( actualSize % sizeof( INTERFACE_INFO ) ) == 0 );
 	n = (int)( actualSize / sizeof( INTERFACE_INFO ) );
+
+	// Now call GetAdaptersInfo so we can get DHCP information for each interface
+
+	pAdapterInfo	= NULL;
+	bufLen			= 0;
+	
+	for ( i = 0; i < 100; i++ )
+	{
+		err = GetAdaptersInfo( pAdapterInfo, &bufLen);
+
+		if ( err != ERROR_BUFFER_OVERFLOW )
+		{
+			break;
+		}
+
+		pAdapterInfo = (IP_ADAPTER_INFO*) realloc( pAdapterInfo, bufLen );
+
+		if ( !pAdapterInfo )
+		{
+			break;
+		}
+	}
 	
 	// Process the raw interface list and build a linked list of IPv4 interfaces.
 	
@@ -4448,6 +4555,19 @@
 		
 			ifa->ifa_extra.index = (uint32_t)( i + 1 );
 		}
+
+		// Now get DHCP configuration information
+
+		for ( pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next )
+		{
+			if ( strcmp( inet_ntoa( ifInfo->iiAddress.AddressIn.sin_addr ), pAdapter->IpAddressList.IpAddress.String ) == 0 )
+			{
+				ifa->ifa_dhcpEnabled		= pAdapter->DhcpEnabled;
+				ifa->ifa_dhcpLeaseExpires	= pAdapter->LeaseExpires;
+				ifa->ifa_womp				= IsWOMPEnabled( pAdapter->AdapterName );
+				break;
+			}
+		}
 	}
 	
 	// Success!
@@ -4460,6 +4580,11 @@
 	err = 0;
 	
 exit:
+
+	if ( pAdapterInfo )
+	{
+		free( pAdapterInfo );
+	}
 	if( head )
 	{
 		freeifaddrs( head );
@@ -5440,3 +5565,70 @@
 
 	return;
 }
+
+
+void
+UpdateWOMPConfig( mDNS * const m )
+{
+	mDNSInterfaceData * ifd;
+
+	mDNSPlatformLock( m );
+
+	m->p->womp = mDNSfalse;
+
+	for( ifd = m->p->interfaceList; ifd; ifd = ifd->next )
+	{
+		ifd->interfaceInfo.NetWake = IsWOMPEnabled( ifd->name );
+
+		if ( ifd->interfaceInfo.NetWake )
+		{
+			m->p->womp = mDNStrue;
+		}
+	}
+
+	mDNSPlatformUnlock( m );
+}
+
+
+mDNSlocal mDNSu8
+IsWOMPEnabled( 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;
+	
+    // 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 );
+    }
+
+	return ( mDNSu8 ) ok;
+}
diff --git a/mDNSWindows/mDNSWin32.h b/mDNSWindows/mDNSWin32.h
index c85f2fe..4d30be5 100755
--- a/mDNSWindows/mDNSWin32.h
+++ b/mDNSWindows/mDNSWin32.h
@@ -17,6 +17,12 @@
     Change History (most recent first):
     
 $Log: mDNSWin32.h,v $
+Revision 1.30  2009/07/17 19:59:46  herscher
+<rdar://problem/7062660> Update the womp settings for each network adapter immediately preceding the call to mDNSCoreMachineSleep().
+
+Revision 1.29  2009/07/07 21:34:58  herscher
+<rdar://problem/6713286> windows platform changes to support use as sleep proxy client
+
 Revision 1.28  2009/04/24 04:55:26  herscher
 <rdar://problem/3496833> Advertise SMB file sharing via Bonjour
 
@@ -211,6 +217,8 @@
 	HANDLE						firewallEvent;		// Firewall changed
 	HANDLE						wakeupEvent;
 	HANDLE						initEvent;
+	time_t						nextDHCPLeaseExpires;
+	mDNSBool					womp;				// Does any interface support wake-on-magic-packet
 	HKEY						descKey;
 	HKEY						tcpipKey;
 	HKEY						ddnsKey;
@@ -257,6 +265,9 @@
 	struct sockaddr	*	ifa_netmask;
 	struct sockaddr	*	ifa_broadaddr;
 	struct sockaddr	*	ifa_dstaddr;
+	BOOL				ifa_dhcpEnabled;
+	time_t				ifa_dhcpLeaseExpires;
+	mDNSu8				ifa_womp;
 	void *				ifa_data;
 	
 	struct
@@ -267,6 +278,9 @@
 };
 
 
+extern void UpdateWOMPConfig();
+
+
 #ifdef	__cplusplus
 	}
 #endif