/*
 * Copyright 2008 Juan Lang
 *
 * 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 "config.h"

#include <stdarg.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winuser.h"
#include "softpub.h"
#include "wingdi.h"
#include "richedit.h"
#include "ole2.h"
#include "richole.h"
#include "commdlg.h"
#include "commctrl.h"
#include "cryptuiapi.h"
#include "cryptuires.h"
#include "urlmon.h"
#include "hlink.h"
#include "winreg.h"
#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(cryptui);

static HINSTANCE hInstance;

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

    switch (fdwReason)
    {
        case DLL_WINE_PREATTACH:
            return FALSE;    /* prefer native version */
        case DLL_PROCESS_ATTACH:
            hInstance = hinstDLL;
            DisableThreadLibraryCalls(hinstDLL);
            break;
        case DLL_PROCESS_DETACH:
            break;
        default:
            break;
    }
    return TRUE;
}

#define MAX_STRING_LEN 512

static void add_cert_columns(HWND hwnd)
{
    HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
    RECT rc;
    WCHAR buf[MAX_STRING_LEN];
    LVCOLUMNW column;

    SendMessageW(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
    GetWindowRect(lv, &rc);
    LoadStringW(hInstance, IDS_SUBJECT_COLUMN, buf,
     sizeof(buf) / sizeof(buf[0]));
    column.mask = LVCF_WIDTH | LVCF_TEXT;
    column.cx = (rc.right - rc.left) * 29 / 100 - 2;
    column.pszText = buf;
    SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
    LoadStringW(hInstance, IDS_ISSUER_COLUMN, buf,
     sizeof(buf) / sizeof(buf[0]));
    SendMessageW(lv, LVM_INSERTCOLUMNW, 1, (LPARAM)&column);
    column.cx = (rc.right - rc.left) * 16 / 100 - 2;
    LoadStringW(hInstance, IDS_EXPIRATION_COLUMN, buf,
     sizeof(buf) / sizeof(buf[0]));
    SendMessageW(lv, LVM_INSERTCOLUMNW, 2, (LPARAM)&column);
    column.cx = (rc.right - rc.left) * 23 / 100 - 1;
    LoadStringW(hInstance, IDS_FRIENDLY_NAME_COLUMN, buf,
     sizeof(buf) / sizeof(buf[0]));
    SendMessageW(lv, LVM_INSERTCOLUMNW, 3, (LPARAM)&column);
}

static void add_cert_to_view(HWND lv, PCCERT_CONTEXT cert, DWORD *allocatedLen,
 LPWSTR *str)
{
    DWORD len;
    LVITEMW item;
    WCHAR dateFmt[80]; /* sufficient for LOCALE_SSHORTDATE */
    WCHAR date[80];
    SYSTEMTIME sysTime;
    LPWSTR none;

    item.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_TEXT;
    item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
    item.iSubItem = 0;
    item.iImage = 0;
    item.lParam = (LPARAM)CertDuplicateCertificateContext(cert);
    len = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
     NULL, 0);
    if (len > *allocatedLen)
    {
        HeapFree(GetProcessHeap(), 0, *str);
        *str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (*str)
            *allocatedLen = len;
    }
    if (*str)
    {
        CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
         *str, len);
        item.pszText = *str;
        SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
    }

    item.mask = LVIF_TEXT;
    len = CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
     CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
    if (len > *allocatedLen)
    {
        HeapFree(GetProcessHeap(), 0, *str);
        *str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (*str)
            *allocatedLen = len;
    }
    if (*str)
    {
        CertGetNameStringW(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
         CERT_NAME_ISSUER_FLAG, NULL, *str, len);
        item.pszText = *str;
        item.iSubItem = 1;
        SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    }

    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt,
     sizeof(dateFmt) / sizeof(dateFmt[0]));
    FileTimeToSystemTime(&cert->pCertInfo->NotAfter, &sysTime);
    GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date,
     sizeof(date) / sizeof(date[0]));
    item.pszText = date;
    item.iSubItem = 2;
    SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);

    if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
     NULL, &len))
        len = LoadStringW(hInstance, IDS_FRIENDLY_NAME_NONE, (LPWSTR)&none, 0);
    if (len > *allocatedLen)
    {
        HeapFree(GetProcessHeap(), 0, *str);
        *str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (*str)
            *allocatedLen = len;
    }
    if (*str)
    {
        if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID,
         *str, &len))
            item.pszText = none;
        else
            item.pszText = *str;
        item.iSubItem = 3;
        SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    }
}

static LPSTR get_cert_mgr_usages(void)
{
    static const WCHAR keyName[] = { 'S','o','f','t','w','a','r','e','\\','M',
     'i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r','a',
     'p','h','y','\\','U','I','\\','C','e','r','t','m','g','r','\\','P','u',
     'r','p','o','s','e',0 };
    LPSTR str = NULL;
    HKEY key;

    if (!RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_READ,
     NULL, &key, NULL))
    {
        LONG rc;
        DWORD type, size;

        rc = RegQueryValueExA(key, "Purpose", NULL, &type, NULL, &size);
        if ((!rc || rc == ERROR_MORE_DATA) && type == REG_SZ)
        {
            str = HeapAlloc(GetProcessHeap(), 0, size);
            if (str)
            {
                rc = RegQueryValueExA(key, "Purpose", NULL, NULL, (LPBYTE)str,
                 &size);
                if (rc)
                {
                    HeapFree(GetProcessHeap(), 0, str);
                    str = NULL;
                }
            }
        }
        RegCloseKey(key);
    }
    return str;
}

typedef enum {
    PurposeFilterShowAll = 0,
    PurposeFilterShowAdvanced = 1,
    PurposeFilterShowOID = 2
} PurposeFilter;

static void initialize_purpose_selection(HWND hwnd)
{
    HWND cb = GetDlgItem(hwnd, IDC_MGR_PURPOSE_SELECTION);
    WCHAR buf[MAX_STRING_LEN];
    LPSTR usages;
    int index;

    LoadStringW(hInstance, IDS_PURPOSE_ALL, buf,
     sizeof(buf) / sizeof(buf[0]));
    index = SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
    SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)PurposeFilterShowAll);
    LoadStringW(hInstance, IDS_PURPOSE_ADVANCED, buf,
     sizeof(buf) / sizeof(buf[0]));
    index = SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
    SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)PurposeFilterShowAdvanced);
    SendMessageW(cb, CB_SETCURSEL, 0, 0);
    if ((usages = get_cert_mgr_usages()))
    {
        LPSTR ptr, comma;

        for (ptr = usages, comma = strchr(ptr, ','); ptr && *ptr;
         ptr = comma ? comma + 1 : NULL,
         comma = ptr ? strchr(ptr, ',') : NULL)
        {
            PCCRYPT_OID_INFO info;

            if (comma)
                *comma = 0;
            if ((info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, ptr, 0)))
            {
                index = SendMessageW(cb, CB_INSERTSTRING, 0,
                 (LPARAM)info->pwszName);
                SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)info);
            }
        }
        HeapFree(GetProcessHeap(), 0, usages);
    }
}

extern BOOL WINAPI WTHelperGetKnownUsages(DWORD action,
 PCCRYPT_OID_INFO **usages);

static CERT_ENHKEY_USAGE *add_oid_to_usage(CERT_ENHKEY_USAGE *usage, LPSTR oid)
{
    if (!usage->cUsageIdentifier)
        usage->rgpszUsageIdentifier = HeapAlloc(GetProcessHeap(), 0,
         sizeof(LPSTR));
    else
        usage->rgpszUsageIdentifier = HeapReAlloc(GetProcessHeap(), 0,
         usage->rgpszUsageIdentifier,
         (usage->cUsageIdentifier + 1) * sizeof(LPSTR));
    if (usage->rgpszUsageIdentifier)
        usage->rgpszUsageIdentifier[usage->cUsageIdentifier++] = oid;
    else
    {
        HeapFree(GetProcessHeap(), 0, usage);
        usage = NULL;
    }
    return usage;
}

static CERT_ENHKEY_USAGE *convert_usages_str_to_usage(LPSTR usageStr)
{
    CERT_ENHKEY_USAGE *usage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
     sizeof(CERT_ENHKEY_USAGE));

    if (usage)
    {
        LPSTR ptr, comma;

        for (ptr = usageStr, comma = strchr(ptr, ','); usage && ptr && *ptr;
         ptr = comma ? comma + 1 : NULL,
         comma = ptr ? strchr(ptr, ',') : NULL)
        {
            if (comma)
                *comma = 0;
            add_oid_to_usage(usage, ptr);
        }
    }
    return usage;
}

static CERT_ENHKEY_USAGE *create_advanced_filter(void)
{
    CERT_ENHKEY_USAGE *advancedUsage = HeapAlloc(GetProcessHeap(),
     HEAP_ZERO_MEMORY, sizeof(CERT_ENHKEY_USAGE));

    if (advancedUsage)
    {
        PCCRYPT_OID_INFO *usages;

        if (WTHelperGetKnownUsages(1, &usages))
        {
            LPSTR disabledUsagesStr;

            if ((disabledUsagesStr = get_cert_mgr_usages()))
            {
                CERT_ENHKEY_USAGE *disabledUsages =
                 convert_usages_str_to_usage(disabledUsagesStr);

                if (disabledUsages)
                {
                    PCCRYPT_OID_INFO *ptr;

                    for (ptr = usages; *ptr; ptr++)
                    {
                        DWORD i;
                        BOOL disabled = FALSE;

                        for (i = 0; !disabled &&
                         i < disabledUsages->cUsageIdentifier; i++)
                            if (!strcmp(disabledUsages->rgpszUsageIdentifier[i],
                             (*ptr)->pszOID))
                                disabled = TRUE;
                        if (!disabled)
                            add_oid_to_usage(advancedUsage,
                             (LPSTR)(*ptr)->pszOID);
                    }
                    /* The individual strings are pointers to disabledUsagesStr,
                     * so they're freed when it is.
                     */
                    HeapFree(GetProcessHeap(), 0,
                     disabledUsages->rgpszUsageIdentifier);
                    HeapFree(GetProcessHeap(), 0, disabledUsages);
                }
                HeapFree(GetProcessHeap(), 0, disabledUsagesStr);
            }
            WTHelperGetKnownUsages(2, &usages);
        }
    }
    return advancedUsage;
}

static int CALLBACK cert_mgr_sort_by_subject(LPARAM lp1, LPARAM lp2, LPARAM lp);

static void show_store_certs(HWND hwnd, HCERTSTORE store)
{
    HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
    HWND cb = GetDlgItem(hwnd, IDC_MGR_PURPOSE_SELECTION);
    PCCERT_CONTEXT cert = NULL;
    DWORD allocatedLen = 0;
    LPWSTR str = NULL;
    int index;
    PurposeFilter filter = PurposeFilterShowAll;
    LPCSTR oid = NULL;
    CERT_ENHKEY_USAGE *advanced = NULL;

    index = SendMessageW(cb, CB_GETCURSEL, 0, 0);
    if (index >= 0)
    {
        INT_PTR data = SendMessageW(cb, CB_GETITEMDATA, index, 0);

        if (!HIWORD(data))
            filter = data;
        else
        {
            PCCRYPT_OID_INFO info = (PCCRYPT_OID_INFO)data;

            filter = PurposeFilterShowOID;
            oid = info->pszOID;
        }
    }
    if (filter == PurposeFilterShowAdvanced)
        advanced = create_advanced_filter();
    do {
        cert = CertEnumCertificatesInStore(store, cert);
        if (cert)
        {
            BOOL show = FALSE;

            if (filter == PurposeFilterShowAll)
                show = TRUE;
            else
            {
                int numOIDs;
                DWORD cbOIDs = 0;

                if (CertGetValidUsages(1, &cert, &numOIDs, NULL, &cbOIDs))
                {
                    if (numOIDs == -1)
                    {
                        /* -1 implies all usages are valid */
                        show = TRUE;
                    }
                    else
                    {
                        LPSTR *oids = HeapAlloc(GetProcessHeap(), 0, cbOIDs);

                        if (oids)
                        {
                            if (CertGetValidUsages(1, &cert, &numOIDs, oids,
                             &cbOIDs))
                            {
                                int i;

                                if (filter == PurposeFilterShowOID)
                                {
                                    for (i = 0; !show && i < numOIDs; i++)
                                        if (!strcmp(oids[i], oid))
                                            show = TRUE;
                                }
                                else
                                {
                                    for (i = 0; !show && i < numOIDs; i++)
                                    {
                                        DWORD j;

                                        for (j = 0; !show &&
                                         j < advanced->cUsageIdentifier; j++)
                                            if (!strcmp(oids[i],
                                             advanced->rgpszUsageIdentifier[j]))
                                                show = TRUE;
                                    }
                                }
                            }
                            HeapFree(GetProcessHeap(), 0, oids);
                        }
                    }
                }
            }
            if (show)
                add_cert_to_view(lv, cert, &allocatedLen, &str);
        }
    } while (cert);
    HeapFree(GetProcessHeap(), 0, str);
    if (advanced)
    {
        HeapFree(GetProcessHeap(), 0, advanced->rgpszUsageIdentifier);
        HeapFree(GetProcessHeap(), 0, advanced);
    }
    SendMessageW(lv, LVM_SORTITEMSEX, (WPARAM)lv,
     (LPARAM)cert_mgr_sort_by_subject);
}

static const WCHAR my[] = { 'M','y',0 };
static const WCHAR addressBook[] = {
 'A','d','d','r','e','s','s','B','o','o','k',0 };
static const WCHAR ca[] = { 'C','A',0 };
static const WCHAR root[] = { 'R','o','o','t',0 };
static const WCHAR trustedPublisher[] = {
 'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0 };
static const WCHAR disallowed[] = { 'D','i','s','a','l','l','o','w','e','d',0 };

struct CertMgrStoreInfo
{
    LPCWSTR name;
    int removeWarning;
    int removePluralWarning;
};

static const struct CertMgrStoreInfo defaultStoreList[] = {
 { my, IDS_WARN_REMOVE_MY, IDS_WARN_REMOVE_PLURAL_MY },
 { addressBook, IDS_WARN_REMOVE_ADDRESSBOOK,
   IDS_WARN_REMOVE_PLURAL_ADDRESSBOOK },
 { ca, IDS_WARN_REMOVE_CA, IDS_WARN_REMOVE_PLURAL_CA },
 { root, IDS_WARN_REMOVE_ROOT, IDS_WARN_REMOVE_PLURAL_ROOT },
 { trustedPublisher, IDS_WARN_REMOVE_TRUSTEDPUBLISHER,
   IDS_WARN_REMOVE_PLURAL_TRUSTEDPUBLISHER },
 { disallowed, IDS_WARN_REMOVE_DEFAULT },
};

static const struct CertMgrStoreInfo publisherStoreList[] = {
 { root, IDS_WARN_REMOVE_ROOT, IDS_WARN_REMOVE_PLURAL_ROOT },
 { trustedPublisher, IDS_WARN_REMOVE_TRUSTEDPUBLISHER,
   IDS_WARN_REMOVE_PLURAL_TRUSTEDPUBLISHER },
 { disallowed, IDS_WARN_REMOVE_PLURAL_DEFAULT },
};

struct CertMgrData
{
    HIMAGELIST imageList;
    LPCWSTR title;
    DWORD nStores;
    const struct CertMgrStoreInfo *stores;
};

static void show_cert_stores(HWND hwnd, DWORD dwFlags, struct CertMgrData *data)
{
    const struct CertMgrStoreInfo *storeList;
    int cStores, i;
    HWND tab = GetDlgItem(hwnd, IDC_MGR_STORES);

    if (dwFlags & CRYPTUI_CERT_MGR_PUBLISHER_TAB)
    {
        storeList = publisherStoreList;
        cStores = sizeof(publisherStoreList) / sizeof(publisherStoreList[0]);
    }
    else
    {
        storeList = defaultStoreList;
        cStores = sizeof(defaultStoreList) / sizeof(defaultStoreList[0]);
    }
    if (dwFlags & CRYPTUI_CERT_MGR_SINGLE_TAB_FLAG)
        cStores = 1;
    data->nStores = cStores;
    data->stores = storeList;
    for (i = 0; i < cStores; i++)
    {
        LPCWSTR name;
        TCITEMW item;
        HCERTSTORE store;

        if (!(name = CryptFindLocalizedName(storeList[i].name)))
            name = storeList[i].name;
        store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, storeList[i].name);
        item.mask = TCIF_TEXT | TCIF_PARAM;
        item.pszText = (LPWSTR)name;
        item.lParam = (LPARAM)store;
        SendMessageW(tab, TCM_INSERTITEMW, i, (LPARAM)&item);
    }
}

static void free_certs(HWND lv)
{
    LVITEMW item;
    int items = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0), i;

    for (i = 0; i < items; i++)
    {
        item.mask = LVIF_PARAM;
        item.iItem = i;
        item.iSubItem = 0;
        SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item);
        CertFreeCertificateContext((PCCERT_CONTEXT)item.lParam);
    }
}

static HCERTSTORE cert_mgr_index_to_store(HWND tab, int index)
{
    TCITEMW item;

    item.mask = TCIF_PARAM;
    SendMessageW(tab, TCM_GETITEMW, index, (LPARAM)&item);
    return (HCERTSTORE)item.lParam;
}

static HCERTSTORE cert_mgr_current_store(HWND hwnd)
{
    HWND tab = GetDlgItem(hwnd, IDC_MGR_STORES);

    return cert_mgr_index_to_store(tab, SendMessageW(tab, TCM_GETCURSEL, 0, 0));
}

static void close_stores(HWND tab)
{
    int i, tabs = SendMessageW(tab, TCM_GETITEMCOUNT, 0, 0);

    for (i = 0; i < tabs; i++)
        CertCloseStore(cert_mgr_index_to_store(tab, i), 0);
}

static void refresh_store_certs(HWND hwnd)
{
    HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);

    free_certs(lv);
    SendMessageW(lv, LVM_DELETEALLITEMS, 0, 0);
    show_store_certs(hwnd, cert_mgr_current_store(hwnd));
}

typedef enum {
    CheckBitmapIndexUnchecked = 1,
    CheckBitmapIndexChecked = 2,
    CheckBitmapIndexDisabledUnchecked = 3,
    CheckBitmapIndexDisabledChecked = 4
} CheckBitmapIndex;

static void add_known_usage(HWND lv, PCCRYPT_OID_INFO info,
 CheckBitmapIndex state)
{
    LVITEMW item;

    item.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
    item.state = INDEXTOSTATEIMAGEMASK(state);
    item.stateMask = LVIS_STATEIMAGEMASK;
    item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
    item.iSubItem = 0;
    item.lParam = (LPARAM)info;
    item.pszText = (LPWSTR)info->pwszName;
    SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
}

static void add_known_usages_to_list(HWND lv, CheckBitmapIndex state)
{
    PCCRYPT_OID_INFO *usages;

    if (WTHelperGetKnownUsages(1, &usages))
    {
        PCCRYPT_OID_INFO *ptr;

        for (ptr = usages; *ptr; ptr++)
            add_known_usage(lv, *ptr, state);
        WTHelperGetKnownUsages(2, &usages);
    }
}

static void toggle_usage(HWND hwnd, int iItem)
{
    LVITEMW item;
    int res;
    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);

    item.mask = LVIF_STATE;
    item.iItem = iItem;
    item.iSubItem = 0;
    item.stateMask = LVIS_STATEIMAGEMASK;
    res = SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item);
    if (res)
    {
        int state = item.state >> 12;

        item.state = INDEXTOSTATEIMAGEMASK(
         state == CheckBitmapIndexChecked ? CheckBitmapIndexUnchecked :
         CheckBitmapIndexChecked);
        SendMessageW(lv, LVM_SETITEMSTATE, iItem, (LPARAM)&item);
    }
}

static LONG_PTR find_oid_in_list(HWND lv, LPCSTR oid)
{
    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
     (void *)oid, CRYPT_ENHKEY_USAGE_OID_GROUP_ID);
    LONG_PTR ret;

    if (oidInfo)
    {
        LVFINDINFOW findInfo;

        findInfo.flags = LVFI_PARAM;
        findInfo.lParam = (LPARAM)oidInfo;
        ret = SendMessageW(lv, LVM_FINDITEMW, -1, (LPARAM)&findInfo);
    }
    else
    {
        LVFINDINFOA findInfo;

        findInfo.flags = LVFI_STRING;
        findInfo.psz = oid;
        ret = SendMessageW(lv, LVM_FINDITEMA, -1, (LPARAM)&findInfo);
    }
    return ret;
}

static void save_cert_mgr_usages(HWND hwnd)
{
    static const WCHAR keyName[] = { 'S','o','f','t','w','a','r','e','\\','M',
     'i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r','a',
     'p','h','y','\\','U','I','\\','C','e','r','t','m','g','r','\\','P','u',
     'r','p','o','s','e',0 };
    HKEY key;
    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
    int purposes = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0), i;
    LVITEMW item;
    LPSTR str = NULL;

    item.mask = LVIF_STATE | LVIF_PARAM;
    item.iSubItem = 0;
    item.stateMask = LVIS_STATEIMAGEMASK;
    for (i = 0; i < purposes; i++)
    {
        item.iItem = i;
        if (SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item))
        {
            int state = item.state >> 12;

            if (state == CheckBitmapIndexUnchecked)
            {
                CRYPT_OID_INFO *info = (CRYPT_OID_INFO *)item.lParam;
                BOOL firstString = TRUE;

                if (!str)
                    str = HeapAlloc(GetProcessHeap(), 0,
                     strlen(info->pszOID) + 1);
                else
                {
                    str = HeapReAlloc(GetProcessHeap(), 0, str,
                     strlen(str) + 1 + strlen(info->pszOID) + 1);
                    firstString = FALSE;
                }
                if (str)
                {
                    LPSTR ptr = firstString ? str : str + strlen(str);

                    if (!firstString)
                        *ptr++ = ',';
                    strcpy(ptr, info->pszOID);
                }
            }
        }
    }
    if (!RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_ALL_ACCESS,
     NULL, &key, NULL))
    {
        if (str)
            RegSetValueExA(key, "Purpose", 0, REG_SZ, (const BYTE *)str,
             strlen(str) + 1);
        else
            RegDeleteValueA(key, "Purpose");
        RegCloseKey(key);
    }
    HeapFree(GetProcessHeap(), 0, str);
}

static LRESULT CALLBACK cert_mgr_advanced_dlg_proc(HWND hwnd, UINT msg,
 WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_INITDIALOG:
    {
        RECT rc;
        LVCOLUMNW column;
        HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
        HIMAGELIST imageList;
        LPSTR disabledUsages;

        GetWindowRect(lv, &rc);
        column.mask = LVCF_WIDTH;
        column.cx = rc.right - rc.left;
        SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
        imageList = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 4, 0);
        if (imageList)
        {
            HBITMAP bmp;
            COLORREF backColor = RGB(255, 0, 255);

            bmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_CHECKS));
            ImageList_AddMasked(imageList, bmp, backColor);
            DeleteObject(bmp);
            ImageList_SetBkColor(imageList, CLR_NONE);
            SendMessageW(lv, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)imageList);
            SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)imageList);
        }
        add_known_usages_to_list(lv, CheckBitmapIndexChecked);
        if ((disabledUsages = get_cert_mgr_usages()))
        {
            LPSTR ptr, comma;

            for (ptr = disabledUsages, comma = strchr(ptr, ','); ptr && *ptr;
             ptr = comma ? comma + 1 : NULL,
             comma = ptr ? strchr(ptr, ',') : NULL)
            {
                LONG_PTR index;

                if (comma)
                    *comma = 0;
                if ((index = find_oid_in_list(lv, ptr)) != -1)
                    toggle_usage(hwnd, index);
            }
            HeapFree(GetProcessHeap(), 0, disabledUsages);
        }
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;
        NMITEMACTIVATE *nm;

        switch (hdr->code)
        {
        case NM_CLICK:
            nm = (NMITEMACTIVATE *)lp;
            toggle_usage(hwnd, nm->iItem);
            SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
            break;
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDOK:
            save_cert_mgr_usages(hwnd);
            ImageList_Destroy((HIMAGELIST)GetWindowLongPtrW(hwnd, DWLP_USER));
            EndDialog(hwnd, IDOK);
            break;
        case IDCANCEL:
            ImageList_Destroy((HIMAGELIST)GetWindowLongPtrW(hwnd, DWLP_USER));
            EndDialog(hwnd, IDCANCEL);
            break;
        }
        break;
    }
    return 0;
}

static void cert_mgr_clear_cert_selection(HWND hwnd)
{
    WCHAR empty[] = { 0 };

    EnableWindow(GetDlgItem(hwnd, IDC_MGR_EXPORT), FALSE);
    EnableWindow(GetDlgItem(hwnd, IDC_MGR_REMOVE), FALSE);
    EnableWindow(GetDlgItem(hwnd, IDC_MGR_VIEW), FALSE);
    SendMessageW(GetDlgItem(hwnd, IDC_MGR_PURPOSES), WM_SETTEXT, 0,
     (LPARAM)empty);
    refresh_store_certs(hwnd);
}

static PCCERT_CONTEXT cert_mgr_index_to_cert(HWND hwnd, int index)
{
    PCCERT_CONTEXT cert = NULL;
    LVITEMW item;

    item.mask = LVIF_PARAM;
    item.iItem = index;
    item.iSubItem = 0;
    if (SendMessageW(GetDlgItem(hwnd, IDC_MGR_CERTS), LVM_GETITEMW, 0,
     (LPARAM)&item))
        cert = (PCCERT_CONTEXT)item.lParam;
    return cert;
}

static void show_selected_cert(HWND hwnd, int index)
{
    PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd, index);

    if (cert)
    {
        CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;

        memset(&viewInfo, 0, sizeof(viewInfo));
        viewInfo.dwSize = sizeof(viewInfo);
        viewInfo.hwndParent = hwnd;
        viewInfo.pCertContext = cert;
        /* FIXME: this should be modal */
        CryptUIDlgViewCertificateW(&viewInfo, NULL);
    }
}

static void cert_mgr_show_cert_usages(HWND hwnd, int index)
{
    HWND text = GetDlgItem(hwnd, IDC_MGR_PURPOSES);
    PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd, index);
    PCERT_ENHKEY_USAGE usage;
    DWORD size;

    /* Get enhanced key usage.  Have to check for a property and an extension
     * separately, because CertGetEnhancedKeyUsage will succeed and return an
     * empty usage if neither is set.  Unfortunately an empty usage implies
     * no usage is allowed, so we have to distinguish between the two cases.
     */
    if (CertGetEnhancedKeyUsage(cert, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
     NULL, &size))
    {
        usage = HeapAlloc(GetProcessHeap(), 0, size);
        if (!CertGetEnhancedKeyUsage(cert,
         CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
        {
            HeapFree(GetProcessHeap(), 0, usage);
            usage = NULL;
        }
    }
    else if (CertGetEnhancedKeyUsage(cert, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
     NULL, &size))
    {
        usage = HeapAlloc(GetProcessHeap(), 0, size);
        if (!CertGetEnhancedKeyUsage(cert,
         CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
        {
            HeapFree(GetProcessHeap(), 0, usage);
            usage = NULL;
        }
    }
    else
        usage = NULL;
    if (usage)
    {
        if (usage->cUsageIdentifier)
        {
            static const WCHAR commaSpace[] = { ',',' ',0 };
            DWORD i, len = 1;
            LPWSTR str, ptr;

            for (i = 0; i < usage->cUsageIdentifier; i++)
            {
                PCCRYPT_OID_INFO info =
                 CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
                 usage->rgpszUsageIdentifier[i],
                 CRYPT_ENHKEY_USAGE_OID_GROUP_ID);

                if (info)
                    len += strlenW(info->pwszName);
                else
                    len += strlen(usage->rgpszUsageIdentifier[i]);
                if (i < usage->cUsageIdentifier - 1)
                    len += strlenW(commaSpace);
            }
            str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
            if (str)
            {
                for (i = 0, ptr = str; i < usage->cUsageIdentifier; i++)
                {
                    PCCRYPT_OID_INFO info =
                     CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
                     usage->rgpszUsageIdentifier[i],
                     CRYPT_ENHKEY_USAGE_OID_GROUP_ID);

                    if (info)
                    {
                        strcpyW(ptr, info->pwszName);
                        ptr += strlenW(info->pwszName);
                    }
                    else
                    {
                        LPCSTR src = usage->rgpszUsageIdentifier[i];

                        for (; *src; ptr++, src++)
                            *ptr = *src;
                        *ptr = 0;
                    }
                    if (i < usage->cUsageIdentifier - 1)
                    {
                        strcpyW(ptr, commaSpace);
                        ptr += strlenW(commaSpace);
                    }
                }
                *ptr = 0;
                SendMessageW(text, WM_SETTEXT, 0, (LPARAM)str);
                HeapFree(GetProcessHeap(), 0, str);
            }
            HeapFree(GetProcessHeap(), 0, usage);
        }
        else
        {
            WCHAR buf[MAX_STRING_LEN];

            LoadStringW(hInstance, IDS_ALLOWED_PURPOSE_NONE, buf,
             sizeof(buf) / sizeof(buf[0]));
            SendMessageW(text, WM_SETTEXT, 0, (LPARAM)buf);
        }
    }
    else
    {
        WCHAR buf[MAX_STRING_LEN];

        LoadStringW(hInstance, IDS_ALLOWED_PURPOSE_ALL, buf,
         sizeof(buf) / sizeof(buf[0]));
        SendMessageW(text, WM_SETTEXT, 0, (LPARAM)buf);
    }
}

static void cert_mgr_do_remove(HWND hwnd)
{
    int tabIndex = SendMessageW(GetDlgItem(hwnd, IDC_MGR_STORES),
     TCM_GETCURSEL, 0, 0);
    struct CertMgrData *data =
     (struct CertMgrData *)GetWindowLongPtrW(hwnd, DWLP_USER);

    if (tabIndex < data->nStores)
    {
        HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
        WCHAR warning[MAX_STRING_LEN], title[MAX_STRING_LEN];
        LPCWSTR pTitle;
        int warningID;

        if (SendMessageW(lv, LVM_GETSELECTEDCOUNT, 0, 0) > 1)
            warningID = data->stores[tabIndex].removePluralWarning;
        else
            warningID = data->stores[tabIndex].removeWarning;
        if (data->title)
            pTitle = data->title;
        else
        {
            LoadStringW(hInstance, IDS_CERT_MGR, title,
             sizeof(title) / sizeof(title[0]));
            pTitle = title;
        }
        LoadStringW(hInstance, warningID, warning,
         sizeof(warning) / sizeof(warning[0]));
        if (MessageBoxW(hwnd, warning, pTitle, MB_YESNO) == IDYES)
        {
            int selection = -1;

            do {
                selection = SendMessageW(lv, LVM_GETNEXTITEM, selection,
                 LVNI_SELECTED);
                if (selection >= 0)
                {
                    PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd,
                     selection);

                    CertDeleteCertificateFromStore(cert);
                }
            } while (selection >= 0);
            cert_mgr_clear_cert_selection(hwnd);
        }
    }
}

static void cert_mgr_do_export(HWND hwnd)
{
    HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
    int selectionCount = SendMessageW(lv, LVM_GETSELECTEDCOUNT, 0, 0);

    if (selectionCount == 1)
    {
        int selection = SendMessageW(lv, LVM_GETNEXTITEM, -1,
         LVNI_SELECTED);

        if (selection >= 0)
        {
            PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd, selection);

            if (cert)
            {
                CRYPTUI_WIZ_EXPORT_INFO info;

                info.dwSize = sizeof(info);
                info.pwszExportFileName = NULL;
                info.dwSubjectChoice = CRYPTUI_WIZ_EXPORT_CERT_CONTEXT;
                info.u.pCertContext = cert;
                info.cStores = 0;
                CryptUIWizExport(0, hwnd, NULL, &info, NULL);
            }
        }
    }
    else if (selectionCount > 1)
    {
        HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
         CERT_STORE_CREATE_NEW_FLAG, NULL);

        if (store)
        {
            CRYPTUI_WIZ_EXPORT_INFO info;
            int selection = -1;

            info.dwSize = sizeof(info);
            info.pwszExportFileName = NULL;
            info.dwSubjectChoice =
             CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY;
            info.u.hCertStore = store;
            info.cStores = 0;
            do {
                selection = SendMessageW(lv, LVM_GETNEXTITEM, selection,
                 LVNI_SELECTED);
                if (selection >= 0)
                {
                    PCCERT_CONTEXT cert = cert_mgr_index_to_cert(hwnd,
                     selection);

                    CertAddCertificateContextToStore(store, cert,
                     CERT_STORE_ADD_ALWAYS, NULL);
                }
            } while (selection >= 0);
            CryptUIWizExport(0, hwnd, NULL, &info, NULL);
            CertCloseStore(store, 0);
        }
    }
}

static int cert_mgr_sort_by_text(HWND lv, int col, int index1, int index2)
{
    LVITEMW item;
    WCHAR buf1[MAX_STRING_LEN];
    WCHAR buf2[MAX_STRING_LEN];

    item.cchTextMax = sizeof(buf1) / sizeof(buf1[0]);
    item.mask = LVIF_TEXT;
    item.pszText = buf1;
    item.iItem = index1;
    item.iSubItem = col;
    SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item);
    item.pszText = buf2;
    item.iItem = index2;
    SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item);
    return strcmpW(buf1, buf2);
}

static int CALLBACK cert_mgr_sort_by_subject(LPARAM lp1, LPARAM lp2, LPARAM lp)
{
    return cert_mgr_sort_by_text((HWND)lp, 0, lp1, lp2);
}

static int CALLBACK cert_mgr_sort_by_issuer(LPARAM lp1, LPARAM lp2, LPARAM lp)
{
    return cert_mgr_sort_by_text((HWND)lp, 1, lp1, lp2);
}

static int CALLBACK cert_mgr_sort_by_date(LPARAM lp1, LPARAM lp2, LPARAM lp)
{
    PCCERT_CONTEXT cert1 = (PCCERT_CONTEXT)lp1;
    PCCERT_CONTEXT cert2 = (PCCERT_CONTEXT)lp2;
    return CompareFileTime(&cert1->pCertInfo->NotAfter,
     &cert2->pCertInfo->NotAfter);
}

static int CALLBACK cert_mgr_sort_by_friendly_name(LPARAM lp1, LPARAM lp2,
 LPARAM lp)
{
    return cert_mgr_sort_by_text((HWND)lp, 3, lp1, lp2);
}

static LRESULT CALLBACK cert_mgr_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    struct CertMgrData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr =
         (PCCRYPTUI_CERT_MGR_STRUCT)lp;
        HWND tab = GetDlgItem(hwnd, IDC_MGR_STORES);

        data = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CertMgrData));
        if (!data)
            return 0;
        data->imageList = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 2, 0);
        if (data->imageList)
        {
            HBITMAP bmp;
            COLORREF backColor = RGB(255, 0, 255);

            bmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_SMALL_ICONS));
            ImageList_AddMasked(data->imageList, bmp, backColor);
            DeleteObject(bmp);
            ImageList_SetBkColor(data->imageList, CLR_NONE);
            SendMessageW(GetDlgItem(hwnd, IDC_MGR_CERTS), LVM_SETIMAGELIST,
                         LVSIL_SMALL, (LPARAM)data->imageList);
        }
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        data->title = pCryptUICertMgr->pwszTitle;

        initialize_purpose_selection(hwnd);
        add_cert_columns(hwnd);
        if (pCryptUICertMgr->pwszTitle)
            SendMessageW(hwnd, WM_SETTEXT, 0,
             (LPARAM)pCryptUICertMgr->pwszTitle);
        show_cert_stores(hwnd, pCryptUICertMgr->dwFlags, data);
        show_store_certs(hwnd, cert_mgr_index_to_store(tab, 0));
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case TCN_SELCHANGE:
            cert_mgr_clear_cert_selection(hwnd);
            break;
        case LVN_ITEMCHANGED:
        {
            WCHAR empty[] = { 0 };
            NMITEMACTIVATE *nm = (NMITEMACTIVATE*)lp;
            HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
            int numSelected = SendMessageW(lv, LVM_GETSELECTEDCOUNT, 0, 0);

            EnableWindow(GetDlgItem(hwnd, IDC_MGR_EXPORT), numSelected > 0);
            EnableWindow(GetDlgItem(hwnd, IDC_MGR_REMOVE), numSelected > 0);
            EnableWindow(GetDlgItem(hwnd, IDC_MGR_VIEW), numSelected == 1);
            if (numSelected == 1)
                cert_mgr_show_cert_usages(hwnd, nm->iItem);
            else
                SendMessageW(GetDlgItem(hwnd, IDC_MGR_PURPOSES), WM_SETTEXT, 0,
                 (LPARAM)empty);
            break;
        }
        case NM_DBLCLK:
            show_selected_cert(hwnd, ((NMITEMACTIVATE *)lp)->iItem);
            break;
        case LVN_KEYDOWN:
        {
            NMLVKEYDOWN *lvk = (NMLVKEYDOWN *)lp;

            if (lvk->wVKey == VK_DELETE)
                cert_mgr_do_remove(hwnd);
            break;
        }
        case LVN_COLUMNCLICK:
        {
            NMLISTVIEW *nmlv = (NMLISTVIEW *)lp;
            HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);

            /* FIXME: doesn't support swapping sort order between ascending
             * and descending.
             */
            switch (nmlv->iSubItem)
            {
            case 0:
                SendMessageW(lv, LVM_SORTITEMSEX, (WPARAM)lv,
                 (LPARAM)cert_mgr_sort_by_subject);
                break;
            case 1:
                SendMessageW(lv, LVM_SORTITEMSEX, (WPARAM)lv,
                (LPARAM)cert_mgr_sort_by_issuer);
                break;
            case 2:
                SendMessageW(lv, LVM_SORTITEMS, 0,
                 (LPARAM)cert_mgr_sort_by_date);
                break;
            case 3:
                SendMessageW(lv, LVM_SORTITEMSEX, (WPARAM)lv,
                 (LPARAM)cert_mgr_sort_by_friendly_name);
                break;
            }
            break;
        }
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case ((CBN_SELCHANGE << 16) | IDC_MGR_PURPOSE_SELECTION):
            cert_mgr_clear_cert_selection(hwnd);
            break;
        case IDC_MGR_IMPORT:
            if (CryptUIWizImport(0, hwnd, NULL, NULL,
             cert_mgr_current_store(hwnd)))
                refresh_store_certs(hwnd);
            break;
        case IDC_MGR_ADVANCED:
            if (DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_CERT_MGR_ADVANCED),
             hwnd, cert_mgr_advanced_dlg_proc) == IDOK)
            {
                HWND cb = GetDlgItem(hwnd, IDC_MGR_PURPOSE_SELECTION);
                int index, len;
                LPWSTR curString = NULL;

                index = SendMessageW(cb, CB_GETCURSEL, 0, 0);
                if (index >= 0)
                {
                    len = SendMessageW(cb, CB_GETLBTEXTLEN, index, 0);
                    curString = HeapAlloc(GetProcessHeap(), 0,
                     (len + 1) * sizeof(WCHAR));
                    SendMessageW(cb, CB_GETLBTEXT, index, (LPARAM)curString);
                }
                SendMessageW(cb, CB_RESETCONTENT, 0, 0);
                initialize_purpose_selection(hwnd);
                if (curString)
                {
                    index = SendMessageW(cb, CB_FINDSTRINGEXACT, -1,
                     (LPARAM)curString);
                    if (index >= 0)
                        SendMessageW(cb, CB_SETCURSEL, index, 0);
                    HeapFree(GetProcessHeap(), 0, curString);
                }
                refresh_store_certs(hwnd);
            }
            break;
        case IDC_MGR_VIEW:
        {
            HWND lv = GetDlgItem(hwnd, IDC_MGR_CERTS);
            int selection = SendMessageW(lv, LVM_GETNEXTITEM, -1,
             LVNI_SELECTED);

            if (selection >= 0)
                show_selected_cert(hwnd, selection);
            break;
        }
        case IDC_MGR_EXPORT:
            cert_mgr_do_export(hwnd);
            break;
        case IDC_MGR_REMOVE:
            cert_mgr_do_remove(hwnd);
            break;
        case IDCANCEL:
            free_certs(GetDlgItem(hwnd, IDC_MGR_CERTS));
            close_stores(GetDlgItem(hwnd, IDC_MGR_STORES));
            data = (struct CertMgrData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            ImageList_Destroy(data->imageList);
            HeapFree(GetProcessHeap(), 0, data);
            EndDialog(hwnd, IDCANCEL);
            break;
        }
        break;
    }
    return 0;
}

/***********************************************************************
 *		CryptUIDlgCertMgr (CRYPTUI.@)
 */
BOOL WINAPI CryptUIDlgCertMgr(PCCRYPTUI_CERT_MGR_STRUCT pCryptUICertMgr)
{
    TRACE("(%p)\n", pCryptUICertMgr);

    if (pCryptUICertMgr->dwSize != sizeof(CRYPTUI_CERT_MGR_STRUCT))
    {
        WARN("unexpected size %d\n", pCryptUICertMgr->dwSize);
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_CERT_MGR),
     pCryptUICertMgr->hwndParent, cert_mgr_dlg_proc, (LPARAM)pCryptUICertMgr);
    return TRUE;
}

/* FIXME: real names are unknown, functions are undocumented */
typedef struct _CRYPTUI_ENUM_SYSTEM_STORE_ARGS
{
    DWORD dwFlags;
    void *pvSystemStoreLocationPara;
} CRYPTUI_ENUM_SYSTEM_STORE_ARGS, *PCRYPTUI_ENUM_SYSTEM_STORE_ARGS;

typedef struct _CRYPTUI_ENUM_DATA
{
    DWORD                           cStores;
    HCERTSTORE                     *rghStore;
    DWORD                           cEnumArgs;
    PCRYPTUI_ENUM_SYSTEM_STORE_ARGS rgEnumArgs;
} CRYPTUI_ENUM_DATA, *PCRYPTUI_ENUM_DATA;

typedef BOOL (WINAPI *PFN_SELECTED_STORE_CB)(HCERTSTORE store, HWND hwnd,
 void *pvArg);

/* Values for dwFlags */
#define CRYPTUI_ENABLE_SHOW_PHYSICAL_STORE 0x00000001

typedef struct _CRYPTUI_SELECTSTORE_INFO_A
{
    DWORD                 dwSize;
    HWND                  parent;
    DWORD                 dwFlags;
    LPSTR                 pszTitle;
    LPSTR                 pszText;
    CRYPTUI_ENUM_DATA    *pEnumData;
    PFN_SELECTED_STORE_CB pfnSelectedStoreCallback;
    void                 *pvArg;
} CRYPTUI_SELECTSTORE_INFO_A, *PCRYPTUI_SELECTSTORE_INFO_A;

typedef struct _CRYPTUI_SELECTSTORE_INFO_W
{
    DWORD                 dwSize;
    HWND                  parent;
    DWORD                 dwFlags;
    LPWSTR                pwszTitle;
    LPWSTR                pwszText;
    CRYPTUI_ENUM_DATA    *pEnumData;
    PFN_SELECTED_STORE_CB pfnSelectedStoreCallback;
    void                 *pvArg;
} CRYPTUI_SELECTSTORE_INFO_W, *PCRYPTUI_SELECTSTORE_INFO_W;

struct StoreInfo
{
    enum {
        StoreHandle,
        SystemStore
    } type;
    union {
        HCERTSTORE store;
        LPWSTR name;
    } DUMMYUNIONNAME;
};

static BOOL WINAPI enum_store_callback(const void *pvSystemStore,
 DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved,
 void *pvArg)
{
    HWND tree = GetDlgItem(pvArg, IDC_STORE_LIST);
    TVINSERTSTRUCTW tvis;
    LPCWSTR localizedName;
    BOOL ret = TRUE;

    tvis.hParent = NULL;
    tvis.hInsertAfter = TVI_LAST;
    tvis.u.item.mask = TVIF_TEXT;
    if ((localizedName = CryptFindLocalizedName(pvSystemStore)))
    {
        struct StoreInfo *storeInfo = HeapAlloc(GetProcessHeap(), 0,
         sizeof(struct StoreInfo));

        if (storeInfo)
        {
            storeInfo->type = SystemStore;
            storeInfo->u.name = HeapAlloc(GetProcessHeap(), 0,
             (strlenW(pvSystemStore) + 1) * sizeof(WCHAR));
            if (storeInfo->u.name)
            {
                tvis.u.item.mask |= TVIF_PARAM;
                tvis.u.item.lParam = (LPARAM)storeInfo;
                strcpyW(storeInfo->u.name, pvSystemStore);
            }
            else
            {
                HeapFree(GetProcessHeap(), 0, storeInfo);
                ret = FALSE;
            }
        }
        else
            ret = FALSE;
        tvis.u.item.pszText = (LPWSTR)localizedName;
    }
    else
        tvis.u.item.pszText = (LPWSTR)pvSystemStore;
    /* FIXME: need a folder icon for the store too */
    if (ret)
        SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
    return ret;
}

static void enumerate_stores(HWND hwnd, CRYPTUI_ENUM_DATA *pEnumData)
{
    DWORD i;
    HWND tree = GetDlgItem(hwnd, IDC_STORE_LIST);

    for (i = 0; i < pEnumData->cEnumArgs; i++)
        CertEnumSystemStore(pEnumData->rgEnumArgs[i].dwFlags,
         pEnumData->rgEnumArgs[i].pvSystemStoreLocationPara,
         hwnd, enum_store_callback);
    for (i = 0; i < pEnumData->cStores; i++)
    {
        DWORD size;

        if (CertGetStoreProperty(pEnumData->rghStore[i],
         CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL, &size))
        {
            LPWSTR name = HeapAlloc(GetProcessHeap(), 0, size);

            if (name)
            {
                if (CertGetStoreProperty(pEnumData->rghStore[i],
                 CERT_STORE_LOCALIZED_NAME_PROP_ID, name, &size))
                {
                    struct StoreInfo *storeInfo = HeapAlloc(GetProcessHeap(),
                     0, sizeof(struct StoreInfo));

                    if (storeInfo)
                    {
                        TVINSERTSTRUCTW tvis;

                        storeInfo->type = StoreHandle;
                        storeInfo->u.store = pEnumData->rghStore[i];
                        tvis.hParent = NULL;
                        tvis.hInsertAfter = TVI_LAST;
                        tvis.u.item.mask = TVIF_TEXT | TVIF_PARAM;
                        tvis.u.item.pszText = name;
                        tvis.u.item.lParam = (LPARAM)storeInfo;
                        SendMessageW(tree, TVM_INSERTITEMW, 0, (LPARAM)&tvis);
                    }
                }
                HeapFree(GetProcessHeap(), 0, name);
            }
        }
    }
}

static void free_store_info(HWND tree)
{
    HTREEITEM next = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM, TVGN_CHILD,
     0);

    while (next)
    {
        TVITEMW item;

        memset(&item, 0, sizeof(item));
        item.mask = TVIF_HANDLE | TVIF_PARAM;
        item.hItem = next;
        SendMessageW(tree, TVM_GETITEMW, 0, (LPARAM)&item);
        if (item.lParam)
        {
            struct StoreInfo *storeInfo = (struct StoreInfo *)item.lParam;

            if (storeInfo->type == SystemStore)
                HeapFree(GetProcessHeap(), 0, storeInfo->u.name);
            HeapFree(GetProcessHeap(), 0, storeInfo);
        }
        next = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM, TVGN_NEXT,
         (LPARAM)next);
    }
}

static HCERTSTORE selected_item_to_store(HWND tree, HTREEITEM hItem)
{
    WCHAR buf[MAX_STRING_LEN];
    TVITEMW item;
    HCERTSTORE store;

    memset(&item, 0, sizeof(item));
    item.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT;
    item.hItem = hItem;
    item.cchTextMax = sizeof(buf) / sizeof(buf[0]);
    item.pszText = buf;
    SendMessageW(tree, TVM_GETITEMW, 0, (LPARAM)&item);
    if (item.lParam)
    {
        struct StoreInfo *storeInfo = (struct StoreInfo *)item.lParam;

        if (storeInfo->type == StoreHandle)
            store = storeInfo->u.store;
        else
            store = CertOpenSystemStoreW(0, storeInfo->u.name);
    }
    else
    {
        /* It's implicitly a system store */
        store = CertOpenSystemStoreW(0, buf);
    }
    return store;
}

struct SelectStoreInfo
{
    PCRYPTUI_SELECTSTORE_INFO_W info;
    HCERTSTORE                  store;
};

static LRESULT CALLBACK select_store_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    struct SelectStoreInfo *selectInfo;
    LRESULT ret = 0;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        selectInfo = (struct SelectStoreInfo *)lp;
        SetWindowLongPtrW(hwnd, DWLP_USER, lp);
        if (selectInfo->info->pwszTitle)
            SendMessageW(hwnd, WM_SETTEXT, 0,
             (LPARAM)selectInfo->info->pwszTitle);
        if (selectInfo->info->pwszText)
            SendMessageW(GetDlgItem(hwnd, IDC_STORE_TEXT), WM_SETTEXT, 0,
             (LPARAM)selectInfo->info->pwszText);
        if (!(selectInfo->info->dwFlags & CRYPTUI_ENABLE_SHOW_PHYSICAL_STORE))
            ShowWindow(GetDlgItem(hwnd, IDC_SHOW_PHYSICAL_STORES), FALSE);
        enumerate_stores(hwnd, selectInfo->info->pEnumData);
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDOK:
        {
            HWND tree = GetDlgItem(hwnd, IDC_STORE_LIST);
            HTREEITEM selection = (HTREEITEM)SendMessageW(tree,
             TVM_GETNEXTITEM, TVGN_CARET, 0);

            selectInfo = (struct SelectStoreInfo *)GetWindowLongPtrW(hwnd,
             DWLP_USER);
            if (!selection)
            {
                WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN], *pTitle;

                if (selectInfo->info->pwszTitle)
                    pTitle = selectInfo->info->pwszTitle;
                else
                {
                    LoadStringW(hInstance, IDS_SELECT_STORE_TITLE, title,
                     sizeof(title) / sizeof(title[0]));
                    pTitle = title;
                }
                LoadStringW(hInstance, IDS_SELECT_STORE, error,
                 sizeof(error) / sizeof(error[0]));
                MessageBoxW(hwnd, error, pTitle, MB_ICONEXCLAMATION | MB_OK);
            }
            else
            {
                HCERTSTORE store = selected_item_to_store(tree, selection);

                if (!selectInfo->info->pfnSelectedStoreCallback ||
                 selectInfo->info->pfnSelectedStoreCallback(store, hwnd,
                 selectInfo->info->pvArg))
                {
                    selectInfo->store = store;
                    free_store_info(tree);
                    EndDialog(hwnd, IDOK);
                }
                else
                    CertCloseStore(store, 0);
            }
            ret = TRUE;
            break;
        }
        case IDCANCEL:
            free_store_info(GetDlgItem(hwnd, IDC_STORE_LIST));
            EndDialog(hwnd, IDCANCEL);
            ret = TRUE;
            break;
        }
        break;
    }
    return ret;
}

/***********************************************************************
 *		CryptUIDlgSelectStoreW (CRYPTUI.@)
 */
HCERTSTORE WINAPI CryptUIDlgSelectStoreW(PCRYPTUI_SELECTSTORE_INFO_W info)
{
    struct SelectStoreInfo selectInfo = { info, NULL };

    TRACE("(%p)\n", info);

    if (info->dwSize != sizeof(CRYPTUI_SELECTSTORE_INFO_W))
    {
        WARN("unexpected size %d\n", info->dwSize);
        SetLastError(E_INVALIDARG);
        return NULL;
    }
    DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_SELECT_STORE), info->parent,
     select_store_dlg_proc, (LPARAM)&selectInfo);
    return selectInfo.store;
}

/***********************************************************************
 *		CryptUIDlgSelectStoreA (CRYPTUI.@)
 */
HCERTSTORE WINAPI CryptUIDlgSelectStoreA(PCRYPTUI_SELECTSTORE_INFO_A info)
{
    CRYPTUI_SELECTSTORE_INFO_W infoW;
    HCERTSTORE ret;
    int len;

    TRACE("(%p)\n", info);

    if (info->dwSize != sizeof(CRYPTUI_SELECTSTORE_INFO_A))
    {
        WARN("unexpected size %d\n", info->dwSize);
        SetLastError(E_INVALIDARG);
        return NULL;
    }
    memcpy(&infoW, info, sizeof(*info));
    if (info->pszTitle)
    {
        len = MultiByteToWideChar(CP_ACP, 0, info->pszTitle, -1, NULL, 0);
        infoW.pwszTitle = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, info->pszTitle, -1, infoW.pwszTitle,
         len);
    }
    if (info->pszText)
    {
        len = MultiByteToWideChar(CP_ACP, 0, info->pszText, -1, NULL, 0);
        infoW.pwszText = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, info->pszText, -1, infoW.pwszText, len);
    }
    ret = CryptUIDlgSelectStoreW(&infoW);
    HeapFree(GetProcessHeap(), 0, infoW.pwszText);
    HeapFree(GetProcessHeap(), 0, infoW.pwszTitle);
    return ret;
}

/***********************************************************************
 *		CryptUIDlgViewCertificateA (CRYPTUI.@)
 */
BOOL WINAPI CryptUIDlgViewCertificateA(
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTA pCertViewInfo, BOOL *pfPropertiesChanged)
{
    CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
    LPWSTR title = NULL;
    BOOL ret;

    TRACE("(%p, %p)\n", pCertViewInfo, pfPropertiesChanged);

    memcpy(&viewInfo, pCertViewInfo, sizeof(viewInfo));
    if (pCertViewInfo->szTitle)
    {
        int len = MultiByteToWideChar(CP_ACP, 0, pCertViewInfo->szTitle, -1,
         NULL, 0);

        title = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (title)
        {
            MultiByteToWideChar(CP_ACP, 0, pCertViewInfo->szTitle, -1, title,
             len);
            viewInfo.szTitle = title;
        }
        else
        {
            ret = FALSE;
            goto error;
        }
    }
    if (pCertViewInfo->cPropSheetPages)
    {
        FIXME("ignoring additional prop sheet pages\n");
        viewInfo.cPropSheetPages = 0;
    }
    ret = CryptUIDlgViewCertificateW(&viewInfo, pfPropertiesChanged);
    HeapFree(GetProcessHeap(), 0, title);
error:
    return ret;
}

struct ReadStringStruct
{
    LPCWSTR buf;
    LONG pos;
    LONG len;
};

static DWORD CALLBACK read_text_callback(DWORD_PTR dwCookie, LPBYTE buf,
 LONG cb, LONG *pcb)
{
    struct ReadStringStruct *string = (struct ReadStringStruct *)dwCookie;
    LONG cch = min(cb / sizeof(WCHAR), string->len - string->pos);

    TRACE("(%p, %p, %d, %p)\n", string, buf, cb, pcb);

    memmove(buf, string->buf + string->pos, cch * sizeof(WCHAR));
    string->pos += cch;
    *pcb = cch * sizeof(WCHAR);
    return 0;
}

static void add_unformatted_text_to_control(HWND hwnd, LPCWSTR text, LONG len)
{
    struct ReadStringStruct string;
    EDITSTREAM editstream;

    TRACE("(%p, %s)\n", hwnd, debugstr_wn(text, len));

    string.buf = text;
    string.pos = 0;
    string.len = len;
    editstream.dwCookie = (DWORD_PTR)&string;
    editstream.dwError = 0;
    editstream.pfnCallback = read_text_callback;
    SendMessageW(hwnd, EM_STREAMIN, SF_TEXT | SFF_SELECTION | SF_UNICODE,
     (LPARAM)&editstream);
}

static void add_string_resource_to_control(HWND hwnd, int id)
{
    LPWSTR str;
    LONG len;

    len = LoadStringW(hInstance, id, (LPWSTR)&str, 0);
    add_unformatted_text_to_control(hwnd, str, len);
}

static void add_text_with_paraformat_to_control(HWND hwnd, LPCWSTR text,
 LONG len, const PARAFORMAT2 *fmt)
{
    add_unformatted_text_to_control(hwnd, text, len);
    SendMessageW(hwnd, EM_SETPARAFORMAT, 0, (LPARAM)fmt);
}

static void add_string_resource_with_paraformat_to_control(HWND hwnd, int id,
 const PARAFORMAT2 *fmt)
{
    LPWSTR str;
    LONG len;

    len = LoadStringW(hInstance, id, (LPWSTR)&str, 0);
    add_text_with_paraformat_to_control(hwnd, str, len, fmt);
}

static LPWSTR get_cert_name_string(PCCERT_CONTEXT pCertContext, DWORD dwType,
 DWORD dwFlags)
{
    LPWSTR buf = NULL;
    DWORD len;

    len = CertGetNameStringW(pCertContext, dwType, dwFlags, NULL, NULL, 0);
    if (len)
    {
        buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (buf)
            CertGetNameStringW(pCertContext, dwType, dwFlags, NULL, buf, len);
    }
    return buf;
}

static void add_cert_string_to_control(HWND hwnd, PCCERT_CONTEXT pCertContext,
 DWORD dwType, DWORD dwFlags)
{
    LPWSTR name = get_cert_name_string(pCertContext, dwType, dwFlags);

    if (name)
    {
        /* Don't include NULL-terminator in output */
        DWORD len = lstrlenW(name);

        add_unformatted_text_to_control(hwnd, name, len);
        HeapFree(GetProcessHeap(), 0, name);
    }
}

static void add_icon_to_control(HWND hwnd, int id)
{
    HRESULT hr;
    LPRICHEDITOLE richEditOle = NULL;
    LPOLEOBJECT object = NULL;
    CLSID clsid;
    LPOLECACHE oleCache = NULL;
    FORMATETC formatEtc;
    DWORD conn;
    LPDATAOBJECT dataObject = NULL;
    HBITMAP bitmap = NULL;
    RECT rect;
    STGMEDIUM stgm;
    LPOLECLIENTSITE clientSite = NULL;
    REOBJECT reObject;

    TRACE("(%p, %d)\n", hwnd, id);

    SendMessageW(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&richEditOle);
    if (!richEditOle)
        goto end;
    hr = OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject,
     (void**)&object);
    if (FAILED(hr))
        goto end;
    hr = IOleObject_GetUserClassID(object, &clsid);
    if (FAILED(hr))
        goto end;
    hr = IOleObject_QueryInterface(object, &IID_IOleCache, (void**)&oleCache);
    if (FAILED(hr))
        goto end;
    formatEtc.cfFormat = CF_BITMAP;
    formatEtc.ptd = NULL;
    formatEtc.dwAspect = DVASPECT_CONTENT;
    formatEtc.lindex = -1;
    formatEtc.tymed = TYMED_GDI;
    hr = IOleCache_Cache(oleCache, &formatEtc, 0, &conn);
    if (FAILED(hr))
        goto end;
    hr = IOleObject_QueryInterface(object, &IID_IDataObject,
     (void**)&dataObject);
    if (FAILED(hr))
        goto end;
    hr = IRichEditOle_GetClientSite(richEditOle, &clientSite);
    if (FAILED(hr))
        goto end;
    bitmap = LoadImageW(hInstance, MAKEINTRESOURCEW(id), IMAGE_BITMAP, 0, 0,
     LR_DEFAULTSIZE | LR_LOADTRANSPARENT);
    if (!bitmap)
        goto end;
    rect.left = rect.top = 0;
    rect.right = GetSystemMetrics(SM_CXICON);
    rect.bottom = GetSystemMetrics(SM_CYICON);
    stgm.tymed = TYMED_GDI;
    stgm.u.hBitmap = bitmap;
    stgm.pUnkForRelease = NULL;
    hr = IDataObject_SetData(dataObject, &formatEtc, &stgm, TRUE);
    if (FAILED(hr))
        goto end;

    reObject.cbStruct = sizeof(reObject);
    reObject.cp = REO_CP_SELECTION;
    reObject.clsid = clsid;
    reObject.poleobj = object;
    reObject.pstg = NULL;
    reObject.polesite = clientSite;
    reObject.sizel.cx = reObject.sizel.cy = 0;
    reObject.dvaspect = DVASPECT_CONTENT;
    reObject.dwFlags = 0;
    reObject.dwUser = 0;

    IRichEditOle_InsertObject(richEditOle, &reObject);

end:
    if (clientSite)
        IOleClientSite_Release(clientSite);
    if (dataObject)
        IDataObject_Release(dataObject);
    if (oleCache)
        IOleCache_Release(oleCache);
    if (object)
        IOleObject_Release(object);
    if (richEditOle)
        IRichEditOle_Release(richEditOle);
}

#define MY_INDENT 200

static void add_oid_text_to_control(HWND hwnd, char *oid)
{
    WCHAR nl = '\n';
    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, oid, 0);
    PARAFORMAT2 parFmt;

    parFmt.cbSize = sizeof(parFmt);
    parFmt.dwMask = PFM_STARTINDENT;
    parFmt.dxStartIndent = MY_INDENT * 3;
    if (oidInfo)
    {
        add_text_with_paraformat_to_control(hwnd, oidInfo->pwszName,
         lstrlenW(oidInfo->pwszName), &parFmt);
        add_unformatted_text_to_control(hwnd, &nl, 1);
    }
}

struct OIDToString
{
    LPCSTR oid;
    int    id;
};

/* The following list MUST be lexicographically sorted by OID */
static struct OIDToString oidMap[] = {
 /* 1.3.6.1.4.1.311.10.3.1 */
 { szOID_KP_CTL_USAGE_SIGNING, IDS_PURPOSE_CTL_USAGE_SIGNING },
 /* 1.3.6.1.4.1.311.10.3.4 */
 { szOID_KP_EFS, IDS_PURPOSE_EFS },
 /* 1.3.6.1.4.1.311.10.3.4.1 */
 { szOID_EFS_RECOVERY, IDS_PURPOSE_EFS_RECOVERY },
 /* 1.3.6.1.4.1.311.10.3.5 */
 { szOID_WHQL_CRYPTO, IDS_PURPOSE_WHQL },
 /* 1.3.6.1.4.1.311.10.3.6 */
 { szOID_NT5_CRYPTO, IDS_PURPOSE_NT5 },
 /* 1.3.6.1.4.1.311.10.3.7 */
 { szOID_OEM_WHQL_CRYPTO, IDS_PURPOSE_OEM_WHQL },
 /* 1.3.6.1.4.1.311.10.3.8 */
 { szOID_EMBEDDED_NT_CRYPTO, IDS_PURPOSE_EMBEDDED_NT },
 /* 1.3.6.1.4.1.311.10.3.9 */
 { szOID_ROOT_LIST_SIGNER, IDS_PURPOSE_ROOT_LIST_SIGNER },
 /* 1.3.6.1.4.1.311.10.3.10 */
 { szOID_KP_QUALIFIED_SUBORDINATION, IDS_PURPOSE_QUALIFIED_SUBORDINATION },
 /* 1.3.6.1.4.1.311.10.3.11 */
 { szOID_KP_KEY_RECOVERY, IDS_PURPOSE_KEY_RECOVERY },
 /* 1.3.6.1.4.1.311.10.3.12 */
 { szOID_KP_DOCUMENT_SIGNING, IDS_PURPOSE_DOCUMENT_SIGNING },
 /* 1.3.6.1.4.1.311.10.3.13 */
 { szOID_KP_LIFETIME_SIGNING, IDS_PURPOSE_LIFETIME_SIGNING },
 /* 1.3.6.1.4.1.311.10.5.1 */
 { szOID_DRM, IDS_PURPOSE_DRM },
 /* 1.3.6.1.4.1.311.10.6.1 */
 { szOID_LICENSES, IDS_PURPOSE_LICENSES },
 /* 1.3.6.1.4.1.311.10.6.2 */
 { szOID_LICENSE_SERVER, IDS_PURPOSE_LICENSE_SERVER },
 /* 1.3.6.1.4.1.311.20.2.1 */
 { szOID_ENROLLMENT_AGENT, IDS_PURPOSE_ENROLLMENT_AGENT },
 /* 1.3.6.1.4.1.311.20.2.2 */
 { szOID_KP_SMARTCARD_LOGON, IDS_PURPOSE_SMARTCARD_LOGON },
 /* 1.3.6.1.4.1.311.21.5 */
 { szOID_KP_CA_EXCHANGE, IDS_PURPOSE_CA_EXCHANGE },
 /* 1.3.6.1.4.1.311.21.6 */
 { szOID_KP_KEY_RECOVERY_AGENT, IDS_PURPOSE_KEY_RECOVERY_AGENT },
 /* 1.3.6.1.4.1.311.21.19 */
 { szOID_DS_EMAIL_REPLICATION, IDS_PURPOSE_DS_EMAIL_REPLICATION },
 /* 1.3.6.1.5.5.7.3.1 */
 { szOID_PKIX_KP_SERVER_AUTH, IDS_PURPOSE_SERVER_AUTH },
 /* 1.3.6.1.5.5.7.3.2 */
 { szOID_PKIX_KP_CLIENT_AUTH, IDS_PURPOSE_CLIENT_AUTH },
 /* 1.3.6.1.5.5.7.3.3 */
 { szOID_PKIX_KP_CODE_SIGNING, IDS_PURPOSE_CODE_SIGNING },
 /* 1.3.6.1.5.5.7.3.4 */
 { szOID_PKIX_KP_EMAIL_PROTECTION, IDS_PURPOSE_EMAIL_PROTECTION },
 /* 1.3.6.1.5.5.7.3.5 */
 { szOID_PKIX_KP_IPSEC_END_SYSTEM, IDS_PURPOSE_IPSEC },
 /* 1.3.6.1.5.5.7.3.6 */
 { szOID_PKIX_KP_IPSEC_TUNNEL, IDS_PURPOSE_IPSEC },
 /* 1.3.6.1.5.5.7.3.7 */
 { szOID_PKIX_KP_IPSEC_USER, IDS_PURPOSE_IPSEC },
 /* 1.3.6.1.5.5.7.3.8 */
 { szOID_PKIX_KP_TIMESTAMP_SIGNING, IDS_PURPOSE_TIMESTAMP_SIGNING },
};

static struct OIDToString *findSupportedOID(LPCSTR oid)
{
    int indexHigh = sizeof(oidMap) / sizeof(oidMap[0]) - 1, indexLow = 0;

    while (indexLow <= indexHigh)
    {
        int cmp, i = (indexLow + indexHigh) / 2;
        if (!(cmp = strcmp(oid, oidMap[i].oid)))
            return &oidMap[i];
        if (cmp > 0)
            indexLow = i + 1;
        else
            indexHigh = i - 1;
    }
    return NULL;
}

static void add_local_oid_text_to_control(HWND text, LPCSTR oid)
{
    struct OIDToString *entry;
    WCHAR nl = '\n';
    PARAFORMAT2 parFmt;

    parFmt.cbSize = sizeof(parFmt);
    parFmt.dwMask = PFM_STARTINDENT;
    parFmt.dxStartIndent = MY_INDENT * 3;
    if ((entry = findSupportedOID(oid)))
    {
        WCHAR *str, *linebreak, *ptr;
        BOOL multiline = FALSE;
        int len;

        len = LoadStringW(hInstance, entry->id, (LPWSTR)&str, 0);
        ptr = str;
        do {
            if ((linebreak = memchrW(ptr, '\n', len)))
            {
                WCHAR copy[MAX_STRING_LEN];

                multiline = TRUE;
                /* The source string contains a newline, which the richedit
                 * control won't find since it's interpreted as a paragraph
                 * break.  Therefore copy up to the newline.  lstrcpynW always
                 * NULL-terminates, so pass one more than the length of the
                 * source line so the copy includes the entire line and the
                 * NULL-terminator.
                 */
                lstrcpynW(copy, ptr, linebreak - ptr + 1);
                add_text_with_paraformat_to_control(text, copy,
                 linebreak - ptr, &parFmt);
                ptr = linebreak + 1;
                add_unformatted_text_to_control(text, &nl, 1);
            }
            else if (multiline && *ptr)
            {
                /* Add the last line */
                add_text_with_paraformat_to_control(text, ptr,
                 len - (ptr - str), &parFmt);
                add_unformatted_text_to_control(text, &nl, 1);
            }
        } while (linebreak);
        if (!multiline)
        {
            add_text_with_paraformat_to_control(text, str, len, &parFmt);
            add_unformatted_text_to_control(text, &nl, 1);
        }
    }
    else
    {
        WCHAR *oidW = HeapAlloc(GetProcessHeap(), 0,
         (strlen(oid) + 1) * sizeof(WCHAR));

        if (oidW)
        {
            LPCSTR src;
            WCHAR *dst;

            for (src = oid, dst = oidW; *src; src++, dst++)
                *dst = *src;
            *dst = 0;
            add_text_with_paraformat_to_control(text, oidW, lstrlenW(oidW),
             &parFmt);
            add_unformatted_text_to_control(text, &nl, 1);
            HeapFree(GetProcessHeap(), 0, oidW);
        }
    }
}

static void display_app_usages(HWND text, PCCERT_CONTEXT cert,
 BOOL *anyUsageAdded)
{
    static char any_app_policy[] = szOID_ANY_APPLICATION_POLICY;
    WCHAR nl = '\n';
    CHARFORMATW charFmt;
    PCERT_EXTENSION policyExt;
    if (!*anyUsageAdded)
    {
        PARAFORMAT2 parFmt;

        parFmt.cbSize = sizeof(parFmt);
        parFmt.dwMask = PFM_STARTINDENT;
        parFmt.dxStartIndent = MY_INDENT;
        add_string_resource_with_paraformat_to_control(text,
         IDS_CERT_INFO_PURPOSES, &parFmt);
        add_unformatted_text_to_control(text, &nl, 1);
        *anyUsageAdded = TRUE;
    }
    memset(&charFmt, 0, sizeof(charFmt));
    charFmt.cbSize = sizeof(charFmt);
    charFmt.dwMask = CFM_BOLD;
    charFmt.dwEffects = 0;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    if ((policyExt = CertFindExtension(szOID_APPLICATION_CERT_POLICIES,
     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension)))
    {
        CERT_POLICIES_INFO *policies;
        DWORD size;

        if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_CERT_POLICIES,
         policyExt->Value.pbData, policyExt->Value.cbData,
         CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size))
        {
            DWORD i;

            for (i = 0; i < policies->cPolicyInfo; i++)
            {
                DWORD j;

                for (j = 0; j < policies->rgPolicyInfo[i].cPolicyQualifier; j++)
                    add_local_oid_text_to_control(text,
                     policies->rgPolicyInfo[i].rgPolicyQualifier[j].
                     pszPolicyQualifierId);
            }
            LocalFree(policies);
        }
    }
    else
        add_oid_text_to_control(text, any_app_policy);
}

static BOOL display_cert_usages(HWND text, PCCERT_CONTEXT cert,
 BOOL *anyUsageAdded)
{
    WCHAR nl = '\n';
    DWORD size;
    BOOL badUsages = FALSE;

    if (CertGetEnhancedKeyUsage(cert, 0, NULL, &size))
    {
        CHARFORMATW charFmt;
        static char any_cert_policy[] = szOID_ANY_CERT_POLICY;
        PCERT_ENHKEY_USAGE usage = HeapAlloc(GetProcessHeap(), 0, size);

        if (usage)
        {
            if (CertGetEnhancedKeyUsage(cert, 0, usage, &size))
            {
                DWORD i;

                if (!*anyUsageAdded)
                {
                    PARAFORMAT2 parFmt;

                    parFmt.cbSize = sizeof(parFmt);
                    parFmt.dwMask = PFM_STARTINDENT;
                    parFmt.dxStartIndent = MY_INDENT;
                    add_string_resource_with_paraformat_to_control(text,
                     IDS_CERT_INFO_PURPOSES, &parFmt);
                    add_unformatted_text_to_control(text, &nl, 1);
                    *anyUsageAdded = TRUE;
                }
                memset(&charFmt, 0, sizeof(charFmt));
                charFmt.cbSize = sizeof(charFmt);
                charFmt.dwMask = CFM_BOLD;
                charFmt.dwEffects = 0;
                SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION,
                 (LPARAM)&charFmt);
                if (!usage->cUsageIdentifier)
                    add_oid_text_to_control(text, any_cert_policy);
                else
                    for (i = 0; i < usage->cUsageIdentifier; i++)
                        add_local_oid_text_to_control(text,
                         usage->rgpszUsageIdentifier[i]);
            }
            else
                badUsages = TRUE;
            HeapFree(GetProcessHeap(), 0, usage);
        }
        else
            badUsages = TRUE;
    }
    else
        badUsages = TRUE;
    return badUsages;
}

static void set_policy_text(HWND text,
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
{
    BOOL includeCertUsages = FALSE, includeAppUsages = FALSE;
    BOOL badUsages = FALSE, anyUsageAdded = FALSE;

    if (pCertViewInfo->cPurposes)
    {
        DWORD i;

        for (i = 0; i < pCertViewInfo->cPurposes; i++)
        {
            if (!strcmp(pCertViewInfo->rgszPurposes[i], szOID_ANY_CERT_POLICY))
                includeCertUsages = TRUE;
            else if (!strcmp(pCertViewInfo->rgszPurposes[i],
             szOID_ANY_APPLICATION_POLICY))
                includeAppUsages = TRUE;
            else
                badUsages = TRUE;
        }
    }
    else
        includeAppUsages = includeCertUsages = TRUE;
    if (includeAppUsages)
        display_app_usages(text, pCertViewInfo->pCertContext, &anyUsageAdded);
    if (includeCertUsages)
        badUsages = display_cert_usages(text, pCertViewInfo->pCertContext,
         &anyUsageAdded);
    if (badUsages)
    {
        PARAFORMAT2 parFmt;

        parFmt.cbSize = sizeof(parFmt);
        parFmt.dwMask = PFM_STARTINDENT;
        parFmt.dxStartIndent = MY_INDENT;
        add_string_resource_with_paraformat_to_control(text,
         IDS_CERT_INFO_BAD_PURPOSES, &parFmt);
    }
}

static CRYPT_OBJID_BLOB *find_policy_qualifier(CERT_POLICIES_INFO *policies,
 LPCSTR policyOid)
{
    CRYPT_OBJID_BLOB *ret = NULL;
    DWORD i;

    for (i = 0; !ret && i < policies->cPolicyInfo; i++)
    {
        DWORD j;

        for (j = 0; !ret && j < policies->rgPolicyInfo[i].cPolicyQualifier; j++)
            if (!strcmp(policies->rgPolicyInfo[i].rgPolicyQualifier[j].
             pszPolicyQualifierId, policyOid))
                ret = &policies->rgPolicyInfo[i].rgPolicyQualifier[j].
                 Qualifier;
    }
    return ret;
}

static WCHAR *get_cps_str_from_qualifier(const CRYPT_OBJID_BLOB *qualifier)
{
    LPWSTR qualifierStr = NULL;
    CERT_NAME_VALUE *qualifierValue;
    DWORD size;

    if (CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME_VALUE,
     qualifier->pbData, qualifier->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
     &qualifierValue, &size))
    {
        size = CertRDNValueToStrW(qualifierValue->dwValueType,
         &qualifierValue->Value, NULL, 0);
        qualifierStr = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
        if (qualifierStr)
            CertRDNValueToStrW(qualifierValue->dwValueType,
             &qualifierValue->Value, qualifierStr, size);
        LocalFree(qualifierValue);
    }
    return qualifierStr;
}

static WCHAR *get_user_notice_from_qualifier(const CRYPT_OBJID_BLOB *qualifier)
{
    LPWSTR str = NULL;
    CERT_POLICY_QUALIFIER_USER_NOTICE *qualifierValue;
    DWORD size;

    if (CryptDecodeObjectEx(X509_ASN_ENCODING,
     X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
     qualifier->pbData, qualifier->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL,
     &qualifierValue, &size))
    {
        str = HeapAlloc(GetProcessHeap(), 0,
         (strlenW(qualifierValue->pszDisplayText) + 1) * sizeof(WCHAR));
        if (str)
            strcpyW(str, qualifierValue->pszDisplayText);
        LocalFree(qualifierValue);
    }
    return str;
}

struct IssuerStatement
{
    LPWSTR cps;
    LPWSTR userNotice;
};

static void set_issuer_statement(HWND hwnd,
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
{
    PCERT_EXTENSION policyExt;

    if (!(pCertViewInfo->dwFlags & CRYPTUI_DISABLE_ISSUERSTATEMENT) &&
     (policyExt = CertFindExtension(szOID_CERT_POLICIES,
     pCertViewInfo->pCertContext->pCertInfo->cExtension,
     pCertViewInfo->pCertContext->pCertInfo->rgExtension)))
    {
        CERT_POLICIES_INFO *policies;
        DWORD size;

        if (CryptDecodeObjectEx(X509_ASN_ENCODING, policyExt->pszObjId,
         policyExt->Value.pbData, policyExt->Value.cbData,
         CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size))
        {
            CRYPT_OBJID_BLOB *qualifier;
            LPWSTR cps = NULL, userNotice = NULL;

            if ((qualifier = find_policy_qualifier(policies,
             szOID_PKIX_POLICY_QUALIFIER_CPS)))
                cps = get_cps_str_from_qualifier(qualifier);
            if ((qualifier = find_policy_qualifier(policies,
             szOID_PKIX_POLICY_QUALIFIER_USERNOTICE)))
                userNotice = get_user_notice_from_qualifier(qualifier);
            if (cps || userNotice)
            {
                struct IssuerStatement *issuerStatement =
                 HeapAlloc(GetProcessHeap(), 0, sizeof(struct IssuerStatement));

                if (issuerStatement)
                {
                    issuerStatement->cps = cps;
                    issuerStatement->userNotice = userNotice;
                    EnableWindow(GetDlgItem(hwnd, IDC_ISSUERSTATEMENT), TRUE);
                    SetWindowLongPtrW(hwnd, DWLP_USER,
                     (ULONG_PTR)issuerStatement);
                }
            }
            LocalFree(policies);
        }
    }
}

static void set_cert_info(HWND hwnd,
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
{
    CHARFORMATW charFmt;
    PARAFORMAT2 parFmt;
    HWND icon = GetDlgItem(hwnd, IDC_CERTIFICATE_ICON);
    HWND text = GetDlgItem(hwnd, IDC_CERTIFICATE_INFO);
    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
     (CRYPT_PROVIDER_DATA *)pCertViewInfo->u.pCryptProviderData,
     pCertViewInfo->idxSigner, pCertViewInfo->fCounterSigner,
     pCertViewInfo->idxCounterSigner);
    CRYPT_PROVIDER_CERT *root =
     &provSigner->pasCertChain[provSigner->csCertChain - 1];

    if (!provSigner->pChainContext ||
     (provSigner->pChainContext->TrustStatus.dwErrorStatus &
     CERT_TRUST_IS_PARTIAL_CHAIN))
        add_icon_to_control(icon, IDB_CERT_WARNING);
    else if (!root->fTrustedRoot)
        add_icon_to_control(icon, IDB_CERT_ERROR);
    else
        add_icon_to_control(icon, IDB_CERT);

    memset(&charFmt, 0, sizeof(charFmt));
    charFmt.cbSize = sizeof(charFmt);
    charFmt.dwMask = CFM_BOLD;
    charFmt.dwEffects = CFE_BOLD;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    /* FIXME: vertically center text */
    parFmt.cbSize = sizeof(parFmt);
    parFmt.dwMask = PFM_STARTINDENT;
    parFmt.dxStartIndent = MY_INDENT;
    add_string_resource_with_paraformat_to_control(text,
     IDS_CERTIFICATEINFORMATION, &parFmt);

    text = GetDlgItem(hwnd, IDC_CERTIFICATE_STATUS);
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    if (provSigner->dwError == TRUST_E_CERT_SIGNATURE)
        add_string_resource_with_paraformat_to_control(text,
         IDS_CERT_INFO_BAD_SIG, &parFmt);
    else if (!provSigner->pChainContext ||
     (provSigner->pChainContext->TrustStatus.dwErrorStatus &
     CERT_TRUST_IS_PARTIAL_CHAIN))
        add_string_resource_with_paraformat_to_control(text,
         IDS_CERT_INFO_PARTIAL_CHAIN, &parFmt);
    else if (!root->fTrustedRoot)
    {
        if (provSigner->csCertChain == 1 && root->fSelfSigned)
            add_string_resource_with_paraformat_to_control(text,
             IDS_CERT_INFO_UNTRUSTED_CA, &parFmt);
        else
            add_string_resource_with_paraformat_to_control(text,
             IDS_CERT_INFO_UNTRUSTED_ROOT, &parFmt);
    }
    else
    {
        set_policy_text(text, pCertViewInfo);
        set_issuer_statement(hwnd, pCertViewInfo);
    }
}

static void set_cert_name_string(HWND hwnd, PCCERT_CONTEXT cert,
 DWORD nameFlags, int heading)
{
    WCHAR nl = '\n';
    HWND text = GetDlgItem(hwnd, IDC_CERTIFICATE_NAMES);
    CHARFORMATW charFmt;
    PARAFORMAT2 parFmt;

    memset(&charFmt, 0, sizeof(charFmt));
    charFmt.cbSize = sizeof(charFmt);
    charFmt.dwMask = CFM_BOLD;
    charFmt.dwEffects = CFE_BOLD;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    parFmt.cbSize = sizeof(parFmt);
    parFmt.dwMask = PFM_STARTINDENT;
    parFmt.dxStartIndent = MY_INDENT * 3;
    add_string_resource_with_paraformat_to_control(text, heading, &parFmt);
    charFmt.dwEffects = 0;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    add_cert_string_to_control(text, cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
     nameFlags);
    add_unformatted_text_to_control(text, &nl, 1);
    add_unformatted_text_to_control(text, &nl, 1);
    add_unformatted_text_to_control(text, &nl, 1);

}

static void add_date_string_to_control(HWND hwnd, const FILETIME *fileTime)
{
    WCHAR dateFmt[80]; /* sufficient for all versions of LOCALE_SSHORTDATE */
    WCHAR date[80];
    SYSTEMTIME sysTime;

    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt,
     sizeof(dateFmt) / sizeof(dateFmt[0]));
    FileTimeToSystemTime(fileTime, &sysTime);
    GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date,
     sizeof(date) / sizeof(date[0]));
    add_unformatted_text_to_control(hwnd, date, lstrlenW(date));
}

static void set_cert_validity_period(HWND hwnd, PCCERT_CONTEXT cert)
{
    WCHAR nl = '\n';
    HWND text = GetDlgItem(hwnd, IDC_CERTIFICATE_NAMES);
    CHARFORMATW charFmt;
    PARAFORMAT2 parFmt;

    memset(&charFmt, 0, sizeof(charFmt));
    charFmt.cbSize = sizeof(charFmt);
    charFmt.dwMask = CFM_BOLD;
    charFmt.dwEffects = CFE_BOLD;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    parFmt.cbSize = sizeof(parFmt);
    parFmt.dwMask = PFM_STARTINDENT;
    parFmt.dxStartIndent = MY_INDENT * 3;
    add_string_resource_with_paraformat_to_control(text, IDS_VALID_FROM,
     &parFmt);
    charFmt.dwEffects = 0;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    add_date_string_to_control(text, &cert->pCertInfo->NotBefore);
    charFmt.dwEffects = CFE_BOLD;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    add_string_resource_to_control(text, IDS_VALID_TO);
    charFmt.dwEffects = 0;
    SendMessageW(text, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&charFmt);
    add_date_string_to_control(text, &cert->pCertInfo->NotAfter);
    add_unformatted_text_to_control(text, &nl, 1);
}

static void set_general_info(HWND hwnd,
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
{
    set_cert_info(hwnd, pCertViewInfo);
    set_cert_name_string(hwnd, pCertViewInfo->pCertContext, 0,
     IDS_SUBJECT_HEADING);
    set_cert_name_string(hwnd, pCertViewInfo->pCertContext,
     CERT_NAME_ISSUER_FLAG, IDS_ISSUER_HEADING);
    set_cert_validity_period(hwnd, pCertViewInfo->pCertContext);
}

static LRESULT CALLBACK user_notice_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    HWND text;
    struct IssuerStatement *issuerStatement;

    switch (msg)
    {
    case WM_INITDIALOG:
        text = GetDlgItem(hwnd, IDC_USERNOTICE);
        issuerStatement = (struct IssuerStatement *)lp;
        add_unformatted_text_to_control(text, issuerStatement->userNotice,
         strlenW(issuerStatement->userNotice));
        if (issuerStatement->cps)
            SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)issuerStatement->cps);
        else
            EnableWindow(GetDlgItem(hwnd, IDC_CPS), FALSE);
        break;
    case WM_COMMAND:
        switch (wp)
        {
        case IDOK:
            EndDialog(hwnd, IDOK);
            ret = TRUE;
            break;
        case IDC_CPS:
        {
            IBindCtx *bctx = NULL;
            LPWSTR cps;

            CreateBindCtx(0, &bctx);
            cps = (LPWSTR)GetWindowLongPtrW(hwnd, DWLP_USER);
            HlinkSimpleNavigateToString(cps, NULL, NULL, NULL, bctx, NULL,
             HLNF_OPENINNEWWINDOW, 0);
            IBindCtx_Release(bctx);
            break;
        }
        }
    }
    return ret;
}

static void show_user_notice(HWND hwnd, struct IssuerStatement *issuerStatement)
{
    DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_USERNOTICE), hwnd,
     user_notice_dlg_proc, (LPARAM)issuerStatement);
}

static LRESULT CALLBACK general_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    PROPSHEETPAGEW *page;
    PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo;

    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);

    switch (msg)
    {
    case WM_INITDIALOG:
        page = (PROPSHEETPAGEW *)lp;
        pCertViewInfo = (PCCRYPTUI_VIEWCERTIFICATE_STRUCTW)page->lParam;
        if (pCertViewInfo->dwFlags & CRYPTUI_DISABLE_ADDTOSTORE)
            ShowWindow(GetDlgItem(hwnd, IDC_ADDTOSTORE), FALSE);
        EnableWindow(GetDlgItem(hwnd, IDC_ISSUERSTATEMENT), FALSE);
        set_general_info(hwnd, pCertViewInfo);
        break;
    case WM_COMMAND:
        switch (wp)
        {
        case IDC_ADDTOSTORE:
            CryptUIWizImport(0, hwnd, NULL, NULL, NULL);
            break;
        case IDC_ISSUERSTATEMENT:
        {
            struct IssuerStatement *issuerStatement =
             (struct IssuerStatement *)GetWindowLongPtrW(hwnd, DWLP_USER);

            if (issuerStatement)
            {
                if (issuerStatement->userNotice)
                    show_user_notice(hwnd, issuerStatement);
                else if (issuerStatement->cps)
                {
                    IBindCtx *bctx = NULL;

                    CreateBindCtx(0, &bctx);
                    HlinkSimpleNavigateToString(issuerStatement->cps, NULL,
                     NULL, NULL, bctx, NULL, HLNF_OPENINNEWWINDOW, 0);
                    IBindCtx_Release(bctx);
                }
            }
            break;
        }
        }
        break;
    }
    return 0;
}

static UINT CALLBACK general_callback_proc(HWND hwnd, UINT msg,
 PROPSHEETPAGEW *page)
{
    struct IssuerStatement *issuerStatement;

    switch (msg)
    {
    case PSPCB_RELEASE:
        issuerStatement =
         (struct IssuerStatement *)GetWindowLongPtrW(hwnd, DWLP_USER);
        if (issuerStatement)
        {
            HeapFree(GetProcessHeap(), 0, issuerStatement->cps);
            HeapFree(GetProcessHeap(), 0, issuerStatement->userNotice);
            HeapFree(GetProcessHeap(), 0, issuerStatement);
        }
        break;
    }
    return 1;
}

static void init_general_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
 PROPSHEETPAGEW *page)
{
    memset(page, 0, sizeof(PROPSHEETPAGEW));
    page->dwSize = sizeof(PROPSHEETPAGEW);
    page->dwFlags = PSP_USECALLBACK;
    page->pfnCallback = general_callback_proc;
    page->hInstance = hInstance;
    page->u.pszTemplate = MAKEINTRESOURCEW(IDD_GENERAL);
    page->pfnDlgProc = general_dlg_proc;
    page->lParam = (LPARAM)pCertViewInfo;
}

typedef WCHAR * (*field_format_func)(PCCERT_CONTEXT cert);

static WCHAR *field_format_version(PCCERT_CONTEXT cert)
{
    static const WCHAR fmt[] = { 'V','%','d',0 };
    WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, 12 * sizeof(WCHAR));

    if (buf)
        sprintfW(buf, fmt, cert->pCertInfo->dwVersion);
    return buf;
}

static WCHAR *format_hex_string(void *pb, DWORD cb)
{
    WCHAR *buf = HeapAlloc(GetProcessHeap(), 0, (cb * 3 + 1) * sizeof(WCHAR));

    if (buf)
    {
        static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
        DWORD i;
        WCHAR *ptr;

        for (i = 0, ptr = buf; i < cb; i++, ptr += 3)
            sprintfW(ptr, fmt, ((BYTE *)pb)[i]);
    }
    return buf;
}

static WCHAR *field_format_serial_number(PCCERT_CONTEXT cert)
{
    return format_hex_string(cert->pCertInfo->SerialNumber.pbData,
     cert->pCertInfo->SerialNumber.cbData);
}

static WCHAR *field_format_issuer(PCCERT_CONTEXT cert)
{
    return get_cert_name_string(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE,
     CERT_NAME_ISSUER_FLAG);
}

static WCHAR *field_format_detailed_cert_name(PCERT_NAME_BLOB name)
{
    WCHAR *str = NULL;
    DWORD len = CertNameToStrW(X509_ASN_ENCODING, name,
     CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, NULL, 0);

    if (len)
    {
        str = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (str)
            CertNameToStrW(X509_ASN_ENCODING, name,
             CERT_X500_NAME_STR | CERT_NAME_STR_CRLF_FLAG, str, len);
    }
    return str;
}

static WCHAR *field_format_detailed_issuer(PCCERT_CONTEXT cert, void *param)
{
    return field_format_detailed_cert_name(&cert->pCertInfo->Issuer);
}

static WCHAR *field_format_subject(PCCERT_CONTEXT cert)
{
    return get_cert_name_string(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0);
}

static WCHAR *field_format_detailed_subject(PCCERT_CONTEXT cert, void *param)
{
    return field_format_detailed_cert_name(&cert->pCertInfo->Subject);
}

static WCHAR *format_long_date(const FILETIME *fileTime)
{
    WCHAR dateFmt[80]; /* long enough for LOCALE_SLONGDATE */
    DWORD len;
    WCHAR *buf = NULL;
    SYSTEMTIME sysTime;

    /* FIXME: format isn't quite right, want time too */
    GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_SLONGDATE, dateFmt,
     sizeof(dateFmt) / sizeof(dateFmt[0]));
    FileTimeToSystemTime(fileTime, &sysTime);
    len = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, NULL, 0);
    if (len)
    {
        buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        if (buf)
            GetDateFormatW(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, buf,
             len);
    }
    return buf;
}

static WCHAR *field_format_from_date(PCCERT_CONTEXT cert)
{
    return format_long_date(&cert->pCertInfo->NotBefore);
}

static WCHAR *field_format_to_date(PCCERT_CONTEXT cert)
{
    return format_long_date(&cert->pCertInfo->NotAfter);
}

static WCHAR *field_format_public_key(PCCERT_CONTEXT cert)
{
    PCCRYPT_OID_INFO oidInfo;
    WCHAR *buf = NULL;

    oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
     cert->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId, 0);
    if (oidInfo)
    {
        WCHAR fmt[MAX_STRING_LEN];

        if (LoadStringW(hInstance, IDS_FIELD_PUBLIC_KEY_FORMAT, fmt,
         sizeof(fmt) / sizeof(fmt[0])))
        {
            DWORD len;

            /* Allocate the output buffer.  Use the number of bytes in the
             * public key as a conservative (high) estimate for the number of
             * digits in its output.
             * The output is of the form (in English)
             * "<public key algorithm> (<public key bit length> bits)".
             * Ordinarily having two positional parameters in a string is not a
             * good idea, but as this isn't a sentence fragment, it shouldn't
             * be word-order dependent.
             */
            len = strlenW(fmt) + strlenW(oidInfo->pwszName) +
                cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData * 8;
            buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*buf));
            if (buf)
            {
                DWORD_PTR args[2];
                args[0] = (DWORD_PTR)oidInfo->pwszName;
                args[1] = CertGetPublicKeyLength(X509_ASN_ENCODING,
                              &cert->pCertInfo->SubjectPublicKeyInfo);
                FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
                               fmt, 0, 0, buf, len, (__ms_va_list*)args);
            }
        }
    }
    return buf;
}

static WCHAR *field_format_detailed_public_key(PCCERT_CONTEXT cert, void *param)
{
    return format_hex_string(
     cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
     cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData);
}

struct field_value_data;
struct detail_data
{
    PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo;
    BOOL *pfPropertiesChanged;
    int cFields;
    struct field_value_data *fields;
};

typedef void (*add_fields_func)(HWND hwnd, struct detail_data *data);

typedef WCHAR *(*create_detailed_value_func)(PCCERT_CONTEXT cert, void *param);

struct field_value_data
{
    create_detailed_value_func create;
    LPWSTR detailed_value;
    void *param;
};

static void add_field_value_data(struct detail_data *data,
 create_detailed_value_func create, void *param)
{
    if (data->cFields)
        data->fields = HeapReAlloc(GetProcessHeap(), 0, data->fields,
         (data->cFields + 1) * sizeof(struct field_value_data));
    else
        data->fields = HeapAlloc(GetProcessHeap(), 0,
         sizeof(struct field_value_data));
    if (data->fields)
    {
        data->fields[data->cFields].create = create;
        data->fields[data->cFields].detailed_value = NULL;
        data->fields[data->cFields].param = param;
        data->cFields++;
    }
}

static void add_field_and_value_to_list(HWND hwnd, struct detail_data *data,
 LPWSTR field, LPWSTR value, create_detailed_value_func create, void *param)
{
    LVITEMW item;
    int iItem = SendMessageW(hwnd, LVM_GETITEMCOUNT, 0, 0);

    item.mask = LVIF_TEXT | LVIF_PARAM;
    item.iItem = iItem;
    item.iSubItem = 0;
    item.pszText = field;
    item.lParam = (LPARAM)data;
    SendMessageW(hwnd, LVM_INSERTITEMW, 0, (LPARAM)&item);
    if (value)
    {
        item.pszText = value;
        item.iSubItem = 1;
        SendMessageW(hwnd, LVM_SETITEMTEXTW, iItem, (LPARAM)&item);
    }
    add_field_value_data(data, create, param);
}

static void add_string_id_and_value_to_list(HWND hwnd, struct detail_data *data,
 int id, LPWSTR value, create_detailed_value_func create, void *param)
{
    WCHAR buf[MAX_STRING_LEN];

    LoadStringW(hInstance, id, buf, sizeof(buf) / sizeof(buf[0]));
    add_field_and_value_to_list(hwnd, data, buf, value, create, param);
}

struct v1_field
{
    int id;
    field_format_func format;
    create_detailed_value_func create_detailed_value;
};

static void add_v1_field(HWND hwnd, struct detail_data *data,
 const struct v1_field *field)
{
    WCHAR *val = field->format(data->pCertViewInfo->pCertContext);

    if (val)
    {
        add_string_id_and_value_to_list(hwnd, data, field->id, val,
         field->create_detailed_value, NULL);
        HeapFree(GetProcessHeap(), 0, val);
    }
}

static const struct v1_field v1_fields[] = {
 { IDS_FIELD_VERSION, field_format_version, NULL },
 { IDS_FIELD_SERIAL_NUMBER, field_format_serial_number, NULL },
 { IDS_FIELD_ISSUER, field_format_issuer, field_format_detailed_issuer },
 { IDS_FIELD_VALID_FROM, field_format_from_date, NULL },
 { IDS_FIELD_VALID_TO, field_format_to_date, NULL },
 { IDS_FIELD_SUBJECT, field_format_subject, field_format_detailed_subject },
 { IDS_FIELD_PUBLIC_KEY, field_format_public_key,
   field_format_detailed_public_key }
};

static void add_v1_fields(HWND hwnd, struct detail_data *data)
{
    int i;
    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;

    /* The last item in v1_fields is the public key, which is not in the loop
     * because it's a special case.
     */
    for (i = 0; i < sizeof(v1_fields) / sizeof(v1_fields[0]) - 1; i++)
        add_v1_field(hwnd, data, &v1_fields[i]);
    if (cert->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData)
        add_v1_field(hwnd, data, &v1_fields[i]);
}

static WCHAR *crypt_format_extension(const CERT_EXTENSION *ext, DWORD formatStrType)
{
    WCHAR *str = NULL;
    DWORD size;

    if (CryptFormatObject(X509_ASN_ENCODING, 0, formatStrType, NULL,
     ext->pszObjId, ext->Value.pbData, ext->Value.cbData, NULL, &size))
    {
        str = HeapAlloc(GetProcessHeap(), 0, size);
        CryptFormatObject(X509_ASN_ENCODING, 0, formatStrType, NULL,
         ext->pszObjId, ext->Value.pbData, ext->Value.cbData, str, &size);
    }
    return str;
}

static WCHAR *field_format_extension_hex_with_ascii(const CERT_EXTENSION *ext)
{
    WCHAR *str = NULL;

    if (ext->Value.cbData)
    {
        /* The output is formatted as:
         * <hex bytes>  <ascii bytes>\n
         * where <hex bytes> is a string of up to 8 bytes, output as %02x,
         * and <ascii bytes> is the ASCII equivalent of each byte, or '.' if
         * the byte is not printable.
         * So, for example, the extension value consisting of the following
         * bytes:
         *   0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x03,
         *   0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67
         * is output as:
         *   30 14 31 12 30 10 06 03  0.1.0...
         *   55 04 03 13 09 4a 75 61  U....Jua
         *   6e 20 4c 61 6e 67        n Lang
         * The allocation size therefore requires:
         * - 4 characters per character in an 8-byte line
         *   (2 for the hex format, one for the space, one for the ASCII value)
         * - 3 more characters per 8-byte line (two spaces and a newline)
         * - 1 character for the terminating nul
         * FIXME: should use a fixed-width font for this
         */
        DWORD lines = (ext->Value.cbData + 7) / 8;

        str = HeapAlloc(GetProcessHeap(), 0,
         (lines * 8 * 4 + lines * 3 + 1) * sizeof(WCHAR));
        if (str)
        {
            static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
            DWORD i, j;
            WCHAR *ptr;

            for (i = 0, ptr = str; i < ext->Value.cbData; i += 8)
            {
                /* Output as hex bytes first */
                for (j = i; j < min(i + 8, ext->Value.cbData); j++, ptr += 3)
                    sprintfW(ptr, fmt, ext->Value.pbData[j]);
                /* Pad the hex output with spaces for alignment */
                if (j == ext->Value.cbData && j % 8)
                {
                    static const WCHAR pad[] = { ' ',' ',' ' };

                    for (; j % 8; j++, ptr += sizeof(pad) / sizeof(pad[0]))
                        memcpy(ptr, pad, sizeof(pad));
                }
                /* The last sprintfW included a space, so just insert one
                 * more space between the hex bytes and the ASCII output
                 */
                *ptr++ = ' ';
                /* Output as ASCII bytes */
                for (j = i; j < min(i + 8, ext->Value.cbData); j++, ptr++)
                {
                    if (isprintW(ext->Value.pbData[j]) &&
                     !isspaceW(ext->Value.pbData[j]))
                        *ptr = ext->Value.pbData[j];
                    else
                        *ptr = '.';
                }
                *ptr++ = '\n';
            }
            *ptr++ = '\0';
        }
    }
    return str;
}

static WCHAR *field_format_detailed_extension(PCCERT_CONTEXT cert, void *param)
{
    PCERT_EXTENSION ext = param;
    LPWSTR str = crypt_format_extension(ext,
     CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX);

    if (!str)
        str = field_format_extension_hex_with_ascii(ext);
    return str;
}

static void add_cert_extension_detail(HWND hwnd, struct detail_data *data,
 PCERT_EXTENSION ext)
{
    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
     ext->pszObjId, 0);
    LPWSTR val = crypt_format_extension(ext, 0);

    if (oidInfo)
        add_field_and_value_to_list(hwnd, data, (LPWSTR)oidInfo->pwszName,
         val, field_format_detailed_extension, ext);
    else
    {
        DWORD len = strlen(ext->pszObjId);
        LPWSTR oidW = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));

        if (oidW)
        {
            DWORD i;

            for (i = 0; i <= len; i++)
                oidW[i] = ext->pszObjId[i];
            add_field_and_value_to_list(hwnd, data, oidW, val,
             field_format_detailed_extension, ext);
            HeapFree(GetProcessHeap(), 0, oidW);
        }
    }
    HeapFree(GetProcessHeap(), 0, val);
}

static void add_all_extensions(HWND hwnd, struct detail_data *data)
{
    DWORD i;
    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;

    for (i = 0; i < cert->pCertInfo->cExtension; i++)
        add_cert_extension_detail(hwnd, data, &cert->pCertInfo->rgExtension[i]);
}

static void add_critical_extensions(HWND hwnd, struct detail_data *data)
{
    DWORD i;
    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;

    for (i = 0; i < cert->pCertInfo->cExtension; i++)
        if (cert->pCertInfo->rgExtension[i].fCritical)
            add_cert_extension_detail(hwnd, data,
             &cert->pCertInfo->rgExtension[i]);
}

typedef WCHAR * (*prop_to_value_func)(void *pb, DWORD cb);

struct prop_id_to_string_id
{
    DWORD prop;
    int id;
    BOOL prop_is_string;
    prop_to_value_func prop_to_value;
};

static WCHAR *format_enhanced_key_usage_value(void *pb, DWORD cb)
{
    CERT_EXTENSION ext;

    ext.pszObjId = (LPSTR)X509_ENHANCED_KEY_USAGE;
    ext.fCritical = FALSE;
    ext.Value.pbData = pb;
    ext.Value.cbData = cb;
    return crypt_format_extension(&ext, 0);
}

/* Logically the access state should also be checked, and IDC_EDITPROPERTIES
 * disabled for read-only certificates, but native doesn't appear to do that.
 */
static const struct prop_id_to_string_id prop_id_map[] = {
 { CERT_HASH_PROP_ID, IDS_PROP_HASH, FALSE, format_hex_string },
 { CERT_FRIENDLY_NAME_PROP_ID, IDS_PROP_FRIENDLY_NAME, TRUE, NULL },
 { CERT_DESCRIPTION_PROP_ID, IDS_PROP_DESCRIPTION, TRUE, NULL },
 { CERT_ENHKEY_USAGE_PROP_ID, IDS_PROP_ENHKEY_USAGE, FALSE,
   format_enhanced_key_usage_value },
};

static void add_properties(HWND hwnd, struct detail_data *data)
{
    DWORD i;
    PCCERT_CONTEXT cert = data->pCertViewInfo->pCertContext;

    for (i = 0; i < sizeof(prop_id_map) / sizeof(prop_id_map[0]); i++)
    {
        DWORD cb;

        if (CertGetCertificateContextProperty(cert, prop_id_map[i].prop, NULL,
         &cb))
        {
            BYTE *pb;
            WCHAR *val = NULL;

            /* FIXME: MS adds a separate value for the signature hash
             * algorithm.
             */
            pb = HeapAlloc(GetProcessHeap(), 0, cb);
            if (pb)
            {
                if (CertGetCertificateContextProperty(cert,
                 prop_id_map[i].prop, pb, &cb))
                {
                    if (prop_id_map[i].prop_is_string)
                    {
                        val = (LPWSTR)pb;
                        /* Don't double-free pb */
                        pb = NULL;
                    }
                    else
                        val = prop_id_map[i].prop_to_value(pb, cb);
                }
                HeapFree(GetProcessHeap(), 0, pb);
            }
            add_string_id_and_value_to_list(hwnd, data, prop_id_map[i].id, val,
             NULL, NULL);
        }
    }
}

static void add_all_fields(HWND hwnd, struct detail_data *data)
{
    add_v1_fields(hwnd, data);
    add_all_extensions(hwnd, data);
    add_properties(hwnd, data);
}

struct selection_list_item
{
    int id;
    add_fields_func add;
};

static const struct selection_list_item listItems[] = {
 { IDS_FIELDS_ALL, add_all_fields },
 { IDS_FIELDS_V1, add_v1_fields },
 { IDS_FIELDS_EXTENSIONS, add_all_extensions },
 { IDS_FIELDS_CRITICAL_EXTENSIONS, add_critical_extensions },
 { IDS_FIELDS_PROPERTIES, add_properties },
};

static void create_show_list(HWND hwnd, struct detail_data *data)
{
    HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
    WCHAR buf[MAX_STRING_LEN];
    int i;

    for (i = 0; i < sizeof(listItems) / sizeof(listItems[0]); i++)
    {
        int index;

        LoadStringW(hInstance, listItems[i].id, buf,
         sizeof(buf) / sizeof(buf[0]));
        index = SendMessageW(cb, CB_INSERTSTRING, -1, (LPARAM)buf);
        SendMessageW(cb, CB_SETITEMDATA, index, (LPARAM)data);
    }
    SendMessageW(cb, CB_SETCURSEL, 0, 0);
}

static void create_listview_columns(HWND hwnd)
{
    HWND lv = GetDlgItem(hwnd, IDC_DETAIL_LIST);
    RECT rc;
    WCHAR buf[MAX_STRING_LEN];
    LVCOLUMNW column;

    SendMessageW(lv, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
    GetWindowRect(lv, &rc);
    LoadStringW(hInstance, IDS_FIELD, buf, sizeof(buf) / sizeof(buf[0]));
    column.mask = LVCF_WIDTH | LVCF_TEXT;
    column.cx = (rc.right - rc.left) / 2 - 2;
    column.pszText = buf;
    SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
    LoadStringW(hInstance, IDS_VALUE, buf, sizeof(buf) / sizeof(buf[0]));
    SendMessageW(lv, LVM_INSERTCOLUMNW, 1, (LPARAM)&column);
}

static void set_fields_selection(HWND hwnd, struct detail_data *data, int sel)
{
    HWND list = GetDlgItem(hwnd, IDC_DETAIL_LIST);

    if (sel >= 0 && sel < sizeof(listItems) / sizeof(listItems[0]))
    {
        SendMessageW(list, LVM_DELETEALLITEMS, 0, 0);
        listItems[sel].add(list, data);
    }
}

static void create_cert_details_list(HWND hwnd, struct detail_data *data)
{
    create_show_list(hwnd, data);
    create_listview_columns(hwnd);
    set_fields_selection(hwnd, data, 0);
}

static void add_purpose(HWND hwnd, LPCSTR oid)
{
    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
    PCRYPT_OID_INFO info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
     sizeof(CRYPT_OID_INFO));

    if (info)
    {
        char *oidCopy = HeapAlloc(GetProcessHeap(), 0, strlen(oid) + 1);

        if (oidCopy)
        {
            LVITEMA item;

            strcpy(oidCopy, oid);
            info->cbSize = sizeof(CRYPT_OID_INFO);
            info->pszOID = oidCopy;
            item.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
            item.state = INDEXTOSTATEIMAGEMASK(CheckBitmapIndexChecked);
            item.stateMask = LVIS_STATEIMAGEMASK;
            item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
            item.iSubItem = 0;
            item.lParam = (LPARAM)info;
            item.pszText = oidCopy;
            SendMessageA(lv, LVM_INSERTITEMA, 0, (LPARAM)&item);
        }
        else
            HeapFree(GetProcessHeap(), 0, info);
    }
}

static BOOL is_valid_oid(LPCSTR oid)
{
    BOOL ret;

    if (oid[0] != '0' && oid[0] != '1' && oid[0] != '2')
        ret = FALSE;
    else if (oid[1] != '.')
        ret = FALSE;
    else if (!oid[2])
        ret = FALSE;
    else
    {
        const char *ptr;
        BOOL expectNum = TRUE;

        for (ptr = oid + 2, ret = TRUE; ret && *ptr; ptr++)
        {
            if (expectNum)
            {
                if (!isdigit(*ptr))
                    ret = FALSE;
                else if (*(ptr + 1) == '.')
                    expectNum = FALSE;
            }
            else
            {
                if (*ptr != '.')
                    ret = FALSE;
                else if (!(*(ptr + 1)))
                    ret = FALSE;
                else
                    expectNum = TRUE;
            }
        }
    }
    return ret;
}

static BOOL is_oid_in_list(HWND hwnd, LPCSTR oid)
{
    return find_oid_in_list(GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES), oid)
     != -1;
}

#define MAX_PURPOSE 255

static LRESULT CALLBACK add_purpose_dlg_proc(HWND hwnd, UINT msg,
 WPARAM wp, LPARAM lp)
{
    LRESULT ret = 0;
    char buf[MAX_PURPOSE + 1];

    switch (msg)
    {
    case WM_INITDIALOG:
        SendMessageW(GetDlgItem(hwnd, IDC_NEW_PURPOSE), EM_SETLIMITTEXT,
         MAX_PURPOSE, 0);
        ShowScrollBar(GetDlgItem(hwnd, IDC_NEW_PURPOSE), SB_VERT, FALSE);
        SetWindowLongPtrW(hwnd, DWLP_USER, lp);
        break;
    case WM_COMMAND:
        switch (HIWORD(wp))
        {
        case EN_CHANGE:
            if (LOWORD(wp) == IDC_NEW_PURPOSE)
            {
                /* Show/hide scroll bar on description depending on how much
                 * text it has.
                 */
                HWND description = GetDlgItem(hwnd, IDC_NEW_PURPOSE);
                int lines = SendMessageW(description, EM_GETLINECOUNT, 0, 0);

                ShowScrollBar(description, SB_VERT, lines > 1);
            }
            break;
        case BN_CLICKED:
            switch (LOWORD(wp))
            {
            case IDOK:
                SendMessageA(GetDlgItem(hwnd, IDC_NEW_PURPOSE), WM_GETTEXT,
                 sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
                if (!buf[0])
                {
                    /* An empty purpose is the same as cancelling */
                    EndDialog(hwnd, IDCANCEL);
                    ret = TRUE;
                }
                else if (!is_valid_oid(buf))
                {
                    WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];

                    LoadStringW(hInstance, IDS_CERTIFICATE_PURPOSE_ERROR, error,
                     sizeof(error) / sizeof(error[0]));
                    LoadStringW(hInstance, IDS_CERTIFICATE_PROPERTIES, title,
                     sizeof(title) / sizeof(title[0]));
                    MessageBoxW(hwnd, error, title, MB_ICONERROR | MB_OK);
                }
                else if (is_oid_in_list(
                 (HWND)GetWindowLongPtrW(hwnd, DWLP_USER), buf))
                {
                    WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];

                    LoadStringW(hInstance, IDS_CERTIFICATE_PURPOSE_EXISTS,
                     error, sizeof(error) / sizeof(error[0]));
                    LoadStringW(hInstance, IDS_CERTIFICATE_PROPERTIES, title,
                     sizeof(title) / sizeof(title[0]));
                    MessageBoxW(hwnd, error, title, MB_ICONEXCLAMATION | MB_OK);
                }
                else
                {
                    HWND parent = (HWND)GetWindowLongPtrW(hwnd, DWLP_USER);

                    add_purpose(parent, buf);
                    EndDialog(hwnd, wp);
                    ret = TRUE;
                }
                break;
            case IDCANCEL:
                EndDialog(hwnd, wp);
                ret = TRUE;
                break;
            }
            break;
        }
        break;
    }
    return ret;
}

static WCHAR *get_cert_property_as_string(PCCERT_CONTEXT cert, DWORD prop)
{
    WCHAR *name = NULL;
    DWORD cb;

    if (CertGetCertificateContextProperty(cert, prop, NULL, &cb))
    {
        name = HeapAlloc(GetProcessHeap(), 0, cb);
        if (name)
        {
            if (!CertGetCertificateContextProperty(cert, prop, name, &cb))
            {
                HeapFree(GetProcessHeap(), 0, name);
                name = NULL;
            }
        }
    }
    return name;
}

static void redraw_states(HWND list, BOOL enabled)
{
    int items = SendMessageW(list, LVM_GETITEMCOUNT, 0, 0), i;

    for (i = 0; i < items; i++)
    {
        BOOL change = FALSE;
        int state;

        state = SendMessageW(list, LVM_GETITEMSTATE, i, LVIS_STATEIMAGEMASK);
        /* This reverses the INDEXTOSTATEIMAGEMASK shift.  There doesn't appear
         * to be a handy macro for it.
         */
        state >>= 12;
        if (enabled)
        {
            if (state == CheckBitmapIndexDisabledChecked)
            {
                state = CheckBitmapIndexChecked;
                change = TRUE;
            }
            if (state == CheckBitmapIndexDisabledUnchecked)
            {
                state = CheckBitmapIndexUnchecked;
                change = TRUE;
            }
        }
        else
        {
            if (state == CheckBitmapIndexChecked)
            {
                state = CheckBitmapIndexDisabledChecked;
                change = TRUE;
            }
            if (state == CheckBitmapIndexUnchecked)
            {
                state = CheckBitmapIndexDisabledUnchecked;
                change = TRUE;
            }
        }
        if (change)
        {
            LVITEMW item;

            item.state = INDEXTOSTATEIMAGEMASK(state);
            item.stateMask = LVIS_STATEIMAGEMASK;
            SendMessageW(list, LVM_SETITEMSTATE, i, (LPARAM)&item);
        }
    }
}

typedef enum {
    PurposeEnableAll = 0,
    PurposeDisableAll,
    PurposeEnableSelected
} PurposeSelection;

static void select_purposes(HWND hwnd, PurposeSelection selection)
{
    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);

    switch (selection)
    {
    case PurposeEnableAll:
    case PurposeDisableAll:
        EnableWindow(lv, FALSE);
        redraw_states(lv, FALSE);
        EnableWindow(GetDlgItem(hwnd, IDC_ADD_PURPOSE), FALSE);
        break;
    case PurposeEnableSelected:
        EnableWindow(lv, TRUE);
        redraw_states(lv, TRUE);
        EnableWindow(GetDlgItem(hwnd, IDC_ADD_PURPOSE), TRUE);
    }
}

struct edit_cert_data
{
    PCCERT_CONTEXT cert;
    BOOL *pfPropertiesChanged;
    HIMAGELIST imageList;
};

static void show_cert_usages(HWND hwnd, struct edit_cert_data *data)
{
    PCCERT_CONTEXT cert = data->cert;
    HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
    PCERT_ENHKEY_USAGE usage;
    DWORD size;
    RECT rc;
    LVCOLUMNW column;
    PurposeSelection purposeSelection = PurposeEnableAll;

    GetWindowRect(lv, &rc);
    column.mask = LVCF_WIDTH;
    column.cx = rc.right - rc.left;
    SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
    SendMessageW(lv, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)data->imageList);

    /* Get enhanced key usage.  Have to check for a property and an extension
     * separately, because CertGetEnhancedKeyUsage will succeed and return an
     * empty usage if neither is set.  Unfortunately an empty usage implies
     * no usage is allowed, so we have to distinguish between the two cases.
     */
    if (CertGetEnhancedKeyUsage(cert, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
     NULL, &size))
    {
        usage = HeapAlloc(GetProcessHeap(), 0, size);
        if (!CertGetEnhancedKeyUsage(cert,
         CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
        {
            HeapFree(GetProcessHeap(), 0, usage);
            usage = NULL;
        }
        else if (usage->cUsageIdentifier)
            purposeSelection = PurposeEnableSelected;
        else
            purposeSelection = PurposeDisableAll;
    }
    else if (CertGetEnhancedKeyUsage(cert, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
     NULL, &size))
    {
        usage = HeapAlloc(GetProcessHeap(), 0, size);
        if (!CertGetEnhancedKeyUsage(cert,
         CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, usage, &size))
        {
            HeapFree(GetProcessHeap(), 0, usage);
            usage = NULL;
        }
        else if (usage->cUsageIdentifier)
            purposeSelection = PurposeEnableAll;
        else
            purposeSelection = PurposeDisableAll;
    }
    else
    {
        purposeSelection = PurposeEnableAll;
        usage = NULL;
    }
    if (usage)
    {
        DWORD i;

        for (i = 0; i < usage->cUsageIdentifier; i++)
        {
            PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
             usage->rgpszUsageIdentifier[i], CRYPT_ENHKEY_USAGE_OID_GROUP_ID);

            if (info)
                add_known_usage(lv, info, CheckBitmapIndexDisabledChecked);
            else
                add_purpose(hwnd, usage->rgpszUsageIdentifier[i]);
        }
        HeapFree(GetProcessHeap(), 0, usage);
    }
    else
        add_known_usages_to_list(lv, CheckBitmapIndexDisabledChecked);
    select_purposes(hwnd, purposeSelection);
    SendMessageW(GetDlgItem(hwnd, IDC_ENABLE_ALL_PURPOSES + purposeSelection),
     BM_CLICK, 0, 0);
}

static void set_general_cert_properties(HWND hwnd, struct edit_cert_data *data)
{
    PCCERT_CONTEXT cert = data->cert;
    WCHAR *str;

    if ((str = get_cert_property_as_string(cert, CERT_FRIENDLY_NAME_PROP_ID)))
    {
        SendMessageW(GetDlgItem(hwnd, IDC_FRIENDLY_NAME), WM_SETTEXT, 0,
         (LPARAM)str);
        HeapFree(GetProcessHeap(), 0, str);
    }
    if ((str = get_cert_property_as_string(cert, CERT_DESCRIPTION_PROP_ID)))
    {
        SendMessageW(GetDlgItem(hwnd, IDC_DESCRIPTION), WM_SETTEXT, 0,
         (LPARAM)str);
        HeapFree(GetProcessHeap(), 0, str);
    }
    show_cert_usages(hwnd, data);
}

static void set_cert_string_property(PCCERT_CONTEXT cert, DWORD prop,
 LPWSTR str)
{
    if (str && strlenW(str))
    {
        CRYPT_DATA_BLOB blob;

        blob.pbData = (BYTE *)str;
        blob.cbData = (strlenW(str) + 1) * sizeof(WCHAR);
        CertSetCertificateContextProperty(cert, prop, 0, &blob);
    }
    else
        CertSetCertificateContextProperty(cert, prop, 0, NULL);
}

#define WM_REFRESH_VIEW WM_USER + 0

static BOOL CALLBACK refresh_propsheet_pages(HWND hwnd, LPARAM lParam)
{
    if ((GetClassLongW(hwnd, GCW_ATOM) == WC_DIALOG))
        SendMessageW(hwnd, WM_REFRESH_VIEW, 0, 0);
    return TRUE;
}

#define MAX_FRIENDLY_NAME 40
#define MAX_DESCRIPTION 255

static void apply_general_changes(HWND hwnd)
{
    WCHAR buf[MAX_DESCRIPTION + 1];
    struct edit_cert_data *data =
     (struct edit_cert_data *)GetWindowLongPtrW(hwnd, DWLP_USER);

    SendMessageW(GetDlgItem(hwnd, IDC_FRIENDLY_NAME), WM_GETTEXT,
     sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
    set_cert_string_property(data->cert, CERT_FRIENDLY_NAME_PROP_ID, buf);
    SendMessageW(GetDlgItem(hwnd, IDC_DESCRIPTION), WM_GETTEXT,
     sizeof(buf) / sizeof(buf[0]), (LPARAM)buf);
    set_cert_string_property(data->cert, CERT_DESCRIPTION_PROP_ID, buf);
    if (IsDlgButtonChecked(hwnd, IDC_ENABLE_ALL_PURPOSES))
    {
        /* Setting a NULL usage removes the enhanced key usage property. */
        CertSetEnhancedKeyUsage(data->cert, NULL);
    }
    else if (IsDlgButtonChecked(hwnd, IDC_DISABLE_ALL_PURPOSES))
    {
        CERT_ENHKEY_USAGE usage = { 0, NULL };

        CertSetEnhancedKeyUsage(data->cert, &usage);
    }
    else if (IsDlgButtonChecked(hwnd, IDC_ENABLE_SELECTED_PURPOSES))
    {
        HWND lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
        CERT_ENHKEY_USAGE usage = { 0, NULL };
        int purposes = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0), i;
        LVITEMW item;

        item.mask = LVIF_STATE | LVIF_PARAM;
        item.iSubItem = 0;
        item.stateMask = LVIS_STATEIMAGEMASK;
        for (i = 0; i < purposes; i++)
        {
            item.iItem = i;
            if (SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item))
            {
                int state = item.state >> 12;

                if (state == CheckBitmapIndexChecked)
                {
                    CRYPT_OID_INFO *info = (CRYPT_OID_INFO *)item.lParam;

                    if (usage.cUsageIdentifier)
                        usage.rgpszUsageIdentifier =
                         HeapReAlloc(GetProcessHeap(), 0,
                         usage.rgpszUsageIdentifier,
                         (usage.cUsageIdentifier + 1) * sizeof(LPSTR));
                    else
                        usage.rgpszUsageIdentifier =
                         HeapAlloc(GetProcessHeap(), 0, sizeof(LPSTR));
                    if (usage.rgpszUsageIdentifier)
                        usage.rgpszUsageIdentifier[usage.cUsageIdentifier++] =
                         (LPSTR)info->pszOID;
                }
            }
        }
        CertSetEnhancedKeyUsage(data->cert, &usage);
        HeapFree(GetProcessHeap(), 0, usage.rgpszUsageIdentifier);
    }
    EnumChildWindows(GetParent(GetParent(hwnd)), refresh_propsheet_pages, 0);
    if (data->pfPropertiesChanged)
        *data->pfPropertiesChanged = TRUE;
}

static LRESULT CALLBACK cert_properties_general_dlg_proc(HWND hwnd, UINT msg,
 WPARAM wp, LPARAM lp)
{
    PROPSHEETPAGEW *page;

    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        HWND description = GetDlgItem(hwnd, IDC_DESCRIPTION);
        struct detail_data *detailData;
        struct edit_cert_data *editData;

        page = (PROPSHEETPAGEW *)lp;
        detailData = (struct detail_data *)page->lParam;
        SendMessageW(GetDlgItem(hwnd, IDC_FRIENDLY_NAME), EM_SETLIMITTEXT,
         MAX_FRIENDLY_NAME, 0);
        SendMessageW(description, EM_SETLIMITTEXT, MAX_DESCRIPTION, 0);
        ShowScrollBar(description, SB_VERT, FALSE);
        editData = HeapAlloc(GetProcessHeap(), 0,
         sizeof(struct edit_cert_data));
        if (editData)
        {
            editData->imageList = ImageList_Create(16, 16,
             ILC_COLOR4 | ILC_MASK, 4, 0);
            if (editData->imageList)
            {
                HBITMAP bmp;
                COLORREF backColor = RGB(255, 0, 255);

                bmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_CHECKS));
                ImageList_AddMasked(editData->imageList, bmp, backColor);
                DeleteObject(bmp);
                ImageList_SetBkColor(editData->imageList, CLR_NONE);
            }
            editData->cert = detailData->pCertViewInfo->pCertContext;
            editData->pfPropertiesChanged = detailData->pfPropertiesChanged;
            SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)editData);
            set_general_cert_properties(hwnd, editData);
        }
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;
        NMITEMACTIVATE *nm;

        switch (hdr->code)
        {
        case NM_CLICK:
            nm = (NMITEMACTIVATE *)lp;
            toggle_usage(hwnd, nm->iItem);
            SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
            break;
        case PSN_APPLY:
            apply_general_changes(hwnd);
            break;
        }
        break;
    }
    case WM_COMMAND:
        switch (HIWORD(wp))
        {
        case EN_CHANGE:
            SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
            if (LOWORD(wp) == IDC_DESCRIPTION)
            {
                /* Show/hide scroll bar on description depending on how much
                 * text it has.
                 */
                HWND description = GetDlgItem(hwnd, IDC_DESCRIPTION);
                int lines = SendMessageW(description, EM_GETLINECOUNT, 0, 0);

                ShowScrollBar(description, SB_VERT, lines > 1);
            }
            break;
        case BN_CLICKED:
            switch (LOWORD(wp))
            {
            case IDC_ADD_PURPOSE:
                if (DialogBoxParamW(hInstance,
                 MAKEINTRESOURCEW(IDD_ADD_CERT_PURPOSE), hwnd,
                 add_purpose_dlg_proc, (LPARAM)hwnd) == IDOK)
                    SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
                break;
            case IDC_ENABLE_ALL_PURPOSES:
            case IDC_DISABLE_ALL_PURPOSES:
            case IDC_ENABLE_SELECTED_PURPOSES:
                SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
                select_purposes(hwnd, LOWORD(wp) - IDC_ENABLE_ALL_PURPOSES);
                break;
            }
            break;
        }
        break;
    }
    return 0;
}

static UINT CALLBACK cert_properties_general_callback(HWND hwnd, UINT msg,
 PROPSHEETPAGEW *page)
{
    HWND lv;
    int cItem, i;
    struct edit_cert_data *data;

    switch (msg)
    {
    case PSPCB_RELEASE:
        lv = GetDlgItem(hwnd, IDC_CERTIFICATE_USAGES);
        cItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
        for (i = 0; i < cItem; i++)
        {
            LVITEMW item;

            item.mask = LVIF_PARAM;
            item.iItem = i;
            item.iSubItem = 0;
            if (SendMessageW(lv, LVM_GETITEMW, 0, (LPARAM)&item) && item.lParam)
            {
                PCRYPT_OID_INFO info = (PCRYPT_OID_INFO)item.lParam;

                if (info->cbSize == sizeof(CRYPT_OID_INFO) && !info->dwGroupId)
                {
                    HeapFree(GetProcessHeap(), 0, (LPSTR)info->pszOID);
                    HeapFree(GetProcessHeap(), 0, info);
                }
            }
        }
        data = (struct edit_cert_data *)GetWindowLongPtrW(hwnd, DWLP_USER);
        if (data)
        {
            ImageList_Destroy(data->imageList);
            HeapFree(GetProcessHeap(), 0, data);
        }
        break;
    }
    return 1;
}

static void show_edit_cert_properties_dialog(HWND parent,
 struct detail_data *data)
{
    PROPSHEETHEADERW hdr;
    PROPSHEETPAGEW page; /* FIXME: need to add a cross-certificate page */

    TRACE("(%p)\n", data);

    memset(&page, 0, sizeof(PROPSHEETPAGEW));
    page.dwSize = sizeof(page);
    page.dwFlags = PSP_USECALLBACK;
    page.pfnCallback = cert_properties_general_callback;
    page.hInstance = hInstance;
    page.u.pszTemplate = MAKEINTRESOURCEW(IDD_CERT_PROPERTIES_GENERAL);
    page.pfnDlgProc = cert_properties_general_dlg_proc;
    page.lParam = (LPARAM)data;

    memset(&hdr, 0, sizeof(hdr));
    hdr.dwSize = sizeof(hdr);
    hdr.hwndParent = parent;
    hdr.dwFlags = PSH_PROPSHEETPAGE;
    hdr.hInstance = hInstance;
    hdr.pszCaption = MAKEINTRESOURCEW(IDS_CERTIFICATE_PROPERTIES);
    hdr.u3.ppsp = &page;
    hdr.nPages = 1;
    PropertySheetW(&hdr);
}

static void free_detail_fields(struct detail_data *data)
{
    DWORD i;

    for (i = 0; i < data->cFields; i++)
        HeapFree(GetProcessHeap(), 0, data->fields[i].detailed_value);
    HeapFree(GetProcessHeap(), 0, data->fields);
    data->fields = NULL;
    data->cFields = 0;
}

static void refresh_details_view(HWND hwnd)
{
    HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
    int curSel;
    struct detail_data *data;

    curSel = SendMessageW(cb, CB_GETCURSEL, 0, 0);
    /* Actually, any index will do, since they all store the same data value */
    data = (struct detail_data *)SendMessageW(cb, CB_GETITEMDATA, curSel, 0);
    free_detail_fields(data);
    set_fields_selection(hwnd, data, curSel);
}

static LRESULT CALLBACK detail_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    PROPSHEETPAGEW *page;
    struct detail_data *data;

    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);

    switch (msg)
    {
    case WM_INITDIALOG:
        page = (PROPSHEETPAGEW *)lp;
        data = (struct detail_data *)page->lParam;
        create_cert_details_list(hwnd, data);
        if (!(data->pCertViewInfo->dwFlags & CRYPTUI_ENABLE_EDITPROPERTIES))
            EnableWindow(GetDlgItem(hwnd, IDC_EDITPROPERTIES), FALSE);
        if (data->pCertViewInfo->dwFlags & CRYPTUI_DISABLE_EXPORT)
            EnableWindow(GetDlgItem(hwnd, IDC_EXPORT), FALSE);
        break;
    case WM_NOTIFY:
    {
        NMITEMACTIVATE *nm;
        HWND list = GetDlgItem(hwnd, IDC_DETAIL_LIST);

        nm = (NMITEMACTIVATE*)lp;
        if (nm->hdr.hwndFrom == list && nm->uNewState & LVN_ITEMACTIVATE
         && nm->hdr.code == LVN_ITEMCHANGED)
        {
            data = (struct detail_data *)nm->lParam;
            if (nm->iItem >= 0 && data && nm->iItem < data->cFields)
            {
                WCHAR buf[MAX_STRING_LEN], *val = NULL;
                HWND valueCtl = GetDlgItem(hwnd, IDC_DETAIL_VALUE);

                if (data->fields[nm->iItem].create)
                    val = data->fields[nm->iItem].create(
                     data->pCertViewInfo->pCertContext,
                     data->fields[nm->iItem].param);
                else
                {
                    LVITEMW item;
                    int res;

                    item.cchTextMax = sizeof(buf) / sizeof(buf[0]);
                    item.mask = LVIF_TEXT;
                    item.pszText = buf;
                    item.iItem = nm->iItem;
                    item.iSubItem = 1;
                    res = SendMessageW(list, LVM_GETITEMW, 0, (LPARAM)&item);
                    if (res)
                        val = buf;
                }
                /* Select all the text in the control, the next update will
                 * replace it
                 */
                SendMessageW(valueCtl, EM_SETSEL, 0, -1);
                add_unformatted_text_to_control(valueCtl, val,
                 val ? strlenW(val) : 0);
                if (val != buf)
                    HeapFree(GetProcessHeap(), 0, val);
            }
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDC_EXPORT:
        {
            HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
            CRYPTUI_WIZ_EXPORT_INFO info;

            data = (struct detail_data *)SendMessageW(cb, CB_GETITEMDATA, 0, 0);
            info.dwSize = sizeof(info);
            info.pwszExportFileName = NULL;
            info.dwSubjectChoice = CRYPTUI_WIZ_EXPORT_CERT_CONTEXT;
            info.u.pCertContext = data->pCertViewInfo->pCertContext;
            info.cStores = 0;
            CryptUIWizExport(0, hwnd, NULL, &info, NULL);
            break;
        }
        case IDC_EDITPROPERTIES:
        {
            HWND cb = GetDlgItem(hwnd, IDC_DETAIL_SELECT);
            int curSel;

            curSel = SendMessageW(cb, CB_GETCURSEL, 0, 0);
            /* Actually, any index will do, since they all store the same
             * data value
             */
            data = (struct detail_data *)SendMessageW(cb, CB_GETITEMDATA,
             curSel, 0);
            show_edit_cert_properties_dialog(GetParent(hwnd), data);
            break;
        }
        case ((CBN_SELCHANGE << 16) | IDC_DETAIL_SELECT):
            refresh_details_view(hwnd);
            break;
        }
        break;
    case WM_REFRESH_VIEW:
        refresh_details_view(hwnd);
        break;
    }
    return 0;
}

static UINT CALLBACK detail_callback(HWND hwnd, UINT msg,
 PROPSHEETPAGEW *page)
{
    struct detail_data *data;

    switch (msg)
    {
    case PSPCB_RELEASE:
        data = (struct detail_data *)page->lParam;
        free_detail_fields(data);
        HeapFree(GetProcessHeap(), 0, data);
        break;
    }
    return 0;
}

static BOOL init_detail_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
 BOOL *pfPropertiesChanged, PROPSHEETPAGEW *page)
{
    BOOL ret;
    struct detail_data *data = HeapAlloc(GetProcessHeap(), 0,
     sizeof(struct detail_data));

    if (data)
    {
        data->pCertViewInfo = pCertViewInfo;
        data->pfPropertiesChanged = pfPropertiesChanged;
        data->cFields = 0;
        data->fields = NULL;
        memset(page, 0, sizeof(PROPSHEETPAGEW));
        page->dwSize = sizeof(PROPSHEETPAGEW);
        page->dwFlags = PSP_USECALLBACK;
        page->pfnCallback = detail_callback;
        page->hInstance = hInstance;
        page->u.pszTemplate = MAKEINTRESOURCEW(IDD_DETAIL);
        page->pfnDlgProc = detail_dlg_proc;
        page->lParam = (LPARAM)data;
        ret = TRUE;
    }
    else
        ret = FALSE;
    return ret;
}

struct hierarchy_data
{
    PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo;
    HIMAGELIST imageList;
    DWORD selectedCert;
};

static LPARAM index_to_lparam(struct hierarchy_data *data, DWORD index)
{
    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
     (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
     data->pCertViewInfo->idxSigner, data->pCertViewInfo->fCounterSigner,
     data->pCertViewInfo->idxCounterSigner);

    /* Takes advantage of the fact that a pointer is 32-bit aligned, and
     * therefore always even.
     */
    if (index == provSigner->csCertChain - 1)
        return (LPARAM)data;
    return index << 1 | 1;
}

static inline DWORD lparam_to_index(struct hierarchy_data *data, LPARAM lp)
{
    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
     (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
     data->pCertViewInfo->idxSigner, data->pCertViewInfo->fCounterSigner,
     data->pCertViewInfo->idxCounterSigner);

    if (!(lp & 1))
        return provSigner->csCertChain - 1;
    return lp >> 1;
}

static struct hierarchy_data *get_hierarchy_data_from_tree_item(HWND tree,
 HTREEITEM hItem)
{
    struct hierarchy_data *data = NULL;
    HTREEITEM root = NULL;

    do {
        HTREEITEM parent = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM,
         TVGN_PARENT, (LPARAM)hItem);

        if (!parent)
            root = hItem;
        hItem = parent;
    } while (hItem);
    if (root)
    {
        TVITEMW item;

        item.mask = TVIF_PARAM;
        item.hItem = root;
        SendMessageW(tree, TVM_GETITEMW, 0, (LPARAM)&item);
        data = (struct hierarchy_data *)item.lParam;
    }
    return data;
}

static WCHAR *get_cert_display_name(PCCERT_CONTEXT cert)
{
    WCHAR *name = get_cert_property_as_string(cert, CERT_FRIENDLY_NAME_PROP_ID);

    if (!name)
        name = get_cert_name_string(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0);
    return name;
}

static void show_cert_chain(HWND hwnd, struct hierarchy_data *data)
{
    HWND tree = GetDlgItem(hwnd, IDC_CERTPATH);
    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
     (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
     data->pCertViewInfo->idxSigner, data->pCertViewInfo->fCounterSigner,
     data->pCertViewInfo->idxCounterSigner);
    DWORD i;
    HTREEITEM parent = NULL;

    SendMessageW(tree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)data->imageList);
    for (i = provSigner->csCertChain; i; i--)
    {
        LPWSTR name;

        name = get_cert_display_name(provSigner->pasCertChain[i - 1].pCert);
        if (name)
        {
            TVINSERTSTRUCTW tvis;

            tvis.hParent = parent;
            tvis.hInsertAfter = TVI_LAST;
            tvis.u.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_IMAGE |
             TVIF_SELECTEDIMAGE | TVIF_PARAM;
            tvis.u.item.pszText = name;
            tvis.u.item.state = TVIS_EXPANDED;
            tvis.u.item.stateMask = TVIS_EXPANDED;
            if (i == 1 && (!provSigner->pChainContext ||
             provSigner->pChainContext->TrustStatus.dwErrorStatus &
             CERT_TRUST_IS_PARTIAL_CHAIN))
            {
                /* The root of the chain has a special case:  if the chain is
                 * a partial chain, the icon is a warning icon rather than an
                 * error icon.
                 */
                tvis.u.item.iImage = 2;
            }
            else if (provSigner->pasCertChain[i - 1].pChainElement->TrustStatus.
             dwErrorStatus == 0)
                tvis.u.item.iImage = 0;
            else
                tvis.u.item.iImage = 1;
            tvis.u.item.iSelectedImage = tvis.u.item.iImage;
            tvis.u.item.lParam = index_to_lparam(data, i - 1);
            parent = (HTREEITEM)SendMessageW(tree, TVM_INSERTITEMW, 0,
             (LPARAM)&tvis);
            HeapFree(GetProcessHeap(), 0, name);
        }
    }
}

static void set_certificate_status(HWND hwnd, const CRYPT_PROVIDER_CERT *cert)
{
    /* Select all the text in the control, the next update will replace it */
    SendMessageW(hwnd, EM_SETSEL, 0, -1);
    /* Set the highest priority error messages first. */
    if (!(cert->dwConfidence & CERT_CONFIDENCE_SIG))
        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_BAD_SIGNATURE);
    else if (!(cert->dwConfidence & CERT_CONFIDENCE_TIME))
        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_BAD_TIME);
    else if (!(cert->dwConfidence & CERT_CONFIDENCE_TIMENEST))
        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_BAD_TIMENEST);
    else if (cert->dwRevokedReason)
        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_REVOKED);
    else
        add_string_resource_to_control(hwnd, IDS_CERTIFICATE_VALID);
}

static void set_certificate_status_for_end_cert(HWND hwnd,
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo)
{
    HWND status = GetDlgItem(hwnd, IDC_CERTIFICATESTATUSTEXT);
    CRYPT_PROVIDER_SGNR *provSigner = WTHelperGetProvSignerFromChain(
     (CRYPT_PROVIDER_DATA *)pCertViewInfo->u.pCryptProviderData,
     pCertViewInfo->idxSigner, pCertViewInfo->fCounterSigner,
     pCertViewInfo->idxCounterSigner);
    CRYPT_PROVIDER_CERT *provCert = WTHelperGetProvCertFromChain(provSigner,
     pCertViewInfo->idxCert);

    set_certificate_status(status, provCert);
}

static void show_cert_hierarchy(HWND hwnd, struct hierarchy_data *data)
{
    /* Disable view certificate button until a certificate is selected */
    EnableWindow(GetDlgItem(hwnd, IDC_VIEWCERTIFICATE), FALSE);
    show_cert_chain(hwnd, data);
    set_certificate_status_for_end_cert(hwnd, data->pCertViewInfo);
}

static void show_dialog_for_selected_cert(HWND hwnd)
{
    HWND tree = GetDlgItem(hwnd, IDC_CERTPATH);
    TVITEMW item;
    struct hierarchy_data *data;
    DWORD selection;

    memset(&item, 0, sizeof(item));
    item.mask = TVIF_HANDLE | TVIF_PARAM;
    item.hItem = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM, TVGN_CARET, 0);
    SendMessageW(tree, TVM_GETITEMW, 0, (LPARAM)&item);
    data = get_hierarchy_data_from_tree_item(tree, item.hItem);
    selection = lparam_to_index(data, item.lParam);
    if (selection != 0)
    {
        CRYPT_PROVIDER_SGNR *provSigner;
        CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
        BOOL changed = FALSE;

        provSigner = WTHelperGetProvSignerFromChain(
         (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
         data->pCertViewInfo->idxSigner,
         data->pCertViewInfo->fCounterSigner,
         data->pCertViewInfo->idxCounterSigner);
        memset(&viewInfo, 0, sizeof(viewInfo));
        viewInfo.dwSize = sizeof(viewInfo);
        viewInfo.dwFlags = data->pCertViewInfo->dwFlags;
        viewInfo.szTitle = data->pCertViewInfo->szTitle;
        viewInfo.pCertContext = provSigner->pasCertChain[selection].pCert;
        viewInfo.cStores = data->pCertViewInfo->cStores;
        viewInfo.rghStores = data->pCertViewInfo->rghStores;
        viewInfo.cPropSheetPages = data->pCertViewInfo->cPropSheetPages;
        viewInfo.rgPropSheetPages = data->pCertViewInfo->rgPropSheetPages;
        viewInfo.nStartPage = data->pCertViewInfo->nStartPage;
        CryptUIDlgViewCertificateW(&viewInfo, &changed);
        if (changed)
        {
            /* Delete the contents of the tree */
            SendMessageW(tree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
            /* Reinitialize the tree */
            show_cert_hierarchy(hwnd, data);
        }
    }
}

static LRESULT CALLBACK hierarchy_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    PROPSHEETPAGEW *page;
    struct hierarchy_data *data;
    LRESULT ret = 0;
    HWND tree = GetDlgItem(hwnd, IDC_CERTPATH);

    TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd, msg, wp, lp);

    switch (msg)
    {
    case WM_INITDIALOG:
        page = (PROPSHEETPAGEW *)lp;
        data = (struct hierarchy_data *)page->lParam;
        show_cert_hierarchy(hwnd, data);
        break;
    case WM_NOTIFY:
    {
        NMHDR *hdr;

        hdr = (NMHDR *)lp;
        switch (hdr->code)
        {
        case TVN_SELCHANGEDW:
        {
            NMTREEVIEWW *nm = (NMTREEVIEWW*)lp;
            DWORD selection;
            CRYPT_PROVIDER_SGNR *provSigner;

            data = get_hierarchy_data_from_tree_item(tree, nm->itemNew.hItem);
            selection = lparam_to_index(data, nm->itemNew.lParam);
            provSigner = WTHelperGetProvSignerFromChain(
             (CRYPT_PROVIDER_DATA *)data->pCertViewInfo->u.pCryptProviderData,
             data->pCertViewInfo->idxSigner,
             data->pCertViewInfo->fCounterSigner,
             data->pCertViewInfo->idxCounterSigner);
            EnableWindow(GetDlgItem(hwnd, IDC_VIEWCERTIFICATE), selection != 0);
            set_certificate_status(GetDlgItem(hwnd, IDC_CERTIFICATESTATUSTEXT),
             &provSigner->pasCertChain[selection]);
            break;
        }
        case NM_DBLCLK:
            show_dialog_for_selected_cert(hwnd);
            SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
            ret = 1;
            break;
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDC_VIEWCERTIFICATE:
            show_dialog_for_selected_cert(hwnd);
            break;
        }
        break;
    case WM_REFRESH_VIEW:
    {
        TVITEMW item;

        /* Get hierarchy data */
        memset(&item, 0, sizeof(item));
        item.mask = TVIF_HANDLE | TVIF_PARAM;
        item.hItem = (HTREEITEM)SendMessageW(tree, TVM_GETNEXTITEM, TVGN_ROOT,
         0);
        data = get_hierarchy_data_from_tree_item(tree, item.hItem);
        /* Delete the contents of the tree */
        SendMessageW(tree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT);
        /* Reinitialize the tree */
        show_cert_hierarchy(hwnd, data);
        break;
    }
    }
    return ret;
}

static UINT CALLBACK hierarchy_callback(HWND hwnd, UINT msg,
 PROPSHEETPAGEW *page)
{
    struct hierarchy_data *data;

    switch (msg)
    {
    case PSPCB_RELEASE:
        data = (struct hierarchy_data *)page->lParam;
        ImageList_Destroy(data->imageList);
        HeapFree(GetProcessHeap(), 0, data);
        break;
    }
    return 0;
}

static BOOL init_hierarchy_page(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
 PROPSHEETPAGEW *page)
{
    struct hierarchy_data *data = HeapAlloc(GetProcessHeap(), 0,
     sizeof(struct hierarchy_data));
    BOOL ret = FALSE;

    if (data)
    {
        data->imageList = ImageList_Create(16, 16, ILC_COLOR4 | ILC_MASK, 2, 0);
        if (data->imageList)
        {
            HBITMAP bmp;
            COLORREF backColor = RGB(255, 0, 255);

            data->pCertViewInfo = pCertViewInfo;
            data->selectedCert = 0xffffffff;

            bmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_SMALL_ICONS));
            ImageList_AddMasked(data->imageList, bmp, backColor);
            DeleteObject(bmp);
            ImageList_SetBkColor(data->imageList, CLR_NONE);

            memset(page, 0, sizeof(PROPSHEETPAGEW));
            page->dwSize = sizeof(PROPSHEETPAGEW);
            page->dwFlags = PSP_USECALLBACK;
            page->hInstance = hInstance;
            page->u.pszTemplate = MAKEINTRESOURCEW(IDD_HIERARCHY);
            page->pfnDlgProc = hierarchy_dlg_proc;
            page->lParam = (LPARAM)data;
            page->pfnCallback = hierarchy_callback;
            ret = TRUE;
        }
        else
            HeapFree(GetProcessHeap(), 0, data);
    }
    return ret;
}

static int CALLBACK cert_prop_sheet_proc(HWND hwnd, UINT msg, LPARAM lp)
{
    RECT rc;

    TRACE("(%p, %08x, %08lx)\n", hwnd, msg, lp);

    switch (msg)
    {
    case PSCB_INITIALIZED:
        /* Get cancel button's position.. */
        GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rc);
        MapWindowPoints( 0, hwnd, (POINT *)&rc, 2 );
        /* hide the cancel button.. */
        ShowWindow(GetDlgItem(hwnd, IDCANCEL), FALSE);
        /* and move the OK button to the cancel button's original position. */
        SetWindowPos(GetDlgItem(hwnd, IDOK), 0, rc.left, rc.top, 0, 0,
                     SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
        break;
    }
    return 0;
}

static BOOL show_cert_dialog(PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo,
 CRYPT_PROVIDER_CERT *provCert, BOOL *pfPropertiesChanged)
{
    static const WCHAR riched[] = { 'r','i','c','h','e','d','2','0',0 };
    DWORD nPages;
    PROPSHEETPAGEW *pages;
    BOOL ret = FALSE;
    HMODULE lib = LoadLibraryW(riched);

    nPages = pCertViewInfo->cPropSheetPages + 1; /* one for the General tab */
    if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_DETAILPAGE))
        nPages++;
    if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_HIERARCHYPAGE))
        nPages++;
    pages = HeapAlloc(GetProcessHeap(), 0, nPages * sizeof(PROPSHEETPAGEW));
    if (pages)
    {
        PROPSHEETHEADERW hdr;
        CRYPTUI_INITDIALOG_STRUCT *init = NULL;
        DWORD i;

        memset(&hdr, 0, sizeof(hdr));
        hdr.dwSize = sizeof(hdr);
        hdr.dwFlags = PSH_NOAPPLYNOW | PSH_PROPSHEETPAGE | PSH_USECALLBACK;
        hdr.hInstance = hInstance;
        if (pCertViewInfo->szTitle)
            hdr.pszCaption = pCertViewInfo->szTitle;
        else
            hdr.pszCaption = MAKEINTRESOURCEW(IDS_CERTIFICATE);
        init_general_page(pCertViewInfo, &pages[hdr.nPages++]);
        if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_DETAILPAGE))
        {
            if (init_detail_page(pCertViewInfo, pfPropertiesChanged,
             &pages[hdr.nPages]))
                hdr.nPages++;
        }
        if (!(pCertViewInfo->dwFlags & CRYPTUI_HIDE_HIERARCHYPAGE))
        {
            if (init_hierarchy_page(pCertViewInfo, &pages[hdr.nPages]))
                hdr.nPages++;
        }
        /* Copy each additional page, and create the init dialog struct for it
         */
        if (pCertViewInfo->cPropSheetPages)
        {
            init = HeapAlloc(GetProcessHeap(), 0,
             pCertViewInfo->cPropSheetPages *
             sizeof(CRYPTUI_INITDIALOG_STRUCT));
            if (init)
            {
                for (i = 0; i < pCertViewInfo->cPropSheetPages; i++)
                {
                    memcpy(&pages[hdr.nPages + i],
                     &pCertViewInfo->rgPropSheetPages[i],
                     sizeof(PROPSHEETPAGEW));
                    init[i].lParam = pCertViewInfo->rgPropSheetPages[i].lParam;
                    init[i].pCertContext = pCertViewInfo->pCertContext;
                    pages[hdr.nPages + i].lParam = (LPARAM)&init[i];
                }
                if (pCertViewInfo->nStartPage & 0x8000)
                {
                    /* Start page index is relative to the number of default
                     * pages
                     */
                    hdr.u2.nStartPage = pCertViewInfo->nStartPage + hdr.nPages;
                }
                else
                    hdr.u2.nStartPage = pCertViewInfo->nStartPage;
                hdr.nPages = nPages;
                ret = TRUE;
            }
            else
                SetLastError(ERROR_OUTOFMEMORY);
        }
        else
        {
            /* Ignore the relative flag if there aren't any additional pages */
            hdr.u2.nStartPage = pCertViewInfo->nStartPage & 0x7fff;
            ret = TRUE;
        }
        if (ret)
        {
            INT_PTR l;

            hdr.u3.ppsp = pages;
            hdr.pfnCallback = cert_prop_sheet_proc;
            l = PropertySheetW(&hdr);
            if (l == 0)
            {
                SetLastError(ERROR_CANCELLED);
                ret = FALSE;
            }
        }
        HeapFree(GetProcessHeap(), 0, init);
        HeapFree(GetProcessHeap(), 0, pages);
    }
    else
        SetLastError(ERROR_OUTOFMEMORY);
    FreeLibrary(lib);
    return ret;
}

/***********************************************************************
 *		CryptUIDlgViewCertificateW (CRYPTUI.@)
 */
BOOL WINAPI CryptUIDlgViewCertificateW(
 PCCRYPTUI_VIEWCERTIFICATE_STRUCTW pCertViewInfo, BOOL *pfPropertiesChanged)
{
    static GUID generic_cert_verify = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
    CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;
    WINTRUST_DATA wvt;
    WINTRUST_CERT_INFO cert;
    BOOL ret = FALSE;
    CRYPT_PROVIDER_SGNR *signer;
    CRYPT_PROVIDER_CERT *provCert = NULL;

    TRACE("(%p, %p)\n", pCertViewInfo, pfPropertiesChanged);

    if (pCertViewInfo->dwSize != sizeof(CRYPTUI_VIEWCERTIFICATE_STRUCTW))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    /* Make a local copy in case we have to call WinVerifyTrust ourselves */
    memcpy(&viewInfo, pCertViewInfo, sizeof(viewInfo));
    if (!pCertViewInfo->u.hWVTStateData)
    {
        memset(&wvt, 0, sizeof(wvt));
        wvt.cbStruct = sizeof(wvt);
        wvt.dwUIChoice = WTD_UI_NONE;
        if (viewInfo.dwFlags &
         CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT)
            wvt.fdwRevocationChecks |= WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT;
        if (viewInfo.dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_END_CERT)
            wvt.fdwRevocationChecks |= WTD_REVOCATION_CHECK_END_CERT;
        if (viewInfo.dwFlags & CRYPTUI_ENABLE_REVOCATION_CHECK_CHAIN)
            wvt.fdwRevocationChecks |= WTD_REVOCATION_CHECK_CHAIN;
        wvt.dwUnionChoice = WTD_CHOICE_CERT;
        memset(&cert, 0, sizeof(cert));
        cert.cbStruct = sizeof(cert);
        cert.psCertContext = (CERT_CONTEXT *)viewInfo.pCertContext;
        cert.chStores = viewInfo.cStores;
        cert.pahStores = viewInfo.rghStores;
        wvt.u.pCert = &cert;
        wvt.dwStateAction = WTD_STATEACTION_VERIFY;
        WinVerifyTrust(NULL, &generic_cert_verify, &wvt);
        viewInfo.u.pCryptProviderData =
         WTHelperProvDataFromStateData(wvt.hWVTStateData);
        signer = WTHelperGetProvSignerFromChain(
         (CRYPT_PROVIDER_DATA *)viewInfo.u.pCryptProviderData, 0, FALSE, 0);
        provCert = WTHelperGetProvCertFromChain(signer, 0);
        ret = TRUE;
    }
    else
    {
        viewInfo.u.pCryptProviderData =
         WTHelperProvDataFromStateData(viewInfo.u.hWVTStateData);
        signer = WTHelperGetProvSignerFromChain(
         (CRYPT_PROVIDER_DATA *)viewInfo.u.pCryptProviderData,
         viewInfo.idxSigner, viewInfo.fCounterSigner,
         viewInfo.idxCounterSigner);
        provCert = WTHelperGetProvCertFromChain(signer, viewInfo.idxCert);
        ret = TRUE;
    }
    if (ret)
    {
        ret = show_cert_dialog(&viewInfo, provCert, pfPropertiesChanged);
        if (!pCertViewInfo->u.hWVTStateData)
        {
            wvt.dwStateAction = WTD_STATEACTION_CLOSE;
            WinVerifyTrust(NULL, &generic_cert_verify, &wvt);
        }
    }
    return ret;
}

/***********************************************************************
 *		CryptUIDlgViewContext (CRYPTUI.@)
 */
BOOL WINAPI CryptUIDlgViewContext(DWORD dwContextType, LPVOID pvContext,
 HWND hwnd, LPCWSTR pwszTitle, DWORD dwFlags, LPVOID pvReserved)
{
    BOOL ret;

    TRACE("(%d, %p, %p, %s, %08x, %p)\n", dwContextType, pvContext, hwnd,
     debugstr_w(pwszTitle), dwFlags, pvReserved);

    switch (dwContextType)
    {
    case CERT_STORE_CERTIFICATE_CONTEXT:
    {
        CRYPTUI_VIEWCERTIFICATE_STRUCTW viewInfo;

        memset(&viewInfo, 0, sizeof(viewInfo));
        viewInfo.dwSize = sizeof(viewInfo);
        viewInfo.hwndParent = hwnd;
        viewInfo.szTitle = pwszTitle;
        viewInfo.pCertContext = pvContext;
        ret = CryptUIDlgViewCertificateW(&viewInfo, NULL);
        break;
    }
    default:
        FIXME("unimplemented for context type %d\n", dwContextType);
        SetLastError(E_INVALIDARG);
        ret = FALSE;
    }
    return ret;
}

/* Decodes a cert's basic constraints extension (either szOID_BASIC_CONSTRAINTS
 * or szOID_BASIC_CONSTRAINTS2, whichever is present) to determine if it
 * should be a CA.  If neither extension is present, returns
 * defaultIfNotSpecified.
 */
static BOOL is_ca_cert(PCCERT_CONTEXT cert, BOOL defaultIfNotSpecified)
{
    BOOL isCA = defaultIfNotSpecified;
    PCERT_EXTENSION ext = CertFindExtension(szOID_BASIC_CONSTRAINTS,
     cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);

    if (ext)
    {
        CERT_BASIC_CONSTRAINTS_INFO *info;
        DWORD size = 0;

        if (CryptDecodeObjectEx(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS,
         ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG,
         NULL, &info, &size))
        {
            if (info->SubjectType.cbData == 1)
                isCA = info->SubjectType.pbData[0] & CERT_CA_SUBJECT_FLAG;
            LocalFree(info);
        }
    }
    else
    {
        ext = CertFindExtension(szOID_BASIC_CONSTRAINTS2,
         cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension);
        if (ext)
        {
            CERT_BASIC_CONSTRAINTS2_INFO info;
            DWORD size = sizeof(CERT_BASIC_CONSTRAINTS2_INFO);

            if (CryptDecodeObjectEx(X509_ASN_ENCODING,
             szOID_BASIC_CONSTRAINTS2, ext->Value.pbData, ext->Value.cbData,
             0, NULL, &info, &size))
                isCA = info.fCA;
        }
    }
    return isCA;
}

static HCERTSTORE choose_store_for_cert(PCCERT_CONTEXT cert)
{
    LPCWSTR storeName;

    if (is_ca_cert(cert, TRUE))
        storeName = ca;
    else
        storeName = addressBook;
    return CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
     CERT_SYSTEM_STORE_CURRENT_USER, storeName);
}

static BOOL import_cert(PCCERT_CONTEXT cert, HCERTSTORE hDestCertStore)
{
    HCERTSTORE store;
    BOOL ret;

    if (!cert)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (hDestCertStore) store = hDestCertStore;
    else
    {
        if (!(store = choose_store_for_cert(cert)))
        {
            WARN("unable to open certificate store\n");
            return FALSE;
        }
    }
    ret = CertAddCertificateContextToStore(store, cert,
     CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL);
    if (!hDestCertStore) CertCloseStore(store, 0);
    return ret;
}

static BOOL import_crl(PCCRL_CONTEXT crl, HCERTSTORE hDestCertStore)
{
    HCERTSTORE store;
    BOOL ret;

    if (!crl)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (hDestCertStore) store = hDestCertStore;
    else
    {
        if (!(store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, ca)))
        {
            WARN("unable to open certificate store\n");
            return FALSE;
        }
    }
    ret = CertAddCRLContextToStore(store, crl,
     CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL);
    if (!hDestCertStore) CertCloseStore(store, 0);
    return ret;
}

static BOOL import_ctl(PCCTL_CONTEXT ctl, HCERTSTORE hDestCertStore)
{
    HCERTSTORE store;
    BOOL ret;

    if (!ctl)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (hDestCertStore) store = hDestCertStore;
    else
    {
        static const WCHAR trust[] = { 'T','r','u','s','t',0 };

        if (!(store = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, trust)))
        {
            WARN("unable to open certificate store\n");
            return FALSE;
        }
    }
    ret = CertAddCTLContextToStore(store, ctl,
     CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL);
    if (!hDestCertStore) CertCloseStore(store, 0);
    return ret;
}

/* Checks type, a type such as CERT_QUERY_CONTENT_CERT returned by
 * CryptQueryObject, against the allowed types.  Returns TRUE if the
 * type is allowed, FALSE otherwise.
 */
static BOOL check_context_type(DWORD dwFlags, DWORD type)
{
    BOOL ret;

    if (dwFlags &
     (CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL |
     CRYPTUI_WIZ_IMPORT_ALLOW_CTL))
    {
        switch (type)
        {
        case CERT_QUERY_CONTENT_CERT:
        case CERT_QUERY_CONTENT_SERIALIZED_CERT:
            ret = dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT;
            break;
        case CERT_QUERY_CONTENT_CRL:
        case CERT_QUERY_CONTENT_SERIALIZED_CRL:
            ret = dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL;
            break;
        case CERT_QUERY_CONTENT_CTL:
        case CERT_QUERY_CONTENT_SERIALIZED_CTL:
            ret = dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL;
            break;
        default:
            /* The remaining types contain more than one type, so allow
             * any combination.
             */
            ret = TRUE;
        }
    }
    else
    {
        /* No allowed types specified, so any type is allowed */
        ret = TRUE;
    }
    if (!ret)
        SetLastError(E_INVALIDARG);
    return ret;
}


static void import_warning(DWORD dwFlags, HWND hwnd, LPCWSTR szTitle,
 int warningID)
{
    if (!(dwFlags & CRYPTUI_WIZ_NO_UI))
    {
        WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
        LPCWSTR pTitle;

        if (szTitle)
            pTitle = szTitle;
        else
        {
            LoadStringW(hInstance, IDS_IMPORT_WIZARD, title,
             sizeof(title) / sizeof(title[0]));
            pTitle = title;
        }
        LoadStringW(hInstance, warningID, error,
         sizeof(error) / sizeof(error[0]));
        MessageBoxW(hwnd, error, pTitle, MB_ICONERROR | MB_OK);
    }
}

static void import_warn_type_mismatch(DWORD dwFlags, HWND hwnd, LPCWSTR szTitle)
{
    import_warning(dwFlags, hwnd, szTitle, IDS_IMPORT_TYPE_MISMATCH);
}

static BOOL check_store_context_type(DWORD dwFlags, HCERTSTORE store)
{
    BOOL ret;

    if (dwFlags &
     (CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL |
     CRYPTUI_WIZ_IMPORT_ALLOW_CTL))
    {
        PCCERT_CONTEXT cert;
        PCCRL_CONTEXT crl;
        PCCTL_CONTEXT ctl;

        ret = TRUE;
        if ((cert = CertEnumCertificatesInStore(store, NULL)))
        {
            CertFreeCertificateContext(cert);
            if (!(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT))
                ret = FALSE;
        }
        if (ret && (crl = CertEnumCRLsInStore(store, NULL)))
        {
            CertFreeCRLContext(crl);
            if (!(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL))
                ret = FALSE;
        }
        if (ret && (ctl = CertEnumCTLsInStore(store, NULL)))
        {
            CertFreeCTLContext(ctl);
            if (!(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL))
                ret = FALSE;
        }
    }
    else
        ret = TRUE;
    if (!ret)
        SetLastError(E_INVALIDARG);
    return ret;
}

static BOOL import_store(DWORD dwFlags, HWND hwnd, LPCWSTR szTitle,
 HCERTSTORE source, HCERTSTORE dest)
{
    BOOL ret;

    if ((ret = check_store_context_type(dwFlags, source)))
    {
        PCCERT_CONTEXT cert = NULL;
        PCCRL_CONTEXT crl = NULL;
        PCCTL_CONTEXT ctl = NULL;

        do {
            cert = CertEnumCertificatesInStore(source, cert);
            if (cert)
                ret = import_cert(cert, dest);
        } while (ret && cert);
        do {
            crl = CertEnumCRLsInStore(source, crl);
            if (crl)
                ret = import_crl(crl, dest);
        } while (ret && crl);
        do {
            ctl = CertEnumCTLsInStore(source, ctl);
            if (ctl)
                ret = import_ctl(ctl, dest);
        } while (ret && ctl);
    }
    else
        import_warn_type_mismatch(dwFlags, hwnd, szTitle);
    return ret;
}

static HCERTSTORE open_store_from_file(DWORD dwFlags, LPCWSTR fileName,
 DWORD *pContentType)
{
    HCERTSTORE store = NULL;
    DWORD contentType = 0, expectedContentTypeFlags;

    if (dwFlags &
     (CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL |
     CRYPTUI_WIZ_IMPORT_ALLOW_CTL))
    {
        expectedContentTypeFlags =
         CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
         CERT_QUERY_CONTENT_FLAG_PFX;
        if (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)
            expectedContentTypeFlags |=
             CERT_QUERY_CONTENT_FLAG_CERT |
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT;
        if (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL)
            expectedContentTypeFlags |=
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL |
             CERT_QUERY_CONTENT_FLAG_CRL;
        if (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL)
            expectedContentTypeFlags |=
             CERT_QUERY_CONTENT_FLAG_CTL |
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL;
    }
    else
        expectedContentTypeFlags =
         CERT_QUERY_CONTENT_FLAG_CERT |
         CERT_QUERY_CONTENT_FLAG_CTL |
         CERT_QUERY_CONTENT_FLAG_CRL |
         CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
         CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT |
         CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL |
         CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL |
         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED |
         CERT_QUERY_CONTENT_FLAG_PFX;

    CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
     expectedContentTypeFlags, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL,
     &contentType, NULL, &store, NULL, NULL);
    if (pContentType)
        *pContentType = contentType;
    return store;
}

static BOOL import_file(DWORD dwFlags, HWND hwnd, LPCWSTR szTitle,
 LPCWSTR fileName, HCERTSTORE dest)
{
    HCERTSTORE source;
    BOOL ret;

    if ((source = open_store_from_file(dwFlags, fileName, NULL)))
    {
        ret = import_store(dwFlags, hwnd, szTitle, source, dest);
        CertCloseStore(source, 0);
    }
    else
        ret = FALSE;
    return ret;
}

struct ImportWizData
{
    HFONT titleFont;
    DWORD dwFlags;
    LPCWSTR pwszWizardTitle;
    CRYPTUI_WIZ_IMPORT_SRC_INFO importSrc;
    LPWSTR fileName;
    DWORD contentType;
    BOOL freeSource;
    HCERTSTORE hDestCertStore;
    BOOL freeDest;
    BOOL autoDest;
    BOOL success;
};

static LRESULT CALLBACK import_welcome_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        struct ImportWizData *data;
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;
        WCHAR fontFace[MAX_STRING_LEN];
        HDC hDC = GetDC(hwnd);
        int height;

        data = (struct ImportWizData *)page->lParam;
        LoadStringW(hInstance, IDS_WIZARD_TITLE_FONT, fontFace,
         sizeof(fontFace) / sizeof(fontFace[0]));
        height = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
        data->titleFont = CreateFontW(height, 0, 0, 0, FW_BOLD, 0, 0, 0,
         DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
         DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontFace);
        SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_TITLE), WM_SETFONT,
         (WPARAM)data->titleFont, TRUE);
        ReleaseDC(hwnd, hDC);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
            ret = TRUE;
            break;
        }
        break;
    }
    }
    return ret;
}

static const WCHAR filter_cert[] = { '*','.','c','e','r',';','*','.',
 'c','r','t',0 };
static const WCHAR filter_pfx[] = { '*','.','p','f','x',';','*','.',
 'p','1','2',0 };
static const WCHAR filter_crl[] = { '*','.','c','r','l',0 };
static const WCHAR filter_ctl[] = { '*','.','s','t','l',0 };
static const WCHAR filter_serialized_store[] = { '*','.','s','s','t',0 };
static const WCHAR filter_cms[] = { '*','.','s','p','c',';','*','.',
 'p','7','b',0 };
static const WCHAR filter_all[] = { '*','.','*',0 };

static struct StringToFilter
{
    int     id;
    DWORD   allowFlags;
    LPCWSTR filter;
} import_filters[] = {
 { IDS_IMPORT_FILTER_CERT, CRYPTUI_WIZ_IMPORT_ALLOW_CERT, filter_cert },
 { IDS_IMPORT_FILTER_PFX, 0, filter_pfx },
 { IDS_IMPORT_FILTER_CRL, CRYPTUI_WIZ_IMPORT_ALLOW_CRL, filter_crl },
 { IDS_IMPORT_FILTER_CTL, CRYPTUI_WIZ_IMPORT_ALLOW_CTL, filter_ctl },
 { IDS_IMPORT_FILTER_SERIALIZED_STORE, 0, filter_serialized_store },
 { IDS_IMPORT_FILTER_CMS, 0, filter_cms },
 { IDS_IMPORT_FILTER_ALL, 0, filter_all },
};

static WCHAR *make_import_file_filter(DWORD dwFlags)
{
    DWORD i;
    int len, totalLen = 2;
    LPWSTR filter = NULL, str;

    for (i = 0; i < sizeof(import_filters) / sizeof(import_filters[0]); i++)
    {
        if (!import_filters[i].allowFlags || !dwFlags ||
         (dwFlags & import_filters[i].allowFlags))
        {
            len = LoadStringW(hInstance, import_filters[i].id, (LPWSTR)&str, 0);
            totalLen += len + strlenW(import_filters[i].filter) + 2;
        }
    }
    filter = HeapAlloc(GetProcessHeap(), 0, totalLen * sizeof(WCHAR));
    if (filter)
    {
        LPWSTR ptr;

        ptr = filter;
        for (i = 0; i < sizeof(import_filters) / sizeof(import_filters[0]); i++)
        {
            if (!import_filters[i].allowFlags || !dwFlags ||
             (dwFlags & import_filters[i].allowFlags))
            {
                len = LoadStringW(hInstance, import_filters[i].id,
                 (LPWSTR)&str, 0);
                memcpy(ptr, str, len * sizeof(WCHAR));
                ptr += len;
                *ptr++ = 0;
                strcpyW(ptr, import_filters[i].filter);
                ptr += strlenW(import_filters[i].filter) + 1;
            }
        }
        *ptr++ = 0;
    }
    return filter;
}

static BOOL import_validate_filename(HWND hwnd, struct ImportWizData *data,
 LPCWSTR fileName)
{
    HANDLE file;
    BOOL ret = FALSE;

    file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
     OPEN_EXISTING, 0, NULL);
    if (file != INVALID_HANDLE_VALUE)
    {
        HCERTSTORE source = open_store_from_file(data->dwFlags, fileName,
         &data->contentType);
        int warningID = 0;

        if (!source)
            warningID = IDS_IMPORT_BAD_FORMAT;
        else if (!check_store_context_type(data->dwFlags, source))
            warningID = IDS_IMPORT_TYPE_MISMATCH;
        else
        {
            data->importSrc.dwSubjectChoice =
             CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE;
            data->importSrc.u.hCertStore = source;
            data->freeSource = TRUE;
            ret = TRUE;
        }
        if (warningID)
        {
            import_warning(data->dwFlags, hwnd, data->pwszWizardTitle,
             warningID);
        }
        CloseHandle(file);
    }
    else
    {
        WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
        LPCWSTR pTitle;
        LPWSTR msgBuf, fullError;

        if (data->pwszWizardTitle)
            pTitle = data->pwszWizardTitle;
        else
        {
            LoadStringW(hInstance, IDS_IMPORT_WIZARD, title,
             sizeof(title) / sizeof(title[0]));
            pTitle = title;
        }
        LoadStringW(hInstance, IDS_IMPORT_OPEN_FAILED, error,
         sizeof(error) / sizeof(error[0]));
        FormatMessageW(
         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
         GetLastError(), 0, (LPWSTR) &msgBuf, 0, NULL);
        fullError = HeapAlloc(GetProcessHeap(), 0,
         (strlenW(error) + strlenW(fileName) + strlenW(msgBuf) + 3)
         * sizeof(WCHAR));
        if (fullError)
        {
            LPWSTR ptr = fullError;

            strcpyW(ptr, error);
            ptr += strlenW(error);
            strcpyW(ptr, fileName);
            ptr += strlenW(fileName);
            *ptr++ = ':';
            *ptr++ = '\n';
            strcpyW(ptr, msgBuf);
            MessageBoxW(hwnd, fullError, pTitle, MB_ICONERROR | MB_OK);
            HeapFree(GetProcessHeap(), 0, fullError);
        }
        LocalFree(msgBuf);
    }
    return ret;
}

static LRESULT CALLBACK import_file_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    struct ImportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;

        data = (struct ImportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        if (data->fileName)
        {
            HWND fileNameEdit = GetDlgItem(hwnd, IDC_IMPORT_FILENAME);

            SendMessageW(fileNameEdit, WM_SETTEXT, 0, (LPARAM)data->fileName);
        }
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_NEXT);
            ret = TRUE;
            break;
        case PSN_WIZNEXT:
        {
            HWND fileNameEdit = GetDlgItem(hwnd, IDC_IMPORT_FILENAME);
            DWORD len = SendMessageW(fileNameEdit, WM_GETTEXTLENGTH, 0, 0);

            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (!len)
            {
                import_warning(data->dwFlags, hwnd, data->pwszWizardTitle,
                 IDS_IMPORT_EMPTY_FILE);
                SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                ret = 1;
            }
            else
            {
                LPWSTR fileName = HeapAlloc(GetProcessHeap(), 0,
                 (len + 1) * sizeof(WCHAR));

                if (fileName)
                {
                    SendMessageW(fileNameEdit, WM_GETTEXT, len + 1,
                     (LPARAM)fileName);
                    if (!import_validate_filename(hwnd, data, fileName))
                    {
                        HeapFree(GetProcessHeap(), 0, fileName);
                        SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                        ret = 1;
                    }
                    else
                        data->fileName = fileName;
                }
            }
            break;
        }
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDC_IMPORT_BROWSE_FILE:
        {
            OPENFILENAMEW ofn;
            WCHAR fileBuf[MAX_PATH];

            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            memset(&ofn, 0, sizeof(ofn));
            ofn.lStructSize = sizeof(ofn);
            ofn.hwndOwner = hwnd;
            ofn.lpstrFilter = make_import_file_filter(data->dwFlags);
            ofn.lpstrFile = fileBuf;
            ofn.nMaxFile = sizeof(fileBuf) / sizeof(fileBuf[0]);
            fileBuf[0] = 0;
            if (GetOpenFileNameW(&ofn))
                SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_FILENAME), WM_SETTEXT,
                 0, (LPARAM)ofn.lpstrFile);
            HeapFree(GetProcessHeap(), 0, (LPWSTR)ofn.lpstrFilter);
            break;
        }
        }
        break;
    }
    return ret;
}

static LRESULT CALLBACK import_store_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    struct ImportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;

        data = (struct ImportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        if (!data->hDestCertStore)
        {
            SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_AUTO_STORE), BM_CLICK,
             0, 0);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_STORE), FALSE);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_BROWSE_STORE), FALSE);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_SPECIFY_STORE), FALSE);
        }
        else
        {
            WCHAR storeTitle[MAX_STRING_LEN];

            SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_SPECIFY_STORE), BM_CLICK,
             0, 0);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_STORE), TRUE);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_BROWSE_STORE), TRUE);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_SPECIFY_STORE),
             !(data->dwFlags & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE));
            LoadStringW(hInstance, IDS_IMPORT_DEST_DETERMINED,
             storeTitle, sizeof(storeTitle) / sizeof(storeTitle[0]));
            SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_STORE), WM_SETTEXT,
             0, (LPARAM)storeTitle);
        }
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_NEXT);
            ret = TRUE;
            break;
        case PSN_WIZNEXT:
        {
            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (IsDlgButtonChecked(hwnd, IDC_IMPORT_SPECIFY_STORE) &&
             !data->hDestCertStore)
            {
                import_warning(data->dwFlags, hwnd, data->pwszWizardTitle,
                 IDS_IMPORT_SELECT_STORE);
                SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                ret = 1;
            }
            break;
        }
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDC_IMPORT_AUTO_STORE:
            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            data->autoDest = TRUE;
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_STORE), FALSE);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_BROWSE_STORE), FALSE);
            break;
        case IDC_IMPORT_SPECIFY_STORE:
            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            data->autoDest = FALSE;
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_STORE), TRUE);
            EnableWindow(GetDlgItem(hwnd, IDC_IMPORT_BROWSE_STORE), TRUE);
            break;
        case IDC_IMPORT_BROWSE_STORE:
        {
            CRYPTUI_ENUM_SYSTEM_STORE_ARGS enumArgs = {
             CERT_SYSTEM_STORE_CURRENT_USER, NULL };
            CRYPTUI_ENUM_DATA enumData = { 0, NULL, 1, &enumArgs };
            CRYPTUI_SELECTSTORE_INFO_W selectInfo;
            HCERTSTORE store;

            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            selectInfo.dwSize = sizeof(selectInfo);
            selectInfo.parent = hwnd;
            selectInfo.dwFlags = CRYPTUI_ENABLE_SHOW_PHYSICAL_STORE;
            selectInfo.pwszTitle = NULL;
            selectInfo.pwszText = NULL;
            selectInfo.pEnumData = &enumData;
            selectInfo.pfnSelectedStoreCallback = NULL;
            if ((store = CryptUIDlgSelectStoreW(&selectInfo)))
            {
                WCHAR storeTitle[MAX_STRING_LEN];

                LoadStringW(hInstance, IDS_IMPORT_DEST_DETERMINED,
                 storeTitle, sizeof(storeTitle) / sizeof(storeTitle[0]));
                SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_STORE), WM_SETTEXT,
                 0, (LPARAM)storeTitle);
                data->hDestCertStore = store;
                data->freeDest = TRUE;
            }
            break;
        }
        }
        break;
    }
    return ret;
}

static void show_import_details(HWND lv, struct ImportWizData *data)
{
    WCHAR text[MAX_STRING_LEN];
    LVITEMW item;
    int contentID;

    item.mask = LVIF_TEXT;
    item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
    item.iSubItem = 0;
    LoadStringW(hInstance, IDS_IMPORT_STORE_SELECTION, text,
     sizeof(text)/ sizeof(text[0]));
    item.pszText = text;
    SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
    item.iSubItem = 1;
    if (data->autoDest)
        LoadStringW(hInstance, IDS_IMPORT_DEST_AUTOMATIC, text,
         sizeof(text)/ sizeof(text[0]));
    else
        LoadStringW(hInstance, IDS_IMPORT_DEST_DETERMINED, text,
         sizeof(text)/ sizeof(text[0]));
    SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
    item.iSubItem = 0;
    LoadStringW(hInstance, IDS_IMPORT_CONTENT, text,
     sizeof(text)/ sizeof(text[0]));
    SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
    switch (data->contentType)
    {
    case CERT_QUERY_CONTENT_CERT:
    case CERT_QUERY_CONTENT_SERIALIZED_CERT:
        contentID = IDS_IMPORT_CONTENT_CERT;
        break;
    case CERT_QUERY_CONTENT_CRL:
    case CERT_QUERY_CONTENT_SERIALIZED_CRL:
        contentID = IDS_IMPORT_CONTENT_CRL;
        break;
    case CERT_QUERY_CONTENT_CTL:
    case CERT_QUERY_CONTENT_SERIALIZED_CTL:
        contentID = IDS_IMPORT_CONTENT_CTL;
        break;
    case CERT_QUERY_CONTENT_PKCS7_SIGNED:
        contentID = IDS_IMPORT_CONTENT_CMS;
        break;
    case CERT_QUERY_CONTENT_FLAG_PFX:
        contentID = IDS_IMPORT_CONTENT_PFX;
        break;
    default:
        contentID = IDS_IMPORT_CONTENT_STORE;
        break;
    }
    LoadStringW(hInstance, contentID, text, sizeof(text)/ sizeof(text[0]));
    item.iSubItem = 1;
    SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    if (data->fileName)
    {
        item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
        item.iSubItem = 0;
        LoadStringW(hInstance, IDS_IMPORT_FILE, text,
         sizeof(text)/ sizeof(text[0]));
        SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
        item.iSubItem = 1;
        item.pszText = data->fileName;
        SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    }
}

static BOOL do_import(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle,
 PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore)
{
    BOOL ret;

    switch (pImportSrc->dwSubjectChoice)
    {
    case CRYPTUI_WIZ_IMPORT_SUBJECT_FILE:
        ret = import_file(dwFlags, hwndParent, pwszWizardTitle,
         pImportSrc->u.pwszFileName, hDestCertStore);
        break;
    case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
        if ((ret = check_context_type(dwFlags, CERT_QUERY_CONTENT_CERT)))
            ret = import_cert(pImportSrc->u.pCertContext, hDestCertStore);
        else
            import_warn_type_mismatch(dwFlags, hwndParent, pwszWizardTitle);
        break;
    case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT:
        if ((ret = check_context_type(dwFlags, CERT_QUERY_CONTENT_CRL)))
            ret = import_crl(pImportSrc->u.pCRLContext, hDestCertStore);
        else
            import_warn_type_mismatch(dwFlags, hwndParent, pwszWizardTitle);
        break;
    case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT:
        if ((ret = check_context_type(dwFlags, CERT_QUERY_CONTENT_CTL)))
            ret = import_ctl(pImportSrc->u.pCTLContext, hDestCertStore);
        else
            import_warn_type_mismatch(dwFlags, hwndParent, pwszWizardTitle);
        break;
    case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE:
        ret = import_store(dwFlags, hwndParent, pwszWizardTitle,
         pImportSrc->u.hCertStore, hDestCertStore);
        break;
    default:
        WARN("unknown source type: %u\n", pImportSrc->dwSubjectChoice);
        SetLastError(E_INVALIDARG);
        ret = FALSE;
    }
    return ret;
}

static LRESULT CALLBACK import_finish_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    struct ImportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;
        HWND lv = GetDlgItem(hwnd, IDC_IMPORT_SETTINGS);
        RECT rc;
        LVCOLUMNW column;

        data = (struct ImportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        SendMessageW(GetDlgItem(hwnd, IDC_IMPORT_TITLE), WM_SETFONT,
         (WPARAM)data->titleFont, TRUE);
        GetWindowRect(lv, &rc);
        column.mask = LVCF_WIDTH;
        column.cx = (rc.right - rc.left) / 2 - 2;
        SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
        SendMessageW(lv, LVM_INSERTCOLUMNW, 1, (LPARAM)&column);
        show_import_details(lv, data);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
        {
            HWND lv = GetDlgItem(hwnd, IDC_IMPORT_SETTINGS);

            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            SendMessageW(lv, LVM_DELETEALLITEMS, 0, 0);
            show_import_details(lv, data);
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_FINISH);
            ret = TRUE;
            break;
        }
        case PSN_WIZFINISH:
        {
            data = (struct ImportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if ((data->success = do_import(data->dwFlags, hwnd,
             data->pwszWizardTitle, &data->importSrc, data->hDestCertStore)))
            {
                WCHAR title[MAX_STRING_LEN], message[MAX_STRING_LEN];
                LPCWSTR pTitle;

                if (data->pwszWizardTitle)
                    pTitle = data->pwszWizardTitle;
                else
                {
                    LoadStringW(hInstance, IDS_IMPORT_WIZARD, title,
                     sizeof(title) / sizeof(title[0]));
                    pTitle = title;
                }
                LoadStringW(hInstance, IDS_IMPORT_SUCCEEDED, message,
                 sizeof(message) / sizeof(message[0]));
                MessageBoxW(hwnd, message, pTitle, MB_OK);
            }
            else
                import_warning(data->dwFlags, hwnd, data->pwszWizardTitle,
                 IDS_IMPORT_FAILED);
            break;
        }
        }
        break;
    }
    }
    return ret;
}

static BOOL show_import_ui(DWORD dwFlags, HWND hwndParent,
 LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc,
 HCERTSTORE hDestCertStore)
{
    PROPSHEETHEADERW hdr;
    PROPSHEETPAGEW pages[4];
    struct ImportWizData data;
    int nPages = 0;

    data.dwFlags = dwFlags;
    data.pwszWizardTitle = pwszWizardTitle;
    if (pImportSrc)
    {
        memcpy(&data.importSrc, pImportSrc, sizeof(data.importSrc));
        data.fileName = (LPWSTR)pImportSrc->u.pwszFileName;
    }
    else
    {
        memset(&data.importSrc, 0, sizeof(data.importSrc));
        data.fileName = NULL;
    }
    data.freeSource = FALSE;
    data.hDestCertStore = hDestCertStore;
    data.freeDest = FALSE;
    data.autoDest = TRUE;
    data.success = TRUE;

    memset(pages, 0, sizeof(pages));

    pages[nPages].dwSize = sizeof(pages[0]);
    pages[nPages].hInstance = hInstance;
    pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_IMPORT_WELCOME);
    pages[nPages].pfnDlgProc = import_welcome_dlg_proc;
    pages[nPages].dwFlags = PSP_HIDEHEADER;
    pages[nPages].lParam = (LPARAM)&data;
    nPages++;

    if (!pImportSrc ||
     pImportSrc->dwSubjectChoice == CRYPTUI_WIZ_IMPORT_SUBJECT_FILE)
    {
        pages[nPages].dwSize = sizeof(pages[0]);
        pages[nPages].hInstance = hInstance;
        pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_IMPORT_FILE);
        pages[nPages].pfnDlgProc = import_file_dlg_proc;
        pages[nPages].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
        pages[nPages].pszHeaderTitle = MAKEINTRESOURCEW(IDS_IMPORT_FILE_TITLE);
        pages[nPages].pszHeaderSubTitle =
         MAKEINTRESOURCEW(IDS_IMPORT_FILE_SUBTITLE);
        pages[nPages].lParam = (LPARAM)&data;
        nPages++;
    }
    else
    {
        switch (pImportSrc->dwSubjectChoice)
        {
        case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT:
            data.contentType = CERT_QUERY_CONTENT_CERT;
            break;
        case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT:
            data.contentType = CERT_QUERY_CONTENT_CRL;
            break;
        case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT:
            data.contentType = CERT_QUERY_CONTENT_CTL;
            break;
        case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE:
            data.contentType = CERT_QUERY_CONTENT_SERIALIZED_STORE;
            break;
        }
    }

    pages[nPages].dwSize = sizeof(pages[0]);
    pages[nPages].hInstance = hInstance;
    pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_IMPORT_STORE);
    pages[nPages].pfnDlgProc = import_store_dlg_proc;
    pages[nPages].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
    pages[nPages].pszHeaderTitle = MAKEINTRESOURCEW(IDS_IMPORT_STORE_TITLE);
    pages[nPages].pszHeaderSubTitle =
     MAKEINTRESOURCEW(IDS_IMPORT_STORE_SUBTITLE);
    pages[nPages].lParam = (LPARAM)&data;
    nPages++;

    pages[nPages].dwSize = sizeof(pages[0]);
    pages[nPages].hInstance = hInstance;
    pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_IMPORT_FINISH);
    pages[nPages].pfnDlgProc = import_finish_dlg_proc;
    pages[nPages].dwFlags = PSP_HIDEHEADER;
    pages[nPages].lParam = (LPARAM)&data;
    nPages++;

    memset(&hdr, 0, sizeof(hdr));
    hdr.dwSize = sizeof(hdr);
    hdr.hwndParent = hwndParent;
    hdr.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD97_NEW | PSH_HEADER |
     PSH_WATERMARK;
    hdr.hInstance = hInstance;
    if (pwszWizardTitle)
        hdr.pszCaption = pwszWizardTitle;
    else
        hdr.pszCaption = MAKEINTRESOURCEW(IDS_IMPORT_WIZARD);
    hdr.u3.ppsp = pages;
    hdr.nPages = nPages;
    hdr.u4.pszbmWatermark = MAKEINTRESOURCEW(IDB_CERT_WATERMARK);
    hdr.u5.pszbmHeader = MAKEINTRESOURCEW(IDB_CERT_HEADER);
    PropertySheetW(&hdr);
    if (data.fileName != data.importSrc.u.pwszFileName)
        HeapFree(GetProcessHeap(), 0, data.fileName);
    if (data.freeSource &&
     data.importSrc.dwSubjectChoice == CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE)
        CertCloseStore(data.importSrc.u.hCertStore, 0);
    DeleteObject(data.titleFont);
    return data.success;
}

BOOL WINAPI CryptUIWizImport(DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle,
                             PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc, HCERTSTORE hDestCertStore)
{
    BOOL ret;

    TRACE("(0x%08x, %p, %s, %p, %p)\n", dwFlags, hwndParent, debugstr_w(pwszWizardTitle),
          pImportSrc, hDestCertStore);

    if (pImportSrc &&
     pImportSrc->dwSize != sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO))
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }

    if (!(dwFlags & CRYPTUI_WIZ_NO_UI))
        ret = show_import_ui(dwFlags, hwndParent, pwszWizardTitle, pImportSrc,
         hDestCertStore);
    else if (pImportSrc)
        ret = do_import(dwFlags, hwndParent, pwszWizardTitle, pImportSrc,
         hDestCertStore);
    else
    {
        /* Can't have no UI without specifying source */
        SetLastError(E_INVALIDARG);
        ret = FALSE;
    }

    return ret;
}

struct ExportWizData
{
    HFONT titleFont;
    DWORD dwFlags;
    LPCWSTR pwszWizardTitle;
    CRYPTUI_WIZ_EXPORT_INFO exportInfo;
    CRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO contextInfo;
    BOOL freePassword;
    PCRYPT_KEY_PROV_INFO keyProvInfo;
    BOOL deleteKeys;
    LPWSTR fileName;
    HANDLE file;
    BOOL success;
};

static LRESULT CALLBACK export_welcome_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        struct ExportWizData *data;
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;
        WCHAR fontFace[MAX_STRING_LEN];
        HDC hDC = GetDC(hwnd);
        int height;

        data = (struct ExportWizData *)page->lParam;
        LoadStringW(hInstance, IDS_WIZARD_TITLE_FONT, fontFace,
         sizeof(fontFace) / sizeof(fontFace[0]));
        height = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
        data->titleFont = CreateFontW(height, 0, 0, 0, FW_BOLD, 0, 0, 0,
         DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
         DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontFace);
        SendMessageW(GetDlgItem(hwnd, IDC_EXPORT_TITLE), WM_SETFONT,
         (WPARAM)data->titleFont, TRUE);
        ReleaseDC(hwnd, hDC);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT);
            ret = TRUE;
            break;
        }
        break;
    }
    }
    return ret;
}

static PCRYPT_KEY_PROV_INFO export_get_private_key_info(PCCERT_CONTEXT cert)
{
    PCRYPT_KEY_PROV_INFO info = NULL;
    DWORD size;

    if (CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID,
     NULL, &size))
    {
        info = HeapAlloc(GetProcessHeap(), 0, size);
        if (info)
        {
            if (!CertGetCertificateContextProperty(cert,
             CERT_KEY_PROV_INFO_PROP_ID, info, &size))
            {
                HeapFree(GetProcessHeap(), 0, info);
                info = NULL;
            }
        }
    }
    return info;
}

static BOOL export_acquire_private_key(const CRYPT_KEY_PROV_INFO *info,
 HCRYPTPROV *phProv)
{
    BOOL ret;

    ret = CryptAcquireContextW(phProv, info->pwszContainerName,
     info->pwszProvName, info->dwProvType, 0);
    if (ret)
    {
        DWORD i;

        for (i = 0; i < info->cProvParam; i++)
            CryptSetProvParam(*phProv, info->rgProvParam[i].dwParam,
             info->rgProvParam[i].pbData, info->rgProvParam[i].dwFlags);
    }
    return ret;
}

static BOOL export_is_key_exportable(HCRYPTPROV hProv, DWORD keySpec)
{
    BOOL ret;
    HCRYPTKEY key;

    if ((ret = CryptGetUserKey(hProv, keySpec, &key)))
    {
        DWORD permissions, size = sizeof(permissions);

        if ((ret = CryptGetKeyParam(key, KP_PERMISSIONS, (BYTE *)&permissions,
         &size, 0)) && !(permissions & CRYPT_EXPORT))
            ret = FALSE;
        CryptDestroyKey(key);
    }
    return ret;
}

static LRESULT CALLBACK export_private_key_dlg_proc(HWND hwnd, UINT msg,
 WPARAM wp, LPARAM lp)
{
    LRESULT ret = 0;
    struct ExportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;
        PCRYPT_KEY_PROV_INFO info;
        HCRYPTPROV hProv = 0;
        int errorID = 0;

        data = (struct ExportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        /* Get enough information about a key to see whether it's exportable.
         */
        if (!(info = export_get_private_key_info(
         data->exportInfo.u.pCertContext)))
            errorID = IDS_EXPORT_PRIVATE_KEY_UNAVAILABLE;
        else if (!export_acquire_private_key(info, &hProv))
            errorID = IDS_EXPORT_PRIVATE_KEY_UNAVAILABLE;
        else if (!export_is_key_exportable(hProv, info->dwKeySpec))
            errorID = IDS_EXPORT_PRIVATE_KEY_NON_EXPORTABLE;

        if (errorID)
        {
            WCHAR error[MAX_STRING_LEN];

            LoadStringW(hInstance, errorID, error,
             sizeof(error) / sizeof(error[0]));
            SendMessageW(GetDlgItem(hwnd, IDC_EXPORT_PRIVATE_KEY_UNAVAILABLE),
             WM_SETTEXT, 0, (LPARAM)error);
            EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_PRIVATE_KEY_YES), FALSE);
        }
        else
            data->keyProvInfo = info;
        if (hProv)
            CryptReleaseContext(hProv, 0);
        SendMessageW(GetDlgItem(hwnd, IDC_EXPORT_PRIVATE_KEY_NO), BM_CLICK,
         0, 0);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_NEXT);
            ret = TRUE;
            break;
        case PSN_WIZNEXT:
            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (IsDlgButtonChecked(hwnd, IDC_EXPORT_PRIVATE_KEY_NO))
            {
                data->contextInfo.dwExportFormat =
                 CRYPTUI_WIZ_EXPORT_FORMAT_DER;
                data->contextInfo.fExportPrivateKeys = FALSE;
            }
            else
            {
                data->contextInfo.dwExportFormat =
                 CRYPTUI_WIZ_EXPORT_FORMAT_PFX;
                data->contextInfo.fExportPrivateKeys = TRUE;
            }
            break;
        }
        break;
    }
    }
    return ret;
}

static BOOL export_info_has_private_key(PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo)
{
    BOOL ret = FALSE;

    if (pExportInfo->dwSubjectChoice == CRYPTUI_WIZ_EXPORT_CERT_CONTEXT)
    {
        DWORD size;

        /* If there's a CRYPT_KEY_PROV_INFO set for this cert, assume the
         * cert has a private key.
         */
        if (CertGetCertificateContextProperty(pExportInfo->u.pCertContext,
         CERT_KEY_PROV_INFO_PROP_ID, NULL, &size))
            ret = TRUE;
    }
    return ret;
}

static void export_format_enable_controls(HWND hwnd, const struct ExportWizData *data)
{
    int defaultFormatID;

    switch (data->contextInfo.dwExportFormat)
    {
    case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
        defaultFormatID = IDC_EXPORT_FORMAT_BASE64;
        break;
    case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
        defaultFormatID = IDC_EXPORT_FORMAT_CMS;
        break;
    case CRYPTUI_WIZ_EXPORT_FORMAT_PFX:
        defaultFormatID = IDC_EXPORT_FORMAT_PFX;
        break;
    default:
        defaultFormatID = IDC_EXPORT_FORMAT_DER;
    }
    SendMessageW(GetDlgItem(hwnd, defaultFormatID), BM_CLICK, 0, 0);
    if (defaultFormatID == IDC_EXPORT_FORMAT_PFX)
    {
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_DER), FALSE);
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_BASE64), FALSE);
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_CMS), FALSE);
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_PFX), TRUE);
    }
    else
    {
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_DER), TRUE);
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_BASE64), TRUE);
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_CMS), TRUE);
        EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_FORMAT_PFX), FALSE);
    }
}

static LRESULT CALLBACK export_format_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    struct ExportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;

        data = (struct ExportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        export_format_enable_controls(hwnd, data);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_NEXT);
            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            export_format_enable_controls(hwnd, data);
            ret = TRUE;
            break;
        case PSN_WIZNEXT:
        {
            BOOL skipPasswordPage = TRUE;

            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (IsDlgButtonChecked(hwnd, IDC_EXPORT_FORMAT_DER))
                data->contextInfo.dwExportFormat =
                 CRYPTUI_WIZ_EXPORT_FORMAT_DER;
            else if (IsDlgButtonChecked(hwnd, IDC_EXPORT_FORMAT_BASE64))
                data->contextInfo.dwExportFormat =
                 CRYPTUI_WIZ_EXPORT_FORMAT_BASE64;
            else if (IsDlgButtonChecked(hwnd, IDC_EXPORT_FORMAT_CMS))
            {
                data->contextInfo.dwExportFormat =
                 CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
                if (IsDlgButtonChecked(hwnd, IDC_EXPORT_CMS_INCLUDE_CHAIN))
                    data->contextInfo.fExportChain =
                     CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
            }
            else
            {
                data->contextInfo.dwExportFormat =
                 CRYPTUI_WIZ_EXPORT_FORMAT_PFX;
                if (IsDlgButtonChecked(hwnd, IDC_EXPORT_PFX_INCLUDE_CHAIN))
                    data->contextInfo.fExportChain = TRUE;
                if (IsDlgButtonChecked(hwnd, IDC_EXPORT_PFX_STRONG_ENCRYPTION))
                    data->contextInfo.fStrongEncryption = TRUE;
                if (IsDlgButtonChecked(hwnd, IDC_EXPORT_PFX_DELETE_PRIVATE_KEY))
                    data->deleteKeys = TRUE;
                skipPasswordPage = FALSE;
            }
            SetWindowLongPtrW(hwnd, DWLP_MSGRESULT,
             skipPasswordPage ? IDD_EXPORT_FILE : 0);
            ret = 1;
            break;
        }
        }
        break;
    }
    case WM_COMMAND:
        switch (HIWORD(wp))
        {
        case BN_CLICKED:
            switch (LOWORD(wp))
            {
            case IDC_EXPORT_FORMAT_DER:
            case IDC_EXPORT_FORMAT_BASE64:
                EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_CMS_INCLUDE_CHAIN),
                 FALSE);
                EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_PFX_INCLUDE_CHAIN),
                 FALSE);
                EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_PFX_STRONG_ENCRYPTION),
                 FALSE);
                EnableWindow(GetDlgItem(hwnd,
                 IDC_EXPORT_PFX_DELETE_PRIVATE_KEY), FALSE);
                break;
            case IDC_EXPORT_FORMAT_CMS:
                EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_CMS_INCLUDE_CHAIN),
                 TRUE);
                break;
            case IDC_EXPORT_FORMAT_PFX:
                EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_PFX_INCLUDE_CHAIN),
                 TRUE);
                EnableWindow(GetDlgItem(hwnd, IDC_EXPORT_PFX_STRONG_ENCRYPTION),
                 TRUE);
                EnableWindow(GetDlgItem(hwnd,
                 IDC_EXPORT_PFX_DELETE_PRIVATE_KEY), TRUE);
                break;
            }
            break;
        }
        break;
    }
    return ret;
}

static void export_password_mismatch(HWND hwnd, const struct ExportWizData *data)
{
    WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
    LPCWSTR pTitle;

    if (data->pwszWizardTitle)
        pTitle = data->pwszWizardTitle;
    else
    {
        LoadStringW(hInstance, IDS_EXPORT_WIZARD, title,
         sizeof(title) / sizeof(title[0]));
        pTitle = title;
    }
    LoadStringW(hInstance, IDS_EXPORT_PASSWORD_MISMATCH, error,
     sizeof(error) / sizeof(error[0]));
    MessageBoxW(hwnd, error, pTitle, MB_ICONERROR | MB_OK);
    SetFocus(GetDlgItem(hwnd, IDC_EXPORT_PASSWORD));
}

static LRESULT CALLBACK export_password_dlg_proc(HWND hwnd, UINT msg,
 WPARAM wp, LPARAM lp)
{
    LRESULT ret = 0;
    struct ExportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;

        data = (struct ExportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_NEXT);
            ret = TRUE;
            break;
        case PSN_WIZNEXT:
        {
            HWND passwordEdit = GetDlgItem(hwnd, IDC_EXPORT_PASSWORD);
            HWND passwordConfirmEdit = GetDlgItem(hwnd,
             IDC_EXPORT_PASSWORD_CONFIRM);
            DWORD passwordLen = SendMessageW(passwordEdit, WM_GETTEXTLENGTH,
             0, 0);
            DWORD passwordConfirmLen = SendMessageW(passwordConfirmEdit,
             WM_GETTEXTLENGTH, 0, 0);

            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (!passwordLen && !passwordConfirmLen)
                data->contextInfo.pwszPassword = NULL;
            else if (passwordLen != passwordConfirmLen)
            {
                export_password_mismatch(hwnd, data);
                SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                ret = 1;
            }
            else
            {
                LPWSTR password = HeapAlloc(GetProcessHeap(), 0,
                 (passwordLen + 1) * sizeof(WCHAR));
                LPWSTR passwordConfirm = HeapAlloc(GetProcessHeap(), 0,
                 (passwordConfirmLen + 1) * sizeof(WCHAR));
                BOOL freePassword = TRUE;

                if (password && passwordConfirm)
                {
                    SendMessageW(passwordEdit, WM_GETTEXT, passwordLen + 1,
                     (LPARAM)password);
                    SendMessageW(passwordConfirmEdit, WM_GETTEXT,
                     passwordConfirmLen + 1, (LPARAM)passwordConfirm);
                    if (strcmpW(password, passwordConfirm))
                    {
                        export_password_mismatch(hwnd, data);
                        SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                        ret = 1;
                    }
                    else
                    {
                        data->contextInfo.pwszPassword = password;
                        freePassword = FALSE;
                        data->freePassword = TRUE;
                    }
                }
                if (freePassword)
                    HeapFree(GetProcessHeap(), 0, password);
                HeapFree(GetProcessHeap(), 0, passwordConfirm);
            }
            break;
        }
        }
        break;
    }
    }
    return ret;
}

static LPWSTR export_append_extension(const struct ExportWizData *data,
 LPWSTR fileName)
{
    static const WCHAR cer[] = { '.','c','e','r',0 };
    static const WCHAR crl[] = { '.','c','r','l',0 };
    static const WCHAR ctl[] = { '.','c','t','l',0 };
    static const WCHAR p7b[] = { '.','p','7','b',0 };
    static const WCHAR pfx[] = { '.','p','f','x',0 };
    static const WCHAR sst[] = { '.','s','s','t',0 };
    LPCWSTR extension;
    LPWSTR dot;
    BOOL appendExtension;

    switch (data->contextInfo.dwExportFormat)
    {
    case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
        extension = p7b;
        break;
    case CRYPTUI_WIZ_EXPORT_FORMAT_PFX:
        extension = pfx;
        break;
    default:
        switch (data->exportInfo.dwSubjectChoice)
        {
        case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
            extension = crl;
            break;
        case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
            extension = ctl;
            break;
        case CRYPTUI_WIZ_EXPORT_CERT_STORE:
            extension = sst;
            break;
        default:
            extension = cer;
        }
    }
    dot = strrchrW(fileName, '.');
    if (dot)
        appendExtension = strcmpiW(dot, extension) != 0;
    else
        appendExtension = TRUE;
    if (appendExtension)
    {
        fileName = HeapReAlloc(GetProcessHeap(), 0, fileName,
         (strlenW(fileName) + strlenW(extension) + 1) * sizeof(WCHAR));
        if (fileName)
            strcatW(fileName, extension);
    }
    return fileName;
}

static BOOL export_validate_filename(HWND hwnd, struct ExportWizData *data,
 LPCWSTR fileName)
{
    HANDLE file;
    BOOL tryCreate = TRUE, forceCreate = FALSE, ret = FALSE;

    file = CreateFileW(fileName, GENERIC_WRITE,
     FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (file != INVALID_HANDLE_VALUE)
    {
        WCHAR warning[MAX_STRING_LEN], title[MAX_STRING_LEN];
        LPCWSTR pTitle;

        if (data->pwszWizardTitle)
            pTitle = data->pwszWizardTitle;
        else
        {
            LoadStringW(hInstance, IDS_EXPORT_WIZARD, title,
             sizeof(title) / sizeof(title[0]));
            pTitle = title;
        }
        LoadStringW(hInstance, IDS_EXPORT_FILE_EXISTS, warning,
         sizeof(warning) / sizeof(warning[0]));
        if (MessageBoxW(hwnd, warning, pTitle, MB_YESNO) == IDYES)
            forceCreate = TRUE;
        else
            tryCreate = FALSE;
        CloseHandle(file);
    }
    if (tryCreate)
    {
        file = CreateFileW(fileName, GENERIC_WRITE,
         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
         forceCreate ? CREATE_ALWAYS : CREATE_NEW,
         0, NULL);
        if (file != INVALID_HANDLE_VALUE)
        {
            data->file = file;
            ret = TRUE;
        }
        else
        {
            WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
            LPCWSTR pTitle;
            LPWSTR msgBuf, fullError;

            if (data->pwszWizardTitle)
                pTitle = data->pwszWizardTitle;
            else
            {
                LoadStringW(hInstance, IDS_EXPORT_WIZARD, title,
                 sizeof(title) / sizeof(title[0]));
                pTitle = title;
            }
            LoadStringW(hInstance, IDS_IMPORT_OPEN_FAILED, error,
             sizeof(error) / sizeof(error[0]));
            FormatMessageW(
             FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
             GetLastError(), 0, (LPWSTR) &msgBuf, 0, NULL);
            fullError = HeapAlloc(GetProcessHeap(), 0,
             (strlenW(error) + strlenW(fileName) + strlenW(msgBuf) + 3)
             * sizeof(WCHAR));
            if (fullError)
            {
                LPWSTR ptr = fullError;

                strcpyW(ptr, error);
                ptr += strlenW(error);
                strcpyW(ptr, fileName);
                ptr += strlenW(fileName);
                *ptr++ = ':';
                *ptr++ = '\n';
                strcpyW(ptr, msgBuf);
                MessageBoxW(hwnd, fullError, pTitle, MB_ICONERROR | MB_OK);
                HeapFree(GetProcessHeap(), 0, fullError);
            }
            LocalFree(msgBuf);
        }
    }
    return ret;
}

static const WCHAR export_filter_cert[] = { '*','.','c','e','r',0 };
static const WCHAR export_filter_crl[] = { '*','.','c','r','l',0 };
static const WCHAR export_filter_ctl[] = { '*','.','s','t','l',0 };
static const WCHAR export_filter_cms[] = { '*','.','p','7','b',0 };
static const WCHAR export_filter_pfx[] = { '*','.','p','f','x',0 };
static const WCHAR export_filter_sst[] = { '*','.','s','s','t',0 };

static WCHAR *make_export_file_filter(DWORD exportFormat, DWORD subjectChoice)
{
    int baseLen, allLen, totalLen = 2, baseID;
    LPWSTR filter = NULL, baseFilter, all;
    LPCWSTR filterStr;

    switch (exportFormat)
    {
    case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
        baseID = IDS_EXPORT_FILTER_BASE64_CERT;
        filterStr = export_filter_cert;
        break;
    case CRYPTUI_WIZ_EXPORT_FORMAT_PFX:
        baseID = IDS_EXPORT_FILTER_PFX;
        filterStr = export_filter_pfx;
        break;
    case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
        baseID = IDS_EXPORT_FILTER_CMS;
        filterStr = export_filter_cms;
        break;
    default:
        switch (subjectChoice)
        {
        case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
            baseID = IDS_EXPORT_FILTER_CRL;
            filterStr = export_filter_crl;
            break;
        case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
            baseID = IDS_EXPORT_FILTER_CTL;
            filterStr = export_filter_ctl;
            break;
        case CRYPTUI_WIZ_EXPORT_CERT_STORE:
            baseID = IDS_EXPORT_FILTER_SERIALIZED_CERT_STORE;
            filterStr = export_filter_sst;
            break;
        default:
            baseID = IDS_EXPORT_FILTER_CERT;
            filterStr = export_filter_cert;
            break;
        }
    }
    baseLen = LoadStringW(hInstance, baseID, (LPWSTR)&baseFilter, 0);
    totalLen += baseLen + strlenW(filterStr) + 2;
    allLen = LoadStringW(hInstance, IDS_IMPORT_FILTER_ALL, (LPWSTR)&all, 0);
    totalLen += allLen + strlenW(filter_all) + 2;
    filter = HeapAlloc(GetProcessHeap(), 0, totalLen * sizeof(WCHAR));
    if (filter)
    {
        LPWSTR ptr;

        ptr = filter;
        memcpy(ptr, baseFilter, baseLen * sizeof(WCHAR));
        ptr += baseLen;
        *ptr++ = 0;
        strcpyW(ptr, filterStr);
        ptr += strlenW(filterStr) + 1;
        memcpy(ptr, all, allLen * sizeof(WCHAR));
        ptr += allLen;
        *ptr++ = 0;
        strcpyW(ptr, filter_all);
        ptr += strlenW(filter_all) + 1;
        *ptr++ = 0;
    }
    return filter;
}

static LRESULT CALLBACK export_file_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    struct ExportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;

        data = (struct ExportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        if (data->exportInfo.pwszExportFileName)
            SendMessageW(GetDlgItem(hwnd, IDC_EXPORT_FILENAME), WM_SETTEXT, 0,
             (LPARAM)data->exportInfo.pwszExportFileName);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_WIZBACK:
            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (data->contextInfo.dwExportFormat !=
             CRYPTUI_WIZ_EXPORT_FORMAT_PFX)
            {
                SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, IDD_EXPORT_FORMAT);
                ret = 1;
            }
            break;
        case PSN_WIZNEXT:
        {
            HWND fileNameEdit = GetDlgItem(hwnd, IDC_EXPORT_FILENAME);
            DWORD len = SendMessageW(fileNameEdit, WM_GETTEXTLENGTH, 0, 0);

            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if (!len)
            {
                WCHAR title[MAX_STRING_LEN], error[MAX_STRING_LEN];
                LPCWSTR pTitle;

                if (data->pwszWizardTitle)
                    pTitle = data->pwszWizardTitle;
                else
                {
                    LoadStringW(hInstance, IDS_EXPORT_WIZARD, title,
                     sizeof(title) / sizeof(title[0]));
                    pTitle = title;
                }
                LoadStringW(hInstance, IDS_IMPORT_EMPTY_FILE, error,
                 sizeof(error) / sizeof(error[0]));
                MessageBoxW(hwnd, error, pTitle, MB_ICONERROR | MB_OK);
                SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                ret = 1;
            }
            else
            {
                LPWSTR fileName = HeapAlloc(GetProcessHeap(), 0,
                 (len + 1) * sizeof(WCHAR));

                if (fileName)
                {
                    SendMessageW(fileNameEdit, WM_GETTEXT, len + 1,
                     (LPARAM)fileName);
                    fileName = export_append_extension(data, fileName);
                    if (!export_validate_filename(hwnd, data, fileName))
                    {
                        HeapFree(GetProcessHeap(), 0, fileName);
                        SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 1);
                        ret = 1;
                    }
                    else
                        data->fileName = fileName;
                }
            }
            break;
        }
        case PSN_SETACTIVE:
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_NEXT);
            ret = TRUE;
            break;
        }
        break;
    }
    case WM_COMMAND:
        switch (wp)
        {
        case IDC_EXPORT_BROWSE_FILE:
        {
            OPENFILENAMEW ofn;
            WCHAR fileBuf[MAX_PATH];

            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            memset(&ofn, 0, sizeof(ofn));
            ofn.lStructSize = sizeof(ofn);
            ofn.hwndOwner = hwnd;
            ofn.lpstrFilter = make_export_file_filter(
             data->contextInfo.dwExportFormat,
             data->exportInfo.dwSubjectChoice);
            ofn.lpstrFile = fileBuf;
            ofn.nMaxFile = sizeof(fileBuf) / sizeof(fileBuf[0]);
            fileBuf[0] = 0;
            if (GetSaveFileNameW(&ofn))
                SendMessageW(GetDlgItem(hwnd, IDC_EXPORT_FILENAME), WM_SETTEXT,
                 0, (LPARAM)ofn.lpstrFile);
            HeapFree(GetProcessHeap(), 0, (LPWSTR)ofn.lpstrFilter);
            break;
        }
        }
        break;
    }
    return ret;
}

static void show_export_details(HWND lv, const struct ExportWizData *data)
{
    WCHAR text[MAX_STRING_LEN];
    LVITEMW item;
    int contentID;

    item.mask = LVIF_TEXT;
    if (data->fileName)
    {
        item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
        item.iSubItem = 0;
        LoadStringW(hInstance, IDS_IMPORT_FILE, text,
         sizeof(text)/ sizeof(text[0]));
        item.pszText = text;
        SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
        item.iSubItem = 1;
        item.pszText = data->fileName;
        SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    }

    item.pszText = text;
    switch (data->exportInfo.dwSubjectChoice)
    {
    case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
    case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
    case CRYPTUI_WIZ_EXPORT_CERT_STORE:
    case CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY:
        /* do nothing */
        break;
    default:
    {
        item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
        item.iSubItem = 0;
        LoadStringW(hInstance, IDS_EXPORT_INCLUDE_CHAIN, text,
         sizeof(text) / sizeof(text[0]));
        SendMessageW(lv, LVM_INSERTITEMW, item.iItem, (LPARAM)&item);
        item.iSubItem = 1;
        LoadStringW(hInstance,
         data->contextInfo.fExportChain ? IDS_YES : IDS_NO, text,
         sizeof(text) / sizeof(text[0]));
        SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);

        item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
        item.iSubItem = 0;
        LoadStringW(hInstance, IDS_EXPORT_KEYS, text,
         sizeof(text) / sizeof(text[0]));
        SendMessageW(lv, LVM_INSERTITEMW, item.iItem, (LPARAM)&item);
        item.iSubItem = 1;
        LoadStringW(hInstance,
         data->contextInfo.fExportPrivateKeys ? IDS_YES : IDS_NO, text,
         sizeof(text) / sizeof(text[0]));
        SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
    }
    }

    item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
    item.iSubItem = 0;
    LoadStringW(hInstance, IDS_EXPORT_FORMAT, text,
     sizeof(text)/ sizeof(text[0]));
    SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);

    item.iSubItem = 1;
    switch (data->exportInfo.dwSubjectChoice)
    {
    case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
        contentID = IDS_EXPORT_FILTER_CRL;
        break;
    case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
        contentID = IDS_EXPORT_FILTER_CTL;
        break;
    case CRYPTUI_WIZ_EXPORT_CERT_STORE:
        contentID = IDS_EXPORT_FILTER_SERIALIZED_CERT_STORE;
        break;
    default:
        switch (data->contextInfo.dwExportFormat)
        {
        case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
            contentID = IDS_EXPORT_FILTER_BASE64_CERT;
            break;
        case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
            contentID = IDS_EXPORT_FILTER_CMS;
            break;
        case CRYPTUI_WIZ_EXPORT_FORMAT_PFX:
            contentID = IDS_EXPORT_FILTER_PFX;
            break;
        default:
            contentID = IDS_EXPORT_FILTER_CERT;
        }
    }
    LoadStringW(hInstance, contentID, text, sizeof(text) / sizeof(text[0]));
    SendMessageW(lv, LVM_SETITEMTEXTW, item.iItem, (LPARAM)&item);
}

static inline BOOL save_der(HANDLE file, const BYTE *pb, DWORD cb)
{
    DWORD bytesWritten;

    return WriteFile(file, pb, cb, &bytesWritten, NULL);
}

static BOOL save_base64(HANDLE file, const BYTE *pb, DWORD cb)
{
    BOOL ret;
    DWORD size = 0;

    if ((ret = CryptBinaryToStringA(pb, cb, CRYPT_STRING_BASE64, NULL, &size)))
    {
        LPSTR buf = HeapAlloc(GetProcessHeap(), 0, size);

        if (buf)
        {
            if ((ret = CryptBinaryToStringA(pb, cb, CRYPT_STRING_BASE64, buf,
             &size)))
                ret = WriteFile(file, buf, size, &size, NULL);
            HeapFree(GetProcessHeap(), 0, buf);
        }
        else
        {
            SetLastError(ERROR_OUTOFMEMORY);
            ret = FALSE;
        }
    }
    return ret;
}

static inline BOOL save_store_as_cms(HANDLE file, HCERTSTORE store)
{
    return CertSaveStore(store, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
     CERT_STORE_SAVE_AS_PKCS7, CERT_STORE_SAVE_TO_FILE, file, 0);
}

static BOOL save_cert_as_cms(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo,
 BOOL includeChain)
{
    BOOL ret;
    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);

    if (store)
    {
        if (includeChain)
        {
            HCERTSTORE addlStore = CertOpenStore(CERT_STORE_PROV_COLLECTION,
             0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);

            if (addlStore)
            {
                DWORD i;

                ret = TRUE;
                for (i = 0; ret && i < pExportInfo->cStores; i++)
                    ret = CertAddStoreToCollection(addlStore,
                     pExportInfo->rghStores, 0, 0);
                if (ret)
                {
                    PCCERT_CHAIN_CONTEXT chain;

                    ret = CertGetCertificateChain(NULL,
                     pExportInfo->u.pCertContext, NULL, addlStore, NULL, 0,
                     NULL, &chain);
                    if (ret)
                    {
                        DWORD j;

                        for (i = 0; ret && i < chain->cChain; i++)
                            for (j = 0; ret && j < chain->rgpChain[i]->cElement;
                             j++)
                                ret = CertAddCertificateContextToStore(store,
                                 chain->rgpChain[i]->rgpElement[j]->pCertContext,
                                 CERT_STORE_ADD_ALWAYS, NULL);
                        CertFreeCertificateChain(chain);
                    }
                    else
                    {
                        /* No chain could be created, just add the individual
                         * cert to the message.
                         */
                        ret = CertAddCertificateContextToStore(store,
                         pExportInfo->u.pCertContext, CERT_STORE_ADD_ALWAYS,
                         NULL);
                    }
                }
                CertCloseStore(addlStore, 0);
            }
            else
                ret = FALSE;
        }
        else
            ret = CertAddCertificateContextToStore(store,
             pExportInfo->u.pCertContext, CERT_STORE_ADD_ALWAYS, NULL);
        if (ret)
            ret = save_store_as_cms(file, store);
        CertCloseStore(store, 0);
    }
    else
        ret = FALSE;
    return ret;
}

static BOOL save_serialized_store(HANDLE file, HCERTSTORE store)
{
    return CertSaveStore(store, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
     CERT_STORE_SAVE_AS_STORE, CERT_STORE_SAVE_TO_FILE, file, 0);
}

static BOOL save_pfx(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo,
 PCCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO pContextInfo,
 PCRYPT_KEY_PROV_INFO keyProvInfo, BOOL deleteKeys)
{
    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING,
     0, CERT_STORE_CREATE_NEW_FLAG, NULL);
    BOOL ret = FALSE;

    if (store)
    {
        CRYPT_DATA_BLOB pfxBlob = { 0, NULL };
        PCCERT_CONTEXT cert = NULL;
        BOOL freeKeyProvInfo = FALSE;

        if (pContextInfo->fExportChain)
        {
            HCERTCHAINENGINE engine = NULL;

            if (pExportInfo->cStores)
            {
                CERT_CHAIN_ENGINE_CONFIG config;

                memset(&config, 0, sizeof(config));
                config.cbSize = sizeof(config);
                config.cAdditionalStore = pExportInfo->cStores;
                config.rghAdditionalStore = pExportInfo->rghStores;
                ret = CertCreateCertificateChainEngine(&config, &engine);
            }
            else
                ret = TRUE;
            if (ret)
            {
                CERT_CHAIN_PARA chainPara;
                PCCERT_CHAIN_CONTEXT chain;

                memset(&chainPara, 0, sizeof(chainPara));
                chainPara.cbSize = sizeof(chainPara);
                ret = CertGetCertificateChain(engine,
                 pExportInfo->u.pCertContext, NULL, NULL, &chainPara, 0, NULL,
                 &chain);
                if (ret)
                {
                    DWORD i, j;

                    for (i = 0; ret && i < chain->cChain; i++)
                        for (j = 0; ret && j < chain->rgpChain[i]->cElement;
                         j++)
                        {
                            if (i == 0 && j == 0)
                                ret = CertAddCertificateContextToStore(store,
                                 chain->rgpChain[i]->rgpElement[j]->pCertContext,
                                 CERT_STORE_ADD_ALWAYS, &cert);
                            else
                                ret = CertAddCertificateContextToStore(store,
                                 chain->rgpChain[i]->rgpElement[j]->pCertContext,
                                 CERT_STORE_ADD_ALWAYS, NULL);
                        }
                    CertFreeCertificateChain(chain);
                }
            }
            if (engine)
                CertFreeCertificateChainEngine(engine);
        }
        else
            ret = CertAddCertificateContextToStore(store,
             pExportInfo->u.pCertContext, CERT_STORE_ADD_ALWAYS, &cert);
        /* Copy private key info to newly created cert, so it'll get exported
         * along with the cert.
         */
        if (ret && pContextInfo->fExportPrivateKeys)
        {
            if (keyProvInfo)
                ret = CertSetCertificateContextProperty(cert,
                 CERT_KEY_PROV_INFO_PROP_ID, 0, keyProvInfo);
            else
            {
                if (!(keyProvInfo = export_get_private_key_info(cert)))
                    ret = FALSE;
                else
                {
                    ret = CertSetCertificateContextProperty(cert,
                     CERT_KEY_PROV_INFO_PROP_ID, 0, keyProvInfo);
                    freeKeyProvInfo = TRUE;
                }
            }
        }
        if (ret)
        {
            DWORD exportFlags =
             REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | EXPORT_PRIVATE_KEYS;

            ret = PFXExportCertStore(store, &pfxBlob,
             pContextInfo->pwszPassword, exportFlags);
            if (ret)
            {
                pfxBlob.pbData = HeapAlloc(GetProcessHeap(), 0, pfxBlob.cbData);
                if (pfxBlob.pbData)
                {
                    ret = PFXExportCertStore(store, &pfxBlob,
                     pContextInfo->pwszPassword, exportFlags);
                    if (ret)
                    {
                        DWORD bytesWritten;

                        ret = WriteFile(file, pfxBlob.pbData, pfxBlob.cbData,
                         &bytesWritten, NULL);
                    }
                }
                else
                {
                    SetLastError(ERROR_OUTOFMEMORY);
                    ret = FALSE;
                }
            }
        }
        if (ret && deleteKeys)
        {
            HCRYPTPROV prov;

            CryptAcquireContextW(&prov, keyProvInfo->pwszContainerName,
             keyProvInfo->pwszProvName, keyProvInfo->dwProvType,
             CRYPT_DELETEKEYSET);
        }
        if (freeKeyProvInfo)
            HeapFree(GetProcessHeap(), 0, keyProvInfo);
        CertFreeCertificateContext(cert);
        CertCloseStore(store, 0);
    }
    return ret;
}

static BOOL do_export(HANDLE file, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo,
 PCCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO pContextInfo,
 PCRYPT_KEY_PROV_INFO keyProvInfo, BOOL deleteKeys)
{
    BOOL ret;

    if (pContextInfo->dwSize != sizeof(CRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO))
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    switch (pExportInfo->dwSubjectChoice)
    {
    case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
        ret = save_der(file,
         pExportInfo->u.pCRLContext->pbCrlEncoded,
         pExportInfo->u.pCRLContext->cbCrlEncoded);
        break;
    case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
        ret = save_der(file,
         pExportInfo->u.pCTLContext->pbCtlEncoded,
         pExportInfo->u.pCTLContext->cbCtlEncoded);
        break;
    case CRYPTUI_WIZ_EXPORT_CERT_STORE:
        ret = save_serialized_store(file, pExportInfo->u.hCertStore);
        break;
    case CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY:
        ret = save_store_as_cms(file, pExportInfo->u.hCertStore);
        break;
    default:
        switch (pContextInfo->dwExportFormat)
        {
        case CRYPTUI_WIZ_EXPORT_FORMAT_DER:
            ret = save_der(file, pExportInfo->u.pCertContext->pbCertEncoded,
             pExportInfo->u.pCertContext->cbCertEncoded);
            break;
        case CRYPTUI_WIZ_EXPORT_FORMAT_BASE64:
            ret = save_base64(file,
             pExportInfo->u.pCertContext->pbCertEncoded,
             pExportInfo->u.pCertContext->cbCertEncoded);
            break;
        case CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7:
            ret = save_cert_as_cms(file, pExportInfo,
             pContextInfo->fExportChain);
            break;
        case CRYPTUI_WIZ_EXPORT_FORMAT_PFX:
            ret = save_pfx(file, pExportInfo, pContextInfo, keyProvInfo,
             deleteKeys);
            break;
        default:
            SetLastError(E_FAIL);
            ret = FALSE;
        }
    }
    return ret;
}

static LRESULT CALLBACK export_finish_dlg_proc(HWND hwnd, UINT msg, WPARAM wp,
 LPARAM lp)
{
    LRESULT ret = 0;
    struct ExportWizData *data;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lp;
        HWND lv = GetDlgItem(hwnd, IDC_EXPORT_SETTINGS);
        RECT rc;
        LVCOLUMNW column;

        data = (struct ExportWizData *)page->lParam;
        SetWindowLongPtrW(hwnd, DWLP_USER, (LPARAM)data);
        SendMessageW(GetDlgItem(hwnd, IDC_EXPORT_TITLE), WM_SETFONT,
         (WPARAM)data->titleFont, TRUE);
        GetWindowRect(lv, &rc);
        column.mask = LVCF_WIDTH;
        column.cx = (rc.right - rc.left) / 2 - 2;
        SendMessageW(lv, LVM_INSERTCOLUMNW, 0, (LPARAM)&column);
        SendMessageW(lv, LVM_INSERTCOLUMNW, 1, (LPARAM)&column);
        show_export_details(lv, data);
        break;
    }
    case WM_NOTIFY:
    {
        NMHDR *hdr = (NMHDR *)lp;

        switch (hdr->code)
        {
        case PSN_SETACTIVE:
        {
            HWND lv = GetDlgItem(hwnd, IDC_EXPORT_SETTINGS);

            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            SendMessageW(lv, LVM_DELETEALLITEMS, 0, 0);
            show_export_details(lv, data);
            PostMessageW(GetParent(hwnd), PSM_SETWIZBUTTONS, 0,
             PSWIZB_BACK | PSWIZB_FINISH);
            ret = TRUE;
            break;
        }
        case PSN_WIZFINISH:
        {
            int messageID;
            WCHAR title[MAX_STRING_LEN], message[MAX_STRING_LEN];
            LPCWSTR pTitle;
            DWORD mbFlags;

            data = (struct ExportWizData *)GetWindowLongPtrW(hwnd, DWLP_USER);
            if ((data->success = do_export(data->file, &data->exportInfo,
             &data->contextInfo, data->keyProvInfo, data->deleteKeys)))
            {
                messageID = IDS_EXPORT_SUCCEEDED;
                mbFlags = MB_OK;
            }
            else
            {
                messageID = IDS_EXPORT_FAILED;
                mbFlags = MB_OK | MB_ICONERROR;
            }
            if (data->pwszWizardTitle)
                pTitle = data->pwszWizardTitle;
            else
            {
                LoadStringW(hInstance, IDS_EXPORT_WIZARD, title,
                 sizeof(title) / sizeof(title[0]));
                pTitle = title;
            }
            LoadStringW(hInstance, messageID, message,
             sizeof(message) / sizeof(message[0]));
            MessageBoxW(hwnd, message, pTitle, mbFlags);
            break;
        }
        }
        break;
    }
    }
    return ret;
}

static BOOL show_export_ui(DWORD dwFlags, HWND hwndParent,
 LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo, const void *pvoid)
{
    PROPSHEETHEADERW hdr;
    PROPSHEETPAGEW pages[6];
    struct ExportWizData data;
    int nPages = 0;
    BOOL hasPrivateKey, showFormatPage = TRUE;
    INT_PTR l;

    data.dwFlags = dwFlags;
    data.pwszWizardTitle = pwszWizardTitle;
    memset(&data.exportInfo, 0, sizeof(data.exportInfo));
    memcpy(&data.exportInfo, pExportInfo,
     min(sizeof(data.exportInfo), pExportInfo->dwSize));
    if (pExportInfo->dwSize > sizeof(data.exportInfo))
        data.exportInfo.dwSize = sizeof(data.exportInfo);
    data.contextInfo.dwSize = sizeof(data.contextInfo);
    data.contextInfo.dwExportFormat = CRYPTUI_WIZ_EXPORT_FORMAT_DER;
    data.contextInfo.fExportChain = FALSE;
    data.contextInfo.fStrongEncryption = FALSE;
    data.contextInfo.fExportPrivateKeys = FALSE;
    data.contextInfo.pwszPassword = NULL;
    data.freePassword = FALSE;
    if (pExportInfo->dwSubjectChoice == CRYPTUI_WIZ_EXPORT_CERT_CONTEXT &&
     pvoid)
        memcpy(&data.contextInfo, pvoid,
         min(((PCCRYPTUI_WIZ_EXPORT_CERTCONTEXT_INFO)pvoid)->dwSize,
         sizeof(data.contextInfo)));
    data.keyProvInfo = NULL;
    data.deleteKeys = FALSE;
    data.fileName = NULL;
    data.file = INVALID_HANDLE_VALUE;
    data.success = FALSE;

    memset(pages, 0, sizeof(pages));

    pages[nPages].dwSize = sizeof(pages[0]);
    pages[nPages].hInstance = hInstance;
    pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_EXPORT_WELCOME);
    pages[nPages].pfnDlgProc = export_welcome_dlg_proc;
    pages[nPages].dwFlags = PSP_HIDEHEADER;
    pages[nPages].lParam = (LPARAM)&data;
    nPages++;

    hasPrivateKey = export_info_has_private_key(pExportInfo);
    switch (pExportInfo->dwSubjectChoice)
    {
    case CRYPTUI_WIZ_EXPORT_CRL_CONTEXT:
    case CRYPTUI_WIZ_EXPORT_CTL_CONTEXT:
        showFormatPage = FALSE;
        data.contextInfo.dwExportFormat = CRYPTUI_WIZ_EXPORT_FORMAT_DER;
        break;
    case CRYPTUI_WIZ_EXPORT_CERT_STORE:
        showFormatPage = FALSE;
        data.contextInfo.dwExportFormat =
         CRYPTUI_WIZ_EXPORT_FORMAT_SERIALIZED_CERT_STORE;
        break;
    case CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY:
        showFormatPage = FALSE;
        data.contextInfo.dwExportFormat = CRYPTUI_WIZ_EXPORT_FORMAT_PKCS7;
        break;
    }

    if (hasPrivateKey && showFormatPage)
    {
        pages[nPages].dwSize = sizeof(pages[0]);
        pages[nPages].hInstance = hInstance;
        pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_EXPORT_PRIVATE_KEY);
        pages[nPages].pfnDlgProc = export_private_key_dlg_proc;
        pages[nPages].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
        pages[nPages].pszHeaderTitle =
         MAKEINTRESOURCEW(IDS_EXPORT_PRIVATE_KEY_TITLE);
        pages[nPages].pszHeaderSubTitle =
         MAKEINTRESOURCEW(IDS_EXPORT_PRIVATE_KEY_SUBTITLE);
        pages[nPages].lParam = (LPARAM)&data;
        nPages++;
    }
    if (showFormatPage)
    {
        pages[nPages].dwSize = sizeof(pages[0]);
        pages[nPages].hInstance = hInstance;
        pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_EXPORT_FORMAT);
        pages[nPages].pfnDlgProc = export_format_dlg_proc;
        pages[nPages].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
        pages[nPages].pszHeaderTitle =
         MAKEINTRESOURCEW(IDS_EXPORT_FORMAT_TITLE);
        pages[nPages].pszHeaderSubTitle =
         MAKEINTRESOURCEW(IDS_EXPORT_FORMAT_SUBTITLE);
        pages[nPages].lParam = (LPARAM)&data;
        nPages++;
    }
    if (hasPrivateKey && showFormatPage)
    {
        pages[nPages].dwSize = sizeof(pages[0]);
        pages[nPages].hInstance = hInstance;
        pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_EXPORT_PASSWORD);
        pages[nPages].pfnDlgProc = export_password_dlg_proc;
        pages[nPages].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
        pages[nPages].pszHeaderTitle =
         MAKEINTRESOURCEW(IDS_EXPORT_PASSWORD_TITLE);
        pages[nPages].pszHeaderSubTitle =
         MAKEINTRESOURCEW(IDS_EXPORT_PASSWORD_SUBTITLE);
        pages[nPages].lParam = (LPARAM)&data;
        nPages++;
    }

    pages[nPages].dwSize = sizeof(pages[0]);
    pages[nPages].hInstance = hInstance;
    pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_EXPORT_FILE);
    pages[nPages].pfnDlgProc = export_file_dlg_proc;
    pages[nPages].dwFlags = PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
    pages[nPages].pszHeaderTitle = MAKEINTRESOURCEW(IDS_EXPORT_FILE_TITLE);
    pages[nPages].pszHeaderSubTitle =
     MAKEINTRESOURCEW(IDS_EXPORT_FILE_SUBTITLE);
    pages[nPages].lParam = (LPARAM)&data;
    nPages++;

    pages[nPages].dwSize = sizeof(pages[0]);
    pages[nPages].hInstance = hInstance;
    pages[nPages].u.pszTemplate = MAKEINTRESOURCEW(IDD_EXPORT_FINISH);
    pages[nPages].pfnDlgProc = export_finish_dlg_proc;
    pages[nPages].dwFlags = PSP_HIDEHEADER;
    pages[nPages].lParam = (LPARAM)&data;
    nPages++;

    memset(&hdr, 0, sizeof(hdr));
    hdr.dwSize = sizeof(hdr);
    hdr.hwndParent = hwndParent;
    hdr.dwFlags = PSH_PROPSHEETPAGE | PSH_WIZARD97_NEW | PSH_HEADER |
     PSH_WATERMARK;
    hdr.hInstance = hInstance;
    if (pwszWizardTitle)
        hdr.pszCaption = pwszWizardTitle;
    else
        hdr.pszCaption = MAKEINTRESOURCEW(IDS_EXPORT_WIZARD);
    hdr.u3.ppsp = pages;
    hdr.nPages = nPages;
    hdr.u4.pszbmWatermark = MAKEINTRESOURCEW(IDB_CERT_WATERMARK);
    hdr.u5.pszbmHeader = MAKEINTRESOURCEW(IDB_CERT_HEADER);
    l = PropertySheetW(&hdr);
    DeleteObject(data.titleFont);
    if (data.freePassword)
        HeapFree(GetProcessHeap(), 0,
         (LPWSTR)data.contextInfo.pwszPassword);
    HeapFree(GetProcessHeap(), 0, data.keyProvInfo);
    CloseHandle(data.file);
    HeapFree(GetProcessHeap(), 0, data.fileName);
    if (l == 0)
    {
        SetLastError(ERROR_CANCELLED);
        return FALSE;
    }
    else
        return data.success;
}

BOOL WINAPI CryptUIWizExport(DWORD dwFlags, HWND hwndParent,
 LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo, void *pvoid)
{
    BOOL ret;

    TRACE("(%08x, %p, %s, %p, %p)\n", dwFlags, hwndParent,
     debugstr_w(pwszWizardTitle), pExportInfo, pvoid);

    if (!(dwFlags & CRYPTUI_WIZ_NO_UI))
        ret = show_export_ui(dwFlags, hwndParent, pwszWizardTitle, pExportInfo,
         pvoid);
    else
    {
        HANDLE file = CreateFileW(pExportInfo->pwszExportFileName,
         GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
         CREATE_ALWAYS, 0, NULL);

        if (file != INVALID_HANDLE_VALUE)
        {
            ret = do_export(file, pExportInfo, pvoid, NULL, FALSE);
            CloseHandle(file);
        }
        else
            ret = FALSE;
    }
    return ret;
}

BOOL WINAPI CryptUIDlgViewSignerInfoA(CRYPTUI_VIEWSIGNERINFO_STRUCTA *pcvsi)
{
    FIXME("%p: stub\n", pcvsi);
    return FALSE;
}

PCCERT_CONTEXT WINAPI CryptUIDlgSelectCertificateW(PCCRYPTUI_SELECTCERTIFICATE_STRUCTW pcsc)
{
    FIXME("%p: stub\n", pcsc);
    return NULL;
}

PCCERT_CONTEXT WINAPI CryptUIDlgSelectCertificateA(PCCRYPTUI_SELECTCERTIFICATE_STRUCTA pcsc)
{
    FIXME("%p: stub\n", pcsc);
    return NULL;
}
