diff options
Diffstat (limited to 'src/Common/Language.c')
-rw-r--r-- | src/Common/Language.c | 1166 |
1 files changed, 583 insertions, 583 deletions
diff --git a/src/Common/Language.c b/src/Common/Language.c index 44615e65..3d9b22d3 100644 --- a/src/Common/Language.c +++ b/src/Common/Language.c @@ -1,583 +1,583 @@ -/*
- Derived from source code of TrueCrypt 7.1a, which is
- Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed
- by the TrueCrypt License 3.0.
-
- Modifications and additions to the original source code (contained in this file)
- and all other portions of this file are Copyright (c) 2013-2016 IDRIX
- and are governed by the Apache License 2.0 the full text of which is
- contained in the file License.txt included in VeraCrypt binary and source
- code distribution packages.
-*/
-
-#include "Language.h"
-#include "Dlgcode.h"
-#include "Dictionary.h"
-#include "Tcdefs.h"
-#include "Xml.h"
-
-#include "../Common/Resource.h"
-
-#ifdef TCMOUNT
-#include "../Mount/Resource.h"
-#endif
-
-#ifdef VOLFORMAT
-#include "../Format/Resource.h"
-#endif
-
-#ifdef SETUP
-#include "../Setup/Resource.h"
-#endif
-
-#include <Strsafe.h>
-
-BOOL LocalizationActive;
-int LocalizationSerialNo;
-
-wchar_t UnknownString[1024] = {0};
-static char *LanguageFileBuffer = NULL;
-static HANDLE LanguageFileFindHandle = INVALID_HANDLE_VALUE;
-static char PreferredLangId[6] = {0};
-static char *LanguageResource = NULL;
-static DWORD LanguageResourceSize = 0;
-static char *HeaderResource[2] = {NULL, NULL};
-static DWORD HeaderResourceSize[2] = {0, 0};
-static char ActiveLangPackVersion[6] = {0};
-
-static char *MapFirstLanguageFile ()
-{
- if (LanguageFileFindHandle != INVALID_HANDLE_VALUE)
- {
- FindClose (LanguageFileFindHandle);
- LanguageFileFindHandle = INVALID_HANDLE_VALUE;
- }
-
- if (LanguageFileBuffer != NULL)
- {
- free (LanguageFileBuffer);
- LanguageFileBuffer = NULL;
- }
-
- if (LanguageResource == NULL)
- {
- DWORD size;
- LanguageResource = MapResource (L"Xml", IDR_LANGUAGE, &size);
- if (LanguageResource)
- LanguageResourceSize = size;
- }
-
- if (LanguageResource)
- {
- LanguageFileBuffer = malloc(LanguageResourceSize + 1);
- if (LanguageFileBuffer)
- {
- memcpy (LanguageFileBuffer, LanguageResource, LanguageResourceSize);
- LanguageFileBuffer[LanguageResourceSize] = 0;
- }
- }
-
- return LanguageFileBuffer;
-}
-
-
-static char *MapNextLanguageFile ()
-{
- wchar_t f[TC_MAX_PATH*2], *t;
- WIN32_FIND_DATAW find;
- HANDLE file;
- DWORD read;
- BOOL bStatus;
-
- /* free memory here to avoid leaks */
- if (LanguageFileBuffer != NULL)
- {
- free (LanguageFileBuffer);
- LanguageFileBuffer = 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"\\Language*.xml");
-
- 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;
-
- 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;
- }
-
- t[1] = 0;
- 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;
- }
-
- 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
-
- return LanguageFileBuffer;
-}
-
-
-BOOL LoadLanguageFile ()
-{
- DWORD size;
- BYTE *res;
- char *xml, *header, *headerPtr;
- char langId[6] = "en", attr[32768], key[128];
- BOOL defaultLangParsed = FALSE, langFound = FALSE;
- WCHAR wattr[32768];
- int i, intKey, len;
-
- char *xmlElements[] = {"control", "string", 0};
-
-#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
-
- LocalizationActive = FALSE;
- ActiveLangPackVersion[0] = 0;
- ClearDictionaryPool ();
-
- if (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 ())
- {
- xml = (char *) res;
- xml = XmlFindElement (xml, "localization");
- if (!xml)
- continue;
-
- // Required TrueCrypt version
- XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr));
-
- // Check version of external language file
- if (defaultLangParsed && strcmp (attr, VERSION_STRING) && strcmp (attr, "DEBUG"))
- {
- 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);
- continue;
- }
-
- // Search language id in language file
- if (defaultLangParsed)
- {
- while (xml = XmlFindElement (xml, "language"))
- {
- XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
- if (strcmp (attr, langId) == 0)
- {
- XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion));
- langFound = TRUE;
- break;
- }
- xml++;
- }
-
- if (!langFound) continue;
- }
-
- // Create font dictionary
- xml = (char *) res;
- while (xml = XmlFindElement (xml, "font"))
- {
- XmlGetAttributeText (xml, "lang", attr, sizeof (attr));
- if (!defaultLangParsed
- || 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++;
- }
-
- // Create string and control dictionaries
- for (i = 0; xmlElements[i] != 0; i++)
- {
- xml = (char *) res;
- while (xml = XmlFindElement (xml, xmlElements[i]))
- {
- void *key;
- void *text;
-
- XmlGetAttributeText (xml, "lang", attr, sizeof (attr));
- if (!defaultLangParsed
- || 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:
- 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)
- {
- 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++;
- }
- }
-
- if (langFound)
- break;
-
- if (!defaultLangParsed)
- {
- defaultLangParsed = TRUE;
- if (langId[0] == 0 || strcmp (langId, "en") == 0)
- break;
- }
- }
-
- LocalizationActive = langFound && strcmp (langId, "en") != 0;
- LocalizationSerialNo++;
-
- // 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;
-
- do
- {
- 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') + 1) != (char *) 1);
-
- free (headerPtr);
- }
-
- return TRUE;
-}
-
-
-// lParam = 1: auto mode
-BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- WORD lw = LOWORD (wParam);
- WORD hw = HIWORD (wParam);
-
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- char *xml;
- char attr[2048], lastLangId[10];
- WCHAR wattr[2048];
- int len;
- int langCount = 0;
- BOOL defaultLangFound = FALSE;
-
- LocalizeDialog (hwndDlg, "IDD_LANGUAGE");
- ToHyperlink (hwndDlg, IDC_GET_LANG_PACKS);
-
- for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile ())
- {
- while (xml = XmlFindElement (xml, "language"))
- {
- XmlGetAttributeText (xml, "name", attr, sizeof (attr));
- len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
-
- if (len != 0
- && (!defaultLangFound || wcscmp (wattr, L"English") != 0))
- {
- int i = (int) SendDlgItemMessageW (hwndDlg, IDC_LANGLIST, LB_ADDSTRING, 0, (LPARAM)wattr);
- if (i >= 0)
- {
- int id;
-
- // Encode language id in LPARAM
- XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
- switch (strlen (attr))
- {
- case 2: id = attr[0] | attr[1] << 8; break;
- case 5: id = attr[0] | attr[1] << 8 | attr[3] << 16 | attr[4] << 24; break;
- default: continue;
- }
-
- if (!defaultLangFound)
- defaultLangFound = TRUE;
-
- SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETITEMDATA, i, (LPARAM) id);
-
- if (strcmp (attr, PreferredLangId) == 0)
- {
- char credits [10000];
- WCHAR wcredits [10000];
- WCHAR wversion [20];
- wchar_t szVers [200];
- int nLen;
-
- SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETCURSEL, i, 0);
-
- // Language pack version
- if (!ActiveLangPackVersion[0] || memcmp (ActiveLangPackVersion, "0.0.0", 5) == 0)
- {
- StringCbPrintfW (szVers, sizeof(szVers), GetString("LANG_PACK_VERSION"), L"--");
- }
- else
- {
- nLen = MultiByteToWideChar (CP_UTF8, 0, ActiveLangPackVersion, -1, wversion, sizeof (wversion) / sizeof(wversion[0]));
- if (nLen != 0)
- StringCbPrintfW (szVers, sizeof(szVers),GetString("LANG_PACK_VERSION"), wversion);
- }
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_VERSION), szVers);
-
- // Translator credits
- XmlGetAttributeText (xml, "translators", credits, sizeof (credits));
- nLen = MultiByteToWideChar (CP_UTF8, 0, credits, -1, wcredits, sizeof (wcredits) / sizeof(wcredits[0]));
- if (nLen != 0)
- {
- SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_CREDITS), wcredits);
- }
- }
-
- StringCbCopyA (lastLangId, sizeof(lastLangId),attr);
- langCount++;
- }
- }
-
- xml++;
- }
- }
-
- if (lParam == 1)
- {
- // Auto mode
- if (langCount < 2)
- EndDialog (hwndDlg, IDCANCEL);
-
- if (langCount == 2)
- StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), lastLangId);
-
- EndDialog (hwndDlg, IDOK);
- }
-
- return 1;
- }
-
- case WM_COMMAND:
-
- if (lw == IDOK || hw == LBN_DBLCLK)
- {
- int i = (int) SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCURSEL, 0, 0);
-
- if (i >= 0)
- {
- int id = (int) SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETITEMDATA, i, 0);
-
- if (id != LB_ERR)
- {
- char l[6];
-
- // Decode language id from LPARAM
- l[0] = (char) id;
- l[1] = (char) (id >> 8);
- l[2] = 0;
-
- if ((id & 0xffff0000) != 0)
- {
- l[2] = '-';
- l[3] = (char) (id >> 16);
- l[4] = id >> 24;
- l[5] = 0;
- }
-
- if (SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCOUNT, 0, 0) > 1)
- StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), l);
- }
- }
-
- EndDialog (hwndDlg, IDOK);
- return 1;
- }
-
- if (lw == IDCANCEL)
- {
- EndDialog (hwndDlg, lw);
- return 1;
- }
-
- if (lw == IDC_GET_LANG_PACKS)
- {
- char tmpstr [256];
-
- if (strlen (ActiveLangPackVersion) > 0 && strlen (GetPreferredLangId()) > 0)
- StringCbPrintfA (tmpstr, sizeof(tmpstr), "&langpackversion=%s&lang=%s", ActiveLangPackVersion, GetPreferredLangId());
- else
- tmpstr[0] = 0;
-
- Applink ("localizations", TRUE, tmpstr);
-
- return 1;
- }
- return 0;
- }
-
- return 0;
-}
-
-
-char *GetPreferredLangId ()
-{
- return PreferredLangId;
-}
-
-
-void SetPreferredLangId (char *langId)
-{
- StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), langId);
-}
-
-
-char *GetActiveLangPackVersion ()
-{
- return ActiveLangPackVersion;
-}
-
-
-wchar_t *GetString (const char *stringId)
-{
- WCHAR *str = (WCHAR *) GetDictionaryValue (stringId);
- if (str != NULL) return str;
-
- StringCbPrintfW (UnknownString, sizeof(UnknownString), UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId);
- return UnknownString;
-}
-
-
-Font *GetFont (char *fontType)
-{
- return (Font *) GetDictionaryValue (fontType);
-
-}
+/* + Derived from source code of TrueCrypt 7.1a, which is + Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed + by the TrueCrypt License 3.0. + + Modifications and additions to the original source code (contained in this file) + and all other portions of this file are Copyright (c) 2013-2016 IDRIX + and are governed by the Apache License 2.0 the full text of which is + contained in the file License.txt included in VeraCrypt binary and source + code distribution packages. +*/ + +#include "Language.h" +#include "Dlgcode.h" +#include "Dictionary.h" +#include "Tcdefs.h" +#include "Xml.h" + +#include "../Common/Resource.h" + +#ifdef TCMOUNT +#include "../Mount/Resource.h" +#endif + +#ifdef VOLFORMAT +#include "../Format/Resource.h" +#endif + +#ifdef SETUP +#include "../Setup/Resource.h" +#endif + +#include <Strsafe.h> + +BOOL LocalizationActive; +int LocalizationSerialNo; + +wchar_t UnknownString[1024] = {0}; +static char *LanguageFileBuffer = NULL; +static HANDLE LanguageFileFindHandle = INVALID_HANDLE_VALUE; +static char PreferredLangId[6] = {0}; +static char *LanguageResource = NULL; +static DWORD LanguageResourceSize = 0; +static char *HeaderResource[2] = {NULL, NULL}; +static DWORD HeaderResourceSize[2] = {0, 0}; +static char ActiveLangPackVersion[6] = {0}; + +static char *MapFirstLanguageFile () +{ + if (LanguageFileFindHandle != INVALID_HANDLE_VALUE) + { + FindClose (LanguageFileFindHandle); + LanguageFileFindHandle = INVALID_HANDLE_VALUE; + } + + if (LanguageFileBuffer != NULL) + { + free (LanguageFileBuffer); + LanguageFileBuffer = NULL; + } + + if (LanguageResource == NULL) + { + DWORD size; + LanguageResource = MapResource (L"Xml", IDR_LANGUAGE, &size); + if (LanguageResource) + LanguageResourceSize = size; + } + + if (LanguageResource) + { + LanguageFileBuffer = malloc(LanguageResourceSize + 1); + if (LanguageFileBuffer) + { + memcpy (LanguageFileBuffer, LanguageResource, LanguageResourceSize); + LanguageFileBuffer[LanguageResourceSize] = 0; + } + } + + return LanguageFileBuffer; +} + + +static char *MapNextLanguageFile () +{ + wchar_t f[TC_MAX_PATH*2], *t; + WIN32_FIND_DATAW find; + HANDLE file; + DWORD read; + BOOL bStatus; + + /* free memory here to avoid leaks */ + if (LanguageFileBuffer != NULL) + { + free (LanguageFileBuffer); + LanguageFileBuffer = 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"\\Language*.xml"); + + 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; + + 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; + } + + t[1] = 0; + 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; + } + + 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 + + return LanguageFileBuffer; +} + + +BOOL LoadLanguageFile () +{ + DWORD size; + BYTE *res; + char *xml, *header, *headerPtr; + char langId[6] = "en", attr[32768], key[128]; + BOOL defaultLangParsed = FALSE, langFound = FALSE; + WCHAR wattr[32768]; + int i, intKey, len; + + char *xmlElements[] = {"control", "string", 0}; + +#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 + + LocalizationActive = FALSE; + ActiveLangPackVersion[0] = 0; + ClearDictionaryPool (); + + if (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 ()) + { + xml = (char *) res; + xml = XmlFindElement (xml, "localization"); + if (!xml) + continue; + + // Required TrueCrypt version + XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr)); + + // Check version of external language file + if (defaultLangParsed && strcmp (attr, VERSION_STRING) && strcmp (attr, "DEBUG")) + { + 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); + continue; + } + + // Search language id in language file + if (defaultLangParsed) + { + while (xml = XmlFindElement (xml, "language")) + { + XmlGetAttributeText (xml, "langid", attr, sizeof (attr)); + if (strcmp (attr, langId) == 0) + { + XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion)); + langFound = TRUE; + break; + } + xml++; + } + + if (!langFound) continue; + } + + // Create font dictionary + xml = (char *) res; + while (xml = XmlFindElement (xml, "font")) + { + XmlGetAttributeText (xml, "lang", attr, sizeof (attr)); + if (!defaultLangParsed + || 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++; + } + + // Create string and control dictionaries + for (i = 0; xmlElements[i] != 0; i++) + { + xml = (char *) res; + while (xml = XmlFindElement (xml, xmlElements[i])) + { + void *key; + void *text; + + XmlGetAttributeText (xml, "lang", attr, sizeof (attr)); + if (!defaultLangParsed + || 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: + 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) + { + 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++; + } + } + + if (langFound) + break; + + if (!defaultLangParsed) + { + defaultLangParsed = TRUE; + if (langId[0] == 0 || strcmp (langId, "en") == 0) + break; + } + } + + LocalizationActive = langFound && strcmp (langId, "en") != 0; + LocalizationSerialNo++; + + // 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; + + do + { + 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') + 1) != (char *) 1); + + free (headerPtr); + } + + return TRUE; +} + + +// lParam = 1: auto mode +BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WORD lw = LOWORD (wParam); + WORD hw = HIWORD (wParam); + + switch (msg) + { + case WM_INITDIALOG: + { + char *xml; + char attr[2048], lastLangId[10]; + WCHAR wattr[2048]; + int len; + int langCount = 0; + BOOL defaultLangFound = FALSE; + + LocalizeDialog (hwndDlg, "IDD_LANGUAGE"); + ToHyperlink (hwndDlg, IDC_GET_LANG_PACKS); + + for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile ()) + { + while (xml = XmlFindElement (xml, "language")) + { + XmlGetAttributeText (xml, "name", attr, sizeof (attr)); + len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0])); + + if (len != 0 + && (!defaultLangFound || wcscmp (wattr, L"English") != 0)) + { + int i = (int) SendDlgItemMessageW (hwndDlg, IDC_LANGLIST, LB_ADDSTRING, 0, (LPARAM)wattr); + if (i >= 0) + { + int id; + + // Encode language id in LPARAM + XmlGetAttributeText (xml, "langid", attr, sizeof (attr)); + switch (strlen (attr)) + { + case 2: id = attr[0] | attr[1] << 8; break; + case 5: id = attr[0] | attr[1] << 8 | attr[3] << 16 | attr[4] << 24; break; + default: continue; + } + + if (!defaultLangFound) + defaultLangFound = TRUE; + + SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETITEMDATA, i, (LPARAM) id); + + if (strcmp (attr, PreferredLangId) == 0) + { + char credits [10000]; + WCHAR wcredits [10000]; + WCHAR wversion [20]; + wchar_t szVers [200]; + int nLen; + + SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETCURSEL, i, 0); + + // Language pack version + if (!ActiveLangPackVersion[0] || memcmp (ActiveLangPackVersion, "0.0.0", 5) == 0) + { + StringCbPrintfW (szVers, sizeof(szVers), GetString("LANG_PACK_VERSION"), L"--"); + } + else + { + nLen = MultiByteToWideChar (CP_UTF8, 0, ActiveLangPackVersion, -1, wversion, sizeof (wversion) / sizeof(wversion[0])); + if (nLen != 0) + StringCbPrintfW (szVers, sizeof(szVers),GetString("LANG_PACK_VERSION"), wversion); + } + SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_VERSION), szVers); + + // Translator credits + XmlGetAttributeText (xml, "translators", credits, sizeof (credits)); + nLen = MultiByteToWideChar (CP_UTF8, 0, credits, -1, wcredits, sizeof (wcredits) / sizeof(wcredits[0])); + if (nLen != 0) + { + SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_CREDITS), wcredits); + } + } + + StringCbCopyA (lastLangId, sizeof(lastLangId),attr); + langCount++; + } + } + + xml++; + } + } + + if (lParam == 1) + { + // Auto mode + if (langCount < 2) + EndDialog (hwndDlg, IDCANCEL); + + if (langCount == 2) + StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), lastLangId); + + EndDialog (hwndDlg, IDOK); + } + + return 1; + } + + case WM_COMMAND: + + if (lw == IDOK || hw == LBN_DBLCLK) + { + int i = (int) SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCURSEL, 0, 0); + + if (i >= 0) + { + int id = (int) SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETITEMDATA, i, 0); + + if (id != LB_ERR) + { + char l[6]; + + // Decode language id from LPARAM + l[0] = (char) id; + l[1] = (char) (id >> 8); + l[2] = 0; + + if ((id & 0xffff0000) != 0) + { + l[2] = '-'; + l[3] = (char) (id >> 16); + l[4] = id >> 24; + l[5] = 0; + } + + if (SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCOUNT, 0, 0) > 1) + StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), l); + } + } + + EndDialog (hwndDlg, IDOK); + return 1; + } + + if (lw == IDCANCEL) + { + EndDialog (hwndDlg, lw); + return 1; + } + + if (lw == IDC_GET_LANG_PACKS) + { + char tmpstr [256]; + + if (strlen (ActiveLangPackVersion) > 0 && strlen (GetPreferredLangId()) > 0) + StringCbPrintfA (tmpstr, sizeof(tmpstr), "&langpackversion=%s&lang=%s", ActiveLangPackVersion, GetPreferredLangId()); + else + tmpstr[0] = 0; + + Applink ("localizations", TRUE, tmpstr); + + return 1; + } + return 0; + } + + return 0; +} + + +char *GetPreferredLangId () +{ + return PreferredLangId; +} + + +void SetPreferredLangId (char *langId) +{ + StringCbCopyA (PreferredLangId, sizeof(PreferredLangId), langId); +} + + +char *GetActiveLangPackVersion () +{ + return ActiveLangPackVersion; +} + + +wchar_t *GetString (const char *stringId) +{ + WCHAR *str = (WCHAR *) GetDictionaryValue (stringId); + if (str != NULL) return str; + + StringCbPrintfW (UnknownString, sizeof(UnknownString), UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId); + return UnknownString; +} + + +Font *GetFont (char *fontType) +{ + return (Font *) GetDictionaryValue (fontType); + +} |