Hello, think I successfully made a managed wrapperclass to the Credential API functions mentioned here with a little help from there At least the Win32-Errorcodes returned from that functions are Zero or other but expected (i.e. 1168 from CredDelete if calling it twice) and the appropriate values are stored at the correct place in the registry (HKLM/Comm/Security/Credman/1..).
Now I am using the Webbrowser-Control embedded in a WindowsForm on a PPC to authenticate to a Website which uses NTLM-Authentication. I dont want to let a popupdialog appear in which the user has to enter his credentials. Instead I am giving the user the possibilities to store his credentials on the device which he has inputted in an Optiondialog-Form in the first place (intern calling CredWrite/CredUpdate).
But the PIE is given a damn about it what I do with the API, neither CredWrite, -Update or -Delete is actually working. So what am I missing here?
Sample code for CredWrite:
[DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int CredWrite([In]IntPtr pCred, [In]CREDWRITE_FLAGS dwflags);
public enum CREDWRITE_FLAGS : int
{
CRED_FLAG_FAIL_IF_EXISTING = 0x00000400
}
public struct CRED
{
public int dwVersion;
public CRED_TYPE dwType;
[MarshalAs(UnmanagedType.LPWStr)]
public string wszUser;
public int dwUserLen;
[MarshalAs(UnmanagedType.LPWStr)]
public string wszTarget;
public int dwTargetLen;
public IntPtr pBlob;
public int dwBlobSize;
public CRED_FLAGS dwFlags;
}
public enum CRED_TYPE
{
CRED_TYPE_NTLM = 0x00010002,
CRED_TYPE_KERBEROS = 0x00010004,
CRED_TYPE_PLAINTEXT_PASSWORD = 0x00010006,
CRED_TYPE_CERTIFICATE = 0x00010008,
CRED_TYPE_GENERIC = 0x0001000a,
CRED_TYPE_DOMAIN_PASSWORD = 0x00010001,
}
public enum CRED_FLAGS : int
{
CRED_FLAG_PERSIST = 0x00000001,
CRED_FLAG_DEFAULT = 0x00000002,
CRED_FLAG_SENSITIVE = 0x00000008,
CRED_FLAG_TRUSTED = 0x00000010
}
public static void WriteCredentials(string target, string userName, string password)
{
CRED cred = new CRED();
cred.dwVersion = 1;
cred.dwType = CRED_TYPE.CRED_TYPE_NTLM;
cred.wszTarget = target;
cred.dwTargetLen = target.Length + 1;
cred.wszUser = userName;
cred.dwUserLen = userName.Length + 1;
cred.dwBlobSize = (Encoding.Unicode.GetBytes(password).Length + 1) * 2;
//cred.pBlob = Marshal.StringToCoTaskMemUni(password); //<--not in CF
//cred.pBlob = Marshal2.StringToHGlobalUni(password); //<--from OpenNETCF, the same?
cred.pBlob = Marshal.StringToBSTR(password); //<--not sure of that, but tried the other one also
cred.dwFlags = CRED_FLAGS.CRED_FLAG_PERSIST | CRED_FLAGS.CRED_FLAG_SENSITIVE | CRED_FLAGS.CRED_FLAG_TRUSTED; //<-- results in 25 which is also used in creds read which are stored by the IE-UI-CredMan-dialog
IntPtr credPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cred));
Marshal.StructureToPtr(cred, credPtr, true);
int ret = -1;
ret = CredWrite(credPtr, CREDWRITE_FLAGS.CRED_FLAG_FAIL_IF_EXISTING); //returns zero, unless called twice with the same target/username-tuple.
Marshal.FreeHGlobal(credPtr);
}
BTW the so called "MS-Experts" are mentioning that PIE has its own cahing mechanism for creds, and thats why PIE is ignoring the changes on CredUpdate. But I doubt that this is 100% correct, cause when I call CredWrite on a device with no credentials at all, that PIE ignores them too (popups cred-inputdialog).
Can someone assist me in that?
Thnx