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; }