private bool PromptForCredentialsCredUI(IntPtr owner, bool storedCredentials)
        {
            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;
            if( ShowSaveCheckBox )
                flags |= NativeMethods.CREDUI_FLAGS.SHOW_SAVE_CHECK_BOX;

            StringBuilder user = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH);
            user.Append(UserName);
            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);
            switch( result )
            {
                case NativeMethods.CredUIReturnCodes.NO_ERROR:
                    UserName = user.ToString();
                    Password = pw.ToString();
                    if( ShowSaveCheckBox )
                    {
                        _confirmTarget = Target;
                        // If the credential was stored previously but the user has now cleared the save checkbox,
                        // we want to delete the credential.
                        if( storedCredentials && !IsSaveChecked )
                            DeleteCredential(Target);
                    }
                    return true;
                case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                    return false;
                default:
                    throw new CredentialException((int)result);
            }
        }
示例#2
0
 /// <summary>
 /// Confirms the credentials.
 /// </summary>
 /// <param name="storedCredentials">If set to <c>true</c> the credentials are stored in the credential manager.</param>
 public void ConfirmCredentials(bool storedCredentials)
 {
     NativeMethods.CredUIReturnCodes ret = NativeMethods.CredUIConfirmCredentials(this.Target, storedCredentials);
     if (ret != NativeMethods.CredUIReturnCodes.NO_ERROR && ret != NativeMethods.CredUIReturnCodes.ERROR_INVALID_PARAMETER)
     {
         throw new InvalidOperationException(string.Format("Unable to confirm credentials. Error: 0x{0:X}", ret));
     }
 }
示例#3
0
 /// <summary>
 /// Confirms the credentials.
 /// </summary>
 /// <param name="storedCredentials">If set to <c>true</c> the credentials are stored in the credential manager.</param>
 public void ConfirmCredentials(bool storedCredentials)
 {
     NativeMethods.CredUIReturnCodes ret = NativeMethods.CredUIConfirmCredentials(Target, storedCredentials);
     if (ret != NativeMethods.CredUIReturnCodes.Success && ret != NativeMethods.CredUIReturnCodes.InvalidParameter)
     {
         throw new InvalidOperationException($"Unable to confirm credentials. Error: 0x{ret:X}");
     }
 }
示例#4
0
        // Token: 0x06000AF5 RID: 2805 RVA: 0x000223F4 File Offset: 0x000205F4
        public override DialogResult ShowDialog(IntPtr owner)
        {
            base.CheckNotDisposed();
            NativeMethods.CREDUI_INFO credui_INFO    = this.CreateCREDUI_INFO(owner);
            StringBuilder             stringBuilder  = new StringBuilder(1000);
            StringBuilder             stringBuilder2 = new StringBuilder(1000);
            bool saveChecked = base.SaveChecked;

            if (string.IsNullOrEmpty(this.Target))
            {
                throw new InvalidOperationException("Target must always be specified.");
            }
            if (this.AlwaysShowUI && !this.GenericCredentials)
            {
                throw new InvalidOperationException("AlwaysShowUI must be specified with GenericCredentials property.");
            }
            NativeMethods.CredUIReturnCodes credUIReturnCodes = NativeMethods.CredUIPromptForCredentials(ref credui_INFO, this.Target, IntPtr.Zero, base.ErrorCode, stringBuilder, 513, stringBuilder2, 256, ref saveChecked, base.DialogFlags);
            if (credUIReturnCodes <= NativeMethods.CredUIReturnCodes.ERROR_INVALID_FLAGS)
            {
                if (credUIReturnCodes <= NativeMethods.CredUIReturnCodes.ERROR_INSUFFICIENT_BUFFER)
                {
                    if (credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_INVALID_PARAMETER && credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_INSUFFICIENT_BUFFER)
                    {
                        goto IL_105;
                    }
                }
                else if (credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_BAD_ARGUMENTS && credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_INVALID_FLAGS)
                {
                    goto IL_105;
                }
            }
            else if (credUIReturnCodes <= NativeMethods.CredUIReturnCodes.ERROR_CANCELLED)
            {
                if (credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_NOT_FOUND)
                {
                    if (credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_CANCELLED)
                    {
                        goto IL_105;
                    }
                    return(DialogResult.Cancel);
                }
            }
            else if (credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_NO_SUCH_LOGON_SESSION && credUIReturnCodes != NativeMethods.CredUIReturnCodes.ERROR_INVALID_ACCOUNT_NAME)
            {
                goto IL_105;
            }
            throw new InvalidOperationException("Invalid properties were specified.", new Win32Exception(Marshal.GetLastWin32Error()));
IL_105:
            base.Username = stringBuilder.ToString();
            base.Password = stringBuilder2.ToString();
            if (stringBuilder2.Length > 0)
            {
                stringBuilder2.Remove(0, stringBuilder2.Length);
            }
            return(DialogResult.OK);
        }
示例#5
0
        private static NativeMethods.CredUIReturnCodes CredUIPromptForCredentials(NativeMethods.CREDUI_INFO credUiInfo, ref bool pfSave, out string userName, out SecureString password)
        {
            StringBuilder stringBuilder  = new StringBuilder(CredentialHelper.MaxUserNameLength);
            StringBuilder stringBuilder2 = new StringBuilder(CredentialHelper.MaxPasswordLength);

            NativeMethods.CredUIReturnCodes credUIReturnCodes = NativeMethods.CredUIPromptForCredentials(ref credUiInfo, null, IntPtr.Zero, 0U, stringBuilder, stringBuilder.Capacity, stringBuilder2, stringBuilder2.Capacity, ref pfSave, 262338);
            userName = ((credUIReturnCodes == null) ? stringBuilder.ToString() : null);
            password = ((credUIReturnCodes == null) ? stringBuilder2.ToString().ConvertToSecureString() : null);
            return(credUIReturnCodes);
        }
示例#6
0
        public override DialogResult ShowDialog(IntPtr owner)
        {
            CheckNotDisposed();

            NativeMethods.CREDUI_INFO credUI = CreateCREDUI_INFO(owner);

            StringBuilder usernameBuffer = new StringBuilder(1000);
            StringBuilder passwordBuffer = new StringBuilder(1000);

            bool persist = SaveChecked;

            if (string.IsNullOrEmpty(Target))
            {
                AMTLogger.WriteToLog("Target must always be specified.", MethodBase.GetCurrentMethod().Name, 0, AMTLogger.LogInfo.Error);
                //  throw new InvalidOperationException("Target must always be specified.");
            }

            if (AlwaysShowUI && !GenericCredentials)
            {
                AMTLogger.WriteToLog("AlwaysShowUI must be specified with GenericCredentials property.", MethodBase.GetCurrentMethod().Name, 0, AMTLogger.LogInfo.Error);
                //throw new InvalidOperationException("AlwaysShowUI must be specified with GenericCredentials property.");
            }

            NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForCredentials(ref credUI, Target,
                                                                                              IntPtr.Zero, ErrorCode, usernameBuffer,
                                                                                              NativeMethods.CREDUI_MAX_USERNAME_LENGTH,
                                                                                              passwordBuffer,
                                                                                              NativeMethods.CREDUI_MAX_PASSWORD_LENGTH,
                                                                                              ref persist, DialogFlags);
            switch (result)
            {
            case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                return(DialogResult.Cancel);

            case NativeMethods.CredUIReturnCodes.ERROR_NO_SUCH_LOGON_SESSION:
            case NativeMethods.CredUIReturnCodes.ERROR_NOT_FOUND:
            case NativeMethods.CredUIReturnCodes.ERROR_INVALID_ACCOUNT_NAME:
            case NativeMethods.CredUIReturnCodes.ERROR_INSUFFICIENT_BUFFER:
            case NativeMethods.CredUIReturnCodes.ERROR_INVALID_PARAMETER:
            case NativeMethods.CredUIReturnCodes.ERROR_INVALID_FLAGS:
            case NativeMethods.CredUIReturnCodes.ERROR_BAD_ARGUMENTS:

                throw new InvalidOperationException("Invalid properties were specified.", new Win32Exception(Marshal.GetLastWin32Error()));
            }

            Username = usernameBuffer.ToString();
            Password = passwordBuffer.ToString();

            if (passwordBuffer.Length > 0)
            {
                passwordBuffer.Remove(0, passwordBuffer.Length);
            }

            return(DialogResult.OK);
        }
示例#7
0
        /// <summary>
        /// This fuction calls CredUIParseUserName() to parse the user name.
        /// </summary>
        /// <param name="username">The username name to pass.</param>
        /// <param name="targetServer">The target for which username is being parsed.</param>
        /// <param name="user">The user part of the username.</param>
        /// <param name="domain">The domain part of the username.</param>
        /// <returns>Returns true if it successfully parsed the username.</returns>
        private static bool ParseUsername(string username, string targetServer, out string user, out string domain)
        {
            user   = string.Empty;
            domain = string.Empty;

            if (string.IsNullOrEmpty(username))
            {
                return(false);
            }

            bool successfullyParsed = true;

            StringBuilder strUser   = new StringBuilder(Convert.ToInt32(NativeMethods.CREDUI_MAX_USERNAME_LENGTH));
            StringBuilder strDomain = new StringBuilder(Convert.ToInt32(NativeMethods.CREDUI_MAX_DOMAIN_TARGET_LENGTH));

            // Call the OS API to do the parsing.
            NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIParseUserName(username,
                                                                                       strUser,
                                                                                       NativeMethods.CREDUI_MAX_USERNAME_LENGTH,
                                                                                       strDomain,
                                                                                       NativeMethods.CREDUI_MAX_DOMAIN_TARGET_LENGTH);

            successfullyParsed = (result == NativeMethods.CredUIReturnCodes.NO_ERROR);

            if (successfullyParsed)
            {
                user   = strUser.ToString();
                domain = strDomain.ToString();

                // Remove the domain part if domain is same as target. This is to workaround
                // the COMPLETE_USERNAME flag which add the target to the user name as the
                // domain component.
                // Read comments in ShowOSCredentialDialog() for more details.
                if (!string.IsNullOrEmpty(domain) &&
                    string.Equals(domain, targetServer, StringComparison.OrdinalIgnoreCase))
                {
                    domain = string.Empty;
                }
            }

            return(successfullyParsed);
        }
示例#8
0
        private static NativeMethods.CredUIReturnCodes SspiPromptForCredentials(NativeMethods.CREDUI_INFO credUiInfo, Uri targetUri, ref bool pfSave, out string userName, out SecureString password)
        {
            IntPtr zero = IntPtr.Zero;

            NativeMethods.CredUIReturnCodes credUIReturnCodes = NativeMethods.SspiPromptForCredentials(targetUri.Host, ref credUiInfo, 0U, "Negotiate", IntPtr.Zero, ref zero, ref pfSave, 1);
            if (credUIReturnCodes == null)
            {
                try
                {
                    CredentialHelper.AuthIdentityToCredential(zero, out userName, out password);
                    return(credUIReturnCodes);
                }
                finally
                {
                    NativeMethods.SspiFreeAuthIdentity(zero);
                }
            }
            userName = null;
            password = null;
            return(credUIReturnCodes);
        }
        private bool PromptForCredentialsCredUIWin(IntPtr owner, bool storedCredentials)
        {
            NativeMethods.CREDUI_INFO    info  = CreateCredUIInfo(owner, false);
            NativeMethods.CredUIWinFlags flags = NativeMethods.CredUIWinFlags.Generic;
            if (ShowSaveCheckBox)
            {
                flags |= NativeMethods.CredUIWinFlags.Checkbox;
            }

            IntPtr inBuffer  = IntPtr.Zero;
            IntPtr outBuffer = IntPtr.Zero;

            try
            {
                uint inBufferSize = 0;
                if (UserName.Length > 0)
                {
                    NativeMethods.CredPackAuthenticationBuffer(0, UserName, Password, IntPtr.Zero, ref inBufferSize);
                    if (inBufferSize > 0)
                    {
                        inBuffer = Marshal.AllocCoTaskMem((int)inBufferSize);
                        if (!NativeMethods.CredPackAuthenticationBuffer(0, UserName, Password, inBuffer, ref inBufferSize))
                        {
                            throw new CredentialException(Marshal.GetLastWin32Error());
                        }
                    }
                }

                uint outBufferSize;
                uint package = 0;
                NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForWindowsCredentials(ref info, 0, ref package, inBuffer, inBufferSize, out outBuffer, out outBufferSize, ref _isSaveChecked, flags);
                switch (result)
                {
                case NativeMethods.CredUIReturnCodes.NO_ERROR:
                    StringBuilder userName     = new StringBuilder(NativeMethods.CREDUI_MAX_USERNAME_LENGTH);
                    StringBuilder password     = new StringBuilder(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH);
                    uint          userNameSize = (uint)userName.Capacity;
                    uint          passwordSize = (uint)password.Capacity;
                    uint          domainSize   = 0;
                    if (!NativeMethods.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 credential was stored previously but the user has now cleared the save checkbox,
                        // we want to delete the credential.
                        if (storedCredentials && !IsSaveChecked)
                        {
                            DeleteCredential(Target);
                        }
                    }
                    return(true);

                case NativeMethods.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);
                }
            }
        }
示例#10
0
        /// <summary>
        /// When overridden in a derived class, specifies a common dialog box.
        /// </summary>
        /// <param name="parentWindowHandle">A value that represents the window handle of the owner window for the common dialog box.</param>
        /// <returns>
        /// true if the dialog box was successfully run; otherwise, false.
        /// </returns>
        protected override bool RunDialog(IntPtr parentWindowHandle)
        {
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO(parentWindowHandle, this.Caption, this.Message, this.Banner);
            try
            {
                StringBuilder userName = new StringBuilder(this.UserName, maxStringLength);
                StringBuilder password = new StringBuilder(maxStringLength);
                bool          save     = this.SaveChecked;

                if (string.IsNullOrEmpty(this.Target))
                {
                    this.Target = this.DefaultTarget;
                }
                NativeMethods.CredUIReturnCodes ret = NativeMethods.CredUIPromptForCredentials(ref info, this.Target, IntPtr.Zero,
                                                                                               this.AuthenticationError, userName, maxStringLength, password, maxStringLength, ref save, this.Options);
                switch (ret)
                {
                case NativeMethods.CredUIReturnCodes.NO_ERROR:
                    if (this.ValidatePassword && !IsValidPassword(userName.ToString(), password.ToString()))
                    {
                        return(false);
                    }

                    /*if (save)
                     * {
                     *      CredUIReturnCodes cret = CredUIConfirmCredentials(this.Target, false);
                     *      if (cret != CredUIReturnCodes.NO_ERROR && cret != CredUIReturnCodes.ERROR_INVALID_PARAMETER)
                     *      {
                     *              this.Options |= CredentialsDialogOptions.IncorrectPassword;
                     *              return false;
                     *      }
                     * }*/
                    break;

                case NativeMethods.CredUIReturnCodes.ERROR_CANCELLED:
                    return(false);

                default:
                    throw new InvalidOperationException(string.Format("Unknown error in CredentialsDialog. Error: 0x{0:X}", ret));
                }

                if (this.EncryptPassword)
                {
                    // Convert the password to a SecureString
                    SecureString newPassword = StringBuilderToSecureString(password);

                    // Clear the old password and set the new one (read-only)
                    if (this.SecurePassword != null)
                    {
                        this.SecurePassword.Dispose();
                    }
                    newPassword.MakeReadOnly();
                    this.SecurePassword = newPassword;
                }
                else
                {
                    this.Password = password.ToString();
                }

                // Update other properties
                this.UserName    = userName.ToString();
                this.SaveChecked = save;
                return(true);
            }
            finally
            {
                info.Dispose();
            }
        }
示例#11
0
        //---------------------------------------------------------------------
        // private methods
        //---------------------------------------------------------------------


        /// <summary>
        /// This function calls the OS dialog to prompt user for credential.
        /// </summary>
        /// <param name="target">
        /// The credential target. It is displayed in the prompt dialog and is
        /// used for credential storage.
        /// </param>
        /// <param name="hwdOwner">The parent for the dialog.</param>
        /// <param name="userName">The username supplied by the user.</param>
        /// <param name="password">The password supplied by the user.</param>
        /// <returns>
        /// DialogResult.OK = if Successfully prompted user for credentials.
        /// DialogResult.Cancel = if user cancelled the prompt dialog.
        /// </returns>
        private static DialogResult ShowOSCredentialDialog(string target, IntPtr hwdOwner, out string userName, out string password)
        {
            DialogResult retValue = DialogResult.Cancel;

            userName = string.Empty;
            password = string.Empty;

            string titleFormat       = SR.CredentialDialog_TitleFormat;
            string descriptionFormat = SR.CredentialDialog_DescriptionTextFormat;

            // Create the CREDUI_INFO structure.
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO();
            info.pszCaptionText      = string.Format(CultureInfo.CurrentUICulture, titleFormat, target);
            info.pszMessageText      = string.Format(CultureInfo.CurrentUICulture, descriptionFormat, target);
            info.hwndParentCERParent = hwdOwner;
            info.hbmBannerCERHandle  = IntPtr.Zero;
            info.cbSize = Marshal.SizeOf(info);

            // We do not use CREDUI_FLAGS_VALIDATE_USERNAME flag as it doesn't allow plain user
            // (one with no domain component). Instead we use CREDUI_FLAGS_COMPLETE_USERNAME.
            // It does some basic username validation (like doesnt allow two "\" in the user name.
            // It does adds the target to the username. For example, if user entered "foo" for
            // taget "bar.com", it will return username as "bar.com\foo". We trim out bar.com
            // while parsing the username. User can input "*****@*****.**" as workaround to provide
            // "bar.com\foo" as the username.
            // We specify CRED_TYPE_SERVER_CREDENTIAL flag as the stored credentials appear in the
            // "Control Panel->Stored Usernames and Password". It is how IE stores and retrieve
            // credentials. By using the CRED_TYPE_SERVER_CREDENTIAL flag allows IE and VS to
            // share credentials.
            // We dont specify the CREDUI_FLAGS_EXPECT_CONFIRMATION as the VS proxy service consumers
            // dont call back into the service to confirm that the call succeeded.
            NativeMethods.CREDUI_FLAGS flags = NativeMethods.CREDUI_FLAGS.SERVER_CREDENTIAL |
                                               NativeMethods.CREDUI_FLAGS.SHOW_SAVE_CHECK_BOX |
                                               NativeMethods.CREDUI_FLAGS.COMPLETE_USERNAME |
                                               NativeMethods.CREDUI_FLAGS.EXCLUDE_CERTIFICATES;

            StringBuilder user            = new StringBuilder(Convert.ToInt32(NativeMethods.CREDUI_MAX_USERNAME_LENGTH));
            StringBuilder pwd             = new StringBuilder(Convert.ToInt32(NativeMethods.CREDUI_MAX_PASSWORD_LENGTH));
            int           saveCredentials = 0;
            // Ensures that CredUPPromptForCredentials results in a prompt.
            int netError = NativeMethods.ERROR_LOGON_FAILURE;

            // Call the OS API to prompt for credentials.
            NativeMethods.CredUIReturnCodes result = NativeMethods.CredUIPromptForCredentials(
                info,
                target,
                IntPtr.Zero,
                netError,
                user,
                NativeMethods.CREDUI_MAX_USERNAME_LENGTH,
                pwd,
                NativeMethods.CREDUI_MAX_PASSWORD_LENGTH,
                ref saveCredentials,
                flags);


            if (result == NativeMethods.CredUIReturnCodes.NO_ERROR)
            {
                userName = user.ToString();
                password = pwd.ToString();

                try {
                    if (Convert.ToBoolean(saveCredentials))
                    {
                        // Try reading the credentials back to ensure that we can read the stored credentials. If
                        // the CredUIPromptForCredentials() function is not able successfully call CredGetTargetInfo(),
                        // it will store credentials with credential type as DOMAIN_PASSWORD. For DOMAIN_PASSWORD
                        // credential type we can only retrive the user name. As a workaround, we store the credentials
                        // as credential type as GENERIC.
                        string storedUserName;
                        string storedPassword;
                        bool   successfullyReadCredentials = ReadOSCredentials(target, out storedUserName, out storedPassword);
                        if (!successfullyReadCredentials ||
                            !string.Equals(userName, storedUserName, StringComparison.Ordinal) ||
                            !string.Equals(password, storedPassword, StringComparison.Ordinal))
                        {
                            // We are not able to retrieve the credentials. Try storing them as GENERIC credetails.

                            // Create the NativeCredential object.
                            NativeMethods.NativeCredential customCredential = new NativeMethods.NativeCredential();
                            customCredential.userName   = userName;
                            customCredential.type       = NativeMethods.CRED_TYPE_GENERIC;
                            customCredential.targetName = CreateCustomTarget(target);
                            // Store credentials across sessions.
                            customCredential.persist = (uint)NativeMethods.CRED_PERSIST.LOCAL_MACHINE;
                            if (!string.IsNullOrEmpty(password))
                            {
                                customCredential.credentialBlobSize = (uint)Marshal.SystemDefaultCharSize * ((uint)password.Length);
                                customCredential.credentialBlob     = Marshal.StringToCoTaskMemAuto(password);
                            }

                            try {
                                NativeMethods.CredWrite(ref customCredential, 0);
                            } finally {
                                if (customCredential.credentialBlob != IntPtr.Zero)
                                {
                                    Marshal.FreeCoTaskMem(customCredential.credentialBlob);
                                }
                            }
                        }
                    }
                } catch {
                    // Ignore that failure to read back the credentials. We still have
                    // username and password to use in the current session.
                }

                retValue = DialogResult.OK;
            }
            else if (result == NativeMethods.CredUIReturnCodes.ERROR_CANCELLED)
            {
                retValue = DialogResult.Cancel;
            }
            else
            {
                Debug.Fail("CredUIPromptForCredentials failed with result = " + result.ToString());
                retValue = DialogResult.Cancel;
            }

            info.Dispose();
            return(retValue);
        }
示例#12
0
        /// <summary>
        /// When overridden in a derived class, specifies a common dialog box.
        /// </summary>
        /// <param name="parentWindowHandle">A value that represents the window handle of the owner window for the common dialog box.</param>
        /// <returns>
        /// true if the dialog box was successfully run; otherwise, false.
        /// </returns>
        protected override bool RunDialog(IntPtr parentWindowHandle)
        {
            NativeMethods.CREDUI_INFO info = new NativeMethods.CREDUI_INFO(parentWindowHandle, Caption, Message, Banner);
            try
            {
                if (Environment.OSVersion.Version.Major <= 5 || ForcePreVistaStyle)
                {
                    StringBuilder userName = new StringBuilder(UserName, maxStringLength);
                    StringBuilder password = new StringBuilder(maxStringLength);
                    bool          save     = SaveChecked;

                    if (string.IsNullOrEmpty(Target))
                    {
                        Target = DefaultTarget;
                    }
                    NativeMethods.CredUIReturnCodes ret = NativeMethods.CredUIPromptForCredentials(ref info, Target, IntPtr.Zero,
                                                                                                   AuthenticationError, userName, maxStringLength, password, maxStringLength, ref save,
                                                                                                   NativeMethods.CredentialsDialogOptions.Default | (SaveChecked ? NativeMethods.CredentialsDialogOptions.ShowSaveCheckBox : 0));
                    switch (ret)
                    {
                    case NativeMethods.CredUIReturnCodes.Success:
                        if (ValidatePassword && !IsValidPassword(userName.ToString(), password.ToString()))
                        {
                            return(false);
                        }

                        /*if (save)
                         * {
                         *      CredUIReturnCodes cret = CredUIConfirmCredentials(this.Target, false);
                         *      if (cret != CredUIReturnCodes.NO_ERROR && cret != CredUIReturnCodes.ERROR_INVALID_PARAMETER)
                         *      {
                         *              this.Options |= CredentialsDialogOptions.IncorrectPassword;
                         *              return false;
                         *      }
                         * }*/
                        break;

                    case NativeMethods.CredUIReturnCodes.Cancelled:
                        return(false);

                    default:
                        throw new InvalidOperationException($"Unknown error in CredentialsDialog. Error: 0x{ret:X}");
                    }

                    if (EncryptPassword)
                    {
                        // Convert the password to a SecureString
                        SecureString newPassword = StringBuilderToSecureString(password);

                        // Clear the old password and set the new one (read-only)
                        if (SecurePassword != null)
                        {
                            SecurePassword.Dispose();
                        }
                        newPassword.MakeReadOnly();
                        SecurePassword = newPassword;
                    }
                    else
                    {
                        Password = password.ToString();
                    }

                    // Update other properties
                    UserName    = userName.ToString();
                    SaveChecked = save;
                    return(true);
                }
                else
                {
                    NativeMethods.WindowsCredentialsDialogOptions flag = NativeMethods.WindowsCredentialsDialogOptions.Generic;
                    if (SaveChecked)
                    {
                        flag |= NativeMethods.WindowsCredentialsDialogOptions.ShowSaveCheckBox;
                    }

                    NativeMethods.AuthenticationBuffer buf = null;
                    if (EncryptPassword && SecurePassword != null)
                    {
                        buf = new NativeMethods.AuthenticationBuffer(UserName.ToSecureString(), SecurePassword);
                    }
                    else
                    {
                        buf = new NativeMethods.AuthenticationBuffer(UserName, Password);
                    }

                    IntPtr outAuthBuffer = IntPtr.Zero;
                    uint   outAuthBufferSize = 0, authPackage = 0;
                    bool   save = SaveChecked;
                    var    retVal = NativeMethods.CredUIPromptForWindowsCredentials(ref info, 0, ref authPackage,
                                                                                    buf, (uint)buf.Size, out outAuthBuffer, out outAuthBufferSize, ref save, flag);
                    var outAuth = new NativeMethods.AuthenticationBuffer(outAuthBuffer, (int)outAuthBufferSize);

                    if (retVal == NativeMethods.CredUIReturnCodes.Cancelled)
                    {
                        return(false);
                    }
                    if (retVal != NativeMethods.CredUIReturnCodes.Success)
                    {
                        throw new Win32Exception((int)retVal);
                    }

                    SaveChecked = save;
                    if (EncryptPassword)
                    {
                        SecureString u, d, p;
                        outAuth.UnPack(true, out u, out d, out p);
                        Password       = null;
                        SecurePassword = p;
                        UserName       = $"{d.ToInsecureString()}\\{u.ToInsecureString()}".TrimStart('\\');
                    }
                    else
                    {
                        string u, d, p;
                        outAuth.UnPack(true, out u, out d, out p);
                        Password       = p;
                        SecurePassword = null;
                        UserName       = $"{d}\\{u}".TrimStart('\\');
                        if (ValidatePassword && !IsValidPassword(UserName, Password))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }
            finally
            {
                info.Dispose();
            }
        }