< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.AppContainerInfo
Assembly: CoreWCF.NetNamedPipe
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.NetNamedPipe/src/CoreWCF/Channels/AppContainerInfo.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 38
Coverable lines: 38
Total lines: 109
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
GetCurrentAppContainerSid()0%440%
RunningInAppContainer()0%220%
GetAppContainerSid()0%660%
GetCurrentProcessToken()100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.NetNamedPipe/src/CoreWCF/Channels/AppContainerInfo.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.ComponentModel;
 6using System.Diagnostics;
 7using System.Runtime.InteropServices;
 8using System.Runtime.Versioning;
 9using System.Security.Principal;
 10using System.Text;
 11using CoreWCF.Runtime;
 12using CoreWCF.Security;
 13using Microsoft.IdentityModel.Tokens;
 14using Microsoft.Win32.SafeHandles;
 15using static CoreWCF.Security.UnsafeNativeMethods;
 16
 17namespace CoreWCF.Channels
 18{
 19    [SupportedOSPlatform("windows")]
 20    internal static class AppContainerInfo
 21    {
 022        private static readonly object s_lock = new object();
 23        private static volatile bool s_isRunningInAppContainerSet;
 24        private static bool s_isRunningInAppContainer;
 25        private static volatile SecurityIdentifier s_currentAppContainerSid;
 26
 27        internal static bool IsRunningInAppContainer
 28        {
 29            get
 30            {
 031                if (!s_isRunningInAppContainerSet)
 32                {
 033                    lock (s_lock)
 34                    {
 035                        if (!s_isRunningInAppContainerSet)
 36                        {
 037                            s_isRunningInAppContainer = RunningInAppContainer();
 038                            s_isRunningInAppContainerSet = true;
 39                        }
 040                    }
 41                }
 42
 043                return s_isRunningInAppContainer;
 44            }
 45        }
 46
 47        internal static SecurityIdentifier GetCurrentAppContainerSid()
 48        {
 049            if (s_currentAppContainerSid == null)
 50            {
 051                lock (s_lock)
 52                {
 053                    if (s_currentAppContainerSid == null)
 54                    {
 055                        s_currentAppContainerSid = GetAppContainerSid();
 56                    }
 057                }
 58            }
 59
 060            return s_currentAppContainerSid;
 61        }
 62
 63        private static bool RunningInAppContainer()
 64        {
 065            uint tokenInfoLength = sizeof(int);
 066            byte[] tokenInformation = new byte[tokenInfoLength];
 067            if (!UnsafeNativeMethods.GetTokenInformation(GetCurrentProcessToken(),
 068                UnsafeNativeMethods.TOKEN_INFORMATION_CLASS.TokenIsAppContainer,
 069                tokenInformation, tokenInfoLength, out _))
 70            {
 071                int error = Marshal.GetLastWin32Error();
 072                throw new Win32Exception(error);
 73            }
 74
 075            return BitConverter.ToInt32(tokenInformation, 0) != 0;
 76        }
 77
 78        private static unsafe SecurityIdentifier GetAppContainerSid()
 79        {
 80            // First call to get the required buffer length
 081            uint returnLength = UnsafeNativeMethods.GetTokenInformationLength(
 082                    GetCurrentProcessToken(),
 083                    TOKEN_INFORMATION_CLASS.TokenAppContainerSid);
 84
 085            byte[] tokenInformation = new byte[returnLength];
 086            fixed (byte* pTokenInformation = tokenInformation)
 87            {
 088                if (!UnsafeNativeMethods.GetTokenInformation(
 089                                                GetCurrentProcessToken(),
 090                                                TOKEN_INFORMATION_CLASS.TokenAppContainerSid,
 091                                                tokenInformation,
 092                                                returnLength,
 093                                                out returnLength))
 94                {
 095                    int errorCode = Marshal.GetLastWin32Error();
 096                    throw Fx.Exception.AsError(new Win32Exception(errorCode));
 97                }
 98
 99                // TOKEN_APPCONTAINER_INFORMATION contains a single PSID field
 0100                IntPtr sidPtr = Marshal.ReadIntPtr(tokenInformation, 0);
 0101                return new SecurityIdentifier(sidPtr);
 102            }
 103        }
 104
 105        // Shortcut for when you only need to a token to query information.
 106        // See https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentproc
 0107        private static IntPtr GetCurrentProcessToken() => (IntPtr)(-4);
 108    }
 109}