Annotation of truecrypt/common/language.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.