Skip to content

Commit 223e183

Browse files
Added set methods for SERVICE_DELAYED_AUTO_START_INFO; added SERVICE_FAILURE_ACTIONS and its set methods; fixed few functions calling themselves (#41)
1 parent 8b07736 commit 223e183

1 file changed

Lines changed: 156 additions & 3 deletions

File tree

NtApiDotNet/Win32/ServiceUtils.cs

Lines changed: 156 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,53 @@ internal struct SERVICE_SID_INFO
359359
public ServiceSidType dwServiceSidType;
360360
}
361361

362+
public enum ServiceControlManagerAction
363+
{
364+
[SDKName("SC_ACTION_NONE")]
365+
None = 0,
366+
[SDKName("SC_ACTION_RESTART")]
367+
Restart = 1,
368+
[SDKName("SC_ACTION_REBOOT")]
369+
Reboot = 2,
370+
[SDKName("SC_ACTION_RUN_COMMAND")]
371+
RunCommand = 3
372+
}
373+
374+
/// <summary>
375+
/// Represents an action that the service control manager can perform.
376+
/// </summary>
377+
[StructLayout(LayoutKind.Sequential)]
378+
public struct FailureAction
379+
{
380+
/// <summary>
381+
/// The action to be performed.
382+
/// </summary>
383+
public ServiceControlManagerAction Action;
384+
385+
/// <summary>
386+
/// The time to wait before performing the specified action, in milliseconds.
387+
/// </summary>
388+
public int Delay;
389+
390+
/// <param name="action">The action to be performed.</param>
391+
/// <param name="delay">The time to wait before performing the specified action, in milliseconds.</param>
392+
public FailureAction(ServiceControlManagerAction action, int delay)
393+
{
394+
Action = action;
395+
Delay = delay;
396+
}
397+
}
398+
399+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
400+
internal struct SERVICE_FAILURE_ACTIONS
401+
{
402+
public int dwResetPeriod;
403+
public string lpRebootMsg;
404+
public string lpCommand;
405+
public int cActions;
406+
public SafeHGlobalBuffer lpsaActions;
407+
}
408+
362409
public enum ServiceLaunchProtectedType
363410
{
364411
[SDKName("SERVICE_LAUNCH_PROTECTED_NONE")]
@@ -1873,7 +1920,7 @@ public static void SetServiceSidType(string machine_name, string name, ServiceSi
18731920
/// <returns>The NT status code.</returns>
18741921
public static NtStatus SetServiceSidType(string name, ServiceSidType sid_type, bool throw_on_error)
18751922
{
1876-
return SetServiceSidType(name, sid_type, throw_on_error);
1923+
return SetServiceSidType(null, name, sid_type, throw_on_error);
18771924
}
18781925

18791926
/// <summary>
@@ -1886,6 +1933,112 @@ public static void SetServiceSidType(string name, ServiceSidType sid_type)
18861933
SetServiceSidType(name, sid_type, true);
18871934
}
18881935

1936+
/// <summary>
1937+
/// Set a service's delayed auto-start.
1938+
/// </summary>
1939+
/// <param name="machine_name">The name of a target computer. Can be null or empty to specify local machine.</param>
1940+
/// <param name="name">The name of the service.</param>
1941+
/// <param name="enabled">If true, the service is started after other auto-start services are started plus a short delay. Otherwise, the service is started during system boot.</param>
1942+
/// <param name="throw_on_error">True to throw on error.</param>
1943+
/// <returns>The NT status code.</returns>
1944+
public static NtStatus SetServiceDelayedAutoStart(string machine_name, string name, bool enabled, bool throw_on_error)
1945+
{
1946+
return ChangeServiceConfig2(machine_name, name, SERVICE_CONFIG_INFO_LEVEL.DELAYED_AUTO_START_INFO,
1947+
new SERVICE_DELAYED_AUTO_START_INFO() { fDelayedAutostart = enabled }, throw_on_error);
1948+
}
1949+
1950+
/// <returns/>
1951+
/// <inheritdoc cref="SetServiceDelayedAutoStart(string, string, bool, bool)"/>
1952+
public static void SetServiceDelayedAutoStart(string machine_name, string name, bool enabled)
1953+
{
1954+
SetServiceDelayedAutoStart(machine_name, name, enabled, true);
1955+
}
1956+
1957+
/// <returns/>
1958+
/// <inheritdoc cref="SetServiceDelayedAutoStart(string, string, bool, bool)"/>
1959+
public static void SetServiceDelayedAutoStart(string name, bool enabled, bool throw_on_error)
1960+
{
1961+
SetServiceDelayedAutoStart(null, name, enabled, throw_on_error);
1962+
}
1963+
1964+
1965+
/// <inheritdoc cref="SetServiceDelayedAutoStart(string, string, bool, bool)"/>
1966+
public static void SetServiceDelayedAutoStart(string name, bool enabled)
1967+
{
1968+
SetServiceDelayedAutoStart(name, enabled, true);
1969+
}
1970+
1971+
/// <summary>
1972+
/// Set a service's failure recover actions.
1973+
/// </summary>
1974+
/// <param name="machine_name">The name of a target computer. Can be null or empty to specify local machine.</param>
1975+
/// <param name="name">The name of the service.</param>
1976+
/// <param name="actions">Actions to be performed on service failure.
1977+
/// <br/>If this value is null, <paramref name="reset_period"/> is ignored.
1978+
/// <br/> If this value is empty, the reset period and array of failure actions are deleted.</param>
1979+
/// <param name="reset_period">The time after which to reset the failure count to zero if there are no failures, in seconds. Specify -1 to indicate that this value should never be reset.</param>
1980+
/// <param name="recover_command">The command line of the process for the CreateProcess function to execute in response to the command run service controller action.
1981+
/// <br/> This process runs under the same account as the service.
1982+
/// <br/> If this value is null, the command is unchanged.
1983+
/// <br/> If the value is an empty string (""), the command is deleted and no program is run when the service fails.</param>
1984+
/// <param name="reboot_msg">The message to be broadcast to server users before rebooting in response to the reboot action service controller action.
1985+
/// <br/> If this value is null, the reboot message is unchanged.
1986+
/// <br/> If the value is an empty string (""), the reboot message is deleted and no message is broadcast.
1987+
/// <br/> This member can specify a localized string using the following format: <c>@[path]dllname,-strID</c>
1988+
/// <br/> The string with identifier <c>strID</c> is loaded from <c>dllname</c>; <c>path</c> is optional.</param>
1989+
/// <param name="throw_on_error">True to throw on error.</param>
1990+
/// <returns>The NT status code.</returns>
1991+
public static NtStatus SetServiceFailureActions(string machine_name, string name, IEnumerable<FailureAction> actions, int reset_period, string recover_command, string reboot_msg, bool throw_on_error)
1992+
{
1993+
int cActions;
1994+
SafeHGlobalBuffer actions_buffer;
1995+
if (actions == null)
1996+
{
1997+
actions_buffer = SafeHGlobalBuffer.Null;
1998+
cActions = 0;
1999+
}
2000+
else
2001+
{
2002+
var actions_array = actions.ToArray();
2003+
actions_buffer = BufferUtils.ToBuffer(actions_array);
2004+
cActions = actions_array.Length;
2005+
}
2006+
2007+
using (actions_buffer)
2008+
{
2009+
var fa_struct = new SERVICE_FAILURE_ACTIONS
2010+
{
2011+
dwResetPeriod = reset_period,
2012+
lpRebootMsg = reboot_msg,
2013+
lpCommand = recover_command,
2014+
cActions = cActions,
2015+
lpsaActions = actions_buffer,
2016+
};
2017+
2018+
return ChangeServiceConfig2(machine_name, name, SERVICE_CONFIG_INFO_LEVEL.FAILURE_ACTIONS, fa_struct, throw_on_error);
2019+
}
2020+
}
2021+
2022+
/// <returns/>
2023+
/// <inheritdoc cref="SetServiceFailureActions(string, string, IEnumerable{FailureAction}, int, string, string, bool)"/>
2024+
public static void SetServiceFailureActions(string machine_name, string name, IEnumerable<FailureAction> actions, int reset_period, string recover_command, string reboot_msg)
2025+
{
2026+
SetServiceFailureActions(machine_name, name, actions, reset_period, recover_command, reboot_msg, true);
2027+
}
2028+
2029+
/// <returns/>
2030+
/// <inheritdoc cref="SetServiceFailureActions(string, string, IEnumerable{FailureAction}, int, string, string, bool)"/>
2031+
public static void SetServiceFailureActions(string name, IEnumerable<FailureAction> actions, int reset_period, string recover_command, string reboot_msg, bool throw_on_error)
2032+
{
2033+
SetServiceFailureActions(null, name, actions, reset_period, recover_command, reboot_msg, throw_on_error);
2034+
}
2035+
2036+
/// <inheritdoc cref="SetServiceFailureActions(string, string, IEnumerable{FailureAction}, int, string, string, bool)"/>
2037+
public static void SetServiceFailureActions(string name, IEnumerable<FailureAction> actions, int reset_period, string recover_command, string reboot_msg)
2038+
{
2039+
SetServiceFailureActions(name, actions, reset_period, recover_command, reboot_msg, true);
2040+
}
2041+
18892042
/// <summary>
18902043
/// Set a service's required privileges.
18912044
/// </summary>
@@ -1920,7 +2073,7 @@ public static void SetServiceRequiredPrivileges(string machine_name, string name
19202073
/// <returns>The NT status code.</returns>
19212074
public static NtStatus SetServiceRequiredPrivileges(string name, string[] privileges, bool throw_on_error)
19222075
{
1923-
return SetServiceRequiredPrivileges(name, privileges, throw_on_error);
2076+
return SetServiceRequiredPrivileges(null, name, privileges, throw_on_error);
19242077
}
19252078

19262079
/// <summary>
@@ -1967,7 +2120,7 @@ public static void SetServiceLaunchProtected(string machine_name, string name, S
19672120
/// <returns>The NT status code.</returns>
19682121
public static NtStatus SetServiceLaunchProtected(string name, ServiceLaunchProtectedType protected_type, bool throw_on_error)
19692122
{
1970-
return SetServiceLaunchProtected(name, protected_type, throw_on_error);
2123+
return SetServiceLaunchProtected(null, name, protected_type, throw_on_error);
19712124
}
19722125

19732126
/// <summary>

0 commit comments

Comments
 (0)