VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Common/Dlgcode.c18
-rw-r--r--src/Common/Language.c202
-rw-r--r--src/Common/Language.h1
-rw-r--r--src/Common/Language.xml1
-rw-r--r--src/Setup/Resource.h23
-rw-r--r--src/Setup/Setup.c139
-rw-r--r--src/Setup/Setup.rc41
-rw-r--r--src/Setup/Wizard.c11
8 files changed, 430 insertions, 6 deletions
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 4d3fdc7..3485eb0 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 092bef4..bcf7b72 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 7ef75ef..4a87ced 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 dc5ab17..9073dc1 100644
--- a/src/Common/Language.xml
+++ b/src/Common/Language.xml
@@ -1423,6 +1423,7 @@
<entry lang="en" key="SYSENC_EFI_UNSUPPORTED_SECUREBOOT">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.</entry>
<entry lang="en" key="PASSWORD_PASTED_TRUNCATED">Pasted text truncated because the password maximum length is 64 characters</entry>
<entry lang="en" key="PASSWORD_MAXLENGTH_REACHED">Password already reached its maximum length of 64 characters.\nNo additional character is allowed.</entry>
+ <entry lang="en" key="IDC_SELECT_LANGUAGE_LABEL">Select the language to use during the installation:</entry>
</localization>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="VeraCrypt">
diff --git a/src/Setup/Resource.h b/src/Setup/Resource.h
index 8feaf3d..8882d67 100644
--- a/src/Setup/Resource.h
+++ b/src/Setup/Resource.h
@@ -3,6 +3,20 @@
// Used by Setup.rc
//
#define IDR_COMREG 10
+#define IDR_LANG_AR 20
+#define IDR_LANG_CS 21
+#define IDR_LANG_DE 22
+#define IDR_LANG_ES 23
+#define IDR_LANG_FR 24
+#define IDR_LANG_IT 25
+#define IDR_LANG_JA 26
+#define IDR_LANG_NL 27
+#define IDR_LANG_PL 28
+#define IDR_LANG_RO 29
+#define IDR_LANG_RU 30
+#define IDR_LANG_VI 31
+#define IDR_LANG_ZHCN 32
+#define IDR_LANG_ZHHK 33
#define IDD_INSTALL 101
#define IDD_INSTALL_OPTIONS_PAGE_DLG 102
#define IDD_UNINSTALL 103
@@ -17,6 +31,7 @@
#define IDD_WIZARD_MODE_PAGE_DLG 112
#define IDD_PROGRESS_PAGE_DLG 113
#define IDD_DONATIONS_PAGE_DLG 114
+#define IDD_INSTALL_LANGUAGE 115
#define IDC_DESTINATION 1000
#define IDC_BOX_TITLE 1001
#define IDC_BROWSE 1002
@@ -50,15 +65,17 @@
#define IDC_BITMAP_SETUP_WIZARD 1030
#define IDC_MAIN_CONTENT_CANVAS 1031
#define IDC_DONATE 1032
+#define IDC_LANGUAGES_LIST 1033
+#define IDC_SELECT_LANGUAGE_LABEL 1034
// Next default values for new objects
-//
+//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
-#define _APS_NEXT_RESOURCE_VALUE 115
+#define _APS_NEXT_RESOURCE_VALUE 116
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1033
+#define _APS_NEXT_CONTROL_VALUE 1035
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c
index 485d333..986bc12 100644
--- a/src/Setup/Setup.c
+++ b/src/Setup/Setup.c
@@ -1,4 +1,4 @@
-/*
+/*
Legal Notice: Some portions of the source code contained in this file were
derived from the source code of TrueCrypt 7.1a, which is
Copyright (c) 2003-2012 TrueCrypt Developers Association and which is
@@ -78,6 +78,8 @@ BOOL bRegisterFileExt = TRUE;
BOOL bAddToStartMenu = TRUE;
BOOL bDesktopIcon = TRUE;
+BOOL bUserSetLanguage = FALSE;
+
BOOL bDesktopIconStatusDetermined = FALSE;
HMODULE volatile SystemRestoreDll = 0;
@@ -2374,6 +2376,137 @@ BOOL CALLBACK UninstallDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lP
}
#endif
+typedef struct
+{
+ LPCWSTR name;
+ int resourceid;
+ WORD langid;
+ LPCSTR internalId;
+ LPCWSTR langtag;
+} tLanguageEntry;
+
+static tLanguageEntry g_languagesEntries[] = {
+ {L"العربية", IDR_LANG_AR, LANG_ARABIC, "ar", NULL},
+ {L"Čeština", IDR_LANG_CS, LANG_CZECH, "cs", NULL},
+ {L"Deutsch", IDR_LANG_DE, LANG_GERMAN, "de", NULL},
+ {L"English", IDR_LANGUAGE, LANG_ENGLISH, "en", NULL},
+ {L"Español", IDR_LANG_ES, LANG_SPANISH, "es", NULL},
+ {L"Français", IDR_LANG_FR, LANG_FRENCH, "fr", NULL},
+ {L"Italiano", IDR_LANG_IT, LANG_ITALIAN, "it", NULL},
+ {L"日本語", IDR_LANG_JA, LANG_JAPANESE, "ja", NULL},
+ {L"Nederlands", IDR_LANG_NL, LANG_DUTCH, "nl", NULL},
+ {L"Polski", IDR_LANG_PL, LANG_POLISH, "pl", NULL},
+ {L"Română", IDR_LANG_RO, LANG_ROMANIAN, "ro", NULL},
+ {L"Русский", IDR_LANG_RU, LANG_RUSSIAN, "ru", NULL},
+ {L"Tiếng Việt", IDR_LANG_VI, LANG_VIETNAMESE, "vi", NULL},
+ {L"简体中文", IDR_LANG_ZHCN, LANG_CHINESE, "zh-cn", L"zh-CN"},
+ {L"繁體中文", IDR_LANG_ZHHK, LANG_CHINESE, "zh-hk", L"zh-HK"},
+};
+
+typedef int (WINAPI *LCIDToLocaleNameFn)(
+ LCID Locale,
+ LPWSTR lpName,
+ int cchName,
+ DWORD dwFlags);
+
+static void UpdateSelectLanguageDialog (HWND hwndDlg)
+{
+ HWND hLangList = GetDlgItem (hwndDlg, IDC_LANGUAGES_LIST);
+ LPARAM nIndex = SendMessage (hLangList, CB_GETCURSEL, 0, 0);
+ int resourceid = (int) SendMessage (hLangList, CB_GETITEMDATA, nIndex, 0);
+
+ LoadLanguageFromResource (resourceid, TRUE, TRUE);
+
+ LocalizeDialog (hwndDlg, "IDD_INSTL_DLG");
+}
+
+BOOL CALLBACK SelectLanguageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ WORD lw = LOWORD (wParam);
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ char* preferredLanguage = GetPreferredLangId ();
+ if (strlen (preferredLanguage))
+ {
+ // language already selected by user in current install
+ // use it for the setup
+ for (size_t i = 0; i < ARRAYSIZE (g_languagesEntries); i++)
+ {
+ if (0 == strcmp (preferredLanguage, g_languagesEntries[i].internalId))
+ {
+ LoadLanguageFromResource (g_languagesEntries[i].resourceid, FALSE, TRUE);
+ break;
+ }
+ }
+ EndDialog (hwndDlg, IDCANCEL);
+ return FALSE;
+ }
+ else
+ {
+ // Get the default UI language
+ LCIDToLocaleNameFn LCIDToLocaleNamePtr = (LCIDToLocaleNameFn) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "LCIDToLocaleName");
+ WCHAR langtag[256];
+ LANGID defaultLanguage = GetUserDefaultUILanguage ();
+ WORD langid = (WORD) (defaultLanguage & 0x03FF); // primary language ID
+
+ InitDialog (hwndDlg);
+
+ LCIDToLocaleNamePtr (MAKELCID (defaultLanguage, 0), langtag, ARRAYSIZE (langtag), 0); // language tag (e.g. "en-US")
+ int resourceid = IDR_LANGUAGE;
+ for (size_t i = 0; i < ARRAYSIZE (g_languagesEntries); i++)
+ {
+ if (g_languagesEntries[i].langid == langid)
+ {
+ if (!g_languagesEntries[i].langtag || (0 == _wcsicmp (g_languagesEntries[i].langtag, langtag)))
+ {
+ resourceid = g_languagesEntries[i].resourceid;
+ break;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < ARRAYSIZE (g_languagesEntries); i++)
+ {
+ AddComboPair (GetDlgItem (hwndDlg, IDC_LANGUAGES_LIST), g_languagesEntries[i].name, g_languagesEntries[i].resourceid);
+ }
+
+ SelectAlgo (GetDlgItem (hwndDlg, IDC_LANGUAGES_LIST), &resourceid);
+
+ UpdateSelectLanguageDialog (hwndDlg);
+ }
+
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ if (CBN_SELCHANGE == HIWORD (wParam))
+ {
+ UpdateSelectLanguageDialog (hwndDlg);
+ return 1;
+ }
+
+ if (lw == IDOK)
+ {
+ bUserSetLanguage = TRUE;
+ EndDialog (hwndDlg, IDOK);
+ return 1;
+ }
+
+ if (lw == IDCANCEL)
+ {
+ SetPreferredLangId ("");
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+ return 0;
+ }
+
+ return 0;
+}
+
int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpszCommandLine, int nCmdShow)
{
@@ -2525,6 +2658,10 @@ int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, wchar_t *lpsz
if (!bUninstall)
{
+ if (!bDevm && !LocalizationActive && (nCurrentOS >= WIN_VISTA))
+ {
+ DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_INSTALL_LANGUAGE), NULL, (DLGPROC) SelectLanguageDialogProc, (LPARAM) 0 );
+ }
/* Create the main dialog for install */
DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_INSTL_DLG), NULL, (DLGPROC) MainDialogProc,
diff --git a/src/Setup/Setup.rc b/src/Setup/Setup.rc
index 587fc84..096a6d9 100644
--- a/src/Setup/Setup.rc
+++ b/src/Setup/Setup.rc
@@ -76,6 +76,26 @@ IDR_COMREG REGISTRY "ComSetup.rgs"
/////////////////////////////////////////////////////////////////////////////
//
+// LANGUAGES
+//
+
+IDR_LANG_AR LANGUAGES "..\\..\\Translations\\Language.ar.xml"
+IDR_LANG_CS LANGUAGES "..\\..\\Translations\\Language.cs.xml"
+IDR_LANG_DE LANGUAGES "..\\..\\Translations\\Language.de.xml"
+IDR_LANG_ES LANGUAGES "..\\..\\Translations\\Language.es.xml"
+IDR_LANG_FR LANGUAGES "..\\..\\Translations\\Language.fr.xml"
+IDR_LANG_IT LANGUAGES "..\\..\\Translations\\Language.it.xml"
+IDR_LANG_JA LANGUAGES "..\\..\\Translations\\Language.ja.xml"
+IDR_LANG_NL LANGUAGES "..\\..\\Translations\\Language.nl.xml"
+IDR_LANG_PL LANGUAGES "..\\..\\Translations\\Language.pl.xml"
+IDR_LANG_RO LANGUAGES "..\\..\\Translations\\Language.ro.xml"
+IDR_LANG_RU LANGUAGES "..\\..\\Translations\\Language.ru.xml"
+IDR_LANG_VI LANGUAGES "..\\..\\Translations\\Language.vi.xml"
+IDR_LANG_ZHCN LANGUAGES "..\\..\\Translations\\Language.zh-cn.xml"
+IDR_LANG_ZHHK LANGUAGES "..\\..\\Translations\\Language.zh-hk.xml"
+
+/////////////////////////////////////////////////////////////////////////////
+//
// Dialog
//
@@ -185,6 +205,17 @@ BEGIN
PUSHBUTTON "Donate now...",IDC_DONATE,124,94,96,14
END
+IDD_INSTALL_LANGUAGE DIALOGEX 0, 0, 213, 87
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "VeraCrypt Setup Wizard"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,102,66,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,156,66,50,14
+ ICON 501,IDC_STATIC,10,10,32,32
+ LTEXT "Select the language to use during the installation:",IDC_SELECT_LANGUAGE_LABEL,42,13,157,26
+ COMBOBOX IDC_LANGUAGES_LIST,42,44,164,155,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+END
/////////////////////////////////////////////////////////////////////////////
//
@@ -228,7 +259,7 @@ END
//
#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
+GUIDELINES DESIGNINFO
BEGIN
IDD_UNINSTALL, DIALOG
BEGIN
@@ -299,6 +330,14 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 147
END
+
+ IDD_INSTALL_LANGUAGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 206
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 80
+ END
END
#endif // APSTUDIO_INVOKED
diff --git a/src/Setup/Wizard.c b/src/Setup/Wizard.c
index 0303f2e..94e3aae 100644
--- a/src/Setup/Wizard.c
+++ b/src/Setup/Wizard.c
@@ -24,6 +24,7 @@
#include "Common/Resource.h"
#include "Resource.h"
#include "Setup.h"
+#include "Registry.h"
#include <tchar.h>
#include <Strsafe.h>
@@ -60,6 +61,8 @@ BOOL bInProgress = FALSE;
BOOL bPromptTutorial = FALSE;
BOOL bPromptReleaseNotes = FALSE;
+extern BOOL bUserSetLanguage;
+
int nPbar = 0; /* Control ID of progress bar */
static HFONT hDonTextFont;
@@ -1069,6 +1072,14 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
/* Installation completed successfully */
+ /* if user selected a language, use for GUI in the next run */
+ if (bUserSetLanguage)
+ {
+ WCHAR langId[6];
+ MultiByteToWideChar (CP_ACP, 0, GetPreferredLangId(), -1, langId, ARRAYSIZE (langId));
+ WriteRegistryString (L"Software\\VeraCrypt", L"SetupUILanguage", langId);
+ }
+
bInProgress = FALSE;
nCurPageNo = DONATIONS_PAGE;