react-native-zeroconf 0.13.7 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +49 -0
- package/README.md +473 -65
- package/android/build.gradle +28 -22
- package/android/src/main/AndroidManifest.xml +1 -2
- package/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java +5 -5
- package/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java +19 -3
- package/android/src/main/java/com/github/druk/dnssd/BaseListener.java +33 -0
- package/android/src/main/java/com/github/druk/dnssd/BrowseListener.java +67 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSRecord.java +47 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSD.java +650 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDBindable.java +67 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDEmbedded.java +135 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDException.java +66 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDRecordRegistrar.java +55 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDRegistration.java +54 -0
- package/android/src/main/java/com/github/druk/dnssd/DNSSDService.java +35 -0
- package/android/src/main/java/com/github/druk/dnssd/DomainListener.java +57 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalBrowseListener.java +76 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSD.java +870 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDRecordRegistrar.java +30 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDRegistration.java +34 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDNSSDService.java +29 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalDomainListener.java +62 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalQueryListener.java +61 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalRegisterListener.java +51 -0
- package/android/src/main/java/com/github/druk/dnssd/InternalResolveListener.java +58 -0
- package/android/src/main/java/com/github/druk/dnssd/NSClass.java +16 -0
- package/android/src/main/java/com/github/druk/dnssd/NSType.java +58 -0
- package/android/src/main/java/com/github/druk/dnssd/QueryListener.java +54 -0
- package/android/src/main/java/com/github/druk/dnssd/RegisterListener.java +46 -0
- package/android/src/main/java/com/github/druk/dnssd/RegisterRecordListener.java +35 -0
- package/android/src/main/java/com/github/druk/dnssd/ResolveListener.java +55 -0
- package/android/src/main/java/com/github/druk/dnssd/TXTRecord.java +293 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/BonjourService.java +400 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2BrowseListener.java +55 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2Dnssd.java +127 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdBindable.java +35 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdCommon.java +280 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdEmbedded.java +31 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2QueryListener.java +70 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2RegisterListener.java +47 -0
- package/android/src/main/java/com/github/druk/rx2dnssd/Rx2ResolveListener.java +51 -0
- package/android/src/main/jni/Android.mk +95 -0
- package/android/src/main/jni/Application.mk +3 -0
- package/android/src/main/jni/DNSSD.java.h +290 -0
- package/android/src/main/jni/JNISupport.c +1140 -0
- package/android/src/main/jni/mdnsresponder/Android.bp +215 -0
- package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.c +75 -0
- package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.h +41 -0
- package/android/src/main/jni/mdnsresponder/Clients/Makefile +54 -0
- package/android/src/main/jni/mdnsresponder/Clients/ReadMe.txt +25 -0
- package/android/src/main/jni/mdnsresponder/Clients/dns-sd.c +1351 -0
- package/android/src/main/jni/mdnsresponder/LICENSE +13 -0
- package/android/src/main/jni/mdnsresponder/MODULE_LICENSE_APACHE2 +0 -0
- package/android/src/main/jni/mdnsresponder/Makefile +41 -0
- package/android/src/main/jni/mdnsresponder/NOTICE +13 -0
- package/android/src/main/jni/mdnsresponder/PrivateDNS.txt +275 -0
- package/android/src/main/jni/mdnsresponder/README.txt +166 -0
- package/android/src/main/jni/mdnsresponder/README.version +3 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/Iphlpapi.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/README +3 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/Resource.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/Ws2tcpip.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/caseMapping/ipExport.h +1 -0
- package/android/src/main/jni/mdnsresponder/android/windows_firewall_dummy.c +10 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/DNSCommon.c +3157 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/DNSCommon.h +292 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/DNSDigest.c +1579 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/Implementer Notes.txt +66 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/mDNS.c +11469 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/mDNSDebug.h +164 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/mDNSEmbeddedAPI.h +2974 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/uDNS.c +4969 -0
- package/android/src/main/jni/mdnsresponder/mDNSCore/uDNS.h +132 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Client.c +223 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.c +91 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.h +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Identify.c +378 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Makefile +520 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/NetMonitor.c +1010 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/PosixDaemon.c +329 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ProxyResponder.c +300 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/ReadMe.txt +314 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Responder.c +792 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/Services.txt +36 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/libnss_mdns.8 +148 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSPosix.c +1685 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSPosix.h +88 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSUNP.c +726 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mDNSUNP.h +130 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/mdnsd.sh +73 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_ReadMe.txt +125 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.c +2723 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf +13 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf.5 +135 -0
- package/android/src/main/jni/mdnsresponder/mDNSPosix/parselog.py +247 -0
- package/android/src/main/jni/mdnsresponder/mDNSResponder.sln +400 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/CommonServices.h +1537 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.c +3075 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.h +1607 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/GenLinkedList.c +319 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/GenLinkedList.h +90 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/PlatformCommon.c +220 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/PlatformCommon.h +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dns-sd.1 +194 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dns_sd.h +2452 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.8 +69 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.c +3146 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.conf +60 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.h +163 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_lexer.l +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_parser.y +585 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientlib.c +368 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientshim.c +802 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_clientstub.c +1988 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_ipc.c +161 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/dnssd_ipc.h +219 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/mDNS.1 +198 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSDebug.c +93 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSResponder.8 +116 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/uds_daemon.c +4758 -0
- package/android/src/main/jni/mdnsresponder/mDNSShared/uds_daemon.h +80 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.cpp +441 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.h +156 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.cpp +59 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.h +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp +301 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.h +105 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.cpp +380 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.def +20 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.h +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.rc +141 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.vcproj +727 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelDll.rc +123 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.cpp +373 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.h +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.rc +123 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.vcproj +764 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.rc +270 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj +487 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.rc +134 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.vcproj +518 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.cpp +197 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.h +87 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.cpp +387 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.h +75 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.cpp +544 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.h +107 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.cpp +273 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.h +123 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.cpp +115 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.h +54 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest +10 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.manifest +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.rc2 +13 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel64.manifest +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/EnergySaver.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/controlpanel.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/failure.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/success.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/resource.h +56 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.cpp +20 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.h +64 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.rc +102 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dllmain.c +112 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.def +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.vcproj +472 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/resource.h +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/AssemblyInfo.cpp +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/PString.h +70 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.cpp +22 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.h +33 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.cpp +1234 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.h +1392 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.rc +113 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.vcproj +446 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/resource.h +3 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.cpp +693 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.h +52 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.vcproj +324 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.cpp +208 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.def +35 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.idl +491 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rc +126 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rgs +11 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.vcproj +625 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSD.cpp +892 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.cpp +31 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.h +133 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.cpp +101 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.h +185 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.cpp +2095 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.h +429 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.cpp +344 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.h +102 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.cpp +381 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.h +203 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.rgs +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/_IDNSSDEvents_CP.h +358 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.c +51 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.h +49 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/resource.h +30 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/stdafx.h +88 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln +21 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj +253 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln +21 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj +267 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc +323 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2 +20 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h +53 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp +71 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h +62 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp +111 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h +68 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp +1426 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h +131 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp +109 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h +53 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h +48 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc +37 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp +868 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw +29 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc +194 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2 +13 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h +28 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h +22 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp +92 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h +57 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp +394 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h +84 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp +18 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h +46 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/Java.vcproj +111 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/jdns_sd.rc +62 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile +143 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile64 +143 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.c +581 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.rc +103 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.vcproj +409 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/Prefix.h +28 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/resource.h +27 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.c +128 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.h +70 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/README.txt +85 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/RegNames.h +57 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.c +338 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.h +42 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLog.mc +11 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLogMessages.bin +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.cpp +484 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.h +79 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Prefix.h +30 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.c +2669 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.h +30 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.mcp +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.rc +114 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.vcproj +562 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/main.c +32 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder.manifest +12 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder64.manifest +12 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resource.h +17 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resrc1.h +15 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.cpp +165 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.h +36 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.cpp +93 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.h +34 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/WinVersRes.h +35 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/isocode.h +135 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.c +268 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.h +54 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.c +5200 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.h +208 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/ReadMe.txt +15 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.aps +0 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.c +2430 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.def +24 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.rc +104 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.vcproj +457 -0
- package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/resource.h +27 -0
- package/android/src/main/jni/mdnsresponder/mdnsd.rc +7 -0
- package/android/src/main/jni/nameser.h +588 -0
- package/dist/index.js +148 -1
- package/package.json +23 -17
- package/src/index.js +166 -0
|
@@ -0,0 +1,2669 @@
|
|
|
1
|
+
/* -*- Mode: C; tab-width: 4 -*-
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <stdio.h>
|
|
19
|
+
#include <stdlib.h>
|
|
20
|
+
#include <crtdbg.h>
|
|
21
|
+
#include <stdarg.h>
|
|
22
|
+
#include <stddef.h>
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#include "CommonServices.h"
|
|
26
|
+
#include "DebugServices.h"
|
|
27
|
+
#include "RegNames.h"
|
|
28
|
+
|
|
29
|
+
#include "uds_daemon.h"
|
|
30
|
+
#include "GenLinkedList.h"
|
|
31
|
+
#include "Service.h"
|
|
32
|
+
#include "mDNSWindows/SystemService/EventLog.h"
|
|
33
|
+
|
|
34
|
+
#include "Resource.h"
|
|
35
|
+
|
|
36
|
+
#include "mDNSEmbeddedAPI.h"
|
|
37
|
+
#include "uDNS.h"
|
|
38
|
+
#include "mDNSWin32.h"
|
|
39
|
+
|
|
40
|
+
#include "Firewall.h"
|
|
41
|
+
|
|
42
|
+
#if( !TARGET_OS_WINDOWS_CE )
|
|
43
|
+
#include <mswsock.h>
|
|
44
|
+
#include <process.h>
|
|
45
|
+
#include <ipExport.h>
|
|
46
|
+
#include <ws2def.h>
|
|
47
|
+
#include <ws2ipdef.h>
|
|
48
|
+
#include <iphlpapi.h>
|
|
49
|
+
#include <netioapi.h>
|
|
50
|
+
#include <iptypes.h>
|
|
51
|
+
#include <powrprof.h>
|
|
52
|
+
#endif
|
|
53
|
+
|
|
54
|
+
#ifndef HeapEnableTerminationOnCorruption
|
|
55
|
+
# define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1
|
|
56
|
+
#endif
|
|
57
|
+
|
|
58
|
+
#if 0
|
|
59
|
+
#pragma mark == Constants ==
|
|
60
|
+
#endif
|
|
61
|
+
|
|
62
|
+
//===========================================================================================================================
|
|
63
|
+
// Constants
|
|
64
|
+
//===========================================================================================================================
|
|
65
|
+
|
|
66
|
+
#define DEBUG_NAME "[mDNSWin32] "
|
|
67
|
+
#define kServiceFirewallName L"Bonjour"
|
|
68
|
+
#define kServiceDependencies TEXT("Tcpip\0\0")
|
|
69
|
+
#define kDNSServiceCacheEntryCountDefault 512
|
|
70
|
+
#define kRetryFirewallPeriod 30 * 1000
|
|
71
|
+
#define kDefValueSize MAX_PATH + 1
|
|
72
|
+
#define kZeroIndex 0
|
|
73
|
+
#define kDefaultRouteMetric 399
|
|
74
|
+
#define kSecondsTo100NSUnits ( 10 * 1000 * 1000 )
|
|
75
|
+
#define kSPSMaintenanceWakePeriod -30
|
|
76
|
+
|
|
77
|
+
#define RR_CACHE_SIZE 500
|
|
78
|
+
static CacheEntity gRRCache[RR_CACHE_SIZE];
|
|
79
|
+
#if 0
|
|
80
|
+
#pragma mark == Structures ==
|
|
81
|
+
#endif
|
|
82
|
+
|
|
83
|
+
//===========================================================================================================================
|
|
84
|
+
// Structures
|
|
85
|
+
//===========================================================================================================================
|
|
86
|
+
|
|
87
|
+
typedef struct EventSource
|
|
88
|
+
{
|
|
89
|
+
HANDLE event;
|
|
90
|
+
void * context;
|
|
91
|
+
RegisterWaitableEventHandler handler;
|
|
92
|
+
struct EventSource * next;
|
|
93
|
+
} EventSource;
|
|
94
|
+
|
|
95
|
+
static BOOL gEventSourceListChanged = FALSE;
|
|
96
|
+
static EventSource * gEventSourceList = NULL;
|
|
97
|
+
static EventSource * gCurrentSource = NULL;
|
|
98
|
+
static int gEventSources = 0;
|
|
99
|
+
|
|
100
|
+
#define kWaitListStopEvent ( WAIT_OBJECT_0 + 0 )
|
|
101
|
+
#define kWaitListInterfaceListChangedEvent ( WAIT_OBJECT_0 + 1 )
|
|
102
|
+
#define kWaitListComputerDescriptionEvent ( WAIT_OBJECT_0 + 2 )
|
|
103
|
+
#define kWaitListTCPIPEvent ( WAIT_OBJECT_0 + 3 )
|
|
104
|
+
#define kWaitListDynDNSEvent ( WAIT_OBJECT_0 + 4 )
|
|
105
|
+
#define kWaitListFileShareEvent ( WAIT_OBJECT_0 + 5 )
|
|
106
|
+
#define kWaitListFirewallEvent ( WAIT_OBJECT_0 + 6 )
|
|
107
|
+
#define kWaitListAdvertisedServicesEvent ( WAIT_OBJECT_0 + 7 )
|
|
108
|
+
#define kWaitListSPSWakeupEvent ( WAIT_OBJECT_0 + 8 )
|
|
109
|
+
#define kWaitListSPSSleepEvent ( WAIT_OBJECT_0 + 9 )
|
|
110
|
+
#define kWaitListFixedItemCount 10
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
#if 0
|
|
114
|
+
#pragma mark == Prototypes ==
|
|
115
|
+
#endif
|
|
116
|
+
|
|
117
|
+
//===========================================================================================================================
|
|
118
|
+
// Prototypes
|
|
119
|
+
//===========================================================================================================================
|
|
120
|
+
static void Usage( void );
|
|
121
|
+
static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent );
|
|
122
|
+
static OSStatus InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath );
|
|
123
|
+
static OSStatus RemoveService( LPCTSTR inName );
|
|
124
|
+
static OSStatus SetServiceParameters();
|
|
125
|
+
static OSStatus GetServiceParameters();
|
|
126
|
+
static OSStatus CheckFirewall();
|
|
127
|
+
static OSStatus SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription );
|
|
128
|
+
static void ReportStatus( int inType, const char *inFormat, ... );
|
|
129
|
+
|
|
130
|
+
static void WINAPI ServiceMain( DWORD argc, LPTSTR argv[] );
|
|
131
|
+
static OSStatus ServiceSetupEventLogging( void );
|
|
132
|
+
static DWORD WINAPI ServiceControlHandler( DWORD inControl, DWORD inEventType, LPVOID inEventData, LPVOID inContext );
|
|
133
|
+
|
|
134
|
+
static OSStatus ServiceRun( int argc, LPTSTR argv[] );
|
|
135
|
+
static void ServiceStop( void );
|
|
136
|
+
|
|
137
|
+
static OSStatus ServiceSpecificInitialize( int argc, LPTSTR argv[] );
|
|
138
|
+
static OSStatus ServiceSpecificRun( int argc, LPTSTR argv[] );
|
|
139
|
+
static OSStatus ServiceSpecificStop( void );
|
|
140
|
+
static void ServiceSpecificFinalize( int argc, LPTSTR argv[] );
|
|
141
|
+
static mStatus SetupNotifications();
|
|
142
|
+
static mStatus TearDownNotifications();
|
|
143
|
+
static mStatus RegisterWaitableEvent( mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler );
|
|
144
|
+
static void UnregisterWaitableEvent( mDNS * const inMDNS, HANDLE event );
|
|
145
|
+
static mStatus SetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount );
|
|
146
|
+
static void UDSCanAccept( mDNS * const inMDNS, HANDLE event, void * context );
|
|
147
|
+
static void UDSCanRead( TCPSocket * sock );
|
|
148
|
+
static void HandlePowerSuspend( void * v );
|
|
149
|
+
static void HandlePowerResumeSuspend( void * v );
|
|
150
|
+
static void CoreCallback(mDNS * const inMDNS, mStatus result);
|
|
151
|
+
static mDNSu8 SystemWakeForNetworkAccess( LARGE_INTEGER * timeout );
|
|
152
|
+
static OSStatus GetRouteDestination(DWORD * ifIndex, DWORD * address);
|
|
153
|
+
static OSStatus SetLLRoute( mDNS * const inMDNS );
|
|
154
|
+
static bool HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric );
|
|
155
|
+
static bool IsValidAddress( const char * addr );
|
|
156
|
+
static bool IsNortelVPN( IP_ADAPTER_INFO * pAdapter );
|
|
157
|
+
static bool IsJuniperVPN( IP_ADAPTER_INFO * pAdapter );
|
|
158
|
+
static bool IsCiscoVPN( IP_ADAPTER_INFO * pAdapter );
|
|
159
|
+
static const char * strnistr( const char * string, const char * subString, size_t max );
|
|
160
|
+
|
|
161
|
+
#if defined(UNICODE)
|
|
162
|
+
# define StrLen(X) wcslen(X)
|
|
163
|
+
# define StrCmp(X,Y) wcscmp(X,Y)
|
|
164
|
+
#else
|
|
165
|
+
# define StrLen(X) strlen(X)
|
|
166
|
+
# define StrCmp(X,Y) strcmp(X,Y)
|
|
167
|
+
#endif
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
#define kLLNetworkAddr "169.254.0.0"
|
|
171
|
+
#define kLLNetworkAddrMask "255.255.0.0"
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
#include "mDNSEmbeddedAPI.h"
|
|
175
|
+
|
|
176
|
+
#if 0
|
|
177
|
+
#pragma mark == Globals ==
|
|
178
|
+
#endif
|
|
179
|
+
|
|
180
|
+
//===========================================================================================================================
|
|
181
|
+
// Globals
|
|
182
|
+
//===========================================================================================================================
|
|
183
|
+
#define gMDNSRecord mDNSStorage
|
|
184
|
+
DEBUG_LOCAL mDNS_PlatformSupport gPlatformStorage;
|
|
185
|
+
DEBUG_LOCAL BOOL gServiceQuietMode = FALSE;
|
|
186
|
+
DEBUG_LOCAL SERVICE_TABLE_ENTRY gServiceDispatchTable[] =
|
|
187
|
+
{
|
|
188
|
+
{ kServiceName, ServiceMain },
|
|
189
|
+
{ NULL, NULL }
|
|
190
|
+
};
|
|
191
|
+
DEBUG_LOCAL SOCKET gInterfaceListChangedSocket = INVALID_SOCKET;
|
|
192
|
+
DEBUG_LOCAL HANDLE gInterfaceListChangedEvent = NULL;
|
|
193
|
+
DEBUG_LOCAL HKEY gDescKey = NULL;
|
|
194
|
+
DEBUG_LOCAL HANDLE gDescChangedEvent = NULL; // Computer description changed event
|
|
195
|
+
DEBUG_LOCAL HKEY gTcpipKey = NULL;
|
|
196
|
+
DEBUG_LOCAL HANDLE gTcpipChangedEvent = NULL; // TCP/IP config changed
|
|
197
|
+
DEBUG_LOCAL HKEY gDdnsKey = NULL;
|
|
198
|
+
DEBUG_LOCAL HANDLE gDdnsChangedEvent = NULL; // DynDNS config changed
|
|
199
|
+
DEBUG_LOCAL HKEY gFileSharingKey = NULL;
|
|
200
|
+
DEBUG_LOCAL HANDLE gFileSharingChangedEvent = NULL; // File Sharing changed
|
|
201
|
+
DEBUG_LOCAL HKEY gFirewallKey = NULL;
|
|
202
|
+
DEBUG_LOCAL HANDLE gFirewallChangedEvent = NULL; // Firewall changed
|
|
203
|
+
DEBUG_LOCAL HKEY gAdvertisedServicesKey = NULL;
|
|
204
|
+
DEBUG_LOCAL HANDLE gAdvertisedServicesChangedEvent = NULL; // Advertised services changed
|
|
205
|
+
DEBUG_LOCAL SERVICE_STATUS gServiceStatus;
|
|
206
|
+
DEBUG_LOCAL SERVICE_STATUS_HANDLE gServiceStatusHandle = NULL;
|
|
207
|
+
DEBUG_LOCAL HANDLE gServiceEventSource = NULL;
|
|
208
|
+
DEBUG_LOCAL bool gServiceAllowRemote = false;
|
|
209
|
+
DEBUG_LOCAL int gServiceCacheEntryCount = 0; // 0 means to use the DNS-SD default.
|
|
210
|
+
DEBUG_LOCAL bool gServiceManageLLRouting = true;
|
|
211
|
+
DEBUG_LOCAL int gWaitCount = 0;
|
|
212
|
+
DEBUG_LOCAL HANDLE * gWaitList = NULL;
|
|
213
|
+
DEBUG_LOCAL HANDLE gStopEvent = NULL;
|
|
214
|
+
DEBUG_LOCAL HANDLE gSPSWakeupEvent = NULL;
|
|
215
|
+
DEBUG_LOCAL HANDLE gSPSSleepEvent = NULL;
|
|
216
|
+
DEBUG_LOCAL HANDLE gUDSEvent = NULL;
|
|
217
|
+
DEBUG_LOCAL SocketRef gUDSSocket = 0;
|
|
218
|
+
DEBUG_LOCAL udsEventCallback gUDSCallback = NULL;
|
|
219
|
+
DEBUG_LOCAL BOOL gRetryFirewall = FALSE;
|
|
220
|
+
DEBUG_LOCAL DWORD gOSMajorVersion;
|
|
221
|
+
DEBUG_LOCAL DWORD gOSMinorVersion;
|
|
222
|
+
|
|
223
|
+
typedef DWORD ( WINAPI * GetIpInterfaceEntryFunctionPtr )( PMIB_IPINTERFACE_ROW );
|
|
224
|
+
mDNSlocal HMODULE gIPHelperLibraryInstance = NULL;
|
|
225
|
+
mDNSlocal GetIpInterfaceEntryFunctionPtr gGetIpInterfaceEntryFunctionPtr = NULL;
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
#if 0
|
|
229
|
+
#pragma mark -
|
|
230
|
+
#endif
|
|
231
|
+
|
|
232
|
+
//===========================================================================================================================
|
|
233
|
+
// Main
|
|
234
|
+
//===========================================================================================================================
|
|
235
|
+
int Main( int argc, LPTSTR argv[] )
|
|
236
|
+
{
|
|
237
|
+
OSStatus err;
|
|
238
|
+
BOOL ok;
|
|
239
|
+
BOOL start;
|
|
240
|
+
int i;
|
|
241
|
+
|
|
242
|
+
HeapSetInformation( NULL, HeapEnableTerminationOnCorruption, NULL, 0 );
|
|
243
|
+
|
|
244
|
+
debug_initialize( kDebugOutputTypeMetaConsole );
|
|
245
|
+
debug_set_property( kDebugPropertyTagPrintLevel, kDebugLevelVerbose );
|
|
246
|
+
|
|
247
|
+
// Default to automatically starting the service dispatcher if no extra arguments are specified.
|
|
248
|
+
|
|
249
|
+
start = ( argc <= 1 );
|
|
250
|
+
|
|
251
|
+
// Parse arguments.
|
|
252
|
+
|
|
253
|
+
for( i = 1; i < argc; ++i )
|
|
254
|
+
{
|
|
255
|
+
if( StrCmp( argv[ i ], TEXT("-install") ) == 0 ) // Install
|
|
256
|
+
{
|
|
257
|
+
TCHAR desc[ 256 ];
|
|
258
|
+
|
|
259
|
+
desc[ 0 ] = 0;
|
|
260
|
+
LoadString( GetModuleHandle( NULL ), IDS_SERVICE_DESCRIPTION, desc, sizeof( desc ) );
|
|
261
|
+
err = InstallService( kServiceName, kServiceName, desc, argv[0] );
|
|
262
|
+
if( err )
|
|
263
|
+
{
|
|
264
|
+
ReportStatus( EVENTLOG_ERROR_TYPE, "install service failed (%d)\n", err );
|
|
265
|
+
goto exit;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else if( StrCmp( argv[ i ], TEXT("-remove") ) == 0 ) // Remove
|
|
269
|
+
{
|
|
270
|
+
err = RemoveService( kServiceName );
|
|
271
|
+
if( err )
|
|
272
|
+
{
|
|
273
|
+
ReportStatus( EVENTLOG_ERROR_TYPE, "remove service failed (%d)\n", err );
|
|
274
|
+
goto exit;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else if( StrCmp( argv[ i ], TEXT("-start") ) == 0 ) // Start
|
|
278
|
+
{
|
|
279
|
+
start = TRUE;
|
|
280
|
+
}
|
|
281
|
+
else if( StrCmp( argv[ i ], TEXT("-server") ) == 0 ) // Server
|
|
282
|
+
{
|
|
283
|
+
err = RunDirect( argc, argv );
|
|
284
|
+
if( err )
|
|
285
|
+
{
|
|
286
|
+
ReportStatus( EVENTLOG_ERROR_TYPE, "run service directly failed (%d)\n", err );
|
|
287
|
+
}
|
|
288
|
+
goto exit;
|
|
289
|
+
}
|
|
290
|
+
else if( StrCmp( argv[ i ], TEXT("-q") ) == 0 ) // Quiet Mode (toggle)
|
|
291
|
+
{
|
|
292
|
+
gServiceQuietMode = !gServiceQuietMode;
|
|
293
|
+
}
|
|
294
|
+
else if( ( StrCmp( argv[ i ], TEXT("-help") ) == 0 ) || // Help
|
|
295
|
+
( StrCmp( argv[ i ], TEXT("-h") ) == 0 ) )
|
|
296
|
+
{
|
|
297
|
+
Usage();
|
|
298
|
+
err = 0;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
else
|
|
302
|
+
{
|
|
303
|
+
Usage();
|
|
304
|
+
err = kParamErr;
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Start the service dispatcher if requested. This does not return until all services have terminated. If any
|
|
310
|
+
// global initialization is needed, it should be done before starting the service dispatcher, but only if it
|
|
311
|
+
// will take less than 30 seconds. Otherwise, use a separate thread for it and start the dispatcher immediately.
|
|
312
|
+
|
|
313
|
+
if( start )
|
|
314
|
+
{
|
|
315
|
+
ok = StartServiceCtrlDispatcher( gServiceDispatchTable );
|
|
316
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kInUseErr );
|
|
317
|
+
if( err != kNoErr )
|
|
318
|
+
{
|
|
319
|
+
ReportStatus( EVENTLOG_ERROR_TYPE, "start service dispatcher failed (%d)\n", err );
|
|
320
|
+
goto exit;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
err = 0;
|
|
324
|
+
|
|
325
|
+
exit:
|
|
326
|
+
dlog( kDebugLevelTrace, DEBUG_NAME "exited (%d %m)\n", err, err );
|
|
327
|
+
_CrtDumpMemoryLeaks();
|
|
328
|
+
return( (int) err );
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
//===========================================================================================================================
|
|
332
|
+
// Usage
|
|
333
|
+
//===========================================================================================================================
|
|
334
|
+
|
|
335
|
+
static void Usage( void )
|
|
336
|
+
{
|
|
337
|
+
fprintf( stderr, "\n" );
|
|
338
|
+
fprintf( stderr, "mDNSResponder 1.0d1\n" );
|
|
339
|
+
fprintf( stderr, "\n" );
|
|
340
|
+
fprintf( stderr, " <no args> Runs the service normally\n" );
|
|
341
|
+
fprintf( stderr, " -install Creates the service and starts it\n" );
|
|
342
|
+
fprintf( stderr, " -remove Stops the service and deletes it\n" );
|
|
343
|
+
fprintf( stderr, " -start Starts the service dispatcher after processing all other arguments\n" );
|
|
344
|
+
fprintf( stderr, " -server Runs the service directly as a server (for debugging)\n" );
|
|
345
|
+
fprintf( stderr, " -q Toggles Quiet Mode (no events or output)\n" );
|
|
346
|
+
fprintf( stderr, " -remote Allow remote connections\n" );
|
|
347
|
+
fprintf( stderr, " -cache n Number of mDNS cache entries (defaults to %d)\n", kDNSServiceCacheEntryCountDefault );
|
|
348
|
+
fprintf( stderr, " -h[elp] Display Help/Usage\n" );
|
|
349
|
+
fprintf( stderr, "\n" );
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
//===========================================================================================================================
|
|
353
|
+
// ConsoleControlHandler
|
|
354
|
+
//===========================================================================================================================
|
|
355
|
+
|
|
356
|
+
static BOOL WINAPI ConsoleControlHandler( DWORD inControlEvent )
|
|
357
|
+
{
|
|
358
|
+
BOOL handled;
|
|
359
|
+
OSStatus err;
|
|
360
|
+
|
|
361
|
+
handled = FALSE;
|
|
362
|
+
switch( inControlEvent )
|
|
363
|
+
{
|
|
364
|
+
case CTRL_C_EVENT:
|
|
365
|
+
case CTRL_BREAK_EVENT:
|
|
366
|
+
case CTRL_CLOSE_EVENT:
|
|
367
|
+
case CTRL_LOGOFF_EVENT:
|
|
368
|
+
case CTRL_SHUTDOWN_EVENT:
|
|
369
|
+
err = ServiceSpecificStop();
|
|
370
|
+
require_noerr( err, exit );
|
|
371
|
+
|
|
372
|
+
handled = TRUE;
|
|
373
|
+
break;
|
|
374
|
+
|
|
375
|
+
default:
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
exit:
|
|
380
|
+
return( handled );
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
//===========================================================================================================================
|
|
384
|
+
// InstallService
|
|
385
|
+
//===========================================================================================================================
|
|
386
|
+
|
|
387
|
+
static OSStatus InstallService( LPCTSTR inName, LPCTSTR inDisplayName, LPCTSTR inDescription, LPCTSTR inPath )
|
|
388
|
+
{
|
|
389
|
+
OSStatus err;
|
|
390
|
+
SC_HANDLE scm;
|
|
391
|
+
SC_HANDLE service;
|
|
392
|
+
BOOL ok;
|
|
393
|
+
TCHAR fullPath[ MAX_PATH ];
|
|
394
|
+
TCHAR * namePtr;
|
|
395
|
+
DWORD size;
|
|
396
|
+
|
|
397
|
+
scm = NULL;
|
|
398
|
+
service = NULL;
|
|
399
|
+
|
|
400
|
+
// Get a full path to the executable since a relative path may have been specified.
|
|
401
|
+
|
|
402
|
+
size = GetFullPathName( inPath, MAX_PATH, fullPath, &namePtr );
|
|
403
|
+
err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
|
|
404
|
+
require_noerr( err, exit );
|
|
405
|
+
|
|
406
|
+
// Create the service and start it.
|
|
407
|
+
|
|
408
|
+
scm = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
|
|
409
|
+
err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
|
|
410
|
+
require_noerr( err, exit );
|
|
411
|
+
|
|
412
|
+
service = CreateService( scm, inName, inDisplayName, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS,
|
|
413
|
+
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, fullPath, NULL, NULL, kServiceDependencies,
|
|
414
|
+
NULL, NULL );
|
|
415
|
+
err = translate_errno( service, (OSStatus) GetLastError(), kDuplicateErr );
|
|
416
|
+
require_noerr( err, exit );
|
|
417
|
+
|
|
418
|
+
err = SetServiceParameters();
|
|
419
|
+
check_noerr( err );
|
|
420
|
+
|
|
421
|
+
if( inDescription )
|
|
422
|
+
{
|
|
423
|
+
err = SetServiceInfo( scm, inName, inDescription );
|
|
424
|
+
check_noerr( err );
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
ok = StartService( service, 0, NULL );
|
|
428
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kInUseErr );
|
|
429
|
+
require_noerr( err, exit );
|
|
430
|
+
|
|
431
|
+
ReportStatus( EVENTLOG_SUCCESS, "installed service\n" );
|
|
432
|
+
err = kNoErr;
|
|
433
|
+
|
|
434
|
+
exit:
|
|
435
|
+
if( service )
|
|
436
|
+
{
|
|
437
|
+
CloseServiceHandle( service );
|
|
438
|
+
}
|
|
439
|
+
if( scm )
|
|
440
|
+
{
|
|
441
|
+
CloseServiceHandle( scm );
|
|
442
|
+
}
|
|
443
|
+
return( err );
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
//===========================================================================================================================
|
|
447
|
+
// RemoveService
|
|
448
|
+
//===========================================================================================================================
|
|
449
|
+
|
|
450
|
+
static OSStatus RemoveService( LPCTSTR inName )
|
|
451
|
+
{
|
|
452
|
+
OSStatus err;
|
|
453
|
+
SC_HANDLE scm;
|
|
454
|
+
SC_HANDLE service;
|
|
455
|
+
BOOL ok;
|
|
456
|
+
SERVICE_STATUS status;
|
|
457
|
+
|
|
458
|
+
scm = NULL;
|
|
459
|
+
service = NULL;
|
|
460
|
+
|
|
461
|
+
// Open a connection to the service.
|
|
462
|
+
|
|
463
|
+
scm = OpenSCManager( 0, 0, SC_MANAGER_ALL_ACCESS );
|
|
464
|
+
err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
|
|
465
|
+
require_noerr( err, exit );
|
|
466
|
+
|
|
467
|
+
service = OpenService( scm, inName, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE );
|
|
468
|
+
err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
|
|
469
|
+
require_noerr( err, exit );
|
|
470
|
+
|
|
471
|
+
// Stop the service, if it is not already stopped, then delete it.
|
|
472
|
+
|
|
473
|
+
ok = QueryServiceStatus( service, &status );
|
|
474
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
|
|
475
|
+
require_noerr( err, exit );
|
|
476
|
+
|
|
477
|
+
if( status.dwCurrentState != SERVICE_STOPPED )
|
|
478
|
+
{
|
|
479
|
+
ok = ControlService( service, SERVICE_CONTROL_STOP, &status );
|
|
480
|
+
check_translated_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
ok = DeleteService( service );
|
|
484
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kDeletedErr );
|
|
485
|
+
require_noerr( err, exit );
|
|
486
|
+
|
|
487
|
+
ReportStatus( EVENTLOG_SUCCESS, "Removed service\n" );
|
|
488
|
+
err = ERROR_SUCCESS;
|
|
489
|
+
|
|
490
|
+
exit:
|
|
491
|
+
if( service )
|
|
492
|
+
{
|
|
493
|
+
CloseServiceHandle( service );
|
|
494
|
+
}
|
|
495
|
+
if( scm )
|
|
496
|
+
{
|
|
497
|
+
CloseServiceHandle( scm );
|
|
498
|
+
}
|
|
499
|
+
return( err );
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
//===========================================================================================================================
|
|
505
|
+
// SetServiceParameters
|
|
506
|
+
//===========================================================================================================================
|
|
507
|
+
|
|
508
|
+
static OSStatus SetServiceParameters()
|
|
509
|
+
{
|
|
510
|
+
DWORD value;
|
|
511
|
+
DWORD valueLen = sizeof(DWORD);
|
|
512
|
+
DWORD type;
|
|
513
|
+
OSStatus err;
|
|
514
|
+
HKEY key;
|
|
515
|
+
|
|
516
|
+
key = NULL;
|
|
517
|
+
|
|
518
|
+
//
|
|
519
|
+
// Add/Open Parameters section under service entry in registry
|
|
520
|
+
//
|
|
521
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
|
|
522
|
+
require_noerr( err, exit );
|
|
523
|
+
|
|
524
|
+
//
|
|
525
|
+
// If the value isn't already there, then we create it
|
|
526
|
+
//
|
|
527
|
+
err = RegQueryValueEx(key, kServiceManageLLRouting, 0, &type, (LPBYTE) &value, &valueLen);
|
|
528
|
+
|
|
529
|
+
if (err != ERROR_SUCCESS)
|
|
530
|
+
{
|
|
531
|
+
value = 1;
|
|
532
|
+
|
|
533
|
+
err = RegSetValueEx( key, kServiceManageLLRouting, 0, REG_DWORD, (const LPBYTE) &value, sizeof(DWORD) );
|
|
534
|
+
require_noerr( err, exit );
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
exit:
|
|
538
|
+
|
|
539
|
+
if ( key )
|
|
540
|
+
{
|
|
541
|
+
RegCloseKey( key );
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
return( err );
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
//===========================================================================================================================
|
|
550
|
+
// GetServiceParameters
|
|
551
|
+
//===========================================================================================================================
|
|
552
|
+
|
|
553
|
+
static OSStatus GetServiceParameters()
|
|
554
|
+
{
|
|
555
|
+
DWORD value;
|
|
556
|
+
DWORD valueLen;
|
|
557
|
+
DWORD type;
|
|
558
|
+
OSStatus err;
|
|
559
|
+
HKEY key;
|
|
560
|
+
|
|
561
|
+
key = NULL;
|
|
562
|
+
|
|
563
|
+
//
|
|
564
|
+
// Add/Open Parameters section under service entry in registry
|
|
565
|
+
//
|
|
566
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
|
|
567
|
+
require_noerr( err, exit );
|
|
568
|
+
|
|
569
|
+
valueLen = sizeof(DWORD);
|
|
570
|
+
err = RegQueryValueEx(key, kServiceManageLLRouting, 0, &type, (LPBYTE) &value, &valueLen);
|
|
571
|
+
if (err == ERROR_SUCCESS)
|
|
572
|
+
{
|
|
573
|
+
gServiceManageLLRouting = (value) ? true : false;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
valueLen = sizeof(DWORD);
|
|
577
|
+
err = RegQueryValueEx(key, kServiceCacheEntryCount, 0, &type, (LPBYTE) &value, &valueLen);
|
|
578
|
+
if (err == ERROR_SUCCESS)
|
|
579
|
+
{
|
|
580
|
+
gServiceCacheEntryCount = value;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
exit:
|
|
584
|
+
|
|
585
|
+
if ( key )
|
|
586
|
+
{
|
|
587
|
+
RegCloseKey( key );
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
return( err );
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
//===========================================================================================================================
|
|
595
|
+
// CheckFirewall
|
|
596
|
+
//===========================================================================================================================
|
|
597
|
+
|
|
598
|
+
static OSStatus CheckFirewall()
|
|
599
|
+
{
|
|
600
|
+
DWORD value;
|
|
601
|
+
DWORD valueLen;
|
|
602
|
+
DWORD type;
|
|
603
|
+
ENUM_SERVICE_STATUS * lpService = NULL;
|
|
604
|
+
SC_HANDLE sc = NULL;
|
|
605
|
+
HKEY key = NULL;
|
|
606
|
+
BOOL ok;
|
|
607
|
+
DWORD bytesNeeded = 0;
|
|
608
|
+
DWORD srvCount;
|
|
609
|
+
DWORD resumeHandle = 0;
|
|
610
|
+
DWORD srvType;
|
|
611
|
+
DWORD srvState;
|
|
612
|
+
DWORD dwBytes = 0;
|
|
613
|
+
DWORD i;
|
|
614
|
+
BOOL isRunning = FALSE;
|
|
615
|
+
OSStatus err = kUnknownErr;
|
|
616
|
+
|
|
617
|
+
// Check to see if the firewall service is running. If it isn't, then
|
|
618
|
+
// we want to return immediately
|
|
619
|
+
|
|
620
|
+
sc = OpenSCManager( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE );
|
|
621
|
+
err = translate_errno( sc, GetLastError(), kUnknownErr );
|
|
622
|
+
require_noerr( err, exit );
|
|
623
|
+
|
|
624
|
+
srvType = SERVICE_WIN32;
|
|
625
|
+
srvState = SERVICE_STATE_ALL;
|
|
626
|
+
|
|
627
|
+
for ( ;; )
|
|
628
|
+
{
|
|
629
|
+
// Call EnumServicesStatus using the handle returned by OpenSCManager
|
|
630
|
+
|
|
631
|
+
ok = EnumServicesStatus ( sc, srvType, srvState, lpService, dwBytes, &bytesNeeded, &srvCount, &resumeHandle );
|
|
632
|
+
|
|
633
|
+
if ( ok || ( GetLastError() != ERROR_MORE_DATA ) )
|
|
634
|
+
{
|
|
635
|
+
break;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
if ( lpService )
|
|
639
|
+
{
|
|
640
|
+
free( lpService );
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
dwBytes = bytesNeeded;
|
|
644
|
+
|
|
645
|
+
lpService = ( ENUM_SERVICE_STATUS* ) malloc( dwBytes );
|
|
646
|
+
require_action( lpService, exit, err = mStatus_NoMemoryErr );
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
err = translate_errno( ok, GetLastError(), kUnknownErr );
|
|
650
|
+
require_noerr( err, exit );
|
|
651
|
+
|
|
652
|
+
for ( i = 0; i < srvCount; i++ )
|
|
653
|
+
{
|
|
654
|
+
if ( wcscmp( lpService[i].lpServiceName, L"SharedAccess" ) == 0 )
|
|
655
|
+
{
|
|
656
|
+
if ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_RUNNING )
|
|
657
|
+
{
|
|
658
|
+
isRunning = TRUE;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
require_action( isRunning, exit, err = kUnknownErr );
|
|
666
|
+
|
|
667
|
+
// Check to see if we've managed the firewall.
|
|
668
|
+
// This package might have been installed, then
|
|
669
|
+
// the OS was upgraded to SP2 or above. If that's
|
|
670
|
+
// the case, then we need to manipulate the firewall
|
|
671
|
+
// so networking works correctly.
|
|
672
|
+
|
|
673
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode, &key );
|
|
674
|
+
require_noerr( err, exit );
|
|
675
|
+
|
|
676
|
+
valueLen = sizeof(DWORD);
|
|
677
|
+
err = RegQueryValueEx(key, kServiceManageFirewall, 0, &type, (LPBYTE) &value, &valueLen);
|
|
678
|
+
|
|
679
|
+
if ((err != ERROR_SUCCESS) || (value == 0))
|
|
680
|
+
{
|
|
681
|
+
wchar_t fullPath[ MAX_PATH ];
|
|
682
|
+
DWORD size;
|
|
683
|
+
|
|
684
|
+
// Get a full path to the executable
|
|
685
|
+
|
|
686
|
+
size = GetModuleFileNameW( NULL, fullPath, MAX_PATH );
|
|
687
|
+
err = translate_errno( size > 0, (OSStatus) GetLastError(), kPathErr );
|
|
688
|
+
require_noerr( err, exit );
|
|
689
|
+
|
|
690
|
+
err = mDNSAddToFirewall(fullPath, kServiceFirewallName);
|
|
691
|
+
require_noerr( err, exit );
|
|
692
|
+
|
|
693
|
+
value = 1;
|
|
694
|
+
err = RegSetValueEx( key, kServiceManageFirewall, 0, REG_DWORD, (const LPBYTE) &value, sizeof( DWORD ) );
|
|
695
|
+
require_noerr( err, exit );
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
exit:
|
|
699
|
+
|
|
700
|
+
if ( key )
|
|
701
|
+
{
|
|
702
|
+
RegCloseKey( key );
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
if ( lpService )
|
|
706
|
+
{
|
|
707
|
+
free( lpService );
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
if ( sc )
|
|
711
|
+
{
|
|
712
|
+
CloseServiceHandle ( sc );
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
return( err );
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
//===========================================================================================================================
|
|
721
|
+
// SetServiceInfo
|
|
722
|
+
//===========================================================================================================================
|
|
723
|
+
|
|
724
|
+
static OSStatus SetServiceInfo( SC_HANDLE inSCM, LPCTSTR inServiceName, LPCTSTR inDescription )
|
|
725
|
+
{
|
|
726
|
+
OSStatus err;
|
|
727
|
+
SC_LOCK lock;
|
|
728
|
+
SC_HANDLE service;
|
|
729
|
+
SERVICE_DESCRIPTION description;
|
|
730
|
+
SERVICE_FAILURE_ACTIONS actions;
|
|
731
|
+
SC_ACTION action;
|
|
732
|
+
BOOL ok;
|
|
733
|
+
|
|
734
|
+
check( inServiceName );
|
|
735
|
+
check( inDescription );
|
|
736
|
+
|
|
737
|
+
lock = NULL;
|
|
738
|
+
service = NULL;
|
|
739
|
+
|
|
740
|
+
// Open the database (if not provided) and lock it to prevent other access while re-configuring.
|
|
741
|
+
|
|
742
|
+
if( !inSCM )
|
|
743
|
+
{
|
|
744
|
+
inSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
|
|
745
|
+
err = translate_errno( inSCM, (OSStatus) GetLastError(), kOpenErr );
|
|
746
|
+
require_noerr( err, exit );
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
lock = LockServiceDatabase( inSCM );
|
|
750
|
+
err = translate_errno( lock, (OSStatus) GetLastError(), kInUseErr );
|
|
751
|
+
require_noerr( err, exit );
|
|
752
|
+
|
|
753
|
+
// Open a handle to the service.
|
|
754
|
+
|
|
755
|
+
service = OpenService( inSCM, inServiceName, SERVICE_CHANGE_CONFIG|SERVICE_START );
|
|
756
|
+
err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
|
|
757
|
+
require_noerr( err, exit );
|
|
758
|
+
|
|
759
|
+
// Change the description.
|
|
760
|
+
|
|
761
|
+
description.lpDescription = (LPTSTR) inDescription;
|
|
762
|
+
ok = ChangeServiceConfig2( service, SERVICE_CONFIG_DESCRIPTION, &description );
|
|
763
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kParamErr );
|
|
764
|
+
require_noerr( err, exit );
|
|
765
|
+
|
|
766
|
+
actions.dwResetPeriod = INFINITE;
|
|
767
|
+
actions.lpRebootMsg = NULL;
|
|
768
|
+
actions.lpCommand = NULL;
|
|
769
|
+
actions.cActions = 1;
|
|
770
|
+
actions.lpsaActions = &action;
|
|
771
|
+
action.Delay = 500;
|
|
772
|
+
action.Type = SC_ACTION_RESTART;
|
|
773
|
+
|
|
774
|
+
ok = ChangeServiceConfig2( service, SERVICE_CONFIG_FAILURE_ACTIONS, &actions );
|
|
775
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kParamErr );
|
|
776
|
+
require_noerr( err, exit );
|
|
777
|
+
|
|
778
|
+
err = ERROR_SUCCESS;
|
|
779
|
+
|
|
780
|
+
exit:
|
|
781
|
+
// Close the service and release the lock.
|
|
782
|
+
|
|
783
|
+
if( service )
|
|
784
|
+
{
|
|
785
|
+
CloseServiceHandle( service );
|
|
786
|
+
}
|
|
787
|
+
if( lock )
|
|
788
|
+
{
|
|
789
|
+
UnlockServiceDatabase( lock );
|
|
790
|
+
}
|
|
791
|
+
return( err );
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
//===========================================================================================================================
|
|
795
|
+
// ReportStatus
|
|
796
|
+
//===========================================================================================================================
|
|
797
|
+
|
|
798
|
+
static void ReportStatus( int inType, const char *inFormat, ... )
|
|
799
|
+
{
|
|
800
|
+
if( !gServiceQuietMode )
|
|
801
|
+
{
|
|
802
|
+
va_list args;
|
|
803
|
+
|
|
804
|
+
va_start( args, inFormat );
|
|
805
|
+
if( gServiceEventSource )
|
|
806
|
+
{
|
|
807
|
+
char s[ 1024 ];
|
|
808
|
+
BOOL ok;
|
|
809
|
+
const char * array[ 1 ];
|
|
810
|
+
|
|
811
|
+
vsprintf( s, inFormat, args );
|
|
812
|
+
array[ 0 ] = s;
|
|
813
|
+
ok = ReportEventA( gServiceEventSource, (WORD) inType, 0, MDNSRESPONDER_LOG, NULL, 1, 0, array, NULL );
|
|
814
|
+
check_translated_errno( ok, GetLastError(), kUnknownErr );
|
|
815
|
+
}
|
|
816
|
+
else
|
|
817
|
+
{
|
|
818
|
+
int n;
|
|
819
|
+
|
|
820
|
+
n = vfprintf( stderr, inFormat, args );
|
|
821
|
+
check( n >= 0 );
|
|
822
|
+
}
|
|
823
|
+
va_end( args );
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
//===========================================================================================================================
|
|
828
|
+
// RunDirect
|
|
829
|
+
//===========================================================================================================================
|
|
830
|
+
|
|
831
|
+
int RunDirect( int argc, LPTSTR argv[] )
|
|
832
|
+
{
|
|
833
|
+
OSStatus err;
|
|
834
|
+
BOOL initialized;
|
|
835
|
+
BOOL ok;
|
|
836
|
+
|
|
837
|
+
initialized = FALSE;
|
|
838
|
+
|
|
839
|
+
// Install a Console Control Handler to handle things like control-c signals.
|
|
840
|
+
|
|
841
|
+
ok = SetConsoleCtrlHandler( ConsoleControlHandler, TRUE );
|
|
842
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
|
|
843
|
+
require_noerr( err, exit );
|
|
844
|
+
|
|
845
|
+
err = ServiceSpecificInitialize( argc, argv );
|
|
846
|
+
require_noerr( err, exit );
|
|
847
|
+
initialized = TRUE;
|
|
848
|
+
|
|
849
|
+
// Run the service. This does not return until the service quits or is stopped.
|
|
850
|
+
|
|
851
|
+
ReportStatus( EVENTLOG_INFORMATION_TYPE, "Running service directly\n" );
|
|
852
|
+
|
|
853
|
+
err = ServiceSpecificRun( argc, argv );
|
|
854
|
+
require_noerr( err, exit );
|
|
855
|
+
|
|
856
|
+
// Clean up.
|
|
857
|
+
|
|
858
|
+
exit:
|
|
859
|
+
if( initialized )
|
|
860
|
+
{
|
|
861
|
+
ServiceSpecificFinalize( argc, argv );
|
|
862
|
+
}
|
|
863
|
+
return( err );
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
#if 0
|
|
867
|
+
#pragma mark -
|
|
868
|
+
#endif
|
|
869
|
+
|
|
870
|
+
//===========================================================================================================================
|
|
871
|
+
// ServiceMain
|
|
872
|
+
//===========================================================================================================================
|
|
873
|
+
|
|
874
|
+
static void WINAPI ServiceMain( DWORD argc, LPTSTR argv[] )
|
|
875
|
+
{
|
|
876
|
+
OSStatus err;
|
|
877
|
+
BOOL ok;
|
|
878
|
+
|
|
879
|
+
err = ServiceSetupEventLogging();
|
|
880
|
+
check_noerr( err );
|
|
881
|
+
|
|
882
|
+
err = GetServiceParameters();
|
|
883
|
+
check_noerr( err );
|
|
884
|
+
|
|
885
|
+
// Initialize the service status and register the service control handler with the name of the service.
|
|
886
|
+
|
|
887
|
+
gServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
|
|
888
|
+
gServiceStatus.dwCurrentState = 0;
|
|
889
|
+
gServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_POWEREVENT;
|
|
890
|
+
gServiceStatus.dwWin32ExitCode = NO_ERROR;
|
|
891
|
+
gServiceStatus.dwServiceSpecificExitCode = NO_ERROR;
|
|
892
|
+
gServiceStatus.dwCheckPoint = 0;
|
|
893
|
+
gServiceStatus.dwWaitHint = 0;
|
|
894
|
+
|
|
895
|
+
gServiceStatusHandle = RegisterServiceCtrlHandlerEx( argv[ 0 ], ServiceControlHandler, NULL );
|
|
896
|
+
err = translate_errno( gServiceStatusHandle, (OSStatus) GetLastError(), kInUseErr );
|
|
897
|
+
require_noerr( err, exit );
|
|
898
|
+
|
|
899
|
+
// Mark the service as starting.
|
|
900
|
+
|
|
901
|
+
gServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
|
902
|
+
gServiceStatus.dwCheckPoint = 0;
|
|
903
|
+
gServiceStatus.dwWaitHint = 5000; // 5 seconds
|
|
904
|
+
ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
|
|
905
|
+
check_translated_errno( ok, GetLastError(), kParamErr );
|
|
906
|
+
|
|
907
|
+
// Run the service. This does not return until the service quits or is stopped.
|
|
908
|
+
|
|
909
|
+
err = ServiceRun( (int) argc, argv );
|
|
910
|
+
if( err != kNoErr )
|
|
911
|
+
{
|
|
912
|
+
gServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
|
|
913
|
+
gServiceStatus.dwServiceSpecificExitCode = (DWORD) err;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
// Service-specific work is done so mark the service as stopped.
|
|
917
|
+
|
|
918
|
+
gServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
|
919
|
+
ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
|
|
920
|
+
check_translated_errno( ok, GetLastError(), kParamErr );
|
|
921
|
+
|
|
922
|
+
// Note: The service status handle should not be closed according to Microsoft documentation.
|
|
923
|
+
|
|
924
|
+
exit:
|
|
925
|
+
if( gServiceEventSource )
|
|
926
|
+
{
|
|
927
|
+
ok = DeregisterEventSource( gServiceEventSource );
|
|
928
|
+
check_translated_errno( ok, GetLastError(), kUnknownErr );
|
|
929
|
+
gServiceEventSource = NULL;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
//===========================================================================================================================
|
|
934
|
+
// ServiceSetupEventLogging
|
|
935
|
+
//===========================================================================================================================
|
|
936
|
+
|
|
937
|
+
static OSStatus ServiceSetupEventLogging( void )
|
|
938
|
+
{
|
|
939
|
+
OSStatus err;
|
|
940
|
+
HKEY key;
|
|
941
|
+
LPCTSTR s;
|
|
942
|
+
DWORD typesSupported;
|
|
943
|
+
TCHAR path[ MAX_PATH ];
|
|
944
|
+
DWORD n;
|
|
945
|
+
|
|
946
|
+
key = NULL;
|
|
947
|
+
|
|
948
|
+
// Add/Open source name as a sub-key under the Application key in the EventLog registry key.
|
|
949
|
+
|
|
950
|
+
s = TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\") kServiceName;
|
|
951
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, s, &key );
|
|
952
|
+
require_noerr( err, exit );
|
|
953
|
+
|
|
954
|
+
// Add the name to the EventMessageFile subkey.
|
|
955
|
+
|
|
956
|
+
path[ 0 ] = '\0';
|
|
957
|
+
GetModuleFileName( NULL, path, MAX_PATH );
|
|
958
|
+
n = (DWORD) ( ( StrLen( path ) + 1 ) * sizeof( TCHAR ) );
|
|
959
|
+
err = RegSetValueEx( key, TEXT("EventMessageFile"), 0, REG_EXPAND_SZ, (const LPBYTE) path, n );
|
|
960
|
+
require_noerr( err, exit );
|
|
961
|
+
|
|
962
|
+
// Set the supported event types in the TypesSupported subkey.
|
|
963
|
+
|
|
964
|
+
typesSupported = 0
|
|
965
|
+
| EVENTLOG_SUCCESS
|
|
966
|
+
| EVENTLOG_ERROR_TYPE
|
|
967
|
+
| EVENTLOG_WARNING_TYPE
|
|
968
|
+
| EVENTLOG_INFORMATION_TYPE
|
|
969
|
+
| EVENTLOG_AUDIT_SUCCESS
|
|
970
|
+
| EVENTLOG_AUDIT_FAILURE;
|
|
971
|
+
err = RegSetValueEx( key, TEXT("TypesSupported"), 0, REG_DWORD, (const LPBYTE) &typesSupported, sizeof( DWORD ) );
|
|
972
|
+
require_noerr( err, exit );
|
|
973
|
+
|
|
974
|
+
// Set up the event source.
|
|
975
|
+
|
|
976
|
+
gServiceEventSource = RegisterEventSource( NULL, kServiceName );
|
|
977
|
+
err = translate_errno( gServiceEventSource, (OSStatus) GetLastError(), kParamErr );
|
|
978
|
+
require_noerr( err, exit );
|
|
979
|
+
|
|
980
|
+
exit:
|
|
981
|
+
if( key )
|
|
982
|
+
{
|
|
983
|
+
RegCloseKey( key );
|
|
984
|
+
}
|
|
985
|
+
return( err );
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
//===========================================================================================================================
|
|
989
|
+
// HandlePowerSuspend
|
|
990
|
+
//===========================================================================================================================
|
|
991
|
+
|
|
992
|
+
static void HandlePowerSuspend( void * v )
|
|
993
|
+
{
|
|
994
|
+
LARGE_INTEGER timeout;
|
|
995
|
+
BOOL ok;
|
|
996
|
+
|
|
997
|
+
( void ) v;
|
|
998
|
+
|
|
999
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "HandlePowerSuspend\n" );
|
|
1000
|
+
|
|
1001
|
+
gMDNSRecord.SystemWakeOnLANEnabled = SystemWakeForNetworkAccess( &timeout );
|
|
1002
|
+
|
|
1003
|
+
if ( gMDNSRecord.SystemWakeOnLANEnabled )
|
|
1004
|
+
{
|
|
1005
|
+
ok = SetWaitableTimer( gSPSWakeupEvent, &timeout, 0, NULL, NULL, TRUE );
|
|
1006
|
+
check( ok );
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
mDNSCoreMachineSleep(&gMDNSRecord, TRUE);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
//===========================================================================================================================
|
|
1014
|
+
// HandlePowerResumeSuspend
|
|
1015
|
+
//===========================================================================================================================
|
|
1016
|
+
|
|
1017
|
+
static void HandlePowerResumeSuspend( void * v )
|
|
1018
|
+
{
|
|
1019
|
+
( void ) v;
|
|
1020
|
+
|
|
1021
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "HandlePowerResumeSuspend\n" );
|
|
1022
|
+
|
|
1023
|
+
if ( gSPSWakeupEvent )
|
|
1024
|
+
{
|
|
1025
|
+
CancelWaitableTimer( gSPSWakeupEvent );
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
if ( gSPSSleepEvent )
|
|
1029
|
+
{
|
|
1030
|
+
CancelWaitableTimer( gSPSSleepEvent );
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
mDNSCoreMachineSleep(&gMDNSRecord, FALSE);
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
//===========================================================================================================================
|
|
1038
|
+
// ServiceControlHandler
|
|
1039
|
+
//===========================================================================================================================
|
|
1040
|
+
|
|
1041
|
+
static DWORD WINAPI ServiceControlHandler( DWORD inControl, DWORD inEventType, LPVOID inEventData, LPVOID inContext )
|
|
1042
|
+
{
|
|
1043
|
+
BOOL setStatus;
|
|
1044
|
+
BOOL ok;
|
|
1045
|
+
|
|
1046
|
+
DEBUG_UNUSED( inEventData );
|
|
1047
|
+
DEBUG_UNUSED( inContext );
|
|
1048
|
+
|
|
1049
|
+
setStatus = TRUE;
|
|
1050
|
+
switch( inControl )
|
|
1051
|
+
{
|
|
1052
|
+
case SERVICE_CONTROL_STOP:
|
|
1053
|
+
case SERVICE_CONTROL_SHUTDOWN:
|
|
1054
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: SERVICE_CONTROL_STOP|SERVICE_CONTROL_SHUTDOWN\n" );
|
|
1055
|
+
|
|
1056
|
+
ServiceStop();
|
|
1057
|
+
setStatus = FALSE;
|
|
1058
|
+
break;
|
|
1059
|
+
|
|
1060
|
+
case SERVICE_CONTROL_POWEREVENT:
|
|
1061
|
+
|
|
1062
|
+
if (inEventType == PBT_APMSUSPEND)
|
|
1063
|
+
{
|
|
1064
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMSUSPEND\n" );
|
|
1065
|
+
|
|
1066
|
+
QueueUserAPC( ( PAPCFUNC ) HandlePowerSuspend, gMDNSRecord.p->mainThread, ( ULONG_PTR ) NULL );
|
|
1067
|
+
}
|
|
1068
|
+
else if (inEventType == PBT_APMRESUMESUSPEND)
|
|
1069
|
+
{
|
|
1070
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "ServiceControlHandler: PBT_APMRESUMESUSPEND\n" );
|
|
1071
|
+
|
|
1072
|
+
QueueUserAPC( ( PAPCFUNC ) HandlePowerResumeSuspend, gMDNSRecord.p->mainThread, ( ULONG_PTR ) NULL );
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
break;
|
|
1076
|
+
|
|
1077
|
+
default:
|
|
1078
|
+
dlog( kDebugLevelNotice, DEBUG_NAME "ServiceControlHandler: event (0x%08X)\n", inControl );
|
|
1079
|
+
break;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
if( setStatus && gServiceStatusHandle )
|
|
1083
|
+
{
|
|
1084
|
+
ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
|
|
1085
|
+
check_translated_errno( ok, GetLastError(), kUnknownErr );
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
return NO_ERROR;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
//===========================================================================================================================
|
|
1092
|
+
// ServiceRun
|
|
1093
|
+
//===========================================================================================================================
|
|
1094
|
+
|
|
1095
|
+
static OSStatus ServiceRun( int argc, LPTSTR argv[] )
|
|
1096
|
+
{
|
|
1097
|
+
OSStatus err;
|
|
1098
|
+
BOOL initialized;
|
|
1099
|
+
BOOL ok;
|
|
1100
|
+
|
|
1101
|
+
DEBUG_UNUSED( argc );
|
|
1102
|
+
DEBUG_UNUSED( argv );
|
|
1103
|
+
|
|
1104
|
+
initialized = FALSE;
|
|
1105
|
+
|
|
1106
|
+
// <rdar://problem/5727548> Make the service as running before we call ServiceSpecificInitialize. We've
|
|
1107
|
+
// had reports that some machines with McAfee firewall installed cause a problem with iTunes installation.
|
|
1108
|
+
// We think that the firewall product is interferring with code in ServiceSpecificInitialize. So as a
|
|
1109
|
+
// simple workaround, we'll mark us as running *before* we call ServiceSpecificInitialize. This will unblock
|
|
1110
|
+
// any installers that are waiting for our state to change.
|
|
1111
|
+
|
|
1112
|
+
gServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
|
1113
|
+
ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
|
|
1114
|
+
check_translated_errno( ok, GetLastError(), kParamErr );
|
|
1115
|
+
|
|
1116
|
+
// Initialize the service-specific stuff
|
|
1117
|
+
|
|
1118
|
+
err = ServiceSpecificInitialize( argc, argv );
|
|
1119
|
+
require_noerr( err, exit );
|
|
1120
|
+
initialized = TRUE;
|
|
1121
|
+
|
|
1122
|
+
err = CheckFirewall();
|
|
1123
|
+
check_noerr( err );
|
|
1124
|
+
|
|
1125
|
+
if ( err )
|
|
1126
|
+
{
|
|
1127
|
+
gRetryFirewall = TRUE;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
// Run the service-specific stuff. This does not return until the service quits or is stopped.
|
|
1131
|
+
|
|
1132
|
+
ReportStatus( EVENTLOG_INFORMATION_TYPE, "Service started\n" );
|
|
1133
|
+
err = ServiceSpecificRun( argc, argv );
|
|
1134
|
+
ReportStatus( EVENTLOG_INFORMATION_TYPE, "Service stopped (%d)\n", err );
|
|
1135
|
+
require_noerr( err, exit );
|
|
1136
|
+
|
|
1137
|
+
// Service stopped. Clean up and we're done.
|
|
1138
|
+
|
|
1139
|
+
exit:
|
|
1140
|
+
if( initialized )
|
|
1141
|
+
{
|
|
1142
|
+
ServiceSpecificFinalize( argc, argv );
|
|
1143
|
+
}
|
|
1144
|
+
return( err );
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
//===========================================================================================================================
|
|
1148
|
+
// ServiceStop
|
|
1149
|
+
//===========================================================================================================================
|
|
1150
|
+
|
|
1151
|
+
static void ServiceStop( void )
|
|
1152
|
+
{
|
|
1153
|
+
BOOL ok;
|
|
1154
|
+
OSStatus err;
|
|
1155
|
+
|
|
1156
|
+
// Signal the event to cause the service to exit.
|
|
1157
|
+
|
|
1158
|
+
if( gServiceStatusHandle )
|
|
1159
|
+
{
|
|
1160
|
+
gServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
|
1161
|
+
ok = SetServiceStatus( gServiceStatusHandle, &gServiceStatus );
|
|
1162
|
+
check_translated_errno( ok, GetLastError(), kParamErr );
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
err = ServiceSpecificStop();
|
|
1166
|
+
check_noerr( err );
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
#if 0
|
|
1170
|
+
#pragma mark -
|
|
1171
|
+
#pragma mark == Service Specific ==
|
|
1172
|
+
#endif
|
|
1173
|
+
|
|
1174
|
+
//===========================================================================================================================
|
|
1175
|
+
// ServiceSpecificInitialize
|
|
1176
|
+
//===========================================================================================================================
|
|
1177
|
+
|
|
1178
|
+
static OSStatus ServiceSpecificInitialize( int argc, LPTSTR argv[] )
|
|
1179
|
+
{
|
|
1180
|
+
OSVERSIONINFO osInfo;
|
|
1181
|
+
OSStatus err;
|
|
1182
|
+
BOOL ok;
|
|
1183
|
+
|
|
1184
|
+
DEBUG_UNUSED( argc );
|
|
1185
|
+
DEBUG_UNUSED( argv );
|
|
1186
|
+
|
|
1187
|
+
mDNSPlatformMemZero( &gMDNSRecord, sizeof gMDNSRecord);
|
|
1188
|
+
mDNSPlatformMemZero( &gPlatformStorage, sizeof gPlatformStorage);
|
|
1189
|
+
|
|
1190
|
+
gPlatformStorage.registerWaitableEventFunc = RegisterWaitableEvent;
|
|
1191
|
+
gPlatformStorage.unregisterWaitableEventFunc = UnregisterWaitableEvent;
|
|
1192
|
+
gPlatformStorage.reportStatusFunc = ReportStatus;
|
|
1193
|
+
|
|
1194
|
+
err = mDNS_Init( &gMDNSRecord, &gPlatformStorage, gRRCache, RR_CACHE_SIZE, mDNS_Init_AdvertiseLocalAddresses, CoreCallback, mDNS_Init_NoInitCallbackContext);
|
|
1195
|
+
require_noerr( err, exit);
|
|
1196
|
+
|
|
1197
|
+
err = SetupNotifications();
|
|
1198
|
+
check_noerr( err );
|
|
1199
|
+
|
|
1200
|
+
err = udsserver_init(mDNSNULL, 0);
|
|
1201
|
+
require_noerr( err, exit);
|
|
1202
|
+
|
|
1203
|
+
//
|
|
1204
|
+
// Get the version of Windows that we're running on
|
|
1205
|
+
//
|
|
1206
|
+
osInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
|
|
1207
|
+
ok = GetVersionEx( &osInfo );
|
|
1208
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
|
|
1209
|
+
require_noerr( err, exit );
|
|
1210
|
+
gOSMajorVersion = osInfo.dwMajorVersion;
|
|
1211
|
+
gOSMinorVersion = osInfo.dwMinorVersion;
|
|
1212
|
+
|
|
1213
|
+
SetLLRoute( &gMDNSRecord );
|
|
1214
|
+
|
|
1215
|
+
exit:
|
|
1216
|
+
if( err != kNoErr )
|
|
1217
|
+
{
|
|
1218
|
+
ServiceSpecificFinalize( argc, argv );
|
|
1219
|
+
}
|
|
1220
|
+
return( err );
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
//===========================================================================================================================
|
|
1224
|
+
// ServiceSpecificRun
|
|
1225
|
+
//===========================================================================================================================
|
|
1226
|
+
|
|
1227
|
+
static OSStatus ServiceSpecificRun( int argc, LPTSTR argv[] )
|
|
1228
|
+
{
|
|
1229
|
+
HANDLE * waitList;
|
|
1230
|
+
int waitListCount;
|
|
1231
|
+
DWORD timeout;
|
|
1232
|
+
DWORD result;
|
|
1233
|
+
BOOL done;
|
|
1234
|
+
mStatus err;
|
|
1235
|
+
|
|
1236
|
+
DEBUG_UNUSED( argc );
|
|
1237
|
+
DEBUG_UNUSED( argv );
|
|
1238
|
+
|
|
1239
|
+
timeout = ( gRetryFirewall ) ? kRetryFirewallPeriod : INFINITE;
|
|
1240
|
+
|
|
1241
|
+
err = SetupInterfaceList( &gMDNSRecord );
|
|
1242
|
+
check( !err );
|
|
1243
|
+
|
|
1244
|
+
err = uDNS_SetupDNSConfig( &gMDNSRecord );
|
|
1245
|
+
check( !err );
|
|
1246
|
+
|
|
1247
|
+
done = FALSE;
|
|
1248
|
+
|
|
1249
|
+
// Main event loop.
|
|
1250
|
+
|
|
1251
|
+
while( !done )
|
|
1252
|
+
{
|
|
1253
|
+
waitList = NULL;
|
|
1254
|
+
waitListCount = 0;
|
|
1255
|
+
|
|
1256
|
+
err = SetupWaitList( &gMDNSRecord, &waitList, &waitListCount );
|
|
1257
|
+
require_noerr( err, exit );
|
|
1258
|
+
|
|
1259
|
+
gEventSourceListChanged = FALSE;
|
|
1260
|
+
|
|
1261
|
+
while ( !gEventSourceListChanged )
|
|
1262
|
+
{
|
|
1263
|
+
static mDNSs32 RepeatedBusy = 0;
|
|
1264
|
+
mDNSs32 nextTimerEvent;
|
|
1265
|
+
|
|
1266
|
+
// Give the mDNS core a chance to do its work and determine next event time.
|
|
1267
|
+
|
|
1268
|
+
nextTimerEvent = udsserver_idle( mDNS_Execute( &gMDNSRecord ) - mDNS_TimeNow( &gMDNSRecord ) );
|
|
1269
|
+
|
|
1270
|
+
if ( nextTimerEvent < 0) nextTimerEvent = 0;
|
|
1271
|
+
else if ( nextTimerEvent > (0x7FFFFFFF / 1000)) nextTimerEvent = 0x7FFFFFFF / mDNSPlatformOneSecond;
|
|
1272
|
+
else nextTimerEvent = ( nextTimerEvent * 1000) / mDNSPlatformOneSecond;
|
|
1273
|
+
|
|
1274
|
+
// Debugging sanity check, to guard against CPU spins
|
|
1275
|
+
|
|
1276
|
+
if ( nextTimerEvent > 0 )
|
|
1277
|
+
{
|
|
1278
|
+
RepeatedBusy = 0;
|
|
1279
|
+
}
|
|
1280
|
+
else
|
|
1281
|
+
{
|
|
1282
|
+
nextTimerEvent = 1;
|
|
1283
|
+
|
|
1284
|
+
if ( ++RepeatedBusy >= mDNSPlatformOneSecond )
|
|
1285
|
+
{
|
|
1286
|
+
ShowTaskSchedulingError( &gMDNSRecord );
|
|
1287
|
+
RepeatedBusy = 0;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
if ( gMDNSRecord.ShutdownTime )
|
|
1292
|
+
{
|
|
1293
|
+
mDNSs32 now = mDNS_TimeNow( &gMDNSRecord );
|
|
1294
|
+
|
|
1295
|
+
if ( mDNS_ExitNow( &gMDNSRecord, now ) )
|
|
1296
|
+
{
|
|
1297
|
+
mDNS_FinalExit( &gMDNSRecord );
|
|
1298
|
+
done = TRUE;
|
|
1299
|
+
break;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
if ( nextTimerEvent - gMDNSRecord.ShutdownTime >= 0 )
|
|
1303
|
+
{
|
|
1304
|
+
nextTimerEvent = gMDNSRecord.ShutdownTime;
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
// Wait until something occurs (e.g. cancel, incoming packet, or timeout).
|
|
1309
|
+
//
|
|
1310
|
+
// Note: There seems to be a bug in WinSock with respect to Alertable I/O. According
|
|
1311
|
+
// to MSDN <http://msdn.microsoft.com/en-us/library/aa363772(VS.85).aspx>, Alertable I/O
|
|
1312
|
+
// callbacks will only be invoked during the following calls (when the caller sets
|
|
1313
|
+
// the appropriate flag):
|
|
1314
|
+
//
|
|
1315
|
+
// - SleepEx
|
|
1316
|
+
// - WaitForSingleObjectEx
|
|
1317
|
+
// - WaitForMultipleObjectsEx
|
|
1318
|
+
// - SignalObjectAndWait
|
|
1319
|
+
// - MsgWaitForMultipleObjectsEx
|
|
1320
|
+
//
|
|
1321
|
+
// However, we have seen callbacks be invoked during calls to bind() (and maybe others). If there
|
|
1322
|
+
// weren't a bug, then socket events would only be queued during the call to WaitForMultipleObjects() and
|
|
1323
|
+
// we'd only have to check them once afterwards. However since that doesn't seem to be the case, we'll
|
|
1324
|
+
// check the queue both before we call WaitForMultipleObjects() and after.
|
|
1325
|
+
|
|
1326
|
+
DispatchSocketEvents( &gMDNSRecord );
|
|
1327
|
+
result = WaitForMultipleObjectsEx( ( DWORD ) waitListCount, waitList, FALSE, (DWORD) nextTimerEvent, TRUE );
|
|
1328
|
+
check( result != WAIT_FAILED );
|
|
1329
|
+
DispatchSocketEvents( &gMDNSRecord );
|
|
1330
|
+
|
|
1331
|
+
if ( result != WAIT_FAILED )
|
|
1332
|
+
{
|
|
1333
|
+
if ( result == WAIT_TIMEOUT )
|
|
1334
|
+
{
|
|
1335
|
+
// Next task timeout occurred. Loop back up to give mDNS core a chance to work.
|
|
1336
|
+
|
|
1337
|
+
dlog( kDebugLevelChatty - 1, DEBUG_NAME "timeout\n" );
|
|
1338
|
+
continue;
|
|
1339
|
+
}
|
|
1340
|
+
else if ( result == WAIT_IO_COMPLETION )
|
|
1341
|
+
{
|
|
1342
|
+
dlog( kDebugLevelChatty - 1, DEBUG_NAME "i/o completion\n" );
|
|
1343
|
+
continue;
|
|
1344
|
+
}
|
|
1345
|
+
else if ( result == kWaitListStopEvent )
|
|
1346
|
+
{
|
|
1347
|
+
// Stop event. Set the done flag and break to exit.
|
|
1348
|
+
|
|
1349
|
+
dlog( kDebugLevelVerbose, DEBUG_NAME "stopping...\n" );
|
|
1350
|
+
udsserver_exit();
|
|
1351
|
+
mDNS_StartExit( &gMDNSRecord );
|
|
1352
|
+
break;
|
|
1353
|
+
}
|
|
1354
|
+
else if( result == kWaitListInterfaceListChangedEvent )
|
|
1355
|
+
{
|
|
1356
|
+
int inBuffer;
|
|
1357
|
+
int outBuffer;
|
|
1358
|
+
DWORD outSize;
|
|
1359
|
+
|
|
1360
|
+
// It would be nice to come up with a more elegant solution to this, but it seems that
|
|
1361
|
+
// GetAdaptersAddresses doesn't always stay in sync after network changed events. So as
|
|
1362
|
+
// as a simple workaround, we'll pause for a couple of seconds before processing the change.
|
|
1363
|
+
|
|
1364
|
+
// We arrived at 2 secs by trial and error. We could reproduce the problem after sleeping
|
|
1365
|
+
// for 500 msec and 750 msec, but couldn't after sleeping for 1 sec. We added another
|
|
1366
|
+
// second on top of that to account for machine load or some other exigency.
|
|
1367
|
+
|
|
1368
|
+
Sleep( 2000 );
|
|
1369
|
+
|
|
1370
|
+
// Interface list changed event. Break out of the inner loop to re-setup the wait list.
|
|
1371
|
+
|
|
1372
|
+
InterfaceListDidChange( &gMDNSRecord );
|
|
1373
|
+
|
|
1374
|
+
// reset the event handler
|
|
1375
|
+
inBuffer = 0;
|
|
1376
|
+
outBuffer = 0;
|
|
1377
|
+
err = WSAIoctl( gInterfaceListChangedSocket, SIO_ADDRESS_LIST_CHANGE, &inBuffer, 0, &outBuffer, 0, &outSize, NULL, NULL );
|
|
1378
|
+
if( err < 0 )
|
|
1379
|
+
{
|
|
1380
|
+
check( errno_compat() == WSAEWOULDBLOCK );
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
else if ( result == kWaitListComputerDescriptionEvent )
|
|
1384
|
+
{
|
|
1385
|
+
// The computer description might have changed
|
|
1386
|
+
|
|
1387
|
+
ComputerDescriptionDidChange( &gMDNSRecord );
|
|
1388
|
+
udsserver_handle_configchange( &gMDNSRecord );
|
|
1389
|
+
|
|
1390
|
+
// and reset the event handler
|
|
1391
|
+
if ( ( gDescKey != NULL ) && ( gDescChangedEvent != NULL ) )
|
|
1392
|
+
{
|
|
1393
|
+
err = RegNotifyChangeKeyValue( gDescKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, gDescChangedEvent, TRUE);
|
|
1394
|
+
check_noerr( err );
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
else if ( result == kWaitListTCPIPEvent )
|
|
1398
|
+
{
|
|
1399
|
+
// The TCP/IP might have changed
|
|
1400
|
+
|
|
1401
|
+
TCPIPConfigDidChange( &gMDNSRecord );
|
|
1402
|
+
udsserver_handle_configchange( &gMDNSRecord );
|
|
1403
|
+
|
|
1404
|
+
// and reset the event handler
|
|
1405
|
+
|
|
1406
|
+
if ( ( gTcpipKey != NULL ) && ( gTcpipChangedEvent ) )
|
|
1407
|
+
{
|
|
1408
|
+
err = RegNotifyChangeKeyValue( gTcpipKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gTcpipChangedEvent, TRUE );
|
|
1409
|
+
check_noerr( err );
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
else if ( result == kWaitListDynDNSEvent )
|
|
1413
|
+
{
|
|
1414
|
+
// The DynDNS config might have changed
|
|
1415
|
+
|
|
1416
|
+
DynDNSConfigDidChange( &gMDNSRecord );
|
|
1417
|
+
udsserver_handle_configchange( &gMDNSRecord );
|
|
1418
|
+
|
|
1419
|
+
// and reset the event handler
|
|
1420
|
+
|
|
1421
|
+
if ((gDdnsKey != NULL) && (gDdnsChangedEvent))
|
|
1422
|
+
{
|
|
1423
|
+
err = RegNotifyChangeKeyValue(gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
|
|
1424
|
+
check_noerr( err );
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
else if ( result == kWaitListFileShareEvent )
|
|
1428
|
+
{
|
|
1429
|
+
// File sharing changed
|
|
1430
|
+
|
|
1431
|
+
FileSharingDidChange( &gMDNSRecord );
|
|
1432
|
+
|
|
1433
|
+
// and reset the event handler
|
|
1434
|
+
|
|
1435
|
+
if ((gFileSharingKey != NULL) && (gFileSharingChangedEvent))
|
|
1436
|
+
{
|
|
1437
|
+
err = RegNotifyChangeKeyValue(gFileSharingKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFileSharingChangedEvent, TRUE);
|
|
1438
|
+
check_noerr( err );
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
else if ( result == kWaitListFirewallEvent )
|
|
1442
|
+
{
|
|
1443
|
+
// Firewall configuration changed
|
|
1444
|
+
|
|
1445
|
+
FirewallDidChange( &gMDNSRecord );
|
|
1446
|
+
|
|
1447
|
+
// and reset the event handler
|
|
1448
|
+
|
|
1449
|
+
if ((gFirewallKey != NULL) && (gFirewallChangedEvent))
|
|
1450
|
+
{
|
|
1451
|
+
err = RegNotifyChangeKeyValue(gFirewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFirewallChangedEvent, TRUE);
|
|
1452
|
+
check_noerr( err );
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
else if ( result == kWaitListAdvertisedServicesEvent )
|
|
1456
|
+
{
|
|
1457
|
+
// Ultimately we'll want to manage multiple services, but right now the only service
|
|
1458
|
+
// we'll be managing is SMB.
|
|
1459
|
+
|
|
1460
|
+
FileSharingDidChange( &gMDNSRecord );
|
|
1461
|
+
|
|
1462
|
+
// and reset the event handler
|
|
1463
|
+
|
|
1464
|
+
if ( ( gAdvertisedServicesKey != NULL ) && ( gAdvertisedServicesChangedEvent ) )
|
|
1465
|
+
{
|
|
1466
|
+
err = RegNotifyChangeKeyValue(gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
|
|
1467
|
+
check_noerr( err );
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
else if ( result == kWaitListSPSWakeupEvent )
|
|
1471
|
+
{
|
|
1472
|
+
LARGE_INTEGER timeout;
|
|
1473
|
+
|
|
1474
|
+
ReportStatus( EVENTLOG_INFORMATION_TYPE, "Maintenance wake" );
|
|
1475
|
+
|
|
1476
|
+
timeout.QuadPart = kSPSMaintenanceWakePeriod;
|
|
1477
|
+
timeout.QuadPart *= kSecondsTo100NSUnits;
|
|
1478
|
+
|
|
1479
|
+
SetWaitableTimer( gSPSSleepEvent, &timeout, 0, NULL, NULL, TRUE );
|
|
1480
|
+
}
|
|
1481
|
+
else if ( result == kWaitListSPSSleepEvent )
|
|
1482
|
+
{
|
|
1483
|
+
ReportStatus( EVENTLOG_INFORMATION_TYPE, "Returning to sleep after maintenance wake" );
|
|
1484
|
+
|
|
1485
|
+
// Calling SetSuspendState() doesn't invoke our sleep handlers, so we'll
|
|
1486
|
+
// call HandlePowerSuspend() explicity. This will reset the
|
|
1487
|
+
// maintenance wake timers.
|
|
1488
|
+
|
|
1489
|
+
HandlePowerSuspend( NULL );
|
|
1490
|
+
SetSuspendState( FALSE, FALSE, FALSE );
|
|
1491
|
+
}
|
|
1492
|
+
else
|
|
1493
|
+
{
|
|
1494
|
+
int waitItemIndex;
|
|
1495
|
+
|
|
1496
|
+
waitItemIndex = (int)( ( (int) result ) - WAIT_OBJECT_0 );
|
|
1497
|
+
dlog( kDebugLevelChatty, DEBUG_NAME "waitable event on %d\n", waitItemIndex );
|
|
1498
|
+
check( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) );
|
|
1499
|
+
|
|
1500
|
+
if ( ( waitItemIndex >= 0 ) && ( waitItemIndex < waitListCount ) )
|
|
1501
|
+
{
|
|
1502
|
+
HANDLE signaledEvent;
|
|
1503
|
+
int n = 0;
|
|
1504
|
+
|
|
1505
|
+
signaledEvent = waitList[ waitItemIndex ];
|
|
1506
|
+
|
|
1507
|
+
// If gCurrentSource is not NULL, then this routine has been called
|
|
1508
|
+
// re-entrantly which should never happen.
|
|
1509
|
+
|
|
1510
|
+
check( !gCurrentSource );
|
|
1511
|
+
|
|
1512
|
+
for ( gCurrentSource = gEventSourceList; gCurrentSource; )
|
|
1513
|
+
{
|
|
1514
|
+
EventSource * current = gCurrentSource;
|
|
1515
|
+
|
|
1516
|
+
if ( gCurrentSource->event == signaledEvent )
|
|
1517
|
+
{
|
|
1518
|
+
gCurrentSource->handler( &gMDNSRecord, gCurrentSource->event, gCurrentSource->context );
|
|
1519
|
+
++n;
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
// If the current node was removed as a result of calling
|
|
1524
|
+
// the handler, then gCurrentSource was already incremented to
|
|
1525
|
+
// the next node. If it wasn't removed, then increment it
|
|
1526
|
+
// ourselves
|
|
1527
|
+
|
|
1528
|
+
if ( gCurrentSource == current )
|
|
1529
|
+
{
|
|
1530
|
+
gCurrentSource = gCurrentSource->next;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
gCurrentSource = NULL;
|
|
1535
|
+
|
|
1536
|
+
check( n > 0 );
|
|
1537
|
+
}
|
|
1538
|
+
else
|
|
1539
|
+
{
|
|
1540
|
+
dlog( kDebugLevelWarning, DEBUG_NAME "%s: unexpected wait result (result=0x%08X)\n", __ROUTINE__, result );
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
else
|
|
1545
|
+
{
|
|
1546
|
+
Sleep( 3 * 1000 );
|
|
1547
|
+
|
|
1548
|
+
err = SetupInterfaceList( &gMDNSRecord );
|
|
1549
|
+
check( !err );
|
|
1550
|
+
|
|
1551
|
+
err = uDNS_SetupDNSConfig( &gMDNSRecord );
|
|
1552
|
+
check( !err );
|
|
1553
|
+
|
|
1554
|
+
break;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
if ( waitList )
|
|
1559
|
+
{
|
|
1560
|
+
free( waitList );
|
|
1561
|
+
waitList = NULL;
|
|
1562
|
+
waitListCount = 0;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
exit:
|
|
1567
|
+
|
|
1568
|
+
return( 0 );
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
//===========================================================================================================================
|
|
1572
|
+
// ServiceSpecificStop
|
|
1573
|
+
//===========================================================================================================================
|
|
1574
|
+
|
|
1575
|
+
static OSStatus ServiceSpecificStop( void )
|
|
1576
|
+
{
|
|
1577
|
+
OSStatus err;
|
|
1578
|
+
BOOL ok;
|
|
1579
|
+
|
|
1580
|
+
ok = SetEvent(gStopEvent);
|
|
1581
|
+
err = translate_errno( ok, (OSStatus) GetLastError(), kUnknownErr );
|
|
1582
|
+
require_noerr( err, exit );
|
|
1583
|
+
exit:
|
|
1584
|
+
return( err );
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
//===========================================================================================================================
|
|
1588
|
+
// ServiceSpecificFinalize
|
|
1589
|
+
//===========================================================================================================================
|
|
1590
|
+
|
|
1591
|
+
static void ServiceSpecificFinalize( int argc, LPTSTR argv[] )
|
|
1592
|
+
{
|
|
1593
|
+
DEBUG_UNUSED( argc );
|
|
1594
|
+
DEBUG_UNUSED( argv );
|
|
1595
|
+
|
|
1596
|
+
//
|
|
1597
|
+
// clean up any open sessions
|
|
1598
|
+
//
|
|
1599
|
+
while ( gEventSourceList )
|
|
1600
|
+
{
|
|
1601
|
+
UnregisterWaitableEvent( &gMDNSRecord, gEventSourceList->event );
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
//
|
|
1605
|
+
// clean up the notifications
|
|
1606
|
+
//
|
|
1607
|
+
TearDownNotifications();
|
|
1608
|
+
|
|
1609
|
+
//
|
|
1610
|
+
// clean up loaded library
|
|
1611
|
+
//
|
|
1612
|
+
|
|
1613
|
+
if( gIPHelperLibraryInstance )
|
|
1614
|
+
{
|
|
1615
|
+
gGetIpInterfaceEntryFunctionPtr = NULL;
|
|
1616
|
+
|
|
1617
|
+
FreeLibrary( gIPHelperLibraryInstance );
|
|
1618
|
+
gIPHelperLibraryInstance = NULL;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
//===========================================================================================================================
|
|
1624
|
+
// SetupNotifications
|
|
1625
|
+
//===========================================================================================================================
|
|
1626
|
+
|
|
1627
|
+
mDNSlocal mStatus SetupNotifications()
|
|
1628
|
+
{
|
|
1629
|
+
mStatus err;
|
|
1630
|
+
SocketRef sock;
|
|
1631
|
+
unsigned long param;
|
|
1632
|
+
int inBuffer;
|
|
1633
|
+
int outBuffer;
|
|
1634
|
+
DWORD outSize;
|
|
1635
|
+
|
|
1636
|
+
gStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
1637
|
+
err = translate_errno( gStopEvent, errno_compat(), kNoResourcesErr );
|
|
1638
|
+
require_noerr( err, exit );
|
|
1639
|
+
|
|
1640
|
+
// Register to listen for address list changes.
|
|
1641
|
+
|
|
1642
|
+
gInterfaceListChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
1643
|
+
err = translate_errno( gInterfaceListChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1644
|
+
require_noerr( err, exit );
|
|
1645
|
+
|
|
1646
|
+
sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
|
1647
|
+
err = translate_errno( IsValidSocket( sock ), errno_compat(), kUnknownErr );
|
|
1648
|
+
require_noerr( err, exit );
|
|
1649
|
+
gInterfaceListChangedSocket = sock;
|
|
1650
|
+
|
|
1651
|
+
// Make the socket non-blocking so the WSAIoctl returns immediately with WSAEWOULDBLOCK. It will set the event
|
|
1652
|
+
// when a change to the interface list is detected.
|
|
1653
|
+
|
|
1654
|
+
param = 1;
|
|
1655
|
+
err = ioctlsocket( sock, FIONBIO, ¶m );
|
|
1656
|
+
err = translate_errno( err == 0, errno_compat(), kUnknownErr );
|
|
1657
|
+
require_noerr( err, exit );
|
|
1658
|
+
|
|
1659
|
+
inBuffer = 0;
|
|
1660
|
+
outBuffer = 0;
|
|
1661
|
+
err = WSAIoctl( sock, SIO_ADDRESS_LIST_CHANGE, &inBuffer, 0, &outBuffer, 0, &outSize, NULL, NULL );
|
|
1662
|
+
if( err < 0 )
|
|
1663
|
+
{
|
|
1664
|
+
check( errno_compat() == WSAEWOULDBLOCK );
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
err = WSAEventSelect( sock, gInterfaceListChangedEvent, FD_ADDRESS_LIST_CHANGE );
|
|
1668
|
+
err = translate_errno( err == 0, errno_compat(), kUnknownErr );
|
|
1669
|
+
require_noerr( err, exit );
|
|
1670
|
+
|
|
1671
|
+
gDescChangedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
1672
|
+
err = translate_errno( gDescChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1673
|
+
require_noerr( err, exit );
|
|
1674
|
+
|
|
1675
|
+
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\parameters"), 0, KEY_READ, &gDescKey);
|
|
1676
|
+
check_translated_errno( err == 0, errno_compat(), kNameErr );
|
|
1677
|
+
|
|
1678
|
+
if ( gDescKey != NULL )
|
|
1679
|
+
{
|
|
1680
|
+
err = RegNotifyChangeKeyValue( gDescKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, gDescChangedEvent, TRUE);
|
|
1681
|
+
require_noerr( err, exit );
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
// This will catch all changes to tcp/ip networking, including changes to the domain search list
|
|
1685
|
+
|
|
1686
|
+
gTcpipChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
1687
|
+
err = translate_errno( gTcpipChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1688
|
+
require_noerr( err, exit );
|
|
1689
|
+
|
|
1690
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), &gTcpipKey );
|
|
1691
|
+
require_noerr( err, exit );
|
|
1692
|
+
|
|
1693
|
+
err = RegNotifyChangeKeyValue( gTcpipKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gTcpipChangedEvent, TRUE);
|
|
1694
|
+
require_noerr( err, exit );
|
|
1695
|
+
|
|
1696
|
+
// This will catch all changes to ddns configuration
|
|
1697
|
+
|
|
1698
|
+
gDdnsChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
1699
|
+
err = translate_errno( gDdnsChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1700
|
+
require_noerr( err, exit );
|
|
1701
|
+
|
|
1702
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\DynDNS\\Setup"), &gDdnsKey );
|
|
1703
|
+
require_noerr( err, exit );
|
|
1704
|
+
|
|
1705
|
+
err = RegNotifyChangeKeyValue( gDdnsKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gDdnsChangedEvent, TRUE);
|
|
1706
|
+
require_noerr( err, exit );
|
|
1707
|
+
|
|
1708
|
+
// This will catch all changes to file sharing
|
|
1709
|
+
|
|
1710
|
+
gFileSharingChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
1711
|
+
err = translate_errno( gFileSharingChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1712
|
+
require_noerr( err, exit );
|
|
1713
|
+
|
|
1714
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\lanmanserver\\Shares"), &gFileSharingKey );
|
|
1715
|
+
|
|
1716
|
+
// Just to make sure that initialization doesn't fail on some old OS
|
|
1717
|
+
// that doesn't have this key, we'll only add the notification if
|
|
1718
|
+
// the key exists.
|
|
1719
|
+
|
|
1720
|
+
if ( !err )
|
|
1721
|
+
{
|
|
1722
|
+
err = RegNotifyChangeKeyValue( gFileSharingKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFileSharingChangedEvent, TRUE);
|
|
1723
|
+
require_noerr( err, exit );
|
|
1724
|
+
}
|
|
1725
|
+
else
|
|
1726
|
+
{
|
|
1727
|
+
err = mStatus_NoError;
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
// This will catch changes to the Windows firewall
|
|
1731
|
+
|
|
1732
|
+
gFirewallChangedEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
1733
|
+
err = translate_errno( gFirewallChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1734
|
+
require_noerr( err, exit );
|
|
1735
|
+
|
|
1736
|
+
// Just to make sure that initialization doesn't fail on some old OS
|
|
1737
|
+
// that doesn't have this key, we'll only add the notification if
|
|
1738
|
+
// the key exists.
|
|
1739
|
+
|
|
1740
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules"), &gFirewallKey );
|
|
1741
|
+
|
|
1742
|
+
if ( !err )
|
|
1743
|
+
{
|
|
1744
|
+
err = RegNotifyChangeKeyValue( gFirewallKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gFirewallChangedEvent, TRUE);
|
|
1745
|
+
require_noerr( err, exit );
|
|
1746
|
+
}
|
|
1747
|
+
else
|
|
1748
|
+
{
|
|
1749
|
+
err = mStatus_NoError;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
// This will catch all changes to advertised services configuration
|
|
1753
|
+
|
|
1754
|
+
gAdvertisedServicesChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
1755
|
+
err = translate_errno( gAdvertisedServicesChangedEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1756
|
+
require_noerr( err, exit );
|
|
1757
|
+
|
|
1758
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode TEXT("\\Services"), &gAdvertisedServicesKey );
|
|
1759
|
+
require_noerr( err, exit );
|
|
1760
|
+
|
|
1761
|
+
err = RegNotifyChangeKeyValue( gAdvertisedServicesKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, gAdvertisedServicesChangedEvent, TRUE);
|
|
1762
|
+
require_noerr( err, exit );
|
|
1763
|
+
|
|
1764
|
+
gSPSWakeupEvent = CreateWaitableTimer( NULL, FALSE, NULL );
|
|
1765
|
+
err = translate_errno( gSPSWakeupEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1766
|
+
require_noerr( err, exit );
|
|
1767
|
+
|
|
1768
|
+
gSPSSleepEvent = CreateWaitableTimer( NULL, FALSE, NULL );
|
|
1769
|
+
err = translate_errno( gSPSSleepEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
1770
|
+
require_noerr( err, exit );
|
|
1771
|
+
|
|
1772
|
+
gUDSEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
1773
|
+
err = translate_errno( gUDSEvent, ( mStatus ) GetLastError(), kUnknownErr );
|
|
1774
|
+
require_noerr( err, exit );
|
|
1775
|
+
|
|
1776
|
+
exit:
|
|
1777
|
+
if( err )
|
|
1778
|
+
{
|
|
1779
|
+
TearDownNotifications();
|
|
1780
|
+
}
|
|
1781
|
+
return( err );
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
//===========================================================================================================================
|
|
1785
|
+
// TearDownNotifications
|
|
1786
|
+
//===========================================================================================================================
|
|
1787
|
+
|
|
1788
|
+
mDNSlocal mStatus TearDownNotifications()
|
|
1789
|
+
{
|
|
1790
|
+
if ( gStopEvent )
|
|
1791
|
+
{
|
|
1792
|
+
CloseHandle( gStopEvent );
|
|
1793
|
+
gStopEvent = NULL;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
if( IsValidSocket( gInterfaceListChangedSocket ) )
|
|
1797
|
+
{
|
|
1798
|
+
close_compat( gInterfaceListChangedSocket );
|
|
1799
|
+
gInterfaceListChangedSocket = kInvalidSocketRef;
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
if( gInterfaceListChangedEvent )
|
|
1803
|
+
{
|
|
1804
|
+
CloseHandle( gInterfaceListChangedEvent );
|
|
1805
|
+
gInterfaceListChangedEvent = 0;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
if ( gDescChangedEvent != NULL )
|
|
1809
|
+
{
|
|
1810
|
+
CloseHandle( gDescChangedEvent );
|
|
1811
|
+
gDescChangedEvent = NULL;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
if ( gDescKey != NULL )
|
|
1815
|
+
{
|
|
1816
|
+
RegCloseKey( gDescKey );
|
|
1817
|
+
gDescKey = NULL;
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
if ( gTcpipChangedEvent != NULL )
|
|
1821
|
+
{
|
|
1822
|
+
CloseHandle( gTcpipChangedEvent );
|
|
1823
|
+
gTcpipChangedEvent = NULL;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
if ( gDdnsChangedEvent != NULL )
|
|
1827
|
+
{
|
|
1828
|
+
CloseHandle( gDdnsChangedEvent );
|
|
1829
|
+
gDdnsChangedEvent = NULL;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
if ( gDdnsKey != NULL )
|
|
1833
|
+
{
|
|
1834
|
+
RegCloseKey( gDdnsKey );
|
|
1835
|
+
gDdnsKey = NULL;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
if ( gFileSharingChangedEvent != NULL )
|
|
1839
|
+
{
|
|
1840
|
+
CloseHandle( gFileSharingChangedEvent );
|
|
1841
|
+
gFileSharingChangedEvent = NULL;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
if ( gFileSharingKey != NULL )
|
|
1845
|
+
{
|
|
1846
|
+
RegCloseKey( gFileSharingKey );
|
|
1847
|
+
gFileSharingKey = NULL;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
if ( gFirewallChangedEvent != NULL )
|
|
1851
|
+
{
|
|
1852
|
+
CloseHandle( gFirewallChangedEvent );
|
|
1853
|
+
gFirewallChangedEvent = NULL;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
if ( gFirewallKey != NULL )
|
|
1857
|
+
{
|
|
1858
|
+
RegCloseKey( gFirewallKey );
|
|
1859
|
+
gFirewallKey = NULL;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
if ( gAdvertisedServicesChangedEvent != NULL )
|
|
1863
|
+
{
|
|
1864
|
+
CloseHandle( gAdvertisedServicesChangedEvent );
|
|
1865
|
+
gAdvertisedServicesChangedEvent = NULL;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
if ( gAdvertisedServicesKey != NULL )
|
|
1869
|
+
{
|
|
1870
|
+
RegCloseKey( gAdvertisedServicesKey );
|
|
1871
|
+
gAdvertisedServicesKey = NULL;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
if ( gSPSWakeupEvent )
|
|
1875
|
+
{
|
|
1876
|
+
CloseHandle( gSPSWakeupEvent );
|
|
1877
|
+
gSPSWakeupEvent = NULL;
|
|
1878
|
+
}
|
|
1879
|
+
|
|
1880
|
+
if ( gSPSSleepEvent )
|
|
1881
|
+
{
|
|
1882
|
+
CloseHandle( gSPSSleepEvent );
|
|
1883
|
+
gSPSSleepEvent = NULL;
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
return( mStatus_NoError );
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
|
|
1890
|
+
//===========================================================================================================================
|
|
1891
|
+
// RegisterWaitableEvent
|
|
1892
|
+
//===========================================================================================================================
|
|
1893
|
+
|
|
1894
|
+
static mStatus RegisterWaitableEvent( mDNS * const inMDNS, HANDLE event, void * context, RegisterWaitableEventHandler handler )
|
|
1895
|
+
{
|
|
1896
|
+
EventSource * source;
|
|
1897
|
+
mStatus err = mStatus_NoError;
|
|
1898
|
+
|
|
1899
|
+
( void ) inMDNS;
|
|
1900
|
+
check( event );
|
|
1901
|
+
check( handler );
|
|
1902
|
+
|
|
1903
|
+
source = ( EventSource* ) malloc( sizeof( EventSource ) );
|
|
1904
|
+
require_action( source, exit, err = mStatus_NoMemoryErr );
|
|
1905
|
+
mDNSPlatformMemZero( source, sizeof( EventSource ) );
|
|
1906
|
+
source->event = event;
|
|
1907
|
+
source->context = context;
|
|
1908
|
+
source->handler = handler;
|
|
1909
|
+
|
|
1910
|
+
source->next = gEventSourceList;
|
|
1911
|
+
gEventSourceList = source;
|
|
1912
|
+
gEventSourceListChanged = TRUE;
|
|
1913
|
+
gEventSources++;
|
|
1914
|
+
|
|
1915
|
+
exit:
|
|
1916
|
+
|
|
1917
|
+
return err;
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
|
|
1921
|
+
//===========================================================================================================================
|
|
1922
|
+
// UnregisterWaitableEvent
|
|
1923
|
+
//===========================================================================================================================
|
|
1924
|
+
|
|
1925
|
+
static void UnregisterWaitableEvent( mDNS * const inMDNS, HANDLE event )
|
|
1926
|
+
{
|
|
1927
|
+
EventSource * current = gEventSourceList;
|
|
1928
|
+
EventSource * last = NULL;
|
|
1929
|
+
|
|
1930
|
+
( void ) inMDNS;
|
|
1931
|
+
check( event );
|
|
1932
|
+
|
|
1933
|
+
while ( current )
|
|
1934
|
+
{
|
|
1935
|
+
if ( current->event == event )
|
|
1936
|
+
{
|
|
1937
|
+
if ( last == NULL )
|
|
1938
|
+
{
|
|
1939
|
+
gEventSourceList = current->next;
|
|
1940
|
+
}
|
|
1941
|
+
else
|
|
1942
|
+
{
|
|
1943
|
+
last->next = current->next;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
gEventSourceListChanged = TRUE;
|
|
1947
|
+
|
|
1948
|
+
// Protect against removing the node that we happen
|
|
1949
|
+
// to be looking at as we iterate through the event
|
|
1950
|
+
// source list in ServiceSpecificRun()
|
|
1951
|
+
|
|
1952
|
+
if ( current == gCurrentSource )
|
|
1953
|
+
{
|
|
1954
|
+
gCurrentSource = current->next;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
gEventSources--;
|
|
1958
|
+
free( current );
|
|
1959
|
+
|
|
1960
|
+
break;
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
last = current;
|
|
1964
|
+
current = current->next;
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
|
|
1969
|
+
//===========================================================================================================================
|
|
1970
|
+
// SetupWaitList
|
|
1971
|
+
//===========================================================================================================================
|
|
1972
|
+
|
|
1973
|
+
mDNSlocal mStatus SetupWaitList( mDNS * const inMDNS, HANDLE **outWaitList, int *outWaitListCount )
|
|
1974
|
+
{
|
|
1975
|
+
int waitListCount;
|
|
1976
|
+
HANDLE * waitList;
|
|
1977
|
+
HANDLE * waitItemPtr;
|
|
1978
|
+
EventSource * source;
|
|
1979
|
+
mStatus err;
|
|
1980
|
+
|
|
1981
|
+
dlog( kDebugLevelTrace, DEBUG_NAME "setting up wait list\n" );
|
|
1982
|
+
|
|
1983
|
+
( void ) inMDNS;
|
|
1984
|
+
check( inMDNS->p );
|
|
1985
|
+
check( outWaitList );
|
|
1986
|
+
check( outWaitListCount );
|
|
1987
|
+
|
|
1988
|
+
// Allocate an array to hold all the objects to wait on.
|
|
1989
|
+
|
|
1990
|
+
waitListCount = kWaitListFixedItemCount + gEventSources;
|
|
1991
|
+
waitList = ( HANDLE* ) malloc( waitListCount * sizeof( *waitList ) );
|
|
1992
|
+
require_action( waitList, exit, err = mStatus_NoMemoryErr );
|
|
1993
|
+
waitItemPtr = waitList;
|
|
1994
|
+
|
|
1995
|
+
// Add the fixed wait items to the beginning of the list.
|
|
1996
|
+
|
|
1997
|
+
*waitItemPtr++ = gStopEvent;
|
|
1998
|
+
*waitItemPtr++ = gInterfaceListChangedEvent;
|
|
1999
|
+
*waitItemPtr++ = gDescChangedEvent;
|
|
2000
|
+
*waitItemPtr++ = gTcpipChangedEvent;
|
|
2001
|
+
*waitItemPtr++ = gDdnsChangedEvent;
|
|
2002
|
+
*waitItemPtr++ = gFileSharingChangedEvent;
|
|
2003
|
+
*waitItemPtr++ = gFirewallChangedEvent;
|
|
2004
|
+
*waitItemPtr++ = gAdvertisedServicesChangedEvent;
|
|
2005
|
+
*waitItemPtr++ = gSPSWakeupEvent;
|
|
2006
|
+
*waitItemPtr++ = gSPSSleepEvent;
|
|
2007
|
+
|
|
2008
|
+
for ( source = gEventSourceList; source; source = source->next )
|
|
2009
|
+
{
|
|
2010
|
+
*waitItemPtr++ = source->event;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
check( ( int )( waitItemPtr - waitList ) == waitListCount );
|
|
2014
|
+
|
|
2015
|
+
*outWaitList = waitList;
|
|
2016
|
+
*outWaitListCount = waitListCount;
|
|
2017
|
+
waitList = NULL;
|
|
2018
|
+
err = mStatus_NoError;
|
|
2019
|
+
|
|
2020
|
+
exit:
|
|
2021
|
+
|
|
2022
|
+
if( waitList )
|
|
2023
|
+
{
|
|
2024
|
+
free( waitList );
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
dlog( kDebugLevelTrace, DEBUG_NAME "setting up wait list done (err=%d %m)\n", err, err );
|
|
2028
|
+
return( err );
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
|
|
2032
|
+
//===========================================================================================================================
|
|
2033
|
+
// CoreCallback
|
|
2034
|
+
//===========================================================================================================================
|
|
2035
|
+
|
|
2036
|
+
static void
|
|
2037
|
+
CoreCallback(mDNS * const inMDNS, mStatus status)
|
|
2038
|
+
{
|
|
2039
|
+
if (status == mStatus_ConfigChanged)
|
|
2040
|
+
{
|
|
2041
|
+
SetLLRoute( inMDNS );
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
|
|
2046
|
+
//===========================================================================================================================
|
|
2047
|
+
// UDSCanAccept
|
|
2048
|
+
//===========================================================================================================================
|
|
2049
|
+
|
|
2050
|
+
mDNSlocal void UDSCanAccept( mDNS * const inMDNS, HANDLE event, void * context )
|
|
2051
|
+
{
|
|
2052
|
+
( void ) inMDNS;
|
|
2053
|
+
( void ) event;
|
|
2054
|
+
|
|
2055
|
+
if ( gUDSCallback )
|
|
2056
|
+
{
|
|
2057
|
+
gUDSCallback( ( int ) gUDSSocket, 0, context );
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
|
|
2062
|
+
//===========================================================================================================================
|
|
2063
|
+
// UDSCanRead
|
|
2064
|
+
//===========================================================================================================================
|
|
2065
|
+
|
|
2066
|
+
mDNSlocal void UDSCanRead( TCPSocket * sock )
|
|
2067
|
+
{
|
|
2068
|
+
udsEventCallback callback = ( udsEventCallback ) sock->userCallback;
|
|
2069
|
+
|
|
2070
|
+
if ( callback )
|
|
2071
|
+
{
|
|
2072
|
+
callback( (int) sock->fd, 0, sock->userContext );
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
|
|
2077
|
+
//===========================================================================================================================
|
|
2078
|
+
// udsSupportAddFDToEventLoop
|
|
2079
|
+
//===========================================================================================================================
|
|
2080
|
+
|
|
2081
|
+
|
|
2082
|
+
mStatus
|
|
2083
|
+
udsSupportAddFDToEventLoop( SocketRef fd, udsEventCallback callback, void *context, void **platform_data)
|
|
2084
|
+
{
|
|
2085
|
+
mStatus err = mStatus_NoError;
|
|
2086
|
+
|
|
2087
|
+
// We are using some knowledge of what is being passed to us here. If the fd is a listen socket,
|
|
2088
|
+
// then the "callback" parameter is NULL. If it is an actual read/write socket, then the "callback"
|
|
2089
|
+
// parameter is not null. This is important because we use waitable events for the listen socket
|
|
2090
|
+
// and alertable I/O for the read/write sockets.
|
|
2091
|
+
|
|
2092
|
+
if ( context )
|
|
2093
|
+
{
|
|
2094
|
+
TCPSocket * sock;
|
|
2095
|
+
|
|
2096
|
+
sock = malloc( sizeof( TCPSocket ) );
|
|
2097
|
+
require_action( sock, exit, err = mStatus_NoMemoryErr );
|
|
2098
|
+
mDNSPlatformMemZero( sock, sizeof( TCPSocket ) );
|
|
2099
|
+
|
|
2100
|
+
sock->fd = (SOCKET) fd;
|
|
2101
|
+
sock->readEventHandler = UDSCanRead;
|
|
2102
|
+
sock->userCallback = callback;
|
|
2103
|
+
sock->userContext = context;
|
|
2104
|
+
sock->m = &gMDNSRecord;
|
|
2105
|
+
|
|
2106
|
+
err = TCPAddSocket( sock->m, sock );
|
|
2107
|
+
require_noerr( err, exit );
|
|
2108
|
+
|
|
2109
|
+
*platform_data = sock;
|
|
2110
|
+
}
|
|
2111
|
+
else
|
|
2112
|
+
{
|
|
2113
|
+
gUDSSocket = fd;
|
|
2114
|
+
gUDSCallback = callback;
|
|
2115
|
+
gUDSEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|
2116
|
+
err = translate_errno( gUDSEvent, (mStatus) GetLastError(), kUnknownErr );
|
|
2117
|
+
require_noerr( err, exit );
|
|
2118
|
+
err = WSAEventSelect( fd, gUDSEvent, FD_ACCEPT | FD_CLOSE );
|
|
2119
|
+
err = translate_errno( err == 0, WSAGetLastError(), kNoResourcesErr );
|
|
2120
|
+
require_noerr( err, exit );
|
|
2121
|
+
err = RegisterWaitableEvent( &gMDNSRecord, gUDSEvent, context, UDSCanAccept );
|
|
2122
|
+
require_noerr( err, exit );
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
exit:
|
|
2126
|
+
|
|
2127
|
+
return err;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
|
|
2131
|
+
int
|
|
2132
|
+
udsSupportReadFD( SocketRef fd, char *buf, int len, int flags, void *platform_data )
|
|
2133
|
+
{
|
|
2134
|
+
TCPSocket * sock;
|
|
2135
|
+
mDNSBool closed;
|
|
2136
|
+
int ret;
|
|
2137
|
+
|
|
2138
|
+
( void ) flags;
|
|
2139
|
+
|
|
2140
|
+
sock = ( TCPSocket* ) platform_data;
|
|
2141
|
+
require_action( sock, exit, ret = -1 );
|
|
2142
|
+
require_action( sock->fd == fd, exit, ret = -1 );
|
|
2143
|
+
|
|
2144
|
+
ret = mDNSPlatformReadTCP( sock, buf, len, &closed );
|
|
2145
|
+
|
|
2146
|
+
if ( closed )
|
|
2147
|
+
{
|
|
2148
|
+
ret = 0;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
exit:
|
|
2152
|
+
|
|
2153
|
+
return ret;
|
|
2154
|
+
}
|
|
2155
|
+
|
|
2156
|
+
|
|
2157
|
+
mStatus
|
|
2158
|
+
udsSupportRemoveFDFromEventLoop( SocketRef fd, void *platform_data) // Note: This also CLOSES the socket
|
|
2159
|
+
{
|
|
2160
|
+
mStatus err = kNoErr;
|
|
2161
|
+
|
|
2162
|
+
if ( platform_data != NULL )
|
|
2163
|
+
{
|
|
2164
|
+
TCPSocket * sock;
|
|
2165
|
+
|
|
2166
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "session closed\n" );
|
|
2167
|
+
sock = ( TCPSocket* ) platform_data;
|
|
2168
|
+
check( sock->fd == fd );
|
|
2169
|
+
mDNSPlatformTCPCloseConnection( sock );
|
|
2170
|
+
}
|
|
2171
|
+
else if ( gUDSEvent != NULL )
|
|
2172
|
+
{
|
|
2173
|
+
UnregisterWaitableEvent( &gMDNSRecord, gUDSEvent );
|
|
2174
|
+
WSAEventSelect( fd, gUDSEvent, 0 );
|
|
2175
|
+
CloseHandle( gUDSEvent );
|
|
2176
|
+
gUDSEvent = NULL;
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
return err;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
|
|
2183
|
+
mDNSexport void RecordUpdatedNiceLabel(mDNS *const m, mDNSs32 delay)
|
|
2184
|
+
{
|
|
2185
|
+
(void)m;
|
|
2186
|
+
(void)delay;
|
|
2187
|
+
// No-op, for now
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
|
|
2191
|
+
//===========================================================================================================================
|
|
2192
|
+
// SystemWakeForNetworkAccess
|
|
2193
|
+
//===========================================================================================================================
|
|
2194
|
+
|
|
2195
|
+
mDNSu8
|
|
2196
|
+
SystemWakeForNetworkAccess( LARGE_INTEGER * timeout )
|
|
2197
|
+
{
|
|
2198
|
+
HKEY key = NULL;
|
|
2199
|
+
DWORD dwSize;
|
|
2200
|
+
DWORD enabled;
|
|
2201
|
+
mDNSu8 ok;
|
|
2202
|
+
SYSTEM_POWER_STATUS powerStatus;
|
|
2203
|
+
time_t startTime;
|
|
2204
|
+
time_t nextWakeupTime;
|
|
2205
|
+
int delta;
|
|
2206
|
+
DWORD err;
|
|
2207
|
+
|
|
2208
|
+
dlog( kDebugLevelInfo, DEBUG_NAME "SystemWakeForNetworkAccess\n" );
|
|
2209
|
+
|
|
2210
|
+
// Make sure we have a timer
|
|
2211
|
+
|
|
2212
|
+
require_action( gSPSWakeupEvent != NULL, exit, ok = FALSE );
|
|
2213
|
+
require_action( gSPSSleepEvent != NULL, exit, ok = FALSE );
|
|
2214
|
+
|
|
2215
|
+
// Make sure the user enabled bonjour sleep proxy client
|
|
2216
|
+
|
|
2217
|
+
err = RegCreateKey( HKEY_LOCAL_MACHINE, kServiceParametersNode L"\\Power Management", &key );
|
|
2218
|
+
require_action( !err, exit, ok = FALSE );
|
|
2219
|
+
dwSize = sizeof( DWORD );
|
|
2220
|
+
err = RegQueryValueEx( key, L"Enabled", NULL, NULL, (LPBYTE) &enabled, &dwSize );
|
|
2221
|
+
require_action( !err, exit, ok = FALSE );
|
|
2222
|
+
require_action( enabled, exit, ok = FALSE );
|
|
2223
|
+
|
|
2224
|
+
// Make sure machine is on AC power
|
|
2225
|
+
|
|
2226
|
+
ok = ( mDNSu8 ) GetSystemPowerStatus( &powerStatus );
|
|
2227
|
+
require_action( ok, exit, ok = FALSE );
|
|
2228
|
+
require_action( powerStatus.ACLineStatus == AC_LINE_ONLINE, exit, ok = FALSE );
|
|
2229
|
+
|
|
2230
|
+
// Now make sure we have a network interface that does wake-on-lan
|
|
2231
|
+
|
|
2232
|
+
ok = ( mDNSu8 ) IsWOMPEnabled( &gMDNSRecord );
|
|
2233
|
+
require_action( ok, exit, ok = FALSE );
|
|
2234
|
+
|
|
2235
|
+
// Now make sure we have advertised services. Doesn't make sense to
|
|
2236
|
+
// enable sleep proxy if we have no multicast services that could
|
|
2237
|
+
// potentially wake us up.
|
|
2238
|
+
|
|
2239
|
+
ok = ( mDNSu8 ) mDNSCoreHaveAdvertisedMulticastServices( &gMDNSRecord );
|
|
2240
|
+
require_action( ok, exit, ok = FALSE );
|
|
2241
|
+
|
|
2242
|
+
// Calculate next wake up time
|
|
2243
|
+
|
|
2244
|
+
startTime = time( NULL ); // Seconds since midnight January 1, 1970
|
|
2245
|
+
nextWakeupTime = startTime + ( 120 * 60 ); // 2 hours later
|
|
2246
|
+
|
|
2247
|
+
if ( gMDNSRecord.p->nextDHCPLeaseExpires < nextWakeupTime )
|
|
2248
|
+
{
|
|
2249
|
+
nextWakeupTime = gMDNSRecord.p->nextDHCPLeaseExpires;
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
// Finally calculate the next relative wakeup time
|
|
2253
|
+
|
|
2254
|
+
delta = ( int )( ( ( double )( nextWakeupTime - startTime ) ) * 0.9 );
|
|
2255
|
+
ReportStatus( EVENTLOG_INFORMATION_TYPE, "enabling sleep proxy client with next maintenance wake in %d seconds", delta );
|
|
2256
|
+
|
|
2257
|
+
// Convert seconds to 100 nanosecond units expected by SetWaitableTimer
|
|
2258
|
+
|
|
2259
|
+
timeout->QuadPart = -delta;
|
|
2260
|
+
timeout->QuadPart *= kSecondsTo100NSUnits;
|
|
2261
|
+
|
|
2262
|
+
ok = TRUE;
|
|
2263
|
+
|
|
2264
|
+
exit:
|
|
2265
|
+
|
|
2266
|
+
if ( key )
|
|
2267
|
+
{
|
|
2268
|
+
RegCloseKey( key );
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
return ok;
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
|
|
2275
|
+
//===========================================================================================================================
|
|
2276
|
+
// HaveRoute
|
|
2277
|
+
//===========================================================================================================================
|
|
2278
|
+
|
|
2279
|
+
static bool
|
|
2280
|
+
HaveRoute( PMIB_IPFORWARDROW rowExtant, unsigned long addr, unsigned long metric )
|
|
2281
|
+
{
|
|
2282
|
+
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
|
|
2283
|
+
DWORD dwSize = 0;
|
|
2284
|
+
BOOL bOrder = FALSE;
|
|
2285
|
+
OSStatus err;
|
|
2286
|
+
bool found = false;
|
|
2287
|
+
unsigned long int i;
|
|
2288
|
+
|
|
2289
|
+
//
|
|
2290
|
+
// Find out how big our buffer needs to be.
|
|
2291
|
+
//
|
|
2292
|
+
err = GetIpForwardTable(NULL, &dwSize, bOrder);
|
|
2293
|
+
require_action( err == ERROR_INSUFFICIENT_BUFFER, exit, err = kUnknownErr );
|
|
2294
|
+
|
|
2295
|
+
//
|
|
2296
|
+
// Allocate the memory for the table
|
|
2297
|
+
//
|
|
2298
|
+
pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc( dwSize );
|
|
2299
|
+
require_action( pIpForwardTable, exit, err = kNoMemoryErr );
|
|
2300
|
+
|
|
2301
|
+
//
|
|
2302
|
+
// Now get the table.
|
|
2303
|
+
//
|
|
2304
|
+
err = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
|
|
2305
|
+
require_noerr( err, exit );
|
|
2306
|
+
|
|
2307
|
+
//
|
|
2308
|
+
// Search for the row in the table we want.
|
|
2309
|
+
//
|
|
2310
|
+
for ( i = 0; i < pIpForwardTable->dwNumEntries; i++)
|
|
2311
|
+
{
|
|
2312
|
+
if ( ( pIpForwardTable->table[i].dwForwardDest == addr ) && ( !metric || ( pIpForwardTable->table[i].dwForwardMetric1 == metric ) ) )
|
|
2313
|
+
{
|
|
2314
|
+
memcpy( rowExtant, &(pIpForwardTable->table[i]), sizeof(*rowExtant) );
|
|
2315
|
+
found = true;
|
|
2316
|
+
break;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
exit:
|
|
2321
|
+
|
|
2322
|
+
if ( pIpForwardTable != NULL )
|
|
2323
|
+
{
|
|
2324
|
+
free(pIpForwardTable);
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
return found;
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
|
|
2331
|
+
//===========================================================================================================================
|
|
2332
|
+
// IsValidAddress
|
|
2333
|
+
//===========================================================================================================================
|
|
2334
|
+
|
|
2335
|
+
static bool
|
|
2336
|
+
IsValidAddress( const char * addr )
|
|
2337
|
+
{
|
|
2338
|
+
return ( addr && ( strcmp( addr, "0.0.0.0" ) != 0 ) ) ? true : false;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
|
|
2342
|
+
//===========================================================================================================================
|
|
2343
|
+
// GetAdditionalMetric
|
|
2344
|
+
//===========================================================================================================================
|
|
2345
|
+
|
|
2346
|
+
static ULONG
|
|
2347
|
+
GetAdditionalMetric( DWORD ifIndex )
|
|
2348
|
+
{
|
|
2349
|
+
ULONG metric = 0;
|
|
2350
|
+
|
|
2351
|
+
if( !gIPHelperLibraryInstance )
|
|
2352
|
+
{
|
|
2353
|
+
gIPHelperLibraryInstance = LoadLibrary( TEXT( "Iphlpapi" ) );
|
|
2354
|
+
|
|
2355
|
+
gGetIpInterfaceEntryFunctionPtr =
|
|
2356
|
+
(GetIpInterfaceEntryFunctionPtr) GetProcAddress( gIPHelperLibraryInstance, "GetIpInterfaceEntry" );
|
|
2357
|
+
|
|
2358
|
+
if( !gGetIpInterfaceEntryFunctionPtr )
|
|
2359
|
+
{
|
|
2360
|
+
BOOL ok;
|
|
2361
|
+
|
|
2362
|
+
ok = FreeLibrary( gIPHelperLibraryInstance );
|
|
2363
|
+
check_translated_errno( ok, GetLastError(), kUnknownErr );
|
|
2364
|
+
gIPHelperLibraryInstance = NULL;
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
if ( gGetIpInterfaceEntryFunctionPtr )
|
|
2369
|
+
{
|
|
2370
|
+
MIB_IPINTERFACE_ROW row;
|
|
2371
|
+
DWORD err;
|
|
2372
|
+
|
|
2373
|
+
ZeroMemory( &row, sizeof( MIB_IPINTERFACE_ROW ) );
|
|
2374
|
+
row.Family = AF_INET;
|
|
2375
|
+
row.InterfaceIndex = ifIndex;
|
|
2376
|
+
err = gGetIpInterfaceEntryFunctionPtr( &row );
|
|
2377
|
+
require_noerr( err, exit );
|
|
2378
|
+
metric = row.Metric + 256;
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
exit:
|
|
2382
|
+
|
|
2383
|
+
return metric;
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
|
|
2387
|
+
//===========================================================================================================================
|
|
2388
|
+
// SetLLRoute
|
|
2389
|
+
//===========================================================================================================================
|
|
2390
|
+
|
|
2391
|
+
static OSStatus
|
|
2392
|
+
SetLLRoute( mDNS * const inMDNS )
|
|
2393
|
+
{
|
|
2394
|
+
OSStatus err = kNoErr;
|
|
2395
|
+
|
|
2396
|
+
DEBUG_UNUSED( inMDNS );
|
|
2397
|
+
|
|
2398
|
+
//
|
|
2399
|
+
// <rdar://problem/4096464> Don't call SetLLRoute on loopback
|
|
2400
|
+
// <rdar://problem/6885843> Default route on Windows 7 breaks network connectivity
|
|
2401
|
+
//
|
|
2402
|
+
// Don't mess w/ the routing table on Vista and later OSes, as
|
|
2403
|
+
// they have a permanent route to link-local addresses. Otherwise,
|
|
2404
|
+
// set a route to link local addresses (169.254.0.0)
|
|
2405
|
+
//
|
|
2406
|
+
if ( ( gOSMajorVersion < 6 ) && gServiceManageLLRouting && !gPlatformStorage.registeredLoopback4 )
|
|
2407
|
+
{
|
|
2408
|
+
DWORD ifIndex;
|
|
2409
|
+
MIB_IPFORWARDROW rowExtant;
|
|
2410
|
+
bool addRoute;
|
|
2411
|
+
MIB_IPFORWARDROW row;
|
|
2412
|
+
|
|
2413
|
+
ZeroMemory(&row, sizeof(row));
|
|
2414
|
+
|
|
2415
|
+
err = GetRouteDestination(&ifIndex, &row.dwForwardNextHop);
|
|
2416
|
+
require_noerr( err, exit );
|
|
2417
|
+
row.dwForwardDest = inet_addr(kLLNetworkAddr);
|
|
2418
|
+
row.dwForwardIfIndex = ifIndex;
|
|
2419
|
+
row.dwForwardMask = inet_addr(kLLNetworkAddrMask);
|
|
2420
|
+
row.dwForwardType = 3;
|
|
2421
|
+
row.dwForwardProto = MIB_IPPROTO_NETMGMT;
|
|
2422
|
+
row.dwForwardAge = 0;
|
|
2423
|
+
row.dwForwardPolicy = 0;
|
|
2424
|
+
row.dwForwardMetric1 = 20 + GetAdditionalMetric( ifIndex );
|
|
2425
|
+
row.dwForwardMetric2 = (DWORD) - 1;
|
|
2426
|
+
row.dwForwardMetric3 = (DWORD) - 1;
|
|
2427
|
+
row.dwForwardMetric4 = (DWORD) - 1;
|
|
2428
|
+
row.dwForwardMetric5 = (DWORD) - 1;
|
|
2429
|
+
|
|
2430
|
+
addRoute = true;
|
|
2431
|
+
|
|
2432
|
+
//
|
|
2433
|
+
// check to make sure we don't already have a route
|
|
2434
|
+
//
|
|
2435
|
+
if ( HaveRoute( &rowExtant, inet_addr( kLLNetworkAddr ), 0 ) )
|
|
2436
|
+
{
|
|
2437
|
+
//
|
|
2438
|
+
// set the age to 0 so that we can do a memcmp.
|
|
2439
|
+
//
|
|
2440
|
+
rowExtant.dwForwardAge = 0;
|
|
2441
|
+
|
|
2442
|
+
//
|
|
2443
|
+
// check to see if this route is the same as our route
|
|
2444
|
+
//
|
|
2445
|
+
if (memcmp(&row, &rowExtant, sizeof(row)) != 0)
|
|
2446
|
+
{
|
|
2447
|
+
//
|
|
2448
|
+
// if it isn't then delete this entry
|
|
2449
|
+
//
|
|
2450
|
+
DeleteIpForwardEntry(&rowExtant);
|
|
2451
|
+
}
|
|
2452
|
+
else
|
|
2453
|
+
{
|
|
2454
|
+
//
|
|
2455
|
+
// else it is, so we don't want to create another route
|
|
2456
|
+
//
|
|
2457
|
+
addRoute = false;
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
if (addRoute && row.dwForwardNextHop)
|
|
2462
|
+
{
|
|
2463
|
+
err = CreateIpForwardEntry(&row);
|
|
2464
|
+
check_noerr( err );
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
exit:
|
|
2469
|
+
|
|
2470
|
+
return ( err );
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
|
|
2474
|
+
//===========================================================================================================================
|
|
2475
|
+
// GetRouteDestination
|
|
2476
|
+
//===========================================================================================================================
|
|
2477
|
+
|
|
2478
|
+
static OSStatus
|
|
2479
|
+
GetRouteDestination(DWORD * ifIndex, DWORD * address)
|
|
2480
|
+
{
|
|
2481
|
+
struct in_addr ia;
|
|
2482
|
+
IP_ADAPTER_INFO * pAdapterInfo = NULL;
|
|
2483
|
+
IP_ADAPTER_INFO * pAdapter = NULL;
|
|
2484
|
+
ULONG bufLen;
|
|
2485
|
+
mDNSBool done = mDNSfalse;
|
|
2486
|
+
OSStatus err;
|
|
2487
|
+
|
|
2488
|
+
//
|
|
2489
|
+
// GetBestInterface will fail if there is no default gateway
|
|
2490
|
+
// configured. If that happens, we will just take the first
|
|
2491
|
+
// interface in the list. MSDN support says there is no surefire
|
|
2492
|
+
// way to manually determine what the best interface might
|
|
2493
|
+
// be for a particular network address.
|
|
2494
|
+
//
|
|
2495
|
+
ia.s_addr = inet_addr(kLLNetworkAddr);
|
|
2496
|
+
err = GetBestInterface(*(IPAddr*) &ia, ifIndex);
|
|
2497
|
+
|
|
2498
|
+
if (err)
|
|
2499
|
+
{
|
|
2500
|
+
*ifIndex = 0;
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
//
|
|
2504
|
+
// Make an initial call to GetAdaptersInfo to get
|
|
2505
|
+
// the necessary size into the bufLen variable
|
|
2506
|
+
//
|
|
2507
|
+
err = GetAdaptersInfo( NULL, &bufLen);
|
|
2508
|
+
require_action( err == ERROR_BUFFER_OVERFLOW, exit, err = kUnknownErr );
|
|
2509
|
+
|
|
2510
|
+
pAdapterInfo = (IP_ADAPTER_INFO*) malloc( bufLen );
|
|
2511
|
+
require_action( pAdapterInfo, exit, err = kNoMemoryErr );
|
|
2512
|
+
|
|
2513
|
+
err = GetAdaptersInfo( pAdapterInfo, &bufLen);
|
|
2514
|
+
require_noerr( err, exit );
|
|
2515
|
+
|
|
2516
|
+
pAdapter = pAdapterInfo;
|
|
2517
|
+
err = kUnknownErr;
|
|
2518
|
+
|
|
2519
|
+
// <rdar://problem/3718122>
|
|
2520
|
+
// <rdar://problem/5652098>
|
|
2521
|
+
//
|
|
2522
|
+
// Look for the Nortel VPN virtual interface, along with Juniper virtual interface.
|
|
2523
|
+
//
|
|
2524
|
+
// If these interfaces are active (i.e., has a non-zero IP Address),
|
|
2525
|
+
// then we want to disable routing table modifications.
|
|
2526
|
+
|
|
2527
|
+
while (pAdapter)
|
|
2528
|
+
{
|
|
2529
|
+
if ( ( IsNortelVPN( pAdapter ) || IsJuniperVPN( pAdapter ) || IsCiscoVPN( pAdapter ) ) &&
|
|
2530
|
+
( inet_addr( pAdapter->IpAddressList.IpAddress.String ) != 0 ) )
|
|
2531
|
+
{
|
|
2532
|
+
dlog( kDebugLevelTrace, DEBUG_NAME "disabling routing table management due to VPN incompatibility" );
|
|
2533
|
+
goto exit;
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
pAdapter = pAdapter->Next;
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
while ( !done )
|
|
2540
|
+
{
|
|
2541
|
+
pAdapter = pAdapterInfo;
|
|
2542
|
+
err = kUnknownErr;
|
|
2543
|
+
|
|
2544
|
+
while (pAdapter)
|
|
2545
|
+
{
|
|
2546
|
+
// If we don't have an interface selected, choose the first one that is of type ethernet and
|
|
2547
|
+
// has a valid IP Address
|
|
2548
|
+
|
|
2549
|
+
if ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) && ( IsValidAddress( pAdapter->IpAddressList.IpAddress.String ) ) && (!(*ifIndex) || (pAdapter->Index == (*ifIndex))))
|
|
2550
|
+
{
|
|
2551
|
+
*address = inet_addr( pAdapter->IpAddressList.IpAddress.String );
|
|
2552
|
+
*ifIndex = pAdapter->Index;
|
|
2553
|
+
err = kNoErr;
|
|
2554
|
+
break;
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
pAdapter = pAdapter->Next;
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
// If we found the right interface, or we weren't trying to find a specific interface then we're done
|
|
2561
|
+
|
|
2562
|
+
if ( !err || !( *ifIndex) )
|
|
2563
|
+
{
|
|
2564
|
+
done = mDNStrue;
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
// Otherwise, try again by wildcarding the interface
|
|
2568
|
+
|
|
2569
|
+
else
|
|
2570
|
+
{
|
|
2571
|
+
*ifIndex = 0;
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2574
|
+
|
|
2575
|
+
exit:
|
|
2576
|
+
|
|
2577
|
+
if ( pAdapterInfo != NULL )
|
|
2578
|
+
{
|
|
2579
|
+
free( pAdapterInfo );
|
|
2580
|
+
}
|
|
2581
|
+
|
|
2582
|
+
return( err );
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
|
|
2586
|
+
static bool
|
|
2587
|
+
IsNortelVPN( IP_ADAPTER_INFO * pAdapter )
|
|
2588
|
+
{
|
|
2589
|
+
return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
|
|
2590
|
+
(pAdapter->AddressLength == 6) &&
|
|
2591
|
+
(pAdapter->Address[0] == 0x44) &&
|
|
2592
|
+
(pAdapter->Address[1] == 0x45) &&
|
|
2593
|
+
(pAdapter->Address[2] == 0x53) &&
|
|
2594
|
+
(pAdapter->Address[3] == 0x54) &&
|
|
2595
|
+
(pAdapter->Address[4] == 0x42) &&
|
|
2596
|
+
(pAdapter->Address[5] == 0x00)) ? true : false;
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
|
|
2600
|
+
static bool
|
|
2601
|
+
IsJuniperVPN( IP_ADAPTER_INFO * pAdapter )
|
|
2602
|
+
{
|
|
2603
|
+
return ( strnistr( pAdapter->Description, "Juniper", sizeof( pAdapter->Description ) ) != NULL ) ? true : false;
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
|
|
2607
|
+
static bool
|
|
2608
|
+
IsCiscoVPN( IP_ADAPTER_INFO * pAdapter )
|
|
2609
|
+
{
|
|
2610
|
+
return ((pAdapter->Type == MIB_IF_TYPE_ETHERNET) &&
|
|
2611
|
+
(pAdapter->AddressLength == 6) &&
|
|
2612
|
+
(pAdapter->Address[0] == 0x00) &&
|
|
2613
|
+
(pAdapter->Address[1] == 0x05) &&
|
|
2614
|
+
(pAdapter->Address[2] == 0x9a) &&
|
|
2615
|
+
(pAdapter->Address[3] == 0x3c) &&
|
|
2616
|
+
(pAdapter->Address[4] == 0x7a) &&
|
|
2617
|
+
(pAdapter->Address[5] == 0x00)) ? true : false;
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2620
|
+
|
|
2621
|
+
static const char *
|
|
2622
|
+
strnistr( const char * string, const char * subString, size_t max )
|
|
2623
|
+
{
|
|
2624
|
+
size_t subStringLen;
|
|
2625
|
+
size_t offset;
|
|
2626
|
+
size_t maxOffset;
|
|
2627
|
+
size_t stringLen;
|
|
2628
|
+
const char * pPos;
|
|
2629
|
+
|
|
2630
|
+
if ( ( string == NULL ) || ( subString == NULL ) )
|
|
2631
|
+
{
|
|
2632
|
+
return string;
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2635
|
+
stringLen = ( max > strlen( string ) ) ? strlen( string ) : max;
|
|
2636
|
+
|
|
2637
|
+
if ( stringLen == 0 )
|
|
2638
|
+
{
|
|
2639
|
+
return NULL;
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
subStringLen = strlen( subString );
|
|
2643
|
+
|
|
2644
|
+
if ( subStringLen == 0 )
|
|
2645
|
+
{
|
|
2646
|
+
return string;
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
if ( subStringLen > stringLen )
|
|
2650
|
+
{
|
|
2651
|
+
return NULL;
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
maxOffset = stringLen - subStringLen;
|
|
2655
|
+
pPos = string;
|
|
2656
|
+
|
|
2657
|
+
for ( offset = 0; offset <= maxOffset; offset++ )
|
|
2658
|
+
{
|
|
2659
|
+
if ( _strnicmp( pPos, subString, subStringLen ) == 0 )
|
|
2660
|
+
{
|
|
2661
|
+
return pPos;
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
pPos++;
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
return NULL;
|
|
2668
|
+
}
|
|
2669
|
+
|