/*
 * Credentials User Interface
 *
 * Copyright 2006 Robert Shearman (for CodeWeavers)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winuser.h"
#include "wincred.h"
#include "rpc.h"
#include "sspi.h"
#include "commctrl.h"

#include "credui_resources.h"

#include "wine/debug.h"
#include "wine/unicode.h"
#include "wine/list.h"

WINE_DEFAULT_DEBUG_CHANNEL(credui);

#define TOOLID_INCORRECTPASSWORD    1
#define TOOLID_CAPSLOCKON           2

#define ID_CAPSLOCKPOP              1

struct pending_credentials
{
    struct list entry;
    PWSTR pszTargetName;
    PWSTR pszUsername;
    PWSTR pszPassword;
    BOOL generic;
};

static HINSTANCE hinstCredUI;

static struct list pending_credentials_list = LIST_INIT(pending_credentials_list);

static CRITICAL_SECTION csPendingCredentials;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &csPendingCredentials,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
    0, 0, { (DWORD_PTR)(__FILE__ ": csPendingCredentials") }
};
static CRITICAL_SECTION csPendingCredentials = { &critsect_debug, -1, 0, 0, 0, 0 };


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    struct pending_credentials *entry, *cursor2;
    TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved);

    switch (fdwReason)
    {
    case DLL_WINE_PREATTACH:
        return FALSE;	/* prefer native version */

    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls(hinstDLL);
        hinstCredUI = hinstDLL;
        InitCommonControls();
        break;

    case DLL_PROCESS_DETACH:
        if (lpvReserved) break;
        LIST_FOR_EACH_ENTRY_SAFE(entry, cursor2, &pending_credentials_list, struct pending_credentials, entry)
        {
            list_remove(&entry->entry);

            HeapFree(GetProcessHeap(), 0, entry->pszTargetName);
            HeapFree(GetProcessHeap(), 0, entry->pszUsername);
            ZeroMemory(entry->pszPassword, (strlenW(entry->pszPassword) + 1) * sizeof(WCHAR));
            HeapFree(GetProcessHeap(), 0, entry->pszPassword);
            HeapFree(GetProcessHeap(), 0, entry);
        }
        DeleteCriticalSection(&csPendingCredentials);
        break;
    }

    return TRUE;
}

static DWORD save_credentials(PCWSTR pszTargetName, PCWSTR pszUsername,
                              PCWSTR pszPassword, BOOL generic)
{
    CREDENTIALW cred;

    TRACE("saving servername %s with username %s\n", debugstr_w(pszTargetName), debugstr_w(pszUsername));

    cred.Flags = 0;
    cred.Type = generic ? CRED_TYPE_GENERIC : CRED_TYPE_DOMAIN_PASSWORD;
    cred.TargetName = (LPWSTR)pszTargetName;
    cred.Comment = NULL;
    cred.CredentialBlobSize = strlenW(pszPassword) * sizeof(WCHAR);
    cred.CredentialBlob = (LPBYTE)pszPassword;
    cred.Persist = CRED_PERSIST_ENTERPRISE;
    cred.AttributeCount = 0;
    cred.Attributes = NULL;
    cred.TargetAlias = NULL;
    cred.UserName = (LPWSTR)pszUsername;

    if (CredWriteW(&cred, 0))
        return ERROR_SUCCESS;
    else
    {
        DWORD ret = GetLastError();
        ERR("CredWriteW failed with error %d\n", ret);
        return ret;
    }
}

struct cred_dialog_params
{
    PCWSTR pszTargetName;
    PCWSTR pszMessageText;
    PCWSTR pszCaptionText;
    HBITMAP hbmBanner;
    PWSTR pszUsername;
    ULONG ulUsernameMaxChars;
    PWSTR pszPassword;
    ULONG ulPasswordMaxChars;
    BOOL fSave;
    DWORD dwFlags;
    HWND hwndBalloonTip;
    BOOL fBalloonTipActive;
};

static void CredDialogFillUsernameCombo(HWND hwndUsername, const struct cred_dialog_params *params)
{
    DWORD count;
    DWORD i;
    PCREDENTIALW *credentials;

    if (!CredEnumerateW(NULL, 0, &count, &credentials))
        return;

    for (i = 0; i < count; i++)
    {
        COMBOBOXEXITEMW comboitem;
        DWORD j;
        BOOL duplicate = FALSE;

        if (params->dwFlags & CREDUI_FLAGS_GENERIC_CREDENTIALS)
        {
            if ((credentials[i]->Type != CRED_TYPE_GENERIC) || !credentials[i]->UserName)
                continue;
        }
        else
        {
            if (credentials[i]->Type == CRED_TYPE_GENERIC)
                continue;
        }

        /* don't add another item with the same name if we've already added it */
        for (j = 0; j < i; j++)
            if (!strcmpW(credentials[i]->UserName, credentials[j]->UserName))
            {
                duplicate = TRUE;
                break;
            }

        if (duplicate)
            continue;

        comboitem.mask = CBEIF_TEXT;
        comboitem.iItem = -1;
        comboitem.pszText = credentials[i]->UserName;
        SendMessageW(hwndUsername, CBEM_INSERTITEMW, 0, (LPARAM)&comboitem);
    }

    CredFree(credentials);
}

static void CredDialogCreateBalloonTip(HWND hwndDlg, struct cred_dialog_params *params)
{
    TTTOOLINFOW toolinfo;
    WCHAR wszText[256];

    if (params->hwndBalloonTip)
        return;

    params->hwndBalloonTip = CreateWindowExW(WS_EX_TOOLWINDOW, TOOLTIPS_CLASSW,
        NULL, WS_POPUP | TTS_NOPREFIX | TTS_BALLOON, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL,
        hinstCredUI, NULL);
    SetWindowPos(params->hwndBalloonTip, HWND_TOPMOST, 0, 0, 0, 0,
                 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

    if (!LoadStringW(hinstCredUI, IDS_INCORRECTPASSWORD, wszText, sizeof(wszText)/sizeof(wszText[0])))
    {
        ERR("failed to load IDS_INCORRECTPASSWORD\n");
        return;
    }

    toolinfo.cbSize = sizeof(toolinfo);
    toolinfo.uFlags = TTF_TRACK;
    toolinfo.hwnd = hwndDlg;
    toolinfo.uId = TOOLID_INCORRECTPASSWORD;
    SetRectEmpty(&toolinfo.rect);
    toolinfo.hinst = NULL;
    toolinfo.lpszText = wszText;
    toolinfo.lParam = 0;
    toolinfo.lpReserved = NULL;
    SendMessageW(params->hwndBalloonTip, TTM_ADDTOOLW, 0, (LPARAM)&toolinfo);

    if (!LoadStringW(hinstCredUI, IDS_CAPSLOCKON, wszText, sizeof(wszText)/sizeof(wszText[0])))
    {
        ERR("failed to load IDS_CAPSLOCKON\n");
        return;
    }

    toolinfo.uId = TOOLID_CAPSLOCKON;
    SendMessageW(params->hwndBalloonTip, TTM_ADDTOOLW, 0, (LPARAM)&toolinfo);
}

static void CredDialogShowIncorrectPasswordBalloon(HWND hwndDlg, struct cred_dialog_params *params)
{
    TTTOOLINFOW toolinfo;
    RECT rcPassword;
    INT x;
    INT y;
    WCHAR wszTitle[256];

    /* user name likely wrong so balloon would be confusing. focus is also
     * not set to the password edit box, so more notification would need to be
     * handled */
    if (!params->pszUsername[0])
        return;

    /* don't show two balloon tips at once */
    if (params->fBalloonTipActive)
        return;

    if (!LoadStringW(hinstCredUI, IDS_INCORRECTPASSWORDTITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
    {
        ERR("failed to load IDS_INCORRECTPASSWORDTITLE\n");
        return;
    }

    CredDialogCreateBalloonTip(hwndDlg, params);

    memset(&toolinfo, 0, sizeof(toolinfo));
    toolinfo.cbSize = sizeof(toolinfo);
    toolinfo.hwnd = hwndDlg;
    toolinfo.uId = TOOLID_INCORRECTPASSWORD;

    SendMessageW(params->hwndBalloonTip, TTM_SETTITLEW, TTI_ERROR, (LPARAM)wszTitle);

    GetWindowRect(GetDlgItem(hwndDlg, IDC_PASSWORD), &rcPassword);
    /* centered vertically and in the right side of the password edit control */
    x = rcPassword.right - 12;
    y = (rcPassword.top + rcPassword.bottom) / 2;
    SendMessageW(params->hwndBalloonTip, TTM_TRACKPOSITION, 0, MAKELONG(x, y));

    SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&toolinfo);

    params->fBalloonTipActive = TRUE;
}

static void CredDialogShowCapsLockBalloon(HWND hwndDlg, struct cred_dialog_params *params)
{
    TTTOOLINFOW toolinfo;
    RECT rcPassword;
    INT x;
    INT y;
    WCHAR wszTitle[256];

    /* don't show two balloon tips at once */
    if (params->fBalloonTipActive)
        return;

    if (!LoadStringW(hinstCredUI, IDS_CAPSLOCKONTITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
    {
        ERR("failed to load IDS_IDSCAPSLOCKONTITLE\n");
        return;
    }

    CredDialogCreateBalloonTip(hwndDlg, params);

    memset(&toolinfo, 0, sizeof(toolinfo));
    toolinfo.cbSize = sizeof(toolinfo);
    toolinfo.hwnd = hwndDlg;
    toolinfo.uId = TOOLID_CAPSLOCKON;

    SendMessageW(params->hwndBalloonTip, TTM_SETTITLEW, TTI_WARNING, (LPARAM)wszTitle);

    GetWindowRect(GetDlgItem(hwndDlg, IDC_PASSWORD), &rcPassword);
    /* just inside the left side of the password edit control */
    x = rcPassword.left + 12;
    y = rcPassword.bottom - 3;
    SendMessageW(params->hwndBalloonTip, TTM_TRACKPOSITION, 0, MAKELONG(x, y));

    SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&toolinfo);

    SetTimer(hwndDlg, ID_CAPSLOCKPOP,
             SendMessageW(params->hwndBalloonTip, TTM_GETDELAYTIME, TTDT_AUTOPOP, 0),
             NULL);

    params->fBalloonTipActive = TRUE;
}

static void CredDialogHideBalloonTip(HWND hwndDlg, struct cred_dialog_params *params)
{
    TTTOOLINFOW toolinfo;

    if (!params->hwndBalloonTip)
        return;

    memset(&toolinfo, 0, sizeof(toolinfo));

    toolinfo.cbSize = sizeof(toolinfo);
    toolinfo.hwnd = hwndDlg;
    toolinfo.uId = 0;
    SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&toolinfo);
    toolinfo.uId = 1;
    SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&toolinfo);

    params->fBalloonTipActive = FALSE;
}

static inline BOOL CredDialogCapsLockOn(void)
{
    return (GetKeyState(VK_CAPITAL) & 0x1) != 0;
}

static LRESULT CALLBACK CredDialogPasswordSubclassProc(HWND hwnd, UINT uMsg,
    WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
    struct cred_dialog_params *params = (struct cred_dialog_params *)dwRefData;
    switch (uMsg)
    {
    case WM_KEYDOWN:
        if (wParam == VK_CAPITAL)
        {
            HWND hwndDlg = GetParent(hwnd);
            if (CredDialogCapsLockOn())
                CredDialogShowCapsLockBalloon(hwndDlg, params);
            else
                CredDialogHideBalloonTip(hwndDlg, params);
        }
        break;
    case WM_DESTROY:
        RemoveWindowSubclass(hwnd, CredDialogPasswordSubclassProc, uIdSubclass);
        break;
    }
    return DefSubclassProc(hwnd, uMsg, wParam, lParam);
}

static BOOL CredDialogInit(HWND hwndDlg, struct cred_dialog_params *params)
{
    HWND hwndUsername = GetDlgItem(hwndDlg, IDC_USERNAME);
    HWND hwndPassword = GetDlgItem(hwndDlg, IDC_PASSWORD);

    SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)params);

    if (params->hbmBanner)
        SendMessageW(GetDlgItem(hwndDlg, IDB_BANNER), STM_SETIMAGE,
                     IMAGE_BITMAP, (LPARAM)params->hbmBanner);

    if (params->pszMessageText)
        SetDlgItemTextW(hwndDlg, IDC_MESSAGE, params->pszMessageText);
    else
    {
        WCHAR format[256];
        WCHAR message[256];
        LoadStringW(hinstCredUI, IDS_MESSAGEFORMAT, format, sizeof(format)/sizeof(format[0]));
        snprintfW(message, sizeof(message)/sizeof(message[0]), format, params->pszTargetName);
        SetDlgItemTextW(hwndDlg, IDC_MESSAGE, message);
    }
    SetWindowTextW(hwndUsername, params->pszUsername);
    SetWindowTextW(hwndPassword, params->pszPassword);

    CredDialogFillUsernameCombo(hwndUsername, params);

    if (params->pszUsername[0])
    {
        /* prevent showing a balloon tip here */
        params->fBalloonTipActive = TRUE;
        SetFocus(hwndPassword);
        params->fBalloonTipActive = FALSE;
    }
    else
        SetFocus(hwndUsername);

    if (params->pszCaptionText)
        SetWindowTextW(hwndDlg, params->pszCaptionText);
    else
    {
        WCHAR format[256];
        WCHAR title[256];
        LoadStringW(hinstCredUI, IDS_TITLEFORMAT, format, sizeof(format)/sizeof(format[0]));
        snprintfW(title, sizeof(title)/sizeof(title[0]), format, params->pszTargetName);
        SetWindowTextW(hwndDlg, title);
    }

    if (params->dwFlags & CREDUI_FLAGS_PERSIST ||
        (params->dwFlags & CREDUI_FLAGS_DO_NOT_PERSIST &&
         !(params->dwFlags & CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX)))
        ShowWindow(GetDlgItem(hwndDlg, IDC_SAVE), SW_HIDE);
    else if (params->fSave)
        CheckDlgButton(hwndDlg, IDC_SAVE, BST_CHECKED);

    /* setup subclassing for Caps Lock detection */
    SetWindowSubclass(hwndPassword, CredDialogPasswordSubclassProc, 1, (DWORD_PTR)params);

    if (params->dwFlags & CREDUI_FLAGS_INCORRECT_PASSWORD)
        CredDialogShowIncorrectPasswordBalloon(hwndDlg, params);
    else if ((GetFocus() == hwndPassword) && CredDialogCapsLockOn())
        CredDialogShowCapsLockBalloon(hwndDlg, params);

    return FALSE;
}

static void CredDialogCommandOk(HWND hwndDlg, struct cred_dialog_params *params)
{
    HWND hwndUsername = GetDlgItem(hwndDlg, IDC_USERNAME);
    LPWSTR user;
    INT len;
    INT len2;

    len = GetWindowTextLengthW(hwndUsername);
    user = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
    GetWindowTextW(hwndUsername, user, len + 1);

    if (!user[0])
    {
        HeapFree(GetProcessHeap(), 0, user);
        return;
    }

    if (!strchrW(user, '\\') && !strchrW(user, '@'))
    {
        ULONG len_target = strlenW(params->pszTargetName);
        memcpy(params->pszUsername, params->pszTargetName,
               min(len_target, params->ulUsernameMaxChars) * sizeof(WCHAR));
        if (len_target + 1 < params->ulUsernameMaxChars)
            params->pszUsername[len_target] = '\\';
        if (len_target + 2 < params->ulUsernameMaxChars)
            params->pszUsername[len_target + 1] = '\0';
    }
    else if (params->ulUsernameMaxChars > 0)
        params->pszUsername[0] = '\0';

    len2 = strlenW(params->pszUsername);
    memcpy(params->pszUsername + len2, user, min(len, params->ulUsernameMaxChars - len2) * sizeof(WCHAR));
    if (params->ulUsernameMaxChars)
        params->pszUsername[len2 + min(len, params->ulUsernameMaxChars - len2 - 1)] = '\0';

    HeapFree(GetProcessHeap(), 0, user);

    GetDlgItemTextW(hwndDlg, IDC_PASSWORD, params->pszPassword,
                    params->ulPasswordMaxChars);

    params->fSave = IsDlgButtonChecked(hwndDlg, IDC_SAVE) == BST_CHECKED;

    EndDialog(hwndDlg, IDOK);
}

static INT_PTR CALLBACK CredDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
                                       LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_INITDIALOG:
        {
            struct cred_dialog_params *params = (struct cred_dialog_params *)lParam;

            return CredDialogInit(hwndDlg, params);
        }
        case WM_COMMAND:
            switch (wParam)
            {
                case MAKELONG(IDOK, BN_CLICKED):
                {
                    struct cred_dialog_params *params =
                        (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
                    CredDialogCommandOk(hwndDlg, params);
                    return TRUE;
                }
                case MAKELONG(IDCANCEL, BN_CLICKED):
                    EndDialog(hwndDlg, IDCANCEL);
                    return TRUE;
                case MAKELONG(IDC_PASSWORD, EN_SETFOCUS):
                    if (CredDialogCapsLockOn())
                    {
                        struct cred_dialog_params *params =
                            (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
                        CredDialogShowCapsLockBalloon(hwndDlg, params);
                    }
                    /* don't allow another window to steal focus while the
                     * user is typing their password */
                    LockSetForegroundWindow(LSFW_LOCK);
                    return TRUE;
                case MAKELONG(IDC_PASSWORD, EN_KILLFOCUS):
                {
                    struct cred_dialog_params *params =
                        (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
                    /* the user is no longer typing their password, so allow
                     * other windows to become foreground ones */
                    LockSetForegroundWindow(LSFW_UNLOCK);
                    CredDialogHideBalloonTip(hwndDlg, params);
                    return TRUE;
                }
                case MAKELONG(IDC_PASSWORD, EN_CHANGE):
                {
                    struct cred_dialog_params *params =
                        (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
                    CredDialogHideBalloonTip(hwndDlg, params);
                    return TRUE;
                }
            }
            return FALSE;
        case WM_TIMER:
            if (wParam == ID_CAPSLOCKPOP)
            {
                struct cred_dialog_params *params =
                    (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
                CredDialogHideBalloonTip(hwndDlg, params);
                return TRUE;
            }
            return FALSE;
        case WM_DESTROY:
        {
            struct cred_dialog_params *params =
                (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
            if (params->hwndBalloonTip) DestroyWindow(params->hwndBalloonTip);
            return TRUE;
        }
        default:
            return FALSE;
    }
}

static BOOL find_existing_credential(const WCHAR *target, WCHAR *username, ULONG len_username,
                                     WCHAR *password, ULONG len_password)
{
    DWORD count, i;
    CREDENTIALW **credentials;

    if (!CredEnumerateW(target, 0, &count, &credentials)) return FALSE;
    for (i = 0; i < count; i++)
    {
        if (credentials[i]->Type != CRED_TYPE_DOMAIN_PASSWORD &&
            credentials[i]->Type != CRED_TYPE_GENERIC)
        {
            FIXME("no support for type %u credentials\n", credentials[i]->Type);
            continue;
        }
        if ((!*username || !strcmpW(username, credentials[i]->UserName)) &&
            strlenW(credentials[i]->UserName) < len_username &&
            credentials[i]->CredentialBlobSize / sizeof(WCHAR) < len_password)
        {
            TRACE("found existing credential for %s\n", debugstr_w(credentials[i]->UserName));

            strcpyW(username, credentials[i]->UserName);
            memcpy(password, credentials[i]->CredentialBlob, credentials[i]->CredentialBlobSize);
            password[credentials[i]->CredentialBlobSize / sizeof(WCHAR)] = 0;

            CredFree(credentials);
            return TRUE;
        }
    }
    CredFree(credentials);
    return FALSE;
}

/******************************************************************************
 *           CredUIPromptForCredentialsW [CREDUI.@]
 */
DWORD WINAPI CredUIPromptForCredentialsW(PCREDUI_INFOW pUIInfo,
                                         PCWSTR pszTargetName,
                                         PCtxtHandle Reserved,
                                         DWORD dwAuthError,
                                         PWSTR pszUsername,
                                         ULONG ulUsernameMaxChars,
                                         PWSTR pszPassword,
                                         ULONG ulPasswordMaxChars, PBOOL pfSave,
                                         DWORD dwFlags)
{
    INT_PTR ret;
    struct cred_dialog_params params;
    DWORD result = ERROR_SUCCESS;

    TRACE("(%p, %s, %p, %d, %s, %d, %p, %d, %p, 0x%08x)\n", pUIInfo,
          debugstr_w(pszTargetName), Reserved, dwAuthError, debugstr_w(pszUsername),
          ulUsernameMaxChars, pszPassword, ulPasswordMaxChars, pfSave, dwFlags);

    if ((dwFlags & (CREDUI_FLAGS_ALWAYS_SHOW_UI|CREDUI_FLAGS_GENERIC_CREDENTIALS)) == CREDUI_FLAGS_ALWAYS_SHOW_UI)
        return ERROR_INVALID_FLAGS;

    if (!pszTargetName)
        return ERROR_INVALID_PARAMETER;

    if ((dwFlags & CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX) && !pfSave)
        return ERROR_INVALID_PARAMETER;

    if (!(dwFlags & CREDUI_FLAGS_ALWAYS_SHOW_UI) &&
        !(dwFlags & CREDUI_FLAGS_INCORRECT_PASSWORD) &&
        find_existing_credential(pszTargetName, pszUsername, ulUsernameMaxChars, pszPassword, ulPasswordMaxChars))
        return ERROR_SUCCESS;

    params.pszTargetName = pszTargetName;
    if (pUIInfo)
    {
        params.pszMessageText = pUIInfo->pszMessageText;
        params.pszCaptionText = pUIInfo->pszCaptionText;
        params.hbmBanner  = pUIInfo->hbmBanner;
    }
    else
    {
        params.pszMessageText = NULL;
        params.pszCaptionText = NULL;
        params.hbmBanner = NULL;
    }
    params.pszUsername = pszUsername;
    params.ulUsernameMaxChars = ulUsernameMaxChars;
    params.pszPassword = pszPassword;
    params.ulPasswordMaxChars = ulPasswordMaxChars;
    params.fSave = pfSave ? *pfSave : FALSE;
    params.dwFlags = dwFlags;
    params.hwndBalloonTip = NULL;
    params.fBalloonTipActive = FALSE;

    ret = DialogBoxParamW(hinstCredUI, MAKEINTRESOURCEW(IDD_CREDDIALOG),
                          pUIInfo ? pUIInfo->hwndParent : NULL,
                          CredDialogProc, (LPARAM)&params);
    if (ret <= 0)
        return GetLastError();

    if (ret == IDCANCEL)
    {
        TRACE("dialog cancelled\n");
        return ERROR_CANCELLED;
    }

    if (pfSave)
        *pfSave = params.fSave;

    if (params.fSave)
    {
        if (dwFlags & CREDUI_FLAGS_EXPECT_CONFIRMATION)
        {
            BOOL found = FALSE;
            struct pending_credentials *entry;
            int len;

            EnterCriticalSection(&csPendingCredentials);

            /* find existing pending credentials for the same target and overwrite */
            /* FIXME: is this correct? */
            LIST_FOR_EACH_ENTRY(entry, &pending_credentials_list, struct pending_credentials, entry)
                if (!strcmpW(pszTargetName, entry->pszTargetName))
                {
                    found = TRUE;
                    HeapFree(GetProcessHeap(), 0, entry->pszUsername);
                    ZeroMemory(entry->pszPassword, (strlenW(entry->pszPassword) + 1) * sizeof(WCHAR));
                    HeapFree(GetProcessHeap(), 0, entry->pszPassword);
                }

            if (!found)
            {
                entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
                len = strlenW(pszTargetName);
                entry->pszTargetName = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
                memcpy(entry->pszTargetName, pszTargetName, (len + 1)*sizeof(WCHAR));
                list_add_tail(&pending_credentials_list, &entry->entry);
            }

            len = strlenW(params.pszUsername);
            entry->pszUsername = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
            memcpy(entry->pszUsername, params.pszUsername, (len + 1)*sizeof(WCHAR));
            len = strlenW(params.pszPassword);
            entry->pszPassword = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
            memcpy(entry->pszPassword, params.pszPassword, (len + 1)*sizeof(WCHAR));
            entry->generic = (dwFlags & CREDUI_FLAGS_GENERIC_CREDENTIALS) != 0;

            LeaveCriticalSection(&csPendingCredentials);
        }
        else if (!(dwFlags & CREDUI_FLAGS_DO_NOT_PERSIST))
            result = save_credentials(pszTargetName, pszUsername, pszPassword,
                                      (dwFlags & CREDUI_FLAGS_GENERIC_CREDENTIALS) != 0);
    }

    return result;
}

/******************************************************************************
 *           CredUIConfirmCredentialsW [CREDUI.@]
 */
DWORD WINAPI CredUIConfirmCredentialsW(PCWSTR pszTargetName, BOOL bConfirm)
{
    struct pending_credentials *entry;
    DWORD result = ERROR_NOT_FOUND;

    TRACE("(%s, %s)\n", debugstr_w(pszTargetName), bConfirm ? "TRUE" : "FALSE");

    if (!pszTargetName)
        return ERROR_INVALID_PARAMETER;

    EnterCriticalSection(&csPendingCredentials);

    LIST_FOR_EACH_ENTRY(entry, &pending_credentials_list, struct pending_credentials, entry)
    {
        if (!strcmpW(pszTargetName, entry->pszTargetName))
        {
            if (bConfirm)
                result = save_credentials(entry->pszTargetName, entry->pszUsername,
                                          entry->pszPassword, entry->generic);
            else
                result = ERROR_SUCCESS;

            list_remove(&entry->entry);

            HeapFree(GetProcessHeap(), 0, entry->pszTargetName);
            HeapFree(GetProcessHeap(), 0, entry->pszUsername);
            ZeroMemory(entry->pszPassword, (strlenW(entry->pszPassword) + 1) * sizeof(WCHAR));
            HeapFree(GetProcessHeap(), 0, entry->pszPassword);
            HeapFree(GetProcessHeap(), 0, entry);

            break;
        }
    }

    LeaveCriticalSection(&csPendingCredentials);

    return result;
}

/******************************************************************************
 *           CredUIParseUserNameW [CREDUI.@]
 */
DWORD WINAPI CredUIParseUserNameW(PCWSTR pszUserName, PWSTR pszUser,
                                  ULONG ulMaxUserChars, PWSTR pszDomain,
                                  ULONG ulMaxDomainChars)
{
    PWSTR p;

    TRACE("(%s, %p, %d, %p, %d)\n", debugstr_w(pszUserName), pszUser,
          ulMaxUserChars, pszDomain, ulMaxDomainChars);

    if (!pszUserName || !pszUser || !ulMaxUserChars || !pszDomain ||
        !ulMaxDomainChars)
        return ERROR_INVALID_PARAMETER;

    /* FIXME: handle marshaled credentials */

    p = strchrW(pszUserName, '\\');
    if (p)
    {
        if (p - pszUserName > ulMaxDomainChars - 1)
            return ERROR_INSUFFICIENT_BUFFER;
        if (strlenW(p + 1) > ulMaxUserChars - 1)
            return ERROR_INSUFFICIENT_BUFFER;
        strcpyW(pszUser, p + 1);
        memcpy(pszDomain, pszUserName, (p - pszUserName)*sizeof(WCHAR));
        pszDomain[p - pszUserName] = '\0';

        return ERROR_SUCCESS;
    }

    p = strrchrW(pszUserName, '@');
    if (p)
    {
        if (p + 1 - pszUserName > ulMaxUserChars - 1)
            return ERROR_INSUFFICIENT_BUFFER;
        if (strlenW(p + 1) > ulMaxDomainChars - 1)
            return ERROR_INSUFFICIENT_BUFFER;
        strcpyW(pszDomain, p + 1);
        memcpy(pszUser, pszUserName, (p - pszUserName)*sizeof(WCHAR));
        pszUser[p - pszUserName] = '\0';

        return ERROR_SUCCESS;
    }

    if (strlenW(pszUserName) > ulMaxUserChars - 1)
        return ERROR_INSUFFICIENT_BUFFER;
    strcpyW(pszUser, pszUserName);
    pszDomain[0] = '\0';

    return ERROR_SUCCESS;
}

/******************************************************************************
 *           CredUIStoreSSOCredA [CREDUI.@]
 */
DWORD WINAPI CredUIStoreSSOCredA(PCSTR pszRealm, PCSTR pszUsername,
                                 PCSTR pszPassword, BOOL bPersist)
{
    FIXME("(%s, %s, %p, %d)\n", debugstr_a(pszRealm), debugstr_a(pszUsername),
          pszPassword, bPersist);
    return ERROR_SUCCESS;
}

/******************************************************************************
 *           CredUIStoreSSOCredW [CREDUI.@]
 */
DWORD WINAPI CredUIStoreSSOCredW(PCWSTR pszRealm, PCWSTR pszUsername,
                                 PCWSTR pszPassword, BOOL bPersist)
{
    FIXME("(%s, %s, %p, %d)\n", debugstr_w(pszRealm), debugstr_w(pszUsername),
          pszPassword, bPersist);
    return ERROR_SUCCESS;
}

/******************************************************************************
 *           CredUIReadSSOCredA [CREDUI.@]
 */
DWORD WINAPI CredUIReadSSOCredA(PCSTR pszRealm, PSTR *ppszUsername)
{
    FIXME("(%s, %p)\n", debugstr_a(pszRealm), ppszUsername);
    if (ppszUsername)
        *ppszUsername = NULL;
    return ERROR_NOT_FOUND;
}

/******************************************************************************
 *           CredUIReadSSOCredW [CREDUI.@]
 */
DWORD WINAPI CredUIReadSSOCredW(PCWSTR pszRealm, PWSTR *ppszUsername)
{
    FIXME("(%s, %p)\n", debugstr_w(pszRealm), ppszUsername);
    if (ppszUsername)
        *ppszUsername = NULL;
    return ERROR_NOT_FOUND;
}

/******************************************************************************
 * CredUIInitControls [CREDUI.@]
 */
BOOL WINAPI CredUIInitControls(void)
{
    FIXME("() stub\n");
    return TRUE;
}

/******************************************************************************
 * SspiPromptForCredentialsW [CREDUI.@]
 */
ULONG SEC_ENTRY SspiPromptForCredentialsW( PCWSTR target, void *info,
                                           DWORD error, PCWSTR package,
                                           PSEC_WINNT_AUTH_IDENTITY_OPAQUE input_id,
                                           PSEC_WINNT_AUTH_IDENTITY_OPAQUE *output_id,
                                           BOOL *save, DWORD sspi_flags )
{
    static const WCHAR basicW[] = {'B','a','s','i','c',0};
    static const WCHAR ntlmW[] = {'N','T','L','M',0};
    static const WCHAR negotiateW[] = {'N','e','g','o','t','i','a','t','e',0};
    WCHAR username[CREDUI_MAX_USERNAME_LENGTH + 1] = {0};
    WCHAR password[CREDUI_MAX_PASSWORD_LENGTH + 1] = {0};
    DWORD len_username = sizeof(username) / sizeof(username[0]);
    DWORD len_password = sizeof(password) / sizeof(password[0]);
    DWORD ret, flags;
    CREDUI_INFOW *cred_info = info;
    SEC_WINNT_AUTH_IDENTITY_W *id = input_id;

    FIXME( "(%s, %p, %u, %s, %p, %p, %p, %x) stub\n", debugstr_w(target), info,
           error, debugstr_w(package), input_id, output_id, save, sspi_flags );

    if (!target) return ERROR_INVALID_PARAMETER;
    if (!package || (strcmpiW( package, basicW ) && strcmpiW( package, ntlmW ) &&
                     strcmpiW( package, negotiateW )))
    {
        FIXME( "package %s not supported\n", debugstr_w(package) );
        return ERROR_NO_SUCH_PACKAGE;
    }

    flags = CREDUI_FLAGS_ALWAYS_SHOW_UI | CREDUI_FLAGS_GENERIC_CREDENTIALS;

    if (sspi_flags & SSPIPFC_CREDPROV_DO_NOT_SAVE)
        flags |= CREDUI_FLAGS_DO_NOT_PERSIST;

    if (!(sspi_flags & SSPIPFC_NO_CHECKBOX))
        flags |= CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX;

    if (!id) find_existing_credential( target, username, len_username, password, len_password );
    else
    {
        if (id->User && id->UserLength > 0 && id->UserLength <= CREDUI_MAX_USERNAME_LENGTH)
        {
            memcpy( username, id->User, id->UserLength * sizeof(WCHAR) );
            username[id->UserLength] = 0;
        }
        if (id->Password && id->PasswordLength > 0 && id->PasswordLength <= CREDUI_MAX_PASSWORD_LENGTH)
        {
            memcpy( password, id->Password, id->PasswordLength * sizeof(WCHAR) );
            password[id->PasswordLength] = 0;
        }
    }

    if (!(ret = CredUIPromptForCredentialsW( cred_info, target, NULL, error, username,
                                             len_username, password, len_password, save, flags )))
    {
        DWORD size = sizeof(*id), len_domain = 0;
        WCHAR *ptr, *user = username, *domain = NULL;

        if ((ptr = strchrW( username, '\\' )))
        {
            user = ptr + 1;
            len_username = strlenW( user );
            if (!strcmpiW( package, ntlmW ) || !strcmpiW( package, negotiateW ))
            {
                domain = username;
                len_domain = ptr - username;
            }
            *ptr = 0;
        }
        else len_username = strlenW( username );
        len_password = strlenW( password );

        size += (len_username + 1) * sizeof(WCHAR);
        size += (len_domain + 1) * sizeof(WCHAR);
        size += (len_password + 1) * sizeof(WCHAR);
        if (!(id = HeapAlloc( GetProcessHeap(), 0, size ))) return ERROR_OUTOFMEMORY;
        ptr = (WCHAR *)(id + 1);

        memcpy( ptr, user, (len_username + 1) * sizeof(WCHAR) );
        id->User           = ptr;
        id->UserLength     = len_username;
        ptr += len_username + 1;
        if (len_domain)
        {
            memcpy( ptr, domain, (len_domain + 1) * sizeof(WCHAR) );
            id->Domain         = ptr;
            id->DomainLength   = len_domain;
            ptr += len_domain + 1;
        }
        else
        {
            id->Domain         = NULL;
            id->DomainLength   = 0;
        }
        memcpy( ptr, password, (len_password + 1) * sizeof(WCHAR) );
        id->Password       = ptr;
        id->PasswordLength = len_password;
        id->Flags          = 0;

        *output_id = id;
    }

    return ret;
}

/******************************************************************************
 * CredUIPromptForWindowsCredentialsW [CREDUI.@]
 */
DWORD WINAPI CredUIPromptForWindowsCredentialsW( CREDUI_INFOW *info, DWORD error, ULONG *package,
                                                 const void *in_buf, ULONG in_buf_size, void **out_buf,
                                                 ULONG *out_buf_size, BOOL *save, DWORD flags )
{
    FIXME( "(%p, %u, %p, %p, %u, %p, %p, %p, %08x) stub\n", info, error, package, in_buf, in_buf_size,
           out_buf, out_buf_size, save, flags );
    return ERROR_CALL_NOT_IMPLEMENTED;
}

/******************************************************************************
 * CredPackAuthenticationBufferW [CREDUI.@]
 */
BOOL  WINAPI CredPackAuthenticationBufferW( DWORD flags, WCHAR *username, WCHAR *password, BYTE *buf,
                                            DWORD *size )
{
    FIXME( "(%08x, %s, %p, %p, %p) stub\n", flags, debugstr_w(username), password, buf, size );
    return ERROR_CALL_NOT_IMPLEMENTED;
}

/******************************************************************************
 * CredUnPackAuthenticationBufferW [CREDUI.@]
 */
BOOL  WINAPI CredUnPackAuthenticationBufferW( DWORD flags, void *buf, DWORD size, WCHAR *username,
                                              DWORD *len_username, WCHAR *domain, DWORD *len_domain,
                                              WCHAR *password, DWORD *len_password )
{
    FIXME( "(%08x, %p, %u, %p, %p, %p, %p, %p, %p) stub\n", flags, buf, size, username, len_username,
           domain, len_domain, password, len_password );
    return ERROR_CALL_NOT_IMPLEMENTED;
}
