mirror of
https://github.com/ZuneDev/ZuneShell.dll.git
synced 2026-07-27 13:11:51 -07:00
Added Meziantou.Framework.Win32.CredentialManager fork
This commit is contained in:
+23
-4
@@ -18,6 +18,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UIX.Debug", "libs\Microsoft
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZuneImpl", "ZuneImpl\ZuneImpl.csproj", "{0B309776-6424-48C4-838A-224E41F793EE}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZuneImpl", "ZuneImpl\ZuneImpl.csproj", "{0B309776-6424-48C4-838A-224E41F793EE}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Meziantou.Framework.Win32.CredentialManager", "libs\Meziantou.Framework.Win32.CredentialManager\Meziantou.Framework.Win32.CredentialManager.csproj", "{90A89707-927E-48D2-BFEB-84F95F531258}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -126,10 +128,10 @@ Global
|
|||||||
{8479F68C-4234-425E-93E7-71597AF528E9}.Release|x64.Build.0 = Release|Any CPU
|
{8479F68C-4234-425E-93E7-71597AF528E9}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{8479F68C-4234-425E-93E7-71597AF528E9}.Release|x86.ActiveCfg = Release|Any CPU
|
{8479F68C-4234-425E-93E7-71597AF528E9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{8479F68C-4234-425E-93E7-71597AF528E9}.Release|x86.Build.0 = Release|Any CPU
|
{8479F68C-4234-425E-93E7-71597AF528E9}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|Any CPU.ActiveCfg = Debug|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|Any CPU.Build.0 = Debug|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|ARM32.ActiveCfg = Debug|Any CPU
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|ARM32.ActiveCfg = Debug|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|ARM32.Build.0 = Debug|Any CPU
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|ARM32.Build.0 = Debug|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|x64.ActiveCfg = Debug|x64
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|x64.Build.0 = Debug|x64
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|x64.Build.0 = Debug|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|x86.ActiveCfg = Debug|x86
|
{0B309776-6424-48C4-838A-224E41F793EE}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
@@ -142,6 +144,22 @@ Global
|
|||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Release|x64.Build.0 = Release|x64
|
{0B309776-6424-48C4-838A-224E41F793EE}.Release|x64.Build.0 = Release|x64
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Release|x86.ActiveCfg = Release|Any CPU
|
{0B309776-6424-48C4-838A-224E41F793EE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{0B309776-6424-48C4-838A-224E41F793EE}.Release|x86.Build.0 = Release|Any CPU
|
{0B309776-6424-48C4-838A-224E41F793EE}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|ARM32.ActiveCfg = Debug|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|ARM32.Build.0 = Debug|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|ARM32.ActiveCfg = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|ARM32.Build.0 = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -150,6 +168,7 @@ Global
|
|||||||
{78A8B08C-C0E9-4BAC-9AF6-58D3A55C05C9} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
{78A8B08C-C0E9-4BAC-9AF6-58D3A55C05C9} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
||||||
{CB2B7609-C7B8-4E2A-82D8-DD631B70B621} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
{CB2B7609-C7B8-4E2A-82D8-DD631B70B621} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
||||||
{8479F68C-4234-425E-93E7-71597AF528E9} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
{8479F68C-4234-425E-93E7-71597AF528E9} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
||||||
|
{90A89707-927E-48D2-BFEB-84F95F531258} = {7640D6FE-600E-44BE-A59F-E90602FA7754}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {6B948258-B457-4B3D-955E-05ED3F03CF36}
|
SolutionGuid = {6B948258-B457-4B3D-955E-05ED3F03CF36}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace Meziantou.Framework.Win32
|
||||||
|
{
|
||||||
|
public class Credential
|
||||||
|
{
|
||||||
|
public CredentialType CredentialType { get; }
|
||||||
|
public string ApplicationName { get; }
|
||||||
|
public string UserName { get; }
|
||||||
|
public string Password { get; }
|
||||||
|
public string Comment { get; }
|
||||||
|
|
||||||
|
public Credential(CredentialType credentialType, string applicationName, string userName, string password, string comment)
|
||||||
|
{
|
||||||
|
ApplicationName = applicationName;
|
||||||
|
UserName = userName;
|
||||||
|
Password = password;
|
||||||
|
CredentialType = credentialType;
|
||||||
|
Comment = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"CredentialType: {CredentialType}, ApplicationName: {ApplicationName}, UserName: {UserName}, Password: {Password}, Comment: {Comment}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using Meziantou.Framework.Win32.Natives;
|
||||||
|
|
||||||
|
namespace Meziantou.Framework.Win32
|
||||||
|
{
|
||||||
|
public static class CredentialManager
|
||||||
|
{
|
||||||
|
public static Credential ReadCredential(string applicationName)
|
||||||
|
{
|
||||||
|
var read = Advapi32.CredRead(applicationName, CredentialType.Generic, 0, out var nCredPtr);
|
||||||
|
if (read)
|
||||||
|
{
|
||||||
|
using (var critCred = new CriticalCredentialHandle(nCredPtr))
|
||||||
|
{
|
||||||
|
var cred = critCred.GetCredential();
|
||||||
|
return ReadCredential(cred);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Credential ReadCredential(CREDENTIAL credential)
|
||||||
|
{
|
||||||
|
var applicationName = Marshal.PtrToStringUni(credential.TargetName);
|
||||||
|
var userName = Marshal.PtrToStringUni(credential.UserName);
|
||||||
|
string secret = null;
|
||||||
|
if (credential.CredentialBlob != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
secret = Marshal.PtrToStringUni(credential.CredentialBlob, (int)credential.CredentialBlobSize / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
string comment = null;
|
||||||
|
if (credential.Comment != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
comment = Marshal.PtrToStringUni(credential.Comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Credential(credential.Type, applicationName, userName, secret, comment);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteCredential(string applicationName, string userName, string secret, CredentialPersistence persistence)
|
||||||
|
{
|
||||||
|
WriteCredential(applicationName, userName, secret, null, persistence);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteCredential(string applicationName, string userName, string secret, string comment, CredentialPersistence persistence)
|
||||||
|
{
|
||||||
|
if (applicationName == null)
|
||||||
|
throw new ArgumentNullException(nameof(applicationName));
|
||||||
|
|
||||||
|
if (userName == null)
|
||||||
|
throw new ArgumentNullException(nameof(userName));
|
||||||
|
|
||||||
|
if (secret == null)
|
||||||
|
throw new ArgumentNullException(nameof(secret));
|
||||||
|
|
||||||
|
// CRED_MAX_CREDENTIAL_BLOB_SIZE
|
||||||
|
// XP and Vista: 512;
|
||||||
|
// 7 and above: 5*512
|
||||||
|
var secretLength = secret.Length * UnicodeEncoding.CharSize;
|
||||||
|
if (Environment.OSVersion.Version < new Version(6, 1) /* Windows 7 */)
|
||||||
|
{
|
||||||
|
if (secretLength > 512)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(secret), "The secret message has exceeded 512 bytes.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (secretLength > 2560)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(secret), "The secret message has exceeded 2560 bytes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comment != null)
|
||||||
|
{
|
||||||
|
// CRED_MAX_STRING_LENGTH 256
|
||||||
|
if (comment.Length > 255)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(comment), "The comment message has exceeded 256 characters.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var commentPtr = IntPtr.Zero;
|
||||||
|
var targetNamePtr = IntPtr.Zero;
|
||||||
|
var credentialBlobPtr = IntPtr.Zero;
|
||||||
|
var userNamePtr = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
commentPtr = comment != null ? Marshal.StringToCoTaskMemUni(comment) : IntPtr.Zero;
|
||||||
|
targetNamePtr = Marshal.StringToCoTaskMemUni(applicationName);
|
||||||
|
credentialBlobPtr = Marshal.StringToCoTaskMemUni(secret);
|
||||||
|
userNamePtr = Marshal.StringToCoTaskMemUni(userName);
|
||||||
|
|
||||||
|
var credential = new CREDENTIAL
|
||||||
|
{
|
||||||
|
AttributeCount = 0,
|
||||||
|
Attributes = IntPtr.Zero,
|
||||||
|
Comment = commentPtr,
|
||||||
|
TargetAlias = IntPtr.Zero,
|
||||||
|
Type = CredentialType.Generic,
|
||||||
|
Persist = persistence,
|
||||||
|
CredentialBlobSize = (uint)secretLength,
|
||||||
|
TargetName = targetNamePtr,
|
||||||
|
CredentialBlob = credentialBlobPtr,
|
||||||
|
UserName = userNamePtr
|
||||||
|
};
|
||||||
|
|
||||||
|
var written = Advapi32.CredWrite(ref credential, 0);
|
||||||
|
var lastError = Marshal.GetLastWin32Error();
|
||||||
|
if (!written)
|
||||||
|
throw new Win32Exception(lastError, $"CredWrite failed with the error code {lastError}.");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
FreeCoTaskMem(commentPtr);
|
||||||
|
FreeCoTaskMem(targetNamePtr);
|
||||||
|
FreeCoTaskMem(credentialBlobPtr);
|
||||||
|
FreeCoTaskMem(userNamePtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteCredential(string applicationName)
|
||||||
|
{
|
||||||
|
if (applicationName == null)
|
||||||
|
throw new ArgumentNullException(nameof(applicationName));
|
||||||
|
|
||||||
|
var success = Advapi32.CredDelete(applicationName, CredentialType.Generic, 0);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
var lastError = Marshal.GetLastWin32Error();
|
||||||
|
throw new Win32Exception(lastError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IReadOnlyList<Credential> EnumerateCrendentials()
|
||||||
|
{
|
||||||
|
return EnumerateCrendentials(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IReadOnlyList<Credential> EnumerateCrendentials(string filter)
|
||||||
|
{
|
||||||
|
var result = new List<Credential>();
|
||||||
|
var ret = Advapi32.CredEnumerate(filter, 0, out var count, out var pCredentials);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
for (var n = 0; n < count; n++)
|
||||||
|
{
|
||||||
|
var credential = Marshal.ReadIntPtr(pCredentials, n * Marshal.SizeOf<IntPtr>());
|
||||||
|
result.Add(ReadCredential(Marshal.PtrToStructure<CREDENTIAL>(credential)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var lastError = Marshal.GetLastWin32Error();
|
||||||
|
throw new Win32Exception(lastError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Advapi32.CredFree(pCredentials);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FreeCoTaskMem(IntPtr ptr)
|
||||||
|
{
|
||||||
|
if (ptr == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Marshal.FreeCoTaskMem(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace Meziantou.Framework.Win32
|
||||||
|
{
|
||||||
|
public enum CredentialPersistence : uint
|
||||||
|
{
|
||||||
|
Session = 1,
|
||||||
|
LocalMachine,
|
||||||
|
Enterprise
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Meziantou.Framework.Win32
|
||||||
|
{
|
||||||
|
public enum CredentialType
|
||||||
|
{
|
||||||
|
Generic = 1,
|
||||||
|
DomainPassword,
|
||||||
|
DomainCertificate,
|
||||||
|
DomainVisiblePassword,
|
||||||
|
GenericCertificate,
|
||||||
|
DomainExtended,
|
||||||
|
Maximum,
|
||||||
|
MaximumEx = Maximum + 1000,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Meziantou.Framework.Win32.Natives;
|
||||||
|
|
||||||
|
namespace Meziantou.Framework.Win32
|
||||||
|
{
|
||||||
|
internal sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid
|
||||||
|
{
|
||||||
|
public CriticalCredentialHandle(IntPtr preexistingHandle)
|
||||||
|
{
|
||||||
|
SetHandle(preexistingHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CREDENTIAL GetCredential()
|
||||||
|
{
|
||||||
|
if (!IsInvalid)
|
||||||
|
{
|
||||||
|
return Marshal.PtrToStructure<CREDENTIAL>(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Invalid CriticalHandle!");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
if (!IsInvalid)
|
||||||
|
{
|
||||||
|
Advapi32.CredFree(handle);
|
||||||
|
SetHandleAsInvalid();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Meziantou.Framework.Win32
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Original code: https://github.com/dotnet/corefx/blob/d0dc5fc099946adc1035b34a8b1f6042eddb0c75/src/Common/src/Microsoft/Win32/SafeHandles/CriticalHandleZeroOrMinusOneIsInvalid.cs
|
||||||
|
/// </summary>
|
||||||
|
internal abstract class CriticalHandleZeroOrMinusOneIsInvalid : CriticalHandle
|
||||||
|
{
|
||||||
|
protected CriticalHandleZeroOrMinusOneIsInvalid() : base(IntPtr.Zero)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsInvalid => handle == new IntPtr(0) || handle == new IntPtr(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
|
||||||
|
<Description>C# wrapper around CredWrite/CredRead/CredDelete functions to store and retrieve from Windows Credential Store</Description>
|
||||||
|
<RootNamespace>Meziantou.Framework.Win32</RootNamespace>
|
||||||
|
<Version>1.1.1</Version>
|
||||||
|
<Platforms>AnyCPU;x64;x86</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Meziantou.Framework.Win32.Natives
|
||||||
|
{
|
||||||
|
internal static class Advapi32
|
||||||
|
{
|
||||||
|
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
public static extern bool CredRead(string target, CredentialType type, int reservedFlag, out IntPtr credentialPtr);
|
||||||
|
|
||||||
|
[DllImport("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
public static extern bool CredDelete(string target, CredentialType type, int reservedFlag);
|
||||||
|
|
||||||
|
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
public static extern bool CredWrite([In] ref CREDENTIAL userCredential, [In] uint flags);
|
||||||
|
|
||||||
|
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
public static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr pCredentials);
|
||||||
|
|
||||||
|
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
|
||||||
|
public static extern bool CredFree([In] IntPtr cred);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Meziantou.Framework.Win32.Natives
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||||
|
internal struct CREDENTIAL
|
||||||
|
{
|
||||||
|
public uint Flags;
|
||||||
|
public CredentialType Type;
|
||||||
|
public IntPtr TargetName;
|
||||||
|
public IntPtr Comment;
|
||||||
|
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
|
||||||
|
public uint CredentialBlobSize;
|
||||||
|
public IntPtr CredentialBlob;
|
||||||
|
public CredentialPersistence Persist;
|
||||||
|
public uint AttributeCount;
|
||||||
|
public IntPtr Attributes;
|
||||||
|
public IntPtr TargetAlias;
|
||||||
|
public IntPtr UserName;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user