/*
 * crypt32 Crypt*Object functions
 *
 * Copyright 2007 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 <stdarg.h>
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "mssip.h"
#include "winuser.h"
#include "wintrust.h"
#include "crypt32_private.h"
#include "cryptres.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

static BOOL CRYPT_ReadBlobFromFile(LPCWSTR fileName, PCERT_BLOB blob)
{
    BOOL ret = FALSE;
    HANDLE file;

    TRACE("%s\n", debugstr_w(fileName));

    file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
     OPEN_EXISTING, 0, NULL);
    if (file != INVALID_HANDLE_VALUE)
    {
        ret = TRUE;
        blob->cbData = GetFileSize(file, NULL);
        if (blob->cbData)
        {
            blob->pbData = CryptMemAlloc(blob->cbData);
            if (blob->pbData)
            {
                DWORD read;

                ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL);
            }
        }
        CloseHandle(file);
    }
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_QueryContextBlob(const CERT_BLOB *blob,
 DWORD dwExpectedContentTypeFlags, HCERTSTORE store,
 DWORD *contentType, const void **ppvContext)
{
    BOOL ret = FALSE;

    if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT)
    {
        ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING,
         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
        if (ret && contentType)
            *contentType = CERT_QUERY_CONTENT_CERT;
    }
    if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL))
    {
        ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
        if (ret && contentType)
            *contentType = CERT_QUERY_CONTENT_CRL;
    }
    if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
    {
        ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING,
         blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext);
        if (ret && contentType)
            *contentType = CERT_QUERY_CONTENT_CTL;
    }
    return ret;
}

static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject,
 DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
 HCERTSTORE *phCertStore, const void **ppvContext)
{
    CERT_BLOB fileBlob;
    const CERT_BLOB *blob;
    HCERTSTORE store;
    BOOL ret;
    DWORD formatType = 0;

    switch (dwObjectType)
    {
    case CERT_QUERY_OBJECT_FILE:
        /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
         * just read the file directly
         */
        ret = CRYPT_ReadBlobFromFile(pvObject, &fileBlob);
        blob = &fileBlob;
        break;
    case CERT_QUERY_OBJECT_BLOB:
        blob = pvObject;
        ret = TRUE;
        break;
    default:
        SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
        ret = FALSE;
    }
    if (!ret)
        return FALSE;

    ret = FALSE;
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
    {
        ret = CRYPT_QueryContextBlob(blob, dwExpectedContentTypeFlags, store,
         pdwContentType, ppvContext);
        if (ret)
            formatType = CERT_QUERY_FORMAT_BINARY;
    }
    if (!ret &&
     (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED))
    {
        CRYPT_DATA_BLOB trimmed = { blob->cbData, blob->pbData };
        CRYPT_DATA_BLOB decoded;

        while (trimmed.cbData && !trimmed.pbData[trimmed.cbData - 1])
            trimmed.cbData--;
        ret = CryptStringToBinaryA((LPSTR)trimmed.pbData, trimmed.cbData,
         CRYPT_STRING_BASE64_ANY, NULL, &decoded.cbData, NULL, NULL);
        if (ret)
        {
            decoded.pbData = CryptMemAlloc(decoded.cbData);
            if (decoded.pbData)
            {
                ret = CryptStringToBinaryA((LPSTR)trimmed.pbData,
                 trimmed.cbData, CRYPT_STRING_BASE64_ANY, decoded.pbData,
                 &decoded.cbData, NULL, NULL);
                if (ret)
                {
                    ret = CRYPT_QueryContextBlob(&decoded,
                     dwExpectedContentTypeFlags, store, pdwContentType,
                     ppvContext);
                    if (ret)
                        formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
                }
                CryptMemFree(decoded.pbData);
            }
            else
                ret = FALSE;
        }
    }
    if (ret)
    {
        if (pdwMsgAndCertEncodingType)
            *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
        if (pdwFormatType)
            *pdwFormatType = formatType;
        if (phCertStore)
            *phCertStore = CertDuplicateStore(store);
    }
    CertCloseStore(store, 0);
    if (blob == &fileBlob)
        CryptMemFree(blob->pbData);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_QuerySerializedContextObject(DWORD dwObjectType,
 const void *pvObject, DWORD dwExpectedContentTypeFlags,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
 HCERTSTORE *phCertStore, const void **ppvContext)
{
    CERT_BLOB fileBlob;
    const CERT_BLOB *blob;
    const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
    const void *context;
    DWORD contextType;
    BOOL ret;

    switch (dwObjectType)
    {
    case CERT_QUERY_OBJECT_FILE:
        /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so
         * just read the file directly
         */
        ret = CRYPT_ReadBlobFromFile(pvObject, &fileBlob);
        blob = &fileBlob;
        break;
    case CERT_QUERY_OBJECT_BLOB:
        blob = pvObject;
        ret = TRUE;
        break;
    default:
        SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
        ret = FALSE;
    }
    if (!ret)
        return FALSE;

    ret = FALSE;
    context = CRYPT_ReadSerializedElement(blob->pbData, blob->cbData,
     CERT_STORE_ALL_CONTEXT_FLAG, &contextType);
    if (context)
    {
        DWORD contentType, certStoreOffset;

        ret = TRUE;
        switch (contextType)
        {
        case CERT_STORE_CERTIFICATE_CONTEXT:
            contextInterface = pCertInterface;
            contentType = CERT_QUERY_CONTENT_SERIALIZED_CERT;
            certStoreOffset = offsetof(CERT_CONTEXT, hCertStore);
            if (!(dwExpectedContentTypeFlags &
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT))
            {
                SetLastError(ERROR_INVALID_DATA);
                ret = FALSE;
                goto end;
            }
            break;
        case CERT_STORE_CRL_CONTEXT:
            contextInterface = pCRLInterface;
            contentType = CERT_QUERY_CONTENT_SERIALIZED_CRL;
            certStoreOffset = offsetof(CRL_CONTEXT, hCertStore);
            if (!(dwExpectedContentTypeFlags &
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL))
            {
                SetLastError(ERROR_INVALID_DATA);
                ret = FALSE;
                goto end;
            }
            break;
        case CERT_STORE_CTL_CONTEXT:
            contextInterface = pCTLInterface;
            contentType = CERT_QUERY_CONTENT_SERIALIZED_CTL;
            certStoreOffset = offsetof(CTL_CONTEXT, hCertStore);
            if (!(dwExpectedContentTypeFlags &
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL))
            {
                SetLastError(ERROR_INVALID_DATA);
                ret = FALSE;
                goto end;
            }
            break;
        default:
            SetLastError(ERROR_INVALID_DATA);
            ret = FALSE;
            goto end;
        }
        if (pdwMsgAndCertEncodingType)
            *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
        if (pdwContentType)
            *pdwContentType = contentType;
        if (phCertStore)
            *phCertStore = CertDuplicateStore(
             *(HCERTSTORE *)((const BYTE *)context + certStoreOffset));
        if (ppvContext)
            *ppvContext = contextInterface->duplicate(context);
    }

end:
    if (contextInterface && context)
        contextInterface->free(context);
    if (blob == &fileBlob)
        CryptMemFree(blob->pbData);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_QuerySerializedStoreFromFile(LPCWSTR fileName,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
 HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
    HANDLE file;
    BOOL ret = FALSE;

    TRACE("%s\n", debugstr_w(fileName));
    file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
     OPEN_EXISTING, 0, NULL);
    if (file != INVALID_HANDLE_VALUE)
    {
        HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
         CERT_STORE_CREATE_NEW_FLAG, NULL);

        ret = CRYPT_ReadSerializedStoreFromFile(file, store);
        if (ret)
        {
            if (pdwMsgAndCertEncodingType)
                *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
            if (pdwContentType)
                *pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE;
            if (phCertStore)
                *phCertStore = CertDuplicateStore(store);
        }
        CertCloseStore(store, 0);
        CloseHandle(file);
    }
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_QuerySerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
 HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
    HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    BOOL ret;

    TRACE("(%d, %p)\n", blob->cbData, blob->pbData);

    ret = CRYPT_ReadSerializedStoreFromBlob(blob, store);
    if (ret)
    {
        if (pdwMsgAndCertEncodingType)
            *pdwMsgAndCertEncodingType = X509_ASN_ENCODING;
        if (pdwContentType)
            *pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE;
        if (phCertStore)
            *phCertStore = CertDuplicateStore(store);
    }
    CertCloseStore(store, 0);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType,
 const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
 HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
    switch (dwObjectType)
    {
    case CERT_QUERY_OBJECT_FILE:
        return CRYPT_QuerySerializedStoreFromFile(pvObject,
         pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
    case CERT_QUERY_OBJECT_BLOB:
        return CRYPT_QuerySerializedStoreFromBlob(pvObject,
         pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
    default:
        FIXME("unimplemented for type %d\n", dwObjectType);
        SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
        return FALSE;
    }
}

static BOOL CRYPT_QuerySignedMessage(const CRYPT_DATA_BLOB *blob,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg)
{
    DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
    BOOL ret = FALSE;
    HCRYPTMSG msg;

    if ((msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL)))
    {
        ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
        if (ret)
        {
            DWORD type, len = sizeof(type);

            ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
            if (ret)
            {
                if (type != CMSG_SIGNED)
                {
                    SetLastError(ERROR_INVALID_DATA);
                    ret = FALSE;
                }
            }
        }
        if (!ret)
        {
            CryptMsgClose(msg);
            msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_SIGNED, 0, NULL,
             NULL);
            if (msg)
            {
                ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
                if (!ret)
                {
                    CryptMsgClose(msg);
                    msg = NULL;
                }
            }
        }
    }
    if (ret)
    {
        if (pdwMsgAndCertEncodingType)
            *pdwMsgAndCertEncodingType = encodingType;
        if (pdwContentType)
            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
        if (phMsg)
            *phMsg = msg;
    }
    return ret;
}

static BOOL CRYPT_QueryUnsignedMessage(const CRYPT_DATA_BLOB *blob,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCRYPTMSG *phMsg)
{
    DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
    BOOL ret = FALSE;
    HCRYPTMSG msg;

    if ((msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL)))
    {
        ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
        if (ret)
        {
            DWORD type, len = sizeof(type);

            ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len);
            if (ret)
            {
                if (type != CMSG_DATA)
                {
                    SetLastError(ERROR_INVALID_DATA);
                    ret = FALSE;
                }
            }
        }
        if (!ret)
        {
            CryptMsgClose(msg);
            msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_DATA, 0,
             NULL, NULL);
            if (msg)
            {
                ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE);
                if (!ret)
                {
                    CryptMsgClose(msg);
                    msg = NULL;
                }
            }
        }
    }
    if (ret)
    {
        if (pdwMsgAndCertEncodingType)
            *pdwMsgAndCertEncodingType = encodingType;
        if (pdwContentType)
            *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED;
        if (phMsg)
            *phMsg = msg;
    }
    return ret;
}

/* Used to decode non-embedded messages */
static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject,
 DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, DWORD *pdwFormatType,
 HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
    CERT_BLOB fileBlob;
    const CERT_BLOB *blob;
    BOOL ret;
    HCRYPTMSG msg = NULL;
    DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
    DWORD formatType = 0;

    TRACE("(%d, %p, %08x, %08x, %p, %p, %p, %p, %p)\n", dwObjectType, pvObject,
     dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
     pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
     phMsg);

    switch (dwObjectType)
    {
    case CERT_QUERY_OBJECT_FILE:
        /* This isn't an embedded PKCS7 message, so just read the file
         * directly
         */
        ret = CRYPT_ReadBlobFromFile(pvObject, &fileBlob);
        blob = &fileBlob;
        break;
    case CERT_QUERY_OBJECT_BLOB:
        blob = pvObject;
        ret = TRUE;
        break;
    default:
        SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */
        ret = FALSE;
    }
    if (!ret)
        return FALSE;

    ret = FALSE;
    if (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BINARY)
    {
        /* Try it first as a signed message */
        if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
            ret = CRYPT_QuerySignedMessage(blob, pdwMsgAndCertEncodingType,
             pdwContentType, &msg);
        /* Failing that, try as an unsigned message */
        if (!ret &&
         (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
            ret = CRYPT_QueryUnsignedMessage(blob, pdwMsgAndCertEncodingType,
             pdwContentType, &msg);
        if (ret)
            formatType = CERT_QUERY_FORMAT_BINARY;
    }
    if (!ret &&
     (dwExpectedFormatTypeFlags & CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED))
    {
        CRYPT_DATA_BLOB trimmed = { blob->cbData, blob->pbData };
        CRYPT_DATA_BLOB decoded;

        while (trimmed.cbData && !trimmed.pbData[trimmed.cbData - 1])
            trimmed.cbData--;
        ret = CryptStringToBinaryA((LPSTR)trimmed.pbData, trimmed.cbData,
         CRYPT_STRING_BASE64_ANY, NULL, &decoded.cbData, NULL, NULL);
        if (ret)
        {
            decoded.pbData = CryptMemAlloc(decoded.cbData);
            if (decoded.pbData)
            {
                ret = CryptStringToBinaryA((LPSTR)trimmed.pbData,
                 trimmed.cbData, CRYPT_STRING_BASE64_ANY, decoded.pbData,
                 &decoded.cbData, NULL, NULL);
                if (ret)
                {
                    /* Try it first as a signed message */
                    if (dwExpectedContentTypeFlags &
                     CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
                        ret = CRYPT_QuerySignedMessage(&decoded,
                         pdwMsgAndCertEncodingType, pdwContentType, &msg);
                    /* Failing that, try as an unsigned message */
                    if (!ret && (dwExpectedContentTypeFlags &
                     CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
                        ret = CRYPT_QueryUnsignedMessage(&decoded,
                         pdwMsgAndCertEncodingType, pdwContentType, &msg);
                    if (ret)
                        formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
                }
                CryptMemFree(decoded.pbData);
            }
            else
                ret = FALSE;
        }
        if (!ret && !(blob->cbData % sizeof(WCHAR)))
        {
            CRYPT_DATA_BLOB decoded;
            LPWSTR str = (LPWSTR)blob->pbData;
            DWORD strLen = blob->cbData / sizeof(WCHAR);

            /* Try again, assuming the input string is UTF-16 base64 */
            while (strLen && !str[strLen - 1])
                strLen--;
            ret = CryptStringToBinaryW(str, strLen, CRYPT_STRING_BASE64_ANY,
             NULL, &decoded.cbData, NULL, NULL);
            if (ret)
            {
                decoded.pbData = CryptMemAlloc(decoded.cbData);
                if (decoded.pbData)
                {
                    ret = CryptStringToBinaryW(str, strLen,
                     CRYPT_STRING_BASE64_ANY, decoded.pbData, &decoded.cbData,
                     NULL, NULL);
                    if (ret)
                    {
                        /* Try it first as a signed message */
                        if (dwExpectedContentTypeFlags &
                         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
                            ret = CRYPT_QuerySignedMessage(&decoded,
                             pdwMsgAndCertEncodingType, pdwContentType, &msg);
                        /* Failing that, try as an unsigned message */
                        if (!ret && (dwExpectedContentTypeFlags &
                         CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED))
                            ret = CRYPT_QueryUnsignedMessage(&decoded,
                             pdwMsgAndCertEncodingType, pdwContentType, &msg);
                        if (ret)
                            formatType = CERT_QUERY_FORMAT_BASE64_ENCODED;
                    }
                    CryptMemFree(decoded.pbData);
                }
                else
                    ret = FALSE;
            }
        }
    }
    if (ret)
    {
        if (pdwFormatType)
            *pdwFormatType = formatType;
        if (phCertStore)
            *phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0,
             0, msg);
        if (phMsg)
            *phMsg = msg;
        else
            CryptMsgClose(msg);
    }
    if (blob == &fileBlob)
        CryptMemFree(blob->pbData);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL CRYPT_QueryEmbeddedMessageObject(DWORD dwObjectType,
 const void *pvObject, DWORD dwExpectedContentTypeFlags,
 DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
 HCERTSTORE *phCertStore, HCRYPTMSG *phMsg)
{
    HANDLE file;
    GUID subject;
    BOOL ret = FALSE;

    TRACE("%s\n", debugstr_w(pvObject));

    if (dwObjectType != CERT_QUERY_OBJECT_FILE)
    {
        WARN("don't know what to do for type %d embedded signed messages\n",
         dwObjectType);
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    file = CreateFileW(pvObject, GENERIC_READ, FILE_SHARE_READ,
     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file != INVALID_HANDLE_VALUE)
    {
        ret = CryptSIPRetrieveSubjectGuid(pvObject, file, &subject);
        if (ret)
        {
            SIP_DISPATCH_INFO sip;

            memset(&sip, 0, sizeof(sip));
            sip.cbSize = sizeof(sip);
            ret = CryptSIPLoad(&subject, 0, &sip);
            if (ret)
            {
                SIP_SUBJECTINFO subjectInfo;
                CERT_BLOB blob;
                DWORD encodingType;

                memset(&subjectInfo, 0, sizeof(subjectInfo));
                subjectInfo.cbSize = sizeof(subjectInfo);
                subjectInfo.pgSubjectType = &subject;
                subjectInfo.hFile = file;
                subjectInfo.pwsFileName = pvObject;
                ret = sip.pfGet(&subjectInfo, &encodingType, 0, &blob.cbData,
                 NULL);
                if (ret)
                {
                    blob.pbData = CryptMemAlloc(blob.cbData);
                    if (blob.pbData)
                    {
                        ret = sip.pfGet(&subjectInfo, &encodingType, 0,
                         &blob.cbData, blob.pbData);
                        if (ret)
                        {
                            ret = CRYPT_QueryMessageObject(
                             CERT_QUERY_OBJECT_BLOB, &blob,
                             CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
                             CERT_QUERY_FORMAT_FLAG_BINARY,
                             pdwMsgAndCertEncodingType, NULL, NULL,
                             phCertStore, phMsg);
                            if (ret && pdwContentType)
                                *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED;
                        }
                        CryptMemFree(blob.pbData);
                    }
                    else
                    {
                        SetLastError(ERROR_OUTOFMEMORY);
                        ret = FALSE;
                    }
                }
            }
        }
        CloseHandle(file);
    }
    TRACE("returning %d\n", ret);
    return ret;
}

BOOL WINAPI CryptQueryObject(DWORD dwObjectType, const void *pvObject,
 DWORD dwExpectedContentTypeFlags, DWORD dwExpectedFormatTypeFlags,
 DWORD dwFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType,
 DWORD *pdwFormatType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg,
 const void **ppvContext)
{
    static const DWORD unimplementedTypes =
     CERT_QUERY_CONTENT_FLAG_PKCS10 | CERT_QUERY_CONTENT_FLAG_PFX |
     CERT_QUERY_CONTENT_FLAG_CERT_PAIR;
    BOOL ret = TRUE;

    TRACE("(%08x, %p, %08x, %08x, %08x, %p, %p, %p, %p, %p, %p)\n",
     dwObjectType, pvObject, dwExpectedContentTypeFlags,
     dwExpectedFormatTypeFlags, dwFlags, pdwMsgAndCertEncodingType,
     pdwContentType, pdwFormatType, phCertStore, phMsg, ppvContext);

    if (dwObjectType != CERT_QUERY_OBJECT_BLOB &&
     dwObjectType != CERT_QUERY_OBJECT_FILE)
    {
        WARN("unsupported type %d\n", dwObjectType);
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (!pvObject)
    {
        WARN("missing required argument\n");
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (dwExpectedContentTypeFlags & unimplementedTypes)
        WARN("unimplemented for types %08x\n",
         dwExpectedContentTypeFlags & unimplementedTypes);

    if (pdwFormatType)
        *pdwFormatType = CERT_QUERY_FORMAT_BINARY;
    if (phCertStore)
        *phCertStore = NULL;
    if (phMsg)
        *phMsg = NULL;
    if (ppvContext)
        *ppvContext = NULL;

    ret = FALSE;
    if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT) ||
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL) ||
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL))
    {
        ret = CRYPT_QueryContextObject(dwObjectType, pvObject,
         dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
         pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType, phCertStore,
         ppvContext);
    }
    if (!ret &&
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE))
    {
        ret = CRYPT_QuerySerializedStoreObject(dwObjectType, pvObject,
         pdwMsgAndCertEncodingType, pdwContentType, phCertStore, phMsg);
    }
    if (!ret &&
     ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT) ||
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL) ||
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL)))
    {
        ret = CRYPT_QuerySerializedContextObject(dwObjectType, pvObject,
         dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
         phCertStore, ppvContext);
    }
    if (!ret &&
     ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) ||
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)))
    {
        ret = CRYPT_QueryMessageObject(dwObjectType, pvObject,
         dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags,
         pdwMsgAndCertEncodingType, pdwContentType, pdwFormatType,
         phCertStore, phMsg);
    }
    if (!ret &&
     (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED))
    {
        ret = CRYPT_QueryEmbeddedMessageObject(dwObjectType, pvObject,
         dwExpectedContentTypeFlags, pdwMsgAndCertEncodingType, pdwContentType,
         phCertStore, phMsg);
    }
    if (!ret)
        SetLastError(CRYPT_E_NO_MATCH);
    TRACE("returning %d\n", ret);
    return ret;
}

static BOOL WINAPI CRYPT_FormatHexString(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    BOOL ret;
    DWORD bytesNeeded;

    if (cbEncoded)
        bytesNeeded = (cbEncoded * 3) * sizeof(WCHAR);
    else
        bytesNeeded = sizeof(WCHAR);
    if (!pbFormat)
    {
        *pcbFormat = bytesNeeded;
        ret = TRUE;
    }
    else if (*pcbFormat < bytesNeeded)
    {
        *pcbFormat = bytesNeeded;
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
    {
        static const WCHAR fmt[] = { '%','0','2','x',' ',0 };
        static const WCHAR endFmt[] = { '%','0','2','x',0 };
        DWORD i;
        LPWSTR ptr = pbFormat;

        *pcbFormat = bytesNeeded;
        if (cbEncoded)
        {
            for (i = 0; i < cbEncoded; i++)
            {
                if (i < cbEncoded - 1)
                    ptr += sprintfW(ptr, fmt, pbEncoded[i]);
                else
                    ptr += sprintfW(ptr, endFmt, pbEncoded[i]);
            }
        }
        else
            *ptr = 0;
        ret = TRUE;
    }
    return ret;
}

#define MAX_STRING_RESOURCE_LEN 128

static const WCHAR commaSpace[] = { ',',' ',0 };

struct BitToString
{
    BYTE bit;
    int id;
    WCHAR str[MAX_STRING_RESOURCE_LEN];
};

static BOOL CRYPT_FormatBits(BYTE bits, const struct BitToString *map,
 DWORD mapEntries, void *pbFormat, DWORD *pcbFormat, BOOL *first)
{
    DWORD bytesNeeded = sizeof(WCHAR);
    unsigned int i;
    BOOL ret = TRUE, localFirst = *first;

    for (i = 0; i < mapEntries; i++)
        if (bits & map[i].bit)
        {
            if (!localFirst)
                bytesNeeded += strlenW(commaSpace) * sizeof(WCHAR);
            localFirst = FALSE;
            bytesNeeded += strlenW(map[i].str) * sizeof(WCHAR);
        }
    if (!pbFormat)
    {
        *first = localFirst;
        *pcbFormat = bytesNeeded;
    }
    else if (*pcbFormat < bytesNeeded)
    {
        *first = localFirst;
        *pcbFormat = bytesNeeded;
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
    {
        LPWSTR str = pbFormat;

        localFirst = *first;
        *pcbFormat = bytesNeeded;
        for (i = 0; i < mapEntries; i++)
            if (bits & map[i].bit)
            {
                if (!localFirst)
                {
                    strcpyW(str, commaSpace);
                    str += strlenW(commaSpace);
                }
                localFirst = FALSE;
                strcpyW(str, map[i].str);
                str += strlenW(map[i].str);
            }
        *first = localFirst;
    }
    return ret;
}

static struct BitToString keyUsageByte0Map[] = {
 { CERT_DIGITAL_SIGNATURE_KEY_USAGE, IDS_DIGITAL_SIGNATURE, { 0 } },
 { CERT_NON_REPUDIATION_KEY_USAGE, IDS_NON_REPUDIATION, { 0 } },
 { CERT_KEY_ENCIPHERMENT_KEY_USAGE, IDS_KEY_ENCIPHERMENT, { 0 } },
 { CERT_DATA_ENCIPHERMENT_KEY_USAGE, IDS_DATA_ENCIPHERMENT, { 0 } },
 { CERT_KEY_AGREEMENT_KEY_USAGE, IDS_KEY_AGREEMENT, { 0 } },
 { CERT_KEY_CERT_SIGN_KEY_USAGE, IDS_CERT_SIGN, { 0 } },
 { CERT_OFFLINE_CRL_SIGN_KEY_USAGE, IDS_OFFLINE_CRL_SIGN, { 0 } },
 { CERT_CRL_SIGN_KEY_USAGE, IDS_CRL_SIGN, { 0 } },
 { CERT_ENCIPHER_ONLY_KEY_USAGE, IDS_ENCIPHER_ONLY, { 0 } },
};
static struct BitToString keyUsageByte1Map[] = {
 { CERT_DECIPHER_ONLY_KEY_USAGE, IDS_DECIPHER_ONLY, { 0 } },
};

static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    DWORD size;
    CRYPT_BIT_BLOB *bits;
    BOOL ret;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_KEY_USAGE,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &bits, &size)))
    {
        WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
        DWORD bytesNeeded = sizeof(WCHAR);

        LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
         sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
        if (!bits->cbData || bits->cbData > 2)
        {
            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                LPWSTR str = pbFormat;

                *pcbFormat = bytesNeeded;
                strcpyW(str, infoNotAvailable);
            }
        }
        else
        {
            static BOOL stringsLoaded = FALSE;
            unsigned int i;
            DWORD bitStringLen;
            BOOL first = TRUE;

            if (!stringsLoaded)
            {
                for (i = 0;
                 i < sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]);
                 i++)
                    LoadStringW(hInstance, keyUsageByte0Map[i].id,
                     keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
                for (i = 0;
                 i < sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]);
                 i++)
                    LoadStringW(hInstance, keyUsageByte1Map[i].id,
                     keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
                stringsLoaded = TRUE;
            }
            CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
             sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
             NULL, &bitStringLen, &first);
            bytesNeeded += bitStringLen;
            if (bits->cbData == 2)
            {
                CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
                 sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
                 NULL, &bitStringLen, &first);
                bytesNeeded += bitStringLen;
            }
            bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
            CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
             bits->cbData, NULL, &size);
            bytesNeeded += size;
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                LPWSTR str = pbFormat;

                bitStringLen = bytesNeeded;
                first = TRUE;
                CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
                 sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
                 str, &bitStringLen, &first);
                str += bitStringLen / sizeof(WCHAR) - 1;
                if (bits->cbData == 2)
                {
                    bitStringLen = bytesNeeded;
                    CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
                     sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
                     str, &bitStringLen, &first);
                    str += bitStringLen / sizeof(WCHAR) - 1;
                }
                *str++ = ' ';
                *str++ = '(';
                CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
                 bits->cbData, str, &size);
                str += size / sizeof(WCHAR) - 1;
                *str++ = ')';
                *str = 0;
            }
        }
        LocalFree(bits);
    }
    return ret;
}

static const WCHAR crlf[] = { '\r','\n',0 };

static WCHAR subjectTypeHeader[MAX_STRING_RESOURCE_LEN];
static WCHAR subjectTypeCA[MAX_STRING_RESOURCE_LEN];
static WCHAR subjectTypeEndCert[MAX_STRING_RESOURCE_LEN];
static WCHAR pathLengthHeader[MAX_STRING_RESOURCE_LEN];

static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    DWORD size;
    CERT_BASIC_CONSTRAINTS2_INFO *info;
    BOOL ret;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BASIC_CONSTRAINTS2,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
    {
        static const WCHAR pathFmt[] = { '%','d',0 };
        static BOOL stringsLoaded = FALSE;
        DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */
        WCHAR pathLength[MAX_STRING_RESOURCE_LEN];
        LPCWSTR sep, subjectType;
        DWORD sepLen;

        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            sep = crlf;
            sepLen = strlenW(crlf) * sizeof(WCHAR);
        }
        else
        {
            sep = commaSpace;
            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
        }

        if (!stringsLoaded)
        {
            LoadStringW(hInstance, IDS_SUBJECT_TYPE, subjectTypeHeader,
             sizeof(subjectTypeHeader) / sizeof(subjectTypeHeader[0]));
            LoadStringW(hInstance, IDS_SUBJECT_TYPE_CA, subjectTypeCA,
             sizeof(subjectTypeCA) / sizeof(subjectTypeCA[0]));
            LoadStringW(hInstance, IDS_SUBJECT_TYPE_END_CERT,
             subjectTypeEndCert,
             sizeof(subjectTypeEndCert) / sizeof(subjectTypeEndCert[0]));
            LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader,
             sizeof(pathLengthHeader) / sizeof(pathLengthHeader[0]));
            stringsLoaded = TRUE;
        }
        bytesNeeded += strlenW(subjectTypeHeader) * sizeof(WCHAR);
        if (info->fCA)
            subjectType = subjectTypeCA;
        else
            subjectType = subjectTypeEndCert;
        bytesNeeded += strlenW(subjectType) * sizeof(WCHAR);
        bytesNeeded += sepLen;
        bytesNeeded += strlenW(pathLengthHeader) * sizeof(WCHAR);
        if (info->fPathLenConstraint)
            sprintfW(pathLength, pathFmt, info->dwPathLenConstraint);
        else
            LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength,
             sizeof(pathLength) / sizeof(pathLength[0]));
        bytesNeeded += strlenW(pathLength) * sizeof(WCHAR);
        if (!pbFormat)
            *pcbFormat = bytesNeeded;
        else if (*pcbFormat < bytesNeeded)
        {
            *pcbFormat = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            LPWSTR str = pbFormat;

            *pcbFormat = bytesNeeded;
            strcpyW(str, subjectTypeHeader);
            str += strlenW(subjectTypeHeader);
            strcpyW(str, subjectType);
            str += strlenW(subjectType);
            strcpyW(str, sep);
            str += sepLen / sizeof(WCHAR);
            strcpyW(str, pathLengthHeader);
            str += strlenW(pathLengthHeader);
            strcpyW(str, pathLength);
        }
        LocalFree(info);
    }
    return ret;
}

static BOOL CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB *blob, int id,
 LPWSTR str, DWORD *pcbStr)
{
    WCHAR buf[MAX_STRING_RESOURCE_LEN];
    DWORD bytesNeeded;
    BOOL ret;

    LoadStringW(hInstance, id, buf, sizeof(buf) / sizeof(buf[0]));
    CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL,
     blob->pbData, blob->cbData, NULL, &bytesNeeded);
    bytesNeeded += strlenW(buf) * sizeof(WCHAR);
    if (!str)
    {
        *pcbStr = bytesNeeded;
        ret = TRUE;
    }
    else if (*pcbStr < bytesNeeded)
    {
        *pcbStr = bytesNeeded;
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
    {
        *pcbStr = bytesNeeded;
        strcpyW(str, buf);
        str += strlenW(str);
        bytesNeeded -= strlenW(str) * sizeof(WCHAR);
        ret = CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL,
         blob->pbData, blob->cbData, str, &bytesNeeded);
    }
    return ret;
}

static BOOL CRYPT_FormatKeyId(const CRYPT_DATA_BLOB *keyId, LPWSTR str,
 DWORD *pcbStr)
{
    return CRYPT_FormatHexStringWithPrefix(keyId, IDS_KEY_ID, str, pcbStr);
}

static BOOL CRYPT_FormatCertSerialNumber(const CRYPT_DATA_BLOB *serialNum, LPWSTR str,
 DWORD *pcbStr)
{
    return CRYPT_FormatHexStringWithPrefix(serialNum, IDS_CERT_SERIAL_NUMBER,
     str, pcbStr);
}

static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 };
static const WCHAR colonCrlf[] = { ':','\r','\n',0 };

static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
 const CERT_ALT_NAME_ENTRY *entry, LPWSTR str, DWORD *pcbStr)
{
    BOOL ret;
    WCHAR buf[MAX_STRING_RESOURCE_LEN];
    WCHAR mask[MAX_STRING_RESOURCE_LEN];
    WCHAR ipAddrBuf[32];
    WCHAR maskBuf[16];
    DWORD bytesNeeded = sizeof(WCHAR);
    DWORD strType = CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG;

    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        bytesNeeded += indentLevel * strlenW(indent) * sizeof(WCHAR);
    switch (entry->dwAltNameChoice)
    {
    case CERT_ALT_NAME_RFC822_NAME:
        LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf,
         sizeof(buf) / sizeof(buf[0]));
        bytesNeeded += strlenW(entry->u.pwszRfc822Name) * sizeof(WCHAR);
        ret = TRUE;
        break;
    case CERT_ALT_NAME_DNS_NAME:
        LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf,
         sizeof(buf) / sizeof(buf[0]));
        bytesNeeded += strlenW(entry->u.pwszDNSName) * sizeof(WCHAR);
        ret = TRUE;
        break;
    case CERT_ALT_NAME_DIRECTORY_NAME:
    {
        DWORD directoryNameLen;

        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            strType |= CERT_NAME_STR_CRLF_FLAG;
        directoryNameLen = cert_name_to_str_with_indent(X509_ASN_ENCODING,
         indentLevel + 1, &entry->u.DirectoryName, strType, NULL, 0);
        LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf,
         sizeof(buf) / sizeof(buf[0]));
        bytesNeeded += (directoryNameLen - 1) * sizeof(WCHAR);
        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            bytesNeeded += strlenW(colonCrlf) * sizeof(WCHAR);
        else
            bytesNeeded += sizeof(WCHAR); /* '=' */
        ret = TRUE;
        break;
    }
    case CERT_ALT_NAME_URL:
        LoadStringW(hInstance, IDS_ALT_NAME_URL, buf,
         sizeof(buf) / sizeof(buf[0]));
        bytesNeeded += strlenW(entry->u.pwszURL) * sizeof(WCHAR);
        ret = TRUE;
        break;
    case CERT_ALT_NAME_IP_ADDRESS:
    {
        static const WCHAR ipAddrWithMaskFmt[] = { '%','d','.','%','d','.',
         '%','d','.','%','d','/','%','d','.','%','d','.','%','d','.','%','d',0
        };
        static const WCHAR ipAddrFmt[] = { '%','d','.','%','d','.','%','d',
         '.','%','d',0 };

        LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf,
         sizeof(buf) / sizeof(buf[0]));
        if (entry->u.IPAddress.cbData == 8)
        {
            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask,
                 sizeof(mask) / sizeof(mask[0]));
                bytesNeeded += strlenW(mask) * sizeof(WCHAR);
                sprintfW(ipAddrBuf, ipAddrFmt,
                 entry->u.IPAddress.pbData[0],
                 entry->u.IPAddress.pbData[1],
                 entry->u.IPAddress.pbData[2],
                 entry->u.IPAddress.pbData[3]);
                bytesNeeded += strlenW(ipAddrBuf) * sizeof(WCHAR);
                /* indent again, for the mask line */
                bytesNeeded += indentLevel * strlenW(indent) * sizeof(WCHAR);
                sprintfW(maskBuf, ipAddrFmt,
                 entry->u.IPAddress.pbData[4],
                 entry->u.IPAddress.pbData[5],
                 entry->u.IPAddress.pbData[6],
                 entry->u.IPAddress.pbData[7]);
                bytesNeeded += strlenW(maskBuf) * sizeof(WCHAR);
                bytesNeeded += strlenW(crlf) * sizeof(WCHAR);
            }
            else
            {
                sprintfW(ipAddrBuf, ipAddrWithMaskFmt,
                 entry->u.IPAddress.pbData[0],
                 entry->u.IPAddress.pbData[1],
                 entry->u.IPAddress.pbData[2],
                 entry->u.IPAddress.pbData[3],
                 entry->u.IPAddress.pbData[4],
                 entry->u.IPAddress.pbData[5],
                 entry->u.IPAddress.pbData[6],
                 entry->u.IPAddress.pbData[7]);
                bytesNeeded += (strlenW(ipAddrBuf) + 1) * sizeof(WCHAR);
            }
            ret = TRUE;
        }
        else
        {
            FIXME("unknown IP address format (%d bytes)\n",
             entry->u.IPAddress.cbData);
            ret = FALSE;
        }
        break;
    }
    default:
        FIXME("unimplemented for %d\n", entry->dwAltNameChoice);
        ret = FALSE;
    }
    if (ret)
    {
        bytesNeeded += strlenW(buf) * sizeof(WCHAR);
        if (!str)
            *pcbStr = bytesNeeded;
        else if (*pcbStr < bytesNeeded)
        {
            *pcbStr = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            DWORD i;

            *pcbStr = bytesNeeded;
            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                for (i = 0; i < indentLevel; i++)
                {
                    strcpyW(str, indent);
                    str += strlenW(indent);
                }
            }
            strcpyW(str, buf);
            str += strlenW(str);
            switch (entry->dwAltNameChoice)
            {
            case CERT_ALT_NAME_RFC822_NAME:
            case CERT_ALT_NAME_DNS_NAME:
            case CERT_ALT_NAME_URL:
                strcpyW(str, entry->u.pwszURL);
                break;
            case CERT_ALT_NAME_DIRECTORY_NAME:
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                {
                    strcpyW(str, colonCrlf);
                    str += strlenW(colonCrlf);
                }
                else
                    *str++ = '=';
                cert_name_to_str_with_indent(X509_ASN_ENCODING,
                 indentLevel + 1, &entry->u.DirectoryName, strType, str,
                 bytesNeeded / sizeof(WCHAR));
                break;
            case CERT_ALT_NAME_IP_ADDRESS:
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                {
                    strcpyW(str, ipAddrBuf);
                    str += strlenW(ipAddrBuf);
                    strcpyW(str, crlf);
                    str += strlenW(crlf);
                    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                    {
                        for (i = 0; i < indentLevel; i++)
                        {
                            strcpyW(str, indent);
                            str += strlenW(indent);
                        }
                    }
                    strcpyW(str, mask);
                    str += strlenW(mask);
                    strcpyW(str, maskBuf);
                }
                else
                    strcpyW(str, ipAddrBuf);
                break;
            }
        }
    }
    return ret;
}

static BOOL CRYPT_FormatAltNameInfo(DWORD dwFormatStrType, DWORD indentLevel,
 const CERT_ALT_NAME_INFO *name, LPWSTR str, DWORD *pcbStr)
{
    DWORD i, size, bytesNeeded = 0;
    BOOL ret = TRUE;
    LPCWSTR sep;
    DWORD sepLen;

    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
    {
        sep = crlf;
        sepLen = strlenW(crlf) * sizeof(WCHAR);
    }
    else
    {
        sep = commaSpace;
        sepLen = strlenW(commaSpace) * sizeof(WCHAR);
    }

    for (i = 0; ret && i < name->cAltEntry; i++)
    {
        ret = CRYPT_FormatAltNameEntry(dwFormatStrType, indentLevel,
         &name->rgAltEntry[i], NULL, &size);
        if (ret)
        {
            bytesNeeded += size - sizeof(WCHAR);
            if (i < name->cAltEntry - 1)
                bytesNeeded += sepLen;
        }
    }
    if (ret)
    {
        bytesNeeded += sizeof(WCHAR);
        if (!str)
            *pcbStr = bytesNeeded;
        else if (*pcbStr < bytesNeeded)
        {
            *pcbStr = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            *pcbStr = bytesNeeded;
            for (i = 0; ret && i < name->cAltEntry; i++)
            {
                ret = CRYPT_FormatAltNameEntry(dwFormatStrType, indentLevel,
                 &name->rgAltEntry[i], str, &size);
                if (ret)
                {
                    str += size / sizeof(WCHAR) - 1;
                    if (i < name->cAltEntry - 1)
                    {
                        strcpyW(str, sep);
                        str += sepLen / sizeof(WCHAR);
                    }
                }
            }
        }
    }
    return ret;
}

static const WCHAR colonSep[] = { ':',' ',0 };

static BOOL WINAPI CRYPT_FormatAltName(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    BOOL ret;
    CERT_ALT_NAME_INFO *info;
    DWORD size;

    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_ALTERNATE_NAME,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
    {
        ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 0, info, pbFormat, pcbFormat);
        LocalFree(info);
    }
    return ret;
}

static BOOL CRYPT_FormatCertIssuer(DWORD dwFormatStrType,
 const CERT_ALT_NAME_INFO *issuer, LPWSTR str, DWORD *pcbStr)
{
    WCHAR buf[MAX_STRING_RESOURCE_LEN];
    DWORD bytesNeeded, sepLen;
    LPCWSTR sep;
    BOOL ret;

    LoadStringW(hInstance, IDS_CERT_ISSUER, buf, sizeof(buf) / sizeof(buf[0]));
    ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, NULL,
     &bytesNeeded);
    bytesNeeded += strlenW(buf) * sizeof(WCHAR);
    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
    {
        sep = colonCrlf;
        sepLen = strlenW(colonCrlf) * sizeof(WCHAR);
    }
    else
    {
        sep = colonSep;
        sepLen = strlenW(colonSep) * sizeof(WCHAR);
    }
    bytesNeeded += sepLen;
    if (ret)
    {
        if (!str)
            *pcbStr = bytesNeeded;
        else if (*pcbStr < bytesNeeded)
        {
            *pcbStr = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            *pcbStr = bytesNeeded;
            strcpyW(str, buf);
            bytesNeeded -= strlenW(str) * sizeof(WCHAR);
            str += strlenW(str);
            strcpyW(str, sep);
            str += sepLen / sizeof(WCHAR);
            ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, str,
             &bytesNeeded);
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_FormatAuthorityKeyId2(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    CERT_AUTHORITY_KEY_ID2_INFO *info;
    DWORD size;
    BOOL ret = FALSE;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_AUTHORITY_KEY_ID2,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
    {
        DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */
        LPCWSTR sep;
        DWORD sepLen;
        BOOL needSeparator = FALSE;

        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            sep = crlf;
            sepLen = strlenW(crlf) * sizeof(WCHAR);
        }
        else
        {
            sep = commaSpace;
            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
        }

        if (info->KeyId.cbData)
        {
            needSeparator = TRUE;
            ret = CRYPT_FormatKeyId(&info->KeyId, NULL, &size);
            if (ret)
            {
                /* don't include NULL-terminator more than once */
                bytesNeeded += size - sizeof(WCHAR);
            }
        }
        if (info->AuthorityCertIssuer.cAltEntry)
        {
            if (needSeparator)
                bytesNeeded += sepLen;
            needSeparator = TRUE;
            ret = CRYPT_FormatCertIssuer(dwFormatStrType,
             &info->AuthorityCertIssuer, NULL, &size);
            if (ret)
            {
                /* don't include NULL-terminator more than once */
                bytesNeeded += size - sizeof(WCHAR);
            }
        }
        if (info->AuthorityCertSerialNumber.cbData)
        {
            if (needSeparator)
                bytesNeeded += sepLen;
            ret = CRYPT_FormatCertSerialNumber(
             &info->AuthorityCertSerialNumber, NULL, &size);
            if (ret)
            {
                /* don't include NULL-terminator more than once */
                bytesNeeded += size - sizeof(WCHAR);
            }
        }
        if (ret)
        {
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                LPWSTR str = pbFormat;

                *pcbFormat = bytesNeeded;
                needSeparator = FALSE;
                if (info->KeyId.cbData)
                {
                    needSeparator = TRUE;
                    /* Overestimate size available, it's already been checked
                     * above.
                     */
                    size = bytesNeeded;
                    ret = CRYPT_FormatKeyId(&info->KeyId, str, &size);
                    if (ret)
                        str += size / sizeof(WCHAR) - 1;
                }
                if (info->AuthorityCertIssuer.cAltEntry)
                {
                    if (needSeparator)
                    {
                        strcpyW(str, sep);
                        str += sepLen / sizeof(WCHAR);
                    }
                    needSeparator = TRUE;
                    /* Overestimate size available, it's already been checked
                     * above.
                     */
                    size = bytesNeeded;
                    ret = CRYPT_FormatCertIssuer(dwFormatStrType,
                     &info->AuthorityCertIssuer, str, &size);
                    if (ret)
                        str += size / sizeof(WCHAR) - 1;
                }
                if (info->AuthorityCertSerialNumber.cbData)
                {
                    if (needSeparator)
                    {
                        strcpyW(str, sep);
                        str += sepLen / sizeof(WCHAR);
                    }
                    /* Overestimate size available, it's already been checked
                     * above.
                     */
                    size = bytesNeeded;
                    ret = CRYPT_FormatCertSerialNumber(
                     &info->AuthorityCertSerialNumber, str, &size);
                }
            }
        }
        LocalFree(info);
    }
    return ret;
}

static WCHAR aia[MAX_STRING_RESOURCE_LEN];
static WCHAR accessMethod[MAX_STRING_RESOURCE_LEN];
static WCHAR ocsp[MAX_STRING_RESOURCE_LEN];
static WCHAR caIssuers[MAX_STRING_RESOURCE_LEN];
static WCHAR unknown[MAX_STRING_RESOURCE_LEN];
static WCHAR accessLocation[MAX_STRING_RESOURCE_LEN];

static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    CERT_AUTHORITY_INFO_ACCESS *info;
    DWORD size;
    BOOL ret = FALSE;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType,
     X509_AUTHORITY_INFO_ACCESS, pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG,
     NULL, &info, &size)))
    {
        DWORD bytesNeeded = sizeof(WCHAR);

        if (!info->cAccDescr)
        {
            WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];

            LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
             sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                *pcbFormat = bytesNeeded;
                strcpyW(pbFormat, infoNotAvailable);
            }
        }
        else
        {
            static const WCHAR numFmt[] = { '%','d',0 };
            static const WCHAR equal[] = { '=',0 };
            static BOOL stringsLoaded = FALSE;
            DWORD i;
            LPCWSTR headingSep, accessMethodSep, locationSep;
            WCHAR accessDescrNum[11];

            if (!stringsLoaded)
            {
                LoadStringW(hInstance, IDS_AIA, aia,
                 sizeof(aia) / sizeof(aia[0]));
                LoadStringW(hInstance, IDS_ACCESS_METHOD, accessMethod,
                 sizeof(accessMethod) / sizeof(accessMethod[0]));
                LoadStringW(hInstance, IDS_ACCESS_METHOD_OCSP, ocsp,
                 sizeof(ocsp) / sizeof(ocsp[0]));
                LoadStringW(hInstance, IDS_ACCESS_METHOD_CA_ISSUERS, caIssuers,
                 sizeof(caIssuers) / sizeof(caIssuers[0]));
                LoadStringW(hInstance, IDS_ACCESS_METHOD_UNKNOWN, unknown,
                 sizeof(unknown) / sizeof(unknown[0]));
                LoadStringW(hInstance, IDS_ACCESS_LOCATION, accessLocation,
                 sizeof(accessLocation) / sizeof(accessLocation[0]));
                stringsLoaded = TRUE;
            }
            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
            {
                headingSep = crlf;
                accessMethodSep = crlf;
                locationSep = colonCrlf;
            }
            else
            {
                headingSep = colonSep;
                accessMethodSep = commaSpace;
                locationSep = equal;
            }

            for (i = 0; ret && i < info->cAccDescr; i++)
            {
                /* Heading */
                bytesNeeded += sizeof(WCHAR); /* left bracket */
                sprintfW(accessDescrNum, numFmt, i + 1);
                bytesNeeded += strlenW(accessDescrNum) * sizeof(WCHAR);
                bytesNeeded += sizeof(WCHAR); /* right bracket */
                bytesNeeded += strlenW(aia) * sizeof(WCHAR);
                bytesNeeded += strlenW(headingSep) * sizeof(WCHAR);
                /* Access method */
                bytesNeeded += strlenW(accessMethod) * sizeof(WCHAR);
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                    bytesNeeded += strlenW(indent) * sizeof(WCHAR);
                if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
                 szOID_PKIX_OCSP))
                    bytesNeeded += strlenW(ocsp) * sizeof(WCHAR);
                else if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
                 szOID_PKIX_CA_ISSUERS))
                    bytesNeeded += strlenW(caIssuers) * sizeof(caIssuers);
                else
                    bytesNeeded += strlenW(unknown) * sizeof(WCHAR);
                bytesNeeded += sizeof(WCHAR); /* space */
                bytesNeeded += sizeof(WCHAR); /* left paren */
                bytesNeeded += strlen(info->rgAccDescr[i].pszAccessMethod)
                 * sizeof(WCHAR);
                bytesNeeded += sizeof(WCHAR); /* right paren */
                /* Delimiter between access method and location */
                bytesNeeded += strlenW(accessMethodSep) * sizeof(WCHAR);
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                    bytesNeeded += strlenW(indent) * sizeof(WCHAR);
                bytesNeeded += strlenW(accessLocation) * sizeof(WCHAR);
                bytesNeeded += strlenW(locationSep) * sizeof(WCHAR);
                ret = CRYPT_FormatAltNameEntry(dwFormatStrType, 2,
                 &info->rgAccDescr[i].AccessLocation, NULL, &size);
                if (ret)
                    bytesNeeded += size - sizeof(WCHAR);
                /* Need extra delimiter between access method entries */
                if (i < info->cAccDescr - 1)
                    bytesNeeded += strlenW(accessMethodSep) * sizeof(WCHAR);
            }
            if (ret)
            {
                if (!pbFormat)
                    *pcbFormat = bytesNeeded;
                else if (*pcbFormat < bytesNeeded)
                {
                    *pcbFormat = bytesNeeded;
                    SetLastError(ERROR_MORE_DATA);
                    ret = FALSE;
                }
                else
                {
                    LPWSTR str = pbFormat;
                    DWORD altNameEntrySize;

                    *pcbFormat = bytesNeeded;
                    for (i = 0; ret && i < info->cAccDescr; i++)
                    {
                        LPCSTR oidPtr;

                        *str++ = '[';
                        sprintfW(accessDescrNum, numFmt, i + 1);
                        strcpyW(str, accessDescrNum);
                        str += strlenW(accessDescrNum);
                        *str++ = ']';
                        strcpyW(str, aia);
                        str += strlenW(aia);
                        strcpyW(str, headingSep);
                        str += strlenW(headingSep);
                        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                        {
                            strcpyW(str, indent);
                            str += strlenW(indent);
                        }
                        strcpyW(str, accessMethod);
                        str += strlenW(accessMethod);
                        if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
                         szOID_PKIX_OCSP))
                        {
                            strcpyW(str, ocsp);
                            str += strlenW(ocsp);
                        }
                        else if (!strcmp(info->rgAccDescr[i].pszAccessMethod,
                         szOID_PKIX_CA_ISSUERS))
                        {
                            strcpyW(str, caIssuers);
                            str += strlenW(caIssuers);
                        }
                        else
                        {
                            strcpyW(str, unknown);
                            str += strlenW(unknown);
                        }
                        *str++ = ' ';
                        *str++ = '(';
                        for (oidPtr = info->rgAccDescr[i].pszAccessMethod;
                         *oidPtr; oidPtr++, str++)
                            *str = *oidPtr;
                        *str++ = ')';
                        strcpyW(str, accessMethodSep);
                        str += strlenW(accessMethodSep);
                        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                        {
                            strcpyW(str, indent);
                            str += strlenW(indent);
                        }
                        strcpyW(str, accessLocation);
                        str += strlenW(accessLocation);
                        strcpyW(str, locationSep);
                        str += strlenW(locationSep);
                        /* This overestimates the size available, but that
                         * won't matter since we checked earlier whether enough
                         * space for the entire string was available.
                         */
                        altNameEntrySize = bytesNeeded;
                        ret = CRYPT_FormatAltNameEntry(dwFormatStrType, 2,
                         &info->rgAccDescr[i].AccessLocation, str,
                         &altNameEntrySize);
                        if (ret)
                            str += altNameEntrySize / sizeof(WCHAR) - 1;
                        if (i < info->cAccDescr - 1)
                        {
                            strcpyW(str, accessMethodSep);
                            str += strlenW(accessMethodSep);
                        }
                    }
                }
            }
        }
        LocalFree(info);
    }
    return ret;
}

static WCHAR keyCompromise[MAX_STRING_RESOURCE_LEN];
static WCHAR caCompromise[MAX_STRING_RESOURCE_LEN];
static WCHAR affiliationChanged[MAX_STRING_RESOURCE_LEN];
static WCHAR superseded[MAX_STRING_RESOURCE_LEN];
static WCHAR operationCeased[MAX_STRING_RESOURCE_LEN];
static WCHAR certificateHold[MAX_STRING_RESOURCE_LEN];

struct reason_map_entry
{
    BYTE   reasonBit;
    LPWSTR reason;
    int    id;
};
static struct reason_map_entry reason_map[] = {
 { CRL_REASON_KEY_COMPROMISE_FLAG, keyCompromise, IDS_REASON_KEY_COMPROMISE },
 { CRL_REASON_CA_COMPROMISE_FLAG, caCompromise, IDS_REASON_CA_COMPROMISE },
 { CRL_REASON_AFFILIATION_CHANGED_FLAG, affiliationChanged,
   IDS_REASON_AFFILIATION_CHANGED },
 { CRL_REASON_SUPERSEDED_FLAG, superseded, IDS_REASON_SUPERSEDED },
 { CRL_REASON_CESSATION_OF_OPERATION_FLAG, operationCeased,
   IDS_REASON_CESSATION_OF_OPERATION },
 { CRL_REASON_CERTIFICATE_HOLD_FLAG, certificateHold,
   IDS_REASON_CERTIFICATE_HOLD },
};

static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
 const CRYPT_BIT_BLOB *reasonFlags, LPWSTR str, DWORD *pcbStr)
{
    static const WCHAR sep[] = { ',',' ',0 };
    static const WCHAR bitsFmt[] = { ' ','(','%','0','2','x',')',0 };
    static BOOL stringsLoaded = FALSE;
    unsigned int i, numReasons = 0;
    BOOL ret = TRUE;
    DWORD bytesNeeded = sizeof(WCHAR);
    WCHAR bits[6];

    if (!stringsLoaded)
    {
        for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
            LoadStringW(hInstance, reason_map[i].id, reason_map[i].reason,
             MAX_STRING_RESOURCE_LEN);
        stringsLoaded = TRUE;
    }
    /* No need to check reasonFlags->cbData, we already know it's positive.
     * Ignore any other bytes, as they're for undefined bits.
     */
    for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
    {
        if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
        {
            bytesNeeded += strlenW(reason_map[i].reason) * sizeof(WCHAR);
            if (numReasons++)
                bytesNeeded += strlenW(sep) * sizeof(WCHAR);
        }
    }
    sprintfW(bits, bitsFmt, reasonFlags->pbData[0]);
    bytesNeeded += strlenW(bits);
    if (!str)
        *pcbStr = bytesNeeded;
    else if (*pcbStr < bytesNeeded)
    {
        *pcbStr = bytesNeeded;
        SetLastError(ERROR_MORE_DATA);
        ret = FALSE;
    }
    else
    {
        *pcbStr = bytesNeeded;
        for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
        {
            if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
            {
                strcpyW(str, reason_map[i].reason);
                str += strlenW(reason_map[i].reason);
                if (i < sizeof(reason_map) / sizeof(reason_map[0]) - 1 &&
                 numReasons)
                {
                    strcpyW(str, sep);
                    str += strlenW(sep);
                }
            }
        }
        strcpyW(str, bits);
    }
    return ret;
}

static WCHAR crlDistPoint[MAX_STRING_RESOURCE_LEN];
static WCHAR distPointName[MAX_STRING_RESOURCE_LEN];
static WCHAR fullName[MAX_STRING_RESOURCE_LEN];
static WCHAR rdnName[MAX_STRING_RESOURCE_LEN];
static WCHAR reason[MAX_STRING_RESOURCE_LEN];
static WCHAR issuer[MAX_STRING_RESOURCE_LEN];

static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    CRL_DIST_POINTS_INFO *info;
    DWORD size;
    BOOL ret = FALSE;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CRL_DIST_POINTS,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size)))
    {
        static const WCHAR numFmt[] = { '%','d',0 };
        static const WCHAR colon[] = { ':',0 };
        static BOOL stringsLoaded = FALSE;
        DWORD bytesNeeded = sizeof(WCHAR); /* space for NULL terminator */
        BOOL haveAnEntry = FALSE;
        LPCWSTR headingSep, nameSep;
        WCHAR distPointNum[11];
        DWORD i;

        if (!stringsLoaded)
        {
            LoadStringW(hInstance, IDS_CRL_DIST_POINT, crlDistPoint,
             sizeof(crlDistPoint) / sizeof(crlDistPoint[0]));
            LoadStringW(hInstance, IDS_CRL_DIST_POINT_NAME, distPointName,
             sizeof(distPointName) / sizeof(distPointName[0]));
            LoadStringW(hInstance, IDS_CRL_DIST_POINT_FULL_NAME, fullName,
             sizeof(fullName) / sizeof(fullName[0]));
            LoadStringW(hInstance, IDS_CRL_DIST_POINT_RDN_NAME, rdnName,
             sizeof(rdnName) / sizeof(rdnName[0]));
            LoadStringW(hInstance, IDS_CRL_DIST_POINT_REASON, reason,
             sizeof(reason) / sizeof(reason[0]));
            LoadStringW(hInstance, IDS_CRL_DIST_POINT_ISSUER, issuer,
             sizeof(issuer) / sizeof(issuer[0]));
            stringsLoaded = TRUE;
        }
        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            headingSep = crlf;
            nameSep = colonCrlf;
        }
        else
        {
            headingSep = colonSep;
            nameSep = colon;
        }

        for (i = 0; ret && i < info->cDistPoint; i++)
        {
            CRL_DIST_POINT *distPoint = &info->rgDistPoint[i];

            if (distPoint->DistPointName.dwDistPointNameChoice !=
             CRL_DIST_POINT_NO_NAME)
            {
                bytesNeeded += strlenW(distPointName) * sizeof(WCHAR);
                bytesNeeded += strlenW(nameSep) * sizeof(WCHAR);
                if (distPoint->DistPointName.dwDistPointNameChoice ==
                 CRL_DIST_POINT_FULL_NAME)
                    bytesNeeded += strlenW(fullName) * sizeof(WCHAR);
                else
                    bytesNeeded += strlenW(rdnName) * sizeof(WCHAR);
                bytesNeeded += strlenW(nameSep) * sizeof(WCHAR);
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                    bytesNeeded += 2 * strlenW(indent) * sizeof(WCHAR);
                /* The indent level (3) is higher than when used as the issuer,
                 * because the name is subordinate to the name type (full vs.
                 * RDN.)
                 */
                ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 3,
                 &distPoint->DistPointName.u.FullName, NULL, &size);
                if (ret)
                    bytesNeeded += size - sizeof(WCHAR);
                haveAnEntry = TRUE;
            }
            else if (distPoint->ReasonFlags.cbData)
            {
                bytesNeeded += strlenW(reason) * sizeof(WCHAR);
                ret = CRYPT_FormatReason(dwFormatStrType,
                 &distPoint->ReasonFlags, NULL, &size);
                if (ret)
                    bytesNeeded += size - sizeof(WCHAR);
                haveAnEntry = TRUE;
            }
            else if (distPoint->CRLIssuer.cAltEntry)
            {
                bytesNeeded += strlenW(issuer) * sizeof(WCHAR);
                bytesNeeded += strlenW(nameSep) * sizeof(WCHAR);
                ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 2,
                 &distPoint->CRLIssuer, NULL, &size);
                if (ret)
                    bytesNeeded += size - sizeof(WCHAR);
                haveAnEntry = TRUE;
            }
            if (haveAnEntry)
            {
                bytesNeeded += sizeof(WCHAR); /* left bracket */
                sprintfW(distPointNum, numFmt, i + 1);
                bytesNeeded += strlenW(distPointNum) * sizeof(WCHAR);
                bytesNeeded += sizeof(WCHAR); /* right bracket */
                bytesNeeded += strlenW(crlDistPoint) * sizeof(WCHAR);
                bytesNeeded += strlenW(headingSep) * sizeof(WCHAR);
                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                    bytesNeeded += strlenW(indent) * sizeof(WCHAR);
            }
        }
        if (!haveAnEntry)
        {
            WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];

            LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
             sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                *pcbFormat = bytesNeeded;
                strcpyW(pbFormat, infoNotAvailable);
            }
        }
        else
        {
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                LPWSTR str = pbFormat;

                *pcbFormat = bytesNeeded;
                for (i = 0; ret && i < info->cDistPoint; i++)
                {
                    CRL_DIST_POINT *distPoint = &info->rgDistPoint[i];

                    *str++ = '[';
                    sprintfW(distPointNum, numFmt, i + 1);
                    strcpyW(str, distPointNum);
                    str += strlenW(distPointNum);
                    *str++ = ']';
                    strcpyW(str, crlDistPoint);
                    str += strlenW(crlDistPoint);
                    strcpyW(str, headingSep);
                    str += strlenW(headingSep);
                    if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                    {
                        strcpyW(str, indent);
                        str += strlenW(indent);
                    }
                    if (distPoint->DistPointName.dwDistPointNameChoice !=
                     CRL_DIST_POINT_NO_NAME)
                    {
                        DWORD altNameSize = bytesNeeded;

                        strcpyW(str, distPointName);
                        str += strlenW(distPointName);
                        strcpyW(str, nameSep);
                        str += strlenW(nameSep);
                        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
                        {
                            strcpyW(str, indent);
                            str += strlenW(indent);
                            strcpyW(str, indent);
                            str += strlenW(indent);
                        }
                        if (distPoint->DistPointName.dwDistPointNameChoice ==
                         CRL_DIST_POINT_FULL_NAME)
                        {
                            strcpyW(str, fullName);
                            str += strlenW(fullName);
                        }
                        else
                        {
                            strcpyW(str, rdnName);
                            str += strlenW(rdnName);
                        }
                        strcpyW(str, nameSep);
                        str += strlenW(nameSep);
                        ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 3,
                         &distPoint->DistPointName.u.FullName, str,
                         &altNameSize);
                        if (ret)
                            str += altNameSize / sizeof(WCHAR) - 1;
                    }
                    else if (distPoint->ReasonFlags.cbData)
                    {
                        DWORD reasonSize = bytesNeeded;

                        strcpyW(str, reason);
                        str += strlenW(reason);
                        ret = CRYPT_FormatReason(dwFormatStrType,
                         &distPoint->ReasonFlags, str, &reasonSize);
                        if (ret)
                            str += reasonSize / sizeof(WCHAR) - 1;
                    }
                    else if (distPoint->CRLIssuer.cAltEntry)
                    {
                        DWORD crlIssuerSize = bytesNeeded;

                        strcpyW(str, issuer);
                        str += strlenW(issuer);
                        strcpyW(str, nameSep);
                        str += strlenW(nameSep);
                        ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 2,
                         &distPoint->CRLIssuer, str,
                         &crlIssuerSize);
                        if (ret)
                            str += crlIssuerSize / sizeof(WCHAR) - 1;
                    }
                }
            }
        }
        LocalFree(info);
    }
    return ret;
}

static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    CERT_ENHKEY_USAGE *usage;
    DWORD size;
    BOOL ret = FALSE;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_ENHANCED_KEY_USAGE,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &usage, &size)))
    {
        WCHAR unknown[MAX_STRING_RESOURCE_LEN];
        DWORD i;
        DWORD bytesNeeded = sizeof(WCHAR); /* space for the NULL terminator */
        LPCWSTR sep;
        DWORD sepLen;

        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            sep = crlf;
            sepLen = strlenW(crlf) * sizeof(WCHAR);
        }
        else
        {
            sep = commaSpace;
            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
        }

        LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown,
         sizeof(unknown) / sizeof(unknown[0]));
        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)
                bytesNeeded += strlenW(info->pwszName) * sizeof(WCHAR);
            else
                bytesNeeded += strlenW(unknown) * sizeof(WCHAR);
            bytesNeeded += sizeof(WCHAR); /* space */
            bytesNeeded += sizeof(WCHAR); /* left paren */
            bytesNeeded += strlen(usage->rgpszUsageIdentifier[i]) *
             sizeof(WCHAR);
            bytesNeeded += sizeof(WCHAR); /* right paren */
            if (i < usage->cUsageIdentifier - 1)
                bytesNeeded += sepLen;
        }
        if (!pbFormat)
            *pcbFormat = bytesNeeded;
        else if (*pcbFormat < bytesNeeded)
        {
            *pcbFormat = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            LPWSTR str = pbFormat;

            *pcbFormat = bytesNeeded;
            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);
                LPCSTR oidPtr;

                if (info)
                {
                    strcpyW(str, info->pwszName);
                    str += strlenW(info->pwszName);
                }
                else
                {
                    strcpyW(str, unknown);
                    str += strlenW(unknown);
                }
                *str++ = ' ';
                *str++ = '(';
                for (oidPtr = usage->rgpszUsageIdentifier[i]; *oidPtr; oidPtr++)
                    *str++ = *oidPtr;
                *str++ = ')';
                *str = 0;
                if (i < usage->cUsageIdentifier - 1)
                {
                    strcpyW(str, sep);
                    str += sepLen / sizeof(WCHAR);
                }
            }
        }
        LocalFree(usage);
    }
    return ret;
}

static struct BitToString netscapeCertTypeMap[] = {
 { NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_CLIENT, { 0 } },
 { NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE, IDS_NETSCAPE_SSL_SERVER, { 0 } },
 { NETSCAPE_SMIME_CERT_TYPE, IDS_NETSCAPE_SMIME, { 0 } },
 { NETSCAPE_SIGN_CERT_TYPE, IDS_NETSCAPE_SIGN, { 0 } },
 { NETSCAPE_SSL_CA_CERT_TYPE, IDS_NETSCAPE_SSL_CA, { 0 } },
 { NETSCAPE_SMIME_CA_CERT_TYPE, IDS_NETSCAPE_SMIME_CA, { 0 } },
 { NETSCAPE_SIGN_CA_CERT_TYPE, IDS_NETSCAPE_SIGN_CA, { 0 } },
};

static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    DWORD size;
    CRYPT_BIT_BLOB *bits;
    BOOL ret;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_BITS,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &bits, &size)))
    {
        WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
        DWORD bytesNeeded = sizeof(WCHAR);

        LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
         sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
        if (!bits->cbData || bits->cbData > 1)
        {
            bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                LPWSTR str = pbFormat;

                *pcbFormat = bytesNeeded;
                strcpyW(str, infoNotAvailable);
            }
        }
        else
        {
            static BOOL stringsLoaded = FALSE;
            unsigned int i;
            DWORD bitStringLen;
            BOOL first = TRUE;

            if (!stringsLoaded)
            {
                for (i = 0; i < sizeof(netscapeCertTypeMap) /
                 sizeof(netscapeCertTypeMap[0]); i++)
                    LoadStringW(hInstance, netscapeCertTypeMap[i].id,
                     netscapeCertTypeMap[i].str, MAX_STRING_RESOURCE_LEN);
                stringsLoaded = TRUE;
            }
            CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
             sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
             NULL, &bitStringLen, &first);
            bytesNeeded += bitStringLen;
            bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
            CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
             bits->cbData, NULL, &size);
            bytesNeeded += size;
            if (!pbFormat)
                *pcbFormat = bytesNeeded;
            else if (*pcbFormat < bytesNeeded)
            {
                *pcbFormat = bytesNeeded;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                LPWSTR str = pbFormat;

                bitStringLen = bytesNeeded;
                first = TRUE;
                CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
                 sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
                 str, &bitStringLen, &first);
                str += bitStringLen / sizeof(WCHAR) - 1;
                *str++ = ' ';
                *str++ = '(';
                CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
                 bits->cbData, str, &size);
                str += size / sizeof(WCHAR) - 1;
                *str++ = ')';
                *str = 0;
            }
        }
        LocalFree(bits);
    }
    return ret;
}

static WCHAR financialCriteria[MAX_STRING_RESOURCE_LEN];
static WCHAR available[MAX_STRING_RESOURCE_LEN];
static WCHAR notAvailable[MAX_STRING_RESOURCE_LEN];
static WCHAR meetsCriteria[MAX_STRING_RESOURCE_LEN];
static WCHAR yes[MAX_STRING_RESOURCE_LEN];
static WCHAR no[MAX_STRING_RESOURCE_LEN];

static BOOL WINAPI CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    SPC_FINANCIAL_CRITERIA criteria;
    DWORD size = sizeof(criteria);
    BOOL ret = FALSE;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType,
     SPC_FINANCIAL_CRITERIA_STRUCT, pbEncoded, cbEncoded, 0, NULL, &criteria,
     &size)))
    {
        static BOOL stringsLoaded = FALSE;
        DWORD bytesNeeded = sizeof(WCHAR);
        LPCWSTR sep;
        DWORD sepLen;

        if (!stringsLoaded)
        {
            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA, financialCriteria,
             sizeof(financialCriteria) / sizeof(financialCriteria[0]));
            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_AVAILABLE, available,
             sizeof(available) / sizeof(available[0]));
            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE,
             notAvailable, sizeof(notAvailable) / sizeof(notAvailable[0]));
            LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA,
             meetsCriteria, sizeof(meetsCriteria) / sizeof(meetsCriteria[0]));
            LoadStringW(hInstance, IDS_YES, yes, sizeof(yes) / sizeof(yes[0]));
            LoadStringW(hInstance, IDS_NO, no, sizeof(no) / sizeof(no[0]));
            stringsLoaded = TRUE;
        }
        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
        {
            sep = crlf;
            sepLen = strlenW(crlf) * sizeof(WCHAR);
        }
        else
        {
            sep = commaSpace;
            sepLen = strlenW(commaSpace) * sizeof(WCHAR);
        }
        bytesNeeded += strlenW(financialCriteria) * sizeof(WCHAR);
        if (criteria.fFinancialInfoAvailable)
        {
            bytesNeeded += strlenW(available) * sizeof(WCHAR);
            bytesNeeded += sepLen;
            bytesNeeded += strlenW(meetsCriteria) * sizeof(WCHAR);
            if (criteria.fMeetsCriteria)
                bytesNeeded += strlenW(yes) * sizeof(WCHAR);
            else
                bytesNeeded += strlenW(no) * sizeof(WCHAR);
        }
        else
            bytesNeeded += strlenW(notAvailable) * sizeof(WCHAR);
        if (!pbFormat)
            *pcbFormat = bytesNeeded;
        else if (*pcbFormat < bytesNeeded)
        {
            *pcbFormat = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            LPWSTR str = pbFormat;

            *pcbFormat = bytesNeeded;
            strcpyW(str, financialCriteria);
            str += strlenW(financialCriteria);
            if (criteria.fFinancialInfoAvailable)
            {
                strcpyW(str, available);
                str += strlenW(available);
                strcpyW(str, sep);
                str += sepLen / sizeof(WCHAR);
                strcpyW(str, meetsCriteria);
                str += strlenW(meetsCriteria);
                if (criteria.fMeetsCriteria)
                    strcpyW(str, yes);
                else
                    strcpyW(str, no);
            }
            else
            {
                strcpyW(str, notAvailable);
            }
        }
    }
    return ret;
}

static BOOL WINAPI CRYPT_FormatUnicodeString(DWORD dwCertEncodingType,
 DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
 LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
 DWORD *pcbFormat)
{
    CERT_NAME_VALUE *value;
    DWORD size;
    BOOL ret;

    if (!cbEncoded)
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_UNICODE_ANY_STRING,
     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &value, &size)))
    {
        if (!pbFormat)
            *pcbFormat = value->Value.cbData;
        else if (*pcbFormat < value->Value.cbData)
        {
            *pcbFormat = value->Value.cbData;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            LPWSTR str = pbFormat;

            *pcbFormat = value->Value.cbData;
            strcpyW(str, (LPWSTR)value->Value.pbData);
        }
    }
    return ret;
}

typedef BOOL (WINAPI *CryptFormatObjectFunc)(DWORD, DWORD, DWORD, void *,
 LPCSTR, const BYTE *, DWORD, void *, DWORD *);

static CryptFormatObjectFunc CRYPT_GetBuiltinFormatFunction(DWORD encodingType,
 DWORD formatStrType, LPCSTR lpszStructType)
{
    CryptFormatObjectFunc format = NULL;

    if ((encodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return NULL;
    }
    if (IS_INTOID(lpszStructType))
    {
        switch (LOWORD(lpszStructType))
        {
        case LOWORD(X509_KEY_USAGE):
            format = CRYPT_FormatKeyUsage;
            break;
        case LOWORD(X509_ALTERNATE_NAME):
            format = CRYPT_FormatAltName;
            break;
        case LOWORD(X509_BASIC_CONSTRAINTS2):
            format = CRYPT_FormatBasicConstraints2;
            break;
        case LOWORD(X509_AUTHORITY_KEY_ID2):
            format = CRYPT_FormatAuthorityKeyId2;
            break;
        case LOWORD(X509_AUTHORITY_INFO_ACCESS):
            format = CRYPT_FormatAuthorityInfoAccess;
            break;
        case LOWORD(X509_CRL_DIST_POINTS):
            format = CRYPT_FormatCRLDistPoints;
            break;
        case LOWORD(X509_ENHANCED_KEY_USAGE):
            format = CRYPT_FormatEnhancedKeyUsage;
            break;
        case LOWORD(SPC_FINANCIAL_CRITERIA_STRUCT):
            format = CRYPT_FormatSpcFinancialCriteria;
            break;
        }
    }
    else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME))
        format = CRYPT_FormatAltName;
    else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME))
        format = CRYPT_FormatAltName;
    else if (!strcmp(lpszStructType, szOID_KEY_USAGE))
        format = CRYPT_FormatKeyUsage;
    else if (!strcmp(lpszStructType, szOID_SUBJECT_ALT_NAME2))
        format = CRYPT_FormatAltName;
    else if (!strcmp(lpszStructType, szOID_ISSUER_ALT_NAME2))
        format = CRYPT_FormatAltName;
    else if (!strcmp(lpszStructType, szOID_BASIC_CONSTRAINTS2))
        format = CRYPT_FormatBasicConstraints2;
    else if (!strcmp(lpszStructType, szOID_AUTHORITY_INFO_ACCESS))
        format = CRYPT_FormatAuthorityInfoAccess;
    else if (!strcmp(lpszStructType, szOID_AUTHORITY_KEY_IDENTIFIER2))
        format = CRYPT_FormatAuthorityKeyId2;
    else if (!strcmp(lpszStructType, szOID_CRL_DIST_POINTS))
        format = CRYPT_FormatCRLDistPoints;
    else if (!strcmp(lpszStructType, szOID_ENHANCED_KEY_USAGE))
        format = CRYPT_FormatEnhancedKeyUsage;
    else if (!strcmp(lpszStructType, szOID_NETSCAPE_CERT_TYPE))
        format = CRYPT_FormatNetscapeCertType;
    else if (!strcmp(lpszStructType, szOID_NETSCAPE_BASE_URL) ||
     !strcmp(lpszStructType, szOID_NETSCAPE_REVOCATION_URL) ||
     !strcmp(lpszStructType, szOID_NETSCAPE_CA_REVOCATION_URL) ||
     !strcmp(lpszStructType, szOID_NETSCAPE_CERT_RENEWAL_URL) ||
     !strcmp(lpszStructType, szOID_NETSCAPE_CA_POLICY_URL) ||
     !strcmp(lpszStructType, szOID_NETSCAPE_SSL_SERVER_NAME) ||
     !strcmp(lpszStructType, szOID_NETSCAPE_COMMENT))
        format = CRYPT_FormatUnicodeString;
    else if (!strcmp(lpszStructType, SPC_FINANCIAL_CRITERIA_OBJID))
        format = CRYPT_FormatSpcFinancialCriteria;
    return format;
}

BOOL WINAPI CryptFormatObject(DWORD dwCertEncodingType, DWORD dwFormatType,
 DWORD dwFormatStrType, void *pFormatStruct, LPCSTR lpszStructType,
 const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat, DWORD *pcbFormat)
{
    CryptFormatObjectFunc format = NULL;
    HCRYPTOIDFUNCADDR hFunc = NULL;
    BOOL ret = FALSE;

    TRACE("(%08x, %d, %08x, %p, %s, %p, %d, %p, %p)\n", dwCertEncodingType,
     dwFormatType, dwFormatStrType, pFormatStruct, debugstr_a(lpszStructType),
     pbEncoded, cbEncoded, pbFormat, pcbFormat);

    if (!(format = CRYPT_GetBuiltinFormatFunction(dwCertEncodingType,
     dwFormatStrType, lpszStructType)))
    {
        static HCRYPTOIDFUNCSET set = NULL;

        if (!set)
            set = CryptInitOIDFunctionSet(CRYPT_OID_FORMAT_OBJECT_FUNC, 0);
        CryptGetOIDFunctionAddress(set, dwCertEncodingType, lpszStructType, 0,
         (void **)&format, &hFunc);
    }
    if (!format && (dwCertEncodingType & CERT_ENCODING_TYPE_MASK) ==
     X509_ASN_ENCODING && !(dwFormatStrType & CRYPT_FORMAT_STR_NO_HEX))
        format = CRYPT_FormatHexString;
    if (format)
        ret = format(dwCertEncodingType, dwFormatType, dwFormatStrType,
         pFormatStruct, lpszStructType, pbEncoded, cbEncoded, pbFormat,
         pcbFormat);
    if (hFunc)
        CryptFreeOIDFunctionAddress(hFunc, 0);
    return ret;
}
