Skip to content

Commit

Permalink
Merge shared directory mapping into core
Browse files Browse the repository at this point in the history
  • Loading branch information
nxtn committed Jan 1, 2021
1 parent 4b00bba commit c020a3f
Show file tree
Hide file tree
Showing 21 changed files with 200 additions and 276 deletions.
6 changes: 4 additions & 2 deletions src/WinSW.Core/Configuration/ServiceConfig.cs
Expand Up @@ -77,13 +77,15 @@ public abstract class ServiceConfig
public virtual string ErrFilePattern => ".err.log";

// Environment
public virtual List<Download> Downloads => new List<Download>(0);
public virtual List<Download> Downloads => new(0);

public virtual Dictionary<string, string> EnvironmentVariables => new Dictionary<string, string>(0);
public virtual Dictionary<string, string> EnvironmentVariables => new(0);

// Misc
public virtual bool BeepOnShutdown => false;

public virtual List<SharedDirectoryMapperConfig> SharedDirectories => new(0);

// Extensions
public virtual XmlNode? ExtensionsConfiguration => null;
}
Expand Down
29 changes: 27 additions & 2 deletions src/WinSW.Core/Configuration/XmlServiceConfig.cs
Expand Up @@ -18,7 +18,7 @@ namespace WinSW
/// </summary>
public class XmlServiceConfig : ServiceConfig
{
protected readonly XmlDocument dom = new XmlDocument();
protected readonly XmlDocument dom = new();

private readonly XmlNode root;
private readonly Dictionary<string, string> environmentVariables;
Expand Down Expand Up @@ -145,7 +145,7 @@ private TimeSpan SingleTimeSpanElement(XmlNode parent, string tagName, TimeSpan
return value is null ? defaultValue : ParseTimeSpan(value);
}

private static readonly Dictionary<string, long> Suffix = new Dictionary<string, long>
private static readonly Dictionary<string, long> Suffix = new()
{
{ "ms", 1 },
{ "sec", 1000L },
Expand Down Expand Up @@ -581,6 +581,31 @@ public override ProcessPriorityClass Priority

public bool AutoRefresh => this.SingleBoolElementOrDefault("autoRefresh", true);

public override List<SharedDirectoryMapperConfig> SharedDirectories
{
get
{
var mapNodes = this.root.SelectSingleNode("sharedDirectoryMapping")?.SelectNodes("map");
if (mapNodes is null)
{
return new();
}

var result = new List<SharedDirectoryMapperConfig>(mapNodes.Count);
for (int i = 0; i < mapNodes.Count; i++)
{
if (mapNodes[i] is XmlElement mapElement)
{
string label = XmlHelper.SingleAttribute<string>(mapElement, "label");
string uncPath = XmlHelper.SingleAttribute<string>(mapElement, "uncpath");
result.Add(new(label, uncPath));
}
}

return result;
}
}

private Dictionary<string, string> LoadEnvironmentVariables()
{
var nodeList = this.root.SelectNodes("env")!;
Expand Down
2 changes: 1 addition & 1 deletion src/WinSW.Core/LogAppenders.cs
Expand Up @@ -419,7 +419,7 @@ protected override Task LogError(StreamReader errorReader)
private async Task CopyStreamWithRotationAsync(StreamReader reader, string extension)
{
// lock required as the timer thread and the thread that will write to the stream could try and access the file stream at the same time
object? fileLock = new object();
object? fileLock = new();

string? baseDirectory = Path.GetDirectoryName(this.BaseLogFileName)!;
string? baseFileName = Path.GetFileName(this.BaseLogFileName);
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions src/WinSW.Core/Native/Libraries.cs
Expand Up @@ -5,6 +5,7 @@ internal static class Libraries
internal const string Advapi32 = "advapi32.dll";
internal const string CredUI = "credui.dll";
internal const string Kernel32 = "kernel32.dll";
internal const string Mpr = "mpr.dll";
internal const string NtDll = "ntdll.dll";
}
}
31 changes: 31 additions & 0 deletions src/WinSW.Core/Native/NetworkApis.cs
@@ -0,0 +1,31 @@
#pragma warning disable SA1310 // Field names should not contain underscore

using System.Runtime.InteropServices;
using static WinSW.Native.Libraries;

namespace WinSW.Native
{
internal static class NetworkApis
{
internal const uint RESOURCETYPE_DISK = 0x00000001;

[DllImport(Mpr, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern int WNetAddConnection2W(in NETRESOURCEW netResource, string? password = null, string? userName = null, uint flags = 0);

[DllImport(Mpr, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern int WNetCancelConnection2W(string name, uint flags = 0, bool force = false);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct NETRESOURCEW
{
public uint Scope;
public uint Type;
public uint DisplayType;
public uint Usage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
}
}
4 changes: 2 additions & 2 deletions src/WinSW.Core/Native/ResourceApis.cs
Expand Up @@ -7,9 +7,9 @@ namespace WinSW.Native
{
internal static class ResourceApis
{
internal static readonly IntPtr VS_VERSION_INFO = new IntPtr(1);
internal static readonly IntPtr VS_VERSION_INFO = new(1);

internal static readonly IntPtr RT_VERSION = new IntPtr(16);
internal static readonly IntPtr RT_VERSION = new(16);

[DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr BeginUpdateResourceW(string fileName, bool deleteExistingResources);
Expand Down
File renamed without changes.
50 changes: 50 additions & 0 deletions src/WinSW.Core/SharedDirectoryMapper.cs
@@ -0,0 +1,50 @@
using System.Collections.Generic;
using WinSW.Native;
using static WinSW.Native.NetworkApis;

namespace WinSW
{
public sealed class SharedDirectoryMapper
{
private readonly List<SharedDirectoryMapperConfig> entries;

public SharedDirectoryMapper(List<SharedDirectoryMapperConfig> entries)
{
this.entries = entries;
}

public void Map()
{
foreach (var config in this.entries)
{
string label = config.Label;
string uncPath = config.UncPath;

int error = WNetAddConnection2W(new()
{
Type = RESOURCETYPE_DISK,
LocalName = label,
RemoteName = uncPath,
});
if (error != 0)
{
Throw.Command.Win32Exception(error, $"Failed to map {label}.");
}
}
}

public void Unmap()
{
foreach (var config in this.entries)
{
string label = config.Label;

int error = WNetCancelConnection2W(label);
if (error != 0)
{
Throw.Command.Win32Exception(error, $"Failed to unmap {label}.");
}
}
}
}
}
15 changes: 15 additions & 0 deletions src/WinSW.Core/SharedDirectoryMapperConfig.cs
@@ -0,0 +1,15 @@
namespace WinSW
{
public sealed class SharedDirectoryMapperConfig
{
public string Label { get; }

public string UncPath { get; }

public SharedDirectoryMapperConfig(string driveLabel, string directoryUncPath)
{
this.Label = driveLabel;
this.UncPath = directoryUncPath;
}
}
}
40 changes: 29 additions & 11 deletions src/WinSW/WrapperService.cs → src/WinSW.Core/WrapperService.cs
Expand Up @@ -17,9 +17,9 @@ namespace WinSW
{
public sealed class WrapperService : ServiceBase, IEventLogger, IServiceEventLog
{
internal static readonly WrapperServiceEventLogProvider eventLogProvider = new WrapperServiceEventLogProvider();
internal static readonly WrapperServiceEventLogProvider EventLogProvider = new();

private static readonly int additionalStopTimeout = 1_000;
private static readonly int AdditionalStopTimeout = 1_000;

private static readonly ILog Log = LogManager.GetLogger(typeof(WrapperService));

Expand All @@ -31,6 +31,8 @@ public sealed class WrapperService : ServiceBase, IEventLogger, IServiceEventLog

internal WinSWExtensionManager ExtensionManager { get; }

private SharedDirectoryMapper? sharedDirectoryMapper;

private bool shuttingdown;

/// <summary>
Expand All @@ -51,7 +53,7 @@ public WrapperService(XmlServiceConfig config)
this.ExtensionManager = new WinSWExtensionManager(config);

// Register the event log provider
eventLogProvider.Service = this;
EventLogProvider.Service = this;

if (config.Preshutdown)
{
Expand Down Expand Up @@ -297,6 +299,13 @@ private void DoStart()
throw new AggregateException(exceptions);
}

var sharedDirectories = this.config.SharedDirectories;
if (sharedDirectories.Count > 0)
{
this.sharedDirectoryMapper = new(sharedDirectories);
this.sharedDirectoryMapper.Map();
}

var prestart = this.config.Prestart;
string? prestartExecutable = prestart.Executable;
if (prestartExecutable != null)
Expand All @@ -306,7 +315,7 @@ private void DoStart()
using var process = this.StartProcess(prestartExecutable, prestart.Arguments, prestart.CreateLogHandler());
this.WaitForProcessToExit(process);
this.LogExited($"Pre-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
process.StopDescendants(additionalStopTimeout);
process.StopDescendants(AdditionalStopTimeout);
}
catch (Exception e)
{
Expand Down Expand Up @@ -335,7 +344,7 @@ private void DoStart()
using var process = StartProcessLocked();
this.WaitForProcessToExit(process);
this.LogExited($"Post-start process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
process.StopDescendants(additionalStopTimeout);
process.StopDescendants(AdditionalStopTimeout);
this.startingProcess = null;

Process StartProcessLocked()
Expand Down Expand Up @@ -367,7 +376,7 @@ private void DoStop()
using var process = StartProcessLocked(prestopExecutable, prestop.Arguments, prestop.CreateLogHandler());
this.WaitForProcessToExit(process);
this.LogExited($"Pre-stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
process.StopDescendants(additionalStopTimeout);
process.StopDescendants(AdditionalStopTimeout);
this.stoppingProcess = null;
}
catch (Exception e)
Expand Down Expand Up @@ -408,7 +417,7 @@ private void DoStop()

Log.Debug("WaitForProcessToExit " + this.process.Id + "+" + stopProcess.Id);
this.WaitForProcessToExit(stopProcess);
stopProcess.StopDescendants(additionalStopTimeout);
stopProcess.StopDescendants(AdditionalStopTimeout);
this.stoppingProcess = null;

this.WaitForProcessToExit(this.process);
Expand All @@ -429,8 +438,8 @@ private void DoStop()
{
using var process = StartProcessLocked(poststopExecutable, poststop.Arguments, poststop.CreateLogHandler());
this.WaitForProcessToExit(process);
this.LogExited($"Post-Stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
process.StopDescendants(additionalStopTimeout);
this.LogExited($"Post-stop process '{process.Format()}' exited with code {process.ExitCode}.", process.ExitCode);
process.StopDescendants(AdditionalStopTimeout);
this.stoppingProcess = null;
}
catch (Exception e)
Expand All @@ -439,6 +448,15 @@ private void DoStop()
}
}

try
{
this.sharedDirectoryMapper?.Unmap();
}
catch (Exception e)
{
Log.Error(e);
}

// Stop extensions
this.ExtensionManager.FireBeforeWrapperStopped();

Expand Down Expand Up @@ -513,8 +531,8 @@ private void OnMainProcessExited(Process process)

process.StopDescendants(this.config.StopTimeoutInMs);

this.startingProcess?.StopTree(additionalStopTimeout);
this.stoppingProcess?.StopTree(additionalStopTimeout);
this.startingProcess?.StopTree(AdditionalStopTimeout);
this.stoppingProcess?.StopTree(AdditionalStopTimeout);

// if we finished orderly, report that to SCM.
// by not reporting unclean shutdown, we let Windows SCM to decide if it wants to
Expand Down

0 comments on commit c020a3f

Please sign in to comment.