* copy vendor drop to trunk
[lab.git] / Dev / utvpn / utvpn-unix-v101-7101-public / src / Mayaqua / Mayaqua.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 // Mayaqua.c\r
79 // Mayaqua Kernel プログラム\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 <locale.h>\r
87 #include <time.h>\r
88 #include <errno.h>\r
89 #include <Mayaqua/Mayaqua.h>\r
90 \r
91 // グローバル変数\r
92 bool g_memcheck;                                                                // メモリチェックの有効化\r
93 bool g_debug;                                                                   // デバッグモード\r
94 UINT64 kernel_status[NUM_KERNEL_STATUS];                // カーネル状態\r
95 UINT64 kernel_status_max[NUM_KERNEL_STATUS];    // カーネル状態 (最大値)\r
96 LOCK *kernel_status_lock[NUM_KERNEL_STATUS];    // カーネル状態ロック\r
97 BOOL kernel_status_inited = false;                              // カーネル状態初期化フラグ\r
98 bool g_little_endian = true;\r
99 char *cmdline = NULL;                                                   // コマンドライン\r
100 wchar_t *uni_cmdline = NULL;                                    // Unicode コマンドライン\r
101 \r
102 // スタティック変数\r
103 static char *exename = NULL;                                            // EXE ファイル名 (ANSI)\r
104 static wchar_t *exename_w = NULL;                                       // EXE ファイル名 (Unicode)\r
105 static TOKEN_LIST *cmdline_token = NULL;                        // コマンドライントークン\r
106 static UNI_TOKEN_LIST *cmdline_uni_token = NULL;        // コマンドライントークン (Unicode)\r
107 static OS_INFO *os_info = NULL;                                         // OS 情報\r
108 static bool dot_net_mode = false;\r
109 static bool minimal_mode = false;\r
110 static UINT last_time_check = 0;\r
111 static UINT first_time_check = 0;\r
112 static bool is_nt = false;\r
113 static bool is_ham_mode = false;\r
114 static UINT init_mayaqua_counter = 0;\r
115 static bool use_probe = false;\r
116 static BUF *probe_buf = NULL;\r
117 static LOCK *probe_lock = NULL;\r
118 static UINT64 probe_start = 0;\r
119 static UINT64 probe_last = 0;\r
120 static bool probe_enabled = false;\r
121 \r
122 // チェックサムを計算する\r
123 USHORT CalcChecksum16(void *buf, UINT size)\r
124 {\r
125         int sum = 0;\r
126         USHORT *addr = (USHORT *)buf;\r
127         int len = (int)size;\r
128         USHORT *w = addr;\r
129         int nleft = len;\r
130         USHORT answer = 0;\r
131 \r
132         while (nleft > 1)\r
133         {\r
134                 sum += *w++;\r
135                 nleft -= 2;\r
136         }\r
137 \r
138         if (nleft == 1)\r
139         {\r
140                 *(UCHAR *)(&answer) = *(UCHAR *)w;\r
141                 sum += answer;\r
142         }\r
143 \r
144         sum = (sum >> 16) + (sum & 0xffff);\r
145         sum += (sum >> 16);\r
146 \r
147         answer = ~sum;\r
148 \r
149         return answer;\r
150 }\r
151 \r
152 // データ付き Probe の書き込み\r
153 void WriteProbeData(char *filename, UINT line, char *str, void *data, UINT size)\r
154 {\r
155         char tmp[MAX_SIZE];\r
156         USHORT cs;\r
157 \r
158         if (IsProbeEnabled() == false)\r
159         {\r
160                 return;\r
161         }\r
162 \r
163         // データのチェックサムをとる\r
164         if (size != 0)\r
165         {\r
166                 cs = CalcChecksum16(data, size);\r
167         }\r
168         else\r
169         {\r
170                 cs = 0;\r
171         }\r
172 \r
173         // 文字列の生成\r
174         snprintf(tmp, sizeof(tmp), "\"%s\" (Size=%5u, Crc=0x%04X)", str, size, cs);\r
175 \r
176         WriteProbe(filename, line, tmp);\r
177 }\r
178 \r
179 // Probe の書き込み\r
180 void WriteProbe(char *filename, UINT line, char *str)\r
181 {\r
182 #ifdef  OS_WIN32\r
183         char *s;\r
184         char tmp[MAX_SIZE];\r
185         char tmp2[MAX_SIZE];\r
186         UINT64 now = 0;\r
187         UINT64 time;\r
188 \r
189         if (IsProbeEnabled() == false)\r
190         {\r
191                 return;\r
192         }\r
193 \r
194         now = MsGetHiResCounter();\r
195 \r
196         Lock(probe_lock);\r
197         {\r
198                 UINT64 diff;\r
199                 \r
200                 time = MsGetHiResTimeSpanUSec(now - probe_start);\r
201 \r
202                 diff = time - probe_last;\r
203 \r
204                 if (time < probe_last)\r
205                 {\r
206                         diff = 0;\r
207                 }\r
208 \r
209                 probe_last = time;\r
210 \r
211                 ToStr64(tmp, time);\r
212                 MakeCharArray2(tmp2, ' ', (UINT)(MIN(12, (int)12 - (int)StrLen(tmp))));\r
213                 WriteBuf(probe_buf, tmp2, StrLen(tmp2));\r
214                 WriteBuf(probe_buf, tmp, StrLen(tmp));\r
215 \r
216                 s = " [+";\r
217                 WriteBuf(probe_buf, s, StrLen(s));\r
218 \r
219                 ToStr64(tmp, diff);\r
220                 MakeCharArray2(tmp2, ' ', (UINT)(MIN(12, (int)12 - (int)StrLen(tmp))));\r
221                 WriteBuf(probe_buf, tmp2, StrLen(tmp2));\r
222                 WriteBuf(probe_buf, tmp, StrLen(tmp));\r
223 \r
224                 s = "] - ";\r
225                 WriteBuf(probe_buf, s, StrLen(s));\r
226 \r
227                 WriteBuf(probe_buf, filename, StrLen(filename));\r
228 \r
229                 s = "(";\r
230                 WriteBuf(probe_buf, s, StrLen(s));\r
231 \r
232                 ToStr64(tmp, (UINT64)line);\r
233                 WriteBuf(probe_buf, tmp, StrLen(tmp));\r
234 \r
235                 s = "): ";\r
236                 WriteBuf(probe_buf, s, StrLen(s));\r
237 \r
238                 WriteBuf(probe_buf, str, StrLen(str));\r
239 \r
240                 s = "\r\n";\r
241                 WriteBuf(probe_buf, s, StrLen(s));\r
242         }\r
243         Unlock(probe_lock);\r
244 #endif  // OS_WIN32\r
245 }\r
246 \r
247 // Probe の初期化\r
248 void InitProbe()\r
249 {\r
250         probe_buf = NewBuf();\r
251         probe_lock = NewLock();\r
252         probe_enabled = false;\r
253 \r
254         probe_start = 0;\r
255 \r
256 #ifdef  OS_WIN32\r
257         probe_start = MsGetHiResCounter();\r
258 #endif  // OS_WIN32\r
259 }\r
260 \r
261 // Probe の解放\r
262 void FreeProbe()\r
263 {\r
264         if (probe_buf->Size >= 1)\r
265         {\r
266                 SYSTEMTIME st;\r
267                 char filename[MAX_SIZE];\r
268 \r
269                 // ファイルにすべて書き出す\r
270                 MakeDirEx("@probe_log");\r
271 \r
272                 LocalTime(&st);\r
273 \r
274                 snprintf(filename, sizeof(filename), "@probe_log/%04u%02u%02u_%02u%02u%02u.log",\r
275                         st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);\r
276 \r
277                 DumpBuf(probe_buf, filename);\r
278         }\r
279 \r
280         FreeBuf(probe_buf);\r
281         DeleteLock(probe_lock);\r
282 }\r
283 \r
284 // Probe を有効 / 無効にする\r
285 void EnableProbe(bool enable)\r
286 {\r
287         probe_enabled = enable;\r
288 }\r
289 \r
290 // Probe が有効かどうか取得する\r
291 bool IsProbeEnabled()\r
292 {\r
293 #ifndef USE_PROBE\r
294         return false;\r
295 #else   // USE_PROBE\r
296         return probe_enabled;\r
297 #endif  // USE_PROBE\r
298 }\r
299 \r
300 // Ham モードに設定する\r
301 void SetHamMode()\r
302 {\r
303         is_ham_mode = true;\r
304 }\r
305 \r
306 // Ham モードかどうか取得する\r
307 bool IsHamMode()\r
308 {\r
309         return is_ham_mode;\r
310 }\r
311 \r
312 // 前回の呼び出しから現在までにかかった時間を表示\r
313 void TimeCheck()\r
314 {\r
315 #ifdef OS_WIN32\r
316         UINT now, ret, total;\r
317         now = Win32GetTick();\r
318         if (last_time_check == 0)\r
319         {\r
320                 ret = 0;\r
321         }\r
322         else\r
323         {\r
324                 ret = now - last_time_check;\r
325         }\r
326         last_time_check = now;\r
327 \r
328         if (first_time_check == 0)\r
329         {\r
330                 first_time_check = now;\r
331         }\r
332 \r
333         total = now - first_time_check;\r
334 \r
335         printf(" -- %3.3f / %3.3f\n", (double)ret / 1000.0f, (double)total / 1000.0f);\r
336 #endif  // OS_WIN32\r
337 }\r
338 \r
339 // IA64 かどうか\r
340 bool IsIA64()\r
341 {\r
342         if (Is64() == false)\r
343         {\r
344                 return false;\r
345         }\r
346 \r
347 #ifndef MAYAQUA_IA_64\r
348         return false;\r
349 #else   // MAYAQUA_IA_64\r
350         return true;\r
351 #endif  // MAYAQUA_IA_64\r
352 }\r
353 \r
354 // x64 かどうか\r
355 bool IsX64()\r
356 {\r
357         if (Is64() == false)\r
358         {\r
359                 return false;\r
360         }\r
361 \r
362 #ifndef MAYAQUA_IA_64\r
363         return true;\r
364 #else   // MAYAQUA_IA_64\r
365         return false;\r
366 #endif  // MAYAQUA_IA_64\r
367 }\r
368 \r
369 // 64bit かどうか\r
370 bool Is64()\r
371 {\r
372 #ifdef  CPU_64\r
373         return true;\r
374 #else   // CPU_64\r
375         return false;\r
376 #endif  // CPU_64\r
377 }\r
378 \r
379 // 32bit かどうか\r
380 bool Is32()\r
381 {\r
382         return Is64() ? false : true;\r
383 }\r
384 \r
385 // .NET モード\r
386 void MayaquaDotNetMode()\r
387 {\r
388         dot_net_mode = true;\r
389 }\r
390 \r
391 // .NET モードかどうか取得\r
392 bool MayaquaIsDotNetMode()\r
393 {\r
394         return dot_net_mode;\r
395 }\r
396 \r
397 // エンディアンチェック\r
398 void CheckEndian()\r
399 {\r
400         unsigned short test;\r
401         UCHAR *buf;\r
402 \r
403         test = 0x1234;\r
404         buf = (UCHAR *)&test;\r
405         if (buf[0] == 0x12)\r
406         {\r
407                 g_little_endian = false;\r
408         }\r
409         else\r
410         {\r
411                 g_little_endian = true;\r
412         }\r
413 }\r
414 \r
415 // 最小モードにする\r
416 void MayaquaMinimalMode()\r
417 {\r
418         minimal_mode = true;\r
419 }\r
420 bool MayaquaIsMinimalMode()\r
421 {\r
422         return minimal_mode;\r
423 }\r
424 \r
425 // NT かどうか\r
426 bool IsNt()\r
427 {\r
428         return is_nt;\r
429 }\r
430 \r
431 // Unicode をサポートしているかどうか\r
432 bool IsUnicode()\r
433 {\r
434 #ifdef  OS_WIN32\r
435         // Windows\r
436         return IsNt();\r
437 #else   // OS_WIN32\r
438         // UNIX\r
439         return true;\r
440 #endif  // OS_WIN32\r
441 }\r
442 \r
443 // Mayaqua ライブラリの初期化\r
444 void InitMayaqua(bool memcheck, bool debug, int argc, char **argv)\r
445 {\r
446         wchar_t tmp[MAX_PATH];\r
447 \r
448         if ((init_mayaqua_counter++) > 0)\r
449         {\r
450                 return;\r
451         }\r
452 \r
453         g_memcheck = memcheck;\r
454         g_debug = debug;\r
455         cmdline = NULL;\r
456         if (dot_net_mode == false)\r
457         {\r
458                 // .NET モードでこれを呼ぶとなぜか落ちる\r
459                 setbuf(stdout, NULL);\r
460         }\r
461 \r
462         // NT かどうか取得\r
463 #ifdef  OS_WIN32\r
464         is_nt = Win32IsNt();\r
465 #endif  // OS_WIN32\r
466 \r
467         // エンディアンチェック\r
468         CheckEndian();\r
469 \r
470 #ifdef  OS_WIN32\r
471         _configthreadlocale(_DISABLE_PER_THREAD_LOCALE);\r
472 #endif  // OS_WIN32\r
473 \r
474         // CRT のロケール情報を日本語にする\r
475         setlocale(LC_ALL, "");\r
476 \r
477         // OS の初期化\r
478         OSInit();\r
479 \r
480         // 乱数の初期化\r
481         srand((UINT)SystemTime64());\r
482 \r
483         tick_manual_lock = NewLock();\r
484 \r
485         // FIFO システムの初期化\r
486         InitFifo();\r
487 \r
488         // カーネルステータスの初期化\r
489         InitKernelStatus();\r
490 \r
491         // トラッキングの初期化\r
492         InitTracking();\r
493 \r
494         // スレッドプールの初期化\r
495         InitThreading();\r
496 \r
497         // 文字列ライブラリの初期化\r
498         InitStringLibrary();\r
499 \r
500         // ロケール情報の初期化\r
501         SetLocale(NULL);\r
502 \r
503         // 暗号化ライブラリの初期化\r
504         InitCryptLibrary();\r
505 \r
506         // リアルタイムクロックの初期化\r
507         InitTick64();\r
508 \r
509         // ネットワーク通信モジュールの初期化\r
510         InitNetwork();\r
511 \r
512         // EXE ファイル名の取得の初期化\r
513         InitGetExeName(argc >= 1 ? argv[0] : NULL);\r
514 \r
515         // コマンドライン文字列の初期化\r
516         InitCommandLineStr(argc, argv);\r
517 \r
518         // OS 情報の初期化\r
519         InitOsInfo();\r
520 \r
521         // オペレーティングシステム固有の初期化\r
522 #ifdef  OS_WIN32\r
523         MsInit();       // Microsoft Win32\r
524 #endif  // OS_WIN32\r
525 \r
526         // セキュリティトークンモジュールの初期化\r
527         InitSecure();\r
528 \r
529         if (OSIsSupportedOs() == false)\r
530         {\r
531                 // 強制終了\r
532                 exit(0);\r
533         }\r
534 \r
535         // RSA チェック\r
536         if (RsaCheckEx() == false)\r
537         {\r
538                 // 強制終了\r
539                 Alert("OpenSSL Library Init Failed. (too old?)\nPlease install the latest version of OpenSSL.\n\n", "RsaCheck()");\r
540                 exit(0);\r
541         }\r
542 \r
543         // HamCore ファイルシステムの初期化\r
544         InitHamcore();\r
545 \r
546         // デフォルトで japanese.stb を読み込む\r
547         LoadTable(DEFAULT_TABLE_FILE_NAME);\r
548 \r
549         if (exename == NULL)\r
550         {\r
551                 // 実行可能ファイル名\r
552                 exename = CopyStr("unknown");\r
553         }\r
554 \r
555         // 自分自身の実行可能ファイル名が見つかるかどうか検査する\r
556         // (見つからない場合は変なパスで起動されているので終了する)\r
557         GetExeNameW(tmp, sizeof(tmp));\r
558         if (IsFileExistsW(tmp) == false)\r
559         {\r
560                 wchar_t tmp2[MAX_SIZE];\r
561 \r
562                 UniFormat(tmp2, sizeof(tmp2),\r
563                         L"Error: Executable binary file \"%s\" not found.\r\n\r\n"\r
564                         L"Please execute program with full path.\r\n",\r
565                         tmp);\r
566 \r
567                 AlertW(tmp2, NULL);\r
568                 _exit(0);\r
569         }\r
570 \r
571         CheckUnixTempDir();\r
572 \r
573         // Probe の初期化\r
574         InitProbe();\r
575 }\r
576 \r
577 // Mayaqua ライブラリの解放\r
578 void FreeMayaqua()\r
579 {\r
580         if ((--init_mayaqua_counter) > 0)\r
581         {\r
582                 return;\r
583         }\r
584 \r
585         // Probe の解放\r
586         FreeProbe();\r
587 \r
588         // テーブルを削除\r
589         FreeTable();\r
590 \r
591         // セキュリティトークンモジュールの解放\r
592         FreeSecure();\r
593 \r
594         // オペレーティングシステム固有の解放\r
595 #ifdef  OS_WIN32\r
596         MsFree();\r
597 #endif  // OS_WIN32\r
598 \r
599         // OS 情報の解放\r
600         FreeOsInfo();\r
601 \r
602         // HamCore ファイルシステムの解放\r
603         FreeHamcore();\r
604 \r
605         // コマンドライン文字列の解放\r
606         FreeCommandLineStr();\r
607 \r
608         // コマンドライントークンの解放\r
609         FreeCommandLineTokens();\r
610 \r
611         // ネットワーク通信モジュールの解放\r
612         FreeNetwork();\r
613 \r
614         // リアルタイムクロックの解放\r
615         FreeTick64();\r
616 \r
617         // 暗号化ライブラリの解放\r
618         FreeCryptLibrary();\r
619 \r
620         // 文字列ライブラリの解放\r
621         FreeStringLibrary();\r
622 \r
623         // スレッドプールの解放\r
624         FreeThreading();\r
625 \r
626 #ifndef VPN_SPEED\r
627         // カーネル状態の表示\r
628         if (g_debug)\r
629         {\r
630                 PrintKernelStatus();\r
631         }\r
632 \r
633         // デバッグ情報の表示\r
634         if (g_memcheck)\r
635         {\r
636                 PrintDebugInformation();\r
637         }\r
638 #endif  // VPN_SPEED\r
639 \r
640         // トラッキングの解放\r
641         FreeTracking();\r
642 \r
643         // カーネルステータスの解放\r
644         FreeKernelStatus();\r
645 \r
646         DeleteLock(tick_manual_lock);\r
647         tick_manual_lock = NULL;\r
648 \r
649         // OS の解放\r
650         OSFree();\r
651 }\r
652 \r
653 // UNIX で /tmp が使用できるかどうか確認する\r
654 void CheckUnixTempDir()\r
655 {\r
656         if (OS_IS_UNIX(GetOsInfo()->OsType))\r
657         {\r
658                 char tmp[128], tmp2[64];\r
659                 UINT64 now = SystemTime64();\r
660                 IO *o;\r
661 \r
662                 MakeDir("/tmp");\r
663 \r
664                 Format(tmp2, sizeof(tmp2), "%I64u", now);\r
665 \r
666                 Format(tmp, sizeof(tmp), "/tmp/.%s", tmp2);\r
667 \r
668                 o = FileCreate(tmp);\r
669                 if (o == NULL)\r
670                 {\r
671                         o = FileOpen(tmp, false);\r
672                         if (o == NULL)\r
673                         {\r
674                                 Print("Unable to use /tmp.\n\n");\r
675                                 exit(0);\r
676                                 return;\r
677                         }\r
678                 }\r
679 \r
680                 FileClose(o);\r
681 \r
682                 FileDelete(tmp);\r
683         }\r
684 }\r
685 \r
686 // アラートの表示\r
687 void Alert(char *msg, char *caption)\r
688 {\r
689         OSAlert(msg, caption);\r
690 }\r
691 void AlertW(wchar_t *msg, wchar_t *caption)\r
692 {\r
693         OSAlertW(msg, caption);\r
694 }\r
695 \r
696 // OS 情報の表示\r
697 void PrintOsInfo(OS_INFO *info)\r
698 {\r
699         // 引数チェック\r
700         if (info == NULL)\r
701         {\r
702                 return;\r
703         }\r
704 \r
705         Print(\r
706                 "OS Type          : %u\n"\r
707                 "OS Service Pack  : %u\n"\r
708                 "os_is_windows    : %s\n"\r
709                 "os_is_windows_nt : %s\n"\r
710                 "OS System Name   : %s\n"\r
711                 "OS Product Name  : %s\n"\r
712                 "OS Vendor Name   : %s\n"\r
713                 "OS Version       : %s\n"\r
714                 "Kernel Name      : %s\n"\r
715                 "Kernel Version   : %s\n",\r
716                 info->OsType,\r
717                 info->OsServicePack,\r
718                 OS_IS_WINDOWS(info->OsType) ? "true" : "false",\r
719                 OS_IS_WINDOWS_NT(info->OsType) ? "true" : "false",\r
720                 info->OsSystemName,\r
721                 info->OsProductName,\r
722                 info->OsVendorName,\r
723                 info->OsVersion,\r
724                 info->KernelName,\r
725                 info->KernelVersion);\r
726 \r
727 #ifdef  OS_WIN32\r
728         {\r
729                 char *exe, *dir;\r
730                 exe = MsGetExeFileName();\r
731                 dir = MsGetExeDirName();\r
732 \r
733                 Print(\r
734                         "EXE File Path    : %s\n"\r
735                         "EXE Dir Path     : %s\n"\r
736                         "Process Id       : %u\n"\r
737                         "Process Handle   : 0x%X\n",\r
738                         exe, dir, MsGetCurrentProcessId(), MsGetCurrentProcess());\r
739         }\r
740 #endif  // OS_WIN32\r
741 }\r
742 \r
743 // OS 種類の取得\r
744 UINT GetOsType()\r
745 {\r
746         OS_INFO *i = GetOsInfo();\r
747 \r
748         if (i == NULL)\r
749         {\r
750                 return 0;\r
751         }\r
752 \r
753         return i->OsType;\r
754 }\r
755 \r
756 // OS 情報の取得\r
757 OS_INFO *GetOsInfo()\r
758 {\r
759         return os_info;\r
760 }\r
761 \r
762 // OS 情報の初期化\r
763 void InitOsInfo()\r
764 {\r
765         if (os_info != NULL)\r
766         {\r
767                 return;\r
768         }\r
769 \r
770         os_info = ZeroMalloc(sizeof(OS_INFO));\r
771 \r
772         OSGetOsInfo(os_info);\r
773 }\r
774 \r
775 // OS 情報の解放\r
776 void FreeOsInfo()\r
777 {\r
778         if (os_info == NULL)\r
779         {\r
780                 return;\r
781         }\r
782 \r
783         Free(os_info->OsSystemName);\r
784         Free(os_info->OsProductName);\r
785         Free(os_info->OsVendorName);\r
786         Free(os_info->OsVersion);\r
787         Free(os_info->KernelName);\r
788         Free(os_info->KernelVersion);\r
789         Free(os_info);\r
790 \r
791         os_info = NULL;\r
792 }\r
793 \r
794 // Unicode コマンドライントークンの取得\r
795 UNI_TOKEN_LIST *GetCommandLineUniToken()\r
796 {\r
797         if (cmdline_uni_token == NULL)\r
798         {\r
799                 return UniNullToken();\r
800         }\r
801         else\r
802         {\r
803                 return UniCopyToken(cmdline_uni_token);\r
804         }\r
805 }\r
806 \r
807 // コマンドライントークンの取得\r
808 TOKEN_LIST *GetCommandLineToken()\r
809 {\r
810         if (cmdline_token == NULL)\r
811         {\r
812                 return NullToken();\r
813         }\r
814         else\r
815         {\r
816                 return CopyToken(cmdline_token);\r
817         }\r
818 }\r
819 \r
820 // コマンドライン文字列をトークンに変換する\r
821 void ParseCommandLineTokens()\r
822 {\r
823         if (cmdline_token != NULL)\r
824         {\r
825                 FreeToken(cmdline_token);\r
826         }\r
827         cmdline_token = ParseCmdLine(cmdline);\r
828 \r
829         if (cmdline_uni_token != NULL)\r
830         {\r
831                 UniFreeToken(cmdline_uni_token);\r
832         }\r
833         cmdline_uni_token = UniParseCmdLine(uni_cmdline);\r
834 }\r
835 \r
836 // コマンドライントークンを解放する\r
837 void FreeCommandLineTokens()\r
838 {\r
839         if (cmdline_token != NULL)\r
840         {\r
841                 FreeToken(cmdline_token);\r
842         }\r
843         cmdline_token = NULL;\r
844 \r
845         if (cmdline_uni_token != NULL)\r
846         {\r
847                 UniFreeToken(cmdline_uni_token);\r
848         }\r
849         cmdline_uni_token = NULL;\r
850 }\r
851 \r
852 // コマンドライン文字列の初期化\r
853 void InitCommandLineStr(int argc, char **argv)\r
854 {\r
855         if (argc >= 1)\r
856         {\r
857 #ifdef  OS_UNIX\r
858                 exename_w = CopyUtfToUni(argv[0]);\r
859                 exename = CopyUniToStr(exename_w);\r
860 #else   // OS_UNIX\r
861                 exename = CopyStr(argv[0]);\r
862                 exename_w = CopyStrToUni(exename);\r
863 #endif  // OS_UNIX\r
864         }\r
865         if (argc < 2 || argv == NULL)\r
866         {\r
867                 // コマンドライン文字列無し\r
868                 SetCommandLineStr(NULL);\r
869         }\r
870         else\r
871         {\r
872                 // コマンドライン文字列有り\r
873                 int i, total_len = 1;\r
874                 char *tmp;\r
875 \r
876                 for (i = 1;i < argc;i++)\r
877                 {\r
878                         total_len += StrLen(argv[i]) * 2 + 32;\r
879                 }\r
880                 tmp = ZeroMalloc(total_len);\r
881 \r
882                 for (i = 1;i < argc;i++)\r
883                 {\r
884                         UINT s_size = StrLen(argv[i]) * 2;\r
885                         char *s = ZeroMalloc(s_size);\r
886                         bool dq = (SearchStrEx(argv[i], " ", 0, true) != INFINITE);\r
887                         ReplaceStrEx(s, s_size, argv[i], "\"", "\"\"", true);\r
888                         if (dq)\r
889                         {\r
890                                 StrCat(tmp, total_len, "\"");\r
891                         }\r
892                         StrCat(tmp, total_len, s);\r
893                         if (dq)\r
894                         {\r
895                                 StrCat(tmp, total_len, "\"");\r
896                         }\r
897                         StrCat(tmp, total_len, " ");\r
898                         Free(s);\r
899                 }\r
900 \r
901                 Trim(tmp);\r
902                 SetCommandLineStr(tmp);\r
903                 Free(tmp);\r
904         }\r
905 }\r
906 \r
907 // コマンドライン文字列の解放\r
908 void FreeCommandLineStr()\r
909 {\r
910         SetCommandLineStr(NULL);\r
911 \r
912         if (exename != NULL)\r
913         {\r
914                 Free(exename);\r
915                 exename = NULL;\r
916         }\r
917 \r
918         if (exename_w != NULL)\r
919         {\r
920                 Free(exename_w);\r
921                 exename_w = NULL;\r
922         }\r
923 }\r
924 \r
925 // Unicode コマンドライン文字列の取得\r
926 wchar_t *GetCommandLineUniStr()\r
927 {\r
928         if (uni_cmdline == NULL)\r
929         {\r
930                 return UniCopyStr(L"");\r
931         }\r
932         else\r
933         {\r
934                 return UniCopyStr(uni_cmdline);\r
935         }\r
936 }\r
937 \r
938 // コマンドライン文字列の取得\r
939 char *GetCommandLineStr()\r
940 {\r
941         if (cmdline == NULL)\r
942         {\r
943                 return CopyStr("");\r
944         }\r
945         else\r
946         {\r
947                 return CopyStr(cmdline);\r
948         }\r
949 }\r
950 \r
951 // Unicode コマンドライン文字列の設定\r
952 void SetCommandLineUniStr(wchar_t *str)\r
953 {\r
954         if (uni_cmdline != NULL)\r
955         {\r
956                 Free(uni_cmdline);\r
957         }\r
958         if (str == NULL)\r
959         {\r
960                 uni_cmdline = NULL;\r
961         }\r
962         else\r
963         {\r
964                 uni_cmdline = CopyUniStr(str);\r
965         }\r
966 \r
967         ParseCommandLineTokens();\r
968 }\r
969 \r
970 // コマンドライン文字列の設定\r
971 void SetCommandLineStr(char *str)\r
972 {\r
973         // 引数チェック\r
974         if (str == NULL)\r
975         {\r
976                 if (cmdline != NULL)\r
977                 {\r
978                         Free(cmdline);\r
979                 }\r
980                 cmdline = NULL;\r
981         }\r
982         else\r
983         {\r
984                 if (cmdline != NULL)\r
985                 {\r
986                         Free(cmdline);\r
987                 }\r
988                 cmdline = CopyStr(str);\r
989         }\r
990 \r
991         if (cmdline == NULL)\r
992         {\r
993                 if (uni_cmdline != NULL)\r
994                 {\r
995                         Free(uni_cmdline);\r
996                         uni_cmdline = NULL;\r
997                 }\r
998         }\r
999         else\r
1000         {\r
1001                 if (uni_cmdline != NULL)\r
1002                 {\r
1003                         Free(uni_cmdline);\r
1004                 }\r
1005                 uni_cmdline = CopyStrToUni(cmdline);\r
1006         }\r
1007 \r
1008         ParseCommandLineTokens();\r
1009 }\r
1010 \r
1011 // カーネルステータスの表示\r
1012 void PrintKernelStatus()\r
1013 {\r
1014         bool leaked = false;\r
1015 \r
1016         Print("\n");\r
1017         Print(\r
1018                 "     --------- Mayaqua Kernel Status ---------\n"\r
1019                 "        Malloc Count ............... %u\n"\r
1020                 "        ReAlloc Count .............. %u\n"\r
1021                 "        Free Count ................. %u\n"\r
1022                 "        Total Memory Size .......... %I64u bytes\n"\r
1023                 "      * Current Memory Blocks ...... %u Blocks (Peek: %u)\n"\r
1024                 "        Total Memory Blocks ........ %u Blocks\n"\r
1025                 "      * Current MemPool Blocks ..... %u Blocks (Peek: %u)\n"\r
1026                 "        Total MemPool Mallocs ...... %u Mallocs\n"\r
1027                 "        Total MemPool ReAllocs ..... %u ReAllocs\n"\r
1028                 "        NewLock Count .............. %u\n"\r
1029                 "        DeleteLock Count ........... %u\n"\r
1030                 "      * Current Lock Objects ....... %u Objects\n"\r
1031                 "      * Current Locked Objects ..... %u Objects\n"\r
1032                 "        NewRef Count ............... %u\n"\r
1033                 "        FreeRef Count .............. %u\n"\r
1034                 "      * Current Ref Objects ........ %u Objects\n"\r
1035                 "      * Current Ref Count .......... %u Refs\n"\r
1036                 "        GetTime Count .............. %u\n"\r
1037                 "        GetTick Count .............. %u\n"\r
1038                 "        NewThread Count ............ %u\n"\r
1039                 "        FreeThread Count ........... %u\n"\r
1040                 "      * Current Threads ............ %u Threads\n"\r
1041                 "        Wait For Event Count ....... %u\n\n",\r
1042                 KS_GET(KS_MALLOC_COUNT),\r
1043                 KS_GET(KS_REALLOC_COUNT),\r
1044                 KS_GET(KS_FREE_COUNT),\r
1045                 KS_GET64(KS_TOTAL_MEM_SIZE),\r
1046                 KS_GET(KS_CURRENT_MEM_COUNT),\r
1047                 KS_GETMAX(KS_CURRENT_MEM_COUNT),\r
1048                 KS_GET(KS_TOTAL_MEM_COUNT),\r
1049                 KS_GET(KS_MEMPOOL_CURRENT_NUM),\r
1050                 KS_GETMAX(KS_MEMPOOL_CURRENT_NUM),\r
1051                 KS_GET(KS_MEMPOOL_MALLOC_COUNT),\r
1052                 KS_GET(KS_MEMPOOL_REALLOC_COUNT),\r
1053                 KS_GET(KS_NEWLOCK_COUNT),\r
1054                 KS_GET(KS_DELETELOCK_COUNT),\r
1055                 KS_GET(KS_CURRENT_LOCK_COUNT),\r
1056                 KS_GET(KS_CURRENT_LOCKED_COUNT),\r
1057                 KS_GET(KS_NEWREF_COUNT),\r
1058                 KS_GET(KS_FREEREF_COUNT),\r
1059                 KS_GET(KS_CURRENT_REF_COUNT),\r
1060                 KS_GET(KS_CURRENT_REFED_COUNT),\r
1061                 KS_GET(KS_GETTIME_COUNT),\r
1062                 KS_GET(KS_GETTICK_COUNT),\r
1063                 KS_GET(KS_NEWTHREAD_COUNT),\r
1064                 KS_GET(KS_FREETHREAD_COUNT),\r
1065                 KS_GET(KS_NEWTHREAD_COUNT) - KS_GET(KS_FREETHREAD_COUNT),\r
1066                 KS_GET(KS_WAIT_COUNT)\r
1067                 );\r
1068 \r
1069         if (KS_GET(KS_CURRENT_MEM_COUNT) != 0 || KS_GET(KS_CURRENT_LOCK_COUNT) != 0 ||\r
1070                 KS_GET(KS_MEMPOOL_CURRENT_NUM) != 0 ||\r
1071                 KS_GET(KS_CURRENT_LOCKED_COUNT) != 0 || KS_GET(KS_CURRENT_REF_COUNT) != 0)\r
1072         {\r
1073                 leaked = true;\r
1074         }\r
1075 \r
1076         if (leaked)\r
1077         {\r
1078                 Print("      !!! MEMORY LEAKS DETECTED !!!\n\n");\r
1079                 if (g_memcheck == false)\r
1080                 {\r
1081                         GetLine(NULL, 0);\r
1082                 }\r
1083         }\r
1084         else\r
1085         {\r
1086                 Print("        @@@ NO MEMORY LEAKS @@@\n\n");\r
1087         }\r
1088 }\r
1089 \r
1090 // カーネルステータスの初期化\r
1091 void InitKernelStatus()\r
1092 {\r
1093         UINT i;\r
1094 \r
1095         // メモリ初期化\r
1096         Zero(kernel_status, sizeof(kernel_status));\r
1097         Zero(kernel_status_max, sizeof(kernel_status_max));\r
1098 \r
1099         // ロック初期化\r
1100         for (i = 0;i < NUM_KERNEL_STATUS;i++)\r
1101         {\r
1102                 kernel_status_lock[i] = OSNewLock();\r
1103         }\r
1104 \r
1105         kernel_status_inited = true;\r
1106 }\r
1107 \r
1108 // カーネルステータスの解放\r
1109 void FreeKernelStatus()\r
1110 {\r
1111         UINT i;\r
1112 \r
1113         kernel_status_inited = false;\r
1114 \r
1115         // ロック解放\r
1116         for (i = 0;i < NUM_KERNEL_STATUS;i++)\r
1117         {\r
1118                 OSDeleteLock(kernel_status_lock[i]);\r
1119         }\r
1120 }\r
1121 \r
1122 // カーネルステータスのロック\r
1123 void LockKernelStatus(UINT id)\r
1124 {\r
1125         // 引数チェック\r
1126         if (id >= NUM_KERNEL_STATUS)\r
1127         {\r
1128                 return;\r
1129         }\r
1130 \r
1131         OSLock(kernel_status_lock[id]);\r
1132 }\r
1133 \r
1134 // カーネルステータスのロック解除\r
1135 void UnlockKernelStatus(UINT id)\r
1136 {\r
1137         // 引数チェック\r
1138         if (id >= NUM_KERNEL_STATUS)\r
1139         {\r
1140                 return;\r
1141         }\r
1142 \r
1143         OSUnlock(kernel_status_lock[id]);\r
1144 }\r
1145 \r
1146 // デバッグ情報の表示\r
1147 void PrintDebugInformation()\r
1148 {\r
1149         MEMORY_STATUS memory_status;\r
1150         GetMemoryStatus(&memory_status);\r
1151 \r
1152         // ヘッダ\r
1153         Print("====== SoftEther UT-VPN System Debug Information ======\n");\r
1154 \r
1155         // メモリ情報\r
1156         Print(" <Memory Status>\n"\r
1157                 "       Number of Allocated Memory Blocks: %u\n"\r
1158                 "   Total Size of Allocated Memory Blocks: %u bytes\n",\r
1159                 memory_status.MemoryBlocksNum, memory_status.MemorySize);\r
1160 \r
1161         // フッタ\r
1162         Print("====================================================\n");\r
1163 \r
1164         if (KS_GET(KS_CURRENT_MEM_COUNT) != 0 || KS_GET(KS_CURRENT_LOCK_COUNT) != 0 ||\r
1165                 KS_GET(KS_CURRENT_LOCKED_COUNT) != 0 || KS_GET(KS_CURRENT_REF_COUNT) != 0)\r
1166         {\r
1167                 // メモリリークしている可能性があるのでデバッグメニューを出す\r
1168                 MemoryDebugMenu();\r
1169         }\r
1170 }\r
1171 \r
1172 \r
1173 \r
1174 \r