private static IReadOnlyCollection <Credential> Enumerate(string filter, CredEnumerateFlags flags = 0x0) { List <Credential> Results = new List <Credential>(); UInt32 Count = 0; IntPtr Credentials = IntPtr.Zero; bool Success = CredEnumerate(filter, (UInt32)flags, out Count, out Credentials); if (Success) { for (int i = 0; i < Count; i++) { IntPtr CredPtr = Marshal.ReadIntPtr(Credentials, i * Marshal.SizeOf <IntPtr>()); CREDENTIAL Cred = Marshal.PtrToStructure <CREDENTIAL>(CredPtr); Results.Add(Credential.FromWin32Credential(Cred)); } CredFree(Credentials); return(Results); } else { ThrowLastWin32Error(); return(null); } }
/// <summary> /// Creates a Win32 CREDENTIAL object from this object for writing to Credential Manager /// </summary> /// <returns></returns> internal CREDENTIAL ToWin32Credential() { CREDENTIAL NewCred = new CREDENTIAL(); if (this.Attributes == null || this.Attributes.Length == 0) { NewCred.Attributes = IntPtr.Zero; NewCred.AttributeCount = 0; } else { // This won't get called, since in this version, the attributes property can't be set NewCred.Attributes = Marshal.AllocHGlobal(Marshal.SizeOf(this.Attributes)); Marshal.StructureToPtr(this.Attributes, NewCred.Attributes, false); NewCred.AttributeCount = (UInt32)this.Attributes.Length; } NewCred.Comment = Marshal.StringToHGlobalUni(this.Comment); NewCred.TargetAlias = Marshal.StringToHGlobalUni(this.TargetAlias); NewCred.Type = this.Type; NewCred.Persist = this.Persist; NewCred.TargetName = Marshal.StringToHGlobalUni(this.TargetName); NewCred.CredentialBlob = Marshal.StringToHGlobalUni(this.CredentialBlob); NewCred.CredentialBlobSize = (UInt32)Encoding.Unicode.GetByteCount(this.CredentialBlob); NewCred.UserName = Marshal.StringToHGlobalUni(this.UserName); NewCred.Flags = this.Flags; return(NewCred); }
/// <summary> /// Reads a credential from the Credential Manager Password Vault /// </summary> /// <param name="target">The credential target</param> /// <param name="type">The credential type</param> /// <returns>The stored credential object</returns> public static Credential Read(string target, CredentialType type = CredentialType.CRED_TYPE_GENERIC) { IntPtr CredentialPtr; bool Success = CredRead(target, type, 0, out CredentialPtr); if (Success) { CREDENTIAL cred = Marshal.PtrToStructure <CREDENTIAL>(CredentialPtr); Credential NewCred = Credential.FromWin32Credential(cred); CredFree(CredentialPtr); return(NewCred); } else { ThrowLastWin32Error(); } return(null); }
/// <summary> /// Writes a credential to the Credential Manager Password Vault /// </summary> /// <param name="credential">The credential to store</param> /// <param name="flags">Write flags</param> public static void Write(Credential credential, CredWriteFlags flags = 0x0) { CREDENTIAL NewCred = credential.ToWin32Credential(); try { bool Success = CredWrite(ref NewCred, (UInt32)flags); if (!Success) { int Err = Marshal.GetLastWin32Error(); ThrowLastWin32Error(); } } finally { Marshal.FreeHGlobal(NewCred.TargetName); Marshal.FreeHGlobal(NewCred.CredentialBlob); Marshal.FreeHGlobal(NewCred.UserName); Marshal.FreeHGlobal(NewCred.Comment); Marshal.FreeHGlobal(NewCred.TargetAlias); Marshal.FreeHGlobal(NewCred.Attributes); } }
/// <summary> /// Creates a credential object from a marshaled Win32 CREDENTIAL object /// </summary> /// <param name="credential">The credential object to convert</param> /// <returns></returns> internal static Credential FromWin32Credential(CREDENTIAL credential) { string Target = Marshal.PtrToStringUni(credential.TargetName); string UserName = Marshal.PtrToStringUni(credential.UserName); string Secret = null; if (credential.CredentialBlob != IntPtr.Zero) { Secret = Marshal.PtrToStringUni(credential.CredentialBlob, (int)credential.CredentialBlobSize / 2); } Credential NewCred = new Credential(UserName, Secret, Target) { Comment = Marshal.PtrToStringUni(credential.Comment), Flags = credential.Flags, LastWritten = ToDateTime(credential.LastWritten), Persist = credential.Persist, TargetAlias = Marshal.PtrToStringUni(credential.TargetAlias), Type = credential.Type }; /* This isn't supported yet since the CREDENTIAL_ATTRIBUTE struct isn't necessarily a constant size * if (credential.Attributes != IntPtr.Zero) * { * NewCred.Attributes = new CREDENTIAL_ATTRIBUTE[credential.AttributeCount]; * * for (int i = 0; i < credential.AttributeCount; i++) * { * NewCred.Attributes[i] = Marshal.PtrToStructure<CREDENTIAL_ATTRIBUTE>(new IntPtr(credential.Attributes.ToInt64() + i * Marshal.SizeOf<CREDENTIAL_ATTRIBUTE>())); * } * } */ return(NewCred); }
private static extern bool CredWrite([In] ref CREDENTIAL credential, [In] UInt32 flags);