Rework P/Invoke signatures

pull/362/head
NextTurn 2018-12-03 00:00:00 +08:00
parent 05b421b37b
commit 80e99d8426
No known key found for this signature in database
GPG Key ID: 17A0D50ADDE1A0C4
4 changed files with 33 additions and 41 deletions

View File

@ -426,7 +426,7 @@ namespace winsw
_wrapperServiceStatus.waitHint = effectiveWaitHint; _wrapperServiceStatus.waitHint = effectiveWaitHint;
// WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint); // WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
_wrapperServiceStatus.currentState = (int)State.SERVICE_STOP_PENDING; _wrapperServiceStatus.currentState = (int)State.SERVICE_STOP_PENDING;
Advapi32.SetServiceStatus(handle, ref _wrapperServiceStatus); Advapi32.SetServiceStatus(handle, _wrapperServiceStatus);
} }
private void SignalShutdownComplete() private void SignalShutdownComplete()
@ -435,7 +435,7 @@ namespace winsw
_wrapperServiceStatus.checkPoint++; _wrapperServiceStatus.checkPoint++;
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint); // WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
_wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED; _wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED;
Advapi32.SetServiceStatus(handle, ref _wrapperServiceStatus); Advapi32.SetServiceStatus(handle, _wrapperServiceStatus);
} }
private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin) private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin)
@ -796,8 +796,7 @@ namespace winsw
// run restart from another process group. see README.md for why this is useful. // run restart from another process group. see README.md for why this is useful.
STARTUPINFO si = default; bool result = Kernel32.CreateProcess(null, descriptor.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, Kernel32.CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, null, default, out _);
bool result = Kernel32.CreateProcess(null, descriptor.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, 0x200/*CREATE_NEW_PROCESS_GROUP*/, IntPtr.Zero, null, ref si, out _);
if (!result) if (!result)
{ {
throw new Exception("Failed to invoke restart: " + Marshal.GetLastWin32Error()); throw new Exception("Failed to invoke restart: " + Marshal.GetLastWin32Error());

View File

@ -35,7 +35,7 @@ namespace winsw.Native
public void Dispose() public void Dispose()
{ {
if (_handle != IntPtr.Zero) if (_handle != IntPtr.Zero)
Advapi32.CloseServiceHandle(_handle); _ = Advapi32.CloseServiceHandle(_handle);
_handle = IntPtr.Zero; _handle = IntPtr.Zero;
} }
} }
@ -71,7 +71,7 @@ namespace winsw.Native
Marshal.StructureToPtr(actions[i], new IntPtr(sfa.lpsaActions.ToInt64() + i * len), false); Marshal.StructureToPtr(actions[i], new IntPtr(sfa.lpsaActions.ToInt64() + i * len), false);
} }
if (!Advapi32.ChangeServiceConfig2(Handle, SERVICE_CONFIG_INFOLEVEL.SERVICE_CONFIG_FAILURE_ACTIONS, ref sfa)) if (!Advapi32.ChangeServiceConfig2(Handle, SERVICE_CONFIG_INFOLEVEL.SERVICE_CONFIG_FAILURE_ACTIONS, sfa))
throw new Exception("Failed to change the failure actions", new Win32Exception()); throw new Exception("Failed to change the failure actions", new Win32Exception());
} }
finally finally
@ -94,7 +94,7 @@ namespace winsw.Native
fDelayedAutostart = enabled fDelayedAutostart = enabled
}; };
if (!Advapi32.ChangeServiceConfig2(Handle, SERVICE_CONFIG_INFOLEVEL.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, ref settings)) if (!Advapi32.ChangeServiceConfig2(Handle, SERVICE_CONFIG_INFOLEVEL.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, settings))
{ {
throw new Exception("Failed to change the DelayedAutoStart setting", new Win32Exception()); throw new Exception("Failed to change the DelayedAutoStart setting", new Win32Exception());
} }
@ -103,7 +103,7 @@ namespace winsw.Native
public void Dispose() public void Dispose()
{ {
if (Handle != IntPtr.Zero) if (Handle != IntPtr.Zero)
Advapi32.CloseServiceHandle(Handle); _ = Advapi32.CloseServiceHandle(Handle);
Handle = IntPtr.Zero; Handle = IntPtr.Zero;
} }
} }
@ -174,19 +174,16 @@ namespace winsw.Native
// StringBuilder and size for the domain name // StringBuilder and size for the domain name
StringBuilder domainName = new StringBuilder(); StringBuilder domainName = new StringBuilder();
int nameSize = 0; int nameSize = 0;
// account-type variable for lookup
int accountType = 0;
// get required buffer size // get required buffer size
Advapi32.LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, ref accountType); _ = Advapi32.LookupAccountName(null, accountName, sid, ref sidSize, domainName, ref nameSize, out _);
// allocate buffers // allocate buffers
domainName = new StringBuilder(nameSize); domainName = new StringBuilder(nameSize);
sid = Marshal.AllocHGlobal(sidSize); sid = Marshal.AllocHGlobal(sidSize);
// lookup the SID for the account // lookup the SID for the account
bool result = Advapi32.LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize, bool result = Advapi32.LookupAccountName(null, accountName, sid, ref sidSize, domainName, ref nameSize, out _);
ref accountType);
// say what you're doing // say what you're doing
// Console.WriteLine("LookupAccountName result = " + result); // Console.WriteLine("LookupAccountName result = " + result);
@ -200,8 +197,6 @@ namespace winsw.Native
} }
else else
{ {
// initialize an empty unicode-string
LSA_UNICODE_STRING systemName = default;
// combine all policies // combine all policies
const int access = (int)( const int access = (int)(
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN | LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
@ -220,18 +215,8 @@ namespace winsw.Native
); );
// initialize a pointer for the policy handle // initialize a pointer for the policy handle
// these attributes are not used, but LsaOpenPolicy wants them to exists
LSA_OBJECT_ATTRIBUTES objectAttributes = new LSA_OBJECT_ATTRIBUTES
{
Length = 0,
RootDirectory = IntPtr.Zero,
Attributes = 0,
SecurityDescriptor = IntPtr.Zero,
SecurityQualityOfService = IntPtr.Zero
};
// get a policy handle // get a policy handle
uint resultPolicy = Advapi32.LsaOpenPolicy(ref systemName, ref objectAttributes, access, out IntPtr policyHandle); uint resultPolicy = Advapi32.LsaOpenPolicy(default, default, access, out IntPtr policyHandle);
winErrorCode = Advapi32.LsaNtStatusToWinError(resultPolicy); winErrorCode = Advapi32.LsaNtStatusToWinError(resultPolicy);
if (winErrorCode != 0) if (winErrorCode != 0)
@ -257,7 +242,7 @@ namespace winsw.Native
Console.WriteLine("LsaAddAccountRights failed: " + winErrorCode); Console.WriteLine("LsaAddAccountRights failed: " + winErrorCode);
} }
Advapi32.LsaClose(policyHandle); _ = Advapi32.LsaClose(policyHandle);
} }
Advapi32.FreeSid(sid); Advapi32.FreeSid(sid);
@ -276,16 +261,13 @@ namespace winsw.Native
private const string Advapi32LibraryName = "advapi32.dll"; private const string Advapi32LibraryName = "advapi32.dll";
[DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")] [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, IntPtr lpInfo); internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, in SERVICE_FAILURE_ACTIONS lpInfo);
[DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")] [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_FAILURE_ACTIONS sfa); internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, in SERVICE_DELAYED_AUTO_START lpInfo);
[DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_DELAYED_AUTO_START sfa);
[DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenSCManagerW")] [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenSCManagerW")]
internal static extern IntPtr OpenSCManager(string? machineName, string? databaseName, uint dwAccess); internal static extern IntPtr OpenSCManager(string? lpMachineName, string? lpDatabaseName, uint dwDesiredAccess);
[DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenServiceW")] [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenServiceW")]
internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess); internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
@ -294,10 +276,13 @@ namespace winsw.Native
internal static extern bool CloseServiceHandle(IntPtr hSCObject); internal static extern bool CloseServiceHandle(IntPtr hSCObject);
[DllImport(Advapi32LibraryName)] [DllImport(Advapi32LibraryName)]
public static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus); public static extern bool SetServiceStatus(IntPtr hServiceStatus, in SERVICE_STATUS lpServiceStatus);
[DllImport(Advapi32LibraryName)] [DllImport(Advapi32LibraryName)]
internal static extern uint LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, int DesiredAccess, internal static extern uint LsaOpenPolicy(
in LSA_UNICODE_STRING SystemName,
in LSA_OBJECT_ATTRIBUTES ObjectAttributes,
int DesiredAccess,
out IntPtr PolicyHandle); out IntPtr PolicyHandle);
[DllImport(Advapi32LibraryName, SetLastError = true)] [DllImport(Advapi32LibraryName, SetLastError = true)]
@ -307,8 +292,14 @@ namespace winsw.Native
internal static extern void FreeSid(IntPtr pSid); internal static extern void FreeSid(IntPtr pSid);
[DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "LookupAccountNameW")] [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "LookupAccountNameW")]
internal static extern bool LookupAccountName(string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder domainName, internal static extern bool LookupAccountName(
ref int cbdomainLength, ref int use); string? lpSystemName,
string lpAccountName,
IntPtr psid,
ref int cbsid,
StringBuilder domainName,
ref int cbdomainLength,
out int use);
[DllImport(Advapi32LibraryName)] [DllImport(Advapi32LibraryName)]
internal static extern bool IsValidSid(IntPtr pSid); internal static extern bool IsValidSid(IntPtr pSid);

View File

@ -9,6 +9,8 @@ namespace winsw.Native
/// </summary> /// </summary>
public class Kernel32 public class Kernel32
{ {
public const uint CREATE_NEW_PROCESS_GROUP = 0x00000200;
private const string Kernel32LibraryName = "kernel32.dll"; private const string Kernel32LibraryName = "kernel32.dll";
[DllImport(Kernel32LibraryName, SetLastError = true)] [DllImport(Kernel32LibraryName, SetLastError = true)]
@ -17,14 +19,14 @@ namespace winsw.Native
[DllImport(Kernel32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateProcessW")] [DllImport(Kernel32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateProcessW")]
public static extern bool CreateProcess( public static extern bool CreateProcess(
string? lpApplicationName, string? lpApplicationName,
string lpCommandLine, string? lpCommandLine,
IntPtr lpProcessAttributes, IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes, IntPtr lpThreadAttributes,
bool bInheritHandles, bool bInheritHandles,
uint dwCreationFlags, uint dwCreationFlags,
IntPtr lpEnvironment, IntPtr lpEnvironment,
string? lpCurrentDirectory, string? lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo, in STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation); out PROCESS_INFORMATION lpProcessInformation);
} }

View File

@ -47,8 +47,8 @@ namespace winsw.Util
if (AttachConsole((uint)process.Id)) if (AttachConsole((uint)process.Id))
{ {
// Disable Ctrl-C handling for our program // Disable Ctrl-C handling for our program
SetConsoleCtrlHandler(null, true); _ = SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0); _ = GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
process.WaitForExit((int)shutdownTimeout.TotalMilliseconds); process.WaitForExit((int)shutdownTimeout.TotalMilliseconds);