Advapi32.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. using System.ComponentModel;
  6. namespace winsw
  7. {
  8. class ServiceManager : IDisposable
  9. {
  10. private IntPtr Handle;
  11. public ServiceManager()
  12. {
  13. Handle = Advapi32.OpenSCManager(null, null, (uint)SCM_ACCESS.SC_MANAGER_ALL_ACCESS);
  14. if (Handle == IntPtr.Zero)
  15. {
  16. throw new Exception(String.Format("Error connecting to Service Control Manager. Error provided was: 0x{0:X}", Marshal.GetLastWin32Error()));
  17. }
  18. }
  19. public Service Open(string serviceName)
  20. {
  21. IntPtr svcHandle = Advapi32.OpenService(Handle, serviceName, (int)SERVICE_ACCESS.SERVICE_ALL_ACCESS);
  22. if (svcHandle == IntPtr.Zero)
  23. {
  24. throw new Exception(String.Format("Error opening service for modifying. Error returned was: 0x{0:X}", Marshal.GetLastWin32Error()));
  25. }
  26. return new Service(svcHandle);
  27. }
  28. public void Dispose()
  29. {
  30. if (Handle != IntPtr.Zero)
  31. Advapi32.CloseServiceHandle(Handle);
  32. Handle = IntPtr.Zero;
  33. }
  34. }
  35. class Service : IDisposable
  36. {
  37. internal IntPtr Handle;
  38. internal Service(IntPtr service)
  39. {
  40. Handle = service;
  41. }
  42. public void ChangeConfig(TimeSpan failureResetPeriod, List<SC_ACTION> actions)
  43. {
  44. SERVICE_FAILURE_ACTIONS sfa = new SERVICE_FAILURE_ACTIONS();
  45. sfa.dwResetPeriod = (int)failureResetPeriod.TotalSeconds;
  46. sfa.lpRebootMsg = ""; // delete message
  47. sfa.lpCommand = ""; // delete the command to run
  48. int len = Marshal.SizeOf(typeof(SC_ACTION));
  49. sfa.cActions = actions.Count;
  50. sfa.lpsaActions = Marshal.AllocHGlobal(len * actions.Count);
  51. try
  52. {
  53. for (int i = 0; i < actions.Count; i++)
  54. {
  55. Marshal.StructureToPtr(actions[i], new IntPtr(sfa.lpsaActions.ToInt64() + i * len), false);
  56. }
  57. if (!Advapi32.ChangeServiceConfig2(Handle, SERVICE_CONFIG_INFOLEVEL.SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa))
  58. throw new Exception("Failed to change the failure actions", new Win32Exception());
  59. }
  60. finally
  61. {
  62. Marshal.FreeHGlobal(sfa.lpsaActions);
  63. }
  64. }
  65. public void Dispose()
  66. {
  67. if (Handle!=IntPtr.Zero)
  68. Advapi32.CloseServiceHandle(Handle);
  69. Handle = IntPtr.Zero;
  70. }
  71. }
  72. static class LogonAsAService
  73. {
  74. public static void AddLogonAsAServiceRight(string Username)
  75. {
  76. //Needs to be at least XP or 2003 server
  77. //https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832%28v=vs.85%29.aspx
  78. System.OperatingSystem osInfo = System.Environment.OSVersion;
  79. if (osInfo.Version.Major >= 5 && osInfo.Version.Minor >= 1)
  80. {
  81. var newuser = GetLocalAccountIfLocalAccount(Username);
  82. //Trace.WriteLine("Username for Logon as A Service: " + newuser);
  83. long rightexitcode = SetRight(newuser, PrivlegeRights.SeServiceLogonRight.ToString());
  84. if (rightexitcode != 0)
  85. {
  86. Console.WriteLine("Failed to set logon as a service right");
  87. Environment.Exit(1);
  88. }
  89. }
  90. else
  91. {
  92. Console.WriteLine("Cannot set Logon as a Service right. Unsupported operating system detected");
  93. }
  94. }
  95. private static string GetDomain(string s)
  96. {
  97. int stop = s.IndexOf("\\");
  98. if (stop >= 0)
  99. return s.Substring(0, stop);
  100. else
  101. return null;
  102. }
  103. private static string GetLogin(string s)
  104. {
  105. int stop = s.IndexOf("\\");
  106. return (stop > -1) ? s.Substring(stop + 1, s.Length - stop - 1) : s;
  107. }
  108. private static string GetLocalAccountIfLocalAccount(string username)
  109. {
  110. var machinename = Environment.MachineName;
  111. string domain = GetDomain(username);
  112. if (domain == null || domain.ToLower() == machinename.ToLower() || domain == ".")
  113. {
  114. return GetLogin(username);
  115. }
  116. return username;
  117. }
  118. /// <summary>Adds a privilege to an account</summary>
  119. /// <param name="accountName">Name of an account - "domain\account" or only "account"</param>
  120. /// <param name="privilegeName">Name ofthe privilege</param>
  121. /// <returns>The windows error code returned by LsaAddAccountRights</returns>
  122. private static long SetRight(String accountName, String privilegeName)
  123. {
  124. long winErrorCode = 0; //contains the last error
  125. //pointer an size for the SID
  126. IntPtr sid = IntPtr.Zero;
  127. int sidSize = 0;
  128. //StringBuilder and size for the domain name
  129. StringBuilder domainName = new StringBuilder();
  130. int nameSize = 0;
  131. //account-type variable for lookup
  132. int accountType = 0;
  133. //get required buffer size
  134. Advapi32.LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType);
  135. //allocate buffers
  136. domainName = new StringBuilder(nameSize);
  137. sid = Marshal.AllocHGlobal(sidSize);
  138. //lookup the SID for the account
  139. bool result = Advapi32.LookupAccountName(String.Empty, accountName, sid, ref sidSize, domainName, ref nameSize,
  140. ref accountType);
  141. //say what you're doing
  142. //Console.WriteLine("LookupAccountName result = " + result);
  143. //Console.WriteLine("IsValidSid: " + Advapi32.IsValidSid(sid));
  144. //Console.WriteLine("LookupAccountName domainName: " + domainName.ToString());
  145. if (!result)
  146. {
  147. winErrorCode = Kernel32.GetLastError();
  148. Console.WriteLine("LookupAccountName failed: " + winErrorCode);
  149. }
  150. else
  151. {
  152. //initialize an empty unicode-string
  153. LSA_UNICODE_STRING systemName = new LSA_UNICODE_STRING();
  154. //combine all policies
  155. int access = (int)(
  156. LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
  157. LSA_AccessPolicy.POLICY_CREATE_ACCOUNT |
  158. LSA_AccessPolicy.POLICY_CREATE_PRIVILEGE |
  159. LSA_AccessPolicy.POLICY_CREATE_SECRET |
  160. LSA_AccessPolicy.POLICY_GET_PRIVATE_INFORMATION |
  161. LSA_AccessPolicy.POLICY_LOOKUP_NAMES |
  162. LSA_AccessPolicy.POLICY_NOTIFICATION |
  163. LSA_AccessPolicy.POLICY_SERVER_ADMIN |
  164. LSA_AccessPolicy.POLICY_SET_AUDIT_REQUIREMENTS |
  165. LSA_AccessPolicy.POLICY_SET_DEFAULT_QUOTA_LIMITS |
  166. LSA_AccessPolicy.POLICY_TRUST_ADMIN |
  167. LSA_AccessPolicy.POLICY_VIEW_AUDIT_INFORMATION |
  168. LSA_AccessPolicy.POLICY_VIEW_LOCAL_INFORMATION
  169. );
  170. //initialize a pointer for the policy handle
  171. IntPtr policyHandle = IntPtr.Zero;
  172. //these attributes are not used, but LsaOpenPolicy wants them to exists
  173. LSA_OBJECT_ATTRIBUTES ObjectAttributes = new LSA_OBJECT_ATTRIBUTES();
  174. ObjectAttributes.Length = 0;
  175. ObjectAttributes.RootDirectory = IntPtr.Zero;
  176. ObjectAttributes.Attributes = 0;
  177. ObjectAttributes.SecurityDescriptor = IntPtr.Zero;
  178. ObjectAttributes.SecurityQualityOfService = IntPtr.Zero;
  179. //get a policy handle
  180. uint resultPolicy = Advapi32.LsaOpenPolicy(ref systemName, ref ObjectAttributes, access, out policyHandle);
  181. winErrorCode = Advapi32.LsaNtStatusToWinError(resultPolicy);
  182. if (winErrorCode != 0)
  183. {
  184. Console.WriteLine("OpenPolicy failed: " + winErrorCode);
  185. }
  186. else
  187. {
  188. //Now that we have the SID an the policy,
  189. //we can add rights to the account.
  190. //initialize an unicode-string for the privilege name
  191. LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1];
  192. userRights[0] = new LSA_UNICODE_STRING();
  193. userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName);
  194. userRights[0].Length = (UInt16)(privilegeName.Length * UnicodeEncoding.CharSize);
  195. userRights[0].MaximumLength = (UInt16)((privilegeName.Length + 1) * UnicodeEncoding.CharSize);
  196. //add the right to the account
  197. uint res = Advapi32.LsaAddAccountRights(policyHandle, sid, userRights, 1);
  198. winErrorCode = Advapi32.LsaNtStatusToWinError(res);
  199. if (winErrorCode != 0)
  200. {
  201. Console.WriteLine("LsaAddAccountRights failed: " + winErrorCode);
  202. }
  203. Advapi32.LsaClose(policyHandle);
  204. }
  205. Advapi32.FreeSid(sid);
  206. }
  207. return winErrorCode;
  208. }
  209. }
  210. /// <summary>
  211. /// Advapi32.dll wrapper for performing additional service related operations that are not
  212. /// available in WMI.
  213. /// </summary>
  214. internal class Advapi32
  215. {
  216. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  217. [return: MarshalAs(UnmanagedType.Bool)]
  218. internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, IntPtr lpInfo);
  219. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  220. [return: MarshalAs(UnmanagedType.Bool)]
  221. internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_FAILURE_ACTIONS sfa);
  222. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  223. internal static extern IntPtr OpenSCManager(string machineName, string databaseName, uint dwAccess);
  224. [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  225. internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
  226. [DllImport("advapi32.dll", SetLastError = true)]
  227. [return: MarshalAs(UnmanagedType.Bool)]
  228. internal static extern bool CloseServiceHandle(IntPtr hSCObject);
  229. [DllImport("advapi32.DLL")]
  230. internal static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
  231. [DllImport("advapi32.dll", PreserveSig = true)]
  232. internal static extern UInt32 LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, Int32 DesiredAccess,
  233. out IntPtr PolicyHandle);
  234. [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
  235. internal static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, uint CountOfRights);
  236. [DllImport("advapi32")]
  237. internal static extern void FreeSid(IntPtr pSid);
  238. [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, PreserveSig = true)]
  239. internal static extern bool LookupAccountName(string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder domainName,
  240. ref int cbdomainLength, ref int use);
  241. [DllImport("advapi32.dll")]
  242. internal static extern bool IsValidSid(IntPtr pSid);
  243. [DllImport("advapi32.dll", SetLastError = true)]
  244. internal static extern uint LsaClose(IntPtr ObjectHandle);
  245. [DllImport("advapi32.dll", SetLastError = false)]
  246. internal static extern uint LsaNtStatusToWinError(uint status);
  247. }
  248. //http://msdn.microsoft.com/en-us/library/windows/desktop/bb545671(v=vs.85).aspx
  249. internal enum PrivlegeRights
  250. {
  251. SeServiceLogonRight, //Required for an account to log on using the service logon type.
  252. SeRemoteInteractiveLogonRight, //Required for an account to log on remotely using the interactive logon type.
  253. SeNetworkLogonRight, //Required for an account to log on using the network logon type.
  254. SeInteractiveLogonRight, //Required for an account to log on using the interactive logon type.
  255. SeDenyServiceLogonRight, //Explicitly denies an account the right to log on using the service logon type.
  256. SeDenyRemoteInteractiveLogonRight, //Explicitly denies an account the right to log on remotely using the interactive logon type.
  257. SeDenyNetworkLogonRight, //Explicitly denies an account the right to log on using the network logon type.
  258. SeDenyInteractiveLogonRight, //Explicitly denies an account the right to log on using the interactive logon type.
  259. SeDenyBatchLogonRight, //Explicitly denies an account the right to log on using the batch logon type.
  260. SeBatchLogonRight //Required for an account to log on using the batch logon type.
  261. }
  262. [StructLayout(LayoutKind.Sequential)]
  263. struct LSA_UNICODE_STRING
  264. {
  265. public UInt16 Length;
  266. public UInt16 MaximumLength;
  267. public IntPtr Buffer;
  268. }
  269. [StructLayout(LayoutKind.Sequential)]
  270. struct LSA_OBJECT_ATTRIBUTES
  271. {
  272. public int Length;
  273. public IntPtr RootDirectory;
  274. public LSA_UNICODE_STRING ObjectName;
  275. public UInt32 Attributes;
  276. public IntPtr SecurityDescriptor;
  277. public IntPtr SecurityQualityOfService;
  278. }
  279. // enum all policies
  280. enum LSA_AccessPolicy : long
  281. {
  282. POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
  283. POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
  284. POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
  285. POLICY_TRUST_ADMIN = 0x00000008L,
  286. POLICY_CREATE_ACCOUNT = 0x00000010L,
  287. POLICY_CREATE_SECRET = 0x00000020L,
  288. POLICY_CREATE_PRIVILEGE = 0x00000040L,
  289. POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
  290. POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
  291. POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
  292. POLICY_SERVER_ADMIN = 0x00000400L,
  293. POLICY_LOOKUP_NAMES = 0x00000800L,
  294. POLICY_NOTIFICATION = 0x00001000L
  295. }
  296. internal enum SCM_ACCESS : uint
  297. {
  298. /// <summary>
  299. /// Required to connect to the service control manager.
  300. /// </summary>
  301. SC_MANAGER_CONNECT = 0x00001,
  302. /// <summary>
  303. /// Required to call the CreateService function to create a service
  304. /// object and add it to the database.
  305. /// </summary>
  306. SC_MANAGER_CREATE_SERVICE = 0x00002,
  307. /// <summary>
  308. /// Required to call the EnumServicesStatusEx function to list the
  309. /// services that are in the database.
  310. /// </summary>
  311. SC_MANAGER_ENUMERATE_SERVICE = 0x00004,
  312. /// <summary>
  313. /// Required to call the LockServiceDatabase function to acquire a
  314. /// lock on the database.
  315. /// </summary>
  316. SC_MANAGER_LOCK = 0x00008,
  317. /// <summary>
  318. /// Required to call the QueryServiceLockStatus function to retrieve
  319. /// the lock status information for the database.
  320. /// </summary>
  321. SC_MANAGER_QUERY_LOCK_STATUS = 0x00010,
  322. /// <summary>
  323. /// Required to call the NotifyBootConfigStatus function.
  324. /// </summary>
  325. SC_MANAGER_MODIFY_BOOT_CONFIG = 0x00020,
  326. /// <summary>
  327. /// Includes STANDARD_RIGHTS_REQUIRED, in addition to all access
  328. /// rights in this table.
  329. /// </summary>
  330. SC_MANAGER_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED |
  331. SC_MANAGER_CONNECT |
  332. SC_MANAGER_CREATE_SERVICE |
  333. SC_MANAGER_ENUMERATE_SERVICE |
  334. SC_MANAGER_LOCK |
  335. SC_MANAGER_QUERY_LOCK_STATUS |
  336. SC_MANAGER_MODIFY_BOOT_CONFIG,
  337. GENERIC_READ = ACCESS_MASK.STANDARD_RIGHTS_READ |
  338. SC_MANAGER_ENUMERATE_SERVICE |
  339. SC_MANAGER_QUERY_LOCK_STATUS,
  340. GENERIC_WRITE = ACCESS_MASK.STANDARD_RIGHTS_WRITE |
  341. SC_MANAGER_CREATE_SERVICE |
  342. SC_MANAGER_MODIFY_BOOT_CONFIG,
  343. GENERIC_EXECUTE = ACCESS_MASK.STANDARD_RIGHTS_EXECUTE |
  344. SC_MANAGER_CONNECT | SC_MANAGER_LOCK,
  345. GENERIC_ALL = SC_MANAGER_ALL_ACCESS,
  346. }
  347. [Flags]
  348. internal enum SERVICE_ACCESS : uint
  349. {
  350. STANDARD_RIGHTS_REQUIRED = 0xF0000,
  351. SERVICE_QUERY_CONFIG = 0x00001,
  352. SERVICE_CHANGE_CONFIG = 0x00002,
  353. SERVICE_QUERY_STATUS = 0x00004,
  354. SERVICE_ENUMERATE_DEPENDENTS = 0x00008,
  355. SERVICE_START = 0x00010,
  356. SERVICE_STOP = 0x00020,
  357. SERVICE_PAUSE_CONTINUE = 0x00040,
  358. SERVICE_INTERROGATE = 0x00080,
  359. SERVICE_USER_DEFINED_CONTROL = 0x00100,
  360. SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
  361. SERVICE_QUERY_CONFIG |
  362. SERVICE_CHANGE_CONFIG |
  363. SERVICE_QUERY_STATUS |
  364. SERVICE_ENUMERATE_DEPENDENTS |
  365. SERVICE_START |
  366. SERVICE_STOP |
  367. SERVICE_PAUSE_CONTINUE |
  368. SERVICE_INTERROGATE |
  369. SERVICE_USER_DEFINED_CONTROL)
  370. }
  371. [Flags]
  372. internal enum ACCESS_MASK : uint
  373. {
  374. DELETE = 0x00010000,
  375. READ_CONTROL = 0x00020000,
  376. WRITE_DAC = 0x00040000,
  377. WRITE_OWNER = 0x00080000,
  378. SYNCHRONIZE = 0x00100000,
  379. STANDARD_RIGHTS_REQUIRED = 0x000f0000,
  380. STANDARD_RIGHTS_READ = 0x00020000,
  381. STANDARD_RIGHTS_WRITE = 0x00020000,
  382. STANDARD_RIGHTS_EXECUTE = 0x00020000,
  383. STANDARD_RIGHTS_ALL = 0x001f0000,
  384. SPECIFIC_RIGHTS_ALL = 0x0000ffff,
  385. ACCESS_SYSTEM_SECURITY = 0x01000000,
  386. MAXIMUM_ALLOWED = 0x02000000,
  387. GENERIC_READ = 0x80000000,
  388. GENERIC_WRITE = 0x40000000,
  389. GENERIC_EXECUTE = 0x20000000,
  390. GENERIC_ALL = 0x10000000,
  391. DESKTOP_READOBJECTS = 0x00000001,
  392. DESKTOP_CREATEWINDOW = 0x00000002,
  393. DESKTOP_CREATEMENU = 0x00000004,
  394. DESKTOP_HOOKCONTROL = 0x00000008,
  395. DESKTOP_JOURNALRECORD = 0x00000010,
  396. DESKTOP_JOURNALPLAYBACK = 0x00000020,
  397. DESKTOP_ENUMERATE = 0x00000040,
  398. DESKTOP_WRITEOBJECTS = 0x00000080,
  399. DESKTOP_SWITCHDESKTOP = 0x00000100,
  400. WINSTA_ENUMDESKTOPS = 0x00000001,
  401. WINSTA_READATTRIBUTES = 0x00000002,
  402. WINSTA_ACCESSCLIPBOARD = 0x00000004,
  403. WINSTA_CREATEDESKTOP = 0x00000008,
  404. WINSTA_WRITEATTRIBUTES = 0x00000010,
  405. WINSTA_ACCESSGLOBALATOMS = 0x00000020,
  406. WINSTA_EXITWINDOWS = 0x00000040,
  407. WINSTA_ENUMERATE = 0x00000100,
  408. WINSTA_READSCREEN = 0x00000200,
  409. WINSTA_ALL_ACCESS = 0x0000037f
  410. }
  411. public struct SERVICE_STATUS
  412. {
  413. public int serviceType;
  414. public int currentState;
  415. public int controlsAccepted;
  416. public int win32ExitCode;
  417. public int serviceSpecificExitCode;
  418. public int checkPoint;
  419. public int waitHint;
  420. }
  421. public enum State
  422. {
  423. SERVICE_STOPPED = 0x00000001,
  424. SERVICE_START_PENDING = 0x00000002,
  425. SERVICE_STOP_PENDING = 0x00000003,
  426. SERVICE_RUNNING = 0x00000004,
  427. SERVICE_CONTINUE_PENDING = 0x00000005,
  428. SERVICE_PAUSE_PENDING = 0x00000006,
  429. SERVICE_PAUSED = 0x00000007,
  430. }
  431. // http://msdn.microsoft.com/en-us/library/windows/desktop/ms685126(v=vs.85).aspx
  432. [StructLayout(LayoutKind.Sequential)]
  433. public struct SC_ACTION
  434. {
  435. public SC_ACTION_TYPE Type;
  436. /// <summary>
  437. /// The time to wait before performing the specified action, in milliseconds.
  438. /// </summary>
  439. public uint Delay;
  440. public SC_ACTION(SC_ACTION_TYPE type, TimeSpan delay)
  441. {
  442. this.Type = type;
  443. this.Delay = (uint)delay.TotalMilliseconds;
  444. }
  445. }
  446. internal enum SERVICE_CONFIG_INFOLEVEL
  447. {
  448. SERVICE_CONFIG_DESCRIPTION = 1,
  449. SERVICE_CONFIG_FAILURE_ACTIONS = 2,
  450. SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3,
  451. SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4,
  452. SERVICE_CONFIG_SERVICE_SID_INFO = 5,
  453. SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6,
  454. SERVICE_CONFIG_PRESHUTDOWN_INFO = 7,
  455. SERVICE_CONFIG_TRIGGER_INFO = 8,
  456. SERVICE_CONFIG_PREFERRED_NODE = 9
  457. }
  458. public enum SC_ACTION_TYPE
  459. {
  460. SC_ACTION_NONE = 0,
  461. SC_ACTION_RESTART = 1,
  462. SC_ACTION_REBOOT = 2,
  463. SC_ACTION_RUN_COMMAND = 3
  464. }
  465. // http://msdn.microsoft.com/en-us/library/windows/desktop/ms685939(v=vs.85).aspx
  466. [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]
  467. public struct SERVICE_FAILURE_ACTIONS
  468. {
  469. /// <summary>
  470. /// The time after which to reset the failure count to zero if there are no failures, in seconds.
  471. /// Specify INFINITE to indicate that this value should never be reset.
  472. /// </summary>
  473. public int dwResetPeriod;
  474. [MarshalAs(UnmanagedType.LPWStr)]
  475. public string lpRebootMsg;
  476. [MarshalAs(UnmanagedType.LPWStr)]
  477. public string lpCommand;
  478. public int cActions;
  479. public IntPtr/*SC_ACTION[]*/ lpsaActions;
  480. }
  481. }