private static object MarshalNativeToManaged(IntPtr nativeDataPtr) { if (nativeDataPtr == IntPtr.Zero) { return(null); } WindowsCredentialTypes.NativeCredential rawCredential = (WindowsCredentialTypes.NativeCredential)Marshal.PtrToStructure(nativeDataPtr, typeof(WindowsCredentialTypes.NativeCredential)); WindowsCredentialTypes.Credential cred = new WindowsCredentialTypes.Credential() { UserName = Marshal.PtrToStringUni(rawCredential.UserName), TargetName = Marshal.PtrToStringUni(rawCredential.TargetName), TargetAlias = Marshal.PtrToStringUni(rawCredential.TargetAlias), Persist = (WindowsCredentialTypes.CredentialPersist)rawCredential.Persist, Comment = Marshal.PtrToStringUni(rawCredential.Comment), Flags = rawCredential.Flags, LastWritten = rawCredential.LastWritten, Type = rawCredential.Type, CredentialBlob = Marshal.PtrToStringUni(rawCredential.CredentialBlob), CredentialBlobSize = rawCredential.CredentialBlobSize, Attributes = new WindowsCredentialTypes.CredentialAttribute[rawCredential.AttributeCount], AttributeCount = rawCredential.AttributeCount }; // ToDo: Fill the Attributes array with values. It is not important because the information is not needed and the complexity to marshal this data is quite high. CredFree(nativeDataPtr); return(cred); }
/// <summary> /// This method derives a NativeCredential instance from a given Credential instance. /// </summary> /// <param name="cred">The managed Credential counterpart containing data to be stored.</param> /// <returns>A NativeCredential instance that is derived from the given Credential /// instance.</returns> private static WindowsCredentialTypes.NativeCredential GetNativeCredential(WindowsCredentialTypes.Credential cred) { WindowsCredentialTypes.NativeCredential ncred = new WindowsCredentialTypes.NativeCredential(); ncred.AttributeCount = 0; ncred.Attributes = IntPtr.Zero; ncred.Comment = IntPtr.Zero; ncred.TargetAlias = IntPtr.Zero; ncred.Type = (WindowsCredentialTypes.CredentialType)cred.Type; ncred.Persist = (UInt32)cred.Persist; ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize; ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName); ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob); ncred.UserName = Marshal.StringToCoTaskMemUni(cred.UserName); return(ncred); }
public bool Add(string targetName, string userName, string password, WindowsCredentialTypes.CredentialType type, WindowsCredentialTypes.CredentialPersist persist) { // Check if the password is not too long. byte[] byteArray = Encoding.Unicode.GetBytes(password); if (byteArray.Length > 512) { throw new ArgumentOutOfRangeException("The password has exceeded 512 bytes."); } WindowsCredentialTypes.Credential cred = new WindowsCredentialTypes.Credential() { UserName = userName, TargetName = targetName, TargetAlias = null, Persist = persist, Comment = null, Flags = 0, Type = type, CredentialBlob = password, CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(password).Length, Attributes = null, AttributeCount = 0 }; WindowsCredentialTypes.NativeCredential ncred = GetNativeCredential(cred); // Write the info into the CredMan storage. bool written = CredWrite(ref ncred, 0); int lastError = Marshal.GetLastWin32Error(); Marshal.FreeCoTaskMem(ncred.TargetName); Marshal.FreeCoTaskMem(ncred.CredentialBlob); Marshal.FreeCoTaskMem(ncred.UserName); if (written) { return(true); } else { string message = string.Format("CredWrite failed with the error code {0}.", lastError); throw new Exception(message); } }
static extern bool CredWrite(ref WindowsCredentialTypes.NativeCredential userCredential, UInt32 flags);