浏览代码

Merge branch 'dev' of https://github.com/zerotier/zerotierone into dev

Joseph Henry 3 年之前
父节点
当前提交
00d9abb612

+ 0 - 1
.gitignore

@@ -30,7 +30,6 @@ Thumbs.db
 /windows/WebUIWrapper/obj
 /windows/WebUIWrapper/obj
 /windows/lib
 /windows/lib
 /ext/installfiles/windows/ZeroTier One-SetupFiles
 /ext/installfiles/windows/ZeroTier One-SetupFiles
-/ext/installfiles/windows/Prerequisites
 /ext/installfiles/windows/*-cache
 /ext/installfiles/windows/*-cache
 /ZeroTier One.msi
 /ZeroTier One.msi
 *.vcxproj.backup
 *.vcxproj.backup

+ 4 - 0
Dockerfile.release

@@ -11,6 +11,8 @@ RUN curl -sSL -o zerotier-one.deb "${PACKAGE_BASEURL}/zerotier-one_${VERSION}_${
 
 
 FROM debian:buster
 FROM debian:buster
 
 
+RUN apt-get update -qq && apt-get install openssl libssl1.1 -y
+
 COPY --from=stage zerotier-one.deb .
 COPY --from=stage zerotier-one.deb .
 
 
 RUN dpkg -i zerotier-one.deb && rm -f zerotier-one.deb
 RUN dpkg -i zerotier-one.deb && rm -f zerotier-one.deb
@@ -20,5 +22,7 @@ RUN rm -rf /var/lib/zerotier-one
 COPY entrypoint.sh.release /entrypoint.sh
 COPY entrypoint.sh.release /entrypoint.sh
 RUN chmod 755 /entrypoint.sh
 RUN chmod 755 /entrypoint.sh
 
 
+HEALTHCHECK --interval=1s CMD bash /healthcheck.sh
+
 CMD []
 CMD []
 ENTRYPOINT ["/entrypoint.sh"]
 ENTRYPOINT ["/entrypoint.sh"]

+ 5 - 4
RELEASE-NOTES.md

@@ -1,11 +1,12 @@
 ZeroTier Release Notes
 ZeroTier Release Notes
 ======
 ======
 
 
-# 2022-03-21 -- Version 1.8.7
+# 2022-03-30 -- Version 1.8.7
 
 
- * Fix for dependency installations in Windows MSI package
- * Fix for privilege escalation in desktop UI when the user is not a current super-user
- * Bug fix in local OIDC / SSO support
+ * Fix for dependency installations in Windows MSI package.
+ * Fix for desktop UI setup when run by a non-super-user.
+ * Bug fix in local OIDC / SSO support for auth0 and other providers.
+ * Other minor fixes for e.g. old Linux distributions.
 
 
 # 2022-03-04 -- Version 1.8.6
 # 2022-03-04 -- Version 1.8.6
 
 

+ 30 - 11
entrypoint.sh.release

@@ -1,7 +1,7 @@
 #!/bin/sh
 #!/bin/sh
 
 
 grepzt() {
 grepzt() {
-  [ ! -n "$(cat /var/lib/zerotier-one/zerotier-one.pid)" -a -d "/proc/$(cat /var/lib/zerotier-one/zerotier-one.pid)" ]
+  [ -f /var/lib/zerotier-one/zerotier-one.pid -a -n "$(cat /var/lib/zerotier-one/zerotier-one.pid)" -a -d "/proc/$(cat /var/lib/zerotier-one/zerotier-one.pid)" ]
   return $?
   return $?
 }
 }
 
 
@@ -40,26 +40,45 @@ killzerotier() {
 
 
 trap killzerotier INT TERM
 trap killzerotier INT TERM
 
 
+echo "Configuring networks to join"
+mkdir -p /var/lib/zerotier-one/networks.d
+
+echo "joining networks: $@"
+for i in "$@"
+do
+  echo "Configuring join for $i"
+  touch "/var/lib/zerotier-one/networks.d/${i}.conf"
+done
+
 echo "starting zerotier"
 echo "starting zerotier"
 nohup /usr/sbin/zerotier-one &
 nohup /usr/sbin/zerotier-one &
 
 
 while ! grepzt
 while ! grepzt
 do
 do
   echo "zerotier hasn't started, waiting a second"
   echo "zerotier hasn't started, waiting a second"
+
+  if [ -f nohup.out ]
+  then
+    tail -n 10 nohup.out
+  fi
+
   sleep 1
   sleep 1
 done
 done
 
 
-echo "joining networks: $@"
+echo "Writing healthcheck for networks: $@"
 
 
-for i in "$@"
+cat >/healthcheck.sh <<EOF
+#!/bin/bash
+for i in $@
 do
 do
-  echo "joining $i"
-
-  while ! zerotier-cli join "$i"
-  do 
-    echo "joining $i failed; trying again in 1s"
-    sleep 1
-  done
+  [ "\$(zerotier-cli get \$i status)" = "OK" ] || exit 1
 done
 done
+EOF
+
+chmod +x /healthcheck.sh
 
 
-sleep infinity
+echo "Sleeping infinitely"
+while true
+do
+  sleep 1
+done

二进制
ext/installfiles/windows/Prerequisites/WebView2/MicrosoftEdgeWebview2Setup.exe


+ 15 - 60
ext/installfiles/windows/ZeroTier One.aip

@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<DOCUMENT Type="Advanced Installer" CreateVersion="10.9" version="19.2" Modules="enterprise" RootPath="." Language="en" Id="{DC564647-6BF0-4550-87F4-89C938D0159C}">
+<DOCUMENT Type="Advanced Installer" CreateVersion="10.9" version="19.3" Modules="enterprise" RootPath="." Language="en" Id="{DC564647-6BF0-4550-87F4-89C938D0159C}">
+  <COMPONENT cid="caphyon.advinst.msicomp.ProjectOptionsComponent">
+    <ROW Name="HiddenItems" Value="ActSyncAppComponent;AutorunComponent;CPLAppletComponent;GameUxComponent;SilverlightSlnComponent;AppXAppDetailsComponent;FixupComponent;AppXCapabilitiesComponent;AppXDependenciesComponent;AppXProductDetailsComponent;AppXVisualAssetsComponent;AppXAppDeclarationsComponent;AppXUriRulesComponent;MsiXDiffComponent;MsixManifestEditorComponent"/>
+  </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
     <ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
     <ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
     <ROW Property="AI_CURRENT_YEAR" Value="2022" ValueLocId="-"/>
     <ROW Property="AI_CURRENT_YEAR" Value="2022" ValueLocId="-"/>
@@ -27,10 +30,10 @@
     <ROW Property="LIMITUI" MultiBuildValue="DefaultBuild:1"/>
     <ROW Property="LIMITUI" MultiBuildValue="DefaultBuild:1"/>
     <ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
     <ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
     <ROW Property="Manufacturer" Value="ZeroTier, Inc."/>
     <ROW Property="Manufacturer" Value="ZeroTier, Inc."/>
-    <ROW Property="ProductCode" Value="1033:{1CF2BF7E-ADE7-440B-A50A-F2912D8B4D0D} " Type="16"/>
+    <ROW Property="ProductCode" Value="1033:{002609B2-C32C-481A-B17F-B7ED428427AC} " Type="16"/>
     <ROW Property="ProductLanguage" Value="1033"/>
     <ROW Property="ProductLanguage" Value="1033"/>
     <ROW Property="ProductName" Value="ZeroTier One"/>
     <ROW Property="ProductName" Value="ZeroTier One"/>
-    <ROW Property="ProductVersion" Value="1.8.6"/>
+    <ROW Property="ProductVersion" Value="1.8.7"/>
     <ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
     <ROW Property="REBOOT" MultiBuildValue="DefaultBuild:ReallySuppress"/>
     <ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR"/>
     <ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND;AI_SETUPEXEPATH;SETUPEXEDIR"/>
     <ROW Property="UpgradeCode" Value="{B0E2A5F3-88B6-4E77-B922-CB4739B4C4C8}"/>
     <ROW Property="UpgradeCode" Value="{B0E2A5F3-88B6-4E77-B922-CB4739B4C4C8}"/>
@@ -65,14 +68,12 @@
     <ROW Directory="x86_Dir" Directory_Parent="tapwindows_Dir" DefaultDir="x86"/>
     <ROW Directory="x86_Dir" Directory_Parent="tapwindows_Dir" DefaultDir="x86"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
-    <ROW Component="A918597FE054CCCB65ABDBA0AD8F63C" ComponentId="{458A5336-4527-4409-BB9D-D074790820A6}" Directory_="APPDIR" Attributes="4" KeyPath="A918597FE054CCCB65ABDBA0AD8F63C" Options="2"/>
-    <ROW Component="AI_CustomARPName" ComponentId="{B098B41F-3C1C-4D4E-BB89-FF0C81A26E9C}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
+    <ROW Component="AI_CustomARPName" ComponentId="{AE9B64A8-133E-4205-A700-6962B9FD02EB}" Directory_="APPDIR" Attributes="4" KeyPath="DisplayName" Options="1"/>
     <ROW Component="AI_DisableModify" ComponentId="{46FFA8C5-A0CB-4E05-9AD3-911D543DE8CA}" Directory_="APPDIR" Attributes="4" KeyPath="NoModify" Options="1"/>
     <ROW Component="AI_DisableModify" ComponentId="{46FFA8C5-A0CB-4E05-9AD3-911D543DE8CA}" Directory_="APPDIR" Attributes="4" KeyPath="NoModify" Options="1"/>
     <ROW Component="AI_ExePath" ComponentId="{8E02B36C-7A19-429B-A93E-77A9261AC918}" Directory_="APPDIR" Attributes="4" KeyPath="AI_ExePath"/>
     <ROW Component="AI_ExePath" ComponentId="{8E02B36C-7A19-429B-A93E-77A9261AC918}" Directory_="APPDIR" Attributes="4" KeyPath="AI_ExePath"/>
     <ROW Component="APPDIR" ComponentId="{4DD7907D-D7FE-4CD6-B1A0-B5C1625F5133}" Directory_="APPDIR" Attributes="0"/>
     <ROW Component="APPDIR" ComponentId="{4DD7907D-D7FE-4CD6-B1A0-B5C1625F5133}" Directory_="APPDIR" Attributes="0"/>
-    <ROW Component="C4FE6FD5B7C4D07B3A313E754A9A6A8" ComponentId="{7A501107-9EEE-45A6-9609-F5E1A7372448}" Directory_="APPDIR" Attributes="260" KeyPath="C4FE6FD5B7C4D07B3A313E754A9A6A8" Options="2"/>
+    <ROW Component="MicrosoftEdgeWebview2Setup.exe" ComponentId="{A243EE85-09B7-4451-B053-0C9BA4CA33A6}" Directory_="APPDIR" Attributes="0" KeyPath="MicrosoftEdgeWebview2Setup.exe"/>
     <ROW Component="ProductInformation" ComponentId="{DB078D04-EA8E-4A7C-9001-89BAD932F9D9}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
     <ROW Component="ProductInformation" ComponentId="{DB078D04-EA8E-4A7C-9001-89BAD932F9D9}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
-    <ROW Component="RequiredApplication" ComponentId="{92E37C98-F8B3-4A85-AE77-3D8D9A223776}" Directory_="APPDIR" Attributes="4" Condition="VersionNT &gt;= 1000" KeyPath="RequiredApplication" Options="2"/>
     <ROW Component="i686" ComponentId="{6EC46014-3BFD-4017-ACBC-C4417D1D6361}" Directory_="i686_1_Dir" Attributes="0"/>
     <ROW Component="i686" ComponentId="{6EC46014-3BFD-4017-ACBC-C4417D1D6361}" Directory_="i686_1_Dir" Attributes="0"/>
     <ROW Component="networks.d" ComponentId="{EF54D0DF-889F-41DC-AF5C-4E7F96AB1C8B}" Directory_="networks.d_Dir" Attributes="0"/>
     <ROW Component="networks.d" ComponentId="{EF54D0DF-889F-41DC-AF5C-4E7F96AB1C8B}" Directory_="networks.d_Dir" Attributes="0"/>
     <ROW Component="regid.201001.com.zerotier" ComponentId="{A39C80FC-6A8F-454F-9052-10DAC3C3B139}" Directory_="regid.201001.com.zerotier_Dir" Attributes="0"/>
     <ROW Component="regid.201001.com.zerotier" ComponentId="{A39C80FC-6A8F-454F-9052-10DAC3C3B139}" Directory_="regid.201001.com.zerotier_Dir" Attributes="0"/>
@@ -84,10 +85,7 @@
     <ROW Component="zttap300_x86_win10" ComponentId="{9F913E48-095B-4EA3-98DA-EDAB1593F3E3}" Directory_="x86_Dir" Attributes="0" Condition="NOT VersionNT64" KeyPath="zttap300.cat_3" Type="0"/>
     <ROW Component="zttap300_x86_win10" ComponentId="{9F913E48-095B-4EA3-98DA-EDAB1593F3E3}" Directory_="x86_Dir" Attributes="0" Condition="NOT VersionNT64" KeyPath="zttap300.cat_3" Type="0"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
-    <ROW Feature="A918597FE054CCCB65ABDBA0AD8F63C" Title="Visual C++ Redistributable for Visual Studio 2015-2019 x86" Description="Visual C++ Redistributable for Visual Studio 2015-2019 x86" Display="3" Level="1" Attributes="0"/>
-    <ROW Feature="C4FE6FD5B7C4D07B3A313E754A9A6A8" Title="Visual C++ Redistributable for Visual Studio 2015-2019 x64" Description="Visual C++ Redistributable for Visual Studio 2015-2019 x64" Display="5" Level="1" Attributes="0"/>
     <ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0"/>
     <ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0"/>
-    <ROW Feature="RequiredApplication" Title="Microsoft Edge Webview2 Runtime" Description="Microsoft Edge Webview2 Runtime" Display="7" Level="1" Attributes="0"/>
     <ROW Feature="ZeroTierOne" Title="MainFeature" Description="ZeroTier One" Display="0" Level="1" Directory_="APPDIR" Attributes="0"/>
     <ROW Feature="ZeroTierOne" Title="MainFeature" Description="ZeroTier One" Display="0" Level="1" Directory_="APPDIR" Attributes="0"/>
     <ATTRIBUTE name="CurrentFeature" value="ZeroTierOne"/>
     <ATTRIBUTE name="CurrentFeature" value="ZeroTierOne"/>
   </COMPONENT>
   </COMPONENT>
@@ -102,6 +100,7 @@
     <ROW File="zttap300.inf_1" Component_="zttap300_x86_win10" FileName="zttap300.inf" Attributes="0" SourcePath="..\..\bin\tap-windows-ndis6\x86\zttap300.inf" SelfReg="false"/>
     <ROW File="zttap300.inf_1" Component_="zttap300_x86_win10" FileName="zttap300.inf" Attributes="0" SourcePath="..\..\bin\tap-windows-ndis6\x86\zttap300.inf" SelfReg="false"/>
     <ROW File="zerotier_desktop_ui.exe" Component_="zerotier_desktop_ui.exe" FileName="ZEROTI~2.EXE|zerotier_desktop_ui.exe" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\..\..\..\DesktopUI\target\x86_64-pc-windows-msvc\release\zerotier_desktop_ui.exe" SelfReg="false" DigSign="true"/>
     <ROW File="zerotier_desktop_ui.exe" Component_="zerotier_desktop_ui.exe" FileName="ZEROTI~2.EXE|zerotier_desktop_ui.exe" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\..\..\..\DesktopUI\target\x86_64-pc-windows-msvc\release\zerotier_desktop_ui.exe" SelfReg="false" DigSign="true"/>
     <ROW File="zerotier_desktop_ui.exe_1" Component_="zerotier_desktop_ui.exe_1" FileName="ZEROTI~1.EXE|zerotier_desktop_ui.exe" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\..\..\..\DesktopUI\target\i686-pc-windows-msvc\release\zerotier_desktop_ui.exe" SelfReg="false" DigSign="true"/>
     <ROW File="zerotier_desktop_ui.exe_1" Component_="zerotier_desktop_ui.exe_1" FileName="ZEROTI~1.EXE|zerotier_desktop_ui.exe" Version="65535.65535.65535.65535" Attributes="0" SourcePath="..\..\..\..\DesktopUI\target\i686-pc-windows-msvc\release\zerotier_desktop_ui.exe" SelfReg="false" DigSign="true"/>
+    <ROW File="MicrosoftEdgeWebview2Setup.exe" Component_="MicrosoftEdgeWebview2Setup.exe" FileName="MICROS~1.EXE|MicrosoftEdgeWebview2Setup.exe" Version="65535.65535.65535.65535" Attributes="0" SourcePath="Prerequisites\WebView2\MicrosoftEdgeWebview2Setup.exe" SelfReg="false"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.custcomp.AiComponentAliasComponent">
   <COMPONENT cid="caphyon.advinst.custcomp.AiComponentAliasComponent">
     <ROW AliasRowId="AI_CustomARPName" AliasRowOperation="2" Condition="#DefaultBuild:ZTHEADLESS=&quot;No&quot;"/>
     <ROW AliasRowId="AI_CustomARPName" AliasRowOperation="2" Condition="#DefaultBuild:ZTHEADLESS=&quot;No&quot;"/>
@@ -155,25 +154,19 @@
     <ROW Fragment="WelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\WelcomeDlg.aip"/>
     <ROW Fragment="WelcomeDlg.aip" Path="&lt;AI_THEMES&gt;classic\fragments\WelcomeDlg.aip"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
-    <ROW Action="AI_ConfigureChainer" Description="Configuring prerequisites launcher" DescriptionLocId="ActionText.Description.AI_ConfigureChainer" Template="Configure Launcher" TemplateLocId="ActionText.Template.AI_ConfigureChainer"/>
     <ROW Action="AI_DeleteLzma" Description="Deleting files extracted from archive" DescriptionLocId="ActionText.Description.AI_DeleteLzma" TemplateLocId="-"/>
     <ROW Action="AI_DeleteLzma" Description="Deleting files extracted from archive" DescriptionLocId="ActionText.Description.AI_DeleteLzma" TemplateLocId="-"/>
     <ROW Action="AI_DeleteRLzma" Description="Deleting files extracted from archive" DescriptionLocId="ActionText.Description.AI_DeleteLzma" TemplateLocId="-"/>
     <ROW Action="AI_DeleteRLzma" Description="Deleting files extracted from archive" DescriptionLocId="ActionText.Description.AI_DeleteLzma" TemplateLocId="-"/>
-    <ROW Action="AI_DownloadPrereq" Description="Downloading prerequisite software" DescriptionLocId="ActionText.Description.AI_DownloadPrereq" Template="Downloading [1]{[2] completed}" TemplateLocId="ActionText.Template.AI_DownloadPrereq"/>
     <ROW Action="AI_ExtractFiles" Description="Extracting files from archive" DescriptionLocId="ActionText.Description.AI_ExtractLzma" TemplateLocId="-"/>
     <ROW Action="AI_ExtractFiles" Description="Extracting files from archive" DescriptionLocId="ActionText.Description.AI_ExtractLzma" TemplateLocId="-"/>
     <ROW Action="AI_ExtractLzma" Description="Extracting files from archive" DescriptionLocId="ActionText.Description.AI_ExtractLzma" TemplateLocId="-"/>
     <ROW Action="AI_ExtractLzma" Description="Extracting files from archive" DescriptionLocId="ActionText.Description.AI_ExtractLzma" TemplateLocId="-"/>
-    <ROW Action="AI_ExtractPrereq" Description="Extracting prerequisite software" DescriptionLocId="ActionText.Description.AI_ExtractPrereq" Template="Extracting [1]{[2] completed}" TemplateLocId="ActionText.Template.AI_ExtractPrereq"/>
     <ROW Action="AI_FwConfig" Description="Executing Windows Firewall configurations" DescriptionLocId="ActionText.Description.AI_FwConfig" Template="Configuring Windows Firewall rule: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_FwConfig"/>
     <ROW Action="AI_FwConfig" Description="Executing Windows Firewall configurations" DescriptionLocId="ActionText.Description.AI_FwConfig" Template="Configuring Windows Firewall rule: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_FwConfig"/>
     <ROW Action="AI_FwInstall" Description="Generating actions to configure Windows Firewall" DescriptionLocId="ActionText.Description.AI_FwInstall"/>
     <ROW Action="AI_FwInstall" Description="Generating actions to configure Windows Firewall" DescriptionLocId="ActionText.Description.AI_FwInstall"/>
     <ROW Action="AI_FwRemove" Description="Executing Windows Firewall configurations" DescriptionLocId="ActionText.Description.AI_FwRemove" Template="Configuring Windows Firewall rule:  &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_FwRemove"/>
     <ROW Action="AI_FwRemove" Description="Executing Windows Firewall configurations" DescriptionLocId="ActionText.Description.AI_FwRemove" Template="Configuring Windows Firewall rule:  &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_FwRemove"/>
     <ROW Action="AI_FwRollback" Description="Rolling back Windows Firewall configurations." DescriptionLocId="ActionText.Description.AI_FwRollback" Template="Rolling back Windows Firewall configurations." TemplateLocId="ActionText.Template.AI_FwRollback"/>
     <ROW Action="AI_FwRollback" Description="Rolling back Windows Firewall configurations." DescriptionLocId="ActionText.Description.AI_FwRollback" Template="Rolling back Windows Firewall configurations." TemplateLocId="ActionText.Template.AI_FwRollback"/>
     <ROW Action="AI_FwUninstall" Description="Generating actions to configure Windows Firewall" DescriptionLocId="ActionText.Description.AI_FwUninstall"/>
     <ROW Action="AI_FwUninstall" Description="Generating actions to configure Windows Firewall" DescriptionLocId="ActionText.Description.AI_FwUninstall"/>
-    <ROW Action="AI_InstallPostPrerequisite" Description="Installing prerequisite software" DescriptionLocId="ActionText.Description.AI_InstallPrerequisite" Template="Installing [1]{[2] completed}" TemplateLocId="ActionText.Template.AI_InstallPrerequisite"/>
-    <ROW Action="AI_InstallPrerequisite" Description="Installing prerequisite software" DescriptionLocId="ActionText.Description.AI_InstallPrerequisite" Template="Installing [1]{[2] completed}" TemplateLocId="ActionText.Template.AI_InstallPrerequisite"/>
     <ROW Action="AI_TxtUpdaterCommit" Description="Commit text file changes. " DescriptionLocId="ActionText.Description.AI_TxtUpdaterCommit" Template="Commit text file changes." TemplateLocId="ActionText.Template.AI_TxtUpdaterCommit"/>
     <ROW Action="AI_TxtUpdaterCommit" Description="Commit text file changes. " DescriptionLocId="ActionText.Description.AI_TxtUpdaterCommit" Template="Commit text file changes." TemplateLocId="ActionText.Template.AI_TxtUpdaterCommit"/>
     <ROW Action="AI_TxtUpdaterConfig" Description="Executing text file updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterConfig" Template="Updating text file: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_TxtUpdaterConfig"/>
     <ROW Action="AI_TxtUpdaterConfig" Description="Executing text file updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterConfig" Template="Updating text file: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_TxtUpdaterConfig"/>
     <ROW Action="AI_TxtUpdaterInstall" Description="Generating actions to configure text files updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterInstall"/>
     <ROW Action="AI_TxtUpdaterInstall" Description="Generating actions to configure text files updates" DescriptionLocId="ActionText.Description.AI_TxtUpdaterInstall"/>
     <ROW Action="AI_TxtUpdaterRollback" Description="Rolling back text file changes. " DescriptionLocId="ActionText.Description.AI_TxtUpdaterRollback" Template="Rolling back text file changes." TemplateLocId="ActionText.Template.AI_TxtUpdaterRollback"/>
     <ROW Action="AI_TxtUpdaterRollback" Description="Rolling back text file changes. " DescriptionLocId="ActionText.Description.AI_TxtUpdaterRollback" Template="Rolling back text file changes." TemplateLocId="ActionText.Template.AI_TxtUpdaterRollback"/>
-    <ROW Action="AI_VerifyPrereq" Description="Verifying prerequisites" DescriptionLocId="ActionText.Description.AI_VerifyPrereq" Template="[1] was not installed correctly." TemplateLocId="ActionText.Template.AI_VerifyPrereq"/>
     <ROW Action="AI_XmlCommit" Description="Committing XML file configurations." DescriptionLocId="ActionText.Description.AI_XmlCommit" Template="Committing XML file configurations." TemplateLocId="ActionText.Template.AI_XmlCommit"/>
     <ROW Action="AI_XmlCommit" Description="Committing XML file configurations." DescriptionLocId="ActionText.Description.AI_XmlCommit" Template="Committing XML file configurations." TemplateLocId="ActionText.Template.AI_XmlCommit"/>
     <ROW Action="AI_XmlConfig" Description="Executing XML file configurations" DescriptionLocId="ActionText.Description.AI_XmlConfig" Template="Configuring XML file: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_XmlConfig"/>
     <ROW Action="AI_XmlConfig" Description="Executing XML file configurations" DescriptionLocId="ActionText.Description.AI_XmlConfig" Template="Configuring XML file: &quot;[1]&quot;" TemplateLocId="ActionText.Template.AI_XmlConfig"/>
     <ROW Action="AI_XmlInstall" Description="Generating actions to configure XML files" DescriptionLocId="ActionText.Description.AI_XmlInstall"/>
     <ROW Action="AI_XmlInstall" Description="Generating actions to configure XML files" DescriptionLocId="ActionText.Description.AI_XmlInstall"/>
@@ -192,9 +185,7 @@
     <ROW Name="SoftwareDetector.dll" SourcePath="&lt;AI_CUSTACTS&gt;SoftwareDetector.dll"/>
     <ROW Name="SoftwareDetector.dll" SourcePath="&lt;AI_CUSTACTS&gt;SoftwareDetector.dll"/>
     <ROW Name="TxtUpdater.dll" SourcePath="&lt;AI_CUSTACTS&gt;TxtUpdater.dll"/>
     <ROW Name="TxtUpdater.dll" SourcePath="&lt;AI_CUSTACTS&gt;TxtUpdater.dll"/>
     <ROW Name="aicustact.dll" SourcePath="&lt;AI_CUSTACTS&gt;aicustact.dll"/>
     <ROW Name="aicustact.dll" SourcePath="&lt;AI_CUSTACTS&gt;aicustact.dll"/>
-    <ROW Name="aipackagechainer.exe" SourcePath="&lt;AI_CUSTACTS&gt;aipackagechainer.exe"/>
     <ROW Name="chainersupport.dll" SourcePath="&lt;AI_CUSTACTS&gt;chainersupport.dll"/>
     <ROW Name="chainersupport.dll" SourcePath="&lt;AI_CUSTACTS&gt;chainersupport.dll"/>
-    <ROW Name="file_deleter.ps1" SourcePath="&lt;AI_SCRIPTS&gt;file_deleter.ps1"/>
     <ROW Name="lzmaextractor.dll" SourcePath="&lt;AI_CUSTACTS&gt;lzmaextractor.dll"/>
     <ROW Name="lzmaextractor.dll" SourcePath="&lt;AI_CUSTACTS&gt;lzmaextractor.dll"/>
     <ROW Name="msichainer.exe" SourcePath="&lt;AI_CUSTACTS&gt;msichainer.exe"/>
     <ROW Name="msichainer.exe" SourcePath="&lt;AI_CUSTACTS&gt;msichainer.exe"/>
     <ROW Name="viewer.exe" SourcePath="&lt;AI_CUSTACTS&gt;viewer.exe"/>
     <ROW Name="viewer.exe" SourcePath="&lt;AI_CUSTACTS&gt;viewer.exe"/>
@@ -242,9 +233,6 @@
     <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
     <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/>
     <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
     <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/>
     <ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
     <ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/>
-    <ROW Dialog_="ExitDialog" Control_="Finish" Event="DoAction" Argument="AI_CleanPrereq" Condition="1" Ordering="301"/>
-    <ROW Dialog_="FatalError" Control_="Finish" Event="DoAction" Argument="AI_CleanPrereq" Condition="1" Ordering="102"/>
-    <ROW Dialog_="UserExit" Control_="Finish" Event="DoAction" Argument="AI_CleanPrereq" Condition="1" Ordering="101"/>
     <ROW Dialog_="Windows7Warning" Control_="Cancel" Event="SpawnDialog" Argument="CancelDlg" Condition="1" Ordering="100"/>
     <ROW Dialog_="Windows7Warning" Control_="Cancel" Event="SpawnDialog" Argument="CancelDlg" Condition="1" Ordering="100"/>
     <ROW Dialog_="WelcomeDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfRbDiskDlg" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST=&quot;P&quot; OR NOT PROMPTROLLBACKCOST)" Ordering="5" Options="2"/>
     <ROW Dialog_="WelcomeDlg" Control_="Next" Event="SpawnDialog" Argument="OutOfRbDiskDlg" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST=&quot;P&quot; OR NOT PROMPTROLLBACKCOST)" Ordering="5" Options="2"/>
     <ROW Dialog_="WelcomeDlg" Control_="Next" Event="EnableRollback" Argument="False" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST=&quot;D&quot;" Ordering="6" Options="2"/>
     <ROW Dialog_="WelcomeDlg" Control_="Next" Event="EnableRollback" Argument="False" Condition="AI_INSTALL AND OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST=&quot;D&quot;" Ordering="6" Options="2"/>
@@ -267,9 +255,7 @@
     <ROW Action="AI_AppSearchEx" Type="1" Source="Prereq.dll" Target="DoAppSearchEx"/>
     <ROW Action="AI_AppSearchEx" Type="1" Source="Prereq.dll" Target="DoAppSearchEx"/>
     <ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
     <ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
     <ROW Action="AI_ChainerScheduleReboot" Type="1" Source="chainersupport.dll" Target="ScheduleReboot" WithoutSeq="true"/>
     <ROW Action="AI_ChainerScheduleReboot" Type="1" Source="chainersupport.dll" Target="ScheduleReboot" WithoutSeq="true"/>
-    <ROW Action="AI_CleanPrereq" Type="65" Source="Prereq.dll" Target="CleanPrereq" WithoutSeq="true"/>
     <ROW Action="AI_CommitChainers" Type="11841" Source="chainersupport.dll" Target="CommitChainedPackages" WithoutSeq="true"/>
     <ROW Action="AI_CommitChainers" Type="11841" Source="chainersupport.dll" Target="CommitChainedPackages" WithoutSeq="true"/>
-    <ROW Action="AI_ConfigureChainer" Type="1" Source="Prereq.dll" Target="ConfigurePrereqLauncher"/>
     <ROW Action="AI_DATA_SETTER" Type="51" Source="CustomActionData" Target="[~]"/>
     <ROW Action="AI_DATA_SETTER" Type="51" Source="CustomActionData" Target="[~]"/>
     <ROW Action="AI_DATA_SETTER_1" Type="51" Source="CustomActionData" Target="[~]"/>
     <ROW Action="AI_DATA_SETTER_1" Type="51" Source="CustomActionData" Target="[~]"/>
     <ROW Action="AI_DATA_SETTER_2" Type="51" Source="CustomActionData" Target="[~]"/>
     <ROW Action="AI_DATA_SETTER_2" Type="51" Source="CustomActionData" Target="[~]"/>
@@ -284,13 +270,11 @@
     <ROW Action="AI_DeleteRLzma" Type="1281" Source="lzmaextractor.dll" Target="DeleteLZMAFiles"/>
     <ROW Action="AI_DeleteRLzma" Type="1281" Source="lzmaextractor.dll" Target="DeleteLZMAFiles"/>
     <ROW Action="AI_DetectSoftware" Type="257" Source="SoftwareDetector.dll" Target="OnDetectSoftware"/>
     <ROW Action="AI_DetectSoftware" Type="257" Source="SoftwareDetector.dll" Target="OnDetectSoftware"/>
     <ROW Action="AI_DoRemoveExternalUIStub" Type="3585" Source="ExternalUICleaner.dll" Target="DoRemoveExternalUIStub" WithoutSeq="true"/>
     <ROW Action="AI_DoRemoveExternalUIStub" Type="3585" Source="ExternalUICleaner.dll" Target="DoRemoveExternalUIStub" WithoutSeq="true"/>
-    <ROW Action="AI_DownloadPrereq" Type="1" Source="Prereq.dll" Target="DownloadPrereq"/>
     <ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
     <ROW Action="AI_DpiContentScale" Type="1" Source="aicustact.dll" Target="DpiContentScale"/>
     <ROW Action="AI_EnableDebugLog" Type="321" Source="aicustact.dll" Target="EnableDebugLog"/>
     <ROW Action="AI_EnableDebugLog" Type="321" Source="aicustact.dll" Target="EnableDebugLog"/>
     <ROW Action="AI_ExtractCadLzma" Type="51" Source="AI_ExtractLzma" Target="[AI_SETUPEXEPATH]"/>
     <ROW Action="AI_ExtractCadLzma" Type="51" Source="AI_ExtractLzma" Target="[AI_SETUPEXEPATH]"/>
     <ROW Action="AI_ExtractFiles" Type="1" Source="Prereq.dll" Target="ExtractSourceFiles" AdditionalSeq="AI_DATA_SETTER_4"/>
     <ROW Action="AI_ExtractFiles" Type="1" Source="Prereq.dll" Target="ExtractSourceFiles" AdditionalSeq="AI_DATA_SETTER_4"/>
     <ROW Action="AI_ExtractLzma" Type="1025" Source="lzmaextractor.dll" Target="ExtractLZMAFiles"/>
     <ROW Action="AI_ExtractLzma" Type="1025" Source="lzmaextractor.dll" Target="ExtractLZMAFiles"/>
-    <ROW Action="AI_ExtractPrereq" Type="65" Source="Prereq.dll" Target="ExtractPrereq"/>
     <ROW Action="AI_FindExeLzma" Type="1" Source="lzmaextractor.dll" Target="FindEXE"/>
     <ROW Action="AI_FindExeLzma" Type="1" Source="lzmaextractor.dll" Target="FindEXE"/>
     <ROW Action="AI_FwConfig" Type="11265" Source="NetFirewall.dll" Target="OnFwConfig" WithoutSeq="true"/>
     <ROW Action="AI_FwConfig" Type="11265" Source="NetFirewall.dll" Target="OnFwConfig" WithoutSeq="true"/>
     <ROW Action="AI_FwInstall" Type="1" Source="NetFirewall.dll" Target="OnFwInstall" AdditionalSeq="AI_DATA_SETTER_2"/>
     <ROW Action="AI_FwInstall" Type="1" Source="NetFirewall.dll" Target="OnFwInstall" AdditionalSeq="AI_DATA_SETTER_2"/>
@@ -299,9 +283,6 @@
     <ROW Action="AI_FwUninstall" Type="1" Source="NetFirewall.dll" Target="OnFwUninstall" AdditionalSeq="AI_DATA_SETTER_3"/>
     <ROW Action="AI_FwUninstall" Type="1" Source="NetFirewall.dll" Target="OnFwUninstall" AdditionalSeq="AI_DATA_SETTER_3"/>
     <ROW Action="AI_GetArpIconPath" Type="1" Source="aicustact.dll" Target="GetArpIconPath"/>
     <ROW Action="AI_GetArpIconPath" Type="1" Source="aicustact.dll" Target="GetArpIconPath"/>
     <ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
     <ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/>
-    <ROW Action="AI_InstallPostPrerequisite" Type="1" Source="Prereq.dll" Target="InstallPostPrereq"/>
-    <ROW Action="AI_InstallPrerequisite" Type="1" Source="Prereq.dll" Target="InstallPrereq"/>
-    <ROW Action="AI_LaunchChainer" Type="3314" Source="AI_PREREQ_CHAINER"/>
     <ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
     <ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/>
     <ROW Action="AI_PrepareChainers" Type="1" Source="chainersupport.dll" Target="PrepareChainedPackages"/>
     <ROW Action="AI_PrepareChainers" Type="1" Source="chainersupport.dll" Target="PrepareChainedPackages"/>
     <ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH" Target="[AI_SETUPEXEPATH_ORIGINAL]"/>
     <ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH" Target="[AI_SETUPEXEPATH_ORIGINAL]"/>
@@ -315,7 +296,6 @@
     <ROW Action="AI_TxtUpdaterConfig" Type="11265" Source="TxtUpdater.dll" Target="OnTxtUpdaterConfig" WithoutSeq="true"/>
     <ROW Action="AI_TxtUpdaterConfig" Type="11265" Source="TxtUpdater.dll" Target="OnTxtUpdaterConfig" WithoutSeq="true"/>
     <ROW Action="AI_TxtUpdaterInstall" Type="1" Source="TxtUpdater.dll" Target="OnTxtUpdaterInstall"/>
     <ROW Action="AI_TxtUpdaterInstall" Type="1" Source="TxtUpdater.dll" Target="OnTxtUpdaterInstall"/>
     <ROW Action="AI_TxtUpdaterRollback" Type="11521" Source="TxtUpdater.dll" Target="OnTxtUpdaterRollback" WithoutSeq="true"/>
     <ROW Action="AI_TxtUpdaterRollback" Type="11521" Source="TxtUpdater.dll" Target="OnTxtUpdaterRollback" WithoutSeq="true"/>
-    <ROW Action="AI_VerifyPrereq" Type="1" Source="Prereq.dll" Target="VerifyPrereq"/>
     <ROW Action="AI_XmlCommit" Type="11777" Source="xmlCfg.dll" Target="OnXmlCommit" WithoutSeq="true"/>
     <ROW Action="AI_XmlCommit" Type="11777" Source="xmlCfg.dll" Target="OnXmlCommit" WithoutSeq="true"/>
     <ROW Action="AI_XmlConfig" Type="11265" Source="xmlCfg.dll" Target="OnXmlConfig" WithoutSeq="true"/>
     <ROW Action="AI_XmlConfig" Type="11265" Source="xmlCfg.dll" Target="OnXmlConfig" WithoutSeq="true"/>
     <ROW Action="AI_XmlInstall" Type="1" Source="xmlCfg.dll" Target="OnXmlInstall" AdditionalSeq="AI_DATA_SETTER"/>
     <ROW Action="AI_XmlInstall" Type="1" Source="xmlCfg.dll" Target="OnXmlInstall" AdditionalSeq="AI_DATA_SETTER"/>
@@ -323,6 +303,7 @@
     <ROW Action="AI_XmlRollback" Type="11521" Source="xmlCfg.dll" Target="OnXmlRollback" WithoutSeq="true"/>
     <ROW Action="AI_XmlRollback" Type="11521" Source="xmlCfg.dll" Target="OnXmlRollback" WithoutSeq="true"/>
     <ROW Action="AI_XmlUninstall" Type="1" Source="xmlCfg.dll" Target="OnXmlUninstall" AdditionalSeq="AI_DATA_SETTER_1"/>
     <ROW Action="AI_XmlUninstall" Type="1" Source="xmlCfg.dll" Target="OnXmlUninstall" AdditionalSeq="AI_DATA_SETTER_1"/>
     <ROW Action="LaunchUI" Type="194" Source="viewer.exe" Target="/DontWait &quot;[APPDIR]zerotier_desktop_ui.exe&quot;" Options="1"/>
     <ROW Action="LaunchUI" Type="194" Source="viewer.exe" Target="/DontWait &quot;[APPDIR]zerotier_desktop_ui.exe&quot;" Options="1"/>
+    <ROW Action="MicrosoftEdgeWebview2Setup.exe" Type="3154" Source="MicrosoftEdgeWebview2Setup.exe" Target="/silent /install"/>
     <ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[ProgramFilesFolder]ZeroTier\One"/>
     <ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="DefaultBuild:[ProgramFilesFolder]ZeroTier\One"/>
     <ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
     <ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
     <ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
     <ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
@@ -353,11 +334,9 @@
     <ROW Feature_="ZeroTierOne" Component_="AI_DisableModify"/>
     <ROW Feature_="ZeroTierOne" Component_="AI_DisableModify"/>
     <ROW Feature_="ZeroTierOne" Component_="zerotier_desktop_ui.exe"/>
     <ROW Feature_="ZeroTierOne" Component_="zerotier_desktop_ui.exe"/>
     <ROW Feature_="ZeroTierOne" Component_="zerotier_desktop_ui.exe_1"/>
     <ROW Feature_="ZeroTierOne" Component_="zerotier_desktop_ui.exe_1"/>
-    <ROW Feature_="A918597FE054CCCB65ABDBA0AD8F63C" Component_="A918597FE054CCCB65ABDBA0AD8F63C"/>
-    <ROW Feature_="C4FE6FD5B7C4D07B3A313E754A9A6A8" Component_="C4FE6FD5B7C4D07B3A313E754A9A6A8"/>
-    <ROW Feature_="RequiredApplication" Component_="RequiredApplication"/>
     <ROW Feature_="ZeroTierOne" Component_="AI_ExePath"/>
     <ROW Feature_="ZeroTierOne" Component_="AI_ExePath"/>
     <ROW Feature_="ZeroTierOne" Component_="i686"/>
     <ROW Feature_="ZeroTierOne" Component_="i686"/>
+    <ROW Feature_="ZeroTierOne" Component_="MicrosoftEdgeWebview2Setup.exe"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
     <ROW Name="ZeroTierIcon.exe" SourcePath="..\..\..\artwork\ZeroTierIcon.ico" Index="0"/>
     <ROW Name="ZeroTierIcon.exe" SourcePath="..\..\..\artwork\ZeroTierIcon.ico" Index="0"/>
@@ -372,7 +351,7 @@
     <ROW Action="AI_DATA_SETTER" Condition="(REMOVE &lt;&gt; &quot;ALL&quot;)" Sequence="5102"/>
     <ROW Action="AI_DATA_SETTER" Condition="(REMOVE &lt;&gt; &quot;ALL&quot;)" Sequence="5102"/>
     <ROW Action="AI_XmlUninstall" Condition="(REMOVE)" Sequence="3102"/>
     <ROW Action="AI_XmlUninstall" Condition="(REMOVE)" Sequence="3102"/>
     <ROW Action="AI_DATA_SETTER_1" Condition="(REMOVE)" Sequence="3101"/>
     <ROW Action="AI_DATA_SETTER_1" Condition="(REMOVE)" Sequence="3101"/>
-    <ROW Action="InstallFinalize" Sequence="6602" SeqType="0" MsiKey="InstallFinalize"/>
+    <ROW Action="InstallFinalize" Sequence="6603" SeqType="0" MsiKey="InstallFinalize"/>
     <ROW Action="AI_RemoveExternalUIStub" Condition="(REMOVE=&quot;ALL&quot;) AND ((VersionNT &gt; 500) OR((VersionNT = 500) AND (ServicePackLevel &gt;= 4)))" Sequence="1501"/>
     <ROW Action="AI_RemoveExternalUIStub" Condition="(REMOVE=&quot;ALL&quot;) AND ((VersionNT &gt; 500) OR((VersionNT = 500) AND (ServicePackLevel &gt;= 4)))" Sequence="1501"/>
     <ROW Action="TapDeviceRemove32" Condition="( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) AND NOT UPGRADINGPRODUCTCODE ) AND ( NOT VersionNT64 )" Sequence="1605"/>
     <ROW Action="TapDeviceRemove32" Condition="( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) AND NOT UPGRADINGPRODUCTCODE ) AND ( NOT VersionNT64 )" Sequence="1605"/>
     <ROW Action="TapDeviceRemove64" Condition="( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) AND NOT UPGRADINGPRODUCTCODE ) AND ( VersionNT64 )" Sequence="1606"/>
     <ROW Action="TapDeviceRemove64" Condition="( Installed AND ( REMOVE = &quot;ALL&quot; OR AI_INSTALL_MODE = &quot;Remove&quot; ) AND NOT UPGRADINGPRODUCTCODE ) AND ( VersionNT64 )" Sequence="1606"/>
@@ -401,10 +380,8 @@
     <ROW Action="AI_GetArpIconPath" Sequence="1401"/>
     <ROW Action="AI_GetArpIconPath" Sequence="1401"/>
     <ROW Action="TerminateUINew" Sequence="1604"/>
     <ROW Action="TerminateUINew" Sequence="1604"/>
     <ROW Action="AI_DATA_SETTER_5" Sequence="1603"/>
     <ROW Action="AI_DATA_SETTER_5" Sequence="1603"/>
-    <ROW Action="AI_ConfigureChainer" Condition="((UILevel = 2) OR (UILevel = 3)) AND (NOT UPGRADINGPRODUCTCODE)" Sequence="6600"/>
-    <ROW Action="AI_LaunchChainer" Condition="AI_PREREQ_CHAINER AND (NOT UPGRADINGPRODUCTCODE)" Sequence="6601"/>
-    <ROW Action="AI_VerifyPrereq" Sequence="1101"/>
-    <ROW Action="LaunchUI" Condition="( NOT Installed ) AND ( ZTHEADLESS = &quot;No&quot; )" Sequence="6603"/>
+    <ROW Action="LaunchUI" Condition="( NOT Installed ) AND ( ZTHEADLESS = &quot;No&quot; )" Sequence="6604"/>
+    <ROW Action="MicrosoftEdgeWebview2Setup.exe" Condition="( NOT Installed )" Sequence="6401"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
     <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
     <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=&quot;&quot;" Sequence="749"/>
@@ -416,11 +393,6 @@
     <ROW Action="AI_DetectSoftware" Sequence="102"/>
     <ROW Action="AI_DetectSoftware" Sequence="102"/>
     <ROW Action="AI_EnableDebugLog" Sequence="51"/>
     <ROW Action="AI_EnableDebugLog" Sequence="51"/>
     <ROW Action="AI_AppSearchEx" Sequence="101"/>
     <ROW Action="AI_AppSearchEx" Sequence="101"/>
-    <ROW Action="AI_DownloadPrereq" Sequence="1296"/>
-    <ROW Action="AI_ExtractPrereq" Sequence="1297"/>
-    <ROW Action="AI_InstallPrerequisite" Sequence="1298"/>
-    <ROW Action="AI_InstallPostPrerequisite" Sequence="1300"/>
-    <ROW Action="AI_CleanPrereq" Sequence="1301"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent">
     <ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 &lt;&gt; 600) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 600) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType = 1)) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
     <ROW Condition="( Version9X OR ( NOT VersionNT64 ) OR ( VersionNT64 AND ((VersionNT64 &lt;&gt; 600) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 600) OR (MsiNTProductType = 1)) AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType &lt;&gt; 1)) AND ((VersionNT64 &lt;&gt; 601) OR (MsiNTProductType = 1)) ) )" Description="[ProductName] cannot be installed on the following Windows versions: [WindowsTypeNT64Display]." DescriptionLocId="AI.LaunchCondition.NoSpecificNT64" IsPredefined="true" Builds="DefaultBuild"/>
@@ -438,10 +410,8 @@
     <ROW Signature_="AI_EXE_PATH_LM" Root="2" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Type="2"/>
     <ROW Signature_="AI_EXE_PATH_LM" Root="2" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Type="2"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.MsiRegsComponent">
-    <ROW Registry="A918597FE054CCCB65ABDBA0AD8F63C" Root="-1" Key="Software\Caphyon\Advanced Installer\Prereqs\[ProductCode]\[ProductVersion]" Name="A918597FE054CCCB65ABDBA0AD8F63C" Value="1" Component_="A918597FE054CCCB65ABDBA0AD8F63C"/>
     <ROW Registry="AI_ExePath" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Value="[AI_SETUPEXEPATH]" Component_="AI_ExePath"/>
     <ROW Registry="AI_ExePath" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="AI_ExePath" Value="[AI_SETUPEXEPATH]" Component_="AI_ExePath"/>
     <ROW Registry="AdvancedInstaller" Root="-1" Key="Software\Caphyon\Advanced Installer" Name="\"/>
     <ROW Registry="AdvancedInstaller" Root="-1" Key="Software\Caphyon\Advanced Installer" Name="\"/>
-    <ROW Registry="C4FE6FD5B7C4D07B3A313E754A9A6A8" Root="-1" Key="Software\Caphyon\Advanced Installer\Prereqs\[ProductCode]\[ProductVersion]" Name="C4FE6FD5B7C4D07B3A313E754A9A6A8" Value="1" Component_="C4FE6FD5B7C4D07B3A313E754A9A6A8"/>
     <ROW Registry="Caphyon" Root="-1" Key="Software\Caphyon" Name="\"/>
     <ROW Registry="Caphyon" Root="-1" Key="Software\Caphyon" Name="\"/>
     <ROW Registry="Comments" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Comments" Value="[ARPCOMMENTS]" Component_="AI_CustomARPName"/>
     <ROW Registry="Comments" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Comments" Value="[ARPCOMMENTS]" Component_="AI_CustomARPName"/>
     <ROW Registry="Contact" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Contact" Value="[ARPCONTACT]" Component_="AI_CustomARPName"/>
     <ROW Registry="Contact" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Contact" Value="[ARPCONTACT]" Component_="AI_CustomARPName"/>
@@ -460,16 +430,12 @@
     <ROW Registry="NoModify" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoModify" Value="#1" Component_="AI_DisableModify" VirtualValue="#"/>
     <ROW Registry="NoModify" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoModify" Value="#1" Component_="AI_DisableModify" VirtualValue="#"/>
     <ROW Registry="NoRepair" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoRepair" Value="#1" Component_="AI_CustomARPName" VirtualValue="#"/>
     <ROW Registry="NoRepair" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="NoRepair" Value="#1" Component_="AI_CustomARPName" VirtualValue="#"/>
     <ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
     <ROW Registry="Path" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
-    <ROW Registry="Prereqs" Root="-1" Key="Software\Caphyon\Advanced Installer\Prereqs" Name="\"/>
-    <ROW Registry="ProductCode" Root="-1" Key="Software\Caphyon\Advanced Installer\Prereqs\[ProductCode]" Name="\"/>
     <ROW Registry="ProductCode_1" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]" Name="\"/>
     <ROW Registry="ProductCode_1" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]" Name="\"/>
     <ROW Registry="ProductName" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="\"/>
     <ROW Registry="ProductName" Root="-1" Key="Software\[Manufacturer]\[ProductName]" Name="\"/>
     <ROW Registry="ProductNameProductVersion" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="\"/>
     <ROW Registry="ProductNameProductVersion" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="\"/>
-    <ROW Registry="ProductVersion" Root="-1" Key="Software\Caphyon\Advanced Installer\Prereqs\[ProductCode]\[ProductVersion]" Name="\"/>
     <ROW Registry="ProductVersion_1" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="\"/>
     <ROW Registry="ProductVersion_1" Root="-1" Key="Software\Caphyon\Advanced Installer\LZMA\[ProductCode]\[ProductVersion]" Name="\"/>
     <ROW Registry="Publisher" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Publisher" Value="[Manufacturer]" Component_="AI_CustomARPName"/>
     <ROW Registry="Publisher" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Publisher" Value="[Manufacturer]" Component_="AI_CustomARPName"/>
     <ROW Registry="Readme" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Readme" Value="[ARPREADME]" Component_="AI_CustomARPName"/>
     <ROW Registry="Readme" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="Readme" Value="[ARPREADME]" Component_="AI_CustomARPName"/>
-    <ROW Registry="RequiredApplication" Root="-1" Key="Software\Caphyon\Advanced Installer\Prereqs\[ProductCode]\[ProductVersion]" Name="RequiredApplication" Value="1" Component_="RequiredApplication"/>
     <ROW Registry="Software" Root="-1" Key="Software" Name="\"/>
     <ROW Registry="Software" Root="-1" Key="Software" Name="\"/>
     <ROW Registry="URLInfoAbout" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="URLInfoAbout" Value="[ARPURLINFOABOUT]" Component_="AI_CustomARPName"/>
     <ROW Registry="URLInfoAbout" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="URLInfoAbout" Value="[ARPURLINFOABOUT]" Component_="AI_CustomARPName"/>
     <ROW Registry="URLUpdateInfo" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="URLUpdateInfo" Value="[ARPURLUPDATEINFO]" Component_="AI_CustomARPName"/>
     <ROW Registry="URLUpdateInfo" Root="-1" Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\[ProductName] [ProductVersion]" Name="URLUpdateInfo" Value="[ARPURLUPDATEINFO]" Component_="AI_CustomARPName"/>
@@ -500,18 +466,7 @@
     <ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
     <ROW UpgradeCode="[|UpgradeCode]" VersionMin="0.0.1" VersionMax="[|ProductVersion]" Attributes="257" ActionProperty="OLDPRODUCTS"/>
     <ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
     <ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/>
   </COMPONENT>
   </COMPONENT>
-  <COMPONENT cid="caphyon.advinst.msicomp.PreReqComponent">
-    <ROW PrereqKey="A918597FE054CCCB65ABDBA0AD8F63C" DisplayName="Visual C++ Redistributable for Visual Studio 2015-2019 x86" VersionMin="14.26" SetupFileUrl="https://download.visualstudio.microsoft.com/download/pr/d60aa805-26e9-47df-b4e3-cd6fcc392333/A06AAC66734A618AB33C1522920654DDFC44FC13CAFAA0F0AB85B199C3D51DC0/VC_redist.x86.exe" Location="1" ExactSize="14413048" WinNT64Versions="Windows XP/Vista/Windows 7/Windows 8 x64/Windows 8.1 x64/Windows 10 x64/Windows 11 x64" Operator="0" ComLine="/q /norestart" BasicUiComLine="/q /norestart" NoUiComLine="/q /norestart" Options="f" MD5="fe6eae1c34528d1ea224569dcdc35618" TargetName="Visual C++ Redistributable for Visual Studio 2015-2019" Feature="A918597FE054CCCB65ABDBA0AD8F63C"/>
-    <ROW PrereqKey="C4FE6FD5B7C4D07B3A313E754A9A6A8" DisplayName="Visual C++ Redistributable for Visual Studio 2015-2019 x64" VersionMin="14.26" SetupFileUrl="https://download.visualstudio.microsoft.com/download/pr/d60aa805-26e9-47df-b4e3-cd6fcc392333/7D7105C52FCD6766BEEE1AE162AA81E278686122C1E44890712326634D0B055E/VC_redist.x64.exe" Location="1" ExactSize="14974616" WinNTVersions="Windows 9x/ME/NT/2000/XP/Vista/Windows 7/Windows 8 x86/Windows 8.1 x86/Windows 10 x86" Operator="1" ComLine="/q /norestart" BasicUiComLine="/q /norestart" NoUiComLine="/q /norestart" Options="xf" MD5="264c296cc0bf00db6ba8e7bf8cc4e706" TargetName="Visual C++ Redistributable for Visual Studio 2015-2019" Feature="C4FE6FD5B7C4D07B3A313E754A9A6A8"/>
-    <ROW PrereqKey="RequiredApplication" DisplayName="Microsoft Edge Webview2 Runtime" SetupFileUrl="https://go.microsoft.com/fwlink/p/?LinkId=2124703" Location="1" ExactSize="0" Operator="1" ComLine="/silent /install" BasicUiComLine="/silent /install" NoUiComLine="/silent /install" Options="fx" TargetName="MicrosoftEdgeWebview2Setup.exe" Feature="RequiredApplication"/>
-    <ATTRIBUTE name="PrereqsOrder" value="A918597FE054CCCB65ABDBA0AD8F63C C4FE6FD5B7C4D07B3A313E754A9A6A8 RequiredApplication"/>
-  </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.PreReqSearchComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.PreReqSearchComponent">
-    <ROW SearchKey="A918597FE054CCCB65ABDBA0AD8F63CSyst" Prereq="A918597FE054CCCB65ABDBA0AD8F63C" SearchType="0" SearchString="[SystemFolder]vcruntime140.dll" VerMin="14.26.28720" Order="2" Property="PreReqSearch_1_A918597FE054CCCB65AB"/>
-    <ROW SearchKey="A918597FE054CCCB65ABDBA0AD8F63CVers" Prereq="A918597FE054CCCB65ABDBA0AD8F63C" SearchType="2" SearchString="HKLM\SOFTWARE\Microsoft\DevDiv\VC\Servicing\14.0\RuntimeMinimum\Version" VerMin="14.26.28720" Order="1" Property="PreReqSearch_A918597FE054CCCB65ABDB"/>
-    <ROW SearchKey="C4FE6FD5B7C4D07B3A313E754A9A6A8Vers" Prereq="C4FE6FD5B7C4D07B3A313E754A9A6A8" SearchType="2" SearchString="HKLM\SOFTWARE\Microsoft\DevDiv\VC\Servicing\14.0\RuntimeMinimum\Version" VerMin="14.26.28720" Order="1" Property="PreReqSearch_C4FE6FD5B7C4D07B3A313E" Platform="1"/>
-    <ROW SearchKey="F3017226FE2A42958BDF00C3A9A7E4C5" Prereq="RequiredApplication" SearchType="5" SearchString="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Order="2" Property="PreReqSearch_1" Platform="1"/>
-    <ROW SearchKey="SystemFolderfile.dll" Prereq="RequiredApplication" SearchType="5" SearchString="HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" Order="1" Property="PreReqSearch" Platform="1"/>
     <ROW SearchKey="UpgradeCode" SearchType="4" SearchString="{88AA80DE-14CA-4443-B024-6EC13F3EDDAD}" Order="2" Property="ZTTAP300_X86_INSTALLED"/>
     <ROW SearchKey="UpgradeCode" SearchType="4" SearchString="{88AA80DE-14CA-4443-B024-6EC13F3EDDAD}" Order="2" Property="ZTTAP300_X86_INSTALLED"/>
     <ROW SearchKey="_" SearchType="4" SearchString="{88AA80DE-14CA-4443-B024-6EC13F3EDDAD}" Order="1" Property="ZTTAP300_X64_INSTALLED"/>
     <ROW SearchKey="_" SearchType="4" SearchString="{88AA80DE-14CA-4443-B024-6EC13F3EDDAD}" Order="1" Property="ZTTAP300_X64_INSTALLED"/>
   </COMPONENT>
   </COMPONENT>
@@ -536,7 +491,7 @@
     <ROW XmlAttribute="xsischemaLocation" XmlElement="swidsoftware_identification_tag" Name="xsi:schemaLocation" Flags="14" Order="3" Value="http://standards.iso.org/iso/19770/-2/2008/schema.xsd software_identification_tag.xsd"/>
     <ROW XmlAttribute="xsischemaLocation" XmlElement="swidsoftware_identification_tag" Name="xsi:schemaLocation" Flags="14" Order="3" Value="http://standards.iso.org/iso/19770/-2/2008/schema.xsd software_identification_tag.xsd"/>
   </COMPONENT>
   </COMPONENT>
   <COMPONENT cid="caphyon.advinst.msicomp.XmlElementComponent">
   <COMPONENT cid="caphyon.advinst.msicomp.XmlElementComponent">
-    <ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Condition="1" Order="2" Flags="14" Text="6" UpdateIndexInParent="0"/>
+    <ROW XmlElement="swidbuild" ParentElement="swidnumeric" Name="swid:build" Condition="1" Order="2" Flags="14" Text="7" UpdateIndexInParent="0"/>
     <ROW XmlElement="swidentitlement_required_indicator" ParentElement="swidsoftware_identification_tag" Name="swid:entitlement_required_indicator" Condition="1" Order="0" Flags="14" Text="false" UpdateIndexInParent="0"/>
     <ROW XmlElement="swidentitlement_required_indicator" ParentElement="swidsoftware_identification_tag" Name="swid:entitlement_required_indicator" Condition="1" Order="0" Flags="14" Text="false" UpdateIndexInParent="0"/>
     <ROW XmlElement="swidmajor" ParentElement="swidnumeric" Name="swid:major" Condition="1" Order="0" Flags="14" Text="1" UpdateIndexInParent="0"/>
     <ROW XmlElement="swidmajor" ParentElement="swidnumeric" Name="swid:major" Condition="1" Order="0" Flags="14" Text="1" UpdateIndexInParent="0"/>
     <ROW XmlElement="swidminor" ParentElement="swidnumeric" Name="swid:minor" Condition="1" Order="1" Flags="14" Text="8" UpdateIndexInParent="0"/>
     <ROW XmlElement="swidminor" ParentElement="swidnumeric" Name="swid:minor" Condition="1" Order="1" Flags="14" Text="8" UpdateIndexInParent="0"/>

+ 5 - 3
windows/ZeroTierOne/ZeroTierOne.vcxproj

@@ -407,7 +407,7 @@
       <SDLCheck>true</SDLCheck>
       <SDLCheck>true</SDLCheck>
       <AdditionalIncludeDirectories>$(SolutionDir)\..\zeroidc\target;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>$(SolutionDir)\..\zeroidc\target;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;STATICLIB;ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;STATICLIB;ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
       <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
       <StringPooling>true</StringPooling>
       <StringPooling>true</StringPooling>
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
@@ -421,6 +421,7 @@
       <CompileAsManaged>false</CompileAsManaged>
       <CompileAsManaged>false</CompileAsManaged>
       <CompileAsWinRT>false</CompileAsWinRT>
       <CompileAsWinRT>false</CompileAsWinRT>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <EnableParallelCodeGeneration>false</EnableParallelCodeGeneration>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <GenerateDebugInformation>false</GenerateDebugInformation>
@@ -440,8 +441,8 @@
       <SDLCheck>true</SDLCheck>
       <SDLCheck>true</SDLCheck>
       <AdditionalIncludeDirectories>$(SolutionDir)\..\zeroidc\target;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>$(SolutionDir)\..\zeroidc\target;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <PreprocessorDefinitions>ZT_EXPORT;FD_SETSIZE=1024;STATICLIB;ZT_SOFTWARE_UPDATE_DEFAULT="apply";ZT_SALSA20_SSE;ZT_USE_MINIUPNPC;MINIUPNP_STATICLIB;WIN32;NOMINMAX;ZT_BUILD_PLATFORM=2;ZT_BUILD_ARCHITECTURE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
-      <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
       <StringPooling>true</StringPooling>
       <StringPooling>true</StringPooling>
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
       <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
       <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
       <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
@@ -456,6 +457,7 @@
       <CompileAsManaged>false</CompileAsManaged>
       <CompileAsManaged>false</CompileAsManaged>
       <CompileAsWinRT>false</CompileAsWinRT>
       <CompileAsWinRT>false</CompileAsWinRT>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <LanguageStandard_C>stdc11</LanguageStandard_C>
     </ClCompile>
     </ClCompile>
     <Link>
     <Link>
       <GenerateDebugInformation>false</GenerateDebugInformation>
       <GenerateDebugInformation>false</GenerateDebugInformation>

+ 6 - 0
zeroidc/.cargo/config.toml

@@ -3,3 +3,9 @@ rustflags=["-C", "link-arg=-mmacosx-version-min=10.13"]
 
 
 [target.aarch64-apple-darwin]
 [target.aarch64-apple-darwin]
 rustflags=["-C", "link-arg=-mmacosx-version-min=10.13"]
 rustflags=["-C", "link-arg=-mmacosx-version-min=10.13"]
+
+[target.x86_64-pc-windows-msvc]
+rustflags = ["-C", "target-feature=+crt-static"]
+
+[target.i686-pc-windows-msvc]
+rustflags = ["-C", "target-feature=+crt-static"]

+ 1 - 1
zeroidc/Cargo.toml

@@ -12,7 +12,7 @@ crate-type = ["staticlib","rlib"]
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 
 [dependencies]
 [dependencies]
-openidconnect = { version = "2.2", default-features = false, features = ["reqwest", "native-tls"] }
+openidconnect = { version = "2.2", default-features = false, features = ["reqwest", "native-tls", "accept-rfc3339-timestamps"] }
 base64 = "0.13"
 base64 = "0.13"
 url = "2.2"
 url = "2.2"
 reqwest = "0.11"
 reqwest = "0.11"

+ 85 - 137
zeroidc/src/lib.rs

@@ -26,6 +26,7 @@ use jwt::{Token};
 use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType};
 use openidconnect::core::{CoreClient, CoreProviderMetadata, CoreResponseType};
 use openidconnect::reqwest::http_client;
 use openidconnect::reqwest::http_client;
 use openidconnect::{AccessToken, AccessTokenHash, AuthorizationCode, AuthenticationFlow, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, TokenResponse};
 use openidconnect::{AccessToken, AccessTokenHash, AuthorizationCode, AuthenticationFlow, ClientId, CsrfToken, IssuerUrl, Nonce, OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, RefreshToken, Scope, TokenResponse};
+use std::error::Error;
 use std::str::from_utf8;
 use std::str::from_utf8;
 use std::sync::{Arc, Mutex};
 use std::sync::{Arc, Mutex};
 use std::thread::{sleep, spawn, JoinHandle};
 use std::thread::{sleep, spawn, JoinHandle};
@@ -140,6 +141,8 @@ impl ZeroIDC {
             })),
             })),
         };
         };
 
 
+        println!("issuer: {}, client_id: {}, auth_endopint: {}, local_web_port: {}",
+            issuer, client_id, auth_ep, local_web_port);
         let iss = IssuerUrl::new(issuer.to_string())?;
         let iss = IssuerUrl::new(issuer.to_string())?;
 
 
         let provider_meta = CoreProviderMetadata::discover(&iss, http_client)?;
         let provider_meta = CoreProviderMetadata::discover(&iss, http_client)?;
@@ -155,7 +158,8 @@ impl ZeroIDC {
                 ClientId::new(client_id.to_string()),
                 ClientId::new(client_id.to_string()),
                 None,
                 None,
             )
             )
-            .set_redirect_uri(redirect),
+            .set_redirect_uri(redirect)
+            .set_auth_type(openidconnect::AuthType::RequestBody),
         );
         );
 
 
         Ok(idc)
         Ok(idc)
@@ -187,6 +191,7 @@ impl ZeroIDC {
                         println!("refresh token thread tick, now: {}, exp: {}", systemtime_strftime(now, "[year]-[month]-[day] [hour]:[minute]:[second]"), systemtime_strftime(exp, "[year]-[month]-[day] [hour]:[minute]:[second]"));
                         println!("refresh token thread tick, now: {}, exp: {}", systemtime_strftime(now, "[year]-[month]-[day] [hour]:[minute]:[second]"), systemtime_strftime(exp, "[year]-[month]-[day] [hour]:[minute]:[second]"));
                     }
                     }
                     let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone();
                     let refresh_token = (*inner_local.lock().unwrap()).refresh_token.clone();
+    
                     if let Some(refresh_token) =  refresh_token {
                     if let Some(refresh_token) =  refresh_token {
                         let should_kick = (*inner_local.lock().unwrap()).kick;
                         let should_kick = (*inner_local.lock().unwrap()).kick;
                         if now >= (exp - Duration::from_secs(30)) || should_kick {
                         if now >= (exp - Duration::from_secs(30)) || should_kick {
@@ -197,6 +202,10 @@ impl ZeroIDC {
                                 (*inner_local.lock().unwrap()).kick = false;
                                 (*inner_local.lock().unwrap()).kick = false;
                             }
                             }
 
 
+                            #[cfg(debug_assertions)] {
+                                println!("Refresh Token: {}", refresh_token.secret());
+                            }
+
                             let token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| {
                             let token_response = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| {
                                 let res = c.exchange_refresh_token(&refresh_token)
                                 let res = c.exchange_refresh_token(&refresh_token)
                                     .request(http_client);
                                     .request(http_client);
@@ -207,151 +216,83 @@ impl ZeroIDC {
                             if let Some(res) = token_response {
                             if let Some(res) = token_response {
                                 match res {
                                 match res {
                                     Ok(res) => {
                                     Ok(res) => {
-
-                                        let n = match nonce.clone() {
-                                            Some(n) => n,
-                                            None => {
-                                                println!("err: no nonce");
-                                                continue;
-                                            }
-                                        };
-                                        
-                                        let id = match res.id_token() {
-                                            Some(t) => t,
-                                            None => {
-                                                println!("err: no id_token");
-                                                continue;
-                                            }
-                                        };
-            
-                                        // verify & validate claims
-                                        let verified = (*inner_local.lock().unwrap()).oidc_client.as_ref().map(|c| {
-                                            let claims = match id.claims(&c.id_token_verifier(), &n) {
-                                                Ok(c) => c,
-                                                Err(e) => {
-                                                    println!("claims err: {}", e);
-                                                    return false;
-                                                }
-                                            };
-                
-                                            let signing_algo = match id.signing_alg() {
-                                                Ok(s) => s,
-                                                Err(e) => {
-                                                    println!("alg err: {}", e);
-                                                    return false;
-                                                }
-                                            };
-                
-                                            if let Some(expected_hash) = claims.access_token_hash() {
-                                                let actual_hash = match AccessTokenHash::from_token(res.access_token(), &signing_algo) {
-                                                    Ok(h) => h,
-                                                    Err(e) => {
-                                                        println!("Error hashing access token: {}", e);
-                                                        return false;
-                                                    }
+                                        match res.id_token() {
+                                            Some(id_token) => {
+                                                let n = match nonce.clone() {
+                                                    Some(n) => n.secret().to_string(),
+                                                    None => "".to_string(),
                                                 };
                                                 };
-                
-                                                if actual_hash != *expected_hash {
-                                                    println!("token hash error");
-                                                    return false;
-                                                }
-                                            }
-                                            return true;
-                                        });
-                                        
-                                        let v = match verified {
-                                            Some(verified) => {
-                                                if !verified {
-                                                    println!("not verified.");
-                                                    (*inner_local.lock().unwrap()).running = false;
-                                                    false
-                                                } else {
-                                                    true
+
+                                                let params = [("id_token", id_token.to_string()),("state", "refresh".to_string()),("extra_nonce", n)];
+                                                #[cfg(debug_assertions)] {
+                                                    println!("New ID token: {}", id_token.to_string());
                                                 }
                                                 }
-                                            },
-                                            None => {
-                                                println!("no verification performed?");
-                                                (*inner_local.lock().unwrap()).running = false;
-                                                false
-                                            }
-                                        };
-                                        
-                                        if v {
-                                            match res.id_token() {
-                                                Some(id_token) => {
-                                                    let params = [("id_token", id_token.to_string()),("state", "refresh".to_string())];
-                                                    #[cfg(debug_assertions)] {
-                                                        println!("New ID token: {}", id_token.to_string());
-                                                    }
-                                                    let client = reqwest::blocking::Client::new();
-                                                    let r = client.post((*inner_local.lock().unwrap()).auth_endpoint.clone())
-                                                        .form(&params)
-                                                        .send();
-
-                                                    match r {
-                                                        Ok(r) => {
-                                                            if r.status().is_success() {
-                                                                #[cfg(debug_assertions)] {
-                                                                    println!("hit url: {}", r.url().as_str());
-                                                                    println!("status: {}", r.status());
-                                                                }
+                                                let client = reqwest::blocking::Client::new();
+                                                let r = client.post((*inner_local.lock().unwrap()).auth_endpoint.clone())
+                                                    .form(&params)
+                                                    .send();
+
+                                                match r {
+                                                    Ok(r) => {
+                                                        if r.status().is_success() {
+                                                            #[cfg(debug_assertions)] {
+                                                                println!("hit url: {}", r.url().as_str());
+                                                                println!("status: {}", r.status());
+                                                            }
 
 
-                                                                let access_token = res.access_token();
-                                                                let at = access_token.secret();
+                                                            let access_token = res.access_token();
+                                                            let idt = &id_token.to_string();
 
 
-                                                                let t: Result<Token<jwt::Header, jwt::Claims, jwt::Unverified<'_>>, jwt::Error>= Token::parse_unverified(at);
-                                                                
-                                                                if let Ok(t) = t {
-                                                                    let claims = t.claims().registered.clone();
-                                                                    match claims.expiration {
-                                                                        Some(exp) => {
-                                                                            (*inner_local.lock().unwrap()).exp_time = exp;
-                                                                        },
-                                                                        None => {
-                                                                            panic!("expiration is None.  This shouldn't happen")
-                                                                        }
+                                                            let t: Result<Token<jwt::Header, jwt::Claims, jwt::Unverified<'_>>, jwt::Error> =
+                                                                 Token::parse_unverified(idt);
+                                                            
+                                                            if let Ok(t) = t {
+                                                                let claims = t.claims().registered.clone();
+                                                                match claims.expiration {
+                                                                    Some(exp) => {
+                                                                        (*inner_local.lock().unwrap()).exp_time = exp;
+                                                                    },
+                                                                    None => {
+                                                                        panic!("expiration is None.  This shouldn't happen")
                                                                     }
                                                                     }
-                                                                }  
-
-                                                                (*inner_local.lock().unwrap()).access_token = Some(access_token.clone());
-                                                                if let Some(t) = res.refresh_token() {
-                                                                    // println!("New Refresh Token: {}", t.secret());
-                                                                    (*inner_local.lock().unwrap()).refresh_token = Some(t.clone());
-                                                                }
-                                                                #[cfg(debug_assertions)] {
-                                                                    println!("Central post succeeded");
                                                                 }
                                                                 }
-                                                            } else {
-                                                                println!("Central post failed: {}", r.status().to_string());
-                                                                println!("hit url: {}", r.url().as_str());
-                                                                println!("Status: {}", r.status());
-                                                                if let Ok(body) = r.bytes() {
-                                                                    if let Ok(body) = std::str::from_utf8(&body) {
-                                                                        println!("Body: {}", body);
-                                                                    }
-                                                                    
+                                                            }  
+
+                                                            (*inner_local.lock().unwrap()).access_token = Some(access_token.clone());
+                                                            if let Some(t) = res.refresh_token() {
+                                                                // println!("New Refresh Token: {}", t.secret());
+                                                                (*inner_local.lock().unwrap()).refresh_token = Some(t.clone());
+                                                            }
+                                                            #[cfg(debug_assertions)] {
+                                                                println!("Central post succeeded");
+                                                            }
+                                                        } else {
+                                                            println!("Central post failed: {}", r.status().to_string());
+                                                            println!("hit url: {}", r.url().as_str());
+                                                            println!("Status: {}", r.status());
+                                                            if let Ok(body) = r.bytes() {
+                                                                if let Ok(body) = std::str::from_utf8(&body) {
+                                                                    println!("Body: {}", body);
                                                                 }
                                                                 }
                                                                 
                                                                 
-                                                                (*inner_local.lock().unwrap()).exp_time = 0;
-                                                                (*inner_local.lock().unwrap()).running = false;
                                                             }
                                                             }
-                                                        },
-                                                        Err(e) => {
                                                             
                                                             
-                                                            println!("Central post failed: {}", e.to_string());
-                                                            println!("hit url: {}", e.url().unwrap().as_str());
-                                                            println!("Status: {}", e.status().unwrap());
                                                             (*inner_local.lock().unwrap()).exp_time = 0;
                                                             (*inner_local.lock().unwrap()).exp_time = 0;
                                                             (*inner_local.lock().unwrap()).running = false;
                                                             (*inner_local.lock().unwrap()).running = false;
                                                         }
                                                         }
+                                                    },
+                                                    Err(e) => {
+                                                        println!("Central post failed: {}", e.to_string());
+                                                        println!("hit url: {}", e.url().unwrap().as_str());
+                                                        println!("Status: {}", e.status().unwrap());
+                                                        (*inner_local.lock().unwrap()).exp_time = 0;
+                                                        (*inner_local.lock().unwrap()).running = false;
                                                     }
                                                     }
-                                                },
-                                                None => {
-                                                    println!("no id token?!?");
                                                 }
                                                 }
+                                            },
+                                            None => {
+                                                println!("no id token?!?");
                                             }
                                             }
-                                        } else {
-                                            println!("claims not verified");
                                         }
                                         }
                                     },
                                     },
                                     Err(e) => {
                                     Err(e) => {
@@ -483,6 +424,8 @@ impl ZeroIDC {
         let res = (*local.lock().unwrap()).as_opt().map(|i| {
         let res = (*local.lock().unwrap()).as_opt().map(|i| {
             if let Some(verifier) = i.pkce_verifier.take() {
             if let Some(verifier) = i.pkce_verifier.take() {
                 let token_response = i.oidc_client.as_ref().map(|c| {
                 let token_response = i.oidc_client.as_ref().map(|c| {
+                    println!("auth code: {}", code);
+
                     let r = c.exchange_code(AuthorizationCode::new(code.to_string()))
                     let r = c.exchange_code(AuthorizationCode::new(code.to_string()))
                         .set_pkce_verifier(verifier)
                         .set_pkce_verifier(verifier)
                         .request(http_client);
                         .request(http_client);
@@ -493,6 +436,7 @@ impl ZeroIDC {
                             let n = match i.nonce.clone() {
                             let n = match i.nonce.clone() {
                                 Some(n) => n,
                                 Some(n) => n,
                                 None => {
                                 None => {
+                                    println!("no noce");
                                     return None;
                                     return None;
                                 }
                                 }
                             };
                             };
@@ -500,6 +444,7 @@ impl ZeroIDC {
                             let id = match res.id_token() {
                             let id = match res.id_token() {
                                 Some(t) => t,
                                 Some(t) => t,
                                 None => {
                                 None => {
+                                    println!("no id token");
                                     return None;
                                     return None;
                                 }
                                 }
                             };
                             };
@@ -507,6 +452,7 @@ impl ZeroIDC {
                             let claims = match id.claims(&c.id_token_verifier(), &n) {
                             let claims = match id.claims(&c.id_token_verifier(), &n) {
                                 Ok(c) => c,
                                 Ok(c) => c,
                                 Err(_e) => {
                                 Err(_e) => {
+                                    println!("no claims");
                                     return None;
                                     return None;
                                 }
                                 }
                             };
                             };
@@ -514,6 +460,7 @@ impl ZeroIDC {
                             let signing_algo = match id.signing_alg() {
                             let signing_algo = match id.signing_alg() {
                                 Ok(s) => s,
                                 Ok(s) => s,
                                 Err(_) => {
                                 Err(_) => {
+                                    println!("no signing algorithm");
                                     return None;
                                     return None;
                                 }
                                 }
                             };
                             };
@@ -534,11 +481,10 @@ impl ZeroIDC {
                             }
                             }
                             Some(res)
                             Some(res)
                         },
                         },
-                        Err(_e) => {
-                            #[cfg(debug_assertions)] {
-                                println!("token response error: {}", _e.to_string());
-                            }
-
+                        Err(e) => {
+                            println!("token response error: {:?}", e.to_string());
+                            println!("\t {:?}", e.source());
+                            
                             return None;
                             return None;
                         },
                         },
                     }
                     }
@@ -574,15 +520,17 @@ impl ZeroIDC {
                                     println!("Status: {}", res.status());
                                     println!("Status: {}", res.status());
                                 }
                                 }
 
 
-                                let at = tok.access_token().secret();
+                                let idt = &id_token.to_string();
 
 
-                                let t: Result<Token<jwt::Header, jwt::Claims, jwt::Unverified<'_>>, jwt::Error>= Token::parse_unverified(at);
+                                let t: Result<Token<jwt::Header, jwt::Claims, jwt::Unverified<'_>>, jwt::Error>= 
+                                    Token::parse_unverified(idt);
                                                                 
                                                                 
                                 if let Ok(t) = t {
                                 if let Ok(t) = t {
                                     let claims = t.claims().registered.clone();
                                     let claims = t.claims().registered.clone();
                                     match claims.expiration {
                                     match claims.expiration {
                                         Some(exp) => {
                                         Some(exp) => {
                                             i.exp_time = exp;
                                             i.exp_time = exp;
+                                            println!("Set exp time to: {:?}", i.exp_time);
                                         },
                                         },
                                         None => {
                                         None => {
                                             panic!("expiration is None.  This shouldn't happen")
                                             panic!("expiration is None.  This shouldn't happen")