Annotation of truecrypt/common/language.c, revision 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.