MainApplicationContext.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using DnsServerSystemTrayApp.Properties;
  16. using Microsoft.Win32;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.Diagnostics;
  20. using System.IO;
  21. using System.Management;
  22. using System.Net;
  23. using System.Net.NetworkInformation;
  24. using System.Net.Sockets;
  25. using System.ServiceProcess;
  26. using System.Text;
  27. using System.Windows.Forms;
  28. using TechnitiumLibrary.IO;
  29. namespace DnsServerSystemTrayApp
  30. {
  31. public class MainApplicationContext : ApplicationContext
  32. {
  33. #region variables
  34. const int SERVICE_WAIT_TIMEOUT_SECONDS = 30;
  35. private readonly ServiceController _service = new ServiceController("DnsService");
  36. readonly string _configFile;
  37. readonly List<DnsProvider> _dnsProviders = new List<DnsProvider>();
  38. private NotifyIcon TrayIcon;
  39. private ContextMenuStrip TrayIconContextMenu;
  40. private ToolStripMenuItem DashboardMenuItem;
  41. private ToolStripMenuItem NetworkDnsMenuItem;
  42. private ToolStripMenuItem DefaultNetworkDnsMenuItem;
  43. private ToolStripMenuItem ManageNetworkDnsMenuItem;
  44. private ToolStripMenuItem ServiceMenuItem;
  45. private ToolStripMenuItem StartServiceMenuItem;
  46. private ToolStripMenuItem RestartServiceMenuItem;
  47. private ToolStripMenuItem StopServiceMenuItem;
  48. private ToolStripMenuItem FirewallMenuItem;
  49. private ToolStripMenuItem AboutMenuItem;
  50. private ToolStripMenuItem AutoStartMenuItem;
  51. private ToolStripMenuItem ExitMenuItem;
  52. #endregion
  53. #region constructor
  54. public MainApplicationContext(string configFile, string[] args, ref bool exitApp)
  55. {
  56. _configFile = configFile;
  57. LoadConfig();
  58. InitializeComponent();
  59. if (args.Length > 0)
  60. {
  61. switch (args[0])
  62. {
  63. case "--network-dns-default-exit":
  64. SetNetworkDnsToDefault(true);
  65. exitApp = true;
  66. break;
  67. case "--network-dns-default":
  68. SetNetworkDnsToDefault();
  69. break;
  70. case "--network-dns-item":
  71. foreach (DnsProvider dnsProvider in _dnsProviders)
  72. {
  73. if ((args.Length > 1) && dnsProvider.Name.Equals(args[1]))
  74. {
  75. NetworkDnsMenuSubItem_Click(new ToolStripMenuItem(dnsProvider.Name) { Tag = dnsProvider }, EventArgs.Empty);
  76. break;
  77. }
  78. }
  79. break;
  80. case "--network-dns-manage":
  81. ManageNetworkDnsMenuItem_Click(this, EventArgs.Empty);
  82. break;
  83. case "--service-start":
  84. StartServiceMenuItem_Click(this, EventArgs.Empty);
  85. break;
  86. case "--service-restart":
  87. RestartServiceMenuItem_Click(this, EventArgs.Empty);
  88. break;
  89. case "--service-stop":
  90. StopServiceMenuItem_Click(this, EventArgs.Empty);
  91. break;
  92. case "--auto-firewall-entry":
  93. if (args.Length > 1)
  94. SetAutoFirewallEntry(bool.Parse(args[1]));
  95. break;
  96. case "--first-run":
  97. bool usingLoopbackAsDns = false;
  98. try
  99. {
  100. foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
  101. {
  102. if (nic.OperationalStatus != OperationalStatus.Up)
  103. continue;
  104. foreach (IPAddress dnsAddress in nic.GetIPProperties().DnsAddresses)
  105. {
  106. if (IPAddress.IsLoopback(dnsAddress))
  107. {
  108. usingLoopbackAsDns = true;
  109. break;
  110. }
  111. }
  112. if (usingLoopbackAsDns)
  113. break;
  114. }
  115. }
  116. catch
  117. { }
  118. if (!usingLoopbackAsDns && MessageBox.Show("Do you want to update this computer's network connections to use the locally running Technitium DNS Server?\r\n\r\nNote! It is recommended that you use the locally running Technitium DNS Server unless you explicitly want to keep using your existing network DNS configuration.", "Switch Network DNS? - Technitium DNS Server", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
  119. SetNetworkDns(new DnsProvider("Technitium", new IPAddress[] { IPAddress.Loopback, IPAddress.IPv6Loopback }));
  120. break;
  121. }
  122. }
  123. }
  124. #endregion
  125. #region IDisposable
  126. protected override void Dispose(bool disposing)
  127. {
  128. if (disposing)
  129. {
  130. TrayIcon?.Dispose();
  131. }
  132. base.Dispose(disposing);
  133. }
  134. #endregion
  135. #region private
  136. private void InitializeComponent()
  137. {
  138. //
  139. // TrayIconContextMenu
  140. //
  141. TrayIconContextMenu = new ContextMenuStrip();
  142. TrayIconContextMenu.SuspendLayout();
  143. //
  144. // TrayIcon
  145. //
  146. TrayIcon = new NotifyIcon();
  147. TrayIcon.Icon = Resources.logo2;
  148. TrayIcon.Visible = true;
  149. TrayIcon.MouseUp += TrayIcon_MouseUp;
  150. TrayIcon.ContextMenuStrip = TrayIconContextMenu;
  151. TrayIcon.Text = Resources.ServiceName;
  152. //
  153. // DashboardMenuItem
  154. //
  155. DashboardMenuItem = new ToolStripMenuItem();
  156. DashboardMenuItem.Name = "DashboardMenuItem";
  157. DashboardMenuItem.Text = Resources.DashboardMenuItem;
  158. DashboardMenuItem.Click += DashboardMenuItem_Click;
  159. //
  160. // NetworkDnsMenuItem
  161. //
  162. NetworkDnsMenuItem = new ToolStripMenuItem();
  163. NetworkDnsMenuItem.Name = "NetworkDnsMenuItem";
  164. NetworkDnsMenuItem.Text = Resources.NetworkDnsMenuItem;
  165. DefaultNetworkDnsMenuItem = new ToolStripMenuItem("Default");
  166. DefaultNetworkDnsMenuItem.Click += DefaultNetworkDnsMenuItem_Click;
  167. ManageNetworkDnsMenuItem = new ToolStripMenuItem("Manage");
  168. ManageNetworkDnsMenuItem.Click += ManageNetworkDnsMenuItem_Click;
  169. //
  170. // ServiceMenuItem
  171. //
  172. ServiceMenuItem = new ToolStripMenuItem();
  173. ServiceMenuItem.Name = "ServiceMenuItem";
  174. ServiceMenuItem.Text = Resources.ServiceMenuItem;
  175. StartServiceMenuItem = new ToolStripMenuItem(Resources.ServiceStartMenuItem);
  176. StartServiceMenuItem.Click += StartServiceMenuItem_Click;
  177. RestartServiceMenuItem = new ToolStripMenuItem(Resources.ServiceRestartMenuItem);
  178. RestartServiceMenuItem.Click += RestartServiceMenuItem_Click;
  179. StopServiceMenuItem = new ToolStripMenuItem(Resources.ServiceStopMenuItem);
  180. StopServiceMenuItem.Click += StopServiceMenuItem_Click;
  181. ServiceMenuItem.DropDownItems.AddRange(new ToolStripItem[]
  182. {
  183. StartServiceMenuItem,
  184. RestartServiceMenuItem,
  185. StopServiceMenuItem
  186. });
  187. //
  188. // FirewallMenuItem
  189. //
  190. FirewallMenuItem = new ToolStripMenuItem();
  191. FirewallMenuItem.Name = "FirewallMenuItem";
  192. FirewallMenuItem.Text = "Auto &Firewall Entry";
  193. FirewallMenuItem.Click += FirewallMenuItem_Click;
  194. //
  195. // AboutMenuItem
  196. //
  197. AboutMenuItem = new ToolStripMenuItem();
  198. AboutMenuItem.Name = "AboutMenuItem";
  199. AboutMenuItem.Text = Resources.AboutMenuItem;
  200. AboutMenuItem.Click += AboutMenuItem_Click;
  201. //
  202. // AutoStartMenuItem
  203. //
  204. AutoStartMenuItem = new ToolStripMenuItem();
  205. AutoStartMenuItem.Name = "AutoStartMenuItem";
  206. AutoStartMenuItem.Text = "&Auto Start Icon";
  207. AutoStartMenuItem.Click += AutoStartMenuItem_Click;
  208. //
  209. // ExitMenuItem
  210. //
  211. ExitMenuItem = new ToolStripMenuItem();
  212. ExitMenuItem.Name = "ExitMenuItem";
  213. ExitMenuItem.Text = Resources.ExitMenuItem;
  214. ExitMenuItem.Click += ExitMenuItem_Click;
  215. TrayIconContextMenu.Items.AddRange(new ToolStripItem[]
  216. {
  217. DashboardMenuItem,
  218. new ToolStripSeparator(),
  219. NetworkDnsMenuItem,
  220. ServiceMenuItem,
  221. FirewallMenuItem,
  222. AboutMenuItem,
  223. new ToolStripSeparator(),
  224. AutoStartMenuItem,
  225. ExitMenuItem
  226. });
  227. TrayIconContextMenu.ResumeLayout(false);
  228. }
  229. private void LoadConfig()
  230. {
  231. try
  232. {
  233. using (FileStream fS = new FileStream(_configFile, FileMode.Open, FileAccess.Read))
  234. {
  235. BinaryReader bR = new BinaryReader(fS);
  236. if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "DT")
  237. throw new InvalidDataException("Invalid DNS Server System Tray App config file format.");
  238. switch (bR.ReadByte())
  239. {
  240. case 1:
  241. int count = bR.ReadInt32();
  242. _dnsProviders.Clear();
  243. for (int i = 0; i < count; i++)
  244. _dnsProviders.Add(new DnsProvider(bR));
  245. _dnsProviders.Sort();
  246. break;
  247. default:
  248. throw new NotSupportedException("DNS Server System Tray App config file format is not supported.");
  249. }
  250. }
  251. }
  252. catch (FileNotFoundException)
  253. {
  254. _dnsProviders.Clear();
  255. _dnsProviders.AddRange(DnsProvider.GetDefaultProviders());
  256. _dnsProviders.Sort();
  257. }
  258. catch (Exception ex)
  259. {
  260. MessageBox.Show("Error occured while loading config file. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  261. }
  262. }
  263. private void SaveConfig()
  264. {
  265. try
  266. {
  267. using (FileStream fS = new FileStream(_configFile, FileMode.Create, FileAccess.Write))
  268. {
  269. BinaryWriter bW = new BinaryWriter(fS);
  270. bW.Write(Encoding.ASCII.GetBytes("DT"));
  271. bW.Write((byte)1);
  272. bW.Write(_dnsProviders.Count);
  273. foreach (DnsProvider dnsProvider in _dnsProviders)
  274. dnsProvider.WriteTo(bW);
  275. }
  276. }
  277. catch (Exception ex)
  278. {
  279. MessageBox.Show("Error occured while saving config file. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  280. }
  281. }
  282. private static void SetNetworkDns(DnsProvider dnsProvider)
  283. {
  284. if (!Program.IsAdmin)
  285. {
  286. Program.RunAsAdmin("--network-dns-item " + dnsProvider.Name);
  287. return;
  288. }
  289. try
  290. {
  291. foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
  292. {
  293. if (nic.OperationalStatus != OperationalStatus.Up)
  294. continue;
  295. IPInterfaceProperties properties = nic.GetIPProperties();
  296. if ((properties.DnsAddresses.Count > 0) && !properties.DnsAddresses[0].IsIPv6SiteLocal)
  297. SetNameServer(nic, dnsProvider.Addresses);
  298. }
  299. MessageBox.Show("The network DNS servers were set to " + dnsProvider.Name + " successfully.", dnsProvider.Name + " Configured - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
  300. }
  301. catch (Exception ex)
  302. {
  303. MessageBox.Show("Error occured while setting " + dnsProvider.Name + " as network DNS server. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  304. }
  305. }
  306. private static void SetNameServer(NetworkInterface nic, ICollection<IPAddress> dnsAddresses)
  307. {
  308. SetNameServerIPv4(nic, dnsAddresses);
  309. SetNameServerIPv6(nic, dnsAddresses);
  310. }
  311. private static void SetNameServerIPv4(NetworkInterface nic, ICollection<IPAddress> dnsAddresses)
  312. {
  313. ManagementClass networkAdapterConfig = new ManagementClass("Win32_NetworkAdapterConfiguration");
  314. ManagementObjectCollection instances = networkAdapterConfig.GetInstances();
  315. foreach (ManagementObject obj in instances)
  316. {
  317. if ((bool)obj["IPEnabled"] && obj["SettingID"].Equals(nic.Id))
  318. {
  319. List<string> dnsServers = new List<string>();
  320. foreach (IPAddress dnsAddress in dnsAddresses)
  321. {
  322. if (dnsAddress.AddressFamily != AddressFamily.InterNetwork)
  323. continue;
  324. dnsServers.Add(dnsAddress.ToString());
  325. }
  326. ManagementBaseObject objParameter = obj.GetMethodParameters("SetDNSServerSearchOrder");
  327. objParameter["DNSServerSearchOrder"] = dnsServers.ToArray();
  328. ManagementBaseObject response = obj.InvokeMethod("SetDNSServerSearchOrder", objParameter, null);
  329. uint returnValue = (uint)response.GetPropertyValue("ReturnValue");
  330. switch (returnValue)
  331. {
  332. case 0: //success
  333. case 1: //reboot required
  334. break;
  335. case 64:
  336. throw new Exception("Method not supported on this platform. WMI error code: " + returnValue);
  337. case 65:
  338. throw new Exception("Unknown failure. WMI error code: " + returnValue);
  339. case 70:
  340. throw new Exception("Invalid IP address. WMI error code: " + returnValue);
  341. case 96:
  342. throw new Exception("Unable to notify DNS service. WMI error code: " + returnValue);
  343. case 97:
  344. throw new Exception("Interface not configurable. WMI error code: " + returnValue);
  345. default:
  346. throw new Exception("WMI error code: " + returnValue);
  347. }
  348. break;
  349. }
  350. }
  351. }
  352. private static void SetNameServerIPv6(NetworkInterface nic, ICollection<IPAddress> dnsAddresses)
  353. {
  354. //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces\{}
  355. string nameServer = null;
  356. foreach (IPAddress dnsAddress in dnsAddresses)
  357. {
  358. if (dnsAddress.AddressFamily != AddressFamily.InterNetworkV6)
  359. continue;
  360. if (nameServer == null)
  361. nameServer = dnsAddress.ToString();
  362. else
  363. nameServer += "," + dnsAddress.ToString();
  364. }
  365. if (nameServer == null)
  366. nameServer = "";
  367. using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters\Interfaces\" + nic.Id, true))
  368. {
  369. if (key is not null)
  370. key.SetValue("NameServer", nameServer, RegistryValueKind.String);
  371. }
  372. }
  373. private static void SetAutoFirewallEntry(bool value)
  374. {
  375. try
  376. {
  377. using (RegistryKey key = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Technitium\DNS Server", true))
  378. {
  379. if (key is not null)
  380. key.SetValue("AutoFirewallEntry", value ? 1 : 0, RegistryValueKind.DWord);
  381. }
  382. }
  383. catch (Exception ex)
  384. {
  385. MessageBox.Show("Error occured while setting auto firewall registry entry value. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  386. }
  387. }
  388. private static bool AddressExists(ICollection<IPAddress> checkAddresses, ICollection<IPAddress> addresses)
  389. {
  390. foreach (IPAddress checkAddress in checkAddresses)
  391. {
  392. foreach (IPAddress address in addresses)
  393. {
  394. if (checkAddress.Equals(address))
  395. return true;
  396. }
  397. }
  398. return false;
  399. }
  400. private void TrayIcon_MouseUp(object sender, MouseEventArgs e)
  401. {
  402. if (e.Button == MouseButtons.Right)
  403. {
  404. #region Network DNS
  405. List<IPAddress> networkDnsAddresses = new List<IPAddress>();
  406. try
  407. {
  408. foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
  409. {
  410. if (nic.OperationalStatus != OperationalStatus.Up)
  411. continue;
  412. networkDnsAddresses.AddRange(nic.GetIPProperties().DnsAddresses);
  413. }
  414. }
  415. catch
  416. { }
  417. NetworkDnsMenuItem.DropDownItems.Clear();
  418. NetworkDnsMenuItem.DropDownItems.Add(DefaultNetworkDnsMenuItem);
  419. NetworkDnsMenuItem.DropDownItems.Add(new ToolStripSeparator());
  420. bool noItemChecked = true;
  421. DefaultNetworkDnsMenuItem.Checked = false;
  422. foreach (DnsProvider dnsProvider in _dnsProviders)
  423. {
  424. ToolStripMenuItem item = new ToolStripMenuItem(dnsProvider.Name);
  425. item.Tag = dnsProvider;
  426. item.Click += NetworkDnsMenuSubItem_Click;
  427. if (AddressExists(networkDnsAddresses, dnsProvider.Addresses))
  428. {
  429. item.Checked = true;
  430. noItemChecked = false;
  431. }
  432. NetworkDnsMenuItem.DropDownItems.Add(item);
  433. }
  434. if (noItemChecked)
  435. {
  436. foreach (IPAddress dnsAddress in networkDnsAddresses)
  437. {
  438. if (!dnsAddress.IsIPv6SiteLocal)
  439. {
  440. DefaultNetworkDnsMenuItem.Checked = true;
  441. break;
  442. }
  443. }
  444. }
  445. if (_dnsProviders.Count > 0)
  446. NetworkDnsMenuItem.DropDownItems.Add(new ToolStripSeparator());
  447. NetworkDnsMenuItem.DropDownItems.Add(ManageNetworkDnsMenuItem);
  448. #endregion
  449. #region service
  450. try
  451. {
  452. _service.Refresh();
  453. switch (_service.Status)
  454. {
  455. case ServiceControllerStatus.Stopped:
  456. DashboardMenuItem.Enabled = false;
  457. StartServiceMenuItem.Enabled = true;
  458. RestartServiceMenuItem.Enabled = false;
  459. StopServiceMenuItem.Enabled = false;
  460. break;
  461. case ServiceControllerStatus.Running:
  462. DashboardMenuItem.Enabled = true;
  463. StartServiceMenuItem.Enabled = false;
  464. RestartServiceMenuItem.Enabled = true;
  465. StopServiceMenuItem.Enabled = true;
  466. break;
  467. default:
  468. DashboardMenuItem.Enabled = false;
  469. StartServiceMenuItem.Enabled = false;
  470. RestartServiceMenuItem.Enabled = false;
  471. StopServiceMenuItem.Enabled = false;
  472. break;
  473. }
  474. ServiceMenuItem.Enabled = true;
  475. }
  476. catch
  477. {
  478. DashboardMenuItem.Enabled = false;
  479. ServiceMenuItem.Enabled = false;
  480. }
  481. #endregion
  482. #region auto firewall
  483. bool autoFirewallEntry = true;
  484. try
  485. {
  486. using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Technitium\DNS Server", false))
  487. {
  488. if (key is not null)
  489. autoFirewallEntry = Convert.ToInt32(key.GetValue("AutoFirewallEntry", 1)) == 1;
  490. }
  491. }
  492. catch
  493. { }
  494. FirewallMenuItem.Checked = autoFirewallEntry;
  495. #endregion
  496. #region auto start
  497. try
  498. {
  499. using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", false))
  500. {
  501. if (key is not null)
  502. {
  503. string autoStartPath = key.GetValue("Technitium DNS System Tray") as string;
  504. AutoStartMenuItem.Checked = (autoStartPath != null) && autoStartPath.Equals("\"" + Program.APP_PATH + "\"");
  505. }
  506. }
  507. }
  508. catch
  509. { }
  510. #endregion
  511. TrayIcon.ShowContextMenu();
  512. }
  513. }
  514. private void DashboardMenuItem_Click(object sender, EventArgs e)
  515. {
  516. int port = 5380;
  517. try
  518. {
  519. //try finding port number from dns config file
  520. string dnsConfigFile = Path.Combine(Path.GetDirectoryName(Program.APP_PATH), "config", "dns.config");
  521. using (FileStream fS = new FileStream(dnsConfigFile, FileMode.Open, FileAccess.Read))
  522. {
  523. BinaryReader bR = new BinaryReader(fS);
  524. if (Encoding.ASCII.GetString(bR.ReadBytes(2)) != "DS") //format
  525. throw new InvalidDataException("DNS Server config file format is invalid.");
  526. int version = bR.ReadByte();
  527. if (version >= 28)
  528. {
  529. port = bR.ReadInt32();
  530. }
  531. else if (version > 1)
  532. {
  533. string serverDomain = bR.ReadShortString();
  534. port = bR.ReadInt32();
  535. }
  536. }
  537. }
  538. catch
  539. { }
  540. ProcessStartInfo processInfo = new ProcessStartInfo("http://localhost:" + port.ToString());
  541. processInfo.UseShellExecute = true;
  542. processInfo.Verb = "open";
  543. Process.Start(processInfo);
  544. }
  545. private void DefaultNetworkDnsMenuItem_Click(object sender, EventArgs e)
  546. {
  547. SetNetworkDnsToDefault();
  548. }
  549. private static void SetNetworkDnsToDefault(bool silent = false)
  550. {
  551. if (!Program.IsAdmin)
  552. {
  553. if (!silent)
  554. Program.RunAsAdmin("--network-dns-default");
  555. return;
  556. }
  557. try
  558. {
  559. foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
  560. {
  561. if (nic.OperationalStatus != OperationalStatus.Up)
  562. continue;
  563. SetNameServerIPv6(nic, Array.Empty<IPAddress>());
  564. try
  565. {
  566. IPInterfaceProperties properties = nic.GetIPProperties();
  567. if (properties.GetIPv4Properties().IsDhcpEnabled)
  568. {
  569. SetNameServerIPv4(nic, Array.Empty<IPAddress>());
  570. }
  571. else if (properties.GatewayAddresses.Count > 0)
  572. {
  573. SetNameServerIPv4(nic, new IPAddress[] { properties.GatewayAddresses[0].Address });
  574. }
  575. else
  576. {
  577. SetNameServerIPv4(nic, Array.Empty<IPAddress>());
  578. }
  579. }
  580. catch (NetworkInformationException)
  581. { }
  582. }
  583. if (!silent)
  584. MessageBox.Show("The network DNS servers were set to default successfully.", "Default DNS Set - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
  585. }
  586. catch (Exception ex)
  587. {
  588. if (!silent)
  589. MessageBox.Show("Error occured while setting default network DNS servers. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  590. }
  591. }
  592. private void ManageNetworkDnsMenuItem_Click(object sender, EventArgs e)
  593. {
  594. if (!Program.IsAdmin)
  595. {
  596. Program.RunAsAdmin("--network-dns-manage");
  597. return;
  598. }
  599. using (frmManageDnsProviders frm = new frmManageDnsProviders(_dnsProviders))
  600. {
  601. if (frm.ShowDialog() == DialogResult.OK)
  602. {
  603. _dnsProviders.Clear();
  604. _dnsProviders.AddRange(frm.DnsProviders);
  605. _dnsProviders.Sort();
  606. SaveConfig();
  607. }
  608. }
  609. }
  610. private void NetworkDnsMenuSubItem_Click(object sender, EventArgs e)
  611. {
  612. ToolStripMenuItem item = sender as ToolStripMenuItem;
  613. DnsProvider dnsProvider = item.Tag as DnsProvider;
  614. SetNetworkDns(dnsProvider);
  615. }
  616. private void StartServiceMenuItem_Click(object sender, EventArgs e)
  617. {
  618. if (!Program.IsAdmin)
  619. {
  620. Program.RunAsAdmin("--service-start");
  621. return;
  622. }
  623. try
  624. {
  625. _service.Start();
  626. _service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, SERVICE_WAIT_TIMEOUT_SECONDS));
  627. MessageBox.Show("The service was started successfully.", "Service Started - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
  628. }
  629. catch (System.ServiceProcess.TimeoutException ex)
  630. {
  631. MessageBox.Show("The service did not respond in time." + ex.Message, "Service Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
  632. }
  633. catch (Exception ex)
  634. {
  635. MessageBox.Show("Error occured while starting service. " + ex.Message, "Service Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  636. }
  637. }
  638. private void RestartServiceMenuItem_Click(object sender, EventArgs e)
  639. {
  640. if (!Program.IsAdmin)
  641. {
  642. Program.RunAsAdmin("--service-restart");
  643. return;
  644. }
  645. try
  646. {
  647. _service.Stop();
  648. _service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, SERVICE_WAIT_TIMEOUT_SECONDS));
  649. _service.Start();
  650. _service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, SERVICE_WAIT_TIMEOUT_SECONDS));
  651. MessageBox.Show("The service was restarted successfully.", "Service Restarted - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
  652. }
  653. catch (System.ServiceProcess.TimeoutException ex)
  654. {
  655. MessageBox.Show("The service did not respond in time." + ex.Message, "Service Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
  656. }
  657. catch (Exception ex)
  658. {
  659. MessageBox.Show("Error occured while restarting service. " + ex.Message, "Service Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  660. }
  661. }
  662. private void StopServiceMenuItem_Click(object sender, EventArgs e)
  663. {
  664. if (!Program.IsAdmin)
  665. {
  666. Program.RunAsAdmin("--service-stop");
  667. return;
  668. }
  669. try
  670. {
  671. _service.Stop();
  672. _service.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, SERVICE_WAIT_TIMEOUT_SECONDS));
  673. MessageBox.Show("The service was stopped successfully.", "Service Stopped - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Information);
  674. }
  675. catch (System.ServiceProcess.TimeoutException ex)
  676. {
  677. MessageBox.Show("The service did not respond in time." + ex.Message, "Service Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
  678. }
  679. catch (Exception ex)
  680. {
  681. MessageBox.Show("Error occured while stopping service. " + ex.Message, "Service Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  682. }
  683. }
  684. private void FirewallMenuItem_Click(object sender, EventArgs e)
  685. {
  686. if (!Program.IsAdmin)
  687. {
  688. Program.RunAsAdmin("--auto-firewall-entry " + (!FirewallMenuItem.Checked).ToString());
  689. return;
  690. }
  691. SetAutoFirewallEntry(!FirewallMenuItem.Checked);
  692. }
  693. private void AboutMenuItem_Click(object sender, EventArgs e)
  694. {
  695. using (frmAbout frm = new frmAbout())
  696. {
  697. frm.ShowDialog();
  698. }
  699. }
  700. private void AutoStartMenuItem_Click(object sender, EventArgs e)
  701. {
  702. if (AutoStartMenuItem.Checked)
  703. {
  704. //remove
  705. try
  706. {
  707. using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true))
  708. {
  709. if (key is not null)
  710. key.DeleteValue("Technitium DNS System Tray", false);
  711. }
  712. }
  713. catch (Exception ex)
  714. {
  715. MessageBox.Show("Error occured while removing auto start registry entry. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  716. }
  717. }
  718. else
  719. {
  720. //add
  721. try
  722. {
  723. using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run", true))
  724. {
  725. if (key is not null)
  726. key.SetValue("Technitium DNS System Tray", "\"" + Program.APP_PATH + "\"", RegistryValueKind.String);
  727. }
  728. }
  729. catch (Exception ex)
  730. {
  731. MessageBox.Show("Error occured while adding auto start registry entry. " + ex.Message, "Error - " + Resources.ServiceName, MessageBoxButtons.OK, MessageBoxIcon.Error);
  732. }
  733. }
  734. }
  735. private void ExitMenuItem_Click(object sender, EventArgs e)
  736. {
  737. if (MessageBox.Show(Resources.AreYouSureYouWantToQuit, Resources.Quit + " - " + Resources.ServiceName, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
  738. Application.Exit();
  739. }
  740. #endregion
  741. }
  742. }