From 89677a7f4982adef4f85638a840cc31cb81887b8 Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Fri, 7 Feb 2020 00:00:00 +0800
Subject: [PATCH 01/13] Support 'If-Modified-Since' for downloads
---
src/Core/WinSWCore/Download.cs | 68 ++++++++++++++++++++++++----------
1 file changed, 48 insertions(+), 20 deletions(-)
diff --git a/src/Core/WinSWCore/Download.cs b/src/Core/WinSWCore/Download.cs
index 69b8dae..ff0ba09 100755
--- a/src/Core/WinSWCore/Download.cs
+++ b/src/Core/WinSWCore/Download.cs
@@ -6,9 +6,7 @@ using System.Text;
using System.Threading.Tasks;
#endif
using System.Xml;
-#if !VNEXT
using log4net;
-#endif
using winsw.Util;
namespace winsw
@@ -26,9 +24,7 @@ namespace winsw
basic
}
-#if !VNEXT
private static readonly ILog Logger = LogManager.GetLogger(typeof(Download));
-#endif
public readonly string From;
public readonly string To;
@@ -163,25 +159,57 @@ namespace winsw
throw new WebException("Code defect. Unsupported authentication type: " + Auth);
}
- string tmpFilePath = To + ".tmp";
-#if VNEXT
- using (WebResponse response = await request.GetResponseAsync())
-#else
- using (WebResponse response = request.GetResponse())
-#endif
- using (Stream responseStream = response.GetResponseStream())
- using (FileStream tmpStream = new FileStream(tmpFilePath, FileMode.Create))
+ bool supportsIfModifiedSince = false;
+ if (request is HttpWebRequest httpRequest && File.Exists(To))
{
-#if VNEXT
- await responseStream.CopyToAsync(tmpStream);
-#elif NET20
- CopyStream(responseStream, tmpStream);
-#else
- responseStream.CopyTo(tmpStream);
-#endif
+ supportsIfModifiedSince = true;
+ httpRequest.IfModifiedSince = File.GetLastWriteTime(To);
}
- FileHelper.MoveOrReplaceFile(To + ".tmp", To);
+ DateTime lastModified = default;
+ string tmpFilePath = To + ".tmp";
+ try
+ {
+#if VNEXT
+ using (WebResponse response = await request.GetResponseAsync())
+#else
+ using (WebResponse response = request.GetResponse())
+#endif
+ using (Stream responseStream = response.GetResponseStream())
+ using (FileStream tmpStream = new FileStream(tmpFilePath, FileMode.Create))
+ {
+ if (supportsIfModifiedSince)
+ {
+ lastModified = ((HttpWebResponse)response).LastModified;
+ }
+
+#if VNEXT
+ await responseStream.CopyToAsync(tmpStream);
+#elif NET20
+ CopyStream(responseStream, tmpStream);
+#else
+ responseStream.CopyTo(tmpStream);
+#endif
+ }
+
+ FileHelper.MoveOrReplaceFile(To + ".tmp", To);
+
+ if (supportsIfModifiedSince)
+ {
+ File.SetLastWriteTime(To, lastModified);
+ }
+ }
+ catch (WebException e)
+ {
+ if (supportsIfModifiedSince && ((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.NotModified)
+ {
+ Logger.Info($"Skipped downloading unmodified resource '{From}'");
+ }
+ else
+ {
+ throw;
+ }
+ }
}
#if NET20
From 3bb10ab60d3a2f1cf792c5b32f0513a4217270ba Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Sun, 2 Dec 2018 00:00:00 +0800
Subject: [PATCH 02/13] Remove unnecessary attributes
---
src/Core/WinSWCore/Native/Advapi32.cs | 13 +++----------
src/Core/WinSWCore/Util/SigIntHelper.cs | 3 +--
2 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/src/Core/WinSWCore/Native/Advapi32.cs b/src/Core/WinSWCore/Native/Advapi32.cs
index 75f1804..7b70095 100755
--- a/src/Core/WinSWCore/Native/Advapi32.cs
+++ b/src/Core/WinSWCore/Native/Advapi32.cs
@@ -274,15 +274,12 @@ namespace winsw.Native
public class Advapi32
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- [return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, IntPtr lpInfo);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- [return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_FAILURE_ACTIONS sfa);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- [return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_DELAYED_AUTO_START sfa);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
@@ -292,23 +289,22 @@ namespace winsw.Native
internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
[DllImport("advapi32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseServiceHandle(IntPtr hSCObject);
[DllImport("advapi32.DLL")]
public static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
- [DllImport("advapi32.dll", PreserveSig = true)]
+ [DllImport("advapi32.dll")]
internal static extern uint LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, int DesiredAccess,
out IntPtr PolicyHandle);
- [DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
+ [DllImport("advapi32.dll", SetLastError = true)]
internal static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, uint CountOfRights);
[DllImport("advapi32")]
internal static extern void FreeSid(IntPtr pSid);
- [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, PreserveSig = true)]
+ [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool LookupAccountName(string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder domainName,
ref int cbdomainLength, ref int use);
@@ -584,9 +580,7 @@ namespace winsw.Native
///
public int dwResetPeriod;
- [MarshalAs(UnmanagedType.LPWStr)]
public string lpRebootMsg;
- [MarshalAs(UnmanagedType.LPWStr)]
public string lpCommand;
public int cActions;
public IntPtr/*SC_ACTION[]*/ lpsaActions;
@@ -596,7 +590,6 @@ namespace winsw.Native
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SERVICE_DELAYED_AUTO_START
{
- [MarshalAs(UnmanagedType.Bool)]
public bool fDelayedAutostart;
}
}
diff --git a/src/Core/WinSWCore/Util/SigIntHelper.cs b/src/Core/WinSWCore/Util/SigIntHelper.cs
index 801539b..3acc949 100644
--- a/src/Core/WinSWCore/Util/SigIntHelper.cs
+++ b/src/Core/WinSWCore/Util/SigIntHelper.cs
@@ -15,7 +15,7 @@ namespace winsw.Util
[DllImport(KERNEL32, SetLastError = true)]
private static extern bool AttachConsole(uint dwProcessId);
- [DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
+ [DllImport(KERNEL32, SetLastError = true)]
private static extern bool FreeConsole();
[DllImport(KERNEL32)]
@@ -35,7 +35,6 @@ namespace winsw.Util
}
[DllImport(KERNEL32)]
- [return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
///
From f1036e613b10849bdc475ddd7ab0097b5dec7d0a Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Sun, 2 Dec 2018 00:00:00 +0800
Subject: [PATCH 03/13] Replace GetLastError
---
src/Core/WinSWCore/Native/Advapi32.cs | 2 +-
src/Core/WinSWCore/Native/Kernel32.cs | 3 ---
src/Core/WinSWCore/Util/SigIntHelper.cs | 3 +--
3 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/src/Core/WinSWCore/Native/Advapi32.cs b/src/Core/WinSWCore/Native/Advapi32.cs
index 7b70095..9efb32c 100755
--- a/src/Core/WinSWCore/Native/Advapi32.cs
+++ b/src/Core/WinSWCore/Native/Advapi32.cs
@@ -195,7 +195,7 @@ namespace winsw.Native
if (!result)
{
- winErrorCode = Kernel32.GetLastError();
+ winErrorCode = Marshal.GetLastWin32Error();
Console.WriteLine("LookupAccountName failed: " + winErrorCode);
}
else
diff --git a/src/Core/WinSWCore/Native/Kernel32.cs b/src/Core/WinSWCore/Native/Kernel32.cs
index 14dd870..1193406 100755
--- a/src/Core/WinSWCore/Native/Kernel32.cs
+++ b/src/Core/WinSWCore/Native/Kernel32.cs
@@ -24,9 +24,6 @@ namespace winsw.Native
string? lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
-
- [DllImport("kernel32.dll")]
- public static extern int GetLastError();
}
[StructLayout(LayoutKind.Sequential)]
diff --git a/src/Core/WinSWCore/Util/SigIntHelper.cs b/src/Core/WinSWCore/Util/SigIntHelper.cs
index 3acc949..11f8f65 100644
--- a/src/Core/WinSWCore/Util/SigIntHelper.cs
+++ b/src/Core/WinSWCore/Util/SigIntHelper.cs
@@ -2,7 +2,6 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using log4net;
-using winsw.Native;
namespace winsw.Util
{
@@ -57,7 +56,7 @@ namespace winsw.Util
bool success = FreeConsole();
if (!success)
{
- long errorCode = Kernel32.GetLastError();
+ long errorCode = Marshal.GetLastWin32Error();
Logger.Warn("Failed to detach from console. Error code: " + errorCode);
}
From 5bc19e43af32afad383f9ed4f62f22b0255d6093 Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Sun, 2 Dec 2018 00:00:00 +0800
Subject: [PATCH 04/13] Introduce constant strings
---
src/Core/WinSWCore/Native/Advapi32.cs | 30 +++++++++++++------------
src/Core/WinSWCore/Native/Kernel32.cs | 6 +++--
src/Core/WinSWCore/Util/SigIntHelper.cs | 10 ++++-----
3 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/src/Core/WinSWCore/Native/Advapi32.cs b/src/Core/WinSWCore/Native/Advapi32.cs
index 9efb32c..4289edd 100755
--- a/src/Core/WinSWCore/Native/Advapi32.cs
+++ b/src/Core/WinSWCore/Native/Advapi32.cs
@@ -273,48 +273,50 @@ namespace winsw.Native
///
public class Advapi32
{
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ private const string Advapi32LibraryName = "advapi32.dll";
+
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, IntPtr lpInfo);
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_FAILURE_ACTIONS sfa);
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_DELAYED_AUTO_START sfa);
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr OpenSCManager(string? machineName, string? databaseName, uint dwAccess);
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
- [DllImport("advapi32.dll", SetLastError = true)]
+ [DllImport(Advapi32LibraryName, SetLastError = true)]
internal static extern bool CloseServiceHandle(IntPtr hSCObject);
- [DllImport("advapi32.DLL")]
+ [DllImport(Advapi32LibraryName)]
public static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
- [DllImport("advapi32.dll")]
+ [DllImport(Advapi32LibraryName)]
internal static extern uint LsaOpenPolicy(ref LSA_UNICODE_STRING SystemName, ref LSA_OBJECT_ATTRIBUTES ObjectAttributes, int DesiredAccess,
out IntPtr PolicyHandle);
- [DllImport("advapi32.dll", SetLastError = true)]
+ [DllImport(Advapi32LibraryName, SetLastError = true)]
internal static extern uint LsaAddAccountRights(IntPtr PolicyHandle, IntPtr AccountSid, LSA_UNICODE_STRING[] UserRights, uint CountOfRights);
- [DllImport("advapi32")]
+ [DllImport(Advapi32LibraryName)]
internal static extern void FreeSid(IntPtr pSid);
- [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ [DllImport(Advapi32LibraryName, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool LookupAccountName(string lpSystemName, string lpAccountName, IntPtr psid, ref int cbsid, StringBuilder domainName,
ref int cbdomainLength, ref int use);
- [DllImport("advapi32.dll")]
+ [DllImport(Advapi32LibraryName)]
internal static extern bool IsValidSid(IntPtr pSid);
- [DllImport("advapi32.dll", SetLastError = true)]
+ [DllImport(Advapi32LibraryName, SetLastError = true)]
internal static extern uint LsaClose(IntPtr ObjectHandle);
- [DllImport("advapi32.dll", SetLastError = false)]
+ [DllImport(Advapi32LibraryName, SetLastError = false)]
internal static extern uint LsaNtStatusToWinError(uint status);
}
diff --git a/src/Core/WinSWCore/Native/Kernel32.cs b/src/Core/WinSWCore/Native/Kernel32.cs
index 1193406..bf323db 100755
--- a/src/Core/WinSWCore/Native/Kernel32.cs
+++ b/src/Core/WinSWCore/Native/Kernel32.cs
@@ -9,10 +9,12 @@ namespace winsw.Native
///
public class Kernel32
{
- [DllImport("kernel32.dll", SetLastError = true)]
+ private const string Kernel32LibraryName = "kernel32.dll";
+
+ [DllImport(Kernel32LibraryName, SetLastError = true)]
public static extern bool SetStdHandle(int nStdHandle, SafeFileHandle handle);
- [DllImport("kernel32.dll", SetLastError = true)]
+ [DllImport(Kernel32LibraryName, SetLastError = true)]
public static extern bool CreateProcess(
string? lpApplicationName,
string lpCommandLine,
diff --git a/src/Core/WinSWCore/Util/SigIntHelper.cs b/src/Core/WinSWCore/Util/SigIntHelper.cs
index 11f8f65..c915d19 100644
--- a/src/Core/WinSWCore/Util/SigIntHelper.cs
+++ b/src/Core/WinSWCore/Util/SigIntHelper.cs
@@ -9,15 +9,15 @@ namespace winsw.Util
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(SigIntHelper));
- private const string KERNEL32 = "kernel32.dll";
+ private const string Kernel32LibraryName = "kernel32.dll";
- [DllImport(KERNEL32, SetLastError = true)]
+ [DllImport(Kernel32LibraryName, SetLastError = true)]
private static extern bool AttachConsole(uint dwProcessId);
- [DllImport(KERNEL32, SetLastError = true)]
+ [DllImport(Kernel32LibraryName, SetLastError = true)]
private static extern bool FreeConsole();
- [DllImport(KERNEL32)]
+ [DllImport(Kernel32LibraryName)]
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate? HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
@@ -33,7 +33,7 @@ namespace winsw.Util
CTRL_SHUTDOWN_EVENT
}
- [DllImport(KERNEL32)]
+ [DllImport(Kernel32LibraryName)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
///
From fc08355620d67b1eba645d016964eb2558e874d1 Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Sun, 2 Dec 2018 00:00:00 +0800
Subject: [PATCH 05/13] Specify Unicode versions
---
src/Core/WinSWCore/Native/Advapi32.cs | 12 ++++++------
src/Core/WinSWCore/Native/Kernel32.cs | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/Core/WinSWCore/Native/Advapi32.cs b/src/Core/WinSWCore/Native/Advapi32.cs
index 4289edd..e83ae6d 100755
--- a/src/Core/WinSWCore/Native/Advapi32.cs
+++ b/src/Core/WinSWCore/Native/Advapi32.cs
@@ -275,19 +275,19 @@ namespace winsw.Native
{
private const string Advapi32LibraryName = "advapi32.dll";
- [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "ChangeServiceConfig2W")]
internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, IntPtr lpInfo);
- [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
+ [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);
- [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
+ [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)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenSCManagerW")]
internal static extern IntPtr OpenSCManager(string? machineName, string? databaseName, uint dwAccess);
- [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
+ [DllImport(Advapi32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenServiceW")]
internal static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, uint dwDesiredAccess);
[DllImport(Advapi32LibraryName, SetLastError = true)]
@@ -306,7 +306,7 @@ namespace winsw.Native
[DllImport(Advapi32LibraryName)]
internal static extern void FreeSid(IntPtr pSid);
- [DllImport(Advapi32LibraryName, CharSet = CharSet.Auto, SetLastError = true)]
+ [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,
ref int cbdomainLength, ref int use);
diff --git a/src/Core/WinSWCore/Native/Kernel32.cs b/src/Core/WinSWCore/Native/Kernel32.cs
index bf323db..73d29b9 100755
--- a/src/Core/WinSWCore/Native/Kernel32.cs
+++ b/src/Core/WinSWCore/Native/Kernel32.cs
@@ -14,7 +14,7 @@ namespace winsw.Native
[DllImport(Kernel32LibraryName, SetLastError = true)]
public static extern bool SetStdHandle(int nStdHandle, SafeFileHandle handle);
- [DllImport(Kernel32LibraryName, SetLastError = true)]
+ [DllImport(Kernel32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateProcessW")]
public static extern bool CreateProcess(
string? lpApplicationName,
string lpCommandLine,
From 05b421b37be97ded707b3ae4430fcb0d16ce6f52 Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Mon, 3 Dec 2018 00:00:00 +0800
Subject: [PATCH 06/13] Remove unused file
---
src/Core/ServiceWrapper/SigIntHelper.cs | 59 -------------------------
1 file changed, 59 deletions(-)
delete mode 100644 src/Core/ServiceWrapper/SigIntHelper.cs
diff --git a/src/Core/ServiceWrapper/SigIntHelper.cs b/src/Core/ServiceWrapper/SigIntHelper.cs
deleted file mode 100644
index 4134740..0000000
--- a/src/Core/ServiceWrapper/SigIntHelper.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace winsw
-{
- public static class SigIntHelper
- {
- private const string KERNEL32 = "kernel32.dll";
-
- [DllImport(KERNEL32, SetLastError = true)]
- private static extern bool AttachConsole(uint dwProcessId);
-
- [DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
- private static extern bool FreeConsole();
-
- [DllImport(KERNEL32)]
- private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate? HandlerRoutine, bool Add);
-
- // Delegate type to be used as the Handler Routine for SCCH
- private delegate bool ConsoleCtrlDelegate(CtrlTypes CtrlType);
-
- // Enumerated type for the control messages sent to the handler routine
- private enum CtrlTypes : uint
- {
- CTRL_C_EVENT = 0,
- CTRL_BREAK_EVENT,
- CTRL_CLOSE_EVENT,
- CTRL_LOGOFF_EVENT = 5,
- CTRL_SHUTDOWN_EVENT
- }
-
- [DllImport(KERNEL32)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
-
- ///
- /// Uses the native funciton "AttachConsole" to attach the thread to the executing process to try to trigger a CTRL_C event (SIGINT). If the application
- /// doesn't honor the event and shut down gracefully, the. wait period will time out after 15 seconds.
- ///
- /// The process to attach to and send the SIGINT
- /// True if the process shut down successfully to the SIGINT, false if it did not.
- public static bool SendSIGINTToProcess(Process process, TimeSpan shutdownTimeout)
- {
- if (AttachConsole((uint)process.Id))
- {
- // Disable Ctrl-C handling for our program
- SetConsoleCtrlHandler(null, true);
- GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
-
- process.WaitForExit((int)shutdownTimeout.TotalMilliseconds);
-
- return process.HasExited;
- }
-
- return false;
- }
- }
-}
From 80e99d8426fedf3ef2ad70066f6087f8b05c55e7 Mon Sep 17 00:00:00 2001
From: NextTurn <45985406+NextTurn@users.noreply.github.com>
Date: Mon, 3 Dec 2018 00:00:00 +0800
Subject: [PATCH 07/13] Rework P/Invoke signatures
---
src/Core/ServiceWrapper/Main.cs | 7 ++-
src/Core/WinSWCore/Native/Advapi32.cs | 57 +++++++++++--------------
src/Core/WinSWCore/Native/Kernel32.cs | 6 ++-
src/Core/WinSWCore/Util/SigIntHelper.cs | 4 +-
4 files changed, 33 insertions(+), 41 deletions(-)
diff --git a/src/Core/ServiceWrapper/Main.cs b/src/Core/ServiceWrapper/Main.cs
index a56ae4d..1aa2476 100644
--- a/src/Core/ServiceWrapper/Main.cs
+++ b/src/Core/ServiceWrapper/Main.cs
@@ -426,7 +426,7 @@ namespace winsw
_wrapperServiceStatus.waitHint = effectiveWaitHint;
// WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
_wrapperServiceStatus.currentState = (int)State.SERVICE_STOP_PENDING;
- Advapi32.SetServiceStatus(handle, ref _wrapperServiceStatus);
+ Advapi32.SetServiceStatus(handle, _wrapperServiceStatus);
}
private void SignalShutdownComplete()
@@ -435,7 +435,7 @@ namespace winsw
_wrapperServiceStatus.checkPoint++;
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
_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)
@@ -796,8 +796,7 @@ namespace winsw
// 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, 0x200/*CREATE_NEW_PROCESS_GROUP*/, IntPtr.Zero, null, ref si, out _);
+ bool result = Kernel32.CreateProcess(null, descriptor.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, Kernel32.CREATE_NEW_PROCESS_GROUP, IntPtr.Zero, null, default, out _);
if (!result)
{
throw new Exception("Failed to invoke restart: " + Marshal.GetLastWin32Error());
diff --git a/src/Core/WinSWCore/Native/Advapi32.cs b/src/Core/WinSWCore/Native/Advapi32.cs
index e83ae6d..10d3c34 100755
--- a/src/Core/WinSWCore/Native/Advapi32.cs
+++ b/src/Core/WinSWCore/Native/Advapi32.cs
@@ -35,7 +35,7 @@ namespace winsw.Native
public void Dispose()
{
if (_handle != IntPtr.Zero)
- Advapi32.CloseServiceHandle(_handle);
+ _ = Advapi32.CloseServiceHandle(_handle);
_handle = IntPtr.Zero;
}
}
@@ -71,7 +71,7 @@ namespace winsw.Native
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());
}
finally
@@ -94,7 +94,7 @@ namespace winsw.Native
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());
}
@@ -103,7 +103,7 @@ namespace winsw.Native
public void Dispose()
{
if (Handle != IntPtr.Zero)
- Advapi32.CloseServiceHandle(Handle);
+ _ = Advapi32.CloseServiceHandle(Handle);
Handle = IntPtr.Zero;
}
}
@@ -174,19 +174,16 @@ namespace winsw.Native
// StringBuilder and size for the domain name
StringBuilder domainName = new StringBuilder();
int nameSize = 0;
- // account-type variable for lookup
- int accountType = 0;
// 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
domainName = new StringBuilder(nameSize);
sid = Marshal.AllocHGlobal(sidSize);
// lookup the SID for the account
- bool result = Advapi32.LookupAccountName(string.Empty, accountName, sid, ref sidSize, domainName, ref nameSize,
- ref accountType);
+ bool result = Advapi32.LookupAccountName(null, accountName, sid, ref sidSize, domainName, ref nameSize, out _);
// say what you're doing
// Console.WriteLine("LookupAccountName result = " + result);
@@ -200,8 +197,6 @@ namespace winsw.Native
}
else
{
- // initialize an empty unicode-string
- LSA_UNICODE_STRING systemName = default;
// combine all policies
const int access = (int)(
LSA_AccessPolicy.POLICY_AUDIT_LOG_ADMIN |
@@ -220,18 +215,8 @@ namespace winsw.Native
);
// 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
- 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);
if (winErrorCode != 0)
@@ -257,7 +242,7 @@ namespace winsw.Native
Console.WriteLine("LsaAddAccountRights failed: " + winErrorCode);
}
- Advapi32.LsaClose(policyHandle);
+ _ = Advapi32.LsaClose(policyHandle);
}
Advapi32.FreeSid(sid);
@@ -276,16 +261,13 @@ namespace winsw.Native
private const string Advapi32LibraryName = "advapi32.dll";
[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")]
- internal static extern bool ChangeServiceConfig2(IntPtr hService, SERVICE_CONFIG_INFOLEVEL dwInfoLevel, ref SERVICE_FAILURE_ACTIONS sfa);
-
- [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);
+ 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 = "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")]
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);
[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)]
- 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);
[DllImport(Advapi32LibraryName, SetLastError = true)]
@@ -307,8 +292,14 @@ namespace winsw.Native
internal static extern void FreeSid(IntPtr pSid);
[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,
- ref int cbdomainLength, ref int use);
+ internal static extern bool LookupAccountName(
+ string? lpSystemName,
+ string lpAccountName,
+ IntPtr psid,
+ ref int cbsid,
+ StringBuilder domainName,
+ ref int cbdomainLength,
+ out int use);
[DllImport(Advapi32LibraryName)]
internal static extern bool IsValidSid(IntPtr pSid);
diff --git a/src/Core/WinSWCore/Native/Kernel32.cs b/src/Core/WinSWCore/Native/Kernel32.cs
index 73d29b9..32528c1 100755
--- a/src/Core/WinSWCore/Native/Kernel32.cs
+++ b/src/Core/WinSWCore/Native/Kernel32.cs
@@ -9,6 +9,8 @@ namespace winsw.Native
///
public class Kernel32
{
+ public const uint CREATE_NEW_PROCESS_GROUP = 0x00000200;
+
private const string Kernel32LibraryName = "kernel32.dll";
[DllImport(Kernel32LibraryName, SetLastError = true)]
@@ -17,14 +19,14 @@ namespace winsw.Native
[DllImport(Kernel32LibraryName, SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateProcessW")]
public static extern bool CreateProcess(
string? lpApplicationName,
- string lpCommandLine,
+ string? lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string? lpCurrentDirectory,
- [In] ref STARTUPINFO lpStartupInfo,
+ in STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
}
diff --git a/src/Core/WinSWCore/Util/SigIntHelper.cs b/src/Core/WinSWCore/Util/SigIntHelper.cs
index c915d19..b8ede86 100644
--- a/src/Core/WinSWCore/Util/SigIntHelper.cs
+++ b/src/Core/WinSWCore/Util/SigIntHelper.cs
@@ -47,8 +47,8 @@ namespace winsw.Util
if (AttachConsole((uint)process.Id))
{
// Disable Ctrl-C handling for our program
- SetConsoleCtrlHandler(null, true);
- GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
+ _ = SetConsoleCtrlHandler(null, true);
+ _ = GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
process.WaitForExit((int)shutdownTimeout.TotalMilliseconds);
From 3a70a9ef3e2632539f7fedef7738e1c8e5a46f0f Mon Sep 17 00:00:00 2001
From: Oleg Nenashev
Date: Tue, 24 Mar 2020 16:53:20 +0100
Subject: [PATCH 08/13] Update the repository location in README
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 374d3dd..51ae722 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
winsw: Windows service wrapper in less restrictive license
=========================
-[](https://github.com/kohsuke/winsw/releases)
+[](https://github.com/winsw/winsw/releases)
[](https://www.nuget.org/packages/WinSW/)
[](https://ci.appveyor.com/project/oleg-nenashev/winsw)
@@ -14,7 +14,7 @@ See the [project manifest](MANIFEST.md).
### Download
-Starting from WinSW `2.x`, the releases are being hosted on [GitHub](https://github.com/kohsuke/winsw/releases) and [nuget.org](https://www.nuget.org/packages/WinSW/).
+Starting from WinSW `2.x`, the releases are being hosted on [GitHub](https://github.com/winsw/winsw/releases) and [nuget.org](https://www.nuget.org/packages/WinSW/).
Due to historical reasons, the project also uses [Jenkins Maven repository](https://jenkins.io/index.html) as a secondary source.
Binaries are available [here](http://repo.jenkins-ci.org/releases/com/sun/winsw/winsw/).
From cee902e8c39beb9b1ed43bbf624d7d50f329bc89 Mon Sep 17 00:00:00 2001
From: Oleg Nenashev
Date: Tue, 24 Mar 2020 16:59:48 +0100
Subject: [PATCH 09/13] Update WinSW hyperlink in the archived changelog
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7631025..256fc0b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@ Release Notes
##### Newer releases
-See [GitHub Releases](https://github.com/kohsuke/winsw/releases)
+See [GitHub Releases](https://github.com/winsw/winsw/releases)
##### 2.3.0
From 8f5a8612826a4c45a142a7823813a25e1e1fc9d8 Mon Sep 17 00:00:00 2001
From: Oleg Nenashev
Date: Tue, 24 Mar 2020 17:22:24 +0100
Subject: [PATCH 10/13] Update the repo reference in the NuGet spec
---
WinSW.nuspec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/WinSW.nuspec b/WinSW.nuspec
index 466b887..4889596 100644
--- a/WinSW.nuspec
+++ b/WinSW.nuspec
@@ -15,7 +15,7 @@ More info about the wrapper is available in the projects GitHub repository.
WinSW contributors
Oleg Nenashev, Kohsuke Kawaguchi
MIT
- https://github.com/kohsuke/winsw
+ https://github.com/winsw/winsw
Copyright (c) 2010-2016 Kohsuke Kawaguchi, Sun Microsystems, Inc., CloudBees, Inc., Oleg Nenashev and other contributors
false
From 8e1e1e8704c7c400e9c66153ad97ec608eb27ea2 Mon Sep 17 00:00:00 2001
From: Oleg Nenashev
Date: Tue, 24 Mar 2020 18:19:33 +0100
Subject: [PATCH 11/13] Add a Gitter chat for the project
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index 374d3dd..6cc4bf4 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ winsw: Windows service wrapper in less restrictive license
[](https://github.com/kohsuke/winsw/releases)
[](https://www.nuget.org/packages/WinSW/)
[](https://ci.appveyor.com/project/oleg-nenashev/winsw)
+[](https://gitter.im/winsw/winsw?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
WinSW is an executable binary, which can be used to wrap and manage a custom process as a Windows service.
Once you download the installation package, you can rename `winsw.exe` to any name, e.g. `myService.exe`.
From 60840fadecf3d2629b7bba8426dbf820f320aef8 Mon Sep 17 00:00:00 2001
From: Oleg Nenashev
Date: Wed, 25 Mar 2020 10:43:36 +0100
Subject: [PATCH 12/13] Update CODEOWNERS to request reviews from all
maintainers (#451)
* Update CODEOWNERS to request reviews from all maintainers
* mention maintainers explicitly
---
.github/CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9bda637..eb4c561 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @oleg-nenashev
+* @oleg-nenashev @NextTurn
From 634fc0a54197d5ce20e3f44879f211ee973b0cdc Mon Sep 17 00:00:00 2001
From: Oleg Nenashev
Date: Wed, 25 Mar 2020 10:52:56 +0100
Subject: [PATCH 13/13] Add .NET 4.6.1 package to the NuGet specification
---
WinSW.nuspec | 2 ++
1 file changed, 2 insertions(+)
diff --git a/WinSW.nuspec b/WinSW.nuspec
index 466b887..5814405 100644
--- a/WinSW.nuspec
+++ b/WinSW.nuspec
@@ -27,7 +27,9 @@ More info about the wrapper is available in the projects GitHub repository.
+
+