MainForm.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /* Copyright (C) 2016 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using ISCSI.Server;
  8. using ISCSIConsole.Mods;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Configuration;
  12. using System.Linq;
  13. using System.Net;
  14. using System.Net.NetworkInformation;
  15. using System.Net.Sockets;
  16. using System.Windows.Forms;
  17. using Utilities;
  18. namespace ISCSIConsole
  19. {
  20. public partial class MainForm : BaseForm
  21. {
  22. private ISCSIServer m_server = new ISCSIServer();
  23. private List<ISCSITarget> m_targets = new List<ISCSITarget>();
  24. private UsageCounter m_usageCounter = new UsageCounter();
  25. private bool m_started = false;
  26. public MainForm()
  27. {
  28. InitializeComponent();
  29. }
  30. private void MainForm_Load(object sender, EventArgs e)
  31. {
  32. var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
  33. Text += " v" + version.ToString(3);
  34. m_server.OnLogEntry += Program.OnLogEntry;
  35. var localIPs = GetHostIPAddresses();
  36. var list = new KeyValuePairList<string, IPAddress>();
  37. list.Add("Any", IPAddress.Any);
  38. foreach (var address in localIPs)
  39. {
  40. list.Add(address.ToString(), address);
  41. }
  42. comboIPAddress.DataSource = list;
  43. comboIPAddress.DisplayMember = "Key";
  44. comboIPAddress.ValueMember = "Value";
  45. lblStatus.Text = "Author: Tal Aloni (tal.aloni.il@gmail.com)";
  46. #if Win32
  47. if (!SecurityHelper.IsAdministrator())
  48. {
  49. lblStatus.Text = "Some features require administrator privileges and have been disabled";
  50. }
  51. #endif
  52. }
  53. private void btnStart_Click(object sender, EventArgs e)
  54. {
  55. if (!m_started)
  56. {
  57. var serverAddress = (IPAddress)comboIPAddress.SelectedValue;
  58. var port = Conversion.ToInt32(txtPort.Text, 0);
  59. if (port <= 0 || port > UInt16.MaxValue)
  60. {
  61. MessageBox.Show("Invalid TCP port", "Error");
  62. return;
  63. }
  64. var endpoint = new IPEndPoint(serverAddress, port);
  65. try
  66. {
  67. m_server.Start(endpoint);
  68. }
  69. catch (SocketException ex)
  70. {
  71. MessageBox.Show("Cannot start server, " + ex.Message, "Error");
  72. return;
  73. }
  74. btnStart.Text = "Stop";
  75. txtPort.Enabled = false;
  76. comboIPAddress.Enabled = false;
  77. m_started = true;
  78. UpdateUI();
  79. }
  80. else
  81. {
  82. m_server.Stop();
  83. lblStatus.Text = String.Empty;
  84. m_started = false;
  85. btnStart.Text = "Start";
  86. txtPort.Enabled = true;
  87. comboIPAddress.Enabled = true;
  88. }
  89. }
  90. private void btnAddTarget_Click(object sender, EventArgs e)
  91. {
  92. var addTarget = new AddTargetForm();
  93. var addTargetResult = addTarget.ShowDialog();
  94. if (addTargetResult == DialogResult.OK)
  95. {
  96. var target = addTarget.Target;
  97. try
  98. {
  99. AddTarget(target);
  100. }
  101. catch (Exception ex)
  102. {
  103. MessageBox.Show(ex.Message, "Error");
  104. }
  105. }
  106. }
  107. private void AddTarget(ISCSITarget target)
  108. {
  109. ((SCSI.VirtualSCSITarget)target.SCSITarget).OnLogEntry += Program.OnLogEntry;
  110. target.OnAuthorizationRequest += ISCSITarget_OnAuthorizationRequest;
  111. target.OnSessionTermination += ISCSITarget_OnSessionTermination;
  112. m_targets.Add(target);
  113. m_server.AddTarget(target);
  114. listTargets.Items.Add(target.TargetName);
  115. }
  116. private void btnRemoveTarget_Click(object sender, EventArgs e)
  117. {
  118. if (listTargets.SelectedIndices.Count > 0)
  119. {
  120. var targetIndex = listTargets.SelectedIndices[0];
  121. var target = m_targets[targetIndex];
  122. var isTargetRemoved = m_server.RemoveTarget(target.TargetName);
  123. if (!isTargetRemoved)
  124. {
  125. MessageBox.Show("Could not remove iSCSI target", "Error");
  126. return;
  127. }
  128. var disks = ((SCSI.VirtualSCSITarget)target.SCSITarget).Disks;
  129. LockUtils.ReleaseDisks(disks);
  130. m_targets.RemoveAt(targetIndex);
  131. listTargets.Items.RemoveAt(targetIndex);
  132. }
  133. }
  134. private void ISCSITarget_OnAuthorizationRequest(object sender, AuthorizationRequestArgs e)
  135. {
  136. var targetName = ((ISCSITarget)sender).TargetName;
  137. m_usageCounter.NotifySessionStart(targetName);
  138. UpdateUI();
  139. }
  140. private void ISCSITarget_OnSessionTermination(object sender, SessionTerminationArgs e)
  141. {
  142. var targetName = ((ISCSITarget)sender).TargetName;
  143. m_usageCounter.NotifySessionTermination(targetName);
  144. UpdateUI();
  145. }
  146. private void UpdateUI()
  147. {
  148. if (InvokeRequired)
  149. {
  150. Invoke((MethodInvoker)UpdateUI);
  151. }
  152. else
  153. {
  154. if (m_started)
  155. {
  156. lblStatus.Text = String.Format("{0} Active Sessions", m_usageCounter.SessionCount);
  157. }
  158. if (listTargets.SelectedIndices.Count > 0)
  159. {
  160. var targetIndex = listTargets.SelectedIndices[0];
  161. var target = m_targets[targetIndex];
  162. var isInUse = m_usageCounter.IsTargetInUse(target.TargetName);
  163. btnRemoveTarget.Enabled = !isInUse;
  164. }
  165. else
  166. {
  167. btnRemoveTarget.Enabled = false;
  168. }
  169. }
  170. }
  171. private static List<IPAddress> GetHostIPAddresses()
  172. {
  173. var result = new List<IPAddress>();
  174. foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
  175. {
  176. var ipProperties = netInterface.GetIPProperties();
  177. foreach (var addressInfo in ipProperties.UnicastAddresses)
  178. {
  179. if (addressInfo.Address.AddressFamily == AddressFamily.InterNetwork)
  180. {
  181. result.Add(addressInfo.Address);
  182. }
  183. }
  184. }
  185. return result;
  186. }
  187. private void listTargets_SelectedIndexChanged(object sender, EventArgs e)
  188. {
  189. UpdateUI();
  190. }
  191. private void LoadConfigButton_Click(object sender, EventArgs e)
  192. {
  193. if (0 != m_targets.Count)
  194. {
  195. MessageBox.Show("Remove all targets before load config");
  196. return;
  197. }
  198. LoadFromConfig();
  199. }
  200. private void LoadFromConfig()
  201. {
  202. var entries = ((List<AutoLoadEntry>)ConfigurationManager.GetSection("autoLoad")).Where(p => p.Enable).ToArray();
  203. if (entries.Length != entries.Select(p => p.Iqn).Distinct().Count())
  204. {
  205. MessageBox.Show("Config error: Iqn should no duplicate");
  206. return;
  207. }
  208. var arr = new ISCSITarget[entries.Length];
  209. for (int i = 0; i < arr.Length; i++)
  210. {
  211. arr[i] = entries[i].CreateTarget();
  212. }
  213. foreach (var target in arr)
  214. {
  215. AddTarget(target);
  216. }
  217. }
  218. private void MainForm_Shown(object sender, EventArgs e)
  219. {
  220. if (IPAddress.TryParse(ConfigurationManager.AppSettings["Listen"], out var ipAddress)) comboIPAddress.Text = ipAddress.ToString();
  221. if (int.TryParse(ConfigurationManager.AppSettings["Port"], out var port)) txtPort.Text = port.ToString();
  222. if ("true" == ConfigurationManager.AppSettings["AutoLoadConfig"]) LoadFromConfig();
  223. if ("true" == ConfigurationManager.AppSettings["AutoStart"]) btnStart_Click(null, null);
  224. }
  225. }
  226. }