|
|
1.1.1.5 root 1: /* 1.1.1.7 root 2: Copyright (c) 2005 TrueCrypt Foundation. All rights reserved. 1.1 root 3: 1.1.1.10! root 4: Governed by the TrueCrypt License 2.6 the full text of which is contained 1.1.1.5 root 5: in the file License.txt included in TrueCrypt binary and source code 6: distribution packages. 1.1 root 7: */ 8: 9: #include "Language.h" 10: #include "Dlgcode.h" 11: #include "Dictionary.h" 12: #include "Tcdefs.h" 13: #include "Xml.h" 14: 15: #include "../Common/Resource.h" 16: 17: #ifdef TCMOUNT 18: #include "../Mount/Resource.h" 19: #endif 20: 21: #ifdef VOLFORMAT 22: #include "../Format/Resource.h" 23: #endif 24: 25: #ifdef SETUP 26: #include "../Setup/Resource.h" 27: #endif 28: 29: BOOL LocalizationActive; 30: int LocalizationSerialNo; 31: 32: wchar_t UnknownString[1024]; 33: static char *LanguageFileBuffer; 34: static HANDLE LanguageFileFindHandle = INVALID_HANDLE_VALUE; 35: static char PreferredLangId[6]; 36: static char *LanguageResource; 37: static char *HeaderResource[2]; 38: static char ActiveLangPackVersion[6]; 39: 40: static char *MapFirstLanguageFile () 41: { 42: if (LanguageFileFindHandle != INVALID_HANDLE_VALUE) 43: { 44: FindClose (LanguageFileFindHandle); 45: LanguageFileFindHandle = INVALID_HANDLE_VALUE; 46: } 47: 48: if (LanguageResource == NULL) 1.1.1.5 root 49: { 50: DWORD size; 51: LanguageResource = MapResource ("Xml", IDR_LANGUAGE, &size); 52: LanguageResource[size - 1] = 0; 53: } 1.1 root 54: 55: return LanguageResource; 56: } 57: 58: 59: static char *MapNextLanguageFile () 60: { 61: wchar_t f[TC_MAX_PATH*2], *t; 62: WIN32_FIND_DATAW find; 63: HANDLE file; 64: DWORD read; 65: 66: if (LanguageFileFindHandle == INVALID_HANDLE_VALUE) 67: { 1.1.1.8 root 68: GetModuleFileNameW (NULL, f, sizeof (f) / sizeof (f[0])); 1.1 root 69: t = wcsrchr (f, L'\\'); 70: if (t == NULL) return NULL; 71: 72: wcscpy (t, L"\\Language*.xml"); 73: 74: LanguageFileFindHandle = FindFirstFileW (f, &find); 75: } 76: else if (!FindNextFileW (LanguageFileFindHandle, &find)) 77: { 78: FindClose (LanguageFileFindHandle); 79: LanguageFileFindHandle = INVALID_HANDLE_VALUE; 80: return NULL; 81: } 82: 83: if (find.nFileSizeHigh != 0) return NULL; 84: 85: if (LanguageFileBuffer != NULL) free (LanguageFileBuffer); 86: LanguageFileBuffer = malloc(find.nFileSizeLow); 87: if (LanguageFileBuffer == NULL) return NULL; 88: 1.1.1.8 root 89: GetModuleFileNameW (NULL, f, sizeof (f) / sizeof(f[0])); 1.1 root 90: t = wcsrchr (f, L'\\'); 91: wcscpy (t + 1, find.cFileName); 92: 93: file = CreateFileW (f, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 94: if (file == INVALID_HANDLE_VALUE) return NULL; 95: 96: ReadFile (file, LanguageFileBuffer, find.nFileSizeLow, &read, NULL); 97: CloseHandle (file); 98: if (read != find.nFileSizeLow) return NULL; 99: 100: return LanguageFileBuffer; 101: } 102: 103: 104: BOOL LoadLanguageFile () 105: { 106: DWORD size; 107: BYTE *res; 108: char *xml, *header; 1.1.1.7 root 109: char langId[6] = "en", attr[32768], key[128]; 1.1 root 110: BOOL defaultLangParsed = FALSE, langFound = FALSE; 1.1.1.7 root 111: WCHAR wattr[32768]; 1.1 root 112: int i, intKey, len; 113: 114: char *xmlElements[] = {"control", "string", 0}; 115: 116: #ifdef TCMOUNT 117: int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_MOUNT_RSRC_HEADER, 0 }; 118: #endif 119: 120: #ifdef VOLFORMAT 121: int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_FORMAT_RSRC_HEADER, 0 }; 122: #endif 123: 124: #ifdef SETUP 125: int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_SETUP_RSRC_HEADER, 0 }; 126: #endif 127: 128: LocalizationActive = FALSE; 1.1.1.6 root 129: ActiveLangPackVersion[0] = 0; 1.1 root 130: ClearDictionaryPool (); 131: 132: if (PreferredLangId[0] != 0) 133: strcpy (langId, PreferredLangId); 134: 135: // Parse all available language files until preferred language is found 136: for (res = MapFirstLanguageFile (); res != NULL; res = MapNextLanguageFile ()) 137: { 138: xml = (char *) res; 139: xml = XmlFindElement (xml, "localization"); 1.1.1.2 root 140: if (!xml) 141: continue; 142: 1.1 root 143: // Required TrueCrypt version 1.1.1.5 root 144: XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr)); 1.1 root 145: 146: // Check version of external language file 1.1.1.6 root 147: if (defaultLangParsed && strcmp (attr, VERSION_STRING) && strcmp (attr, "DEBUG")) 1.1 root 148: { 1.1.1.5 root 149: wchar_t m[2048]; 150: swprintf (m, L"The installed language pack is incompatible with this version of TrueCrypt (the language pack is for TrueCrypt %hs). A newer version may be available at www.truecrypt.org.\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\\TrueCrypt' or '%%LOCALAPPDATA%%\\VirtualStore\\Program Files\\TrueCrypt', etc.)", attr); 1.1 root 151: MessageBoxW (NULL, m, L"TrueCrypt", MB_ICONERROR); 152: continue; 153: } 154: 155: // Search language id in language file 156: if (defaultLangParsed) 157: { 158: while (xml = XmlFindElement (xml, "language")) 159: { 1.1.1.6 root 160: XmlGetAttributeText (xml, "langid", attr, sizeof (attr)); 1.1 root 161: if (strcmp (attr, langId) == 0) 162: { 1.1.1.6 root 163: XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion)); 1.1 root 164: langFound = TRUE; 165: break; 166: } 1.1.1.6 root 167: xml++; 1.1 root 168: } 169: 170: if (!langFound) continue; 171: } 172: 173: // Create font dictionary 174: xml = (char *) res; 175: while (xml = XmlFindElement (xml, "font")) 176: { 1.1.1.5 root 177: XmlGetAttributeText (xml, "lang", attr, sizeof (attr)); 1.1 root 178: if (!defaultLangParsed 179: || strcmp (attr, langId) == 0) 180: { 181: Font font; 1.1.1.2 root 182: memset (&font, 0, sizeof (font)); 183: 1.1.1.5 root 184: XmlGetAttributeText (xml, "face", attr, sizeof (attr)); 1.1 root 185: 1.1.1.8 root 186: len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0])); 1.1 root 187: font.FaceName = AddPoolData ((void *) wattr, len * 2); 188: 1.1.1.5 root 189: XmlGetAttributeText (xml, "size", attr, sizeof (attr)); 1.1 root 190: sscanf (attr, "%d", &font.Size); 191: 192: strcpy (attr, "font_"); 1.1.1.5 root 193: XmlGetAttributeText (xml, "class", attr + 5, sizeof (attr) - 5); 1.1.1.2 root 194: AddDictionaryEntry ( 195: AddPoolData ((void *) attr, strlen (attr) + 1), 0, 1.1 root 196: AddPoolData ((void *) &font, sizeof(font))); 197: } 198: 199: xml++; 200: } 201: 202: // Create string and control dictionaries 203: for (i = 0; xmlElements[i] != 0; i++) 204: { 205: xml = (char *) res; 206: while (xml = XmlFindElement (xml, xmlElements[i])) 207: { 208: void *key; 209: void *text; 210: 1.1.1.5 root 211: XmlGetAttributeText (xml, "lang", attr, sizeof (attr)); 1.1 root 212: if (!defaultLangParsed 213: || strcmp (attr, langId) == 0) 214: { 1.1.1.5 root 215: if (XmlGetAttributeText (xml, "key", attr, sizeof (attr))) 1.1 root 216: { 217: key = AddPoolData (attr, strlen (attr) + 1); 218: if (key == NULL) return FALSE; 219: 1.1.1.5 root 220: XmlGetNodeText (xml, attr, sizeof (attr)); 1.1 root 221: 222: // Parse \ escape sequences 223: { 224: char *in = attr, *out = attr; 225: while (*in) 226: { 227: if (*in == '\\') 228: { 229: in++; 230: switch (*in++) 231: { 232: case '\\': *out++ = '\\'; break; 233: case 't': *out++ = '\t'; break; 234: case 'n': *out++ = 13; *out++ = 10; break; 235: default: 236: MessageBox (0, key, "TrueCrypt: Unknown '\\' escape sequence in string", MB_ICONERROR); 237: return FALSE; 238: } 239: } 240: else 241: *out++ = *in++; 242: } 243: *out = 0; 244: } 245: 246: // UTF8 => wide char 1.1.1.8 root 247: len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0])); 1.1 root 248: if (len == 0 || len == ERROR_NO_UNICODE_TRANSLATION) 249: { 250: MessageBox (0, key, "TrueCrypt: Error while decoding UTF-8 string", MB_ICONERROR); 251: return FALSE; 252: } 253: 254: // Add to dictionary 255: text = AddPoolData ((void *) wattr, len * 2); 256: if (text == NULL) return FALSE; 257: 258: AddDictionaryEntry ((char *) key, 0, text); 259: } 260: } 261: 262: xml++; 263: } 264: } 265: 266: if (langFound) 267: break; 268: 269: if (!defaultLangParsed) 270: { 271: defaultLangParsed = TRUE; 272: if (langId[0] == 0 || strcmp (langId, "en") == 0) 273: break; 274: } 275: } 276: 277: LocalizationActive = langFound && strcmp (langId, "en") != 0; 278: LocalizationSerialNo++; 279: 280: // Create control ID dictionary 281: 282: // Default controls 283: AddDictionaryEntry (NULL, 1, GetString ("IDOK")); 284: AddDictionaryEntry (NULL, 2, GetString ("IDCANCEL")); 285: AddDictionaryEntry (NULL, 8, GetString ("IDCLOSE")); 286: AddDictionaryEntry (NULL, 9, GetString ("IDHELP")); 287: 288: for (i = 0; headers[i] != 0; i++) 289: { 290: if (HeaderResource[i] == NULL) 1.1.1.5 root 291: { 1.1 root 292: HeaderResource[i] = MapResource ("Header", headers[i], &size); 1.1.1.5 root 293: *(HeaderResource[i] + size - 1) = 0; 294: } 1.1 root 295: 296: header = HeaderResource[i]; 297: if (header == NULL) return FALSE; 298: 299: do 300: { 301: if (sscanf (header, "#define %s %d", key, &intKey) == 2) 302: { 303: WCHAR *str = GetString (key); 304: 305: if (str != UnknownString) 306: AddDictionaryEntry (NULL, intKey, str); 307: } 308: 309: } while ((header = strchr (header, '\n') + 1) != (char *) 1); 310: } 311: 312: return TRUE; 313: } 314: 315: 316: // lParam = 1: auto mode 1.1.1.6 root 317: BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) 1.1 root 318: { 319: WORD lw = LOWORD (wParam); 320: WORD hw = HIWORD (wParam); 321: 322: switch (msg) 323: { 324: case WM_INITDIALOG: 325: { 326: char *xml; 327: char attr[2048], lastLangId[10]; 328: WCHAR wattr[2048]; 329: int len; 330: int langCount = 0; 331: BOOL defaultLangFound = FALSE; 332: 333: LocalizeDialog (hwndDlg, "IDD_LANGUAGE"); 1.1.1.5 root 334: ToHyperlink (hwndDlg, IDC_GET_LANG_PACKS); 1.1 root 335: 336: for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile ()) 337: { 338: while (xml = XmlFindElement (xml, "language")) 339: { 1.1.1.5 root 340: XmlGetAttributeText (xml, "name", attr, sizeof (attr)); 1.1.1.8 root 341: len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0])); 1.1 root 342: 343: if (len != 0 && len != ERROR_NO_UNICODE_TRANSLATION 344: && (!defaultLangFound || wcscmp (wattr, L"English") != 0)) 345: { 346: int i = SendDlgItemMessageW (hwndDlg, IDC_LANGLIST, LB_ADDSTRING, 0, (LPARAM)wattr); 347: if (i >= 0) 348: { 349: int id; 350: 351: // Encode language id in LPARAM 1.1.1.5 root 352: XmlGetAttributeText (xml, "langid", attr, sizeof (attr)); 1.1 root 353: switch (strlen (attr)) 354: { 355: case 2: id = attr[0] | attr[1] << 8; break; 356: case 5: id = attr[0] | attr[1] << 8 | attr[3] << 16 | attr[4] << 24; break; 357: default: continue; 358: } 359: 360: if (!defaultLangFound) 361: defaultLangFound = TRUE; 362: 363: SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETITEMDATA, i, (LPARAM) id); 364: 365: if (strcmp (attr, PreferredLangId) == 0) 366: { 367: char credits [10000]; 368: WCHAR wcredits [10000]; 369: WCHAR wversion [20]; 370: wchar_t szVers [200]; 371: int nLen; 372: 373: SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETCURSEL, i, 0); 374: 375: // Language pack version 1.1.1.6 root 376: if (!ActiveLangPackVersion[0] || memcmp (ActiveLangPackVersion, "0.0.0", 5) == 0) 1.1 root 377: { 378: swprintf (szVers, GetString("LANG_PACK_VERSION"), L"--"); 379: } 380: else 381: { 1.1.1.8 root 382: nLen = MultiByteToWideChar (CP_UTF8, 0, ActiveLangPackVersion, -1, wversion, sizeof (wversion) / sizeof(wversion[0])); 1.1 root 383: if (nLen != 0 && nLen != ERROR_NO_UNICODE_TRANSLATION) 384: swprintf (szVers, GetString("LANG_PACK_VERSION"), wversion); 385: } 386: SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_VERSION), szVers); 387: 388: // Translator credits 1.1.1.5 root 389: XmlGetAttributeText (xml, "translators", credits, sizeof (credits)); 1.1.1.8 root 390: nLen = MultiByteToWideChar (CP_UTF8, 0, credits, -1, wcredits, sizeof (wcredits) / sizeof(wcredits[0])); 1.1 root 391: if (nLen != 0 && nLen != ERROR_NO_UNICODE_TRANSLATION) 392: { 393: SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_CREDITS), wcredits); 394: } 395: } 396: 397: strcpy (lastLangId, attr); 398: langCount++; 399: } 400: } 401: 402: xml++; 403: } 404: } 405: 406: if (lParam == 1) 407: { 408: // Auto mode 409: if (langCount < 2) 410: EndDialog (hwndDlg, IDCANCEL); 411: 412: if (langCount == 2) 413: strcpy (PreferredLangId, lastLangId); 1.1.1.5 root 414: 415: EndDialog (hwndDlg, IDOK); 1.1 root 416: } 417: 418: return 1; 419: } 420: 421: case WM_COMMAND: 422: 423: if (lw == IDOK || hw == LBN_DBLCLK) 424: { 425: int i = SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCURSEL, 0, 0); 426: 427: if (i >= 0) 428: { 429: int id = SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETITEMDATA, i, 0); 430: 431: if (id != LB_ERR) 432: { 433: char l[6]; 434: 435: // Decode language id from LPARAM 436: l[0] = id; 437: l[1] = id >> 8; 438: l[2] = 0; 439: 440: if ((id & 0xffff0000) != 0) 441: { 442: l[2] = '-'; 443: l[3] = id >> 16; 444: l[4] = id >> 24; 445: l[5] = 0; 446: } 447: 448: if (SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCOUNT, 0, 0) > 1) 449: strcpy (PreferredLangId, l); 450: } 451: } 452: 453: EndDialog (hwndDlg, IDOK); 454: return 1; 455: } 456: 457: if (lw == IDCANCEL) 458: { 459: EndDialog (hwndDlg, lw); 460: return 1; 461: } 462: 463: if (lw == IDC_GET_LANG_PACKS) 464: { 465: char tmpstr [256]; 466: 1.1.1.5 root 467: if (strlen (ActiveLangPackVersion) > 0 && strlen (GetPreferredLangId()) > 0) 468: sprintf (tmpstr, "&langpackversion=%s&lang=%s", ActiveLangPackVersion, GetPreferredLangId()); 1.1 root 469: else 1.1.1.5 root 470: tmpstr[0] = 0; 471: 472: Applink ("localizations", TRUE, tmpstr); 1.1 root 473: 474: return 1; 475: } 476: return 0; 477: } 478: 479: return 0; 480: } 481: 482: 483: char *GetPreferredLangId () 484: { 485: return PreferredLangId; 486: } 487: 488: 489: void SetPreferredLangId (char *langId) 490: { 491: strncpy (PreferredLangId, langId, 5); 492: } 493: 494: 1.1.1.6 root 495: char *GetActiveLangPackVersion () 496: { 497: return ActiveLangPackVersion; 498: } 499: 500: 1.1.1.10! root 501: wchar_t *GetString (const char *stringId) 1.1 root 502: { 503: WCHAR *str = (WCHAR *) GetDictionaryValue (stringId); 504: if (str != NULL) return str; 505: 506: wsprintfW (UnknownString, UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId); 507: return UnknownString; 508: } 509: 510: 511: Font *GetFont (char *fontType) 512: { 513: return (Font *) GetDictionaryValue (fontType); 514: 515: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.