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

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