VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Language.c
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2018-08-13 14:52:52 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2018-08-13 15:20:07 +0200
commit17af27bc7fa82030084c3c3065f9516bfb88a899 (patch)
treeb09132ba99f571f93a1732bab31d7b759091670b /src/Common/Language.c
parent68fe28af429bcea4996e1fd57b8c4159ec076290 (diff)
downloadVeraCrypt-17af27bc7fa82030084c3c3065f9516bfb88a899.tar.gz
VeraCrypt-17af27bc7fa82030084c3c3065f9516bfb88a899.zip
Windows: code enhancements for language selection mechanism in the installer.
Diffstat (limited to 'src/Common/Language.c')
-rw-r--r--src/Common/Language.c357
1 files changed, 103 insertions, 254 deletions
diff --git a/src/Common/Language.c b/src/Common/Language.c
index bcf7b72f..ba0b6d19 100644
--- a/src/Common/Language.c
+++ b/src/Common/Language.c
@@ -44,6 +44,7 @@ static DWORD LanguageResourceSize = 0;
static char *HeaderResource[2] = {NULL, NULL};
static DWORD HeaderResourceSize[2] = {0, 0};
static char ActiveLangPackVersion[6] = {0};
+static int LanguageResourceId = 0;
static char *MapFirstLanguageFile ()
{
@@ -59,6 +60,8 @@ static char *MapFirstLanguageFile ()
LanguageFileBuffer = NULL;
}
+ LanguageResourceId = 0;
+
if (LanguageResource == NULL)
{
DWORD size;
@@ -81,7 +84,7 @@ static char *MapFirstLanguageFile ()
}
-static char *MapNextLanguageFile ()
+static char *MapNextLanguageFile (int resourceid)
{
wchar_t f[TC_MAX_PATH*2], *t;
WIN32_FIND_DATAW find;
@@ -96,67 +99,90 @@ static char *MapNextLanguageFile ()
LanguageFileBuffer = NULL;
}
- if (LanguageFileFindHandle == INVALID_HANDLE_VALUE)
+ if (resourceid == 0)
{
- GetModuleFileNameW (NULL, f, sizeof (f) / sizeof (f[0]));
- t = wcsrchr (f, L'\\');
- if (t == NULL) return NULL;
+ if (LanguageFileFindHandle == INVALID_HANDLE_VALUE)
+ {
+ GetModuleFileNameW (NULL, f, sizeof (f) / sizeof (f[0]));
+ t = wcsrchr (f, L'\\');
+ if (t == NULL) return NULL;
- *t = 0;
- StringCbCatW (f, sizeof(f), L"\\Languages\\Language*.xml");
+ *t = 0;
+ StringCbCatW (f, sizeof(f), L"\\Languages\\Language*.xml");
- LanguageFileFindHandle = FindFirstFileW (f, &find);
- }
- else if (!FindNextFileW (LanguageFileFindHandle, &find))
- {
- FindClose (LanguageFileFindHandle);
- LanguageFileFindHandle = INVALID_HANDLE_VALUE;
- return NULL;
- }
+ LanguageFileFindHandle = FindFirstFileW (f, &find);
+ }
+ else if (!FindNextFileW (LanguageFileFindHandle, &find))
+ {
+ FindClose (LanguageFileFindHandle);
+ LanguageFileFindHandle = INVALID_HANDLE_VALUE;
+ return NULL;
+ }
- if (LanguageFileFindHandle == INVALID_HANDLE_VALUE) return NULL;
- if (find.nFileSizeHigh != 0) return NULL;
+ if (LanguageFileFindHandle == INVALID_HANDLE_VALUE) return NULL;
+ if (find.nFileSizeHigh != 0) return NULL;
- LanguageFileBuffer = malloc(find.nFileSizeLow + 1);
- if (LanguageFileBuffer == NULL) return NULL;
+ LanguageFileBuffer = malloc(find.nFileSizeLow + 1);
+ if (LanguageFileBuffer == NULL) return NULL;
- GetModuleFileNameW (NULL, f, sizeof (f) / sizeof(f[0]));
- t = wcsrchr (f, L'\\');
- if (t == NULL)
- {
- free(LanguageFileBuffer);
- LanguageFileBuffer = NULL;
- return NULL;
- }
+ GetModuleFileNameW (NULL, f, sizeof (f) / sizeof(f[0]));
+ t = wcsrchr (f, L'\\');
+ if (t == NULL)
+ {
+ free(LanguageFileBuffer);
+ LanguageFileBuffer = NULL;
+ return NULL;
+ }
- t[1] = 0;
- StringCbCatW (f, sizeof(f), L"Languages\\");
- StringCbCatW (f, sizeof(f),find.cFileName);
+ t[1] = 0;
+ StringCbCatW (f, sizeof(f), L"Languages\\");
+ StringCbCatW (f, sizeof(f),find.cFileName);
- file = CreateFileW (f, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (file == INVALID_HANDLE_VALUE)
- {
- free(LanguageFileBuffer);
- LanguageFileBuffer = NULL;
- return NULL;
- }
+ file = CreateFileW (f, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ {
+ free(LanguageFileBuffer);
+ LanguageFileBuffer = NULL;
+ return NULL;
+ }
- bStatus = ReadFile (file, LanguageFileBuffer, find.nFileSizeLow, &read, NULL);
- CloseHandle (file);
- if (!bStatus || (read != find.nFileSizeLow))
- {
- free(LanguageFileBuffer);
- LanguageFileBuffer = NULL;
- return NULL;
+ bStatus = ReadFile (file, LanguageFileBuffer, find.nFileSizeLow, &read, NULL);
+ CloseHandle (file);
+ if (!bStatus || (read != find.nFileSizeLow))
+ {
+ free(LanguageFileBuffer);
+ LanguageFileBuffer = NULL;
+ return NULL;
+ }
+
+ LanguageFileBuffer [find.nFileSizeLow] = 0; // we have allocated (find.nFileSizeLow + 1) bytes
}
+ else if (LanguageResourceId != resourceid)
+ {
+ DWORD size;
+
+ LanguageResourceId = resourceid;
+
+ LanguageResource = MapResource (L"Languages", LanguageResourceId, &size);
+ if (LanguageResource)
+ LanguageResourceSize = size;
- LanguageFileBuffer [find.nFileSizeLow] = 0; // we have allocated (find.nFileSizeLow + 1) bytes
+ if (LanguageResource)
+ {
+ LanguageFileBuffer = malloc(LanguageResourceSize + 1);
+ if (LanguageFileBuffer)
+ {
+ memcpy (LanguageFileBuffer, LanguageResource, LanguageResourceSize);
+ LanguageFileBuffer[LanguageResourceSize] = 0;
+ }
+ }
+ }
return LanguageFileBuffer;
}
-BOOL LoadLanguageFile ()
+static BOOL LoadLanguageData (int resourceid, BOOL bForceSetPreferredLanguage, BOOL bForceSilent)
{
DWORD size;
BYTE *res;
@@ -184,11 +210,11 @@ BOOL LoadLanguageFile ()
ActiveLangPackVersion[0] = 0;
ClearDictionaryPool ();
- if (PreferredLangId[0] != 0)
+ if ((resourceid == 0) && (PreferredLangId[0] != 0))
StringCbCopyA (langId, sizeof(langId), PreferredLangId);
// Parse all available language files until preferred language is found
- for (res = MapFirstLanguageFile (); res != NULL; res = MapNextLanguageFile ())
+ for (res = MapFirstLanguageFile (); res != NULL; res = MapNextLanguageFile (resourceid))
{
xml = (char *) res;
xml = XmlFindElement (xml, "localization");
@@ -203,7 +229,8 @@ BOOL LoadLanguageFile ()
{
wchar_t m[2048];
StringCbPrintfW (m, sizeof(m), L"The installed language pack is incompatible with this version of VeraCrypt (the language pack is for VeraCrypt %hs). A newer version may be available at www.idrix.fr.\n\nTo prevent this message from being displayed, do any of the following:\n\n- Select 'Settings' > 'Language'; then select 'English' and click 'OK'.\n\n- Remove or replace the language pack with a compatible version (the language pack may reside e.g. in 'C:\\Program Files\\VeraCrypt' or '%%LOCALAPPDATA%%\\VirtualStore\\Program Files\\VeraCrypt', etc.)", attr);
- MessageBoxW (NULL, m, L"VeraCrypt", MB_ICONERROR);
+ if (!bForceSilent)
+ MessageBoxW (NULL, m, L"VeraCrypt", MB_ICONERROR);
continue;
}
@@ -213,13 +240,23 @@ BOOL LoadLanguageFile ()
while (xml = XmlFindElement (xml, "language"))
{
XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
- if (strcmp (attr, langId) == 0)
+ if (resourceid == 0)
+ {
+ if (strcmp (attr, langId) == 0)
+ {
+ XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion));
+ langFound = TRUE;
+ break;
+ }
+ xml++;
+ }
+ else
{
+ StringCbCopyA (langId, sizeof (langId), attr);
XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion));
langFound = TRUE;
break;
}
- xml++;
}
if (!langFound) continue;
@@ -288,7 +325,8 @@ BOOL LoadLanguageFile ()
case 't': *out++ = '\t'; break;
case 'n': *out++ = 13; *out++ = 10; break;
default:
- MessageBoxA (0, key, "VeraCrypt: Unknown '\\' escape sequence in string", MB_ICONERROR);
+ if (!bForceSilent)
+ MessageBoxA (0, key, "VeraCrypt: Unknown '\\' escape sequence in string", MB_ICONERROR);
return FALSE;
}
}
@@ -302,7 +340,8 @@ BOOL LoadLanguageFile ()
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
if (len == 0)
{
- MessageBoxA (0, key, "VeraCrypt: Error while decoding UTF-8 string", MB_ICONERROR);
+ if (!bForceSilent)
+ MessageBoxA (0, key, "VeraCrypt: Error while decoding UTF-8 string", MB_ICONERROR);
return FALSE;
}
@@ -324,7 +363,7 @@ BOOL LoadLanguageFile ()
if (!defaultLangParsed)
{
defaultLangParsed = TRUE;
- if (langId[0] == 0 || strcmp (langId, "en") == 0)
+ if ((resourceid == 0) && (langId[0] == 0 || strcmp (langId, "en") == 0))
break;
}
}
@@ -332,6 +371,9 @@ BOOL LoadLanguageFile ()
LocalizationActive = langFound && strcmp (langId, "en") != 0;
LocalizationSerialNo++;
+ if (bForceSetPreferredLanguage)
+ StringCbCopyA (PreferredLangId, sizeof (PreferredLangId), langId);
+
// Create control ID dictionary
// Default controls
@@ -383,208 +425,15 @@ BOOL LoadLanguageFile ()
return TRUE;
}
-BOOL LoadLanguageFromResource (int resourceid, BOOL bSetPreferredLanguage, BOOL bForceSilent)
+BOOL LoadLanguageFile ()
{
- 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;
+ return LoadLanguageData (0, FALSE, FALSE);
}
+BOOL LoadLanguageFromResource (int resourceid, BOOL bSetPreferredLanguage, BOOL bForceSilent)
+{
+ return LoadLanguageData (resourceid, bSetPreferredLanguage, bForceSilent);
+}
// lParam = 1: auto mode
BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -606,7 +455,7 @@ BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa
LocalizeDialog (hwndDlg, "IDD_LANGUAGE");
ToHyperlink (hwndDlg, IDC_GET_LANG_PACKS);
- for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile ())
+ for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile (0))
{
while (xml = XmlFindElement (xml, "language"))
{