VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/Language.c
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2018-08-12 01:20:20 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2018-08-12 18:30:21 +0200
commit652dfd43d603c33bc0be3bc0c849708d7e064a59 (patch)
tree4c158528097a43262d7e88388ec3bd9c84a9dee0 /src/Common/Language.c
parent012f7bfa93c31143be57cb01ac747f7961b2e534 (diff)
downloadVeraCrypt-652dfd43d603c33bc0be3bc0c849708d7e064a59.tar.gz
VeraCrypt-652dfd43d603c33bc0be3bc0c849708d7e064a59.zip
Windows Installer: implement language selection mechanism at the start of the installer to make easier for international users.
Diffstat (limited to 'src/Common/Language.c')
-rw-r--r--src/Common/Language.c202
1 files changed, 202 insertions, 0 deletions
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)