CliProgram.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. using SvdCli.App;
  2. using SvdCli.ServiceUtils;
  3. using SvdCli.Storage;
  4. using SvdCli.WindowsService;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Reflection;
  11. using System.Security;
  12. using System.ServiceProcess;
  13. using System.Text.RegularExpressions;
  14. namespace SvdCli
  15. {
  16. internal static class CliProgram
  17. {
  18. private static void Main(string[] args)
  19. {
  20. if (args.Length < 3)
  21. {
  22. Console.WriteLine(@"Usage:");
  23. Console.WriteLine(@"");
  24. Console.WriteLine(@"Create Raw 50GB C:\Path\To\Your\Image.img");
  25. Console.WriteLine(@"Create Bdd 10GB 64KB C:\Path\To\Your\Bdd.bdd");
  26. Console.WriteLine(@"Create Bdd 64KB C:\Path\To\Your\Image.img C:\Path\To\Your\Bdd.bdd");
  27. Console.WriteLine(@"Compact Bdd C:\Path\To\Your\Bdd.bdd");
  28. Console.WriteLine(@"");
  29. Console.WriteLine(@"[Install ServiceName|Service] <Mount|Server 0.0.0.0 2333> RamDisk 10GB");
  30. Console.WriteLine(@"[Install ServiceName|Service] <Mount|Server 0.0.0.0 2333> RamDisk 10GB C:\Path\To\Your\Bdd.Bdd [ReadOnly]");
  31. Console.WriteLine(@"[Install ServiceName|Service] <Mount|Server 0.0.0.0 2333> Image C:\Path\To\Your\Image.img [ReadOnly]");
  32. Console.WriteLine(@"[Install ServiceName|Service] <Mount|Server 0.0.0.0 2333> Image C:\Path\To\Your\Bdd.bdd [ReadOnly]");
  33. Console.WriteLine(@"[Install ServiceName|Service] Mount Net 192.168.233.233 2333");
  34. Console.WriteLine(@"[Install ServiceName|Service] Server 192.168.233.233 2333 Dispatch 64KB C:\Path\To\Your\Image.img C:\Path\To\Your\Dir\");
  35. Console.WriteLine(@"");
  36. Console.WriteLine(@"Uninstall ServiceName Safe:Restrict to register by this program");
  37. Console.WriteLine(@"");
  38. Console.Write("Press ENTER to exit");
  39. Console.ReadLine();
  40. return;
  41. }
  42. EndPoint serverEndPoint = null;
  43. IStorage storage = null;
  44. switch (args[0].ToLower())
  45. {
  46. case "install":
  47. {
  48. var serviceName = args[1];
  49. var serviceArgs = new List<string>() { Assembly.GetExecutingAssembly().Location, "Service" };
  50. serviceArgs.AddRange(args.Skip(2));
  51. ServiceHelper.Install(serviceName, "", string.Join(" ", serviceArgs), "", ServiceStartType.Auto);
  52. }
  53. break;
  54. case "uninstall":
  55. {
  56. var serviceName = args[1];
  57. var binPath = ServiceHelper.GetBinPath(serviceName);
  58. if (true == binPath?.Contains(Path.GetFileName(Assembly.GetExecutingAssembly().Location))) ServiceHelper.Uninstall(serviceName);
  59. else throw new SecurityException("Specified service must register by this program");
  60. }
  61. break;
  62. case "service":
  63. args = args.Skip(1).ToArray();
  64. switch (args[0].ToLower())
  65. {
  66. default: throw new InvalidOperationException("Invalid param: OP");
  67. case "server":
  68. serverEndPoint = new IPEndPoint(IPAddress.Parse(args[1]), int.Parse(args[2]));
  69. if (args[3].ToLower() == "dispatch")
  70. {
  71. //Start TCP Server and listening
  72. //Accept and Get Client MAC
  73. //Create Bdd If Not Exist
  74. //Serving Bdd in `forked' Process use Socket.DuplicateAndClose
  75. throw new NotImplementedException();
  76. }
  77. args = args.Skip(3).ToArray();
  78. goto case "mount";
  79. case "mount":
  80. storage = ParseMount(args.Skip(1).ToArray());
  81. break;
  82. }
  83. ServiceBase.Run(new ServiceBase[] { new SvdServiceForWindows(new SvdService(storage, serverEndPoint)) });
  84. break;
  85. default:
  86. switch (args[0].ToLower())
  87. {
  88. case "create":
  89. ParseCreate(args.Skip(1).ToArray());
  90. return;
  91. case "compact":
  92. ParseCompact(args.Skip(1).ToArray());
  93. return;
  94. case "server":
  95. serverEndPoint = new IPEndPoint(IPAddress.Parse(args[1]), int.Parse(args[2]));
  96. args = args.Skip(3).ToArray();
  97. goto case "mount";
  98. case "mount":
  99. storage = ParseMount(args.Skip(1).ToArray());
  100. break;
  101. }
  102. var svc = new SvdService(storage, serverEndPoint);
  103. svc.Start();
  104. Console.WriteLine();
  105. Console.Write("Press ENTER to Stop");
  106. Console.ReadLine();
  107. svc.Stop();
  108. break;
  109. }
  110. }
  111. private static void ParseCreate(string[] args)
  112. {
  113. //Raw 50GB C:\Path\To\Your\Image.img
  114. //Bdd 10GB 64KB C:\Path\To\Your\Bdd.bdd
  115. //Bdd 64KB C:\Path\To\Your\Image.img C:\Path\To\Your\Bdd.bdd
  116. switch (args[0].ToLower())
  117. {
  118. case "raw":
  119. case "bdd":
  120. default: throw new ArgumentException("Unknown image type");
  121. }
  122. }
  123. private static IStorage ParseMount(string[] args)
  124. {
  125. //RamDisk 10GB
  126. //RamDisk 10GB C:\Path\To\Your\Bdd.Bdd [ReadOnly]
  127. //Image C:\Path\To\Your\Image.img [ReadOnly]
  128. //Image C:\Path\To\Your\Bdd.bdd [ReadOnly]
  129. //Net 192.168.233.233 2333
  130. switch (args[0].ToLower())
  131. {
  132. case "ramdisk":
  133. if (ParseDiskSize(args[1], out var value, out var unit))
  134. {
  135. if (false == string.IsNullOrWhiteSpace(unit) && false == unit.StartsWith("g"))
  136. throw new ArgumentException("RamDisk only GB supported");
  137. var storage = new UnmanagedGigabyteRamDisk(value);
  138. //TODO: load bdd
  139. if (args.Length > 2) throw new NotImplementedException();
  140. if (args.Length > 3 && args[3].ToLower() == "readonly") storage.WriteProtect = true;
  141. return storage;
  142. }
  143. throw new ArgumentException("Failure to parse args");
  144. case "image":
  145. case "net":
  146. default:
  147. throw new ArgumentOutOfRangeException();
  148. }
  149. }
  150. private static void ParseCompact(string[] args)
  151. {
  152. //Bdd C:\Path\To\Your\Bdd.bdd
  153. throw new NotImplementedException();
  154. }
  155. //////////////////////////////////////////////
  156. private static readonly Regex DiskSizeRegex = new Regex(@"^(\d+)([KkMmGg]{1}[Bb]{0,1}){0,1}$", RegexOptions.Compiled);
  157. private static bool ParseDiskSize(string input, out int value, out string unit)
  158. {
  159. var m = DiskSizeRegex.Match(input);
  160. if (false == m.Success)
  161. {
  162. value = 0;
  163. unit = null;
  164. return false;
  165. }
  166. unit = m.Groups[2].Value.ToLower();
  167. value = int.Parse(m.Groups[1].Value);
  168. return true;
  169. }
  170. private static long CalcDiskSize(int value, string unit)
  171. {
  172. switch (unit.ToLower())
  173. {
  174. case "":
  175. return value;
  176. case "k":
  177. case "kb":
  178. return value * CapacityUnits.KiloByte;
  179. case "m":
  180. case "mb":
  181. return value * CapacityUnits.MegaByte;
  182. case "g":
  183. case "gb":
  184. return value * CapacityUnits.Gigabyte;
  185. default: throw new ArgumentOutOfRangeException();
  186. }
  187. }
  188. }
  189. }