private bool PromptForCredentialsCredUIWin(IntPtr owner, bool storedCredentials)
{
if (AllowStoredCredentials)
{
var credentials = ReadCredential(Target);
if (credentials != null)
{
UserName = credentials.UserName;
Password = credentials.Password;
return(true);
}
}
if (!IsAuthenticationRequired)
{
return(false);
}
var info = CreateCredUIInfo(owner, false);
var flags = CredUi.CredUiWinFlags.Generic;
if (ShowSaveCheckBox)
{
flags |= CredUi.CredUiWinFlags.Checkbox;
}
var inBuffer = IntPtr.Zero;
var outBuffer = IntPtr.Zero;
try
{
uint inBufferSize = 0;
if (UserName.Length > 0)
{
CredUi.CredPackAuthenticationBuffer(0, UserName, Password, IntPtr.Zero, ref inBufferSize);
if (inBufferSize > 0)
{
inBuffer = Marshal.AllocCoTaskMem((int)inBufferSize);
if (!CredUi.CredPackAuthenticationBuffer(0, UserName, Password, inBuffer, ref inBufferSize))
{
throw new CredentialException(Marshal.GetLastWin32Error());
}
}
}
uint outBufferSize = 0;
uint package = 0;
var result = CredUi.CredUIPromptForWindowsCredentials(ref info, 0, ref package, inBuffer, inBufferSize,
out outBuffer, out outBufferSize, ref _isSaveChecked, flags);
switch (result)
{
case CredUi.CredUiReturnCodes.NO_ERROR:
var userName = new StringBuilder(CredUi.CREDUI_MAX_USERNAME_LENGTH);
var password = new StringBuilder(CredUi.CREDUI_MAX_PASSWORD_LENGTH);
var userNameSize = (uint)userName.Capacity;
var passwordSize = (uint)password.Capacity;
uint domainSize = 0;
if (!CredUi.CredUnPackAuthenticationBuffer(0, outBuffer, outBufferSize, userName, ref userNameSize, null, ref domainSize, password, ref passwordSize))
{
throw new CredentialException(Marshal.GetLastWin32Error());
}
UserName = userName.ToString();
Password = password.ToString();
if (ShowSaveCheckBox)
{
_confirmTarget = Target;
// If the NativeCredential was stored previously but the user has now cleared the save checkbox,
// we want to delete the NativeCredential.
if (storedCredentials && !IsSaveChecked)
{
DeleteCredential(Target);
}
if (IsSaveChecked)
{
WriteCredential(Target, UserName, Password);
}
}
return(true);
case CredUi.CredUiReturnCodes.ERROR_CANCELLED:
return(false);
default:
throw new CredentialException((int)result);
}
}
finally
{
if (inBuffer != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(inBuffer);
}
if (outBuffer != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(outBuffer);
}
}
}