diff --git a/src/dialogs.h b/src/dialogs.h
index 217b0d0..4510fb5 100644
--- a/src/dialogs.h
+++ b/src/dialogs.h
@@ -1,78 +1,81 @@
/* dialogs.h
Resouces IDs for the dialogs.
*/
#ifndef DIALOGS_H
#define DIALOGS_H
#define IDB_LOGO 0x1060
/* Ids for the extended options dialog. */
#define IDD_EXT_OPTIONS 0x4110
#define IDC_T_DEBUG_LOGFILE 0x4120
#define IDC_DEBUG_LOGFILE 0x4130
/* Ids used for the main config dialog. */
#define IDD_GPG_OPTIONS 0x5000
#define IDD_ADDIN_OPTIONS 0x5001
#define IDC_TIME_PHRASES 0x5010
#define IDC_ENCRYPT_DEFAULT 0x5020
#define IDC_SIGN_DEFAULT 0x5030
#define IDC_ENCRYPT_WITH_STANDARD_KEY 0x5040
#define IDC_OPENPGP_DEFAULT 0x5050
#define IDC_SMIME_DEFAULT 0x5060
#define IDC_GPG_OPTIONS 0x5070
#define IDC_ADDIN_OPTIONS 0x5071
#define IDC_BITMAP 0x5080
#define IDC_VERSION_INFO 0x5090
#define IDC_ENCRYPT_TO 0x50A0
#define IDC_ENABLE_SMIME 0x50B0
#define IDC_PREVIEW_DECRYPT 0x50C0
#define IDC_PREFER_HTML 0x50D0
#define IDC_G_GENERAL 0x50E0
#define IDC_G_SEND 0x50F0
#define IDC_G_RECV 0x5100
#define IDC_BODY_AS_ATTACHMENT 0x5110
#define IDC_GPG_CONF 0x5120
#define IDC_G10CODE_STRING 0x5130
#define IDC_GPG4WIN_STRING 0x5131
#define IDC_START_CERTMAN 0x5132
#define IDC_MIME_UI 0x5133
#define IDC_INLINE_PGP 0x5134
#define IDC_AUTORRESOLVE 0x5135
#define IDC_REPLYCRYPT 0x5136
/* Ids for PNG Images */
#define IDI_ENCRYPT_16_PNG 0x6000
#define IDI_ENCRYPT_48_PNG 0x6010
#define IDI_DECRYPT_16_PNG 0x6020
#define IDI_DECRYPT_48_PNG 0x6030
#define IDI_ENCSIGN_FILE_48_PNG 0x6050
#define IDI_SIGN_48_PNG 0x6060
#define IDI_VERIFY_48_PNG 0x6070
#define IDI_EMBLEM_WARNING_64_PNG 0x6071
#define IDI_EMBLEM_QUESTION_64_PNG 0x6074
#define IDI_SIGN_ENCRYPT_40_PNG 0x6075
#define IDI_ENCRYPT_20_PNG 0x6076
#define IDI_SIGN_20_PNG 0x6077
#define IDI_GPGOL_LOCK_ICON 0x6078
/* Status icons */
#define ENCRYPT_ICON_OFFSET 0x10
#define IDI_LEVEL_0 0x6080
#define IDI_LEVEL_1 0x6081
#define IDI_LEVEL_2 0x6082
#define IDI_LEVEL_3 0x6083
#define IDI_LEVEL_4 0x6084
#define IDI_LEVEL_0_ENC (IDI_LEVEL_0 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_1_ENC (IDI_LEVEL_1 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_2_ENC (IDI_LEVEL_2 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_3_ENC (IDI_LEVEL_3 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_4_ENC (IDI_LEVEL_4 + ENCRYPT_ICON_OFFSET)
+/* Other ids */
+#define DISPID_MLANG_CHARSET 0x7000
+
#endif /*DIALOGS_H*/
diff --git a/src/mlang-charset.cpp b/src/mlang-charset.cpp
index e9b327a..0529856 100644
--- a/src/mlang-charset.cpp
+++ b/src/mlang-charset.cpp
@@ -1,125 +1,139 @@
/* @file mlang-charset.cpp
* @brief Convert between charsets using Mlang
*
* Copyright (C) 2015 by Bundesamt für Sicherheit in der Informationstechnik
* Software engineering by Intevation GmbH
*
* This file is part of GpgOL.
*
* GpgOL 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.
*
* GpgOL 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 program; if not, see .
*/
#include "config.h"
#include "common.h"
#define INITGUID
#include
DEFINE_GUID (IID_IMultiLanguage, 0x275c23e1,0x3747,0x11d0,0x9f,
0xea,0x00,0xaa,0x00,0x3f,0x86,0x46);
#include
#undef INITGUID
+#include "dialogs.h"
+#include "dispcache.h"
+
#include "mlang-charset.h"
char *ansi_charset_to_utf8 (const char *charset, const char *input,
size_t inlen, int codepage)
{
LPMULTILANGUAGE multilang = NULL;
MIMECSETINFO mime_info;
HRESULT err;
DWORD enc;
DWORD mode = 0;
unsigned int wlen = 0,
uinlen = 0;
wchar_t *buf;
char *ret;
if ((!charset || !strlen (charset)) && !codepage)
{
log_debug ("%s:%s: No charset / codepage returning plain.",
SRCNAME, __func__);
return xstrdup (input);
}
- CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
- IID_IMultiLanguage, (void**)&multilang);
- memdbg_addRef (multilang);
+ auto cache = DispCache::instance ();
+ LPDISPATCH cachedLang = cache->getDisp (DISPID_MLANG_CHARSET);
+
+ if (!cachedLang)
+ {
+ CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
+ IID_IMultiLanguage, (void**)&multilang);
+ memdbg_addRef (multilang);
+ cache->addDisp (DISPID_MLANG_CHARSET, (LPDISPATCH) multilang);
+ }
+ else
+ {
+ multilang = (LPMULTILANGUAGE) cachedLang;
+ }
+
if (!multilang)
{
log_error ("%s:%s: Failed to get multilang obj.",
SRCNAME, __func__);
return NULL;
}
if (inlen > UINT_MAX)
{
log_error ("%s:%s: Inlen too long. Bug.",
SRCNAME, __func__);
gpgol_release (multilang);
return NULL;
}
uinlen = (unsigned int) inlen;
if (!codepage)
{
mime_info.uiCodePage = 0;
mime_info.uiInternetEncoding = 0;
BSTR w_charset = utf8_to_wchar (charset);
err = multilang->GetCharsetInfo (w_charset, &mime_info);
xfree (w_charset);
if (err != S_OK)
{
log_error ("%s:%s: Failed to find charset for: %s",
SRCNAME, __func__, charset);
gpgol_release (multilang);
return xstrdup (input);
}
enc = (mime_info.uiInternetEncoding == 0) ? mime_info.uiCodePage :
mime_info.uiInternetEncoding;
}
else
{
enc = codepage;
}
/** Get the size of the result */
err = multilang->ConvertStringToUnicode(&mode, enc, const_cast(input),
&uinlen, NULL, &wlen);
if (FAILED (err))
{
log_error ("%s:%s: Failed conversion.",
SRCNAME, __func__);
gpgol_release (multilang);
return NULL;
}
buf = (wchar_t*) xmalloc(sizeof(wchar_t) * (wlen + 1));
err = multilang->ConvertStringToUnicode(&mode, enc, const_cast(input),
&uinlen, buf, &wlen);
- gpgol_release (multilang);
if (FAILED (err))
{
log_error ("%s:%s: Failed conversion 2.",
SRCNAME, __func__);
xfree (buf);
return NULL;
}
/* Doc is not clear if this is terminated. */
buf[wlen] = L'\0';
ret = wchar_to_utf8 (buf);
xfree (buf);
return ret;
}