crytpui/tests: Add tests for CryptUIDlgSelectCertificateA.

Alexander Morozov amorozov at etersoft.ru
Mon Aug 29 07:44:20 CDT 2011


On new Windows (for example, Win2008) CryptUIDlgSelectCertificate creates a 
dialog which is different from old Windows (for example, WinXP). But a 
function description in MSDN is better conforming to old dialog. New dialog 
does not have some features. It does not contain list view with columns so 
dwDontUseColumn does nothing. Also with new dialog a function does not call 
pDisplayCallback. One can force new Windows to create old dialog if set 
cPropSheetPages. And I do so in a test where there is a difference between old 
and new dialogs.

New dialog: http://updates.etersoft.ru/pub/people/amorozov/cryptui_new.png
Old dialog: http://updates.etersoft.ru/pub/people/amorozov/cryptui_old.png
-------------- next part --------------
From 1bdbd7fed88632700ed61cf7715233caa0d00887 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov at etersoft.ru>
Date: Fri, 12 Aug 2011 18:06:28 +0400
Subject: [PATCH] crytpui/tests: Add tests for CryptUIDlgSelectCertificateA.

---
 dlls/cryptui/tests/Makefile.in |    2 +
 dlls/cryptui/tests/cryptui.c   |  259 ++++++++++++++++++++++++++++++++++++++++
 dlls/cryptui/tests/resource.rc |   27 ++++
 dlls/cryptui/tests/resources.h |   26 ++++
 4 files changed, 314 insertions(+), 0 deletions(-)
 create mode 100644 dlls/cryptui/tests/resource.rc
 create mode 100644 dlls/cryptui/tests/resources.h

diff --git a/dlls/cryptui/tests/Makefile.in b/dlls/cryptui/tests/Makefile.in
index cc2c638..56f941d 100644
--- a/dlls/cryptui/tests/Makefile.in
+++ b/dlls/cryptui/tests/Makefile.in
@@ -4,4 +4,6 @@ IMPORTS   = cryptui crypt32 user32
 C_SRCS = \
 	cryptui.c
 
+RC_SRCS = resource.rc
+
 @MAKE_TEST_RULES@
diff --git a/dlls/cryptui/tests/cryptui.c b/dlls/cryptui/tests/cryptui.c
index bb1db92..c134e95 100644
--- a/dlls/cryptui/tests/cryptui.c
+++ b/dlls/cryptui/tests/cryptui.c
@@ -24,9 +24,12 @@
 #include <winbase.h>
 #include <winerror.h>
 #include <winuser.h>
+#include <commctrl.h>
 #include <wincrypt.h>
 #include <cryptuiapi.h>
 
+#include "resources.h"
+
 #include "wine/test.h"
 
 static BYTE v1CertWithValidPubKey[] = {
@@ -300,6 +303,8 @@ static LRESULT CALLBACK cbt_hook_proc(int code, WPARAM wp, LPARAM lp)
 static BOOL (WINAPI *pCryptUIWizImport)(DWORD dwFlags, HWND hwndParent,
  LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSrc,
  HCERTSTORE hDestCertStore);
+static PCCERT_CONTEXT (WINAPI *pCryptUIDlgSelectCertificateA)(
+ PCCRYPTUI_SELECTCERTIFICATE_STRUCTA pcsc);
 
 static BOOL find_and_delete_cert_in_store(HCERTSTORE store, PCCERT_CONTEXT cert)
 {
@@ -649,6 +654,258 @@ static void test_crypt_ui_wiz_import(void)
     UnhookWindowsHookEx(hook);
 }
 
+static BOOL CALLBACK get_tab_ctrl_hwnd(HWND hwnd, LPARAM lp)
+{
+    char buf[16];
+
+    if (GetClassNameA(hwnd, buf, sizeof(buf)) && !lstrcmpA(buf, "SysTabControl32"))
+    {
+        *(HWND *)lp = hwnd;
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static BOOL CALLBACK get_list_view_hwnd(HWND hwnd, LPARAM lp)
+{
+    char buf[16];
+
+    GetClassNameA(hwnd, buf, sizeof(buf));
+
+    if (GetClassNameA(hwnd, buf, sizeof(buf)) && !lstrcmpA(buf, "SysListView32"))
+    {
+        *(HWND *)lp = hwnd;
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static BOOL CALLBACK press_view_cert_button(HWND hwnd, LPARAM lp)
+{
+    char buf[7];
+
+    if (GetClassNameA(hwnd, buf, sizeof(buf)) && !lstrcmpA(buf, "Button"))
+    {
+        int button_id = GetDlgCtrlID(hwnd);
+
+        if (button_id != IDOK && button_id != IDCANCEL)
+        {
+            PostMessageA((HWND)lp, WM_COMMAND, button_id, 0);
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+static int button = IDCANCEL;
+static int view_cert;
+static int setcursel_ret;
+static HWND ctrl_hwnd;
+
+static LRESULT CALLBACK select_cert_hook_proc(int code, WPARAM wp, LPARAM lp)
+{
+    CWPRETSTRUCT *cwpret = (CWPRETSTRUCT *)lp;
+    HWND lv = NULL;
+
+    if (cwpret->message == WM_INITDIALOG)
+    {
+        if (GetParent(cwpret->hwnd))
+        {
+            /* certificate view window */
+            ctrl_hwnd = NULL;
+            EnumChildWindows(cwpret->hwnd, get_tab_ctrl_hwnd, (LPARAM)&ctrl_hwnd);
+            if (ctrl_hwnd)
+                setcursel_ret = TabCtrl_SetCurSel(ctrl_hwnd, 3);
+            PostMessageA(cwpret->hwnd, WM_COMMAND, IDOK, 0);
+        }
+        else
+        {
+            /* certificate selection window */
+            EnumChildWindows(cwpret->hwnd, get_list_view_hwnd, (LPARAM)&lv);
+            if (lv)
+                ListView_SetItemState(lv, 0, LVIS_SELECTED, LVIS_SELECTED);
+            if (view_cert)
+                EnumChildWindows(cwpret->hwnd, press_view_cert_button, (LPARAM)cwpret->hwnd);
+            PostMessageA(cwpret->hwnd, WM_COMMAND, button, 0);
+        }
+    }
+    return CallNextHookEx(hook, code, wp, lp);
+}
+
+static BOOL WINAPI filter_proc(PCCERT_CONTEXT pCertContext, BOOL *pfInitialSelectedCert,
+ void *pvCallbackData)
+{
+    todo_wine
+    ok(pCertContext->cbCertEncoded == sizeof(v1CertWithValidPubKey) ||
+     pCertContext->cbCertEncoded == sizeof(iTunesCert1), "wrong certificate context\n");
+    todo_wine
+    ok(pvCallbackData == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", pvCallbackData);
+    if (pCertContext->cbCertEncoded == sizeof(iTunesCert1))
+        return TRUE;
+    return FALSE;
+}
+
+static int display_proc_flag;
+static int display_proc_ret;
+
+static BOOL WINAPI display_proc(PCCERT_CONTEXT pCertContext, HWND hWndSelCertDlg,
+ void *pvCallbackData)
+{
+    display_proc_flag = 1;
+    todo_wine
+    ok(pCertContext->cbCertEncoded == sizeof(v1CertWithValidPubKey) ||
+     pCertContext->cbCertEncoded == sizeof(iTunesCert1), "wrong certificate context\n");
+    todo_wine
+    ok(pvCallbackData == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", pvCallbackData);
+    todo_wine
+    ok(IsWindow(hWndSelCertDlg), "hWndSelCertDlg does not identify an existing window\n");
+    if (hWndSelCertDlg)
+        MessageBoxA(hWndSelCertDlg, "Wine Test", "Wine Test", MB_OKCANCEL);
+    return display_proc_ret;
+}
+
+static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    return 0;
+}
+
+static void test_crypt_ui_dlg_select_certificate(void)
+{
+    BOOL ret;
+    CRYPTUI_SELECTCERTIFICATE_STRUCTA sel;
+    PCCERT_CONTEXT cert;
+    HCERTSTORE store[2];
+    PROPSHEETPAGEA psp;
+
+    if (!pCryptUIDlgSelectCertificateA)
+    {
+        skip("No CryptUIDlgSelectCertificate\n");
+        return;
+    }
+
+    hook = SetWindowsHookExA(WH_CALLWNDPROCRET, select_cert_hook_proc, 0, GetCurrentThreadId());
+
+    memset(&sel, 0, sizeof(sel));
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(!cert && (GetLastError() == E_INVALIDARG ||
+     GetLastError() == ERROR_FILE_NOT_FOUND), /* NT4 */
+     "expected E_INVALIDARG, got %08x\n", GetLastError());
+    sel.dwSize = sizeof(sel);
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(!cert && (GetLastError() == ERROR_SUCCESS ||
+     broken(GetLastError() == 0xdeadbeef)), /* NT4 */
+     "expected ERROR_SUCCESS, got %08x\n", GetLastError());
+    sel.dwSize = 60;
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(!cert && GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %08x\n",
+     GetLastError());
+
+    SetLastError(0xdeadbeef);
+    store[0] = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store[0] != NULL, "CertOpenStore failed: %08x\n", GetLastError());
+    SetLastError(0xdeadbeef);
+    cert = CertCreateCertificateContext(X509_ASN_ENCODING, v1CertWithValidPubKey,
+     sizeof(v1CertWithValidPubKey));
+    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n", GetLastError());
+    SetLastError(0xdeadbeef);
+    ret = CertAddCertificateContextToStore(store[0], cert, CERT_STORE_ADD_NEW, NULL);
+    ok(ret, "CertAddCertificateContextToStore failed: %08x\n", GetLastError());
+    CertFreeCertificateContext(cert);
+    SetLastError(0xdeadbeef);
+    store[1] = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL);
+    ok(store[1] != NULL, "CertOpenStore failed: %08x\n", GetLastError());
+    SetLastError(0xdeadbeef);
+    cert = CertCreateCertificateContext(X509_ASN_ENCODING, iTunesCert1, sizeof(iTunesCert1));
+    ok(cert != NULL, "CertCreateCertificateContext failed: %08x\n", GetLastError());
+    SetLastError(0xdeadbeef);
+    ret = CertAddCertificateContextToStore(store[1], cert, CERT_STORE_ADD_NEW, NULL);
+    ok(ret, "CertAddCertificateContextToStore failed: %08x\n", GetLastError());
+    CertFreeCertificateContext(cert);
+
+    sel.dwDontUseColumn = 0;
+    sel.cDisplayStores = 2;
+    sel.rghDisplayStores = store;
+    sel.cPropSheetPages = 1;
+    sel.rgPropSheetPages = &psp;
+    memset(&psp, 0, sizeof(psp));
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(!cert && GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %08x\n",
+     GetLastError());
+    button = IDOK;
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(cert != NULL, "CryptUIDlgSelectCertificate failed: %08x\n", GetLastError());
+    if (cert)
+        todo_wine
+        ok(cert->cbCertEncoded == sizeof(v1CertWithValidPubKey), "wrong certificate is selected\n");
+    CertFreeCertificateContext(cert);
+
+    sel.pFilterCallback = filter_proc;
+    sel.pvCallbackData = (void *)0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(cert != NULL, "CryptUIDlgSelectCertificate failed: %08x\n", GetLastError());
+    if (cert)
+        todo_wine
+        ok(cert->cbCertEncoded == sizeof(iTunesCert1), "wrong certificate is selected\n");
+    CertFreeCertificateContext(cert);
+
+    view_cert = 1;
+    sel.pFilterCallback = NULL;
+    sel.pDisplayCallback = display_proc;
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(cert != NULL, "CryptUIDlgSelectCertificate failed: %08x\n", GetLastError());
+    todo_wine
+    ok(display_proc_flag, "display callback was not called\n");
+    todo_wine
+    ok(ctrl_hwnd != NULL, "the dialog box did not display certificate\n");
+    CertFreeCertificateContext(cert);
+    display_proc_ret = TRUE;
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(cert != NULL, "CryptUIDlgSelectCertificate failed: %08x\n", GetLastError());
+    todo_wine
+    ok(display_proc_flag, "display callback was not called\n");
+    ok(!ctrl_hwnd, "the dialog box displayed certificate\n");
+    CertFreeCertificateContext(cert);
+
+    sel.pDisplayCallback = NULL;
+    sel.pvCallbackData = NULL;
+    psp.dwSize = sizeof(psp);
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(cert != NULL, "CryptUIDlgSelectCertificate failed: %08x\n", GetLastError());
+    CertFreeCertificateContext(cert);
+    psp.u.pszTemplate = MAKEINTRESOURCEA(IDD_CERT_VIEW_PROP_PAGE);
+    psp.pfnDlgProc = page_dlg_proc;
+    setcursel_ret = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    cert = pCryptUIDlgSelectCertificateA(&sel);
+    todo_wine
+    ok(cert != NULL, "CryptUIDlgSelectCertificate failed: %08x\n", GetLastError());
+    todo_wine
+    ok(setcursel_ret == 0, "TabCtrl_SetCurSel returned %d\n", setcursel_ret);
+    CertFreeCertificateContext(cert);
+
+    CertCloseStore(store[0], 0);
+    CertCloseStore(store[1], 0);
+    UnhookWindowsHookEx(hook);
+}
+
 START_TEST(cryptui)
 {
     HMODULE lib = LoadLibraryA("cryptui");
@@ -656,8 +913,10 @@ START_TEST(cryptui)
     if (lib)
     {
         pCryptUIWizImport = (void *)GetProcAddress(lib, "CryptUIWizImport");
+        pCryptUIDlgSelectCertificateA = (void *)GetProcAddress(lib, "CryptUIDlgSelectCertificateA");
 
         test_crypt_ui_wiz_import();
+        test_crypt_ui_dlg_select_certificate();
         FreeLibrary(lib);
     }
 }
diff --git a/dlls/cryptui/tests/resource.rc b/dlls/cryptui/tests/resource.rc
new file mode 100644
index 0000000..634dc1c
--- /dev/null
+++ b/dlls/cryptui/tests/resource.rc
@@ -0,0 +1,27 @@
+/*
+ * Resource file for cryptui tests
+ *
+ * Copyright 2011 Alexander Morozov for Etersoft
+ *
+ * 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 "resources.h"
+
+IDD_CERT_VIEW_PROP_PAGE DIALOG 0, 0, 255, 236
+CAPTION "Test"
+BEGIN
+    LTEXT "", -1, 0, 0, 0, 0
+END
diff --git a/dlls/cryptui/tests/resources.h b/dlls/cryptui/tests/resources.h
new file mode 100644
index 0000000..c4c19b4
--- /dev/null
+++ b/dlls/cryptui/tests/resources.h
@@ -0,0 +1,26 @@
+/*
+ * Resource IDs
+ *
+ * Copyright 2011 Alexander Morozov for Etersoft
+ *
+ * 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 __WINE_CRYPTUI_TEST_RESOURCES_H
+#define __WINE_CRYPTUI_TEST_RESOURCES_H
+
+#define IDD_CERT_VIEW_PROP_PAGE 100
+
+#endif  /* __WINE_CRYPTUI_TEST_RESOURCES_H */
-- 
1.7.6.1



More information about the wine-patches mailing list