From 55a243ea51c6ad64e2d8b983ef5872b79252ba02 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 5 Jul 2019 13:20:23 +0800
Subject: [PATCH] cryptext: Implement CryptExtOpenCER.

Moved the strings to resource file
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
Signed-off-by: Vijay Kiran Kamuju <infyquest@gmail.com>
---
 configure                       |  1 +
 configure.ac                    |  1 +
 dlls/cryptext/Makefile.in       |  5 ++-
 dlls/cryptext/cryptext.rc       | 31 ++++++++++++++
 dlls/cryptext/cryptext.spec     |  4 +-
 dlls/cryptext/cryptext_main.c   | 75 +++++++++++++++++++++++++++++++++
 dlls/cryptext/cryptextres.h     | 27 ++++++++++++
 dlls/cryptext/tests/Makefile.in |  4 ++
 dlls/cryptext/tests/cryptext.c  | 61 +++++++++++++++++++++++++++
 9 files changed, 206 insertions(+), 3 deletions(-)
 create mode 100644 dlls/cryptext/cryptext.rc
 create mode 100644 dlls/cryptext/cryptextres.h
 create mode 100644 dlls/cryptext/tests/Makefile.in
 create mode 100644 dlls/cryptext/tests/cryptext.c

diff --git a/configure b/configure
index 5c01f4a27c..4aa63bb745 100755
--- a/configure
+++ b/configure
@@ -20391,6 +20391,7 @@ wine_fn_config_makefile dlls/crypt32/tests enable_tests
 wine_fn_config_makefile dlls/cryptdlg enable_cryptdlg
 wine_fn_config_makefile dlls/cryptdll enable_cryptdll
 wine_fn_config_makefile dlls/cryptext enable_cryptext
+wine_fn_config_makefile dlls/cryptext/tests enable_tests
 wine_fn_config_makefile dlls/cryptnet enable_cryptnet
 wine_fn_config_makefile dlls/cryptnet/tests enable_tests
 wine_fn_config_makefile dlls/cryptui enable_cryptui
diff --git a/configure.ac b/configure.ac
index 2a472864b1..4da1cfbb00 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3081,6 +3081,7 @@ WINE_CONFIG_MAKEFILE(dlls/crypt32/tests)
 WINE_CONFIG_MAKEFILE(dlls/cryptdlg)
 WINE_CONFIG_MAKEFILE(dlls/cryptdll)
 WINE_CONFIG_MAKEFILE(dlls/cryptext)
+WINE_CONFIG_MAKEFILE(dlls/cryptext/tests)
 WINE_CONFIG_MAKEFILE(dlls/cryptnet)
 WINE_CONFIG_MAKEFILE(dlls/cryptnet/tests)
 WINE_CONFIG_MAKEFILE(dlls/cryptui)
diff --git a/dlls/cryptext/Makefile.in b/dlls/cryptext/Makefile.in
index 9c9f84cee8..f284dad2d0 100644
--- a/dlls/cryptext/Makefile.in
+++ b/dlls/cryptext/Makefile.in
@@ -1,6 +1,9 @@
-MODULE = cryptext.dll
+MODULE  = cryptext.dll
+IMPORTS = crypt32 cryptui user32
 
 EXTRADLLFLAGS = -mno-cygwin
 
 C_SRCS = \
 	cryptext_main.c
+
+RC_SRCS = cryptext.rc
diff --git a/dlls/cryptext/cryptext.rc b/dlls/cryptext/cryptext.rc
new file mode 100644
index 0000000000..ef4f637559
--- /dev/null
+++ b/dlls/cryptext/cryptext.rc
@@ -0,0 +1,31 @@
+/*
+ * cryptext dll resources
+ *
+ * Copyright 2020 Vijay Kiran Kamuju
+ *
+ * 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 "cryptextres.h"
+
+#pragma makedep po
+
+LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+{
+    IDS_INVALID_PKSO_FILE "Invalid Public Key Security Object File"
+    IDS_INVALID_FILE_USE "This file is invalid for use as the following: %s."
+    IDS_SECURITY_CERT "Security Certificate"
+}
diff --git a/dlls/cryptext/cryptext.spec b/dlls/cryptext/cryptext.spec
index 0dba38e393..911ab2f4ba 100644
--- a/dlls/cryptext/cryptext.spec
+++ b/dlls/cryptext/cryptext.spec
@@ -12,8 +12,8 @@
 @ stub CryptExtAddSPCW
 @ stub CryptExtOpenCAT
 @ stub CryptExtOpenCATW
-@ stub CryptExtOpenCER
-@ stub CryptExtOpenCERW
+@ stdcall CryptExtOpenCER(long ptr str long)
+@ stdcall CryptExtOpenCERW(long ptr wstr long)
 @ stub CryptExtOpenCRL
 @ stub CryptExtOpenCRLW
 @ stub CryptExtOpenCTL
diff --git a/dlls/cryptext/cryptext_main.c b/dlls/cryptext/cryptext_main.c
index f7c7bd1f55..39fa842862 100644
--- a/dlls/cryptext/cryptext_main.c
+++ b/dlls/cryptext/cryptext_main.c
@@ -22,10 +22,32 @@
 
 #include "windef.h"
 #include "winbase.h"
+#include "winnls.h"
+#include "wincrypt.h"
+#include "winuser.h"
+#include "cryptextres.h"
+#include "cryptuiapi.h"
+
+#include "wine/heap.h"
 #include "wine/debug.h"
 
+#define MAX_STRING_LEN 1024
+
 WINE_DEFAULT_DEBUG_CHANNEL(cryptext);
 
+static WCHAR *heap_strdupAtoW(const char *str)
+{
+    WCHAR *ret;
+    INT len;
+
+    if (!str) return NULL;
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    ret = heap_alloc(len * sizeof(WCHAR));
+    if (ret)
+        MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+    return ret;
+}
+
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
 {
     TRACE("(%p, %u, %p)\n", instance, reason, reserved);
@@ -59,3 +81,56 @@ HRESULT WINAPI CryptExtAddPFXW(LPCWSTR filename)
     FIXME("stub: %s\n", debugstr_w(filename));
     return E_NOTIMPL;
 }
+
+/***********************************************************************
+ * CryptExtOpenCERW (CRYPTEXT.@)
+ */
+HRESULT WINAPI CryptExtOpenCERW(HWND hwnd, HINSTANCE hinst, LPCWSTR filename, DWORD showcmd)
+{
+    PCCERT_CONTEXT ctx;
+    CRYPTUI_VIEWCERTIFICATE_STRUCTW info;
+
+    TRACE("(%p, %p, %s, %u)\n", hwnd, hinst, debugstr_w(filename), showcmd);
+
+    if (!CryptQueryObject(CERT_QUERY_OBJECT_FILE, filename, CERT_QUERY_CONTENT_FLAG_CERT,
+                          CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, NULL, NULL,
+                          (const void **)&ctx))
+    {
+        WCHAR errormsg[MAX_STRING_LEN];
+        WCHAR title[MAX_STRING_LEN];
+        WCHAR invalidmsg[MAX_STRING_LEN];
+        WCHAR certtype[MAX_STRING_LEN];
+
+        LoadStringW(hinst, IDS_INVALID_PKSO_FILE, title, ARRAY_SIZE(title));
+        LoadStringW(hinst, IDS_INVALID_FILE_USE, invalidmsg, ARRAY_SIZE(invalidmsg));
+        LoadStringW(hinst, IDS_SECURITY_CERT, certtype, ARRAY_SIZE(certtype));
+        wsprintfW(errormsg, invalidmsg, certtype);
+
+        MessageBoxW(NULL, errormsg, title, MB_OK | MB_ICONERROR);
+        return S_OK; /* according to the tests */
+    }
+
+    memset(&info, 0, sizeof(info));
+    info.dwSize = sizeof(info);
+    info.pCertContext = ctx;
+    CryptUIDlgViewCertificateW(&info, NULL);
+    CertFreeCertificateContext(ctx);
+
+    return S_OK;
+}
+
+/***********************************************************************
+ * CryptExtOpenCER (CRYPTEXT.@)
+ */
+HRESULT WINAPI CryptExtOpenCER(HWND hwnd, HINSTANCE hinst, LPCSTR filename, DWORD showcmd)
+{
+    HRESULT hr;
+    LPWSTR filenameW;
+
+    TRACE("(%p, %p, %s, %u)\n", hwnd, hinst, debugstr_a(filename), showcmd);
+
+    filenameW = heap_strdupAtoW(filename);
+    hr = CryptExtOpenCERW(hwnd, hinst, filenameW, showcmd);
+    heap_free(filenameW);
+    return hr;
+}
diff --git a/dlls/cryptext/cryptextres.h b/dlls/cryptext/cryptextres.h
new file mode 100644
index 0000000000..3a5cdfe5be
--- /dev/null
+++ b/dlls/cryptext/cryptextres.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 Vijay Kiran Kamuju
+ *
+ * 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_CRYPTEXTRES_H__
+#define __WINE_CRYPTEXTRES_H__
+
+#include <windef.h>
+
+#define IDS_INVALID_PKSO_FILE 1000
+#define IDS_INVALID_FILE_USE 1001
+#define IDS_SECURITY_CERT 1002
+
+#endif /* ndef __WINE_CRYPTEXTRES_H__ */
diff --git a/dlls/cryptext/tests/Makefile.in b/dlls/cryptext/tests/Makefile.in
new file mode 100644
index 0000000000..522fc60a4a
--- /dev/null
+++ b/dlls/cryptext/tests/Makefile.in
@@ -0,0 +1,4 @@
+TESTDLL = cryptext.dll
+
+C_SRCS = \
+	cryptext.c
diff --git a/dlls/cryptext/tests/cryptext.c b/dlls/cryptext/tests/cryptext.c
new file mode 100644
index 0000000000..cc62a772b5
--- /dev/null
+++ b/dlls/cryptext/tests/cryptext.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 Dmitry Timoshkov
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+#include <assert.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winuser.h>
+#include <winerror.h>
+
+#include "wine/test.h"
+
+static HRESULT (WINAPI *pCryptExtOpenCER)(HWND,HINSTANCE,LPCSTR,DWORD);
+
+static void test_CryptExtOpenCER(void)
+{
+    HRESULT hr;
+
+    if (!pCryptExtOpenCER)
+    {
+        win_skip("CryptExtOpenCER is not available on this platform\n");
+        return;
+    }
+
+    if (!winetest_interactive)
+    {
+        skip("CryptExtOpenCER test needs user interaction\n");
+        return;
+    }
+
+    SetLastError(0xdeadbeef);
+    hr = pCryptExtOpenCER(0, 0, "dead.beef", SW_HIDE);
+    ok(hr == S_OK, "got %#x\n", hr);
+
+    hr = pCryptExtOpenCER(0, 0, "VeriSign Class 3 Public Primary Certification Authority - G4.txt", SW_SHOW);
+    ok(hr == S_OK, "got %#x\n", hr);
+}
+
+START_TEST(cryptext)
+{
+    HMODULE hmod = LoadLibraryA("cryptext.dll");
+
+    pCryptExtOpenCER = (void *)GetProcAddress(hmod, "CryptExtOpenCER");
+
+    test_CryptExtOpenCER();
+}
-- 
2.26.1

