[ros-diffs] [cwittich] 39044: add cryptdlg from wine 1.1.13

cwittich at svn.reactos.org cwittich at svn.reactos.org
Fri Jan 23 14:06:34 CET 2009


Author: cwittich
Date: Fri Jan 23 07:06:33 2009
New Revision: 39044

URL: http://svn.reactos.org/svn/reactos?rev=39044&view=rev
Log:
add cryptdlg from wine 1.1.13

Added:
    trunk/reactos/dll/win32/cryptdlg/   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptdlg.rbuild   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptdlg.rc   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptdlg.spec   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptdlg_En.rc   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptdlg_Fr.rc   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptdlg_Ko.rc   (with props)
    trunk/reactos/dll/win32/cryptdlg/cryptres.h   (with props)
    trunk/reactos/dll/win32/cryptdlg/main.c   (with props)
Modified:
    trunk/reactos/baseaddress.rbuild
    trunk/reactos/boot/bootdata/packages/reactos.dff
    trunk/reactos/dll/win32/win32.rbuild

Modified: trunk/reactos/baseaddress.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/baseaddress.rbuild?rev=39044&r1=39043&r2=39044&view=diff
==============================================================================
--- trunk/reactos/baseaddress.rbuild [iso-8859-1] (original)
+++ trunk/reactos/baseaddress.rbuild [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -3,6 +3,7 @@
 <group xmlns:xi="http://www.w3.org/2001/XInclude">
   <property name="BASEADDRESS_REGTESTS" value="0x07000000" />
   <property name="BASEADDRESS_NOTIFYHOOK" value="0x08000000" />
+  <property name="BASEADDRESS_CRYPTDLG" value="0x209C0000" />
   <property name="BASEADDRESS_COMCAT" value="0x20A50000" />
   <property name="BASEADDRESS_DEVENUM" value="0x35680000" />
   <property name="BASEADDRESS_RSABASE" value="0x35700000" />

Modified: trunk/reactos/boot/bootdata/packages/reactos.dff
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/packages/reactos.dff?rev=39044&r1=39043&r2=39044&view=diff
==============================================================================
--- trunk/reactos/boot/bootdata/packages/reactos.dff [iso-8859-1] (original)
+++ trunk/reactos/boot/bootdata/packages/reactos.dff [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -248,6 +248,7 @@
 dll\win32\credui\credui.dll                         1
 dll\win32\crtdll\crtdll.dll                         1
 dll\win32\crypt32\crypt32.dll                       1
+dll\win32\cryptdlg\cryptdlg.dll                     1
 dll\win32\cryptdll\cryptdll.dll                     1
 dll\win32\cryptnet\cryptnet.dll                     1
 dll\win32\cryptui\cryptui.dll                       1

Propchange: trunk/reactos/dll/win32/cryptdlg/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Fri Jan 23 07:06:33 2009
@@ -1,0 +1,2 @@
+([Ii]ssue|[Bb]ug)s? #?(\d+)(,? ?#?(\d+))*(,? ?(and |or )?#?(\d+))?
+(\d+)

Propchange: trunk/reactos/dll/win32/cryptdlg/
------------------------------------------------------------------------------
    bugtraq:message = See issue #%BUGID% for more details.

Propchange: trunk/reactos/dll/win32/cryptdlg/
------------------------------------------------------------------------------
    bugtraq:url = http://www.reactos.org/bugzilla/show_bug.cgi?id=%BUGID%

Propchange: trunk/reactos/dll/win32/cryptdlg/
------------------------------------------------------------------------------
    tsvn:logminsize = 10

Added: trunk/reactos/dll/win32/cryptdlg/cryptdlg.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptdlg.rbuild?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptdlg.rbuild (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptdlg.rbuild [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,19 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="cryptdlg" type="win32dll" baseaddress="${BASEADDRESS_CRYPTDLG}" installbase="system32" installname="cryptdlg.dll" allowwarnings="true">
+	<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
+	<importlibrary definition="cryptdlg.spec" />
+	<include base="cryptdlg">.</include>
+	<include base="ReactOS">include/reactos/wine</include>
+	<define name="__WINESRC__" />
+	<library>wine</library>
+	<library>advapi32</library>
+	<library>kernel32</library>
+	<library>user32</library>
+	<library>crypt32</library>
+	<library>cryptui</library>
+	<library>wintrust</library>
+	<library>ntdll</library>
+	<file>main.c</file>
+	<file>cryptdlg.rc</file>
+</module>

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptdlg.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/cryptdlg.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptdlg.rc?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptdlg.rc (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptdlg.rc [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,27 @@
+/*
+ * cryptdlg dll resources
+ *
+ * Copyright 2008 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "cryptres.h"
+
+#include "cryptdlg_En.rc"
+#include "cryptdlg_Fr.rc"
+#include "cryptdlg_Ko.rc"

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptdlg.rc
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/cryptdlg.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptdlg.spec?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptdlg.spec (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptdlg.spec [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,21 @@
+1 stub CertConfigureTrustA
+2 stub CertConfigureTrustW
+3 stdcall CertTrustCertPolicy(ptr long long long)
+4 stdcall CertTrustCleanup(ptr)
+5 stdcall CertTrustFinalPolicy(ptr)
+6 stdcall CertTrustInit(ptr)
+7 stub DecodeAttrSequence
+8 stub DecodeRecipientID
+9 stub EncodeAttrSequence
+10 stub EncodeRecipientID
+11 stub FormatPKIXEmailProtection
+12 stdcall FormatVerisignExtension(long long long ptr str ptr long ptr ptr)
+13 stub CertModifyCertificatesToTrust
+14 stub CertSelectCertificateA
+15 stub CertSelectCertificateW
+16 stdcall CertViewPropertiesA(ptr)
+17 stdcall CertViewPropertiesW(ptr)
+18 stdcall -private DllRegisterServer()
+19 stdcall -private DllUnregisterServer()
+20 stdcall GetFriendlyNameOfCertA(ptr ptr long)
+21 stdcall GetFriendlyNameOfCertW(ptr ptr long)

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptdlg.spec
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/cryptdlg_En.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptdlg_En.rc?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptdlg_En.rc (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptdlg_En.rc [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,36 @@
+/*
+ * cryptdlg dll resources
+ *
+ * Copyright 2008 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_CERT_POLICY "Certificate Policy"
+    IDS_POLICY_ID "Policy Identifier: "
+    IDS_POLICY_QUALIFIER_INFO "Policy Qualifier Info"
+    IDS_POLICY_QUALIFIER_ID "Policy Qualifier Id="
+    IDS_CPS "CPS"
+    IDS_USER_NOTICE "User Notice"
+    IDS_QUALIFIER "Qualifier"
+    IDS_NOTICE_REF "Notice Reference"
+    IDS_ORGANIZATION "Organization="
+    IDS_NOTICE_NUM "Notice Number="
+    IDS_NOTICE_TEXT "Notice Text="
+}

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptdlg_En.rc
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/cryptdlg_Fr.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptdlg_Fr.rc?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptdlg_Fr.rc (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptdlg_Fr.rc [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,36 @@
+/*
+ * cryptdlg dll French resources
+ *
+ * Copyright 2008 Jonathan Ernst
+ *
+ * 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
+ */
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_CERT_POLICY "Politique de certificat"
+    IDS_POLICY_ID "Identifiant de politique : "
+    IDS_POLICY_QUALIFIER_INFO "Policy Qualifier Info"
+    IDS_POLICY_QUALIFIER_ID "Policy Qualifier Id="
+    IDS_CPS "CPS"
+    IDS_USER_NOTICE "User Notice"
+    IDS_QUALIFIER "Qualifier"
+    IDS_NOTICE_REF "Notice Reference"
+    IDS_ORGANIZATION "Organisation="
+    IDS_NOTICE_NUM "Notice Number="
+    IDS_NOTICE_TEXT "Notice Text="
+}

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptdlg_Fr.rc
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/cryptdlg_Ko.rc
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptdlg_Ko.rc?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptdlg_Ko.rc (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptdlg_Ko.rc [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,37 @@
+/*
+ * cryptdlg dll resources
+ *
+ * Copyright 2008 Juan Lang
+ * Copyright 2008 YunSong Hwang
+ *
+ * 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
+ */
+
+LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
+
+STRINGTABLE DISCARDABLE
+{
+    IDS_CERT_POLICY "ÀÎÁõ Á¤Ã¥"
+    IDS_POLICY_ID "Á¤Ã¥ ½Äº°ÀÚ: "
+    IDS_POLICY_QUALIFIER_INFO "Á¤Ã¥ ±¸º°ÀÚ Á¤º¸"
+    IDS_POLICY_QUALIFIER_ID "Á¤Ã¥ ±¸º°ÀÚ ¾ÆÀ̵ð="
+    IDS_CPS "CPS"
+    IDS_USER_NOTICE "»ç¿ëÀÚ ÅëÁö"
+    IDS_QUALIFIER "±¸º°ÀÚ"
+    IDS_NOTICE_REF "ÅëÁö ÂüÁ¶"
+    IDS_ORGANIZATION "±â°ü="
+    IDS_NOTICE_NUM "ÅëÁö ¹øÈ£="
+    IDS_NOTICE_TEXT "ÅëÁö ÅؽºÆ®="
+}

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptdlg_Ko.rc
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/cryptres.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/cryptres.h?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/cryptres.h (added)
+++ trunk/reactos/dll/win32/cryptdlg/cryptres.h [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,33 @@
+/*
+ * Copyright 2008 Juan Lang
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef __CRYPTRES_H__
+#define __CRYPTRES_H__
+
+#define IDS_CERT_POLICY 100
+#define IDS_POLICY_ID 101
+#define IDS_POLICY_QUALIFIER_INFO 102
+#define IDS_POLICY_QUALIFIER_ID 103
+#define IDS_CPS 104
+#define IDS_USER_NOTICE 105
+#define IDS_QUALIFIER 106
+#define IDS_NOTICE_REF 107
+#define IDS_ORGANIZATION 108
+#define IDS_NOTICE_NUM 109
+#define IDS_NOTICE_TEXT 110
+
+#endif /* ndef __CRYPTRES_H__ */

Propchange: trunk/reactos/dll/win32/cryptdlg/cryptres.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/cryptdlg/main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/cryptdlg/main.c?rev=39044&view=auto
==============================================================================
--- trunk/reactos/dll/win32/cryptdlg/main.c (added)
+++ trunk/reactos/dll/win32/cryptdlg/main.c [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -1,0 +1,1211 @@
+/*
+ * Copyright 2008 Maarten Lankhorst
+ *
+ * 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
+ */
+
+#define NONAMELESSUNION
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winnls.h"
+#include "winreg.h"
+#include "wincrypt.h"
+#include "wintrust.h"
+#include "winuser.h"
+#include "objbase.h"
+#include "cryptdlg.h"
+#include "cryptuiapi.h"
+#include "cryptres.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(cryptdlg);
+
+static HINSTANCE hInstance;
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
+
+    switch (fdwReason)
+    {
+        case DLL_WINE_PREATTACH:
+            return FALSE;    /* prefer native version */
+        case DLL_PROCESS_ATTACH:
+            DisableThreadLibraryCalls(hinstDLL);
+            hInstance = hinstDLL;
+            break;
+        case DLL_PROCESS_DETACH:
+            break;
+        default:
+            break;
+    }
+    return TRUE;
+}
+
+/***********************************************************************
+ *		GetFriendlyNameOfCertA (CRYPTDLG.@)
+ */
+DWORD WINAPI GetFriendlyNameOfCertA(PCCERT_CONTEXT pccert, LPSTR pchBuffer,
+                             DWORD cchBuffer)
+{
+    return CertGetNameStringA(pccert, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
+     pchBuffer, cchBuffer);
+}
+
+/***********************************************************************
+ *		GetFriendlyNameOfCertW (CRYPTDLG.@)
+ */
+DWORD WINAPI GetFriendlyNameOfCertW(PCCERT_CONTEXT pccert, LPWSTR pchBuffer,
+                             DWORD cchBuffer)
+{
+    return CertGetNameStringW(pccert, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
+     pchBuffer, cchBuffer);
+}
+
+/***********************************************************************
+ *		CertTrustInit (CRYPTDLG.@)
+ */
+HRESULT WINAPI CertTrustInit(CRYPT_PROVIDER_DATA *pProvData)
+{
+    HRESULT ret = S_FALSE;
+
+    TRACE("(%p)\n", pProvData);
+
+    if (pProvData->padwTrustStepErrors &&
+     !pProvData->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_WVTINIT])
+        ret = S_OK;
+    TRACE("returning %08x\n", ret);
+    return ret;
+}
+
+/***********************************************************************
+ *		CertTrustCertPolicy (CRYPTDLG.@)
+ */
+BOOL WINAPI CertTrustCertPolicy(CRYPT_PROVIDER_DATA *pProvData, DWORD idxSigner, BOOL fCounterSignerChain, DWORD idxCounterSigner)
+{
+    FIXME("(%p, %d, %s, %d)\n", pProvData, idxSigner, fCounterSignerChain ? "TRUE" : "FALSE", idxCounterSigner);
+    return FALSE;
+}
+
+/***********************************************************************
+ *		CertTrustCleanup (CRYPTDLG.@)
+ */
+HRESULT WINAPI CertTrustCleanup(CRYPT_PROVIDER_DATA *pProvData)
+{
+    FIXME("(%p)\n", pProvData);
+    return E_NOTIMPL;
+}
+
+static BOOL CRYPTDLG_CheckOnlineCRL(void)
+{
+    static const WCHAR policyFlagsKey[] = { 'S','o','f','t','w','a','r','e',
+     '\\','M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g',
+     'r','a','p','h','y','\\','{','7','8','0','1','e','b','d','0','-','c','f',
+     '4','b','-','1','1','d','0','-','8','5','1','f','-','0','0','6','0','9',
+     '7','9','3','8','7','e','a','}',0 };
+    static const WCHAR policyFlags[] = { 'P','o','l','i','c','y','F','l','a',
+     'g','s',0 };
+    HKEY key;
+    BOOL ret = FALSE;
+
+    if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, policyFlagsKey, 0, KEY_READ, &key))
+    {
+        DWORD type, flags, size = sizeof(flags);
+
+        if (!RegQueryValueExW(key, policyFlags, NULL, &type, (BYTE *)&flags,
+         &size) && type == REG_DWORD)
+        {
+            /* The flag values aren't defined in any header I'm aware of, but
+             * this value is well documented on the net.
+             */
+            if (flags & 0x00010000)
+                ret = TRUE;
+        }
+        RegCloseKey(key);
+    }
+    return ret;
+}
+
+/* Returns TRUE if pCert is not in the Disallowed system store, or FALSE if it
+ * is.
+ */
+static BOOL CRYPTDLG_IsCertAllowed(PCCERT_CONTEXT pCert)
+{
+    BOOL ret;
+    BYTE hash[20];
+    DWORD size = sizeof(hash);
+
+    if ((ret = CertGetCertificateContextProperty(pCert,
+     CERT_SIGNATURE_HASH_PROP_ID, hash, &size)))
+    {
+        static const WCHAR disallowedW[] =
+         { 'D','i','s','a','l','l','o','w','e','d',0 };
+        HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W,
+         X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, disallowedW);
+
+        if (disallowed)
+        {
+            PCCERT_CONTEXT found = CertFindCertificateInStore(disallowed,
+             X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, hash, NULL);
+
+            if (found)
+            {
+                ret = FALSE;
+                CertFreeCertificateContext(found);
+            }
+            CertCloseStore(disallowed, 0);
+        }
+    }
+    return ret;
+}
+
+static DWORD CRYPTDLG_TrustStatusToConfidence(DWORD errorStatus)
+{
+    DWORD confidence = 0;
+
+    confidence = 0;
+    if (!(errorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID))
+        confidence |= CERT_CONFIDENCE_SIG;
+    if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_VALID))
+        confidence |= CERT_CONFIDENCE_TIME;
+    if (!(errorStatus & CERT_TRUST_IS_NOT_TIME_NESTED))
+        confidence |= CERT_CONFIDENCE_TIMENEST;
+    return confidence;
+}
+
+static BOOL CRYPTDLG_CopyChain(CRYPT_PROVIDER_DATA *data,
+ PCCERT_CHAIN_CONTEXT chain)
+{
+    BOOL ret;
+    CRYPT_PROVIDER_SGNR signer;
+    PCERT_SIMPLE_CHAIN simpleChain = chain->rgpChain[0];
+    DWORD i;
+
+    memset(&signer, 0, sizeof(signer));
+    signer.cbStruct = sizeof(signer);
+    ret = data->psPfns->pfnAddSgnr2Chain(data, FALSE, 0, &signer);
+    if (ret)
+    {
+        CRYPT_PROVIDER_SGNR *sgnr = WTHelperGetProvSignerFromChain(data, 0,
+         FALSE, 0);
+
+        if (sgnr)
+        {
+            sgnr->dwError = simpleChain->TrustStatus.dwErrorStatus;
+            sgnr->pChainContext = CertDuplicateCertificateChain(chain);
+        }
+        else
+            ret = FALSE;
+        for (i = 0; ret && i < simpleChain->cElement; i++)
+        {
+            ret = data->psPfns->pfnAddCert2Chain(data, 0, FALSE, 0,
+             simpleChain->rgpElement[i]->pCertContext);
+            if (ret)
+            {
+                CRYPT_PROVIDER_CERT *cert;
+
+                if ((cert = WTHelperGetProvCertFromChain(sgnr, i)))
+                {
+                    CERT_CHAIN_ELEMENT *element = simpleChain->rgpElement[i];
+
+                    cert->dwConfidence = CRYPTDLG_TrustStatusToConfidence(
+                     element->TrustStatus.dwErrorStatus);
+                    cert->dwError = element->TrustStatus.dwErrorStatus;
+                    cert->pChainElement = element;
+                }
+                else
+                    ret = FALSE;
+            }
+        }
+    }
+    return ret;
+}
+
+static CERT_VERIFY_CERTIFICATE_TRUST *CRYPTDLG_GetVerifyData(
+ CRYPT_PROVIDER_DATA *data)
+{
+    CERT_VERIFY_CERTIFICATE_TRUST *pCert = NULL;
+
+    /* This should always be true, but just in case the calling function is
+     * called directly:
+     */
+    if (data->pWintrustData->dwUnionChoice == WTD_CHOICE_BLOB &&
+     data->pWintrustData->u.pBlob && data->pWintrustData->u.pBlob->cbMemObject ==
+     sizeof(CERT_VERIFY_CERTIFICATE_TRUST) &&
+     data->pWintrustData->u.pBlob->pbMemObject)
+         pCert = (CERT_VERIFY_CERTIFICATE_TRUST *)
+          data->pWintrustData->u.pBlob->pbMemObject;
+    return pCert;
+}
+
+static HCERTCHAINENGINE CRYPTDLG_MakeEngine(CERT_VERIFY_CERTIFICATE_TRUST *cert)
+{
+    HCERTCHAINENGINE engine = NULL;
+    HCERTSTORE root = NULL, trust = NULL;
+    DWORD i;
+
+    if (cert->cRootStores)
+    {
+        root = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
+         CERT_STORE_CREATE_NEW_FLAG, NULL);
+        if (root)
+        {
+            for (i = 0; i < cert->cRootStores; i++)
+                CertAddStoreToCollection(root, cert->rghstoreRoots[i], 0, 0);
+        }
+    }
+    if (cert->cTrustStores)
+    {
+        trust = CertOpenStore(CERT_STORE_PROV_COLLECTION, 0, 0,
+         CERT_STORE_CREATE_NEW_FLAG, NULL);
+        if (root)
+        {
+            for (i = 0; i < cert->cTrustStores; i++)
+                CertAddStoreToCollection(trust, cert->rghstoreTrust[i], 0, 0);
+        }
+    }
+    if (cert->cRootStores || cert->cStores || cert->cTrustStores)
+    {
+        CERT_CHAIN_ENGINE_CONFIG config;
+
+        memset(&config, 0, sizeof(config));
+        config.cbSize = sizeof(config);
+        config.hRestrictedRoot = root;
+        config.hRestrictedTrust = trust;
+        config.cAdditionalStore = cert->cStores;
+        config.rghAdditionalStore = cert->rghstoreCAs;
+        config.hRestrictedRoot = root;
+        CertCreateCertificateChainEngine(&config, &engine);
+        CertCloseStore(root, 0);
+        CertCloseStore(trust, 0);
+    }
+    return engine;
+}
+
+/***********************************************************************
+ *		CertTrustFinalPolicy (CRYPTDLG.@)
+ */
+HRESULT WINAPI CertTrustFinalPolicy(CRYPT_PROVIDER_DATA *data)
+{
+    BOOL ret;
+    DWORD err = S_OK;
+    CERT_VERIFY_CERTIFICATE_TRUST *pCert = CRYPTDLG_GetVerifyData(data);
+
+    TRACE("(%p)\n", data);
+
+    if (data->pWintrustData->dwUIChoice != WTD_UI_NONE)
+        FIXME("unimplemented for UI choice %d\n",
+         data->pWintrustData->dwUIChoice);
+    if (pCert)
+    {
+        DWORD flags = 0;
+        CERT_CHAIN_PARA chainPara;
+        HCERTCHAINENGINE engine;
+
+        memset(&chainPara, 0, sizeof(chainPara));
+        chainPara.cbSize = sizeof(chainPara);
+        if (CRYPTDLG_CheckOnlineCRL())
+            flags |= CERT_CHAIN_REVOCATION_CHECK_END_CERT;
+        engine = CRYPTDLG_MakeEngine(pCert);
+        GetSystemTimeAsFileTime(&data->sftSystemTime);
+        ret = CRYPTDLG_IsCertAllowed(pCert->pccert);
+        if (ret)
+        {
+            PCCERT_CHAIN_CONTEXT chain;
+
+            ret = CertGetCertificateChain(engine, pCert->pccert,
+             &data->sftSystemTime, NULL, &chainPara, flags, NULL, &chain);
+            if (ret)
+            {
+                if (chain->cChain != 1)
+                {
+                    FIXME("unimplemented for more than 1 simple chain\n");
+                    err = TRUST_E_SUBJECT_FORM_UNKNOWN;
+                    ret = FALSE;
+                }
+                else if ((ret = CRYPTDLG_CopyChain(data, chain)))
+                {
+                    if (CertVerifyTimeValidity(&data->sftSystemTime,
+                     pCert->pccert->pCertInfo))
+                    {
+                        ret = FALSE;
+                        err = CERT_E_EXPIRED;
+                    }
+                }
+                else
+                    err = TRUST_E_SYSTEM_ERROR;
+                CertFreeCertificateChain(chain);
+            }
+            else
+                err = TRUST_E_SUBJECT_NOT_TRUSTED;
+        }
+        CertFreeCertificateChainEngine(engine);
+    }
+    else
+    {
+        ret = FALSE;
+        err = TRUST_E_NOSIGNATURE;
+    }
+    /* Oddly, native doesn't set the error in the trust step error location,
+     * probably because this action is more advisory than anything else.
+     * Instead it stores it as the final error, but the function "succeeds" in
+     * any case.
+     */
+    if (!ret)
+        data->dwFinalError = err;
+    TRACE("returning %d (%08x)\n", S_OK, data->dwFinalError);
+    return S_OK;
+}
+
+/***********************************************************************
+ *		CertViewPropertiesA (CRYPTDLG.@)
+ */
+BOOL WINAPI CertViewPropertiesA(CERT_VIEWPROPERTIES_STRUCT_A *info)
+{
+    CERT_VIEWPROPERTIES_STRUCT_W infoW;
+    LPWSTR title = NULL;
+    BOOL ret;
+
+    TRACE("(%p)\n", info);
+
+    memcpy(&infoW, info, sizeof(infoW));
+    if (info->szTitle)
+    {
+        int len = MultiByteToWideChar(CP_ACP, 0, info->szTitle, -1, NULL, 0);
+
+        title = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        if (title)
+        {
+            MultiByteToWideChar(CP_ACP, 0, info->szTitle, -1, title, len);
+            infoW.szTitle = title;
+        }
+        else
+        {
+            ret = FALSE;
+            goto error;
+        }
+    }
+    ret = CertViewPropertiesW(&infoW);
+    HeapFree(GetProcessHeap(), 0, title);
+error:
+    return ret;
+}
+
+/***********************************************************************
+ *		CertViewPropertiesW (CRYPTDLG.@)
+ */
+BOOL WINAPI CertViewPropertiesW(CERT_VIEWPROPERTIES_STRUCT_W *info)
+{
+    static GUID cert_action_verify = CERT_CERTIFICATE_ACTION_VERIFY;
+    CERT_VERIFY_CERTIFICATE_TRUST trust;
+    WINTRUST_BLOB_INFO blob;
+    WINTRUST_DATA wtd;
+    LONG err;
+    BOOL ret;
+
+    TRACE("(%p)\n", info);
+
+    memset(&trust, 0, sizeof(trust));
+    trust.cbSize = sizeof(trust);
+    trust.pccert = info->pCertContext;
+    trust.cRootStores = info->cRootStores;
+    trust.rghstoreRoots = info->rghstoreRoots;
+    trust.cStores = info->cStores;
+    trust.rghstoreCAs = info->rghstoreCAs;
+    trust.cTrustStores = info->cTrustStores;
+    trust.rghstoreTrust = info->rghstoreTrust;
+    memset(&blob, 0, sizeof(blob));
+    blob.cbStruct = sizeof(blob);
+    blob.cbMemObject = sizeof(trust);
+    blob.pbMemObject = (BYTE *)&trust;
+    memset(&wtd, 0, sizeof(wtd));
+    wtd.cbStruct = sizeof(wtd);
+    wtd.dwUIChoice = WTD_UI_NONE;
+    wtd.dwUnionChoice = WTD_CHOICE_BLOB;
+    wtd.u.pBlob = &blob;
+    wtd.dwStateAction = WTD_STATEACTION_VERIFY;
+    err = WinVerifyTrust(NULL, &cert_action_verify, &wtd);
+    if (err == ERROR_SUCCESS)
+    {
+        CRYPTUI_VIEWCERTIFICATE_STRUCTW uiInfo;
+        BOOL propsChanged = FALSE;
+
+        memset(&uiInfo, 0, sizeof(uiInfo));
+        uiInfo.dwSize = sizeof(uiInfo);
+        uiInfo.hwndParent = info->hwndParent;
+        uiInfo.dwFlags =
+         CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_ENABLE_EDITPROPERTIES;
+        uiInfo.szTitle = info->szTitle;
+        uiInfo.pCertContext = info->pCertContext;
+        uiInfo.cPurposes = info->cArrayPurposes;
+        uiInfo.rgszPurposes = (LPCSTR *)info->arrayPurposes;
+        uiInfo.u.hWVTStateData = wtd.hWVTStateData;
+        uiInfo.fpCryptProviderDataTrustedUsage = TRUE;
+        uiInfo.cPropSheetPages = info->cArrayPropSheetPages;
+        uiInfo.rgPropSheetPages = info->arrayPropSheetPages;
+        uiInfo.nStartPage = info->nStartPage;
+        ret = CryptUIDlgViewCertificateW(&uiInfo, &propsChanged);
+        wtd.dwStateAction = WTD_STATEACTION_CLOSE;
+        WinVerifyTrust(NULL, &cert_action_verify, &wtd);
+    }
+    else
+        ret = FALSE;
+    return ret;
+}
+
+static BOOL CRYPT_FormatHexString(const BYTE *pbEncoded, DWORD cbEncoded,
+ WCHAR *str, DWORD *pcchStr)
+{
+    BOOL ret;
+    DWORD charsNeeded;
+
+    if (cbEncoded)
+        charsNeeded = (cbEncoded * 3);
+    else
+        charsNeeded = 1;
+    if (!str)
+    {
+        *pcchStr = charsNeeded;
+        ret = TRUE;
+    }
+    else if (*pcchStr < charsNeeded)
+    {
+        *pcchStr = charsNeeded;
+        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 = str;
+
+        *pcchStr = charsNeeded;
+        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;
+}
+
+static const WCHAR indent[] = { ' ',' ',' ',' ',' ',0 };
+static const WCHAR colonCrlf[] = { ':','\r','\n',0 };
+static const WCHAR colonSpace[] = { ':',' ',0 };
+static const WCHAR crlf[] = { '\r','\n',0 };
+static const WCHAR commaSep[] = { ',',' ',0 };
+
+static BOOL CRYPT_FormatCPS(DWORD dwCertEncodingType,
+ DWORD dwFormatStrType, const BYTE *pbEncoded, DWORD cbEncoded,
+ WCHAR *str, DWORD *pcchStr)
+{
+    BOOL ret;
+    DWORD size, charsNeeded = 1;
+    CERT_NAME_VALUE *cpsValue;
+
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_UNICODE_ANY_STRING,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &cpsValue, &size)))
+    {
+        LPCWSTR headingSep, sep;
+        DWORD headingSepLen, sepLen;
+
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            headingSep = colonCrlf;
+            sep = crlf;
+        }
+        else
+        {
+            headingSep = colonSpace;
+            sep = commaSep;
+        }
+        sepLen = strlenW(sep);
+        headingSepLen = strlenW(headingSep);
+
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            charsNeeded += 3 * strlenW(indent);
+            if (str && *pcchStr >= charsNeeded)
+            {
+                strcpyW(str, indent);
+                str += strlenW(indent);
+                strcpyW(str, indent);
+                str += strlenW(indent);
+                strcpyW(str, indent);
+                str += strlenW(indent);
+            }
+        }
+        charsNeeded += cpsValue->Value.cbData / sizeof(WCHAR);
+        if (str && *pcchStr >= charsNeeded)
+        {
+            strcpyW(str, (LPWSTR)cpsValue->Value.pbData);
+            str += cpsValue->Value.cbData / sizeof(WCHAR);
+        }
+        charsNeeded += sepLen;
+        if (str && *pcchStr >= charsNeeded)
+        {
+            strcpyW(str, sep);
+            str += sepLen;
+        }
+        LocalFree(cpsValue);
+        if (!str)
+            *pcchStr = charsNeeded;
+        else if (*pcchStr < charsNeeded)
+        {
+            *pcchStr = charsNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+            *pcchStr = charsNeeded;
+    }
+    return ret;
+}
+
+static BOOL CRYPT_FormatUserNotice(DWORD dwCertEncodingType,
+ DWORD dwFormatStrType, const BYTE *pbEncoded, DWORD cbEncoded,
+ WCHAR *str, DWORD *pcchStr)
+{
+    BOOL ret;
+    DWORD size, charsNeeded = 1;
+    CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
+
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType,
+     X509_PKIX_POLICY_QUALIFIER_USERNOTICE, pbEncoded, cbEncoded,
+     CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size)))
+    {
+        static const WCHAR numFmt[] = { '%','d',0 };
+        CERT_POLICY_QUALIFIER_NOTICE_REFERENCE *pNoticeRef =
+         notice->pNoticeReference;
+        LPCWSTR headingSep, sep;
+        DWORD headingSepLen, sepLen;
+        LPWSTR noticeRef, organization, noticeNum, noticeText;
+        DWORD noticeRefLen, organizationLen, noticeNumLen, noticeTextLen;
+        WCHAR noticeNumStr[11];
+
+        noticeRefLen = LoadStringW(hInstance, IDS_NOTICE_REF,
+         (LPWSTR)&noticeRef, 0);
+        organizationLen = LoadStringW(hInstance, IDS_ORGANIZATION,
+         (LPWSTR)&organization, 0);
+        noticeNumLen = LoadStringW(hInstance, IDS_NOTICE_NUM,
+         (LPWSTR)&noticeNum, 0);
+        noticeTextLen = LoadStringW(hInstance, IDS_NOTICE_TEXT,
+         (LPWSTR)&noticeText, 0);
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            headingSep = colonCrlf;
+            sep = crlf;
+        }
+        else
+        {
+            headingSep = colonSpace;
+            sep = commaSep;
+        }
+        sepLen = strlenW(sep);
+        headingSepLen = strlenW(headingSep);
+
+        if (pNoticeRef)
+        {
+            DWORD k;
+            LPCSTR src;
+
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                charsNeeded += 3 * strlenW(indent);
+                if (str && *pcchStr >= charsNeeded)
+                {
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                }
+            }
+            charsNeeded += noticeRefLen;
+            if (str && *pcchStr >= charsNeeded)
+            {
+                memcpy(str, noticeRef, noticeRefLen * sizeof(WCHAR));
+                str += noticeRefLen;
+            }
+            charsNeeded += headingSepLen;
+            if (str && *pcchStr >= charsNeeded)
+            {
+                strcpyW(str, headingSep);
+                str += headingSepLen;
+            }
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                charsNeeded += 4 * strlenW(indent);
+                if (str && *pcchStr >= charsNeeded)
+                {
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                }
+            }
+            charsNeeded += organizationLen;
+            if (str && *pcchStr >= charsNeeded)
+            {
+                memcpy(str, organization, organizationLen * sizeof(WCHAR));
+                str += organizationLen;
+            }
+            charsNeeded += strlen(pNoticeRef->pszOrganization);
+            if (str && *pcchStr >= charsNeeded)
+                for (src = pNoticeRef->pszOrganization; src && *src;
+                 src++, str++)
+                    *str = *src;
+            charsNeeded += sepLen;
+            if (str && *pcchStr >= charsNeeded)
+            {
+                strcpyW(str, sep);
+                str += sepLen;
+            }
+            for (k = 0; k < pNoticeRef->cNoticeNumbers; k++)
+            {
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                {
+                    charsNeeded += 4 * strlenW(indent);
+                    if (str && *pcchStr >= charsNeeded)
+                    {
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                    }
+                }
+                charsNeeded += noticeNumLen;
+                if (str && *pcchStr >= charsNeeded)
+                {
+                    memcpy(str, noticeNum, noticeNumLen * sizeof(WCHAR));
+                    str += noticeNumLen;
+                }
+                sprintfW(noticeNumStr, numFmt, k + 1);
+                charsNeeded += strlenW(noticeNumStr);
+                if (str && *pcchStr >= charsNeeded)
+                {
+                    strcpyW(str, noticeNumStr);
+                    str += strlenW(noticeNumStr);
+                }
+                charsNeeded += sepLen;
+                if (str && *pcchStr >= charsNeeded)
+                {
+                    strcpyW(str, sep);
+                    str += sepLen;
+                }
+            }
+        }
+        if (notice->pszDisplayText)
+        {
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                charsNeeded += 3 * strlenW(indent);
+                if (str && *pcchStr >= charsNeeded)
+                {
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                }
+            }
+            charsNeeded += noticeTextLen;
+            if (str && *pcchStr >= charsNeeded)
+            {
+                memcpy(str, noticeText, noticeTextLen * sizeof(WCHAR));
+                str += noticeTextLen;
+            }
+            charsNeeded += strlenW(notice->pszDisplayText);
+            if (str && *pcchStr >= charsNeeded)
+            {
+                strcpyW(str, notice->pszDisplayText);
+                str += strlenW(notice->pszDisplayText);
+            }
+            charsNeeded += sepLen;
+            if (str && *pcchStr >= charsNeeded)
+            {
+                strcpyW(str, sep);
+                str += sepLen;
+            }
+        }
+        LocalFree(notice);
+        if (!str)
+            *pcchStr = charsNeeded;
+        else if (*pcchStr < charsNeeded)
+        {
+            *pcchStr = charsNeeded;
+            SetLastError(ERROR_MORE_DATA);
+            ret = FALSE;
+        }
+        else
+            *pcchStr = charsNeeded;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *		FormatVerisignExtension (CRYPTDLG.@)
+ */
+BOOL WINAPI FormatVerisignExtension(DWORD dwCertEncodingType,
+ DWORD dwFormatType, DWORD dwFormatStrType, void *pFormatStruct,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, void *pbFormat,
+ DWORD *pcbFormat)
+{
+    CERT_POLICIES_INFO *policies;
+    DWORD size;
+    BOOL ret = FALSE;
+
+    if (!cbEncoded)
+    {
+        SetLastError(E_INVALIDARG);
+        return FALSE;
+    }
+    if ((ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_POLICIES,
+     pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &policies, &size)))
+    {
+        static const WCHAR numFmt[] = { '%','d',0 };
+        DWORD charsNeeded = 1; /* space for NULL terminator */
+        LPCWSTR headingSep, sep;
+        DWORD headingSepLen, sepLen;
+        WCHAR policyNum[11], policyQualifierNum[11];
+        LPWSTR certPolicy, policyId, policyQualifierInfo, policyQualifierId;
+        LPWSTR cps, userNotice, qualifier;
+        DWORD certPolicyLen, policyIdLen, policyQualifierInfoLen;
+        DWORD policyQualifierIdLen, cpsLen, userNoticeLen, qualifierLen;
+        DWORD i;
+        LPWSTR str = pbFormat;
+
+        certPolicyLen = LoadStringW(hInstance, IDS_CERT_POLICY,
+         (LPWSTR)&certPolicy, 0);
+        policyIdLen = LoadStringW(hInstance, IDS_POLICY_ID, (LPWSTR)&policyId,
+         0);
+        policyQualifierInfoLen = LoadStringW(hInstance,
+         IDS_POLICY_QUALIFIER_INFO, (LPWSTR)&policyQualifierInfo, 0);
+        policyQualifierIdLen = LoadStringW(hInstance, IDS_POLICY_QUALIFIER_ID,
+         (LPWSTR)&policyQualifierId, 0);
+        cpsLen = LoadStringW(hInstance, IDS_CPS, (LPWSTR)&cps, 0);
+        userNoticeLen = LoadStringW(hInstance, IDS_USER_NOTICE,
+         (LPWSTR)&userNotice, 0);
+        qualifierLen = LoadStringW(hInstance, IDS_QUALIFIER,
+         (LPWSTR)&qualifier, 0);
+        if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+        {
+            headingSep = colonCrlf;
+            sep = crlf;
+        }
+        else
+        {
+            headingSep = colonSpace;
+            sep = commaSep;
+        }
+        sepLen = strlenW(sep);
+        headingSepLen = strlenW(headingSep);
+
+        for (i = 0; ret && i < policies->cPolicyInfo; i++)
+        {
+            CERT_POLICY_INFO *policy = &policies->rgPolicyInfo[i];
+            DWORD j;
+            LPCSTR src;
+
+            charsNeeded += 1; /* '['*/
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                *str++ = '[';
+            sprintfW(policyNum, numFmt, i + 1);
+            charsNeeded += strlenW(policyNum);
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+            {
+                strcpyW(str, policyNum);
+                str += strlenW(policyNum);
+            }
+            charsNeeded += 1; /* ']'*/
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                *str++ = ']';
+            charsNeeded += certPolicyLen;
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+            {
+                memcpy(str, certPolicy, certPolicyLen * sizeof(WCHAR));
+                str += certPolicyLen;
+            }
+            charsNeeded += headingSepLen;
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+            {
+                strcpyW(str, headingSep);
+                str += headingSepLen;
+            }
+            if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+            {
+                charsNeeded += strlenW(indent);
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    strcpyW(str, indent);
+                    str += strlenW(indent);
+                }
+            }
+            charsNeeded += policyIdLen;
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+            {
+                memcpy(str, policyId, policyIdLen * sizeof(WCHAR));
+                str += policyIdLen;
+            }
+            charsNeeded += strlen(policy->pszPolicyIdentifier);
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+            {
+                for (src = policy->pszPolicyIdentifier; src && *src;
+                 src++, str++)
+                    *str = *src;
+            }
+            charsNeeded += sepLen;
+            if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+            {
+                strcpyW(str, sep);
+                str += sepLen;
+            }
+            for (j = 0; j < policy->cPolicyQualifier; j++)
+            {
+                CERT_POLICY_QUALIFIER_INFO *qualifierInfo =
+                 &policy->rgPolicyQualifier[j];
+                DWORD sizeRemaining;
+
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                {
+                    charsNeeded += strlenW(indent);
+                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    {
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                    }
+                }
+                charsNeeded += 1; /* '['*/
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    *str++ = '[';
+                charsNeeded += strlenW(policyNum);
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    strcpyW(str, policyNum);
+                    str += strlenW(policyNum);
+                }
+                charsNeeded += 1; /* ','*/
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    *str++ = ',';
+                sprintfW(policyQualifierNum, numFmt, j + 1);
+                charsNeeded += strlenW(policyQualifierNum);
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    strcpyW(str, policyQualifierNum);
+                    str += strlenW(policyQualifierNum);
+                }
+                charsNeeded += 1; /* ']'*/
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    *str++ = ']';
+                charsNeeded += policyQualifierInfoLen;
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    memcpy(str, policyQualifierInfo,
+                     policyQualifierInfoLen * sizeof(WCHAR));
+                    str += policyQualifierInfoLen;
+                }
+                charsNeeded += headingSepLen;
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    strcpyW(str, headingSep);
+                    str += headingSepLen;
+                }
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                {
+                    charsNeeded += 2 * strlenW(indent);
+                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    {
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                    }
+                }
+                charsNeeded += policyQualifierIdLen;
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    memcpy(str, policyQualifierId,
+                     policyQualifierIdLen * sizeof(WCHAR));
+                    str += policyQualifierIdLen;
+                }
+                if (!strcmp(qualifierInfo->pszPolicyQualifierId,
+                 szOID_PKIX_POLICY_QUALIFIER_CPS))
+                {
+                    charsNeeded += cpsLen;
+                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    {
+                        memcpy(str, cps, cpsLen * sizeof(WCHAR));
+                        str += cpsLen;
+                    }
+                }
+                else if (!strcmp(qualifierInfo->pszPolicyQualifierId,
+                 szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
+                {
+                    charsNeeded += userNoticeLen;
+                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    {
+                        memcpy(str, userNotice, userNoticeLen * sizeof(WCHAR));
+                        str += userNoticeLen;
+                    }
+                }
+                else
+                {
+                    charsNeeded += strlen(qualifierInfo->pszPolicyQualifierId);
+                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    {
+                        for (src = qualifierInfo->pszPolicyQualifierId;
+                         src && *src; src++, str++)
+                            *str = *src;
+                    }
+                }
+                charsNeeded += sepLen;
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    strcpyW(str, sep);
+                    str += sepLen;
+                }
+                if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
+                {
+                    charsNeeded += 2 * strlenW(indent);
+                    if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                    {
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                        strcpyW(str, indent);
+                        str += strlenW(indent);
+                    }
+                }
+                charsNeeded += qualifierLen;
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    memcpy(str, qualifier, qualifierLen * sizeof(WCHAR));
+                    str += qualifierLen;
+                }
+                charsNeeded += headingSepLen;
+                if (str && *pcbFormat >= charsNeeded * sizeof(WCHAR))
+                {
+                    strcpyW(str, headingSep);
+                    str += headingSepLen;
+                }
+                /* This if block is deliberately redundant with the same if
+                 * block above, in order to keep the code more readable (the
+                 * code flow follows the order in which the strings are output.)
+                 */
+                if (!strcmp(qualifierInfo->pszPolicyQualifierId,
+                 szOID_PKIX_POLICY_QUALIFIER_CPS))
+                {
+                    if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR))
+                    {
+                        /* Insufficient space, determine how much is needed. */
+                        ret = CRYPT_FormatCPS(dwCertEncodingType,
+                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
+                         qualifierInfo->Qualifier.cbData, NULL, &size);
+                        if (ret)
+                            charsNeeded += size - 1;
+                    }
+                    else
+                    {
+                        sizeRemaining = *pcbFormat / sizeof(WCHAR);
+                        sizeRemaining -= str - (LPWSTR)pbFormat;
+                        ret = CRYPT_FormatCPS(dwCertEncodingType,
+                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
+                         qualifierInfo->Qualifier.cbData, str, &sizeRemaining);
+                        if (ret || GetLastError() == ERROR_MORE_DATA)
+                        {
+                            charsNeeded += sizeRemaining - 1;
+                            str += sizeRemaining - 1;
+                        }
+                    }
+                }
+                else if (!strcmp(qualifierInfo->pszPolicyQualifierId,
+                 szOID_PKIX_POLICY_QUALIFIER_USERNOTICE))
+                {
+                    if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR))
+                    {
+                        /* Insufficient space, determine how much is needed. */
+                        ret = CRYPT_FormatUserNotice(dwCertEncodingType,
+                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
+                         qualifierInfo->Qualifier.cbData, NULL, &size);
+                        if (ret)
+                            charsNeeded += size - 1;
+                    }
+                    else
+                    {
+                        sizeRemaining = *pcbFormat / sizeof(WCHAR);
+                        sizeRemaining -= str - (LPWSTR)pbFormat;
+                        ret = CRYPT_FormatUserNotice(dwCertEncodingType,
+                         dwFormatStrType, qualifierInfo->Qualifier.pbData,
+                         qualifierInfo->Qualifier.cbData, str, &sizeRemaining);
+                        if (ret || GetLastError() == ERROR_MORE_DATA)
+                        {
+                            charsNeeded += sizeRemaining - 1;
+                            str += sizeRemaining - 1;
+                        }
+                    }
+                }
+                else
+                {
+                    if (!str || *pcbFormat < charsNeeded * sizeof(WCHAR))
+                    {
+                        /* Insufficient space, determine how much is needed. */
+                        ret = CRYPT_FormatHexString(
+                         qualifierInfo->Qualifier.pbData,
+                         qualifierInfo->Qualifier.cbData, NULL, &size);
+                        if (ret)
+                            charsNeeded += size - 1;
+                    }
+                    else
+                    {
+                        sizeRemaining = *pcbFormat / sizeof(WCHAR);
+                        sizeRemaining -= str - (LPWSTR)pbFormat;
+                        ret = CRYPT_FormatHexString(
+                         qualifierInfo->Qualifier.pbData,
+                         qualifierInfo->Qualifier.cbData, str, &sizeRemaining);
+                        if (ret || GetLastError() == ERROR_MORE_DATA)
+                        {
+                            charsNeeded += sizeRemaining - 1;
+                            str += sizeRemaining - 1;
+                        }
+                    }
+                }
+            }
+        }
+        LocalFree(policies);
+        if (ret)
+        {
+            if (!pbFormat)
+                *pcbFormat = charsNeeded * sizeof(WCHAR);
+            else if (*pcbFormat < charsNeeded * sizeof(WCHAR))
+            {
+                *pcbFormat = charsNeeded * sizeof(WCHAR);
+                SetLastError(ERROR_MORE_DATA);
+                ret = FALSE;
+            }
+            else
+                *pcbFormat = charsNeeded * sizeof(WCHAR);
+        }
+    }
+    return ret;
+}
+
+#define szOID_MICROSOFT_Encryption_Key_Preference "1.3.6.1.4.1.311.16.4"
+
+/***********************************************************************
+ *		DllRegisterServer (CRYPTDLG.@)
+ */
+HRESULT WINAPI DllRegisterServer(void)
+{
+    static WCHAR cryptdlg[] = { 'c','r','y','p','t','d','l','g','.',
+     'd','l','l',0 };
+    static WCHAR wintrust[] = { 'w','i','n','t','r','u','s','t','.',
+     'd','l','l',0 };
+    static WCHAR certTrustInit[] = { 'C','e','r','t','T','r','u','s','t',
+     'I','n','i','t',0 };
+    static WCHAR wintrustCertificateTrust[] = { 'W','i','n','t','r','u','s','t',
+     'C','e','r','t','i','f','i','c','a','t','e','T','r','u','s','t',0 };
+    static WCHAR certTrustCertPolicy[] = { 'C','e','r','t','T','r','u','s','t',
+     'C','e','r','t','P','o','l','i','c','y',0 };
+    static WCHAR certTrustFinalPolicy[] = { 'C','e','r','t','T','r','u','s','t',
+     'F','i','n','a','l','P','o','l','i','c','y',0 };
+    static WCHAR certTrustCleanup[] = { 'C','e','r','t','T','r','u','s','t',
+     'C','l','e','a','n','u','p',0 };
+    static const WCHAR cryptDlg[] = { 'c','r','y','p','t','d','l','g','.',
+       'd','l','l',0 };
+    CRYPT_REGISTER_ACTIONID reg;
+    GUID guid = CERT_CERTIFICATE_ACTION_VERIFY;
+    HRESULT hr = S_OK;
+
+    memset(&reg, 0, sizeof(reg));
+    reg.cbStruct = sizeof(reg);
+    reg.sInitProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
+    reg.sInitProvider.pwszDLLName = cryptdlg;
+    reg.sInitProvider.pwszFunctionName = certTrustInit;
+    reg.sCertificateProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
+    reg.sCertificateProvider.pwszDLLName = wintrust;
+    reg.sCertificateProvider.pwszFunctionName = wintrustCertificateTrust;
+    reg.sCertificatePolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
+    reg.sCertificatePolicyProvider.pwszDLLName = cryptdlg;
+    reg.sCertificatePolicyProvider.pwszFunctionName = certTrustCertPolicy;
+    reg.sFinalPolicyProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
+    reg.sFinalPolicyProvider.pwszDLLName = cryptdlg;
+    reg.sFinalPolicyProvider.pwszFunctionName = certTrustFinalPolicy;
+    reg.sCleanupProvider.cbStruct = sizeof(CRYPT_TRUST_REG_ENTRY);
+    reg.sCleanupProvider.pwszDLLName = cryptdlg;
+    reg.sCleanupProvider.pwszFunctionName = certTrustCleanup;
+    if (!WintrustAddActionID(&guid, WT_ADD_ACTION_ID_RET_RESULT_FLAG, &reg))
+        hr = GetLastError();
+    CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC,
+     "1.3.6.1.4.1.311.16.1.1", cryptDlg, "EncodeAttrSequence");
+    CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC,
+     szOID_MICROSOFT_Encryption_Key_Preference, cryptDlg, "EncodeRecipientID");
+    CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC,
+     "1.3.6.1.4.1.311.16.1.1", cryptDlg, "DecodeAttrSequence");
+    CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC,
+     szOID_MICROSOFT_Encryption_Key_Preference, cryptDlg, "DecodeRecipientID");
+    CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC,
+     szOID_PKIX_KP_EMAIL_PROTECTION, cryptDlg, "FormatPKIXEmailProtection");
+    CryptRegisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC,
+     szOID_CERT_POLICIES, cryptDlg, "FormatVerisignExtension");
+    return hr;
+}
+
+/***********************************************************************
+ *		DllUnregisterServer (CRYPTDLG.@)
+ */
+HRESULT WINAPI DllUnregisterServer(void)
+{
+    GUID guid = CERT_CERTIFICATE_ACTION_VERIFY;
+
+    WintrustRemoveActionID(&guid);
+    CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC,
+     "1.3.6.1.4.1.311.16.1.1");
+    CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_ENCODE_OBJECT_FUNC,
+     szOID_MICROSOFT_Encryption_Key_Preference);
+    CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC,
+     "1.3.6.1.4.1.311.16.1.1");
+    CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_DECODE_OBJECT_FUNC,
+     szOID_MICROSOFT_Encryption_Key_Preference);
+    CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC,
+     szOID_PKIX_KP_EMAIL_PROTECTION);
+    CryptUnregisterOIDFunction(X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC,
+     szOID_CERT_POLICIES);
+    return S_OK;
+}

Propchange: trunk/reactos/dll/win32/cryptdlg/main.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/dll/win32/win32.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/win32.rbuild?rev=39044&r1=39043&r2=39044&view=diff
==============================================================================
--- trunk/reactos/dll/win32/win32.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/win32.rbuild [iso-8859-1] Fri Jan 23 07:06:33 2009
@@ -61,6 +61,9 @@
 <directory name="crypt32">
 	<xi:include href="crypt32/crypt32.rbuild" />
 </directory>
+<directory name="cryptdlg">
+	<xi:include href="cryptdlg/cryptdlg.rbuild" />
+</directory>
 <directory name="cryptdll">
 	<xi:include href="cryptdll/cryptdll.rbuild" />
 </directory>



More information about the Ros-diffs mailing list