summaryrefslogtreecommitdiff
path: root/src/Agent.Windows/Diagnostics/WindowsPlatformCheck.cs
blob: b8ca0ae173ceae62e49e17266776d44b2d2b8e93 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.ComponentModel;
using System.Security.Principal;
using Agent.Windows.Network;
using Agent.Windows.Security;

namespace Agent.Windows.Diagnostics;

public sealed record WindowsPlatformCheckResult(
    bool IsAdministrator,
    bool BfeEngineOpen,
    bool WfpWriteTransaction,
    bool WfpFilterAddDelete,
    int? ErrorCode,
    string? ErrorOperation)
{
    public bool Success => IsAdministrator && BfeEngineOpen && WfpWriteTransaction && WfpFilterAddDelete;
}

public static class WindowsPlatformCheck
{
    public static WindowsPlatformCheckResult Run()
    {
        using WindowsIdentity identity = WindowsIdentity.GetCurrent();
        bool administrator = new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
        bool open = false;
        bool transaction = false;
        bool filters = 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);
        }
        catch (Exception ex) when (ex is UnauthorizedAccessException or InvalidOperationException or IOException)
        {
            return new(administrator, open, transaction, filters, ex.HResult, ex.Message);
        }
    }
}