[DllImport("Advapi32.dll", SetLastError=true, EntryPoint="CredWriteW", CharSet=CharSet.Unicode)]
static extern bool CredWrite([In] Credential userCredential, [In] UInt32 flags);
Declare Function CredWrite Lib "advapi32.dll" (TODO) As TODO
enum CRED_TYPE : uint
{
CRED_TYPE_GENERIC = 1,
CRED_TYPE_DOMAIN_PASSWORD = 2,
CRED_TYPE_DOMAIN_CERTIFICATE = 3,
CRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 4
}
enum CRED_PERSIST : uint
{
CRED_PERSIST_SESSION = 1,
CRED_PERSIST_LOCAL_MACHINE = 2,
CRED_PERSIST_ENTERPRISE = 3
}
[StructLayout(LayoutKind.Sequential)]
private struct Credential
{
public UInt32 flags;
public UInt32 type;
public string targetName;
public string comment;
//public System.Runtime.InteropServices.FILETIME lastWritten; // .NET 1.1
public System.Runtime.InteropServices.ComTypes.FILETIME lastWritten; // .NET 2.0
public UInt32 credentialBlobSize;
public IntPtr credentialBlob;
public UInt32 persist;
public UInt32 attributeCount;
public IntPtr credAttribute;
public string targetAlias;
public string userName;
}
If it's legal for PInvoke.net to swipe Microsoft's own code, the stuff here is even better:
http://blogs.msdn.com/peerchan/pages/487834.aspx
Needs extensive custom marshaling code. See CredRead to for an example on the custom marshaling code.
internal static void AddDomainUserCredential(string target, string userName, string password)
{
Credential userCredential = new Credential();
userCredential.targetName = target;
userCredential.type = (UInt32)CRED_TYPE.CRED_TYPE_DOMAIN_PASSWORD;
userCredential.userName = userName;
userCredential.attributeCount = 0;
userCredential.persist = (UInt32)CRED_PERSIST.CRED_PERSIST_ENTERPRISE;
byte[] bpassword = Encoding.Unicode.GetBytes(password);
userCredential.credentialBlobSize = (UInt32)bpassword.Length;
userCredential.credentialBlob = Marshal.StringToCoTaskMemUni(password);
if (!Unmanaged.CredWrite(ref userCredential, 0))
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
}
}
Do you know one? Please contribute it!