source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.c @ a1bae3e

trunk
Last change on this file since a1bae3e was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

  • Property mode set to 100644
File size: 19.3 KB
Line 
1// SoftEther UT-VPN SourceCode
2//
3// Copyright (C) 2004-2010 SoftEther Corporation.
4// Copyright (C) 2004-2010 University of Tsukuba, Japan.
5// Copyright (C) 2003-2010 Daiyuu Nobori.
6// All Rights Reserved.
7//
8// http://utvpn.tsukuba.ac.jp/
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License
12// version 2 as published by the Free Software Foundation.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License version 2
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22//
23// このファイルは GPL バージョン 2 ライセンスで公開されています。
24// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
25// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
26// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
27// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
28//
29// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
30// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
31// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
32// ホストされています。
33// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
34// および、試験または研究のために利用が行われることを想定して配布
35// しています。
36// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
37// あります。
38// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
39// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
40// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
41// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
42// に組み込みさせていただきます。
43//
44// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
45// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
46//
47// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
48// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
49// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
50// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
51// ください。
52//
53// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
54// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
55// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
56// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
57// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
58// 公益保護にご協力いただきますようお願い申し上げます。
59//
60// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
61// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
62// を保護するための努力を行います。
63//
64// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
65// 日本国内の脆弱性情報届出受付公的機関:
66//         独立行政法人 情報処理推進機構
67//         http://www.ipa.go.jp/security/vuln/report/
68//
69// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
70// 連絡先: http://www.softether.co.jp/jp/contact/
71
72// -----------------------------------------------
73// [ChangeLog]
74// 2010.05.20
75//  新規リリース by SoftEther
76// -----------------------------------------------
77
78// Table.c
79// 文字列テーブル読み込み & 管理ルーチン
80
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <wchar.h>
85#include <stdarg.h>
86#include <time.h>
87#include <errno.h>
88#include <Mayaqua/Mayaqua.h>
89
90// TABLE のリスト
91static LIST *TableList = NULL;
92static wchar_t old_table_name[MAX_SIZE] = {0};      // 古いテーブル名
93
94// エラー文字列を Unicode で取得する
95wchar_t *GetUniErrorStr(UINT err)
96{
97    wchar_t *ret;
98    char name[MAX_SIZE];
99    Format(name, sizeof(name), "ERR_%u", err);
100
101    ret = GetTableUniStr(name);
102    if (UniStrLen(ret) != 0)
103    {
104        return ret;
105    }
106    else
107    {
108        return _UU("ERR_UNKNOWN");
109    }
110}
111
112// エラー文字列を取得する
113char *GetErrorStr(UINT err)
114{
115    char *ret;
116    char name[MAX_SIZE];
117    Format(name, sizeof(name), "ERR_%u", err);
118
119    ret = GetTableStr(name);
120    if (StrLen(ret) != 0)
121    {
122        return ret;
123    }
124    else
125    {
126        return _SS("ERR_UNKNOWN");
127    }
128}
129
130// テーブルから整数値をロードする
131UINT GetTableInt(char *name)
132{
133    char *str;
134    // 引数チェック
135    if (name == NULL)
136    {
137        return 0;
138    }
139
140    str = GetTableStr(name);
141    return ToInt(str);
142}
143
144// テーブルから Unicode 文字列をロードする
145wchar_t *GetTableUniStr(char *name)
146{
147    TABLE *t;
148    // 引数チェック
149    if (name == NULL)
150    {
151//      Debug("%s: ************\n", name);
152        return L"";
153    }
154
155    // 検索
156    t = FindTable(name);
157    if (t == NULL)
158    {
159//      Debug("%s: UNICODE STRING NOT FOUND\n", name);
160        return L"";
161    }
162
163    return t->unistr;
164}
165
166// テーブルから文字列をロードする
167char *GetTableStr(char *name)
168{
169    TABLE *t;
170    // 引数チェック
171    if (name == NULL)
172    {
173        return "";
174    }
175
176#ifdef  OS_WIN32
177    if (StrCmpi(name, "DEFAULT_FONT") == 0)
178    {
179        if (_II("LANG") == 2)
180        {
181            UINT os_type = GetOsType();
182            if (OS_IS_WINDOWS_9X(os_type) ||
183                GET_KETA(os_type, 100) <= 4)
184            {
185                // Windows 9x, Windows NT 4.0, Windows 2000, Windows XP, Windows Server 2003 の場合は SimSun フォントを利用する
186                return "SimSun";
187            }
188        }
189    }
190#endif  // OS_WIN32
191
192    // 検索
193    t = FindTable(name);
194    if (t == NULL)
195    {
196//      Debug("%s: ANSI STRING NOT FOUND\n", name);
197        return "";
198    }
199
200    return t->str;
201}
202
203// 指定した名前で始まる文字列名を取得する
204TOKEN_LIST *GetTableNameStartWith(char *str)
205{
206    UINT i;
207    UINT len;
208    LIST *o;
209    TOKEN_LIST *t;
210    char tmp[MAX_SIZE];
211    // 引数チェック
212    if (str == NULL)
213    {
214        return NullToken();
215    }
216
217    StrCpy(tmp, sizeof(tmp), str);
218    StrUpper(tmp);
219
220    len = StrLen(tmp);
221
222    o = NewListFast(NULL);
223
224    for (i = 0;i < LIST_NUM(TableList);i++)
225    {
226        TABLE *t = LIST_DATA(TableList, i);
227        UINT len2 = StrLen(t->name);
228
229        if (len2 >= len)
230        {
231            if (Cmp(t->name, tmp, len) == 0)
232            {
233                Insert(o, CopyStr(t->name));
234            }
235        }
236    }
237
238    t = ZeroMalloc(sizeof(TOKEN_LIST));
239    t->NumTokens = LIST_NUM(o);
240    t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
241
242    for (i = 0;i < t->NumTokens;i++)
243    {
244        t->Token[i] = LIST_DATA(o, i);
245    }
246
247    ReleaseList(o);
248
249    return t;
250}
251
252// テーブルを検索する
253TABLE *FindTable(char *name)
254{
255    TABLE *t, tt;
256    // 引数チェック
257    if (name == NULL || TableList == NULL)
258    {
259        return NULL;
260    }
261
262    tt.name = CopyStr(name);
263    t = Search(TableList, &tt);
264    Free(tt.name);
265
266    return t;
267}
268
269// テーブル名を比較する関数
270int CmpTableName(void *p1, void *p2)
271{
272    TABLE *t1, *t2;
273    if (p1 == NULL || p2 == NULL)
274    {
275        return 0;
276    }
277    t1 = *(TABLE **)p1;
278    t2 = *(TABLE **)p2;
279    if (t1 == NULL || t2 == NULL)
280    {
281        return 0;
282    }
283
284    return StrCmpi(t1->name, t2->name);
285}
286
287// 1 行を解釈する
288TABLE *ParseTableLine(char *line, char *prefix, UINT prefix_size)
289{
290    UINT i, len;
291    UINT len_name;
292    UINT string_start;
293    char *name;
294    char *name2;
295    UINT name2_size;
296    wchar_t *unistr;
297    char *str;
298    UINT unistr_size, str_size;
299    TABLE *t;
300    // 引数チェック
301    if (line == NULL || prefix == NULL)
302    {
303        return NULL;
304    }
305    TrimLeft(line);
306
307    // 行無し
308    len = StrLen(line);
309    if (len == 0)
310    {
311        return NULL;
312    }
313
314    // コメント
315    if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
316    {
317        return NULL;
318    }
319
320    // 名前の終了位置まで検索
321    len_name = 0;
322    for (i = 0;;i++)
323    {
324        if (line[i] == 0)
325        {
326            // トークンが 1 つしか無い
327            return NULL;
328        }
329        if (line[i] == ' ' || line[i] == '\t')
330        {
331            break;
332        }
333        len_name++;
334    }
335
336    name = Malloc(len_name + 1);
337    StrCpy(name, len_name + 1, line);
338
339    string_start = len_name;
340    for (i = len_name;i < len;i++)
341    {
342        if (line[i] != ' ' && line[i] != '\t')
343        {
344            break;
345        }
346        string_start++;
347    }
348    if (i == len)
349    {
350        Free(name);
351        return NULL;
352    }
353
354    // アンエスケープ
355    UnescapeStr(&line[string_start]);
356
357    // Unicode に変換する
358    unistr_size = CalcUtf8ToUni(&line[string_start], StrLen(&line[string_start]));
359    if (unistr_size == 0)
360    {
361        Free(name);
362        return NULL;
363    }
364    unistr = Malloc(unistr_size);
365    Utf8ToUni(unistr, unistr_size, &line[string_start], StrLen(&line[string_start]));
366
367    // ANSI に変換する
368    str_size = CalcUniToStr(unistr);
369    if (str_size == 0)
370    {
371        str_size = 1;
372        str = Malloc(1);
373        str[0] = 0;
374    }
375    else
376    {
377        str = Malloc(str_size);
378        UniToStr(str, str_size, unistr);
379    }
380
381    if (StrCmpi(name, "PREFIX") == 0)
382    {
383        // プレフィックスが指定された
384        StrCpy(prefix, prefix_size, str);
385        Trim(prefix);
386
387        if (StrCmpi(prefix, "$") == 0 || StrCmpi(prefix, "NULL") == 0)
388        {
389            prefix[0] = 0;
390        }
391
392        Free(name);
393        Free(str);
394        Free(unistr);
395
396        return NULL;
397    }
398
399    name2_size = StrLen(name) + StrLen(prefix) + 2;
400    name2 = ZeroMalloc(name2_size);
401
402    if (prefix[0] != 0)
403    {
404        StrCat(name2, name2_size, prefix);
405        StrCat(name2, name2_size, "@");
406    }
407
408    StrCat(name2, name2_size, name);
409
410    Free(name);
411
412    // TABLE を作成する
413    t = Malloc(sizeof(TABLE));
414    StrUpper(name2);
415    t->name = name2;
416    t->str = str;
417    t->unistr = unistr;
418
419    return t;
420}
421
422// 文字列のアンエスケープ
423void UnescapeStr(char *src)
424{
425    UINT i, len, wp;
426    char *tmp;
427    // 引数チェック
428    if (src == NULL)
429    {
430        return;
431    }
432   
433    len = StrLen(src);
434    tmp = Malloc(len + 1);
435    wp = 0;
436    for (i = 0;i < len;i++)
437    {
438        if (src[i] == '\\')
439        {
440            i++;
441            switch (src[i])
442            {
443            case 0:
444                goto FINISH;
445            case '\\':
446                tmp[wp++] = '\\';
447                break;
448            case ' ':
449                tmp[wp++] = ' ';
450                break;
451            case 'n':
452            case 'N':
453                tmp[wp++] = '\n';
454                break;
455            case 'r':
456            case 'R':
457                tmp[wp++] = '\r';
458                break;
459            case 't':
460            case 'T':
461                tmp[wp++] = '\t';
462                break;
463            }
464        }
465        else
466        {
467            tmp[wp++] = src[i];
468        }
469    }
470FINISH:
471    tmp[wp++] = 0;
472    StrCpy(src, 0, tmp);
473    Free(tmp);
474}
475
476// テーブルを解放する
477void FreeTable()
478{
479    UINT i, num;
480    TABLE **tables;
481    if (TableList == NULL)
482    {
483        return;
484    }
485
486    TrackingDisable();
487
488    num = LIST_NUM(TableList);
489    tables = ToArray(TableList);
490    for (i = 0;i < num;i++)
491    {
492        TABLE *t = tables[i];
493        Free(t->name);
494        Free(t->str);
495        Free(t->unistr);
496        Free(t);
497    }
498    ReleaseList(TableList);
499    TableList = NULL;
500    Free(tables);
501
502    Zero(old_table_name, sizeof(old_table_name));
503
504    TrackingEnable();
505}
506
507// バッファから文字列テーブルを読み込む
508bool LoadTableFromBuf(BUF *b)
509{
510    char *tmp;
511    char prefix[MAX_SIZE];
512    // 引数チェック
513    if (b == NULL)
514    {
515        return false;
516    }
517
518    // すでにテーブルがある場合は削除する
519    FreeTable();
520
521    // リストを作成する
522    TableList = NewList(CmpTableName);
523
524    Zero(prefix, sizeof(prefix));
525
526    // バッファの内容を 1 行ずつ読んでいく
527    while (true)
528    {
529        TABLE *t;
530        tmp = CfgReadNextLine(b);
531        if (tmp == NULL)
532        {
533            break;
534        }
535        t = ParseTableLine(tmp, prefix, sizeof(prefix));
536        if (t != NULL)
537        {
538            // 登録する
539            Insert(TableList, t);
540        }
541        Free(tmp);
542    }
543
544    return true;
545}
546
547// Unicode 文字列キャッシュファイル名の生成
548void GenerateUnicodeCacheFileName(wchar_t *name, UINT size, wchar_t *strfilename, UINT strfilesize, UCHAR *filehash)
549{
550    wchar_t tmp[MAX_SIZE];
551    wchar_t hashstr[64];
552    wchar_t hashtemp[MAX_SIZE];
553    wchar_t exe[MAX_SIZE];
554    UCHAR hash[SHA1_SIZE];
555    // 引数チェック
556    if (name == NULL || strfilename == NULL || filehash == NULL)
557    {
558        return;
559    }
560
561    GetExeDirW(exe, sizeof(exe));
562    UniStrCpy(hashtemp, sizeof(hashtemp), strfilename);
563    BinToStrW(tmp, sizeof(tmp), filehash, MD5_SIZE);
564    UniStrCat(hashtemp, sizeof(hashtemp), tmp);
565    UniStrCat(hashtemp, sizeof(hashtemp), exe);
566    UniStrLower(hashtemp);
567
568    Hash(hash, hashtemp, UniStrLen(hashtemp) * sizeof(wchar_t), true);
569    BinToStrW(hashstr, sizeof(hashstr), hash, 4);
570    UniFormat(tmp, sizeof(tmp), UNICODE_CACHE_FILE, hashstr);
571    UniStrLower(tmp);
572
573#ifndef OS_WIN32
574    UniStrCpy(exe, sizeof(exe), L"/tmp");
575#else   // OS_WIN32
576    StrToUni(exe, sizeof(exe), MsGetTempDir());
577#endif  // OS_WIN32
578
579    UniFormat(name, size, L"%s/%s", exe, tmp);
580    NormalizePathW(name, size, name);
581}
582
583// Unicode キャッシュの保存
584void SaveUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
585{
586    UNICODE_CACHE c;
587    BUF *b;
588    UINT i;
589    IO *io;
590    wchar_t name[MAX_PATH];
591    UCHAR binhash[MD5_SIZE];
592    // 引数チェック
593    if (strfilename == NULL || hash == NULL)
594    {
595        return;
596    }
597
598    Zero(&c, sizeof(c));
599    UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
600    c.StrFileSize = strfilesize;
601    GetMachineName(c.MachineName, sizeof(c.MachineName));
602    c.OsType = GetOsInfo()->OsType;
603    Copy(c.hash, hash, MD5_SIZE);
604
605#ifdef  OS_UNIX
606    GetCurrentCharSet(c.CharSet, sizeof(c.CharSet));
607#else   // OS_UNIX
608    {
609        UINT id = MsGetThreadLocale();
610        Copy(c.CharSet, &id, sizeof(id));
611    }
612#endif  // OS_UNIX
613
614    b = NewBuf();
615    WriteBuf(b, &c, sizeof(c));
616
617    WriteBufInt(b, LIST_NUM(TableList));
618    for (i = 0;i < LIST_NUM(TableList);i++)
619    {
620        TABLE *t = LIST_DATA(TableList, i);
621        WriteBufInt(b, StrLen(t->name));
622        WriteBuf(b, t->name, StrLen(t->name));
623        WriteBufInt(b, StrLen(t->str));
624        WriteBuf(b, t->str, StrLen(t->str));
625        WriteBufInt(b, UniStrLen(t->unistr));
626        WriteBuf(b, t->unistr, UniStrLen(t->unistr) * sizeof(wchar_t));
627    }
628
629    Hash(binhash, b->Buf, b->Size, false);
630    WriteBuf(b, binhash, MD5_SIZE);
631
632    GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash);
633
634    io = FileCreateW(name);
635    if (io != NULL)
636    {
637        SeekBuf(b, 0, 0);
638        BufToFile(io, b);
639        FileClose(io);
640    }
641
642    FreeBuf(b);
643}
644
645// Unicode キャッシュの読み込み
646bool LoadUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
647{
648    UNICODE_CACHE c, t;
649    BUF *b;
650    UINT i, num;
651    IO *io;
652    wchar_t name[MAX_PATH];
653    UCHAR binhash[MD5_SIZE];
654    UCHAR binhash_2[MD5_SIZE];
655    // 引数チェック
656    if (strfilename == NULL || hash == NULL)
657    {
658        return false;
659    }
660
661    GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash);
662
663    io = FileOpenW(name, false);
664    if (io == NULL)
665    {
666        return false;
667    }
668
669    b = FileToBuf(io);
670    if (b == NULL)
671    {
672        FileClose(io);
673        return false;
674    }
675
676    SeekBuf(b, 0, 0);
677    FileClose(io);
678
679    Hash(binhash, b->Buf, b->Size >= MD5_SIZE ? (b->Size - MD5_SIZE) : 0, false);
680    Copy(binhash_2, ((UCHAR *)b->Buf) + (b->Size >= MD5_SIZE ? (b->Size - MD5_SIZE) : 0), MD5_SIZE);
681    if (Cmp(binhash, binhash_2, MD5_SIZE) != 0)
682    {
683        FreeBuf(b);
684        return false;
685    }
686
687    Zero(&c, sizeof(c));
688    UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
689    c.StrFileSize = strfilesize;
690    DisableNetworkNameCache();
691    GetMachineName(c.MachineName, sizeof(c.MachineName));
692    EnableNetworkNameCache();
693    c.OsType = GetOsInfo()->OsType;
694    Copy(c.hash, hash, MD5_SIZE);
695
696#ifdef  OS_UNIX
697    GetCurrentCharSet(c.CharSet, sizeof(c.CharSet));
698#else   // OS_UNIX
699    {
700        UINT id = MsGetThreadLocale();
701        Copy(c.CharSet, &id, sizeof(id));
702    }
703#endif  // OS_UNIX
704
705    Zero(&t, sizeof(t));
706    ReadBuf(b, &t, sizeof(t));
707
708    if (Cmp(&c, &t, sizeof(UNICODE_CACHE)) != 0)
709    {
710        FreeBuf(b);
711        return false;
712    }
713
714    num = ReadBufInt(b);
715
716    FreeTable();
717    TableList = NewList(CmpTableName);
718
719    for (i = 0;i < num;i++)
720    {
721        UINT len;
722        TABLE *t = ZeroMalloc(sizeof(TABLE));
723
724        len = ReadBufInt(b);
725        t->name = ZeroMalloc(len + 1);
726        ReadBuf(b, t->name, len);
727
728        len = ReadBufInt(b);
729        t->str = ZeroMalloc(len + 1);
730        ReadBuf(b, t->str, len);
731
732        len = ReadBufInt(b);
733        t->unistr = ZeroMalloc((len + 1) * sizeof(wchar_t));
734        ReadBuf(b, t->unistr, len * sizeof(wchar_t));
735
736        Add(TableList, t);
737    }
738
739    FreeBuf(b);
740
741    Sort(TableList);
742
743    return true;
744}
745
746// 文字列テーブルを読み込む
747bool LoadTableMain(wchar_t *filename)
748{
749    BUF *b;
750    UINT64 t1, t2;
751    UCHAR hash[MD5_SIZE];
752    // 引数チェック
753    if (filename == NULL)
754    {
755        return false;
756    }
757
758    if (MayaquaIsMinimalMode())
759    {
760        return true;
761    }
762
763    if (UniStrCmpi(old_table_name, filename) == 0)
764    {
765        // すでに読み込まれている
766        return true;
767    }
768
769    t1 = Tick64();
770
771    // ファイルを開く
772    b = ReadDumpW(filename);
773    if (b == NULL)
774    {
775        char tmp[MAX_SIZE];
776        StrCpy(tmp, sizeof(tmp), "Error: Can't read string tables (file not found).\r\nPlease check hamcore.utvpn.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)");
777        Alert(tmp, NULL);
778        exit(0);
779        return false;
780    }
781
782    Hash(hash, b->Buf, b->Size, false);
783
784    if (LoadUnicodeCache(filename, b->Size, hash) == false)
785    {
786        if (LoadTableFromBuf(b) == false)
787        {
788            FreeBuf(b);
789            return false;
790        }
791
792        SaveUnicodeCache(filename, b->Size, hash);
793
794        Debug("Unicode Source: strtable.stb\n");
795    }
796    else
797    {
798        Debug("Unicode Source: unicode_cache\n");
799    }
800
801    FreeBuf(b);
802
803    SetLocale(_UU("DEFAULE_LOCALE"));
804
805    UniStrCpy(old_table_name, sizeof(old_table_name), filename);
806
807    t2 = Tick64();
808
809    if (StrCmpi(_SS("STRTABLE_ID"), STRTABLE_ID) != 0)
810    {
811        char tmp[MAX_SIZE];
812        StrCpy(tmp, sizeof(tmp), "Error: Can't read string tables (invalid version).\r\nPlease check hamcore.utvpn.\r\n\r\n(First, reboot the computer. If this problem occurs again, please reinstall VPN software files.)");
813        Alert(tmp, NULL);
814        exit(0);
815        return false;
816    }
817
818    Debug("Unicode File Read Cost: %u (%u Lines)\n", (UINT)(t2 - t1), LIST_NUM(TableList));
819
820    return true;
821}
822bool LoadTable(char *filename)
823{
824    wchar_t *filename_a = CopyStrToUni(filename);
825    bool ret = LoadTableW(filename_a);
826
827    Free(filename_a);
828
829    return ret;
830}
831bool LoadTableW(wchar_t *filename)
832{
833    bool ret;
834    BUF *b;
835    wchar_t replace_name[MAX_PATH];
836
837    Zero(replace_name, sizeof(replace_name));
838
839    TrackingDisable();
840
841    b = ReadDump("@table_name.txt");
842    if (b != NULL)
843    {
844        char *s = CfgReadNextLine(b);
845        if (s != NULL)
846        {
847            if (IsEmptyStr(s) == false)
848            {
849                StrToUni(replace_name, sizeof(replace_name), s);
850                filename = replace_name;
851            }
852
853            Free(s);
854        }
855        FreeBuf(b);
856    }
857
858    ret = LoadTableMain(filename);
859
860    TrackingEnable();
861
862    return ret;
863}
864
865
Note: See TracBrowser for help on using the repository browser.