internal static bool PromptForCredentials(string target, ref bool save, string Message, string Caption, out string user, out string password, out string domain)
 {
     NativeCode.CredentialUIInfo credUI = new NativeCode.CredentialUIInfo();
     credUI.pszMessageText = Message;
     credUI.pszCaptionText = Caption;
     return(PromptForCredentials(target, credUI, ref save, out user, out password, out domain));
 }
        private static bool PromptForCredentials(string target, NativeCode.CredentialUIInfo credUI, ref bool save, out string user, out string password, out string domain)
        {
            user     = String.Empty;
            password = String.Empty;
            domain   = String.Empty;



            // Setup the flags and variables
            credUI.cbSize = Marshal.SizeOf(credUI);
            int  errorcode   = 0;
            uint authPackage = 0;

            IntPtr outCredBuffer = new IntPtr();
            uint   outCredSize;
            var    flags = NativeCode.PromptForWindowsCredentialsFlags.GenericCredentials | NativeCode.PromptForWindowsCredentialsFlags.EnumerateCurrentUser;

            flags = save ? flags | NativeCode.PromptForWindowsCredentialsFlags.ShowCheckbox : flags;

            // Setup the flags and variables
            int result = NativeCode.CredUIPromptForWindowsCredentials(ref credUI,
                                                                      errorcode,
                                                                      ref authPackage,
                                                                      IntPtr.Zero,
                                                                      0,
                                                                      out outCredBuffer,
                                                                      out outCredSize,
                                                                      ref save,
                                                                      flags);

            var usernameBuf = new StringBuilder(100);
            var passwordBuf = new StringBuilder(100);
            var domainBuf   = new StringBuilder(100);

            int maxUserName = 100;
            int maxDomain   = 100;
            int maxPassword = 100;

            if (result == 0)
            {
                if (NativeCode.CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName,
                                                              domainBuf, ref maxDomain, passwordBuf, ref maxPassword))
                {
                    user     = usernameBuf.ToString();
                    password = passwordBuf.ToString();
                    domain   = domainBuf.ToString();
                    if (String.IsNullOrWhiteSpace(domain))
                    {
                        Debug.WriteLine("Domain null");
                        if (!ParseUserName(usernameBuf.ToString(), maxUserName, maxDomain, out user, out domain))
                        {
                            user = usernameBuf.ToString();
                        }
                        password = passwordBuf.ToString();
                    }
                }

                //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);

                //clear the memory allocated by CredUIPromptForWindowsCredentials
                NativeCode.CoTaskMemFree(outCredBuffer);
                return(true);
            }

            user   = null;
            domain = null;
            return(false);
        }