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: