summaryrefslogtreecommitdiff
path: root/src/Agent.Windows/Diagnostics
diff options
context:
space:
mode:
Diffstat (limited to 'src/Agent.Windows/Diagnostics')
-rw-r--r--src/Agent.Windows/Diagnostics/WindowsPlatformCheck.cs64
1 files changed, 35 insertions, 29 deletions
diff --git a/src/Agent.Windows/Diagnostics/WindowsPlatformCheck.cs b/src/Agent.Windows/Diagnostics/WindowsPlatformCheck.cs
index b8ca0ae..89a2106 100644
--- a/src/Agent.Windows/Diagnostics/WindowsPlatformCheck.cs
+++ b/src/Agent.Windows/Diagnostics/WindowsPlatformCheck.cs
@@ -1,50 +1,56 @@
using System.ComponentModel;
-using System.Security.Principal;
-using Agent.Windows.Network;
+using System.Diagnostics;
+using System.Reflection;
using Agent.Windows.Security;
+using Windows.Win32;
+using Windows.Win32.NetworkManagement.WindowsFilteringPlatform;
namespace Agent.Windows.Diagnostics;
public sealed record WindowsPlatformCheckResult(
- bool IsAdministrator,
+ bool PlatformSupported,
+ bool ApplicationProfileAvailable,
bool BfeEngineOpen,
- bool WfpWriteTransaction,
- bool WfpFilterAddDelete,
+ bool HelperAvailable,
+ bool HelperVersionCompatible,
int? ErrorCode,
string? ErrorOperation)
{
- public bool Success => IsAdministrator && BfeEngineOpen && WfpWriteTransaction && WfpFilterAddDelete;
+ public bool Success => PlatformSupported && ApplicationProfileAvailable && BfeEngineOpen && HelperAvailable && HelperVersionCompatible;
}
public static class WindowsPlatformCheck
{
- public static WindowsPlatformCheckResult Run()
+ public static WindowsPlatformCheckResult Run(string helperPath)
{
- using WindowsIdentity identity = WindowsIdentity.GetCurrent();
- bool administrator = new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
- bool open = false;
- bool transaction = false;
- bool filters = false;
+ bool platform = OperatingSystem.IsWindowsVersionAtLeast(10, 0, 26100);
+ bool profile = false;
+ bool bfe = false;
+ bool helper = File.Exists(helperPath);
+ bool version = false;
try
{
- AppContainerProfile profile = AppContainerProfile.EnsureFixed();
- using WfpDynamicSession session = WfpDynamicSession.Open();
- open = true;
- session.ProbeWriteTransaction();
- transaction = true;
- IReadOnlyList<ulong> ids = session.ApplyDefaultBlock(profile.Sid);
- if (ids.Count != 2 || ids.Any(static id => id == 0)) throw new InvalidOperationException("WFP probe did not create both IPv4 and IPv6 filters.");
- session.RemovePolicy();
- filters = true;
- return new(administrator, open, transaction, filters, null, null);
- }
- catch (Win32Exception ex)
- {
- return new(administrator, open, transaction, filters, ex.NativeErrorCode, ex.Message);
+ _ = AppContainerProfile.DeriveFixed();
+ profile = true;
+ using FwpmEngineClose0SafeHandle engine = OpenBfeReadOnly();
+ bfe = true;
+ if (helper)
+ {
+ string current = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(3) ?? "";
+ string candidate = FileVersionInfo.GetVersionInfo(helperPath).FileVersion ?? "";
+ version = candidate.StartsWith(current, StringComparison.Ordinal);
+ }
+ return new(platform, profile, bfe, helper, version, null, null);
}
+ catch (Win32Exception ex) { return new(platform, profile, bfe, helper, version, ex.NativeErrorCode, ex.Message); }
catch (Exception ex) when (ex is UnauthorizedAccessException or InvalidOperationException or IOException)
- {
- return new(administrator, open, transaction, filters, ex.HResult, ex.Message);
- }
+ { return new(platform, profile, bfe, helper, version, ex.HResult, ex.Message); }
+ }
+
+ private static FwpmEngineClose0SafeHandle OpenBfeReadOnly()
+ {
+ uint result = PInvoke.FwpmEngineOpen0(10, null, null, out FwpmEngineClose0SafeHandle engine);
+ if (result != 0) throw new Win32Exception(unchecked((int)result), $"FwpmEngineOpen0 failed with WFP/Win32 error 0x{result:X8}.");
+ return engine;
}
}