diff --git a/src/Ookii.Dialogs.WinForms/CredentialDialog.cs b/src/Ookii.Dialogs.WinForms/CredentialDialog.cs
index 1874623..c328a47 100644
--- a/src/Ookii.Dialogs.WinForms/CredentialDialog.cs
+++ b/src/Ookii.Dialogs.WinForms/CredentialDialog.cs
@@ -50,6 +50,12 @@ namespace Ookii.Dialogs.WinForms
[DefaultProperty("MainInstruction"), DefaultEvent("UserNameChanged"), Description("Allows access to credential UI for generic credentials.")]
public partial class CredentialDialog : Component
{
+ ///
+ /// The logon attempt failed
+ ///
+ /// A possible value for the authError parameter. Imported from WinError.h.
+ public const int SEC_E_LOGON_DENIED = unchecked((int)0x8009030C);
+
private string _confirmTarget;
private NetworkCredential _credentials = new NetworkCredential();
private bool _isSaveChecked;
@@ -381,10 +387,10 @@ public string Content
///
public bool IsStoredCredential { get; private set; }
-
///
/// Shows the credentials dialog as a modal dialog.
///
+ /// An optionally provided Windows error specifying why the credential dialog box is needed, for example .
/// if the user clicked OK; otherwise, .
///
///
@@ -417,15 +423,16 @@ public string Content
/// An error occurred while showing the credentials dialog.
/// is an empty string ("").
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public DialogResult ShowDialog()
+ public DialogResult ShowDialog(int authError = 0)
{
- return ShowDialog(null);
+ return ShowDialog(null, authError);
}
///
/// Shows the credentials dialog as a modal dialog with the specified owner.
///
/// The Win32 handle that owns the credentials dialog.
+ /// An optionally provided Windows error specifying why the credential dialog box is needed, for example .
/// if the user clicked OK; otherwise, .
///
///
@@ -458,7 +465,7 @@ public DialogResult ShowDialog()
/// An error occurred while showing the credentials dialog.
/// is an empty string ("").
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public DialogResult ShowDialog(IntPtr owner)
+ public DialogResult ShowDialog(IntPtr owner, int authError = 0)
{
if( string.IsNullOrEmpty(_target) )
throw new InvalidOperationException(Properties.Resources.CredentialEmptyTargetError);
@@ -490,9 +497,9 @@ public DialogResult ShowDialog(IntPtr owner)
IntPtr ownerHandle = owner == IntPtr.Zero ? NativeMethods.GetActiveWindow() : owner;
bool result;
if( NativeMethods.IsWindowsVistaOrLater )
- result = PromptForCredentialsCredUIWin(ownerHandle, storedCredentials);
+ result = PromptForCredentialsCredUIWin(ownerHandle, storedCredentials, authError);
else
- result = PromptForCredentialsCredUI(ownerHandle, storedCredentials);
+ result = PromptForCredentialsCredUI(ownerHandle, storedCredentials, authError);
return result ? DialogResult.OK : DialogResult.Cancel;
}
@@ -500,6 +507,7 @@ public DialogResult ShowDialog(IntPtr owner)
/// Shows the credentials dialog as a modal dialog with the specified owner.
///
/// The that owns the credentials dialog.
+ /// An optionally provided Windows error specifying why the credential dialog box is needed, for example .
/// if the user clicked OK; otherwise, .
///
///
@@ -532,14 +540,14 @@ public DialogResult ShowDialog(IntPtr owner)
/// An error occurred while showing the credentials dialog.
/// is an empty string ("").
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public DialogResult ShowDialog(IWin32Window owner)
+ public DialogResult ShowDialog(IWin32Window owner, int authError = 0)
{
IntPtr ownerHandle;
if( owner == null )
ownerHandle = NativeMethods.GetActiveWindow();
else
ownerHandle = owner.Handle;
- return ShowDialog(ownerHandle);
+ return ShowDialog(ownerHandle, authError);
}
///
@@ -786,7 +794,7 @@ protected virtual void OnPasswordChanged(EventArgs e)
PasswordChanged(this, e);
}
- private bool PromptForCredentialsCredUI(IntPtr owner, bool storedCredentials)
+ private bool PromptForCredentialsCredUI(IntPtr owner, bool storedCredentials, int authError)
{
NativeMethods.CREDUI_INFO info = CreateCredUIInfo(owner, true);
NativeMethods.CREDUI_FLAGS flags = NativeMethods.CREDUI_FLAGS.GENERIC_CREDENTIALS | NativeMethods.CREDUI_FLAGS.DO_NOT_PERSIST | NativeMethods.CREDUI_FLAGS.ALWAYS_SHOW_UI;
@@ -798,7 +806,7 @@ private bool PromptForCredentialsCredUI(IntPtr owner, bool storedCredentials)
StringBuilder pw = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH);
pw.Append(Password);
- NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForCredentials(ref info, Target, IntPtr.Zero, 0, user, NativeMethods.CREDUI_MAX_USERNAME_LENGTH, pw, NativeMethods.CREDUI_MAX_PASSWORD_LENGTH, ref _isSaveChecked, flags);
+ NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForCredentials(ref info, Target, IntPtr.Zero, authError, user, NativeMethods.CREDUI_MAX_USERNAME_LENGTH, pw, NativeMethods.CREDUI_MAX_PASSWORD_LENGTH, ref _isSaveChecked, flags);
switch( result )
{
case NativeMethods.CredUIReturnCodes.NO_ERROR:
@@ -820,7 +828,7 @@ private bool PromptForCredentialsCredUI(IntPtr owner, bool storedCredentials)
}
}
- private bool PromptForCredentialsCredUIWin(IntPtr owner, bool storedCredentials)
+ private bool PromptForCredentialsCredUIWin(IntPtr owner, bool storedCredentials, int authError)
{
NativeMethods.CREDUI_INFO info = CreateCredUIInfo(owner, false);
NativeMethods.CredUIWinFlags flags = NativeMethods.CredUIWinFlags.Generic;
@@ -845,7 +853,7 @@ private bool PromptForCredentialsCredUIWin(IntPtr owner, bool storedCredentials)
uint outBufferSize;
uint package = 0;
- NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForWindowsCredentials(ref info, 0, ref package, inBuffer, inBufferSize, out outBuffer, out outBufferSize, ref _isSaveChecked, flags);
+ NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForWindowsCredentials(ref info, authError, ref package, inBuffer, inBufferSize, out outBuffer, out outBufferSize, ref _isSaveChecked, flags);
switch( result )
{
case NativeMethods.CredUIReturnCodes.NO_ERROR: