Skip to content

Commit

Permalink
Fixed isssue where is no policy enabled then the app should show the …
Browse files Browse the repository at this point in the history
…watermark. Add process names wildcard feature and small refactoring
  • Loading branch information
amgdy committed Mar 29, 2024
1 parent 49be174 commit 483fee1
Show file tree
Hide file tree
Showing 20 changed files with 168 additions and 197 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 89 additions & 8 deletions src/Magdys.ScreenPrivacyWatermark.App/Forms/MainForm.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using DnsClient.Internal;
using Magdys.ScreenPrivacyWatermark.App.Infrastructure.AccessPolicy;
using Magdys.ScreenPrivacyWatermark.App.Infrastructure.Core;
using Magdys.ScreenPrivacyWatermark.App.Settings;
using Magdys.ScreenPrivacyWatermark.App.Watermark;
using System.ComponentModel;
using System.Diagnostics;
using System.Text.RegularExpressions;
using static Magdys.ScreenPrivacyWatermark.App.NativeMethods;

namespace Magdys.ScreenPrivacyWatermark.App.Forms;
Expand All @@ -11,19 +15,19 @@ public partial class MainForm : Form, IMainForm
private readonly ILogger<MainForm> _logger;

private readonly IServiceProvider _serviceProvider;


private readonly ProcessAccessPolicyOptions _processAccessPolicyOptions;
private readonly WatermarkManager _watermarkManager;
private bool _isDisplaySettingsChanged = true;

public MainForm(ILogger<MainForm> logger,
IServiceProvider serviceProvider,

ProcessAccessPolicyOptions processAccessPolicyOptions,
WatermarkManager watermarkManager)
{
InitializeComponent();
_logger = logger;
_serviceProvider = serviceProvider;
_processAccessPolicyOptions = processAccessPolicyOptions;
_watermarkManager = watermarkManager;
Microsoft.Win32.SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
Expand Down Expand Up @@ -54,6 +58,15 @@ private async void MainForm_Load(object sender, EventArgs e)
{
_logger.LogTrace("Executing {e}.", nameof(MainForm_Load));

if (_processAccessPolicyOptions.AllowedProcessesList.Length > 0)
{
_logger.LogTrace("Process access policy check enabled.");

_logger.LogTrace("Wildcard names is {EnableWildcardNames}.", _processAccessPolicyOptions.EnableWildcardNames ? "enabled" : "disabled");

TimeProcessAccessPolicyCheck.Enabled = true;
}

BackgroundWorkerDispatcher.RunWorkerAsync();

_logger.LogTrace("Executed {e}.", nameof(MainForm_Load));
Expand All @@ -71,14 +84,10 @@ private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
case CloseReason.MdiFormClosing:
case CloseReason.UserClosing:
case CloseReason.TaskManagerClosing:
case CloseReason.ApplicationExitCall:
//case CloseReason.ApplicationExitCall:
e.Cancel = true;
_logger.LogDebug("Form closing CANCELLED");
break;
default:
_logger.LogDebug("Form closing CANCELLED");
e.Cancel = true;
break;
}

_logger.LogTrace("Executed {e}.", nameof(MainForm_FormClosing));
Expand Down Expand Up @@ -149,4 +158,76 @@ private async void TimerOnlineStatus_Tick(object sender, EventArgs e)
await ShowWatermarkFormsAsync();
_logger.LogTrace("Executed {e}.", nameof(TimerOnlineStatus_Tick));
}

private void TimeProcessAccessPolicyCheck_Tick(object sender, EventArgs e)
{

#if !(DEBUG)
_logger.LogTrace(_loggerExecutingText, nameof(TimeProcessPolicyCheck_Tick), Text);
#endif
if (_processAccessPolicyOptions.AllowedProcessesList.Length == 0)
{
return;
}

// this feature is an expensive operation, so we need to measure the time it takes to execute
var timestamp = Stopwatch.GetTimestamp();

var allowedProcessList = _processAccessPolicyOptions.EnableWildcardNames
? _processAccessPolicyOptions.AllowedProcessesList.Select(p => p.Replace(".", @"\.").Replace("*", ".*")).ToHashSet(StringComparer.OrdinalIgnoreCase)
: new HashSet<string>(_processAccessPolicyOptions.AllowedProcessesList, StringComparer.OrdinalIgnoreCase);


var allProcessesWithWindows = Process
.GetProcesses()
.Where(p => p.MainWindowHandle != IntPtr.Zero)
.ToArray();

var filteredProcesses = new List<Process>();
foreach (var processWithWindow in allProcessesWithWindows)
{
if (_processAccessPolicyOptions.EnableWildcardNames)
{
foreach (var allowedProcess in allowedProcessList)
{

if (Regex.IsMatch(processWithWindow.ProcessName, allowedProcess, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(0.5)))
{
filteredProcesses.Add(processWithWindow);
}
}
}
else
{
if (allowedProcessList.Contains(processWithWindow.ProcessName))
{
filteredProcesses.Add(processWithWindow);
}
}
}

foreach (var process in filteredProcesses)
{
var isMinimized = IsIconic(process.MainWindowHandle);
if (!isMinimized)
{
ProcessAccessPolicyState.HideWatermark = false;
return;
}

}

ProcessAccessPolicyState.HideWatermark = true;


var elapsed = Stopwatch.GetElapsedTime(timestamp);

_logger.LogDebug("Process access policy check took {elapsed} ms", elapsed.Milliseconds);


#if !(DEBUG)
_logger.LogTrace(_loggerExecutedText, nameof(TimeProcessPolicyCheck_Tick), Text);
#endif

}
}
3 changes: 3 additions & 0 deletions src/Magdys.ScreenPrivacyWatermark.App/Forms/MainForm.resx
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,7 @@
<metadata name="TimerOnlineStatus.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>229, 17</value>
</metadata>
<metadata name="TimeProcessAccessPolicyCheck.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>380, 17</value>
</metadata>
</root>
131 changes: 15 additions & 116 deletions src/Magdys.ScreenPrivacyWatermark.App/Forms/WatermarkForm.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Magdys.ScreenPrivacyWatermark.App.Infrastructure.AccessPolicy;
using Magdys.ScreenPrivacyWatermark.App.Settings;
using Magdys.ScreenPrivacyWatermark.App.Watermark.Options;
using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Text;
using static Magdys.ScreenPrivacyWatermark.App.NativeMethods;
Expand All @@ -11,24 +10,18 @@ namespace Magdys.ScreenPrivacyWatermark.App.Forms;
public partial class WatermarkForm : Form
{
private readonly ILogger<WatermarkForm> _logger;
private readonly IOptions<WatermarkFormatSettings> _watermarkFormatSetting;

private readonly ProcessAccessPolicyOptions _processAccessPolicyOptions;


private readonly IOptions<WatermarkFormatOptions> _watermarkFormatSetting;
private bool _isFormClosingSubscribed = true;
private bool _isInitialized = false;
private WatermarkFormOptions _watermarkFormOptions = null;
private const string _loggerExecutingText = "Executing {method} for '{text}'";

private const string _loggerExecutedText = "Executed {method} for '{text}'";

public WatermarkForm(ILogger<WatermarkForm> logger, IOptions<WatermarkFormatSettings> watermarkFormatSetting, ProcessAccessPolicyOptions _processAccessPolicyOptions)
public WatermarkForm(ILogger<WatermarkForm> logger, IOptions<WatermarkFormatOptions> watermarkFormatSetting)
{
InitializeComponent();
_logger = logger;
_watermarkFormatSetting = watermarkFormatSetting;
this._processAccessPolicyOptions = _processAccessPolicyOptions;
}

protected override CreateParams CreateParams
Expand Down Expand Up @@ -88,7 +81,7 @@ private void WatermarkForm_FormClosing(object sender, FormClosingEventArgs e)
case CloseReason.MdiFormClosing:
case CloseReason.UserClosing:
case CloseReason.TaskManagerClosing:
case CloseReason.ApplicationExitCall:
//case CloseReason.ApplicationExitCall:
e.Cancel = true;
break;
}
Expand All @@ -104,13 +97,13 @@ private async void WatermarkForm_Load(object sender, EventArgs e)
throw new InvalidOperationException($"Form is not initialized. You need to call {nameof(InitializeForm)} method first.");
}

if (_processAccessPolicyOptions.AllowedProcessesList.Length != 0)
// Means the process access policy is enabled.
if (ProcessAccessPolicyState.HideWatermark.HasValue)
{
_logger.LogDebug("Process Access Policy is enabled.");
TimeProcessPolicyCheck.Enabled = true;
}



_logger.LogTrace(_loggerExecutedText, nameof(WatermarkForm_Load), Text);
}

Expand Down Expand Up @@ -192,121 +185,27 @@ private void DrawWatermarkText(Graphics graphics)
_logger.LogTrace(_loggerExecutedText, nameof(DrawWatermarkText), Text);
}

//private string GetFormattedWatermarkText(Graphics graphics)
//{
// _logger.LogTrace(_loggerExecutingText, nameof(GetFormattedWatermarkText), Text);

// string watermarkText = _watermarkFormOptions._watermarkText;

// string spacer = new string(' ', _watermarkFormatSetting.Value.UseDynamicsSpacing ? new Random().Next(6, 15) : 10);

// string watermarkBaseString = $"{watermarkText} {spacer}";

// _logger.LogDebug("Watermark text: {_watermarkText}", watermarkBaseString);

// double width = _watermarkFormOptions.Screen.Bounds.Width;
// double height = _watermarkFormOptions.Screen.Bounds.Height;
// double diagonalSize = Math.Sqrt(Math.Pow(width, 2) + Math.Pow(height, 2));

// StringBuilder formatedText = new StringBuilder();
// for (int i = 0; i < 100; i++)
// {
// formatedText.Append(watermarkBaseString);
// }

// _logger.LogTrace(_loggerExecutedText, nameof(GetFormattedWatermarkText), Text);

// return formatedText.ToString();
//}

//private void DrawWatermarkTextOld(Graphics graphics, string text)
//{
// _logger.LogTrace(_loggerExecutingText, nameof(DrawWatermarkText), Text);

// ArgumentNullException.ThrowIfNull(graphics);

// if (string.IsNullOrEmpty(text))
// {
// throw new ArgumentException("Watermark text cannot be NULL or empty.", nameof(text));
// }

// graphics.TextRenderingHint = _watermarkFormatSetting.Value.TextRender;
// graphics.SmoothingMode = SmoothingMode.Default;
// graphics.InterpolationMode = InterpolationMode.Default;

// using var font = new Font(_watermarkFormatSetting.Value.FontName, _watermarkFormatSetting.Value.FontSize, FontStyle.Regular, GraphicsUnit.Point);
// using var brush = new SolidBrush(Color.FromArgb(255, _watermarkFormatSetting.Value.Color));
// using var stringFormat = new StringFormat(StringFormatFlags.NoClip);


// graphics.ResetTransform();
// if (_watermarkFormatSetting.Value.UseDiagonalLines)
// {
// graphics.RotateTransform(-45);
// }

// double screenDiagonal = Math.Round(Math.Sqrt(Math.Pow(_watermarkFormOptions.Screen.WorkingArea.Width, 2) + Math.Pow(_watermarkFormOptions.Screen.WorkingArea.Height, 2)));

// int repeatCounts = _watermarkFormatSetting.Value.LinesCount;

// int x = _watermarkFormatSetting.Value.UseDiagonalLines ? (int)screenDiagonal : Bounds.Height;

// int spacer = x / repeatCounts;

// int firstPoint = _watermarkFormatSetting.Value.UseDynamicsSpacing ? new Random().Next(-2, 2) : 0;

// for (int i = firstPoint; i < repeatCounts + 2 + firstPoint; i++)
// {
// var point = new Point(-spacer * i, spacer * i);

// if (_watermarkFormatSetting.Value.OutlineColor == null)
// {
// graphics.DrawString(text, font, brush, point, stringFormat);
// }
// else
// {
// using GraphicsPath graphicPath = new GraphicsPath();
// using Pen pen = new Pen(_watermarkFormatSetting.Value.OutlineColor.Value, _watermarkFormatSetting.Value.OutlineWidth);
// graphicPath.AddString(text, font.FontFamily, (int)font.Style, font.Size * 1.5f, point, stringFormat);

// graphics.DrawPath(pen, graphicPath);
// graphics.FillPath(brush, graphicPath);
// }
// }

// _logger.LogTrace(_loggerExecutedText, nameof(DrawWatermarkText), Text);
//}

private void TimeProcessPolicyCheck_Tick(object sender, EventArgs e)
{
#if !(DEBUG)
_logger.LogTrace(_loggerExecutingText, nameof(TimeProcessPolicyCheck_Tick), Text);
#endif

var allowedProcessesList = _processAccessPolicyOptions.AllowedProcessesList.Select(p => p.ToUpperInvariant()).ToArray();

if (allowedProcessesList.Length == 0)
if (ProcessAccessPolicyState.HideWatermark == null)
{
Opacity = _watermarkFormatSetting.Value.OpacityF;
// this should not happen since the timer should be disabled if the HideWatermark is null
return;
}

var processes = Process
.GetProcesses()
.Where(p => allowedProcessesList.Contains(p.ProcessName.ToUpperInvariant()) && p.MainWindowHandle != IntPtr.Zero)
.ToArray();

foreach (var process in processes)
if (ProcessAccessPolicyState.HideWatermark.Value)
{
var isMinimized = IsIconic(process.MainWindowHandle);
if (!isMinimized)
{
Opacity = _watermarkFormatSetting.Value.OpacityF;
return;
}
Opacity = 0f;
}
else
{
Opacity = _watermarkFormatSetting.Value.OpacityF;
}

Opacity = 0f;

#if !(DEBUG)
_logger.LogTrace(_loggerExecutedText, nameof(TimeProcessPolicyCheck_Tick), Text);
Expand Down
4 changes: 0 additions & 4 deletions src/Magdys.ScreenPrivacyWatermark.App/GlobalUsings.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ private async Task<bool> EvaulateAccessPolicies()
.OrderBy(p => p.Order)
.ToList();

// if there is no policy enabled, grant access
if (policies.Count == 0)
{
logger.LogDebug("No enabled policies found. Granting access.");
return true;
}

switch (evaluationMode)
{
case EvaluationMode.Any:
Expand Down
Loading

0 comments on commit 483fee1

Please sign in to comment.