Exemplo n.º 1
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();
            }
        }