< Summary

Class:Azure.Identity.WindowsNativeMethods
Assembly:Azure.Identity
File(s):C:\Git\azure-sdk-for-net\sdk\identity\Azure.Identity\src\WindowsNativeMethods.cs
Covered lines:9
Uncovered lines:17
Coverable lines:26
Total lines:139
Line coverage:34.6% (9 of 26)
Covered branches:3
Total branches:12
Branch coverage:25% (3 of 12)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
CredRead(...)-100%100%
CredWrite(...)-100%100%
CredDelete(...)-100%100%
CredFree(...)-100%100%
ThrowIfFailed(...)-40%25%
MessageFromErrorCode(...)-0%0%

File(s)

C:\Git\azure-sdk-for-net\sdk\identity\Azure.Identity\src\WindowsNativeMethods.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.ComponentModel;
 6using System.Runtime.CompilerServices;
 7using System.Runtime.InteropServices;
 8
 9namespace Azure.Identity
 10{
 11    internal static class WindowsNativeMethods
 12    {
 13        public enum CRED_PERSIST : uint
 14        {
 15            CRED_PERSIST_SESSION = 1,
 16            CRED_PERSIST_LOCAL_MACHINE = 2,
 17            CRED_PERSIST_ENTERPRISE = 3
 18        }
 19
 20        public enum CRED_TYPE
 21        {
 22            GENERIC = 1,
 23            DOMAIN_PASSWORD = 2,
 24            DOMAIN_CERTIFICATE = 3,
 25            DOMAIN_VISIBLE_PASSWORD = 4,
 26            MAXIMUM = 5
 27        }
 28
 29        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
 30        public struct CredentialData
 31        {
 32            public uint Flags;
 33            public CRED_TYPE Type;
 34            public string TargetName;
 35            public string Comment;
 36            public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
 37            public uint CredentialBlobSize;
 38            public IntPtr CredentialBlob;
 39            public CRED_PERSIST Persist;
 40            public uint AttributeCount;
 41            public IntPtr Attributes;
 42            public string TargetAlias;
 43            public string UserName;
 44        }
 45
 46        public const int ERROR_NOT_FOUND = 1168;
 47
 48        public const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
 49        public const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
 50        public const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
 51
 52        public static IntPtr CredRead(string target, CRED_TYPE type)
 53        {
 4854            ThrowIfFailed(Imports.CredRead(target, type, 0, out IntPtr userCredential));
 4855            return userCredential;
 56        }
 57
 1658        public static void CredWrite(IntPtr userCredential) => ThrowIfFailed(Imports.CredWrite(userCredential, 0));
 59
 1660        public static void CredDelete(string target, CRED_TYPE type) => ThrowIfFailed(Imports.CredDelete(target, type, 0
 61
 62        public static void CredFree(IntPtr userCredential)
 63        {
 4864            if (userCredential != IntPtr.Zero)
 65            {
 4866                Imports.CredFree(userCredential);
 67            }
 4868        }
 69
 70        private static void ThrowIfFailed(bool isSucceeded, [CallerMemberName] string methodName = default)
 71        {
 8072            if (isSucceeded)
 73            {
 8074                return;
 75            }
 76
 077            var error = Marshal.GetLastWin32Error();
 078            var message = error == ERROR_NOT_FOUND ? $"{methodName} has failed but error is unknown." : MessageFromError
 079            throw new InvalidOperationException(message);
 80        }
 81
 82        private static string MessageFromErrorCode(int errorCode)
 83        {
 84            // Twy Win32 first
 085            uint flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
 86
 087            IntPtr messageBuffer = IntPtr.Zero;
 088            string message = null;
 89
 90            try
 91            {
 092                var length = Imports.FormatMessage(flags, IntPtr.Zero, errorCode, 0, ref messageBuffer, 0, IntPtr.Zero);
 093                if (length == 0)
 94                {
 95                    // If failed, try to convert NTSTATUS to Win32 error
 096                    int code = Imports.RtlNtStatusToDosError(errorCode);
 097                    return new Win32Exception(code).Message;
 98                }
 099            }
 100            finally
 101            {
 0102                if (messageBuffer != IntPtr.Zero)
 103                {
 0104                    message = Marshal.PtrToStringUni(messageBuffer);
 0105                    Marshal.FreeHGlobal(messageBuffer);
 106                }
 0107            }
 108
 0109            return message ?? string.Empty;
 0110        }
 111
 112        private static class Imports
 113        {
 114            [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
 115            [DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
 116            public static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, int dwMessageId, uint dwLanguageId, r
 117
 118            [DllImport("ntdll.dll")]
 119            [DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
 120            public static extern int RtlNtStatusToDosError(int Status);
 121
 122            [DllImport("advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
 123            [DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
 124            public static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr userCredentia
 125
 126            [DllImport("advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
 127            [DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
 128            public static extern bool CredWrite(IntPtr userCredential, int reservedFlag);
 129
 130            [DllImport("advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode, SetLastError = true)]
 131            [DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
 132            public static extern bool CredDelete(string target, CRED_TYPE type, int reservedFlag);
 133
 134            [DllImport("advapi32.dll", SetLastError = true)]
 135            [DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
 136            public static extern void CredFree([In] IntPtr buffer);
 137        }
 138    }
 139}