diff --git a/DnsServerSystemTrayApp/DnsProvider.cs b/DnsServerSystemTrayApp/DnsProvider.cs
new file mode 100644
index 00000000..c818343d
--- /dev/null
+++ b/DnsServerSystemTrayApp/DnsProvider.cs
@@ -0,0 +1,135 @@
+/*
+Technitium DNS Server
+Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using TechnitiumLibrary.IO;
+using TechnitiumLibrary.Net;
+
+namespace DnsServerSystemTrayApp
+{
+ public class DnsProvider : IComparable
+ {
+ #region variables
+
+ public string Name;
+ public ICollection Addresses;
+
+ #endregion
+
+ #region constructor
+
+ public DnsProvider(string name, ICollection addresses)
+ {
+ this.Name = name;
+ this.Addresses = addresses;
+ }
+
+ public DnsProvider(BinaryReader bR)
+ {
+ this.Name = bR.ReadShortString();
+ this.Addresses = new List();
+
+ int count = bR.ReadInt32();
+
+ for (int i = 0; i < count; i++)
+ this.Addresses.Add(IPAddressExtension.Parse(bR));
+ }
+
+ #endregion
+
+ #region static
+
+ public static DnsProvider[] GetDefaultProviders()
+ {
+ return new DnsProvider[] {
+ new DnsProvider("Technitium", new IPAddress[] { IPAddress.Loopback, IPAddress.IPv6Loopback }),
+ new DnsProvider("Cloudflare", new IPAddress[] { IPAddress.Parse("1.1.1.1"), IPAddress.Parse("1.0.0.1"), IPAddress.Parse("[2606:4700:4700::1111]"), IPAddress.Parse("[2606:4700:4700::1001]") }),
+ new DnsProvider("Google", new IPAddress[] { IPAddress.Parse("8.8.8.8"), IPAddress.Parse("8.8.4.4"), IPAddress.Parse("[2001:4860:4860::8888]"), IPAddress.Parse("[2001:4860:4860::8844]") }),
+ new DnsProvider("Quad9", new IPAddress[] { IPAddress.Parse("9.9.9.9"), IPAddress.Parse("[2620:fe::fe]") }),
+ new DnsProvider("OpenDNS", new IPAddress[] { IPAddress.Parse("208.67.222.222"), IPAddress.Parse("208.67.220.220"), IPAddress.Parse("[2620:0:ccc::2]"), IPAddress.Parse("[2620:0:ccd::2]") })
+ };
+ }
+
+ #endregion
+
+ #region public
+
+ public string GetIpv4Addresses()
+ {
+ string ipv4Addresses = null;
+
+ foreach (IPAddress address in Addresses)
+ {
+ if (address.AddressFamily == AddressFamily.InterNetwork)
+ {
+ if (ipv4Addresses == null)
+ ipv4Addresses = address.ToString();
+ else
+ ipv4Addresses += ", " + address.ToString();
+ }
+ }
+
+ return ipv4Addresses;
+ }
+
+ public string GetIpv6Addresses()
+ {
+ string ipv6Addresses = null;
+
+ foreach (IPAddress address in Addresses)
+ {
+ if (address.AddressFamily == AddressFamily.InterNetworkV6)
+ {
+ if (ipv6Addresses == null)
+ ipv6Addresses = address.ToString();
+ else
+ ipv6Addresses += ", " + address.ToString();
+ }
+ }
+
+ return ipv6Addresses;
+ }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ public int CompareTo(DnsProvider other)
+ {
+ return this.Name.CompareTo(other.Name);
+ }
+
+ public void WriteTo(BinaryWriter bW)
+ {
+ bW.WriteShortString(Name);
+
+ bW.Write(Addresses.Count);
+
+ foreach (IPAddress address in Addresses)
+ address.WriteTo(bW);
+ }
+
+ #endregion
+ }
+}
diff --git a/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj b/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj
index 11016048..9eeb007f 100644
--- a/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj
+++ b/DnsServerSystemTrayApp/DnsServerSystemTrayApp.csproj
@@ -38,28 +38,43 @@
+
+
False
..\..\TechnitiumLibrary\bin\TechnitiumLibrary.IO.dll
+
+ ..\..\TechnitiumLibrary\bin\TechnitiumLibrary.Net.dll
+
-
+
+
Form
-
- AboutForm.cs
+
+ frmAbout.cs
+
+
+ Form
+
+
+ frmManageDnsProviders.cs
-
- AboutForm.cs
+
+ frmAbout.cs
+
+
+ frmManageDnsProviders.cs
ResXFileCodeGenerator
diff --git a/DnsServerSystemTrayApp/MainApplicationContext.cs b/DnsServerSystemTrayApp/MainApplicationContext.cs
index ee967d0c..63d5e018 100644
--- a/DnsServerSystemTrayApp/MainApplicationContext.cs
+++ b/DnsServerSystemTrayApp/MainApplicationContext.cs
@@ -20,6 +20,7 @@ along with this program. If not, see .
using DnsServerSystemTrayApp.Properties;
using Microsoft.Win32;
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
@@ -43,19 +44,15 @@ namespace DnsServerSystemTrayApp
const int SERVICE_WAIT_TIMEOUT_SECONDS = 30;
private readonly ServiceController _service = new ServiceController("DnsService");
- readonly IPAddress[] _cloudflareDns = new IPAddress[] { IPAddress.Parse("1.1.1.1"), IPAddress.Parse("1.0.0.1") };
- readonly IPAddress[] _googleDns = new IPAddress[] { IPAddress.Parse("8.8.8.8"), IPAddress.Parse("8.8.4.4") };
- readonly IPAddress[] _quad9Dns = new IPAddress[] { IPAddress.Parse("9.9.9.9") };
+ readonly string _configFile;
+ readonly List _dnsProviders = new List();
private NotifyIcon TrayIcon;
private ContextMenuStrip TrayIconContextMenu;
private ToolStripMenuItem DashboardMenuItem;
private ToolStripMenuItem NetworkDnsMenuItem;
private ToolStripMenuItem DefaultNetworkDnsMenuItem;
- private ToolStripMenuItem TechnitiumNetworkDnsMenuItem;
- private ToolStripMenuItem CloudflareNetworkDnsMenuItem;
- private ToolStripMenuItem GoogleNetworkDnsMenuItem;
- private ToolStripMenuItem Quad9NetworkDnsMenuItem;
+ private ToolStripMenuItem ManageNetworkDnsMenuItem;
private ToolStripMenuItem ServiceMenuItem;
private ToolStripMenuItem StartServiceMenuItem;
private ToolStripMenuItem RestartServiceMenuItem;
@@ -68,8 +65,11 @@ namespace DnsServerSystemTrayApp
#region constructor
- public MainApplicationContext()
+ public MainApplicationContext(string configFile)
{
+ _configFile = configFile;
+ LoadConfig();
+
InitializeComponent();
}
@@ -102,7 +102,7 @@ namespace DnsServerSystemTrayApp
//
// TrayIcon
//
- var resources = new ComponentResourceManager(typeof(AboutForm));
+ var resources = new ComponentResourceManager(typeof(frmAbout));
TrayIcon = new NotifyIcon();
TrayIcon.Icon = (Icon)resources.GetObject("$this.Icon");
TrayIcon.Visible = true;
@@ -129,27 +129,8 @@ namespace DnsServerSystemTrayApp
DefaultNetworkDnsMenuItem = new ToolStripMenuItem("Default");
DefaultNetworkDnsMenuItem.Click += DefaultNetworkDnsMenuItem_Click;
- TechnitiumNetworkDnsMenuItem = new ToolStripMenuItem("Technitium");
- TechnitiumNetworkDnsMenuItem.Click += TechnitiumNetworkDnsMenuItem_Click;
-
- CloudflareNetworkDnsMenuItem = new ToolStripMenuItem("Cloudflare");
- CloudflareNetworkDnsMenuItem.Click += CloudflareNetworkDnsMenuItem_Click;
-
- GoogleNetworkDnsMenuItem = new ToolStripMenuItem("Google");
- GoogleNetworkDnsMenuItem.Click += GoogleNetworkDnsMenuItem_Click;
-
- Quad9NetworkDnsMenuItem = new ToolStripMenuItem("IBM Quad9");
- Quad9NetworkDnsMenuItem.Click += Quad9NetworkDnsMenuItem_Click;
-
- NetworkDnsMenuItem.DropDownItems.AddRange(new ToolStripItem[]
- {
- DefaultNetworkDnsMenuItem,
- new ToolStripSeparator(),
- TechnitiumNetworkDnsMenuItem,
- CloudflareNetworkDnsMenuItem,
- GoogleNetworkDnsMenuItem,
- Quad9NetworkDnsMenuItem
- });
+ ManageNetworkDnsMenuItem = new ToolStripMenuItem("Manage");
+ ManageNetworkDnsMenuItem.Click += ManageNetworkDnsMenuItem_Click;
//
// ServiceMenuItem
@@ -213,7 +194,76 @@ namespace DnsServerSystemTrayApp
TrayIconContextMenu.ResumeLayout(false);
}
- private static void SetNameServerIPv4(NetworkInterface nic, IPAddress[] dnsAddresses)
+ private void LoadConfig()
+ {
+ try
+ {
+ using (FileStream fS = new FileStream(_configFile, FileMode.Open, FileAccess.Read))
+ {
+ BinaryReader bR = new BinaryReader(fS);
+
+ if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "DT")
+ throw new InvalidDataException("Invalid DNS Server System Tray App config file format.");
+
+ switch (bR.ReadByte())
+ {
+ case 1:
+ int count = bR.ReadInt32();
+ _dnsProviders.Clear();
+
+ for (int i = 0; i < count; i++)
+ _dnsProviders.Add(new DnsProvider(bR));
+
+ _dnsProviders.Sort();
+ break;
+
+ default:
+ throw new NotSupportedException("DNS Server System Tray App config file format is not supported.");
+ }
+ }
+ }
+ catch (FileNotFoundException)
+ {
+ _dnsProviders.Clear();
+ _dnsProviders.AddRange(DnsProvider.GetDefaultProviders());
+ SaveConfig();
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error occured while loading config file. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ private void SaveConfig()
+ {
+ try
+ {
+ using (FileStream fS = new FileStream(_configFile, FileMode.Create, FileAccess.Write))
+ {
+ BinaryWriter bW = new BinaryWriter(fS);
+
+ bW.Write(Encoding.ASCII.GetBytes("DT"));
+ bW.Write((byte)1);
+
+ bW.Write(_dnsProviders.Count);
+
+ foreach (DnsProvider dnsProvider in _dnsProviders)
+ dnsProvider.WriteTo(bW);
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error occured while saving config file. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+
+ private static void SetNameServer(NetworkInterface nic, ICollection dnsAddresses)
+ {
+ SetNameServerIPv4(nic, dnsAddresses);
+ SetNameServerIPv6(nic, dnsAddresses);
+ }
+
+ private static void SetNameServerIPv4(NetworkInterface nic, ICollection dnsAddresses)
{
ManagementClass networkAdapterConfig = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection instances = networkAdapterConfig.GetInstances();
@@ -222,17 +272,18 @@ namespace DnsServerSystemTrayApp
{
if ((bool)obj["IPEnabled"] && obj["SettingID"].Equals(nic.Id))
{
- string[] dnsServers = new string[dnsAddresses.Length];
+ List dnsServers = new List();
- for (int i = 0; i < dnsServers.Length; i++)
+ foreach (IPAddress dnsAddress in dnsAddresses)
{
- if (dnsAddresses[i].AddressFamily != AddressFamily.InterNetwork)
- throw new ArgumentException();
+ if (dnsAddress.AddressFamily != AddressFamily.InterNetwork)
+ continue;
- dnsServers[i] = dnsAddresses[i].ToString();
+ dnsServers.Add(dnsAddress.ToString());
}
+
ManagementBaseObject objParameter = obj.GetMethodParameters("SetDNSServerSearchOrder");
- objParameter["DNSServerSearchOrder"] = dnsServers;
+ objParameter["DNSServerSearchOrder"] = dnsServers.ToArray();
ManagementBaseObject response = obj.InvokeMethod("SetDNSServerSearchOrder", objParameter, null);
uint returnValue = (uint)response.GetPropertyValue("ReturnValue");
@@ -267,7 +318,7 @@ namespace DnsServerSystemTrayApp
}
}
- private static void SetNameServerIPv6(NetworkInterface nic, IPAddress[] dnsAddresses)
+ private static void SetNameServerIPv6(NetworkInterface nic, ICollection dnsAddresses)
{
//HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces\{}
@@ -276,7 +327,7 @@ namespace DnsServerSystemTrayApp
foreach (IPAddress dnsAddress in dnsAddresses)
{
if (dnsAddress.AddressFamily != AddressFamily.InterNetworkV6)
- throw new ArgumentException();
+ continue;
if (nameServer == null)
nameServer = dnsAddress.ToString();
@@ -294,12 +345,15 @@ namespace DnsServerSystemTrayApp
}
}
- private static bool AddressExists(IPAddress checkAddress, IPAddress[] addresses)
+ private static bool AddressExists(ICollection checkAddresses, ICollection addresses)
{
- foreach (IPAddress address in addresses)
+ foreach (IPAddress checkAddress in checkAddresses)
{
- if (checkAddress.Equals(address))
- return true;
+ foreach (IPAddress address in addresses)
+ {
+ if (checkAddress.Equals(address))
+ return true;
+ }
}
return false;
@@ -311,11 +365,7 @@ namespace DnsServerSystemTrayApp
{
#region Network DNS
- bool isDefaultDns = false;
- bool isTechnitiumDns = false;
- bool isCloudflareDns = false;
- bool isGoogleDns = false;
- bool isQuad9Dns = false;
+ List networkDnsAddresses = new List();
try
{
@@ -324,42 +374,51 @@ namespace DnsServerSystemTrayApp
if (nic.OperationalStatus != OperationalStatus.Up)
continue;
- foreach (IPAddress dnsAddress in nic.GetIPProperties().DnsAddresses)
- {
- if (IPAddress.IsLoopback(dnsAddress))
- {
- isTechnitiumDns = true;
- }
- else if (AddressExists(dnsAddress, _cloudflareDns))
- {
- isCloudflareDns = true;
- }
- else if (AddressExists(dnsAddress, _googleDns))
- {
- isGoogleDns = true;
- }
- else if (AddressExists(dnsAddress, _quad9Dns))
- {
- isQuad9Dns = true;
- }
- else if (!dnsAddress.IsIPv6SiteLocal)
- {
- isDefaultDns = true;
- }
-
- if (isDefaultDns && isTechnitiumDns && isCloudflareDns && isGoogleDns && isQuad9Dns)
- break;
- }
+ networkDnsAddresses.AddRange(nic.GetIPProperties().DnsAddresses);
}
}
catch
{ }
- DefaultNetworkDnsMenuItem.Checked = isDefaultDns;
- TechnitiumNetworkDnsMenuItem.Checked = isTechnitiumDns;
- CloudflareNetworkDnsMenuItem.Checked = isCloudflareDns;
- GoogleNetworkDnsMenuItem.Checked = isGoogleDns;
- Quad9NetworkDnsMenuItem.Checked = isQuad9Dns;
+
+ NetworkDnsMenuItem.DropDownItems.Clear();
+ NetworkDnsMenuItem.DropDownItems.Add(DefaultNetworkDnsMenuItem);
+ NetworkDnsMenuItem.DropDownItems.Add(new ToolStripSeparator());
+
+ bool noItemChecked = true;
+ DefaultNetworkDnsMenuItem.Checked = false;
+
+ foreach (DnsProvider dnsProvider in _dnsProviders)
+ {
+ ToolStripMenuItem item = new ToolStripMenuItem(dnsProvider.Name);
+ item.Tag = dnsProvider;
+ item.Click += NetworkDnsMenuSubItem_Click;
+
+ if (AddressExists(networkDnsAddresses, dnsProvider.Addresses))
+ {
+ item.Checked = true;
+ noItemChecked = false;
+ }
+
+ NetworkDnsMenuItem.DropDownItems.Add(item);
+ }
+
+ if (noItemChecked)
+ {
+ foreach (IPAddress dnsAddress in networkDnsAddresses)
+ {
+ if (!dnsAddress.IsIPv6SiteLocal)
+ {
+ DefaultNetworkDnsMenuItem.Checked = true;
+ break;
+ }
+ }
+ }
+
+ if (_dnsProviders.Count > 0)
+ NetworkDnsMenuItem.DropDownItems.Add(new ToolStripSeparator());
+
+ NetworkDnsMenuItem.DropDownItems.Add(ManageNetworkDnsMenuItem);
#endregion
@@ -370,7 +429,6 @@ namespace DnsServerSystemTrayApp
switch (_service.Status)
{
case ServiceControllerStatus.Stopped:
- TechnitiumNetworkDnsMenuItem.Enabled = false;
DashboardMenuItem.Enabled = false;
StartServiceMenuItem.Enabled = true;
RestartServiceMenuItem.Enabled = false;
@@ -378,7 +436,6 @@ namespace DnsServerSystemTrayApp
break;
case ServiceControllerStatus.Running:
- TechnitiumNetworkDnsMenuItem.Enabled = true;
DashboardMenuItem.Enabled = true;
StartServiceMenuItem.Enabled = false;
RestartServiceMenuItem.Enabled = true;
@@ -386,7 +443,6 @@ namespace DnsServerSystemTrayApp
break;
default:
- TechnitiumNetworkDnsMenuItem.Enabled = false;
DashboardMenuItem.Enabled = false;
StartServiceMenuItem.Enabled = false;
RestartServiceMenuItem.Enabled = false;
@@ -398,7 +454,6 @@ namespace DnsServerSystemTrayApp
}
catch
{
- TechnitiumNetworkDnsMenuItem.Enabled = false;
DashboardMenuItem.Enabled = false;
ServiceMenuItem.Enabled = false;
}
@@ -471,20 +526,25 @@ namespace DnsServerSystemTrayApp
SetNameServerIPv6(nic, new IPAddress[] { });
- IPInterfaceProperties properties = nic.GetIPProperties();
+ try
+ {
+ IPInterfaceProperties properties = nic.GetIPProperties();
- if (properties.GetIPv4Properties().IsDhcpEnabled)
- {
- SetNameServerIPv4(nic, new IPAddress[] { });
- }
- else if (properties.GatewayAddresses.Count > 0)
- {
- SetNameServerIPv4(nic, new IPAddress[] { properties.GatewayAddresses[0].Address });
- }
- else
- {
- SetNameServerIPv4(nic, new IPAddress[] { });
+ if (properties.GetIPv4Properties().IsDhcpEnabled)
+ {
+ SetNameServerIPv4(nic, new IPAddress[] { });
+ }
+ else if (properties.GatewayAddresses.Count > 0)
+ {
+ SetNameServerIPv4(nic, new IPAddress[] { properties.GatewayAddresses[0].Address });
+ }
+ else
+ {
+ SetNameServerIPv4(nic, new IPAddress[] { });
+ }
}
+ catch (NetworkInformationException)
+ { }
}
MessageBox.Show("The network DNS servers were set to default successfully.", "Default DNS Set - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
@@ -495,34 +555,26 @@ namespace DnsServerSystemTrayApp
}
}
- private void TechnitiumNetworkDnsMenuItem_Click(object sender, EventArgs e)
+ private void ManageNetworkDnsMenuItem_Click(object sender, EventArgs e)
{
- try
+ using (frmManageDnsProviders frm = new frmManageDnsProviders(_dnsProviders))
{
- foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
+ if (frm.ShowDialog() == DialogResult.OK)
{
- if (nic.OperationalStatus != OperationalStatus.Up)
- continue;
+ _dnsProviders.Clear();
+ _dnsProviders.AddRange(frm.DnsProviders);
+ _dnsProviders.Sort();
- IPInterfaceProperties properties = nic.GetIPProperties();
-
- if ((properties.DnsAddresses.Count > 0) && !properties.DnsAddresses[0].IsIPv6SiteLocal)
- {
- SetNameServerIPv6(nic, new IPAddress[] { IPAddress.IPv6Loopback });
- SetNameServerIPv4(nic, new IPAddress[] { IPAddress.Loopback });
- }
+ SaveConfig();
}
-
- MessageBox.Show("The network DNS servers were set to Technitium DNS successfully.", "Technitium DNS Set - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- catch (Exception ex)
- {
- MessageBox.Show("Error occured while setting Technitium as network DNS server. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
- private void CloudflareNetworkDnsMenuItem_Click(object sender, EventArgs e)
+ private void NetworkDnsMenuSubItem_Click(object sender, EventArgs e)
{
+ ToolStripMenuItem item = sender as ToolStripMenuItem;
+ DnsProvider dnsProvider = item.Tag as DnsProvider;
+
try
{
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
@@ -533,69 +585,14 @@ namespace DnsServerSystemTrayApp
IPInterfaceProperties properties = nic.GetIPProperties();
if ((properties.DnsAddresses.Count > 0) && !properties.DnsAddresses[0].IsIPv6SiteLocal)
- {
- SetNameServerIPv6(nic, new IPAddress[] { });
- SetNameServerIPv4(nic, _cloudflareDns);
- }
+ SetNameServer(nic, dnsProvider.Addresses);
}
- MessageBox.Show("The network DNS servers were set to Cloudflare DNS successfully.", "Cloudflare DNS Set - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ MessageBox.Show("The network DNS servers were set to " + dnsProvider.Name + " successfully.", dnsProvider.Name + " Configured - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
- MessageBox.Show("Error occured while setting Cloudflare as network DNS server. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- private void GoogleNetworkDnsMenuItem_Click(object sender, EventArgs e)
- {
- try
- {
- foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
- {
- if (nic.OperationalStatus != OperationalStatus.Up)
- continue;
-
- IPInterfaceProperties properties = nic.GetIPProperties();
-
- if ((properties.DnsAddresses.Count > 0) && !properties.DnsAddresses[0].IsIPv6SiteLocal)
- {
- SetNameServerIPv6(nic, new IPAddress[] { });
- SetNameServerIPv4(nic, _googleDns);
- }
- }
-
- MessageBox.Show("The network DNS servers were set to Google DNS successfully.", "Google DNS Set - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- catch (Exception ex)
- {
- MessageBox.Show("Error occured while setting Google as network DNS server. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
- }
- }
-
- private void Quad9NetworkDnsMenuItem_Click(object sender, EventArgs e)
- {
- try
- {
- foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
- {
- if (nic.OperationalStatus != OperationalStatus.Up)
- continue;
-
- IPInterfaceProperties properties = nic.GetIPProperties();
-
- if ((properties.DnsAddresses.Count > 0) && !properties.DnsAddresses[0].IsIPv6SiteLocal)
- {
- SetNameServerIPv6(nic, new IPAddress[] { });
- SetNameServerIPv4(nic, _quad9Dns);
- }
- }
-
- MessageBox.Show("The network DNS servers were set to IBM Quad9 DNS successfully.", "IBM Quad9 DNS Set - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
- }
- catch (Exception ex)
- {
- MessageBox.Show("Error occured while setting IBM Quad9 as network DNS server. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ MessageBox.Show("Error occured while setting " + dnsProvider.Name + " as network DNS server. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
@@ -660,9 +657,9 @@ namespace DnsServerSystemTrayApp
private void AboutMenuItem_Click(object sender, EventArgs e)
{
- using (AboutForm aboutForm = new AboutForm())
+ using (frmAbout frm = new frmAbout())
{
- aboutForm.ShowDialog();
+ frm.ShowDialog();
}
}
diff --git a/DnsServerSystemTrayApp/Program.cs b/DnsServerSystemTrayApp/Program.cs
index f59caa25..fccceaba 100644
--- a/DnsServerSystemTrayApp/Program.cs
+++ b/DnsServerSystemTrayApp/Program.cs
@@ -20,6 +20,7 @@ along with this program. If not, see .
using System;
using System.ComponentModel;
using System.Diagnostics;
+using System.IO;
using System.Reflection;
using System.Security.Principal;
using System.Threading;
@@ -45,12 +46,13 @@ namespace DnsServerSystemTrayApp
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
+ string appPath = Assembly.GetEntryAssembly().Location;
+
#region admin elevation
bool isAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator);
if (!isAdmin)
{
- string appPath = Assembly.GetEntryAssembly().Location;
ProcessStartInfo processInfo = new ProcessStartInfo(appPath, string.Join(" ", args));
processInfo.UseShellExecute = true;
@@ -86,7 +88,9 @@ namespace DnsServerSystemTrayApp
#endregion
- Application.Run(new MainApplicationContext());
+ string configFile = Path.Combine(Path.GetDirectoryName(appPath), "SystemTrayApp.config");
+
+ Application.Run(new MainApplicationContext(configFile));
}
#endregion
diff --git a/DnsServerSystemTrayApp/frmManageDnsProviders.Designer.cs b/DnsServerSystemTrayApp/frmManageDnsProviders.Designer.cs
new file mode 100644
index 00000000..7e877cf5
--- /dev/null
+++ b/DnsServerSystemTrayApp/frmManageDnsProviders.Designer.cs
@@ -0,0 +1,270 @@
+namespace DnsServerSystemTrayApp
+{
+ partial class frmManageDnsProviders
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmManageDnsProviders));
+ this.listView1 = new System.Windows.Forms.ListView();
+ this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.groupBox1 = new System.Windows.Forms.GroupBox();
+ this.btnDelete = new System.Windows.Forms.Button();
+ this.btnClear = new System.Windows.Forms.Button();
+ this.btnAddUpdate = new System.Windows.Forms.Button();
+ this.txtIpv6Addresses = new System.Windows.Forms.TextBox();
+ this.label3 = new System.Windows.Forms.Label();
+ this.txtIpv4Addresses = new System.Windows.Forms.TextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.txtDnsProviderName = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.btnOK = new System.Windows.Forms.Button();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.btnRestoreDefaults = new System.Windows.Forms.Button();
+ this.groupBox1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // listView1
+ //
+ this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeader1,
+ this.columnHeader2,
+ this.columnHeader3});
+ this.listView1.FullRowSelect = true;
+ this.listView1.HideSelection = false;
+ this.listView1.Location = new System.Drawing.Point(12, 12);
+ this.listView1.MultiSelect = false;
+ this.listView1.Name = "listView1";
+ this.listView1.Size = new System.Drawing.Size(660, 200);
+ this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
+ this.listView1.TabIndex = 0;
+ this.listView1.UseCompatibleStateImageBehavior = false;
+ this.listView1.View = System.Windows.Forms.View.Details;
+ this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged);
+ //
+ // columnHeader1
+ //
+ this.columnHeader1.Text = "DNS Provider";
+ this.columnHeader1.Width = 150;
+ //
+ // columnHeader2
+ //
+ this.columnHeader2.Text = "IPv4 Addresses";
+ this.columnHeader2.Width = 240;
+ //
+ // columnHeader3
+ //
+ this.columnHeader3.Text = "IPv6 Addresses";
+ this.columnHeader3.Width = 240;
+ //
+ // groupBox1
+ //
+ this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.groupBox1.Controls.Add(this.btnDelete);
+ this.groupBox1.Controls.Add(this.btnClear);
+ this.groupBox1.Controls.Add(this.btnAddUpdate);
+ this.groupBox1.Controls.Add(this.txtIpv6Addresses);
+ this.groupBox1.Controls.Add(this.label3);
+ this.groupBox1.Controls.Add(this.txtIpv4Addresses);
+ this.groupBox1.Controls.Add(this.label2);
+ this.groupBox1.Controls.Add(this.txtDnsProviderName);
+ this.groupBox1.Controls.Add(this.label1);
+ this.groupBox1.Location = new System.Drawing.Point(12, 216);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(661, 130);
+ this.groupBox1.TabIndex = 9;
+ this.groupBox1.TabStop = false;
+ //
+ // btnDelete
+ //
+ this.btnDelete.Enabled = false;
+ this.btnDelete.Location = new System.Drawing.Point(179, 97);
+ this.btnDelete.Name = "btnDelete";
+ this.btnDelete.Size = new System.Drawing.Size(75, 23);
+ this.btnDelete.TabIndex = 16;
+ this.btnDelete.Text = "&Delete";
+ this.btnDelete.UseVisualStyleBackColor = true;
+ this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
+ //
+ // btnClear
+ //
+ this.btnClear.Location = new System.Drawing.Point(260, 97);
+ this.btnClear.Name = "btnClear";
+ this.btnClear.Size = new System.Drawing.Size(75, 23);
+ this.btnClear.TabIndex = 17;
+ this.btnClear.Text = "&Clear";
+ this.btnClear.UseVisualStyleBackColor = true;
+ this.btnClear.Click += new System.EventHandler(this.btnClear_Click);
+ //
+ // btnAddUpdate
+ //
+ this.btnAddUpdate.Location = new System.Drawing.Point(98, 97);
+ this.btnAddUpdate.Name = "btnAddUpdate";
+ this.btnAddUpdate.Size = new System.Drawing.Size(75, 23);
+ this.btnAddUpdate.TabIndex = 15;
+ this.btnAddUpdate.Text = "&Add";
+ this.btnAddUpdate.UseVisualStyleBackColor = true;
+ this.btnAddUpdate.Click += new System.EventHandler(this.btnAddUpdate_Click);
+ //
+ // txtIpv6Addresses
+ //
+ this.txtIpv6Addresses.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtIpv6Addresses.Location = new System.Drawing.Point(98, 71);
+ this.txtIpv6Addresses.MaxLength = 255;
+ this.txtIpv6Addresses.Name = "txtIpv6Addresses";
+ this.txtIpv6Addresses.Size = new System.Drawing.Size(552, 20);
+ this.txtIpv6Addresses.TabIndex = 14;
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Location = new System.Drawing.Point(11, 74);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(81, 13);
+ this.label3.TabIndex = 13;
+ this.label3.Text = "IPv6 Addresses";
+ //
+ // txtIpv4Addresses
+ //
+ this.txtIpv4Addresses.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.txtIpv4Addresses.Location = new System.Drawing.Point(98, 45);
+ this.txtIpv4Addresses.MaxLength = 255;
+ this.txtIpv4Addresses.Name = "txtIpv4Addresses";
+ this.txtIpv4Addresses.Size = new System.Drawing.Size(552, 20);
+ this.txtIpv4Addresses.TabIndex = 12;
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(11, 48);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(81, 13);
+ this.label2.TabIndex = 11;
+ this.label2.Text = "IPv4 Addresses";
+ //
+ // txtDnsProviderName
+ //
+ this.txtDnsProviderName.Location = new System.Drawing.Point(98, 19);
+ this.txtDnsProviderName.MaxLength = 255;
+ this.txtDnsProviderName.Name = "txtDnsProviderName";
+ this.txtDnsProviderName.Size = new System.Drawing.Size(200, 20);
+ this.txtDnsProviderName.TabIndex = 10;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(20, 22);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(72, 13);
+ this.label1.TabIndex = 9;
+ this.label1.Text = "DNS Provider";
+ //
+ // btnOK
+ //
+ this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnOK.Location = new System.Drawing.Point(517, 356);
+ this.btnOK.Name = "btnOK";
+ this.btnOK.Size = new System.Drawing.Size(75, 23);
+ this.btnOK.TabIndex = 10;
+ this.btnOK.Text = "OK";
+ this.btnOK.UseVisualStyleBackColor = true;
+ //
+ // btnCancel
+ //
+ this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(598, 356);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(75, 23);
+ this.btnCancel.TabIndex = 11;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ //
+ // btnRestoreDefaults
+ //
+ this.btnRestoreDefaults.Location = new System.Drawing.Point(12, 356);
+ this.btnRestoreDefaults.Name = "btnRestoreDefaults";
+ this.btnRestoreDefaults.Size = new System.Drawing.Size(100, 23);
+ this.btnRestoreDefaults.TabIndex = 12;
+ this.btnRestoreDefaults.Text = "Restore &Defaults";
+ this.btnRestoreDefaults.UseVisualStyleBackColor = true;
+ this.btnRestoreDefaults.Click += new System.EventHandler(this.btnRestoreDefaults_Click);
+ //
+ // frmManageDnsProviders
+ //
+ this.AcceptButton = this.btnOK;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnCancel;
+ this.ClientSize = new System.Drawing.Size(684, 386);
+ this.Controls.Add(this.btnRestoreDefaults);
+ this.Controls.Add(this.btnCancel);
+ this.Controls.Add(this.btnOK);
+ this.Controls.Add(this.groupBox1);
+ this.Controls.Add(this.listView1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "frmManageDnsProviders";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Manage Network DNS Providers - Technitium DNS Server";
+ this.Load += new System.EventHandler(this.frmManageDnsProviders_Load);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ListView listView1;
+ private System.Windows.Forms.ColumnHeader columnHeader1;
+ private System.Windows.Forms.ColumnHeader columnHeader2;
+ private System.Windows.Forms.ColumnHeader columnHeader3;
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.Button btnClear;
+ private System.Windows.Forms.Button btnAddUpdate;
+ private System.Windows.Forms.TextBox txtIpv6Addresses;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.TextBox txtIpv4Addresses;
+ private System.Windows.Forms.Label label2;
+ private System.Windows.Forms.TextBox txtDnsProviderName;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button btnOK;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.Button btnRestoreDefaults;
+ private System.Windows.Forms.Button btnDelete;
+ }
+}
\ No newline at end of file
diff --git a/DnsServerSystemTrayApp/frmManageDnsProviders.cs b/DnsServerSystemTrayApp/frmManageDnsProviders.cs
new file mode 100644
index 00000000..f61eca06
--- /dev/null
+++ b/DnsServerSystemTrayApp/frmManageDnsProviders.cs
@@ -0,0 +1,196 @@
+/*
+Technitium DNS Server
+Copyright (C) 2019 Shreyas Zare (shreyas@technitium.com)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
+using System.Windows.Forms;
+
+namespace DnsServerSystemTrayApp
+{
+ public partial class frmManageDnsProviders : Form
+ {
+ #region variables
+
+ readonly List _dnsProviders = new List();
+
+ #endregion
+
+ #region constructor
+
+ public frmManageDnsProviders(ICollection dnsProviders)
+ {
+ InitializeComponent();
+
+ _dnsProviders.AddRange(dnsProviders);
+ }
+
+ #endregion
+
+ #region private
+
+ private void RefreshDnsProvidersList()
+ {
+ listView1.SuspendLayout();
+
+ listView1.Items.Clear();
+
+ foreach (DnsProvider dnsProvider in _dnsProviders)
+ {
+ ListViewItem item = listView1.Items.Add(dnsProvider.Name);
+ item.SubItems.Add(dnsProvider.GetIpv4Addresses());
+ item.SubItems.Add(dnsProvider.GetIpv6Addresses());
+
+ item.Tag = dnsProvider;
+ }
+
+ listView1.ResumeLayout();
+ }
+
+ private void ClearForm()
+ {
+ txtDnsProviderName.Text = "";
+ txtIpv4Addresses.Text = "";
+ txtIpv6Addresses.Text = "";
+ btnAddUpdate.Text = "Add";
+ btnDelete.Enabled = false;
+ }
+
+ private void frmManageDnsProviders_Load(object sender, EventArgs e)
+ {
+ RefreshDnsProvidersList();
+ }
+
+ private void listView1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (listView1.SelectedItems.Count > 0)
+ {
+ ListViewItem selectedItem = listView1.SelectedItems[0];
+
+ txtDnsProviderName.Text = selectedItem.Text;
+ txtIpv4Addresses.Text = selectedItem.SubItems[1].Text;
+ txtIpv6Addresses.Text = selectedItem.SubItems[2].Text;
+ btnAddUpdate.Text = "&Update";
+ btnDelete.Enabled = true;
+ }
+ else
+ {
+ ClearForm();
+ }
+ }
+
+ private void btnAddUpdate_Click(object sender, EventArgs e)
+ {
+ if (string.IsNullOrWhiteSpace(txtDnsProviderName.Text))
+ {
+ MessageBox.Show("Please enter a valid DNS Provider name.", "Missing DNS Provider!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ return;
+ }
+
+ List addresses = new List();
+
+ foreach (string item in txtIpv4Addresses.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ if (IPAddress.TryParse(item.Trim(), out IPAddress address) && (address.AddressFamily == AddressFamily.InterNetwork))
+ {
+ addresses.Add(address);
+ }
+ else
+ {
+ MessageBox.Show("Please enter a valid IPv4 address.", "Invalid IPv4 Address!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ return;
+ }
+ }
+
+ foreach (string item in txtIpv6Addresses.Text.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ if (IPAddress.TryParse(item.Trim(), out IPAddress address) && (address.AddressFamily == AddressFamily.InterNetworkV6))
+ {
+ addresses.Add(address);
+ }
+ else
+ {
+ MessageBox.Show("Please enter a valid IPv6 address.", "Invalid IPv6 Address!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ return;
+ }
+ }
+
+ if (addresses.Count == 0)
+ {
+ MessageBox.Show("Please enter at least one valid DNS provider IP address.", "Missing DNS Provider IP Address!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ return;
+ }
+
+ if ((btnAddUpdate.Text != "Add") && (listView1.SelectedItems.Count > 0))
+ {
+ ListViewItem selectedItem = listView1.SelectedItems[0];
+ DnsProvider dnsProvider = selectedItem.Tag as DnsProvider;
+
+ dnsProvider.Name = txtDnsProviderName.Text.Trim();
+ dnsProvider.Addresses = addresses;
+ }
+ else
+ {
+ _dnsProviders.Add(new DnsProvider(txtDnsProviderName.Text.Trim(), addresses));
+ }
+
+ RefreshDnsProvidersList();
+ ClearForm();
+ }
+
+ private void btnDelete_Click(object sender, EventArgs e)
+ {
+ if (listView1.SelectedItems.Count > 0)
+ {
+ ListViewItem selectedItem = listView1.SelectedItems[0];
+ DnsProvider dnsProvider = selectedItem.Tag as DnsProvider;
+
+ _dnsProviders.Remove(dnsProvider);
+ listView1.Items.Remove(selectedItem);
+ }
+
+ RefreshDnsProvidersList();
+ ClearForm();
+ }
+
+ private void btnClear_Click(object sender, EventArgs e)
+ {
+ ClearForm();
+ }
+
+ private void btnRestoreDefaults_Click(object sender, EventArgs e)
+ {
+ _dnsProviders.Clear();
+ _dnsProviders.AddRange(DnsProvider.GetDefaultProviders());
+
+ RefreshDnsProvidersList();
+ ClearForm();
+ }
+
+ #endregion
+
+ #region properties
+
+ public List DnsProviders
+ { get { return _dnsProviders; } }
+
+ #endregion
+ }
+}
diff --git a/DnsServerSystemTrayApp/frmManageDnsProviders.resx b/DnsServerSystemTrayApp/frmManageDnsProviders.resx
new file mode 100644
index 00000000..06462274
--- /dev/null
+++ b/DnsServerSystemTrayApp/frmManageDnsProviders.resx
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+
+
+ AAABAAUAICAQAAAAAADoAgAAVgAAACAgAAAAAAAAqAgAAD4DAAAwMAAAAAAAAKgOAADmCwAAEBAQAAAA
+ AAAoAQAAjhoAABAQAAAAAAAAaAUAALYbAAAoAAAAIAAAAEAAAAABAAQAAAAAAIACAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwACAgIAAAAD/AAD/AAAA//8A/wAAAP8A
+ /wD//wAA////AMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzP//zP//////////////zMz/
+ /8z//////////////8zM///M///////////////MzP//zP//////////////zMz//8zMzMzMzMz//8zM
+ zMzM///MzMzMzMzM///MzMzMzP//////////zP//zP//zMz//////////8z//8z//8zM///////////M
+ ///M///MzP//////////zP//zP//zMz//8zMzMzMzMz//8z//8zM///MzMzMzMzM///M///MzP//zP//
+ zMzMzP//zP//zMz//8z//8zMzMz//8z//8zM///M///MzMzM///M///MzP//zP//zMzMzP//zP//zMz/
+ /8z//8zMzMzMzMz//8zM///M///MzMzMzMzM///MzP//zP//zP//////////zMz//8z//8z/////////
+ /8zM///M///M///////////MzP//zP//zP//////////zMzMzMz//8zMzMzMzMz//8zMzMzM///MzMzM
+ zMzM///MzP//////////////zP//zMz//////////////8z//8zM///////////////M///MzP//////
+ ////////zP//zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAA
+ AAABAAgAAAAAAIAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDA
+ wADA3MAA8MqmAAQEBAAICAgADAwMABEREQAWFhYAHBwcACIiIgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8
+ /wBQUP8AkwDWAP/szADG1u8A1ufnAJCprQAAADMAAABmAAAAmQAAAMwAADMAAAAzMwAAM2YAADOZAAAz
+ zAAAM/8AAGYAAABmMwAAZmYAAGaZAABmzAAAZv8AAJkAAACZMwAAmWYAAJmZAACZzAAAmf8AAMwAAADM
+ MwAAzGYAAMyZAADMzAAAzP8AAP9mAAD/mQAA/8wAMwAAADMAMwAzAGYAMwCZADMAzAAzAP8AMzMAADMz
+ MwAzM2YAMzOZADMzzAAzM/8AM2YAADNmMwAzZmYAM2aZADNmzAAzZv8AM5kAADOZMwAzmWYAM5mZADOZ
+ zAAzmf8AM8wAADPMMwAzzGYAM8yZADPMzAAzzP8AM/8zADP/ZgAz/5kAM//MADP//wBmAAAAZgAzAGYA
+ ZgBmAJkAZgDMAGYA/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz/wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZ
+ AABmmTMAZplmAGaZmQBmmcwAZpn/AGbMAABmzDMAZsyZAGbMzABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA
+ /wD/AMwAmZkAAJkzmQCZAJkAmQDMAJkAAACZMzMAmQBmAJkzzACZAP8AmWYAAJlmMwCZM2YAmWaZAJlm
+ zACZM/8AmZkzAJmZZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbMZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnM
+ ZgCZ/5kAmf/MAJn//wDMAAAAmQAzAMwAZgDMAJkAzADMAJkzAADMMzMAzDNmAMwzmQDMM8wAzDP/AMxm
+ AADMZjMAmWZmAMxmmQDMZswAmWb/AMyZAADMmTMAzJlmAMyZmQDMmcwAzJn/AMzMAADMzDMAzMxmAMzM
+ mQDMzMwAzMz/AMz/AADM/zMAmf9mAMz/mQDM/8wAzP//AMwAMwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8z
+ mQD/M8wA/zP/AP9mAAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+ZAAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/M
+ AAD/zDMA/8xmAP/MmQD/zMwA/8z/AP//MwDM/2YA//+ZAP//zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//
+ ZgAhAKUAX19fAHd3dwCGhoYAlpaWAMvLywCysrIA19fXAN3d3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSg
+ oACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////ANXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1f/////V1f//////////////////
+ ///////////V1dXV/////9XV/////////////////////////////9XV1dX/////1dX/////////////
+ ////////////////1dXV1f/////V1f/////////////////////////////V1dXV/////9XV1dXV1dXV
+ 1dXV1dXV/////9XV1dXV1dXV1dX/////1dXV1dXV1dXV1dXV1dX/////1dXV1dXV1dXV1f//////////
+ ///////////V1f/////V1f/////V1dXV/////////////////////9XV/////9XV/////9XV1dX/////
+ ////////////////1dX/////1dX/////1dXV1f/////////////////////V1f/////V1f/////V1dXV
+ /////9XV1dXV1dXV1dXV1dXV/////9XV/////9XV1dX/////1dXV1dXV1dXV1dXV1dX/////1dX/////
+ 1dXV1f/////V1f/////V1dXV1dXV1f/////V1f/////V1dXV/////9XV/////9XV1dXV1dXV/////9XV
+ /////9XV1dX/////1dX/////1dXV1dXV1dX/////1dX/////1dXV1f/////V1f/////V1dXV1dXV1f//
+ ///V1f/////V1dXV/////9XV/////9XV1dXV1dXV1dXV1dXV/////9XV1dX/////1dX/////1dXV1dXV
+ 1dXV1dXV1dX/////1dXV1f/////V1f/////V1f/////////////////////V1dXV/////9XV/////9XV
+ /////////////////////9XV1dX/////1dX/////1dX/////////////////////1dXV1f/////V1f//
+ ///V1f/////////////////////V1dXV1dXV1dXV/////9XV1dXV1dXV1dXV1dXV/////9XV1dXV1dXV
+ 1dX/////1dXV1dXV1dXV1dXV1dX/////1dXV1f/////////////////////////////V1f/////V1dXV
+ /////////////////////////////9XV/////9XV1dX/////////////////////////////1dX/////
+ 1dXV1f/////////////////////////////V1f/////V1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAwAAAAYAAAAAEA
+ CAAAAAAAgAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDc
+ wADwyqYABAQEAAgICAAMDAwAERERABYWFgAcHBwAIiIiACkpKQBVVVUATU1NAEJCQgA5OTkAgHz/AFBQ
+ /wCTANYA/+zMAMbW7wDW5+cAkKmtAAAAMwAAAGYAAACZAAAAzAAAMwAAADMzAAAzZgAAM5kAADPMAAAz
+ /wAAZgAAAGYzAABmZgAAZpkAAGbMAABm/wAAmQAAAJkzAACZZgAAmZkAAJnMAACZ/wAAzAAAAMwzAADM
+ ZgAAzJkAAMzMAADM/wAA/2YAAP+ZAAD/zAAzAAAAMwAzADMAZgAzAJkAMwDMADMA/wAzMwAAMzMzADMz
+ ZgAzM5kAMzPMADMz/wAzZgAAM2YzADNmZgAzZpkAM2bMADNm/wAzmQAAM5kzADOZZgAzmZkAM5nMADOZ
+ /wAzzAAAM8wzADPMZgAzzJkAM8zMADPM/wAz/zMAM/9mADP/mQAz/8wAM///AGYAAABmADMAZgBmAGYA
+ mQBmAMwAZgD/AGYzAABmMzMAZjNmAGYzmQBmM8wAZjP/AGZmAABmZjMAZmZmAGZmmQBmZswAZpkAAGaZ
+ MwBmmWYAZpmZAGaZzABmmf8AZswAAGbMMwBmzJkAZszMAGbM/wBm/wAAZv8zAGb/mQBm/8wAzAD/AP8A
+ zACZmQAAmTOZAJkAmQCZAMwAmQAAAJkzMwCZAGYAmTPMAJkA/wCZZgAAmWYzAJkzZgCZZpkAmWbMAJkz
+ /wCZmTMAmZlmAJmZmQCZmcwAmZn/AJnMAACZzDMAZsxmAJnMmQCZzMwAmcz/AJn/AACZ/zMAmcxmAJn/
+ mQCZ/8wAmf//AMwAAACZADMAzABmAMwAmQDMAMwAmTMAAMwzMwDMM2YAzDOZAMwzzADMM/8AzGYAAMxm
+ MwCZZmYAzGaZAMxmzACZZv8AzJkAAMyZMwDMmWYAzJmZAMyZzADMmf8AzMwAAMzMMwDMzGYAzMyZAMzM
+ zADMzP8AzP8AAMz/MwCZ/2YAzP+ZAMz/zADM//8AzAAzAP8AZgD/AJkAzDMAAP8zMwD/M2YA/zOZAP8z
+ zAD/M/8A/2YAAP9mMwDMZmYA/2aZAP9mzADMZv8A/5kAAP+ZMwD/mWYA/5mZAP+ZzAD/mf8A/8wAAP/M
+ MwD/zGYA/8yZAP/MzAD/zP8A//8zAMz/ZgD//5kA///MAGZm/wBm/2YAZv//AP9mZgD/Zv8A//9mACEA
+ pQBfX18Ad3d3AIaGhgCWlpYAy8vLALKysgDX19cA3d3dAOPj4wDq6uoA8fHxAPj4+ADw+/8ApKCgAICA
+ gAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8A1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV////
+ ////1dXV////////////////////////////////////////////1dXV1dXV////////1dXV////////
+ ////////////////////////////////////1dXV1dXV////////1dXV////////////////////////
+ ////////////////////1dXV1dXV////////1dXV////////////////////////////////////////
+ ////1dXV1dXV////////1dXV////////////////////////////////////////////1dXV1dXV////
+ ////1dXV////////////////////////////////////////////1dXV1dXV////////1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ ////////1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV
+ 1dXV1dXV1dXV////////////////////////////////1dXV////////1dXV////////1dXV1dXV////
+ ////////////////////////////1dXV////////1dXV////////1dXV1dXV////////////////////
+ ////////////1dXV////////1dXV////////1dXV1dXV////////////////////////////////1dXV
+ ////////1dXV////////1dXV1dXV////////////////////////////////1dXV////////1dXV////
+ ////1dXV1dXV////////////////////////////////1dXV////////1dXV////////1dXV1dXV////
+ ////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV////////1dXV1dXV////////1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV////////1dXV////////1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ ////////1dXV////////1dXV1dXV////////1dXV////////1dXV1dXV1dXV1dXV////////1dXV////
+ ////1dXV1dXV////////1dXV////////1dXV1dXV1dXV1dXV////////1dXV////////1dXV1dXV////
+ ////1dXV////////1dXV1dXV1dXV1dXV////////1dXV////////1dXV1dXV////////1dXV////////
+ 1dXV1dXV1dXV1dXV////////1dXV////////1dXV1dXV////////1dXV////////1dXV1dXV1dXV1dXV
+ ////////1dXV////////1dXV1dXV////////1dXV////////1dXV1dXV1dXV1dXV////////1dXV////
+ ////1dXV1dXV////////1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV////
+ ////1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV////////1dXV////////
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV////////1dXV////////1dXV////////////
+ ////////////////////1dXV1dXV////////1dXV////////1dXV////////////////////////////
+ ////1dXV1dXV////////1dXV////////1dXV////////////////////////////////1dXV1dXV////
+ ////1dXV////////1dXV////////////////////////////////1dXV1dXV////////1dXV////////
+ 1dXV////////////////////////////////1dXV1dXV////////1dXV////////1dXV////////////
+ ////////////////////1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////
+ ////1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV1dXV
+ 1dXV1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV////////1dXV1dXV////////////////////
+ ////////////////////////1dXV////////1dXV1dXV////////////////////////////////////
+ ////////1dXV////////1dXV1dXV////////////////////////////////////////////1dXV////
+ ////1dXV1dXV////////////////////////////////////////////1dXV////////1dXV1dXV////
+ ////////////////////////////////////////1dXV////////1dXV1dXV////////////////////
+ ////////////////////////1dXV////////1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV
+ 1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXVAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAKAAAABAAAAAgAAAAAQAEAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAIAAAIAAAACAgACAAAAAgACAAICAAADAwMAAgICAAAAA/wAA/wAAAP//AP8AAAD/AP8A//8AAP//
+ /wDMzMzMzMzMzM/8///////8z/z///////zP/MzMzP/MzM/////8/8/8z/////z/z/zP/MzMzP/P/M/8
+ /8zM/8/8z/z/zMz/z/zP/P/MzMzP/M/8/8/////8z/z/z/////zMzP/MzMzP/M///////8/8z///////
+ z/zMzMzMzMzMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAoAAAAEAAAACAAAAABAAgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ gAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAQEBAAICAgADAwMABEREQAWFhYAHBwcACIi
+ IgApKSkAVVVVAE1NTQBCQkIAOTk5AIB8/wBQUP8AkwDWAP/szADG1u8A1ufnAJCprQAAADMAAABmAAAA
+ mQAAAMwAADMAAAAzMwAAM2YAADOZAAAzzAAAM/8AAGYAAABmMwAAZmYAAGaZAABmzAAAZv8AAJkAAACZ
+ MwAAmWYAAJmZAACZzAAAmf8AAMwAAADMMwAAzGYAAMyZAADMzAAAzP8AAP9mAAD/mQAA/8wAMwAAADMA
+ MwAzAGYAMwCZADMAzAAzAP8AMzMAADMzMwAzM2YAMzOZADMzzAAzM/8AM2YAADNmMwAzZmYAM2aZADNm
+ zAAzZv8AM5kAADOZMwAzmWYAM5mZADOZzAAzmf8AM8wAADPMMwAzzGYAM8yZADPMzAAzzP8AM/8zADP/
+ ZgAz/5kAM//MADP//wBmAAAAZgAzAGYAZgBmAJkAZgDMAGYA/wBmMwAAZjMzAGYzZgBmM5kAZjPMAGYz
+ /wBmZgAAZmYzAGZmZgBmZpkAZmbMAGaZAABmmTMAZplmAGaZmQBmmcwAZpn/AGbMAABmzDMAZsyZAGbM
+ zABmzP8AZv8AAGb/MwBm/5kAZv/MAMwA/wD/AMwAmZkAAJkzmQCZAJkAmQDMAJkAAACZMzMAmQBmAJkz
+ zACZAP8AmWYAAJlmMwCZM2YAmWaZAJlmzACZM/8AmZkzAJmZZgCZmZkAmZnMAJmZ/wCZzAAAmcwzAGbM
+ ZgCZzJkAmczMAJnM/wCZ/wAAmf8zAJnMZgCZ/5kAmf/MAJn//wDMAAAAmQAzAMwAZgDMAJkAzADMAJkz
+ AADMMzMAzDNmAMwzmQDMM8wAzDP/AMxmAADMZjMAmWZmAMxmmQDMZswAmWb/AMyZAADMmTMAzJlmAMyZ
+ mQDMmcwAzJn/AMzMAADMzDMAzMxmAMzMmQDMzMwAzMz/AMz/AADM/zMAmf9mAMz/mQDM/8wAzP//AMwA
+ MwD/AGYA/wCZAMwzAAD/MzMA/zNmAP8zmQD/M8wA/zP/AP9mAAD/ZjMAzGZmAP9mmQD/ZswAzGb/AP+Z
+ AAD/mTMA/5lmAP+ZmQD/mcwA/5n/AP/MAAD/zDMA/8xmAP/MmQD/zMwA/8z/AP//MwDM/2YA//+ZAP//
+ zABmZv8AZv9mAGb//wD/ZmYA/2b/AP//ZgAhAKUAX19fAHd3dwCGhoYAlpaWAMvLywCysrIA19fXAN3d
+ 3QDj4+MA6urqAPHx8QD4+PgA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////ANXV
+ 1dXV1dXV1dXV1dXV1dXV///V///////////////V1f//1f//////////////1dX//9XV1dXV1dX//9XV
+ 1dXV///////////V///V///V1f//////////1f//1f//1dX//9XV1dXV1dX//9X//9XV///V///V1dXV
+ ///V///V1f//1f//1dXV1f//1f//1dX//9X//9XV1dXV1dX//9XV///V///V///////////V1f//1f//
+ 1f//////////1dXV1dX//9XV1dXV1dX//9XV///////////////V///V1f//////////////1f//1dXV
+ 1dXV1dXV1dXV1dXV1dUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAA
+
+
+
\ No newline at end of file