218 lines
7.6 KiB
C#
218 lines
7.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Security.Principal;
|
|
using AmagnoVirtualPrinter.Agent.Core.Enums;
|
|
using AmagnoVirtualPrinter.Agent.Core.Interfaces;
|
|
using AmagnoVirtualPrinter.Agent.Core.Model;
|
|
using AmagnoVirtualPrinter.Logging;
|
|
using Cassia;
|
|
|
|
using JetBrains.Annotations;
|
|
|
|
using AmagnoVirtualPrinter.Agent.Core;
|
|
|
|
namespace AmagnoVirtualPrinter.Agent.Lib.Misc
|
|
{
|
|
public class JobFactory : IJobFactory
|
|
{
|
|
[NotNull]
|
|
private readonly IVirtualPrinterLogger<JobFactory> _logger;
|
|
private readonly IDirectoryHelper _directoryHelper;
|
|
[NotNull]
|
|
private readonly IRegistryRepository _registryRepository;
|
|
|
|
public JobFactory
|
|
(
|
|
[NotNull]IRegistryRepository registryRepository,
|
|
[NotNull]IVirtualPrinterLogger<JobFactory> logger,
|
|
[NotNull]IDirectoryHelper directoryHelper
|
|
)
|
|
{
|
|
if (registryRepository == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(registryRepository));
|
|
}
|
|
|
|
if (logger == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
if (directoryHelper == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(logger));
|
|
}
|
|
|
|
_registryRepository = registryRepository;
|
|
_logger = logger;
|
|
_directoryHelper = directoryHelper;
|
|
}
|
|
|
|
public IJob Create(string printerName, Stream stream)
|
|
{
|
|
if (printerName == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(printerName));
|
|
}
|
|
|
|
if (stream == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(stream));
|
|
}
|
|
|
|
try
|
|
{
|
|
var now = DateTime.Now;
|
|
|
|
var jobInfo = PrintJobReader.GetCurrentPrintJobs(printerName).FirstOrDefault();
|
|
if (jobInfo == null)
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
var sessions = GetCurrentSessions(jobInfo).ToArray();
|
|
var session = sessions.FirstOrDefault(s => s.FoundDomain) ?? sessions.FirstOrDefault();
|
|
|
|
var config = _registryRepository.GetRegistryConfig();
|
|
var userConfig = _registryRepository.GetUserRegistryConfig(session.Sid);
|
|
var root = _directoryHelper.GetOutputDirectory(userConfig);
|
|
var iniName = GenerateFileName(now, jobInfo.JobId, 0, config.FileNameMask, "ini");
|
|
var iniPath = Path.Combine(root, iniName);
|
|
var extension = GetRawFileExtension(config.IntermediateFormat);
|
|
var rawName = $"{Path.GetFileNameWithoutExtension(iniName)}.{extension}";
|
|
var rawPath = Path.Combine(root, rawName);
|
|
using (var output = File.Create(rawPath))
|
|
{
|
|
stream.CopyTo(output);
|
|
}
|
|
|
|
return new Job
|
|
{
|
|
RawDataPath = rawPath,
|
|
IniDataPath = iniPath,
|
|
JobInfo = jobInfo,
|
|
SessionInfo = session
|
|
};
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
LogError(exception, "Failed to create job.");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public IJob Create(string iniPath, string rawPath, IJobInfo jobInfo, ISessionInfo sessionInfo)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(iniPath))
|
|
{
|
|
throw new ArgumentException("Value cannot be null or whitespace.", nameof(iniPath));
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(rawPath))
|
|
{
|
|
throw new ArgumentException("Value cannot be null or whitespace.", nameof(rawPath));
|
|
}
|
|
|
|
return new Job
|
|
{
|
|
IniDataPath = iniPath,
|
|
RawDataPath = rawPath,
|
|
JobInfo = jobInfo,
|
|
SessionInfo = sessionInfo
|
|
};
|
|
}
|
|
|
|
[NotNull]
|
|
private string GenerateFileName(DateTime time, int job, int page, [NotNull]string pattern, [NotNull]string ending)
|
|
{
|
|
var fileName = pattern;
|
|
fileName = fileName.Replace("{yyyy}", $"{time.Year:0000}");
|
|
fileName = fileName.Replace("{MM}", $"{time.Month:00}");
|
|
fileName = fileName.Replace("{DD}", $"{time.Day:00}");
|
|
fileName = fileName.Replace("{hh}", $"{time.Hour:00}");
|
|
fileName = fileName.Replace("{mm}", $"{time.Minute:00}");
|
|
fileName = fileName.Replace("{ss}", $"{time.Second:00}");
|
|
fileName = fileName.Replace("{fff}", $"{time.Millisecond:000}");
|
|
fileName = fileName.Replace("{job05}", $"{job:00000}");
|
|
fileName = fileName.Replace("{page03}", $"{page:000}");
|
|
|
|
return $"{fileName}.{ending}";
|
|
}
|
|
|
|
private IEnumerable<SessionInfo> GetCurrentSessions([NotNull]IJobInfo job)
|
|
{
|
|
var domain = job.DomainName;
|
|
var machine = job.MachineName?.TrimStart('\\');
|
|
var username = job.UserName;
|
|
|
|
LogDebug($"Searching for session of {domain}\\{username} on {machine} !");
|
|
|
|
if (domain == null || machine == null || username == null)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
const StringComparison cmp = StringComparison.OrdinalIgnoreCase;
|
|
using (var server = new TerminalServicesManager().GetLocalServer())
|
|
{
|
|
var sessions = server.GetSessions().Where(s => s.UserName != null && s.DomainName != null);
|
|
foreach (var session in sessions)
|
|
{
|
|
if (!session.UserName.Equals(username, cmp))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var isSingleUser = session.DomainName.Equals(machine, cmp);
|
|
var isDomainUser = session.DomainName.Equals(domain, cmp);
|
|
if (!isSingleUser && !isDomainUser)
|
|
{
|
|
LogWarn("Found Session {sessionId} for {username} but its not of domain {domain} or {machine}", session.SessionId, username, domain, machine);
|
|
}
|
|
|
|
var sessionId = session.SessionId;
|
|
var desktopName = session.WindowStationName;
|
|
var account = session.UserAccount;
|
|
yield return new SessionInfo
|
|
{
|
|
Id = sessionId,
|
|
Desktop = desktopName,
|
|
Sid = account.Translate(typeof(SecurityIdentifier)).Value,
|
|
FoundDomain = isSingleUser || isDomainUser
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
[NotNull]
|
|
private string GetRawFileExtension(IntermediateFormat format)
|
|
{
|
|
switch (format)
|
|
{
|
|
case IntermediateFormat.Xps:
|
|
return "xps";
|
|
case IntermediateFormat.Ps:
|
|
return "ps";
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
|
|
private void LogDebug(string message)
|
|
{
|
|
_logger.Debug(message);
|
|
}
|
|
|
|
private void LogError(Exception exception, string message, params object[] args)
|
|
{
|
|
_logger.Error(exception, message, args);
|
|
}
|
|
|
|
private void LogWarn(string message, params object[] args)
|
|
{
|
|
_logger.Warn(message, args);
|
|
}
|
|
}
|
|
}
|