public static CredentialResult PromptForCredentialsConsole(string target, string userName = null, CredentialSaveOption saveCredential = CredentialSaveOption.Unselected)
        {
            var userId       = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);
            var userPassword = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);

            if (!string.IsNullOrEmpty(userName))
            {
                userId.Append(userName);
            }

            var save  = saveCredential == CredentialSaveOption.Selected ? true : false;
            var flags = CredentialUIFlags.CompleteUsername | CredentialUIFlags.ExcludeCertificates | CredentialUIFlags.GenericCredentials;

            if (saveCredential == CredentialSaveOption.Unselected)
            {
                flags |= CredentialUIFlags.ShowSaveCheckBox | CredentialUIFlags.DoNotPersist;
            }
            else if (saveCredential == CredentialSaveOption.Selected)
            {
                flags |= CredentialUIFlags.ShowSaveCheckBox | CredentialUIFlags.Persist;
            }
            else
            {
                flags |= CredentialUIFlags.DoNotPersist;
            }

            var returnCode = Credui.CredUICmdLinePromptForCredentials(target, IntPtr.Zero, 0, userId, userId.Capacity, userPassword, userPassword.Capacity, ref save, flags);

            var userBuilder   = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);
            var domainBuilder = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);

            var credentialSaved = saveCredential == CredentialSaveOption.Hidden ? CredentialSaveOption.Hidden : (save ? CredentialSaveOption.Selected : CredentialSaveOption.Unselected);

            returnCode = Credui.CredUIParseUserName(userId.ToString(), userBuilder, userBuilder.Capacity, domainBuilder, domainBuilder.Capacity);
            switch (returnCode)
            {
            case CredentialUIReturnCodes.Success:
                return(new CredentialResult(
                           userBuilder.ToString(),
                           userPassword.ToString(),
                           domainBuilder.ToString(),
                           credentialSaved));

            case CredentialUIReturnCodes.InvalidAccountName:
                return(new CredentialResult(
                           userId.ToString(),
                           userPassword.ToString(),
                           null,
                           credentialSaved));

            case CredentialUIReturnCodes.InsufficientBuffer:
                throw new OutOfMemoryException();

            case CredentialUIReturnCodes.InvalidParameter:
                throw new ArgumentException();

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        private static bool GetCredentialsFromOutputBuffer(IntPtr outCredBuffer, uint outCredSize, out string userName, out string password, out string domain)
        {
            var maxUserName = Credui.CREDUI_MAX_USERNAME_LENGTH;
            var maxDomain   = Credui.CREDUI_MAX_USERNAME_LENGTH;
            var maxPassword = Credui.CREDUI_MAX_USERNAME_LENGTH;
            var usernameBuf = new StringBuilder(maxUserName);
            var passwordBuf = new StringBuilder(maxDomain);
            var domainBuf   = new StringBuilder(maxPassword);

            try
            {
                if (Credui.CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName, domainBuf, ref maxDomain, passwordBuf, ref maxPassword))
                {
                    userName = usernameBuf.ToString();
                    password = passwordBuf.ToString();
                    domain   = domainBuf.ToString();
                    if (string.IsNullOrWhiteSpace(domain))
                    {
                        usernameBuf.Clear();
                        domainBuf.Clear();

                        var returnCode = Credui.CredUIParseUserName(userName, usernameBuf, usernameBuf.Capacity, domainBuf, domainBuf.Capacity);
                        switch (returnCode)
                        {
                        case CredentialUIReturnCodes.Success:
                            userName = usernameBuf.ToString();
                            domain   = domainBuf.ToString();
                            break;

                        case CredentialUIReturnCodes.InvalidAccountName:
                            return(true);

                        case CredentialUIReturnCodes.InsufficientBuffer:
                            throw new OutOfMemoryException();

                        case CredentialUIReturnCodes.InvalidParameter:
                            throw new ArgumentException();

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                    }
                }

                userName = null;
                password = null;
                domain   = null;
                return(false);
            }
            finally
            {
                //mimic SecureZeroMem function to make sure buffer is zeroed out. SecureZeroMem is not an exported function, neither is RtlSecureZeroMemory
                var zeroBytes = new byte[outCredSize];
                Marshal.Copy(zeroBytes, 0, outCredBuffer, (int)outCredSize);
                FreeCoTaskMem(outCredBuffer);
            }
        }
        private static void GetInputBuffer(string user, out IntPtr inCredBuffer, out int inCredSize)
        {
            if (!string.IsNullOrEmpty(user))
            {
                var usernameBuf = new StringBuilder(user);
                var passwordBuf = new StringBuilder();

                inCredSize   = 1024;
                inCredBuffer = Marshal.AllocCoTaskMem(inCredSize);
                if (Credui.CredPackAuthenticationBuffer(0, usernameBuf, passwordBuf, inCredBuffer, ref inCredSize))
                {
                    return;
                }
            }

            inCredBuffer = IntPtr.Zero;
            inCredSize   = 0;
        }
        public static CredentialResult PromptForCredentialsConsole(string target, string?userName = null, CredentialSaveOption saveCredential = CredentialSaveOption.Unselected)
        {
            var userId       = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);
            var userPassword = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);

            if (!string.IsNullOrEmpty(userName))
            {
                userId.Append(userName);
            }

            var save  = saveCredential == CredentialSaveOption.Selected;
            var flags = CredentialUIFlags.CompleteUsername | CredentialUIFlags.ExcludeCertificates | CredentialUIFlags.GenericCredentials;

            if (saveCredential == CredentialSaveOption.Unselected)
            {
                flags |= CredentialUIFlags.ShowSaveCheckBox | CredentialUIFlags.DoNotPersist;
            }
            else if (saveCredential == CredentialSaveOption.Selected)
            {
                flags |= CredentialUIFlags.ShowSaveCheckBox | CredentialUIFlags.Persist;
            }
            else
            {
                flags |= CredentialUIFlags.DoNotPersist;
            }

            _ = Credui.CredUICmdLinePromptForCredentialsW(target, IntPtr.Zero, 0, userId, userId.Capacity, userPassword, userPassword.Capacity, ref save, flags);

            var userBuilder   = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);
            var domainBuilder = new StringBuilder(Credui.CREDUI_MAX_USERNAME_LENGTH);

            var credentialSaved = saveCredential == CredentialSaveOption.Hidden ? CredentialSaveOption.Hidden : (save ? CredentialSaveOption.Selected : CredentialSaveOption.Unselected);

            var returnCode = Credui.CredUIParseUserName(userId.ToString(), userBuilder, userBuilder.Capacity, domainBuilder, domainBuilder.Capacity);

            return(returnCode switch
            {
                CredentialUIReturnCodes.Success => new CredentialResult(userBuilder.ToString(), userPassword.ToString(), domainBuilder.ToString(), credentialSaved),
                CredentialUIReturnCodes.InvalidAccountName => new CredentialResult(userId.ToString(), userPassword.ToString(), domain: null, credentialSaved),
                CredentialUIReturnCodes.InsufficientBuffer => throw new Win32Exception((int)returnCode, "Insufficient buffer"),
                CredentialUIReturnCodes.InvalidParameter => throw new Win32Exception((int)returnCode, "Invalid parameter"),
                _ => throw new Win32Exception((int)returnCode),
            });