From 652dfd43d603c33bc0be3bc0c849708d7e064a59 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 12 Aug 2018 01:20:20 +0200 Subject: Windows Installer: implement language selection mechanism at the start of the installer to make easier for international users. --- src/Common/Dlgcode.c | 18 ++++- src/Common/Language.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Common/Language.h | 1 + src/Common/Language.xml | 1 + 4 files changed, 221 insertions(+), 1 deletion(-) (limited to 'src/Common') diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 4d3fdc78..3485eb0b 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -3031,6 +3031,22 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine) // Language langId[0] = 0; SetPreferredLangId (ConfigReadString ("Language", "", langId, sizeof (langId))); + +#ifndef SETUP + if (langId[0] == 0) + { + // check if user selected a language during installation + WCHAR uiLang[6]; + ReadRegistryString (L"Software\\VeraCrypt", L"SetupUILanguage", L"", uiLang, sizeof (uiLang)); + if (0 < WideCharToMultiByte (CP_ACP, 0, uiLang, -1, langId, sizeof (langId), NULL, NULL)) + { + SetPreferredLangId (langId); + } + } + + // delete the registry key created by the installer (if any) + DeleteRegistryKey (HKEY_CURRENT_USER, L"Software\\VeraCrypt"); +#endif if (langId[0] == 0) { @@ -5529,7 +5545,7 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) a single digest. */ { - BYTE *digest [MAX_DIGESTSIZE]; + BYTE digest [MAX_DIGESTSIZE]; WHIRLPOOL_CTX wctx; RMD160_CTX rctx; sha512_ctx s2ctx; diff --git a/src/Common/Language.c b/src/Common/Language.c index 092bef48..bcf7b72f 100644 --- a/src/Common/Language.c +++ b/src/Common/Language.c @@ -383,6 +383,208 @@ BOOL LoadLanguageFile () return TRUE; } +BOOL LoadLanguageFromResource (int resourceid, BOOL bSetPreferredLanguage, BOOL bForceSilent) +{ + DWORD size; + BYTE *res; + char *xml, *header, *headerPtr; + char langId[16] = "en", attr[32768], key[128]; + BOOL defaultLangParsed = FALSE, langFound = FALSE; + WCHAR wattr[32768]; + int i, intKey, len; + +#ifdef TCMOUNT + int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_MOUNT_RSRC_HEADER, 0 }; +#endif + +#ifdef VOLFORMAT + int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_FORMAT_RSRC_HEADER, 0 }; +#endif + +#ifdef SETUP + int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_SETUP_RSRC_HEADER, 0 }; +#endif + + res = (char*) MapResource (L"Languages", resourceid, &size); + if (!res) + return FALSE; + + LocalizationActive = FALSE; + ActiveLangPackVersion[0] = 0; + ClearDictionaryPool (); + + xml = res; + xml = XmlFindElement (xml, "localization"); + if (!xml) + return FALSE; + + // Required VeraCrypt version + XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr)); + + // Search language id in language file + while (xml = XmlFindElement (xml, "language")) + { + XmlGetAttributeText (xml, "langid", attr, sizeof (attr)); + if (strlen (attr)) + { + StringCbCopyA (langId, sizeof (langId), attr); + XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion)); + langFound = TRUE; + break; + } + xml++; + } + + if (!langFound) return FALSE; + + // Create font dictionary + xml = (char *) res; + while (xml = XmlFindElement (xml, "font")) + { + XmlGetAttributeText (xml, "lang", attr, sizeof (attr)); + if (strcmp (attr, langId) == 0) + { + Font font; + memset (&font, 0, sizeof (font)); + + XmlGetAttributeText (xml, "face", attr, sizeof (attr)); + + len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0])); + font.FaceName = AddPoolData ((void *) wattr, len * 2); + + XmlGetAttributeText (xml, "size", attr, sizeof (attr)); + sscanf (attr, "%d", &font.Size); + + StringCbCopyA (attr, sizeof(attr), "font_"); + XmlGetAttributeText (xml, "class", attr + 5, sizeof (attr) - 5); + AddDictionaryEntry ( + AddPoolData ((void *) attr, strlen (attr) + 1), 0, + AddPoolData ((void *) &font, sizeof(font))); + } + + xml++; + } + + xml = (char *) res; + while (xml = XmlFindElement (xml, "entry")) + { + void *key; + void *text; + + XmlGetAttributeText (xml, "lang", attr, sizeof (attr)); + if (strcmp (attr, langId) == 0) + { + if (XmlGetAttributeText (xml, "key", attr, sizeof (attr))) + { + key = AddPoolData (attr, strlen (attr) + 1); + if (key == NULL) return FALSE; + + XmlGetNodeText (xml, attr, sizeof (attr)); + + // Parse \ escape sequences + { + char *in = attr, *out = attr; + while (*in) + { + if (*in == '\\') + { + in++; + switch (*in++) + { + case '\\': *out++ = '\\'; break; + case 't': *out++ = '\t'; break; + case 'n': *out++ = 13; *out++ = 10; break; + default: + if (!bForceSilent) + MessageBoxA (0, key, "VeraCrypt: Unknown '\\' escape sequence in string", MB_ICONERROR); + return FALSE; + } + } + else + *out++ = *in++; + } + *out = 0; + } + + // UTF8 => wide char + len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0])); + if (len == 0) + { + if (!bForceSilent) + MessageBoxA (0, key, "VeraCrypt: Error while decoding UTF-8 string", MB_ICONERROR); + return FALSE; + } + + // Add to dictionary + text = AddPoolData ((void *) wattr, len * 2); + if (text == NULL) return FALSE; + + AddDictionaryEntry ((char *) key, 0, text); + } + } + + xml++; + } + + defaultLangParsed = TRUE; + + LocalizationActive = strcmp (langId, "en") != 0; + LocalizationSerialNo++; + + if (bSetPreferredLanguage) + StringCbCopyA (PreferredLangId, sizeof (PreferredLangId), langId); + + // Create control ID dictionary + + // Default controls + AddDictionaryEntry (NULL, 1, GetString ("IDOK")); + AddDictionaryEntry (NULL, 2, GetString ("IDCANCEL")); + AddDictionaryEntry (NULL, 8, GetString ("IDCLOSE")); + AddDictionaryEntry (NULL, 9, GetString ("IDHELP")); + + for (i = 0; headers[i] != 0; i++) + { + if (HeaderResource[i] == NULL) + { + HeaderResource[i] = MapResource (L"Header", headers[i], &size); + if (HeaderResource[i]) + HeaderResourceSize[i] = size; + } + + headerPtr = NULL; + if (HeaderResource[i]) + { + headerPtr = (char*) malloc (HeaderResourceSize[i] + 1); + if (headerPtr) + { + memcpy (headerPtr, HeaderResource[i], HeaderResourceSize[i]); + headerPtr [HeaderResourceSize[i]] = 0; + } + } + + header = headerPtr; + if (header == NULL) return FALSE; + header--; + + do + { + header++; + if (sscanf (header, "#define %127s %d", key, &intKey) == 2) + { + WCHAR *str = GetString (key); + + if (str != UnknownString) + AddDictionaryEntry (NULL, intKey, str); + } + + } while ((header = strchr (header, '\n')) != NULL); + + free (headerPtr); + } + + return TRUE; +} + // lParam = 1: auto mode BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) diff --git a/src/Common/Language.h b/src/Common/Language.h index 7ef75ef3..4a87ceda 100644 --- a/src/Common/Language.h +++ b/src/Common/Language.h @@ -34,6 +34,7 @@ BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa wchar_t *GetString (const char *stringId); Font *GetFont (char *fontType); BOOL LoadLanguageFile (); +BOOL LoadLanguageFromResource (int resourceid, BOOL bSetPreferredLanguage, BOOL bForceSilent); char *GetPreferredLangId (); void SetPreferredLangId (char *langId); char *GetActiveLangPackVersion (); diff --git a/src/Common/Language.xml b/src/Common/Language.xml index dc5ab171..9073dc1e 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1423,6 +1423,7 @@ It is currently not possible to encrypt a system if SecureBoot is enabled and if VeraCrypt custom keys are not loaded into the machine firmware. SecureBoot needs to be disabled in the BIOS configuration in order to allow system encryption to proceed. Pasted text truncated because the password maximum length is 64 characters Password already reached its maximum length of 64 characters.\nNo additional character is allowed. + Select the language to use during the installation: -- cgit v1.2.3