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